From c8bec9dd3afac052cf78de281067ff57e256017d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 4 Oct 2005 01:02:06 +0000 Subject: r10703: Add a new user account, change the password and test it in the SAMLOGON test. The semantics for the user account are very odd, the old password is still valid, but the session keys appear to be blanked out. Andrew Bartlett (This used to be commit bbfaf4821d81116efa91313655acb75d6f577953) --- source4/torture/rpc/samlogon.c | 159 ++++++++++++++++++++++++++++++++--------- source4/torture/rpc/samr.c | 20 +++--- 2 files changed, 135 insertions(+), 44 deletions(-) (limited to 'source4/torture/rpc') diff --git a/source4/torture/rpc/samlogon.c b/source4/torture/rpc/samlogon.c index 00b3c56408..70da9b935a 100644 --- a/source4/torture/rpc/samlogon.c +++ b/source4/torture/rpc/samlogon.c @@ -42,6 +42,7 @@ enum ntlm_break { struct samlogon_state { TALLOC_CTX *mem_ctx; + const char *comment; const char *account_name; const char *account_domain; const char *password; @@ -416,20 +417,30 @@ static BOOL test_ntlm(struct samlogon_state *samlogon_state, char **error_string static BOOL test_ntlm_in_lm(struct samlogon_state *samlogon_state, char **error_string) { + BOOL lm_good; BOOL pass = True; NTSTATUS nt_status; DATA_BLOB nt_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24); + DATA_BLOB session_key = data_blob_talloc(samlogon_state->mem_ctx, NULL, 16); uint8_t lm_key[8]; uint8_t lm_hash[16]; uint8_t user_session_key[16]; + uint8_t nt_hash[16]; + ZERO_STRUCT(lm_key); ZERO_STRUCT(user_session_key); - SMBNTencrypt(samlogon_state->password, samlogon_state->chall.data, nt_response.data); - - E_deshash(samlogon_state->password, lm_hash); + SMBNTencrypt(samlogon_state->password, samlogon_state->chall.data, + nt_response.data); + E_md4hash(samlogon_state->password, nt_hash); + SMBsesskeygen_ntv1(nt_hash, + session_key.data); + lm_good = E_deshash(samlogon_state->password, lm_hash); + if (!lm_good) { + ZERO_STRUCT(lm_hash); + } nt_status = check_samlogon(samlogon_state, BREAK_NONE, &samlogon_state->chall, @@ -449,14 +460,26 @@ static BOOL test_ntlm_in_lm(struct samlogon_state *samlogon_state, char **error_ return False; } - if (memcmp(lm_hash, lm_key, - sizeof(lm_key)) != 0) { - printf("LM Key does not match expectations!\n"); - printf("lm_key:\n"); - dump_data(1, lm_key, 8); - printf("expected:\n"); - dump_data(1, lm_hash, 8); - pass = False; + if (lm_good) { + if (memcmp(lm_hash, lm_key, + sizeof(lm_key)) != 0) { + printf("LM Key does not match expectations!\n"); + printf("lm_key:\n"); + dump_data(1, lm_key, 8); + printf("expected:\n"); + dump_data(1, lm_hash, 8); + pass = False; + } + } else { + if (memcmp(session_key.data, lm_key, + sizeof(lm_key)) != 0) { + printf("LM Key does not match expectations (first 8 session key)!\n"); + printf("lm_key:\n"); + dump_data(1, lm_key, 8); + printf("expected:\n"); + dump_data(1, session_key.data, 8); + pass = False; + } } if (memcmp(lm_hash, user_session_key, 8) != 0) { uint8_t lm_key_expected[16]; @@ -646,7 +669,7 @@ static BOOL test_lmv2_ntlmv2_broken(struct samlogon_state *samlogon_state, pass = False; } if (memcmp(lmv2_session_key.data, lm_session_key, - sizeof(lm_session_key)) != 0) { + sizeof(lm_session_key)) != 0) { printf("LM (LMv2) Session Key does not match expectations!\n"); printf("lm_session_key:\n"); dump_data(1, lm_session_key, 8); @@ -720,6 +743,7 @@ static BOOL test_lmv2_ntlm_broken(struct samlogon_state *samlogon_state, DATA_BLOB ntlm_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24); DATA_BLOB ntlm_session_key = data_blob_talloc(samlogon_state->mem_ctx, NULL, 16); + BOOL lm_good; uint8_t lm_hash[16]; uint8_t lm_session_key[8]; uint8_t user_session_key[16]; @@ -730,7 +754,11 @@ static BOOL test_lmv2_ntlm_broken(struct samlogon_state *samlogon_state, E_md4hash(samlogon_state->password, nt_hash); SMBsesskeygen_ntv1(nt_hash, ntlm_session_key.data); - E_deshash(samlogon_state->password, lm_hash); + + lm_good = E_deshash(samlogon_state->password, lm_hash); + if (!lm_good) { + ZERO_STRUCT(lm_hash); + } ZERO_STRUCT(lm_session_key); ZERO_STRUCT(user_session_key); @@ -822,14 +850,27 @@ static BOOL test_lmv2_ntlm_broken(struct samlogon_state *samlogon_state, dump_data(1, ntlm_session_key.data, ntlm_session_key.length); pass = False; } - if (memcmp(lm_hash, lm_session_key, - sizeof(lm_session_key)) != 0) { - printf("LM Session Key does not match expectations!\n"); - printf("lm_session_key:\n"); - dump_data(1, lm_session_key, 8); - printf("expected:\n"); - dump_data(1, lm_hash, 8); - pass = False; + if (lm_good) { + if (memcmp(lm_hash, lm_session_key, + sizeof(lm_session_key)) != 0) { + printf("LM Session Key does not match expectations!\n"); + printf("lm_session_key:\n"); + dump_data(1, lm_session_key, 8); + printf("expected:\n"); + dump_data(1, lm_hash, 8); + pass = False; + } + } else { + static const char zeros[8]; + if (memcmp(zeros, lm_session_key, + sizeof(lm_session_key)) != 0) { + printf("LM Session Key does not match expectations (zeros)!\n"); + printf("lm_session_key:\n"); + dump_data(1, lm_session_key, 8); + printf("expected:\n"); + dump_data(1, zeros, 8); + pass = False; + } } break; default: @@ -996,6 +1037,7 @@ static BOOL test_ntlm2(struct samlogon_state *samlogon_state, char **error_strin DATA_BLOB lm_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24); DATA_BLOB nt_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24); + BOOL lm_good; uint8_t lm_key[8]; uint8_t nt_hash[16]; uint8_t lm_hash[16]; @@ -1018,7 +1060,7 @@ static BOOL test_ntlm2(struct samlogon_state *samlogon_state, char **error_strin MD5Final(session_nonce_hash, &md5_session_nonce_ctx); E_md4hash(samlogon_state->password, (uint8_t *)nt_hash); - E_deshash(samlogon_state->password, (uint8_t *)lm_hash); + lm_good = E_deshash(samlogon_state->password, (uint8_t *)lm_hash); SMBsesskeygen_ntv1((const uint8_t *)nt_hash, nt_key); @@ -1051,17 +1093,30 @@ static BOOL test_ntlm2(struct samlogon_state *samlogon_state, char **error_strin return False; } - if (memcmp(lm_hash, lm_key, - sizeof(lm_key)) != 0) { - printf("LM Key does not match expectations!\n"); - printf("lm_key:\n"); - dump_data(1, lm_key, 8); - printf("expected:\n"); - dump_data(1, lm_hash, 8); - pass = False; + if (lm_good) { + if (memcmp(lm_hash, lm_key, + sizeof(lm_key)) != 0) { + printf("LM Key does not match expectations!\n"); + printf("lm_key:\n"); + dump_data(1, lm_key, 8); + printf("expected:\n"); + dump_data(1, lm_hash, 8); + pass = False; + } + } else { + static const char zeros[8]; + if (memcmp(zeros, lm_key, + sizeof(lm_key)) != 0) { + printf("LM Session Key does not match expectations (zeros)!\n"); + printf("lm_key:\n"); + dump_data(1, lm_key, 8); + printf("expected:\n"); + dump_data(1, zeros, 8); + pass = False; + } } if (memcmp(nt_key, user_session_key, 16) != 0) { - printf("NT Session Key does not match expectations (should be first-8 LM hash)!\n"); + printf("NT Session Key does not match expectations (should be NT Key)!\n"); printf("user_session_key:\n"); dump_data(1, user_session_key, sizeof(user_session_key)); printf("expected:\n"); @@ -1215,6 +1270,7 @@ static const struct ntlm_tests { */ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct creds_CredentialState *creds, + const char *comment, const char *account_domain, const char *account_name, const char *plain_pass, NTSTATUS expected_error, int n_subtests) @@ -1232,6 +1288,7 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, printf("testing netr_LogonSamLogon and netr_LogonSamLogonWithFlags\n"); + samlogon_state.comment = comment; samlogon_state.account_name = account_name; samlogon_state.account_domain = account_domain; samlogon_state.password = plain_pass; @@ -1274,7 +1331,8 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, samlogon_state.r_flags.in.validation_level = validation_levels[v]; samlogon_state.r_flags.in.logon_level = logon_levels[l]; if (!test_table[i].fn(&samlogon_state, &error_string)) { - printf("Testing [%s]\\[%s] '%s' at validation level %d, logon level %d, function %d: \n", + printf("Testing '%s' [%s]\\[%s] '%s' at validation level %d, logon level %d, function %d: \n", + samlogon_state.comment, samlogon_state.account_domain, samlogon_state.account_name, test_table[i].name, validation_levels[v], @@ -1302,6 +1360,7 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, */ BOOL test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct creds_CredentialState *creds, + const char *comment, const char *workstation_name, const char *account_domain, const char *account_name, const char *plain_pass, NTSTATUS expected_error) @@ -1347,7 +1406,7 @@ BOOL test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, creds_des_encrypt(creds, &pinfo.ntpassword); } - printf("Testing netr_LogonSamLogonWithFlags (Interactive Logon)\n"); + printf("Testing netr_LogonSamLogonWithFlags '%s' (Interactive Logon)\n", comment); status = dcerpc_netr_LogonSamLogonWithFlags(p, fn_ctx, &r); if (!r.out.return_authenticator @@ -1381,6 +1440,7 @@ BOOL torture_rpc_samlogon(void) struct test_join *join_ctx; struct test_join *user_ctx; const char *user_password; + const char *old_user_password; char *test_machine_account; const char *binding = lp_parm_string(-1, "torture", "binding"); const char *userdomain; @@ -1422,6 +1482,11 @@ BOOL torture_rpc_samlogon(void) return False; } + old_user_password = user_password; + + test_ChangePasswordUser3(torture_join_samr_pipe(user_ctx), mem_ctx, + TEST_USER_NAME, 16 /* > 14 */, &user_password); + status = dcerpc_parse_binding(mem_ctx, binding, &b); if (!NT_STATUS_IS_OK(status)) { printf("Bad binding string %s\n", binding); @@ -1455,6 +1520,7 @@ BOOL torture_rpc_samlogon(void) { struct { + const char *comment; const char *domain; const char *username; const char *password; @@ -1463,6 +1529,7 @@ BOOL torture_rpc_samlogon(void) NTSTATUS expected_network_error; } usercreds[] = { { + "domain\\user", cli_credentials_get_domain(cmdline_credentials), cli_credentials_get_username(cmdline_credentials), cli_credentials_get_password(cmdline_credentials), @@ -1471,6 +1538,7 @@ BOOL torture_rpc_samlogon(void) NT_STATUS_OK }, { + "realm\\user", cli_credentials_get_realm(cmdline_credentials), cli_credentials_get_username(cmdline_credentials), cli_credentials_get_password(cmdline_credentials), @@ -1479,6 +1547,7 @@ BOOL torture_rpc_samlogon(void) NT_STATUS_OK }, { + "user@domain", NULL, talloc_asprintf(mem_ctx, "%s@%s", @@ -1491,6 +1560,7 @@ BOOL torture_rpc_samlogon(void) NT_STATUS_OK }, { + "user@realm", NULL, talloc_asprintf(mem_ctx, "%s@%s", @@ -1503,6 +1573,7 @@ BOOL torture_rpc_samlogon(void) NT_STATUS_OK }, { + "machine domain\\user", cli_credentials_get_domain(machine_credentials), cli_credentials_get_username(machine_credentials), cli_credentials_get_password(machine_credentials), @@ -1511,6 +1582,7 @@ BOOL torture_rpc_samlogon(void) NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT }, { + "machine realm\\user", cli_credentials_get_realm(machine_credentials), cli_credentials_get_username(machine_credentials), cli_credentials_get_password(machine_credentials), @@ -1519,6 +1591,7 @@ BOOL torture_rpc_samlogon(void) NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT }, { + "machine user@domain", NULL, talloc_asprintf(mem_ctx, "%s@%s", @@ -1531,6 +1604,7 @@ BOOL torture_rpc_samlogon(void) NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT }, { + "machine user@realm", NULL, talloc_asprintf(mem_ctx, "%s@%s", @@ -1543,6 +1617,7 @@ BOOL torture_rpc_samlogon(void) NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT }, { + "test user (long pw): domain\\user", userdomain, TEST_USER_NAME, user_password, @@ -1551,6 +1626,7 @@ BOOL torture_rpc_samlogon(void) NT_STATUS_OK }, { + "test user (long pw): user@realm", NULL, talloc_asprintf(mem_ctx, "%s@%s", @@ -1562,6 +1638,7 @@ BOOL torture_rpc_samlogon(void) NT_STATUS_OK }, { + "test user (long pw): user@domain", NULL, talloc_asprintf(mem_ctx, "%s@%s", @@ -1571,6 +1648,16 @@ BOOL torture_rpc_samlogon(void) False, NT_STATUS_OK, NT_STATUS_OK + }, + /* Oddball, can we use the old password ? */ + { + "test user: user\\domain OLD PASSWORD", + userdomain, + TEST_USER_NAME, + old_user_password, + True, + NT_STATUS_WRONG_PASSWORD, + NT_STATUS_OK } }; @@ -1578,6 +1665,7 @@ BOOL torture_rpc_samlogon(void) for (ci = 0; ci < ARRAY_SIZE(usercreds); ci++) { if (!test_InteractiveLogon(p, mem_ctx, creds, + usercreds[ci].comment, TEST_MACHINE_NAME, usercreds[ci].domain, usercreds[ci].username, @@ -1588,6 +1676,7 @@ BOOL torture_rpc_samlogon(void) if (usercreds[ci].network_login) { if (!test_SamLogon(p, mem_ctx, creds, + usercreds[ci].comment, usercreds[ci].domain, usercreds[ci].username, usercreds[ci].password, @@ -1604,6 +1693,7 @@ BOOL torture_rpc_samlogon(void) for (i=0; i < ARRAY_SIZE(credential_flags); i++) { if (!test_InteractiveLogon(p, mem_ctx, creds, + usercreds[0].comment, TEST_MACHINE_NAME, usercreds[0].domain, usercreds[0].username, @@ -1613,7 +1703,8 @@ BOOL torture_rpc_samlogon(void) } if (usercreds[ci].network_login) { - if (!test_SamLogon(p, mem_ctx, creds, + if (!test_SamLogon(p, mem_ctx, creds, + usercreds[0].comment, usercreds[0].domain, usercreds[0].username, usercreds[0].password, diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index 7b06c854b0..3344699c2b 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -1082,10 +1082,10 @@ static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, } -static BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, - struct policy_handle *handle, - int policy_min_pw_len, - char **password) +BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, + const char *account_string, + int policy_min_pw_len, + char **password) { NTSTATUS status; struct samr_ChangePasswordUser3 r; @@ -1101,7 +1101,7 @@ static BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, printf("Testing ChangePasswordUser3\n"); server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p)); - init_lsa_String(&account, TEST_ACCOUNT_NAME); + init_lsa_String(&account, account_string); E_md4hash(oldpass, old_nt_hash); E_md4hash(newpass, new_nt_hash); @@ -1133,7 +1133,7 @@ static BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, policy_min_pw_len = r.out.dominfo->min_password_length; } if (policy_min_pw_len) /* try again with the right min password length */ { - ret = test_ChangePasswordUser3(p, mem_ctx, handle, policy_min_pw_len, password); + ret = test_ChangePasswordUser3(p, mem_ctx, account_string, policy_min_pw_len, password); } else { printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status)); ret = False; @@ -1546,11 +1546,11 @@ static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, /* we change passwords twice - this has the effect of verifying they were changed correctly for the final call */ - if (!test_ChangePasswordUser3(p, mem_ctx, domain_handle, 0, password)) { + if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) { ret = False; } - if (!test_ChangePasswordUser3(p, mem_ctx, domain_handle, 0, password)) { + if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) { ret = False; } @@ -1645,7 +1645,7 @@ static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, } /* check it was set right */ - if (!test_ChangePasswordUser3(p, user_ctx, domain_handle, 0, &password)) { + if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) { ret = False; } } @@ -1656,7 +1656,7 @@ static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, } /* check it was set right */ - if (!test_ChangePasswordUser3(p, user_ctx, domain_handle, 0, &password)) { + if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) { ret = False; } } -- cgit