summaryrefslogtreecommitdiff
path: root/source3/rpc_server/srv_samr.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/rpc_server/srv_samr.c')
-rw-r--r--source3/rpc_server/srv_samr.c186
1 files changed, 172 insertions, 14 deletions
diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c
index f82a1f5afe..06ed6603b3 100644
--- a/source3/rpc_server/srv_samr.c
+++ b/source3/rpc_server/srv_samr.c
@@ -30,6 +30,8 @@ extern int DEBUGLEVEL;
extern BOOL sam_logon_in_ssb;
extern pstring samlogon_user;
+extern pstring global_myworkgroup;
+extern pstring global_myname;
extern DOM_SID global_machine_sid;
extern rid_name domain_group_rids[];
@@ -216,6 +218,54 @@ static void api_samr_open_domain( uint16 vuid, prs_struct *data, prs_struct *rda
/*******************************************************************
+ samr_reply_unknown_2c
+ ********************************************************************/
+static void samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
+ prs_struct *rdata)
+{
+ SAMR_R_UNKNOWN_2C r_u;
+ uint32 status = 0x0;
+ uint32 rid;
+
+ /* find the policy handle. open a policy on it. */
+ if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
+ {
+ status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* find the user's rid */
+ if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff)
+ {
+ status = NT_STATUS_OBJECT_TYPE_MISMATCH;
+ }
+
+ make_samr_r_unknown_2c(&r_u, status);
+
+ DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
+
+ /* store the response in the SMB stream */
+ samr_io_r_unknown_2c("", &r_u, rdata, 0);
+
+ DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_unknown_2c
+ ********************************************************************/
+static void api_samr_unknown_2c( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_UNKNOWN_2C q_u;
+
+ /* grab the samr open */
+ samr_io_q_unknown_2c("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
+ samr_reply_unknown_2c(&q_u, rdata);
+}
+
+
+/*******************************************************************
samr_reply_unknown_3
********************************************************************/
static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
@@ -242,24 +292,24 @@ static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
if (status == 0x0)
{
- DOM_SID user_sid;
- DOM_SID other_sid;
+ DOM_SID user_sid;
+ DOM_SID everyone_sid;
- user_sid = global_machine_sid;
+ user_sid = global_machine_sid;
- SMB_ASSERT_ARRAY(user_sid.sub_auths, user_sid.num_auths+1);
+ SMB_ASSERT_ARRAY(user_sid.sub_auths, user_sid.num_auths+1);
- /*
- * Add the user RID.
- */
- user_sid.sub_auths[user_sid.num_auths++] = rid;
-
- string_to_sid(&other_sid, "S-1-1");
+ /*
+ * Add the user RID.
+ */
+ user_sid.sub_auths[user_sid.num_auths++] = rid;
+
+ string_to_sid(&everyone_sid, "S-1-1");
- /* maybe need another 1 or 2 (S-1-5-20-0x220 and S-1-5-20-0x224) */
- /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
- make_dom_sid3(&(sid[0]), 0x035b, 0x0002, &other_sid);
- make_dom_sid3(&(sid[1]), 0x0044, 0x0002, &user_sid);
+ /* maybe need another 1 or 2 (S-1-5-20-0x220 and S-1-5-20-0x224) */
+ /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
+ make_dom_sid3(&(sid[0]), 0x035b, 0x0002, &everyone_sid);
+ make_dom_sid3(&(sid[1]), 0x0044, 0x0002, &user_sid);
}
make_samr_r_unknown_3(&r_u,
@@ -946,6 +996,36 @@ static void api_samr_open_user( uint16 vuid, prs_struct *data, prs_struct *rdata
/*************************************************************************
+ get_user_info_10
+ *************************************************************************/
+static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
+{
+ struct smb_passwd *smb_pass;
+
+ if (!pdb_rid_is_user(user_rid))
+ {
+ DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
+ return False;
+ }
+
+ become_root(True);
+ smb_pass = getsmbpwrid(user_rid);
+ unbecome_root(True);
+
+ if (smb_pass == NULL)
+ {
+ DEBUG(4,("User 0x%x not found\n", user_rid));
+ return False;
+ }
+
+ DEBUG(3,("User:[%s]\n", smb_pass->smb_name));
+
+ make_sam_user_info10(id10, smb_pass->acct_ctrl);
+
+ return True;
+}
+
+/*************************************************************************
get_user_info_21
*************************************************************************/
static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
@@ -1029,6 +1109,7 @@ static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
#if 0
SAM_USER_INFO_11 id11;
#endif
+ SAM_USER_INFO_10 id10;
SAM_USER_INFO_21 id21;
void *info = NULL;
@@ -1056,6 +1137,12 @@ static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
{
switch (q_u->switch_value)
{
+ case 0x10:
+ {
+ info = (void*)&id10;
+ status = get_user_info_10(&id10, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
+ break;
+ }
#if 0
/* whoops - got this wrong. i think. or don't understand what's happening. */
case 0x11:
@@ -1189,6 +1276,75 @@ static void api_samr_query_usergroups( uint16 vuid, prs_struct *data, prs_struct
/*******************************************************************
+ samr_reply_unknown_8
+ ********************************************************************/
+static void samr_reply_unknown_8(SAMR_Q_UNKNOWN_8 *q_u,
+ prs_struct *rdata)
+{
+ SAMR_R_UNKNOWN_8 r_u;
+ SAM_UNK_CTR ctr;
+ uint16 switch_value = 0x0;
+ uint32 status = 0x0;
+
+ ZERO_STRUCT(r_u);
+ ZERO_STRUCT(ctr);
+
+ r_u.ctr = &ctr;
+
+ DEBUG(5,("samr_reply_unknown_8: %d\n", __LINE__));
+
+ /* find the policy handle. open a policy on it. */
+ if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
+ {
+ r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ DEBUG(5,("samr_reply_unknown_8: invalid handle\n"));
+ }
+
+ if (status == 0x0)
+ {
+ switch (q_u->switch_value)
+ {
+ case 0x02:
+ {
+ switch_value = 0x2;
+ make_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname);
+
+ break;
+ }
+ default:
+ {
+ status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+ break;
+ }
+ }
+ }
+
+ make_samr_r_unknown_8(&r_u, switch_value, &ctr, status);
+
+ /* store the response in the SMB stream */
+ samr_io_r_unknown_8("", &r_u, rdata, 0);
+
+ DEBUG(5,("samr_unknown_8: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_unknown_8
+ ********************************************************************/
+static void api_samr_unknown_8( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_UNKNOWN_8 q_e;
+
+ /* grab the samr unknown 8 command */
+ samr_io_q_unknown_8("", &q_e, data, 0);
+
+ /* construct reply. */
+ samr_reply_unknown_8(&q_e, rdata);
+}
+
+
+
+/*******************************************************************
samr_reply_unknown_32
********************************************************************/
static void samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u,
@@ -1439,6 +1595,7 @@ static struct api_struct api_samr_cmds [] =
{ "SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES , api_samr_lookup_names },
{ "SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
{ "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
+ { "SAMR_UNKNOWN_8" , SAMR_UNKNOWN_8 , api_samr_unknown_8 },
{ "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
{ "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
{ "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
@@ -1449,6 +1606,7 @@ static struct api_struct api_samr_cmds [] =
{ "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
{ "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain },
{ "SAMR_UNKNOWN_3" , SAMR_UNKNOWN_3 , api_samr_unknown_3 },
+ { "SAMR_UNKNOWN_2C" , SAMR_UNKNOWN_2C , api_samr_unknown_2c },
{ NULL , 0 , NULL }
};