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
9 Copyright (C) Matthias Dieter Wallnöfer 2009
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #include "torture/torture.h"
28 #include "lib/events/events.h"
29 #include "auth/auth.h"
30 #include "auth/gensec/gensec.h"
31 #include "lib/cmdline/popt_common.h"
32 #include "torture/rpc/rpc.h"
33 #include "torture/rpc/netlogon.h"
34 #include "../lib/crypto/crypto.h"
35 #include "libcli/auth/libcli_auth.h"
36 #include "librpc/gen_ndr/ndr_netlogon_c.h"
37 #include "librpc/gen_ndr/ndr_netlogon.h"
38 #include "librpc/gen_ndr/ndr_lsa_c.h"
39 #include "param/param.h"
40 #include "libcli/security/security.h"
41 #include "lib/ldb/include/ldb.h"
42 #include "lib/util/util_ldb.h"
43 #include "lib/ldb_wrap.h"
45 #define TEST_MACHINE_NAME "torturetest"
46 #define TEST_MACHINE_DNS_SUFFIX "torturedomain"
48 static bool test_LogonUasLogon(struct torture_context *tctx,
49 struct dcerpc_pipe *p)
52 struct netr_LogonUasLogon r;
53 struct netr_UasInfo *info = NULL;
55 r.in.server_name = NULL;
56 r.in.account_name = cli_credentials_get_username(cmdline_credentials);
57 r.in.workstation = TEST_MACHINE_NAME;
60 status = dcerpc_netr_LogonUasLogon(p, tctx, &r);
61 torture_assert_ntstatus_ok(tctx, status, "LogonUasLogon");
66 static bool test_LogonUasLogoff(struct torture_context *tctx,
67 struct dcerpc_pipe *p)
70 struct netr_LogonUasLogoff r;
71 struct netr_UasLogoffInfo info;
73 r.in.server_name = NULL;
74 r.in.account_name = cli_credentials_get_username(cmdline_credentials);
75 r.in.workstation = TEST_MACHINE_NAME;
78 status = dcerpc_netr_LogonUasLogoff(p, tctx, &r);
79 torture_assert_ntstatus_ok(tctx, status, "LogonUasLogoff");
84 bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
85 struct cli_credentials *credentials,
86 struct netlogon_creds_CredentialState **creds_out)
89 struct netr_ServerReqChallenge r;
90 struct netr_ServerAuthenticate a;
91 struct netr_Credential credentials1, credentials2, credentials3;
92 struct netlogon_creds_CredentialState *creds;
93 const struct samr_Password *mach_password;
94 const char *machine_name;
96 mach_password = cli_credentials_get_nt_hash(credentials, tctx);
97 machine_name = cli_credentials_get_workstation(credentials);
99 torture_comment(tctx, "Testing ServerReqChallenge\n");
101 r.in.server_name = NULL;
102 r.in.computer_name = machine_name;
103 r.in.credentials = &credentials1;
104 r.out.return_credentials = &credentials2;
106 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
108 status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
109 torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
111 a.in.server_name = NULL;
112 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
113 a.in.secure_channel_type = SEC_CHAN_BDC;
114 a.in.computer_name = machine_name;
115 a.in.credentials = &credentials3;
116 a.out.return_credentials = &credentials3;
118 creds = netlogon_creds_client_init(tctx, a.in.account_name,
120 &credentials1, &credentials2,
121 mach_password, &credentials3,
123 torture_assert(tctx, creds != NULL, "memory allocation");
126 torture_comment(tctx, "Testing ServerAuthenticate\n");
128 status = dcerpc_netr_ServerAuthenticate(p, tctx, &a);
130 /* This allows the tests to continue against the more fussy windows 2008 */
131 if (NT_STATUS_EQUAL(status, NT_STATUS_DOWNGRADE_DETECTED)) {
132 return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
133 credentials, SEC_CHAN_BDC, creds_out);
136 torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate");
138 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
139 "Credential chaining failed");
145 bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx,
146 uint32_t negotiate_flags,
147 struct cli_credentials *machine_credentials,
149 struct netlogon_creds_CredentialState **creds_out)
152 struct netr_ServerReqChallenge r;
153 struct netr_ServerAuthenticate2 a;
154 struct netr_Credential credentials1, credentials2, credentials3;
155 struct netlogon_creds_CredentialState *creds;
156 const struct samr_Password *mach_password;
157 const char *machine_name;
159 mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
160 machine_name = cli_credentials_get_workstation(machine_credentials);
162 torture_comment(tctx, "Testing ServerReqChallenge\n");
165 r.in.server_name = NULL;
166 r.in.computer_name = machine_name;
167 r.in.credentials = &credentials1;
168 r.out.return_credentials = &credentials2;
170 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
172 status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
173 torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
175 a.in.server_name = NULL;
176 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
177 a.in.secure_channel_type = sec_chan_type;
178 a.in.computer_name = machine_name;
179 a.in.negotiate_flags = &negotiate_flags;
180 a.out.negotiate_flags = &negotiate_flags;
181 a.in.credentials = &credentials3;
182 a.out.return_credentials = &credentials3;
184 creds = netlogon_creds_client_init(tctx, a.in.account_name,
186 &credentials1, &credentials2,
187 mach_password, &credentials3,
190 torture_assert(tctx, creds != NULL, "memory allocation");
192 torture_comment(tctx, "Testing ServerAuthenticate2\n");
194 status = dcerpc_netr_ServerAuthenticate2(p, tctx, &a);
195 torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate2");
197 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
198 "Credential chaining failed");
200 torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
207 static bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx,
208 uint32_t negotiate_flags,
209 struct cli_credentials *machine_credentials,
210 struct netlogon_creds_CredentialState **creds_out)
213 struct netr_ServerReqChallenge r;
214 struct netr_ServerAuthenticate3 a;
215 struct netr_Credential credentials1, credentials2, credentials3;
216 struct netlogon_creds_CredentialState *creds;
217 struct samr_Password mach_password;
219 const char *machine_name;
220 const char *plain_pass;
222 machine_name = cli_credentials_get_workstation(machine_credentials);
223 plain_pass = cli_credentials_get_password(machine_credentials);
225 torture_comment(tctx, "Testing ServerReqChallenge\n");
227 r.in.server_name = NULL;
228 r.in.computer_name = machine_name;
229 r.in.credentials = &credentials1;
230 r.out.return_credentials = &credentials2;
232 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
234 status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
235 torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
237 E_md4hash(plain_pass, mach_password.hash);
239 a.in.server_name = NULL;
240 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
241 a.in.secure_channel_type = SEC_CHAN_BDC;
242 a.in.computer_name = machine_name;
243 a.in.negotiate_flags = &negotiate_flags;
244 a.in.credentials = &credentials3;
245 a.out.return_credentials = &credentials3;
246 a.out.negotiate_flags = &negotiate_flags;
249 creds = netlogon_creds_client_init(tctx, a.in.account_name,
251 &credentials1, &credentials2,
252 &mach_password, &credentials3,
255 torture_assert(tctx, creds != NULL, "memory allocation");
257 torture_comment(tctx, "Testing ServerAuthenticate3\n");
259 status = dcerpc_netr_ServerAuthenticate3(p, tctx, &a);
260 torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate3");
261 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
263 torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
265 /* Prove that requesting a challenge again won't break it */
266 status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
267 torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
274 try a change password for our machine account
276 static bool test_SetPassword(struct torture_context *tctx,
277 struct dcerpc_pipe *p,
278 struct cli_credentials *machine_credentials)
281 struct netr_ServerPasswordSet r;
282 const char *password;
283 struct netlogon_creds_CredentialState *creds;
284 struct netr_Authenticator credential, return_authenticator;
285 struct samr_Password new_password;
287 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
291 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
292 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
293 r.in.secure_channel_type = SEC_CHAN_BDC;
294 r.in.computer_name = TEST_MACHINE_NAME;
295 r.in.credential = &credential;
296 r.in.new_password = &new_password;
297 r.out.return_authenticator = &return_authenticator;
299 password = generate_random_str(tctx, 8);
300 E_md4hash(password, new_password.hash);
302 netlogon_creds_des_encrypt(creds, &new_password);
304 torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
305 torture_comment(tctx, "Changing machine account password to '%s'\n",
308 netlogon_creds_client_authenticator(creds, &credential);
310 status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
311 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet");
313 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
314 torture_comment(tctx, "Credential chaining failed\n");
317 /* by changing the machine password twice we test the
318 credentials chaining fully, and we verify that the server
319 allows the password to be set to the same value twice in a
320 row (match win2k3) */
321 torture_comment(tctx,
322 "Testing a second ServerPasswordSet on machine account\n");
323 torture_comment(tctx,
324 "Changing machine account password to '%s' (same as previous run)\n", password);
326 netlogon_creds_client_authenticator(creds, &credential);
328 status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
329 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (2)");
331 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
332 torture_comment(tctx, "Credential chaining failed\n");
335 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
338 test_SetupCredentials(p, tctx, machine_credentials, &creds),
339 "ServerPasswordSet failed to actually change the password");
345 generate a random password for password change tests
347 static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
350 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
351 generate_random_buffer(password.data, password.length);
353 for (i=0; i < len; i++) {
354 if (((uint16_t *)password.data)[i] == 0) {
355 ((uint16_t *)password.data)[i] = 1;
363 try a change password for our machine account
365 static bool test_SetPassword2(struct torture_context *tctx,
366 struct dcerpc_pipe *p,
367 struct cli_credentials *machine_credentials)
370 struct netr_ServerPasswordSet2 r;
371 const char *password;
372 DATA_BLOB new_random_pass;
373 struct netlogon_creds_CredentialState *creds;
374 struct samr_CryptPassword password_buf;
375 struct samr_Password nt_hash;
376 struct netr_Authenticator credential, return_authenticator;
377 struct netr_CryptPassword new_password;
379 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
383 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
384 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
385 r.in.secure_channel_type = SEC_CHAN_BDC;
386 r.in.computer_name = TEST_MACHINE_NAME;
387 r.in.credential = &credential;
388 r.in.new_password = &new_password;
389 r.out.return_authenticator = &return_authenticator;
391 password = generate_random_str(tctx, 8);
392 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
393 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
395 memcpy(new_password.data, password_buf.data, 512);
396 new_password.length = IVAL(password_buf.data, 512);
398 torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
399 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
401 netlogon_creds_client_authenticator(creds, &credential);
403 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
404 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2");
406 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
407 torture_comment(tctx, "Credential chaining failed\n");
410 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
412 if (!torture_setting_bool(tctx, "dangerous", false)) {
413 torture_comment(tctx,
414 "Not testing ability to set password to '', enable dangerous tests to perform this test\n");
416 /* by changing the machine password to ""
417 * we check if the server uses password restrictions
418 * for ServerPasswordSet2
419 * (win2k3 accepts "")
422 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
423 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
425 memcpy(new_password.data, password_buf.data, 512);
426 new_password.length = IVAL(password_buf.data, 512);
428 torture_comment(tctx,
429 "Testing ServerPasswordSet2 on machine account\n");
430 torture_comment(tctx,
431 "Changing machine account password to '%s'\n", password);
433 netlogon_creds_client_authenticator(creds, &credential);
435 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
436 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2");
438 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
439 torture_comment(tctx, "Credential chaining failed\n");
442 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
445 torture_assert(tctx, test_SetupCredentials(p, tctx, machine_credentials, &creds),
446 "ServerPasswordSet failed to actually change the password");
448 /* now try a random password */
449 password = generate_random_str(tctx, 8);
450 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
451 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
453 memcpy(new_password.data, password_buf.data, 512);
454 new_password.length = IVAL(password_buf.data, 512);
456 torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
457 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
459 netlogon_creds_client_authenticator(creds, &credential);
461 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
462 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2 (2)");
464 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
465 torture_comment(tctx, "Credential chaining failed\n");
468 /* by changing the machine password twice we test the
469 credentials chaining fully, and we verify that the server
470 allows the password to be set to the same value twice in a
471 row (match win2k3) */
472 torture_comment(tctx,
473 "Testing a second ServerPasswordSet2 on machine account\n");
474 torture_comment(tctx,
475 "Changing machine account password to '%s' (same as previous run)\n", password);
477 netlogon_creds_client_authenticator(creds, &credential);
479 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
480 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (3)");
482 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
483 torture_comment(tctx, "Credential chaining failed\n");
486 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
488 torture_assert (tctx,
489 test_SetupCredentials(p, tctx, machine_credentials, &creds),
490 "ServerPasswordSet failed to actually change the password");
492 new_random_pass = netlogon_very_rand_pass(tctx, 128);
494 /* now try a random stream of bytes for a password */
495 set_pw_in_buffer(password_buf.data, &new_random_pass);
497 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
499 memcpy(new_password.data, password_buf.data, 512);
500 new_password.length = IVAL(password_buf.data, 512);
502 torture_comment(tctx,
503 "Testing a third ServerPasswordSet2 on machine account, with a compleatly random password\n");
505 netlogon_creds_client_authenticator(creds, &credential);
507 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
508 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (3)");
510 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
511 torture_comment(tctx, "Credential chaining failed\n");
514 mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
516 cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
517 cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
519 torture_assert (tctx,
520 test_SetupCredentials(p, tctx, machine_credentials, &creds),
521 "ServerPasswordSet failed to actually change the password");
526 static bool test_GetPassword(struct torture_context *tctx,
527 struct dcerpc_pipe *p,
528 struct cli_credentials *machine_credentials)
530 struct netr_ServerPasswordGet r;
531 struct netlogon_creds_CredentialState *creds;
532 struct netr_Authenticator credential;
534 struct netr_Authenticator return_authenticator;
535 struct samr_Password password;
537 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
541 netlogon_creds_client_authenticator(creds, &credential);
543 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
544 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
545 r.in.secure_channel_type = SEC_CHAN_BDC;
546 r.in.computer_name = TEST_MACHINE_NAME;
547 r.in.credential = &credential;
548 r.out.return_authenticator = &return_authenticator;
549 r.out.password = &password;
551 status = dcerpc_netr_ServerPasswordGet(p, tctx, &r);
552 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
557 static bool test_GetTrustPasswords(struct torture_context *tctx,
558 struct dcerpc_pipe *p,
559 struct cli_credentials *machine_credentials)
561 struct netr_ServerTrustPasswordsGet r;
562 struct netlogon_creds_CredentialState *creds;
563 struct netr_Authenticator credential;
565 struct netr_Authenticator return_authenticator;
566 struct samr_Password password, password2;
568 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
572 netlogon_creds_client_authenticator(creds, &credential);
574 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
575 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
576 r.in.secure_channel_type = SEC_CHAN_BDC;
577 r.in.computer_name = TEST_MACHINE_NAME;
578 r.in.credential = &credential;
579 r.out.return_authenticator = &return_authenticator;
580 r.out.password = &password;
581 r.out.password2 = &password2;
583 status = dcerpc_netr_ServerTrustPasswordsGet(p, tctx, &r);
584 torture_assert_ntstatus_ok(tctx, status, "ServerTrustPasswordsGet");
590 try a netlogon SamLogon
592 bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
593 struct cli_credentials *credentials,
594 struct netlogon_creds_CredentialState *creds)
597 struct netr_LogonSamLogon r;
598 struct netr_Authenticator auth, auth2;
599 union netr_LogonLevel logon;
600 union netr_Validation validation;
601 uint8_t authoritative;
602 struct netr_NetworkInfo ninfo;
603 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
605 int flags = CLI_CRED_NTLM_AUTH;
606 if (lp_client_lanman_auth(tctx->lp_ctx)) {
607 flags |= CLI_CRED_LANMAN_AUTH;
610 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
611 flags |= CLI_CRED_NTLMv2_AUTH;
614 cli_credentials_get_ntlm_username_domain(cmdline_credentials, tctx,
615 &ninfo.identity_info.account_name.string,
616 &ninfo.identity_info.domain_name.string);
618 generate_random_buffer(ninfo.challenge,
619 sizeof(ninfo.challenge));
620 chal = data_blob_const(ninfo.challenge,
621 sizeof(ninfo.challenge));
623 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials),
624 cli_credentials_get_domain(credentials));
626 status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx,
632 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
634 ninfo.lm.data = lm_resp.data;
635 ninfo.lm.length = lm_resp.length;
637 ninfo.nt.data = nt_resp.data;
638 ninfo.nt.length = nt_resp.length;
640 ninfo.identity_info.parameter_control = 0;
641 ninfo.identity_info.logon_id_low = 0;
642 ninfo.identity_info.logon_id_high = 0;
643 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
645 logon.network = &ninfo;
647 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
648 r.in.computer_name = cli_credentials_get_workstation(credentials);
649 r.in.credential = &auth;
650 r.in.return_authenticator = &auth2;
651 r.in.logon_level = 2;
653 r.out.validation = &validation;
654 r.out.authoritative = &authoritative;
656 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
660 netlogon_creds_client_authenticator(creds, &auth);
662 r.in.validation_level = i;
664 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
665 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
667 torture_assert(tctx, netlogon_creds_client_check(creds,
668 &r.out.return_authenticator->cred),
669 "Credential chaining failed");
672 r.in.credential = NULL;
676 r.in.validation_level = i;
678 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
680 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
681 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_INVALID_PARAMETER,
682 "LogonSamLogon expected INVALID_PARAMETER");
690 try a netlogon SamLogon
692 static bool test_SamLogon(struct torture_context *tctx,
693 struct dcerpc_pipe *p,
694 struct cli_credentials *credentials)
696 struct netlogon_creds_CredentialState *creds;
698 if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
702 return test_netlogon_ops(p, tctx, credentials, creds);
705 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
706 static uint64_t sequence_nums[3];
709 try a netlogon DatabaseSync
711 static bool test_DatabaseSync(struct torture_context *tctx,
712 struct dcerpc_pipe *p,
713 struct cli_credentials *machine_credentials)
716 struct netr_DatabaseSync r;
717 struct netlogon_creds_CredentialState *creds;
718 const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
720 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
721 struct netr_Authenticator credential, return_authenticator;
723 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
727 ZERO_STRUCT(return_authenticator);
729 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
730 r.in.computername = TEST_MACHINE_NAME;
731 r.in.preferredmaximumlength = (uint32_t)-1;
732 r.in.return_authenticator = &return_authenticator;
733 r.out.delta_enum_array = &delta_enum_array;
734 r.out.return_authenticator = &return_authenticator;
736 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
738 uint32_t sync_context = 0;
740 r.in.database_id = database_ids[i];
741 r.in.sync_context = &sync_context;
742 r.out.sync_context = &sync_context;
744 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
747 netlogon_creds_client_authenticator(creds, &credential);
749 r.in.credential = &credential;
751 status = dcerpc_netr_DatabaseSync(p, tctx, &r);
752 if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
755 /* Native mode servers don't do this */
756 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
759 torture_assert_ntstatus_ok(tctx, status, "DatabaseSync");
761 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
762 torture_comment(tctx, "Credential chaining failed\n");
765 if (delta_enum_array &&
766 delta_enum_array->num_deltas > 0 &&
767 delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
768 delta_enum_array->delta_enum[0].delta_union.domain) {
769 sequence_nums[r.in.database_id] =
770 delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
771 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
773 (unsigned long long)sequence_nums[r.in.database_id]);
775 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
783 try a netlogon DatabaseDeltas
785 static bool test_DatabaseDeltas(struct torture_context *tctx,
786 struct dcerpc_pipe *p,
787 struct cli_credentials *machine_credentials)
790 struct netr_DatabaseDeltas r;
791 struct netlogon_creds_CredentialState *creds;
792 struct netr_Authenticator credential;
793 struct netr_Authenticator return_authenticator;
794 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
795 const uint32_t database_ids[] = {0, 1, 2};
798 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
802 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
803 r.in.computername = TEST_MACHINE_NAME;
804 r.in.preferredmaximumlength = (uint32_t)-1;
805 ZERO_STRUCT(r.in.return_authenticator);
806 r.out.return_authenticator = &return_authenticator;
807 r.out.delta_enum_array = &delta_enum_array;
809 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
810 r.in.database_id = database_ids[i];
811 r.in.sequence_num = &sequence_nums[r.in.database_id];
813 if (*r.in.sequence_num == 0) continue;
815 *r.in.sequence_num -= 1;
817 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n",
818 r.in.database_id, (unsigned long long)*r.in.sequence_num);
821 netlogon_creds_client_authenticator(creds, &credential);
823 status = dcerpc_netr_DatabaseDeltas(p, tctx, &r);
824 if (NT_STATUS_EQUAL(status,
825 NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
826 torture_comment(tctx, "not considering %s to be an error\n",
830 if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
833 torture_assert_ntstatus_ok(tctx, status, "DatabaseDeltas");
835 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
836 torture_comment(tctx, "Credential chaining failed\n");
839 (*r.in.sequence_num)++;
840 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
846 static bool test_DatabaseRedo(struct torture_context *tctx,
847 struct dcerpc_pipe *p,
848 struct cli_credentials *machine_credentials)
851 struct netr_DatabaseRedo r;
852 struct netlogon_creds_CredentialState *creds;
853 struct netr_Authenticator credential;
854 struct netr_Authenticator return_authenticator;
855 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
856 struct netr_ChangeLogEntry e;
857 struct dom_sid null_sid, *sid;
860 ZERO_STRUCT(null_sid);
862 sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
873 NTSTATUS expected_error;
874 uint32_t expected_num_results;
875 uint8_t expected_delta_type_1;
876 uint8_t expected_delta_type_2;
880 /* SAM_DATABASE_DOMAIN */
885 .db_index = SAM_DATABASE_DOMAIN,
886 .delta_type = NETR_DELTA_MODIFY_COUNT,
889 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
890 .expected_num_results = 0,
891 .comment = "NETR_DELTA_MODIFY_COUNT"
896 .db_index = SAM_DATABASE_DOMAIN,
900 .expected_error = NT_STATUS_OK,
901 .expected_num_results = 1,
902 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
903 .comment = "NULL DELTA"
908 .db_index = SAM_DATABASE_DOMAIN,
909 .delta_type = NETR_DELTA_DOMAIN,
912 .expected_error = NT_STATUS_OK,
913 .expected_num_results = 1,
914 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
915 .comment = "NETR_DELTA_DOMAIN"
918 .rid = DOMAIN_RID_ADMINISTRATOR,
920 .db_index = SAM_DATABASE_DOMAIN,
921 .delta_type = NETR_DELTA_USER,
924 .expected_error = NT_STATUS_OK,
925 .expected_num_results = 1,
926 .expected_delta_type_1 = NETR_DELTA_USER,
927 .comment = "NETR_DELTA_USER by rid 500"
930 .rid = DOMAIN_RID_GUEST,
932 .db_index = SAM_DATABASE_DOMAIN,
933 .delta_type = NETR_DELTA_USER,
936 .expected_error = NT_STATUS_OK,
937 .expected_num_results = 1,
938 .expected_delta_type_1 = NETR_DELTA_USER,
939 .comment = "NETR_DELTA_USER by rid 501"
943 .flags = NETR_CHANGELOG_SID_INCLUDED,
944 .db_index = SAM_DATABASE_DOMAIN,
945 .delta_type = NETR_DELTA_USER,
948 .expected_error = NT_STATUS_OK,
949 .expected_num_results = 1,
950 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
951 .comment = "NETR_DELTA_USER by sid and flags"
955 .flags = NETR_CHANGELOG_SID_INCLUDED,
956 .db_index = SAM_DATABASE_DOMAIN,
957 .delta_type = NETR_DELTA_USER,
960 .expected_error = NT_STATUS_OK,
961 .expected_num_results = 1,
962 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
963 .comment = "NETR_DELTA_USER by null_sid and flags"
967 .flags = NETR_CHANGELOG_NAME_INCLUDED,
968 .db_index = SAM_DATABASE_DOMAIN,
969 .delta_type = NETR_DELTA_USER,
971 .name = "administrator",
972 .expected_error = NT_STATUS_OK,
973 .expected_num_results = 1,
974 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
975 .comment = "NETR_DELTA_USER by name 'administrator'"
978 .rid = DOMAIN_RID_ADMINS,
980 .db_index = SAM_DATABASE_DOMAIN,
981 .delta_type = NETR_DELTA_GROUP,
984 .expected_error = NT_STATUS_OK,
985 .expected_num_results = 2,
986 .expected_delta_type_1 = NETR_DELTA_GROUP,
987 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
988 .comment = "NETR_DELTA_GROUP by rid 512"
991 .rid = DOMAIN_RID_ADMINS,
993 .db_index = SAM_DATABASE_DOMAIN,
994 .delta_type = NETR_DELTA_GROUP_MEMBER,
997 .expected_error = NT_STATUS_OK,
998 .expected_num_results = 2,
999 .expected_delta_type_1 = NETR_DELTA_GROUP,
1000 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
1001 .comment = "NETR_DELTA_GROUP_MEMBER by rid 512"
1005 /* SAM_DATABASE_BUILTIN */
1010 .db_index = SAM_DATABASE_BUILTIN,
1011 .delta_type = NETR_DELTA_MODIFY_COUNT,
1014 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1015 .expected_num_results = 0,
1016 .comment = "NETR_DELTA_MODIFY_COUNT"
1021 .db_index = SAM_DATABASE_BUILTIN,
1022 .delta_type = NETR_DELTA_DOMAIN,
1025 .expected_error = NT_STATUS_OK,
1026 .expected_num_results = 1,
1027 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1028 .comment = "NETR_DELTA_DOMAIN"
1031 .rid = DOMAIN_RID_ADMINISTRATOR,
1033 .db_index = SAM_DATABASE_BUILTIN,
1034 .delta_type = NETR_DELTA_USER,
1037 .expected_error = NT_STATUS_OK,
1038 .expected_num_results = 1,
1039 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1040 .comment = "NETR_DELTA_USER by rid 500"
1045 .db_index = SAM_DATABASE_BUILTIN,
1046 .delta_type = NETR_DELTA_USER,
1049 .expected_error = NT_STATUS_OK,
1050 .expected_num_results = 1,
1051 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1052 .comment = "NETR_DELTA_USER"
1057 .db_index = SAM_DATABASE_BUILTIN,
1058 .delta_type = NETR_DELTA_ALIAS,
1061 .expected_error = NT_STATUS_OK,
1062 .expected_num_results = 2,
1063 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1064 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1065 .comment = "NETR_DELTA_ALIAS by rid 544"
1070 .db_index = SAM_DATABASE_BUILTIN,
1071 .delta_type = NETR_DELTA_ALIAS_MEMBER,
1074 .expected_error = NT_STATUS_OK,
1075 .expected_num_results = 2,
1076 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1077 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1078 .comment = "NETR_DELTA_ALIAS_MEMBER by rid 544"
1083 .db_index = SAM_DATABASE_BUILTIN,
1087 .expected_error = NT_STATUS_OK,
1088 .expected_num_results = 1,
1089 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1090 .comment = "NULL DELTA by rid 544"
1094 .flags = NETR_CHANGELOG_SID_INCLUDED,
1095 .db_index = SAM_DATABASE_BUILTIN,
1097 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1099 .expected_error = NT_STATUS_OK,
1100 .expected_num_results = 1,
1101 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1102 .comment = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
1106 .flags = NETR_CHANGELOG_SID_INCLUDED,
1107 .db_index = SAM_DATABASE_BUILTIN,
1108 .delta_type = NETR_DELTA_ALIAS,
1109 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1111 .expected_error = NT_STATUS_OK,
1112 .expected_num_results = 2,
1113 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1114 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1115 .comment = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
1119 .flags = NETR_CHANGELOG_SID_INCLUDED,
1120 .db_index = SAM_DATABASE_BUILTIN,
1121 .delta_type = NETR_DELTA_ALIAS,
1122 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1124 .expected_error = NT_STATUS_OK,
1125 .expected_num_results = 1,
1126 .expected_delta_type_1 = NETR_DELTA_DELETE_ALIAS,
1127 .comment = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
1130 /* SAM_DATABASE_PRIVS */
1135 .db_index = SAM_DATABASE_PRIVS,
1139 .expected_error = NT_STATUS_ACCESS_DENIED,
1140 .expected_num_results = 0,
1141 .comment = "NULL DELTA"
1146 .db_index = SAM_DATABASE_PRIVS,
1147 .delta_type = NETR_DELTA_MODIFY_COUNT,
1150 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1151 .expected_num_results = 0,
1152 .comment = "NETR_DELTA_MODIFY_COUNT"
1157 .db_index = SAM_DATABASE_PRIVS,
1158 .delta_type = NETR_DELTA_POLICY,
1161 .expected_error = NT_STATUS_OK,
1162 .expected_num_results = 1,
1163 .expected_delta_type_1 = NETR_DELTA_POLICY,
1164 .comment = "NETR_DELTA_POLICY"
1168 .flags = NETR_CHANGELOG_SID_INCLUDED,
1169 .db_index = SAM_DATABASE_PRIVS,
1170 .delta_type = NETR_DELTA_POLICY,
1173 .expected_error = NT_STATUS_OK,
1174 .expected_num_results = 1,
1175 .expected_delta_type_1 = NETR_DELTA_POLICY,
1176 .comment = "NETR_DELTA_POLICY by null sid and flags"
1180 .flags = NETR_CHANGELOG_SID_INCLUDED,
1181 .db_index = SAM_DATABASE_PRIVS,
1182 .delta_type = NETR_DELTA_POLICY,
1183 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
1185 .expected_error = NT_STATUS_OK,
1186 .expected_num_results = 1,
1187 .expected_delta_type_1 = NETR_DELTA_POLICY,
1188 .comment = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
1191 .rid = DOMAIN_RID_ADMINISTRATOR,
1193 .db_index = SAM_DATABASE_PRIVS,
1194 .delta_type = NETR_DELTA_ACCOUNT,
1197 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
1198 .expected_num_results = 0,
1199 .comment = "NETR_DELTA_ACCOUNT by rid 500"
1203 .flags = NETR_CHANGELOG_SID_INCLUDED,
1204 .db_index = SAM_DATABASE_PRIVS,
1205 .delta_type = NETR_DELTA_ACCOUNT,
1206 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1208 .expected_error = NT_STATUS_OK,
1209 .expected_num_results = 1,
1210 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
1211 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
1215 .flags = NETR_CHANGELOG_SID_INCLUDED |
1216 NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
1217 .db_index = SAM_DATABASE_PRIVS,
1218 .delta_type = NETR_DELTA_ACCOUNT,
1219 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1221 .expected_error = NT_STATUS_OK,
1222 .expected_num_results = 1,
1223 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
1224 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
1228 .flags = NETR_CHANGELOG_SID_INCLUDED |
1229 NETR_CHANGELOG_NAME_INCLUDED,
1230 .db_index = SAM_DATABASE_PRIVS,
1231 .delta_type = NETR_DELTA_ACCOUNT,
1232 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1234 .expected_error = NT_STATUS_INVALID_PARAMETER,
1235 .expected_num_results = 0,
1236 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
1239 .rid = DOMAIN_RID_ADMINISTRATOR,
1240 .flags = NETR_CHANGELOG_SID_INCLUDED,
1241 .db_index = SAM_DATABASE_PRIVS,
1242 .delta_type = NETR_DELTA_ACCOUNT,
1245 .expected_error = NT_STATUS_OK,
1246 .expected_num_results = 1,
1247 .expected_delta_type_1 = NETR_DELTA_DELETE_ACCOUNT,
1248 .comment = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
1252 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1253 .db_index = SAM_DATABASE_PRIVS,
1254 .delta_type = NETR_DELTA_SECRET,
1256 .name = "IsurelydontexistIhope",
1257 .expected_error = NT_STATUS_OK,
1258 .expected_num_results = 1,
1259 .expected_delta_type_1 = NETR_DELTA_DELETE_SECRET,
1260 .comment = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
1264 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1265 .db_index = SAM_DATABASE_PRIVS,
1266 .delta_type = NETR_DELTA_SECRET,
1268 .name = "G$BCKUPKEY_P",
1269 .expected_error = NT_STATUS_OK,
1270 .expected_num_results = 1,
1271 .expected_delta_type_1 = NETR_DELTA_SECRET,
1272 .comment = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
1276 ZERO_STRUCT(return_authenticator);
1278 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1279 r.in.computername = TEST_MACHINE_NAME;
1280 r.in.return_authenticator = &return_authenticator;
1281 r.out.return_authenticator = &return_authenticator;
1282 r.out.delta_enum_array = &delta_enum_array;
1284 for (d=0; d<3; d++) {
1286 const char *database;
1293 database = "BUILTIN";
1302 torture_comment(tctx, "Testing DatabaseRedo\n");
1304 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1308 for (i=0;i<ARRAY_SIZE(changes);i++) {
1310 if (d != changes[i].db_index) {
1314 netlogon_creds_client_authenticator(creds, &credential);
1316 r.in.credential = &credential;
1318 e.serial_number1 = 0;
1319 e.serial_number2 = 0;
1320 e.object_rid = changes[i].rid;
1321 e.flags = changes[i].flags;
1322 e.db_index = changes[i].db_index;
1323 e.delta_type = changes[i].delta_type;
1325 switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
1326 case NETR_CHANGELOG_SID_INCLUDED:
1327 e.object.object_sid = changes[i].sid;
1329 case NETR_CHANGELOG_NAME_INCLUDED:
1330 e.object.object_name = changes[i].name;
1336 r.in.change_log_entry = e;
1338 torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
1339 database, changes[i].comment);
1341 status = dcerpc_netr_DatabaseRedo(p, tctx, &r);
1342 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1346 torture_assert_ntstatus_equal(tctx, status, changes[i].expected_error, changes[i].comment);
1347 if (delta_enum_array) {
1348 torture_assert_int_equal(tctx,
1349 delta_enum_array->num_deltas,
1350 changes[i].expected_num_results,
1351 changes[i].comment);
1352 if (delta_enum_array->num_deltas > 0) {
1353 torture_assert_int_equal(tctx,
1354 delta_enum_array->delta_enum[0].delta_type,
1355 changes[i].expected_delta_type_1,
1356 changes[i].comment);
1358 if (delta_enum_array->num_deltas > 1) {
1359 torture_assert_int_equal(tctx,
1360 delta_enum_array->delta_enum[1].delta_type,
1361 changes[i].expected_delta_type_2,
1362 changes[i].comment);
1366 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1367 torture_comment(tctx, "Credential chaining failed\n");
1368 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1380 try a netlogon AccountDeltas
1382 static bool test_AccountDeltas(struct torture_context *tctx,
1383 struct dcerpc_pipe *p,
1384 struct cli_credentials *machine_credentials)
1387 struct netr_AccountDeltas r;
1388 struct netlogon_creds_CredentialState *creds;
1390 struct netr_AccountBuffer buffer;
1391 uint32_t count_returned = 0;
1392 uint32_t total_entries = 0;
1393 struct netr_UAS_INFO_0 recordid;
1394 struct netr_Authenticator return_authenticator;
1396 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1400 ZERO_STRUCT(return_authenticator);
1402 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1403 r.in.computername = TEST_MACHINE_NAME;
1404 r.in.return_authenticator = &return_authenticator;
1405 netlogon_creds_client_authenticator(creds, &r.in.credential);
1406 ZERO_STRUCT(r.in.uas);
1409 r.in.buffersize=100;
1410 r.out.buffer = &buffer;
1411 r.out.count_returned = &count_returned;
1412 r.out.total_entries = &total_entries;
1413 r.out.recordid = &recordid;
1414 r.out.return_authenticator = &return_authenticator;
1416 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1417 status = dcerpc_netr_AccountDeltas(p, tctx, &r);
1418 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
1424 try a netlogon AccountSync
1426 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
1427 struct cli_credentials *machine_credentials)
1430 struct netr_AccountSync r;
1431 struct netlogon_creds_CredentialState *creds;
1433 struct netr_AccountBuffer buffer;
1434 uint32_t count_returned = 0;
1435 uint32_t total_entries = 0;
1436 uint32_t next_reference = 0;
1437 struct netr_UAS_INFO_0 recordid;
1438 struct netr_Authenticator return_authenticator;
1440 ZERO_STRUCT(recordid);
1441 ZERO_STRUCT(return_authenticator);
1443 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1447 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1448 r.in.computername = TEST_MACHINE_NAME;
1449 r.in.return_authenticator = &return_authenticator;
1450 netlogon_creds_client_authenticator(creds, &r.in.credential);
1451 r.in.recordid = &recordid;
1454 r.in.buffersize=100;
1455 r.out.buffer = &buffer;
1456 r.out.count_returned = &count_returned;
1457 r.out.total_entries = &total_entries;
1458 r.out.next_reference = &next_reference;
1459 r.out.recordid = &recordid;
1460 r.out.return_authenticator = &return_authenticator;
1462 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1463 status = dcerpc_netr_AccountSync(p, tctx, &r);
1464 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
1470 try a netlogon GetDcName
1472 static bool test_GetDcName(struct torture_context *tctx,
1473 struct dcerpc_pipe *p)
1476 struct netr_GetDcName r;
1477 const char *dcname = NULL;
1479 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1480 r.in.domainname = lp_workgroup(tctx->lp_ctx);
1481 r.out.dcname = &dcname;
1483 status = dcerpc_netr_GetDcName(p, tctx, &r);
1484 torture_assert_ntstatus_ok(tctx, status, "GetDcName");
1485 torture_assert_werr_ok(tctx, r.out.result, "GetDcName");
1487 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1493 try a netlogon LogonControl
1495 static bool test_LogonControl(struct torture_context *tctx,
1496 struct dcerpc_pipe *p)
1499 struct netr_LogonControl r;
1500 union netr_CONTROL_QUERY_INFORMATION query;
1503 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1504 r.in.function_code = 1;
1505 r.out.query = &query;
1510 torture_comment(tctx, "Testing LogonControl level %d\n", i);
1512 status = dcerpc_netr_LogonControl(p, tctx, &r);
1513 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1521 try a netlogon GetAnyDCName
1523 static bool test_GetAnyDCName(struct torture_context *tctx,
1524 struct dcerpc_pipe *p)
1527 struct netr_GetAnyDCName r;
1528 const char *dcname = NULL;
1530 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1531 r.in.domainname = lp_workgroup(tctx->lp_ctx);
1532 r.out.dcname = &dcname;
1534 status = dcerpc_netr_GetAnyDCName(p, tctx, &r);
1535 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
1536 torture_assert_werr_ok(tctx, r.out.result, "GetAnyDCName");
1539 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1547 try a netlogon LogonControl2
1549 static bool test_LogonControl2(struct torture_context *tctx,
1550 struct dcerpc_pipe *p)
1553 struct netr_LogonControl2 r;
1554 union netr_CONTROL_DATA_INFORMATION data;
1555 union netr_CONTROL_QUERY_INFORMATION query;
1558 data.domain = lp_workgroup(tctx->lp_ctx);
1560 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1562 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1564 r.out.query = &query;
1569 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1570 i, r.in.function_code);
1572 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1573 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1576 data.domain = lp_workgroup(tctx->lp_ctx);
1578 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1584 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1585 i, r.in.function_code);
1587 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1588 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1591 data.domain = lp_workgroup(tctx->lp_ctx);
1593 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1599 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1600 i, r.in.function_code);
1602 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1603 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1606 data.debug_level = ~0;
1608 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1614 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1615 i, r.in.function_code);
1617 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1618 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1625 try a netlogon DatabaseSync2
1627 static bool test_DatabaseSync2(struct torture_context *tctx,
1628 struct dcerpc_pipe *p,
1629 struct cli_credentials *machine_credentials)
1632 struct netr_DatabaseSync2 r;
1633 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1634 struct netr_Authenticator return_authenticator, credential;
1636 struct netlogon_creds_CredentialState *creds;
1637 const uint32_t database_ids[] = {0, 1, 2};
1640 if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
1641 machine_credentials,
1642 SEC_CHAN_BDC, &creds)) {
1646 ZERO_STRUCT(return_authenticator);
1648 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1649 r.in.computername = TEST_MACHINE_NAME;
1650 r.in.preferredmaximumlength = (uint32_t)-1;
1651 r.in.return_authenticator = &return_authenticator;
1652 r.out.return_authenticator = &return_authenticator;
1653 r.out.delta_enum_array = &delta_enum_array;
1655 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1657 uint32_t sync_context = 0;
1659 r.in.database_id = database_ids[i];
1660 r.in.sync_context = &sync_context;
1661 r.out.sync_context = &sync_context;
1662 r.in.restart_state = 0;
1664 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
1667 netlogon_creds_client_authenticator(creds, &credential);
1669 r.in.credential = &credential;
1671 status = dcerpc_netr_DatabaseSync2(p, tctx, &r);
1672 if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
1675 /* Native mode servers don't do this */
1676 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1680 torture_assert_ntstatus_ok(tctx, status, "DatabaseSync2");
1682 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1683 torture_comment(tctx, "Credential chaining failed\n");
1686 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
1694 try a netlogon LogonControl2Ex
1696 static bool test_LogonControl2Ex(struct torture_context *tctx,
1697 struct dcerpc_pipe *p)
1700 struct netr_LogonControl2Ex r;
1701 union netr_CONTROL_DATA_INFORMATION data;
1702 union netr_CONTROL_QUERY_INFORMATION query;
1705 data.domain = lp_workgroup(tctx->lp_ctx);
1707 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1709 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1711 r.out.query = &query;
1716 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
1717 i, r.in.function_code);
1719 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1720 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1723 data.domain = lp_workgroup(tctx->lp_ctx);
1725 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1731 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
1732 i, r.in.function_code);
1734 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1735 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1738 data.domain = lp_workgroup(tctx->lp_ctx);
1740 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1746 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
1747 i, r.in.function_code);
1749 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1750 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1753 data.debug_level = ~0;
1755 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1761 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
1762 i, r.in.function_code);
1764 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1765 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1771 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
1772 struct dcerpc_pipe *p, const char *trusted_domain_name)
1775 struct netr_DsRGetForestTrustInformation r;
1776 struct lsa_ForestTrustInformation info, *info_ptr;
1780 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1781 r.in.trusted_domain_name = trusted_domain_name;
1783 r.out.forest_trust_info = &info_ptr;
1785 torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
1787 status = dcerpc_netr_DsRGetForestTrustInformation(p, tctx, &r);
1788 torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
1789 torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
1795 try a netlogon netr_DsrEnumerateDomainTrusts
1797 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
1798 struct dcerpc_pipe *p)
1801 struct netr_DsrEnumerateDomainTrusts r;
1802 struct netr_DomainTrustList trusts;
1805 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1806 r.in.trust_flags = 0x3f;
1807 r.out.trusts = &trusts;
1809 status = dcerpc_netr_DsrEnumerateDomainTrusts(p, tctx, &r);
1810 torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
1811 torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
1813 /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
1814 * will show non-forest trusts and all UPN suffixes of the own forest
1815 * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
1817 if (r.out.trusts->count) {
1818 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
1823 for (i=0; i<r.out.trusts->count; i++) {
1825 /* get info for transitive forest trusts */
1827 if (r.out.trusts->array[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
1828 if (!test_netr_DsRGetForestTrustInformation(tctx, p,
1829 r.out.trusts->array[i].dns_name)) {
1838 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
1839 struct dcerpc_pipe *p)
1842 struct netr_NetrEnumerateTrustedDomains r;
1843 struct netr_Blob trusted_domains_blob;
1845 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1846 r.out.trusted_domains_blob = &trusted_domains_blob;
1848 status = dcerpc_netr_NetrEnumerateTrustedDomains(p, tctx, &r);
1849 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
1850 torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
1855 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
1856 struct dcerpc_pipe *p)
1859 struct netr_NetrEnumerateTrustedDomainsEx r;
1860 struct netr_DomainTrustList dom_trust_list;
1862 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1863 r.out.dom_trust_list = &dom_trust_list;
1865 status = dcerpc_netr_NetrEnumerateTrustedDomainsEx(p, tctx, &r);
1866 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
1867 torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
1873 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
1874 const char *computer_name,
1875 const char *expected_site)
1878 struct netr_DsRGetSiteName r;
1879 const char *site = NULL;
1881 if (torture_setting_bool(tctx, "samba4", false))
1882 torture_skip(tctx, "skipping DsRGetSiteName test against Samba4");
1884 r.in.computer_name = computer_name;
1886 torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
1888 status = dcerpc_netr_DsRGetSiteName(p, tctx, &r);
1889 torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
1890 torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
1891 torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
1893 r.in.computer_name = talloc_asprintf(tctx, "\\\\%s", computer_name);
1894 torture_comment(tctx,
1895 "Testing netr_DsRGetSiteName with broken computer name: %s\n", r.in.computer_name);
1897 status = dcerpc_netr_DsRGetSiteName(p, tctx, &r);
1898 torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
1899 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_COMPUTERNAME, "netr_DsRGetSiteName");
1905 try a netlogon netr_DsRGetDCName
1907 static bool test_netr_DsRGetDCName(struct torture_context *tctx,
1908 struct dcerpc_pipe *p)
1911 struct netr_DsRGetDCName r;
1912 struct netr_DsRGetDCNameInfo *info = NULL;
1914 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1915 r.in.domain_name = talloc_asprintf(tctx, "%s", lp_realm(tctx->lp_ctx));
1916 r.in.domain_guid = NULL;
1917 r.in.site_guid = NULL;
1918 r.in.flags = DS_RETURN_DNS_NAME;
1921 status = dcerpc_netr_DsRGetDCName(p, tctx, &r);
1922 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
1923 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
1924 return test_netr_DsRGetSiteName(p, tctx,
1926 info->dc_site_name);
1930 try a netlogon netr_DsRGetDCNameEx
1932 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
1933 struct dcerpc_pipe *p)
1936 struct netr_DsRGetDCNameEx r;
1937 struct netr_DsRGetDCNameInfo *info = NULL;
1939 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1940 r.in.domain_name = talloc_asprintf(tctx, "%s", lp_realm(tctx->lp_ctx));
1941 r.in.domain_guid = NULL;
1942 r.in.site_name = NULL;
1943 r.in.flags = DS_RETURN_DNS_NAME;
1946 status = dcerpc_netr_DsRGetDCNameEx(p, tctx, &r);
1947 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
1948 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
1950 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
1951 info->dc_site_name);
1955 try a netlogon netr_DsRGetDCNameEx2
1957 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
1958 struct dcerpc_pipe *p)
1961 struct netr_DsRGetDCNameEx2 r;
1962 struct netr_DsRGetDCNameInfo *info = NULL;
1964 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1965 r.in.client_account = NULL;
1966 r.in.mask = 0x00000000;
1967 r.in.domain_name = talloc_asprintf(tctx, "%s", lp_realm(tctx->lp_ctx));
1968 r.in.domain_guid = NULL;
1969 r.in.site_name = NULL;
1970 r.in.flags = DS_RETURN_DNS_NAME;
1973 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
1975 status = dcerpc_netr_DsRGetDCNameEx2(p, tctx, &r);
1976 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
1977 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
1979 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client acount\n");
1980 r.in.client_account = TEST_MACHINE_NAME"$";
1981 r.in.mask = ACB_SVRTRUST;
1982 r.in.flags = DS_RETURN_FLAT_NAME;
1985 status = dcerpc_netr_DsRGetDCNameEx2(p, tctx, &r);
1986 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
1987 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
1988 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
1989 info->dc_site_name);
1992 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
1993 struct dcerpc_pipe *p)
1996 struct netr_DsrGetDcSiteCoverageW r;
1997 struct DcSitesCtr *ctr = NULL;
1999 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2002 status = dcerpc_netr_DsrGetDcSiteCoverageW(p, tctx, &r);
2003 torture_assert_ntstatus_ok(tctx, status, "failed");
2004 torture_assert_werr_ok(tctx, r.out.result, "failed");
2009 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
2010 struct dcerpc_pipe *p)
2013 struct netr_DsRAddressToSitenamesW r;
2014 struct netr_DsRAddress addr;
2015 struct netr_DsRAddressToSitenamesWCtr *ctr;
2017 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
2020 addr.buffer = talloc_zero_array(tctx, uint8_t, addr.size);
2022 addr.buffer[0] = 2; /* AF_INET */
2023 addr.buffer[4] = 127;
2028 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2030 r.in.addresses = talloc_zero_array(tctx, struct netr_DsRAddress, r.in.count);
2031 r.in.addresses[0] = addr;
2034 status = dcerpc_netr_DsRAddressToSitenamesW(p, tctx, &r);
2035 torture_assert_ntstatus_ok(tctx, status, "failed");
2036 torture_assert_werr_ok(tctx, r.out.result, "failed");
2041 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
2042 struct dcerpc_pipe *p)
2045 struct netr_DsRAddressToSitenamesExW r;
2046 struct netr_DsRAddress addr;
2047 struct netr_DsRAddressToSitenamesExWCtr *ctr;
2049 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
2052 addr.buffer = talloc_zero_array(tctx, uint8_t, addr.size);
2054 addr.buffer[0] = 2; /* AF_INET */
2055 addr.buffer[4] = 127;
2060 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2062 r.in.addresses = talloc_zero_array(tctx, struct netr_DsRAddress, r.in.count);
2063 r.in.addresses[0] = addr;
2066 status = dcerpc_netr_DsRAddressToSitenamesExW(p, tctx, &r);
2067 torture_assert_ntstatus_ok(tctx, status, "failed");
2068 torture_assert_werr_ok(tctx, r.out.result, "failed");
2073 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
2074 struct dcerpc_pipe *p,
2075 struct cli_credentials *machine_credentials)
2078 struct netr_ServerGetTrustInfo r;
2080 struct netr_Authenticator a;
2081 struct netr_Authenticator return_authenticator;
2082 struct samr_Password new_owf_password;
2083 struct samr_Password old_owf_password;
2084 struct netr_TrustInfo *trust_info;
2086 struct netlogon_creds_CredentialState *creds;
2088 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2089 machine_credentials, &creds)) {
2093 netlogon_creds_client_authenticator(creds, &a);
2095 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2096 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
2097 r.in.secure_channel_type = SEC_CHAN_BDC;
2098 r.in.computer_name = TEST_MACHINE_NAME;
2099 r.in.credential = &a;
2101 r.out.return_authenticator = &return_authenticator;
2102 r.out.new_owf_password = &new_owf_password;
2103 r.out.old_owf_password = &old_owf_password;
2104 r.out.trust_info = &trust_info;
2106 status = dcerpc_netr_ServerGetTrustInfo(p, tctx, &r);
2107 torture_assert_ntstatus_ok(tctx, status, "failed");
2108 torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
2114 static bool test_GetDomainInfo(struct torture_context *tctx,
2115 struct dcerpc_pipe *p,
2116 struct cli_credentials *machine_credentials)
2119 struct netr_LogonGetDomainInfo r;
2120 struct netr_WorkstationInformation q1;
2121 struct netr_Authenticator a;
2122 struct netlogon_creds_CredentialState *creds;
2123 struct netr_OsVersion os;
2124 union netr_WorkstationInfo query;
2125 union netr_DomainInfo info;
2126 const char* const attrs[] = { "dNSHostName", "operatingSystem",
2127 "operatingSystemServicePack", "operatingSystemVersion",
2128 "servicePrincipalName", NULL };
2130 struct ldb_context *sam_ctx;
2131 struct ldb_message **res;
2132 struct ldb_message_element *spn_el;
2135 const char *old_dnsname;
2140 torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
2142 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2143 machine_credentials, &creds)) {
2147 /* Set up connection to SAMDB on DC */
2148 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2149 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2151 cmdline_credentials,
2154 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2157 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
2158 netlogon_creds_client_authenticator(creds, &a);
2161 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2162 r.in.computer_name = TEST_MACHINE_NAME;
2163 r.in.credential = &a;
2165 r.in.return_authenticator = &a;
2166 r.in.query = &query;
2167 r.out.return_authenticator = &a;
2171 os.os.MajorVersion = SAMBA_VERSION_MAJOR;
2172 os.os.MinorVersion = SAMBA_VERSION_MINOR;
2173 os.os.BuildNumber = SAMBA_VERSION_RELEASE;
2174 os.os.CSDVersion = "Service Pack 1";
2175 os.os.ServicePackMajor = 1;
2176 os.os.ServicePackMinor = 0;
2177 os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
2178 os.os.ProductType = NETR_VER_NT_SERVER;
2181 version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
2182 os.os.MinorVersion, os.os.BuildNumber);
2185 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
2186 TEST_MACHINE_DNS_SUFFIX);
2187 q1.sitename = "Default-First-Site-Name";
2188 q1.os_version.os = &os;
2189 q1.os_name.string = "UNIX/Linux or similar";
2191 /* The workstation handles the "servicePrincipalName" and DNS hostname
2193 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
2195 query.workstation_info = &q1;
2197 /* Gets back the old DNS hostname in AD */
2198 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2199 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2201 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
2203 /* Gets back the "servicePrincipalName"s in AD */
2204 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2205 if (spn_el != NULL) {
2206 for (i=0; i < spn_el->num_values; i++) {
2207 spns = talloc_realloc(tctx, spns, char *, i + 1);
2208 spns[i] = (char *) spn_el->values[i].data;
2213 status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2214 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2215 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2219 /* AD workstation infos entry check */
2220 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2221 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2222 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
2223 torture_assert_str_equal(tctx,
2224 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
2225 q1.os_name.string, "'operatingSystem' wrong!");
2226 torture_assert_str_equal(tctx,
2227 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
2228 os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
2229 torture_assert_str_equal(tctx,
2230 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
2231 version_str, "'operatingSystemVersion' wrong!");
2233 if (old_dnsname != NULL) {
2234 /* If before a DNS hostname was set then it should remain
2235 the same in combination with the "servicePrincipalName"s.
2236 The DNS hostname should also be returned by our
2237 "LogonGetDomainInfo" call (in the domain info structure). */
2239 torture_assert_str_equal(tctx,
2240 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
2241 old_dnsname, "'DNS hostname' was not set!");
2243 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2244 torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
2245 "'servicePrincipalName's not set!");
2246 torture_assert(tctx, spn_el->num_values == num_spns,
2247 "'servicePrincipalName's incorrect!");
2248 for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
2249 torture_assert_str_equal(tctx,
2250 (char *) spn_el->values[i].data,
2251 spns[i], "'servicePrincipalName's incorrect!");
2253 torture_assert_str_equal(tctx,
2254 info.domain_info->dns_hostname.string,
2256 "Out 'DNS hostname' doesn't match the old one!");
2258 /* If no DNS hostname was set then also now none should be set,
2259 the "servicePrincipalName"s should remain empty and no DNS
2260 hostname should be returned by our "LogonGetDomainInfo"
2261 call (in the domain info structure). */
2263 torture_assert(tctx,
2264 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
2265 "'DNS hostname' was set!");
2267 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2268 torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
2269 "'servicePrincipalName's were set!");
2271 torture_assert(tctx,
2272 info.domain_info->dns_hostname.string == NULL,
2273 "Out 'DNS host name' was set!");
2276 /* Checks "workstation flags" */
2277 torture_assert(tctx,
2278 info.domain_info->workstation_flags
2279 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
2280 "Out 'workstation flags' don't match!");
2283 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname)\n");
2284 netlogon_creds_client_authenticator(creds, &a);
2286 /* Wipe out the osVersion, and prove which values still 'stick' */
2287 q1.os_version.os = NULL;
2289 /* Change also the DNS hostname to test differences in behaviour */
2290 q1.dns_hostname = talloc_asprintf(tctx, "%s.newdomain",
2293 /* Let the DC handle the "servicePrincipalName" and DNS hostname
2295 q1.workstation_flags = 0;
2297 status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2298 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2299 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2303 /* AD workstation infos entry check */
2304 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2305 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2306 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
2307 torture_assert_str_equal(tctx,
2308 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
2309 q1.os_name.string, "'operatingSystem' should stick!");
2310 torture_assert(tctx,
2311 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
2312 "'operatingSystemServicePack' shouldn't stick!");
2313 torture_assert(tctx,
2314 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
2315 "'operatingSystemVersion' shouldn't stick!");
2317 /* The DNS host name should have been updated now by the server */
2318 torture_assert_str_equal(tctx,
2319 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
2320 q1.dns_hostname, "'DNS host name' didn't change!");
2322 /* Find the two "servicePrincipalName"s which the DC should have been
2323 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
2325 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2326 torture_assert(tctx, spn_el != NULL,
2327 "There should exist 'servicePrincipalName's in AD!");
2328 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
2329 for (i=0; i < spn_el->num_values; i++)
2330 if (strcmp((char *) spn_el->values[i].data, temp_str) == 0)
2332 torture_assert(tctx, i != spn_el->num_values,
2333 "'servicePrincipalName' HOST/<Netbios name> not found!");
2334 temp_str = talloc_asprintf(tctx, "HOST/%s", q1.dns_hostname);
2335 for (i=0; i < spn_el->num_values; i++)
2336 if (strcmp((char *) spn_el->values[i].data, temp_str) == 0)
2338 torture_assert(tctx, i != spn_el->num_values,
2339 "'servicePrincipalName' HOST/<FQDN name> not found!");
2341 /* Check that the out DNS hostname was set properly */
2342 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
2343 old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
2345 /* Checks "workstation flags" */
2346 torture_assert(tctx,
2347 info.domain_info->workstation_flags == 0,
2348 "Out 'workstation flags' don't match!");
2351 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (verification of DNS hostname and check for trusted domains)\n");
2352 netlogon_creds_client_authenticator(creds, &a);
2354 /* The workstation handles the "servicePrincipalName" and DNS hostname
2356 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
2358 status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2359 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2360 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2364 /* Now the in/out DNS hostnames should be the same */
2365 torture_assert_str_equal(tctx,
2366 info.domain_info->dns_hostname.string,
2367 query.workstation_info->dns_hostname,
2368 "In/Out 'DNS hostnames' don't match!");
2370 /* Checks "workstation flags" */
2371 torture_assert(tctx,
2372 info.domain_info->workstation_flags
2373 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
2374 "Out 'workstation flags' don't match!");
2376 /* Checks for trusted domains */
2377 torture_assert(tctx,
2378 (info.domain_info->trusted_domain_count != 0)
2379 && (info.domain_info->trusted_domains != NULL),
2380 "Trusted domains have been requested!");
2383 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (check for trusted domains)\n");
2384 netlogon_creds_client_authenticator(creds, &a);
2386 /* The workstation handles the "servicePrincipalName" and DNS hostname
2387 updates and requests inbound trusts */
2388 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
2389 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
2391 status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2392 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2393 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2397 /* Checks "workstation flags" */
2398 torture_assert(tctx,
2399 info.domain_info->workstation_flags
2400 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
2401 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
2402 "Out 'workstation flags' don't match!");
2404 /* Checks for trusted domains */
2405 torture_assert(tctx,
2406 (info.domain_info->trusted_domain_count != 0)
2407 && (info.domain_info->trusted_domains != NULL),
2408 "Trusted domains have been requested!");
2414 static void async_callback(struct rpc_request *req)
2416 int *counter = (int *)req->async.private_data;
2417 if (NT_STATUS_IS_OK(req->status)) {
2422 static bool test_GetDomainInfo_async(struct torture_context *tctx,
2423 struct dcerpc_pipe *p,
2424 struct cli_credentials *machine_credentials)
2427 struct netr_LogonGetDomainInfo r;
2428 struct netr_WorkstationInformation q1;
2429 struct netr_Authenticator a;
2430 #define ASYNC_COUNT 100
2431 struct netlogon_creds_CredentialState *creds;
2432 struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
2433 struct rpc_request *req[ASYNC_COUNT];
2435 int *async_counter = talloc(tctx, int);
2436 union netr_WorkstationInfo query;
2437 union netr_DomainInfo info;
2439 torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
2441 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2442 machine_credentials, &creds)) {
2447 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2448 r.in.computer_name = TEST_MACHINE_NAME;
2449 r.in.credential = &a;
2451 r.in.return_authenticator = &a;
2452 r.in.query = &query;
2453 r.out.return_authenticator = &a;
2457 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
2458 TEST_MACHINE_DNS_SUFFIX);
2459 q1.sitename = "Default-First-Site-Name";
2460 q1.os_name.string = "UNIX/Linux or similar";
2462 query.workstation_info = &q1;
2466 for (i=0;i<ASYNC_COUNT;i++) {
2467 netlogon_creds_client_authenticator(creds, &a);
2469 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
2470 req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, tctx, &r);
2472 req[i]->async.callback = async_callback;
2473 req[i]->async.private_data = async_counter;
2475 /* even with this flush per request a w2k3 server seems to
2476 clag with multiple outstanding requests. bleergh. */
2477 torture_assert_int_equal(tctx, event_loop_once(dcerpc_event_context(p)), 0,
2478 "event_loop_once failed");
2481 for (i=0;i<ASYNC_COUNT;i++) {
2482 status = dcerpc_ndr_request_recv(req[i]);
2484 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
2485 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
2487 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred),
2488 "Credential chaining failed at async");
2491 torture_comment(tctx,
2492 "Testing netr_LogonGetDomainInfo - async count %d OK\n", *async_counter);
2494 torture_assert_int_equal(tctx, (*async_counter), ASYNC_COUNT, "int");
2499 static bool test_ManyGetDCName(struct torture_context *tctx,
2500 struct dcerpc_pipe *p)
2503 struct dcerpc_pipe *p2;
2504 struct lsa_ObjectAttribute attr;
2505 struct lsa_QosInfo qos;
2506 struct lsa_OpenPolicy2 o;
2507 struct policy_handle lsa_handle;
2508 struct lsa_DomainList domains;
2510 struct lsa_EnumTrustDom t;
2511 uint32_t resume_handle = 0;
2512 struct netr_GetAnyDCName d;
2513 const char *dcname = NULL;
2517 if (p->conn->transport.transport != NCACN_NP) {
2521 torture_comment(tctx, "Torturing GetDCName\n");
2523 status = dcerpc_secondary_connection(p, &p2, p->binding);
2524 torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
2526 status = dcerpc_bind_auth_none(p2, &ndr_table_lsarpc);
2527 torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
2530 qos.impersonation_level = 2;
2531 qos.context_mode = 1;
2532 qos.effective_only = 0;
2535 attr.root_dir = NULL;
2536 attr.object_name = NULL;
2537 attr.attributes = 0;
2538 attr.sec_desc = NULL;
2539 attr.sec_qos = &qos;
2541 o.in.system_name = "\\";
2543 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2544 o.out.handle = &lsa_handle;
2546 status = dcerpc_lsa_OpenPolicy2(p2, tctx, &o);
2547 torture_assert_ntstatus_ok(tctx, status, "OpenPolicy2 failed");
2549 t.in.handle = &lsa_handle;
2550 t.in.resume_handle = &resume_handle;
2551 t.in.max_size = 1000;
2552 t.out.domains = &domains;
2553 t.out.resume_handle = &resume_handle;
2555 status = dcerpc_lsa_EnumTrustDom(p2, tctx, &t);
2557 if ((!NT_STATUS_IS_OK(status) &&
2558 (!NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES))))
2559 torture_fail(tctx, "Could not list domains");
2563 d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
2564 dcerpc_server_name(p));
2565 d.out.dcname = &dcname;
2567 for (i=0; i<domains.count * 4; i++) {
2568 struct lsa_DomainInfo *info =
2569 &domains.domains[rand()%domains.count];
2571 d.in.domainname = info->name.string;
2573 status = dcerpc_netr_GetAnyDCName(p, tctx, &d);
2574 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2576 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
2577 dcname ? dcname : "unknown");
2583 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
2585 struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON");
2586 struct torture_rpc_tcase *tcase;
2587 struct torture_test *test;
2589 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
2590 &ndr_table_netlogon, TEST_MACHINE_NAME);
2592 torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
2593 torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
2594 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
2595 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
2596 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
2597 torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
2598 torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
2599 torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
2600 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
2601 torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
2602 torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
2603 torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
2604 torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
2605 torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
2606 torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
2607 torture_rpc_tcase_add_test(tcase, "LogonControl", test_LogonControl);
2608 torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
2609 torture_rpc_tcase_add_test(tcase, "LogonControl2", test_LogonControl2);
2610 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
2611 torture_rpc_tcase_add_test(tcase, "LogonControl2Ex", test_LogonControl2Ex);
2612 torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
2613 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
2614 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
2615 test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
2616 test->dangerous = true;
2617 torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
2618 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
2619 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
2620 torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
2621 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
2622 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
2623 torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);