summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/rpc_samr.h57
-rw-r--r--source3/rpc_parse/parse_samr.c271
-rw-r--r--source3/rpc_server/srv_samr.c64
-rw-r--r--source3/rpc_server/srv_samr_nt.c98
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;
+}
+