From 75c346e70c83f7386ecd2f10fe155c4a4dfd47de Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Sat, 7 Oct 2000 15:56:36 +0000 Subject: added samr_set_user_info and info_2. cleanup of create_user cleanup of rid/sid mix in samr. now we only have sid. some prs_align() missing in parse_samr.c a small debug change in srv_pipe.c You still can't change a user's password in this commit. Will be availble in the next one. J.F. (This used to be commit b655bc281fa183b1827a946ada1fcf500fb93aea) --- source3/rpc_server/srv_lsa_hnd.c | 31 +- source3/rpc_server/srv_pipe.c | 2 +- source3/rpc_server/srv_samr.c | 687 +++++++++++++++++++++++++++++---------- 3 files changed, 522 insertions(+), 198 deletions(-) (limited to 'source3/rpc_server') diff --git a/source3/rpc_server/srv_lsa_hnd.c b/source3/rpc_server/srv_lsa_hnd.c index 5670178732..0782c8c4b2 100644 --- a/source3/rpc_server/srv_lsa_hnd.c +++ b/source3/rpc_server/srv_lsa_hnd.c @@ -32,16 +32,15 @@ extern int DEBUGLEVEL; struct reg_info { - /* for use by \PIPE\winreg */ + /* for use by \PIPE\winreg */ fstring name; /* name of registry key */ }; struct samr_info { - /* for use by the \PIPE\samr policy */ + /* for use by the \PIPE\samr policy */ DOM_SID sid; - uint32 rid; /* relative id associated with the pol_hnd */ - uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */ + uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */ }; static struct policy @@ -162,25 +161,6 @@ int find_lsa_policy_by_hnd(POLICY_HND *hnd) return p?p->pnum:-1; } -/**************************************************************************** - set samr rid -****************************************************************************/ -BOOL set_lsa_policy_samr_rid(POLICY_HND *hnd, uint32 rid) -{ - struct policy *p = find_lsa_policy(hnd); - - if (p && p->open) { - DEBUG(3,("Setting policy device rid=%x pnum=%x\n", - rid, p->pnum)); - - p->dev.samr.rid = rid; - return True; - } - - DEBUG(3,("Error setting policy rid=%x\n",rid)); - return False; -} - /**************************************************************************** set samr pol status. absolutely no idea what this is. @@ -230,8 +210,7 @@ BOOL get_lsa_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid) { struct policy *p = find_lsa_policy(hnd); - if (p != NULL && p->open) - { + if (p != NULL && p->open) { fstring sidstr; memcpy(sid, &p->dev.samr.sid, sizeof(*sid)); DEBUG(3,("Getting policy sid=%s pnum=%x\n", @@ -252,7 +231,7 @@ uint32 get_lsa_policy_samr_rid(POLICY_HND *hnd) struct policy *p = find_lsa_policy(hnd); if (p && p->open) { - uint32 rid = p->dev.samr.rid; + uint32 rid = p->dev.samr.sid.sub_auths[p->dev.samr.sid.num_auths-1]; DEBUG(3,("Getting policy device rid=%x pnum=%x\n", rid, p->pnum)); diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 44bca13c1a..01d9568477 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1195,7 +1195,7 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, /* do the actual command */ if(!api_rpc_cmds[fn_num].fn(p)) { - DEBUG(0,("api_rpcTNP: %s: failed.\n", rpc_name)); + DEBUG(0,("api_rpcTNP: %s: %s failed.\n", rpc_name, api_rpc_cmds[fn_num].name)); prs_mem_free(&p->out_data.rdata); return False; } diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c index 7891fc16dc..59a541abd9 100644 --- a/source3/rpc_server/srv_samr.c +++ b/source3/rpc_server/srv_samr.c @@ -1306,9 +1306,9 @@ static BOOL api_samr_unknown_38(pipes_struct *p) /******************************************************************* - samr_reply_unknown_12 + samr_reply_lookup_rids ********************************************************************/ -static BOOL samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u, +static BOOL samr_reply_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u, prs_struct *rdata) { fstring group_names[MAX_SAM_ENTRIES]; @@ -1316,9 +1316,9 @@ static BOOL samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u, uint32 status = 0; int num_gids = q_u->num_gids1; - SAMR_R_UNKNOWN_12 r_u; + SAMR_R_LOOKUP_RIDS r_u; - DEBUG(5,("samr_unknown_12: %d\n", __LINE__)); + DEBUG(5,("samr_reply_lookup_rids: %d\n", __LINE__)); /* find the policy handle. open a policy on it. */ if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1)) @@ -1332,7 +1332,7 @@ static BOOL samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u, if (num_gids > MAX_SAM_ENTRIES) { num_gids = MAX_SAM_ENTRIES; - DEBUG(5,("samr_unknown_12: truncating entries to %d\n", num_gids)); + DEBUG(5,("samr_reply_lookup_rids: truncating entries to %d\n", num_gids)); } for (i = 0; i < num_gids && status == 0; i++) @@ -1342,32 +1342,32 @@ static BOOL samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u, } } - init_samr_r_unknown_12(&r_u, num_gids, group_names, group_attrs, status); + init_samr_r_lookup_rids(&r_u, num_gids, group_names, group_attrs, status); /* store the response in the SMB stream */ - if(!samr_io_r_unknown_12("", &r_u, rdata, 0)) + if(!samr_io_r_lookup_rids("", &r_u, rdata, 0)) return False; - DEBUG(5,("samr_unknown_12: %d\n", __LINE__)); + DEBUG(5,("samr_reply_lookup_rids: %d\n", __LINE__)); return True; } /******************************************************************* - api_samr_unknown_12 + api_samr_lookup_rids ********************************************************************/ -static BOOL api_samr_unknown_12(pipes_struct *p) +static BOOL api_samr_lookup_rids(pipes_struct *p) { - SAMR_Q_UNKNOWN_12 q_u; + SAMR_Q_LOOKUP_RIDS q_u; prs_struct *data = &p->in_data.data; prs_struct *rdata = &p->out_data.rdata; /* grab the samr lookup names */ - if(!samr_io_q_unknown_12("", &q_u, data, 0)) + if(!samr_io_q_lookup_rids("", &q_u, data, 0)) return False; /* construct reply. always indicate success */ - if(!samr_reply_unknown_12(&q_u, rdata)) + if(!samr_reply_lookup_rids(&q_u, rdata)) return False; return True; @@ -1375,62 +1375,51 @@ static BOOL api_samr_unknown_12(pipes_struct *p) /******************************************************************* - samr_reply_open_user + _api_samr_open_user ********************************************************************/ -static BOOL samr_reply_open_user(SAMR_Q_OPEN_USER *q_u, prs_struct *rdata, int status) +static uint32 _api_samr_open_user(POLICY_HND domain_pol, uint32 user_rid, POLICY_HND *user_pol) { - SAMR_R_OPEN_USER r_u; struct sam_passwd *sam_pass; - BOOL pol_open = False; - - /* set up the SAMR open_user response */ - memset((char *)r_u.user_pol.data, '\0', POL_HND_SIZE); + DOM_SID sid; - r_u.status = 0x0; - - /* 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; - } + /* find the domain policy handle. */ + if (find_lsa_policy_by_hnd(&domain_pol) == -1) + return NT_STATUS_INVALID_HANDLE; /* get a (unique) handle. open a policy on it. */ - if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.user_pol)))) - { - r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND; - } + if (!open_lsa_policy_hnd(user_pol)) + return NT_STATUS_OBJECT_NAME_NOT_FOUND; become_root(); - sam_pass = getsam21pwrid(q_u->user_rid); + sam_pass = getsam21pwrid(user_rid); unbecome_root(); /* check that the RID exists in our domain. */ - if (r_u.status == 0x0 && sam_pass == NULL) - { - r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_USER; + if (sam_pass == NULL) { + close_lsa_policy_hnd(user_pol); + return NT_STATUS_NO_SUCH_USER; } - - /* associate the RID with the (unique) handle. */ - if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.user_pol), q_u->user_rid)) - { - /* oh, whoops. don't know what error message to return, here */ - r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND; + + /* Get the domain SID stored in the domain policy */ + if(!get_lsa_policy_samr_sid(&domain_pol, &sid)) { + close_lsa_policy_hnd(user_pol); + return NT_STATUS_INVALID_HANDLE; } - if (r_u.status != 0 && pol_open) - { - close_lsa_policy_hnd(&(r_u.user_pol)); + /* append the user's RID to it */ + if(!sid_append_rid(&sid, user_rid)) { + close_lsa_policy_hnd(user_pol); + return NT_STATUS_NO_SUCH_USER; } - DEBUG(5,("samr_open_user: %d\n", __LINE__)); - - /* store the response in the SMB stream */ - if(!samr_io_r_open_user("", &r_u, rdata, 0)) - return False; - - DEBUG(5,("samr_open_user: %d\n", __LINE__)); + /* associate the user's SID with the handle. */ + if (!set_lsa_policy_samr_sid(user_pol, &sid)) { + /* oh, whoops. don't know what error message to return, here */ + close_lsa_policy_hnd(user_pol); + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } - return True; + return NT_STATUS_NO_PROBLEMO; } /******************************************************************* @@ -1439,21 +1428,28 @@ static BOOL samr_reply_open_user(SAMR_Q_OPEN_USER *q_u, prs_struct *rdata, int s static BOOL api_samr_open_user(pipes_struct *p) { SAMR_Q_OPEN_USER q_u; + SAMR_R_OPEN_USER 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 22 */ if(!samr_io_q_open_user("", &q_u, data, 0)) return False; - /* construct reply. always indicate success */ - if(!samr_reply_open_user(&q_u, rdata, 0x0)) + r_u.status = _api_samr_open_user(q_u.domain_pol, q_u.user_rid, &r_u.user_pol); + + /* store the response in the SMB stream */ + if(!samr_io_r_open_user("", &r_u, rdata, 0)) return False; + DEBUG(5,("samr_open_user: %d\n", __LINE__)); + return True; } - /************************************************************************* get_user_info_10 *************************************************************************/ @@ -1753,45 +1749,64 @@ static BOOL api_samr_query_usergroups(pipes_struct *p) /******************************************************************* - samr_reply_query_dom_info + api_samr_query_dom_info ********************************************************************/ -static BOOL samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_struct *rdata) +static BOOL api_samr_query_dom_info(pipes_struct *p) { + SAMR_Q_QUERY_DOMAIN_INFO q_u; SAMR_R_QUERY_DOMAIN_INFO r_u; SAM_UNK_CTR ctr; + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + uint16 switch_value = 0x0; uint32 status = 0x0; + ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); ZERO_STRUCT(ctr); - r_u.ctr = &ctr; + DEBUG(5,("api_samr_query_dom_info: %d\n", __LINE__)); - DEBUG(5,("samr_reply_query_dom_info: %d\n", __LINE__)); + /* grab the samr unknown 8 command */ + if(!samr_io_q_query_dom_info("", &q_u, data, 0)) + return False; /* 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_query_dom_info: invalid handle\n")); + if (find_lsa_policy_by_hnd(&q_u.domain_pol) == -1) { + status = NT_STATUS_INVALID_HANDLE; + DEBUG(5,("api_samr_query_dom_info: invalid handle\n")); } - if (status == 0x0) - { - switch (q_u->switch_value) - { + if (status == 0x0) { + switch (q_u.switch_value) { + case 0x01: + switch_value = 0x1; + init_unk_info1(&ctr.info.inf1); + break; case 0x02: - { switch_value = 0x2; init_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname); - break; - } + case 0x03: + switch_value = 0x3; + init_unk_info3(&ctr.info.inf3); + break; + case 0x06: + switch_value = 0x6; + init_unk_info6(&ctr.info.inf6); + break; + case 0x07: + switch_value = 0x7; + init_unk_info7(&ctr.info.inf7); + break; + case 0x0c: + switch_value = 0xc; + init_unk_info12(&ctr.info.inf12); + break; default: - { - status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS; + status = NT_STATUS_INVALID_INFO_CLASS; break; - } } } @@ -1801,65 +1816,28 @@ static BOOL samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_struct if(!samr_io_r_query_dom_info("", &r_u, rdata, 0)) return False; - DEBUG(5,("samr_query_dom_info: %d\n", __LINE__)); - - return True; -} - -/******************************************************************* - api_samr_query_dom_info - ********************************************************************/ -static BOOL api_samr_query_dom_info(pipes_struct *p) -{ - SAMR_Q_QUERY_DOMAIN_INFO q_e; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - /* grab the samr unknown 8 command */ - if(!samr_io_q_query_dom_info("", &q_e, data, 0)) - return False; - - /* construct reply. */ - if(!samr_reply_query_dom_info(&q_e, rdata)) - return False; + DEBUG(5,("api_samr_query_dom_info: %d\n", __LINE__)); return True; } /******************************************************************* - api_samr_create_user + _api_samr_create_user ********************************************************************/ -static BOOL api_samr_create_user(pipes_struct *p) +static BOOL _api_samr_create_user(POLICY_HND dom_pol, UNISTR2 user_account, uint32 acb_info, uint32 access_mask, + POLICY_HND *user_pol, uint32 *unknown0, uint32 *user_rid) { struct sam_passwd *sam_pass; fstring mach_acct; pstring err_str; pstring msg_str; int local_flags=0; + DOM_SID sid; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - SAMR_Q_CREATE_USER q_u; - SAMR_R_CREATE_USER r_u; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - DEBUG(5,("api_samr_create_user: %d\n", __LINE__)); - - /* grab the samr create user */ - if (!samr_io_q_create_user("", &q_u, data, 0)) { - DEBUG(0,("api_samr_create_user: Unable to unmarshall SAMR_Q_CREATE_USER.\n")); - return False; - } - /* find the policy handle. open a policy on it. */ - if ((find_lsa_policy_by_hnd(&q_u.pol) == -1)) { - r_u.status = NT_STATUS_INVALID_HANDLE; - goto out; - } + if (find_lsa_policy_by_hnd(&dom_pol) == -1) + return NT_STATUS_INVALID_HANDLE; /* find the machine account: tell the caller if it exists. lkclXXXX i have *no* idea if this is a problem or not @@ -1867,7 +1845,7 @@ static BOOL api_samr_create_user(pipes_struct *p) reply if the account already exists... */ - fstrcpy(mach_acct, dos_unistrn2(q_u.uni_mach_acct.buffer, q_u.uni_mach_acct.uni_str_len)); + fstrcpy(mach_acct, dos_unistrn2(user_account.buffer, user_account.uni_str_len)); strlower(mach_acct); become_root(); @@ -1875,18 +1853,15 @@ static BOOL api_samr_create_user(pipes_struct *p) unbecome_root(); if (sam_pass != NULL) { /* machine account exists: say so */ - r_u.status = NT_STATUS_USER_EXISTS; - goto out; + return NT_STATUS_USER_EXISTS; } /* get a (unique) handle. open a policy on it. */ - if (!open_lsa_policy_hnd(&r_u.pol)) { - r_u.status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - goto out; - } + if (!open_lsa_policy_hnd(user_pol)) + return NT_STATUS_OBJECT_NAME_NOT_FOUND; local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD; - local_flags|= (q_u.acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0; + local_flags|= (acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0; /* * NB. VERY IMPORTANT ! This call must be done as the current pipe user, @@ -1897,10 +1872,8 @@ static BOOL api_samr_create_user(pipes_struct *p) if (!local_password_change(mach_acct, local_flags, NULL, err_str, sizeof(err_str), msg_str, sizeof(msg_str))) { DEBUG(0, ("%s\n", err_str)); - r_u.status = NT_STATUS_ACCESS_DENIED; - close_lsa_policy_hnd(&r_u.pol); - memset((char *)r_u.pol.data, '\0', POL_HND_SIZE); - goto out; + close_lsa_policy_hnd(user_pol); + return NT_STATUS_ACCESS_DENIED; } become_root(); @@ -1908,31 +1881,62 @@ static BOOL api_samr_create_user(pipes_struct *p) unbecome_root(); if (sam_pass == NULL) { /* account doesn't exist: say so */ - r_u.status = NT_STATUS_ACCESS_DENIED; - close_lsa_policy_hnd(&r_u.pol); - memset((char *)r_u.pol.data, '\0', POL_HND_SIZE); - goto out; + close_lsa_policy_hnd(user_pol); + return NT_STATUS_ACCESS_DENIED; + } + + /* Get the domain SID stored in the domain policy */ + if(!get_lsa_policy_samr_sid(&dom_pol, &sid)) { + close_lsa_policy_hnd(user_pol); + return NT_STATUS_INVALID_HANDLE; + } + + /* append the user's RID to it */ + if(!sid_append_rid(&sid, sam_pass->user_rid)) { + close_lsa_policy_hnd(user_pol); + return NT_STATUS_NO_SUCH_USER; } /* associate the RID with the (unique) handle. */ - if (!set_lsa_policy_samr_rid(&r_u.pol, sam_pass->user_rid)) { + if (!set_lsa_policy_samr_sid(user_pol, &sid)) { /* oh, whoops. don't know what error message to return, here */ - r_u.status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - close_lsa_policy_hnd(&r_u.pol); - memset((char *)r_u.pol.data, '\0', POL_HND_SIZE); - goto out; + close_lsa_policy_hnd(user_pol); + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + *unknown0=0x000703ff; + *user_rid=sam_pass->user_rid; + + return NT_STATUS_NO_PROBLEMO; +} + +/******************************************************************* + api_samr_create_user + ********************************************************************/ +static BOOL api_samr_create_user(pipes_struct *p) +{ + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + SAMR_Q_CREATE_USER q_u; + SAMR_R_CREATE_USER r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + /* grab the samr create user */ + if (!samr_io_q_create_user("", &q_u, data, 0)) { + DEBUG(0,("api_samr_create_user: Unable to unmarshall SAMR_Q_CREATE_USER.\n")); + return False; } - r_u.unknown_0=0x000703ff; - r_u.user_rid=sam_pass->user_rid; + r_u.status=_api_samr_create_user(q_u.pol, q_u.uni_mach_acct, q_u.acb_info, q_u.access_mask, + &r_u.pol, &r_u.unknown_0, &r_u.user_rid); - out: /* store the response in the SMB stream */ if(!samr_io_r_create_user("", &r_u, rdata, 0)) return False; - DEBUG(5,("api_samr_create_user: %d\n", __LINE__)); - return True; } @@ -2146,66 +2150,405 @@ static BOOL api_samr_enum_domains(pipes_struct *p) return True; } + /******************************************************************* - samr_reply_open_alias + api_samr_open_alias ********************************************************************/ -static BOOL samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u, prs_struct *rdata) +static uint32 _api_samr_open_alias(POLICY_HND domain_pol, uint32 alias_rid, POLICY_HND *alias_pol) { - SAMR_R_OPEN_ALIAS r_u; - BOOL pol_open = False; - - /* set up the SAMR open_alias response */ + DOM_SID sid; + + /* get the domain policy. */ + if (!open_lsa_policy_hnd(&domain_pol)) + return NT_STATUS_OBJECT_NAME_NOT_FOUND; - r_u.status = 0x0; /* get a (unique) handle. open a policy on it. */ - if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.pol)))) - { - r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND; + if (!open_lsa_policy_hnd(alias_pol)) + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + + /* Get the domain SID stored in the domain policy */ + if(!get_lsa_policy_samr_sid(&domain_pol, &sid)) { + close_lsa_policy_hnd(alias_pol); + return NT_STATUS_INVALID_HANDLE; + } + + /* append the alias' RID to it */ + if(!sid_append_rid(&sid, alias_rid)) { + close_lsa_policy_hnd(alias_pol); + return NT_STATUS_NO_SUCH_USER; } /* associate a RID with the (unique) handle. */ - if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.pol), q_u->rid_alias)) - { + if (!set_lsa_policy_samr_sid(alias_pol, &sid)) { /* oh, whoops. don't know what error message to return, here */ - r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND; + close_lsa_policy_hnd(alias_pol); + return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - if (r_u.status != 0 && pol_open) - { - close_lsa_policy_hnd(&(r_u.pol)); - } + return NT_STATUS_NO_PROBLEMO; +} - DEBUG(5,("samr_open_alias: %d\n", __LINE__)); +/******************************************************************* + api_samr_open_alias + ********************************************************************/ +static BOOL api_samr_open_alias(pipes_struct *p) +{ + SAMR_Q_OPEN_ALIAS q_u; + SAMR_R_OPEN_ALIAS 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 open policy */ + if(!samr_io_q_open_alias("", &q_u, data, 0)) + return False; + + r_u.status=_api_samr_open_alias(q_u.dom_pol, q_u.rid_alias, &r_u.pol); /* store the response in the SMB stream */ if(!samr_io_r_open_alias("", &r_u, rdata, 0)) return False; + + return True; +} + +/******************************************************************* + set_user_info_10 + ********************************************************************/ +static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid) +{ + struct sam_passwd *pwd = getsam21pwrid(rid); + struct sam_passwd new_pwd; + + if (id10 == NULL) { + DEBUG(5, ("set_user_info_10: NULL id10\n")); + return False; + } + + if (pwd == NULL) + return False; + + copy_sam_passwd(&new_pwd, pwd); + + new_pwd.acct_ctrl = id10->acb_info; + + if(!mod_sam21pwd_entry(&new_pwd, True)) + return False; + + return True; +} + +/******************************************************************* + set_user_info_12 + ********************************************************************/ +static BOOL set_user_info_12(const SAM_USER_INFO_12 *id12, uint32 rid) +{ + struct sam_passwd *pwd = getsam21pwrid(rid); + struct sam_passwd new_pwd; + static uchar nt_hash[16]; + static uchar lm_hash[16]; + + if (pwd == NULL) + return False; + + if (id12 == NULL) { + DEBUG(2, ("set_user_info_12: id12 is NULL\n")); + return False; + } + + pdb_init_sam(&new_pwd); + copy_sam_passwd(&new_pwd, pwd); + + memcpy(nt_hash, id12->nt_pwd, sizeof(nt_hash)); + memcpy(lm_hash, id12->lm_pwd, sizeof(lm_hash)); + + new_pwd.smb_passwd = lm_hash; + new_pwd.smb_nt_passwd = nt_hash; + + if(!mod_sam21pwd_entry(&new_pwd, True)) + return False; + + return True; +} + +/******************************************************************* + set_user_info_21 + ********************************************************************/ +static BOOL set_user_info_21(SAM_USER_INFO_21 * id21, uint32 rid) +{ + struct sam_passwd *pwd = getsam21pwrid(rid); + struct sam_passwd new_pwd; + static uchar nt_hash[16]; + static uchar lm_hash[16]; + + if (id21 == NULL) { + DEBUG(5, ("set_user_info_21: NULL id21\n")); + return False; + } + + if (pwd == NULL) + return False; + + pdb_init_sam(&new_pwd); + copy_sam_passwd(&new_pwd, pwd); + copy_id21_to_sam_passwd(&new_pwd, id21); + + if (pwd->smb_nt_passwd != NULL) { + memcpy(nt_hash, pwd->smb_nt_passwd, 16); + new_pwd.smb_nt_passwd = nt_hash; + } else + new_pwd.smb_nt_passwd = NULL; + + if (pwd->smb_nt_passwd != NULL) { + memcpy(lm_hash, pwd->smb_passwd, 16); + new_pwd.smb_passwd = lm_hash; + } else + new_pwd.smb_passwd = NULL; + + if(!mod_sam21pwd_entry(&new_pwd, True)) + return False; + + return True; +} + +/******************************************************************* + set_user_info_23 + ********************************************************************/ +static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid) +{ + struct sam_passwd *pwd = getsam21pwrid(rid); + struct sam_passwd new_pwd; + static uchar nt_hash[16]; + static uchar lm_hash[16]; + pstring buf; + uint32 len; + + if (id23 == NULL) { + DEBUG(5, ("set_user_info_23: NULL id23\n")); + return False; + } + + if (pwd == NULL) + return False; + + pdb_init_sam(&new_pwd); + copy_sam_passwd(&new_pwd, pwd); + copy_id23_to_sam_passwd(&new_pwd, id23); - DEBUG(5,("samr_open_alias: %d\n", __LINE__)); + if (!decode_pw_buffer(id23->pass, buf, 256, &len)) + return False; + + nt_lm_owf_gen(buf, nt_hash, lm_hash); + + new_pwd.smb_passwd = lm_hash; + new_pwd.smb_nt_passwd = nt_hash; + + if(!mod_sam21pwd_entry(&new_pwd, True)) + return False; return True; } /******************************************************************* - api_samr_open_alias + set_user_info_24 ********************************************************************/ -static BOOL api_samr_open_alias(pipes_struct *p) +static BOOL set_user_info_24(const SAM_USER_INFO_24 *id24, uint32 rid) { - SAMR_Q_OPEN_ALIAS q_u; + struct sam_passwd *pwd = getsam21pwrid(rid); + struct sam_passwd new_pwd; + static uchar nt_hash[16]; + static uchar lm_hash[16]; + uint32 len; + pstring buf; + + if (pwd == NULL) + return False; + + pdb_init_sam(&new_pwd); + copy_sam_passwd(&new_pwd, pwd); + + if (!decode_pw_buffer(id24->pass, buf, 256, &len)) + return False; + + nt_lm_owf_gen(buf, nt_hash, lm_hash); + + new_pwd.smb_passwd = lm_hash; + new_pwd.smb_nt_passwd = nt_hash; + + if(!mod_sam21pwd_entry(&new_pwd, True)) + return False; + + return True; +} + +/******************************************************************* + samr_reply_set_userinfo + ********************************************************************/ +static uint32 _samr_set_userinfo(POLICY_HND *pol, uint16 switch_value, SAM_USERINFO_CTR *ctr, uint16 vuid) +{ + uint32 rid = 0x0; + DOM_SID sid; + user_struct *vuser = NULL; + + DEBUG(5, ("samr_reply_set_userinfo: %d\n", __LINE__)); + + /* search for the handle */ + if (find_lsa_policy_by_hnd(pol) == -1) + return NT_STATUS_INVALID_HANDLE; + + if ((vuser = get_valid_user_struct(vuid)) == NULL) + return NT_STATUS_INVALID_HANDLE; + + /* find the policy handle. open a policy on it. */ + if (!get_lsa_policy_samr_sid(pol, &sid)) + return NT_STATUS_INVALID_HANDLE; + + sid_split_rid(&sid, &rid); + + DEBUG(5, ("samr_reply_set_userinfo: rid:0x%x, level:%d\n", rid, switch_value)); + + if (ctr == NULL) { + DEBUG(5, ("samr_reply_set_userinfo: NULL info level\n")); + return NT_STATUS_INVALID_INFO_CLASS; + } + + /* ok! user info levels (lots: see MSDEV help), off we go... */ + switch (switch_value) { + case 0x12: + if (!set_user_info_12(ctr->info.id12, rid)) + return NT_STATUS_ACCESS_DENIED; + break; + + case 24: + SamOEMhash(ctr->info.id24->pass, vuser->dc.sess_key, True); + if (!set_user_info_24(ctr->info.id24, rid)) + return NT_STATUS_ACCESS_DENIED; + break; + + case 23: + DEBUG(5, ("samr_reply_set_userinfo: sess key:[%s]\n", credstr(vuser->dc.sess_key))); + SamOEMhash(ctr->info.id23->pass, vuser->dc.sess_key, 1); + if (!set_user_info_23(ctr->info.id23, rid)) + return NT_STATUS_ACCESS_DENIED; + break; + + default: + return NT_STATUS_INVALID_INFO_CLASS; + } + + return NT_STATUS_NOPROBLEMO; +} + +/******************************************************************* + api_samr_set_userinfo + ********************************************************************/ +static BOOL api_samr_set_userinfo(pipes_struct *p) +{ + SAMR_Q_SET_USERINFO q_u; + SAMR_R_SET_USERINFO r_u; + prs_struct *data = &p->in_data.data; prs_struct *rdata = &p->out_data.rdata; - /* grab the samr open policy */ - if(!samr_io_q_open_alias("", &q_u, data, 0)) + SAM_USERINFO_CTR ctr; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + q_u.ctr = &ctr; + + if (!samr_io_q_set_userinfo("", &q_u, data, 0)) return False; - /* construct reply. always indicate success */ - if(!samr_reply_open_alias(&q_u, rdata)) + r_u.status = _samr_set_userinfo(&q_u.pol, q_u.switch_value, &ctr, p->vuid); + + free_samr_q_set_userinfo(&q_u); + + if(!samr_io_r_set_userinfo("", &r_u, rdata, 0)) return False; return True; } +/******************************************************************* + samr_reply_set_userinfo2 + ********************************************************************/ +static uint32 _samr_set_userinfo2(POLICY_HND *pol, uint16 switch_value, SAM_USERINFO_CTR *ctr) +{ + DOM_SID sid; + uint32 rid = 0x0; + + DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__)); + + /* search for the handle */ + if (find_lsa_policy_by_hnd(pol) == -1) + return NT_STATUS_INVALID_HANDLE; + + /* find the policy handle. open a policy on it. */ + if (!get_lsa_policy_samr_sid(pol, &sid)) + return NT_STATUS_INVALID_HANDLE; + + sid_split_rid(&sid, &rid); + + DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid)); + + if (ctr == NULL) { + DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n")); + return NT_STATUS_INVALID_INFO_CLASS; + } + + ctr->switch_value = switch_value; + + /* ok! user info levels (lots: see MSDEV help), off we go... */ + switch (switch_value) { + case 21: + if (!set_user_info_21(ctr->info.id21, rid)) + return NT_STATUS_ACCESS_DENIED; + break; + case 16: + if (!set_user_info_10(ctr->info.id10, rid)) + return NT_STATUS_ACCESS_DENIED; + break; + default: + return NT_STATUS_INVALID_INFO_CLASS; + } + + return NT_STATUS_NOPROBLEMO; +} + +/******************************************************************* + api_samr_set_userinfo2 + ********************************************************************/ +static BOOL api_samr_set_userinfo2(pipes_struct *p) +{ + SAMR_Q_SET_USERINFO2 q_u; + SAMR_R_SET_USERINFO2 r_u; + SAM_USERINFO_CTR ctr; + + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + q_u.ctr = &ctr; + + if (!samr_io_q_set_userinfo2("", &q_u, data, 0)) + return False; + + r_u.status = _samr_set_userinfo2(&q_u.pol, q_u.switch_value, &ctr); + + free_samr_q_set_userinfo2(&q_u); + + if(!samr_io_r_set_userinfo2("", &r_u, rdata, 0)) + return False; + + return True; +} + + /******************************************************************* array of \PIPE\samr operations ********************************************************************/ @@ -2221,12 +2564,12 @@ 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_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info }, + { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info }, { "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 }, { "SAMR_CREATE_USER" , SAMR_CREATE_USER , api_samr_create_user }, - { "SAMR_UNKNOWN_12" , SAMR_UNKNOWN_12 , api_samr_unknown_12 }, + { "SAMR_LOOKUP_RIDS" , SAMR_LOOKUP_RIDS , api_samr_lookup_rids }, { "SAMR_UNKNOWN_38" , SAMR_UNKNOWN_38 , api_samr_unknown_38 }, { "SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER , api_samr_chgpasswd_user }, { "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias }, @@ -2235,6 +2578,8 @@ static struct api_struct api_samr_cmds [] = { "SAMR_UNKNOWN_2C" , SAMR_UNKNOWN_2C , api_samr_unknown_2c }, { "SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN , api_samr_lookup_domain }, { "SAMR_ENUM_DOMAINS" , SAMR_ENUM_DOMAINS , api_samr_enum_domains }, + { "SAMR_SET_USERINFO" , SAMR_SET_USERINFO , api_samr_set_userinfo }, + { "SAMR_SET_USERINFO2" , SAMR_SET_USERINFO2 , api_samr_set_userinfo2 }, { NULL , 0 , NULL } }; -- cgit