summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/torture/rpc/samr.c165
1 files changed, 149 insertions, 16 deletions
diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c
index e76599b3e4..0367cc4dc8 100644
--- a/source4/torture/rpc/samr.c
+++ b/source4/torture/rpc/samr.c
@@ -1034,6 +1034,7 @@ static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
char *oldpass;
uint8_t old_nt_hash[16], new_nt_hash[16];
uint8_t old_lm_hash[16], new_lm_hash[16];
+ BOOL changed = True;
char *newpass;
struct samr_GetUserPwInfo pwp;
@@ -1081,6 +1082,43 @@ static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.new_nt_crypted = &hash4;
r.in.cross1_present = 1;
r.in.nt_cross = &hash5;
+ r.in.cross2_present = 0;
+ r.in.lm_cross = NULL;
+
+ status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED)) {
+ printf("ChangePasswordUser failed: expected NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
+ ret = False;
+ }
+
+
+ r.in.user_handle = &user_handle;
+ r.in.lm_present = 1;
+ r.in.old_lm_crypted = &hash1;
+ r.in.new_lm_crypted = &hash2;
+ r.in.nt_present = 1;
+ r.in.old_nt_crypted = &hash3;
+ r.in.new_nt_crypted = &hash4;
+ r.in.cross1_present = 0;
+ r.in.nt_cross = NULL;
+ r.in.cross2_present = 1;
+ r.in.lm_cross = &hash6;
+
+ status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED)) {
+ printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
+ ret = False;
+ }
+
+ r.in.user_handle = &user_handle;
+ r.in.lm_present = 1;
+ r.in.old_lm_crypted = &hash1;
+ r.in.new_lm_crypted = &hash2;
+ r.in.nt_present = 1;
+ r.in.old_nt_crypted = &hash3;
+ r.in.new_nt_crypted = &hash4;
+ r.in.cross1_present = 1;
+ r.in.nt_cross = &hash5;
r.in.cross2_present = 1;
r.in.lm_cross = &hash6;
@@ -1091,9 +1129,30 @@ static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
ret = False;
} else {
+ changed = True;
*password = newpass;
}
+ r.in.user_handle = &user_handle;
+ r.in.lm_present = 1;
+ r.in.old_lm_crypted = &hash1;
+ r.in.new_lm_crypted = &hash2;
+ r.in.nt_present = 1;
+ r.in.old_nt_crypted = &hash3;
+ r.in.new_nt_crypted = &hash4;
+ r.in.cross1_present = 1;
+ r.in.nt_cross = &hash5;
+ r.in.cross2_present = 1;
+ r.in.lm_cross = &hash6;
+
+ if (changed) {
+ status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
+ printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
+ ret = False;
+ }
+ }
+
if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
ret = False;
}
@@ -1167,6 +1226,45 @@ static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_c
ret = False;
}
+ encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
+ /* Break the old password */
+ old_lm_hash[0]++;
+ arcfour_crypt(lm_pass.data, old_lm_hash, 516);
+ /* unbreak it for the next operation */
+ old_lm_hash[0]--;
+ E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
+
+ r.in.server = &server;
+ r.in.account = &account;
+ r.in.password = &lm_pass;
+ r.in.hash = &lm_verifier;
+
+ status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
+
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
+ && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
+ printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
+ nt_errstr(status));
+ ret = False;
+ }
+
+ encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
+ arcfour_crypt(lm_pass.data, old_lm_hash, 516);
+
+ r.in.server = &server;
+ r.in.account = &account;
+ r.in.password = &lm_pass;
+ r.in.hash = NULL;
+
+ status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
+
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
+ && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
+ printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
+ nt_errstr(status));
+ ret = False;
+ }
+
/* This shouldn't be a valid name */
account_bad.string = TEST_ACCOUNT_NAME "XX";
r.in.account = &account_bad;
@@ -1305,11 +1403,13 @@ BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
printf("Testing ChangePasswordUser3\n");
if (newpass == NULL) {
- if (policy_min_pw_len == 0) {
- newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
- } else {
- newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len);
- }
+ do {
+ if (policy_min_pw_len == 0) {
+ newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
+ } else {
+ newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len);
+ }
+ } while (check_password_quality(newpass) == False);
} else {
printf("Using password '%s'\n", newpass);
}
@@ -1357,6 +1457,35 @@ BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
ret = False;
}
+ encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
+ arcfour_crypt(lm_pass.data, old_nt_hash, 516);
+ E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
+
+ encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
+ /* Break the NT hash */
+ old_nt_hash[0]++;
+ arcfour_crypt(nt_pass.data, old_nt_hash, 516);
+ /* Unbreak it again */
+ old_nt_hash[0]--;
+ E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
+
+ r.in.server = &server;
+ r.in.account = &account;
+ r.in.nt_password = &nt_pass;
+ r.in.nt_verifier = &nt_verifier;
+ r.in.lm_change = 1;
+ r.in.lm_password = &lm_pass;
+ r.in.lm_verifier = &lm_verifier;
+ r.in.password3 = NULL;
+
+ status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
+ (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
+ printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
+ nt_errstr(status));
+ ret = False;
+ }
+
/* This shouldn't be a valid name */
init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
@@ -1434,14 +1563,6 @@ BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return False;
}
- } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
-
- if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
- printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
- SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
- return False;
- }
-
} else if ((r.out.dominfo->password_history_length > 0) &&
strequal(oldpass, newpass)) {
@@ -1450,6 +1571,14 @@ BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
return False;
}
+ } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
+
+ if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
+ printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
+ SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
+ return False;
+ }
+
}
if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
@@ -1970,9 +2099,10 @@ static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct samr_QueryDomainInfo r;
struct samr_SetDomainInfo s;
uint16_t len_old, len;
+ uint32_t pwd_prop_old;
NTSTATUS status;
- len = 3;
+ len = 5;
r.in.domain_handle = domain_handle;
r.in.level = 1;
@@ -1987,8 +2117,12 @@ static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
s.in.level = 1;
s.in.info = r.out.info;
+ /* remember the old min length, so we can reset it */
len_old = s.in.info->info1.min_password_length;
s.in.info->info1.min_password_length = len;
+ pwd_prop_old = s.in.info->info1.password_properties;
+ /* turn off password complexity checks for this test */
+ s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
printf("testing samr_SetDomainInfo level 1\n");
status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
@@ -2003,6 +2137,7 @@ static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
}
s.in.info->info1.min_password_length = len_old;
+ s.in.info->info1.password_properties = pwd_prop_old;
printf("testing samr_SetDomainInfo level 1\n");
status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
@@ -2058,8 +2193,6 @@ static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
}
}
- return True;
-
/* we change passwords twice - this has the effect of verifying
they were changed correctly for the final call */
if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {