diff options
-rw-r--r-- | source3/include/rpc_samr_old.h | 10 | ||||
-rw-r--r-- | source3/passdb/smbpass.c | 6 | ||||
-rw-r--r-- | source3/passdb/smbpasschange.c | 4 | ||||
-rw-r--r-- | source3/rpc_parse/parse_samr.c | 11 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr.c | 71 |
5 files changed, 74 insertions, 28 deletions
diff --git a/source3/include/rpc_samr_old.h b/source3/include/rpc_samr_old.h index d385f18e76..620f5bc628 100644 --- a/source3/include/rpc_samr_old.h +++ b/source3/include/rpc_samr_old.h @@ -991,9 +991,8 @@ typedef struct q_samr_create_user_info UNIHDR hdr_mach_acct; /* unicode machine account name header */ UNISTR2 uni_mach_acct; /* unicode machine account name */ - uint32 acct_ctrl; /* 32 bit ACB_XXXX */ - uint16 unknown_1; /* 16 bit unknown - 0x00B0 */ - uint16 unknown_2; /* 16 bit unknown - 0xe005 */ + uint32 acb_info; /* 32 bit ACB_XXXX */ + uint32 access_mask; /* 0xe005 00b0 */ } SAMR_Q_CREATE_USER; @@ -1003,9 +1002,8 @@ typedef struct r_samr_create_user_info { POLICY_HND pol; /* policy handle */ - /* rid4.unknown - fail: 0030 success: 0x03ff */ - DOM_RID4 rid4; /* rid and attributes */ - + uint32 unknown_0; /* 0x0007 03ff */ + uint32 user_rid; /* user RID */ uint32 status; /* return status - fail: 0xC000 0099: user exists */ } SAMR_R_CREATE_USER; diff --git a/source3/passdb/smbpass.c b/source3/passdb/smbpass.c index ec1a984b76..45935db99e 100644 --- a/source3/passdb/smbpass.c +++ b/source3/passdb/smbpass.c @@ -329,7 +329,13 @@ static struct smb_passwd *getsmbfilepwent(void *vp) pw_buf.smb_nt_passwd = NULL; pw_buf.smb_passwd = NULL; pw_buf.acct_ctrl |= ACB_DISABLED; + +#if 0 /* JFM */ + /* commented to continue in the case of a trust account disabled */ + /* samr_create_user() is adding disabled accounts */ + return &pw_buf; +#endif } if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) { diff --git a/source3/passdb/smbpasschange.c b/source3/passdb/smbpasschange.c index 2c971fbff9..0c30bbe4a5 100644 --- a/source3/passdb/smbpasschange.c +++ b/source3/passdb/smbpasschange.c @@ -41,7 +41,9 @@ static BOOL add_new_user(char *user_name, uid_t uid, int local_flags, if(local_flags & LOCAL_DISABLE_USER) { new_smb_pwent.acct_ctrl |= ACB_DISABLED; - } else if (local_flags & LOCAL_SET_NO_PASSWORD) { + } + + if (local_flags & LOCAL_SET_NO_PASSWORD) { new_smb_pwent.acct_ctrl |= ACB_PWNOTREQ; } else { new_smb_pwent.smb_passwd = new_p16; diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index 72e803d22b..ce26ad454f 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -3082,11 +3082,9 @@ BOOL samr_io_q_create_user(char *desc, SAMR_Q_CREATE_USER *q_u, prs_struct *ps, if(!prs_align(ps)) return False; - if(!prs_uint32("acct_ctrl", ps, depth, &q_u->acct_ctrl)) + if(!prs_uint32("acb_info", ps, depth, &q_u->acb_info)) return False; - if(!prs_uint16("unknown_1", ps, depth, &q_u->unknown_1)) - return False; - if(!prs_uint16("unknown_2", ps, depth, &q_u->unknown_2)) + if(!prs_uint32("access_mask", ps, depth, &q_u->access_mask)) return False; return True; @@ -3109,7 +3107,10 @@ BOOL samr_io_r_create_user(char *desc, SAMR_R_CREATE_USER *r_u, prs_struct *ps, if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth)) return False; - if(!prs_align(ps)) + + if(!prs_uint32("unknown_0", ps, depth, &r_u->unknown_0)) + return False; + if(!prs_uint32("user_rid", ps, depth, &r_u->user_rid)) return False; if(!prs_uint32("status", ps, depth, &r_u->status)) diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c index ab32bfe563..2ef29df990 100644 --- a/source3/rpc_server/srv_samr.c +++ b/source3/rpc_server/srv_samr.c @@ -1826,26 +1826,38 @@ static BOOL api_samr_query_dom_info(pipes_struct *p) return True; } + /******************************************************************* api_samr_create_user ********************************************************************/ static BOOL api_samr_create_user(pipes_struct *p) { - uint32 status = 0; struct sam_passwd *sam_pass; fstring mach_acct; + pstring err_str; + pstring msg_str; + int local_flags=0; + prs_struct *data = &p->in_data.data; prs_struct *rdata = &p->out_data.rdata; - int i; 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 */ samr_io_q_create_user("", &q_u, data, 0); + /* 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; + } + /* find the machine account: tell the caller if it exists. lkclXXXX i have *no* idea if this is a problem or not or even if you are supposed to construct a different @@ -1853,31 +1865,58 @@ static BOOL api_samr_create_user(pipes_struct *p) */ fstrcpy(mach_acct, dos_unistrn2(q_u.uni_mach_acct.buffer, q_u.uni_mach_acct.uni_str_len)); + strlower(mach_acct); become_root(); sam_pass = getsam21pwnam(mach_acct); unbecome_root(); - if (sam_pass != NULL) { /* machine account exists: say so */ - status = 0xC0000000 | NT_STATUS_USER_EXISTS; - } else { - /* this could cause trouble... */ - DEBUG(0,("trouble!\n")); - status = 0; + r_u.status = NT_STATUS_USER_EXISTS; + goto out; } - /* set up the SAMR create_user response */ - memset((char *)r_u.pol.data, '\0', POL_HND_SIZE); - if (status == 0) { - for (i = 4; i < POL_HND_SIZE; i++) { - r_u.pol.data[i] = i+1; - } + /* 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; + } + + local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD; + local_flags|= (q_u.acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0; + + 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; + } + + become_root(); + sam_pass = getsam21pwnam(mach_acct); + 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; + } + + /* associate the RID with the (unique) handle. */ + if (!set_lsa_policy_samr_rid(&r_u.pol, sam_pass->user_rid)) { + /* 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; } - init_dom_rid4(&(r_u.rid4), 0x0030, 0, 0); - r_u.status = status; + r_u.unknown_0=0x000703ff; + r_u.user_rid=sam_pass->user_rid; + out: /* store the response in the SMB stream */ if(!samr_io_r_create_user("", &r_u, rdata, 0)) return False; |