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.
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)
82 struct netr_ServerReqChallenge r;
83 struct netr_ServerAuthenticate a;
84 struct netr_Credential credentials1, credentials2, credentials3;
85 struct samr_Password mach_password;
87 printf("Testing ServerReqChallenge\n");
89 r.in.server_name = NULL;
90 r.in.computer_name = machine_name;
91 r.in.credentials = &credentials1;
92 r.out.credentials = &credentials2;
94 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
96 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
97 if (!NT_STATUS_IS_OK(status)) {
98 printf("ServerReqChallenge - %s\n", nt_errstr(status));
102 E_md4hash(plain_pass, mach_password.hash);
104 a.in.server_name = NULL;
105 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", machine_name);
106 a.in.secure_channel_type = SEC_CHAN_BDC;
107 a.in.computer_name = machine_name;
108 a.in.credentials = &credentials3;
109 a.out.credentials = &credentials3;
111 creds_client_init(creds, &credentials1, &credentials2, &mach_password, &credentials3,
114 printf("Testing ServerAuthenticate\n");
116 status = dcerpc_netr_ServerAuthenticate(p, mem_ctx, &a);
117 if (!NT_STATUS_IS_OK(status)) {
118 printf("ServerAuthenticate - %s\n", nt_errstr(status));
122 if (!creds_client_check(creds, &credentials3)) {
123 printf("Credential chaining failed\n");
130 BOOL test_SetupCredentials2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
131 uint32_t negotiate_flags,
132 const char *machine_name,
133 const char *plain_pass,
135 struct creds_CredentialState *creds)
138 struct netr_ServerReqChallenge r;
139 struct netr_ServerAuthenticate2 a;
140 struct netr_Credential credentials1, credentials2, credentials3;
141 struct samr_Password mach_password;
143 printf("Testing ServerReqChallenge\n");
145 r.in.server_name = NULL;
146 r.in.computer_name = machine_name;
147 r.in.credentials = &credentials1;
148 r.out.credentials = &credentials2;
150 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
152 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
153 if (!NT_STATUS_IS_OK(status)) {
154 printf("ServerReqChallenge - %s\n", nt_errstr(status));
158 E_md4hash(plain_pass, mach_password.hash);
160 a.in.server_name = NULL;
161 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", machine_name);
162 a.in.secure_channel_type = sec_chan_type;
163 a.in.computer_name = machine_name;
164 a.in.negotiate_flags = &negotiate_flags;
165 a.out.negotiate_flags = &negotiate_flags;
166 a.in.credentials = &credentials3;
167 a.out.credentials = &credentials3;
169 creds_client_init(creds, &credentials1, &credentials2, &mach_password, &credentials3,
172 printf("Testing ServerAuthenticate2\n");
174 status = dcerpc_netr_ServerAuthenticate2(p, mem_ctx, &a);
175 if (!NT_STATUS_IS_OK(status)) {
176 printf("ServerAuthenticate2 - %s\n", nt_errstr(status));
180 if (!creds_client_check(creds, &credentials3)) {
181 printf("Credential chaining failed\n");
185 printf("negotiate_flags=0x%08x\n", negotiate_flags);
191 BOOL test_SetupCredentials3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
192 uint32_t negotiate_flags,
193 const char *machine_name,
194 const char *plain_pass,
195 struct creds_CredentialState *creds)
198 struct netr_ServerReqChallenge r;
199 struct netr_ServerAuthenticate3 a;
200 struct netr_Credential credentials1, credentials2, credentials3;
201 struct samr_Password mach_password;
204 printf("Testing ServerReqChallenge\n");
206 r.in.server_name = NULL;
207 r.in.computer_name = machine_name;
208 r.in.credentials = &credentials1;
209 r.out.credentials = &credentials2;
211 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
213 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
214 if (!NT_STATUS_IS_OK(status)) {
215 printf("ServerReqChallenge - %s\n", nt_errstr(status));
219 E_md4hash(plain_pass, mach_password.hash);
221 a.in.server_name = NULL;
222 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", machine_name);
223 a.in.secure_channel_type = SEC_CHAN_BDC;
224 a.in.computer_name = machine_name;
225 a.in.negotiate_flags = &negotiate_flags;
226 a.in.credentials = &credentials3;
227 a.out.credentials = &credentials3;
228 a.out.negotiate_flags = &negotiate_flags;
231 creds_client_init(creds, &credentials1, &credentials2, &mach_password, &credentials3,
234 printf("Testing ServerAuthenticate3\n");
236 status = dcerpc_netr_ServerAuthenticate3(p, mem_ctx, &a);
237 if (!NT_STATUS_IS_OK(status)) {
238 printf("ServerAuthenticate3 - %s\n", nt_errstr(status));
242 if (!creds_client_check(creds, &credentials3)) {
243 printf("Credential chaining failed\n");
247 printf("negotiate_flags=0x%08x\n", negotiate_flags);
253 try a change password for our machine account
255 static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
258 struct netr_ServerPasswordSet r;
259 const char *password;
260 struct creds_CredentialState creds;
262 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME,
263 machine_password, &creds)) {
267 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
268 r.in.account_name = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
269 r.in.secure_channel_type = SEC_CHAN_BDC;
270 r.in.computer_name = TEST_MACHINE_NAME;
273 E_md4hash(password, r.in.new_password.hash);
275 creds_des_encrypt(&creds, &r.in.new_password);
276 /* by changing the machine password to ""
277 * we check if the server uses password restrictions
278 * for ServerPasswordSet2
279 * (win2k3 accepts "")
281 printf("Testing a second ServerPasswordSet on machine account\n");
282 printf("Changing machine account password to '%s'\n", password);
284 creds_client_authenticator(&creds, &r.in.credential);
286 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
287 if (!NT_STATUS_IS_OK(status)) {
288 printf("ServerPasswordSet (2) - %s\n", nt_errstr(status));
292 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
293 printf("Credential chaining failed\n");
296 machine_password = password;
298 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
299 printf("ServerPasswordSet failed to actually change the password\n");
303 password = generate_random_str(mem_ctx, 8);
304 E_md4hash(password, r.in.new_password.hash);
306 creds_des_encrypt(&creds, &r.in.new_password);
308 printf("Testing ServerPasswordSet on machine account\n");
309 printf("Changing machine account password to '%s'\n", password);
311 creds_client_authenticator(&creds, &r.in.credential);
313 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
314 if (!NT_STATUS_IS_OK(status)) {
315 printf("ServerPasswordSet - %s\n", nt_errstr(status));
319 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
320 printf("Credential chaining failed\n");
323 /* by changing the machine password twice we test the
324 credentials chaining fully, and we verify that the server
325 allows the password to be set to the same value twice in a
326 row (match win2k3) */
327 printf("Testing a second ServerPasswordSet on machine account\n");
328 printf("Changing machine account password to '%s' (same as previous run)\n", password);
330 creds_client_authenticator(&creds, &r.in.credential);
332 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
333 if (!NT_STATUS_IS_OK(status)) {
334 printf("ServerPasswordSet (2) - %s\n", nt_errstr(status));
338 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
339 printf("Credential chaining failed\n");
342 machine_password = password;
344 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
345 printf("ServerPasswordSet failed to actually change the password\n");
353 try a change password for our machine account
355 static BOOL test_SetPassword2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
358 struct netr_ServerPasswordSet2 r;
359 const char *password;
360 struct creds_CredentialState creds;
362 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME,
363 machine_password, &creds)) {
367 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
368 r.in.account_name = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
369 r.in.secure_channel_type = SEC_CHAN_BDC;
370 r.in.computer_name = TEST_MACHINE_NAME;
373 encode_pw_buffer(r.in.new_password.data, password, STR_UNICODE);
374 creds_arcfour_crypt(&creds, r.in.new_password.data, 516);
376 /* by changing the machine password to ""
377 * we check if the server uses password restrictions
378 * for ServerPasswordSet2
379 * (win2k3 accepts "")
381 printf("Testing a second ServerPasswordSet2 on machine account\n");
382 printf("Changing machine account password to '%s'\n", password);
384 creds_client_authenticator(&creds, &r.in.credential);
386 status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
387 if (!NT_STATUS_IS_OK(status)) {
388 printf("ServerPasswordSet (2) - %s\n", nt_errstr(status));
392 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
393 printf("Credential chaining failed\n");
396 machine_password = password;
398 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
399 printf("ServerPasswordSet failed to actually change the password\n");
403 /* now try a random password */
404 password = generate_random_str(mem_ctx, 8);
405 encode_pw_buffer(r.in.new_password.data, password, STR_UNICODE);
406 creds_arcfour_crypt(&creds, r.in.new_password.data, 516);
408 printf("Testing ServerPasswordSet2 on machine account\n");
409 printf("Changing machine account password to '%s'\n", password);
411 creds_client_authenticator(&creds, &r.in.credential);
413 status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
414 if (!NT_STATUS_IS_OK(status)) {
415 printf("ServerPasswordSet2 - %s\n", nt_errstr(status));
419 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
420 printf("Credential chaining failed\n");
423 /* by changing the machine password twice we test the
424 credentials chaining fully, and we verify that the server
425 allows the password to be set to the same value twice in a
426 row (match win2k3) */
427 printf("Testing a second ServerPasswordSet2 on machine account\n");
428 printf("Changing machine account password to '%s' (same as previous run)\n", password);
430 creds_client_authenticator(&creds, &r.in.credential);
432 status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
433 if (!NT_STATUS_IS_OK(status)) {
434 printf("ServerPasswordSet (2) - %s\n", nt_errstr(status));
438 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
439 printf("Credential chaining failed\n");
442 machine_password = password;
444 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
445 printf("ServerPasswordSet failed to actually change the password\n");
453 try a netlogon SamLogon
455 static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
458 struct netr_LogonSamLogon r;
459 struct netr_Authenticator auth, auth2;
460 struct netr_NetworkInfo ninfo;
461 const char *username = lp_parm_string(-1, "torture", "username");
462 const char *password = lp_parm_string(-1, "torture", "password");
463 struct creds_CredentialState creds;
468 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME,
469 machine_password, &creds)) {
473 ninfo.identity_info.domain_name.string = lp_workgroup();
474 ninfo.identity_info.parameter_control = 0;
475 ninfo.identity_info.logon_id_low = 0;
476 ninfo.identity_info.logon_id_high = 0;
477 ninfo.identity_info.account_name.string = username;
478 ninfo.identity_info.workstation.string = TEST_MACHINE_NAME;
479 generate_random_buffer(ninfo.challenge,
480 sizeof(ninfo.challenge));
481 ninfo.nt.length = 24;
482 ninfo.nt.data = talloc_size(mem_ctx, 24);
483 SMBNTencrypt(password, ninfo.challenge, ninfo.nt.data);
484 ninfo.lm.length = 24;
485 ninfo.lm.data = talloc_size(mem_ctx, 24);
486 SMBencrypt(password, ninfo.challenge, ninfo.lm.data);
488 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
489 r.in.workstation = TEST_MACHINE_NAME;
490 r.in.credential = &auth;
491 r.in.return_authenticator = &auth2;
492 r.in.logon_level = 2;
493 r.in.logon.network = &ninfo;
497 creds_client_authenticator(&creds, &auth);
499 r.in.validation_level = i;
501 printf("Testing SamLogon with validation level %d\n", i);
503 status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r);
504 if (!NT_STATUS_IS_OK(status)) {
505 printf("LogonSamLogon - %s\n", nt_errstr(status));
509 if (!creds_client_check(&creds, &r.out.return_authenticator->cred)) {
510 printf("Credential chaining failed\n");
514 r.in.credential = NULL;
518 r.in.validation_level = i;
520 printf("Testing SamLogon with validation level %d\n", i);
522 status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r);
523 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
524 printf("LogonSamLogon expected INVALID_PARAMETER, got: %s\n", nt_errstr(status));
533 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
534 static uint64_t sequence_nums[3];
537 try a netlogon DatabaseSync
539 static BOOL test_DatabaseSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
542 struct netr_DatabaseSync r;
543 struct creds_CredentialState creds;
544 const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
548 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
552 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
553 r.in.computername = TEST_MACHINE_NAME;
554 r.in.preferredmaximumlength = (uint32_t)-1;
555 ZERO_STRUCT(r.in.return_authenticator);
557 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
558 r.in.sync_context = 0;
559 r.in.database_id = database_ids[i];
561 printf("Testing DatabaseSync of id %d\n", r.in.database_id);
564 creds_client_authenticator(&creds, &r.in.credential);
566 status = dcerpc_netr_DatabaseSync(p, mem_ctx, &r);
567 if (!NT_STATUS_IS_OK(status) &&
568 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
569 printf("DatabaseSync - %s\n", nt_errstr(status));
574 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
575 printf("Credential chaining failed\n");
578 r.in.sync_context = r.out.sync_context;
580 if (r.out.delta_enum_array &&
581 r.out.delta_enum_array->num_deltas > 0 &&
582 r.out.delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
583 r.out.delta_enum_array->delta_enum[0].delta_union.domain) {
584 sequence_nums[r.in.database_id] =
585 r.out.delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
586 printf("\tsequence_nums[%d]=%llu\n",
588 sequence_nums[r.in.database_id]);
590 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
598 try a netlogon DatabaseDeltas
600 static BOOL test_DatabaseDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
603 struct netr_DatabaseDeltas r;
604 struct creds_CredentialState creds;
605 const uint32_t database_ids[] = {0, 1, 2};
609 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
613 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
614 r.in.computername = TEST_MACHINE_NAME;
615 r.in.preferredmaximumlength = (uint32_t)-1;
616 ZERO_STRUCT(r.in.return_authenticator);
618 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
619 r.in.database_id = database_ids[i];
620 r.in.sequence_num = sequence_nums[r.in.database_id];
622 if (r.in.sequence_num == 0) continue;
624 r.in.sequence_num -= 1;
627 printf("Testing DatabaseDeltas of id %d at %llu\n",
628 r.in.database_id, r.in.sequence_num);
631 creds_client_authenticator(&creds, &r.in.credential);
633 status = dcerpc_netr_DatabaseDeltas(p, mem_ctx, &r);
634 if (!NT_STATUS_IS_OK(status) &&
635 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
636 printf("DatabaseDeltas - %s\n", nt_errstr(status));
641 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
642 printf("Credential chaining failed\n");
646 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
654 try a netlogon AccountDeltas
656 static BOOL test_AccountDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
659 struct netr_AccountDeltas r;
660 struct creds_CredentialState creds;
663 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
667 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
668 r.in.computername = TEST_MACHINE_NAME;
669 ZERO_STRUCT(r.in.return_authenticator);
670 creds_client_authenticator(&creds, &r.in.credential);
671 ZERO_STRUCT(r.in.uas);
676 printf("Testing AccountDeltas\n");
678 /* w2k3 returns "NOT IMPLEMENTED" for this call */
679 status = dcerpc_netr_AccountDeltas(p, mem_ctx, &r);
680 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
681 printf("AccountDeltas - %s\n", nt_errstr(status));
689 try a netlogon AccountSync
691 static BOOL test_AccountSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
694 struct netr_AccountSync r;
695 struct creds_CredentialState creds;
698 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
702 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
703 r.in.computername = TEST_MACHINE_NAME;
704 ZERO_STRUCT(r.in.return_authenticator);
705 creds_client_authenticator(&creds, &r.in.credential);
706 ZERO_STRUCT(r.in.recordid);
711 printf("Testing AccountSync\n");
713 /* w2k3 returns "NOT IMPLEMENTED" for this call */
714 status = dcerpc_netr_AccountSync(p, mem_ctx, &r);
715 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
716 printf("AccountSync - %s\n", nt_errstr(status));
724 try a netlogon GetDcName
726 static BOOL test_GetDcName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
729 struct netr_GetDcName r;
731 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
732 r.in.domainname = lp_workgroup();
734 printf("Testing GetDcName\n");
736 status = dcerpc_netr_GetDcName(p, mem_ctx, &r);
737 if (!NT_STATUS_IS_OK(status)) {
738 printf("GetDcName - %s\n", nt_errstr(status));
742 printf("\tDC is at '%s'\n", r.out.dcname);
748 try a netlogon LogonControl
750 static BOOL test_LogonControl(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
753 struct netr_LogonControl r;
757 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
758 r.in.function_code = 1;
763 printf("Testing LogonControl level %d\n", i);
765 status = dcerpc_netr_LogonControl(p, mem_ctx, &r);
766 if (!NT_STATUS_IS_OK(status)) {
767 printf("LogonControl - %s\n", nt_errstr(status));
777 try a netlogon GetAnyDCName
779 static BOOL test_GetAnyDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
782 struct netr_GetAnyDCName r;
784 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
785 r.in.domainname = lp_workgroup();
787 printf("Testing GetAnyDCName\n");
789 status = dcerpc_netr_GetAnyDCName(p, mem_ctx, &r);
790 if (!NT_STATUS_IS_OK(status)) {
791 printf("GetAnyDCName - %s\n", nt_errstr(status));
796 printf("\tDC is at '%s'\n", r.out.dcname);
804 try a netlogon LogonControl2
806 static BOOL test_LogonControl2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
809 struct netr_LogonControl2 r;
813 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
815 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
816 r.in.data.domain = lp_workgroup();
821 printf("Testing LogonControl2 level %d function %d\n",
822 i, r.in.function_code);
824 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
825 if (!NT_STATUS_IS_OK(status)) {
826 printf("LogonControl - %s\n", nt_errstr(status));
831 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
832 r.in.data.domain = lp_workgroup();
837 printf("Testing LogonControl2 level %d function %d\n",
838 i, r.in.function_code);
840 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
841 if (!NT_STATUS_IS_OK(status)) {
842 printf("LogonControl - %s\n", nt_errstr(status));
847 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
848 r.in.data.domain = lp_workgroup();
853 printf("Testing LogonControl2 level %d function %d\n",
854 i, r.in.function_code);
856 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
857 if (!NT_STATUS_IS_OK(status)) {
858 printf("LogonControl - %s\n", nt_errstr(status));
863 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
864 r.in.data.debug_level = ~0;
869 printf("Testing LogonControl2 level %d function %d\n",
870 i, r.in.function_code);
872 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
873 if (!NT_STATUS_IS_OK(status)) {
874 printf("LogonControl - %s\n", nt_errstr(status));
883 try a netlogon DatabaseSync2
885 static BOOL test_DatabaseSync2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
888 struct netr_DatabaseSync2 r;
889 struct creds_CredentialState creds;
890 const uint32_t database_ids[] = {0, 1, 2};
894 if (!test_SetupCredentials2(p, mem_ctx, NETLOGON_NEG_AUTH2_FLAGS,
895 TEST_MACHINE_NAME, machine_password,
896 SEC_CHAN_BDC, &creds)) {
900 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
901 r.in.computername = TEST_MACHINE_NAME;
902 r.in.preferredmaximumlength = (uint32_t)-1;
903 ZERO_STRUCT(r.in.return_authenticator);
905 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
906 r.in.sync_context = 0;
907 r.in.database_id = database_ids[i];
908 r.in.restart_state = 0;
910 printf("Testing DatabaseSync2 of id %d\n", r.in.database_id);
913 creds_client_authenticator(&creds, &r.in.credential);
915 status = dcerpc_netr_DatabaseSync2(p, mem_ctx, &r);
916 if (!NT_STATUS_IS_OK(status) &&
917 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
918 printf("DatabaseSync2 - %s\n", nt_errstr(status));
923 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
924 printf("Credential chaining failed\n");
927 r.in.sync_context = r.out.sync_context;
928 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
936 try a netlogon LogonControl2Ex
938 static BOOL test_LogonControl2Ex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
941 struct netr_LogonControl2Ex r;
945 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
947 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
948 r.in.data.domain = lp_workgroup();
953 printf("Testing LogonControl2Ex level %d function %d\n",
954 i, r.in.function_code);
956 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
957 if (!NT_STATUS_IS_OK(status)) {
958 printf("LogonControl - %s\n", nt_errstr(status));
963 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
964 r.in.data.domain = lp_workgroup();
969 printf("Testing LogonControl2Ex level %d function %d\n",
970 i, r.in.function_code);
972 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
973 if (!NT_STATUS_IS_OK(status)) {
974 printf("LogonControl - %s\n", nt_errstr(status));
979 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
980 r.in.data.domain = lp_workgroup();
985 printf("Testing LogonControl2Ex level %d function %d\n",
986 i, r.in.function_code);
988 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
989 if (!NT_STATUS_IS_OK(status)) {
990 printf("LogonControl - %s\n", nt_errstr(status));
995 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
996 r.in.data.debug_level = ~0;
1001 printf("Testing LogonControl2Ex level %d function %d\n",
1002 i, r.in.function_code);
1004 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1005 if (!NT_STATUS_IS_OK(status)) {
1006 printf("LogonControl - %s\n", nt_errstr(status));
1016 try a netlogon netr_DsrEnumerateDomainTrusts
1018 static BOOL test_DsrEnumerateDomainTrusts(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1021 struct netr_DsrEnumerateDomainTrusts r;
1023 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1024 r.in.trust_flags = 0x3f;
1026 printf("Testing netr_DsrEnumerateDomainTrusts\n");
1028 status = dcerpc_netr_DsrEnumerateDomainTrusts(p, mem_ctx, &r);
1029 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1030 printf("netr_DsrEnumerateDomainTrusts - %s/%s\n",
1031 nt_errstr(status), win_errstr(r.out.result));
1039 try a netlogon netr_DrsGetDCNameEx2
1041 static BOOL test_netr_DrsGetDCNameEx2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1044 struct netr_DrsGetDCNameEx2 r;
1047 r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1048 r.in.client_account = NULL;
1049 r.in.mask = 0x00000000;
1050 r.in.domain_name = talloc_asprintf(mem_ctx, "%s", lp_realm());
1051 r.in.domain_guid = NULL;
1052 r.in.site_name = NULL;
1053 r.in.flags = 0x40000000;
1055 printf("Testing netr_DrsGetDCNameEx2 without client account\n");
1057 status = dcerpc_netr_DrsGetDCNameEx2(p, mem_ctx, &r);
1058 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1059 printf("netr_DrsGetDCNameEx2 - %s/%s\n",
1060 nt_errstr(status), win_errstr(r.out.result));
1064 printf("Testing netr_DrsGetDCNameEx2 with client acount\n");
1065 r.in.client_account = TEST_MACHINE_NAME"$";
1066 r.in.mask = 0x00002000;
1067 r.in.flags = 0x80000000;
1069 status = dcerpc_netr_DrsGetDCNameEx2(p, mem_ctx, &r);
1070 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1071 printf("netr_DrsGetDCNameEx2 - %s/%s\n",
1072 nt_errstr(status), win_errstr(r.out.result));
1079 static BOOL test_GetDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1082 struct netr_LogonGetDomainInfo r;
1083 struct netr_DomainQuery1 q1;
1084 struct netr_Authenticator a;
1085 struct creds_CredentialState creds;
1087 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
1088 TEST_MACHINE_NAME, machine_password, &creds)) {
1094 creds_client_authenticator(&creds, &a);
1096 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1097 r.in.computer_name = TEST_MACHINE_NAME;
1099 r.in.credential = &a;
1100 r.in.return_authenticator = &a;
1101 r.out.return_authenticator = &a;
1103 r.in.query.query1 = &q1;
1106 /* this should really be the fully qualified name */
1107 q1.workstation_domain = TEST_MACHINE_NAME;
1108 q1.workstation_site = "Default-First-Site-Name";
1109 q1.blob2.length = 0;
1111 q1.blob2.data = NULL;
1112 q1.product.string = "product string";
1114 printf("Testing netr_LogonGetDomainInfo\n");
1116 status = dcerpc_netr_LogonGetDomainInfo(p, mem_ctx, &r);
1117 if (!NT_STATUS_IS_OK(status)) {
1118 printf("netr_LogonGetDomainInfo - %s\n", nt_errstr(status));
1122 if (!creds_client_check(&creds, &a.cred)) {
1123 printf("Credential chaining failed\n");
1131 static void async_callback(struct rpc_request *req)
1133 int *counter = req->async.private;
1134 if (NT_STATUS_IS_OK(req->status)) {
1139 static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1142 struct netr_LogonGetDomainInfo r;
1143 struct netr_DomainQuery1 q1;
1144 struct netr_Authenticator a;
1145 #define ASYNC_COUNT 100
1146 struct creds_CredentialState creds;
1147 struct creds_CredentialState creds_async[ASYNC_COUNT];
1148 struct rpc_request *req[ASYNC_COUNT];
1150 int *async_counter = talloc(mem_ctx, int);
1152 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
1153 printf("test_GetDomainInfo_async disabled - enable dangerous tests to use\n");
1157 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
1158 TEST_MACHINE_NAME, machine_password, &creds)) {
1163 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1164 r.in.computer_name = TEST_MACHINE_NAME;
1166 r.in.credential = &a;
1167 r.in.return_authenticator = &a;
1168 r.out.return_authenticator = &a;
1170 r.in.query.query1 = &q1;
1173 /* this should really be the fully qualified name */
1174 q1.workstation_domain = TEST_MACHINE_NAME;
1175 q1.workstation_site = "Default-First-Site-Name";
1176 q1.blob2.length = 0;
1178 q1.blob2.data = NULL;
1179 q1.product.string = "product string";
1181 printf("Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
1185 for (i=0;i<ASYNC_COUNT;i++) {
1186 creds_client_authenticator(&creds, &a);
1188 creds_async[i] = creds;
1189 req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, mem_ctx, &r);
1191 req[i]->async.callback = async_callback;
1192 req[i]->async.private = async_counter;
1194 /* even with this flush per request a w2k3 server seems to
1195 clag with multiple outstanding requests. bleergh. */
1196 if (event_loop_once(dcerpc_event_context(p)) != 0) {
1201 for (i=0;i<ASYNC_COUNT;i++) {
1202 status = dcerpc_ndr_request_recv(req[i]);
1203 if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(r.out.result)) {
1204 printf("netr_LogonGetDomainInfo_async(%d) - %s/%s\n",
1205 i, nt_errstr(status), nt_errstr(r.out.result));
1209 if (!creds_client_check(&creds_async[i], &a.cred)) {
1210 printf("Credential chaining failed at async %d\n", i);
1215 printf("Testing netr_LogonGetDomainInfo - async count %d OK\n", *async_counter);
1217 return (*async_counter) == ASYNC_COUNT;
1220 static BOOL test_ManyGetDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1223 struct dcerpc_pipe *p2;
1224 struct lsa_ObjectAttribute attr;
1225 struct lsa_QosInfo qos;
1226 struct lsa_OpenPolicy2 o;
1227 struct policy_handle lsa_handle;
1228 struct lsa_DomainList domains;
1230 struct lsa_EnumTrustDom t;
1231 uint32_t resume_handle = 0;
1232 struct netr_GetAnyDCName d;
1237 if (p->conn->transport.transport != NCACN_NP) {
1241 printf("Torturing GetDCName\n");
1243 status = dcerpc_secondary_connection(p, &p2,
1246 DCERPC_LSARPC_VERSION);
1247 if (!NT_STATUS_IS_OK(status)) {
1248 printf("Failed to create secondary connection\n");
1253 qos.impersonation_level = 2;
1254 qos.context_mode = 1;
1255 qos.effective_only = 0;
1258 attr.root_dir = NULL;
1259 attr.object_name = NULL;
1260 attr.attributes = 0;
1261 attr.sec_desc = NULL;
1262 attr.sec_qos = &qos;
1264 o.in.system_name = "\\";
1266 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1267 o.out.handle = &lsa_handle;
1269 status = dcerpc_lsa_OpenPolicy2(p2, mem_ctx, &o);
1270 if (!NT_STATUS_IS_OK(status)) {
1271 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
1275 t.in.handle = &lsa_handle;
1276 t.in.resume_handle = &resume_handle;
1277 t.in.max_size = 1000;
1278 t.out.domains = &domains;
1279 t.out.resume_handle = &resume_handle;
1281 status = dcerpc_lsa_EnumTrustDom(p2, mem_ctx, &t);
1283 if ((!NT_STATUS_IS_OK(status) &&
1284 (!NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)))) {
1285 printf("Could not list domains\n");
1289 dcerpc_pipe_close(p2);
1291 d.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s",
1292 dcerpc_server_name(p));
1294 for (i=0; i<domains.count * 4; i++) {
1295 struct lsa_DomainInformation *info =
1296 &domains.domains[rand()%domains.count];
1298 d.in.domainname = info->name.string;
1300 status = dcerpc_netr_GetAnyDCName(p, mem_ctx, &d);
1301 if (!NT_STATUS_IS_OK(status)) {
1302 printf("GetAnyDCName - %s\n", nt_errstr(status));
1306 printf("\tDC for domain %s is %s\n", info->name.string,
1307 d.out.dcname ? d.out.dcname : "unknown");
1314 BOOL torture_rpc_netlogon(void)
1317 struct dcerpc_pipe *p;
1318 TALLOC_CTX *mem_ctx;
1320 struct test_join *join_ctx;
1322 mem_ctx = talloc_init("torture_rpc_netlogon");
1324 join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), ACB_SVRTRUST,
1327 printf("Failed to join as BDC\n");
1331 status = torture_rpc_connection(&p,
1332 DCERPC_NETLOGON_NAME,
1333 DCERPC_NETLOGON_UUID,
1334 DCERPC_NETLOGON_VERSION);
1335 if (!NT_STATUS_IS_OK(status)) {
1339 ret &= test_LogonUasLogon(p, mem_ctx);
1340 ret &= test_LogonUasLogoff(p, mem_ctx);
1341 ret &= test_SamLogon(p, mem_ctx);
1342 ret &= test_SetPassword(p, mem_ctx);
1343 ret &= test_SetPassword2(p, mem_ctx);
1344 ret &= test_GetDomainInfo(p, mem_ctx);
1345 ret &= test_DatabaseSync(p, mem_ctx);
1346 ret &= test_DatabaseDeltas(p, mem_ctx);
1347 ret &= test_AccountDeltas(p, mem_ctx);
1348 ret &= test_AccountSync(p, mem_ctx);
1349 ret &= test_GetDcName(p, mem_ctx);
1350 ret &= test_ManyGetDCName(p, mem_ctx);
1351 ret &= test_LogonControl(p, mem_ctx);
1352 ret &= test_GetAnyDCName(p, mem_ctx);
1353 ret &= test_LogonControl2(p, mem_ctx);
1354 ret &= test_DatabaseSync2(p, mem_ctx);
1355 ret &= test_LogonControl2Ex(p, mem_ctx);
1356 ret &= test_DsrEnumerateDomainTrusts(p, mem_ctx);
1357 ret &= test_GetDomainInfo_async(p, mem_ctx);
1358 ret &= test_netr_DrsGetDCNameEx2(p, mem_ctx);
1360 talloc_free(mem_ctx);
1362 torture_rpc_close(p);
1364 torture_leave_domain(join_ctx);