r14470: Remove some unnecessary headers.
[Samba.git] / source / torture / rpc / netlogon.c
blob14e7a49305a01e58f6f5a927a8787558ec45a788
1 /*
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.
25 #include "includes.h"
26 #include "torture/torture.h"
27 #include "lib/events/events.h"
28 #include "auth/auth.h"
29 #include "smb.h"
30 #include "lib/cmdline/popt_common.h"
31 #include "torture/rpc/rpc.h"
32 #include "libcli/auth/libcli_auth.h"
33 #include "librpc/gen_ndr/ndr_netlogon_c.h"
34 #include "librpc/gen_ndr/ndr_lsa_c.h"
36 static const char *machine_password;
38 #define TEST_MACHINE_NAME "torturetest"
40 static BOOL test_LogonUasLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
42 NTSTATUS status;
43 struct netr_LogonUasLogon r;
45 r.in.server_name = NULL;
46 r.in.account_name = cli_credentials_get_username(cmdline_credentials);
47 r.in.workstation = TEST_MACHINE_NAME;
49 printf("Testing LogonUasLogon\n");
51 status = dcerpc_netr_LogonUasLogon(p, mem_ctx, &r);
52 if (!NT_STATUS_IS_OK(status)) {
53 printf("LogonUasLogon - %s\n", nt_errstr(status));
54 return False;
57 return True;
61 static BOOL test_LogonUasLogoff(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
63 NTSTATUS status;
64 struct netr_LogonUasLogoff r;
66 r.in.server_name = NULL;
67 r.in.account_name = cli_credentials_get_username(cmdline_credentials);
68 r.in.workstation = TEST_MACHINE_NAME;
70 printf("Testing LogonUasLogoff\n");
72 status = dcerpc_netr_LogonUasLogoff(p, mem_ctx, &r);
73 if (!NT_STATUS_IS_OK(status)) {
74 printf("LogonUasLogoff - %s\n", nt_errstr(status));
75 return False;
78 return True;
82 static BOOL test_SetupCredentials(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
83 const char *machine_name,
84 const char *plain_pass,
85 struct creds_CredentialState **creds_out)
87 NTSTATUS status;
88 struct netr_ServerReqChallenge r;
89 struct netr_ServerAuthenticate a;
90 struct netr_Credential credentials1, credentials2, credentials3;
91 struct creds_CredentialState *creds;
92 struct samr_Password mach_password;
94 printf("Testing ServerReqChallenge\n");
96 creds = talloc(mem_ctx, struct creds_CredentialState);
97 if (!creds) {
98 return False;
101 r.in.server_name = NULL;
102 r.in.computer_name = machine_name;
103 r.in.credentials = &credentials1;
104 r.out.credentials = &credentials2;
106 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
108 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
109 if (!NT_STATUS_IS_OK(status)) {
110 printf("ServerReqChallenge - %s\n", nt_errstr(status));
111 return False;
114 E_md4hash(plain_pass, mach_password.hash);
116 a.in.server_name = NULL;
117 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", machine_name);
118 a.in.secure_channel_type = SEC_CHAN_BDC;
119 a.in.computer_name = machine_name;
120 a.in.credentials = &credentials3;
121 a.out.credentials = &credentials3;
123 creds_client_init(creds, &credentials1, &credentials2,
124 &mach_password, &credentials3,
127 printf("Testing ServerAuthenticate\n");
129 status = dcerpc_netr_ServerAuthenticate(p, mem_ctx, &a);
130 if (!NT_STATUS_IS_OK(status)) {
131 printf("ServerAuthenticate - %s\n", nt_errstr(status));
132 return False;
135 if (!creds_client_check(creds, &credentials3)) {
136 printf("Credential chaining failed\n");
137 return False;
140 *creds_out = creds;
141 return True;
144 static BOOL test_SetupCredentials2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
145 uint32_t negotiate_flags,
146 const char *machine_name,
147 const char *plain_pass,
148 int sec_chan_type,
149 struct creds_CredentialState **creds_out)
151 NTSTATUS status;
152 struct netr_ServerReqChallenge r;
153 struct netr_ServerAuthenticate2 a;
154 struct netr_Credential credentials1, credentials2, credentials3;
155 struct creds_CredentialState *creds;
156 struct samr_Password mach_password;
158 printf("Testing ServerReqChallenge\n");
160 creds = talloc(mem_ctx, struct creds_CredentialState);
161 if (!creds) {
162 return False;
165 r.in.server_name = NULL;
166 r.in.computer_name = machine_name;
167 r.in.credentials = &credentials1;
168 r.out.credentials = &credentials2;
170 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
172 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
173 if (!NT_STATUS_IS_OK(status)) {
174 printf("ServerReqChallenge - %s\n", nt_errstr(status));
175 return False;
178 E_md4hash(plain_pass, mach_password.hash);
180 a.in.server_name = NULL;
181 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", machine_name);
182 a.in.secure_channel_type = sec_chan_type;
183 a.in.computer_name = machine_name;
184 a.in.negotiate_flags = &negotiate_flags;
185 a.out.negotiate_flags = &negotiate_flags;
186 a.in.credentials = &credentials3;
187 a.out.credentials = &credentials3;
189 creds_client_init(creds, &credentials1, &credentials2,
190 &mach_password, &credentials3,
191 negotiate_flags);
193 printf("Testing ServerAuthenticate2\n");
195 status = dcerpc_netr_ServerAuthenticate2(p, mem_ctx, &a);
196 if (!NT_STATUS_IS_OK(status)) {
197 printf("ServerAuthenticate2 - %s\n", nt_errstr(status));
198 return False;
201 if (!creds_client_check(creds, &credentials3)) {
202 printf("Credential chaining failed\n");
203 return False;
206 printf("negotiate_flags=0x%08x\n", negotiate_flags);
208 *creds_out = creds;
209 return True;
213 static BOOL test_SetupCredentials3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
214 uint32_t negotiate_flags,
215 const char *machine_name,
216 const char *plain_pass,
217 struct creds_CredentialState **creds_out)
219 NTSTATUS status;
220 struct netr_ServerReqChallenge r;
221 struct netr_ServerAuthenticate3 a;
222 struct netr_Credential credentials1, credentials2, credentials3;
223 struct creds_CredentialState *creds;
224 struct samr_Password mach_password;
225 uint32_t rid;
227 printf("Testing ServerReqChallenge\n");
229 creds = talloc(mem_ctx, struct creds_CredentialState);
230 if (!creds) {
231 return False;
234 r.in.server_name = NULL;
235 r.in.computer_name = machine_name;
236 r.in.credentials = &credentials1;
237 r.out.credentials = &credentials2;
239 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
241 status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
242 if (!NT_STATUS_IS_OK(status)) {
243 printf("ServerReqChallenge - %s\n", nt_errstr(status));
244 return False;
247 E_md4hash(plain_pass, mach_password.hash);
249 a.in.server_name = NULL;
250 a.in.account_name = talloc_asprintf(mem_ctx, "%s$", machine_name);
251 a.in.secure_channel_type = SEC_CHAN_BDC;
252 a.in.computer_name = machine_name;
253 a.in.negotiate_flags = &negotiate_flags;
254 a.in.credentials = &credentials3;
255 a.out.credentials = &credentials3;
256 a.out.negotiate_flags = &negotiate_flags;
257 a.out.rid = &rid;
259 creds_client_init(creds, &credentials1, &credentials2,
260 &mach_password, &credentials3,
261 negotiate_flags);
263 printf("Testing ServerAuthenticate3\n");
265 status = dcerpc_netr_ServerAuthenticate3(p, mem_ctx, &a);
266 if (!NT_STATUS_IS_OK(status)) {
267 printf("ServerAuthenticate3 - %s\n", nt_errstr(status));
268 return False;
271 if (!creds_client_check(creds, &credentials3)) {
272 printf("Credential chaining failed\n");
273 return False;
276 printf("negotiate_flags=0x%08x\n", negotiate_flags);
278 *creds_out = creds;
279 return True;
283 try a change password for our machine account
285 static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
287 NTSTATUS status;
288 struct netr_ServerPasswordSet r;
289 const char *password;
290 struct creds_CredentialState *creds;
292 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME,
293 machine_password, &creds)) {
294 return False;
297 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
298 r.in.account_name = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
299 r.in.secure_channel_type = SEC_CHAN_BDC;
300 r.in.computer_name = TEST_MACHINE_NAME;
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));
315 return False;
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));
334 return False;
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");
345 return False;
348 return True;
352 try a change password for our machine account
354 static BOOL test_SetPassword2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
356 NTSTATUS status;
357 struct netr_ServerPasswordSet2 r;
358 const char *password;
359 struct creds_CredentialState *creds;
360 struct samr_CryptPassword password_buf;
362 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME,
363 machine_password, &creds)) {
364 return False;
367 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
368 r.in.account_name = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
369 r.in.secure_channel_type = SEC_CHAN_BDC;
370 r.in.computer_name = TEST_MACHINE_NAME;
372 password = generate_random_str(mem_ctx, 8);
373 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
374 creds_arcfour_crypt(creds, password_buf.data, 516);
376 memcpy(r.in.new_password.data, password_buf.data, 512);
377 r.in.new_password.length = IVAL(password_buf.data, 512);
379 printf("Testing ServerPasswordSet2 on machine account\n");
380 printf("Changing machine account password to '%s'\n", password);
382 creds_client_authenticator(creds, &r.in.credential);
384 status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
385 if (!NT_STATUS_IS_OK(status)) {
386 printf("ServerPasswordSet2 - %s\n", nt_errstr(status));
387 return False;
390 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
391 printf("Credential chaining failed\n");
394 machine_password = password;
396 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
397 printf("Not testing ability to set password to '', enable dangerous tests to perform this test\n");
398 } else {
399 /* by changing the machine password to ""
400 * we check if the server uses password restrictions
401 * for ServerPasswordSet2
402 * (win2k3 accepts "")
404 password = "";
405 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
406 creds_arcfour_crypt(creds, password_buf.data, 516);
408 memcpy(r.in.new_password.data, password_buf.data, 512);
409 r.in.new_password.length = IVAL(password_buf.data, 512);
411 printf("Testing ServerPasswordSet2 on machine account\n");
412 printf("Changing machine account password to '%s'\n", password);
414 creds_client_authenticator(creds, &r.in.credential);
416 status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
417 if (!NT_STATUS_IS_OK(status)) {
418 printf("ServerPasswordSet2 - %s\n", nt_errstr(status));
419 return False;
422 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
423 printf("Credential chaining failed\n");
426 machine_password = password;
429 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
430 printf("ServerPasswordSet failed to actually change the password\n");
431 return False;
434 /* now try a random password */
435 password = generate_random_str(mem_ctx, 8);
436 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
437 creds_arcfour_crypt(creds, password_buf.data, 516);
439 memcpy(r.in.new_password.data, password_buf.data, 512);
440 r.in.new_password.length = IVAL(password_buf.data, 512);
442 printf("Testing second ServerPasswordSet2 on machine account\n");
443 printf("Changing machine account password to '%s'\n", password);
445 creds_client_authenticator(creds, &r.in.credential);
447 status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
448 if (!NT_STATUS_IS_OK(status)) {
449 printf("ServerPasswordSet2 (2) - %s\n", nt_errstr(status));
450 return False;
453 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
454 printf("Credential chaining failed\n");
457 /* by changing the machine password twice we test the
458 credentials chaining fully, and we verify that the server
459 allows the password to be set to the same value twice in a
460 row (match win2k3) */
461 printf("Testing a second ServerPasswordSet2 on machine account\n");
462 printf("Changing machine account password to '%s' (same as previous run)\n", password);
464 creds_client_authenticator(creds, &r.in.credential);
466 status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
467 if (!NT_STATUS_IS_OK(status)) {
468 printf("ServerPasswordSet (3) - %s\n", nt_errstr(status));
469 return False;
472 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
473 printf("Credential chaining failed\n");
476 machine_password = password;
478 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
479 printf("ServerPasswordSet failed to actually change the password\n");
480 return False;
483 return True;
487 try a netlogon SamLogon
489 BOOL test_netlogon_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
490 struct cli_credentials *credentials,
491 struct creds_CredentialState *creds)
493 NTSTATUS status;
494 struct netr_LogonSamLogon r;
495 struct netr_Authenticator auth, auth2;
496 struct netr_NetworkInfo ninfo;
497 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
498 int i;
499 BOOL ret = True;
500 int flags = CLI_CRED_NTLM_AUTH;
501 if (lp_client_lanman_auth()) {
502 flags |= CLI_CRED_LANMAN_AUTH;
505 if (lp_client_ntlmv2_auth()) {
506 flags |= CLI_CRED_NTLMv2_AUTH;
509 cli_credentials_get_ntlm_username_domain(cmdline_credentials, mem_ctx,
510 &ninfo.identity_info.account_name.string,
511 &ninfo.identity_info.domain_name.string);
513 generate_random_buffer(ninfo.challenge,
514 sizeof(ninfo.challenge));
515 chal = data_blob_const(ninfo.challenge,
516 sizeof(ninfo.challenge));
518 names_blob = NTLMv2_generate_names_blob(mem_ctx, cli_credentials_get_workstation(credentials),
519 cli_credentials_get_domain(credentials));
521 status = cli_credentials_get_ntlm_response(cmdline_credentials, mem_ctx,
522 &flags,
523 chal,
524 names_blob,
525 &lm_resp, &nt_resp,
526 NULL, NULL);
527 if (!NT_STATUS_IS_OK(status)) {
528 printf("cli_credentials_get_ntlm_response failed: %s\n",
529 nt_errstr(status));
530 return False;
533 ninfo.lm.data = lm_resp.data;
534 ninfo.lm.length = lm_resp.length;
536 ninfo.nt.data = nt_resp.data;
537 ninfo.nt.length = nt_resp.length;
539 ninfo.identity_info.parameter_control = 0;
540 ninfo.identity_info.logon_id_low = 0;
541 ninfo.identity_info.logon_id_high = 0;
542 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
544 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
545 r.in.computer_name = cli_credentials_get_workstation(credentials);
546 r.in.credential = &auth;
547 r.in.return_authenticator = &auth2;
548 r.in.logon_level = 2;
549 r.in.logon.network = &ninfo;
551 printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
553 for (i=2;i<3;i++) {
554 ZERO_STRUCT(auth2);
555 creds_client_authenticator(creds, &auth);
557 r.in.validation_level = i;
559 status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r);
560 if (!NT_STATUS_IS_OK(status)) {
561 printf("LogonSamLogon failed: %s\n",
562 nt_errstr(status));
563 return False;
566 if (!creds_client_check(creds, &r.out.return_authenticator->cred)) {
567 printf("Credential chaining failed\n");
568 ret = False;
572 r.in.credential = NULL;
574 for (i=2;i<=3;i++) {
576 r.in.validation_level = i;
578 printf("Testing SamLogon with validation level %d and a NULL credential\n", i);
580 status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r);
581 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
582 printf("LogonSamLogon expected INVALID_PARAMETER, got: %s\n", nt_errstr(status));
583 ret = False;
589 return ret;
593 try a netlogon SamLogon
595 static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
596 struct cli_credentials *credentials)
598 struct creds_CredentialState *creds;
600 if (!test_SetupCredentials(p, mem_ctx, cli_credentials_get_workstation(credentials),
601 cli_credentials_get_password(credentials), &creds)) {
602 return False;
605 return test_netlogon_ops(p, mem_ctx, credentials, creds);
608 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
609 static uint64_t sequence_nums[3];
612 try a netlogon DatabaseSync
614 static BOOL test_DatabaseSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
616 NTSTATUS status;
617 struct netr_DatabaseSync r;
618 struct creds_CredentialState *creds;
619 const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
620 int i;
621 BOOL ret = True;
623 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
624 return False;
627 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
628 r.in.computername = TEST_MACHINE_NAME;
629 r.in.preferredmaximumlength = (uint32_t)-1;
630 ZERO_STRUCT(r.in.return_authenticator);
632 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
633 r.in.sync_context = 0;
634 r.in.database_id = database_ids[i];
636 printf("Testing DatabaseSync of id %d\n", r.in.database_id);
638 do {
639 creds_client_authenticator(creds, &r.in.credential);
641 status = dcerpc_netr_DatabaseSync(p, mem_ctx, &r);
642 if (!NT_STATUS_IS_OK(status) &&
643 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
644 printf("DatabaseSync - %s\n", nt_errstr(status));
645 ret = False;
646 break;
649 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
650 printf("Credential chaining failed\n");
653 r.in.sync_context = r.out.sync_context;
655 if (r.out.delta_enum_array &&
656 r.out.delta_enum_array->num_deltas > 0 &&
657 r.out.delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
658 r.out.delta_enum_array->delta_enum[0].delta_union.domain) {
659 sequence_nums[r.in.database_id] =
660 r.out.delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
661 printf("\tsequence_nums[%d]=%llu\n",
662 r.in.database_id,
663 (unsigned long long)sequence_nums[r.in.database_id]);
665 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
668 return ret;
673 try a netlogon DatabaseDeltas
675 static BOOL test_DatabaseDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
677 NTSTATUS status;
678 struct netr_DatabaseDeltas r;
679 struct creds_CredentialState *creds;
680 const uint32_t database_ids[] = {0, 1, 2};
681 int i;
682 BOOL ret = True;
684 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
685 return False;
688 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
689 r.in.computername = TEST_MACHINE_NAME;
690 r.in.preferredmaximumlength = (uint32_t)-1;
691 ZERO_STRUCT(r.in.return_authenticator);
693 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
694 r.in.database_id = database_ids[i];
695 r.in.sequence_num = sequence_nums[r.in.database_id];
697 if (r.in.sequence_num == 0) continue;
699 r.in.sequence_num -= 1;
702 printf("Testing DatabaseDeltas of id %d at %llu\n",
703 r.in.database_id, (unsigned long long)r.in.sequence_num);
705 do {
706 creds_client_authenticator(creds, &r.in.credential);
708 status = dcerpc_netr_DatabaseDeltas(p, mem_ctx, &r);
709 if (NT_STATUS_EQUAL(status,
710 NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
711 printf("no considering %s to be an error\n",
712 nt_errstr(status));
713 return True;
715 if (!NT_STATUS_IS_OK(status) &&
716 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
717 printf("DatabaseDeltas - %s\n", nt_errstr(status));
718 ret = False;
719 break;
722 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
723 printf("Credential chaining failed\n");
726 r.in.sequence_num++;
727 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
730 return ret;
735 try a netlogon AccountDeltas
737 static BOOL test_AccountDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
739 NTSTATUS status;
740 struct netr_AccountDeltas r;
741 struct creds_CredentialState *creds;
742 BOOL ret = True;
744 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
745 return False;
748 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
749 r.in.computername = TEST_MACHINE_NAME;
750 ZERO_STRUCT(r.in.return_authenticator);
751 creds_client_authenticator(creds, &r.in.credential);
752 ZERO_STRUCT(r.in.uas);
753 r.in.count=10;
754 r.in.level=0;
755 r.in.buffersize=100;
757 printf("Testing AccountDeltas\n");
759 /* w2k3 returns "NOT IMPLEMENTED" for this call */
760 status = dcerpc_netr_AccountDeltas(p, mem_ctx, &r);
761 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
762 printf("AccountDeltas - %s\n", nt_errstr(status));
763 ret = False;
766 return ret;
770 try a netlogon AccountSync
772 static BOOL test_AccountSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
774 NTSTATUS status;
775 struct netr_AccountSync r;
776 struct creds_CredentialState *creds;
777 BOOL ret = True;
779 if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
780 return False;
783 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
784 r.in.computername = TEST_MACHINE_NAME;
785 ZERO_STRUCT(r.in.return_authenticator);
786 creds_client_authenticator(creds, &r.in.credential);
787 ZERO_STRUCT(r.in.recordid);
788 r.in.reference=0;
789 r.in.level=0;
790 r.in.buffersize=100;
792 printf("Testing AccountSync\n");
794 /* w2k3 returns "NOT IMPLEMENTED" for this call */
795 status = dcerpc_netr_AccountSync(p, mem_ctx, &r);
796 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
797 printf("AccountSync - %s\n", nt_errstr(status));
798 ret = False;
801 return ret;
805 try a netlogon GetDcName
807 static BOOL test_GetDcName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
809 NTSTATUS status;
810 struct netr_GetDcName r;
812 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
813 r.in.domainname = lp_workgroup();
815 printf("Testing GetDcName\n");
817 status = dcerpc_netr_GetDcName(p, mem_ctx, &r);
818 if (!NT_STATUS_IS_OK(status)) {
819 printf("GetDcName - %s\n", nt_errstr(status));
820 return False;
823 printf("\tDC is at '%s'\n", r.out.dcname);
825 return True;
829 try a netlogon LogonControl
831 static BOOL test_LogonControl(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
833 NTSTATUS status;
834 struct netr_LogonControl r;
835 BOOL ret = True;
836 int i;
838 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
839 r.in.function_code = 1;
841 for (i=1;i<4;i++) {
842 r.in.level = i;
844 printf("Testing LogonControl level %d\n", i);
846 status = dcerpc_netr_LogonControl(p, mem_ctx, &r);
847 if (!NT_STATUS_IS_OK(status)) {
848 printf("LogonControl - %s\n", nt_errstr(status));
849 ret = False;
853 return ret;
858 try a netlogon GetAnyDCName
860 static BOOL test_GetAnyDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
862 NTSTATUS status;
863 struct netr_GetAnyDCName r;
865 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
866 r.in.domainname = lp_workgroup();
868 printf("Testing GetAnyDCName\n");
870 status = dcerpc_netr_GetAnyDCName(p, mem_ctx, &r);
871 if (!NT_STATUS_IS_OK(status)) {
872 printf("GetAnyDCName - %s\n", nt_errstr(status));
873 return False;
876 if (r.out.dcname) {
877 printf("\tDC is at '%s'\n", r.out.dcname);
880 return True;
885 try a netlogon LogonControl2
887 static BOOL test_LogonControl2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
889 NTSTATUS status;
890 struct netr_LogonControl2 r;
891 BOOL ret = True;
892 int i;
894 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
896 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
897 r.in.data.domain = lp_workgroup();
899 for (i=1;i<4;i++) {
900 r.in.level = i;
902 printf("Testing LogonControl2 level %d function %d\n",
903 i, r.in.function_code);
905 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
906 if (!NT_STATUS_IS_OK(status)) {
907 printf("LogonControl - %s\n", nt_errstr(status));
908 ret = False;
912 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
913 r.in.data.domain = lp_workgroup();
915 for (i=1;i<4;i++) {
916 r.in.level = i;
918 printf("Testing LogonControl2 level %d function %d\n",
919 i, r.in.function_code);
921 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
922 if (!NT_STATUS_IS_OK(status)) {
923 printf("LogonControl - %s\n", nt_errstr(status));
924 ret = False;
928 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
929 r.in.data.domain = lp_workgroup();
931 for (i=1;i<4;i++) {
932 r.in.level = i;
934 printf("Testing LogonControl2 level %d function %d\n",
935 i, r.in.function_code);
937 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
938 if (!NT_STATUS_IS_OK(status)) {
939 printf("LogonControl - %s\n", nt_errstr(status));
940 ret = False;
944 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
945 r.in.data.debug_level = ~0;
947 for (i=1;i<4;i++) {
948 r.in.level = i;
950 printf("Testing LogonControl2 level %d function %d\n",
951 i, r.in.function_code);
953 status = dcerpc_netr_LogonControl2(p, mem_ctx, &r);
954 if (!NT_STATUS_IS_OK(status)) {
955 printf("LogonControl - %s\n", nt_errstr(status));
956 ret = False;
960 return ret;
964 try a netlogon DatabaseSync2
966 static BOOL test_DatabaseSync2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
968 NTSTATUS status;
969 struct netr_DatabaseSync2 r;
970 struct creds_CredentialState *creds;
971 const uint32_t database_ids[] = {0, 1, 2};
972 int i;
973 BOOL ret = True;
975 if (!test_SetupCredentials2(p, mem_ctx, NETLOGON_NEG_AUTH2_FLAGS,
976 TEST_MACHINE_NAME, machine_password,
977 SEC_CHAN_BDC, &creds)) {
978 return False;
981 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
982 r.in.computername = TEST_MACHINE_NAME;
983 r.in.preferredmaximumlength = (uint32_t)-1;
984 ZERO_STRUCT(r.in.return_authenticator);
986 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
987 r.in.sync_context = 0;
988 r.in.database_id = database_ids[i];
989 r.in.restart_state = 0;
991 printf("Testing DatabaseSync2 of id %d\n", r.in.database_id);
993 do {
994 creds_client_authenticator(creds, &r.in.credential);
996 status = dcerpc_netr_DatabaseSync2(p, mem_ctx, &r);
997 if (!NT_STATUS_IS_OK(status) &&
998 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
999 printf("DatabaseSync2 - %s\n", nt_errstr(status));
1000 ret = False;
1001 break;
1004 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
1005 printf("Credential chaining failed\n");
1008 r.in.sync_context = r.out.sync_context;
1009 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
1012 return ret;
1017 try a netlogon LogonControl2Ex
1019 static BOOL test_LogonControl2Ex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1021 NTSTATUS status;
1022 struct netr_LogonControl2Ex r;
1023 BOOL ret = True;
1024 int i;
1026 r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1028 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1029 r.in.data.domain = lp_workgroup();
1031 for (i=1;i<4;i++) {
1032 r.in.level = i;
1034 printf("Testing LogonControl2Ex level %d function %d\n",
1035 i, r.in.function_code);
1037 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1038 if (!NT_STATUS_IS_OK(status)) {
1039 printf("LogonControl - %s\n", nt_errstr(status));
1040 ret = False;
1044 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1045 r.in.data.domain = lp_workgroup();
1047 for (i=1;i<4;i++) {
1048 r.in.level = i;
1050 printf("Testing LogonControl2Ex level %d function %d\n",
1051 i, r.in.function_code);
1053 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1054 if (!NT_STATUS_IS_OK(status)) {
1055 printf("LogonControl - %s\n", nt_errstr(status));
1056 ret = False;
1060 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1061 r.in.data.domain = lp_workgroup();
1063 for (i=1;i<4;i++) {
1064 r.in.level = i;
1066 printf("Testing LogonControl2Ex level %d function %d\n",
1067 i, r.in.function_code);
1069 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1070 if (!NT_STATUS_IS_OK(status)) {
1071 printf("LogonControl - %s\n", nt_errstr(status));
1072 ret = False;
1076 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1077 r.in.data.debug_level = ~0;
1079 for (i=1;i<4;i++) {
1080 r.in.level = i;
1082 printf("Testing LogonControl2Ex level %d function %d\n",
1083 i, r.in.function_code);
1085 status = dcerpc_netr_LogonControl2Ex(p, mem_ctx, &r);
1086 if (!NT_STATUS_IS_OK(status)) {
1087 printf("LogonControl - %s\n", nt_errstr(status));
1088 ret = False;
1092 return ret;
1097 try a netlogon netr_DsrEnumerateDomainTrusts
1099 static BOOL test_DsrEnumerateDomainTrusts(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1101 NTSTATUS status;
1102 struct netr_DsrEnumerateDomainTrusts r;
1104 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1105 r.in.trust_flags = 0x3f;
1107 printf("Testing netr_DsrEnumerateDomainTrusts\n");
1109 status = dcerpc_netr_DsrEnumerateDomainTrusts(p, mem_ctx, &r);
1110 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1111 printf("netr_DsrEnumerateDomainTrusts - %s/%s\n",
1112 nt_errstr(status), win_errstr(r.out.result));
1113 return False;
1116 return True;
1119 static BOOL test_netr_DsRGetSiteName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1120 const char *computer_name,
1121 const char *expected_site)
1123 NTSTATUS status;
1124 struct netr_DsRGetSiteName r;
1125 BOOL ret = True;
1127 r.in.computer_name = computer_name;
1128 printf("Testing netr_DsRGetSiteName\n");
1130 status = dcerpc_netr_DsRGetSiteName(p, mem_ctx, &r);
1131 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1132 printf("netr_DsRGetSiteName - %s/%s\n",
1133 nt_errstr(status), win_errstr(r.out.result));
1134 ret = False;
1135 } else {
1136 if (strcmp(expected_site, r.out.site) != 0) {
1137 printf("netr_DsRGetSiteName - unexpected result: %s, expected %s\n",
1138 r.out.site, expected_site);
1140 ret = False;
1143 r.in.computer_name = talloc_asprintf(mem_ctx, "\\\\%s", computer_name);
1144 printf("Testing netr_DsRGetSiteName with broken computer name: %s\n", r.in.computer_name);
1146 status = dcerpc_netr_DsRGetSiteName(p, mem_ctx, &r);
1147 if (!NT_STATUS_IS_OK(status)) {
1148 printf("netr_DsRGetSiteName - %s\n",
1149 nt_errstr(status));
1150 ret = False;
1151 } else if (!W_ERROR_EQUAL(r.out.result, WERR_INVALID_COMPUTERNAME)) {
1152 printf("netr_DsRGetSiteName - incorrect error return %s, expected %s\n",
1153 win_errstr(r.out.result), win_errstr(WERR_INVALID_COMPUTERNAME));
1154 ret = False;
1156 return ret;
1160 try a netlogon netr_DsRGetDCName
1162 static BOOL test_netr_DsRGetDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1164 NTSTATUS status;
1165 struct netr_DsRGetDCName r;
1166 BOOL ret = True;
1168 r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1169 r.in.domain_name = talloc_asprintf(mem_ctx, "%s", lp_realm());
1170 r.in.domain_guid = NULL;
1171 r.in.site_guid = NULL;
1172 r.in.flags = 0x40000000;
1174 printf("Testing netr_DsRGetDCName\n");
1176 status = dcerpc_netr_DsRGetDCName(p, mem_ctx, &r);
1177 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1178 printf("netr_DsRGetDCName - %s/%s\n",
1179 nt_errstr(status), win_errstr(r.out.result));
1180 ret = False;
1181 } else {
1182 ret = test_netr_DsRGetSiteName(p, mem_ctx,
1183 r.out.info->dc_unc,
1184 r.out.info->dc_site_name);
1187 return ret;
1191 try a netlogon netr_DsRGetDCNameEx
1193 static BOOL test_netr_DsRGetDCNameEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1195 NTSTATUS status;
1196 struct netr_DsRGetDCNameEx r;
1197 BOOL ret = True;
1199 r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1200 r.in.domain_name = talloc_asprintf(mem_ctx, "%s", lp_realm());
1201 r.in.domain_guid = NULL;
1202 r.in.site_name = NULL;
1203 r.in.flags = 0x40000000;
1205 printf("Testing netr_DsRGetDCNameEx\n");
1207 status = dcerpc_netr_DsRGetDCNameEx(p, mem_ctx, &r);
1208 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1209 printf("netr_DsRGetDCNameEx - %s/%s\n",
1210 nt_errstr(status), win_errstr(r.out.result));
1211 ret = False;
1212 } else {
1213 ret = test_netr_DsRGetSiteName(p, mem_ctx,
1214 r.out.info->dc_unc,
1215 r.out.info->dc_site_name);
1218 return ret;
1222 try a netlogon netr_DsRGetDCNameEx2
1224 static BOOL test_netr_DsRGetDCNameEx2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1226 NTSTATUS status;
1227 struct netr_DsRGetDCNameEx2 r;
1228 BOOL ret = True;
1230 r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1231 r.in.client_account = NULL;
1232 r.in.mask = 0x00000000;
1233 r.in.domain_name = talloc_asprintf(mem_ctx, "%s", lp_realm());
1234 r.in.domain_guid = NULL;
1235 r.in.site_name = NULL;
1236 r.in.flags = 0x40000000;
1238 printf("Testing netr_DsRGetDCNameEx2 without client account\n");
1240 status = dcerpc_netr_DsRGetDCNameEx2(p, mem_ctx, &r);
1241 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1242 printf("netr_DsRGetDCNameEx2 - %s/%s\n",
1243 nt_errstr(status), win_errstr(r.out.result));
1244 ret = False;
1247 printf("Testing netr_DsRGetDCNameEx2 with client acount\n");
1248 r.in.client_account = TEST_MACHINE_NAME"$";
1249 r.in.mask = 0x00002000;
1250 r.in.flags = 0x80000000;
1252 status = dcerpc_netr_DsRGetDCNameEx2(p, mem_ctx, &r);
1253 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
1254 printf("netr_DsRGetDCNameEx2 - %s/%s\n",
1255 nt_errstr(status), win_errstr(r.out.result));
1256 ret = False;
1257 } else {
1258 ret = test_netr_DsRGetSiteName(p, mem_ctx,
1259 r.out.info->dc_unc,
1260 r.out.info->dc_site_name);
1263 return ret;
1266 static BOOL test_GetDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1268 NTSTATUS status;
1269 struct netr_LogonGetDomainInfo r;
1270 struct netr_DomainQuery1 q1;
1271 struct netr_Authenticator a;
1272 struct creds_CredentialState *creds;
1274 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
1275 TEST_MACHINE_NAME, machine_password, &creds)) {
1276 return False;
1279 ZERO_STRUCT(r);
1281 creds_client_authenticator(creds, &a);
1283 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1284 r.in.computer_name = TEST_MACHINE_NAME;
1285 r.in.level = 1;
1286 r.in.credential = &a;
1287 r.in.return_authenticator = &a;
1288 r.out.return_authenticator = &a;
1290 r.in.query.query1 = &q1;
1291 ZERO_STRUCT(q1);
1293 /* this should really be the fully qualified name */
1294 q1.workstation_domain = TEST_MACHINE_NAME;
1295 q1.workstation_site = "Default-First-Site-Name";
1296 q1.blob2.length = 0;
1297 q1.blob2.size = 0;
1298 q1.blob2.data = NULL;
1299 q1.product.string = "product string";
1301 printf("Testing netr_LogonGetDomainInfo\n");
1303 status = dcerpc_netr_LogonGetDomainInfo(p, mem_ctx, &r);
1304 if (!NT_STATUS_IS_OK(status)) {
1305 printf("netr_LogonGetDomainInfo - %s\n", nt_errstr(status));
1306 return False;
1309 if (!creds_client_check(creds, &a.cred)) {
1310 printf("Credential chaining failed\n");
1311 return False;
1314 return True;
1318 static void async_callback(struct rpc_request *req)
1320 int *counter = req->async.private;
1321 if (NT_STATUS_IS_OK(req->status)) {
1322 (*counter)++;
1326 static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1328 NTSTATUS status;
1329 struct netr_LogonGetDomainInfo r;
1330 struct netr_DomainQuery1 q1;
1331 struct netr_Authenticator a;
1332 #define ASYNC_COUNT 100
1333 struct creds_CredentialState *creds;
1334 struct creds_CredentialState *creds_async[ASYNC_COUNT];
1335 struct rpc_request *req[ASYNC_COUNT];
1336 int i;
1337 int *async_counter = talloc(mem_ctx, int);
1339 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
1340 printf("test_GetDomainInfo_async disabled - enable dangerous tests to use\n");
1341 return True;
1344 if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
1345 TEST_MACHINE_NAME, machine_password, &creds)) {
1346 return False;
1349 ZERO_STRUCT(r);
1350 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1351 r.in.computer_name = TEST_MACHINE_NAME;
1352 r.in.level = 1;
1353 r.in.credential = &a;
1354 r.in.return_authenticator = &a;
1355 r.out.return_authenticator = &a;
1357 r.in.query.query1 = &q1;
1358 ZERO_STRUCT(q1);
1360 /* this should really be the fully qualified name */
1361 q1.workstation_domain = TEST_MACHINE_NAME;
1362 q1.workstation_site = "Default-First-Site-Name";
1363 q1.blob2.length = 0;
1364 q1.blob2.size = 0;
1365 q1.blob2.data = NULL;
1366 q1.product.string = "product string";
1368 printf("Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
1370 *async_counter = 0;
1372 for (i=0;i<ASYNC_COUNT;i++) {
1373 creds_client_authenticator(creds, &a);
1375 creds_async[i] = talloc_memdup(creds, creds, sizeof(*creds));
1376 req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, mem_ctx, &r);
1378 req[i]->async.callback = async_callback;
1379 req[i]->async.private = async_counter;
1381 /* even with this flush per request a w2k3 server seems to
1382 clag with multiple outstanding requests. bleergh. */
1383 if (event_loop_once(dcerpc_event_context(p)) != 0) {
1384 return False;
1388 for (i=0;i<ASYNC_COUNT;i++) {
1389 status = dcerpc_ndr_request_recv(req[i]);
1390 if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(r.out.result)) {
1391 printf("netr_LogonGetDomainInfo_async(%d) - %s/%s\n",
1392 i, nt_errstr(status), nt_errstr(r.out.result));
1393 break;
1396 if (!creds_client_check(creds_async[i], &a.cred)) {
1397 printf("Credential chaining failed at async %d\n", i);
1398 break;
1402 printf("Testing netr_LogonGetDomainInfo - async count %d OK\n", *async_counter);
1404 return (*async_counter) == ASYNC_COUNT;
1407 static BOOL test_ManyGetDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1409 NTSTATUS status;
1410 struct dcerpc_pipe *p2;
1411 struct lsa_ObjectAttribute attr;
1412 struct lsa_QosInfo qos;
1413 struct lsa_OpenPolicy2 o;
1414 struct policy_handle lsa_handle;
1415 struct lsa_DomainList domains;
1417 struct lsa_EnumTrustDom t;
1418 uint32_t resume_handle = 0;
1419 struct netr_GetAnyDCName d;
1421 int i;
1422 BOOL ret = True;
1424 if (p->conn->transport.transport != NCACN_NP) {
1425 return True;
1428 printf("Torturing GetDCName\n");
1430 status = dcerpc_secondary_connection(p, &p2, p->binding);
1431 if (!NT_STATUS_IS_OK(status)) {
1432 printf("Failed to create secondary connection\n");
1433 return False;
1436 status = dcerpc_bind_auth_none(p2, &dcerpc_table_lsarpc);
1437 if (!NT_STATUS_IS_OK(status)) {
1438 printf("Failed to create bind on secondary connection\n");
1439 return False;
1442 qos.len = 0;
1443 qos.impersonation_level = 2;
1444 qos.context_mode = 1;
1445 qos.effective_only = 0;
1447 attr.len = 0;
1448 attr.root_dir = NULL;
1449 attr.object_name = NULL;
1450 attr.attributes = 0;
1451 attr.sec_desc = NULL;
1452 attr.sec_qos = &qos;
1454 o.in.system_name = "\\";
1455 o.in.attr = &attr;
1456 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1457 o.out.handle = &lsa_handle;
1459 status = dcerpc_lsa_OpenPolicy2(p2, mem_ctx, &o);
1460 if (!NT_STATUS_IS_OK(status)) {
1461 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
1462 return False;
1465 t.in.handle = &lsa_handle;
1466 t.in.resume_handle = &resume_handle;
1467 t.in.max_size = 1000;
1468 t.out.domains = &domains;
1469 t.out.resume_handle = &resume_handle;
1471 status = dcerpc_lsa_EnumTrustDom(p2, mem_ctx, &t);
1473 if ((!NT_STATUS_IS_OK(status) &&
1474 (!NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)))) {
1475 printf("Could not list domains\n");
1476 return False;
1479 talloc_free(p2);
1481 d.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s",
1482 dcerpc_server_name(p));
1484 for (i=0; i<domains.count * 4; i++) {
1485 struct lsa_DomainInformation *info =
1486 &domains.domains[rand()%domains.count];
1488 d.in.domainname = info->name.string;
1490 status = dcerpc_netr_GetAnyDCName(p, mem_ctx, &d);
1491 if (!NT_STATUS_IS_OK(status)) {
1492 printf("GetAnyDCName - %s\n", nt_errstr(status));
1493 continue;
1496 printf("\tDC for domain %s is %s\n", info->name.string,
1497 d.out.dcname ? d.out.dcname : "unknown");
1500 return ret;
1504 BOOL torture_rpc_netlogon(void)
1506 NTSTATUS status;
1507 struct dcerpc_pipe *p;
1508 TALLOC_CTX *mem_ctx;
1509 BOOL ret = True;
1510 struct test_join *join_ctx;
1511 struct cli_credentials *machine_credentials;
1513 mem_ctx = talloc_init("torture_rpc_netlogon");
1515 join_ctx = torture_join_domain(TEST_MACHINE_NAME, ACB_SVRTRUST,
1516 &machine_credentials);
1517 if (!join_ctx) {
1518 talloc_free(mem_ctx);
1519 printf("Failed to join as BDC\n");
1520 return False;
1523 machine_password = cli_credentials_get_password(machine_credentials);
1525 status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_netlogon);
1526 if (!NT_STATUS_IS_OK(status)) {
1527 talloc_free(mem_ctx);
1528 return False;
1531 ret &= test_LogonUasLogon(p, mem_ctx);
1532 ret &= test_LogonUasLogoff(p, mem_ctx);
1533 ret &= test_SamLogon(p, mem_ctx, machine_credentials);
1534 ret &= test_SetPassword(p, mem_ctx);
1535 ret &= test_SetPassword2(p, mem_ctx);
1536 ret &= test_GetDomainInfo(p, mem_ctx);
1537 ret &= test_DatabaseSync(p, mem_ctx);
1538 ret &= test_DatabaseDeltas(p, mem_ctx);
1539 ret &= test_AccountDeltas(p, mem_ctx);
1540 ret &= test_AccountSync(p, mem_ctx);
1541 ret &= test_GetDcName(p, mem_ctx);
1542 ret &= test_ManyGetDCName(p, mem_ctx);
1543 ret &= test_LogonControl(p, mem_ctx);
1544 ret &= test_GetAnyDCName(p, mem_ctx);
1545 ret &= test_LogonControl2(p, mem_ctx);
1546 ret &= test_DatabaseSync2(p, mem_ctx);
1547 ret &= test_LogonControl2Ex(p, mem_ctx);
1548 ret &= test_DsrEnumerateDomainTrusts(p, mem_ctx);
1549 ret &= test_GetDomainInfo_async(p, mem_ctx);
1550 ret &= test_netr_DsRGetDCName(p, mem_ctx);
1551 ret &= test_netr_DsRGetDCNameEx(p, mem_ctx);
1552 ret &= test_netr_DsRGetDCNameEx2(p, mem_ctx);
1554 talloc_free(mem_ctx);
1556 torture_leave_domain(join_ctx);
1558 return ret;