summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/torture/rpc/samlogon.c159
-rw-r--r--source4/torture/rpc/samr.c20
2 files changed, 135 insertions, 44 deletions
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;
}
}