2 Unix SMB/CIFS implementation.
4 test suite for netlogon rpc operations
6 Copyright (C) Andrew Tridgell 2003
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2004
8 Copyright (C) Tim Potter 2003
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include "lib/events/events.h"
27 #include "librpc/gen_ndr/ndr_netlogon.h"
28 #include "auth/auth.h"
29 #include "lib/cmdline/popt_common.h"
31 static const char *machine_password;
33 #define TEST_MACHINE_NAME "torturetest"
35 static BOOL test_LogonUasLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
38 struct netr_LogonUasLogon r;
40 r.in.server_name = NULL;
41 r.in.account_name = cli_credentials_get_username(cmdline_credentials, mem_ctx);
42 r.in.workstation = TEST_MACHINE_NAME;
44 printf("Testing LogonUasLogon\n");
46 status = dcerpc_netr_LogonUasLogon(p, mem_ctx, &r);
47 if (!NT_STATUS_IS_OK(status)) {
48 printf("LogonUasLogon - %s\n", nt_errstr(status));
56 static BOOL test_LogonUasLogoff(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
59 struct netr_LogonUasLogoff r;
61 r.in.server_name = NULL;
62 r.in.account_name = cli_credentials_get_username(cmdline_credentials, mem_ctx);
63 r.in.workstation = TEST_MACHINE_NAME;
65 printf("Testing LogonUasLogoff\n");
67 status = dcerpc_netr_LogonUasLogoff(p, mem_ctx, &r);
68 if (!NT_STATUS_IS_OK(status)) {
69 printf("LogonUasLogoff - %s\n", nt_errstr(status));
77 static BOOL test_SetupCredentials(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
78 const char *machine_name,
79 const char *plain_pass,
80 struct creds_CredentialState **creds_out)
83 struct netr_ServerReqChallenge r;
84 struct netr_ServerAuthenticate a;
85 struct netr_Credential credentials1, credentials2, credentials3;
86 struct creds_CredentialState *creds;
87 struct samr_Password mach_password;
89 printf("Testing ServerReqChallenge\n");
91 creds = talloc(mem_ctx, struct creds_CredentialState);
96 r.in.server_name = NULL;
97 r.in.computer_name = machine_name;
98 r.in.credentials = &credentials1;
99 r.out.credentials = &credentials2;
101 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
103 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
104 if (!NT_STATUS_IS_OK(status)) {
105 printf("ServerReqChallenge - %s\n", nt_errstr(status));
109 E_md4hash(plain_pass, mach_password.hash);
111 a.in.server_name = NULL;
112 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", machine_name);
113 a.in.secure_channel_type = SEC_CHAN_BDC;
114 a.in.computer_name = machine_name;
115 a.in.credentials = &credentials3;
116 a.out.credentials = &credentials3;
118 creds_client_init(creds, &credentials1, &credentials2,
119 &mach_password, &credentials3,
122 printf("Testing ServerAuthenticate\n");
124 status = dcerpc_netr_ServerAuthenticate(p, mem_ctx, &a);
125 if (!NT_STATUS_IS_OK(status)) {
126 printf("ServerAuthenticate - %s\n", nt_errstr(status));
130 if (!creds_client_check(creds, &credentials3)) {
131 printf("Credential chaining failed\n");
139 static BOOL test_SetupCredentials2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
140 uint32_t negotiate_flags,
141 const char *machine_name,
142 const char *plain_pass,
144 struct creds_CredentialState **creds_out)
147 struct netr_ServerReqChallenge r;
148 struct netr_ServerAuthenticate2 a;
149 struct netr_Credential credentials1, credentials2, credentials3;
150 struct creds_CredentialState *creds;
151 struct samr_Password mach_password;
153 printf("Testing ServerReqChallenge\n");
155 creds = talloc(mem_ctx, struct creds_CredentialState);
160 r.in.server_name = NULL;
161 r.in.computer_name = machine_name;
162 r.in.credentials = &credentials1;
163 r.out.credentials = &credentials2;
165 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
167 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
168 if (!NT_STATUS_IS_OK(status)) {
169 printf("ServerReqChallenge - %s\n", nt_errstr(status));
173 E_md4hash(plain_pass, mach_password.hash);
175 a.in.server_name = NULL;
176 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", machine_name);
177 a.in.secure_channel_type = sec_chan_type;
178 a.in.computer_name = machine_name;
179 a.in.negotiate_flags = &negotiate_flags;
180 a.out.negotiate_flags = &negotiate_flags;
181 a.in.credentials = &credentials3;
182 a.out.credentials = &credentials3;
184 creds_client_init(creds, &credentials1, &credentials2,
185 &mach_password, &credentials3,
188 printf("Testing ServerAuthenticate2\n");
190 status = dcerpc_netr_ServerAuthenticate2(p, mem_ctx, &a);
191 if (!NT_STATUS_IS_OK(status)) {
192 printf("ServerAuthenticate2 - %s\n", nt_errstr(status));
196 if (!creds_client_check(creds, &credentials3)) {
197 printf("Credential chaining failed\n");
201 printf("negotiate_flags=0x%08x\n", negotiate_flags);
208 static BOOL test_SetupCredentials3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
209 uint32_t negotiate_flags,
210 const char *machine_name,
211 const char *plain_pass,
212 struct creds_CredentialState **creds_out)
215 struct netr_ServerReqChallenge r;
216 struct netr_ServerAuthenticate3 a;
217 struct netr_Credential credentials1, credentials2, credentials3;
218 struct creds_CredentialState *creds;
219 struct samr_Password mach_password;
222 printf("Testing ServerReqChallenge\n");
224 creds = talloc(mem_ctx, struct creds_CredentialState);
229 r.in.server_name = NULL;
230 r.in.computer_name = machine_name;
231 r.in.credentials = &credentials1;
232 r.out.credentials = &credentials2;
234 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
236 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
237 if (!NT_STATUS_IS_OK(status)) {
238 printf("ServerReqChallenge - %s\n", nt_errstr(status));
242 E_md4hash(plain_pass, mach_password.hash);
244 a.in.server_name = NULL;
245 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", machine_name);
246 a.in.secure_channel_type = SEC_CHAN_BDC;
247 a.in.computer_name = machine_name;
248 a.in.negotiate_flags = &negotiate_flags;
249 a.in.credentials = &credentials3;
250 a.out.credentials = &credentials3;
251 a.out.negotiate_flags = &negotiate_flags;
254 creds_client_init(creds, &credentials1, &credentials2,
255 &mach_password, &credentials3,
258 printf("Testing ServerAuthenticate3\n");
260 status = dcerpc_netr_ServerAuthenticate3(p, mem_ctx, &a);
261 if (!NT_STATUS_IS_OK(status)) {
262 printf("ServerAuthenticate3 - %s\n", nt_errstr(status));
266 if (!creds_client_check(creds, &credentials3)) {
267 printf("Credential chaining failed\n");
271 printf("negotiate_flags=0x%08x\n", negotiate_flags);
278 try a change password for our machine account
280 static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
283 struct netr_ServerPasswordSet r;
284 const char *password;
285 struct creds_CredentialState *creds;
287 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME,
288 machine_password, &creds)) {
292 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
293 r.in.account_name = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
294 r.in.secure_channel_type = SEC_CHAN_BDC;
295 r.in.computer_name = TEST_MACHINE_NAME;
297 password = generate_random_str(mem_ctx, 8);
298 E_md4hash(password, r.in.new_password.hash);
300 creds_des_encrypt(creds, &r.in.new_password);
302 printf("Testing ServerPasswordSet on machine account\n");
303 printf("Changing machine account password to '%s'\n", password);
305 creds_client_authenticator(creds, &r.in.credential);
307 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
308 if (!NT_STATUS_IS_OK(status)) {
309 printf("ServerPasswordSet - %s\n", nt_errstr(status));
313 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
314 printf("Credential chaining failed\n");
317 /* by changing the machine password twice we test the
318 credentials chaining fully, and we verify that the server
319 allows the password to be set to the same value twice in a
320 row (match win2k3) */
321 printf("Testing a second ServerPasswordSet on machine account\n");
322 printf("Changing machine account password to '%s' (same as previous run)\n", password);
324 creds_client_authenticator(creds, &r.in.credential);
326 status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
327 if (!NT_STATUS_IS_OK(status)) {
328 printf("ServerPasswordSet (2) - %s\n", nt_errstr(status));
332 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
333 printf("Credential chaining failed\n");
336 machine_password = password;
338 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
339 printf("ServerPasswordSet failed to actually change the password\n");
347 try a change password for our machine account
349 static BOOL test_SetPassword2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
352 struct netr_ServerPasswordSet2 r;
353 const char *password;
354 struct creds_CredentialState *creds;
355 struct samr_CryptPassword password_buf;
357 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME,
358 machine_password, &creds)) {
362 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
363 r.in.account_name = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
364 r.in.secure_channel_type = SEC_CHAN_BDC;
365 r.in.computer_name = TEST_MACHINE_NAME;
367 password = generate_random_str(mem_ctx, 8);
368 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
369 creds_arcfour_crypt(creds, password_buf.data, 516);
371 memcpy(r.in.new_password.data, password_buf.data, 512);
372 r.in.new_password.length = IVAL(password_buf.data, 512);
374 printf("Testing ServerPasswordSet2 on machine account\n");
375 printf("Changing machine account password to '%s'\n", password);
377 creds_client_authenticator(creds, &r.in.credential);
379 status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
380 if (!NT_STATUS_IS_OK(status)) {
381 printf("ServerPasswordSet2 - %s\n", nt_errstr(status));
385 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
386 printf("Credential chaining failed\n");
389 machine_password = password;
391 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
392 printf("Not testing ability to set password to '', enable dangerous tests to perform this test\n");
394 /* by changing the machine password to ""
395 * we check if the server uses password restrictions
396 * for ServerPasswordSet2
397 * (win2k3 accepts "")
400 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
401 creds_arcfour_crypt(creds, password_buf.data, 516);
403 memcpy(r.in.new_password.data, password_buf.data, 512);
404 r.in.new_password.length = IVAL(password_buf.data, 512);
406 printf("Testing ServerPasswordSet2 on machine account\n");
407 printf("Changing machine account password to '%s'\n", password);
409 creds_client_authenticator(creds, &r.in.credential);
411 status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
412 if (!NT_STATUS_IS_OK(status)) {
413 printf("ServerPasswordSet2 - %s\n", nt_errstr(status));
417 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
418 printf("Credential chaining failed\n");
421 machine_password = password;
424 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
425 printf("ServerPasswordSet failed to actually change the password\n");
429 /* now try a random password */
430 password = generate_random_str(mem_ctx, 8);
431 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
432 creds_arcfour_crypt(creds, password_buf.data, 516);
434 memcpy(r.in.new_password.data, password_buf.data, 512);
435 r.in.new_password.length = IVAL(password_buf.data, 512);
437 printf("Testing second ServerPasswordSet2 on machine account\n");
438 printf("Changing machine account password to '%s'\n", password);
440 creds_client_authenticator(creds, &r.in.credential);
442 status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
443 if (!NT_STATUS_IS_OK(status)) {
444 printf("ServerPasswordSet2 (2) - %s\n", nt_errstr(status));
448 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
449 printf("Credential chaining failed\n");
452 /* by changing the machine password twice we test the
453 credentials chaining fully, and we verify that the server
454 allows the password to be set to the same value twice in a
455 row (match win2k3) */
456 printf("Testing a second ServerPasswordSet2 on machine account\n");
457 printf("Changing machine account password to '%s' (same as previous run)\n", password);
459 creds_client_authenticator(creds, &r.in.credential);
461 status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
462 if (!NT_STATUS_IS_OK(status)) {
463 printf("ServerPasswordSet (3) - %s\n", nt_errstr(status));
467 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
468 printf("Credential chaining failed\n");
471 machine_password = password;
473 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
474 printf("ServerPasswordSet failed to actually change the password\n");
482 try a netlogon SamLogon
484 static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
487 struct netr_LogonSamLogon r;
488 struct netr_Authenticator auth, auth2;
489 struct netr_NetworkInfo ninfo;
490 const char *username = cli_credentials_get_username(cmdline_credentials, mem_ctx);
491 const char *password = cli_credentials_get_password(cmdline_credentials);
492 struct creds_CredentialState *creds;
497 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME,
498 machine_password, &creds)) {
502 ninfo.identity_info.domain_name.string = cli_credentials_get_domain(cmdline_credentials);
503 ninfo.identity_info.parameter_control = 0;
504 ninfo.identity_info.logon_id_low = 0;
505 ninfo.identity_info.logon_id_high = 0;
506 ninfo.identity_info.account_name.string = username;
507 ninfo.identity_info.workstation.string = TEST_MACHINE_NAME;
508 generate_random_buffer(ninfo.challenge,
509 sizeof(ninfo.challenge));
510 ninfo.nt.length = 24;
511 ninfo.nt.data = talloc_size(mem_ctx, 24);
512 SMBNTencrypt(password, ninfo.challenge, ninfo.nt.data);
513 ninfo.lm.length = 24;
514 ninfo.lm.data = talloc_size(mem_ctx, 24);
515 SMBencrypt(password, ninfo.challenge, ninfo.lm.data);
517 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
518 r.in.workstation = TEST_MACHINE_NAME;
519 r.in.credential = &auth;
520 r.in.return_authenticator = &auth2;
521 r.in.logon_level = 2;
522 r.in.logon.network = &ninfo;
526 creds_client_authenticator(creds, &auth);
528 r.in.validation_level = i;
530 printf("Testing SamLogon with validation level %d\n", i);
532 status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r);
533 if (!NT_STATUS_IS_OK(status)) {
534 printf("LogonSamLogon - %s\n", nt_errstr(status));
538 if (!creds_client_check(creds, &r.out.return_authenticator->cred)) {
539 printf("Credential chaining failed\n");
543 r.in.credential = NULL;
547 r.in.validation_level = i;
549 printf("Testing SamLogon with validation level %d\n", i);
551 status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r);
552 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
553 printf("LogonSamLogon expected INVALID_PARAMETER, got: %s\n", nt_errstr(status));
562 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
563 static uint64_t sequence_nums[3];
566 try a netlogon DatabaseSync
568 static BOOL test_DatabaseSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
571 struct netr_DatabaseSync r;
572 struct creds_CredentialState *creds;
573 const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
577 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
581 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
582 r.in.computername = TEST_MACHINE_NAME;
583 r.in.preferredmaximumlength = (uint32_t)-1;
584 ZERO_STRUCT(r.in.return_authenticator);
586 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
587 r.in.sync_context = 0;
588 r.in.database_id = database_ids[i];
590 printf("Testing DatabaseSync of id %d\n", r.in.database_id);
593 creds_client_authenticator(creds, &r.in.credential);
595 status = dcerpc_netr_DatabaseSync(p, mem_ctx, &r);
596 if (!NT_STATUS_IS_OK(status) &&
597 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
598 printf("DatabaseSync - %s\n", nt_errstr(status));
603 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
604 printf("Credential chaining failed\n");
607 r.in.sync_context = r.out.sync_context;
609 if (r.out.delta_enum_array &&
610 r.out.delta_enum_array->num_deltas > 0 &&
611 r.out.delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
612 r.out.delta_enum_array->delta_enum[0].delta_union.domain) {
613 sequence_nums[r.in.database_id] =
614 r.out.delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
615 printf("\tsequence_nums[%d]=%llu\n",
617 sequence_nums[r.in.database_id]);
619 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
627 try a netlogon DatabaseDeltas
629 static BOOL test_DatabaseDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
632 struct netr_DatabaseDeltas r;
633 struct creds_CredentialState *creds;
634 const uint32_t database_ids[] = {0, 1, 2};
638 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
642 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
643 r.in.computername = TEST_MACHINE_NAME;
644 r.in.preferredmaximumlength = (uint32_t)-1;
645 ZERO_STRUCT(r.in.return_authenticator);
647 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
648 r.in.database_id = database_ids[i];
649 r.in.sequence_num = sequence_nums[r.in.database_id];
651 if (r.in.sequence_num == 0) continue;
653 r.in.sequence_num -= 1;
656 printf("Testing DatabaseDeltas of id %d at %llu\n",
657 r.in.database_id, r.in.sequence_num);
660 creds_client_authenticator(creds, &r.in.credential);
662 status = dcerpc_netr_DatabaseDeltas(p, mem_ctx, &r);
663 if (!NT_STATUS_IS_OK(status) &&
664 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
665 printf("DatabaseDeltas - %s\n", nt_errstr(status));
670 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
671 printf("Credential chaining failed\n");
675 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
683 try a netlogon AccountDeltas
685 static BOOL test_AccountDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
688 struct netr_AccountDeltas r;
689 struct creds_CredentialState *creds;
692 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
696 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
697 r.in.computername = TEST_MACHINE_NAME;
698 ZERO_STRUCT(r.in.return_authenticator);
699 creds_client_authenticator(creds, &r.in.credential);
700 ZERO_STRUCT(r.in.uas);
705 printf("Testing AccountDeltas\n");
707 /* w2k3 returns "NOT IMPLEMENTED" for this call */
708 status = dcerpc_netr_AccountDeltas(p, mem_ctx, &r);
709 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
710 printf("AccountDeltas - %s\n", nt_errstr(status));
718 try a netlogon AccountSync
720 static BOOL test_AccountSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
723 struct netr_AccountSync r;
724 struct creds_CredentialState *creds;
727 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
731 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
732 r.in.computername = TEST_MACHINE_NAME;
733 ZERO_STRUCT(r.in.return_authenticator);
734 creds_client_authenticator(creds, &r.in.credential);
735 ZERO_STRUCT(r.in.recordid);
740 printf("Testing AccountSync\n");
742 /* w2k3 returns "NOT IMPLEMENTED" for this call */
743 status = dcerpc_netr_AccountSync(p, mem_ctx, &r);
744 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
745 printf("AccountSync - %s\n", nt_errstr(status));
753 try a netlogon GetDcName
755 static BOOL test_GetDcName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
758 struct netr_GetDcName r;
760 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
761 r.in.domainname = lp_workgroup();
763 printf("Testing GetDcName\n");
765 status = dcerpc_netr_GetDcName(p, mem_ctx, &r);
766 if (!NT_STATUS_IS_OK(status)) {
767 printf("GetDcName - %s\n", nt_errstr(status));
771 printf("\tDC is at '%s'\n", r.out.dcname);
777 try a netlogon LogonControl
779 static BOOL test_LogonControl(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
782 struct netr_LogonControl r;
786 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
787 r.in.function_code = 1;
792 printf("Testing LogonControl level %d\n", i);
794 status = dcerpc_netr_LogonControl(p, mem_ctx, &r);
795 if (!NT_STATUS_IS_OK(status)) {
796 printf("LogonControl - %s\n", nt_errstr(status));
806 try a netlogon GetAnyDCName
808 static BOOL test_GetAnyDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
811 struct netr_GetAnyDCName r;
813 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
814 r.in.domainname = lp_workgroup();
816 printf("Testing GetAnyDCName\n");
818 status = dcerpc_netr_GetAnyDCName(p, mem_ctx, &r);
819 if (!NT_STATUS_IS_OK(status)) {
820 printf("GetAnyDCName - %s\n", nt_errstr(status));
825 printf("\tDC is at '%s'\n", r.out.dcname);
833 try a netlogon LogonControl2
835 static BOOL test_LogonControl2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
838 struct netr_LogonControl2 r;
842 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
844 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
845 r.in.data.domain = lp_workgroup();
850 printf("Testing LogonControl2 level %d function %d\n",
851 i, r.in.function_code);
853 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
854 if (!NT_STATUS_IS_OK(status)) {
855 printf("LogonControl - %s\n", nt_errstr(status));
860 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
861 r.in.data.domain = lp_workgroup();
866 printf("Testing LogonControl2 level %d function %d\n",
867 i, r.in.function_code);
869 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
870 if (!NT_STATUS_IS_OK(status)) {
871 printf("LogonControl - %s\n", nt_errstr(status));
876 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
877 r.in.data.domain = lp_workgroup();
882 printf("Testing LogonControl2 level %d function %d\n",
883 i, r.in.function_code);
885 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
886 if (!NT_STATUS_IS_OK(status)) {
887 printf("LogonControl - %s\n", nt_errstr(status));
892 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
893 r.in.data.debug_level = ~0;
898 printf("Testing LogonControl2 level %d function %d\n",
899 i, r.in.function_code);
901 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
902 if (!NT_STATUS_IS_OK(status)) {
903 printf("LogonControl - %s\n", nt_errstr(status));
912 try a netlogon DatabaseSync2
914 static BOOL test_DatabaseSync2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
917 struct netr_DatabaseSync2 r;
918 struct creds_CredentialState *creds;
919 const uint32_t database_ids[] = {0, 1, 2};
923 if (!test_SetupCredentials2(p, mem_ctx, NETLOGON_NEG_AUTH2_FLAGS,
924 TEST_MACHINE_NAME, machine_password,
925 SEC_CHAN_BDC, &creds)) {
929 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
930 r.in.computername = TEST_MACHINE_NAME;
931 r.in.preferredmaximumlength = (uint32_t)-1;
932 ZERO_STRUCT(r.in.return_authenticator);
934 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
935 r.in.sync_context = 0;
936 r.in.database_id = database_ids[i];
937 r.in.restart_state = 0;
939 printf("Testing DatabaseSync2 of id %d\n", r.in.database_id);
942 creds_client_authenticator(creds, &r.in.credential);
944 status = dcerpc_netr_DatabaseSync2(p, mem_ctx, &r);
945 if (!NT_STATUS_IS_OK(status) &&
946 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
947 printf("DatabaseSync2 - %s\n", nt_errstr(status));
952 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
953 printf("Credential chaining failed\n");
956 r.in.sync_context = r.out.sync_context;
957 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
965 try a netlogon LogonControl2Ex
967 static BOOL test_LogonControl2Ex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
970 struct netr_LogonControl2Ex r;
974 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
976 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
977 r.in.data.domain = lp_workgroup();
982 printf("Testing LogonControl2Ex level %d function %d\n",
983 i, r.in.function_code);
985 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
986 if (!NT_STATUS_IS_OK(status)) {
987 printf("LogonControl - %s\n", nt_errstr(status));
992 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
993 r.in.data.domain = lp_workgroup();
998 printf("Testing LogonControl2Ex level %d function %d\n",
999 i, r.in.function_code);
1001 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1002 if (!NT_STATUS_IS_OK(status)) {
1003 printf("LogonControl - %s\n", nt_errstr(status));
1008 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1009 r.in.data.domain = lp_workgroup();
1014 printf("Testing LogonControl2Ex level %d function %d\n",
1015 i, r.in.function_code);
1017 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1018 if (!NT_STATUS_IS_OK(status)) {
1019 printf("LogonControl - %s\n", nt_errstr(status));
1024 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1025 r.in.data.debug_level = ~0;
1030 printf("Testing LogonControl2Ex level %d function %d\n",
1031 i, r.in.function_code);
1033 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1034 if (!NT_STATUS_IS_OK(status)) {
1035 printf("LogonControl - %s\n", nt_errstr(status));
1045 try a netlogon netr_DsrEnumerateDomainTrusts
1047 static BOOL test_DsrEnumerateDomainTrusts(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1050 struct netr_DsrEnumerateDomainTrusts r;
1052 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1053 r.in.trust_flags = 0x3f;
1055 printf("Testing netr_DsrEnumerateDomainTrusts\n");
1057 status = dcerpc_netr_DsrEnumerateDomainTrusts(p, mem_ctx, &r);
1058 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1059 printf("netr_DsrEnumerateDomainTrusts - %s/%s\n",
1060 nt_errstr(status), win_errstr(r.out.result));
1068 try a netlogon netr_DrsGetDCNameEx2
1070 static BOOL test_netr_DrsGetDCNameEx2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1073 struct netr_DrsGetDCNameEx2 r;
1076 r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1077 r.in.client_account = NULL;
1078 r.in.mask = 0x00000000;
1079 r.in.domain_name = talloc_asprintf(mem_ctx, "%s", lp_realm());
1080 r.in.domain_guid = NULL;
1081 r.in.site_name = NULL;
1082 r.in.flags = 0x40000000;
1084 printf("Testing netr_DrsGetDCNameEx2 without client account\n");
1086 status = dcerpc_netr_DrsGetDCNameEx2(p, mem_ctx, &r);
1087 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1088 printf("netr_DrsGetDCNameEx2 - %s/%s\n",
1089 nt_errstr(status), win_errstr(r.out.result));
1093 printf("Testing netr_DrsGetDCNameEx2 with client acount\n");
1094 r.in.client_account = TEST_MACHINE_NAME"$";
1095 r.in.mask = 0x00002000;
1096 r.in.flags = 0x80000000;
1098 status = dcerpc_netr_DrsGetDCNameEx2(p, mem_ctx, &r);
1099 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1100 printf("netr_DrsGetDCNameEx2 - %s/%s\n",
1101 nt_errstr(status), win_errstr(r.out.result));
1108 static BOOL test_GetDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1111 struct netr_LogonGetDomainInfo r;
1112 struct netr_DomainQuery1 q1;
1113 struct netr_Authenticator a;
1114 struct creds_CredentialState *creds;
1116 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
1117 TEST_MACHINE_NAME, machine_password, &creds)) {
1123 creds_client_authenticator(creds, &a);
1125 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1126 r.in.computer_name = TEST_MACHINE_NAME;
1128 r.in.credential = &a;
1129 r.in.return_authenticator = &a;
1130 r.out.return_authenticator = &a;
1132 r.in.query.query1 = &q1;
1135 /* this should really be the fully qualified name */
1136 q1.workstation_domain = TEST_MACHINE_NAME;
1137 q1.workstation_site = "Default-First-Site-Name";
1138 q1.blob2.length = 0;
1140 q1.blob2.data = NULL;
1141 q1.product.string = "product string";
1143 printf("Testing netr_LogonGetDomainInfo\n");
1145 status = dcerpc_netr_LogonGetDomainInfo(p, mem_ctx, &r);
1146 if (!NT_STATUS_IS_OK(status)) {
1147 printf("netr_LogonGetDomainInfo - %s\n", nt_errstr(status));
1151 if (!creds_client_check(creds, &a.cred)) {
1152 printf("Credential chaining failed\n");
1160 static void async_callback(struct rpc_request *req)
1162 int *counter = req->async.private;
1163 if (NT_STATUS_IS_OK(req->status)) {
1168 static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1171 struct netr_LogonGetDomainInfo r;
1172 struct netr_DomainQuery1 q1;
1173 struct netr_Authenticator a;
1174 #define ASYNC_COUNT 100
1175 struct creds_CredentialState *creds;
1176 struct creds_CredentialState *creds_async[ASYNC_COUNT];
1177 struct rpc_request *req[ASYNC_COUNT];
1179 int *async_counter = talloc(mem_ctx, int);
1181 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
1182 printf("test_GetDomainInfo_async disabled - enable dangerous tests to use\n");
1186 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
1187 TEST_MACHINE_NAME, machine_password, &creds)) {
1192 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1193 r.in.computer_name = TEST_MACHINE_NAME;
1195 r.in.credential = &a;
1196 r.in.return_authenticator = &a;
1197 r.out.return_authenticator = &a;
1199 r.in.query.query1 = &q1;
1202 /* this should really be the fully qualified name */
1203 q1.workstation_domain = TEST_MACHINE_NAME;
1204 q1.workstation_site = "Default-First-Site-Name";
1205 q1.blob2.length = 0;
1207 q1.blob2.data = NULL;
1208 q1.product.string = "product string";
1210 printf("Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
1214 for (i=0;i<ASYNC_COUNT;i++) {
1215 creds_client_authenticator(creds, &a);
1217 creds_async[i] = talloc_memdup(creds, creds, sizeof(*creds));
1218 req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, mem_ctx, &r);
1220 req[i]->async.callback = async_callback;
1221 req[i]->async.private = async_counter;
1223 /* even with this flush per request a w2k3 server seems to
1224 clag with multiple outstanding requests. bleergh. */
1225 if (event_loop_once(dcerpc_event_context(p)) != 0) {
1230 for (i=0;i<ASYNC_COUNT;i++) {
1231 status = dcerpc_ndr_request_recv(req[i]);
1232 if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(r.out.result)) {
1233 printf("netr_LogonGetDomainInfo_async(%d) - %s/%s\n",
1234 i, nt_errstr(status), nt_errstr(r.out.result));
1238 if (!creds_client_check(creds_async[i], &a.cred)) {
1239 printf("Credential chaining failed at async %d\n", i);
1244 printf("Testing netr_LogonGetDomainInfo - async count %d OK\n", *async_counter);
1246 return (*async_counter) == ASYNC_COUNT;
1249 static BOOL test_ManyGetDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1252 struct dcerpc_binding *b;
1253 struct dcerpc_pipe *p2;
1254 struct lsa_ObjectAttribute attr;
1255 struct lsa_QosInfo qos;
1256 struct lsa_OpenPolicy2 o;
1257 struct policy_handle lsa_handle;
1258 struct lsa_DomainList domains;
1260 struct lsa_EnumTrustDom t;
1261 uint32_t resume_handle = 0;
1262 struct netr_GetAnyDCName d;
1267 if (p->conn->transport.transport != NCACN_NP) {
1271 printf("Torturing GetDCName\n");
1273 status = dcerpc_parse_binding(mem_ctx, p->conn->binding_string, &b);
1274 if (!NT_STATUS_IS_OK(status)) {
1275 printf("Failed to parse dcerpc binding '%s'\n", p->conn->binding_string);
1279 status = dcerpc_secondary_connection(p, &p2, b);
1280 if (!NT_STATUS_IS_OK(status)) {
1281 printf("Failed to create secondary connection\n");
1285 status = dcerpc_bind_auth_none(p2, DCERPC_LSARPC_UUID,
1286 DCERPC_LSARPC_VERSION);
1287 if (!NT_STATUS_IS_OK(status)) {
1288 printf("Failed to create bind on secondary connection\n");
1293 qos.impersonation_level = 2;
1294 qos.context_mode = 1;
1295 qos.effective_only = 0;
1298 attr.root_dir = NULL;
1299 attr.object_name = NULL;
1300 attr.attributes = 0;
1301 attr.sec_desc = NULL;
1302 attr.sec_qos = &qos;
1304 o.in.system_name = "\\";
1306 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1307 o.out.handle = &lsa_handle;
1309 status = dcerpc_lsa_OpenPolicy2(p2, mem_ctx, &o);
1310 if (!NT_STATUS_IS_OK(status)) {
1311 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
1315 t.in.handle = &lsa_handle;
1316 t.in.resume_handle = &resume_handle;
1317 t.in.max_size = 1000;
1318 t.out.domains = &domains;
1319 t.out.resume_handle = &resume_handle;
1321 status = dcerpc_lsa_EnumTrustDom(p2, mem_ctx, &t);
1323 if ((!NT_STATUS_IS_OK(status) &&
1324 (!NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)))) {
1325 printf("Could not list domains\n");
1331 d.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s",
1332 dcerpc_server_name(p));
1334 for (i=0; i<domains.count * 4; i++) {
1335 struct lsa_DomainInformation *info =
1336 &domains.domains[rand()%domains.count];
1338 d.in.domainname = info->name.string;
1340 status = dcerpc_netr_GetAnyDCName(p, mem_ctx, &d);
1341 if (!NT_STATUS_IS_OK(status)) {
1342 printf("GetAnyDCName - %s\n", nt_errstr(status));
1346 printf("\tDC for domain %s is %s\n", info->name.string,
1347 d.out.dcname ? d.out.dcname : "unknown");
1354 BOOL torture_rpc_netlogon(void)
1357 struct dcerpc_pipe *p;
1358 TALLOC_CTX *mem_ctx;
1360 struct test_join *join_ctx;
1362 mem_ctx = talloc_init("torture_rpc_netlogon");
1364 join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), ACB_SVRTRUST,
1367 talloc_free(mem_ctx);
1368 printf("Failed to join as BDC\n");
1372 status = torture_rpc_connection(mem_ctx, &p,
1373 DCERPC_NETLOGON_NAME,
1374 DCERPC_NETLOGON_UUID,
1375 DCERPC_NETLOGON_VERSION);
1376 if (!NT_STATUS_IS_OK(status)) {
1377 talloc_free(mem_ctx);
1381 ret &= test_LogonUasLogon(p, mem_ctx);
1382 ret &= test_LogonUasLogoff(p, mem_ctx);
1383 ret &= test_SamLogon(p, mem_ctx);
1384 ret &= test_SetPassword(p, mem_ctx);
1385 ret &= test_SetPassword2(p, mem_ctx);
1386 ret &= test_GetDomainInfo(p, mem_ctx);
1387 ret &= test_DatabaseSync(p, mem_ctx);
1388 ret &= test_DatabaseDeltas(p, mem_ctx);
1389 ret &= test_AccountDeltas(p, mem_ctx);
1390 ret &= test_AccountSync(p, mem_ctx);
1391 ret &= test_GetDcName(p, mem_ctx);
1392 ret &= test_ManyGetDCName(p, mem_ctx);
1393 ret &= test_LogonControl(p, mem_ctx);
1394 ret &= test_GetAnyDCName(p, mem_ctx);
1395 ret &= test_LogonControl2(p, mem_ctx);
1396 ret &= test_DatabaseSync2(p, mem_ctx);
1397 ret &= test_LogonControl2Ex(p, mem_ctx);
1398 ret &= test_DsrEnumerateDomainTrusts(p, mem_ctx);
1399 ret &= test_GetDomainInfo_async(p, mem_ctx);
1400 ret &= test_netr_DrsGetDCNameEx2(p, mem_ctx);
1402 talloc_free(mem_ctx);
1404 torture_leave_domain(join_ctx);