diff options
-rw-r--r-- | source3/include/rpc_samr.h | 57 | ||||
-rw-r--r-- | source3/rpc_parse/parse_samr.c | 271 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr.c | 64 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr_nt.c | 98 |
4 files changed, 448 insertions, 42 deletions
diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h index 7817579ba9..b3b46c6f0c 100644 --- a/source3/include/rpc_samr.h +++ b/source3/include/rpc_samr.h @@ -87,6 +87,7 @@ SamrTestPrivateFunctionsUser #define SAMR_ENUM_DOMAINS 0x06 #define SAMR_OPEN_DOMAIN 0x07 #define SAMR_QUERY_DOMAIN_INFO 0x08 +#define SAMR_SET_DOMAIN_INFO 0x09 #define SAMR_CREATE_DOM_GROUP 0x0a #define SAMR_ENUM_DOM_GROUPS 0x0b @@ -127,7 +128,7 @@ SamrTestPrivateFunctionsUser #define SAMR_UNKNOWN_2b 0x2b #define SAMR_GET_USRDOM_PWINFO 0x2c #define SAMR_UNKNOWN_2D 0x2d -#define SAMR_UNKNOWN_2e 0x2e +#define SAMR_UNKNOWN_2E 0x2e /* looks like an alias for SAMR_QUERY_DOMAIN_INFO */ #define SAMR_UNKNOWN_2f 0x2f #define SAMR_QUERY_DISPINFO3 0x30 /* Alias for SAMR_QUERY_DISPINFO with info level 3 */ @@ -507,12 +508,9 @@ typedef struct sam_unknown_info_7_info typedef struct sam_unknown_info_12_inf { - uint32 unknown_0; /* 0xcf1d cc00 */ - uint32 unknown_1; /* 0xffff fffb */ - uint32 unknown_2; /* 0xcf1d cc00 */ - uint32 unknown_3; /* 0xffff fffb */ - - uint32 unknown_4; /* 0x8a88 0000 */ + NTTIME duration; + NTTIME reset_count; + uint16 bad_attempt_lockout; } SAM_UNK_INFO_12; @@ -1760,39 +1758,38 @@ typedef struct sid_info_3 /* SAMR_Q_UNKNOWN_2E */ typedef struct q_samr_unknown_2e_info { - POLICY_HND dom_pol; /* policy handle */ + POLICY_HND domain_pol; /* policy handle */ uint16 switch_value; } SAMR_Q_UNKNOWN_2E; -typedef struct sam_unknown_2e_info_12 +/* SAMR_R_UNKNOWN_2E */ +typedef struct r_samr_unknown_2e_info { - uint32 duration_low; - uint32 duration_high; - uint32 reset_count_low; - uint32 reset_count_high; - uint32 bad_attempt_lockout; -} SAM_UNK_2E_INFO_12; + uint32 ptr_0; + uint16 switch_value; + SAM_UNK_CTR *ctr; + NTSTATUS status; /* return status */ -typedef struct sam_unknown_2e_ctr_info -{ - union - { - SAM_UNK_2E_INFO_12 info12; - } info; +} SAMR_R_UNKNOWN_2E; -} SAM_UNK_2E_CTR; +/* SAMR_Q_SET_DOMAIN_INFO */ +typedef struct q_samr_set_domain_info +{ + POLICY_HND domain_pol; /* policy handle */ + uint16 switch_value0; + uint16 switch_value; + SAM_UNK_CTR *ctr; +} SAMR_Q_SET_DOMAIN_INFO; -/* SAMR_R_UNKNOWN_2E - probably an open */ -typedef struct r_samr_unknown_2e_info +/* SAMR_R_SET_DOMAIN_INFO */ +typedef struct r_samr_set_domain_info { - uint32 ptr; - uint16 switch_value; - SAM_UNK_2E_CTR *ctr; - - uint32 status; /* return status */ + NTSTATUS status; /* return status */ + +} SAMR_R_SET_DOMAIN_INFO; + -} SAMR_R_UNKNOWN_2E; #endif /* _RPC_SAMR_H */ diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index a7fb77d382..99c0fe30be 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -556,12 +556,12 @@ inits a structure. void init_unk_info12(SAM_UNK_INFO_12 * u_12) { - u_12->unknown_0 = 0xcf1dcc00; - u_12->unknown_1 = 0xfffffffb; - u_12->unknown_2 = 0xcf1dcc00; - u_12->unknown_3 = 0xfffffffb; + u_12->duration.low = 0xcf1dcc00; + u_12->duration.high = 0xfffffffb; + u_12->reset_count.low = 0xcf1dcc00; + u_12->reset_count.high = 0xfffffffb; - u_12->unknown_4 = 0x8a880000; + u_12->bad_attempt_lockout = 0x0000; } /******************************************************************* @@ -577,15 +577,11 @@ static BOOL sam_io_unk_info12(char *desc, SAM_UNK_INFO_12 * u_12, prs_debug(ps, depth, desc, "sam_io_unk_info12"); depth++; - if(!prs_uint32("unknown_0", ps, depth, &u_12->unknown_0)) + if(!smb_io_time("duration", &u_12->duration, ps, depth)) return False; - if(!prs_uint32("unknown_1", ps, depth, &u_12->unknown_1)) + if(!smb_io_time("reset_count", &u_12->reset_count, ps, depth)) return False; - if(!prs_uint32("unknown_2", ps, depth, &u_12->unknown_2)) - return False; - if(!prs_uint32("unknown_3", ps, depth, &u_12->unknown_3)) - return False; - if(!prs_uint32("unknown_4", ps, depth, &u_12->unknown_4)) + if(!prs_uint16("bad_attempt_lockout", ps, depth, &u_12->bad_attempt_lockout)) return False; return True; @@ -6864,3 +6860,254 @@ BOOL samr_io_r_chgpasswd_user(char *desc, SAMR_R_CHGPASSWD_USER * r_u, return True; } + +/******************************************************************* +reads or writes a structure. +********************************************************************/ + +void init_samr_q_unknown_2e(SAMR_Q_UNKNOWN_2E *q_u, + POLICY_HND *domain_pol, uint16 switch_value) +{ + DEBUG(5, ("init_samr_q_unknown_2e\n")); + + q_u->domain_pol = *domain_pol; + q_u->switch_value = switch_value; +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ + +BOOL samr_io_q_unknown_2e(char *desc, SAMR_Q_UNKNOWN_2E *q_u, + prs_struct *ps, int depth) +{ + if (q_u == NULL) + return False; + + prs_debug(ps, depth, desc, "samr_io_q_unknown_2e"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!smb_io_pol_hnd("domain_pol", &q_u->domain_pol, ps, depth)) + return False; + + if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value)) + return False; + + return True; +} + +/******************************************************************* +inits a SAMR_R_QUERY_DOMAIN_INFO structure. +********************************************************************/ + +void init_samr_r_samr_unknown_2e(SAMR_R_UNKNOWN_2E * r_u, + uint16 switch_value, SAM_UNK_CTR * ctr, + NTSTATUS status) +{ + DEBUG(5, ("init_samr_r_samr_unknown_2e\n")); + + r_u->ptr_0 = 0; + r_u->switch_value = 0; + r_u->status = status; /* return status */ + + if (NT_STATUS_IS_OK(status)) { + r_u->switch_value = switch_value; + r_u->ptr_0 = 1; + r_u->ctr = ctr; + } +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ + +BOOL samr_io_r_samr_unknown_2e(char *desc, SAMR_R_UNKNOWN_2E * r_u, + prs_struct *ps, int depth) +{ + if (r_u == NULL) + return False; + + prs_debug(ps, depth, desc, "samr_io_r_samr_unknown_2e"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("ptr_0 ", ps, depth, &r_u->ptr_0)) + return False; + + if (r_u->ptr_0 != 0 && r_u->ctr != NULL) { + if(!prs_uint16("switch_value", ps, depth, &r_u->switch_value)) + return False; + if(!prs_align(ps)) + return False; + + switch (r_u->switch_value) { + case 0x0c: + if(!sam_io_unk_info12("unk_inf12", &r_u->ctr->info.inf12, ps, depth)) + return False; + break; + case 0x07: + if(!sam_io_unk_info7("unk_inf7",&r_u->ctr->info.inf7, ps,depth)) + return False; + break; + case 0x06: + if(!sam_io_unk_info6("unk_inf6",&r_u->ctr->info.inf6, ps,depth)) + return False; + break; + case 0x05: + if(!sam_io_unk_info5("unk_inf5",&r_u->ctr->info.inf5, ps,depth)) + return False; + break; + case 0x03: + if(!sam_io_unk_info3("unk_inf3",&r_u->ctr->info.inf3, ps,depth)) + return False; + break; + case 0x02: + if(!sam_io_unk_info2("unk_inf2",&r_u->ctr->info.inf2, ps,depth)) + return False; + break; + case 0x01: + if(!sam_io_unk_info1("unk_inf1",&r_u->ctr->info.inf1, ps,depth)) + return False; + break; + default: + DEBUG(0, ("samr_io_r_samr_unknown_2e: unknown switch level 0x%x\n", + r_u->switch_value)); + r_u->status = NT_STATUS_INVALID_INFO_CLASS; + return False; + } + } + + if(!prs_align(ps)) + return False; + + if(!prs_ntstatus("status", ps, depth, &r_u->status)) + return False; + + return True; +} + + +/******************************************************************* +reads or writes a structure. +********************************************************************/ + +void init_samr_q_set_domain_info(SAMR_Q_SET_DOMAIN_INFO *q_u, + POLICY_HND *domain_pol, uint16 switch_value, SAM_UNK_CTR *ctr) +{ + DEBUG(5, ("init_samr_q_set_domain_info\n")); + + q_u->domain_pol = *domain_pol; + q_u->switch_value0 = switch_value; + + q_u->switch_value = switch_value; + q_u->ctr = ctr; + +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ + +BOOL samr_io_q_set_domain_info(char *desc, SAMR_Q_SET_DOMAIN_INFO *q_u, + prs_struct *ps, int depth) +{ + if (q_u == NULL) + return False; + + prs_debug(ps, depth, desc, "samr_io_q_set_domain_info"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!smb_io_pol_hnd("domain_pol", &q_u->domain_pol, ps, depth)) + return False; + + if(!prs_uint16("switch_value0", ps, depth, &q_u->switch_value0)) + return False; + + if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value)) + return False; + + if(!prs_align(ps)) + return False; + + if ((q_u->ctr = (SAM_UNK_CTR *)prs_alloc_mem(ps, sizeof(SAM_UNK_CTR))) == NULL) + return False; + + switch (q_u->switch_value) { + + case 0x0c: + if(!sam_io_unk_info12("unk_inf12", &q_u->ctr->info.inf12, ps, depth)) + return False; + break; + case 0x07: + if(!sam_io_unk_info7("unk_inf7",&q_u->ctr->info.inf7, ps,depth)) + return False; + break; + case 0x06: + if(!sam_io_unk_info6("unk_inf6",&q_u->ctr->info.inf6, ps,depth)) + return False; + break; + case 0x05: + if(!sam_io_unk_info5("unk_inf5",&q_u->ctr->info.inf5, ps,depth)) + return False; + break; + case 0x03: + if(!sam_io_unk_info3("unk_inf3",&q_u->ctr->info.inf3, ps,depth)) + return False; + break; + case 0x02: + if(!sam_io_unk_info2("unk_inf2",&q_u->ctr->info.inf2, ps,depth)) + return False; + break; + case 0x01: + if(!sam_io_unk_info1("unk_inf1",&q_u->ctr->info.inf1, ps,depth)) + return False; + break; + default: + DEBUG(0, ("samr_io_r_samr_unknown_2e: unknown switch level 0x%x\n", + q_u->switch_value)); + return False; + } + + return True; +} + +/******************************************************************* +inits a SAMR_R_QUERY_DOMAIN_INFO structure. +********************************************************************/ + +void init_samr_r_set_domain_info(SAMR_R_SET_DOMAIN_INFO * r_u, NTSTATUS status) +{ + DEBUG(5, ("init_samr_r_set_domain_info\n")); + + r_u->status = status; /* return status */ +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ + +BOOL samr_io_r_set_domain_info(char *desc, SAMR_R_SET_DOMAIN_INFO * r_u, + prs_struct *ps, int depth) +{ + if (r_u == NULL) + return False; + + prs_debug(ps, depth, desc, "samr_io_r_samr_unknown_2e"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_ntstatus("status", ps, depth, &r_u->status)) + return False; + + return True; +} diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c index fb7bd4fb25..177ee51d25 100644 --- a/source3/rpc_server/srv_samr.c +++ b/source3/rpc_server/srv_samr.c @@ -1312,6 +1312,68 @@ static BOOL api_samr_unknown_2d(pipes_struct *p) } /******************************************************************* + api_samr_query_dom_info + ********************************************************************/ + +static BOOL api_samr_unknown_2e(pipes_struct *p) +{ + SAMR_Q_UNKNOWN_2E q_u; + SAMR_R_UNKNOWN_2E r_u; + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + /* grab the samr unknown 8 command */ + if(!samr_io_q_unknown_2e("", &q_u, data, 0)) { + DEBUG(0,("api_samr_unknown_2e: unable to unmarshall SAMR_Q_UNKNOWN_2E.\n")); + return False; + } + + r_u.status = _samr_unknown_2e(p, &q_u, &r_u); + + /* store the response in the SMB stream */ + if(!samr_io_r_samr_unknown_2e("", &r_u, rdata, 0)) { + DEBUG(0,("api_samr_unknown_2e: unable to marshall SAMR_R_UNKNOWN_2E.\n")); + return False; + } + + return True; +} + +/******************************************************************* + api_samr_set_dom_info + ********************************************************************/ + +static BOOL api_samr_set_dom_info(pipes_struct *p) +{ + SAMR_Q_SET_DOMAIN_INFO q_u; + SAMR_R_SET_DOMAIN_INFO r_u; + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + /* grab the samr unknown 8 command */ + if(!samr_io_q_set_domain_info("", &q_u, data, 0)) { + DEBUG(0,("api_samr_set_dom_info: unable to unmarshall SAMR_Q_SET_DOMAIN_INFO.\n")); + return False; + } + + r_u.status = _samr_set_dom_info(p, &q_u, &r_u); + + /* store the response in the SMB stream */ + if(!samr_io_r_set_domain_info("", &r_u, rdata, 0)) { + DEBUG(0,("api_samr_set_dom_info: unable to marshall SAMR_R_SET_DOMAIN_INFO.\n")); + return False; + } + + return True; +} + +/******************************************************************* array of \PIPE\samr operations ********************************************************************/ @@ -1366,6 +1428,8 @@ static struct api_struct api_samr_cmds [] = {"SAMR_QUERY_SEC_OBJECT" , SAMR_QUERY_SEC_OBJECT , api_samr_query_sec_obj }, {"SAMR_GET_USRDOM_PWINFO" , SAMR_GET_USRDOM_PWINFO, api_samr_get_usrdom_pwinfo}, + {"SAMR_UNKNOWN_2E" , SAMR_UNKNOWN_2E , api_samr_unknown_2e }, + {"SAMR_SET_DOMAIN_INFO" , SAMR_SET_DOMAIN_INFO , api_samr_set_dom_info }, {NULL , 0 , NULL } }; diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 71237a9eec..12b37834d8 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -3336,3 +3336,101 @@ NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOW DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n")); return NT_STATUS_NOT_IMPLEMENTED; } + +/******************************************************************* + _samr_unknown_2e + ********************************************************************/ + +NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u) +{ + SAM_UNK_CTR *ctr; + + if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL) + return NT_STATUS_NO_MEMORY; + + ZERO_STRUCTP(ctr); + + r_u->status = NT_STATUS_OK; + + DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__)); + + /* find the policy handle. open a policy on it. */ + if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL)) + return NT_STATUS_INVALID_HANDLE; + + switch (q_u->switch_value) { + case 0x01: + init_unk_info1(&ctr->info.inf1); + break; + case 0x02: + /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */ + init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL)); + break; + case 0x03: + init_unk_info3(&ctr->info.inf3); + break; + case 0x05: + init_unk_info5(&ctr->info.inf5, global_myname); + break; + case 0x06: + init_unk_info6(&ctr->info.inf6); + break; + case 0x07: + init_unk_info7(&ctr->info.inf7); + break; + case 0x0c: + init_unk_info12(&ctr->info.inf12); + break; + default: + return NT_STATUS_INVALID_INFO_CLASS; + } + + init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK); + + DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__)); + + return r_u->status; +} + +/******************************************************************* + _samr_ + ********************************************************************/ + +NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u) +{ + r_u->status = NT_STATUS_OK; + + DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__)); + + /* find the policy handle. open a policy on it. */ + if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL)) + return NT_STATUS_INVALID_HANDLE; + + DEBUG(0,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value)); + + switch (q_u->switch_value) { + case 0x01: + break; + case 0x02: + break; + case 0x03: + break; + case 0x05: + break; + case 0x06: + break; + case 0x07: + break; + case 0x0c: + break; + default: + return NT_STATUS_INVALID_INFO_CLASS; + } + + init_samr_r_set_domain_info(r_u, NT_STATUS_OK); + + DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__)); + + return r_u->status; +} + |