diff options
-rw-r--r-- | source4/libcli/auth/credentials.c | 12 | ||||
-rw-r--r-- | source4/librpc/idl/misc.idl | 4 | ||||
-rw-r--r-- | source4/librpc/idl/netlogon.idl | 14 | ||||
-rw-r--r-- | source4/librpc/idl/samr.idl | 28 | ||||
-rw-r--r-- | source4/rpc_server/netlogon/dcerpc_netlogon.c | 5 | ||||
-rw-r--r-- | source4/rpc_server/samr/samdb.c | 36 | ||||
-rw-r--r-- | source4/rpc_server/samr/samr_password.c | 49 | ||||
-rw-r--r-- | source4/torture/rpc/netlogon.c | 2 | ||||
-rw-r--r-- | source4/torture/rpc/samr.c | 10 |
9 files changed, 82 insertions, 78 deletions
diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index 27a3e32cf3..e0989eff4b 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -128,20 +128,20 @@ static void creds_step(struct creds_CredentialState *creds) /* DES encrypt a 16 byte password buffer using the session key */ -void creds_des_encrypt(struct creds_CredentialState *creds, struct netr_Password *pass) +void creds_des_encrypt(struct creds_CredentialState *creds, struct samr_Password *pass) { - struct netr_Password tmp; - des_crypt112_16(tmp.data, pass->data, creds->session_key, 1); + struct samr_Password tmp; + des_crypt112_16(tmp.hash, pass->hash, creds->session_key, 1); *pass = tmp; } /* DES decrypt a 16 byte password buffer using the session key */ -void creds_des_decrypt(struct creds_CredentialState *creds, struct netr_Password *pass) +void creds_des_decrypt(struct creds_CredentialState *creds, struct samr_Password *pass) { - struct netr_Password tmp; - des_crypt112_16(tmp.data, pass->data, creds->session_key, 0); + struct samr_Password tmp; + des_crypt112_16(tmp.hash, pass->hash, creds->session_key, 0); *pass = tmp; } diff --git a/source4/librpc/idl/misc.idl b/source4/librpc/idl/misc.idl index 240c0026e3..548deeb21b 100644 --- a/source4/librpc/idl/misc.idl +++ b/source4/librpc/idl/misc.idl @@ -120,4 +120,8 @@ interface misc uint16 units_per_week; [size_is(1260), length_is(units_per_week/8)] uint8 *bitmap; } samr_LogonHours; + + typedef [public, flag(NDR_PAHEX)] struct { + uint8 hash[16]; + } samr_Password; } diff --git a/source4/librpc/idl/netlogon.idl b/source4/librpc/idl/netlogon.idl index 386a98856d..64d9afeac3 100644 --- a/source4/librpc/idl/netlogon.idl +++ b/source4/librpc/idl/netlogon.idl @@ -101,14 +101,10 @@ interface netlogon netr_String workstation; } netr_IdentityInfo; - typedef [flag(NDR_PAHEX)] struct { - uint8 data[16]; - } netr_Password; - typedef struct { netr_IdentityInfo identity_info; - netr_Password lmpassword; - netr_Password ntpassword; + samr_Password lmpassword; + samr_Password ntpassword; } netr_PasswordInfo; typedef [flag(NDR_PAHEX)] struct { @@ -300,7 +296,7 @@ interface netlogon [in] uint16 secure_channel_type, [in] unistr computer_name, [in] netr_Authenticator credential, - [in] netr_Password new_password, + [in] samr_Password new_password, [out] netr_Authenticator return_authenticator ); @@ -344,8 +340,8 @@ interface netlogon NTTIME PwLastSet; NTTIME AccountExpires; uint32 AccountControl; - netr_Password lmpw; - netr_Password ntpw; + samr_Password lmpw; + samr_Password ntpw; bool8 NTPwPresent; bool8 LMPwPresent; bool8 PwExpired; diff --git a/source4/librpc/idl/samr.idl b/source4/librpc/idl/samr.idl index eb45513db0..8d0a6c0584 100644 --- a/source4/librpc/idl/samr.idl +++ b/source4/librpc/idl/samr.idl @@ -808,10 +808,6 @@ /************************/ /* Function 0x26 */ - typedef [flag(NDR_PAHEX)] struct { - uint8 hash[16]; - } samr_Hash; - /* this is a password change interface that doesn't give the server the plaintext password. Depricated. @@ -819,15 +815,15 @@ NTSTATUS samr_ChangePasswordUser( [in,ref] policy_handle *handle, [in] bool8 lm_present, - [in] samr_Hash *old_lm_crypted, - [in] samr_Hash *new_lm_crypted, + [in] samr_Password *old_lm_crypted, + [in] samr_Password *new_lm_crypted, [in] bool8 nt_present, - [in] samr_Hash *old_nt_crypted, - [in] samr_Hash *new_nt_crypted, + [in] samr_Password *old_nt_crypted, + [in] samr_Password *new_nt_crypted, [in] bool8 cross1_present, - [in] samr_Hash *nt_cross, + [in] samr_Password *nt_cross, [in] bool8 cross2_present, - [in] samr_Hash *lm_cross + [in] samr_Password *lm_cross ); /************************/ @@ -1090,7 +1086,7 @@ [in] samr_AsciiName *server, [in,ref] samr_AsciiName *account, [in] samr_CryptPassword *password, - [in] samr_Hash *hash + [in] samr_Password *hash ); /************************/ @@ -1099,10 +1095,10 @@ [in] samr_Name *server, [in,ref] samr_Name *account, [in] samr_CryptPassword *nt_password, - [in] samr_Hash *nt_verifier, + [in] samr_Password *nt_verifier, [in] bool8 lm_change, [in] samr_CryptPassword *lm_password, - [in] samr_Hash *lm_verifier + [in] samr_Password *lm_verifier ); /************************/ @@ -1186,10 +1182,10 @@ [in] samr_Name *server, [in,ref] samr_Name *account, [in] samr_CryptPassword *nt_password, - [in] samr_Hash *nt_verifier, + [in] samr_Password *nt_verifier, [in] bool8 lm_change, [in] samr_CryptPassword *lm_password, - [in] samr_Hash *lm_verifier, + [in] samr_Password *lm_verifier, [in] samr_CryptPassword *password3, [out] samr_DomInfo1 *dominfo, [out] samr_ChangeReject *reject @@ -1236,7 +1232,7 @@ NTSTATUS samr_SetDsrmPassword( [in] samr_Name *name, [in] uint32 unknown, - [in] samr_Hash *hash + [in] samr_Password *hash ); diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 5f4717a5c6..f662e45246 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -332,7 +332,6 @@ static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLO struct ldb_message **msgs; struct ldb_message **msgs_domain; NTSTATUS nt_status; - struct samr_Hash newNtHash; struct ldb_message mod, *msg_set_pw = &mod; const char *domain_dn; const char *domain_sid; @@ -410,15 +409,13 @@ static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLO creds_des_decrypt(pipe_state->creds, &r->in.new_password); - memcpy(newNtHash.hash, r->in.new_password.data, sizeof(newNtHash.hash)); - /* set the password - samdb needs to know both the domain and user DNs, so the domain password policy can be used */ nt_status = samdb_set_password(sam_ctx, mem_ctx, msgs[0]->dn, domain_dn, msg_set_pw, NULL, /* Don't have plaintext */ - NULL, &newNtHash, + NULL, &r->in.new_password, False /* This is not considered a password change */, NULL); diff --git a/source4/rpc_server/samr/samdb.c b/source4/rpc_server/samr/samdb.c index 37063b551d..e6862eb8f9 100644 --- a/source4/rpc_server/samr/samdb.c +++ b/source4/rpc_server/samr/samdb.c @@ -482,11 +482,11 @@ NTTIME samdb_result_force_pwd_change(void *ctx, TALLOC_CTX *mem_ctx, } /* - pull a samr_Hash structutre from a result set. + pull a samr_Password structutre from a result set. */ -struct samr_Hash samdb_result_hash(struct ldb_message *msg, const char *attr) +struct samr_Password samdb_result_hash(struct ldb_message *msg, const char *attr) { - struct samr_Hash hash; + struct samr_Password hash; const struct ldb_val *val = ldb_msg_find_ldb_val(msg, attr); ZERO_STRUCT(hash); if (val) { @@ -496,10 +496,10 @@ struct samr_Hash samdb_result_hash(struct ldb_message *msg, const char *attr) } /* - pull an array of samr_Hash structutres from a result set. + pull an array of samr_Password structutres from a result set. */ uint_t samdb_result_hashes(TALLOC_CTX *mem_ctx, struct ldb_message *msg, - const char *attr, struct samr_Hash **hashes) + const char *attr, struct samr_Password **hashes) { uint_t count = 0; const struct ldb_val *val = ldb_msg_find_ldb_val(msg, attr); @@ -514,7 +514,7 @@ uint_t samdb_result_hashes(TALLOC_CTX *mem_ctx, struct ldb_message *msg, return 0; } - *hashes = talloc_array_p(mem_ctx, struct samr_Hash, count); + *hashes = talloc_array_p(mem_ctx, struct samr_Password, count); if (! *hashes) { return 0; } @@ -527,27 +527,27 @@ uint_t samdb_result_hashes(TALLOC_CTX *mem_ctx, struct ldb_message *msg, } NTSTATUS samdb_result_passwords(TALLOC_CTX *mem_ctx, struct ldb_message *msg, - uint8_t **lm_pwd, uint8_t **nt_pwd) + struct samr_Password **lm_pwd, struct samr_Password **nt_pwd) { const char *unicodePwd = samdb_result_string(msg, "unicodePwd", NULL); - struct samr_Hash *lmPwdHash, *ntPwdHash; + struct samr_Password *lmPwdHash, *ntPwdHash; if (unicodePwd) { if (nt_pwd) { - ntPwdHash = talloc_p(mem_ctx, struct samr_Hash); + ntPwdHash = talloc_p(mem_ctx, struct samr_Password); if (!ntPwdHash) { return NT_STATUS_NO_MEMORY; } E_md4hash(unicodePwd, ntPwdHash->hash); - *nt_pwd = ntPwdHash->hash; + *nt_pwd = ntPwdHash; } if (lm_pwd) { BOOL lm_hash_ok; - lmPwdHash = talloc_p(mem_ctx, struct samr_Hash); + lmPwdHash = talloc_p(mem_ctx, struct samr_Password); if (!lmPwdHash) { return NT_STATUS_NO_MEMORY; } @@ -556,7 +556,7 @@ NTSTATUS samdb_result_passwords(TALLOC_CTX *mem_ctx, struct ldb_message *msg, lm_hash_ok = E_deshash(unicodePwd, lmPwdHash->hash); if (lm_hash_ok) { - *lm_pwd = lmPwdHash->hash; + *lm_pwd = lmPwdHash; } else { *lm_pwd = NULL; } @@ -570,7 +570,7 @@ NTSTATUS samdb_result_passwords(TALLOC_CTX *mem_ctx, struct ldb_message *msg, } else if (num_nt > 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } else { - *nt_pwd = ntPwdHash[0].hash; + *nt_pwd = &ntPwdHash[0]; } } if (lm_pwd) { @@ -581,7 +581,7 @@ NTSTATUS samdb_result_passwords(TALLOC_CTX *mem_ctx, struct ldb_message *msg, } else if (num_lm > 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } else { - *lm_pwd = lmPwdHash[0].hash; + *lm_pwd = &lmPwdHash[0]; } } @@ -824,10 +824,10 @@ int samdb_msg_add_uint64(void *ctx, TALLOC_CTX *mem_ctx, struct ldb_message *msg } /* - add a samr_Hash element to a message + add a samr_Password element to a message */ int samdb_msg_add_hash(void *ctx, TALLOC_CTX *mem_ctx, struct ldb_message *msg, - const char *attr_name, struct samr_Hash hash) + const char *attr_name, struct samr_Password hash) { struct samdb_context *sam_ctx = ctx; struct ldb_val val; @@ -842,10 +842,10 @@ int samdb_msg_add_hash(void *ctx, TALLOC_CTX *mem_ctx, struct ldb_message *msg, } /* - add a samr_Hash array to a message + add a samr_Password array to a message */ int samdb_msg_add_hashes(void *ctx, TALLOC_CTX *mem_ctx, struct ldb_message *msg, - const char *attr_name, struct samr_Hash *hashes, uint_t count) + const char *attr_name, struct samr_Password *hashes, uint_t count) { struct samdb_context *sam_ctx = ctx; struct ldb_val val; diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c index 228b8b53c0..b1dc4a7f6b 100644 --- a/source4/rpc_server/samr/samr_password.c +++ b/source4/rpc_server/samr/samr_password.c @@ -34,8 +34,8 @@ NTSTATUS samr_ChangePasswordUser(struct dcesrv_call_state *dce_call, TALLOC_CTX struct samr_account_state *a_state; struct ldb_message **res, mod, *msg; int ret; - struct samr_Hash new_lmPwdHash, new_ntPwdHash, checkHash; - uint8 *lm_pwd, *nt_pwd; + struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash; + struct samr_Password *lm_pwd, *nt_pwd; NTSTATUS status = NT_STATUS_OK; const char * const attrs[] = { "lmPwdHash", "ntPwdHash" , "unicodePwd", NULL }; @@ -72,27 +72,27 @@ NTSTATUS samr_ChangePasswordUser(struct dcesrv_call_state *dce_call, TALLOC_CTX } /* decrypt and check the new lm hash */ - D_P16(lm_pwd, r->in.new_lm_crypted->hash, new_lmPwdHash.hash); + D_P16(lm_pwd->hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash); D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash); if (memcmp(checkHash.hash, lm_pwd, 16) != 0) { return NT_STATUS_WRONG_PASSWORD; } /* decrypt and check the new nt hash */ - D_P16(nt_pwd, r->in.new_nt_crypted->hash, new_ntPwdHash.hash); + D_P16(nt_pwd->hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash); D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash); if (memcmp(checkHash.hash, nt_pwd, 16) != 0) { return NT_STATUS_WRONG_PASSWORD; } /* check the nt cross hash */ - D_P16(lm_pwd, r->in.nt_cross->hash, checkHash.hash); + D_P16(lm_pwd->hash, r->in.nt_cross->hash, checkHash.hash); if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) { return NT_STATUS_WRONG_PASSWORD; } /* check the lm cross hash */ - D_P16(nt_pwd, r->in.lm_cross->hash, checkHash.hash); + D_P16(nt_pwd->hash, r->in.lm_cross->hash, checkHash.hash); if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) { return NT_STATUS_WRONG_PASSWORD; } @@ -136,7 +136,8 @@ NTSTATUS samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, TALLOC_ struct ldb_message **res, mod; const char * const attrs[] = { "objectSid", "lmPwdHash", "unicodePwd", NULL }; const char *domain_sid; - uint8 *lm_pwd; + struct samr_Password *lm_pwd; + DATA_BLOB lm_pwd_blob; if (pwbuf == NULL) { return NT_STATUS_WRONG_PASSWORD; @@ -169,8 +170,10 @@ NTSTATUS samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, TALLOC_ } /* decrypt the password we have been given */ - arcfour_crypt(pwbuf->data, lm_pwd, 516); - + lm_pwd_blob = data_blob(lm_pwd->hash, sizeof(lm_pwd->hash)); + arcfour_crypt_blob(pwbuf->data, 516, &lm_pwd_blob); + data_blob_free(&lm_pwd_blob); + if (!decode_pw_buffer(pwbuf->data, new_pass, sizeof(new_pass), &new_pass_len, STR_ASCII)) { DEBUG(3,("samr: failed to decode password buffer\n")); @@ -243,7 +246,8 @@ NTSTATUS samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call, "pwdProperties", "minPwdAge", "maxPwdAge", NULL }; const char *domain_sid; - uint8 *nt_pwd; + struct samr_Password *nt_pwd; + DATA_BLOB nt_pwd_blob; struct samr_DomInfo1 *dominfo; struct samr_ChangeReject *reject; uint32_t reason = 0; @@ -279,12 +283,19 @@ NTSTATUS samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call, user_dn = res[0]->dn; status = samdb_result_passwords(mem_ctx, res[0], NULL, &nt_pwd); - if (!NT_STATUS_IS_OK(status)) { + if (!NT_STATUS_IS_OK(status) ) { + goto failed; + } + + if (!nt_pwd) { + status = NT_STATUS_WRONG_PASSWORD; goto failed; } /* decrypt the password we have been given */ - arcfour_crypt(r->in.nt_password->data, nt_pwd, 516); + nt_pwd_blob = data_blob(nt_pwd->hash, sizeof(nt_pwd->hash)); + arcfour_crypt_blob(r->in.nt_password->data, 516, &nt_pwd_blob); + data_blob_free(&nt_pwd_blob); if (!decode_pw_buffer(r->in.nt_password->data, new_pass, sizeof(new_pass), &new_pass_len, STR_UNICODE)) { @@ -425,8 +436,8 @@ NTSTATUS samdb_set_password(void *ctx, TALLOC_CTX *mem_ctx, const char *user_dn, const char *domain_dn, struct ldb_message *mod, const char *new_pass, - struct samr_Hash *lmNewHash, - struct samr_Hash *ntNewHash, + struct samr_Password *lmNewHash, + struct samr_Password *ntNewHash, BOOL user_change, uint32_t *reject_reason) { @@ -442,9 +453,9 @@ NTSTATUS samdb_set_password(void *ctx, TALLOC_CTX *mem_ctx, int64_t minPwdAge; uint_t minPwdLength, pwdProperties, pwdHistoryLength; uint_t userAccountControl, badPwdCount; - struct samr_Hash *lmPwdHistory, *ntPwdHistory, lmPwdHash, ntPwdHash; - struct samr_Hash *new_lmPwdHistory, *new_ntPwdHistory; - struct samr_Hash local_lmNewHash, local_ntNewHash; + struct samr_Password *lmPwdHistory, *ntPwdHistory, lmPwdHash, ntPwdHash; + struct samr_Password *new_lmPwdHistory, *new_ntPwdHistory; + struct samr_Password local_lmNewHash, local_ntNewHash; int lmPwdHistory_len, ntPwdHistory_len; struct ldb_message **res; int count; @@ -623,12 +634,12 @@ NTSTATUS samdb_set_password(void *ctx, TALLOC_CTX *mem_ctx, } /* store the password history */ - new_lmPwdHistory = talloc_array_p(mem_ctx, struct samr_Hash, + new_lmPwdHistory = talloc_array_p(mem_ctx, struct samr_Password, pwdHistoryLength); if (!new_lmPwdHistory) { return NT_STATUS_NO_MEMORY; } - new_ntPwdHistory = talloc_array_p(mem_ctx, struct samr_Hash, + new_ntPwdHistory = talloc_array_p(mem_ctx, struct samr_Password, pwdHistoryLength); if (!new_ntPwdHistory) { return NT_STATUS_NO_MEMORY; diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index bfa63c2af7..902910d179 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -1119,7 +1119,7 @@ static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) r.in.computer_name = TEST_MACHINE_NAME; password = generate_random_str(mem_ctx, 8); - E_md4hash(password, r.in.new_password.data); + E_md4hash(password, r.in.new_password.hash); creds_des_encrypt(&creds, &r.in.new_password); diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index dab1b3bed5..311ed23dbe 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -91,7 +91,7 @@ static BOOL test_SetDsrmPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, NTSTATUS status; struct samr_SetDsrmPassword r; struct samr_Name name; - struct samr_Hash hash; + struct samr_Password hash; if (lp_parm_int(-1, "torture", "dangerous") != 1) { printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n"); @@ -734,7 +734,7 @@ static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, NTSTATUS status; struct samr_ChangePasswordUser r; BOOL ret = True; - struct samr_Hash hash1, hash2, hash3, hash4, hash5, hash6; + struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6; struct policy_handle user_handle; char *oldpass = *password; char *newpass = samr_rand_pass(mem_ctx); @@ -794,7 +794,7 @@ static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_c NTSTATUS status; struct samr_OemChangePasswordUser2 r; BOOL ret = True; - struct samr_Hash lm_verifier; + struct samr_Password lm_verifier; struct samr_CryptPassword lm_pass; struct samr_AsciiName server, account; char *oldpass = *password; @@ -838,7 +838,7 @@ static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, BOOL ret = True; struct samr_Name server, account; struct samr_CryptPassword nt_pass, lm_pass; - struct samr_Hash nt_verifier, lm_verifier; + struct samr_Password nt_verifier, lm_verifier; char *oldpass = *password; char *newpass = samr_rand_pass(mem_ctx); uint8_t old_nt_hash[16], new_nt_hash[16]; @@ -891,7 +891,7 @@ static BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, BOOL ret = True; struct samr_Name server, account; struct samr_CryptPassword nt_pass, lm_pass; - struct samr_Hash nt_verifier, lm_verifier; + struct samr_Password nt_verifier, lm_verifier; char *oldpass = *password; char *newpass = samr_rand_pass(mem_ctx); uint8_t old_nt_hash[16], new_nt_hash[16]; |