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);
781 smb_ucs2_t *unicodepw;
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, (smb_ucs2_t **)&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,
797 strlen_w(((void *)unicodepw))*sizeof(smb_ucs2_t));
799 password = strupper_talloc(samlogon_state->mem_ctx, samlogon_state->password);
801 if ((convert_string_talloc(samlogon_state->mem_ctx, CH_UNIX,
804 (void**)&dospw)) == -1) {
805 DEBUG(0, ("convert_string_talloc failed!\n"));
809 lm_response = data_blob_talloc(samlogon_state->mem_ctx, dospw, strlen(dospw));
811 nt_status = check_samlogon(samlogon_state,
820 if (!NT_STATUS_IS_OK(nt_status)) {
821 return break_which == BREAK_NT;
827 static BOOL test_plaintext_none_broken(struct samlogon_state *samlogon_state,
828 char **error_string) {
829 return test_plaintext(samlogon_state, BREAK_NONE, error_string);
832 static BOOL test_plaintext_lm_broken(struct samlogon_state *samlogon_state,
833 char **error_string) {
834 return test_plaintext(samlogon_state, BREAK_LM, error_string);
837 static BOOL test_plaintext_nt_broken(struct samlogon_state *samlogon_state,
838 char **error_string) {
839 return test_plaintext(samlogon_state, BREAK_NT, error_string);
842 static BOOL test_plaintext_nt_only(struct samlogon_state *samlogon_state,
843 char **error_string) {
844 return test_plaintext(samlogon_state, NO_LM, error_string);
847 static BOOL test_plaintext_lm_only(struct samlogon_state *samlogon_state,
848 char **error_string) {
849 return test_plaintext(samlogon_state, NO_NT, error_string);
863 - plaintext tests (in challenge-response fields)
865 check we get the correct session key in each case
866 check what values we get for the LM session key
870 static const struct ntlm_tests {
871 BOOL (*fn)(struct samlogon_state *, char **);
875 {test_lm, "LM", False},
876 {test_lm_ntlm, "LM and NTLM", False},
877 {test_ntlm, "NTLM", False},
878 {test_ntlm_in_lm, "NTLM in LM", False},
879 {test_ntlm_in_both, "NTLM in both", False},
880 {test_ntlmv2, "NTLMv2", False},
881 {test_lmv2_ntlmv2, "NTLMv2 and LMv2", False},
882 {test_lmv2, "LMv2", False},
883 {test_ntlmv2_lmv2_broken, "NTLMv2 and LMv2, LMv2 broken", False},
884 {test_ntlmv2_ntlmv2_broken, "NTLMv2 and LMv2, NTLMv2 broken", False},
885 {test_ntlm_lm_broken, "NTLM and LM, LM broken", False},
886 {test_ntlm_ntlm_broken, "NTLM and LM, NTLM broken", False},
887 {test_plaintext_none_broken, "Plaintext", True},
888 {test_plaintext_lm_broken, "Plaintext LM broken", True},
889 {test_plaintext_nt_broken, "Plaintext NT broken", True},
890 {test_plaintext_nt_only, "Plaintext NT only", True},
891 {test_plaintext_lm_only, "Plaintext LM only", True},
896 try a netlogon SamLogon
898 static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
902 int validation_levels[] = {2,3,6};
903 int logon_levels[] = { 2, 6 };
904 struct samlogon_state samlogon_state;
906 samlogon_state.mem_ctx = mem_ctx;
907 samlogon_state.account_name = lp_parm_string(-1, "torture", "username");
908 samlogon_state.account_domain = lp_parm_string(-1, "torture", "userdomain");
909 samlogon_state.password = lp_parm_string(-1, "torture", "password");
910 samlogon_state.p = p;
912 samlogon_state.chall = data_blob_talloc(mem_ctx, NULL, 8);
914 generate_random_buffer(samlogon_state.chall.data, 8);
916 if (!test_SetupCredentials2(p, mem_ctx, NETLOGON_NEG_AUTH2_FLAGS, &samlogon_state.creds)) {
920 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_FLAGS, &samlogon_state.creds)) {
924 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, &samlogon_state.creds)) {
928 samlogon_state.r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
929 samlogon_state.r.in.workstation = TEST_MACHINE_NAME;
930 samlogon_state.r.in.credential = &samlogon_state.auth;
931 samlogon_state.r.in.return_authenticator = &samlogon_state.auth2;
933 for (i=0; test_table[i].fn; i++) {
934 for (v=0;v<ARRAY_SIZE(validation_levels);v++) {
935 for (l=0;l<ARRAY_SIZE(logon_levels);l++) {
936 char *error_string = NULL;
937 samlogon_state.r.in.validation_level = validation_levels[v];
938 samlogon_state.r.in.logon_level = logon_levels[l];
939 printf("Testing SamLogon with '%s' at validation level %d, logon level %d\n",
940 test_table[i].name, validation_levels[v], logon_levels[l]);
942 if (!test_table[i].fn(&samlogon_state, &error_string)) {
943 if (test_table[i].expect_fail) {
944 printf("Test %s failed (expected, test incomplete): %s\n", test_table[i].name, error_string);
946 printf("Test %s failed: %s\n", test_table[i].name, error_string);
949 SAFE_FREE(error_string);
960 try a change password for our machine account
962 static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
965 struct netr_ServerPasswordSet r;
966 const char *password;
967 struct creds_CredentialState creds;
969 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
973 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
974 r.in.account_name = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
975 r.in.secure_channel_type = SEC_CHAN_BDC;
976 r.in.computer_name = TEST_MACHINE_NAME;
978 password = generate_random_str(mem_ctx, 8);
979 E_md4hash(password, r.in.new_password.hash);
981 creds_des_encrypt(&creds, &r.in.new_password);
983 printf("Testing ServerPasswordSet on machine account\n");
984 printf("Changing machine account password to '%s'\n", password);
986 creds_client_authenticator(&creds, &r.in.credential);
988 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
989 if (!NT_STATUS_IS_OK(status)) {
990 printf("ServerPasswordSet - %s\n", nt_errstr(status));
994 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
995 printf("Credential chaining failed\n");
998 /* by changing the machine password twice we test the
999 credentials chaining fully, and we verify that the server
1000 allows the password to be set to the same value twice in a
1001 row (match win2k3) */
1002 printf("Testing a second ServerPasswordSet on machine account\n");
1003 printf("Changing machine account password to '%s' (same as previous run)\n", password);
1005 creds_client_authenticator(&creds, &r.in.credential);
1007 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
1008 if (!NT_STATUS_IS_OK(status)) {
1009 printf("ServerPasswordSet (2) - %s\n", nt_errstr(status));
1013 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
1014 printf("Credential chaining failed\n");
1017 machine_password = password;
1019 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
1020 printf("ServerPasswordSet failed to actually change the password\n");
1028 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
1029 static uint64_t sequence_nums[3];
1032 try a netlogon DatabaseSync
1034 static BOOL test_DatabaseSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1037 struct netr_DatabaseSync r;
1038 struct creds_CredentialState creds;
1039 const uint32_t database_ids[] = {0, 1, 2};
1043 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
1047 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1048 r.in.computername = TEST_MACHINE_NAME;
1049 r.in.preferredmaximumlength = (uint32_t)-1;
1050 ZERO_STRUCT(r.in.return_authenticator);
1052 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1053 r.in.sync_context = 0;
1054 r.in.database_id = database_ids[i];
1056 printf("Testing DatabaseSync of id %d\n", r.in.database_id);
1059 creds_client_authenticator(&creds, &r.in.credential);
1061 status = dcerpc_netr_DatabaseSync(p, mem_ctx, &r);
1062 if (!NT_STATUS_IS_OK(status) &&
1063 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
1064 printf("DatabaseSync - %s\n", nt_errstr(status));
1069 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
1070 printf("Credential chaining failed\n");
1073 r.in.sync_context = r.out.sync_context;
1075 if (r.out.delta_enum_array &&
1076 r.out.delta_enum_array->num_deltas > 0 &&
1077 r.out.delta_enum_array->delta_enum[0].delta_type == 1 &&
1078 r.out.delta_enum_array->delta_enum[0].delta_union.domain) {
1079 sequence_nums[r.in.database_id] =
1080 r.out.delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
1081 printf("\tsequence_nums[%d]=%llu\n",
1083 sequence_nums[r.in.database_id]);
1085 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
1093 try a netlogon DatabaseDeltas
1095 static BOOL test_DatabaseDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1098 struct netr_DatabaseDeltas r;
1099 struct creds_CredentialState creds;
1100 const uint32_t database_ids[] = {0, 1, 2};
1104 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
1108 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1109 r.in.computername = TEST_MACHINE_NAME;
1110 r.in.preferredmaximumlength = (uint32_t)-1;
1111 ZERO_STRUCT(r.in.return_authenticator);
1113 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1114 r.in.database_id = database_ids[i];
1115 r.in.sequence_num = sequence_nums[r.in.database_id];
1117 if (r.in.sequence_num == 0) continue;
1119 r.in.sequence_num -= 1;
1122 printf("Testing DatabaseDeltas of id %d at %llu\n",
1123 r.in.database_id, r.in.sequence_num);
1126 creds_client_authenticator(&creds, &r.in.credential);
1128 status = dcerpc_netr_DatabaseDeltas(p, mem_ctx, &r);
1129 if (!NT_STATUS_IS_OK(status) &&
1130 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
1131 printf("DatabaseDeltas - %s\n", nt_errstr(status));
1136 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
1137 printf("Credential chaining failed\n");
1140 r.in.sequence_num++;
1141 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
1149 try a netlogon AccountDeltas
1151 static BOOL test_AccountDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1154 struct netr_AccountDeltas r;
1155 struct creds_CredentialState creds;
1158 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
1162 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1163 r.in.computername = TEST_MACHINE_NAME;
1164 ZERO_STRUCT(r.in.return_authenticator);
1165 creds_client_authenticator(&creds, &r.in.credential);
1166 ZERO_STRUCT(r.in.uas);
1169 r.in.buffersize=100;
1171 printf("Testing AccountDeltas\n");
1173 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1174 status = dcerpc_netr_AccountDeltas(p, mem_ctx, &r);
1175 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
1176 printf("AccountDeltas - %s\n", nt_errstr(status));
1184 try a netlogon AccountSync
1186 static BOOL test_AccountSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1189 struct netr_AccountSync r;
1190 struct creds_CredentialState creds;
1193 if (!test_SetupCredentials(p, mem_ctx, &creds)) {
1197 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1198 r.in.computername = TEST_MACHINE_NAME;
1199 ZERO_STRUCT(r.in.return_authenticator);
1200 creds_client_authenticator(&creds, &r.in.credential);
1201 ZERO_STRUCT(r.in.recordid);
1204 r.in.buffersize=100;
1206 printf("Testing AccountSync\n");
1208 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1209 status = dcerpc_netr_AccountSync(p, mem_ctx, &r);
1210 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
1211 printf("AccountSync - %s\n", nt_errstr(status));
1219 try a netlogon GetDcName
1221 static BOOL test_GetDcName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1224 struct netr_GetDcName r;
1226 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1227 r.in.domainname = lp_workgroup();
1229 printf("Testing GetDcName\n");
1231 status = dcerpc_netr_GetDcName(p, mem_ctx, &r);
1232 if (!NT_STATUS_IS_OK(status)) {
1233 printf("GetDcName - %s\n", nt_errstr(status));
1237 printf("\tDC is at '%s'\n", r.out.dcname);
1243 try a netlogon LogonControl
1245 static BOOL test_LogonControl(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1248 struct netr_LogonControl r;
1252 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1253 r.in.function_code = 1;
1258 printf("Testing LogonControl level %d\n", i);
1260 status = dcerpc_netr_LogonControl(p, mem_ctx, &r);
1261 if (!NT_STATUS_IS_OK(status)) {
1262 printf("LogonControl - %s\n", nt_errstr(status));
1272 try a netlogon GetAnyDCName
1274 static BOOL test_GetAnyDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1277 struct netr_GetAnyDCName r;
1279 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1280 r.in.domainname = lp_workgroup();
1282 printf("Testing GetAnyDCName\n");
1284 status = dcerpc_netr_GetAnyDCName(p, mem_ctx, &r);
1285 if (!NT_STATUS_IS_OK(status)) {
1286 printf("GetAnyDCName - %s\n", nt_errstr(status));
1291 printf("\tDC is at '%s'\n", r.out.dcname);
1299 try a netlogon LogonControl2
1301 static BOOL test_LogonControl2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1304 struct netr_LogonControl2 r;
1308 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1310 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1311 r.in.data.domain = lp_workgroup();
1316 printf("Testing LogonControl2 level %d function %d\n",
1317 i, r.in.function_code);
1319 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
1320 if (!NT_STATUS_IS_OK(status)) {
1321 printf("LogonControl - %s\n", nt_errstr(status));
1326 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1327 r.in.data.domain = lp_workgroup();
1332 printf("Testing LogonControl2 level %d function %d\n",
1333 i, r.in.function_code);
1335 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
1336 if (!NT_STATUS_IS_OK(status)) {
1337 printf("LogonControl - %s\n", nt_errstr(status));
1342 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1343 r.in.data.domain = lp_workgroup();
1348 printf("Testing LogonControl2 level %d function %d\n",
1349 i, r.in.function_code);
1351 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
1352 if (!NT_STATUS_IS_OK(status)) {
1353 printf("LogonControl - %s\n", nt_errstr(status));
1358 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1359 r.in.data.debug_level = ~0;
1364 printf("Testing LogonControl2 level %d function %d\n",
1365 i, r.in.function_code);
1367 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
1368 if (!NT_STATUS_IS_OK(status)) {
1369 printf("LogonControl - %s\n", nt_errstr(status));
1378 try a netlogon DatabaseSync2
1380 static BOOL test_DatabaseSync2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1383 struct netr_DatabaseSync2 r;
1384 struct creds_CredentialState creds;
1385 const uint32_t database_ids[] = {0, 1, 2};
1389 if (!test_SetupCredentials2(p, mem_ctx, NETLOGON_NEG_AUTH2_FLAGS, &creds)) {
1393 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1394 r.in.computername = TEST_MACHINE_NAME;
1395 r.in.preferredmaximumlength = (uint32_t)-1;
1396 ZERO_STRUCT(r.in.return_authenticator);
1398 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1399 r.in.sync_context = 0;
1400 r.in.database_id = database_ids[i];
1401 r.in.restart_state = 0;
1403 printf("Testing DatabaseSync2 of id %d\n", r.in.database_id);
1406 creds_client_authenticator(&creds, &r.in.credential);
1408 status = dcerpc_netr_DatabaseSync2(p, mem_ctx, &r);
1409 if (!NT_STATUS_IS_OK(status) &&
1410 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
1411 printf("DatabaseSync2 - %s\n", nt_errstr(status));
1416 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
1417 printf("Credential chaining failed\n");
1420 r.in.sync_context = r.out.sync_context;
1421 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
1429 try a netlogon LogonControl2Ex
1431 static BOOL test_LogonControl2Ex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1434 struct netr_LogonControl2Ex r;
1438 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1440 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1441 r.in.data.domain = lp_workgroup();
1446 printf("Testing LogonControl2Ex level %d function %d\n",
1447 i, r.in.function_code);
1449 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1450 if (!NT_STATUS_IS_OK(status)) {
1451 printf("LogonControl - %s\n", nt_errstr(status));
1456 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1457 r.in.data.domain = lp_workgroup();
1462 printf("Testing LogonControl2Ex level %d function %d\n",
1463 i, r.in.function_code);
1465 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1466 if (!NT_STATUS_IS_OK(status)) {
1467 printf("LogonControl - %s\n", nt_errstr(status));
1472 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1473 r.in.data.domain = lp_workgroup();
1478 printf("Testing LogonControl2Ex level %d function %d\n",
1479 i, r.in.function_code);
1481 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1482 if (!NT_STATUS_IS_OK(status)) {
1483 printf("LogonControl - %s\n", nt_errstr(status));
1488 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1489 r.in.data.debug_level = ~0;
1494 printf("Testing LogonControl2Ex level %d function %d\n",
1495 i, r.in.function_code);
1497 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1498 if (!NT_STATUS_IS_OK(status)) {
1499 printf("LogonControl - %s\n", nt_errstr(status));
1509 try a netlogon netr_DsrEnumerateDomainTrusts
1511 static BOOL test_DsrEnumerateDomainTrusts(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1514 struct netr_DsrEnumerateDomainTrusts r;
1516 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1517 r.in.trust_flags = 0x3f;
1519 printf("Testing netr_DsrEnumerateDomainTrusts\n");
1521 status = dcerpc_netr_DsrEnumerateDomainTrusts(p, mem_ctx, &r);
1522 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1523 printf("netr_DsrEnumerateDomainTrusts - %s/%s\n",
1524 nt_errstr(status), win_errstr(r.out.result));
1533 test an ADS style interactive domain login
1535 static BOOL test_InteractiveLogin(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1536 struct creds_CredentialState *creds)
1539 struct netr_LogonSamLogonWithFlags r;
1540 struct netr_Authenticator a, ra;
1541 struct netr_PasswordInfo pinfo;
1542 const char *plain_pass;
1547 creds_client_authenticator(creds, &a);
1549 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1550 r.in.workstation = TEST_MACHINE_NAME;
1551 r.in.credential = &a;
1552 r.in.return_authenticator = &ra;
1553 r.in.logon_level = 5;
1554 r.in.logon.password = &pinfo;
1555 r.in.validation_level = 6;
1558 pinfo.identity_info.domain_name.string = lp_parm_string(-1, "torture", "userdomain");
1559 pinfo.identity_info.parameter_control = 0;
1560 pinfo.identity_info.logon_id_low = 0;
1561 pinfo.identity_info.logon_id_high = 0;
1562 pinfo.identity_info.account_name.string = lp_parm_string(-1, "torture", "username");
1563 pinfo.identity_info.workstation.string = TEST_MACHINE_NAME;
1565 plain_pass = lp_parm_string(-1, "torture", "password");
1567 E_deshash(plain_pass, pinfo.lmpassword.hash);
1568 E_md4hash(plain_pass, pinfo.ntpassword.hash);
1570 creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
1571 creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
1573 printf("Testing netr_LogonSamLogonWithFlags\n");
1575 status = dcerpc_netr_LogonSamLogonWithFlags(p, mem_ctx, &r);
1576 if (!NT_STATUS_IS_OK(status)) {
1577 printf("netr_LogonSamLogonWithFlags - %s\n", nt_errstr(status));
1582 if (!creds_client_check(creds, &r.out.return_authenticator->cred)) {
1583 printf("Credential chaining failed\n");
1591 static BOOL test_GetDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1594 struct netr_LogonGetDomainInfo r;
1595 struct netr_DomainQuery1 q1;
1596 struct netr_Authenticator a;
1597 struct creds_CredentialState creds;
1599 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, &creds)) {
1605 creds_client_authenticator(&creds, &a);
1607 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1608 r.in.computer_name = TEST_MACHINE_NAME;
1609 r.in.unknown1 = 512;
1611 r.in.credential = &a;
1612 r.out.credential = &a;
1617 r.in.query.query1 = &q1;
1620 /* this should really be the fully qualified name */
1621 q1.workstation_domain = TEST_MACHINE_NAME;
1622 q1.workstation_site = "Default-First-Site-Name";
1623 q1.blob2.length = 0;
1625 q1.blob2.data = NULL;
1626 q1.product.string = "product string";
1628 printf("Testing netr_LogonGetDomainInfo\n");
1630 status = dcerpc_netr_LogonGetDomainInfo(p, mem_ctx, &r);
1631 if (!NT_STATUS_IS_OK(status)) {
1632 printf("netr_LogonGetDomainInfo - %s\n", nt_errstr(status));
1636 if (!creds_client_check(&creds, &a.cred)) {
1637 printf("Credential chaining failed\n");
1641 test_InteractiveLogin(p, mem_ctx, &creds);
1647 static void async_callback(struct rpc_request *req)
1649 int *counter = req->async.private;
1650 if (NT_STATUS_IS_OK(req->status)) {
1655 static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1658 struct netr_LogonGetDomainInfo r;
1659 struct netr_DomainQuery1 q1;
1660 struct netr_Authenticator a;
1661 #define ASYNC_COUNT 100
1662 struct creds_CredentialState creds;
1663 struct creds_CredentialState creds_async[ASYNC_COUNT];
1664 struct rpc_request *req[ASYNC_COUNT];
1666 int async_counter = 0;
1668 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, &creds)) {
1673 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1674 r.in.computer_name = TEST_MACHINE_NAME;
1675 r.in.unknown1 = 512;
1677 r.in.credential = &a;
1678 r.out.credential = &a;
1683 r.in.query.query1 = &q1;
1686 /* this should really be the fully qualified name */
1687 q1.workstation_domain = TEST_MACHINE_NAME;
1688 q1.workstation_site = "Default-First-Site-Name";
1689 q1.blob2.length = 0;
1691 q1.blob2.data = NULL;
1692 q1.product.string = "product string";
1694 printf("Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
1696 for (i=0;i<ASYNC_COUNT;i++) {
1697 creds_client_authenticator(&creds, &a);
1699 creds_async[i] = creds;
1700 req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, mem_ctx, &r);
1702 req[i]->async.callback = async_callback;
1703 req[i]->async.private = &async_counter;
1705 /* even with this flush per request a w2k3 server seems to
1706 clag with multiple outstanding requests. bleergh. */
1707 if (event_loop_once(dcerpc_event_context(p)) != 0) {
1712 for (i=0;i<ASYNC_COUNT;i++) {
1713 status = dcerpc_ndr_request_recv(req[i]);
1714 if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(r.out.result)) {
1715 printf("netr_LogonGetDomainInfo_async(%d) - %s/%s\n",
1716 i, nt_errstr(status), nt_errstr(r.out.result));
1720 if (!creds_client_check(&creds_async[i], &a.cred)) {
1721 printf("Credential chaining failed at async %d\n", i);
1726 printf("Testing netr_LogonGetDomainInfo - async count %d OK\n", async_counter);
1728 return async_counter == ASYNC_COUNT;
1732 BOOL torture_rpc_netlogon(int dummy)
1735 struct dcerpc_pipe *p;
1736 TALLOC_CTX *mem_ctx;
1740 mem_ctx = talloc_init("torture_rpc_netlogon");
1742 join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), ACB_SVRTRUST,
1745 printf("Failed to join as BDC\n");
1749 status = torture_rpc_connection(&p,
1750 DCERPC_NETLOGON_NAME,
1751 DCERPC_NETLOGON_UUID,
1752 DCERPC_NETLOGON_VERSION);
1753 if (!NT_STATUS_IS_OK(status)) {
1757 if (!test_LogonUasLogon(p, mem_ctx)) {
1761 if (!test_LogonUasLogoff(p, mem_ctx)) {
1765 if (!test_SetPassword(p, mem_ctx)) {
1769 if (!test_SamLogon(p, mem_ctx)) {
1773 if (!test_GetDomainInfo(p, mem_ctx)) {
1777 if (!test_DatabaseSync(p, mem_ctx)) {
1781 if (!test_DatabaseDeltas(p, mem_ctx)) {
1785 if (!test_AccountDeltas(p, mem_ctx)) {
1789 if (!test_AccountSync(p, mem_ctx)) {
1793 if (!test_GetDcName(p, mem_ctx)) {
1797 if (!test_LogonControl(p, mem_ctx)) {
1801 if (!test_GetAnyDCName(p, mem_ctx)) {
1805 if (!test_LogonControl2(p, mem_ctx)) {
1809 if (!test_DatabaseSync2(p, mem_ctx)) {
1813 if (!test_LogonControl2Ex(p, mem_ctx)) {
1817 if (!test_DsrEnumerateDomainTrusts(p, mem_ctx)) {
1821 if (!test_GetDomainInfo_async(p, mem_ctx)) {
1825 talloc_destroy(mem_ctx);
1827 torture_rpc_close(p);
1829 torture_leave_domain(join_ctx);