X-Git-Url: http://git.samba.org/samba.git/?a=blobdiff_plain;f=source3%2Frpc_server%2Fsrv_samr_nt.c;h=513634019bc1652410f62cdfd7d2b4c626746b67;hb=3656cb2e57d971f8119024dff8eb3594b559592d;hp=537d58fac1019d46798dec4080d6e8adc665efac;hpb=e398eed15a7a94d2a53d3bb865927a9db411008c;p=kai%2Fsamba.git diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 537d58fac10..513634019bc 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -1012,6 +1012,7 @@ NTSTATUS _samr_EnumDomainUsers(pipes_struct *p, if (!samr_array) { return NT_STATUS_NO_MEMORY; } + *r->out.sam = samr_array; become_root(); @@ -1071,7 +1072,6 @@ NTSTATUS _samr_EnumDomainUsers(pipes_struct *p, samr_array->entries = samr_entries; *r->out.resume_handle = *r->in.resume_handle + num_account; - *r->out.sam = samr_array; *r->out.num_entries = num_account; DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__)); @@ -2255,11 +2255,9 @@ static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx, static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx, struct samr_UserInfo5 *r, - DOM_SID *user_sid, + struct samu *pw, DOM_SID *domain_sid) { - struct samu *pw = NULL; - bool ret; const DOM_SID *sid_user, *sid_group; uint32_t rid, primary_gid; NTTIME last_logon, last_logoff, last_password_change, @@ -2271,24 +2269,6 @@ static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx, ZERO_STRUCTP(r); - if (!(pw = samu_new(mem_ctx))) { - return NT_STATUS_NO_MEMORY; - } - - become_root(); - ret = pdb_getsampwsid(pw, user_sid); - unbecome_root(); - - if (ret == False) { - DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid))); - TALLOC_FREE(pw); - return NT_STATUS_NO_SUCH_USER; - } - - samr_clear_sam_passwd(pw); - - DEBUG(3,("User:[%s]\n", pdb_get_username(pw))); - sid_user = pdb_get_user_sid(pw); if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) { @@ -2296,7 +2276,6 @@ static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx, "the domain sid %s. Failing operation.\n", pdb_get_username(pw), sid_string_dbg(sid_user), sid_string_dbg(domain_sid))); - TALLOC_FREE(pw); return NT_STATUS_UNSUCCESSFUL; } @@ -2309,7 +2288,6 @@ static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx, "which conflicts with the domain sid %s. Failing operation.\n", pdb_get_username(pw), sid_string_dbg(sid_group), sid_string_dbg(domain_sid))); - TALLOC_FREE(pw); return NT_STATUS_UNSUCCESSFUL; } @@ -2350,8 +2328,6 @@ static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx, acct_expiry, pdb_get_acct_ctrl(pw)); - TALLOC_FREE(pw); - return NT_STATUS_OK; } @@ -2361,35 +2337,16 @@ static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx, static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx, struct samr_UserInfo7 *r, - DOM_SID *user_sid) + struct samu *smbpass) { - struct samu *smbpass=NULL; - bool ret; const char *account_name = NULL; ZERO_STRUCTP(r); - if ( !(smbpass = samu_new( mem_ctx )) ) { - return NT_STATUS_NO_MEMORY; - } - - become_root(); - ret = pdb_getsampwsid(smbpass, user_sid); - unbecome_root(); - - if ( !ret ) { - DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid))); - return NT_STATUS_NO_SUCH_USER; - } - account_name = talloc_strdup(mem_ctx, pdb_get_username(smbpass)); if (!account_name) { - TALLOC_FREE(smbpass); return NT_STATUS_NO_MEMORY; } - TALLOC_FREE(smbpass); - - DEBUG(3,("User:[%s]\n", account_name)); init_samr_user_info7(r, account_name); @@ -2402,33 +2359,12 @@ static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx, static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx, struct samr_UserInfo9 *r, - DOM_SID *user_sid) + struct samu *smbpass) { - struct samu *smbpass=NULL; - bool ret; - ZERO_STRUCTP(r); - if ( !(smbpass = samu_new( mem_ctx )) ) { - return NT_STATUS_NO_MEMORY; - } - - become_root(); - ret = pdb_getsampwsid(smbpass, user_sid); - unbecome_root(); - - if (ret==False) { - DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid))); - TALLOC_FREE(smbpass); - return NT_STATUS_NO_SUCH_USER; - } - - DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) )); - init_samr_user_info9(r, pdb_get_group_rid(smbpass)); - TALLOC_FREE(smbpass); - return NT_STATUS_OK; } @@ -2438,33 +2374,12 @@ static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx, static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx, struct samr_UserInfo16 *r, - DOM_SID *user_sid) + struct samu *smbpass) { - struct samu *smbpass=NULL; - bool ret; - ZERO_STRUCTP(r); - if ( !(smbpass = samu_new( mem_ctx )) ) { - return NT_STATUS_NO_MEMORY; - } - - become_root(); - ret = pdb_getsampwsid(smbpass, user_sid); - unbecome_root(); - - if (ret==False) { - DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid))); - TALLOC_FREE(smbpass); - return NT_STATUS_NO_SUCH_USER; - } - - DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) )); - init_samr_user_info16(r, pdb_get_acct_ctrl(smbpass)); - TALLOC_FREE(smbpass); - return NT_STATUS_OK; } @@ -2515,8 +2430,10 @@ static NTSTATUS get_user_info_18(pipes_struct *p, return NT_STATUS_ACCOUNT_DISABLED; } - init_samr_user_info18(r, pdb_get_lanman_passwd(smbpass), - pdb_get_nt_passwd(smbpass)); + init_samr_user_info18(r, + pdb_get_lanman_passwd(smbpass), + pdb_get_nt_passwd(smbpass), + 0 /* FIXME */); TALLOC_FREE(smbpass); @@ -2529,10 +2446,8 @@ static NTSTATUS get_user_info_18(pipes_struct *p, static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, struct samr_UserInfo20 *r, - DOM_SID *user_sid) + struct samu *sampass) { - struct samu *sampass=NULL; - bool ret; const char *munged_dial = NULL; DATA_BLOB blob; NTSTATUS status; @@ -2540,24 +2455,8 @@ static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, ZERO_STRUCTP(r); - if ( !(sampass = samu_new( mem_ctx )) ) { - return NT_STATUS_NO_MEMORY; - } - - become_root(); - ret = pdb_getsampwsid(sampass, user_sid); - unbecome_root(); - - if (ret == False) { - DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid))); - TALLOC_FREE(sampass); - return NT_STATUS_NO_SUCH_USER; - } - munged_dial = pdb_get_munged_dial(sampass); - samr_clear_sam_passwd(sampass); - DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass), munged_dial, (int)strlen(munged_dial))); @@ -2569,7 +2468,6 @@ static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, status = init_samr_parameters_string(mem_ctx, &blob, ¶meters); data_blob_free(&blob); - TALLOC_FREE(sampass); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -2586,12 +2484,10 @@ static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, struct samr_UserInfo21 *r, - DOM_SID *user_sid, + struct samu *pw, DOM_SID *domain_sid) { NTSTATUS status; - struct samu *pw = NULL; - bool ret; const DOM_SID *sid_user, *sid_group; uint32_t rid, primary_gid; NTTIME last_logon, last_logoff, last_password_change, @@ -2608,24 +2504,6 @@ static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, ZERO_STRUCTP(r); - if (!(pw = samu_new(mem_ctx))) { - return NT_STATUS_NO_MEMORY; - } - - become_root(); - ret = pdb_getsampwsid(pw, user_sid); - unbecome_root(); - - if (ret == False) { - DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid))); - TALLOC_FREE(pw); - return NT_STATUS_NO_SUCH_USER; - } - - samr_clear_sam_passwd(pw); - - DEBUG(3,("User:[%s]\n", pdb_get_username(pw))); - sid_user = pdb_get_user_sid(pw); if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) { @@ -2633,7 +2511,6 @@ static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, "the domain sid %s. Failing operation.\n", pdb_get_username(pw), sid_string_dbg(sid_user), sid_string_dbg(domain_sid))); - TALLOC_FREE(pw); return NT_STATUS_UNSUCCESSFUL; } @@ -2646,7 +2523,6 @@ static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, "which conflicts with the domain sid %s. Failing operation.\n", pdb_get_username(pw), sid_string_dbg(sid_group), sid_string_dbg(domain_sid))); - TALLOC_FREE(pw); return NT_STATUS_UNSUCCESSFUL; } @@ -2679,7 +2555,6 @@ static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, status = init_samr_parameters_string(mem_ctx, &blob, ¶meters); data_blob_free(&blob); if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(pw); return status; } @@ -2734,10 +2609,9 @@ static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, pdb_get_logon_count(pw), 0, /* country_code */ 0, /* code_page */ - 0, /* nt_password_set */ 0, /* lm_password_set */ + 0, /* nt_password_set */ password_expired); - TALLOC_FREE(pw); return NT_STATUS_OK; } @@ -2754,6 +2628,8 @@ NTSTATUS _samr_QueryUserInfo(pipes_struct *p, struct samr_info *info = NULL; DOM_SID domain_sid; uint32 rid; + bool ret = false; + struct samu *pwd = NULL; /* search for the handle */ if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info)) @@ -2783,58 +2659,54 @@ NTSTATUS _samr_QueryUserInfo(pipes_struct *p, DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level)); + if (!(pwd = samu_new(p->mem_ctx))) { + return NT_STATUS_NO_MEMORY; + } + + become_root(); + ret = pdb_getsampwsid(pwd, &info->sid); + unbecome_root(); + + if (ret == false) { + DEBUG(4,("User %s not found\n", sid_string_dbg(&info->sid))); + TALLOC_FREE(pwd); + return NT_STATUS_NO_SUCH_USER; + } + + DEBUG(3,("User:[%s]\n", pdb_get_username(pwd))); + + samr_clear_sam_passwd(pwd); + switch (r->in.level) { case 5: - status = get_user_info_5(p->mem_ctx, &user_info->info5, &info->sid, &domain_sid); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid); break; case 7: - status = get_user_info_7(p->mem_ctx, &user_info->info7, &info->sid); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd); break; case 9: - status = get_user_info_9(p->mem_ctx, &user_info->info9, &info->sid); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd); break; case 16: - status = get_user_info_16(p->mem_ctx, &user_info->info16, &info->sid); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd); break; - case 18: + /* level 18 is special */ status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid); - if (!NT_STATUS_IS_OK(status)) { - return status; - } break; - case 20: - status = get_user_info_20(p->mem_ctx, &user_info->info20, &info->sid); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd); break; - case 21: - status = get_user_info_21(p->mem_ctx, &user_info->info21, - &info->sid, &domain_sid); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid); break; - default: - return NT_STATUS_INVALID_INFO_CLASS; + status = NT_STATUS_INVALID_INFO_CLASS; + break; } + TALLOC_FREE(pwd); + *r->out.info = user_info; DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__)); @@ -3109,7 +2981,7 @@ NTSTATUS _samr_QueryDomainInfo(pipes_struct *p, lp_workgroup(), global_myname(), seq_num, - 1, + DOMAIN_SERVER_ENABLED, server_role, 1, num_users, @@ -3478,14 +3350,26 @@ NTSTATUS _samr_Connect2(pipes_struct *p, uint32 des_access = r->in.access_mask; NTSTATUS nt_status; size_t sd_size; + const char *fn = "_samr_Connect2"; + switch (p->hdr_req.opnum) { + case NDR_SAMR_CONNECT2: + fn = "_samr_Connect2"; + break; + case NDR_SAMR_CONNECT4: + fn = "_samr_Connect4"; + break; + case NDR_SAMR_CONNECT5: + fn = "_samr_Connect5"; + break; + } - DEBUG(5,("_samr_Connect2: %d\n", __LINE__)); + DEBUG(5,("%s: %d\n", fn, __LINE__)); /* Access check */ if (!pipe_access_check(p)) { - DEBUG(3, ("access denied to _samr_Connect2\n")); + DEBUG(3, ("access denied to %s\n", fn)); return NT_STATUS_ACCESS_DENIED; } @@ -3495,7 +3379,7 @@ NTSTATUS _samr_Connect2(pipes_struct *p, se_map_generic(&des_access, &sam_generic_mapping); nt_status = access_check_samr_object(psd, p->server_info->ptok, - NULL, 0, des_access, &acc_granted, "_samr_Connect2"); + NULL, 0, des_access, &acc_granted, fn); if ( !NT_STATUS_IS_OK(nt_status) ) return nt_status; @@ -3511,7 +3395,7 @@ NTSTATUS _samr_Connect2(pipes_struct *p, if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info)) return NT_STATUS_OBJECT_NAME_NOT_FOUND; - DEBUG(5,("_samr_Connect2: %d\n", __LINE__)); + DEBUG(5,("%s: %d\n", fn, __LINE__)); return nt_status; } @@ -3523,48 +3407,13 @@ NTSTATUS _samr_Connect2(pipes_struct *p, NTSTATUS _samr_Connect4(pipes_struct *p, struct samr_Connect4 *r) { - struct samr_info *info = NULL; - SEC_DESC *psd = NULL; - uint32 acc_granted; - uint32 des_access = r->in.access_mask; - NTSTATUS nt_status; - size_t sd_size; + struct samr_Connect2 c; + c.in.system_name = r->in.system_name; + c.in.access_mask = r->in.access_mask; + c.out.connect_handle = r->out.connect_handle; - DEBUG(5,("_samr_Connect4: %d\n", __LINE__)); - - /* Access check */ - - if (!pipe_access_check(p)) { - DEBUG(3, ("access denied to samr_Connect4\n")); - return NT_STATUS_ACCESS_DENIED; - } - - map_max_allowed_access(p->server_info->ptok, &des_access); - - make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0); - se_map_generic(&des_access, &sam_generic_mapping); - - nt_status = access_check_samr_object(psd, p->server_info->ptok, - NULL, 0, des_access, &acc_granted, "_samr_Connect4"); - - if ( !NT_STATUS_IS_OK(nt_status) ) - return nt_status; - - /* associate the user's SID and access granted with the new handle. */ - if ((info = get_samr_info_by_sid(NULL)) == NULL) - return NT_STATUS_NO_MEMORY; - - info->acc_granted = acc_granted; - info->status = r->in.access_mask; /* ??? */ - - /* get a (unique) handle. open a policy on it. */ - if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info)) - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - - DEBUG(5,("_samr_Connect4: %d\n", __LINE__)); - - return NT_STATUS_OK; + return _samr_Connect2(p, &c); } /******************************************************************* @@ -3574,50 +3423,22 @@ NTSTATUS _samr_Connect4(pipes_struct *p, NTSTATUS _samr_Connect5(pipes_struct *p, struct samr_Connect5 *r) { - struct samr_info *info = NULL; - SEC_DESC *psd = NULL; - uint32 acc_granted; - uint32 des_access = r->in.access_mask; - NTSTATUS nt_status; - size_t sd_size; + NTSTATUS status; + struct samr_Connect2 c; struct samr_ConnectInfo1 info1; - DEBUG(5,("_samr_Connect5: %d\n", __LINE__)); + info1.client_version = SAMR_CONNECT_AFTER_W2K; + info1.unknown2 = 0; - /* Access check */ + c.in.system_name = r->in.system_name; + c.in.access_mask = r->in.access_mask; + c.out.connect_handle = r->out.connect_handle; - if (!pipe_access_check(p)) { - DEBUG(3, ("access denied to samr_Connect5\n")); - return NT_STATUS_ACCESS_DENIED; + status = _samr_Connect2(p, &c); + if (!NT_STATUS_IS_OK(status)) { + return status; } - map_max_allowed_access(p->server_info->ptok, &des_access); - - make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0); - se_map_generic(&des_access, &sam_generic_mapping); - - nt_status = access_check_samr_object(psd, p->server_info->ptok, - NULL, 0, des_access, &acc_granted, "_samr_Connect5"); - - if ( !NT_STATUS_IS_OK(nt_status) ) - return nt_status; - - /* associate the user's SID and access granted with the new handle. */ - if ((info = get_samr_info_by_sid(NULL)) == NULL) - return NT_STATUS_NO_MEMORY; - - info->acc_granted = acc_granted; - info->status = r->in.access_mask; /* ??? */ - - /* get a (unique) handle. open a policy on it. */ - if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info)) - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - - DEBUG(5,("_samr_Connect5: %d\n", __LINE__)); - - info1.client_version = SAMR_CONNECT_AFTER_W2K; - info1.unknown2 = 0; - *r->out.level_out = 1; r->out.info_out->info1 = info1; @@ -3825,13 +3646,11 @@ static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx, if (id7 == NULL) { DEBUG(5, ("set_user_info_7: NULL id7\n")); - TALLOC_FREE(pwd); return NT_STATUS_ACCESS_DENIED; } if (!id7->account_name.string) { DEBUG(5, ("set_user_info_7: failed to get new username\n")); - TALLOC_FREE(pwd); return NT_STATUS_ACCESS_DENIED; } @@ -3851,7 +3670,6 @@ static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx, rc = pdb_rename_sam_account(pwd, id7->account_name.string); - TALLOC_FREE(pwd); return rc; } @@ -3864,23 +3682,18 @@ static bool set_user_info_16(struct samr_UserInfo16 *id16, { if (id16 == NULL) { DEBUG(5, ("set_user_info_16: NULL id16\n")); - TALLOC_FREE(pwd); return False; } /* FIX ME: check if the value is really changed --metze */ if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) { - TALLOC_FREE(pwd); return False; } if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) { - TALLOC_FREE(pwd); return False; } - TALLOC_FREE(pwd); - return True; } @@ -3888,35 +3701,58 @@ static bool set_user_info_16(struct samr_UserInfo16 *id16, set_user_info_18 ********************************************************************/ -static bool set_user_info_18(struct samr_UserInfo18 *id18, - struct samu *pwd) +static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18, + TALLOC_CTX *mem_ctx, + DATA_BLOB *session_key, + struct samu *pwd) { if (id18 == NULL) { DEBUG(2, ("set_user_info_18: id18 is NULL\n")); - TALLOC_FREE(pwd); - return False; + return NT_STATUS_INVALID_PARAMETER; } - if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd.hash, PDB_CHANGED)) { - TALLOC_FREE(pwd); - return False; + if (id18->nt_pwd_active || id18->lm_pwd_active) { + if (!session_key->length) { + return NT_STATUS_NO_USER_SESSION_KEY; + } } - if (!pdb_set_nt_passwd (pwd, id18->nt_pwd.hash, PDB_CHANGED)) { - TALLOC_FREE(pwd); - return False; + + if (id18->nt_pwd_active) { + + DATA_BLOB in, out; + + in = data_blob_const(id18->nt_pwd.hash, 16); + out = data_blob_talloc_zero(mem_ctx, 16); + + sess_crypt_blob(&out, &in, session_key, false); + + if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) { + return NT_STATUS_ACCESS_DENIED; + } } - if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) { - TALLOC_FREE(pwd); - return False; + + if (id18->lm_pwd_active) { + + DATA_BLOB in, out; + + in = data_blob_const(id18->lm_pwd.hash, 16); + out = data_blob_talloc_zero(mem_ctx, 16); + + sess_crypt_blob(&out, &in, session_key, false); + + if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) { + return NT_STATUS_ACCESS_DENIED; + } } - if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) { - TALLOC_FREE(pwd); - return False; - } + if (id18->password_expired) { + pdb_set_pass_last_set_time(pwd, 0, PDB_CHANGED); + } else { + /* FIXME */ + pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED); + } - TALLOC_FREE(pwd); - return True; + return pdb_update_sam_account(pwd); } /******************************************************************* @@ -3935,12 +3771,9 @@ static bool set_user_info_20(struct samr_UserInfo20 *id20, /* write the change out */ if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) { - TALLOC_FREE(pwd); return False; } - TALLOC_FREE(pwd); - return True; } @@ -3959,6 +3792,14 @@ static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx, return NT_STATUS_INVALID_PARAMETER; } + if (id21->fields_present == 0) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) { + return NT_STATUS_ACCESS_DENIED; + } + /* we need to separately check for an account rename first */ if (id21->account_name.string && @@ -3984,7 +3825,6 @@ static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx, if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("set_user_info_21: failed to rename account: %s\n", nt_errstr(status))); - TALLOC_FREE(pwd); return status; } @@ -4015,12 +3855,9 @@ static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx, /* write the change out */ if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) { - TALLOC_FREE(pwd); return status; } - TALLOC_FREE(pwd); - return NT_STATUS_OK; } @@ -4034,7 +3871,7 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx, { char *plaintext_buf = NULL; uint32 len = 0; - uint16 acct_ctrl; + uint32_t acct_ctrl; NTSTATUS status; if (id23 == NULL) { @@ -4042,39 +3879,48 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx, return NT_STATUS_INVALID_PARAMETER; } - DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n", - pdb_get_username(pwd))); - - acct_ctrl = pdb_get_acct_ctrl(pwd); - - if (!decode_pw_buffer(mem_ctx, - id23->password.data, - &plaintext_buf, - &len, - STR_UNICODE)) { - TALLOC_FREE(pwd); + if (id23->info.fields_present == 0) { return NT_STATUS_INVALID_PARAMETER; - } + } - if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) { - TALLOC_FREE(pwd); + if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) { return NT_STATUS_ACCESS_DENIED; } + if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) || + (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) { + + DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n", + pdb_get_username(pwd))); + + if (!decode_pw_buffer(mem_ctx, + id23->password.data, + &plaintext_buf, + &len, + STR_UNICODE)) { + return NT_STATUS_WRONG_PASSWORD; + } + + if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) { + return NT_STATUS_ACCESS_DENIED; + } + } + copy_id23_to_sam_passwd(pwd, id23); + acct_ctrl = pdb_get_acct_ctrl(pwd); + /* if it's a trust account, don't update /etc/passwd */ if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) || ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) || ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) { DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n")); - } else { + } else if (plaintext_buf) { /* update the UNIX password */ if (lp_unix_password_sync() ) { struct passwd *passwd; if (pdb_get_username(pwd) == NULL) { DEBUG(1, ("chgpasswd: User without name???\n")); - TALLOC_FREE(pwd); return NT_STATUS_ACCESS_DENIED; } @@ -4084,29 +3930,26 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx, } if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) { - TALLOC_FREE(pwd); return NT_STATUS_ACCESS_DENIED; } TALLOC_FREE(passwd); } } - memset(plaintext_buf, '\0', strlen(plaintext_buf)); + if (plaintext_buf) { + memset(plaintext_buf, '\0', strlen(plaintext_buf)); + } if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) && (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx, pwd)))) { - TALLOC_FREE(pwd); return status; } if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) { - TALLOC_FREE(pwd); return status; } - TALLOC_FREE(pwd); - return NT_STATUS_OK; } @@ -4137,12 +3980,10 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd, &plaintext_buf, &len, STR_UNICODE)) { - TALLOC_FREE(pwd); return False; } if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) { - TALLOC_FREE(pwd); return False; } @@ -4158,7 +3999,6 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd, if (pdb_get_username(pwd) == NULL) { DEBUG(1, ("chgpasswd: User without name???\n")); - TALLOC_FREE(pwd); return False; } @@ -4168,7 +4008,6 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd, } if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) { - TALLOC_FREE(pwd); return False; } TALLOC_FREE(passwd); @@ -4196,12 +4035,9 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd, /* update the SAMBA password */ if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) { - TALLOC_FREE(pwd); return False; } - TALLOC_FREE(pwd); - return True; } @@ -4220,11 +4056,18 @@ static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx, return NT_STATUS_INVALID_PARAMETER; } + if (id25->info.fields_present == 0) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) { + return NT_STATUS_ACCESS_DENIED; + } + copy_id25_to_sam_passwd(pwd, id25); /* write the change out */ if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) { - TALLOC_FREE(pwd); return status; } @@ -4243,9 +4086,6 @@ static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx, } } - /* WARNING: No TALLOC_FREE(pwd), we are about to set the password - * hereafter! */ - return NT_STATUS_OK; } @@ -4369,9 +4209,10 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p, case 18: /* Used by AS/U JRA. */ - if (!set_user_info_18(&info->info18, pwd)) { - status = NT_STATUS_ACCESS_DENIED; - } + status = set_user_info_18(&info->info18, + p->mem_ctx, + &p->server_info->user_session_key, + pwd); break; case 20: @@ -4410,7 +4251,7 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p, if (!set_user_info_pw(info->info24.password.data, pwd, switch_value)) { - status = NT_STATUS_ACCESS_DENIED; + status = NT_STATUS_WRONG_PASSWORD; } break; @@ -4431,7 +4272,7 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p, } if (!set_user_info_pw(info->info25.password.data, pwd, switch_value)) { - status = NT_STATUS_ACCESS_DENIED; + status = NT_STATUS_WRONG_PASSWORD; } break; @@ -4447,7 +4288,7 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p, if (!set_user_info_pw(info->info26.password.data, pwd, switch_value)) { - status = NT_STATUS_ACCESS_DENIED; + status = NT_STATUS_WRONG_PASSWORD; } break; @@ -4457,6 +4298,8 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p, done: + TALLOC_FREE(pwd); + if (has_enough_rights) { unbecome_root(); }