summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorAndreas Schneider <asn@samba.org>2022-07-05 13:26:37 +0200
committerAndreas Schneider <asn@cryptomilk.org>2022-07-28 11:51:29 +0000
commit8733fabd581ff6ecd766e19daa85d1c88966676a (patch)
tree7904c7e93ad3078498ed79f8d1605432e27b6e69 /source4
parent1ca42e12ef27eea29787bb4cebacf325be3e2f9f (diff)
downloadsamba-8733fabd581ff6ecd766e19daa85d1c88966676a.tar.gz
s4:torture: Add test for dcerpc_samr_ChangePasswordUser4
Signed-off-by: Andreas Schneider <asn@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'source4')
-rw-r--r--source4/torture/rpc/samr.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c
index 77afe47470a..5fe51e51022 100644
--- a/source4/torture/rpc/samr.c
+++ b/source4/torture/rpc/samr.c
@@ -41,6 +41,7 @@
#include "../libcli/auth/schannel.h"
#include "torture/util.h"
#include "source4/librpc/rpc/dcerpc.h"
+#include "librpc/rpc/dcerpc_samr.h"
#include "source3/rpc_client/init_samr.h"
#include "lib/crypto/gnutls_helpers.h"
@@ -3015,6 +3016,123 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct
return ret;
}
+bool test_ChangePasswordUser4(struct dcerpc_pipe *p,
+ struct torture_context *tctx,
+ const char *account_string,
+ int policy_min_pw_len,
+ char **password,
+ const char *newpassword)
+{
+#ifdef HAVE_GNUTLS_PBKDF2
+ struct dcerpc_binding_handle *b = p->binding_handle;
+ struct samr_ChangePasswordUser4 r;
+ const char *oldpassword = *password;
+ char *srv_str = NULL;
+ struct lsa_String server;
+ struct lsa_String account;
+ uint8_t old_nt_key_data[16] = {0};
+ gnutls_datum_t old_nt_key = {
+ .data = old_nt_key_data,
+ .size = sizeof(old_nt_key),
+ };
+ uint8_t cek_data[16] = {0};
+ DATA_BLOB cek = {
+ .data = cek_data,
+ .length = sizeof(cek_data),
+ };
+ uint8_t pw_data[514] = {0};
+ DATA_BLOB plaintext = {
+ .data = pw_data,
+ .length = sizeof(pw_data),
+ };
+ DATA_BLOB ciphertext = data_blob_null;
+ struct samr_EncryptedPasswordAES pwd_buf = {.cipher_len = 0};
+ DATA_BLOB iv = {
+ .data = pwd_buf.salt,
+ .length = sizeof(pwd_buf.salt),
+ };
+ gnutls_datum_t iv_datum = {
+ .data = iv.data,
+ .size = iv.length,
+ };
+ uint64_t pbkdf2_iterations = generate_random_u64_range(5000, 1000000);
+ NTSTATUS status;
+ bool ok;
+ int rc;
+
+ torture_comment(tctx, "Testing ChangePasswordUser4\n");
+
+ if (newpassword == NULL) {
+ do {
+ if (policy_min_pw_len == 0) {
+ newpassword =
+ samr_rand_pass(tctx, policy_min_pw_len);
+ } else {
+ newpassword = samr_rand_pass_fixed_len(
+ tctx,
+ policy_min_pw_len);
+ }
+ } while (check_password_quality(newpassword) == false);
+ } else {
+ torture_comment(tctx, "Using password '%s'\n", newpassword);
+ }
+
+ torture_assert_not_null(tctx,
+ *password,
+ "Failing ChangePasswordUser4 as old password "
+ "was NULL. Previous test failed?");
+
+ srv_str = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
+ torture_assert_not_null(tctx, srv_str, "srvstr is NULL");
+ init_lsa_String(&server, srv_str);
+
+ init_lsa_String(&account, account_string);
+
+ E_md4hash(oldpassword, old_nt_key_data);
+
+ generate_nonce_buffer(iv.data, iv.length);
+
+ rc = gnutls_pbkdf2(GNUTLS_MAC_SHA512,
+ &old_nt_key,
+ &iv_datum,
+ pbkdf2_iterations,
+ cek.data,
+ cek.length);
+ torture_assert_int_equal(tctx, rc, 0, "gnutls_pbkdf2 failed");
+
+ ok = encode_pwd_buffer514_from_str(pw_data, newpassword, STR_UNICODE);
+ torture_assert(tctx, ok, "encode_aes_pw_buffer failed");
+
+ status = samba_gnutls_aead_aes_256_cbc_hmac_sha512_encrypt(
+ tctx,
+ &plaintext,
+ &cek,
+ &samr_aes256_enc_key_salt,
+ &samr_aes256_mac_key_salt,
+ &iv,
+ &ciphertext,
+ pwd_buf.auth_data);
+ torture_assert_ntstatus_ok(
+ tctx,
+ status,
+ "samba_gnutls_aead_aes_256_cbc_hmac_sha512_encrypt failed");
+
+ pwd_buf.cipher_len = ciphertext.length;
+ pwd_buf.cipher = ciphertext.data;
+ pwd_buf.PBKDF2Iterations = pbkdf2_iterations;
+
+ r.in.server = &server;
+ r.in.account = &account;
+ r.in.password = &pwd_buf;
+
+ status = dcerpc_samr_ChangePasswordUser4_r(b, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser4 failed");
+
+ *password = talloc_strdup(tctx, newpassword);
+#endif /* HAVE_GNUTLS_PBKDF2 */
+ return true;
+}
+
bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
const char *account_string,
struct policy_handle *handle,
@@ -6210,6 +6328,10 @@ static bool test_ChangePassword(struct dcerpc_pipe *p,
ret = false;
}
+ if (!test_ChangePasswordUser4(p, tctx, acct_name, 0, password, NULL)) {
+ ret = false;
+ }
+
return ret;
}