diff options
author | Andrew Bartlett <abartlet@samba.org> | 2004-09-04 00:02:43 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:58:32 -0500 |
commit | 26abe13ff7ed5cb3c58e6aef91a3a0632a4be3a9 (patch) | |
tree | f54158031e9669641f2ee42b686ac3d83bb4d559 | |
parent | f0ae80e18ceb937c2053f2c8cf56c62ab24fc54e (diff) | |
download | samba-26abe13ff7ed5cb3c58e6aef91a3a0632a4be3a9.tar.gz samba-26abe13ff7ed5cb3c58e6aef91a3a0632a4be3a9.tar.bz2 samba-26abe13ff7ed5cb3c58e6aef91a3a0632a4be3a9.zip |
r2220: Updates to the NETLOGON torture test. This copes with 'long'
passwords - where the LM hash is invalid.
Also, we now drive all the logon levels and validation levels from the
outer loop, so we can check the expected return values (rather than
overwriting them).
Andrew Bartlett
(This used to be commit f7f7c3de23ffb042f7cf7b4fa42b6b18c205719d)
-rw-r--r-- | source4/torture/rpc/netlogon.c | 271 |
1 files changed, 146 insertions, 125 deletions
diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index 5cb4caa942..fba39c14c9 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -296,131 +296,126 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state, { NTSTATUS status; struct netr_LogonSamLogon *r = &samlogon_state->r; - int levels[] = { 2, 6 }; - int i; struct netr_NetworkInfo ninfo; - for (i=0;i<ARRAY_SIZE(levels);i++) { - struct netr_SamBaseInfo *base; - - printf("testing netr_LogonSamLogon with logon level %d\n", levels[i]); - - samlogon_state->r.in.logon_level = levels[i]; - samlogon_state->r.in.logon.network = &ninfo; + struct netr_SamBaseInfo *base; + + printf("testing netr_LogonSamLogon\n"); - ninfo.identity_info.domain_name.string = samlogon_state->account_domain; - ninfo.identity_info.parameter_control = 0; - ninfo.identity_info.logon_id_low = 0; - ninfo.identity_info.logon_id_high = 0; - ninfo.identity_info.account_name.string = samlogon_state->account_name; - ninfo.identity_info.workstation.string = TEST_MACHINE_NAME; + samlogon_state->r.in.logon.network = &ninfo; + + ninfo.identity_info.domain_name.string = samlogon_state->account_domain; + ninfo.identity_info.parameter_control = 0; + ninfo.identity_info.logon_id_low = 0; + ninfo.identity_info.logon_id_high = 0; + ninfo.identity_info.account_name.string = samlogon_state->account_name; + ninfo.identity_info.workstation.string = TEST_MACHINE_NAME; - memcpy(ninfo.challenge, chall->data, 8); + memcpy(ninfo.challenge, chall->data, 8); - switch (break_which) { - case BREAK_NONE: - break; - case BREAK_LM: - if (lm_response && lm_response->data) { - lm_response->data[0]++; - } - break; - case BREAK_NT: - if (nt_response && nt_response->data) { - nt_response->data[0]++; - } - break; - case NO_LM: - data_blob_free(lm_response); - break; - case NO_NT: - data_blob_free(nt_response); - break; + switch (break_which) { + case BREAK_NONE: + break; + case BREAK_LM: + if (lm_response && lm_response->data) { + lm_response->data[0]++; } - - if (nt_response) { - ninfo.nt.data = nt_response->data; - ninfo.nt.length = nt_response->length; - } else { - ninfo.nt.data = NULL; - ninfo.nt.length = 0; + break; + case BREAK_NT: + if (nt_response && nt_response->data) { + nt_response->data[0]++; } + break; + case NO_LM: + data_blob_free(lm_response); + break; + case NO_NT: + data_blob_free(nt_response); + break; + } - if (lm_response) { - ninfo.lm.data = lm_response->data; - ninfo.lm.length = lm_response->length; - } else { - ninfo.lm.data = NULL; - ninfo.lm.length = 0; - } + if (nt_response) { + ninfo.nt.data = nt_response->data; + ninfo.nt.length = nt_response->length; + } else { + ninfo.nt.data = NULL; + ninfo.nt.length = 0; + } - ZERO_STRUCT(samlogon_state->auth2); - creds_client_authenticator(&samlogon_state->creds, &samlogon_state->auth); + if (lm_response) { + ninfo.lm.data = lm_response->data; + ninfo.lm.length = lm_response->length; + } else { + ninfo.lm.data = NULL; + ninfo.lm.length = 0; + } - r->out.return_authenticator = NULL; - status = dcerpc_netr_LogonSamLogon(samlogon_state->p, samlogon_state->mem_ctx, r); - if (!NT_STATUS_IS_OK(status)) { - if (error_string) { - *error_string = strdup(nt_errstr(status)); - } - } + ZERO_STRUCT(samlogon_state->auth2); + creds_client_authenticator(&samlogon_state->creds, &samlogon_state->auth); - if (!r->out.return_authenticator || - !creds_client_check(&samlogon_state->creds, &r->out.return_authenticator->cred)) { - printf("Credential chaining failed\n"); - } - - if (!NT_STATUS_IS_OK(status)) { - /* we cannot check the session key, if the logon failed... */ - return status; + r->out.return_authenticator = NULL; + status = dcerpc_netr_LogonSamLogon(samlogon_state->p, samlogon_state->mem_ctx, r); + if (!NT_STATUS_IS_OK(status)) { + if (error_string) { + *error_string = strdup(nt_errstr(status)); } + } - /* find and decyrpt the session keys, return in parameters above */ - if (r->in.validation_level == 2) { - base = &r->out.validation.sam2->base; - } else if (r->in.validation_level == 3) { - base = &r->out.validation.sam3->base; - } else if (r->in.validation_level == 6) { - base = &r->out.validation.sam6->base; - } else { - base = NULL; - } + if (!r->out.return_authenticator || + !creds_client_check(&samlogon_state->creds, &r->out.return_authenticator->cred)) { + printf("Credential chaining failed\n"); + } - if (r->in.validation_level != 6) { - static const char zeros[16]; + if (!NT_STATUS_IS_OK(status)) { + /* we cannot check the session key, if the logon failed... */ + return status; + } + + /* find and decyrpt the session keys, return in parameters above */ + if (r->in.validation_level == 2) { + base = &r->out.validation.sam2->base; + } else if (r->in.validation_level == 3) { + base = &r->out.validation.sam3->base; + } else if (r->in.validation_level == 6) { + base = &r->out.validation.sam6->base; + } else { + base = NULL; + } + + if (r->in.validation_level != 6) { + static const char zeros[16]; - if (memcmp(base->key.key, zeros, - sizeof(base->key.key)) != 0) { - creds_arcfour_crypt(&samlogon_state->creds, - base->key.key, - sizeof(base->key.key)); - } + if (memcmp(base->key.key, zeros, + sizeof(base->key.key)) != 0) { + creds_arcfour_crypt(&samlogon_state->creds, + base->key.key, + sizeof(base->key.key)); + } - if (user_session_key) { - memcpy(user_session_key, base->key.key, 16); - } + if (user_session_key) { + memcpy(user_session_key, base->key.key, 16); + } - if (memcmp(base->LMSessKey.key, zeros, - sizeof(base->LMSessKey.key)) != 0) { - creds_arcfour_crypt(&samlogon_state->creds, - base->LMSessKey.key, - sizeof(base->LMSessKey.key)); - } + if (memcmp(base->LMSessKey.key, zeros, + sizeof(base->LMSessKey.key)) != 0) { + creds_arcfour_crypt(&samlogon_state->creds, + base->LMSessKey.key, + sizeof(base->LMSessKey.key)); + } - if (lm_key) { - memcpy(lm_key, base->LMSessKey.key, 8); - } - } else { - /* they aren't encrypted! */ - if (user_session_key) { - memcpy(user_session_key, base->key.key, 16); - } - if (lm_key) { - memcpy(lm_key, base->LMSessKey.key, 8); - } + if (lm_key) { + memcpy(lm_key, base->LMSessKey.key, 8); + } + } else { + /* they aren't encrypted! */ + if (user_session_key) { + memcpy(user_session_key, base->key.key, 16); + } + if (lm_key) { + memcpy(lm_key, base->LMSessKey.key, 8); } } - + return status; } @@ -432,6 +427,7 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state, static BOOL test_lm_ntlm_broken(struct samlogon_state *samlogon_state, enum ntlm_break break_which, char **error_string) { BOOL pass = True; + BOOL lm_good; NTSTATUS nt_status; 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); @@ -445,9 +441,13 @@ static BOOL test_lm_ntlm_broken(struct samlogon_state *samlogon_state, enum ntlm ZERO_STRUCT(lm_key); ZERO_STRUCT(user_session_key); - SMBencrypt(samlogon_state->password, samlogon_state->chall.data, lm_response.data); - E_deshash(samlogon_state->password, lm_hash); - + lm_good = SMBencrypt(samlogon_state->password, samlogon_state->chall.data, lm_response.data); + if (samlogon_state->r.in.logon_level == 6 || !lm_good) { + ZERO_STRUCT(lm_hash); + } else { + 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); @@ -464,14 +464,27 @@ static BOOL test_lm_ntlm_broken(struct samlogon_state *samlogon_state, enum ntlm data_blob_free(&lm_response); - if (!NT_STATUS_IS_OK(nt_status)) { + if (NT_STATUS_EQUAL(NT_STATUS_WRONG_PASSWORD, nt_status)) { + /* for 'long' passwords, the LM password is invalid */ + if (break_which == NO_NT && !lm_good) { + return True; + } return break_which == BREAK_NT; } + if (!NT_STATUS_IS_OK(nt_status)) { + return False; + } + + if (break_which == NO_NT && !lm_good) { + printf("LM password is 'long' (> 14 chars and therefore invalid) but login did not fail!"); + return False; + } + if (memcmp(lm_hash, lm_key, sizeof(lm_key)) != 0) { printf("LM Key does not match expectations!\n"); - printf("lm_key:\n"); + printf("lm_key:\n"); dump_data(1, (const char *)lm_key, 8); printf("expected:\n"); dump_data(1, (const char *)lm_hash, 8); @@ -590,6 +603,7 @@ static BOOL test_ntlm_in_lm(struct samlogon_state *samlogon_state, char **error_ static BOOL test_ntlm_in_both(struct samlogon_state *samlogon_state, char **error_string) { BOOL pass = True; + BOOL lm_good; 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); @@ -608,7 +622,10 @@ static BOOL test_ntlm_in_both(struct samlogon_state *samlogon_state, char **erro SMBsesskeygen_ntv1((const uint8_t *)nt_hash, session_key.data); - E_deshash(samlogon_state->password, (uint8_t *)lm_hash); + lm_good = E_deshash(samlogon_state->password, (uint8_t *)lm_hash); + if (!lm_good) { + ZERO_STRUCT(lm_hash); + } nt_status = check_samlogon(samlogon_state, BREAK_NONE, @@ -882,9 +899,10 @@ static const struct ntlm_tests { */ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) { - int i, j; + int i, v, l; BOOL ret = True; int validation_levels[] = {2,3,6}; + int logon_levels[] = { 2, 6 }; struct samlogon_state samlogon_state; samlogon_state.mem_ctx = mem_ctx; @@ -914,21 +932,24 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) samlogon_state.r.in.credential = &samlogon_state.auth; samlogon_state.r.in.return_authenticator = &samlogon_state.auth2; - for (i=0;i<ARRAY_SIZE(validation_levels);i++) { - samlogon_state.r.in.validation_level = validation_levels[i]; - for (j=0; test_table[j].fn; j++) { - char *error_string = NULL; - printf("Testing SamLogon with '%s' at validation level %d\n", - test_table[j].name, validation_levels[i]); + for (i=0; test_table[i].fn; i++) { + for (v=0;v<ARRAY_SIZE(validation_levels);v++) { + for (l=0;l<ARRAY_SIZE(logon_levels);l++) { + char *error_string = NULL; + samlogon_state.r.in.validation_level = validation_levels[v]; + samlogon_state.r.in.logon_level = logon_levels[l]; + printf("Testing SamLogon with '%s' at validation level %d, logon level %d\n", + test_table[i].name, validation_levels[v], logon_levels[l]); - if (!test_table[j].fn(&samlogon_state, &error_string)) { - if (test_table[j].expect_fail) { - printf("Test %s failed (expected, test incomplete): %s\n", test_table[j].name, error_string); - } else { - printf("Test %s failed: %s\n", test_table[j].name, error_string); - ret = False; + if (!test_table[i].fn(&samlogon_state, &error_string)) { + if (test_table[i].expect_fail) { + printf("Test %s failed (expected, test incomplete): %s\n", test_table[i].name, error_string); + } else { + printf("Test %s failed: %s\n", test_table[i].name, error_string); + ret = False; + } + SAFE_FREE(error_string); } - SAFE_FREE(error_string); } } } |