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 "librpc/gen_ndr/ndr_netlogon.h"
27 #include "auth/auth.h"
29 static const char *machine_password;
31 #define TEST_MACHINE_NAME "torturetest"
33 static BOOL test_LogonUasLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
36 struct netr_LogonUasLogon r;
38 r.in.server_name = NULL;
39 r.in.account_name = lp_parm_string(-1, "torture", "username");
40 r.in.workstation = TEST_MACHINE_NAME;
42 printf("Testing LogonUasLogon\n");
44 status = dcerpc_netr_LogonUasLogon(p, mem_ctx, &r);
45 if (!NT_STATUS_IS_OK(status)) {
46 printf("LogonUasLogon - %s\n", nt_errstr(status));
54 static BOOL test_LogonUasLogoff(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
57 struct netr_LogonUasLogoff r;
59 r.in.server_name = NULL;
60 r.in.account_name = lp_parm_string(-1, "torture", "username");
61 r.in.workstation = TEST_MACHINE_NAME;
63 printf("Testing LogonUasLogoff\n");
65 status = dcerpc_netr_LogonUasLogoff(p, mem_ctx, &r);
66 if (!NT_STATUS_IS_OK(status)) {
67 printf("LogonUasLogoff - %s\n", nt_errstr(status));
75 BOOL test_SetupCredentials(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
76 const char *machine_name,
77 const char *plain_pass,
78 struct creds_CredentialState *creds)
81 struct netr_ServerReqChallenge r;
82 struct netr_ServerAuthenticate a;
83 struct netr_Credential credentials1, credentials2, credentials3;
84 struct samr_Password mach_password;
86 printf("Testing ServerReqChallenge\n");
88 r.in.server_name = NULL;
89 r.in.computer_name = machine_name;
90 r.in.credentials = &credentials1;
91 r.out.credentials = &credentials2;
93 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
95 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
96 if (!NT_STATUS_IS_OK(status)) {
97 printf("ServerReqChallenge - %s\n", nt_errstr(status));
101 E_md4hash(plain_pass, mach_password.hash);
103 a.in.server_name = NULL;
104 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", machine_name);
105 a.in.secure_channel_type = SEC_CHAN_BDC;
106 a.in.computer_name = machine_name;
107 a.in.credentials = &credentials3;
108 a.out.credentials = &credentials3;
110 creds_client_init(creds, &credentials1, &credentials2, &mach_password, &credentials3,
113 printf("Testing ServerAuthenticate\n");
115 status = dcerpc_netr_ServerAuthenticate(p, mem_ctx, &a);
116 if (!NT_STATUS_IS_OK(status)) {
117 printf("ServerAuthenticate - %s\n", nt_errstr(status));
121 if (!creds_client_check(creds, &credentials3)) {
122 printf("Credential chaining failed\n");
129 BOOL test_SetupCredentials2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
130 uint32_t negotiate_flags,
131 const char *machine_name,
132 const char *plain_pass,
134 struct creds_CredentialState *creds)
137 struct netr_ServerReqChallenge r;
138 struct netr_ServerAuthenticate2 a;
139 struct netr_Credential credentials1, credentials2, credentials3;
140 struct samr_Password mach_password;
142 printf("Testing ServerReqChallenge\n");
144 r.in.server_name = NULL;
145 r.in.computer_name = machine_name;
146 r.in.credentials = &credentials1;
147 r.out.credentials = &credentials2;
149 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
151 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
152 if (!NT_STATUS_IS_OK(status)) {
153 printf("ServerReqChallenge - %s\n", nt_errstr(status));
157 E_md4hash(plain_pass, mach_password.hash);
159 a.in.server_name = NULL;
160 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", machine_name);
161 a.in.secure_channel_type = sec_chan_type;
162 a.in.computer_name = machine_name;
163 a.in.negotiate_flags = &negotiate_flags;
164 a.out.negotiate_flags = &negotiate_flags;
165 a.in.credentials = &credentials3;
166 a.out.credentials = &credentials3;
168 creds_client_init(creds, &credentials1, &credentials2, &mach_password, &credentials3,
171 printf("Testing ServerAuthenticate2\n");
173 status = dcerpc_netr_ServerAuthenticate2(p, mem_ctx, &a);
174 if (!NT_STATUS_IS_OK(status)) {
175 printf("ServerAuthenticate2 - %s\n", nt_errstr(status));
179 if (!creds_client_check(creds, &credentials3)) {
180 printf("Credential chaining failed\n");
184 printf("negotiate_flags=0x%08x\n", negotiate_flags);
190 BOOL test_SetupCredentials3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
191 uint32_t negotiate_flags,
192 const char *machine_name,
193 const char *plain_pass,
194 struct creds_CredentialState *creds)
197 struct netr_ServerReqChallenge r;
198 struct netr_ServerAuthenticate3 a;
199 struct netr_Credential credentials1, credentials2, credentials3;
200 struct samr_Password mach_password;
203 printf("Testing ServerReqChallenge\n");
205 r.in.server_name = NULL;
206 r.in.computer_name = machine_name;
207 r.in.credentials = &credentials1;
208 r.out.credentials = &credentials2;
210 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
212 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
213 if (!NT_STATUS_IS_OK(status)) {
214 printf("ServerReqChallenge - %s\n", nt_errstr(status));
218 E_md4hash(plain_pass, mach_password.hash);
220 a.in.server_name = NULL;
221 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", machine_name);
222 a.in.secure_channel_type = SEC_CHAN_BDC;
223 a.in.computer_name = machine_name;
224 a.in.negotiate_flags = &negotiate_flags;
225 a.in.credentials = &credentials3;
226 a.out.credentials = &credentials3;
227 a.out.negotiate_flags = &negotiate_flags;
230 creds_client_init(creds, &credentials1, &credentials2, &mach_password, &credentials3,
233 printf("Testing ServerAuthenticate3\n");
235 status = dcerpc_netr_ServerAuthenticate3(p, mem_ctx, &a);
236 if (!NT_STATUS_IS_OK(status)) {
237 printf("ServerAuthenticate3 - %s\n", nt_errstr(status));
241 if (!creds_client_check(creds, &credentials3)) {
242 printf("Credential chaining failed\n");
246 printf("negotiate_flags=0x%08x\n", negotiate_flags);
252 try a change password for our machine account
254 static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
257 struct netr_ServerPasswordSet r;
258 const char *password;
259 struct creds_CredentialState creds;
261 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME,
262 machine_password, &creds)) {
266 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
267 r.in.account_name = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
268 r.in.secure_channel_type = SEC_CHAN_BDC;
269 r.in.computer_name = TEST_MACHINE_NAME;
271 password = generate_random_str(mem_ctx, 8);
272 E_md4hash(password, r.in.new_password.hash);
274 creds_des_encrypt(&creds, &r.in.new_password);
276 printf("Testing ServerPasswordSet on machine account\n");
277 printf("Changing machine account password to '%s'\n", password);
279 creds_client_authenticator(&creds, &r.in.credential);
281 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
282 if (!NT_STATUS_IS_OK(status)) {
283 printf("ServerPasswordSet - %s\n", nt_errstr(status));
287 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
288 printf("Credential chaining failed\n");
291 /* by changing the machine password twice we test the
292 credentials chaining fully, and we verify that the server
293 allows the password to be set to the same value twice in a
294 row (match win2k3) */
295 printf("Testing a second ServerPasswordSet on machine account\n");
296 printf("Changing machine account password to '%s' (same as previous run)\n", password);
298 creds_client_authenticator(&creds, &r.in.credential);
300 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
301 if (!NT_STATUS_IS_OK(status)) {
302 printf("ServerPasswordSet (2) - %s\n", nt_errstr(status));
306 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
307 printf("Credential chaining failed\n");
310 machine_password = password;
312 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
313 printf("ServerPasswordSet failed to actually change the password\n");
321 try a netlogon SamLogon
323 static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
326 struct netr_LogonSamLogon r;
327 struct netr_Authenticator auth, auth2;
328 struct netr_NetworkInfo ninfo;
329 const char *username = lp_parm_string(-1, "torture", "username");
330 const char *password = lp_parm_string(-1, "torture", "password");
331 struct creds_CredentialState creds;
336 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME,
337 machine_password, &creds)) {
341 ninfo.identity_info.domain_name.string = lp_workgroup();
342 ninfo.identity_info.parameter_control = 0;
343 ninfo.identity_info.logon_id_low = 0;
344 ninfo.identity_info.logon_id_high = 0;
345 ninfo.identity_info.account_name.string = username;
346 ninfo.identity_info.workstation.string = TEST_MACHINE_NAME;
347 generate_random_buffer(ninfo.challenge,
348 sizeof(ninfo.challenge));
349 ninfo.nt.length = 24;
350 ninfo.nt.data = talloc_size(mem_ctx, 24);
351 SMBNTencrypt(password, ninfo.challenge, ninfo.nt.data);
352 ninfo.lm.length = 24;
353 ninfo.lm.data = talloc_size(mem_ctx, 24);
354 SMBencrypt(password, ninfo.challenge, ninfo.lm.data);
356 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
357 r.in.workstation = TEST_MACHINE_NAME;
358 r.in.credential = &auth;
359 r.in.return_authenticator = &auth2;
360 r.in.logon_level = 2;
361 r.in.logon.network = &ninfo;
365 creds_client_authenticator(&creds, &auth);
367 r.in.validation_level = i;
369 printf("Testing SamLogon with validation level %d\n", i);
371 status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r);
372 if (!NT_STATUS_IS_OK(status)) {
373 printf("LogonSamLogon - %s\n", nt_errstr(status));
377 if (!creds_client_check(&creds, &r.out.return_authenticator->cred)) {
378 printf("Credential chaining failed\n");
382 r.in.credential = NULL;
386 r.in.validation_level = i;
388 printf("Testing SamLogon with validation level %d\n", i);
390 status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r);
391 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
392 printf("LogonSamLogon expected INVALID_PARAMETER, got: %s\n", nt_errstr(status));
403 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
404 static uint64_t sequence_nums[3];
407 try a netlogon DatabaseSync
409 static BOOL test_DatabaseSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
412 struct netr_DatabaseSync r;
413 struct creds_CredentialState creds;
414 const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
418 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
422 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
423 r.in.computername = TEST_MACHINE_NAME;
424 r.in.preferredmaximumlength = (uint32_t)-1;
425 ZERO_STRUCT(r.in.return_authenticator);
427 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
428 r.in.sync_context = 0;
429 r.in.database_id = database_ids[i];
431 printf("Testing DatabaseSync of id %d\n", r.in.database_id);
434 creds_client_authenticator(&creds, &r.in.credential);
436 status = dcerpc_netr_DatabaseSync(p, mem_ctx, &r);
437 if (!NT_STATUS_IS_OK(status) &&
438 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
439 printf("DatabaseSync - %s\n", nt_errstr(status));
444 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
445 printf("Credential chaining failed\n");
448 r.in.sync_context = r.out.sync_context;
450 if (r.out.delta_enum_array &&
451 r.out.delta_enum_array->num_deltas > 0 &&
452 r.out.delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
453 r.out.delta_enum_array->delta_enum[0].delta_union.domain) {
454 sequence_nums[r.in.database_id] =
455 r.out.delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
456 printf("\tsequence_nums[%d]=%llu\n",
458 sequence_nums[r.in.database_id]);
460 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
468 try a netlogon DatabaseDeltas
470 static BOOL test_DatabaseDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
473 struct netr_DatabaseDeltas r;
474 struct creds_CredentialState creds;
475 const uint32_t database_ids[] = {0, 1, 2};
479 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
483 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
484 r.in.computername = TEST_MACHINE_NAME;
485 r.in.preferredmaximumlength = (uint32_t)-1;
486 ZERO_STRUCT(r.in.return_authenticator);
488 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
489 r.in.database_id = database_ids[i];
490 r.in.sequence_num = sequence_nums[r.in.database_id];
492 if (r.in.sequence_num == 0) continue;
494 r.in.sequence_num -= 1;
497 printf("Testing DatabaseDeltas of id %d at %llu\n",
498 r.in.database_id, r.in.sequence_num);
501 creds_client_authenticator(&creds, &r.in.credential);
503 status = dcerpc_netr_DatabaseDeltas(p, mem_ctx, &r);
504 if (!NT_STATUS_IS_OK(status) &&
505 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
506 printf("DatabaseDeltas - %s\n", nt_errstr(status));
511 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
512 printf("Credential chaining failed\n");
516 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
524 try a netlogon AccountDeltas
526 static BOOL test_AccountDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
529 struct netr_AccountDeltas r;
530 struct creds_CredentialState creds;
533 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
537 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
538 r.in.computername = TEST_MACHINE_NAME;
539 ZERO_STRUCT(r.in.return_authenticator);
540 creds_client_authenticator(&creds, &r.in.credential);
541 ZERO_STRUCT(r.in.uas);
546 printf("Testing AccountDeltas\n");
548 /* w2k3 returns "NOT IMPLEMENTED" for this call */
549 status = dcerpc_netr_AccountDeltas(p, mem_ctx, &r);
550 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
551 printf("AccountDeltas - %s\n", nt_errstr(status));
559 try a netlogon AccountSync
561 static BOOL test_AccountSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
564 struct netr_AccountSync r;
565 struct creds_CredentialState creds;
568 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
572 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
573 r.in.computername = TEST_MACHINE_NAME;
574 ZERO_STRUCT(r.in.return_authenticator);
575 creds_client_authenticator(&creds, &r.in.credential);
576 ZERO_STRUCT(r.in.recordid);
581 printf("Testing AccountSync\n");
583 /* w2k3 returns "NOT IMPLEMENTED" for this call */
584 status = dcerpc_netr_AccountSync(p, mem_ctx, &r);
585 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
586 printf("AccountSync - %s\n", nt_errstr(status));
594 try a netlogon GetDcName
596 static BOOL test_GetDcName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
599 struct netr_GetDcName r;
601 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
602 r.in.domainname = lp_workgroup();
604 printf("Testing GetDcName\n");
606 status = dcerpc_netr_GetDcName(p, mem_ctx, &r);
607 if (!NT_STATUS_IS_OK(status)) {
608 printf("GetDcName - %s\n", nt_errstr(status));
612 printf("\tDC is at '%s'\n", r.out.dcname);
618 try a netlogon LogonControl
620 static BOOL test_LogonControl(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
623 struct netr_LogonControl r;
627 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
628 r.in.function_code = 1;
633 printf("Testing LogonControl level %d\n", i);
635 status = dcerpc_netr_LogonControl(p, mem_ctx, &r);
636 if (!NT_STATUS_IS_OK(status)) {
637 printf("LogonControl - %s\n", nt_errstr(status));
647 try a netlogon GetAnyDCName
649 static BOOL test_GetAnyDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
652 struct netr_GetAnyDCName r;
654 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
655 r.in.domainname = lp_workgroup();
657 printf("Testing GetAnyDCName\n");
659 status = dcerpc_netr_GetAnyDCName(p, mem_ctx, &r);
660 if (!NT_STATUS_IS_OK(status)) {
661 printf("GetAnyDCName - %s\n", nt_errstr(status));
666 printf("\tDC is at '%s'\n", r.out.dcname);
674 try a netlogon LogonControl2
676 static BOOL test_LogonControl2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
679 struct netr_LogonControl2 r;
683 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
685 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
686 r.in.data.domain = lp_workgroup();
691 printf("Testing LogonControl2 level %d function %d\n",
692 i, r.in.function_code);
694 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
695 if (!NT_STATUS_IS_OK(status)) {
696 printf("LogonControl - %s\n", nt_errstr(status));
701 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
702 r.in.data.domain = lp_workgroup();
707 printf("Testing LogonControl2 level %d function %d\n",
708 i, r.in.function_code);
710 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
711 if (!NT_STATUS_IS_OK(status)) {
712 printf("LogonControl - %s\n", nt_errstr(status));
717 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
718 r.in.data.domain = lp_workgroup();
723 printf("Testing LogonControl2 level %d function %d\n",
724 i, r.in.function_code);
726 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
727 if (!NT_STATUS_IS_OK(status)) {
728 printf("LogonControl - %s\n", nt_errstr(status));
733 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
734 r.in.data.debug_level = ~0;
739 printf("Testing LogonControl2 level %d function %d\n",
740 i, r.in.function_code);
742 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
743 if (!NT_STATUS_IS_OK(status)) {
744 printf("LogonControl - %s\n", nt_errstr(status));
753 try a netlogon DatabaseSync2
755 static BOOL test_DatabaseSync2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
758 struct netr_DatabaseSync2 r;
759 struct creds_CredentialState creds;
760 const uint32_t database_ids[] = {0, 1, 2};
764 if (!test_SetupCredentials2(p, mem_ctx, NETLOGON_NEG_AUTH2_FLAGS,
765 TEST_MACHINE_NAME, machine_password,
766 SEC_CHAN_BDC, &creds)) {
770 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
771 r.in.computername = TEST_MACHINE_NAME;
772 r.in.preferredmaximumlength = (uint32_t)-1;
773 ZERO_STRUCT(r.in.return_authenticator);
775 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
776 r.in.sync_context = 0;
777 r.in.database_id = database_ids[i];
778 r.in.restart_state = 0;
780 printf("Testing DatabaseSync2 of id %d\n", r.in.database_id);
783 creds_client_authenticator(&creds, &r.in.credential);
785 status = dcerpc_netr_DatabaseSync2(p, mem_ctx, &r);
786 if (!NT_STATUS_IS_OK(status) &&
787 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
788 printf("DatabaseSync2 - %s\n", nt_errstr(status));
793 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
794 printf("Credential chaining failed\n");
797 r.in.sync_context = r.out.sync_context;
798 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
806 try a netlogon LogonControl2Ex
808 static BOOL test_LogonControl2Ex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
811 struct netr_LogonControl2Ex r;
815 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
817 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
818 r.in.data.domain = lp_workgroup();
823 printf("Testing LogonControl2Ex level %d function %d\n",
824 i, r.in.function_code);
826 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
827 if (!NT_STATUS_IS_OK(status)) {
828 printf("LogonControl - %s\n", nt_errstr(status));
833 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
834 r.in.data.domain = lp_workgroup();
839 printf("Testing LogonControl2Ex level %d function %d\n",
840 i, r.in.function_code);
842 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
843 if (!NT_STATUS_IS_OK(status)) {
844 printf("LogonControl - %s\n", nt_errstr(status));
849 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
850 r.in.data.domain = lp_workgroup();
855 printf("Testing LogonControl2Ex level %d function %d\n",
856 i, r.in.function_code);
858 status = dcerpc_netr_LogonControl2Ex(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_SET_DBFLAG;
866 r.in.data.debug_level = ~0;
871 printf("Testing LogonControl2Ex level %d function %d\n",
872 i, r.in.function_code);
874 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
875 if (!NT_STATUS_IS_OK(status)) {
876 printf("LogonControl - %s\n", nt_errstr(status));
886 try a netlogon netr_DsrEnumerateDomainTrusts
888 static BOOL test_DsrEnumerateDomainTrusts(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
891 struct netr_DsrEnumerateDomainTrusts r;
893 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
894 r.in.trust_flags = 0x3f;
896 printf("Testing netr_DsrEnumerateDomainTrusts\n");
898 status = dcerpc_netr_DsrEnumerateDomainTrusts(p, mem_ctx, &r);
899 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
900 printf("netr_DsrEnumerateDomainTrusts - %s/%s\n",
901 nt_errstr(status), win_errstr(r.out.result));
909 try a netlogon netr_DrsGetDCNameEx2
911 static BOOL test_netr_DrsGetDCNameEx2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
914 struct netr_DrsGetDCNameEx2 r;
917 r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
918 r.in.client_account = NULL;
919 r.in.mask = 0x00000000;
920 r.in.domain_name = talloc_asprintf(mem_ctx, "%s", lp_realm());
921 r.in.domain_guid = NULL;
922 r.in.site_name = NULL;
923 r.in.flags = 0x40000000;
925 printf("Testing netr_DrsGetDCNameEx2 without client account\n");
927 status = dcerpc_netr_DrsGetDCNameEx2(p, mem_ctx, &r);
928 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
929 printf("netr_DrsGetDCNameEx2 - %s/%s\n",
930 nt_errstr(status), win_errstr(r.out.result));
934 printf("Testing netr_DrsGetDCNameEx2 with client acount\n");
935 r.in.client_account = TEST_MACHINE_NAME"$";
936 r.in.mask = 0x00002000;
937 r.in.flags = 0x80000000;
939 status = dcerpc_netr_DrsGetDCNameEx2(p, mem_ctx, &r);
940 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
941 printf("netr_DrsGetDCNameEx2 - %s/%s\n",
942 nt_errstr(status), win_errstr(r.out.result));
949 static BOOL test_GetDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
952 struct netr_LogonGetDomainInfo r;
953 struct netr_DomainQuery1 q1;
954 struct netr_Authenticator a;
955 struct creds_CredentialState creds;
957 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
958 TEST_MACHINE_NAME, machine_password, &creds)) {
964 creds_client_authenticator(&creds, &a);
966 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
967 r.in.computer_name = TEST_MACHINE_NAME;
970 r.in.credential = &a;
971 r.out.credential = &a;
976 r.in.query.query1 = &q1;
979 /* this should really be the fully qualified name */
980 q1.workstation_domain = TEST_MACHINE_NAME;
981 q1.workstation_site = "Default-First-Site-Name";
984 q1.blob2.data = NULL;
985 q1.product.string = "product string";
987 printf("Testing netr_LogonGetDomainInfo\n");
989 status = dcerpc_netr_LogonGetDomainInfo(p, mem_ctx, &r);
990 if (!NT_STATUS_IS_OK(status)) {
991 printf("netr_LogonGetDomainInfo - %s\n", nt_errstr(status));
995 if (!creds_client_check(&creds, &a.cred)) {
996 printf("Credential chaining failed\n");
1004 static void async_callback(struct rpc_request *req)
1006 int *counter = req->async.private;
1007 if (NT_STATUS_IS_OK(req->status)) {
1012 static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1015 struct netr_LogonGetDomainInfo r;
1016 struct netr_DomainQuery1 q1;
1017 struct netr_Authenticator a;
1018 #define ASYNC_COUNT 100
1019 struct creds_CredentialState creds;
1020 struct creds_CredentialState creds_async[ASYNC_COUNT];
1021 struct rpc_request *req[ASYNC_COUNT];
1023 int *async_counter = talloc_p(mem_ctx, int);
1025 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
1026 printf("test_GetDomainInfo_async disabled - enable dangerous tests to use\n");
1030 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
1031 TEST_MACHINE_NAME, machine_password, &creds)) {
1036 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1037 r.in.computer_name = TEST_MACHINE_NAME;
1038 r.in.unknown1 = 512;
1040 r.in.credential = &a;
1041 r.out.credential = &a;
1046 r.in.query.query1 = &q1;
1049 /* this should really be the fully qualified name */
1050 q1.workstation_domain = TEST_MACHINE_NAME;
1051 q1.workstation_site = "Default-First-Site-Name";
1052 q1.blob2.length = 0;
1054 q1.blob2.data = NULL;
1055 q1.product.string = "product string";
1057 printf("Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
1061 for (i=0;i<ASYNC_COUNT;i++) {
1062 creds_client_authenticator(&creds, &a);
1064 creds_async[i] = creds;
1065 req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, mem_ctx, &r);
1067 req[i]->async.callback = async_callback;
1068 req[i]->async.private = async_counter;
1070 /* even with this flush per request a w2k3 server seems to
1071 clag with multiple outstanding requests. bleergh. */
1072 if (event_loop_once(dcerpc_event_context(p)) != 0) {
1077 for (i=0;i<ASYNC_COUNT;i++) {
1078 status = dcerpc_ndr_request_recv(req[i]);
1079 if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(r.out.result)) {
1080 printf("netr_LogonGetDomainInfo_async(%d) - %s/%s\n",
1081 i, nt_errstr(status), nt_errstr(r.out.result));
1085 if (!creds_client_check(&creds_async[i], &a.cred)) {
1086 printf("Credential chaining failed at async %d\n", i);
1091 printf("Testing netr_LogonGetDomainInfo - async count %d OK\n", *async_counter);
1093 return (*async_counter) == ASYNC_COUNT;
1096 static BOOL test_ManyGetDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1099 struct dcerpc_pipe *p2;
1100 struct lsa_ObjectAttribute attr;
1101 struct lsa_QosInfo qos;
1102 struct lsa_OpenPolicy2 o;
1103 struct policy_handle lsa_handle;
1104 struct lsa_DomainList domains;
1106 struct lsa_EnumTrustDom t;
1107 uint32_t resume_handle = 0;
1108 struct netr_GetAnyDCName d;
1113 if (p->conn->transport.transport != NCACN_NP) {
1117 printf("Torturing GetDCName\n");
1119 status = dcerpc_secondary_connection(p, &p2,
1122 DCERPC_LSARPC_VERSION);
1123 if (!NT_STATUS_IS_OK(status)) {
1124 printf("Failed to create secondary connection\n");
1129 qos.impersonation_level = 2;
1130 qos.context_mode = 1;
1131 qos.effective_only = 0;
1134 attr.root_dir = NULL;
1135 attr.object_name = NULL;
1136 attr.attributes = 0;
1137 attr.sec_desc = NULL;
1138 attr.sec_qos = &qos;
1140 o.in.system_name = "\\";
1142 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1143 o.out.handle = &lsa_handle;
1145 status = dcerpc_lsa_OpenPolicy2(p2, mem_ctx, &o);
1146 if (!NT_STATUS_IS_OK(status)) {
1147 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
1151 t.in.handle = &lsa_handle;
1152 t.in.resume_handle = &resume_handle;
1153 t.in.num_entries = 1000;
1154 t.out.domains = &domains;
1155 t.out.resume_handle = &resume_handle;
1157 status = dcerpc_lsa_EnumTrustDom(p2, mem_ctx, &t);
1159 if ((!NT_STATUS_IS_OK(status) &&
1160 (!NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)))) {
1161 printf("Could not list domains\n");
1165 dcerpc_pipe_close(p2);
1167 d.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s",
1168 dcerpc_server_name(p));
1170 for (i=0; i<domains.count * 4; i++) {
1171 struct lsa_DomainInformation *info =
1172 &domains.domains[rand()%domains.count];
1174 d.in.domainname = info->name.string;
1176 status = dcerpc_netr_GetAnyDCName(p, mem_ctx, &d);
1177 if (!NT_STATUS_IS_OK(status)) {
1178 printf("GetAnyDCName - %s\n", nt_errstr(status));
1182 printf("\tDC for domain %s is %s\n", info->name.string,
1183 d.out.dcname ? d.out.dcname : "unknown");
1190 BOOL torture_rpc_netlogon(void)
1193 struct dcerpc_pipe *p;
1194 TALLOC_CTX *mem_ctx;
1196 struct test_join *join_ctx;
1198 mem_ctx = talloc_init("torture_rpc_netlogon");
1200 join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), ACB_SVRTRUST,
1203 printf("Failed to join as BDC\n");
1207 status = torture_rpc_connection(&p,
1208 DCERPC_NETLOGON_NAME,
1209 DCERPC_NETLOGON_UUID,
1210 DCERPC_NETLOGON_VERSION);
1211 if (!NT_STATUS_IS_OK(status)) {
1215 ret &= test_LogonUasLogon(p, mem_ctx);
1216 ret &= test_LogonUasLogoff(p, mem_ctx);
1217 ret &= test_SamLogon(p, mem_ctx);
1218 ret &= test_SetPassword(p, mem_ctx);
1219 ret &= test_GetDomainInfo(p, mem_ctx);
1220 ret &= test_DatabaseSync(p, mem_ctx);
1221 ret &= test_DatabaseDeltas(p, mem_ctx);
1222 ret &= test_AccountDeltas(p, mem_ctx);
1223 ret &= test_AccountSync(p, mem_ctx);
1224 ret &= test_GetDcName(p, mem_ctx);
1225 ret &= test_ManyGetDCName(p, mem_ctx);
1226 ret &= test_LogonControl(p, mem_ctx);
1227 ret &= test_GetAnyDCName(p, mem_ctx);
1228 ret &= test_LogonControl2(p, mem_ctx);
1229 ret &= test_DatabaseSync2(p, mem_ctx);
1230 ret &= test_LogonControl2Ex(p, mem_ctx);
1231 ret &= test_DsrEnumerateDomainTrusts(p, mem_ctx);
1232 ret &= test_GetDomainInfo_async(p, mem_ctx);
1233 ret &= test_netr_DrsGetDCNameEx2(p, mem_ctx);
1235 talloc_destroy(mem_ctx);
1237 torture_rpc_close(p);
1239 torture_leave_domain(join_ctx);