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.
28 static const char *machine_password;
30 #define TEST_MACHINE_NAME "torturetest"
32 static BOOL test_LogonUasLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
35 struct netr_LogonUasLogon r;
37 r.in.server_name = NULL;
38 r.in.account_name = lp_parm_string(-1, "torture", "username");
39 r.in.workstation = TEST_MACHINE_NAME;
41 printf("Testing LogonUasLogon\n");
43 status = dcerpc_netr_LogonUasLogon(p, mem_ctx, &r);
44 if (!NT_STATUS_IS_OK(status)) {
45 printf("LogonUasLogon - %s\n", nt_errstr(status));
53 static BOOL test_LogonUasLogoff(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
56 struct netr_LogonUasLogoff r;
58 r.in.server_name = NULL;
59 r.in.account_name = lp_parm_string(-1, "torture", "username");
60 r.in.workstation = TEST_MACHINE_NAME;
62 printf("Testing LogonUasLogoff\n");
64 status = dcerpc_netr_LogonUasLogoff(p, mem_ctx, &r);
65 if (!NT_STATUS_IS_OK(status)) {
66 printf("LogonUasLogoff - %s\n", nt_errstr(status));
74 static BOOL test_SetupCredentials(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
75 struct creds_CredentialState *creds)
78 struct netr_ServerReqChallenge r;
79 struct netr_ServerAuthenticate a;
80 struct netr_Credential credentials1, credentials2, credentials3;
81 const char *plain_pass;
82 struct samr_Password mach_password;
84 printf("Testing ServerReqChallenge\n");
86 r.in.server_name = NULL;
87 r.in.computer_name = TEST_MACHINE_NAME;
88 r.in.credentials = &credentials1;
89 r.out.credentials = &credentials2;
91 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
93 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
94 if (!NT_STATUS_IS_OK(status)) {
95 printf("ServerReqChallenge - %s\n", nt_errstr(status));
99 plain_pass = machine_password;
101 printf("Unable to fetch machine password!\n");
105 E_md4hash(plain_pass, mach_password.hash);
107 a.in.server_name = NULL;
108 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
109 a.in.secure_channel_type = SEC_CHAN_BDC;
110 a.in.computer_name = TEST_MACHINE_NAME;
111 a.in.credentials = &credentials3;
112 a.out.credentials = &credentials3;
114 creds_client_init(creds, &credentials1, &credentials2, &mach_password, &credentials3,
115 NETLOGON_NEG_AUTH2_FLAGS);
117 printf("Testing ServerAuthenticate\n");
119 status = dcerpc_netr_ServerAuthenticate(p, mem_ctx, &a);
120 if (!NT_STATUS_IS_OK(status)) {
121 printf("ServerAuthenticate - %s\n", nt_errstr(status));
125 if (!creds_client_check(creds, &credentials3)) {
126 printf("Credential chaining failed\n");
133 static BOOL test_SetupCredentials2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
134 uint32_t negotiate_flags,
135 struct creds_CredentialState *creds)
138 struct netr_ServerReqChallenge r;
139 struct netr_ServerAuthenticate2 a;
140 struct netr_Credential credentials1, credentials2, credentials3;
141 const char *plain_pass;
142 struct samr_Password mach_password;
144 printf("Testing ServerReqChallenge\n");
146 r.in.server_name = NULL;
147 r.in.computer_name = TEST_MACHINE_NAME;
148 r.in.credentials = &credentials1;
149 r.out.credentials = &credentials2;
151 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
153 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
154 if (!NT_STATUS_IS_OK(status)) {
155 printf("ServerReqChallenge - %s\n", nt_errstr(status));
159 plain_pass = machine_password;
161 printf("Unable to fetch machine password!\n");
165 E_md4hash(plain_pass, mach_password.hash);
167 a.in.server_name = NULL;
168 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
169 a.in.secure_channel_type = SEC_CHAN_BDC;
170 a.in.computer_name = TEST_MACHINE_NAME;
171 a.in.negotiate_flags = &negotiate_flags;
172 a.out.negotiate_flags = &negotiate_flags;
173 a.in.credentials = &credentials3;
174 a.out.credentials = &credentials3;
176 creds_client_init(creds, &credentials1, &credentials2, &mach_password, &credentials3,
179 printf("Testing ServerAuthenticate2\n");
181 status = dcerpc_netr_ServerAuthenticate2(p, mem_ctx, &a);
182 if (!NT_STATUS_IS_OK(status)) {
183 printf("ServerAuthenticate2 - %s\n", nt_errstr(status));
187 if (!creds_client_check(creds, &credentials3)) {
188 printf("Credential chaining failed\n");
192 printf("negotiate_flags=0x%08x\n", negotiate_flags);
198 static BOOL test_SetupCredentials3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
199 uint32_t negotiate_flags,
200 struct creds_CredentialState *creds)
203 struct netr_ServerReqChallenge r;
204 struct netr_ServerAuthenticate3 a;
205 struct netr_Credential credentials1, credentials2, credentials3;
206 const char *plain_pass;
207 struct samr_Password mach_password;
210 printf("Testing ServerReqChallenge\n");
212 r.in.server_name = NULL;
213 r.in.computer_name = TEST_MACHINE_NAME;
214 r.in.credentials = &credentials1;
215 r.out.credentials = &credentials2;
217 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
219 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
220 if (!NT_STATUS_IS_OK(status)) {
221 printf("ServerReqChallenge - %s\n", nt_errstr(status));
225 plain_pass = machine_password;
227 printf("Unable to fetch machine password!\n");
231 E_md4hash(plain_pass, mach_password.hash);
233 a.in.server_name = NULL;
234 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
235 a.in.secure_channel_type = SEC_CHAN_BDC;
236 a.in.computer_name = TEST_MACHINE_NAME;
237 a.in.negotiate_flags = &negotiate_flags;
238 a.in.credentials = &credentials3;
239 a.out.credentials = &credentials3;
240 a.out.negotiate_flags = &negotiate_flags;
243 creds_client_init(creds, &credentials1, &credentials2, &mach_password, &credentials3,
246 printf("Testing ServerAuthenticate3\n");
248 status = dcerpc_netr_ServerAuthenticate3(p, mem_ctx, &a);
249 if (!NT_STATUS_IS_OK(status)) {
250 printf("ServerAuthenticate3 - %s\n", nt_errstr(status));
254 if (!creds_client_check(creds, &credentials3)) {
255 printf("Credential chaining failed\n");
259 printf("negotiate_flags=0x%08x\n", negotiate_flags);
272 struct samlogon_state {
274 const char *account_name;
275 const char *account_domain;
276 const char *password;
277 struct dcerpc_pipe *p;
278 struct netr_LogonSamLogon r;
279 struct netr_Authenticator auth, auth2;
280 struct creds_CredentialState creds;
285 Authenticate a user with a challenge/response, checking session key
286 and valid authentication types
288 static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state,
289 enum ntlm_break break_which,
291 DATA_BLOB *lm_response,
292 DATA_BLOB *nt_response,
294 uint8_t user_session_key[16],
298 struct netr_LogonSamLogon *r = &samlogon_state->r;
299 struct netr_NetworkInfo ninfo;
301 struct netr_SamBaseInfo *base;
303 printf("testing netr_LogonSamLogon\n");
305 samlogon_state->r.in.logon.network = &ninfo;
307 ninfo.identity_info.domain_name.string = samlogon_state->account_domain;
308 ninfo.identity_info.parameter_control = 0;
309 ninfo.identity_info.logon_id_low = 0;
310 ninfo.identity_info.logon_id_high = 0;
311 ninfo.identity_info.account_name.string = samlogon_state->account_name;
312 ninfo.identity_info.workstation.string = TEST_MACHINE_NAME;
314 memcpy(ninfo.challenge, chall->data, 8);
316 switch (break_which) {
320 if (lm_response && lm_response->data) {
321 lm_response->data[0]++;
325 if (nt_response && nt_response->data) {
326 nt_response->data[0]++;
330 data_blob_free(lm_response);
333 data_blob_free(nt_response);
338 ninfo.nt.data = nt_response->data;
339 ninfo.nt.length = nt_response->length;
341 ninfo.nt.data = NULL;
346 ninfo.lm.data = lm_response->data;
347 ninfo.lm.length = lm_response->length;
349 ninfo.lm.data = NULL;
353 ZERO_STRUCT(samlogon_state->auth2);
354 creds_client_authenticator(&samlogon_state->creds, &samlogon_state->auth);
356 r->out.return_authenticator = NULL;
357 status = dcerpc_netr_LogonSamLogon(samlogon_state->p, samlogon_state->mem_ctx, r);
358 if (!NT_STATUS_IS_OK(status)) {
360 *error_string = strdup(nt_errstr(status));
364 if (!r->out.return_authenticator ||
365 !creds_client_check(&samlogon_state->creds, &r->out.return_authenticator->cred)) {
366 printf("Credential chaining failed\n");
369 if (!NT_STATUS_IS_OK(status)) {
370 /* we cannot check the session key, if the logon failed... */
374 /* find and decyrpt the session keys, return in parameters above */
375 if (r->in.validation_level == 2) {
376 base = &r->out.validation.sam2->base;
377 } else if (r->in.validation_level == 3) {
378 base = &r->out.validation.sam3->base;
379 } else if (r->in.validation_level == 6) {
380 base = &r->out.validation.sam6->base;
385 if (r->in.validation_level != 6) {
386 static const char zeros[16];
388 if (memcmp(base->key.key, zeros,
389 sizeof(base->key.key)) != 0) {
390 creds_arcfour_crypt(&samlogon_state->creds,
392 sizeof(base->key.key));
395 if (user_session_key) {
396 memcpy(user_session_key, base->key.key, 16);
399 if (memcmp(base->LMSessKey.key, zeros,
400 sizeof(base->LMSessKey.key)) != 0) {
401 creds_arcfour_crypt(&samlogon_state->creds,
403 sizeof(base->LMSessKey.key));
407 memcpy(lm_key, base->LMSessKey.key, 8);
410 /* they aren't encrypted! */
411 if (user_session_key) {
412 memcpy(user_session_key, base->key.key, 16);
415 memcpy(lm_key, base->LMSessKey.key, 8);
424 * Test the normal 'LM and NTLM' combination
427 static BOOL test_lm_ntlm_broken(struct samlogon_state *samlogon_state, enum ntlm_break break_which, char **error_string)
432 DATA_BLOB lm_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);
433 DATA_BLOB nt_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);
434 DATA_BLOB session_key = data_blob_talloc(samlogon_state->mem_ctx, NULL, 16);
437 uint8_t user_session_key[16];
442 ZERO_STRUCT(user_session_key);
444 lm_good = SMBencrypt(samlogon_state->password, samlogon_state->chall.data, lm_response.data);
445 if (samlogon_state->r.in.logon_level == 6 || !lm_good) {
446 ZERO_STRUCT(lm_hash);
448 E_deshash(samlogon_state->password, lm_hash);
451 SMBNTencrypt(samlogon_state->password, samlogon_state->chall.data, nt_response.data);
453 E_md4hash(samlogon_state->password, nt_hash);
454 SMBsesskeygen_ntv1(nt_hash, session_key.data);
456 nt_status = check_samlogon(samlogon_state,
458 &samlogon_state->chall,
465 data_blob_free(&lm_response);
467 if (NT_STATUS_EQUAL(NT_STATUS_WRONG_PASSWORD, nt_status)) {
468 /* for 'long' passwords, the LM password is invalid */
469 if (break_which == NO_NT && !lm_good) {
472 return break_which == BREAK_NT;
475 if (!NT_STATUS_IS_OK(nt_status)) {
479 if (break_which == NO_NT && !lm_good) {
480 printf("LM password is 'long' (> 14 chars and therefore invalid) but login did not fail!");
484 if (memcmp(lm_hash, lm_key,
485 sizeof(lm_key)) != 0) {
486 printf("LM Key does not match expectations!\n");
488 dump_data(1, (const char *)lm_key, 8);
489 printf("expected:\n");
490 dump_data(1, (const char *)lm_hash, 8);
494 if (break_which == NO_NT) {
495 char lm_key_expected[16];
496 memcpy(lm_key_expected, lm_hash, 8);
497 memset(lm_key_expected+8, '\0', 8);
498 if (memcmp(lm_key_expected, user_session_key,
500 printf("NT Session Key does not match expectations (should be first-8 LM hash)!\n");
501 printf("user_session_key:\n");
502 dump_data(1, (const char *)user_session_key, sizeof(user_session_key));
503 printf("expected:\n");
504 dump_data(1, (const char *)lm_key_expected, sizeof(lm_key_expected));
508 if (memcmp(session_key.data, user_session_key,
509 sizeof(user_session_key)) != 0) {
510 printf("NT Session Key does not match expectations!\n");
511 printf("user_session_key:\n");
512 dump_data(1, (const char *)user_session_key, 16);
513 printf("expected:\n");
514 dump_data(1, (const char *)session_key.data, session_key.length);
522 * Test LM authentication, no NT response supplied
525 static BOOL test_lm(struct samlogon_state *samlogon_state, char **error_string)
528 return test_lm_ntlm_broken(samlogon_state, NO_NT, error_string);
532 * Test the NTLM response only, no LM.
535 static BOOL test_ntlm(struct samlogon_state *samlogon_state, char **error_string)
537 return test_lm_ntlm_broken(samlogon_state, NO_LM, error_string);
541 * Test the NTLM response only, but in the LM field.
544 static BOOL test_ntlm_in_lm(struct samlogon_state *samlogon_state, char **error_string)
548 DATA_BLOB nt_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);
552 uint8_t user_session_key[16];
554 ZERO_STRUCT(user_session_key);
556 SMBNTencrypt(samlogon_state->password, samlogon_state->chall.data, nt_response.data);
558 E_deshash(samlogon_state->password, lm_hash);
560 nt_status = check_samlogon(samlogon_state,
562 &samlogon_state->chall,
569 if (!NT_STATUS_IS_OK(nt_status)) {
573 if (memcmp(lm_hash, lm_key,
574 sizeof(lm_key)) != 0) {
575 printf("LM Key does not match expectations!\n");
577 dump_data(1, (const char *)lm_key, 8);
578 printf("expected:\n");
579 dump_data(1, (const char *)lm_hash, 8);
582 if (memcmp(lm_hash, user_session_key, 8) != 0) {
583 char lm_key_expected[16];
584 memcpy(lm_key_expected, lm_hash, 8);
585 memset(lm_key_expected+8, '\0', 8);
586 if (memcmp(lm_key_expected, user_session_key,
588 printf("NT Session Key does not match expectations (should be first-8 LM hash)!\n");
589 printf("user_session_key:\n");
590 dump_data(1, (const char *)user_session_key, sizeof(user_session_key));
591 printf("expected:\n");
592 dump_data(1, (const char *)lm_key_expected, sizeof(lm_key_expected));
600 * Test the NTLM response only, but in the both the NT and LM fields.
603 static BOOL test_ntlm_in_both(struct samlogon_state *samlogon_state, char **error_string)
608 DATA_BLOB nt_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);
609 DATA_BLOB session_key = data_blob_talloc(samlogon_state->mem_ctx, NULL, 16);
613 char user_session_key[16];
617 ZERO_STRUCT(user_session_key);
619 SMBNTencrypt(samlogon_state->password, samlogon_state->chall.data,
621 E_md4hash(samlogon_state->password, (uint8_t *)nt_hash);
622 SMBsesskeygen_ntv1((const uint8_t *)nt_hash,
625 lm_good = E_deshash(samlogon_state->password, (uint8_t *)lm_hash);
627 ZERO_STRUCT(lm_hash);
630 nt_status = check_samlogon(samlogon_state,
632 &samlogon_state->chall,
639 if (!NT_STATUS_IS_OK(nt_status)) {
643 if (memcmp(lm_hash, lm_key,
644 sizeof(lm_key)) != 0) {
645 printf("LM Key does not match expectations!\n");
647 dump_data(1, lm_key, 8);
648 printf("expected:\n");
649 dump_data(1, lm_hash, 8);
652 if (memcmp(session_key.data, user_session_key,
653 sizeof(user_session_key)) != 0) {
654 printf("NT Session Key does not match expectations!\n");
655 printf("user_session_key:\n");
656 dump_data(1, user_session_key, 16);
657 printf("expected:\n");
658 dump_data(1, (const char *)session_key.data, session_key.length);
667 * Test the NTLMv2 and LMv2 responses
670 static BOOL test_lmv2_ntlmv2_broken(struct samlogon_state *samlogon_state, enum ntlm_break break_which, char **error_string)
674 DATA_BLOB ntlmv2_response = data_blob(NULL, 0);
675 DATA_BLOB lmv2_response = data_blob(NULL, 0);
676 DATA_BLOB ntlmv2_session_key = data_blob(NULL, 0);
677 DATA_BLOB names_blob = NTLMv2_generate_names_blob(samlogon_state->mem_ctx, lp_netbios_name(), lp_workgroup());
679 uint8_t user_session_key[16];
681 ZERO_STRUCT(user_session_key);
683 /* TODO - test with various domain cases, and without domain */
684 if (!SMBNTLMv2encrypt(samlogon_state->account_name, samlogon_state->account_domain,
685 samlogon_state->password, &samlogon_state->chall,
687 &lmv2_response, &ntlmv2_response,
688 &ntlmv2_session_key)) {
689 data_blob_free(&names_blob);
692 data_blob_free(&names_blob);
694 nt_status = check_samlogon(samlogon_state,
696 &samlogon_state->chall,
703 data_blob_free(&lmv2_response);
704 data_blob_free(&ntlmv2_response);
706 if (!NT_STATUS_IS_OK(nt_status)) {
707 return break_which == BREAK_NT;
710 if (break_which != NO_NT && break_which != BREAK_NT && memcmp(ntlmv2_session_key.data, user_session_key,
711 sizeof(user_session_key)) != 0) {
712 printf("USER (NTLMv2) Session Key does not match expectations!\n");
713 printf("user_session_key:\n");
714 dump_data(1, (const char *)user_session_key, 16);
715 printf("expected:\n");
716 dump_data(1, (const char *)ntlmv2_session_key.data, ntlmv2_session_key.length);
723 * Test the NTLMv2 and LMv2 responses
726 static BOOL test_lmv2_ntlmv2(struct samlogon_state *samlogon_state, char **error_string)
728 return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_NONE, error_string);
732 * Test the LMv2 response only
735 static BOOL test_lmv2(struct samlogon_state *samlogon_state, char **error_string)
737 return test_lmv2_ntlmv2_broken(samlogon_state, NO_NT, error_string);
741 * Test the NTLMv2 response only
744 static BOOL test_ntlmv2(struct samlogon_state *samlogon_state, char **error_string)
746 return test_lmv2_ntlmv2_broken(samlogon_state, NO_LM, error_string);
749 static BOOL test_lm_ntlm(struct samlogon_state *samlogon_state, char **error_string)
751 return test_lm_ntlm_broken(samlogon_state, BREAK_NONE, error_string);
754 static BOOL test_ntlm_lm_broken(struct samlogon_state *samlogon_state, char **error_string)
756 return test_lm_ntlm_broken(samlogon_state, BREAK_LM, error_string);
759 static BOOL test_ntlm_ntlm_broken(struct samlogon_state *samlogon_state, char **error_string)
761 return test_lm_ntlm_broken(samlogon_state, BREAK_NT, error_string);
764 static BOOL test_ntlmv2_lmv2_broken(struct samlogon_state *samlogon_state, char **error_string)
766 return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_LM, error_string);
769 static BOOL test_ntlmv2_ntlmv2_broken(struct samlogon_state *samlogon_state, char **error_string)
771 return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_NT, error_string);
774 static BOOL test_plaintext(struct samlogon_state *samlogon_state, enum ntlm_break break_which, char **error_string)
777 DATA_BLOB nt_response = data_blob(NULL, 0);
778 DATA_BLOB lm_response = data_blob(NULL, 0);
783 uint8_t user_session_key[16];
785 static const uint8_t zeros[8];
786 DATA_BLOB chall = data_blob_talloc(samlogon_state->mem_ctx, zeros, sizeof(zeros));
788 ZERO_STRUCT(user_session_key);
790 if ((push_ucs2_talloc(samlogon_state->mem_ctx, &unicodepw,
791 samlogon_state->password)) == -1) {
792 DEBUG(0, ("push_ucs2_allocate failed!\n"));
796 nt_response = data_blob_talloc(samlogon_state->mem_ctx, unicodepw, utf16_len(unicodepw));
798 password = strupper_talloc(samlogon_state->mem_ctx, samlogon_state->password);
800 if ((convert_string_talloc(samlogon_state->mem_ctx, CH_UNIX,
803 (void**)&dospw)) == -1) {
804 DEBUG(0, ("convert_string_talloc failed!\n"));
808 lm_response = data_blob_talloc(samlogon_state->mem_ctx, dospw, strlen(dospw));
810 nt_status = check_samlogon(samlogon_state,
819 if (!NT_STATUS_IS_OK(nt_status)) {
820 return break_which == BREAK_NT;
826 static BOOL test_plaintext_none_broken(struct samlogon_state *samlogon_state,
827 char **error_string) {
828 return test_plaintext(samlogon_state, BREAK_NONE, error_string);
831 static BOOL test_plaintext_lm_broken(struct samlogon_state *samlogon_state,
832 char **error_string) {
833 return test_plaintext(samlogon_state, BREAK_LM, error_string);
836 static BOOL test_plaintext_nt_broken(struct samlogon_state *samlogon_state,
837 char **error_string) {
838 return test_plaintext(samlogon_state, BREAK_NT, error_string);
841 static BOOL test_plaintext_nt_only(struct samlogon_state *samlogon_state,
842 char **error_string) {
843 return test_plaintext(samlogon_state, NO_LM, error_string);
846 static BOOL test_plaintext_lm_only(struct samlogon_state *samlogon_state,
847 char **error_string) {
848 return test_plaintext(samlogon_state, NO_NT, error_string);
862 - plaintext tests (in challenge-response fields)
864 check we get the correct session key in each case
865 check what values we get for the LM session key
869 static const struct ntlm_tests {
870 BOOL (*fn)(struct samlogon_state *, char **);
874 {test_lm, "LM", False},
875 {test_lm_ntlm, "LM and NTLM", False},
876 {test_ntlm, "NTLM", False},
877 {test_ntlm_in_lm, "NTLM in LM", False},
878 {test_ntlm_in_both, "NTLM in both", False},
879 {test_ntlmv2, "NTLMv2", False},
880 {test_lmv2_ntlmv2, "NTLMv2 and LMv2", False},
881 {test_lmv2, "LMv2", False},
882 {test_ntlmv2_lmv2_broken, "NTLMv2 and LMv2, LMv2 broken", False},
883 {test_ntlmv2_ntlmv2_broken, "NTLMv2 and LMv2, NTLMv2 broken", False},
884 {test_ntlm_lm_broken, "NTLM and LM, LM broken", False},
885 {test_ntlm_ntlm_broken, "NTLM and LM, NTLM broken", False},
886 {test_plaintext_none_broken, "Plaintext", True},
887 {test_plaintext_lm_broken, "Plaintext LM broken", True},
888 {test_plaintext_nt_broken, "Plaintext NT broken", True},
889 {test_plaintext_nt_only, "Plaintext NT only", True},
890 {test_plaintext_lm_only, "Plaintext LM only", True},
895 try a netlogon SamLogon
897 static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
901 int validation_levels[] = {2,3,6};
902 int logon_levels[] = { 2, 6 };
903 struct samlogon_state samlogon_state;
905 samlogon_state.mem_ctx = mem_ctx;
906 samlogon_state.account_name = lp_parm_string(-1, "torture", "username");
907 samlogon_state.account_domain = lp_parm_string(-1, "torture", "userdomain");
908 samlogon_state.password = lp_parm_string(-1, "torture", "password");
909 samlogon_state.p = p;
911 samlogon_state.chall = data_blob_talloc(mem_ctx, NULL, 8);
913 generate_random_buffer(samlogon_state.chall.data, 8);
915 if (!test_SetupCredentials2(p, mem_ctx, NETLOGON_NEG_AUTH2_FLAGS, &samlogon_state.creds)) {
919 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_FLAGS, &samlogon_state.creds)) {
923 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, &samlogon_state.creds)) {
927 samlogon_state.r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
928 samlogon_state.r.in.workstation = TEST_MACHINE_NAME;
929 samlogon_state.r.in.credential = &samlogon_state.auth;
930 samlogon_state.r.in.return_authenticator = &samlogon_state.auth2;
932 for (i=0; test_table[i].fn; i++) {
933 for (v=0;v<ARRAY_SIZE(validation_levels);v++) {
934 for (l=0;l<ARRAY_SIZE(logon_levels);l++) {
935 char *error_string = NULL;
936 samlogon_state.r.in.validation_level = validation_levels[v];
937 samlogon_state.r.in.logon_level = logon_levels[l];
938 printf("Testing SamLogon with '%s' at validation level %d, logon level %d\n",
939 test_table[i].name, validation_levels[v], logon_levels[l]);
941 if (!test_table[i].fn(&samlogon_state, &error_string)) {
942 if (test_table[i].expect_fail) {
943 printf("Test %s failed (expected, test incomplete): %s\n", test_table[i].name, error_string);
945 printf("Test %s failed: %s\n", test_table[i].name, error_string);
948 SAFE_FREE(error_string);
959 try a change password for our machine account
961 static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
964 struct netr_ServerPasswordSet r;
965 const char *password;
966 struct creds_CredentialState creds;
968 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
972 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
973 r.in.account_name = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
974 r.in.secure_channel_type = SEC_CHAN_BDC;
975 r.in.computer_name = TEST_MACHINE_NAME;
977 password = generate_random_str(mem_ctx, 8);
978 E_md4hash(password, r.in.new_password.hash);
980 creds_des_encrypt(&creds, &r.in.new_password);
982 printf("Testing ServerPasswordSet on machine account\n");
983 printf("Changing machine account password to '%s'\n", password);
985 creds_client_authenticator(&creds, &r.in.credential);
987 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
988 if (!NT_STATUS_IS_OK(status)) {
989 printf("ServerPasswordSet - %s\n", nt_errstr(status));
993 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
994 printf("Credential chaining failed\n");
997 /* by changing the machine password twice we test the
998 credentials chaining fully, and we verify that the server
999 allows the password to be set to the same value twice in a
1000 row (match win2k3) */
1001 printf("Testing a second ServerPasswordSet on machine account\n");
1002 printf("Changing machine account password to '%s' (same as previous run)\n", password);
1004 creds_client_authenticator(&creds, &r.in.credential);
1006 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
1007 if (!NT_STATUS_IS_OK(status)) {
1008 printf("ServerPasswordSet (2) - %s\n", nt_errstr(status));
1012 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
1013 printf("Credential chaining failed\n");
1016 machine_password = password;
1018 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
1019 printf("ServerPasswordSet failed to actually change the password\n");
1027 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
1028 static uint64_t sequence_nums[3];
1031 try a netlogon DatabaseSync
1033 static BOOL test_DatabaseSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1036 struct netr_DatabaseSync r;
1037 struct creds_CredentialState creds;
1038 const uint32_t database_ids[] = {0, 1, 2};
1042 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
1046 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1047 r.in.computername = TEST_MACHINE_NAME;
1048 r.in.preferredmaximumlength = (uint32_t)-1;
1049 ZERO_STRUCT(r.in.return_authenticator);
1051 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1052 r.in.sync_context = 0;
1053 r.in.database_id = database_ids[i];
1055 printf("Testing DatabaseSync of id %d\n", r.in.database_id);
1058 creds_client_authenticator(&creds, &r.in.credential);
1060 status = dcerpc_netr_DatabaseSync(p, mem_ctx, &r);
1061 if (!NT_STATUS_IS_OK(status) &&
1062 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
1063 printf("DatabaseSync - %s\n", nt_errstr(status));
1068 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
1069 printf("Credential chaining failed\n");
1072 r.in.sync_context = r.out.sync_context;
1074 if (r.out.delta_enum_array &&
1075 r.out.delta_enum_array->num_deltas > 0 &&
1076 r.out.delta_enum_array->delta_enum[0].delta_type == 1 &&
1077 r.out.delta_enum_array->delta_enum[0].delta_union.domain) {
1078 sequence_nums[r.in.database_id] =
1079 r.out.delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
1080 printf("\tsequence_nums[%d]=%llu\n",
1082 sequence_nums[r.in.database_id]);
1084 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
1092 try a netlogon DatabaseDeltas
1094 static BOOL test_DatabaseDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1097 struct netr_DatabaseDeltas r;
1098 struct creds_CredentialState creds;
1099 const uint32_t database_ids[] = {0, 1, 2};
1103 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
1107 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1108 r.in.computername = TEST_MACHINE_NAME;
1109 r.in.preferredmaximumlength = (uint32_t)-1;
1110 ZERO_STRUCT(r.in.return_authenticator);
1112 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1113 r.in.database_id = database_ids[i];
1114 r.in.sequence_num = sequence_nums[r.in.database_id];
1116 if (r.in.sequence_num == 0) continue;
1118 r.in.sequence_num -= 1;
1121 printf("Testing DatabaseDeltas of id %d at %llu\n",
1122 r.in.database_id, r.in.sequence_num);
1125 creds_client_authenticator(&creds, &r.in.credential);
1127 status = dcerpc_netr_DatabaseDeltas(p, mem_ctx, &r);
1128 if (!NT_STATUS_IS_OK(status) &&
1129 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
1130 printf("DatabaseDeltas - %s\n", nt_errstr(status));
1135 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
1136 printf("Credential chaining failed\n");
1139 r.in.sequence_num++;
1140 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
1148 try a netlogon AccountDeltas
1150 static BOOL test_AccountDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1153 struct netr_AccountDeltas r;
1154 struct creds_CredentialState creds;
1157 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
1161 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1162 r.in.computername = TEST_MACHINE_NAME;
1163 ZERO_STRUCT(r.in.return_authenticator);
1164 creds_client_authenticator(&creds, &r.in.credential);
1165 ZERO_STRUCT(r.in.uas);
1168 r.in.buffersize=100;
1170 printf("Testing AccountDeltas\n");
1172 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1173 status = dcerpc_netr_AccountDeltas(p, mem_ctx, &r);
1174 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
1175 printf("AccountDeltas - %s\n", nt_errstr(status));
1183 try a netlogon AccountSync
1185 static BOOL test_AccountSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1188 struct netr_AccountSync r;
1189 struct creds_CredentialState creds;
1192 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
1196 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1197 r.in.computername = TEST_MACHINE_NAME;
1198 ZERO_STRUCT(r.in.return_authenticator);
1199 creds_client_authenticator(&creds, &r.in.credential);
1200 ZERO_STRUCT(r.in.recordid);
1203 r.in.buffersize=100;
1205 printf("Testing AccountSync\n");
1207 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1208 status = dcerpc_netr_AccountSync(p, mem_ctx, &r);
1209 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
1210 printf("AccountSync - %s\n", nt_errstr(status));
1218 try a netlogon GetDcName
1220 static BOOL test_GetDcName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1223 struct netr_GetDcName r;
1225 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1226 r.in.domainname = lp_workgroup();
1228 printf("Testing GetDcName\n");
1230 status = dcerpc_netr_GetDcName(p, mem_ctx, &r);
1231 if (!NT_STATUS_IS_OK(status)) {
1232 printf("GetDcName - %s\n", nt_errstr(status));
1236 printf("\tDC is at '%s'\n", r.out.dcname);
1242 try a netlogon LogonControl
1244 static BOOL test_LogonControl(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1247 struct netr_LogonControl r;
1251 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1252 r.in.function_code = 1;
1257 printf("Testing LogonControl level %d\n", i);
1259 status = dcerpc_netr_LogonControl(p, mem_ctx, &r);
1260 if (!NT_STATUS_IS_OK(status)) {
1261 printf("LogonControl - %s\n", nt_errstr(status));
1271 try a netlogon GetAnyDCName
1273 static BOOL test_GetAnyDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1276 struct netr_GetAnyDCName r;
1278 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1279 r.in.domainname = lp_workgroup();
1281 printf("Testing GetAnyDCName\n");
1283 status = dcerpc_netr_GetAnyDCName(p, mem_ctx, &r);
1284 if (!NT_STATUS_IS_OK(status)) {
1285 printf("GetAnyDCName - %s\n", nt_errstr(status));
1290 printf("\tDC is at '%s'\n", r.out.dcname);
1298 try a netlogon LogonControl2
1300 static BOOL test_LogonControl2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1303 struct netr_LogonControl2 r;
1307 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1309 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1310 r.in.data.domain = lp_workgroup();
1315 printf("Testing LogonControl2 level %d function %d\n",
1316 i, r.in.function_code);
1318 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
1319 if (!NT_STATUS_IS_OK(status)) {
1320 printf("LogonControl - %s\n", nt_errstr(status));
1325 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1326 r.in.data.domain = lp_workgroup();
1331 printf("Testing LogonControl2 level %d function %d\n",
1332 i, r.in.function_code);
1334 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
1335 if (!NT_STATUS_IS_OK(status)) {
1336 printf("LogonControl - %s\n", nt_errstr(status));
1341 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1342 r.in.data.domain = lp_workgroup();
1347 printf("Testing LogonControl2 level %d function %d\n",
1348 i, r.in.function_code);
1350 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
1351 if (!NT_STATUS_IS_OK(status)) {
1352 printf("LogonControl - %s\n", nt_errstr(status));
1357 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1358 r.in.data.debug_level = ~0;
1363 printf("Testing LogonControl2 level %d function %d\n",
1364 i, r.in.function_code);
1366 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
1367 if (!NT_STATUS_IS_OK(status)) {
1368 printf("LogonControl - %s\n", nt_errstr(status));
1377 try a netlogon DatabaseSync2
1379 static BOOL test_DatabaseSync2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1382 struct netr_DatabaseSync2 r;
1383 struct creds_CredentialState creds;
1384 const uint32_t database_ids[] = {0, 1, 2};
1388 if (!test_SetupCredentials2(p, mem_ctx, NETLOGON_NEG_AUTH2_FLAGS, &creds)) {
1392 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1393 r.in.computername = TEST_MACHINE_NAME;
1394 r.in.preferredmaximumlength = (uint32_t)-1;
1395 ZERO_STRUCT(r.in.return_authenticator);
1397 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1398 r.in.sync_context = 0;
1399 r.in.database_id = database_ids[i];
1400 r.in.restart_state = 0;
1402 printf("Testing DatabaseSync2 of id %d\n", r.in.database_id);
1405 creds_client_authenticator(&creds, &r.in.credential);
1407 status = dcerpc_netr_DatabaseSync2(p, mem_ctx, &r);
1408 if (!NT_STATUS_IS_OK(status) &&
1409 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
1410 printf("DatabaseSync2 - %s\n", nt_errstr(status));
1415 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
1416 printf("Credential chaining failed\n");
1419 r.in.sync_context = r.out.sync_context;
1420 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
1428 try a netlogon LogonControl2Ex
1430 static BOOL test_LogonControl2Ex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1433 struct netr_LogonControl2Ex r;
1437 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1439 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1440 r.in.data.domain = lp_workgroup();
1445 printf("Testing LogonControl2Ex level %d function %d\n",
1446 i, r.in.function_code);
1448 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1449 if (!NT_STATUS_IS_OK(status)) {
1450 printf("LogonControl - %s\n", nt_errstr(status));
1455 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1456 r.in.data.domain = lp_workgroup();
1461 printf("Testing LogonControl2Ex level %d function %d\n",
1462 i, r.in.function_code);
1464 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1465 if (!NT_STATUS_IS_OK(status)) {
1466 printf("LogonControl - %s\n", nt_errstr(status));
1471 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1472 r.in.data.domain = lp_workgroup();
1477 printf("Testing LogonControl2Ex level %d function %d\n",
1478 i, r.in.function_code);
1480 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1481 if (!NT_STATUS_IS_OK(status)) {
1482 printf("LogonControl - %s\n", nt_errstr(status));
1487 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1488 r.in.data.debug_level = ~0;
1493 printf("Testing LogonControl2Ex level %d function %d\n",
1494 i, r.in.function_code);
1496 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1497 if (!NT_STATUS_IS_OK(status)) {
1498 printf("LogonControl - %s\n", nt_errstr(status));
1508 try a netlogon netr_DsrEnumerateDomainTrusts
1510 static BOOL test_DsrEnumerateDomainTrusts(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1513 struct netr_DsrEnumerateDomainTrusts r;
1515 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1516 r.in.trust_flags = 0x3f;
1518 printf("Testing netr_DsrEnumerateDomainTrusts\n");
1520 status = dcerpc_netr_DsrEnumerateDomainTrusts(p, mem_ctx, &r);
1521 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1522 printf("netr_DsrEnumerateDomainTrusts - %s/%s\n",
1523 nt_errstr(status), win_errstr(r.out.result));
1532 test an ADS style interactive domain login
1534 static BOOL test_InteractiveLogin(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1535 struct creds_CredentialState *creds)
1538 struct netr_LogonSamLogonWithFlags r;
1539 struct netr_Authenticator a, ra;
1540 struct netr_PasswordInfo pinfo;
1541 const char *plain_pass;
1546 creds_client_authenticator(creds, &a);
1548 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1549 r.in.workstation = TEST_MACHINE_NAME;
1550 r.in.credential = &a;
1551 r.in.return_authenticator = &ra;
1552 r.in.logon_level = 5;
1553 r.in.logon.password = &pinfo;
1554 r.in.validation_level = 6;
1557 pinfo.identity_info.domain_name.string = lp_parm_string(-1, "torture", "userdomain");
1558 pinfo.identity_info.parameter_control = 0;
1559 pinfo.identity_info.logon_id_low = 0;
1560 pinfo.identity_info.logon_id_high = 0;
1561 pinfo.identity_info.account_name.string = lp_parm_string(-1, "torture", "username");
1562 pinfo.identity_info.workstation.string = TEST_MACHINE_NAME;
1564 plain_pass = lp_parm_string(-1, "torture", "password");
1566 E_deshash(plain_pass, pinfo.lmpassword.hash);
1567 E_md4hash(plain_pass, pinfo.ntpassword.hash);
1569 creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
1570 creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
1572 printf("Testing netr_LogonSamLogonWithFlags\n");
1574 status = dcerpc_netr_LogonSamLogonWithFlags(p, mem_ctx, &r);
1575 if (!NT_STATUS_IS_OK(status)) {
1576 printf("netr_LogonSamLogonWithFlags - %s\n", nt_errstr(status));
1581 if (!creds_client_check(creds, &r.out.return_authenticator->cred)) {
1582 printf("Credential chaining failed\n");
1590 static BOOL test_GetDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1593 struct netr_LogonGetDomainInfo r;
1594 struct netr_DomainQuery1 q1;
1595 struct netr_Authenticator a;
1596 struct creds_CredentialState creds;
1598 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, &creds)) {
1604 creds_client_authenticator(&creds, &a);
1606 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1607 r.in.computer_name = TEST_MACHINE_NAME;
1608 r.in.unknown1 = 512;
1610 r.in.credential = &a;
1611 r.out.credential = &a;
1616 r.in.query.query1 = &q1;
1619 /* this should really be the fully qualified name */
1620 q1.workstation_domain = TEST_MACHINE_NAME;
1621 q1.workstation_site = "Default-First-Site-Name";
1622 q1.blob2.length = 0;
1624 q1.blob2.data = NULL;
1625 q1.product.string = "product string";
1627 printf("Testing netr_LogonGetDomainInfo\n");
1629 status = dcerpc_netr_LogonGetDomainInfo(p, mem_ctx, &r);
1630 if (!NT_STATUS_IS_OK(status)) {
1631 printf("netr_LogonGetDomainInfo - %s\n", nt_errstr(status));
1635 if (!creds_client_check(&creds, &a.cred)) {
1636 printf("Credential chaining failed\n");
1640 test_InteractiveLogin(p, mem_ctx, &creds);
1646 static void async_callback(struct rpc_request *req)
1648 int *counter = req->async.private;
1649 if (NT_STATUS_IS_OK(req->status)) {
1654 static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1657 struct netr_LogonGetDomainInfo r;
1658 struct netr_DomainQuery1 q1;
1659 struct netr_Authenticator a;
1660 #define ASYNC_COUNT 100
1661 struct creds_CredentialState creds;
1662 struct creds_CredentialState creds_async[ASYNC_COUNT];
1663 struct rpc_request *req[ASYNC_COUNT];
1665 int async_counter = 0;
1667 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, &creds)) {
1672 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1673 r.in.computer_name = TEST_MACHINE_NAME;
1674 r.in.unknown1 = 512;
1676 r.in.credential = &a;
1677 r.out.credential = &a;
1682 r.in.query.query1 = &q1;
1685 /* this should really be the fully qualified name */
1686 q1.workstation_domain = TEST_MACHINE_NAME;
1687 q1.workstation_site = "Default-First-Site-Name";
1688 q1.blob2.length = 0;
1690 q1.blob2.data = NULL;
1691 q1.product.string = "product string";
1693 printf("Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
1695 for (i=0;i<ASYNC_COUNT;i++) {
1696 creds_client_authenticator(&creds, &a);
1698 creds_async[i] = creds;
1699 req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, mem_ctx, &r);
1701 req[i]->async.callback = async_callback;
1702 req[i]->async.private = &async_counter;
1704 /* even with this flush per request a w2k3 server seems to
1705 clag with multiple outstanding requests. bleergh. */
1706 if (event_loop_once(dcerpc_event_context(p)) != 0) {
1711 for (i=0;i<ASYNC_COUNT;i++) {
1712 status = dcerpc_ndr_request_recv(req[i]);
1713 if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(r.out.result)) {
1714 printf("netr_LogonGetDomainInfo_async(%d) - %s/%s\n",
1715 i, nt_errstr(status), nt_errstr(r.out.result));
1719 if (!creds_client_check(&creds_async[i], &a.cred)) {
1720 printf("Credential chaining failed at async %d\n", i);
1725 printf("Testing netr_LogonGetDomainInfo - async count %d OK\n", async_counter);
1727 return async_counter == ASYNC_COUNT;
1731 BOOL torture_rpc_netlogon(int dummy)
1734 struct dcerpc_pipe *p;
1735 TALLOC_CTX *mem_ctx;
1739 mem_ctx = talloc_init("torture_rpc_netlogon");
1741 join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), ACB_SVRTRUST,
1744 printf("Failed to join as BDC\n");
1748 status = torture_rpc_connection(&p,
1749 DCERPC_NETLOGON_NAME,
1750 DCERPC_NETLOGON_UUID,
1751 DCERPC_NETLOGON_VERSION);
1752 if (!NT_STATUS_IS_OK(status)) {
1756 if (!test_LogonUasLogon(p, mem_ctx)) {
1760 if (!test_LogonUasLogoff(p, mem_ctx)) {
1764 if (!test_SetPassword(p, mem_ctx)) {
1768 if (!test_SamLogon(p, mem_ctx)) {
1772 if (!test_GetDomainInfo(p, mem_ctx)) {
1776 if (!test_DatabaseSync(p, mem_ctx)) {
1780 if (!test_DatabaseDeltas(p, mem_ctx)) {
1784 if (!test_AccountDeltas(p, mem_ctx)) {
1788 if (!test_AccountSync(p, mem_ctx)) {
1792 if (!test_GetDcName(p, mem_ctx)) {
1796 if (!test_LogonControl(p, mem_ctx)) {
1800 if (!test_GetAnyDCName(p, mem_ctx)) {
1804 if (!test_LogonControl2(p, mem_ctx)) {
1808 if (!test_DatabaseSync2(p, mem_ctx)) {
1812 if (!test_LogonControl2Ex(p, mem_ctx)) {
1816 if (!test_DsrEnumerateDomainTrusts(p, mem_ctx)) {
1820 if (!test_GetDomainInfo_async(p, mem_ctx)) {
1824 talloc_destroy(mem_ctx);
1826 torture_rpc_close(p);
1828 torture_leave_domain(join_ctx);