2 Unix SMB/CIFS implementation.
4 test suite for netlogon rpc 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"
30 static const char *machine_password;
32 #define TEST_MACHINE_NAME "torturetest"
34 static BOOL test_LogonUasLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
37 struct netr_LogonUasLogon r;
39 r.in.server_name = NULL;
40 r.in.account_name = lp_parm_string(-1, "torture", "username");
41 r.in.workstation = TEST_MACHINE_NAME;
43 printf("Testing LogonUasLogon\n");
45 status = dcerpc_netr_LogonUasLogon(p, mem_ctx, &r);
46 if (!NT_STATUS_IS_OK(status)) {
47 printf("LogonUasLogon - %s\n", nt_errstr(status));
55 static BOOL test_LogonUasLogoff(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
58 struct netr_LogonUasLogoff r;
60 r.in.server_name = NULL;
61 r.in.account_name = lp_parm_string(-1, "torture", "username");
62 r.in.workstation = TEST_MACHINE_NAME;
64 printf("Testing LogonUasLogoff\n");
66 status = dcerpc_netr_LogonUasLogoff(p, mem_ctx, &r);
67 if (!NT_STATUS_IS_OK(status)) {
68 printf("LogonUasLogoff - %s\n", nt_errstr(status));
76 static BOOL test_SetupCredentials(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
77 struct creds_CredentialState *creds)
80 struct netr_ServerReqChallenge r;
81 struct netr_ServerAuthenticate a;
82 struct netr_Credential credentials1, credentials2, credentials3;
83 const char *plain_pass;
84 struct samr_Password mach_password;
86 printf("Testing ServerReqChallenge\n");
88 r.in.server_name = NULL;
89 r.in.computer_name = TEST_MACHINE_NAME;
90 r.in.credentials = &credentials1;
91 r.out.credentials = &credentials2;
93 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
95 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
96 if (!NT_STATUS_IS_OK(status)) {
97 printf("ServerReqChallenge - %s\n", nt_errstr(status));
101 plain_pass = machine_password;
103 printf("Unable to fetch machine password!\n");
107 E_md4hash(plain_pass, mach_password.hash);
109 a.in.server_name = NULL;
110 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
111 a.in.secure_channel_type = SEC_CHAN_BDC;
112 a.in.computer_name = TEST_MACHINE_NAME;
113 a.in.credentials = &credentials3;
114 a.out.credentials = &credentials3;
116 creds_client_init(creds, &credentials1, &credentials2, &mach_password, &credentials3,
117 NETLOGON_NEG_AUTH2_FLAGS);
119 printf("Testing ServerAuthenticate\n");
121 status = dcerpc_netr_ServerAuthenticate(p, mem_ctx, &a);
122 if (!NT_STATUS_IS_OK(status)) {
123 printf("ServerAuthenticate - %s\n", nt_errstr(status));
127 if (!creds_client_check(creds, &credentials3)) {
128 printf("Credential chaining failed\n");
135 static BOOL test_SetupCredentials2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
136 uint32_t negotiate_flags,
137 struct creds_CredentialState *creds)
140 struct netr_ServerReqChallenge r;
141 struct netr_ServerAuthenticate2 a;
142 struct netr_Credential credentials1, credentials2, credentials3;
143 const char *plain_pass;
144 struct samr_Password mach_password;
146 printf("Testing ServerReqChallenge\n");
148 r.in.server_name = NULL;
149 r.in.computer_name = TEST_MACHINE_NAME;
150 r.in.credentials = &credentials1;
151 r.out.credentials = &credentials2;
153 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
155 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
156 if (!NT_STATUS_IS_OK(status)) {
157 printf("ServerReqChallenge - %s\n", nt_errstr(status));
161 plain_pass = machine_password;
163 printf("Unable to fetch machine password!\n");
167 E_md4hash(plain_pass, mach_password.hash);
169 a.in.server_name = NULL;
170 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
171 a.in.secure_channel_type = SEC_CHAN_BDC;
172 a.in.computer_name = TEST_MACHINE_NAME;
173 a.in.negotiate_flags = &negotiate_flags;
174 a.out.negotiate_flags = &negotiate_flags;
175 a.in.credentials = &credentials3;
176 a.out.credentials = &credentials3;
178 creds_client_init(creds, &credentials1, &credentials2, &mach_password, &credentials3,
181 printf("Testing ServerAuthenticate2\n");
183 status = dcerpc_netr_ServerAuthenticate2(p, mem_ctx, &a);
184 if (!NT_STATUS_IS_OK(status)) {
185 printf("ServerAuthenticate2 - %s\n", nt_errstr(status));
189 if (!creds_client_check(creds, &credentials3)) {
190 printf("Credential chaining failed\n");
194 printf("negotiate_flags=0x%08x\n", negotiate_flags);
200 static BOOL test_SetupCredentials3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
201 uint32_t negotiate_flags,
202 struct creds_CredentialState *creds)
205 struct netr_ServerReqChallenge r;
206 struct netr_ServerAuthenticate3 a;
207 struct netr_Credential credentials1, credentials2, credentials3;
208 const char *plain_pass;
209 struct samr_Password mach_password;
212 printf("Testing ServerReqChallenge\n");
214 r.in.server_name = NULL;
215 r.in.computer_name = TEST_MACHINE_NAME;
216 r.in.credentials = &credentials1;
217 r.out.credentials = &credentials2;
219 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
221 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
222 if (!NT_STATUS_IS_OK(status)) {
223 printf("ServerReqChallenge - %s\n", nt_errstr(status));
227 plain_pass = machine_password;
229 printf("Unable to fetch machine password!\n");
233 E_md4hash(plain_pass, mach_password.hash);
235 a.in.server_name = NULL;
236 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
237 a.in.secure_channel_type = SEC_CHAN_BDC;
238 a.in.computer_name = TEST_MACHINE_NAME;
239 a.in.negotiate_flags = &negotiate_flags;
240 a.in.credentials = &credentials3;
241 a.out.credentials = &credentials3;
242 a.out.negotiate_flags = &negotiate_flags;
245 creds_client_init(creds, &credentials1, &credentials2, &mach_password, &credentials3,
248 printf("Testing ServerAuthenticate3\n");
250 status = dcerpc_netr_ServerAuthenticate3(p, mem_ctx, &a);
251 if (!NT_STATUS_IS_OK(status)) {
252 printf("ServerAuthenticate3 - %s\n", nt_errstr(status));
256 if (!creds_client_check(creds, &credentials3)) {
257 printf("Credential chaining failed\n");
261 printf("negotiate_flags=0x%08x\n", negotiate_flags);
275 struct samlogon_state {
277 const char *account_name;
278 const char *account_domain;
279 const char *password;
280 struct dcerpc_pipe *p;
281 struct netr_LogonSamLogon r;
282 struct netr_Authenticator auth, auth2;
283 struct creds_CredentialState creds;
289 Authenticate a user with a challenge/response, checking session key
290 and valid authentication types
292 static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state,
293 enum ntlm_break break_which,
295 DATA_BLOB *lm_response,
296 DATA_BLOB *nt_response,
298 uint8_t user_session_key[16],
302 struct netr_LogonSamLogon *r = &samlogon_state->r;
303 struct netr_NetworkInfo ninfo;
305 struct netr_SamBaseInfo *base;
307 printf("testing netr_LogonSamLogon\n");
309 samlogon_state->r.in.logon.network = &ninfo;
311 ninfo.identity_info.domain_name.string = samlogon_state->account_domain;
312 ninfo.identity_info.parameter_control = 0;
313 ninfo.identity_info.logon_id_low = 0;
314 ninfo.identity_info.logon_id_high = 0;
315 ninfo.identity_info.account_name.string = samlogon_state->account_name;
316 ninfo.identity_info.workstation.string = TEST_MACHINE_NAME;
318 memcpy(ninfo.challenge, chall->data, 8);
320 switch (break_which) {
324 if (lm_response && lm_response->data) {
325 lm_response->data[0]++;
329 if (nt_response && nt_response->data) {
330 nt_response->data[0]++;
334 if (lm_response && lm_response->data) {
335 lm_response->data[0]++;
337 if (nt_response && nt_response->data) {
338 nt_response->data[0]++;
342 data_blob_free(lm_response);
345 data_blob_free(nt_response);
350 ninfo.nt.data = nt_response->data;
351 ninfo.nt.length = nt_response->length;
353 ninfo.nt.data = NULL;
358 ninfo.lm.data = lm_response->data;
359 ninfo.lm.length = lm_response->length;
361 ninfo.lm.data = NULL;
365 ZERO_STRUCT(samlogon_state->auth2);
366 creds_client_authenticator(&samlogon_state->creds, &samlogon_state->auth);
368 r->out.return_authenticator = NULL;
369 status = dcerpc_netr_LogonSamLogon(samlogon_state->p, samlogon_state->mem_ctx, r);
370 if (!NT_STATUS_IS_OK(status)) {
372 *error_string = strdup(nt_errstr(status));
376 if (!r->out.return_authenticator ||
377 !creds_client_check(&samlogon_state->creds, &r->out.return_authenticator->cred)) {
378 printf("Credential chaining failed\n");
381 if (!NT_STATUS_IS_OK(status)) {
382 /* we cannot check the session key, if the logon failed... */
386 /* find and decyrpt the session keys, return in parameters above */
387 switch (r->in.validation_level) {
389 base = &r->out.validation.sam2->base;
392 base = &r->out.validation.sam3->base;
395 base = &r->out.validation.sam6->base;
399 if (r->in.validation_level != 6) {
400 static const char zeros[16];
402 if (memcmp(base->key.key, zeros,
403 sizeof(base->key.key)) != 0) {
404 creds_arcfour_crypt(&samlogon_state->creds,
406 sizeof(base->key.key));
409 if (user_session_key) {
410 memcpy(user_session_key, base->key.key, 16);
413 if (memcmp(base->LMSessKey.key, zeros,
414 sizeof(base->LMSessKey.key)) != 0) {
415 creds_arcfour_crypt(&samlogon_state->creds,
417 sizeof(base->LMSessKey.key));
421 memcpy(lm_key, base->LMSessKey.key, 8);
424 /* they aren't encrypted! */
425 if (user_session_key) {
426 memcpy(user_session_key, base->key.key, 16);
429 memcpy(lm_key, base->LMSessKey.key, 8);
438 * Test the normal 'LM and NTLM' combination
441 static BOOL test_lm_ntlm_broken(struct samlogon_state *samlogon_state, enum ntlm_break break_which, char **error_string)
446 DATA_BLOB lm_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);
447 DATA_BLOB nt_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);
448 DATA_BLOB session_key = data_blob_talloc(samlogon_state->mem_ctx, NULL, 16);
451 uint8_t user_session_key[16];
456 ZERO_STRUCT(user_session_key);
458 lm_good = SMBencrypt(samlogon_state->password, samlogon_state->chall.data, lm_response.data);
460 ZERO_STRUCT(lm_hash);
462 E_deshash(samlogon_state->password, lm_hash);
465 SMBNTencrypt(samlogon_state->password, samlogon_state->chall.data, nt_response.data);
467 E_md4hash(samlogon_state->password, nt_hash);
468 SMBsesskeygen_ntv1(nt_hash, session_key.data);
470 nt_status = check_samlogon(samlogon_state,
472 &samlogon_state->chall,
479 data_blob_free(&lm_response);
481 if (NT_STATUS_EQUAL(NT_STATUS_WRONG_PASSWORD, nt_status)) {
482 /* for 'long' passwords, the LM password is invalid */
483 if (break_which == NO_NT && !lm_good) {
486 return ((break_which == BREAK_NT) || (break_which == BREAK_BOTH));
489 if (!NT_STATUS_IS_OK(nt_status)) {
493 if (break_which == NO_NT && !lm_good) {
494 printf("LM password is 'long' (> 14 chars and therefore invalid) but login did not fail!");
498 if (memcmp(lm_hash, lm_key,
499 sizeof(lm_key)) != 0) {
500 printf("LM Key does not match expectations!\n");
502 dump_data(1, (const char *)lm_key, 8);
503 printf("expected:\n");
504 dump_data(1, (const char *)lm_hash, 8);
508 if (break_which == NO_NT) {
509 char lm_key_expected[16];
510 memcpy(lm_key_expected, lm_hash, 8);
511 memset(lm_key_expected+8, '\0', 8);
512 if (memcmp(lm_key_expected, user_session_key,
514 printf("NT Session Key does not match expectations (should be first-8 LM hash)!\n");
515 printf("user_session_key:\n");
516 dump_data(1, (const char *)user_session_key, sizeof(user_session_key));
517 printf("expected:\n");
518 dump_data(1, (const char *)lm_key_expected, sizeof(lm_key_expected));
522 if (memcmp(session_key.data, user_session_key,
523 sizeof(user_session_key)) != 0) {
524 printf("NT Session Key does not match expectations!\n");
525 printf("user_session_key:\n");
526 dump_data(1, (const char *)user_session_key, 16);
527 printf("expected:\n");
528 dump_data(1, (const char *)session_key.data, session_key.length);
536 * Test LM authentication, no NT response supplied
539 static BOOL test_lm(struct samlogon_state *samlogon_state, char **error_string)
542 return test_lm_ntlm_broken(samlogon_state, NO_NT, error_string);
546 * Test the NTLM response only, no LM.
549 static BOOL test_ntlm(struct samlogon_state *samlogon_state, char **error_string)
551 return test_lm_ntlm_broken(samlogon_state, NO_LM, error_string);
555 * Test the NTLM response only, but in the LM field.
558 static BOOL test_ntlm_in_lm(struct samlogon_state *samlogon_state, char **error_string)
562 DATA_BLOB nt_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);
566 uint8_t user_session_key[16];
568 ZERO_STRUCT(user_session_key);
570 SMBNTencrypt(samlogon_state->password, samlogon_state->chall.data, nt_response.data);
572 E_deshash(samlogon_state->password, lm_hash);
574 nt_status = check_samlogon(samlogon_state,
576 &samlogon_state->chall,
583 if (!NT_STATUS_IS_OK(nt_status)) {
587 if (memcmp(lm_hash, lm_key,
588 sizeof(lm_key)) != 0) {
589 printf("LM Key does not match expectations!\n");
591 dump_data(1, (const char *)lm_key, 8);
592 printf("expected:\n");
593 dump_data(1, (const char *)lm_hash, 8);
596 if (memcmp(lm_hash, user_session_key, 8) != 0) {
597 char lm_key_expected[16];
598 memcpy(lm_key_expected, lm_hash, 8);
599 memset(lm_key_expected+8, '\0', 8);
600 if (memcmp(lm_key_expected, user_session_key,
602 printf("NT Session Key does not match expectations (should be first-8 LM hash)!\n");
603 printf("user_session_key:\n");
604 dump_data(1, (const char *)user_session_key, sizeof(user_session_key));
605 printf("expected:\n");
606 dump_data(1, (const char *)lm_key_expected, sizeof(lm_key_expected));
614 * Test the NTLM response only, but in the both the NT and LM fields.
617 static BOOL test_ntlm_in_both(struct samlogon_state *samlogon_state, char **error_string)
622 DATA_BLOB nt_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);
623 DATA_BLOB session_key = data_blob_talloc(samlogon_state->mem_ctx, NULL, 16);
627 char user_session_key[16];
631 ZERO_STRUCT(user_session_key);
633 SMBNTencrypt(samlogon_state->password, samlogon_state->chall.data,
635 E_md4hash(samlogon_state->password, (uint8_t *)nt_hash);
636 SMBsesskeygen_ntv1((const uint8_t *)nt_hash,
639 lm_good = E_deshash(samlogon_state->password, (uint8_t *)lm_hash);
641 ZERO_STRUCT(lm_hash);
644 nt_status = check_samlogon(samlogon_state,
646 &samlogon_state->chall,
653 if (!NT_STATUS_IS_OK(nt_status)) {
657 if (memcmp(lm_hash, lm_key,
658 sizeof(lm_key)) != 0) {
659 printf("LM Key does not match expectations!\n");
661 dump_data(1, lm_key, 8);
662 printf("expected:\n");
663 dump_data(1, lm_hash, 8);
666 if (memcmp(session_key.data, user_session_key,
667 sizeof(user_session_key)) != 0) {
668 printf("NT Session Key does not match expectations!\n");
669 printf("user_session_key:\n");
670 dump_data(1, user_session_key, 16);
671 printf("expected:\n");
672 dump_data(1, (const char *)session_key.data, session_key.length);
681 * Test the NTLMv2 and LMv2 responses
684 static BOOL test_lmv2_ntlmv2_broken(struct samlogon_state *samlogon_state, enum ntlm_break break_which, char **error_string)
688 DATA_BLOB ntlmv2_response = data_blob(NULL, 0);
689 DATA_BLOB lmv2_response = data_blob(NULL, 0);
690 DATA_BLOB lmv2_session_key = data_blob(NULL, 0);
691 DATA_BLOB ntlmv2_session_key = data_blob(NULL, 0);
692 DATA_BLOB names_blob = NTLMv2_generate_names_blob(samlogon_state->mem_ctx, lp_netbios_name(), lp_workgroup());
694 uint8_t lm_session_key[8];
695 uint8_t user_session_key[16];
697 ZERO_STRUCT(lm_session_key);
698 ZERO_STRUCT(user_session_key);
700 /* TODO - test with various domain cases, and without domain */
701 if (!SMBNTLMv2encrypt(samlogon_state->account_name, samlogon_state->account_domain,
702 samlogon_state->password, &samlogon_state->chall,
704 &lmv2_response, &ntlmv2_response,
705 &lmv2_session_key, &ntlmv2_session_key)) {
706 data_blob_free(&names_blob);
709 data_blob_free(&names_blob);
711 nt_status = check_samlogon(samlogon_state,
713 &samlogon_state->chall,
720 data_blob_free(&lmv2_response);
721 data_blob_free(&ntlmv2_response);
724 if (!NT_STATUS_IS_OK(nt_status)) {
725 return break_which == BREAK_BOTH;
728 if (break_which == NO_NT) {
729 if (memcmp(lmv2_session_key.data, user_session_key,
730 sizeof(user_session_key)) != 0) {
731 printf("USER (NTLMv2) Session Key does not match expectations!\n");
732 printf("user_session_key:\n");
733 dump_data(1, (const char *)user_session_key, 16);
734 printf("expected:\n");
735 dump_data(1, (const char *)lmv2_session_key.data, ntlmv2_session_key.length);
738 if (memcmp(lmv2_session_key.data, lm_session_key,
739 sizeof(lm_session_key)) != 0) {
740 printf("LM (NTLMv2) Session Key does not match expectations!\n");
741 printf("lm_session_key:\n");
742 dump_data(1, (const char *)lm_session_key, 8);
743 printf("expected:\n");
744 dump_data(1, (const char *)lmv2_session_key.data, 8);
748 if (memcmp(ntlmv2_session_key.data, user_session_key,
749 sizeof(user_session_key)) != 0) {
750 printf("USER (NTLMv2) Session Key does not match expectations!\n");
751 printf("user_session_key:\n");
752 dump_data(1, (const char *)user_session_key, 16);
753 printf("expected:\n");
754 dump_data(1, (const char *)ntlmv2_session_key.data, ntlmv2_session_key.length);
757 if (memcmp(ntlmv2_session_key.data, lm_session_key,
758 sizeof(lm_session_key)) != 0) {
759 printf("LM (NTLMv2) Session Key does not match expectations!\n");
760 printf("lm_session_key:\n");
761 dump_data(1, (const char *)lm_session_key, 8);
762 printf("expected:\n");
763 dump_data(1, (const char *)ntlmv2_session_key.data, 8);
772 * Test the NTLMv2 and LMv2 responses
775 static BOOL test_lmv2_ntlmv2(struct samlogon_state *samlogon_state, char **error_string)
777 return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_NONE, error_string);
781 * Test the LMv2 response only
784 static BOOL test_lmv2(struct samlogon_state *samlogon_state, char **error_string)
786 return test_lmv2_ntlmv2_broken(samlogon_state, NO_NT, error_string);
790 * Test the NTLMv2 response only
793 static BOOL test_ntlmv2(struct samlogon_state *samlogon_state, char **error_string)
795 return test_lmv2_ntlmv2_broken(samlogon_state, NO_LM, error_string);
798 static BOOL test_lm_ntlm(struct samlogon_state *samlogon_state, char **error_string)
800 return test_lm_ntlm_broken(samlogon_state, BREAK_NONE, error_string);
803 static BOOL test_ntlm_lm_broken(struct samlogon_state *samlogon_state, char **error_string)
805 return test_lm_ntlm_broken(samlogon_state, BREAK_LM, error_string);
808 static BOOL test_ntlm_ntlm_broken(struct samlogon_state *samlogon_state, char **error_string)
810 return test_lm_ntlm_broken(samlogon_state, BREAK_NT, error_string);
813 static BOOL test_lm_ntlm_both_broken(struct samlogon_state *samlogon_state, char **error_string)
815 return test_lm_ntlm_broken(samlogon_state, BREAK_BOTH, error_string);
817 static BOOL test_ntlmv2_lmv2_broken(struct samlogon_state *samlogon_state, char **error_string)
819 return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_LM, error_string);
822 static BOOL test_ntlmv2_ntlmv2_broken(struct samlogon_state *samlogon_state, char **error_string)
824 return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_NT, error_string);
827 static BOOL test_ntlmv2_both_broken(struct samlogon_state *samlogon_state, char **error_string)
829 return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_BOTH, error_string);
832 static BOOL test_plaintext(struct samlogon_state *samlogon_state, enum ntlm_break break_which, char **error_string)
835 DATA_BLOB nt_response = data_blob(NULL, 0);
836 DATA_BLOB lm_response = data_blob(NULL, 0);
841 uint8_t user_session_key[16];
843 static const uint8_t zeros[8];
844 DATA_BLOB chall = data_blob_talloc(samlogon_state->mem_ctx, zeros, sizeof(zeros));
846 ZERO_STRUCT(user_session_key);
848 if ((push_ucs2_talloc(samlogon_state->mem_ctx, &unicodepw,
849 samlogon_state->password)) == -1) {
850 DEBUG(0, ("push_ucs2_allocate failed!\n"));
854 nt_response = data_blob_talloc(samlogon_state->mem_ctx, unicodepw, utf16_len(unicodepw));
856 password = strupper_talloc(samlogon_state->mem_ctx, samlogon_state->password);
858 if ((convert_string_talloc(samlogon_state->mem_ctx, CH_UNIX,
861 (void**)&dospw)) == -1) {
862 DEBUG(0, ("convert_string_talloc failed!\n"));
866 lm_response = data_blob_talloc(samlogon_state->mem_ctx, dospw, strlen(dospw));
868 nt_status = check_samlogon(samlogon_state,
877 if (!NT_STATUS_IS_OK(nt_status)) {
878 return break_which == BREAK_NT;
884 static BOOL test_plaintext_none_broken(struct samlogon_state *samlogon_state,
885 char **error_string) {
886 return test_plaintext(samlogon_state, BREAK_NONE, error_string);
889 static BOOL test_plaintext_lm_broken(struct samlogon_state *samlogon_state,
890 char **error_string) {
891 return test_plaintext(samlogon_state, BREAK_LM, error_string);
894 static BOOL test_plaintext_nt_broken(struct samlogon_state *samlogon_state,
895 char **error_string) {
896 return test_plaintext(samlogon_state, BREAK_NT, error_string);
899 static BOOL test_plaintext_nt_only(struct samlogon_state *samlogon_state,
900 char **error_string) {
901 return test_plaintext(samlogon_state, NO_LM, error_string);
904 static BOOL test_plaintext_lm_only(struct samlogon_state *samlogon_state,
905 char **error_string) {
906 return test_plaintext(samlogon_state, NO_NT, error_string);
920 - plaintext tests (in challenge-response fields)
922 check we get the correct session key in each case
923 check what values we get for the LM session key
927 static const struct ntlm_tests {
928 BOOL (*fn)(struct samlogon_state *, char **);
932 {test_lm, "LM", False},
933 {test_lm_ntlm, "LM and NTLM", False},
934 {test_lm_ntlm_both_broken, "LM and NTLM, both broken", False},
935 {test_ntlm, "NTLM", False},
936 {test_ntlm_in_lm, "NTLM in LM", False},
937 {test_ntlm_in_both, "NTLM in both", False},
938 {test_ntlmv2, "NTLMv2", False},
939 {test_lmv2_ntlmv2, "NTLMv2 and LMv2", False},
940 {test_lmv2, "LMv2", False},
941 {test_ntlmv2_lmv2_broken, "NTLMv2 and LMv2, LMv2 broken", False},
942 {test_ntlmv2_ntlmv2_broken, "NTLMv2 and LMv2, NTLMv2 broken", False},
943 {test_ntlmv2_both_broken, "NTLMv2 and LMv2, both broken", False},
944 {test_ntlm_lm_broken, "NTLM and LM, LM broken", False},
945 {test_ntlm_ntlm_broken, "NTLM and LM, NTLM broken", False},
946 {test_plaintext_none_broken, "Plaintext", True},
947 {test_plaintext_lm_broken, "Plaintext LM broken", True},
948 {test_plaintext_nt_broken, "Plaintext NT broken", True},
949 {test_plaintext_nt_only, "Plaintext NT only", True},
950 {test_plaintext_lm_only, "Plaintext LM only", True},
955 try a netlogon SamLogon
957 static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
961 int validation_levels[] = {2,3,6};
962 int logon_levels[] = { 2, 6 };
963 struct samlogon_state samlogon_state;
965 samlogon_state.mem_ctx = mem_ctx;
966 samlogon_state.account_name = lp_parm_string(-1, "torture", "username");
967 samlogon_state.account_domain = lp_parm_string(-1, "torture", "userdomain");
968 samlogon_state.password = lp_parm_string(-1, "torture", "password");
969 samlogon_state.p = p;
971 samlogon_state.chall = data_blob_talloc(mem_ctx, NULL, 8);
973 generate_random_buffer(samlogon_state.chall.data, 8);
975 if (!test_SetupCredentials2(p, mem_ctx, NETLOGON_NEG_AUTH2_FLAGS, &samlogon_state.creds)) {
979 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_FLAGS, &samlogon_state.creds)) {
983 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, &samlogon_state.creds)) {
987 samlogon_state.r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
988 samlogon_state.r.in.workstation = TEST_MACHINE_NAME;
989 samlogon_state.r.in.credential = &samlogon_state.auth;
990 samlogon_state.r.in.return_authenticator = &samlogon_state.auth2;
992 for (i=0; test_table[i].fn; i++) {
993 for (v=0;v<ARRAY_SIZE(validation_levels);v++) {
994 for (l=0;l<ARRAY_SIZE(logon_levels);l++) {
995 char *error_string = NULL;
996 samlogon_state.r.in.validation_level = validation_levels[v];
997 samlogon_state.r.in.logon_level = logon_levels[l];
998 printf("Testing SamLogon with '%s' at validation level %d, logon level %d\n",
999 test_table[i].name, validation_levels[v], logon_levels[l]);
1001 if (!test_table[i].fn(&samlogon_state, &error_string)) {
1002 if (test_table[i].expect_fail) {
1003 printf("Test %s failed (expected, test incomplete): %s\n", test_table[i].name, error_string);
1005 printf("Test %s failed: %s\n", test_table[i].name, error_string);
1008 SAFE_FREE(error_string);
1018 test an ADS style interactive domain login
1020 static BOOL test_InteractiveLogin(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1021 struct creds_CredentialState *creds)
1024 struct netr_LogonSamLogonWithFlags r;
1025 struct netr_Authenticator a, ra;
1026 struct netr_PasswordInfo pinfo;
1027 const char *plain_pass;
1032 creds_client_authenticator(creds, &a);
1034 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1035 r.in.workstation = TEST_MACHINE_NAME;
1036 r.in.credential = &a;
1037 r.in.return_authenticator = &ra;
1038 r.in.logon_level = 5;
1039 r.in.logon.password = &pinfo;
1040 r.in.validation_level = 6;
1043 pinfo.identity_info.domain_name.string = lp_parm_string(-1, "torture", "userdomain");
1044 pinfo.identity_info.parameter_control = 0;
1045 pinfo.identity_info.logon_id_low = 0;
1046 pinfo.identity_info.logon_id_high = 0;
1047 pinfo.identity_info.account_name.string = lp_parm_string(-1, "torture", "username");
1048 pinfo.identity_info.workstation.string = TEST_MACHINE_NAME;
1050 plain_pass = lp_parm_string(-1, "torture", "password");
1052 E_deshash(plain_pass, pinfo.lmpassword.hash);
1053 E_md4hash(plain_pass, pinfo.ntpassword.hash);
1055 creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
1056 creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
1058 printf("Testing netr_LogonSamLogonWithFlags\n");
1060 status = dcerpc_netr_LogonSamLogonWithFlags(p, mem_ctx, &r);
1061 if (!NT_STATUS_IS_OK(status)) {
1062 printf("netr_LogonSamLogonWithFlags - %s\n", nt_errstr(status));
1067 if (!creds_client_check(creds, &r.out.return_authenticator->cred)) {
1068 printf("Credential chaining failed\n");
1078 try a change password for our machine account
1080 static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1083 struct netr_ServerPasswordSet r;
1084 const char *password;
1085 struct creds_CredentialState creds;
1087 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
1091 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1092 r.in.account_name = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
1093 r.in.secure_channel_type = SEC_CHAN_BDC;
1094 r.in.computer_name = TEST_MACHINE_NAME;
1096 password = generate_random_str(mem_ctx, 8);
1097 E_md4hash(password, r.in.new_password.hash);
1099 creds_des_encrypt(&creds, &r.in.new_password);
1101 printf("Testing ServerPasswordSet on machine account\n");
1102 printf("Changing machine account password to '%s'\n", password);
1104 creds_client_authenticator(&creds, &r.in.credential);
1106 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
1107 if (!NT_STATUS_IS_OK(status)) {
1108 printf("ServerPasswordSet - %s\n", nt_errstr(status));
1112 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
1113 printf("Credential chaining failed\n");
1116 /* by changing the machine password twice we test the
1117 credentials chaining fully, and we verify that the server
1118 allows the password to be set to the same value twice in a
1119 row (match win2k3) */
1120 printf("Testing a second ServerPasswordSet on machine account\n");
1121 printf("Changing machine account password to '%s' (same as previous run)\n", password);
1123 creds_client_authenticator(&creds, &r.in.credential);
1125 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
1126 if (!NT_STATUS_IS_OK(status)) {
1127 printf("ServerPasswordSet (2) - %s\n", nt_errstr(status));
1131 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
1132 printf("Credential chaining failed\n");
1135 machine_password = password;
1137 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
1138 printf("ServerPasswordSet failed to actually change the password\n");
1146 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
1147 static uint64_t sequence_nums[3];
1150 try a netlogon DatabaseSync
1152 static BOOL test_DatabaseSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1155 struct netr_DatabaseSync r;
1156 struct creds_CredentialState creds;
1157 const uint32_t database_ids[] = {0, 1, 2};
1161 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
1165 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1166 r.in.computername = TEST_MACHINE_NAME;
1167 r.in.preferredmaximumlength = (uint32_t)-1;
1168 ZERO_STRUCT(r.in.return_authenticator);
1170 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1171 r.in.sync_context = 0;
1172 r.in.database_id = database_ids[i];
1174 printf("Testing DatabaseSync of id %d\n", r.in.database_id);
1177 creds_client_authenticator(&creds, &r.in.credential);
1179 status = dcerpc_netr_DatabaseSync(p, mem_ctx, &r);
1180 if (!NT_STATUS_IS_OK(status) &&
1181 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
1182 printf("DatabaseSync - %s\n", nt_errstr(status));
1187 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
1188 printf("Credential chaining failed\n");
1191 r.in.sync_context = r.out.sync_context;
1193 if (r.out.delta_enum_array &&
1194 r.out.delta_enum_array->num_deltas > 0 &&
1195 r.out.delta_enum_array->delta_enum[0].delta_type == 1 &&
1196 r.out.delta_enum_array->delta_enum[0].delta_union.domain) {
1197 sequence_nums[r.in.database_id] =
1198 r.out.delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
1199 printf("\tsequence_nums[%d]=%llu\n",
1201 sequence_nums[r.in.database_id]);
1203 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
1211 try a netlogon DatabaseDeltas
1213 static BOOL test_DatabaseDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1216 struct netr_DatabaseDeltas r;
1217 struct creds_CredentialState creds;
1218 const uint32_t database_ids[] = {0, 1, 2};
1222 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
1226 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1227 r.in.computername = TEST_MACHINE_NAME;
1228 r.in.preferredmaximumlength = (uint32_t)-1;
1229 ZERO_STRUCT(r.in.return_authenticator);
1231 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1232 r.in.database_id = database_ids[i];
1233 r.in.sequence_num = sequence_nums[r.in.database_id];
1235 if (r.in.sequence_num == 0) continue;
1237 r.in.sequence_num -= 1;
1240 printf("Testing DatabaseDeltas of id %d at %llu\n",
1241 r.in.database_id, r.in.sequence_num);
1244 creds_client_authenticator(&creds, &r.in.credential);
1246 status = dcerpc_netr_DatabaseDeltas(p, mem_ctx, &r);
1247 if (!NT_STATUS_IS_OK(status) &&
1248 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
1249 printf("DatabaseDeltas - %s\n", nt_errstr(status));
1254 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
1255 printf("Credential chaining failed\n");
1258 r.in.sequence_num++;
1259 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
1267 try a netlogon AccountDeltas
1269 static BOOL test_AccountDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1272 struct netr_AccountDeltas r;
1273 struct creds_CredentialState creds;
1276 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
1280 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1281 r.in.computername = TEST_MACHINE_NAME;
1282 ZERO_STRUCT(r.in.return_authenticator);
1283 creds_client_authenticator(&creds, &r.in.credential);
1284 ZERO_STRUCT(r.in.uas);
1287 r.in.buffersize=100;
1289 printf("Testing AccountDeltas\n");
1291 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1292 status = dcerpc_netr_AccountDeltas(p, mem_ctx, &r);
1293 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
1294 printf("AccountDeltas - %s\n", nt_errstr(status));
1302 try a netlogon AccountSync
1304 static BOOL test_AccountSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1307 struct netr_AccountSync r;
1308 struct creds_CredentialState creds;
1311 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
1315 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1316 r.in.computername = TEST_MACHINE_NAME;
1317 ZERO_STRUCT(r.in.return_authenticator);
1318 creds_client_authenticator(&creds, &r.in.credential);
1319 ZERO_STRUCT(r.in.recordid);
1322 r.in.buffersize=100;
1324 printf("Testing AccountSync\n");
1326 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1327 status = dcerpc_netr_AccountSync(p, mem_ctx, &r);
1328 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
1329 printf("AccountSync - %s\n", nt_errstr(status));
1337 try a netlogon GetDcName
1339 static BOOL test_GetDcName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1342 struct netr_GetDcName r;
1344 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1345 r.in.domainname = lp_workgroup();
1347 printf("Testing GetDcName\n");
1349 status = dcerpc_netr_GetDcName(p, mem_ctx, &r);
1350 if (!NT_STATUS_IS_OK(status)) {
1351 printf("GetDcName - %s\n", nt_errstr(status));
1355 printf("\tDC is at '%s'\n", r.out.dcname);
1361 try a netlogon LogonControl
1363 static BOOL test_LogonControl(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1366 struct netr_LogonControl r;
1370 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1371 r.in.function_code = 1;
1376 printf("Testing LogonControl level %d\n", i);
1378 status = dcerpc_netr_LogonControl(p, mem_ctx, &r);
1379 if (!NT_STATUS_IS_OK(status)) {
1380 printf("LogonControl - %s\n", nt_errstr(status));
1390 try a netlogon GetAnyDCName
1392 static BOOL test_GetAnyDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1395 struct netr_GetAnyDCName r;
1397 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1398 r.in.domainname = lp_workgroup();
1400 printf("Testing GetAnyDCName\n");
1402 status = dcerpc_netr_GetAnyDCName(p, mem_ctx, &r);
1403 if (!NT_STATUS_IS_OK(status)) {
1404 printf("GetAnyDCName - %s\n", nt_errstr(status));
1409 printf("\tDC is at '%s'\n", r.out.dcname);
1417 try a netlogon LogonControl2
1419 static BOOL test_LogonControl2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1422 struct netr_LogonControl2 r;
1426 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1428 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1429 r.in.data.domain = lp_workgroup();
1434 printf("Testing LogonControl2 level %d function %d\n",
1435 i, r.in.function_code);
1437 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
1438 if (!NT_STATUS_IS_OK(status)) {
1439 printf("LogonControl - %s\n", nt_errstr(status));
1444 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1445 r.in.data.domain = lp_workgroup();
1450 printf("Testing LogonControl2 level %d function %d\n",
1451 i, r.in.function_code);
1453 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
1454 if (!NT_STATUS_IS_OK(status)) {
1455 printf("LogonControl - %s\n", nt_errstr(status));
1460 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1461 r.in.data.domain = lp_workgroup();
1466 printf("Testing LogonControl2 level %d function %d\n",
1467 i, r.in.function_code);
1469 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
1470 if (!NT_STATUS_IS_OK(status)) {
1471 printf("LogonControl - %s\n", nt_errstr(status));
1476 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1477 r.in.data.debug_level = ~0;
1482 printf("Testing LogonControl2 level %d function %d\n",
1483 i, r.in.function_code);
1485 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
1486 if (!NT_STATUS_IS_OK(status)) {
1487 printf("LogonControl - %s\n", nt_errstr(status));
1496 try a netlogon DatabaseSync2
1498 static BOOL test_DatabaseSync2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1501 struct netr_DatabaseSync2 r;
1502 struct creds_CredentialState creds;
1503 const uint32_t database_ids[] = {0, 1, 2};
1507 if (!test_SetupCredentials2(p, mem_ctx, NETLOGON_NEG_AUTH2_FLAGS, &creds)) {
1511 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1512 r.in.computername = TEST_MACHINE_NAME;
1513 r.in.preferredmaximumlength = (uint32_t)-1;
1514 ZERO_STRUCT(r.in.return_authenticator);
1516 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1517 r.in.sync_context = 0;
1518 r.in.database_id = database_ids[i];
1519 r.in.restart_state = 0;
1521 printf("Testing DatabaseSync2 of id %d\n", r.in.database_id);
1524 creds_client_authenticator(&creds, &r.in.credential);
1526 status = dcerpc_netr_DatabaseSync2(p, mem_ctx, &r);
1527 if (!NT_STATUS_IS_OK(status) &&
1528 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
1529 printf("DatabaseSync2 - %s\n", nt_errstr(status));
1534 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
1535 printf("Credential chaining failed\n");
1538 r.in.sync_context = r.out.sync_context;
1539 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
1547 try a netlogon LogonControl2Ex
1549 static BOOL test_LogonControl2Ex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1552 struct netr_LogonControl2Ex r;
1556 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1558 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1559 r.in.data.domain = lp_workgroup();
1564 printf("Testing LogonControl2Ex level %d function %d\n",
1565 i, r.in.function_code);
1567 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1568 if (!NT_STATUS_IS_OK(status)) {
1569 printf("LogonControl - %s\n", nt_errstr(status));
1574 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1575 r.in.data.domain = lp_workgroup();
1580 printf("Testing LogonControl2Ex level %d function %d\n",
1581 i, r.in.function_code);
1583 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1584 if (!NT_STATUS_IS_OK(status)) {
1585 printf("LogonControl - %s\n", nt_errstr(status));
1590 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1591 r.in.data.domain = lp_workgroup();
1596 printf("Testing LogonControl2Ex level %d function %d\n",
1597 i, r.in.function_code);
1599 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1600 if (!NT_STATUS_IS_OK(status)) {
1601 printf("LogonControl - %s\n", nt_errstr(status));
1606 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1607 r.in.data.debug_level = ~0;
1612 printf("Testing LogonControl2Ex level %d function %d\n",
1613 i, r.in.function_code);
1615 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1616 if (!NT_STATUS_IS_OK(status)) {
1617 printf("LogonControl - %s\n", nt_errstr(status));
1627 try a netlogon netr_DsrEnumerateDomainTrusts
1629 static BOOL test_DsrEnumerateDomainTrusts(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1632 struct netr_DsrEnumerateDomainTrusts r;
1634 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1635 r.in.trust_flags = 0x3f;
1637 printf("Testing netr_DsrEnumerateDomainTrusts\n");
1639 status = dcerpc_netr_DsrEnumerateDomainTrusts(p, mem_ctx, &r);
1640 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1641 printf("netr_DsrEnumerateDomainTrusts - %s/%s\n",
1642 nt_errstr(status), win_errstr(r.out.result));
1650 static BOOL test_GetDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1653 struct netr_LogonGetDomainInfo r;
1654 struct netr_DomainQuery1 q1;
1655 struct netr_Authenticator a;
1656 struct creds_CredentialState creds;
1658 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, &creds)) {
1664 creds_client_authenticator(&creds, &a);
1666 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1667 r.in.computer_name = TEST_MACHINE_NAME;
1668 r.in.unknown1 = 512;
1670 r.in.credential = &a;
1671 r.out.credential = &a;
1676 r.in.query.query1 = &q1;
1679 /* this should really be the fully qualified name */
1680 q1.workstation_domain = TEST_MACHINE_NAME;
1681 q1.workstation_site = "Default-First-Site-Name";
1682 q1.blob2.length = 0;
1684 q1.blob2.data = NULL;
1685 q1.product.string = "product string";
1687 printf("Testing netr_LogonGetDomainInfo\n");
1689 status = dcerpc_netr_LogonGetDomainInfo(p, mem_ctx, &r);
1690 if (!NT_STATUS_IS_OK(status)) {
1691 printf("netr_LogonGetDomainInfo - %s\n", nt_errstr(status));
1695 if (!creds_client_check(&creds, &a.cred)) {
1696 printf("Credential chaining failed\n");
1700 test_InteractiveLogin(p, mem_ctx, &creds);
1706 static void async_callback(struct rpc_request *req)
1708 int *counter = req->async.private;
1709 if (NT_STATUS_IS_OK(req->status)) {
1714 static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1717 struct netr_LogonGetDomainInfo r;
1718 struct netr_DomainQuery1 q1;
1719 struct netr_Authenticator a;
1720 #define ASYNC_COUNT 100
1721 struct creds_CredentialState creds;
1722 struct creds_CredentialState creds_async[ASYNC_COUNT];
1723 struct rpc_request *req[ASYNC_COUNT];
1725 int async_counter = 0;
1727 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, &creds)) {
1732 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1733 r.in.computer_name = TEST_MACHINE_NAME;
1734 r.in.unknown1 = 512;
1736 r.in.credential = &a;
1737 r.out.credential = &a;
1742 r.in.query.query1 = &q1;
1745 /* this should really be the fully qualified name */
1746 q1.workstation_domain = TEST_MACHINE_NAME;
1747 q1.workstation_site = "Default-First-Site-Name";
1748 q1.blob2.length = 0;
1750 q1.blob2.data = NULL;
1751 q1.product.string = "product string";
1753 printf("Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
1755 for (i=0;i<ASYNC_COUNT;i++) {
1756 creds_client_authenticator(&creds, &a);
1758 creds_async[i] = creds;
1759 req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, mem_ctx, &r);
1761 req[i]->async.callback = async_callback;
1762 req[i]->async.private = &async_counter;
1764 /* even with this flush per request a w2k3 server seems to
1765 clag with multiple outstanding requests. bleergh. */
1766 if (event_loop_once(dcerpc_event_context(p)) != 0) {
1771 for (i=0;i<ASYNC_COUNT;i++) {
1772 status = dcerpc_ndr_request_recv(req[i]);
1773 if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(r.out.result)) {
1774 printf("netr_LogonGetDomainInfo_async(%d) - %s/%s\n",
1775 i, nt_errstr(status), nt_errstr(r.out.result));
1779 if (!creds_client_check(&creds_async[i], &a.cred)) {
1780 printf("Credential chaining failed at async %d\n", i);
1785 printf("Testing netr_LogonGetDomainInfo - async count %d OK\n", async_counter);
1787 return async_counter == ASYNC_COUNT;
1791 BOOL torture_rpc_netlogon(void)
1794 struct dcerpc_pipe *p;
1795 TALLOC_CTX *mem_ctx;
1799 mem_ctx = talloc_init("torture_rpc_netlogon");
1801 join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), ACB_SVRTRUST,
1804 printf("Failed to join as BDC\n");
1808 status = torture_rpc_connection(&p,
1809 DCERPC_NETLOGON_NAME,
1810 DCERPC_NETLOGON_UUID,
1811 DCERPC_NETLOGON_VERSION);
1812 if (!NT_STATUS_IS_OK(status)) {
1816 if (!test_LogonUasLogon(p, mem_ctx)) {
1820 if (!test_LogonUasLogoff(p, mem_ctx)) {
1824 if (!test_SetPassword(p, mem_ctx)) {
1828 if (!test_SamLogon(p, mem_ctx)) {
1832 if (!test_GetDomainInfo(p, mem_ctx)) {
1836 if (!test_DatabaseSync(p, mem_ctx)) {
1840 if (!test_DatabaseDeltas(p, mem_ctx)) {
1844 if (!test_AccountDeltas(p, mem_ctx)) {
1848 if (!test_AccountSync(p, mem_ctx)) {
1852 if (!test_GetDcName(p, mem_ctx)) {
1856 if (!test_LogonControl(p, mem_ctx)) {
1860 if (!test_GetAnyDCName(p, mem_ctx)) {
1864 if (!test_LogonControl2(p, mem_ctx)) {
1868 if (!test_DatabaseSync2(p, mem_ctx)) {
1872 if (!test_LogonControl2Ex(p, mem_ctx)) {
1876 if (!test_DsrEnumerateDomainTrusts(p, mem_ctx)) {
1880 if (!test_GetDomainInfo_async(p, mem_ctx)) {
1884 talloc_destroy(mem_ctx);
1886 torture_rpc_close(p);
1888 torture_leave_domain(join_ctx);