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;
272 E_md4hash(password, r.in.new_password.hash);
274 creds_des_encrypt(&creds, &r.in.new_password);
275 /* by changing the machine password to ""
276 * we check if the server uses password restrictions
277 * for ServerPasswordSet2
278 * (win2k3 accepts "")
280 printf("Testing a second ServerPasswordSet on machine account\n");
281 printf("Changing machine account password to '%s'\n", password);
283 creds_client_authenticator(&creds, &r.in.credential);
285 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
286 if (!NT_STATUS_IS_OK(status)) {
287 printf("ServerPasswordSet (2) - %s\n", nt_errstr(status));
291 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
292 printf("Credential chaining failed\n");
295 machine_password = password;
297 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
298 printf("ServerPasswordSet failed to actually change the password\n");
302 password = generate_random_str(mem_ctx, 8);
303 E_md4hash(password, r.in.new_password.hash);
305 creds_des_encrypt(&creds, &r.in.new_password);
307 printf("Testing ServerPasswordSet on machine account\n");
308 printf("Changing machine account password to '%s'\n", password);
310 creds_client_authenticator(&creds, &r.in.credential);
312 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
313 if (!NT_STATUS_IS_OK(status)) {
314 printf("ServerPasswordSet - %s\n", nt_errstr(status));
318 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
319 printf("Credential chaining failed\n");
322 /* by changing the machine password twice we test the
323 credentials chaining fully, and we verify that the server
324 allows the password to be set to the same value twice in a
325 row (match win2k3) */
326 printf("Testing a second ServerPasswordSet on machine account\n");
327 printf("Changing machine account password to '%s' (same as previous run)\n", password);
329 creds_client_authenticator(&creds, &r.in.credential);
331 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
332 if (!NT_STATUS_IS_OK(status)) {
333 printf("ServerPasswordSet (2) - %s\n", nt_errstr(status));
337 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
338 printf("Credential chaining failed\n");
341 machine_password = password;
343 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
344 printf("ServerPasswordSet failed to actually change the password\n");
352 try a change password for our machine account
354 static BOOL test_SetPassword2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
357 struct netr_ServerPasswordSet2 r;
358 const char *password;
359 struct creds_CredentialState creds;
361 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME,
362 machine_password, &creds)) {
366 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
367 r.in.account_name = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
368 r.in.secure_channel_type = SEC_CHAN_BDC;
369 r.in.computer_name = TEST_MACHINE_NAME;
372 encode_pw_buffer(r.in.new_password.data, password, STR_UNICODE);
373 creds_arcfour_crypt(&creds, r.in.new_password.data, 516);
375 /* by changing the machine password to ""
376 * we check if the server uses password restrictions
377 * for ServerPasswordSet2
378 * (win2k3 accepts "")
380 printf("Testing a second ServerPasswordSet2 on machine account\n");
381 printf("Changing machine account password to '%s'\n", password);
383 creds_client_authenticator(&creds, &r.in.credential);
385 status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
386 if (!NT_STATUS_IS_OK(status)) {
387 printf("ServerPasswordSet (2) - %s\n", nt_errstr(status));
391 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
392 printf("Credential chaining failed\n");
395 machine_password = password;
397 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
398 printf("ServerPasswordSet failed to actually change the password\n");
402 /* now try a random password */
403 password = generate_random_str(mem_ctx, 8);
404 encode_pw_buffer(r.in.new_password.data, password, STR_UNICODE);
405 creds_arcfour_crypt(&creds, r.in.new_password.data, 516);
407 printf("Testing ServerPasswordSet2 on machine account\n");
408 printf("Changing machine account password to '%s'\n", password);
410 creds_client_authenticator(&creds, &r.in.credential);
412 status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
413 if (!NT_STATUS_IS_OK(status)) {
414 printf("ServerPasswordSet2 - %s\n", nt_errstr(status));
418 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
419 printf("Credential chaining failed\n");
422 /* by changing the machine password twice we test the
423 credentials chaining fully, and we verify that the server
424 allows the password to be set to the same value twice in a
425 row (match win2k3) */
426 printf("Testing a second ServerPasswordSet2 on machine account\n");
427 printf("Changing machine account password to '%s' (same as previous run)\n", password);
429 creds_client_authenticator(&creds, &r.in.credential);
431 status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
432 if (!NT_STATUS_IS_OK(status)) {
433 printf("ServerPasswordSet (2) - %s\n", nt_errstr(status));
437 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
438 printf("Credential chaining failed\n");
441 machine_password = password;
443 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
444 printf("ServerPasswordSet failed to actually change the password\n");
452 try a netlogon SamLogon
454 static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
457 struct netr_LogonSamLogon r;
458 struct netr_Authenticator auth, auth2;
459 struct netr_NetworkInfo ninfo;
460 const char *username = lp_parm_string(-1, "torture", "username");
461 const char *password = lp_parm_string(-1, "torture", "password");
462 struct creds_CredentialState creds;
467 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME,
468 machine_password, &creds)) {
472 ninfo.identity_info.domain_name.string = lp_workgroup();
473 ninfo.identity_info.parameter_control = 0;
474 ninfo.identity_info.logon_id_low = 0;
475 ninfo.identity_info.logon_id_high = 0;
476 ninfo.identity_info.account_name.string = username;
477 ninfo.identity_info.workstation.string = TEST_MACHINE_NAME;
478 generate_random_buffer(ninfo.challenge,
479 sizeof(ninfo.challenge));
480 ninfo.nt.length = 24;
481 ninfo.nt.data = talloc_size(mem_ctx, 24);
482 SMBNTencrypt(password, ninfo.challenge, ninfo.nt.data);
483 ninfo.lm.length = 24;
484 ninfo.lm.data = talloc_size(mem_ctx, 24);
485 SMBencrypt(password, ninfo.challenge, ninfo.lm.data);
487 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
488 r.in.workstation = TEST_MACHINE_NAME;
489 r.in.credential = &auth;
490 r.in.return_authenticator = &auth2;
491 r.in.logon_level = 2;
492 r.in.logon.network = &ninfo;
496 creds_client_authenticator(&creds, &auth);
498 r.in.validation_level = i;
500 printf("Testing SamLogon with validation level %d\n", i);
502 status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r);
503 if (!NT_STATUS_IS_OK(status)) {
504 printf("LogonSamLogon - %s\n", nt_errstr(status));
508 if (!creds_client_check(&creds, &r.out.return_authenticator->cred)) {
509 printf("Credential chaining failed\n");
513 r.in.credential = NULL;
517 r.in.validation_level = i;
519 printf("Testing SamLogon with validation level %d\n", i);
521 status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r);
522 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
523 printf("LogonSamLogon expected INVALID_PARAMETER, got: %s\n", nt_errstr(status));
532 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
533 static uint64_t sequence_nums[3];
536 try a netlogon DatabaseSync
538 static BOOL test_DatabaseSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
541 struct netr_DatabaseSync r;
542 struct creds_CredentialState creds;
543 const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
547 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
551 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
552 r.in.computername = TEST_MACHINE_NAME;
553 r.in.preferredmaximumlength = (uint32_t)-1;
554 ZERO_STRUCT(r.in.return_authenticator);
556 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
557 r.in.sync_context = 0;
558 r.in.database_id = database_ids[i];
560 printf("Testing DatabaseSync of id %d\n", r.in.database_id);
563 creds_client_authenticator(&creds, &r.in.credential);
565 status = dcerpc_netr_DatabaseSync(p, mem_ctx, &r);
566 if (!NT_STATUS_IS_OK(status) &&
567 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
568 printf("DatabaseSync - %s\n", nt_errstr(status));
573 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
574 printf("Credential chaining failed\n");
577 r.in.sync_context = r.out.sync_context;
579 if (r.out.delta_enum_array &&
580 r.out.delta_enum_array->num_deltas > 0 &&
581 r.out.delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
582 r.out.delta_enum_array->delta_enum[0].delta_union.domain) {
583 sequence_nums[r.in.database_id] =
584 r.out.delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
585 printf("\tsequence_nums[%d]=%llu\n",
587 sequence_nums[r.in.database_id]);
589 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
597 try a netlogon DatabaseDeltas
599 static BOOL test_DatabaseDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
602 struct netr_DatabaseDeltas r;
603 struct creds_CredentialState creds;
604 const uint32_t database_ids[] = {0, 1, 2};
608 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
612 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
613 r.in.computername = TEST_MACHINE_NAME;
614 r.in.preferredmaximumlength = (uint32_t)-1;
615 ZERO_STRUCT(r.in.return_authenticator);
617 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
618 r.in.database_id = database_ids[i];
619 r.in.sequence_num = sequence_nums[r.in.database_id];
621 if (r.in.sequence_num == 0) continue;
623 r.in.sequence_num -= 1;
626 printf("Testing DatabaseDeltas of id %d at %llu\n",
627 r.in.database_id, r.in.sequence_num);
630 creds_client_authenticator(&creds, &r.in.credential);
632 status = dcerpc_netr_DatabaseDeltas(p, mem_ctx, &r);
633 if (!NT_STATUS_IS_OK(status) &&
634 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
635 printf("DatabaseDeltas - %s\n", nt_errstr(status));
640 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
641 printf("Credential chaining failed\n");
645 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
653 try a netlogon AccountDeltas
655 static BOOL test_AccountDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
658 struct netr_AccountDeltas r;
659 struct creds_CredentialState creds;
662 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
666 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
667 r.in.computername = TEST_MACHINE_NAME;
668 ZERO_STRUCT(r.in.return_authenticator);
669 creds_client_authenticator(&creds, &r.in.credential);
670 ZERO_STRUCT(r.in.uas);
675 printf("Testing AccountDeltas\n");
677 /* w2k3 returns "NOT IMPLEMENTED" for this call */
678 status = dcerpc_netr_AccountDeltas(p, mem_ctx, &r);
679 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
680 printf("AccountDeltas - %s\n", nt_errstr(status));
688 try a netlogon AccountSync
690 static BOOL test_AccountSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
693 struct netr_AccountSync r;
694 struct creds_CredentialState creds;
697 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
701 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
702 r.in.computername = TEST_MACHINE_NAME;
703 ZERO_STRUCT(r.in.return_authenticator);
704 creds_client_authenticator(&creds, &r.in.credential);
705 ZERO_STRUCT(r.in.recordid);
710 printf("Testing AccountSync\n");
712 /* w2k3 returns "NOT IMPLEMENTED" for this call */
713 status = dcerpc_netr_AccountSync(p, mem_ctx, &r);
714 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
715 printf("AccountSync - %s\n", nt_errstr(status));
723 try a netlogon GetDcName
725 static BOOL test_GetDcName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
728 struct netr_GetDcName r;
730 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
731 r.in.domainname = lp_workgroup();
733 printf("Testing GetDcName\n");
735 status = dcerpc_netr_GetDcName(p, mem_ctx, &r);
736 if (!NT_STATUS_IS_OK(status)) {
737 printf("GetDcName - %s\n", nt_errstr(status));
741 printf("\tDC is at '%s'\n", r.out.dcname);
747 try a netlogon LogonControl
749 static BOOL test_LogonControl(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
752 struct netr_LogonControl r;
756 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
757 r.in.function_code = 1;
762 printf("Testing LogonControl level %d\n", i);
764 status = dcerpc_netr_LogonControl(p, mem_ctx, &r);
765 if (!NT_STATUS_IS_OK(status)) {
766 printf("LogonControl - %s\n", nt_errstr(status));
776 try a netlogon GetAnyDCName
778 static BOOL test_GetAnyDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
781 struct netr_GetAnyDCName r;
783 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
784 r.in.domainname = lp_workgroup();
786 printf("Testing GetAnyDCName\n");
788 status = dcerpc_netr_GetAnyDCName(p, mem_ctx, &r);
789 if (!NT_STATUS_IS_OK(status)) {
790 printf("GetAnyDCName - %s\n", nt_errstr(status));
795 printf("\tDC is at '%s'\n", r.out.dcname);
803 try a netlogon LogonControl2
805 static BOOL test_LogonControl2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
808 struct netr_LogonControl2 r;
812 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
814 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
815 r.in.data.domain = lp_workgroup();
820 printf("Testing LogonControl2 level %d function %d\n",
821 i, r.in.function_code);
823 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
824 if (!NT_STATUS_IS_OK(status)) {
825 printf("LogonControl - %s\n", nt_errstr(status));
830 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
831 r.in.data.domain = lp_workgroup();
836 printf("Testing LogonControl2 level %d function %d\n",
837 i, r.in.function_code);
839 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
840 if (!NT_STATUS_IS_OK(status)) {
841 printf("LogonControl - %s\n", nt_errstr(status));
846 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
847 r.in.data.domain = lp_workgroup();
852 printf("Testing LogonControl2 level %d function %d\n",
853 i, r.in.function_code);
855 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
856 if (!NT_STATUS_IS_OK(status)) {
857 printf("LogonControl - %s\n", nt_errstr(status));
862 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
863 r.in.data.debug_level = ~0;
868 printf("Testing LogonControl2 level %d function %d\n",
869 i, r.in.function_code);
871 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
872 if (!NT_STATUS_IS_OK(status)) {
873 printf("LogonControl - %s\n", nt_errstr(status));
882 try a netlogon DatabaseSync2
884 static BOOL test_DatabaseSync2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
887 struct netr_DatabaseSync2 r;
888 struct creds_CredentialState creds;
889 const uint32_t database_ids[] = {0, 1, 2};
893 if (!test_SetupCredentials2(p, mem_ctx, NETLOGON_NEG_AUTH2_FLAGS,
894 TEST_MACHINE_NAME, machine_password,
895 SEC_CHAN_BDC, &creds)) {
899 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
900 r.in.computername = TEST_MACHINE_NAME;
901 r.in.preferredmaximumlength = (uint32_t)-1;
902 ZERO_STRUCT(r.in.return_authenticator);
904 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
905 r.in.sync_context = 0;
906 r.in.database_id = database_ids[i];
907 r.in.restart_state = 0;
909 printf("Testing DatabaseSync2 of id %d\n", r.in.database_id);
912 creds_client_authenticator(&creds, &r.in.credential);
914 status = dcerpc_netr_DatabaseSync2(p, mem_ctx, &r);
915 if (!NT_STATUS_IS_OK(status) &&
916 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
917 printf("DatabaseSync2 - %s\n", nt_errstr(status));
922 if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
923 printf("Credential chaining failed\n");
926 r.in.sync_context = r.out.sync_context;
927 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
935 try a netlogon LogonControl2Ex
937 static BOOL test_LogonControl2Ex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
940 struct netr_LogonControl2Ex r;
944 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
946 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
947 r.in.data.domain = lp_workgroup();
952 printf("Testing LogonControl2Ex level %d function %d\n",
953 i, r.in.function_code);
955 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
956 if (!NT_STATUS_IS_OK(status)) {
957 printf("LogonControl - %s\n", nt_errstr(status));
962 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
963 r.in.data.domain = lp_workgroup();
968 printf("Testing LogonControl2Ex level %d function %d\n",
969 i, r.in.function_code);
971 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
972 if (!NT_STATUS_IS_OK(status)) {
973 printf("LogonControl - %s\n", nt_errstr(status));
978 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
979 r.in.data.domain = lp_workgroup();
984 printf("Testing LogonControl2Ex level %d function %d\n",
985 i, r.in.function_code);
987 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
988 if (!NT_STATUS_IS_OK(status)) {
989 printf("LogonControl - %s\n", nt_errstr(status));
994 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
995 r.in.data.debug_level = ~0;
1000 printf("Testing LogonControl2Ex level %d function %d\n",
1001 i, r.in.function_code);
1003 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1004 if (!NT_STATUS_IS_OK(status)) {
1005 printf("LogonControl - %s\n", nt_errstr(status));
1015 try a netlogon netr_DsrEnumerateDomainTrusts
1017 static BOOL test_DsrEnumerateDomainTrusts(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1020 struct netr_DsrEnumerateDomainTrusts r;
1022 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1023 r.in.trust_flags = 0x3f;
1025 printf("Testing netr_DsrEnumerateDomainTrusts\n");
1027 status = dcerpc_netr_DsrEnumerateDomainTrusts(p, mem_ctx, &r);
1028 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1029 printf("netr_DsrEnumerateDomainTrusts - %s/%s\n",
1030 nt_errstr(status), win_errstr(r.out.result));
1038 try a netlogon netr_DrsGetDCNameEx2
1040 static BOOL test_netr_DrsGetDCNameEx2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1043 struct netr_DrsGetDCNameEx2 r;
1046 r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1047 r.in.client_account = NULL;
1048 r.in.mask = 0x00000000;
1049 r.in.domain_name = talloc_asprintf(mem_ctx, "%s", lp_realm());
1050 r.in.domain_guid = NULL;
1051 r.in.site_name = NULL;
1052 r.in.flags = 0x40000000;
1054 printf("Testing netr_DrsGetDCNameEx2 without client account\n");
1056 status = dcerpc_netr_DrsGetDCNameEx2(p, mem_ctx, &r);
1057 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1058 printf("netr_DrsGetDCNameEx2 - %s/%s\n",
1059 nt_errstr(status), win_errstr(r.out.result));
1063 printf("Testing netr_DrsGetDCNameEx2 with client acount\n");
1064 r.in.client_account = TEST_MACHINE_NAME"$";
1065 r.in.mask = 0x00002000;
1066 r.in.flags = 0x80000000;
1068 status = dcerpc_netr_DrsGetDCNameEx2(p, mem_ctx, &r);
1069 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1070 printf("netr_DrsGetDCNameEx2 - %s/%s\n",
1071 nt_errstr(status), win_errstr(r.out.result));
1078 static BOOL test_GetDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1081 struct netr_LogonGetDomainInfo r;
1082 struct netr_DomainQuery1 q1;
1083 struct netr_Authenticator a;
1084 struct creds_CredentialState creds;
1086 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
1087 TEST_MACHINE_NAME, machine_password, &creds)) {
1093 creds_client_authenticator(&creds, &a);
1095 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1096 r.in.computer_name = TEST_MACHINE_NAME;
1098 r.in.credential = &a;
1099 r.in.return_authenticator = &a;
1100 r.out.return_authenticator = &a;
1102 r.in.query.query1 = &q1;
1105 /* this should really be the fully qualified name */
1106 q1.workstation_domain = TEST_MACHINE_NAME;
1107 q1.workstation_site = "Default-First-Site-Name";
1108 q1.blob2.length = 0;
1110 q1.blob2.data = NULL;
1111 q1.product.string = "product string";
1113 printf("Testing netr_LogonGetDomainInfo\n");
1115 status = dcerpc_netr_LogonGetDomainInfo(p, mem_ctx, &r);
1116 if (!NT_STATUS_IS_OK(status)) {
1117 printf("netr_LogonGetDomainInfo - %s\n", nt_errstr(status));
1121 if (!creds_client_check(&creds, &a.cred)) {
1122 printf("Credential chaining failed\n");
1130 static void async_callback(struct rpc_request *req)
1132 int *counter = req->async.private;
1133 if (NT_STATUS_IS_OK(req->status)) {
1138 static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1141 struct netr_LogonGetDomainInfo r;
1142 struct netr_DomainQuery1 q1;
1143 struct netr_Authenticator a;
1144 #define ASYNC_COUNT 100
1145 struct creds_CredentialState creds;
1146 struct creds_CredentialState creds_async[ASYNC_COUNT];
1147 struct rpc_request *req[ASYNC_COUNT];
1149 int *async_counter = talloc(mem_ctx, int);
1151 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
1152 printf("test_GetDomainInfo_async disabled - enable dangerous tests to use\n");
1156 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
1157 TEST_MACHINE_NAME, machine_password, &creds)) {
1162 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1163 r.in.computer_name = TEST_MACHINE_NAME;
1165 r.in.credential = &a;
1166 r.in.return_authenticator = &a;
1167 r.out.return_authenticator = &a;
1169 r.in.query.query1 = &q1;
1172 /* this should really be the fully qualified name */
1173 q1.workstation_domain = TEST_MACHINE_NAME;
1174 q1.workstation_site = "Default-First-Site-Name";
1175 q1.blob2.length = 0;
1177 q1.blob2.data = NULL;
1178 q1.product.string = "product string";
1180 printf("Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
1184 for (i=0;i<ASYNC_COUNT;i++) {
1185 creds_client_authenticator(&creds, &a);
1187 creds_async[i] = creds;
1188 req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, mem_ctx, &r);
1190 req[i]->async.callback = async_callback;
1191 req[i]->async.private = async_counter;
1193 /* even with this flush per request a w2k3 server seems to
1194 clag with multiple outstanding requests. bleergh. */
1195 if (event_loop_once(dcerpc_event_context(p)) != 0) {
1200 for (i=0;i<ASYNC_COUNT;i++) {
1201 status = dcerpc_ndr_request_recv(req[i]);
1202 if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(r.out.result)) {
1203 printf("netr_LogonGetDomainInfo_async(%d) - %s/%s\n",
1204 i, nt_errstr(status), nt_errstr(r.out.result));
1208 if (!creds_client_check(&creds_async[i], &a.cred)) {
1209 printf("Credential chaining failed at async %d\n", i);
1214 printf("Testing netr_LogonGetDomainInfo - async count %d OK\n", *async_counter);
1216 return (*async_counter) == ASYNC_COUNT;
1219 static BOOL test_ManyGetDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1222 struct dcerpc_pipe *p2;
1223 struct lsa_ObjectAttribute attr;
1224 struct lsa_QosInfo qos;
1225 struct lsa_OpenPolicy2 o;
1226 struct policy_handle lsa_handle;
1227 struct lsa_DomainList domains;
1229 struct lsa_EnumTrustDom t;
1230 uint32_t resume_handle = 0;
1231 struct netr_GetAnyDCName d;
1236 if (p->conn->transport.transport != NCACN_NP) {
1240 printf("Torturing GetDCName\n");
1242 status = dcerpc_secondary_connection(p, &p2,
1245 DCERPC_LSARPC_VERSION);
1246 if (!NT_STATUS_IS_OK(status)) {
1247 printf("Failed to create secondary connection\n");
1252 qos.impersonation_level = 2;
1253 qos.context_mode = 1;
1254 qos.effective_only = 0;
1257 attr.root_dir = NULL;
1258 attr.object_name = NULL;
1259 attr.attributes = 0;
1260 attr.sec_desc = NULL;
1261 attr.sec_qos = &qos;
1263 o.in.system_name = "\\";
1265 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1266 o.out.handle = &lsa_handle;
1268 status = dcerpc_lsa_OpenPolicy2(p2, mem_ctx, &o);
1269 if (!NT_STATUS_IS_OK(status)) {
1270 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
1274 t.in.handle = &lsa_handle;
1275 t.in.resume_handle = &resume_handle;
1276 t.in.max_size = 1000;
1277 t.out.domains = &domains;
1278 t.out.resume_handle = &resume_handle;
1280 status = dcerpc_lsa_EnumTrustDom(p2, mem_ctx, &t);
1282 if ((!NT_STATUS_IS_OK(status) &&
1283 (!NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)))) {
1284 printf("Could not list domains\n");
1288 dcerpc_pipe_close(p2);
1290 d.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s",
1291 dcerpc_server_name(p));
1293 for (i=0; i<domains.count * 4; i++) {
1294 struct lsa_DomainInformation *info =
1295 &domains.domains[rand()%domains.count];
1297 d.in.domainname = info->name.string;
1299 status = dcerpc_netr_GetAnyDCName(p, mem_ctx, &d);
1300 if (!NT_STATUS_IS_OK(status)) {
1301 printf("GetAnyDCName - %s\n", nt_errstr(status));
1305 printf("\tDC for domain %s is %s\n", info->name.string,
1306 d.out.dcname ? d.out.dcname : "unknown");
1313 BOOL torture_rpc_netlogon(void)
1316 struct dcerpc_pipe *p;
1317 TALLOC_CTX *mem_ctx;
1319 struct test_join *join_ctx;
1321 mem_ctx = talloc_init("torture_rpc_netlogon");
1323 join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), ACB_SVRTRUST,
1326 printf("Failed to join as BDC\n");
1330 status = torture_rpc_connection(&p,
1331 DCERPC_NETLOGON_NAME,
1332 DCERPC_NETLOGON_UUID,
1333 DCERPC_NETLOGON_VERSION);
1334 if (!NT_STATUS_IS_OK(status)) {
1338 ret &= test_LogonUasLogon(p, mem_ctx);
1339 ret &= test_LogonUasLogoff(p, mem_ctx);
1340 ret &= test_SamLogon(p, mem_ctx);
1341 ret &= test_SetPassword(p, mem_ctx);
1342 ret &= test_SetPassword2(p, mem_ctx);
1343 ret &= test_GetDomainInfo(p, mem_ctx);
1344 ret &= test_DatabaseSync(p, mem_ctx);
1345 ret &= test_DatabaseDeltas(p, mem_ctx);
1346 ret &= test_AccountDeltas(p, mem_ctx);
1347 ret &= test_AccountSync(p, mem_ctx);
1348 ret &= test_GetDcName(p, mem_ctx);
1349 ret &= test_ManyGetDCName(p, mem_ctx);
1350 ret &= test_LogonControl(p, mem_ctx);
1351 ret &= test_GetAnyDCName(p, mem_ctx);
1352 ret &= test_LogonControl2(p, mem_ctx);
1353 ret &= test_DatabaseSync2(p, mem_ctx);
1354 ret &= test_LogonControl2Ex(p, mem_ctx);
1355 ret &= test_DsrEnumerateDomainTrusts(p, mem_ctx);
1356 ret &= test_GetDomainInfo_async(p, mem_ctx);
1357 ret &= test_netr_DrsGetDCNameEx2(p, mem_ctx);
1359 talloc_free(mem_ctx);
1361 torture_rpc_close(p);
1363 torture_leave_domain(join_ctx);