summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2007-03-06 05:30:25 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:49:17 -0500
commit3e1dd63927b6d50aa21f32ffaa41b320026be6a1 (patch)
tree297f900eaf4f03a4bb796fc28d68089f9967a3d3
parentac9bb2e4fbb3a2aa483b8f24359250278411e013 (diff)
downloadsamba-3e1dd63927b6d50aa21f32ffaa41b320026be6a1.tar.gz
samba-3e1dd63927b6d50aa21f32ffaa41b320026be6a1.tar.bz2
samba-3e1dd63927b6d50aa21f32ffaa41b320026be6a1.zip
r21719: Try to cover more of the server-side password processing.
Don't just exit the test with 'return True', actually process the result. Turn off password complexity checking for the password length test. Andrew Bartlett (This used to be commit 1a7635baa701c6268eebd84dd0dc187379c44e6e)
-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)) {