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;
1097 r.in.unknown1 = 512;
1099 r.in.credential = &a;
1100 r.out.credential = &a;
1105 r.in.query.query1 = &q1;
1108 /* this should really be the fully qualified name */
1109 q1.workstation_domain = TEST_MACHINE_NAME;
1110 q1.workstation_site = "Default-First-Site-Name";
1111 q1.blob2.length = 0;
1113 q1.blob2.data = NULL;
1114 q1.product.string = "product string";
1116 printf("Testing netr_LogonGetDomainInfo\n");
1118 status = dcerpc_netr_LogonGetDomainInfo(p, mem_ctx, &r);
1119 if (!NT_STATUS_IS_OK(status)) {
1120 printf("netr_LogonGetDomainInfo - %s\n", nt_errstr(status));
1124 if (!creds_client_check(&creds, &a.cred)) {
1125 printf("Credential chaining failed\n");
1133 static void async_callback(struct rpc_request *req)
1135 int *counter = req->async.private;
1136 if (NT_STATUS_IS_OK(req->status)) {
1141 static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1144 struct netr_LogonGetDomainInfo r;
1145 struct netr_DomainQuery1 q1;
1146 struct netr_Authenticator a;
1147 #define ASYNC_COUNT 100
1148 struct creds_CredentialState creds;
1149 struct creds_CredentialState creds_async[ASYNC_COUNT];
1150 struct rpc_request *req[ASYNC_COUNT];
1152 int *async_counter = talloc(mem_ctx, int);
1154 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
1155 printf("test_GetDomainInfo_async disabled - enable dangerous tests to use\n");
1159 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
1160 TEST_MACHINE_NAME, machine_password, &creds)) {
1165 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1166 r.in.computer_name = TEST_MACHINE_NAME;
1167 r.in.unknown1 = 512;
1169 r.in.credential = &a;
1170 r.out.credential = &a;
1175 r.in.query.query1 = &q1;
1178 /* this should really be the fully qualified name */
1179 q1.workstation_domain = TEST_MACHINE_NAME;
1180 q1.workstation_site = "Default-First-Site-Name";
1181 q1.blob2.length = 0;
1183 q1.blob2.data = NULL;
1184 q1.product.string = "product string";
1186 printf("Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
1190 for (i=0;i<ASYNC_COUNT;i++) {
1191 creds_client_authenticator(&creds, &a);
1193 creds_async[i] = creds;
1194 req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, mem_ctx, &r);
1196 req[i]->async.callback = async_callback;
1197 req[i]->async.private = async_counter;
1199 /* even with this flush per request a w2k3 server seems to
1200 clag with multiple outstanding requests. bleergh. */
1201 if (event_loop_once(dcerpc_event_context(p)) != 0) {
1206 for (i=0;i<ASYNC_COUNT;i++) {
1207 status = dcerpc_ndr_request_recv(req[i]);
1208 if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(r.out.result)) {
1209 printf("netr_LogonGetDomainInfo_async(%d) - %s/%s\n",
1210 i, nt_errstr(status), nt_errstr(r.out.result));
1214 if (!creds_client_check(&creds_async[i], &a.cred)) {
1215 printf("Credential chaining failed at async %d\n", i);
1220 printf("Testing netr_LogonGetDomainInfo - async count %d OK\n", *async_counter);
1222 return (*async_counter) == ASYNC_COUNT;
1225 static BOOL test_ManyGetDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1228 struct dcerpc_pipe *p2;
1229 struct lsa_ObjectAttribute attr;
1230 struct lsa_QosInfo qos;
1231 struct lsa_OpenPolicy2 o;
1232 struct policy_handle lsa_handle;
1233 struct lsa_DomainList domains;
1235 struct lsa_EnumTrustDom t;
1236 uint32_t resume_handle = 0;
1237 struct netr_GetAnyDCName d;
1242 if (p->conn->transport.transport != NCACN_NP) {
1246 printf("Torturing GetDCName\n");
1248 status = dcerpc_secondary_connection(p, &p2,
1251 DCERPC_LSARPC_VERSION);
1252 if (!NT_STATUS_IS_OK(status)) {
1253 printf("Failed to create secondary connection\n");
1258 qos.impersonation_level = 2;
1259 qos.context_mode = 1;
1260 qos.effective_only = 0;
1263 attr.root_dir = NULL;
1264 attr.object_name = NULL;
1265 attr.attributes = 0;
1266 attr.sec_desc = NULL;
1267 attr.sec_qos = &qos;
1269 o.in.system_name = "\\";
1271 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1272 o.out.handle = &lsa_handle;
1274 status = dcerpc_lsa_OpenPolicy2(p2, mem_ctx, &o);
1275 if (!NT_STATUS_IS_OK(status)) {
1276 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
1280 t.in.handle = &lsa_handle;
1281 t.in.resume_handle = &resume_handle;
1282 t.in.max_size = 1000;
1283 t.out.domains = &domains;
1284 t.out.resume_handle = &resume_handle;
1286 status = dcerpc_lsa_EnumTrustDom(p2, mem_ctx, &t);
1288 if ((!NT_STATUS_IS_OK(status) &&
1289 (!NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)))) {
1290 printf("Could not list domains\n");
1294 dcerpc_pipe_close(p2);
1296 d.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s",
1297 dcerpc_server_name(p));
1299 for (i=0; i<domains.count * 4; i++) {
1300 struct lsa_DomainInformation *info =
1301 &domains.domains[rand()%domains.count];
1303 d.in.domainname = info->name.string;
1305 status = dcerpc_netr_GetAnyDCName(p, mem_ctx, &d);
1306 if (!NT_STATUS_IS_OK(status)) {
1307 printf("GetAnyDCName - %s\n", nt_errstr(status));
1311 printf("\tDC for domain %s is %s\n", info->name.string,
1312 d.out.dcname ? d.out.dcname : "unknown");
1319 BOOL torture_rpc_netlogon(void)
1322 struct dcerpc_pipe *p;
1323 TALLOC_CTX *mem_ctx;
1325 struct test_join *join_ctx;
1327 mem_ctx = talloc_init("torture_rpc_netlogon");
1329 join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), ACB_SVRTRUST,
1332 printf("Failed to join as BDC\n");
1336 status = torture_rpc_connection(&p,
1337 DCERPC_NETLOGON_NAME,
1338 DCERPC_NETLOGON_UUID,
1339 DCERPC_NETLOGON_VERSION);
1340 if (!NT_STATUS_IS_OK(status)) {
1344 ret &= test_LogonUasLogon(p, mem_ctx);
1345 ret &= test_LogonUasLogoff(p, mem_ctx);
1346 ret &= test_SamLogon(p, mem_ctx);
1347 ret &= test_SetPassword(p, mem_ctx);
1348 ret &= test_SetPassword2(p, mem_ctx);
1349 ret &= test_GetDomainInfo(p, mem_ctx);
1350 ret &= test_DatabaseSync(p, mem_ctx);
1351 ret &= test_DatabaseDeltas(p, mem_ctx);
1352 ret &= test_AccountDeltas(p, mem_ctx);
1353 ret &= test_AccountSync(p, mem_ctx);
1354 ret &= test_GetDcName(p, mem_ctx);
1355 ret &= test_ManyGetDCName(p, mem_ctx);
1356 ret &= test_LogonControl(p, mem_ctx);
1357 ret &= test_GetAnyDCName(p, mem_ctx);
1358 ret &= test_LogonControl2(p, mem_ctx);
1359 ret &= test_DatabaseSync2(p, mem_ctx);
1360 ret &= test_LogonControl2Ex(p, mem_ctx);
1361 ret &= test_DsrEnumerateDomainTrusts(p, mem_ctx);
1362 ret &= test_GetDomainInfo_async(p, mem_ctx);
1363 ret &= test_netr_DrsGetDCNameEx2(p, mem_ctx);
1365 talloc_free(mem_ctx);
1367 torture_rpc_close(p);
1369 torture_leave_domain(join_ctx);