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 "lib/events/events.h"
27 #include "librpc/gen_ndr/ndr_netlogon.h"
28 #include "auth/auth.h"
29 #include "lib/cmdline/popt_common.h"
31 static const char *machine_password;
33 #define TEST_MACHINE_NAME "torturetest"
35 static BOOL test_LogonUasLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
38 struct netr_LogonUasLogon r;
40 r.in.server_name = NULL;
41 r.in.account_name = cli_credentials_get_username(cmdline_credentials),
42 r.in.workstation = TEST_MACHINE_NAME;
44 printf("Testing LogonUasLogon\n");
46 status = dcerpc_netr_LogonUasLogon(p, mem_ctx, &r);
47 if (!NT_STATUS_IS_OK(status)) {
48 printf("LogonUasLogon - %s\n", nt_errstr(status));
56 static BOOL test_LogonUasLogoff(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
59 struct netr_LogonUasLogoff r;
61 r.in.server_name = NULL;
62 r.in.account_name = cli_credentials_get_username(cmdline_credentials),
63 r.in.workstation = TEST_MACHINE_NAME;
65 printf("Testing LogonUasLogoff\n");
67 status = dcerpc_netr_LogonUasLogoff(p, mem_ctx, &r);
68 if (!NT_STATUS_IS_OK(status)) {
69 printf("LogonUasLogoff - %s\n", nt_errstr(status));
77 BOOL test_SetupCredentials(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
78 const char *machine_name,
79 const char *plain_pass,
80 struct creds_CredentialState **creds_out)
83 struct netr_ServerReqChallenge r;
84 struct netr_ServerAuthenticate a;
85 struct netr_Credential credentials1, credentials2, credentials3;
86 struct creds_CredentialState *creds;
87 struct samr_Password mach_password;
89 printf("Testing ServerReqChallenge\n");
91 creds = talloc(mem_ctx, struct creds_CredentialState);
96 r.in.server_name = NULL;
97 r.in.computer_name = machine_name;
98 r.in.credentials = &credentials1;
99 r.out.credentials = &credentials2;
101 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
103 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
104 if (!NT_STATUS_IS_OK(status)) {
105 printf("ServerReqChallenge - %s\n", nt_errstr(status));
109 E_md4hash(plain_pass, mach_password.hash);
111 a.in.server_name = NULL;
112 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", machine_name);
113 a.in.secure_channel_type = SEC_CHAN_BDC;
114 a.in.computer_name = machine_name;
115 a.in.credentials = &credentials3;
116 a.out.credentials = &credentials3;
118 creds_client_init(creds, &credentials1, &credentials2,
122 &mach_password, &credentials3,
125 printf("Testing ServerAuthenticate\n");
127 status = dcerpc_netr_ServerAuthenticate(p, mem_ctx, &a);
128 if (!NT_STATUS_IS_OK(status)) {
129 printf("ServerAuthenticate - %s\n", nt_errstr(status));
133 if (!creds_client_check(creds, &credentials3)) {
134 printf("Credential chaining failed\n");
142 BOOL test_SetupCredentials2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
143 uint32_t negotiate_flags,
144 const char *machine_name,
145 const char *plain_pass,
147 struct creds_CredentialState **creds_out)
150 struct netr_ServerReqChallenge r;
151 struct netr_ServerAuthenticate2 a;
152 struct netr_Credential credentials1, credentials2, credentials3;
153 struct creds_CredentialState *creds;
154 struct samr_Password mach_password;
156 printf("Testing ServerReqChallenge\n");
158 creds = talloc(mem_ctx, struct creds_CredentialState);
163 r.in.server_name = NULL;
164 r.in.computer_name = machine_name;
165 r.in.credentials = &credentials1;
166 r.out.credentials = &credentials2;
168 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
170 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
171 if (!NT_STATUS_IS_OK(status)) {
172 printf("ServerReqChallenge - %s\n", nt_errstr(status));
176 E_md4hash(plain_pass, mach_password.hash);
178 a.in.server_name = NULL;
179 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", machine_name);
180 a.in.secure_channel_type = sec_chan_type;
181 a.in.computer_name = machine_name;
182 a.in.negotiate_flags = &negotiate_flags;
183 a.out.negotiate_flags = &negotiate_flags;
184 a.in.credentials = &credentials3;
185 a.out.credentials = &credentials3;
187 creds_client_init(creds, &credentials1, &credentials2,
191 &mach_password, &credentials3,
194 printf("Testing ServerAuthenticate2\n");
196 status = dcerpc_netr_ServerAuthenticate2(p, mem_ctx, &a);
197 if (!NT_STATUS_IS_OK(status)) {
198 printf("ServerAuthenticate2 - %s\n", nt_errstr(status));
202 if (!creds_client_check(creds, &credentials3)) {
203 printf("Credential chaining failed\n");
207 printf("negotiate_flags=0x%08x\n", negotiate_flags);
214 BOOL test_SetupCredentials3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
215 uint32_t negotiate_flags,
216 const char *machine_name,
217 const char *plain_pass,
218 struct creds_CredentialState **creds_out)
221 struct netr_ServerReqChallenge r;
222 struct netr_ServerAuthenticate3 a;
223 struct netr_Credential credentials1, credentials2, credentials3;
224 struct creds_CredentialState *creds;
225 struct samr_Password mach_password;
228 printf("Testing ServerReqChallenge\n");
230 creds = talloc(mem_ctx, struct creds_CredentialState);
235 r.in.server_name = NULL;
236 r.in.computer_name = machine_name;
237 r.in.credentials = &credentials1;
238 r.out.credentials = &credentials2;
240 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
242 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
243 if (!NT_STATUS_IS_OK(status)) {
244 printf("ServerReqChallenge - %s\n", nt_errstr(status));
248 E_md4hash(plain_pass, mach_password.hash);
250 a.in.server_name = NULL;
251 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", machine_name);
252 a.in.secure_channel_type = SEC_CHAN_BDC;
253 a.in.computer_name = machine_name;
254 a.in.negotiate_flags = &negotiate_flags;
255 a.in.credentials = &credentials3;
256 a.out.credentials = &credentials3;
257 a.out.negotiate_flags = &negotiate_flags;
260 creds_client_init(creds, &credentials1, &credentials2,
264 &mach_password, &credentials3,
267 printf("Testing ServerAuthenticate3\n");
269 status = dcerpc_netr_ServerAuthenticate3(p, mem_ctx, &a);
270 if (!NT_STATUS_IS_OK(status)) {
271 printf("ServerAuthenticate3 - %s\n", nt_errstr(status));
275 if (!creds_client_check(creds, &credentials3)) {
276 printf("Credential chaining failed\n");
280 printf("negotiate_flags=0x%08x\n", negotiate_flags);
287 try a change password for our machine account
289 static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
292 struct netr_ServerPasswordSet r;
293 const char *password;
294 struct creds_CredentialState *creds;
296 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME,
297 machine_password, &creds)) {
301 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
302 r.in.account_name = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
303 r.in.secure_channel_type = SEC_CHAN_BDC;
304 r.in.computer_name = TEST_MACHINE_NAME;
307 E_md4hash(password, r.in.new_password.hash);
309 creds_des_encrypt(creds, &r.in.new_password);
310 /* by changing the machine password to ""
311 * we check if the server uses password restrictions
312 * for ServerPasswordSet2
313 * (win2k3 accepts "")
315 printf("Testing a second ServerPasswordSet on machine account\n");
316 printf("Changing machine account password to '%s'\n", password);
318 creds_client_authenticator(creds, &r.in.credential);
320 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
321 if (!NT_STATUS_IS_OK(status)) {
322 printf("ServerPasswordSet (2) - %s\n", nt_errstr(status));
326 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
327 printf("Credential chaining failed\n");
330 machine_password = password;
332 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
333 printf("ServerPasswordSet failed to actually change the password\n");
337 password = generate_random_str(mem_ctx, 8);
338 E_md4hash(password, r.in.new_password.hash);
340 creds_des_encrypt(creds, &r.in.new_password);
342 printf("Testing ServerPasswordSet on machine account\n");
343 printf("Changing machine account password to '%s'\n", password);
345 creds_client_authenticator(creds, &r.in.credential);
347 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
348 if (!NT_STATUS_IS_OK(status)) {
349 printf("ServerPasswordSet - %s\n", nt_errstr(status));
353 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
354 printf("Credential chaining failed\n");
357 /* by changing the machine password twice we test the
358 credentials chaining fully, and we verify that the server
359 allows the password to be set to the same value twice in a
360 row (match win2k3) */
361 printf("Testing a second ServerPasswordSet on machine account\n");
362 printf("Changing machine account password to '%s' (same as previous run)\n", password);
364 creds_client_authenticator(creds, &r.in.credential);
366 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
367 if (!NT_STATUS_IS_OK(status)) {
368 printf("ServerPasswordSet (2) - %s\n", nt_errstr(status));
372 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
373 printf("Credential chaining failed\n");
376 machine_password = password;
378 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
379 printf("ServerPasswordSet failed to actually change the password\n");
387 try a change password for our machine account
389 static BOOL test_SetPassword2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
392 struct netr_ServerPasswordSet2 r;
393 const char *password;
394 struct creds_CredentialState *creds;
396 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME,
397 machine_password, &creds)) {
401 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
402 r.in.account_name = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
403 r.in.secure_channel_type = SEC_CHAN_BDC;
404 r.in.computer_name = TEST_MACHINE_NAME;
407 encode_pw_buffer(r.in.new_password.data, password, STR_UNICODE);
408 creds_arcfour_crypt(creds, r.in.new_password.data, 516);
410 /* by changing the machine password to ""
411 * we check if the server uses password restrictions
412 * for ServerPasswordSet2
413 * (win2k3 accepts "")
415 printf("Testing a second ServerPasswordSet2 on machine account\n");
416 printf("Changing machine account password to '%s'\n", password);
418 creds_client_authenticator(creds, &r.in.credential);
420 status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
421 if (!NT_STATUS_IS_OK(status)) {
422 printf("ServerPasswordSet (2) - %s\n", nt_errstr(status));
426 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
427 printf("Credential chaining failed\n");
430 machine_password = password;
432 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
433 printf("ServerPasswordSet failed to actually change the password\n");
437 /* now try a random password */
438 password = generate_random_str(mem_ctx, 8);
439 encode_pw_buffer(r.in.new_password.data, password, STR_UNICODE);
440 creds_arcfour_crypt(creds, r.in.new_password.data, 516);
442 printf("Testing ServerPasswordSet2 on machine account\n");
443 printf("Changing machine account password to '%s'\n", password);
445 creds_client_authenticator(creds, &r.in.credential);
447 status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
448 if (!NT_STATUS_IS_OK(status)) {
449 printf("ServerPasswordSet2 - %s\n", nt_errstr(status));
453 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
454 printf("Credential chaining failed\n");
457 /* by changing the machine password twice we test the
458 credentials chaining fully, and we verify that the server
459 allows the password to be set to the same value twice in a
460 row (match win2k3) */
461 printf("Testing a second ServerPasswordSet2 on machine account\n");
462 printf("Changing machine account password to '%s' (same as previous run)\n", password);
464 creds_client_authenticator(creds, &r.in.credential);
466 status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
467 if (!NT_STATUS_IS_OK(status)) {
468 printf("ServerPasswordSet (2) - %s\n", nt_errstr(status));
472 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
473 printf("Credential chaining failed\n");
476 machine_password = password;
478 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
479 printf("ServerPasswordSet failed to actually change the password\n");
487 try a netlogon SamLogon
489 static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
492 struct netr_LogonSamLogon r;
493 struct netr_Authenticator auth, auth2;
494 struct netr_NetworkInfo ninfo;
495 const char *username = cli_credentials_get_username(cmdline_credentials);
496 const char *password = cli_credentials_get_password(cmdline_credentials);
497 struct creds_CredentialState *creds;
502 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME,
503 machine_password, &creds)) {
507 ninfo.identity_info.domain_name.string = cli_credentials_get_domain(cmdline_credentials);
508 ninfo.identity_info.parameter_control = 0;
509 ninfo.identity_info.logon_id_low = 0;
510 ninfo.identity_info.logon_id_high = 0;
511 ninfo.identity_info.account_name.string = username;
512 ninfo.identity_info.workstation.string = TEST_MACHINE_NAME;
513 generate_random_buffer(ninfo.challenge,
514 sizeof(ninfo.challenge));
515 ninfo.nt.length = 24;
516 ninfo.nt.data = talloc_size(mem_ctx, 24);
517 SMBNTencrypt(password, ninfo.challenge, ninfo.nt.data);
518 ninfo.lm.length = 24;
519 ninfo.lm.data = talloc_size(mem_ctx, 24);
520 SMBencrypt(password, ninfo.challenge, ninfo.lm.data);
522 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
523 r.in.workstation = TEST_MACHINE_NAME;
524 r.in.credential = &auth;
525 r.in.return_authenticator = &auth2;
526 r.in.logon_level = 2;
527 r.in.logon.network = &ninfo;
531 creds_client_authenticator(creds, &auth);
533 r.in.validation_level = i;
535 printf("Testing SamLogon with validation level %d\n", i);
537 status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r);
538 if (!NT_STATUS_IS_OK(status)) {
539 printf("LogonSamLogon - %s\n", nt_errstr(status));
543 if (!creds_client_check(creds, &r.out.return_authenticator->cred)) {
544 printf("Credential chaining failed\n");
548 r.in.credential = NULL;
552 r.in.validation_level = i;
554 printf("Testing SamLogon with validation level %d\n", i);
556 status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r);
557 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
558 printf("LogonSamLogon expected INVALID_PARAMETER, got: %s\n", nt_errstr(status));
567 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
568 static uint64_t sequence_nums[3];
571 try a netlogon DatabaseSync
573 static BOOL test_DatabaseSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
576 struct netr_DatabaseSync r;
577 struct creds_CredentialState *creds;
578 const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
582 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
586 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
587 r.in.computername = TEST_MACHINE_NAME;
588 r.in.preferredmaximumlength = (uint32_t)-1;
589 ZERO_STRUCT(r.in.return_authenticator);
591 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
592 r.in.sync_context = 0;
593 r.in.database_id = database_ids[i];
595 printf("Testing DatabaseSync of id %d\n", r.in.database_id);
598 creds_client_authenticator(creds, &r.in.credential);
600 status = dcerpc_netr_DatabaseSync(p, mem_ctx, &r);
601 if (!NT_STATUS_IS_OK(status) &&
602 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
603 printf("DatabaseSync - %s\n", nt_errstr(status));
608 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
609 printf("Credential chaining failed\n");
612 r.in.sync_context = r.out.sync_context;
614 if (r.out.delta_enum_array &&
615 r.out.delta_enum_array->num_deltas > 0 &&
616 r.out.delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
617 r.out.delta_enum_array->delta_enum[0].delta_union.domain) {
618 sequence_nums[r.in.database_id] =
619 r.out.delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
620 printf("\tsequence_nums[%d]=%llu\n",
622 sequence_nums[r.in.database_id]);
624 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
632 try a netlogon DatabaseDeltas
634 static BOOL test_DatabaseDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
637 struct netr_DatabaseDeltas r;
638 struct creds_CredentialState *creds;
639 const uint32_t database_ids[] = {0, 1, 2};
643 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
647 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
648 r.in.computername = TEST_MACHINE_NAME;
649 r.in.preferredmaximumlength = (uint32_t)-1;
650 ZERO_STRUCT(r.in.return_authenticator);
652 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
653 r.in.database_id = database_ids[i];
654 r.in.sequence_num = sequence_nums[r.in.database_id];
656 if (r.in.sequence_num == 0) continue;
658 r.in.sequence_num -= 1;
661 printf("Testing DatabaseDeltas of id %d at %llu\n",
662 r.in.database_id, r.in.sequence_num);
665 creds_client_authenticator(creds, &r.in.credential);
667 status = dcerpc_netr_DatabaseDeltas(p, mem_ctx, &r);
668 if (!NT_STATUS_IS_OK(status) &&
669 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
670 printf("DatabaseDeltas - %s\n", nt_errstr(status));
675 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
676 printf("Credential chaining failed\n");
680 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
688 try a netlogon AccountDeltas
690 static BOOL test_AccountDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
693 struct netr_AccountDeltas r;
694 struct creds_CredentialState *creds;
697 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
701 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
702 r.in.computername = TEST_MACHINE_NAME;
703 ZERO_STRUCT(r.in.return_authenticator);
704 creds_client_authenticator(creds, &r.in.credential);
705 ZERO_STRUCT(r.in.uas);
710 printf("Testing AccountDeltas\n");
712 /* w2k3 returns "NOT IMPLEMENTED" for this call */
713 status = dcerpc_netr_AccountDeltas(p, mem_ctx, &r);
714 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
715 printf("AccountDeltas - %s\n", nt_errstr(status));
723 try a netlogon AccountSync
725 static BOOL test_AccountSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
728 struct netr_AccountSync r;
729 struct creds_CredentialState *creds;
732 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
736 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
737 r.in.computername = TEST_MACHINE_NAME;
738 ZERO_STRUCT(r.in.return_authenticator);
739 creds_client_authenticator(creds, &r.in.credential);
740 ZERO_STRUCT(r.in.recordid);
745 printf("Testing AccountSync\n");
747 /* w2k3 returns "NOT IMPLEMENTED" for this call */
748 status = dcerpc_netr_AccountSync(p, mem_ctx, &r);
749 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
750 printf("AccountSync - %s\n", nt_errstr(status));
758 try a netlogon GetDcName
760 static BOOL test_GetDcName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
763 struct netr_GetDcName r;
765 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
766 r.in.domainname = lp_workgroup();
768 printf("Testing GetDcName\n");
770 status = dcerpc_netr_GetDcName(p, mem_ctx, &r);
771 if (!NT_STATUS_IS_OK(status)) {
772 printf("GetDcName - %s\n", nt_errstr(status));
776 printf("\tDC is at '%s'\n", r.out.dcname);
782 try a netlogon LogonControl
784 static BOOL test_LogonControl(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
787 struct netr_LogonControl r;
791 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
792 r.in.function_code = 1;
797 printf("Testing LogonControl level %d\n", i);
799 status = dcerpc_netr_LogonControl(p, mem_ctx, &r);
800 if (!NT_STATUS_IS_OK(status)) {
801 printf("LogonControl - %s\n", nt_errstr(status));
811 try a netlogon GetAnyDCName
813 static BOOL test_GetAnyDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
816 struct netr_GetAnyDCName r;
818 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
819 r.in.domainname = lp_workgroup();
821 printf("Testing GetAnyDCName\n");
823 status = dcerpc_netr_GetAnyDCName(p, mem_ctx, &r);
824 if (!NT_STATUS_IS_OK(status)) {
825 printf("GetAnyDCName - %s\n", nt_errstr(status));
830 printf("\tDC is at '%s'\n", r.out.dcname);
838 try a netlogon LogonControl2
840 static BOOL test_LogonControl2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
843 struct netr_LogonControl2 r;
847 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
849 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
850 r.in.data.domain = lp_workgroup();
855 printf("Testing LogonControl2 level %d function %d\n",
856 i, r.in.function_code);
858 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
859 if (!NT_STATUS_IS_OK(status)) {
860 printf("LogonControl - %s\n", nt_errstr(status));
865 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
866 r.in.data.domain = lp_workgroup();
871 printf("Testing LogonControl2 level %d function %d\n",
872 i, r.in.function_code);
874 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
875 if (!NT_STATUS_IS_OK(status)) {
876 printf("LogonControl - %s\n", nt_errstr(status));
881 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
882 r.in.data.domain = lp_workgroup();
887 printf("Testing LogonControl2 level %d function %d\n",
888 i, r.in.function_code);
890 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
891 if (!NT_STATUS_IS_OK(status)) {
892 printf("LogonControl - %s\n", nt_errstr(status));
897 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
898 r.in.data.debug_level = ~0;
903 printf("Testing LogonControl2 level %d function %d\n",
904 i, r.in.function_code);
906 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
907 if (!NT_STATUS_IS_OK(status)) {
908 printf("LogonControl - %s\n", nt_errstr(status));
917 try a netlogon DatabaseSync2
919 static BOOL test_DatabaseSync2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
922 struct netr_DatabaseSync2 r;
923 struct creds_CredentialState *creds;
924 const uint32_t database_ids[] = {0, 1, 2};
928 if (!test_SetupCredentials2(p, mem_ctx, NETLOGON_NEG_AUTH2_FLAGS,
929 TEST_MACHINE_NAME, machine_password,
930 SEC_CHAN_BDC, &creds)) {
934 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
935 r.in.computername = TEST_MACHINE_NAME;
936 r.in.preferredmaximumlength = (uint32_t)-1;
937 ZERO_STRUCT(r.in.return_authenticator);
939 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
940 r.in.sync_context = 0;
941 r.in.database_id = database_ids[i];
942 r.in.restart_state = 0;
944 printf("Testing DatabaseSync2 of id %d\n", r.in.database_id);
947 creds_client_authenticator(creds, &r.in.credential);
949 status = dcerpc_netr_DatabaseSync2(p, mem_ctx, &r);
950 if (!NT_STATUS_IS_OK(status) &&
951 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
952 printf("DatabaseSync2 - %s\n", nt_errstr(status));
957 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
958 printf("Credential chaining failed\n");
961 r.in.sync_context = r.out.sync_context;
962 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
970 try a netlogon LogonControl2Ex
972 static BOOL test_LogonControl2Ex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
975 struct netr_LogonControl2Ex r;
979 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
981 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
982 r.in.data.domain = lp_workgroup();
987 printf("Testing LogonControl2Ex level %d function %d\n",
988 i, r.in.function_code);
990 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
991 if (!NT_STATUS_IS_OK(status)) {
992 printf("LogonControl - %s\n", nt_errstr(status));
997 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
998 r.in.data.domain = lp_workgroup();
1003 printf("Testing LogonControl2Ex level %d function %d\n",
1004 i, r.in.function_code);
1006 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1007 if (!NT_STATUS_IS_OK(status)) {
1008 printf("LogonControl - %s\n", nt_errstr(status));
1013 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1014 r.in.data.domain = lp_workgroup();
1019 printf("Testing LogonControl2Ex level %d function %d\n",
1020 i, r.in.function_code);
1022 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1023 if (!NT_STATUS_IS_OK(status)) {
1024 printf("LogonControl - %s\n", nt_errstr(status));
1029 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1030 r.in.data.debug_level = ~0;
1035 printf("Testing LogonControl2Ex level %d function %d\n",
1036 i, r.in.function_code);
1038 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1039 if (!NT_STATUS_IS_OK(status)) {
1040 printf("LogonControl - %s\n", nt_errstr(status));
1050 try a netlogon netr_DsrEnumerateDomainTrusts
1052 static BOOL test_DsrEnumerateDomainTrusts(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1055 struct netr_DsrEnumerateDomainTrusts r;
1057 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1058 r.in.trust_flags = 0x3f;
1060 printf("Testing netr_DsrEnumerateDomainTrusts\n");
1062 status = dcerpc_netr_DsrEnumerateDomainTrusts(p, mem_ctx, &r);
1063 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1064 printf("netr_DsrEnumerateDomainTrusts - %s/%s\n",
1065 nt_errstr(status), win_errstr(r.out.result));
1073 try a netlogon netr_DrsGetDCNameEx2
1075 static BOOL test_netr_DrsGetDCNameEx2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1078 struct netr_DrsGetDCNameEx2 r;
1081 r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1082 r.in.client_account = NULL;
1083 r.in.mask = 0x00000000;
1084 r.in.domain_name = talloc_asprintf(mem_ctx, "%s", lp_realm());
1085 r.in.domain_guid = NULL;
1086 r.in.site_name = NULL;
1087 r.in.flags = 0x40000000;
1089 printf("Testing netr_DrsGetDCNameEx2 without client account\n");
1091 status = dcerpc_netr_DrsGetDCNameEx2(p, mem_ctx, &r);
1092 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1093 printf("netr_DrsGetDCNameEx2 - %s/%s\n",
1094 nt_errstr(status), win_errstr(r.out.result));
1098 printf("Testing netr_DrsGetDCNameEx2 with client acount\n");
1099 r.in.client_account = TEST_MACHINE_NAME"$";
1100 r.in.mask = 0x00002000;
1101 r.in.flags = 0x80000000;
1103 status = dcerpc_netr_DrsGetDCNameEx2(p, mem_ctx, &r);
1104 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1105 printf("netr_DrsGetDCNameEx2 - %s/%s\n",
1106 nt_errstr(status), win_errstr(r.out.result));
1113 static BOOL test_GetDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1116 struct netr_LogonGetDomainInfo r;
1117 struct netr_DomainQuery1 q1;
1118 struct netr_Authenticator a;
1119 struct creds_CredentialState *creds;
1121 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
1122 TEST_MACHINE_NAME, machine_password, &creds)) {
1128 creds_client_authenticator(creds, &a);
1130 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1131 r.in.computer_name = TEST_MACHINE_NAME;
1133 r.in.credential = &a;
1134 r.in.return_authenticator = &a;
1135 r.out.return_authenticator = &a;
1137 r.in.query.query1 = &q1;
1140 /* this should really be the fully qualified name */
1141 q1.workstation_domain = TEST_MACHINE_NAME;
1142 q1.workstation_site = "Default-First-Site-Name";
1143 q1.blob2.length = 0;
1145 q1.blob2.data = NULL;
1146 q1.product.string = "product string";
1148 printf("Testing netr_LogonGetDomainInfo\n");
1150 status = dcerpc_netr_LogonGetDomainInfo(p, mem_ctx, &r);
1151 if (!NT_STATUS_IS_OK(status)) {
1152 printf("netr_LogonGetDomainInfo - %s\n", nt_errstr(status));
1156 if (!creds_client_check(creds, &a.cred)) {
1157 printf("Credential chaining failed\n");
1165 static void async_callback(struct rpc_request *req)
1167 int *counter = req->async.private;
1168 if (NT_STATUS_IS_OK(req->status)) {
1173 static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1176 struct netr_LogonGetDomainInfo r;
1177 struct netr_DomainQuery1 q1;
1178 struct netr_Authenticator a;
1179 #define ASYNC_COUNT 100
1180 struct creds_CredentialState *creds;
1181 struct creds_CredentialState *creds_async[ASYNC_COUNT];
1182 struct rpc_request *req[ASYNC_COUNT];
1184 int *async_counter = talloc(mem_ctx, int);
1186 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
1187 printf("test_GetDomainInfo_async disabled - enable dangerous tests to use\n");
1191 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
1192 TEST_MACHINE_NAME, machine_password, &creds)) {
1197 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1198 r.in.computer_name = TEST_MACHINE_NAME;
1200 r.in.credential = &a;
1201 r.in.return_authenticator = &a;
1202 r.out.return_authenticator = &a;
1204 r.in.query.query1 = &q1;
1207 /* this should really be the fully qualified name */
1208 q1.workstation_domain = TEST_MACHINE_NAME;
1209 q1.workstation_site = "Default-First-Site-Name";
1210 q1.blob2.length = 0;
1212 q1.blob2.data = NULL;
1213 q1.product.string = "product string";
1215 printf("Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
1219 for (i=0;i<ASYNC_COUNT;i++) {
1220 creds_client_authenticator(creds, &a);
1222 creds_async[i] = talloc_memdup(creds, creds, sizeof(*creds));
1223 req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, mem_ctx, &r);
1225 req[i]->async.callback = async_callback;
1226 req[i]->async.private = async_counter;
1228 /* even with this flush per request a w2k3 server seems to
1229 clag with multiple outstanding requests. bleergh. */
1230 if (event_loop_once(dcerpc_event_context(p)) != 0) {
1235 for (i=0;i<ASYNC_COUNT;i++) {
1236 status = dcerpc_ndr_request_recv(req[i]);
1237 if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(r.out.result)) {
1238 printf("netr_LogonGetDomainInfo_async(%d) - %s/%s\n",
1239 i, nt_errstr(status), nt_errstr(r.out.result));
1243 if (!creds_client_check(creds_async[i], &a.cred)) {
1244 printf("Credential chaining failed at async %d\n", i);
1249 printf("Testing netr_LogonGetDomainInfo - async count %d OK\n", *async_counter);
1251 return (*async_counter) == ASYNC_COUNT;
1254 static BOOL test_ManyGetDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1257 struct dcerpc_binding *b;
1258 struct dcerpc_pipe *p2;
1259 struct lsa_ObjectAttribute attr;
1260 struct lsa_QosInfo qos;
1261 struct lsa_OpenPolicy2 o;
1262 struct policy_handle lsa_handle;
1263 struct lsa_DomainList domains;
1265 struct lsa_EnumTrustDom t;
1266 uint32_t resume_handle = 0;
1267 struct netr_GetAnyDCName d;
1272 if (p->conn->transport.transport != NCACN_NP) {
1276 printf("Torturing GetDCName\n");
1278 status = dcerpc_parse_binding(mem_ctx, p->conn->binding_string, &b);
1279 if (!NT_STATUS_IS_OK(status)) {
1280 printf("Failed to parse dcerpc binding '%s'\n", p->conn->binding_string);
1284 status = dcerpc_secondary_connection(p, &p2, b);
1285 if (!NT_STATUS_IS_OK(status)) {
1286 printf("Failed to create secondary connection\n");
1290 status = dcerpc_bind_auth_none(p2, DCERPC_LSARPC_UUID,
1291 DCERPC_LSARPC_VERSION);
1292 if (!NT_STATUS_IS_OK(status)) {
1293 printf("Failed to create bind on secondary connection\n");
1298 qos.impersonation_level = 2;
1299 qos.context_mode = 1;
1300 qos.effective_only = 0;
1303 attr.root_dir = NULL;
1304 attr.object_name = NULL;
1305 attr.attributes = 0;
1306 attr.sec_desc = NULL;
1307 attr.sec_qos = &qos;
1309 o.in.system_name = "\\";
1311 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1312 o.out.handle = &lsa_handle;
1314 status = dcerpc_lsa_OpenPolicy2(p2, mem_ctx, &o);
1315 if (!NT_STATUS_IS_OK(status)) {
1316 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
1320 t.in.handle = &lsa_handle;
1321 t.in.resume_handle = &resume_handle;
1322 t.in.max_size = 1000;
1323 t.out.domains = &domains;
1324 t.out.resume_handle = &resume_handle;
1326 status = dcerpc_lsa_EnumTrustDom(p2, mem_ctx, &t);
1328 if ((!NT_STATUS_IS_OK(status) &&
1329 (!NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)))) {
1330 printf("Could not list domains\n");
1336 d.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s",
1337 dcerpc_server_name(p));
1339 for (i=0; i<domains.count * 4; i++) {
1340 struct lsa_DomainInformation *info =
1341 &domains.domains[rand()%domains.count];
1343 d.in.domainname = info->name.string;
1345 status = dcerpc_netr_GetAnyDCName(p, mem_ctx, &d);
1346 if (!NT_STATUS_IS_OK(status)) {
1347 printf("GetAnyDCName - %s\n", nt_errstr(status));
1351 printf("\tDC for domain %s is %s\n", info->name.string,
1352 d.out.dcname ? d.out.dcname : "unknown");
1359 BOOL torture_rpc_netlogon(void)
1362 struct dcerpc_pipe *p;
1363 TALLOC_CTX *mem_ctx;
1365 struct test_join *join_ctx;
1367 mem_ctx = talloc_init("torture_rpc_netlogon");
1369 join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), ACB_SVRTRUST,
1372 talloc_free(mem_ctx);
1373 printf("Failed to join as BDC\n");
1377 status = torture_rpc_connection(mem_ctx, &p,
1378 DCERPC_NETLOGON_NAME,
1379 DCERPC_NETLOGON_UUID,
1380 DCERPC_NETLOGON_VERSION);
1381 if (!NT_STATUS_IS_OK(status)) {
1382 talloc_free(mem_ctx);
1386 ret &= test_LogonUasLogon(p, mem_ctx);
1387 ret &= test_LogonUasLogoff(p, mem_ctx);
1388 ret &= test_SamLogon(p, mem_ctx);
1389 ret &= test_SetPassword(p, mem_ctx);
1390 ret &= test_SetPassword2(p, mem_ctx);
1391 ret &= test_GetDomainInfo(p, mem_ctx);
1392 ret &= test_DatabaseSync(p, mem_ctx);
1393 ret &= test_DatabaseDeltas(p, mem_ctx);
1394 ret &= test_AccountDeltas(p, mem_ctx);
1395 ret &= test_AccountSync(p, mem_ctx);
1396 ret &= test_GetDcName(p, mem_ctx);
1397 ret &= test_ManyGetDCName(p, mem_ctx);
1398 ret &= test_LogonControl(p, mem_ctx);
1399 ret &= test_GetAnyDCName(p, mem_ctx);
1400 ret &= test_LogonControl2(p, mem_ctx);
1401 ret &= test_DatabaseSync2(p, mem_ctx);
1402 ret &= test_LogonControl2Ex(p, mem_ctx);
1403 ret &= test_DsrEnumerateDomainTrusts(p, mem_ctx);
1404 ret &= test_GetDomainInfo_async(p, mem_ctx);
1405 ret &= test_netr_DrsGetDCNameEx2(p, mem_ctx);
1407 talloc_free(mem_ctx);
1409 torture_leave_domain(join_ctx);