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 3 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, see <http://www.gnu.org/licenses/>.
25 #include "torture/torture.h"
26 #include "lib/events/events.h"
27 #include "auth/auth.h"
28 #include "auth/gensec/gensec.h"
29 #include "lib/cmdline/popt_common.h"
30 #include "torture/rpc/rpc.h"
31 #include "torture/rpc/netlogon.h"
32 #include "../lib/crypto/crypto.h"
33 #include "libcli/auth/libcli_auth.h"
34 #include "librpc/gen_ndr/ndr_netlogon_c.h"
35 #include "librpc/gen_ndr/ndr_lsa_c.h"
36 #include "param/param.h"
38 #define TEST_MACHINE_NAME "torturetest"
40 static bool test_LogonUasLogon(struct torture_context *tctx,
41 struct dcerpc_pipe *p)
44 struct netr_LogonUasLogon r;
45 struct netr_UasInfo *info = NULL;
47 r.in.server_name = NULL;
48 r.in.account_name = cli_credentials_get_username(cmdline_credentials);
49 r.in.workstation = TEST_MACHINE_NAME;
52 status = dcerpc_netr_LogonUasLogon(p, tctx, &r);
53 torture_assert_ntstatus_ok(tctx, status, "LogonUasLogon");
58 static bool test_LogonUasLogoff(struct torture_context *tctx,
59 struct dcerpc_pipe *p)
62 struct netr_LogonUasLogoff r;
63 struct netr_UasLogoffInfo info;
65 r.in.server_name = NULL;
66 r.in.account_name = cli_credentials_get_username(cmdline_credentials);
67 r.in.workstation = TEST_MACHINE_NAME;
70 status = dcerpc_netr_LogonUasLogoff(p, tctx, &r);
71 torture_assert_ntstatus_ok(tctx, status, "LogonUasLogoff");
76 static bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
77 struct cli_credentials *credentials,
78 struct creds_CredentialState **creds_out)
81 struct netr_ServerReqChallenge r;
82 struct netr_ServerAuthenticate a;
83 struct netr_Credential credentials1, credentials2, credentials3;
84 struct creds_CredentialState *creds;
85 const struct samr_Password *mach_password;
86 const char *machine_name;
88 mach_password = cli_credentials_get_nt_hash(credentials, tctx);
89 machine_name = cli_credentials_get_workstation(credentials);
91 torture_comment(tctx, "Testing ServerReqChallenge\n");
93 creds = talloc(tctx, struct creds_CredentialState);
94 torture_assert(tctx, creds != NULL, "memory allocation");
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, tctx, &r);
104 torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
106 a.in.server_name = NULL;
107 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
108 a.in.secure_channel_type = SEC_CHAN_BDC;
109 a.in.computer_name = machine_name;
110 a.in.credentials = &credentials3;
111 a.out.credentials = &credentials3;
113 creds_client_init(creds, &credentials1, &credentials2,
114 mach_password, &credentials3,
117 torture_comment(tctx, "Testing ServerAuthenticate\n");
119 status = dcerpc_netr_ServerAuthenticate(p, tctx, &a);
121 /* This allows the tests to continue against the more fussy windows 2008 */
122 if (NT_STATUS_EQUAL(status, NT_STATUS_DOWNGRADE_DETECTED)) {
123 return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
124 credentials, SEC_CHAN_BDC, creds_out);
127 torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate");
129 torture_assert(tctx, creds_client_check(creds, &credentials3),
130 "Credential chaining failed");
136 bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx,
137 uint32_t negotiate_flags,
138 struct cli_credentials *machine_credentials,
140 struct creds_CredentialState **creds_out)
143 struct netr_ServerReqChallenge r;
144 struct netr_ServerAuthenticate2 a;
145 struct netr_Credential credentials1, credentials2, credentials3;
146 struct creds_CredentialState *creds;
147 const struct samr_Password *mach_password;
148 const char *machine_name;
149 const char *plain_pass;
151 mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
152 machine_name = cli_credentials_get_workstation(machine_credentials);
154 torture_comment(tctx, "Testing ServerReqChallenge\n");
156 creds = talloc(tctx, struct creds_CredentialState);
157 torture_assert(tctx, creds != NULL, "memory allocation");
159 r.in.server_name = NULL;
160 r.in.computer_name = machine_name;
161 r.in.credentials = &credentials1;
162 r.out.credentials = &credentials2;
164 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
166 status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
167 torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
169 a.in.server_name = NULL;
170 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
171 a.in.secure_channel_type = sec_chan_type;
172 a.in.computer_name = machine_name;
173 a.in.negotiate_flags = &negotiate_flags;
174 a.out.negotiate_flags = &negotiate_flags;
175 a.in.credentials = &credentials3;
176 a.out.credentials = &credentials3;
178 creds_client_init(creds, &credentials1, &credentials2,
179 mach_password, &credentials3,
182 torture_comment(tctx, "Testing ServerAuthenticate2\n");
184 status = dcerpc_netr_ServerAuthenticate2(p, tctx, &a);
185 torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate2");
187 torture_assert(tctx, creds_client_check(creds, &credentials3),
188 "Credential chaining failed");
190 torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
197 static bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx,
198 uint32_t negotiate_flags,
199 struct cli_credentials *machine_credentials,
200 struct creds_CredentialState **creds_out)
203 struct netr_ServerReqChallenge r;
204 struct netr_ServerAuthenticate3 a;
205 struct netr_Credential credentials1, credentials2, credentials3;
206 struct creds_CredentialState *creds;
207 struct samr_Password mach_password;
209 const char *machine_name;
210 const char *plain_pass;
212 machine_name = cli_credentials_get_workstation(machine_credentials);
213 plain_pass = cli_credentials_get_password(machine_credentials);
215 torture_comment(tctx, "Testing ServerReqChallenge\n");
217 creds = talloc(tctx, struct creds_CredentialState);
218 torture_assert(tctx, creds != NULL, "memory allocation");
220 r.in.server_name = NULL;
221 r.in.computer_name = machine_name;
222 r.in.credentials = &credentials1;
223 r.out.credentials = &credentials2;
225 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
227 status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
228 torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
230 E_md4hash(plain_pass, mach_password.hash);
232 a.in.server_name = NULL;
233 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
234 a.in.secure_channel_type = SEC_CHAN_BDC;
235 a.in.computer_name = machine_name;
236 a.in.negotiate_flags = &negotiate_flags;
237 a.in.credentials = &credentials3;
238 a.out.credentials = &credentials3;
239 a.out.negotiate_flags = &negotiate_flags;
242 creds_client_init(creds, &credentials1, &credentials2,
243 &mach_password, &credentials3,
246 torture_comment(tctx, "Testing ServerAuthenticate3\n");
248 status = dcerpc_netr_ServerAuthenticate3(p, tctx, &a);
249 torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate3");
250 torture_assert(tctx, creds_client_check(creds, &credentials3), "Credential chaining failed");
252 torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
254 /* Prove that requesting a challenge again won't break it */
255 status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
256 torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
263 try a change password for our machine account
265 static bool test_SetPassword(struct torture_context *tctx,
266 struct dcerpc_pipe *p,
267 struct cli_credentials *machine_credentials)
270 struct netr_ServerPasswordSet r;
271 const char *password;
272 struct creds_CredentialState *creds;
274 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
278 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
279 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
280 r.in.secure_channel_type = SEC_CHAN_BDC;
281 r.in.computer_name = TEST_MACHINE_NAME;
283 password = generate_random_str(tctx, 8);
284 E_md4hash(password, r.in.new_password.hash);
286 creds_des_encrypt(creds, &r.in.new_password);
288 torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
289 torture_comment(tctx, "Changing machine account password to '%s'\n",
292 creds_client_authenticator(creds, &r.in.credential);
294 status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
295 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet");
297 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
298 torture_comment(tctx, "Credential chaining failed\n");
301 /* by changing the machine password twice we test the
302 credentials chaining fully, and we verify that the server
303 allows the password to be set to the same value twice in a
304 row (match win2k3) */
305 torture_comment(tctx,
306 "Testing a second ServerPasswordSet on machine account\n");
307 torture_comment(tctx,
308 "Changing machine account password to '%s' (same as previous run)\n", password);
310 creds_client_authenticator(creds, &r.in.credential);
312 status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
313 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (2)");
315 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
316 torture_comment(tctx, "Credential chaining failed\n");
319 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
322 test_SetupCredentials(p, tctx, machine_credentials, &creds),
323 "ServerPasswordSet failed to actually change the password");
329 generate a random password for password change tests
331 static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
334 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
335 generate_random_buffer(password.data, password.length);
337 for (i=0; i < len; i++) {
338 if (((uint16_t *)password.data)[i] == 0) {
339 ((uint16_t *)password.data)[i] = 1;
347 try a change password for our machine account
349 static bool test_SetPassword2(struct torture_context *tctx,
350 struct dcerpc_pipe *p,
351 struct cli_credentials *machine_credentials)
354 struct netr_ServerPasswordSet2 r;
355 const char *password;
356 DATA_BLOB new_random_pass;
357 struct creds_CredentialState *creds;
358 struct samr_CryptPassword password_buf;
359 struct samr_Password nt_hash;
361 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
365 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
366 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
367 r.in.secure_channel_type = SEC_CHAN_BDC;
368 r.in.computer_name = TEST_MACHINE_NAME;
370 password = generate_random_str(tctx, 8);
371 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
372 creds_arcfour_crypt(creds, password_buf.data, 516);
374 memcpy(r.in.new_password.data, password_buf.data, 512);
375 r.in.new_password.length = IVAL(password_buf.data, 512);
377 torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
378 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
380 creds_client_authenticator(creds, &r.in.credential);
382 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
383 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2");
385 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
386 torture_comment(tctx, "Credential chaining failed\n");
389 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
391 if (!torture_setting_bool(tctx, "dangerous", false)) {
392 torture_comment(tctx,
393 "Not testing ability to set password to '', enable dangerous tests to perform this test\n");
395 /* by changing the machine password to ""
396 * we check if the server uses password restrictions
397 * for ServerPasswordSet2
398 * (win2k3 accepts "")
401 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
402 creds_arcfour_crypt(creds, password_buf.data, 516);
404 memcpy(r.in.new_password.data, password_buf.data, 512);
405 r.in.new_password.length = IVAL(password_buf.data, 512);
407 torture_comment(tctx,
408 "Testing ServerPasswordSet2 on machine account\n");
409 torture_comment(tctx,
410 "Changing machine account password to '%s'\n", password);
412 creds_client_authenticator(creds, &r.in.credential);
414 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
415 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2");
417 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
418 torture_comment(tctx, "Credential chaining failed\n");
421 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
424 torture_assert(tctx, test_SetupCredentials(p, tctx, machine_credentials, &creds),
425 "ServerPasswordSet failed to actually change the password");
427 /* now try a random password */
428 password = generate_random_str(tctx, 8);
429 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
430 creds_arcfour_crypt(creds, password_buf.data, 516);
432 memcpy(r.in.new_password.data, password_buf.data, 512);
433 r.in.new_password.length = IVAL(password_buf.data, 512);
435 torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
436 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
438 creds_client_authenticator(creds, &r.in.credential);
440 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
441 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2 (2)");
443 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
444 torture_comment(tctx, "Credential chaining failed\n");
447 /* by changing the machine password twice we test the
448 credentials chaining fully, and we verify that the server
449 allows the password to be set to the same value twice in a
450 row (match win2k3) */
451 torture_comment(tctx,
452 "Testing a second ServerPasswordSet2 on machine account\n");
453 torture_comment(tctx,
454 "Changing machine account password to '%s' (same as previous run)\n", password);
456 creds_client_authenticator(creds, &r.in.credential);
458 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
459 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (3)");
461 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
462 torture_comment(tctx, "Credential chaining failed\n");
465 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
467 torture_assert (tctx,
468 test_SetupCredentials(p, tctx, machine_credentials, &creds),
469 "ServerPasswordSet failed to actually change the password");
471 new_random_pass = netlogon_very_rand_pass(tctx, 128);
473 /* now try a random stream of bytes for a password */
474 set_pw_in_buffer(password_buf.data, &new_random_pass);
476 creds_arcfour_crypt(creds, password_buf.data, 516);
478 memcpy(r.in.new_password.data, password_buf.data, 512);
479 r.in.new_password.length = IVAL(password_buf.data, 512);
481 torture_comment(tctx,
482 "Testing a third ServerPasswordSet2 on machine account, with a compleatly random password\n");
484 creds_client_authenticator(creds, &r.in.credential);
486 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
487 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (3)");
489 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
490 torture_comment(tctx, "Credential chaining failed\n");
493 mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
495 cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
496 cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
498 torture_assert (tctx,
499 test_SetupCredentials(p, tctx, machine_credentials, &creds),
500 "ServerPasswordSet failed to actually change the password");
505 static bool test_GetPassword(struct torture_context *tctx,
506 struct dcerpc_pipe *p,
507 struct cli_credentials *machine_credentials)
509 struct netr_ServerPasswordGet r;
510 struct creds_CredentialState *creds;
511 struct netr_Authenticator credential;
513 struct netr_Authenticator return_authenticator;
514 struct samr_Password password;
516 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
520 creds_client_authenticator(creds, &credential);
522 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
523 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
524 r.in.secure_channel_type = SEC_CHAN_BDC;
525 r.in.computer_name = TEST_MACHINE_NAME;
526 r.in.credential = &credential;
527 r.out.return_authenticator = &return_authenticator;
528 r.out.password = &password;
530 status = dcerpc_netr_ServerPasswordGet(p, tctx, &r);
531 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
536 static bool test_GetTrustPasswords(struct torture_context *tctx,
537 struct dcerpc_pipe *p,
538 struct cli_credentials *machine_credentials)
540 struct netr_ServerTrustPasswordsGet r;
541 struct creds_CredentialState *creds;
542 struct netr_Authenticator credential;
544 struct netr_Authenticator return_authenticator;
545 struct samr_Password password, password2;
547 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
551 creds_client_authenticator(creds, &credential);
553 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
554 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
555 r.in.secure_channel_type = SEC_CHAN_BDC;
556 r.in.computer_name = TEST_MACHINE_NAME;
557 r.in.credential = &credential;
558 r.out.return_authenticator = &return_authenticator;
559 r.out.password = &password;
560 r.out.password2 = &password2;
562 status = dcerpc_netr_ServerTrustPasswordsGet(p, tctx, &r);
563 torture_assert_ntstatus_ok(tctx, status, "ServerTrustPasswordsGet");
569 try a netlogon SamLogon
571 bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
572 struct cli_credentials *credentials,
573 struct creds_CredentialState *creds)
576 struct netr_LogonSamLogon r;
577 struct netr_Authenticator auth, auth2;
578 union netr_LogonLevel logon;
579 union netr_Validation validation;
580 uint8_t authoritative;
581 struct netr_NetworkInfo ninfo;
582 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
584 int flags = CLI_CRED_NTLM_AUTH;
585 if (lp_client_lanman_auth(tctx->lp_ctx)) {
586 flags |= CLI_CRED_LANMAN_AUTH;
589 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
590 flags |= CLI_CRED_NTLMv2_AUTH;
593 cli_credentials_get_ntlm_username_domain(cmdline_credentials, tctx,
594 &ninfo.identity_info.account_name.string,
595 &ninfo.identity_info.domain_name.string);
597 generate_random_buffer(ninfo.challenge,
598 sizeof(ninfo.challenge));
599 chal = data_blob_const(ninfo.challenge,
600 sizeof(ninfo.challenge));
602 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials),
603 cli_credentials_get_domain(credentials));
605 status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx,
611 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
613 ninfo.lm.data = lm_resp.data;
614 ninfo.lm.length = lm_resp.length;
616 ninfo.nt.data = nt_resp.data;
617 ninfo.nt.length = nt_resp.length;
619 ninfo.identity_info.parameter_control = 0;
620 ninfo.identity_info.logon_id_low = 0;
621 ninfo.identity_info.logon_id_high = 0;
622 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
624 logon.network = &ninfo;
626 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
627 r.in.computer_name = cli_credentials_get_workstation(credentials);
628 r.in.credential = &auth;
629 r.in.return_authenticator = &auth2;
630 r.in.logon_level = 2;
632 r.out.validation = &validation;
633 r.out.authoritative = &authoritative;
635 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
639 creds_client_authenticator(creds, &auth);
641 r.in.validation_level = i;
643 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
644 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
646 torture_assert(tctx, creds_client_check(creds, &r.out.return_authenticator->cred),
647 "Credential chaining failed");
650 r.in.credential = NULL;
654 r.in.validation_level = i;
656 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
658 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
659 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_INVALID_PARAMETER,
660 "LogonSamLogon expected INVALID_PARAMETER");
668 try a netlogon SamLogon
670 static bool test_SamLogon(struct torture_context *tctx,
671 struct dcerpc_pipe *p,
672 struct cli_credentials *credentials)
674 struct creds_CredentialState *creds;
676 if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
680 return test_netlogon_ops(p, tctx, credentials, creds);
683 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
684 static uint64_t sequence_nums[3];
687 try a netlogon DatabaseSync
689 static bool test_DatabaseSync(struct torture_context *tctx,
690 struct dcerpc_pipe *p,
691 struct cli_credentials *machine_credentials)
694 struct netr_DatabaseSync r;
695 struct creds_CredentialState *creds;
696 const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
698 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
699 struct netr_Authenticator credential, return_authenticator;
701 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
705 ZERO_STRUCT(return_authenticator);
707 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
708 r.in.computername = TEST_MACHINE_NAME;
709 r.in.preferredmaximumlength = (uint32_t)-1;
710 r.in.return_authenticator = &return_authenticator;
711 r.out.delta_enum_array = &delta_enum_array;
712 r.out.return_authenticator = &return_authenticator;
714 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
716 uint32_t sync_context = 0;
718 r.in.database_id = database_ids[i];
719 r.in.sync_context = &sync_context;
720 r.out.sync_context = &sync_context;
722 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
725 creds_client_authenticator(creds, &credential);
727 r.in.credential = &credential;
729 status = dcerpc_netr_DatabaseSync(p, tctx, &r);
730 if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
733 /* Native mode servers don't do this */
734 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
737 torture_assert_ntstatus_ok(tctx, status, "DatabaseSync");
739 if (!creds_client_check(creds, &r.out.return_authenticator->cred)) {
740 torture_comment(tctx, "Credential chaining failed\n");
743 if (delta_enum_array &&
744 delta_enum_array->num_deltas > 0 &&
745 delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
746 delta_enum_array->delta_enum[0].delta_union.domain) {
747 sequence_nums[r.in.database_id] =
748 delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
749 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
751 (unsigned long long)sequence_nums[r.in.database_id]);
753 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
761 try a netlogon DatabaseDeltas
763 static bool test_DatabaseDeltas(struct torture_context *tctx,
764 struct dcerpc_pipe *p,
765 struct cli_credentials *machine_credentials)
768 struct netr_DatabaseDeltas r;
769 struct creds_CredentialState *creds;
770 struct netr_Authenticator credential;
771 struct netr_Authenticator return_authenticator;
772 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
773 const uint32_t database_ids[] = {0, 1, 2};
776 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
780 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
781 r.in.computername = TEST_MACHINE_NAME;
782 r.in.preferredmaximumlength = (uint32_t)-1;
783 ZERO_STRUCT(r.in.return_authenticator);
784 r.out.return_authenticator = &return_authenticator;
785 r.out.delta_enum_array = &delta_enum_array;
787 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
788 r.in.database_id = database_ids[i];
789 r.in.sequence_num = &sequence_nums[r.in.database_id];
791 if (*r.in.sequence_num == 0) continue;
793 *r.in.sequence_num -= 1;
795 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n",
796 r.in.database_id, (unsigned long long)*r.in.sequence_num);
799 creds_client_authenticator(creds, &credential);
801 status = dcerpc_netr_DatabaseDeltas(p, tctx, &r);
802 if (NT_STATUS_EQUAL(status,
803 NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
804 torture_comment(tctx, "not considering %s to be an error\n",
808 if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
811 torture_assert_ntstatus_ok(tctx, status, "DatabaseDeltas");
813 if (!creds_client_check(creds, &return_authenticator.cred)) {
814 torture_comment(tctx, "Credential chaining failed\n");
817 (*r.in.sequence_num)++;
818 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
826 try a netlogon AccountDeltas
828 static bool test_AccountDeltas(struct torture_context *tctx,
829 struct dcerpc_pipe *p,
830 struct cli_credentials *machine_credentials)
833 struct netr_AccountDeltas r;
834 struct creds_CredentialState *creds;
836 struct netr_AccountBuffer buffer;
837 uint32_t count_returned = 0;
838 uint32_t total_entries = 0;
839 struct netr_UAS_INFO_0 recordid;
840 struct netr_Authenticator return_authenticator;
842 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
846 ZERO_STRUCT(return_authenticator);
848 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
849 r.in.computername = TEST_MACHINE_NAME;
850 r.in.return_authenticator = &return_authenticator;
851 creds_client_authenticator(creds, &r.in.credential);
852 ZERO_STRUCT(r.in.uas);
856 r.out.buffer = &buffer;
857 r.out.count_returned = &count_returned;
858 r.out.total_entries = &total_entries;
859 r.out.recordid = &recordid;
860 r.out.return_authenticator = &return_authenticator;
862 /* w2k3 returns "NOT IMPLEMENTED" for this call */
863 status = dcerpc_netr_AccountDeltas(p, tctx, &r);
864 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
870 try a netlogon AccountSync
872 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
873 struct cli_credentials *machine_credentials)
876 struct netr_AccountSync r;
877 struct creds_CredentialState *creds;
879 struct netr_AccountBuffer buffer;
880 uint32_t count_returned = 0;
881 uint32_t total_entries = 0;
882 uint32_t next_reference = 0;
883 struct netr_UAS_INFO_0 recordid;
884 struct netr_Authenticator return_authenticator;
886 ZERO_STRUCT(recordid);
887 ZERO_STRUCT(return_authenticator);
889 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
893 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
894 r.in.computername = TEST_MACHINE_NAME;
895 r.in.return_authenticator = &return_authenticator;
896 creds_client_authenticator(creds, &r.in.credential);
897 r.in.recordid = &recordid;
901 r.out.buffer = &buffer;
902 r.out.count_returned = &count_returned;
903 r.out.total_entries = &total_entries;
904 r.out.next_reference = &next_reference;
905 r.out.recordid = &recordid;
906 r.out.return_authenticator = &return_authenticator;
908 /* w2k3 returns "NOT IMPLEMENTED" for this call */
909 status = dcerpc_netr_AccountSync(p, tctx, &r);
910 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
916 try a netlogon GetDcName
918 static bool test_GetDcName(struct torture_context *tctx,
919 struct dcerpc_pipe *p)
922 struct netr_GetDcName r;
923 const char *dcname = NULL;
925 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
926 r.in.domainname = lp_workgroup(tctx->lp_ctx);
927 r.out.dcname = &dcname;
929 status = dcerpc_netr_GetDcName(p, tctx, &r);
930 torture_assert_ntstatus_ok(tctx, status, "GetDcName");
931 torture_assert_werr_ok(tctx, r.out.result, "GetDcName");
933 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
939 try a netlogon LogonControl
941 static bool test_LogonControl(struct torture_context *tctx,
942 struct dcerpc_pipe *p)
945 struct netr_LogonControl r;
946 union netr_CONTROL_QUERY_INFORMATION info;
949 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
950 r.in.function_code = 1;
956 torture_comment(tctx, "Testing LogonControl level %d\n", i);
958 status = dcerpc_netr_LogonControl(p, tctx, &r);
959 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
967 try a netlogon GetAnyDCName
969 static bool test_GetAnyDCName(struct torture_context *tctx,
970 struct dcerpc_pipe *p)
973 struct netr_GetAnyDCName r;
974 const char *dcname = NULL;
976 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
977 r.in.domainname = lp_workgroup(tctx->lp_ctx);
978 r.out.dcname = &dcname;
980 status = dcerpc_netr_GetAnyDCName(p, tctx, &r);
981 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
984 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
992 try a netlogon LogonControl2
994 static bool test_LogonControl2(struct torture_context *tctx,
995 struct dcerpc_pipe *p)
998 struct netr_LogonControl2 r;
999 union netr_CONTROL_DATA_INFORMATION data;
1000 union netr_CONTROL_QUERY_INFORMATION query;
1003 data.domain = lp_workgroup(tctx->lp_ctx);
1005 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1007 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1009 r.out.query = &query;
1014 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1015 i, r.in.function_code);
1017 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1018 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1021 data.domain = lp_workgroup(tctx->lp_ctx);
1023 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1029 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1030 i, r.in.function_code);
1032 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1033 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1036 data.domain = lp_workgroup(tctx->lp_ctx);
1038 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1044 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1045 i, r.in.function_code);
1047 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1048 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1051 data.debug_level = ~0;
1053 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1059 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1060 i, r.in.function_code);
1062 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1063 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1070 try a netlogon DatabaseSync2
1072 static bool test_DatabaseSync2(struct torture_context *tctx,
1073 struct dcerpc_pipe *p,
1074 struct cli_credentials *machine_credentials)
1077 struct netr_DatabaseSync2 r;
1078 struct creds_CredentialState *creds;
1079 const uint32_t database_ids[] = {0, 1, 2};
1082 if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
1083 machine_credentials,
1084 SEC_CHAN_BDC, &creds)) {
1088 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1089 r.in.computername = TEST_MACHINE_NAME;
1090 r.in.preferredmaximumlength = (uint32_t)-1;
1091 ZERO_STRUCT(r.in.return_authenticator);
1093 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1094 r.in.sync_context = 0;
1095 r.in.database_id = database_ids[i];
1096 r.in.restart_state = 0;
1098 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
1101 creds_client_authenticator(creds, &r.in.credential);
1103 status = dcerpc_netr_DatabaseSync2(p, tctx, &r);
1104 if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
1107 /* Native mode servers don't do this */
1108 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1112 torture_assert_ntstatus_ok(tctx, status, "DatabaseSync2");
1114 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
1115 torture_comment(tctx, "Credential chaining failed\n");
1118 r.in.sync_context = r.out.sync_context;
1119 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
1127 try a netlogon LogonControl2Ex
1129 static bool test_LogonControl2Ex(struct torture_context *tctx,
1130 struct dcerpc_pipe *p)
1133 struct netr_LogonControl2Ex r;
1134 union netr_CONTROL_QUERY_INFORMATION query;
1137 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1139 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1140 r.in.data.domain = lp_workgroup(tctx->lp_ctx);
1141 r.out.query = &query;
1146 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
1147 i, r.in.function_code);
1149 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1150 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1153 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1154 r.in.data.domain = lp_workgroup(tctx->lp_ctx);
1159 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
1160 i, r.in.function_code);
1162 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1163 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1166 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1167 r.in.data.domain = lp_workgroup(tctx->lp_ctx);
1172 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
1173 i, r.in.function_code);
1175 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1176 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1179 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1180 r.in.data.debug_level = ~0;
1185 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
1186 i, r.in.function_code);
1188 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1189 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1195 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
1196 struct dcerpc_pipe *p, const char *trusted_domain_name)
1199 struct netr_DsRGetForestTrustInformation r;
1200 struct lsa_ForestTrustInformation info, *info_ptr;
1204 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1205 r.in.trusted_domain_name = trusted_domain_name;
1207 r.out.forest_trust_info = &info_ptr;
1209 torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
1211 status = dcerpc_netr_DsRGetForestTrustInformation(p, tctx, &r);
1212 torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
1213 torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
1219 try a netlogon netr_DsrEnumerateDomainTrusts
1221 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
1222 struct dcerpc_pipe *p)
1225 struct netr_DsrEnumerateDomainTrusts r;
1226 struct netr_DomainTrustList trusts;
1229 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1230 r.in.trust_flags = 0x3f;
1231 r.out.trusts = &trusts;
1233 status = dcerpc_netr_DsrEnumerateDomainTrusts(p, tctx, &r);
1234 torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
1235 torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
1237 /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
1238 * will show non-forest trusts and all UPN suffixes of the own forest
1239 * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
1241 if (r.out.trusts->count) {
1242 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
1247 for (i=0; i<r.out.trusts->count; i++) {
1249 /* get info for transitive forest trusts */
1251 if (r.out.trusts->array[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
1252 if (!test_netr_DsRGetForestTrustInformation(tctx, p,
1253 r.out.trusts->array[i].dns_name)) {
1262 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
1263 struct dcerpc_pipe *p)
1266 struct netr_NetrEnumerateTrustedDomains r;
1267 struct netr_Blob trusted_domains_blob;
1269 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1270 r.out.trusted_domains_blob = &trusted_domains_blob;
1272 status = dcerpc_netr_NetrEnumerateTrustedDomains(p, tctx, &r);
1273 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
1274 torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
1279 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
1280 struct dcerpc_pipe *p)
1283 struct netr_NetrEnumerateTrustedDomainsEx r;
1284 struct netr_DomainTrustList dom_trust_list;
1286 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1287 r.out.dom_trust_list = &dom_trust_list;
1289 status = dcerpc_netr_NetrEnumerateTrustedDomainsEx(p, tctx, &r);
1290 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
1291 torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
1297 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
1298 const char *computer_name,
1299 const char *expected_site)
1302 struct netr_DsRGetSiteName r;
1303 const char *site = NULL;
1305 if (torture_setting_bool(tctx, "samba4", false))
1306 torture_skip(tctx, "skipping DsRGetSiteName test against Samba4");
1308 r.in.computer_name = computer_name;
1310 torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
1312 status = dcerpc_netr_DsRGetSiteName(p, tctx, &r);
1313 torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
1314 torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
1315 torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
1317 r.in.computer_name = talloc_asprintf(tctx, "\\\\%s", computer_name);
1318 torture_comment(tctx,
1319 "Testing netr_DsRGetSiteName with broken computer name: %s\n", r.in.computer_name);
1321 status = dcerpc_netr_DsRGetSiteName(p, tctx, &r);
1322 torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
1323 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_COMPUTERNAME, "netr_DsRGetSiteName");
1329 try a netlogon netr_DsRGetDCName
1331 static bool test_netr_DsRGetDCName(struct torture_context *tctx,
1332 struct dcerpc_pipe *p)
1335 struct netr_DsRGetDCName r;
1336 struct netr_DsRGetDCNameInfo *info = NULL;
1338 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1339 r.in.domain_name = talloc_asprintf(tctx, "%s", lp_realm(tctx->lp_ctx));
1340 r.in.domain_guid = NULL;
1341 r.in.site_guid = NULL;
1342 r.in.flags = DS_RETURN_DNS_NAME;
1345 status = dcerpc_netr_DsRGetDCName(p, tctx, &r);
1346 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
1347 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
1348 return test_netr_DsRGetSiteName(p, tctx,
1350 info->dc_site_name);
1354 try a netlogon netr_DsRGetDCNameEx
1356 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
1357 struct dcerpc_pipe *p)
1360 struct netr_DsRGetDCNameEx r;
1361 struct netr_DsRGetDCNameInfo *info = NULL;
1363 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1364 r.in.domain_name = talloc_asprintf(tctx, "%s", lp_realm(tctx->lp_ctx));
1365 r.in.domain_guid = NULL;
1366 r.in.site_name = NULL;
1367 r.in.flags = DS_RETURN_DNS_NAME;
1370 status = dcerpc_netr_DsRGetDCNameEx(p, tctx, &r);
1371 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
1372 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
1374 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
1375 info->dc_site_name);
1379 try a netlogon netr_DsRGetDCNameEx2
1381 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
1382 struct dcerpc_pipe *p)
1385 struct netr_DsRGetDCNameEx2 r;
1386 struct netr_DsRGetDCNameInfo *info = NULL;
1388 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1389 r.in.client_account = NULL;
1390 r.in.mask = 0x00000000;
1391 r.in.domain_name = talloc_asprintf(tctx, "%s", lp_realm(tctx->lp_ctx));
1392 r.in.domain_guid = NULL;
1393 r.in.site_name = NULL;
1394 r.in.flags = DS_RETURN_DNS_NAME;
1397 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
1399 status = dcerpc_netr_DsRGetDCNameEx2(p, tctx, &r);
1400 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
1401 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
1403 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client acount\n");
1404 r.in.client_account = TEST_MACHINE_NAME"$";
1405 r.in.mask = ACB_SVRTRUST;
1406 r.in.flags = DS_RETURN_FLAT_NAME;
1409 status = dcerpc_netr_DsRGetDCNameEx2(p, tctx, &r);
1410 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
1411 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
1412 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
1413 info->dc_site_name);
1416 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
1417 struct dcerpc_pipe *p)
1420 struct netr_DsrGetDcSiteCoverageW r;
1421 struct DcSitesCtr *ctr = NULL;
1423 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1426 status = dcerpc_netr_DsrGetDcSiteCoverageW(p, tctx, &r);
1427 torture_assert_ntstatus_ok(tctx, status, "failed");
1428 torture_assert_werr_ok(tctx, r.out.result, "failed");
1433 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
1434 struct dcerpc_pipe *p)
1437 struct netr_DsRAddressToSitenamesW r;
1438 struct netr_DsRAddress addr;
1439 struct netr_DsRAddressToSitenamesWCtr *ctr;
1441 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
1444 addr.buffer = talloc_zero_array(tctx, uint8_t, addr.size);
1446 addr.buffer[0] = 2; /* AF_INET */
1447 addr.buffer[4] = 127;
1452 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1454 r.in.addresses = talloc_zero_array(tctx, struct netr_DsRAddress, r.in.count);
1455 r.in.addresses[0] = addr;
1458 status = dcerpc_netr_DsRAddressToSitenamesW(p, tctx, &r);
1459 torture_assert_ntstatus_ok(tctx, status, "failed");
1460 torture_assert_werr_ok(tctx, r.out.result, "failed");
1465 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
1466 struct dcerpc_pipe *p)
1469 struct netr_DsRAddressToSitenamesExW r;
1470 struct netr_DsRAddress addr;
1471 struct netr_DsRAddressToSitenamesExWCtr *ctr;
1473 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
1476 addr.buffer = talloc_zero_array(tctx, uint8_t, addr.size);
1478 addr.buffer[0] = 2; /* AF_INET */
1479 addr.buffer[4] = 127;
1484 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1486 r.in.addresses = talloc_zero_array(tctx, struct netr_DsRAddress, r.in.count);
1487 r.in.addresses[0] = addr;
1490 status = dcerpc_netr_DsRAddressToSitenamesExW(p, tctx, &r);
1491 torture_assert_ntstatus_ok(tctx, status, "failed");
1492 torture_assert_werr_ok(tctx, r.out.result, "failed");
1497 static bool test_GetDomainInfo(struct torture_context *tctx,
1498 struct dcerpc_pipe *p,
1499 struct cli_credentials *machine_credentials)
1502 struct netr_LogonGetDomainInfo r;
1503 struct netr_DomainQuery1 q1;
1504 struct netr_Authenticator a;
1505 struct creds_CredentialState *creds;
1506 union netr_DomainInfo info;
1508 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
1509 machine_credentials, &creds)) {
1515 creds_client_authenticator(creds, &a);
1517 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1518 r.in.computer_name = TEST_MACHINE_NAME;
1520 r.in.credential = &a;
1521 r.in.return_authenticator = &a;
1522 r.out.return_authenticator = &a;
1525 r.in.query.query1 = &q1;
1528 /* this should really be the fully qualified name */
1529 q1.workstation_domain = TEST_MACHINE_NAME;
1530 q1.workstation_site = "Default-First-Site-Name";
1531 q1.blob2.length = 0;
1533 q1.blob2.data = NULL;
1534 q1.product.string = "product string";
1536 torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
1538 status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
1539 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
1540 torture_assert(tctx, creds_client_check(creds, &a.cred), "Credential chaining failed");
1542 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call\n");
1543 creds_client_authenticator(creds, &a);
1545 status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
1546 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
1547 torture_assert(tctx, creds_client_check(creds, &a.cred), "Credential chaining failed");
1553 static void async_callback(struct rpc_request *req)
1555 int *counter = (int *)req->async.private_data;
1556 if (NT_STATUS_IS_OK(req->status)) {
1561 static bool test_GetDomainInfo_async(struct torture_context *tctx,
1562 struct dcerpc_pipe *p,
1563 struct cli_credentials *machine_credentials)
1566 struct netr_LogonGetDomainInfo r;
1567 struct netr_DomainQuery1 q1;
1568 struct netr_Authenticator a;
1569 #define ASYNC_COUNT 100
1570 struct creds_CredentialState *creds;
1571 struct creds_CredentialState *creds_async[ASYNC_COUNT];
1572 struct rpc_request *req[ASYNC_COUNT];
1574 int *async_counter = talloc(tctx, int);
1575 union netr_DomainInfo info;
1577 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
1578 machine_credentials, &creds)) {
1583 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1584 r.in.computer_name = TEST_MACHINE_NAME;
1586 r.in.credential = &a;
1587 r.in.return_authenticator = &a;
1588 r.out.return_authenticator = &a;
1591 r.in.query.query1 = &q1;
1594 /* this should really be the fully qualified name */
1595 q1.workstation_domain = TEST_MACHINE_NAME;
1596 q1.workstation_site = "Default-First-Site-Name";
1597 q1.blob2.length = 0;
1599 q1.blob2.data = NULL;
1600 q1.product.string = "product string";
1602 torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
1606 for (i=0;i<ASYNC_COUNT;i++) {
1607 creds_client_authenticator(creds, &a);
1609 creds_async[i] = (struct creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
1610 req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, tctx, &r);
1612 req[i]->async.callback = async_callback;
1613 req[i]->async.private_data = async_counter;
1615 /* even with this flush per request a w2k3 server seems to
1616 clag with multiple outstanding requests. bleergh. */
1617 torture_assert_int_equal(tctx, event_loop_once(dcerpc_event_context(p)), 0,
1618 "event_loop_once failed");
1621 for (i=0;i<ASYNC_COUNT;i++) {
1622 status = dcerpc_ndr_request_recv(req[i]);
1624 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
1625 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
1627 torture_assert(tctx, creds_client_check(creds_async[i], &a.cred),
1628 "Credential chaining failed at async");
1631 torture_comment(tctx,
1632 "Testing netr_LogonGetDomainInfo - async count %d OK\n", *async_counter);
1634 torture_assert_int_equal(tctx, (*async_counter), ASYNC_COUNT, "int");
1639 static bool test_ManyGetDCName(struct torture_context *tctx,
1640 struct dcerpc_pipe *p)
1643 struct dcerpc_pipe *p2;
1644 struct lsa_ObjectAttribute attr;
1645 struct lsa_QosInfo qos;
1646 struct lsa_OpenPolicy2 o;
1647 struct policy_handle lsa_handle;
1648 struct lsa_DomainList domains;
1650 struct lsa_EnumTrustDom t;
1651 uint32_t resume_handle = 0;
1652 struct netr_GetAnyDCName d;
1653 const char *dcname = NULL;
1657 if (p->conn->transport.transport != NCACN_NP) {
1661 torture_comment(tctx, "Torturing GetDCName\n");
1663 status = dcerpc_secondary_connection(p, &p2, p->binding);
1664 torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
1666 status = dcerpc_bind_auth_none(p2, &ndr_table_lsarpc);
1667 torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
1670 qos.impersonation_level = 2;
1671 qos.context_mode = 1;
1672 qos.effective_only = 0;
1675 attr.root_dir = NULL;
1676 attr.object_name = NULL;
1677 attr.attributes = 0;
1678 attr.sec_desc = NULL;
1679 attr.sec_qos = &qos;
1681 o.in.system_name = "\\";
1683 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1684 o.out.handle = &lsa_handle;
1686 status = dcerpc_lsa_OpenPolicy2(p2, tctx, &o);
1687 torture_assert_ntstatus_ok(tctx, status, "OpenPolicy2 failed");
1689 t.in.handle = &lsa_handle;
1690 t.in.resume_handle = &resume_handle;
1691 t.in.max_size = 1000;
1692 t.out.domains = &domains;
1693 t.out.resume_handle = &resume_handle;
1695 status = dcerpc_lsa_EnumTrustDom(p2, tctx, &t);
1697 if ((!NT_STATUS_IS_OK(status) &&
1698 (!NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES))))
1699 torture_fail(tctx, "Could not list domains");
1703 d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
1704 dcerpc_server_name(p));
1705 d.out.dcname = &dcname;
1707 for (i=0; i<domains.count * 4; i++) {
1708 struct lsa_DomainInfo *info =
1709 &domains.domains[rand()%domains.count];
1711 d.in.domainname = info->name.string;
1713 status = dcerpc_netr_GetAnyDCName(p, tctx, &d);
1714 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
1716 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
1717 dcname ? dcname : "unknown");
1723 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
1725 struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON");
1726 struct torture_rpc_tcase *tcase;
1727 struct torture_test *test;
1729 tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "netlogon",
1730 &ndr_table_netlogon, TEST_MACHINE_NAME);
1732 torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
1733 torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
1734 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
1735 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
1736 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
1737 torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
1738 torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
1739 torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
1740 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
1741 torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
1742 torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
1743 torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
1744 torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
1745 torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
1746 torture_rpc_tcase_add_test(tcase, "LogonControl", test_LogonControl);
1747 torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
1748 torture_rpc_tcase_add_test(tcase, "LogonControl2", test_LogonControl2);
1749 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
1750 torture_rpc_tcase_add_test(tcase, "LogonControl2Ex", test_LogonControl2Ex);
1751 torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
1752 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
1753 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
1754 test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
1755 test->dangerous = true;
1756 torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
1757 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
1758 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
1759 torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
1760 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
1761 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);