Changeset 862 for trunk/server/source4/rpc_server/samr
- Timestamp:
- May 13, 2014, 11:39:04 AM (11 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 860
- Property svn:mergeinfo changed
-
trunk/server/source4/rpc_server/samr/samr_password.c
r752 r862 33 33 /* 34 34 samr_ChangePasswordUser 35 36 So old it is just not worth implementing 37 because it does not supply a plaintext and so we can't do password 38 complexity checking and cannot update all the other password hashes. 39 35 40 */ 36 41 NTSTATUS dcesrv_samr_ChangePasswordUser(struct dcesrv_call_state *dce_call, … … 38 43 struct samr_ChangePasswordUser *r) 39 44 { 40 struct dcesrv_handle *h; 41 struct samr_account_state *a_state; 42 struct ldb_context *sam_ctx; 43 struct ldb_message **res; 44 int ret; 45 struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash; 46 struct samr_Password *lm_pwd, *nt_pwd; 47 NTSTATUS status = NT_STATUS_OK; 48 const char * const attrs[] = { "dBCSPwd", "unicodePwd" , NULL }; 49 50 DCESRV_PULL_HANDLE(h, r->in.user_handle, SAMR_HANDLE_USER); 51 52 a_state = h->data; 53 54 /* basic sanity checking on parameters. Do this before any database ops */ 55 if (!r->in.lm_present || !r->in.nt_present || 56 !r->in.old_lm_crypted || !r->in.new_lm_crypted || 57 !r->in.old_nt_crypted || !r->in.new_nt_crypted) { 58 /* we should really handle a change with lm not 59 present */ 60 return NT_STATUS_INVALID_PARAMETER_MIX; 61 } 62 63 /* Connect to a SAMDB with system privileges for fetching the old pw 64 * hashes. */ 65 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, 66 dce_call->conn->dce_ctx->lp_ctx, 67 system_session(dce_call->conn->dce_ctx->lp_ctx), 0); 68 if (sam_ctx == NULL) { 69 return NT_STATUS_INVALID_SYSTEM_SERVICE; 70 } 71 72 /* fetch the old hashes */ 73 ret = gendb_search_dn(sam_ctx, mem_ctx, 74 a_state->account_dn, &res, attrs); 75 if (ret != 1) { 76 return NT_STATUS_WRONG_PASSWORD; 77 } 78 79 status = samdb_result_passwords(mem_ctx, 80 dce_call->conn->dce_ctx->lp_ctx, 81 res[0], &lm_pwd, &nt_pwd); 82 if (!NT_STATUS_IS_OK(status) || !nt_pwd) { 83 return NT_STATUS_WRONG_PASSWORD; 84 } 85 86 /* decrypt and check the new lm hash */ 87 if (lm_pwd) { 88 D_P16(lm_pwd->hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash); 89 D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash); 90 if (memcmp(checkHash.hash, lm_pwd, 16) != 0) { 91 return NT_STATUS_WRONG_PASSWORD; 92 } 93 } 94 95 /* decrypt and check the new nt hash */ 96 D_P16(nt_pwd->hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash); 97 D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash); 98 if (memcmp(checkHash.hash, nt_pwd, 16) != 0) { 99 return NT_STATUS_WRONG_PASSWORD; 100 } 101 102 /* The NT Cross is not required by Win2k3 R2, but if present 103 check the nt cross hash */ 104 if (r->in.cross1_present && r->in.nt_cross && lm_pwd) { 105 D_P16(lm_pwd->hash, r->in.nt_cross->hash, checkHash.hash); 106 if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) { 107 return NT_STATUS_WRONG_PASSWORD; 108 } 109 } 110 111 /* The LM Cross is not required by Win2k3 R2, but if present 112 check the lm cross hash */ 113 if (r->in.cross2_present && r->in.lm_cross && lm_pwd) { 114 D_P16(nt_pwd->hash, r->in.lm_cross->hash, checkHash.hash); 115 if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) { 116 return NT_STATUS_WRONG_PASSWORD; 117 } 118 } 119 120 /* Start a SAM with user privileges for the password change */ 121 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, 122 dce_call->conn->dce_ctx->lp_ctx, 123 dce_call->conn->auth_state.session_info, 0); 124 if (sam_ctx == NULL) { 125 return NT_STATUS_INVALID_SYSTEM_SERVICE; 126 } 127 128 /* Start transaction */ 129 ret = ldb_transaction_start(sam_ctx); 130 if (ret != LDB_SUCCESS) { 131 DEBUG(1, ("Failed to start transaction: %s\n", ldb_errstring(sam_ctx))); 132 return NT_STATUS_TRANSACTION_ABORTED; 133 } 134 135 /* Performs the password modification. We pass the old hashes read out 136 * from the database since they were already checked against the user- 137 * provided ones. */ 138 status = samdb_set_password(sam_ctx, mem_ctx, 139 a_state->account_dn, 140 a_state->domain_state->domain_dn, 141 NULL, &new_lmPwdHash, &new_ntPwdHash, 142 lm_pwd, nt_pwd, /* this is a user password change */ 143 NULL, 144 NULL); 145 if (!NT_STATUS_IS_OK(status)) { 146 ldb_transaction_cancel(sam_ctx); 147 return status; 148 } 149 150 /* And this confirms it in a transaction commit */ 151 ret = ldb_transaction_commit(sam_ctx); 152 if (ret != LDB_SUCCESS) { 153 DEBUG(1,("Failed to commit transaction to change password on %s: %s\n", 154 ldb_dn_get_linearized(a_state->account_dn), 155 ldb_errstring(sam_ctx))); 156 return NT_STATUS_TRANSACTION_ABORTED; 157 } 158 159 return NT_STATUS_OK; 45 return NT_STATUS_NOT_IMPLEMENTED; 160 46 } 161 47
Note:
See TracChangeset
for help on using the changeset viewer.