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"
30 static const char *machine_password;
32 #define TEST_MACHINE_NAME "torturetest"
34 static BOOL test_LogonUasLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
37 struct netr_LogonUasLogon r;
39 r.in.server_name = NULL;
40 r.in.account_name = lp_parm_string(-1, "torture", "username");
41 r.in.workstation = TEST_MACHINE_NAME;
43 printf("Testing LogonUasLogon\n");
45 status = dcerpc_netr_LogonUasLogon(p, mem_ctx, &r);
46 if (!NT_STATUS_IS_OK(status)) {
47 printf("LogonUasLogon - %s\n", nt_errstr(status));
55 static BOOL test_LogonUasLogoff(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
58 struct netr_LogonUasLogoff r;
60 r.in.server_name = NULL;
61 r.in.account_name = lp_parm_string(-1, "torture", "username");
62 r.in.workstation = TEST_MACHINE_NAME;
64 printf("Testing LogonUasLogoff\n");
66 status = dcerpc_netr_LogonUasLogoff(p, mem_ctx, &r);
67 if (!NT_STATUS_IS_OK(status)) {
68 printf("LogonUasLogoff - %s\n", nt_errstr(status));
76 BOOL test_SetupCredentials(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
77 const char *machine_name,
78 const char *plain_pass,
79 struct creds_CredentialState **creds_out)
82 struct netr_ServerReqChallenge r;
83 struct netr_ServerAuthenticate a;
84 struct netr_Credential credentials1, credentials2, credentials3;
85 struct creds_CredentialState *creds;
86 struct samr_Password mach_password;
88 printf("Testing ServerReqChallenge\n");
90 creds = talloc(mem_ctx, struct creds_CredentialState);
95 r.in.server_name = NULL;
96 r.in.computer_name = machine_name;
97 r.in.credentials = &credentials1;
98 r.out.credentials = &credentials2;
100 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
102 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
103 if (!NT_STATUS_IS_OK(status)) {
104 printf("ServerReqChallenge - %s\n", nt_errstr(status));
108 E_md4hash(plain_pass, mach_password.hash);
110 a.in.server_name = NULL;
111 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", machine_name);
112 a.in.secure_channel_type = SEC_CHAN_BDC;
113 a.in.computer_name = machine_name;
114 a.in.credentials = &credentials3;
115 a.out.credentials = &credentials3;
117 creds_client_init(creds, &credentials1, &credentials2,
121 &mach_password, &credentials3,
124 printf("Testing ServerAuthenticate\n");
126 status = dcerpc_netr_ServerAuthenticate(p, mem_ctx, &a);
127 if (!NT_STATUS_IS_OK(status)) {
128 printf("ServerAuthenticate - %s\n", nt_errstr(status));
132 if (!creds_client_check(creds, &credentials3)) {
133 printf("Credential chaining failed\n");
141 BOOL test_SetupCredentials2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
142 uint32_t negotiate_flags,
143 const char *machine_name,
144 const char *plain_pass,
146 struct creds_CredentialState **creds_out)
149 struct netr_ServerReqChallenge r;
150 struct netr_ServerAuthenticate2 a;
151 struct netr_Credential credentials1, credentials2, credentials3;
152 struct creds_CredentialState *creds;
153 struct samr_Password mach_password;
155 printf("Testing ServerReqChallenge\n");
157 creds = talloc(mem_ctx, struct creds_CredentialState);
162 r.in.server_name = NULL;
163 r.in.computer_name = machine_name;
164 r.in.credentials = &credentials1;
165 r.out.credentials = &credentials2;
167 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
169 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
170 if (!NT_STATUS_IS_OK(status)) {
171 printf("ServerReqChallenge - %s\n", nt_errstr(status));
175 E_md4hash(plain_pass, mach_password.hash);
177 a.in.server_name = NULL;
178 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", machine_name);
179 a.in.secure_channel_type = sec_chan_type;
180 a.in.computer_name = machine_name;
181 a.in.negotiate_flags = &negotiate_flags;
182 a.out.negotiate_flags = &negotiate_flags;
183 a.in.credentials = &credentials3;
184 a.out.credentials = &credentials3;
186 creds_client_init(creds, &credentials1, &credentials2,
190 &mach_password, &credentials3,
193 printf("Testing ServerAuthenticate2\n");
195 status = dcerpc_netr_ServerAuthenticate2(p, mem_ctx, &a);
196 if (!NT_STATUS_IS_OK(status)) {
197 printf("ServerAuthenticate2 - %s\n", nt_errstr(status));
201 if (!creds_client_check(creds, &credentials3)) {
202 printf("Credential chaining failed\n");
206 printf("negotiate_flags=0x%08x\n", negotiate_flags);
213 BOOL test_SetupCredentials3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
214 uint32_t negotiate_flags,
215 const char *machine_name,
216 const char *plain_pass,
217 struct creds_CredentialState **creds_out)
220 struct netr_ServerReqChallenge r;
221 struct netr_ServerAuthenticate3 a;
222 struct netr_Credential credentials1, credentials2, credentials3;
223 struct creds_CredentialState *creds;
224 struct samr_Password mach_password;
227 printf("Testing ServerReqChallenge\n");
229 creds = talloc(mem_ctx, struct creds_CredentialState);
234 r.in.server_name = NULL;
235 r.in.computer_name = machine_name;
236 r.in.credentials = &credentials1;
237 r.out.credentials = &credentials2;
239 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
241 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
242 if (!NT_STATUS_IS_OK(status)) {
243 printf("ServerReqChallenge - %s\n", nt_errstr(status));
247 E_md4hash(plain_pass, mach_password.hash);
249 a.in.server_name = NULL;
250 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", machine_name);
251 a.in.secure_channel_type = SEC_CHAN_BDC;
252 a.in.computer_name = machine_name;
253 a.in.negotiate_flags = &negotiate_flags;
254 a.in.credentials = &credentials3;
255 a.out.credentials = &credentials3;
256 a.out.negotiate_flags = &negotiate_flags;
259 creds_client_init(creds, &credentials1, &credentials2,
263 &mach_password, &credentials3,
266 printf("Testing ServerAuthenticate3\n");
268 status = dcerpc_netr_ServerAuthenticate3(p, mem_ctx, &a);
269 if (!NT_STATUS_IS_OK(status)) {
270 printf("ServerAuthenticate3 - %s\n", nt_errstr(status));
274 if (!creds_client_check(creds, &credentials3)) {
275 printf("Credential chaining failed\n");
279 printf("negotiate_flags=0x%08x\n", negotiate_flags);
286 try a change password for our machine account
288 static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
291 struct netr_ServerPasswordSet r;
292 const char *password;
293 struct creds_CredentialState *creds;
295 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME,
296 machine_password, &creds)) {
300 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
301 r.in.account_name = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
302 r.in.secure_channel_type = SEC_CHAN_BDC;
303 r.in.computer_name = TEST_MACHINE_NAME;
306 E_md4hash(password, r.in.new_password.hash);
308 creds_des_encrypt(creds, &r.in.new_password);
309 /* by changing the machine password to ""
310 * we check if the server uses password restrictions
311 * for ServerPasswordSet2
312 * (win2k3 accepts "")
314 printf("Testing a second ServerPasswordSet on machine account\n");
315 printf("Changing machine account password to '%s'\n", password);
317 creds_client_authenticator(creds, &r.in.credential);
319 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
320 if (!NT_STATUS_IS_OK(status)) {
321 printf("ServerPasswordSet (2) - %s\n", nt_errstr(status));
325 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
326 printf("Credential chaining failed\n");
329 machine_password = password;
331 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
332 printf("ServerPasswordSet failed to actually change the password\n");
336 password = generate_random_str(mem_ctx, 8);
337 E_md4hash(password, r.in.new_password.hash);
339 creds_des_encrypt(creds, &r.in.new_password);
341 printf("Testing ServerPasswordSet on machine account\n");
342 printf("Changing machine account password to '%s'\n", password);
344 creds_client_authenticator(creds, &r.in.credential);
346 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
347 if (!NT_STATUS_IS_OK(status)) {
348 printf("ServerPasswordSet - %s\n", nt_errstr(status));
352 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
353 printf("Credential chaining failed\n");
356 /* by changing the machine password twice we test the
357 credentials chaining fully, and we verify that the server
358 allows the password to be set to the same value twice in a
359 row (match win2k3) */
360 printf("Testing a second ServerPasswordSet on machine account\n");
361 printf("Changing machine account password to '%s' (same as previous run)\n", password);
363 creds_client_authenticator(creds, &r.in.credential);
365 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
366 if (!NT_STATUS_IS_OK(status)) {
367 printf("ServerPasswordSet (2) - %s\n", nt_errstr(status));
371 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
372 printf("Credential chaining failed\n");
375 machine_password = password;
377 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
378 printf("ServerPasswordSet failed to actually change the password\n");
386 try a change password for our machine account
388 static BOOL test_SetPassword2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
391 struct netr_ServerPasswordSet2 r;
392 const char *password;
393 struct creds_CredentialState *creds;
395 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME,
396 machine_password, &creds)) {
400 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
401 r.in.account_name = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
402 r.in.secure_channel_type = SEC_CHAN_BDC;
403 r.in.computer_name = TEST_MACHINE_NAME;
406 encode_pw_buffer(r.in.new_password.data, password, STR_UNICODE);
407 creds_arcfour_crypt(creds, r.in.new_password.data, 516);
409 /* by changing the machine password to ""
410 * we check if the server uses password restrictions
411 * for ServerPasswordSet2
412 * (win2k3 accepts "")
414 printf("Testing a second ServerPasswordSet2 on machine account\n");
415 printf("Changing machine account password to '%s'\n", password);
417 creds_client_authenticator(creds, &r.in.credential);
419 status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
420 if (!NT_STATUS_IS_OK(status)) {
421 printf("ServerPasswordSet (2) - %s\n", nt_errstr(status));
425 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
426 printf("Credential chaining failed\n");
429 machine_password = password;
431 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
432 printf("ServerPasswordSet failed to actually change the password\n");
436 /* now try a random password */
437 password = generate_random_str(mem_ctx, 8);
438 encode_pw_buffer(r.in.new_password.data, password, STR_UNICODE);
439 creds_arcfour_crypt(creds, r.in.new_password.data, 516);
441 printf("Testing ServerPasswordSet2 on machine account\n");
442 printf("Changing machine account password to '%s'\n", password);
444 creds_client_authenticator(creds, &r.in.credential);
446 status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
447 if (!NT_STATUS_IS_OK(status)) {
448 printf("ServerPasswordSet2 - %s\n", nt_errstr(status));
452 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
453 printf("Credential chaining failed\n");
456 /* by changing the machine password twice we test the
457 credentials chaining fully, and we verify that the server
458 allows the password to be set to the same value twice in a
459 row (match win2k3) */
460 printf("Testing a second ServerPasswordSet2 on machine account\n");
461 printf("Changing machine account password to '%s' (same as previous run)\n", password);
463 creds_client_authenticator(creds, &r.in.credential);
465 status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
466 if (!NT_STATUS_IS_OK(status)) {
467 printf("ServerPasswordSet (2) - %s\n", nt_errstr(status));
471 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
472 printf("Credential chaining failed\n");
475 machine_password = password;
477 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
478 printf("ServerPasswordSet failed to actually change the password\n");
486 try a netlogon SamLogon
488 static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
491 struct netr_LogonSamLogon r;
492 struct netr_Authenticator auth, auth2;
493 struct netr_NetworkInfo ninfo;
494 const char *username = lp_parm_string(-1, "torture", "username");
495 const char *password = lp_parm_string(-1, "torture", "password");
496 struct creds_CredentialState *creds;
501 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME,
502 machine_password, &creds)) {
506 ninfo.identity_info.domain_name.string = lp_workgroup();
507 ninfo.identity_info.parameter_control = 0;
508 ninfo.identity_info.logon_id_low = 0;
509 ninfo.identity_info.logon_id_high = 0;
510 ninfo.identity_info.account_name.string = username;
511 ninfo.identity_info.workstation.string = TEST_MACHINE_NAME;
512 generate_random_buffer(ninfo.challenge,
513 sizeof(ninfo.challenge));
514 ninfo.nt.length = 24;
515 ninfo.nt.data = talloc_size(mem_ctx, 24);
516 SMBNTencrypt(password, ninfo.challenge, ninfo.nt.data);
517 ninfo.lm.length = 24;
518 ninfo.lm.data = talloc_size(mem_ctx, 24);
519 SMBencrypt(password, ninfo.challenge, ninfo.lm.data);
521 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
522 r.in.workstation = TEST_MACHINE_NAME;
523 r.in.credential = &auth;
524 r.in.return_authenticator = &auth2;
525 r.in.logon_level = 2;
526 r.in.logon.network = &ninfo;
530 creds_client_authenticator(creds, &auth);
532 r.in.validation_level = i;
534 printf("Testing SamLogon with validation level %d\n", i);
536 status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r);
537 if (!NT_STATUS_IS_OK(status)) {
538 printf("LogonSamLogon - %s\n", nt_errstr(status));
542 if (!creds_client_check(creds, &r.out.return_authenticator->cred)) {
543 printf("Credential chaining failed\n");
547 r.in.credential = NULL;
551 r.in.validation_level = i;
553 printf("Testing SamLogon with validation level %d\n", i);
555 status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r);
556 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
557 printf("LogonSamLogon expected INVALID_PARAMETER, got: %s\n", nt_errstr(status));
566 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
567 static uint64_t sequence_nums[3];
570 try a netlogon DatabaseSync
572 static BOOL test_DatabaseSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
575 struct netr_DatabaseSync r;
576 struct creds_CredentialState *creds;
577 const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
581 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
585 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
586 r.in.computername = TEST_MACHINE_NAME;
587 r.in.preferredmaximumlength = (uint32_t)-1;
588 ZERO_STRUCT(r.in.return_authenticator);
590 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
591 r.in.sync_context = 0;
592 r.in.database_id = database_ids[i];
594 printf("Testing DatabaseSync of id %d\n", r.in.database_id);
597 creds_client_authenticator(creds, &r.in.credential);
599 status = dcerpc_netr_DatabaseSync(p, mem_ctx, &r);
600 if (!NT_STATUS_IS_OK(status) &&
601 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
602 printf("DatabaseSync - %s\n", nt_errstr(status));
607 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
608 printf("Credential chaining failed\n");
611 r.in.sync_context = r.out.sync_context;
613 if (r.out.delta_enum_array &&
614 r.out.delta_enum_array->num_deltas > 0 &&
615 r.out.delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
616 r.out.delta_enum_array->delta_enum[0].delta_union.domain) {
617 sequence_nums[r.in.database_id] =
618 r.out.delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
619 printf("\tsequence_nums[%d]=%llu\n",
621 sequence_nums[r.in.database_id]);
623 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
631 try a netlogon DatabaseDeltas
633 static BOOL test_DatabaseDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
636 struct netr_DatabaseDeltas r;
637 struct creds_CredentialState *creds;
638 const uint32_t database_ids[] = {0, 1, 2};
642 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
646 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
647 r.in.computername = TEST_MACHINE_NAME;
648 r.in.preferredmaximumlength = (uint32_t)-1;
649 ZERO_STRUCT(r.in.return_authenticator);
651 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
652 r.in.database_id = database_ids[i];
653 r.in.sequence_num = sequence_nums[r.in.database_id];
655 if (r.in.sequence_num == 0) continue;
657 r.in.sequence_num -= 1;
660 printf("Testing DatabaseDeltas of id %d at %llu\n",
661 r.in.database_id, r.in.sequence_num);
664 creds_client_authenticator(creds, &r.in.credential);
666 status = dcerpc_netr_DatabaseDeltas(p, mem_ctx, &r);
667 if (!NT_STATUS_IS_OK(status) &&
668 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
669 printf("DatabaseDeltas - %s\n", nt_errstr(status));
674 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
675 printf("Credential chaining failed\n");
679 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
687 try a netlogon AccountDeltas
689 static BOOL test_AccountDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
692 struct netr_AccountDeltas r;
693 struct creds_CredentialState *creds;
696 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
700 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
701 r.in.computername = TEST_MACHINE_NAME;
702 ZERO_STRUCT(r.in.return_authenticator);
703 creds_client_authenticator(creds, &r.in.credential);
704 ZERO_STRUCT(r.in.uas);
709 printf("Testing AccountDeltas\n");
711 /* w2k3 returns "NOT IMPLEMENTED" for this call */
712 status = dcerpc_netr_AccountDeltas(p, mem_ctx, &r);
713 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
714 printf("AccountDeltas - %s\n", nt_errstr(status));
722 try a netlogon AccountSync
724 static BOOL test_AccountSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
727 struct netr_AccountSync r;
728 struct creds_CredentialState *creds;
731 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
735 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
736 r.in.computername = TEST_MACHINE_NAME;
737 ZERO_STRUCT(r.in.return_authenticator);
738 creds_client_authenticator(creds, &r.in.credential);
739 ZERO_STRUCT(r.in.recordid);
744 printf("Testing AccountSync\n");
746 /* w2k3 returns "NOT IMPLEMENTED" for this call */
747 status = dcerpc_netr_AccountSync(p, mem_ctx, &r);
748 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
749 printf("AccountSync - %s\n", nt_errstr(status));
757 try a netlogon GetDcName
759 static BOOL test_GetDcName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
762 struct netr_GetDcName r;
764 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
765 r.in.domainname = lp_workgroup();
767 printf("Testing GetDcName\n");
769 status = dcerpc_netr_GetDcName(p, mem_ctx, &r);
770 if (!NT_STATUS_IS_OK(status)) {
771 printf("GetDcName - %s\n", nt_errstr(status));
775 printf("\tDC is at '%s'\n", r.out.dcname);
781 try a netlogon LogonControl
783 static BOOL test_LogonControl(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
786 struct netr_LogonControl r;
790 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
791 r.in.function_code = 1;
796 printf("Testing LogonControl level %d\n", i);
798 status = dcerpc_netr_LogonControl(p, mem_ctx, &r);
799 if (!NT_STATUS_IS_OK(status)) {
800 printf("LogonControl - %s\n", nt_errstr(status));
810 try a netlogon GetAnyDCName
812 static BOOL test_GetAnyDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
815 struct netr_GetAnyDCName r;
817 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
818 r.in.domainname = lp_workgroup();
820 printf("Testing GetAnyDCName\n");
822 status = dcerpc_netr_GetAnyDCName(p, mem_ctx, &r);
823 if (!NT_STATUS_IS_OK(status)) {
824 printf("GetAnyDCName - %s\n", nt_errstr(status));
829 printf("\tDC is at '%s'\n", r.out.dcname);
837 try a netlogon LogonControl2
839 static BOOL test_LogonControl2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
842 struct netr_LogonControl2 r;
846 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
848 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
849 r.in.data.domain = lp_workgroup();
854 printf("Testing LogonControl2 level %d function %d\n",
855 i, r.in.function_code);
857 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
858 if (!NT_STATUS_IS_OK(status)) {
859 printf("LogonControl - %s\n", nt_errstr(status));
864 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
865 r.in.data.domain = lp_workgroup();
870 printf("Testing LogonControl2 level %d function %d\n",
871 i, r.in.function_code);
873 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
874 if (!NT_STATUS_IS_OK(status)) {
875 printf("LogonControl - %s\n", nt_errstr(status));
880 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
881 r.in.data.domain = lp_workgroup();
886 printf("Testing LogonControl2 level %d function %d\n",
887 i, r.in.function_code);
889 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
890 if (!NT_STATUS_IS_OK(status)) {
891 printf("LogonControl - %s\n", nt_errstr(status));
896 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
897 r.in.data.debug_level = ~0;
902 printf("Testing LogonControl2 level %d function %d\n",
903 i, r.in.function_code);
905 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
906 if (!NT_STATUS_IS_OK(status)) {
907 printf("LogonControl - %s\n", nt_errstr(status));
916 try a netlogon DatabaseSync2
918 static BOOL test_DatabaseSync2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
921 struct netr_DatabaseSync2 r;
922 struct creds_CredentialState *creds;
923 const uint32_t database_ids[] = {0, 1, 2};
927 if (!test_SetupCredentials2(p, mem_ctx, NETLOGON_NEG_AUTH2_FLAGS,
928 TEST_MACHINE_NAME, machine_password,
929 SEC_CHAN_BDC, &creds)) {
933 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
934 r.in.computername = TEST_MACHINE_NAME;
935 r.in.preferredmaximumlength = (uint32_t)-1;
936 ZERO_STRUCT(r.in.return_authenticator);
938 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
939 r.in.sync_context = 0;
940 r.in.database_id = database_ids[i];
941 r.in.restart_state = 0;
943 printf("Testing DatabaseSync2 of id %d\n", r.in.database_id);
946 creds_client_authenticator(creds, &r.in.credential);
948 status = dcerpc_netr_DatabaseSync2(p, mem_ctx, &r);
949 if (!NT_STATUS_IS_OK(status) &&
950 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
951 printf("DatabaseSync2 - %s\n", nt_errstr(status));
956 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
957 printf("Credential chaining failed\n");
960 r.in.sync_context = r.out.sync_context;
961 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
969 try a netlogon LogonControl2Ex
971 static BOOL test_LogonControl2Ex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
974 struct netr_LogonControl2Ex r;
978 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
980 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
981 r.in.data.domain = lp_workgroup();
986 printf("Testing LogonControl2Ex level %d function %d\n",
987 i, r.in.function_code);
989 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
990 if (!NT_STATUS_IS_OK(status)) {
991 printf("LogonControl - %s\n", nt_errstr(status));
996 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
997 r.in.data.domain = lp_workgroup();
1002 printf("Testing LogonControl2Ex level %d function %d\n",
1003 i, r.in.function_code);
1005 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1006 if (!NT_STATUS_IS_OK(status)) {
1007 printf("LogonControl - %s\n", nt_errstr(status));
1012 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1013 r.in.data.domain = lp_workgroup();
1018 printf("Testing LogonControl2Ex level %d function %d\n",
1019 i, r.in.function_code);
1021 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1022 if (!NT_STATUS_IS_OK(status)) {
1023 printf("LogonControl - %s\n", nt_errstr(status));
1028 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1029 r.in.data.debug_level = ~0;
1034 printf("Testing LogonControl2Ex level %d function %d\n",
1035 i, r.in.function_code);
1037 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1038 if (!NT_STATUS_IS_OK(status)) {
1039 printf("LogonControl - %s\n", nt_errstr(status));
1049 try a netlogon netr_DsrEnumerateDomainTrusts
1051 static BOOL test_DsrEnumerateDomainTrusts(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1054 struct netr_DsrEnumerateDomainTrusts r;
1056 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1057 r.in.trust_flags = 0x3f;
1059 printf("Testing netr_DsrEnumerateDomainTrusts\n");
1061 status = dcerpc_netr_DsrEnumerateDomainTrusts(p, mem_ctx, &r);
1062 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1063 printf("netr_DsrEnumerateDomainTrusts - %s/%s\n",
1064 nt_errstr(status), win_errstr(r.out.result));
1072 try a netlogon netr_DrsGetDCNameEx2
1074 static BOOL test_netr_DrsGetDCNameEx2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1077 struct netr_DrsGetDCNameEx2 r;
1080 r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1081 r.in.client_account = NULL;
1082 r.in.mask = 0x00000000;
1083 r.in.domain_name = talloc_asprintf(mem_ctx, "%s", lp_realm());
1084 r.in.domain_guid = NULL;
1085 r.in.site_name = NULL;
1086 r.in.flags = 0x40000000;
1088 printf("Testing netr_DrsGetDCNameEx2 without client account\n");
1090 status = dcerpc_netr_DrsGetDCNameEx2(p, mem_ctx, &r);
1091 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1092 printf("netr_DrsGetDCNameEx2 - %s/%s\n",
1093 nt_errstr(status), win_errstr(r.out.result));
1097 printf("Testing netr_DrsGetDCNameEx2 with client acount\n");
1098 r.in.client_account = TEST_MACHINE_NAME"$";
1099 r.in.mask = 0x00002000;
1100 r.in.flags = 0x80000000;
1102 status = dcerpc_netr_DrsGetDCNameEx2(p, mem_ctx, &r);
1103 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1104 printf("netr_DrsGetDCNameEx2 - %s/%s\n",
1105 nt_errstr(status), win_errstr(r.out.result));
1112 static BOOL test_GetDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1115 struct netr_LogonGetDomainInfo r;
1116 struct netr_DomainQuery1 q1;
1117 struct netr_Authenticator a;
1118 struct creds_CredentialState *creds;
1120 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
1121 TEST_MACHINE_NAME, machine_password, &creds)) {
1127 creds_client_authenticator(creds, &a);
1129 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1130 r.in.computer_name = TEST_MACHINE_NAME;
1132 r.in.credential = &a;
1133 r.in.return_authenticator = &a;
1134 r.out.return_authenticator = &a;
1136 r.in.query.query1 = &q1;
1139 /* this should really be the fully qualified name */
1140 q1.workstation_domain = TEST_MACHINE_NAME;
1141 q1.workstation_site = "Default-First-Site-Name";
1142 q1.blob2.length = 0;
1144 q1.blob2.data = NULL;
1145 q1.product.string = "product string";
1147 printf("Testing netr_LogonGetDomainInfo\n");
1149 status = dcerpc_netr_LogonGetDomainInfo(p, mem_ctx, &r);
1150 if (!NT_STATUS_IS_OK(status)) {
1151 printf("netr_LogonGetDomainInfo - %s\n", nt_errstr(status));
1155 if (!creds_client_check(creds, &a.cred)) {
1156 printf("Credential chaining failed\n");
1164 static void async_callback(struct rpc_request *req)
1166 int *counter = req->async.private;
1167 if (NT_STATUS_IS_OK(req->status)) {
1172 static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1175 struct netr_LogonGetDomainInfo r;
1176 struct netr_DomainQuery1 q1;
1177 struct netr_Authenticator a;
1178 #define ASYNC_COUNT 100
1179 struct creds_CredentialState *creds;
1180 struct creds_CredentialState *creds_async[ASYNC_COUNT];
1181 struct rpc_request *req[ASYNC_COUNT];
1183 int *async_counter = talloc(mem_ctx, int);
1185 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
1186 printf("test_GetDomainInfo_async disabled - enable dangerous tests to use\n");
1190 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
1191 TEST_MACHINE_NAME, machine_password, &creds)) {
1196 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1197 r.in.computer_name = TEST_MACHINE_NAME;
1199 r.in.credential = &a;
1200 r.in.return_authenticator = &a;
1201 r.out.return_authenticator = &a;
1203 r.in.query.query1 = &q1;
1206 /* this should really be the fully qualified name */
1207 q1.workstation_domain = TEST_MACHINE_NAME;
1208 q1.workstation_site = "Default-First-Site-Name";
1209 q1.blob2.length = 0;
1211 q1.blob2.data = NULL;
1212 q1.product.string = "product string";
1214 printf("Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
1218 for (i=0;i<ASYNC_COUNT;i++) {
1219 creds_client_authenticator(creds, &a);
1221 creds_async[i] = talloc_memdup(creds, creds, sizeof(*creds));
1222 req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, mem_ctx, &r);
1224 req[i]->async.callback = async_callback;
1225 req[i]->async.private = async_counter;
1227 /* even with this flush per request a w2k3 server seems to
1228 clag with multiple outstanding requests. bleergh. */
1229 if (event_loop_once(dcerpc_event_context(p)) != 0) {
1234 for (i=0;i<ASYNC_COUNT;i++) {
1235 status = dcerpc_ndr_request_recv(req[i]);
1236 if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(r.out.result)) {
1237 printf("netr_LogonGetDomainInfo_async(%d) - %s/%s\n",
1238 i, nt_errstr(status), nt_errstr(r.out.result));
1242 if (!creds_client_check(creds_async[i], &a.cred)) {
1243 printf("Credential chaining failed at async %d\n", i);
1248 printf("Testing netr_LogonGetDomainInfo - async count %d OK\n", *async_counter);
1250 return (*async_counter) == ASYNC_COUNT;
1253 static BOOL test_ManyGetDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1256 struct dcerpc_binding *b;
1257 struct dcerpc_pipe *p2;
1258 struct lsa_ObjectAttribute attr;
1259 struct lsa_QosInfo qos;
1260 struct lsa_OpenPolicy2 o;
1261 struct policy_handle lsa_handle;
1262 struct lsa_DomainList domains;
1264 struct lsa_EnumTrustDom t;
1265 uint32_t resume_handle = 0;
1266 struct netr_GetAnyDCName d;
1271 if (p->conn->transport.transport != NCACN_NP) {
1275 printf("Torturing GetDCName\n");
1277 status = dcerpc_parse_binding(mem_ctx, p->conn->binding_string, &b);
1278 if (!NT_STATUS_IS_OK(status)) {
1279 printf("Failed to parse dcerpc binding '%s'\n", p->conn->binding_string);
1283 status = dcerpc_secondary_connection(p, &p2, b);
1284 if (!NT_STATUS_IS_OK(status)) {
1285 printf("Failed to create secondary connection\n");
1289 status = dcerpc_bind_auth_none(p2, DCERPC_LSARPC_UUID,
1290 DCERPC_LSARPC_VERSION);
1291 if (!NT_STATUS_IS_OK(status)) {
1292 printf("Failed to create bind on secondary connection\n");
1297 qos.impersonation_level = 2;
1298 qos.context_mode = 1;
1299 qos.effective_only = 0;
1302 attr.root_dir = NULL;
1303 attr.object_name = NULL;
1304 attr.attributes = 0;
1305 attr.sec_desc = NULL;
1306 attr.sec_qos = &qos;
1308 o.in.system_name = "\\";
1310 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1311 o.out.handle = &lsa_handle;
1313 status = dcerpc_lsa_OpenPolicy2(p2, mem_ctx, &o);
1314 if (!NT_STATUS_IS_OK(status)) {
1315 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
1319 t.in.handle = &lsa_handle;
1320 t.in.resume_handle = &resume_handle;
1321 t.in.max_size = 1000;
1322 t.out.domains = &domains;
1323 t.out.resume_handle = &resume_handle;
1325 status = dcerpc_lsa_EnumTrustDom(p2, mem_ctx, &t);
1327 if ((!NT_STATUS_IS_OK(status) &&
1328 (!NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)))) {
1329 printf("Could not list domains\n");
1333 dcerpc_pipe_close(p2);
1335 d.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s",
1336 dcerpc_server_name(p));
1338 for (i=0; i<domains.count * 4; i++) {
1339 struct lsa_DomainInformation *info =
1340 &domains.domains[rand()%domains.count];
1342 d.in.domainname = info->name.string;
1344 status = dcerpc_netr_GetAnyDCName(p, mem_ctx, &d);
1345 if (!NT_STATUS_IS_OK(status)) {
1346 printf("GetAnyDCName - %s\n", nt_errstr(status));
1350 printf("\tDC for domain %s is %s\n", info->name.string,
1351 d.out.dcname ? d.out.dcname : "unknown");
1358 BOOL torture_rpc_netlogon(void)
1361 struct dcerpc_pipe *p;
1362 TALLOC_CTX *mem_ctx;
1364 struct test_join *join_ctx;
1366 mem_ctx = talloc_init("torture_rpc_netlogon");
1368 join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), ACB_SVRTRUST,
1371 printf("Failed to join as BDC\n");
1375 status = torture_rpc_connection(&p,
1376 DCERPC_NETLOGON_NAME,
1377 DCERPC_NETLOGON_UUID,
1378 DCERPC_NETLOGON_VERSION);
1379 if (!NT_STATUS_IS_OK(status)) {
1383 ret &= test_LogonUasLogon(p, mem_ctx);
1384 ret &= test_LogonUasLogoff(p, mem_ctx);
1385 ret &= test_SamLogon(p, mem_ctx);
1386 ret &= test_SetPassword(p, mem_ctx);
1387 ret &= test_SetPassword2(p, mem_ctx);
1388 ret &= test_GetDomainInfo(p, mem_ctx);
1389 ret &= test_DatabaseSync(p, mem_ctx);
1390 ret &= test_DatabaseDeltas(p, mem_ctx);
1391 ret &= test_AccountDeltas(p, mem_ctx);
1392 ret &= test_AccountSync(p, mem_ctx);
1393 ret &= test_GetDcName(p, mem_ctx);
1394 ret &= test_ManyGetDCName(p, mem_ctx);
1395 ret &= test_LogonControl(p, mem_ctx);
1396 ret &= test_GetAnyDCName(p, mem_ctx);
1397 ret &= test_LogonControl2(p, mem_ctx);
1398 ret &= test_DatabaseSync2(p, mem_ctx);
1399 ret &= test_LogonControl2Ex(p, mem_ctx);
1400 ret &= test_DsrEnumerateDomainTrusts(p, mem_ctx);
1401 ret &= test_GetDomainInfo_async(p, mem_ctx);
1402 ret &= test_netr_DrsGetDCNameEx2(p, mem_ctx);
1404 talloc_free(mem_ctx);
1406 torture_rpc_close(p);
1408 torture_leave_domain(join_ctx);