2 Unix SMB/CIFS implementation.
4 test suite for netlogon SamLogon operations
6 Copyright (C) Andrew Tridgell 2003
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2004
8 Copyright (C) Tim Potter 2003
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include "librpc/gen_ndr/ndr_netlogon.h"
27 #include "auth/auth.h"
28 #include "lib/crypto/crypto.h"
29 #include "lib/cmdline/popt_common.h"
31 #define TEST_MACHINE_NAME "samlogontest"
32 #define TEST_USER_NAME "samlogontestuser"
43 struct samlogon_state {
46 const char *account_name;
47 const char *account_domain;
49 struct dcerpc_pipe *p;
51 struct netr_LogonSamLogon r;
52 struct netr_LogonSamLogonEx r_ex;
53 struct netr_LogonSamLogonWithFlags r_flags;
54 struct netr_Authenticator auth, auth2;
55 struct creds_CredentialState *creds;
56 NTSTATUS expected_error;
61 Authenticate a user with a challenge/response, checking session key
62 and valid authentication types
64 static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state,
65 enum ntlm_break break_which,
67 DATA_BLOB *lm_response,
68 DATA_BLOB *nt_response,
70 uint8_t user_session_key[16],
74 struct netr_LogonSamLogon *r = &samlogon_state->r;
75 struct netr_LogonSamLogonEx *r_ex = &samlogon_state->r_ex;
76 struct netr_LogonSamLogonWithFlags *r_flags = &samlogon_state->r_flags;
77 struct netr_NetworkInfo ninfo;
78 struct netr_SamBaseInfo *base = NULL;
79 uint16_t validation_level = 0;
81 samlogon_state->r.in.logon.network = &ninfo;
82 samlogon_state->r_ex.in.logon.network = &ninfo;
83 samlogon_state->r_flags.in.logon.network = &ninfo;
85 ninfo.identity_info.domain_name.string = samlogon_state->account_domain;
86 ninfo.identity_info.parameter_control = 0;
87 ninfo.identity_info.logon_id_low = 0;
88 ninfo.identity_info.logon_id_high = 0;
89 ninfo.identity_info.account_name.string = samlogon_state->account_name;
90 ninfo.identity_info.workstation.string = TEST_MACHINE_NAME;
92 memcpy(ninfo.challenge, chall->data, 8);
94 switch (break_which) {
98 if (lm_response && lm_response->data) {
99 lm_response->data[0]++;
103 if (nt_response && nt_response->data) {
104 nt_response->data[0]++;
108 if (lm_response && lm_response->data) {
109 lm_response->data[0]++;
111 if (nt_response && nt_response->data) {
112 nt_response->data[0]++;
116 data_blob_free(lm_response);
119 data_blob_free(nt_response);
124 ninfo.nt.data = nt_response->data;
125 ninfo.nt.length = nt_response->length;
127 ninfo.nt.data = NULL;
132 ninfo.lm.data = lm_response->data;
133 ninfo.lm.length = lm_response->length;
135 ninfo.lm.data = NULL;
139 switch (samlogon_state->function_level) {
140 case DCERPC_NETR_LOGONSAMLOGON:
141 ZERO_STRUCT(samlogon_state->auth2);
142 creds_client_authenticator(samlogon_state->creds, &samlogon_state->auth);
144 r->out.return_authenticator = NULL;
145 status = dcerpc_netr_LogonSamLogon(samlogon_state->p, samlogon_state->mem_ctx, r);
146 if (!r->out.return_authenticator ||
147 !creds_client_check(samlogon_state->creds, &r->out.return_authenticator->cred)) {
148 printf("Credential chaining failed\n");
150 if (!NT_STATUS_IS_OK(status)) {
152 *error_string = strdup(nt_errstr(status));
157 validation_level = r->in.validation_level;
159 creds_decrypt_samlogon(samlogon_state->creds, validation_level, &r->out.validation);
161 switch (validation_level) {
163 base = &r->out.validation.sam2->base;
166 base = &r->out.validation.sam3->base;
169 base = &r->out.validation.sam6->base;
173 case DCERPC_NETR_LOGONSAMLOGONEX:
174 status = dcerpc_netr_LogonSamLogonEx(samlogon_state->p, samlogon_state->mem_ctx, r_ex);
175 if (!NT_STATUS_IS_OK(status)) {
177 *error_string = strdup(nt_errstr(status));
182 validation_level = r_ex->in.validation_level;
184 creds_decrypt_samlogon(samlogon_state->creds, validation_level, &r_ex->out.validation);
186 switch (validation_level) {
188 base = &r_ex->out.validation.sam2->base;
191 base = &r_ex->out.validation.sam3->base;
194 base = &r_ex->out.validation.sam6->base;
198 case DCERPC_NETR_LOGONSAMLOGONWITHFLAGS:
199 ZERO_STRUCT(samlogon_state->auth2);
200 creds_client_authenticator(samlogon_state->creds, &samlogon_state->auth);
202 r_flags->out.return_authenticator = NULL;
203 status = dcerpc_netr_LogonSamLogonWithFlags(samlogon_state->p, samlogon_state->mem_ctx, r_flags);
204 if (!r_flags->out.return_authenticator ||
205 !creds_client_check(samlogon_state->creds, &r_flags->out.return_authenticator->cred)) {
206 printf("Credential chaining failed\n");
208 if (!NT_STATUS_IS_OK(status)) {
210 *error_string = strdup(nt_errstr(status));
215 validation_level = r_flags->in.validation_level;
217 creds_decrypt_samlogon(samlogon_state->creds, validation_level, &r_flags->out.validation);
219 switch (validation_level) {
221 base = &r_flags->out.validation.sam2->base;
224 base = &r_flags->out.validation.sam3->base;
227 base = &r_flags->out.validation.sam6->base;
234 printf("No user info returned from 'successful' SamLogon*() call!\n");
235 return NT_STATUS_INVALID_PARAMETER;
238 if (user_session_key) {
239 memcpy(user_session_key, base->key.key, 16);
242 memcpy(lm_key, base->LMSessKey.key, 8);
250 * Test the normal 'LM and NTLM' combination
253 static BOOL test_lm_ntlm_broken(struct samlogon_state *samlogon_state, enum ntlm_break break_which, char **error_string)
258 DATA_BLOB lm_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);
259 DATA_BLOB nt_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);
260 DATA_BLOB session_key = data_blob_talloc(samlogon_state->mem_ctx, NULL, 16);
263 uint8_t user_session_key[16];
268 ZERO_STRUCT(user_session_key);
270 lm_good = SMBencrypt(samlogon_state->password, samlogon_state->chall.data, lm_response.data);
272 ZERO_STRUCT(lm_hash);
274 E_deshash(samlogon_state->password, lm_hash);
277 SMBNTencrypt(samlogon_state->password, samlogon_state->chall.data, nt_response.data);
279 E_md4hash(samlogon_state->password, nt_hash);
280 SMBsesskeygen_ntv1(nt_hash, session_key.data);
282 nt_status = check_samlogon(samlogon_state,
284 &samlogon_state->chall,
291 data_blob_free(&lm_response);
293 if (NT_STATUS_EQUAL(NT_STATUS_WRONG_PASSWORD, nt_status)) {
294 /* for 'long' passwords, the LM password is invalid */
295 if (break_which == NO_NT && !lm_good) {
298 return ((break_which == BREAK_NT) || (break_which == BREAK_BOTH));
301 if (!NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status)) {
302 SAFE_FREE(*error_string);
303 asprintf(error_string, "Expected error: %s, got %s", nt_errstr(samlogon_state->expected_error), nt_errstr(nt_status));
305 } else if (NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status) && !NT_STATUS_IS_OK(nt_status)) {
307 } else if (!NT_STATUS_IS_OK(nt_status)) {
311 if (break_which == NO_NT && !lm_good) {
312 *error_string = strdup("LM password is 'long' (> 14 chars and therefore invalid) but login did not fail!");
316 if (memcmp(lm_hash, lm_key,
317 sizeof(lm_key)) != 0) {
318 printf("LM Key does not match expectations!\n");
320 dump_data(1, lm_key, 8);
321 printf("expected:\n");
322 dump_data(1, lm_hash, 8);
326 switch (break_which) {
329 uint8_t lm_key_expected[16];
330 memcpy(lm_key_expected, lm_hash, 8);
331 memset(lm_key_expected+8, '\0', 8);
332 if (memcmp(lm_key_expected, user_session_key,
334 *error_string = strdup("NT Session Key does not match expectations (should be first-8 LM hash)!\n");
335 printf("user_session_key:\n");
336 dump_data(1, user_session_key, sizeof(user_session_key));
337 printf("expected:\n");
338 dump_data(1, lm_key_expected, sizeof(lm_key_expected));
344 if (memcmp(session_key.data, user_session_key,
345 sizeof(user_session_key)) != 0) {
346 *error_string = strdup("NT Session Key does not match expectations!\n");
347 printf("user_session_key:\n");
348 dump_data(1, user_session_key, 16);
349 printf("expected:\n");
350 dump_data(1, session_key.data, session_key.length);
358 * Test LM authentication, no NT response supplied
361 static BOOL test_lm(struct samlogon_state *samlogon_state, char **error_string)
364 return test_lm_ntlm_broken(samlogon_state, NO_NT, error_string);
368 * Test the NTLM response only, no LM.
371 static BOOL test_ntlm(struct samlogon_state *samlogon_state, char **error_string)
373 return test_lm_ntlm_broken(samlogon_state, NO_LM, error_string);
377 * Test the NTLM response only, but in the LM field.
380 static BOOL test_ntlm_in_lm(struct samlogon_state *samlogon_state, char **error_string)
385 DATA_BLOB nt_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);
386 DATA_BLOB session_key = data_blob_talloc(samlogon_state->mem_ctx, NULL, 16);
390 uint8_t user_session_key[16];
394 ZERO_STRUCT(user_session_key);
396 SMBNTencrypt(samlogon_state->password, samlogon_state->chall.data,
398 E_md4hash(samlogon_state->password, nt_hash);
399 SMBsesskeygen_ntv1(nt_hash,
402 lm_good = E_deshash(samlogon_state->password, lm_hash);
404 ZERO_STRUCT(lm_hash);
406 nt_status = check_samlogon(samlogon_state,
408 &samlogon_state->chall,
415 if (!NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status)) {
416 SAFE_FREE(*error_string);
417 asprintf(error_string, "Expected error: %s, got %s", nt_errstr(samlogon_state->expected_error), nt_errstr(nt_status));
419 } else if (NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status) && !NT_STATUS_IS_OK(nt_status)) {
421 } else if (!NT_STATUS_IS_OK(nt_status)) {
426 if (memcmp(lm_hash, lm_key,
427 sizeof(lm_key)) != 0) {
428 printf("LM Key does not match expectations!\n");
430 dump_data(1, lm_key, 8);
431 printf("expected:\n");
432 dump_data(1, lm_hash, 8);
436 if (memcmp(session_key.data, lm_key,
437 sizeof(lm_key)) != 0) {
438 printf("LM Key does not match expectations (first 8 session key)!\n");
440 dump_data(1, lm_key, 8);
441 printf("expected:\n");
442 dump_data(1, session_key.data, 8);
446 if (memcmp(lm_hash, user_session_key, 8) != 0) {
447 uint8_t lm_key_expected[16];
448 memcpy(lm_key_expected, lm_hash, 8);
449 memset(lm_key_expected+8, '\0', 8);
450 if (memcmp(lm_key_expected, user_session_key,
452 printf("NT Session Key does not match expectations (should be first-8 LM hash)!\n");
453 printf("user_session_key:\n");
454 dump_data(1, user_session_key, sizeof(user_session_key));
455 printf("expected:\n");
456 dump_data(1, lm_key_expected, sizeof(lm_key_expected));
464 * Test the NTLM response only, but in the both the NT and LM fields.
467 static BOOL test_ntlm_in_both(struct samlogon_state *samlogon_state, char **error_string)
472 DATA_BLOB nt_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);
473 DATA_BLOB session_key = data_blob_talloc(samlogon_state->mem_ctx, NULL, 16);
477 uint8_t user_session_key[16];
481 ZERO_STRUCT(user_session_key);
483 SMBNTencrypt(samlogon_state->password, samlogon_state->chall.data,
485 E_md4hash(samlogon_state->password, nt_hash);
486 SMBsesskeygen_ntv1(nt_hash,
489 lm_good = E_deshash(samlogon_state->password, lm_hash);
491 ZERO_STRUCT(lm_hash);
494 nt_status = check_samlogon(samlogon_state,
496 &samlogon_state->chall,
503 if (!NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status)) {
504 SAFE_FREE(*error_string);
505 asprintf(error_string, "Expected error: %s, got %s", nt_errstr(samlogon_state->expected_error), nt_errstr(nt_status));
507 } else if (NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status) && !NT_STATUS_IS_OK(nt_status)) {
509 } else if (!NT_STATUS_IS_OK(nt_status)) {
513 if (!NT_STATUS_IS_OK(nt_status)) {
517 if (memcmp(lm_hash, lm_key,
518 sizeof(lm_key)) != 0) {
519 printf("LM Key does not match expectations!\n");
521 dump_data(1, lm_key, 8);
522 printf("expected:\n");
523 dump_data(1, lm_hash, 8);
526 if (memcmp(session_key.data, user_session_key,
527 sizeof(user_session_key)) != 0) {
528 printf("NT Session Key does not match expectations!\n");
529 printf("user_session_key:\n");
530 dump_data(1, user_session_key, 16);
531 printf("expected:\n");
532 dump_data(1, session_key.data, session_key.length);
541 * Test the NTLMv2 and LMv2 responses
549 static BOOL test_lmv2_ntlmv2_broken(struct samlogon_state *samlogon_state,
550 enum ntlm_break break_which,
551 enum ntlmv2_domain ntlmv2_domain,
556 DATA_BLOB ntlmv2_response = data_blob(NULL, 0);
557 DATA_BLOB lmv2_response = data_blob(NULL, 0);
558 DATA_BLOB lmv2_session_key = data_blob(NULL, 0);
559 DATA_BLOB ntlmv2_session_key = data_blob(NULL, 0);
560 DATA_BLOB names_blob = NTLMv2_generate_names_blob(samlogon_state->mem_ctx, TEST_MACHINE_NAME, lp_workgroup());
562 uint8_t lm_session_key[8];
563 uint8_t user_session_key[16];
565 ZERO_STRUCT(lm_session_key);
566 ZERO_STRUCT(user_session_key);
568 switch (ntlmv2_domain) {
570 if (!SMBNTLMv2encrypt(samlogon_state->mem_ctx,
571 samlogon_state->account_name, samlogon_state->account_domain,
572 samlogon_state->password, &samlogon_state->chall,
574 &lmv2_response, &ntlmv2_response,
575 &lmv2_session_key, &ntlmv2_session_key)) {
576 data_blob_free(&names_blob);
581 if (!SMBNTLMv2encrypt(samlogon_state->mem_ctx,
582 samlogon_state->account_name, "",
583 samlogon_state->password, &samlogon_state->chall,
585 &lmv2_response, &ntlmv2_response,
586 &lmv2_session_key, &ntlmv2_session_key)) {
587 data_blob_free(&names_blob);
592 data_blob_free(&names_blob);
594 nt_status = check_samlogon(samlogon_state,
596 &samlogon_state->chall,
603 data_blob_free(&lmv2_response);
604 data_blob_free(&ntlmv2_response);
607 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD)) {
608 return break_which == BREAK_BOTH;
611 if (!NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status)) {
612 SAFE_FREE(*error_string);
613 asprintf(error_string, "Expected error: %s, got %s", nt_errstr(samlogon_state->expected_error), nt_errstr(nt_status));
615 } else if (NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status) && !NT_STATUS_IS_OK(nt_status)) {
617 } else if (!NT_STATUS_IS_OK(nt_status)) {
622 switch (break_which) {
624 if (memcmp(lmv2_session_key.data, user_session_key,
625 sizeof(user_session_key)) != 0) {
626 printf("USER (LMv2) Session Key does not match expectations!\n");
627 printf("user_session_key:\n");
628 dump_data(1, user_session_key, 16);
629 printf("expected:\n");
630 dump_data(1, lmv2_session_key.data, ntlmv2_session_key.length);
633 if (memcmp(lmv2_session_key.data, lm_session_key,
634 sizeof(lm_session_key)) != 0) {
635 printf("LM (LMv2) Session Key does not match expectations!\n");
636 printf("lm_session_key:\n");
637 dump_data(1, lm_session_key, 8);
638 printf("expected:\n");
639 dump_data(1, lmv2_session_key.data, 8);
644 if (memcmp(ntlmv2_session_key.data, user_session_key,
645 sizeof(user_session_key)) != 0) {
646 if (memcmp(lmv2_session_key.data, user_session_key,
647 sizeof(user_session_key)) == 0) {
648 printf("USER (NTLMv2) Session Key expected, got LMv2 sessesion key instead:\n");
649 printf("user_session_key:\n");
650 dump_data(1, user_session_key, 16);
651 printf("expected:\n");
652 dump_data(1, ntlmv2_session_key.data, ntlmv2_session_key.length);
656 printf("USER (NTLMv2) Session Key does not match expectations!\n");
657 printf("user_session_key:\n");
658 dump_data(1, user_session_key, 16);
659 printf("expected:\n");
660 dump_data(1, ntlmv2_session_key.data, ntlmv2_session_key.length);
664 if (memcmp(ntlmv2_session_key.data, lm_session_key,
665 sizeof(lm_session_key)) != 0) {
666 if (memcmp(lmv2_session_key.data, lm_session_key,
667 sizeof(lm_session_key)) == 0) {
668 printf("LM (NTLMv2) Session Key expected, got LMv2 sessesion key instead:\n");
669 printf("user_session_key:\n");
670 dump_data(1, lm_session_key, 8);
671 printf("expected:\n");
672 dump_data(1, ntlmv2_session_key.data, 8);
675 printf("LM (NTLMv2) Session Key does not match expectations!\n");
676 printf("lm_session_key:\n");
677 dump_data(1, lm_session_key, 8);
678 printf("expected:\n");
679 dump_data(1, ntlmv2_session_key.data, 8);
689 * Test the NTLM and LMv2 responses
692 static BOOL test_lmv2_ntlm_broken(struct samlogon_state *samlogon_state,
693 enum ntlm_break break_which,
694 enum ntlmv2_domain ntlmv2_domain,
699 DATA_BLOB ntlmv2_response = data_blob(NULL, 0);
700 DATA_BLOB lmv2_response = data_blob(NULL, 0);
701 DATA_BLOB lmv2_session_key = data_blob(NULL, 0);
702 DATA_BLOB ntlmv2_session_key = data_blob(NULL, 0);
703 DATA_BLOB names_blob = NTLMv2_generate_names_blob(samlogon_state->mem_ctx, lp_netbios_name(), lp_workgroup());
705 DATA_BLOB ntlm_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);
706 DATA_BLOB ntlm_session_key = data_blob_talloc(samlogon_state->mem_ctx, NULL, 16);
710 uint8_t lm_session_key[8];
711 uint8_t user_session_key[16];
714 SMBNTencrypt(samlogon_state->password, samlogon_state->chall.data,
716 E_md4hash(samlogon_state->password, nt_hash);
717 SMBsesskeygen_ntv1(nt_hash,
718 ntlm_session_key.data);
720 lm_good = E_deshash(samlogon_state->password, lm_hash);
722 ZERO_STRUCT(lm_hash);
725 ZERO_STRUCT(lm_session_key);
726 ZERO_STRUCT(user_session_key);
728 switch (ntlmv2_domain) {
730 /* TODO - test with various domain cases, and without domain */
731 if (!SMBNTLMv2encrypt(samlogon_state->mem_ctx,
732 samlogon_state->account_name, samlogon_state->account_domain,
733 samlogon_state->password, &samlogon_state->chall,
735 &lmv2_response, &ntlmv2_response,
736 &lmv2_session_key, &ntlmv2_session_key)) {
737 data_blob_free(&names_blob);
742 /* TODO - test with various domain cases, and without domain */
743 if (!SMBNTLMv2encrypt(samlogon_state->mem_ctx,
744 samlogon_state->account_name, "",
745 samlogon_state->password, &samlogon_state->chall,
747 &lmv2_response, &ntlmv2_response,
748 &lmv2_session_key, &ntlmv2_session_key)) {
749 data_blob_free(&names_blob);
755 data_blob_free(&names_blob);
757 nt_status = check_samlogon(samlogon_state,
759 &samlogon_state->chall,
766 data_blob_free(&lmv2_response);
767 data_blob_free(&ntlmv2_response);
770 if (NT_STATUS_EQUAL(NT_STATUS_WRONG_PASSWORD, nt_status)) {
771 return ((break_which == BREAK_NT) || (break_which == BREAK_BOTH));
774 if (!NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status)) {
775 SAFE_FREE(*error_string);
776 asprintf(error_string, "Expected error: %s, got %s", nt_errstr(samlogon_state->expected_error), nt_errstr(nt_status));
778 } else if (NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status) && !NT_STATUS_IS_OK(nt_status)) {
780 } else if (!NT_STATUS_IS_OK(nt_status)) {
784 switch (break_which) {
786 if (memcmp(lmv2_session_key.data, user_session_key,
787 sizeof(user_session_key)) != 0) {
788 printf("USER (LMv2) Session Key does not match expectations!\n");
789 printf("user_session_key:\n");
790 dump_data(1, user_session_key, 16);
791 printf("expected:\n");
792 dump_data(1, lmv2_session_key.data, ntlmv2_session_key.length);
795 if (memcmp(lmv2_session_key.data, lm_session_key,
796 sizeof(lm_session_key)) != 0) {
797 printf("LM (LMv2) Session Key does not match expectations!\n");
798 printf("lm_session_key:\n");
799 dump_data(1, lm_session_key, 8);
800 printf("expected:\n");
801 dump_data(1, lmv2_session_key.data, 8);
806 if (memcmp(ntlm_session_key.data, user_session_key,
807 sizeof(user_session_key)) != 0) {
808 printf("USER (NTLMv2) Session Key does not match expectations!\n");
809 printf("user_session_key:\n");
810 dump_data(1, user_session_key, 16);
811 printf("expected:\n");
812 dump_data(1, ntlm_session_key.data, ntlm_session_key.length);
816 if (memcmp(lm_hash, lm_session_key,
817 sizeof(lm_session_key)) != 0) {
818 printf("LM Session Key does not match expectations!\n");
819 printf("lm_session_key:\n");
820 dump_data(1, lm_session_key, 8);
821 printf("expected:\n");
822 dump_data(1, lm_hash, 8);
826 static const char zeros[8];
827 if (memcmp(zeros, lm_session_key,
828 sizeof(lm_session_key)) != 0) {
829 printf("LM Session Key does not match expectations (zeros)!\n");
830 printf("lm_session_key:\n");
831 dump_data(1, lm_session_key, 8);
832 printf("expected:\n");
833 dump_data(1, zeros, 8);
839 if (memcmp(ntlm_session_key.data, user_session_key,
840 sizeof(user_session_key)) != 0) {
841 printf("USER (NTLMv2) Session Key does not match expectations!\n");
842 printf("user_session_key:\n");
843 dump_data(1, user_session_key, 16);
844 printf("expected:\n");
845 dump_data(1, ntlm_session_key.data, ntlm_session_key.length);
848 if (memcmp(ntlm_session_key.data, lm_session_key,
849 sizeof(lm_session_key)) != 0) {
850 printf("LM (NTLMv2) Session Key does not match expectations!\n");
851 printf("lm_session_key:\n");
852 dump_data(1, lm_session_key, 8);
853 printf("expected:\n");
854 dump_data(1, ntlm_session_key.data, 8);
863 * Test the NTLMv2 and LMv2 responses
866 static BOOL test_lmv2_ntlmv2(struct samlogon_state *samlogon_state, char **error_string)
868 return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_NONE, UPPER_DOMAIN, error_string);
872 static BOOL test_lmv2_ntlmv2_no_dom(struct samlogon_state *samlogon_state, char **error_string)
874 return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_NONE, NO_DOMAIN, error_string);
879 * Test the LMv2 response only
882 static BOOL test_lmv2(struct samlogon_state *samlogon_state, char **error_string)
884 return test_lmv2_ntlmv2_broken(samlogon_state, NO_NT, UPPER_DOMAIN, error_string);
887 static BOOL test_lmv2_no_dom(struct samlogon_state *samlogon_state, char **error_string)
889 return test_lmv2_ntlmv2_broken(samlogon_state, NO_NT, NO_DOMAIN, error_string);
893 * Test the NTLMv2 response only
896 static BOOL test_ntlmv2(struct samlogon_state *samlogon_state, char **error_string)
898 return test_lmv2_ntlmv2_broken(samlogon_state, NO_LM, UPPER_DOMAIN, error_string);
901 static BOOL test_ntlmv2_no_dom(struct samlogon_state *samlogon_state, char **error_string)
903 return test_lmv2_ntlmv2_broken(samlogon_state, NO_LM, NO_DOMAIN, error_string);
906 static BOOL test_lm_ntlm(struct samlogon_state *samlogon_state, char **error_string)
908 return test_lm_ntlm_broken(samlogon_state, BREAK_NONE, error_string);
911 static BOOL test_ntlm_lm_broken(struct samlogon_state *samlogon_state, char **error_string)
913 return test_lm_ntlm_broken(samlogon_state, BREAK_LM, error_string);
916 static BOOL test_ntlm_ntlm_broken(struct samlogon_state *samlogon_state, char **error_string)
918 return test_lm_ntlm_broken(samlogon_state, BREAK_NT, error_string);
921 static BOOL test_lm_ntlm_both_broken(struct samlogon_state *samlogon_state, char **error_string)
923 return test_lm_ntlm_broken(samlogon_state, BREAK_BOTH, error_string);
925 static BOOL test_ntlmv2_lmv2_broken(struct samlogon_state *samlogon_state, char **error_string)
927 return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_LM, UPPER_DOMAIN, error_string);
930 static BOOL test_ntlmv2_lmv2_broken_no_dom(struct samlogon_state *samlogon_state, char **error_string)
932 return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_LM, NO_DOMAIN, error_string);
935 static BOOL test_ntlmv2_ntlmv2_broken(struct samlogon_state *samlogon_state, char **error_string)
937 return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_NT, UPPER_DOMAIN, error_string);
941 static BOOL test_ntlmv2_ntlmv2_broken_no_dom(struct samlogon_state *samlogon_state, char **error_string)
943 return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_NT, NO_DOMAIN, error_string);
947 static BOOL test_ntlmv2_both_broken(struct samlogon_state *samlogon_state, char **error_string)
949 return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_BOTH, UPPER_DOMAIN, error_string);
952 static BOOL test_ntlmv2_both_broken_no_dom(struct samlogon_state *samlogon_state, char **error_string)
954 return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_BOTH, NO_DOMAIN, error_string);
957 static BOOL test_lmv2_ntlm_both_broken(struct samlogon_state *samlogon_state, char **error_string)
959 return test_lmv2_ntlm_broken(samlogon_state, BREAK_BOTH, UPPER_DOMAIN, error_string);
962 static BOOL test_lmv2_ntlm_both_broken_no_dom(struct samlogon_state *samlogon_state, char **error_string)
964 return test_lmv2_ntlm_broken(samlogon_state, BREAK_BOTH, NO_DOMAIN, error_string);
967 static BOOL test_lmv2_ntlm_break_ntlm(struct samlogon_state *samlogon_state, char **error_string)
969 return test_lmv2_ntlm_broken(samlogon_state, BREAK_NT, UPPER_DOMAIN, error_string);
972 static BOOL test_lmv2_ntlm_break_ntlm_no_dom(struct samlogon_state *samlogon_state, char **error_string)
974 return test_lmv2_ntlm_broken(samlogon_state, BREAK_NT, NO_DOMAIN, error_string);
977 static BOOL test_lmv2_ntlm_break_lm(struct samlogon_state *samlogon_state, char **error_string)
979 return test_lmv2_ntlm_broken(samlogon_state, BREAK_LM, UPPER_DOMAIN, error_string);
982 static BOOL test_lmv2_ntlm_break_lm_no_dom(struct samlogon_state *samlogon_state, char **error_string)
984 return test_lmv2_ntlm_broken(samlogon_state, BREAK_LM, NO_DOMAIN, error_string);
988 * Test the NTLM2 response (extra challenge in LM feild)
990 * This test is the same as the 'break LM' test, but checks that the
991 * server implements NTLM2 session security in the right place
992 * (NETLOGON is the wrong place).
995 static BOOL test_ntlm2(struct samlogon_state *samlogon_state, char **error_string)
999 DATA_BLOB lm_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);
1000 DATA_BLOB nt_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);
1004 uint8_t nt_hash[16];
1005 uint8_t lm_hash[16];
1007 uint8_t user_session_key[16];
1008 uint8_t expected_user_session_key[16];
1009 uint8_t session_nonce_hash[16];
1010 uint8_t client_chall[8];
1012 struct MD5Context md5_session_nonce_ctx;
1013 HMACMD5Context hmac_ctx;
1015 ZERO_STRUCT(user_session_key);
1016 ZERO_STRUCT(lm_key);
1017 generate_random_buffer(client_chall, 8);
1019 MD5Init(&md5_session_nonce_ctx);
1020 MD5Update(&md5_session_nonce_ctx, samlogon_state->chall.data, 8);
1021 MD5Update(&md5_session_nonce_ctx, client_chall, 8);
1022 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
1024 E_md4hash(samlogon_state->password, (uint8_t *)nt_hash);
1025 lm_good = E_deshash(samlogon_state->password, (uint8_t *)lm_hash);
1026 SMBsesskeygen_ntv1((const uint8_t *)nt_hash,
1029 SMBNTencrypt(samlogon_state->password, samlogon_state->chall.data, nt_response.data);
1031 memcpy(lm_response.data, session_nonce_hash, 8);
1032 memset(lm_response.data + 8, 0, 16);
1034 hmac_md5_init_rfc2104(nt_key, 16, &hmac_ctx);
1035 hmac_md5_update(samlogon_state->chall.data, 8, &hmac_ctx);
1036 hmac_md5_update(client_chall, 8, &hmac_ctx);
1037 hmac_md5_final(expected_user_session_key, &hmac_ctx);
1039 nt_status = check_samlogon(samlogon_state,
1041 &samlogon_state->chall,
1048 if (!NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status)) {
1049 SAFE_FREE(*error_string);
1050 asprintf(error_string, "Expected error: %s, got %s", nt_errstr(samlogon_state->expected_error), nt_errstr(nt_status));
1052 } else if (NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status) && !NT_STATUS_IS_OK(nt_status)) {
1054 } else if (!NT_STATUS_IS_OK(nt_status)) {
1059 if (memcmp(lm_hash, lm_key,
1060 sizeof(lm_key)) != 0) {
1061 printf("LM Key does not match expectations!\n");
1062 printf("lm_key:\n");
1063 dump_data(1, lm_key, 8);
1064 printf("expected:\n");
1065 dump_data(1, lm_hash, 8);
1069 static const char zeros[8];
1070 if (memcmp(zeros, lm_key,
1071 sizeof(lm_key)) != 0) {
1072 printf("LM Session Key does not match expectations (zeros)!\n");
1073 printf("lm_key:\n");
1074 dump_data(1, lm_key, 8);
1075 printf("expected:\n");
1076 dump_data(1, zeros, 8);
1080 if (memcmp(nt_key, user_session_key, 16) != 0) {
1081 printf("NT Session Key does not match expectations (should be NT Key)!\n");
1082 printf("user_session_key:\n");
1083 dump_data(1, user_session_key, sizeof(user_session_key));
1084 printf("expected:\n");
1085 dump_data(1, nt_key, sizeof(nt_key));
1091 static BOOL test_plaintext(struct samlogon_state *samlogon_state, enum ntlm_break break_which, char **error_string)
1094 DATA_BLOB nt_response = data_blob(NULL, 0);
1095 DATA_BLOB lm_response = data_blob(NULL, 0);
1100 uint8_t user_session_key[16];
1102 static const uint8_t zeros[8];
1103 DATA_BLOB chall = data_blob_talloc(samlogon_state->mem_ctx, zeros, sizeof(zeros));
1105 ZERO_STRUCT(user_session_key);
1107 if ((push_ucs2_talloc(samlogon_state->mem_ctx, &unicodepw,
1108 samlogon_state->password)) == -1) {
1109 DEBUG(0, ("push_ucs2_allocate failed!\n"));
1113 nt_response = data_blob_talloc(samlogon_state->mem_ctx, unicodepw, strlen_m(samlogon_state->password)*2);
1115 password = strupper_talloc(samlogon_state->mem_ctx, samlogon_state->password);
1117 if ((convert_string_talloc(samlogon_state->mem_ctx, CH_UNIX,
1120 (void**)&dospw)) == -1) {
1121 DEBUG(0, ("convert_string_talloc failed!\n"));
1125 lm_response = data_blob_talloc(samlogon_state->mem_ctx, dospw, strlen(dospw));
1127 nt_status = check_samlogon(samlogon_state,
1136 if (!NT_STATUS_IS_OK(nt_status)) {
1137 return break_which == BREAK_NT;
1143 static BOOL test_plaintext_none_broken(struct samlogon_state *samlogon_state,
1144 char **error_string) {
1145 return test_plaintext(samlogon_state, BREAK_NONE, error_string);
1148 static BOOL test_plaintext_lm_broken(struct samlogon_state *samlogon_state,
1149 char **error_string) {
1150 return test_plaintext(samlogon_state, BREAK_LM, error_string);
1153 static BOOL test_plaintext_nt_broken(struct samlogon_state *samlogon_state,
1154 char **error_string) {
1155 return test_plaintext(samlogon_state, BREAK_NT, error_string);
1158 static BOOL test_plaintext_nt_only(struct samlogon_state *samlogon_state,
1159 char **error_string) {
1160 return test_plaintext(samlogon_state, NO_LM, error_string);
1163 static BOOL test_plaintext_lm_only(struct samlogon_state *samlogon_state,
1164 char **error_string) {
1165 return test_plaintext(samlogon_state, NO_NT, error_string);
1179 - plaintext tests (in challenge-response fields)
1181 check we get the correct session key in each case
1182 check what values we get for the LM session key
1186 static const struct ntlm_tests {
1187 BOOL (*fn)(struct samlogon_state *, char **);
1191 {test_lmv2_ntlmv2, "NTLMv2 and LMv2", False},
1193 {test_lmv2_ntlmv2_no_dom, "NTLMv2 and LMv2 (no domain)", False},
1195 {test_lm, "LM", False},
1196 {test_lm_ntlm, "LM and NTLM", False},
1197 {test_lm_ntlm_both_broken, "LM and NTLM, both broken", False},
1198 {test_ntlm, "NTLM", False},
1199 {test_ntlm_in_lm, "NTLM in LM", False},
1200 {test_ntlm_in_both, "NTLM in both", False},
1201 {test_ntlmv2, "NTLMv2", False},
1202 {test_ntlmv2_no_dom, "NTLMv2 (no domain)", False},
1203 {test_lmv2, "LMv2", False},
1204 {test_lmv2_no_dom, "LMv2 (no domain)", False},
1205 {test_ntlmv2_lmv2_broken, "NTLMv2 and LMv2, LMv2 broken", False},
1206 {test_ntlmv2_lmv2_broken_no_dom, "NTLMv2 and LMv2, LMv2 broken (no domain)", False},
1207 {test_ntlmv2_ntlmv2_broken, "NTLMv2 and LMv2, NTLMv2 broken", False},
1209 {test_ntlmv2_ntlmv2_broken_no_dom, "NTLMv2 and LMv2, NTLMv2 broken (no domain)", False},
1211 {test_ntlmv2_both_broken, "NTLMv2 and LMv2, both broken", False},
1212 {test_ntlmv2_both_broken_no_dom, "NTLMv2 and LMv2, both broken (no domain)", False},
1213 {test_ntlm_lm_broken, "NTLM and LM, LM broken", False},
1214 {test_ntlm_ntlm_broken, "NTLM and LM, NTLM broken", False},
1215 {test_ntlm2, "NTLM2 (NTLMv2 session security)", False},
1216 {test_lmv2_ntlm_both_broken, "LMv2 and NTLM, both broken", False},
1217 {test_lmv2_ntlm_both_broken_no_dom, "LMv2 and NTLM, both broken (no domain)", False},
1218 {test_lmv2_ntlm_break_ntlm, "LMv2 and NTLM, NTLM broken", False},
1219 {test_lmv2_ntlm_break_ntlm_no_dom, "LMv2 and NTLM, NTLM broken (no domain)", False},
1220 {test_lmv2_ntlm_break_lm, "LMv2 and NTLM, LMv2 broken", False},
1221 {test_lmv2_ntlm_break_lm_no_dom, "LMv2 and NTLM, LMv2 broken (no domain)", False},
1222 {test_plaintext_none_broken, "Plaintext", True},
1223 {test_plaintext_lm_broken, "Plaintext LM broken", True},
1224 {test_plaintext_nt_broken, "Plaintext NT broken", True},
1225 {test_plaintext_nt_only, "Plaintext NT only", True},
1226 {test_plaintext_lm_only, "Plaintext LM only", True},
1231 try a netlogon SamLogon
1233 static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1234 struct creds_CredentialState *creds,
1235 const char *comment,
1236 const char *account_domain, const char *account_name,
1237 const char *plain_pass, NTSTATUS expected_error,
1240 TALLOC_CTX *fn_ctx = talloc_named(mem_ctx, 0, "test_SamLogon function-level context");
1243 int validation_levels[] = {2,3,6};
1244 int logon_levels[] = { 2, 6 };
1245 int function_levels[] = {
1246 DCERPC_NETR_LOGONSAMLOGON,
1247 DCERPC_NETR_LOGONSAMLOGONEX,
1248 DCERPC_NETR_LOGONSAMLOGONWITHFLAGS };
1249 struct samlogon_state samlogon_state;
1251 printf("testing netr_LogonSamLogon and netr_LogonSamLogonWithFlags\n");
1253 samlogon_state.comment = comment;
1254 samlogon_state.account_name = account_name;
1255 samlogon_state.account_domain = account_domain;
1256 samlogon_state.password = plain_pass;
1257 samlogon_state.p = p;
1258 samlogon_state.creds = creds;
1259 samlogon_state.expected_error = expected_error;
1260 samlogon_state.chall = data_blob_talloc(fn_ctx, NULL, 8);
1262 generate_random_buffer(samlogon_state.chall.data, 8);
1263 samlogon_state.r_flags.in.server_name = talloc_asprintf(fn_ctx, "\\\\%s", dcerpc_server_name(p));
1264 samlogon_state.r_flags.in.workstation = TEST_MACHINE_NAME;
1265 samlogon_state.r_flags.in.credential = &samlogon_state.auth;
1266 samlogon_state.r_flags.in.return_authenticator = &samlogon_state.auth2;
1267 samlogon_state.r_flags.in.flags = 0;
1269 samlogon_state.r_ex.in.server_name = talloc_asprintf(fn_ctx, "\\\\%s", dcerpc_server_name(p));
1270 samlogon_state.r_ex.in.workstation = TEST_MACHINE_NAME;
1271 samlogon_state.r_ex.in.flags = 0;
1273 samlogon_state.r.in.server_name = talloc_asprintf(fn_ctx, "\\\\%s", dcerpc_server_name(p));
1274 samlogon_state.r.in.workstation = TEST_MACHINE_NAME;
1275 samlogon_state.r.in.credential = &samlogon_state.auth;
1276 samlogon_state.r.in.return_authenticator = &samlogon_state.auth2;
1278 for (f=0;f<ARRAY_SIZE(function_levels);f++) {
1279 for (i=0; test_table[i].fn; i++) {
1280 if (n_subtests && (i > n_subtests)) {
1283 for (v=0;v<ARRAY_SIZE(validation_levels);v++) {
1284 for (l=0;l<ARRAY_SIZE(logon_levels);l++) {
1285 char *error_string = NULL;
1286 TALLOC_CTX *tmp_ctx = talloc_named(fn_ctx, 0, "test_SamLogon inner loop");
1287 samlogon_state.mem_ctx = tmp_ctx;
1288 samlogon_state.function_level = function_levels[f];
1289 samlogon_state.r.in.validation_level = validation_levels[v];
1290 samlogon_state.r.in.logon_level = logon_levels[l];
1291 samlogon_state.r_ex.in.validation_level = validation_levels[v];
1292 samlogon_state.r_ex.in.logon_level = logon_levels[l];
1293 samlogon_state.r_flags.in.validation_level = validation_levels[v];
1294 samlogon_state.r_flags.in.logon_level = logon_levels[l];
1295 if (!test_table[i].fn(&samlogon_state, &error_string)) {
1296 printf("Testing '%s' [%s]\\[%s] '%s' at validation level %d, logon level %d, function %d: \n",
1297 samlogon_state.comment,
1298 samlogon_state.account_domain,
1299 samlogon_state.account_name,
1300 test_table[i].name, validation_levels[v],
1301 logon_levels[l], function_levels[f]);
1303 if (test_table[i].expect_fail) {
1304 printf(" failed (expected, test incomplete): %s\n", error_string);
1306 printf(" failed: %s\n", error_string);
1309 SAFE_FREE(error_string);
1311 talloc_free(tmp_ctx);
1316 talloc_free(fn_ctx);
1321 test an ADS style interactive domain logon
1323 BOOL test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1324 struct creds_CredentialState *creds,
1325 const char *comment,
1326 const char *workstation_name,
1327 const char *account_domain, const char *account_name,
1328 const char *plain_pass, NTSTATUS expected_error)
1331 TALLOC_CTX *fn_ctx = talloc_named(mem_ctx, 0, "test_InteractiveLogon function-level context");
1332 struct netr_LogonSamLogonWithFlags r;
1333 struct netr_Authenticator a, ra;
1334 struct netr_PasswordInfo pinfo;
1340 creds_client_authenticator(creds, &a);
1342 r.in.server_name = talloc_asprintf(fn_ctx, "\\\\%s", dcerpc_server_name(p));
1343 r.in.workstation = TEST_MACHINE_NAME;
1344 r.in.credential = &a;
1345 r.in.return_authenticator = &ra;
1346 r.in.logon_level = 5;
1347 r.in.logon.password = &pinfo;
1348 r.in.validation_level = 6;
1351 pinfo.identity_info.domain_name.string = account_domain;
1352 pinfo.identity_info.parameter_control = 0;
1353 pinfo.identity_info.logon_id_low = 0;
1354 pinfo.identity_info.logon_id_high = 0;
1355 pinfo.identity_info.account_name.string = account_name;
1356 pinfo.identity_info.workstation.string = workstation_name;
1358 if (!E_deshash(plain_pass, pinfo.lmpassword.hash)) {
1359 ZERO_STRUCT(pinfo.lmpassword.hash);
1361 E_md4hash(plain_pass, pinfo.ntpassword.hash);
1363 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
1364 creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
1365 creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
1367 creds_des_encrypt(creds, &pinfo.lmpassword);
1368 creds_des_encrypt(creds, &pinfo.ntpassword);
1371 printf("Testing netr_LogonSamLogonWithFlags '%s' (Interactive Logon)\n", comment);
1373 status = dcerpc_netr_LogonSamLogonWithFlags(p, fn_ctx, &r);
1374 if (!r.out.return_authenticator
1375 || !creds_client_check(creds, &r.out.return_authenticator->cred)) {
1376 printf("Credential chaining failed\n");
1377 talloc_free(fn_ctx);
1381 talloc_free(fn_ctx);
1383 if (!NT_STATUS_EQUAL(expected_error, status)) {
1384 printf("[%s]\\[%s] netr_LogonSamLogonWithFlags - expected %s got %s\n",
1385 account_domain, account_name, nt_errstr(expected_error), nt_errstr(status));
1394 BOOL torture_rpc_samlogon(void)
1397 struct dcerpc_pipe *p;
1398 struct dcerpc_binding *b;
1399 struct cli_credentials *machine_credentials;
1400 TALLOC_CTX *mem_ctx = talloc_init("torture_rpc_netlogon");
1402 struct test_join *join_ctx;
1403 struct test_join *user_ctx;
1404 const char *user_password;
1405 const char *old_user_password;
1406 char *test_machine_account;
1407 const char *binding = lp_parm_string(-1, "torture", "binding");
1408 const char *userdomain;
1412 unsigned int credential_flags[] = {
1413 NETLOGON_NEG_AUTH2_FLAGS,
1414 NETLOGON_NEG_ARCFOUR,
1415 NETLOGON_NEG_ARCFOUR | NETLOGON_NEG_128BIT,
1416 NETLOGON_NEG_AUTH2_ADS_FLAGS,
1417 0 /* yes, this is a valid flag, causes the use of DES */
1420 struct creds_CredentialState *creds;
1422 test_machine_account = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
1423 /* We only need to join as a workstation here, and in future,
1424 * if we wish to test against trusted domains, we must be a
1425 * workstation here */
1426 join_ctx = torture_join_domain(TEST_MACHINE_NAME, ACB_WSTRUST,
1427 &machine_credentials);
1429 printf("Failed to join as Workstation\n");
1433 userdomain = lp_parm_string(-1, "torture", "userdomain");
1435 userdomain = lp_workgroup();
1438 user_ctx = torture_create_testuser(TEST_USER_NAME,
1443 printf("Failed to join as Workstation\n");
1447 old_user_password = user_password;
1449 test_ChangePasswordUser3(torture_join_samr_pipe(user_ctx), mem_ctx,
1450 TEST_USER_NAME, 16 /* > 14 */, &user_password);
1452 status = dcerpc_parse_binding(mem_ctx, binding, &b);
1453 if (!NT_STATUS_IS_OK(status)) {
1454 printf("Bad binding string %s\n", binding);
1459 /* We have to use schannel, otherwise the SamLogonEx fails
1460 * with INTERNAL_ERROR */
1462 b->flags &= ~DCERPC_AUTH_OPTIONS;
1463 b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
1465 status = dcerpc_pipe_connect_b(mem_ctx, &p, b,
1466 DCERPC_NETLOGON_UUID,
1467 DCERPC_NETLOGON_VERSION,
1468 machine_credentials, NULL);
1470 if (!NT_STATUS_IS_OK(status)) {
1471 printf("RPC pipe connect as domain member failed: %s\n", nt_errstr(status));
1476 status = dcerpc_schannel_creds(p->conn->security_state.generic_state, mem_ctx, &creds);
1477 if (!NT_STATUS_IS_OK(status)) {
1485 const char *comment;
1487 const char *username;
1488 const char *password;
1490 NTSTATUS expected_interactive_error;
1491 NTSTATUS expected_network_error;
1494 .comment = "domain\\user",
1495 .domain = cli_credentials_get_domain(cmdline_credentials),
1496 .username = cli_credentials_get_username(cmdline_credentials),
1497 .password = cli_credentials_get_password(cmdline_credentials),
1498 .network_login = True,
1499 .expected_interactive_error = NT_STATUS_OK,
1500 .expected_network_error = NT_STATUS_OK
1503 .comment = "realm\\user",
1504 .domain = cli_credentials_get_realm(cmdline_credentials),
1505 .username = cli_credentials_get_username(cmdline_credentials),
1506 .password = cli_credentials_get_password(cmdline_credentials),
1507 .network_login = True,
1508 .expected_interactive_error = NT_STATUS_OK,
1509 .expected_network_error = NT_STATUS_OK
1512 .comment = "user@domain",
1514 .username = talloc_asprintf(mem_ctx,
1516 cli_credentials_get_username(cmdline_credentials),
1517 cli_credentials_get_domain(cmdline_credentials)
1519 .password = cli_credentials_get_password(cmdline_credentials),
1520 .network_login = False,
1521 .expected_interactive_error = NT_STATUS_OK,
1522 .expected_network_error = NT_STATUS_OK
1525 .comment = "user@realm",
1527 .username = talloc_asprintf(mem_ctx,
1529 cli_credentials_get_username(cmdline_credentials),
1530 cli_credentials_get_realm(cmdline_credentials)
1532 .password = cli_credentials_get_password(cmdline_credentials),
1533 .network_login = True,
1534 .expected_interactive_error = NT_STATUS_OK,
1535 .expected_network_error = NT_STATUS_OK
1538 .comment = "machine domain\\user",
1539 .domain = cli_credentials_get_domain(machine_credentials),
1540 .username = cli_credentials_get_username(machine_credentials),
1541 .password = cli_credentials_get_password(machine_credentials),
1542 .network_login = True,
1543 .expected_interactive_error = NT_STATUS_NO_SUCH_USER,
1544 .expected_network_error = NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT
1547 .comment = "machine realm\\user",
1548 .domain = cli_credentials_get_realm(machine_credentials),
1549 .username = cli_credentials_get_username(machine_credentials),
1550 .password = cli_credentials_get_password(machine_credentials),
1551 .network_login = True,
1552 .expected_interactive_error = NT_STATUS_NO_SUCH_USER,
1553 .expected_network_error = NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT
1556 .comment = "machine user@domain",
1558 .username = talloc_asprintf(mem_ctx,
1560 cli_credentials_get_username(machine_credentials),
1561 cli_credentials_get_domain(machine_credentials)
1563 .password = cli_credentials_get_password(machine_credentials),
1564 .network_login = False,
1565 .expected_interactive_error = NT_STATUS_NO_SUCH_USER,
1566 .expected_network_error = NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT
1569 .comment = "machine user@realm",
1571 .username = talloc_asprintf(mem_ctx,
1573 cli_credentials_get_username(machine_credentials),
1574 cli_credentials_get_realm(machine_credentials)
1576 .password = cli_credentials_get_password(machine_credentials),
1577 .network_login = True,
1578 .expected_interactive_error = NT_STATUS_NO_SUCH_USER,
1579 .expected_network_error = NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT
1582 .comment = "test user (long pw): domain\\user",
1583 .domain = userdomain,
1584 .username = TEST_USER_NAME,
1585 .password = user_password,
1586 .network_login = True,
1587 .expected_interactive_error = NT_STATUS_OK,
1588 .expected_network_error = NT_STATUS_OK
1591 .comment = "test user (long pw): user@realm",
1593 .username = talloc_asprintf(mem_ctx,
1597 .password = user_password,
1598 .network_login = True,
1599 .expected_interactive_error = NT_STATUS_OK,
1600 .expected_network_error = NT_STATUS_OK
1603 .comment = "test user (long pw): user@domain",
1605 .username = talloc_asprintf(mem_ctx,
1609 .password = user_password,
1610 .network_login = False,
1611 .expected_interactive_error = NT_STATUS_OK,
1612 .expected_network_error = NT_STATUS_OK
1614 /* Oddball, can we use the old password ? */
1616 .comment = "test user: user\\domain OLD PASSWORD",
1617 .domain = userdomain,
1618 .username = TEST_USER_NAME,
1619 .password = old_user_password,
1620 .network_login = True,
1621 .expected_interactive_error = NT_STATUS_WRONG_PASSWORD,
1622 .expected_network_error = NT_STATUS_OK
1626 /* Try all the tests for different username forms */
1627 for (ci = 0; ci < ARRAY_SIZE(usercreds); ci++) {
1629 if (!test_InteractiveLogon(p, mem_ctx, creds,
1630 usercreds[ci].comment,
1632 usercreds[ci].domain,
1633 usercreds[ci].username,
1634 usercreds[ci].password,
1635 usercreds[ci].expected_interactive_error)) {
1639 if (usercreds[ci].network_login) {
1640 if (!test_SamLogon(p, mem_ctx, creds,
1641 usercreds[ci].comment,
1642 usercreds[ci].domain,
1643 usercreds[ci].username,
1644 usercreds[ci].password,
1645 usercreds[ci].expected_network_error,
1652 /* Using the first username form, try the different
1653 * credentials flag setups, on only one of the tests (checks
1654 * session key encryption) */
1656 for (i=0; i < ARRAY_SIZE(credential_flags); i++) {
1657 if (!test_InteractiveLogon(p, mem_ctx, creds,
1658 usercreds[0].comment,
1660 usercreds[0].domain,
1661 usercreds[0].username,
1662 usercreds[0].password,
1663 usercreds[0].expected_interactive_error)) {
1667 if (usercreds[ci].network_login) {
1668 if (!test_SamLogon(p, mem_ctx, creds,
1669 usercreds[0].comment,
1670 usercreds[0].domain,
1671 usercreds[0].username,
1672 usercreds[0].password,
1673 usercreds[0].expected_network_error,
1682 talloc_free(mem_ctx);
1684 torture_leave_domain(join_ctx);
1685 torture_leave_domain(user_ctx);