From 53f0cd990c3d26e73b42266be35516d6db9621e0 Mon Sep 17 00:00:00 2001 From: Matthew Chapman Date: Thu, 8 Apr 1999 05:35:53 +0000 Subject: Mainly BDC-related changes. * Added SEC_CHAN_BDC * Fix for endianness problem reported by Edan Idzerda . A BUFFER2 is really a "unibuf" in my terminology and we should treat it as such. * Added some more common NT structures (BIGINT, BUFHDR2, BUFFER4). * Added NET_SAM_SYNC (-> NetDatabaseSync2) RPC for account replication. Still experimental and incomplete, with a few too many NULL security descriptors lying around (must go look at Jeremy's SD code). Haven't worked out password encryption yet either. However, the XXX_INFO structures I've added to rpc_netlogon.h are quite nice as they give some insight into how these objects are stored in the SAM. (This used to be commit 74d6dec25d6b44e26d3895f789f1958d5f4639ee) --- source3/include/proto.h | 26 ++++- source3/include/rpc_misc.h | 28 ++++- source3/include/rpc_netlogon.h | 246 +++++++++++++++++++++++++++++++++++++++- source3/rpc_server/srv_netlog.c | 78 +++++++++++++ 4 files changed, 370 insertions(+), 8 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 7982e1094e..85ef3623bb 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1594,7 +1594,8 @@ BOOL cli_nt_setup_creds(struct cli_state *cli, uint16 fnum, const char* trust_acct, unsigned char trust_pwd[16], uint16 sec_chan); -BOOL cli_nt_srv_pwset(struct cli_state *cli, uint16 fnum, unsigned char *new_hashof_trust_pwd); +BOOL cli_nt_srv_pwset(struct cli_state *cli, uint16 fnum, + unsigned char *new_hashof_trust_pwd, uint16 sec_chan); BOOL cli_nt_login_interactive(struct cli_state *cli, uint16 fnum, char *domain, char *username, uint32 luid_low, char *password, NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3); @@ -1641,11 +1642,14 @@ BOOL cli_net_auth2(struct cli_state *cli, uint16 nt_pipe_fnum, const char *trust_acct, uint16 sec_chan, uint32 neg_flags, DOM_CHAL *srv_chal); BOOL cli_net_req_chal(struct cli_state *cli, uint16 nt_pipe_fnum, DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal); -BOOL cli_net_srv_pwset(struct cli_state *cli, uint16 nt_pipe_fnum, uint8 hashed_mach_pwd[16]); +BOOL cli_net_srv_pwset(struct cli_state *cli, uint16 nt_pipe_fnum, + uint8 hashed_mach_pwd[16], uint16 sec_chan_type); BOOL cli_net_sam_logon(struct cli_state *cli, uint16 nt_pipe_fnum, NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3); BOOL cli_net_sam_logoff(struct cli_state *cli, uint16 nt_pipe_fnum, NET_ID_INFO_CTR *ctr); -BOOL change_trust_account_password( char *domain, char *remote_machine_list); +BOOL cli_net_sam_sync(struct cli_state *cli, uint16 nt_pipe_fnum, uint32 database_id); +BOOL change_trust_account_password(char *domain, char *remote_machine_list, + uint16 sec_chan); /*The following definitions come from rpc_client/cli_pipe.c */ @@ -1941,6 +1945,7 @@ void lsa_io_r_close(char *desc, LSA_R_CLOSE *r_c, prs_struct *ps, int depth); /*The following definitions come from rpc_parse/parse_misc.c */ +void smb_io_bigint(char *desc, BIGINT *bigint, prs_struct *ps, int depth); void smb_io_time(char *desc, NTTIME *nttime, prs_struct *ps, int depth); void smb_io_lookup_level(char *desc, LOOKUP_LEVEL *level, prs_struct *ps, int depth); uint32 get_enum_hnd(ENUM_HND *enh); @@ -1960,6 +1965,8 @@ void smb_io_hdrbuf_pre(char *desc, BUFHDR *hdr, prs_struct *ps, int depth, uint void smb_io_hdrbuf_post(char *desc, BUFHDR *hdr, prs_struct *ps, int depth, uint32 ptr_hdrbuf, uint32 max_len, uint32 len); void smb_io_hdrbuf(char *desc, BUFHDR *hdr, prs_struct *ps, int depth); +void make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer); +void smb_io_bufhdr2(char *desc, BUFHDR2 *hdr, prs_struct *ps, int depth); void make_uni_hdr2(UNIHDR2 *hdr, int len); void smb_io_unihdr2(char *desc, UNIHDR2 *hdr2, prs_struct *ps, int depth); void make_unistr(UNISTR *str, char *buf); @@ -1969,6 +1976,7 @@ void make_buffer3_str(BUFFER3 *str, char *buf, int len); void make_buffer3_hex(BUFFER3 *str, char *buf); void make_buffer3_bytes(BUFFER3 *str, uint8 *buf, int len); void smb_io_buffer3(char *desc, BUFFER3 *buf3, prs_struct *ps, int depth); +void smb_io_buffer4(char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, int depth); void make_buffer2(BUFFER2 *str, const char *buf, int len); void smb_io_buffer2(char *desc, BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth); void make_buf_unistr2(UNISTR2 *str, uint32 *ptr, char *buf); @@ -1996,8 +2004,6 @@ void make_clnt_info(DOM_CLNT_INFO *clnt, uint16 sec_chan, char *comp_name, DOM_CRED *cred); void smb_io_clnt_info(char *desc, DOM_CLNT_INFO *clnt, prs_struct *ps, int depth); -void make_logon_id(DOM_LOGON_ID *log, uint32 log_id_low, uint32 log_id_high); -void smb_io_logon_id(char *desc, DOM_LOGON_ID *log, prs_struct *ps, int depth); void make_owf_info(OWF_INFO *hash, uint8 data[16]); void smb_io_owf_info(char *desc, OWF_INFO *hash, prs_struct *ps, int depth); void smb_io_gid(char *desc, DOM_GID *gid, prs_struct *ps, int depth); @@ -2083,6 +2089,15 @@ void net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int d void net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth); void net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth); void net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth); +void make_q_sam_sync(NET_Q_SAM_SYNC *q_s, char *srv_name, char *cli_name, + DOM_CRED *cli_creds, uint32 database_id); +void net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC *q_s, prs_struct *ps, int depth); +void make_sam_delta_hdr(SAM_DELTA_HDR *delta, uint16 type, uint32 rid); +void make_sam_account_info(SAM_ACCOUNT_INFO *info, char *user_name, + char *full_name, uint32 user_rid, uint32 group_rid, + char *home_dir, char *dir_drive, char *logon_script, + char *acct_desc, uint32 acb_info, char *profile); +void net_io_r_sam_sync(char *desc, NET_R_SAM_SYNC *r_s, prs_struct *ps, int depth); /*The following definitions come from rpc_parse/parse_prs.c */ @@ -2838,6 +2853,7 @@ void cmd_lsa_query_secret(struct client_info *info); void cmd_netlogon_login_test(struct client_info *info); void cmd_netlogon_domain_test(struct client_info *info); +void cmd_sam_sync(struct client_info *info); /*The following definitions come from rpcclient/cmd_reg.c */ diff --git a/source3/include/rpc_misc.h b/source3/include/rpc_misc.h index 3e4d52a038..eb345770ff 100644 --- a/source3/include/rpc_misc.h +++ b/source3/include/rpc_misc.h @@ -63,6 +63,15 @@ #define RID_TYPE_GROUP 1 #define RID_TYPE_ALIAS 2 +/* BIGINT - NT-style 64-bit integer */ +typedef struct bigint_info +{ + uint32 low; + uint32 high; + +} BIGINT; + + /* ENUM_HND */ typedef struct enum_hnd_info { @@ -142,6 +151,15 @@ typedef struct bufhdr_info } BUFHDR; +/* BUFHDR2 - another buffer header, with info level */ +typedef struct bufhdr2_info +{ + uint32 info_level; + uint32 length; /* uint8 chars */ + uint32 buffer; + +} BUFHDR2; + /* BUFFER2 - unicode string, size (in uint8 ascii chars) and buffer */ /* pathetic. some stupid team of \PIPE\winreg writers got the concept */ /* of a unicode string different from the other \PIPE\ writers */ @@ -150,7 +168,7 @@ typedef struct buffer2_info uint32 buf_max_len; uint32 undoc; uint32 buf_len; - uint16 buffer[MAX_UNISTRLEN]; /* unicode characters. **NOT** necessarily null-terminated */ + uint8 buffer[MAX_UNISTRLEN]; } BUFFER2; @@ -163,6 +181,14 @@ typedef struct buffer3_info } BUFFER3; +/* BUFFER4 - simple length and buffer */ +typedef struct buffer4_info +{ + uint32 buf_len; + uint8 buffer[MAX_BUFFERLEN]; + +} BUFFER4; + /* UNISTR2 - unicode string size (in uint16 unicode chars) and buffer */ typedef struct unistr2_info { diff --git a/source3/include/rpc_netlogon.h b/source3/include/rpc_netlogon.h index ca8231fc5b..2d8f5ae1b7 100644 --- a/source3/include/rpc_netlogon.h +++ b/source3/include/rpc_netlogon.h @@ -34,9 +34,13 @@ #define NET_LOGON_CTRL2 0x0e #define NET_TRUST_DOM_LIST 0x13 +#define NET_SAM_SYNC 0x10 +#define NET_SAM_DELTAS 0x07 + /* Secure Channel types. used in NetrServerAuthenticate negotiation */ #define SEC_CHAN_WKSTA 2 #define SEC_CHAN_DOMAIN 4 +#define SEC_CHAN_BDC 6 /* NET_USER_INFO_3 */ @@ -269,7 +273,7 @@ typedef struct net_network_info_2 uint32 ptr_id_info2; /* pointer to id_info_2 */ UNIHDR hdr_domain_name; /* domain name unicode header */ uint32 param_ctrl; /* param control (0x2) */ - DOM_LOGON_ID logon_id; /* logon ID */ + BIGINT logon_id; /* logon ID */ UNIHDR hdr_user_name; /* user name unicode header */ UNIHDR hdr_wksta_name; /* workstation name unicode header */ uint8 lm_chal[8]; /* lan manager 8 byte challenge */ @@ -290,7 +294,7 @@ typedef struct id_info_1 uint32 ptr_id_info1; /* pointer to id_info_1 */ UNIHDR hdr_domain_name; /* domain name unicode header */ uint32 param_ctrl; /* param control */ - DOM_LOGON_ID logon_id; /* logon ID */ + BIGINT logon_id; /* logon ID */ UNIHDR hdr_user_name; /* user name unicode header */ UNIHDR hdr_wksta_name; /* workstation name unicode header */ OWF_INFO lm_owf; /* LM OWF Password */ @@ -371,5 +375,243 @@ typedef struct net_r_sam_logoff_info } NET_R_SAM_LOGOFF; +/* NET_Q_SAM_SYNC */ +typedef struct net_q_sam_sync_info +{ + UNISTR2 uni_srv_name; /* \\PDC */ + UNISTR2 uni_cli_name; /* BDC */ + DOM_CRED cli_creds; + DOM_CRED ret_creds; + + uint32 database_id; + uint32 restart_state; + uint32 sync_context; + + uint32 max_size; /* preferred maximum length */ + +} NET_Q_SAM_SYNC; + +#define MAX_GROUP_MEM 256 +#define MAX_SAM_DELTAS 256 + +/* SAM_DELTA_HDR */ +typedef struct sam_delta_hdr_info +{ + uint16 type; /* type of structure attached, see below */ + uint16 type2; + uint32 target_rid; + + uint32 type3; + uint32 ptr_delta; + +} SAM_DELTA_HDR; + +/* SAM_DOMAIN_INFO (0x1) */ +typedef struct sam_domain_info_info +{ + UNIHDR hdr_dom_name; + UNIHDR hdr_oem_info; + + BIGINT force_logoff; + uint16 min_pwd_len; + uint16 pwd_history_len; + BIGINT max_pwd_age; + BIGINT min_pwd_age; + BIGINT dom_mod_count; + NTTIME creation_time; + + BUFHDR2 hdr_sec_desc; /* security descriptor */ + UNIHDR hdr_unknown; + uint8 reserved[40]; + + UNISTR2 uni_dom_name; + UNISTR2 buf_oem_info; /* never seen */ + + BUFFER4 buf_sec_desc; + UNISTR2 buf_unknown; + +} SAM_DOMAIN_INFO; + +/* SAM_GROUP_INFO (0x2) */ +typedef struct sam_group_info_info +{ + UNIHDR hdr_grp_name; + DOM_GID gid; + UNIHDR hdr_grp_desc; + BUFHDR2 hdr_sec_desc; /* security descriptor */ + uint8 reserved[48]; + + UNISTR2 uni_grp_name; + UNISTR2 uni_grp_desc; + BUFFER4 buf_sec_desc; + +} SAM_GROUP_INFO; + +/* SAM_ACCOUNT_INFO (0x5) */ +typedef struct sam_account_info_info +{ + UNIHDR hdr_acct_name; + UNIHDR hdr_full_name; + + uint32 user_rid; + uint32 group_rid; + + UNIHDR hdr_home_dir; + UNIHDR hdr_dir_drive; + UNIHDR hdr_logon_script; + UNIHDR hdr_acct_desc; + + NTTIME time_1; + NTTIME time_2; + NTTIME time_3; + + uint32 logon_divs; /* 0xA8 */ + uint32 ptr_logon_hrs; + + /* N.B. 8-byte alignment */ + NTTIME time_4; + NTTIME time_5; + uint32 acb_info; + char reserved[36]; + + UNIHDR hdr_comment; + char unknown1[12]; + + BUFHDR2 hdr_pwd_info; + BUFHDR2 hdr_sec_desc; /* security descriptor */ + UNIHDR hdr_profile; + + char unknown2[24]; + NTTIME time_6; /* *** HIGH/LOW DWORDS THE WRONG WAY!!! *** */ + char unknown3[8]; + + UNISTR2 uni_acct_name; + UNISTR2 uni_full_name; + UNISTR2 uni_home_dir; + UNISTR2 uni_dir_drive; + UNISTR2 uni_logon_script; + UNISTR2 uni_acct_desc; + + uint32 unknown4; /* 0x4EC */ + uint32 unknown5; /* 0 */ + + BUFFER4 buf_logon_hrs; + UNISTR2 uni_comment; + BUFFER4 buf_pwd_info; + BUFFER4 buf_sec_desc; + UNISTR2 uni_profile; + +} SAM_ACCOUNT_INFO; + +/* SAM_GROUP_MEM_INFO (0x8) */ +typedef struct sam_group_mem_info_info +{ + uint32 ptr_rids; + uint32 ptr_attribs; + uint32 num_members; + uint8 unknown[16]; + + uint32 num_members2; + uint32 rids[MAX_GROUP_MEM]; + + uint32 num_members3; + uint32 attribs[MAX_GROUP_MEM]; + +} SAM_GROUP_MEM_INFO; + +/* SAM_ALIAS_INFO (0x9) */ +typedef struct sam_alias_info_info +{ + UNIHDR hdr_als_name; + uint32 als_rid; + BUFHDR2 hdr_sec_desc; /* security descriptor */ + UNIHDR hdr_als_desc; + uint8 reserved[40]; + + UNISTR2 uni_als_name; + BUFFER4 buf_sec_desc; + UNISTR2 uni_als_desc; + +} SAM_ALIAS_INFO; + +/* SAM_ALIAS_MEM_INFO (0xC) */ +typedef struct sam_alias_mem_info_info +{ + uint32 num_members; + uint32 ptr_members; + uint8 unknown[16]; + + uint32 num_sids; + uint32 ptr_sids[MAX_GROUP_MEM]; + DOM_SID2 sids[MAX_GROUP_MEM]; + +} SAM_ALIAS_MEM_INFO; + +/* SAM_DELTA_CTR */ +typedef union sam_delta_ctr_info +{ + SAM_DOMAIN_INFO domain_info ; + SAM_GROUP_INFO group_info ; + SAM_ACCOUNT_INFO account_info; + SAM_GROUP_MEM_INFO grp_mem_info; + SAM_ALIAS_INFO alias_info ; + SAM_ALIAS_MEM_INFO als_mem_info; + +} SAM_DELTA_CTR; + +/* NET_R_SAM_SYNC */ +typedef struct net_r_sam_sync_info +{ + DOM_CRED srv_creds; + + uint32 sync_context; + + uint32 ptr_deltas; + uint32 num_deltas; + uint32 ptr_deltas2; + uint32 num_deltas2; + + SAM_DELTA_HDR hdr_deltas[MAX_SAM_DELTAS]; + SAM_DELTA_CTR deltas[MAX_SAM_DELTAS]; + + uint32 status; + +} NET_R_SAM_SYNC; + + +/* NET_Q_SAM_DELTAS */ +typedef struct net_q_sam_deltas_info +{ + UNISTR2 uni_srv_name; + UNISTR2 uni_cli_name; + DOM_CRED cli_creds; + DOM_CRED ret_creds; + + uint32 database_id; + BIGINT dom_mod_count; /* domain mod count at last sync */ + + uint32 max_size; /* preferred maximum length */ + +} NET_Q_SAM_DELTAS; + +/* NET_R_SAM_DELTAS */ +typedef struct net_r_sam_deltas_info +{ + DOM_CRED srv_creds; + + BIGINT dom_mod_count; /* new domain mod count */ + + uint32 num_deltas; + uint32 ptr_deltas; + uint32 num_deltas2; + + SAM_DELTA_HDR hdr_deltas[MAX_SAM_DELTAS]; + SAM_DELTA_CTR deltas[MAX_SAM_DELTAS]; + + uint32 status; + +} NET_R_SAM_DELTAS; + + #endif /* _RPC_NETLOGON_H */ diff --git a/source3/rpc_server/srv_netlog.c b/source3/rpc_server/srv_netlog.c index 33af093625..c84e91f643 100644 --- a/source3/rpc_server/srv_netlog.c +++ b/source3/rpc_server/srv_netlog.c @@ -224,6 +224,48 @@ static void net_reply_sam_logoff(NET_Q_SAM_LOGOFF *q_s, prs_struct *rdata, } +/************************************************************************* + net_reply_sam_sync: + *************************************************************************/ +static void net_reply_sam_sync(NET_Q_SAM_SYNC *q_s, prs_struct *rdata, + DOM_CRED *srv_creds, uint32 status) +{ + NET_R_SAM_SYNC r_s; + int i = 0; + struct sam_passwd *pwd; + void *vp; + + memcpy(&(r_s.srv_creds), srv_creds, sizeof(r_s.srv_creds)); + r_s.sync_context = 1; + r_s.ptr_deltas = 0; + + if ((status == 0x0) && ((vp = startsmbpwent(False)) != NULL)) + { + /* Give the poor BDC some accounts */ + + while (((pwd = getsam21pwent(vp)) != NULL) && (i < MAX_SAM_DELTAS)) + { + make_sam_delta_hdr(&r_s.hdr_deltas[i], 5, pwd->user_rid); + make_sam_account_info(&r_s.deltas[i].account_info, + pwd->nt_name, pwd->full_name, pwd->user_rid, + pwd->group_rid, pwd->home_dir, pwd->dir_drive, + pwd->logon_script, pwd->acct_desc, + pwd->acct_ctrl, pwd->profile_path); + } + + endsmbpwent(vp); + + r_s.ptr_deltas = r_s.ptr_deltas2 = 1; + r_s.num_deltas = r_s.num_deltas2 = i; + } + + r_s.status = status; + + /* store the response in the SMB stream */ + net_io_r_sam_sync("", &r_s, rdata, 0); + +} + /****************************************************************** gets a machine password entry. checks access rights of the host. ******************************************************************/ @@ -487,6 +529,41 @@ static void api_net_sam_logoff( uint16 vuid, 0x0); } +/************************************************************************* + api_net_sam_sync: + *************************************************************************/ +static void api_net_sam_sync( uint16 vuid, + prs_struct *data, + prs_struct *rdata) +{ + NET_Q_SAM_SYNC q_s; + DOM_CRED srv_creds; + user_struct *vuser; + uint32 status = 0x0; + + if ((vuser = get_valid_user_struct(vuid)) == NULL) + return; + + /* grab the challenge... */ + net_io_q_sam_sync("", &q_s, data, 0); + + /* checks and updates credentials. creates reply credentials */ + if (deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred), + &(q_s.cli_creds), &srv_creds)) + { + memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), + sizeof(vuser->dc.clnt_cred)); + } + else + { + status = 0xC0000000 | NT_STATUS_NETWORK_CREDENTIAL_CONFLICT; + } + + /* construct reply. */ + net_reply_sam_sync(&q_s, rdata, &srv_creds, status); +} + + /************************************************************************* net_login_interactive: *************************************************************************/ @@ -881,6 +958,7 @@ static struct api_struct api_net_cmds [] = { "NET_SAMLOGOFF" , NET_SAMLOGOFF , api_net_sam_logoff }, { "NET_LOGON_CTRL2" , NET_LOGON_CTRL2 , api_net_logon_ctrl2 }, { "NET_TRUST_DOM_LIST", NET_TRUST_DOM_LIST, api_net_trust_dom_list }, + { "NET_SAM_SYNC" , NET_SAM_SYNC , api_net_sam_sync }, { NULL , 0 , NULL } }; -- cgit