From: Andreas Schneider Date: Fri, 7 Oct 2022 12:35:15 +0000 (+0200) Subject: s3:rpcclient: Pass salt down to init_samr_CryptPasswordAES() X-Git-Tag: talloc-2.4.0~669 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=16335412ff312ecb330f7890bd3e94117a5fa6ff;p=thirdparty%2Fsamba.git s3:rpcclient: Pass salt down to init_samr_CryptPasswordAES() BUG: https://bugzilla.samba.org/show_bug.cgi?id=15206 Signed-off-by: Andreas Schneider Reviewed-by: Noel Power --- diff --git a/source3/rpc_client/init_samr.c b/source3/rpc_client/init_samr.c index 68f42b602b3..52fa2f90d6e 100644 --- a/source3/rpc_client/init_samr.c +++ b/source3/rpc_client/init_samr.c @@ -79,6 +79,7 @@ NTSTATUS init_samr_CryptPassword(const char *pwd, NTSTATUS init_samr_CryptPasswordAES(TALLOC_CTX *mem_ctx, const char *password, + DATA_BLOB *salt, DATA_BLOB *session_key, struct samr_EncryptedPasswordAES *ppwd_buf) { @@ -87,12 +88,6 @@ NTSTATUS init_samr_CryptPasswordAES(TALLOC_CTX *mem_ctx, .data = pw_data, .length = sizeof(pw_data), }; - size_t iv_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_256_CBC); - uint8_t iv_data[iv_size]; - DATA_BLOB iv = { - .data = iv_data, - .length = iv_size, - }; DATA_BLOB ciphertext = data_blob_null; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; bool ok; @@ -101,8 +96,6 @@ NTSTATUS init_samr_CryptPasswordAES(TALLOC_CTX *mem_ctx, return NT_STATUS_INVALID_PARAMETER; } - generate_nonce_buffer(iv.data, iv.length); - ok = encode_pwd_buffer514_from_str(pw_data, password, STR_UNICODE); if (!ok) { return NT_STATUS_INTERNAL_ERROR; @@ -114,7 +107,7 @@ NTSTATUS init_samr_CryptPasswordAES(TALLOC_CTX *mem_ctx, session_key, &samr_aes256_enc_key_salt, &samr_aes256_mac_key_salt, - &iv, + salt, &ciphertext, ppwd_buf->auth_data); BURN_DATA(pw_data); @@ -126,8 +119,8 @@ NTSTATUS init_samr_CryptPasswordAES(TALLOC_CTX *mem_ctx, ppwd_buf->cipher = ciphertext.data; ppwd_buf->PBKDF2Iterations = 0; - SMB_ASSERT(iv.length == sizeof(ppwd_buf->salt)); - memcpy(ppwd_buf->salt, iv.data, iv.length); + SMB_ASSERT(salt->length == sizeof(ppwd_buf->salt)); + memcpy(ppwd_buf->salt, salt->data, salt->length); return NT_STATUS_OK; } diff --git a/source3/rpc_client/init_samr.h b/source3/rpc_client/init_samr.h index 940534e7168..71b4c0e573d 100644 --- a/source3/rpc_client/init_samr.h +++ b/source3/rpc_client/init_samr.h @@ -47,6 +47,7 @@ NTSTATUS init_samr_CryptPassword(const char *pwd, */ NTSTATUS init_samr_CryptPasswordAES(TALLOC_CTX *mem_ctx, const char *password, + DATA_BLOB *salt, DATA_BLOB *session_key, struct samr_EncryptedPasswordAES *ppwd_buf); diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c index 9ccd2f78a8d..8106ca90cf2 100644 --- a/source3/rpcclient/cmd_samr.c +++ b/source3/rpcclient/cmd_samr.c @@ -3172,6 +3172,11 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, uint8_t nt_hash[16]; uint8_t lm_hash[16]; DATA_BLOB session_key; + uint8_t salt_data[16]; + DATA_BLOB salt = { + .data = salt_data, + .length = sizeof(salt_data), + }; uint8_t password_expired = 0; struct dcerpc_binding_handle *b = cli->binding_handle; TALLOC_CTX *frame = NULL; @@ -3198,6 +3203,8 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, goto done; } + generate_nonce_buffer(salt.data, salt.length); + switch(level) { case 18: case 21: @@ -3220,6 +3227,7 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli, case 31: status = init_samr_CryptPasswordAES(frame, param, + &salt, &session_key, &pwd_buf_aes); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/libnet/libnet_passwd.c b/source4/libnet/libnet_passwd.c index 4f662110e55..a1672104824 100644 --- a/source4/libnet/libnet_passwd.c +++ b/source4/libnet/libnet_passwd.c @@ -57,13 +57,13 @@ static NTSTATUS libnet_ChangePassword_samr_aes(TALLOC_CTX *mem_ctx, struct samr_EncryptedPasswordAES pwd_buf = { .cipher_len = 0 }; - DATA_BLOB iv = { + DATA_BLOB salt = { .data = pwd_buf.salt, .length = sizeof(pwd_buf.salt), }; - gnutls_datum_t iv_datum = { - .data = iv.data, - .size = iv.length, + gnutls_datum_t salt_datum = { + .data = pwd_buf.salt, + .size = sizeof(pwd_buf.salt), }; uint64_t pbkdf2_iterations = generate_random_u64_range(5000, 1000000); NTSTATUS status; @@ -71,11 +71,11 @@ static NTSTATUS libnet_ChangePassword_samr_aes(TALLOC_CTX *mem_ctx, E_md4hash(old_password, old_nt_key_data); - generate_nonce_buffer(iv.data, iv.length); + generate_nonce_buffer(salt.data, salt.length); rc = gnutls_pbkdf2(GNUTLS_MAC_SHA512, &old_nt_key, - &iv_datum, + &salt_datum, pbkdf2_iterations, cek.data, cek.length); @@ -86,6 +86,7 @@ static NTSTATUS libnet_ChangePassword_samr_aes(TALLOC_CTX *mem_ctx, status = init_samr_CryptPasswordAES(mem_ctx, new_password, + &salt, &cek, &pwd_buf); data_blob_clear(&cek); diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index de354659067..0b1880efa18 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -783,6 +783,11 @@ static bool test_SetUserPass_32(struct dcerpc_pipe *p, struct torture_context *t struct samr_SetUserInfo s; union samr_UserInfo u; DATA_BLOB session_key; + uint8_t salt_data[16]; + DATA_BLOB salt = { + .data = salt_data, + .length = sizeof(salt_data), + }; char *newpass = NULL; struct dcerpc_binding_handle *b = p->binding_handle; struct samr_GetUserPwInfo pwp; @@ -818,8 +823,11 @@ static bool test_SetUserPass_32(struct dcerpc_pipe *p, struct torture_context *t return false; } + generate_nonce_buffer(salt.data, salt.length); + status = init_samr_CryptPasswordAES(tctx, newpass, + &salt, &session_key, &u.info32.password); torture_assert_ntstatus_ok(tctx, @@ -852,6 +860,7 @@ static bool test_SetUserPass_32(struct dcerpc_pipe *p, struct torture_context *t status = init_samr_CryptPasswordAES(tctx, newpass, + &salt, &session_key, &u.info32.password); torture_assert_ntstatus_ok(tctx, @@ -896,6 +905,11 @@ static bool test_SetUserPass_31(struct dcerpc_pipe *p, struct torture_context *t union samr_UserInfo u; bool ret = true; DATA_BLOB session_key; + uint8_t salt_data[16]; + DATA_BLOB salt = { + .data = salt_data, + .length = sizeof(salt_data), + }; char *newpass; struct dcerpc_binding_handle *b = p->binding_handle; struct samr_GetUserPwInfo pwp; @@ -931,8 +945,11 @@ static bool test_SetUserPass_31(struct dcerpc_pipe *p, struct torture_context *t return false; } + generate_nonce_buffer(salt.data, salt.length); + status = init_samr_CryptPasswordAES(tctx, newpass, + &salt, &session_key, &u.info31.password); torture_assert_ntstatus_ok(tctx, @@ -959,6 +976,7 @@ static bool test_SetUserPass_31(struct dcerpc_pipe *p, struct torture_context *t status = init_samr_CryptPasswordAES(tctx, newpass, + &salt, &session_key, &u.info31.password); torture_assert_ntstatus_ok(tctx, @@ -1381,6 +1399,11 @@ static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p, union samr_UserInfo u; bool ret = true; DATA_BLOB session_key; + uint8_t salt_data[16]; + DATA_BLOB salt = { + .data = salt_data, + .length = sizeof(salt_data), + }; char *newpass; struct dcerpc_binding_handle *b = p->binding_handle; struct samr_GetUserPwInfo pwp; @@ -1490,6 +1513,8 @@ static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p, return false; } + generate_nonce_buffer(salt.data, salt.length); + switch (level) { case 18: { @@ -1561,6 +1586,7 @@ static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p, case 31: status = init_samr_CryptPasswordAES(tctx, newpass, + &salt, &session_key, &u.info31.password); @@ -1568,6 +1594,7 @@ static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p, case 32: status = init_samr_CryptPasswordAES(tctx, newpass, + &salt, &session_key, &u.info32.password);