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-2010
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/>.
26 #include "lib/events/events.h"
27 #include "lib/cmdline/popt_common.h"
28 #include "torture/rpc/torture_rpc.h"
29 #include "../lib/crypto/crypto.h"
30 #include "libcli/auth/libcli_auth.h"
31 #include "librpc/gen_ndr/ndr_netlogon_c.h"
32 #include "librpc/gen_ndr/ndr_lsa_c.h"
33 #include "param/param.h"
34 #include "libcli/security/security.h"
36 #include "lib/util/util_ldb.h"
38 #include "lib/replace/system/network.h"
39 #include "dsdb/samdb/samdb.h"
43 #define TEST_MACHINE_NAME "torturetest"
45 static bool test_netr_broken_binding_handle(struct torture_context *tctx,
46 struct dcerpc_pipe *p)
49 struct netr_DsRGetSiteName r;
50 const char *site = NULL;
51 struct dcerpc_binding_handle *b = p->binding_handle;
53 r.in.computer_name = talloc_asprintf(tctx, "\\\\%s",
54 dcerpc_server_name(p));
58 "Testing netlogon request with correct binding handle: %s\n",
61 status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
62 torture_assert_ntstatus_ok(tctx, status,
63 "Netlogon request with broken binding handle");
64 torture_assert_werr_ok(tctx, r.out.result,
65 "Netlogon request with broken binding handle");
67 if (torture_setting_bool(tctx, "samba3", false) ||
68 torture_setting_bool(tctx, "samba4", false)) {
70 "Skipping broken binding handle check against Samba");
73 r.in.computer_name = talloc_asprintf(tctx, "\\\\\\\\%s",
74 dcerpc_server_name(p));
77 "Testing netlogon request with broken binding handle: %s\n",
80 status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
81 torture_assert_ntstatus_ok(tctx, status,
82 "Netlogon request with broken binding handle");
83 torture_assert_werr_equal(tctx, r.out.result,
84 WERR_INVALID_COMPUTERNAME,
85 "Netlogon request with broken binding handle");
87 r.in.computer_name = "\\\\\\\\THIS_IS_NOT_VALID";
90 "Testing netlogon request with broken binding handle: %s\n",
93 status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
94 torture_assert_ntstatus_ok(tctx, status,
95 "Netlogon request with broken binding handle");
96 torture_assert_werr_equal(tctx, r.out.result,
97 WERR_INVALID_COMPUTERNAME,
98 "Netlogon request with broken binding handle");
103 static bool test_LogonUasLogon(struct torture_context *tctx,
104 struct dcerpc_pipe *p)
107 struct netr_LogonUasLogon r;
108 struct netr_UasInfo *info = NULL;
109 struct dcerpc_binding_handle *b = p->binding_handle;
111 r.in.server_name = NULL;
112 r.in.account_name = cli_credentials_get_username(
113 popt_get_cmdline_credentials());
114 r.in.workstation = TEST_MACHINE_NAME;
117 status = dcerpc_netr_LogonUasLogon_r(b, tctx, &r);
118 torture_assert_ntstatus_ok(tctx, status, "LogonUasLogon");
123 static bool test_LogonUasLogoff(struct torture_context *tctx,
124 struct dcerpc_pipe *p)
127 struct netr_LogonUasLogoff r;
128 struct netr_UasLogoffInfo info;
129 struct dcerpc_binding_handle *b = p->binding_handle;
131 r.in.server_name = NULL;
132 r.in.account_name = cli_credentials_get_username(
133 popt_get_cmdline_credentials());
134 r.in.workstation = TEST_MACHINE_NAME;
137 status = dcerpc_netr_LogonUasLogoff_r(b, tctx, &r);
138 torture_assert_ntstatus_ok(tctx, status, "LogonUasLogoff");
143 bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
144 struct cli_credentials *credentials,
145 struct netlogon_creds_CredentialState **creds_out)
147 struct netr_ServerReqChallenge r;
148 struct netr_ServerAuthenticate a;
149 struct netr_Credential credentials1, credentials2, credentials3;
150 struct netlogon_creds_CredentialState *creds;
151 const struct samr_Password *mach_password;
152 const char *machine_name;
153 struct dcerpc_binding_handle *b = p->binding_handle;
155 mach_password = cli_credentials_get_nt_hash(credentials, tctx);
156 machine_name = cli_credentials_get_workstation(credentials);
158 torture_comment(tctx, "Testing ServerReqChallenge\n");
160 r.in.server_name = NULL;
161 r.in.computer_name = machine_name;
162 r.in.credentials = &credentials1;
163 r.out.return_credentials = &credentials2;
165 netlogon_creds_random_challenge(&credentials1);
167 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
168 "ServerReqChallenge failed");
169 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
171 a.in.server_name = NULL;
172 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
173 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(credentials);
174 a.in.computer_name = machine_name;
175 a.in.credentials = &credentials3;
176 a.out.return_credentials = &credentials3;
178 creds = netlogon_creds_client_init(tctx, a.in.account_name,
180 a.in.secure_channel_type,
181 &credentials1, &credentials2,
182 mach_password, &credentials3,
184 torture_assert(tctx, creds != NULL, "memory allocation");
187 torture_comment(tctx, "Testing ServerAuthenticate\n");
189 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate_r(b, tctx, &a),
190 "ServerAuthenticate failed");
192 /* This allows the tests to continue against the more fussy windows 2008 */
193 if (NT_STATUS_EQUAL(a.out.result, NT_STATUS_DOWNGRADE_DETECTED)) {
194 return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
196 cli_credentials_get_secure_channel_type(credentials),
200 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate");
202 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
203 "Credential chaining failed");
209 bool test_SetupCredentials2ex(struct dcerpc_pipe *p, struct torture_context *tctx,
210 uint32_t negotiate_flags,
211 struct cli_credentials *machine_credentials,
212 const char *computer_name,
213 enum netr_SchannelType sec_chan_type,
214 NTSTATUS expected_result,
215 struct netlogon_creds_CredentialState **creds_out)
217 struct netr_ServerReqChallenge r;
218 struct netr_ServerAuthenticate2 a;
219 struct netr_Credential credentials1, credentials2, credentials3;
220 struct netlogon_creds_CredentialState *creds;
221 const struct samr_Password *mach_password;
222 struct dcerpc_binding_handle *b = p->binding_handle;
223 const char *account_name = cli_credentials_get_username(machine_credentials);
225 mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
227 torture_comment(tctx, "Testing ServerReqChallenge\n");
229 r.in.server_name = NULL;
230 r.in.computer_name = computer_name;
231 r.in.credentials = &credentials1;
232 r.out.return_credentials = &credentials2;
234 netlogon_creds_random_challenge(&credentials1);
236 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
237 "ServerReqChallenge failed");
238 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
240 a.in.server_name = NULL;
241 a.in.account_name = account_name;
242 a.in.secure_channel_type = sec_chan_type;
243 a.in.computer_name = computer_name;
244 a.in.negotiate_flags = &negotiate_flags;
245 a.out.negotiate_flags = &negotiate_flags;
246 a.in.credentials = &credentials3;
247 a.out.return_credentials = &credentials3;
249 creds = netlogon_creds_client_init(tctx, a.in.account_name,
251 a.in.secure_channel_type,
252 &credentials1, &credentials2,
253 mach_password, &credentials3,
256 torture_assert(tctx, creds != NULL, "memory allocation");
258 torture_comment(tctx, "Testing ServerAuthenticate2\n");
260 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
261 "ServerAuthenticate2 failed");
262 torture_assert_ntstatus_equal(tctx, a.out.result, expected_result,
263 "ServerAuthenticate2 unexpected");
265 if (NT_STATUS_IS_OK(expected_result)) {
266 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
267 "Credential chaining failed");
269 torture_assert(tctx, !netlogon_creds_client_check(creds, &credentials3),
270 "Credential chaining passed unexptected");
273 torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
279 bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx,
280 uint32_t negotiate_flags,
281 struct cli_credentials *machine_credentials,
282 enum netr_SchannelType sec_chan_type,
283 struct netlogon_creds_CredentialState **creds_out)
285 const char *computer_name =
286 cli_credentials_get_workstation(machine_credentials);
288 return test_SetupCredentials2ex(p, tctx, negotiate_flags,
296 bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx,
297 uint32_t negotiate_flags,
298 struct cli_credentials *machine_credentials,
299 struct netlogon_creds_CredentialState **creds_out)
301 struct netr_ServerReqChallenge r;
302 struct netr_ServerAuthenticate3 a;
303 struct netr_Credential credentials1, credentials2, credentials3;
304 struct netlogon_creds_CredentialState *creds;
305 struct samr_Password mach_password;
307 const char *machine_name;
308 const char *plain_pass;
309 struct dcerpc_binding_handle *b = NULL;
315 b = p->binding_handle;
317 machine_name = cli_credentials_get_workstation(machine_credentials);
318 torture_assert(tctx, machine_name != NULL, "machine_name");
319 plain_pass = cli_credentials_get_password(machine_credentials);
320 torture_assert(tctx, plain_pass != NULL, "plain_pass");
322 torture_comment(tctx, "Testing ServerReqChallenge\n");
324 r.in.server_name = NULL;
325 r.in.computer_name = machine_name;
326 r.in.credentials = &credentials1;
327 r.out.return_credentials = &credentials2;
329 netlogon_creds_random_challenge(&credentials1);
331 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
332 "ServerReqChallenge failed");
333 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
335 E_md4hash(plain_pass, mach_password.hash);
337 a.in.server_name = NULL;
338 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
339 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
340 a.in.computer_name = machine_name;
341 a.in.negotiate_flags = &negotiate_flags;
342 a.in.credentials = &credentials3;
343 a.out.return_credentials = &credentials3;
344 a.out.negotiate_flags = &negotiate_flags;
347 creds = netlogon_creds_client_init(tctx, a.in.account_name,
349 a.in.secure_channel_type,
350 &credentials1, &credentials2,
351 &mach_password, &credentials3,
354 torture_assert(tctx, creds != NULL, "memory allocation");
356 torture_comment(tctx, "Testing ServerAuthenticate3\n");
358 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
359 "ServerAuthenticate3 failed");
360 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed");
361 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
363 torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
365 /* Prove that requesting a challenge again won't break it */
366 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
367 "ServerReqChallenge failed");
368 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
374 bool test_SetupCredentialsDowngrade(struct torture_context *tctx,
375 struct dcerpc_pipe *p,
376 struct cli_credentials *machine_credentials)
378 struct netr_ServerReqChallenge r;
379 struct netr_ServerAuthenticate3 a;
380 struct netr_Credential credentials1, credentials2, credentials3;
381 struct netlogon_creds_CredentialState *creds;
382 struct samr_Password mach_password;
384 const char *machine_name;
385 const char *plain_pass;
386 struct dcerpc_binding_handle *b = p->binding_handle;
387 uint32_t negotiate_flags = 0;
389 machine_name = cli_credentials_get_workstation(machine_credentials);
390 torture_assert(tctx, machine_name != NULL, "machine_name");
391 plain_pass = cli_credentials_get_password(machine_credentials);
392 torture_assert(tctx, plain_pass != NULL, "plain_pass");
394 torture_comment(tctx, "Testing ServerReqChallenge\n");
396 r.in.server_name = NULL;
397 r.in.computer_name = machine_name;
398 r.in.credentials = &credentials1;
399 r.out.return_credentials = &credentials2;
401 netlogon_creds_random_challenge(&credentials1);
403 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
404 "ServerReqChallenge failed");
405 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
407 E_md4hash(plain_pass, mach_password.hash);
409 a.in.server_name = NULL;
410 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
411 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
412 a.in.computer_name = machine_name;
413 a.in.negotiate_flags = &negotiate_flags;
414 a.in.credentials = &credentials3;
415 a.out.return_credentials = &credentials3;
416 a.out.negotiate_flags = &negotiate_flags;
419 creds = netlogon_creds_client_init(tctx, a.in.account_name,
421 a.in.secure_channel_type,
422 &credentials1, &credentials2,
423 &mach_password, &credentials3,
426 torture_assert(tctx, creds != NULL, "memory allocation");
428 torture_comment(tctx, "Testing ServerAuthenticate3\n");
430 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
431 "ServerAuthenticate3 failed");
432 torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_DOWNGRADE_DETECTED, "ServerAuthenticate3 should have failed");
434 negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
435 creds = netlogon_creds_client_init(tctx, a.in.account_name,
437 a.in.secure_channel_type,
438 &credentials1, &credentials2,
439 &mach_password, &credentials3,
442 torture_assert(tctx, creds != NULL, "memory allocation");
444 torture_comment(tctx, "Testing ServerAuthenticate3\n");
446 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
447 "ServerAuthenticate3 failed");
448 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 should succeed");
450 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
452 torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
454 /* Prove that requesting a challenge again won't break it */
455 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
456 "ServerReqChallenge failed");
457 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
462 bool test_SetupCredentialsPipe(const struct dcerpc_pipe *p1,
463 struct torture_context *tctx,
464 struct cli_credentials *machine_credentials,
465 struct netlogon_creds_CredentialState *creds,
466 uint32_t additional_flags,
467 struct dcerpc_pipe **_p2)
470 struct dcerpc_binding *b2 = NULL;
471 struct dcerpc_pipe *p2 = NULL;
473 b2 = dcerpc_binding_dup(tctx, p1->binding);
474 torture_assert(tctx, b2 != NULL, "dcerpc_binding_dup");
475 dcerpc_binding_set_flags(b2,
476 DCERPC_SCHANNEL | additional_flags,
477 DCERPC_AUTH_OPTIONS);
479 cli_credentials_set_netlogon_creds(machine_credentials, creds);
480 status = dcerpc_pipe_connect_b(tctx, &p2, b2,
483 tctx->ev, tctx->lp_ctx);
484 cli_credentials_set_netlogon_creds(machine_credentials, NULL);
485 torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b schannel");
491 static bool test_ServerReqChallenge(
492 struct torture_context *tctx,
493 struct dcerpc_pipe *p,
494 struct cli_credentials *credentials)
496 struct netr_ServerReqChallenge r;
497 struct netr_Credential credentials1, credentials2, credentials3;
498 const char *machine_name;
499 struct dcerpc_binding_handle *b = p->binding_handle;
500 struct netr_ServerAuthenticate2 a;
501 uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
502 uint32_t out_negotiate_flags = 0;
503 const struct samr_Password *mach_password = NULL;
504 enum netr_SchannelType sec_chan_type = 0;
505 struct netlogon_creds_CredentialState *creds = NULL;
506 const char *account_name = NULL;
508 machine_name = cli_credentials_get_workstation(credentials);
509 mach_password = cli_credentials_get_nt_hash(credentials, tctx);
510 account_name = cli_credentials_get_username(credentials);
511 sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
513 torture_comment(tctx, "Testing ServerReqChallenge\n");
515 r.in.server_name = NULL;
516 r.in.computer_name = machine_name;
517 r.in.credentials = &credentials1;
518 r.out.return_credentials = &credentials2;
520 netlogon_creds_random_challenge(&credentials1);
522 torture_assert_ntstatus_ok(
524 dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
525 "ServerReqChallenge failed");
526 torture_assert_ntstatus_ok(
529 "ServerReqChallenge failed");
530 a.in.server_name = NULL;
531 a.in.account_name = account_name;
532 a.in.secure_channel_type = sec_chan_type;
533 a.in.computer_name = machine_name;
534 a.in.negotiate_flags = &in_negotiate_flags;
535 a.out.negotiate_flags = &out_negotiate_flags;
536 a.in.credentials = &credentials3;
537 a.out.return_credentials = &credentials3;
539 creds = netlogon_creds_client_init(tctx, a.in.account_name,
541 a.in.secure_channel_type,
542 &credentials1, &credentials2,
543 mach_password, &credentials3,
546 torture_assert(tctx, creds != NULL, "memory allocation");
548 torture_comment(tctx, "Testing ServerAuthenticate2\n");
550 torture_assert_ntstatus_ok(
552 dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
553 "ServerAuthenticate2 failed");
554 torture_assert_ntstatus_equal(
558 "ServerAuthenticate2 unexpected");
563 static bool test_ServerReqChallenge_zero_challenge(
564 struct torture_context *tctx,
565 struct dcerpc_pipe *p,
566 struct cli_credentials *credentials)
568 struct netr_ServerReqChallenge r;
569 struct netr_Credential credentials1, credentials2, credentials3;
570 const char *machine_name;
571 struct dcerpc_binding_handle *b = p->binding_handle;
572 struct netr_ServerAuthenticate2 a;
573 uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
574 uint32_t out_negotiate_flags = 0;
575 const struct samr_Password *mach_password = NULL;
576 enum netr_SchannelType sec_chan_type = 0;
577 struct netlogon_creds_CredentialState *creds = NULL;
578 const char *account_name = NULL;
580 machine_name = cli_credentials_get_workstation(credentials);
581 mach_password = cli_credentials_get_nt_hash(credentials, tctx);
582 account_name = cli_credentials_get_username(credentials);
583 sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
585 torture_comment(tctx, "Testing ServerReqChallenge\n");
587 r.in.server_name = NULL;
588 r.in.computer_name = machine_name;
589 r.in.credentials = &credentials1;
590 r.out.return_credentials = &credentials2;
593 * Set the client challenge to zero, this should fail
594 * CVE-2020-1472(ZeroLogon)
595 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
597 ZERO_STRUCT(credentials1);
599 torture_assert_ntstatus_ok(
601 dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
602 "ServerReqChallenge failed");
603 torture_assert_ntstatus_ok(
606 "ServerReqChallenge failed");
607 a.in.server_name = NULL;
608 a.in.account_name = account_name;
609 a.in.secure_channel_type = sec_chan_type;
610 a.in.computer_name = machine_name;
611 a.in.negotiate_flags = &in_negotiate_flags;
612 a.out.negotiate_flags = &out_negotiate_flags;
613 a.in.credentials = &credentials3;
614 a.out.return_credentials = &credentials3;
616 creds = netlogon_creds_client_init(tctx, a.in.account_name,
618 a.in.secure_channel_type,
619 &credentials1, &credentials2,
620 mach_password, &credentials3,
623 torture_assert(tctx, creds != NULL, "memory allocation");
625 torture_comment(tctx, "Testing ServerAuthenticate2\n");
627 torture_assert_ntstatus_ok(
629 dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
630 "ServerAuthenticate2 failed");
631 torture_assert_ntstatus_equal(
634 NT_STATUS_ACCESS_DENIED,
635 "ServerAuthenticate2 unexpected");
640 static bool test_ServerReqChallenge_5_repeats(
641 struct torture_context *tctx,
642 struct dcerpc_pipe *p,
643 struct cli_credentials *credentials)
645 struct netr_ServerReqChallenge r;
646 struct netr_Credential credentials1, credentials2, credentials3;
647 const char *machine_name;
648 struct dcerpc_binding_handle *b = p->binding_handle;
649 struct netr_ServerAuthenticate2 a;
650 uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
651 uint32_t out_negotiate_flags = 0;
652 const struct samr_Password *mach_password = NULL;
653 enum netr_SchannelType sec_chan_type = 0;
654 struct netlogon_creds_CredentialState *creds = NULL;
655 const char *account_name = NULL;
657 machine_name = cli_credentials_get_workstation(credentials);
658 mach_password = cli_credentials_get_nt_hash(credentials, tctx);
659 account_name = cli_credentials_get_username(credentials);
660 sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
662 torture_comment(tctx, "Testing ServerReqChallenge\n");
664 r.in.server_name = NULL;
665 r.in.computer_name = machine_name;
666 r.in.credentials = &credentials1;
667 r.out.return_credentials = &credentials2;
670 * Set the first 5 bytes of the client challenge to the same value,
671 * this should fail CVE-2020-1472(ZeroLogon)
672 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
674 credentials1.data[0] = 'A';
675 credentials1.data[1] = 'A';
676 credentials1.data[2] = 'A';
677 credentials1.data[3] = 'A';
678 credentials1.data[4] = 'A';
679 credentials1.data[5] = 'B';
680 credentials1.data[6] = 'C';
681 credentials1.data[7] = 'D';
683 torture_assert_ntstatus_ok(
685 dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
686 "ServerReqChallenge failed");
687 torture_assert_ntstatus_ok(
690 "ServerReqChallenge failed");
691 a.in.server_name = NULL;
692 a.in.account_name = account_name;
693 a.in.secure_channel_type = sec_chan_type;
694 a.in.computer_name = machine_name;
695 a.in.negotiate_flags = &in_negotiate_flags;
696 a.out.negotiate_flags = &out_negotiate_flags;
697 a.in.credentials = &credentials3;
698 a.out.return_credentials = &credentials3;
700 creds = netlogon_creds_client_init(tctx, a.in.account_name,
702 a.in.secure_channel_type,
703 &credentials1, &credentials2,
704 mach_password, &credentials3,
707 torture_assert(tctx, creds != NULL, "memory allocation");
709 torture_comment(tctx, "Testing ServerAuthenticate2\n");
711 torture_assert_ntstatus_ok(
713 dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
714 "ServerAuthenticate2 failed");
715 torture_assert_ntstatus_equal(
718 NT_STATUS_ACCESS_DENIED,
719 "ServerAuthenticate2 unexpected");
724 static bool test_ServerReqChallenge_4_repeats(
725 struct torture_context *tctx,
726 struct dcerpc_pipe *p,
727 struct cli_credentials *credentials)
729 struct netr_ServerReqChallenge r;
730 struct netr_Credential credentials1, credentials2, credentials3;
731 const char *machine_name;
732 struct dcerpc_binding_handle *b = p->binding_handle;
733 struct netr_ServerAuthenticate2 a;
734 uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
735 uint32_t out_negotiate_flags = 0;
736 const struct samr_Password *mach_password = NULL;
737 enum netr_SchannelType sec_chan_type = 0;
738 struct netlogon_creds_CredentialState *creds = NULL;
739 const char *account_name = NULL;
741 machine_name = cli_credentials_get_workstation(credentials);
742 mach_password = cli_credentials_get_nt_hash(credentials, tctx);
743 account_name = cli_credentials_get_username(credentials);
744 sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
746 torture_comment(tctx, "Testing ServerReqChallenge\n");
748 r.in.server_name = NULL;
749 r.in.computer_name = machine_name;
750 r.in.credentials = &credentials1;
751 r.out.return_credentials = &credentials2;
754 * Set the first 4 bytes of the client challenge to the same
755 * value, this should pass as 5 bytes identical are needed to
756 * fail for CVE-2020-1472(ZeroLogon)
758 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
760 credentials1.data[0] = 'A';
761 credentials1.data[1] = 'A';
762 credentials1.data[2] = 'A';
763 credentials1.data[3] = 'A';
764 credentials1.data[4] = 'B';
765 credentials1.data[5] = 'C';
766 credentials1.data[6] = 'D';
767 credentials1.data[7] = 'E';
769 torture_assert_ntstatus_ok(
771 dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
772 "ServerReqChallenge failed");
773 torture_assert_ntstatus_ok(
776 "ServerReqChallenge failed");
777 a.in.server_name = NULL;
778 a.in.account_name = account_name;
779 a.in.secure_channel_type = sec_chan_type;
780 a.in.computer_name = machine_name;
781 a.in.negotiate_flags = &in_negotiate_flags;
782 a.out.negotiate_flags = &out_negotiate_flags;
783 a.in.credentials = &credentials3;
784 a.out.return_credentials = &credentials3;
786 creds = netlogon_creds_client_init(tctx, a.in.account_name,
788 a.in.secure_channel_type,
789 &credentials1, &credentials2,
790 mach_password, &credentials3,
793 torture_assert(tctx, creds != NULL, "memory allocation");
795 torture_comment(tctx, "Testing ServerAuthenticate2\n");
797 torture_assert_ntstatus_ok(
799 dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
800 "ServerAuthenticate2 failed");
801 torture_assert_ntstatus_equal(
805 "ServerAuthenticate2 unexpected");
811 * Establish a NetLogon session, using a session key that encrypts the
812 * target character to zero
814 static bool test_ServerAuthenticate2_encrypts_to_zero(
815 struct torture_context *tctx,
816 struct dcerpc_pipe *p,
817 struct cli_credentials *machine_credentials,
819 struct netlogon_creds_CredentialState **creds_out)
821 const char *computer_name =
822 cli_credentials_get_workstation(machine_credentials);
823 struct netr_ServerReqChallenge r;
824 struct netr_ServerAuthenticate2 a;
825 struct netr_Credential credentials1, credentials2, credentials3;
826 struct netlogon_creds_CredentialState *creds = NULL;
827 const struct samr_Password *mach_password;
828 struct dcerpc_binding_handle *b = p->binding_handle;
829 const char *account_name = cli_credentials_get_username(
830 machine_credentials);
832 NETLOGON_NEG_AUTH2_ADS_FLAGS |
833 NETLOGON_NEG_SUPPORTS_AES;
834 enum netr_SchannelType sec_chan_type =
835 cli_credentials_get_secure_channel_type(machine_credentials);
837 * Limit the number of attempts to generate a suitable session key.
839 const unsigned MAX_ITER = 4096;
842 mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
844 r.in.server_name = NULL;
845 r.in.computer_name = computer_name;
846 r.in.credentials = &credentials1;
847 r.out.return_credentials = &credentials2;
849 netlogon_creds_random_challenge(&credentials1);
850 credentials1.data[0] = target;
852 torture_comment(tctx, "Generating candidate session keys\n");
857 torture_assert_ntstatus_ok(
859 dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
860 "ServerReqChallenge failed");
861 torture_assert_ntstatus_ok(
864 "ServerReqChallenge failed");
866 a.in.server_name = NULL;
867 a.in.account_name = account_name;
868 a.in.secure_channel_type = sec_chan_type;
869 a.in.computer_name = computer_name;
870 a.in.negotiate_flags = &flags;
871 a.out.negotiate_flags = &flags;
872 a.in.credentials = &credentials3;
873 a.out.return_credentials = &credentials3;
875 creds = netlogon_creds_client_init(
879 a.in.secure_channel_type,
886 torture_assert(tctx, creds != NULL, "memory allocation");
887 } while (credentials3.data[0] != 0 && i < MAX_ITER);
892 "Unable to obtain a suitable session key, "
893 "after [%u] attempts\n",
895 torture_fail(tctx, "Unable obtain suitable session key");
898 torture_assert_ntstatus_ok(
900 dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
901 "ServerAuthenticate2 failed");
902 torture_assert_ntstatus_equal(
906 "ServerAuthenticate2 unexpected result code");
913 try a change password for our machine account
915 static bool test_SetPassword(struct torture_context *tctx,
916 struct dcerpc_pipe *p,
917 struct cli_credentials *machine_credentials)
919 struct netr_ServerPasswordSet r;
920 const char *password;
921 struct netlogon_creds_CredentialState *creds;
922 struct netr_Authenticator credential, return_authenticator;
923 struct samr_Password new_password;
924 struct dcerpc_binding_handle *b = p->binding_handle;
926 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
930 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
931 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
932 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
933 r.in.computer_name = TEST_MACHINE_NAME;
934 r.in.credential = &credential;
935 r.in.new_password = &new_password;
936 r.out.return_authenticator = &return_authenticator;
938 password = generate_random_password(tctx, 8, 255);
939 E_md4hash(password, new_password.hash);
941 netlogon_creds_des_encrypt(creds, &new_password);
943 torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
944 torture_comment(tctx, "Changing machine account password to '%s'\n",
947 netlogon_creds_client_authenticator(creds, &credential);
949 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
950 "ServerPasswordSet failed");
951 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
953 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
954 torture_comment(tctx, "Credential chaining failed\n");
957 /* by changing the machine password twice we test the
958 credentials chaining fully, and we verify that the server
959 allows the password to be set to the same value twice in a
960 row (match win2k3) */
961 torture_comment(tctx,
962 "Testing a second ServerPasswordSet on machine account\n");
963 torture_comment(tctx,
964 "Changing machine account password to '%s' (same as previous run)\n", password);
966 netlogon_creds_client_authenticator(creds, &credential);
968 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
969 "ServerPasswordSet (2) failed");
970 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
972 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
973 torture_comment(tctx, "Credential chaining failed\n");
976 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
979 test_SetupCredentials(p, tctx, machine_credentials, &creds),
980 "ServerPasswordSet failed to actually change the password");
986 try a change password for our machine account
988 static bool test_SetPassword_flags(struct torture_context *tctx,
989 struct dcerpc_pipe *p1,
990 struct cli_credentials *machine_credentials,
991 uint32_t negotiate_flags)
993 struct netr_ServerPasswordSet r;
994 const char *password;
995 struct netlogon_creds_CredentialState *creds;
996 struct netr_Authenticator credential, return_authenticator;
997 struct samr_Password new_password;
998 struct dcerpc_pipe *p = NULL;
999 struct dcerpc_binding_handle *b = NULL;
1001 if (!test_SetupCredentials2(p1, tctx, negotiate_flags,
1002 machine_credentials,
1003 cli_credentials_get_secure_channel_type(machine_credentials),
1007 if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
1008 DCERPC_SIGN | DCERPC_SEAL, &p)) {
1011 b = p->binding_handle;
1013 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1014 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1015 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1016 r.in.computer_name = TEST_MACHINE_NAME;
1017 r.in.credential = &credential;
1018 r.in.new_password = &new_password;
1019 r.out.return_authenticator = &return_authenticator;
1021 password = generate_random_password(tctx, 8, 255);
1022 E_md4hash(password, new_password.hash);
1024 netlogon_creds_des_encrypt(creds, &new_password);
1026 torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
1027 torture_comment(tctx, "Changing machine account password to '%s'\n",
1030 netlogon_creds_client_authenticator(creds, &credential);
1032 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
1033 "ServerPasswordSet failed");
1034 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
1036 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1037 torture_comment(tctx, "Credential chaining failed\n");
1040 /* by changing the machine password twice we test the
1041 credentials chaining fully, and we verify that the server
1042 allows the password to be set to the same value twice in a
1043 row (match win2k3) */
1044 torture_comment(tctx,
1045 "Testing a second ServerPasswordSet on machine account\n");
1046 torture_comment(tctx,
1047 "Changing machine account password to '%s' (same as previous run)\n", password);
1049 netlogon_creds_client_authenticator(creds, &credential);
1051 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
1052 "ServerPasswordSet (2) failed");
1053 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
1055 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1056 torture_comment(tctx, "Credential chaining failed\n");
1059 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
1061 torture_assert(tctx,
1062 test_SetupCredentials(p, tctx, machine_credentials, &creds),
1063 "ServerPasswordSet failed to actually change the password");
1070 generate a random password for password change tests
1072 static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
1075 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
1076 generate_random_buffer(password.data, password.length);
1078 for (i=0; i < len; i++) {
1079 if (((uint16_t *)password.data)[i] == 0) {
1080 ((uint16_t *)password.data)[i] = 1;
1088 try a change password for our machine account
1090 static bool test_SetPassword2_with_flags(struct torture_context *tctx,
1091 struct dcerpc_pipe *p1,
1092 struct cli_credentials *machine_credentials,
1095 struct netr_ServerPasswordSet2 r;
1096 const char *password;
1097 DATA_BLOB new_random_pass;
1098 struct netlogon_creds_CredentialState *creds;
1099 struct samr_CryptPassword password_buf;
1100 struct samr_Password nt_hash;
1101 struct netr_Authenticator credential, return_authenticator;
1102 struct netr_CryptPassword new_password;
1103 struct dcerpc_pipe *p = NULL;
1104 struct dcerpc_binding_handle *b = NULL;
1106 if (!test_SetupCredentials2(p1, tctx, flags, machine_credentials,
1107 cli_credentials_get_secure_channel_type(machine_credentials),
1111 if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
1112 DCERPC_SIGN | DCERPC_SEAL, &p)) {
1115 b = p->binding_handle;
1117 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1118 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1119 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1120 r.in.computer_name = TEST_MACHINE_NAME;
1121 r.in.credential = &credential;
1122 r.in.new_password = &new_password;
1123 r.out.return_authenticator = &return_authenticator;
1125 password = generate_random_password(tctx, 8, 255);
1126 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
1127 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1128 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1130 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1133 memcpy(new_password.data, password_buf.data, 512);
1134 new_password.length = IVAL(password_buf.data, 512);
1136 torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
1137 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
1139 netlogon_creds_client_authenticator(creds, &credential);
1141 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1142 "ServerPasswordSet2 failed");
1143 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
1145 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1146 torture_comment(tctx, "Credential chaining failed\n");
1149 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
1152 * As a consequence of CVE-2020-1472(ZeroLogon)
1153 * Samba explicitly disallows the setting of an empty machine account
1156 * Note that this may fail against Windows, and leave a machine account
1157 * with an empty password.
1160 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
1161 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1162 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1164 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1166 memcpy(new_password.data, password_buf.data, 512);
1167 new_password.length = IVAL(password_buf.data, 512);
1169 torture_comment(tctx,
1170 "Testing ServerPasswordSet2 on machine account\n");
1171 torture_comment(tctx,
1172 "Changing machine account password to '%s'\n", password);
1174 netlogon_creds_client_authenticator(creds, &credential);
1176 torture_assert_ntstatus_ok(
1177 tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1178 "ServerPasswordSet2 failed");
1179 torture_assert_ntstatus_equal(
1182 NT_STATUS_WRONG_PASSWORD,
1183 "ServerPasswordSet2 did not return NT_STATUS_WRONG_PASSWORD");
1185 /* now try a random password */
1186 password = generate_random_password(tctx, 8, 255);
1187 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
1188 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1189 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1191 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1193 memcpy(new_password.data, password_buf.data, 512);
1194 new_password.length = IVAL(password_buf.data, 512);
1196 torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
1197 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
1199 netlogon_creds_client_authenticator(creds, &credential);
1201 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1202 "ServerPasswordSet2 (2) failed");
1203 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 (2) failed");
1205 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1206 torture_comment(tctx, "Credential chaining failed\n");
1209 /* by changing the machine password twice we test the
1210 credentials chaining fully, and we verify that the server
1211 allows the password to be set to the same value twice in a
1212 row (match win2k3) */
1213 torture_comment(tctx,
1214 "Testing a second ServerPasswordSet2 on machine account\n");
1215 torture_comment(tctx,
1216 "Changing machine account password to '%s' (same as previous run)\n", password);
1218 netlogon_creds_client_authenticator(creds, &credential);
1220 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1221 "ServerPasswordSet (3) failed");
1222 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
1224 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1225 torture_comment(tctx, "Credential chaining failed\n");
1228 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
1230 torture_assert (tctx,
1231 test_SetupCredentials(p, tctx, machine_credentials, &creds),
1232 "ServerPasswordSet failed to actually change the password");
1234 new_random_pass = netlogon_very_rand_pass(tctx, 128);
1236 /* now try a random stream of bytes for a password */
1237 set_pw_in_buffer(password_buf.data, &new_random_pass);
1239 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1240 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1242 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1245 memcpy(new_password.data, password_buf.data, 512);
1246 new_password.length = IVAL(password_buf.data, 512);
1248 torture_comment(tctx,
1249 "Testing a third ServerPasswordSet2 on machine account, with a completely random password\n");
1251 netlogon_creds_client_authenticator(creds, &credential);
1253 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1254 "ServerPasswordSet (3) failed");
1255 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
1257 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1258 torture_comment(tctx, "Credential chaining failed\n");
1261 mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
1263 cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
1264 cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
1266 torture_assert (tctx,
1267 test_SetupCredentials(p, tctx, machine_credentials, &creds),
1268 "ServerPasswordSet failed to actually change the password");
1274 try to change the password of our machine account using a buffer of all zeros,
1275 and a session key that encrypts that to all zeros.
1277 Note: The test does use sign and seal, it's purpose is to exercise
1278 the detection code in dcesrv_netr_ServerPasswordSet2
1280 static bool test_SetPassword2_encrypted_to_all_zeros(
1281 struct torture_context *tctx,
1282 struct dcerpc_pipe *p1,
1283 struct cli_credentials *machine_credentials)
1285 struct netr_ServerPasswordSet2 r;
1286 struct netlogon_creds_CredentialState *creds;
1287 struct samr_CryptPassword password_buf;
1288 struct netr_Authenticator credential, return_authenticator;
1289 struct netr_CryptPassword new_password;
1290 struct dcerpc_pipe *p = NULL;
1291 struct dcerpc_binding_handle *b = NULL;
1293 if (!test_ServerAuthenticate2_encrypts_to_zero(
1296 machine_credentials,
1303 if (!test_SetupCredentialsPipe(
1306 machine_credentials,
1308 DCERPC_SIGN | DCERPC_SEAL,
1313 b = p->binding_handle;
1315 r.in.server_name = talloc_asprintf(
1317 "\\\\%s", dcerpc_server_name(p));
1318 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1319 r.in.secure_channel_type =
1320 cli_credentials_get_secure_channel_type(machine_credentials);
1321 r.in.computer_name = TEST_MACHINE_NAME;
1322 r.in.credential = &credential;
1323 r.in.new_password = &new_password;
1324 r.out.return_authenticator = &return_authenticator;
1326 ZERO_STRUCT(password_buf);
1328 if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
1329 torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES not set");
1331 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1332 if(!all_zero(password_buf.data, 516)) {
1333 torture_fail(tctx, "Password did not encrypt to all zeros\n");
1336 memcpy(new_password.data, password_buf.data, 512);
1337 new_password.length = IVAL(password_buf.data, 512);
1338 torture_assert_int_equal(
1340 new_password.length,
1342 "Length should have encrypted to 0");
1344 netlogon_creds_client_authenticator(creds, &credential);
1346 torture_assert_ntstatus_ok(
1348 dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1349 "ServerPasswordSet2 zero length check failed");
1350 torture_assert_ntstatus_equal(
1351 tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
1357 * Choose a session key that encrypts a password of all zeros to all zeros.
1358 * Then try to set the password, using a zeroed buffer, with a non zero
1361 * This exercises the password self encryption check.
1363 * Note: The test does use sign and seal, it's purpose is to exercise
1364 * the detection code in dcesrv_netr_ServerPasswordSet2
1366 static bool test_SetPassword2_password_encrypts_to_zero(
1367 struct torture_context *tctx,
1368 struct dcerpc_pipe *p1,
1369 struct cli_credentials *machine_credentials)
1371 struct netr_ServerPasswordSet2 r;
1372 struct netlogon_creds_CredentialState *creds;
1373 struct samr_CryptPassword password_buf;
1374 struct netr_Authenticator credential, return_authenticator;
1375 struct netr_CryptPassword new_password;
1376 struct dcerpc_pipe *p = NULL;
1377 struct dcerpc_binding_handle *b = NULL;
1379 if (!test_ServerAuthenticate2_encrypts_to_zero(
1382 machine_credentials,
1389 if (!test_SetupCredentialsPipe(
1392 machine_credentials,
1394 DCERPC_SIGN | DCERPC_SEAL,
1399 b = p->binding_handle;
1401 r.in.server_name = talloc_asprintf(
1403 "\\\\%s", dcerpc_server_name(p));
1404 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1405 r.in.secure_channel_type =
1406 cli_credentials_get_secure_channel_type(machine_credentials);
1407 r.in.computer_name = TEST_MACHINE_NAME;
1408 r.in.credential = &credential;
1409 r.in.new_password = &new_password;
1410 r.out.return_authenticator = &return_authenticator;
1412 ZERO_STRUCT(password_buf);
1413 SIVAL(password_buf.data, 512, 512);
1415 if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
1416 torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES not set");
1418 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1420 memcpy(new_password.data, password_buf.data, 512);
1421 new_password.length = IVAL(password_buf.data, 512);
1423 netlogon_creds_client_authenticator(creds, &credential);
1425 torture_assert_ntstatus_ok(
1427 dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1428 "ServerPasswordSet2 password encrypts to zero check failed");
1429 torture_assert_ntstatus_equal(
1430 tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
1436 * Check that an all zero confounder, that encrypts to all zeros is
1439 * Note: The test does use sign and seal, it's purpose is to exercise
1440 * the detection code in dcesrv_netr_ServerPasswordSet2
1442 static bool test_SetPassword2_confounder(
1443 struct torture_context *tctx,
1444 struct dcerpc_pipe *p1,
1445 struct cli_credentials *machine_credentials)
1447 struct netr_ServerPasswordSet2 r;
1448 struct netlogon_creds_CredentialState *creds;
1449 struct samr_CryptPassword password_buf;
1450 struct netr_Authenticator credential, return_authenticator;
1451 struct netr_CryptPassword new_password;
1452 struct dcerpc_pipe *p = NULL;
1453 struct dcerpc_binding_handle *b = NULL;
1455 if (!test_ServerAuthenticate2_encrypts_to_zero(
1458 machine_credentials,
1465 if (!test_SetupCredentialsPipe(
1468 machine_credentials,
1470 DCERPC_SIGN | DCERPC_SEAL,
1475 b = p->binding_handle;
1477 r.in.server_name = talloc_asprintf(
1479 "\\\\%s", dcerpc_server_name(p));
1480 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1481 r.in.secure_channel_type =
1482 cli_credentials_get_secure_channel_type(machine_credentials);
1483 r.in.computer_name = TEST_MACHINE_NAME;
1484 r.in.credential = &credential;
1485 r.in.new_password = &new_password;
1486 r.out.return_authenticator = &return_authenticator;
1488 ZERO_STRUCT(password_buf);
1489 password_buf.data[511] = 'A';
1490 SIVAL(password_buf.data, 512, 2);
1492 if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
1493 torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES not set");
1495 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1497 memcpy(new_password.data, password_buf.data, 512);
1498 new_password.length = IVAL(password_buf.data, 512);
1500 netlogon_creds_client_authenticator(creds, &credential);
1502 torture_assert_ntstatus_ok(
1504 dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1505 "ServerPasswordSet2 confounder check failed");
1506 torture_assert_ntstatus_equal(
1507 tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
1513 * try a change password for our machine account, using an all zero
1514 * request. This should fail on the zero length check.
1516 * Note: This test uses ARC4 encryption to exercise the desired check.
1518 static bool test_SetPassword2_all_zeros(
1519 struct torture_context *tctx,
1520 struct dcerpc_pipe *p1,
1521 struct cli_credentials *machine_credentials)
1523 struct netr_ServerPasswordSet2 r;
1524 struct netlogon_creds_CredentialState *creds;
1525 struct samr_CryptPassword password_buf;
1526 struct netr_Authenticator credential, return_authenticator;
1527 struct netr_CryptPassword new_password;
1528 struct dcerpc_pipe *p = NULL;
1529 struct dcerpc_binding_handle *b = NULL;
1530 uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
1532 if (!test_SetupCredentials2(
1536 machine_credentials,
1537 cli_credentials_get_secure_channel_type(machine_credentials),
1542 if (!test_SetupCredentialsPipe(
1545 machine_credentials,
1547 DCERPC_SIGN | DCERPC_SEAL,
1552 b = p->binding_handle;
1554 r.in.server_name = talloc_asprintf(
1556 "\\\\%s", dcerpc_server_name(p));
1557 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1558 r.in.secure_channel_type =
1559 cli_credentials_get_secure_channel_type(machine_credentials);
1560 r.in.computer_name = TEST_MACHINE_NAME;
1561 r.in.credential = &credential;
1562 r.in.new_password = &new_password;
1563 r.out.return_authenticator = &return_authenticator;
1565 ZERO_STRUCT(password_buf.data);
1566 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1567 torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES enabled\n");
1569 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1571 memcpy(new_password.data, password_buf.data, 512);
1572 new_password.length = IVAL(password_buf.data, 512);
1576 "Testing ServerPasswordSet2 on machine account\n");
1578 netlogon_creds_client_authenticator(creds, &credential);
1580 torture_assert_ntstatus_ok(
1582 dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1583 "ServerPasswordSet2 zero length check failed");
1584 torture_assert_ntstatus_equal(
1585 tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
1591 try a change password for our machine account, using a maximum length
1594 static bool test_SetPassword2_maximum_length_password(
1595 struct torture_context *tctx,
1596 struct dcerpc_pipe *p1,
1597 struct cli_credentials *machine_credentials)
1599 struct netr_ServerPasswordSet2 r;
1600 struct netlogon_creds_CredentialState *creds;
1601 struct samr_CryptPassword password_buf;
1602 struct netr_Authenticator credential, return_authenticator;
1603 struct netr_CryptPassword new_password;
1604 struct dcerpc_pipe *p = NULL;
1605 struct dcerpc_binding_handle *b = NULL;
1606 uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
1607 DATA_BLOB new_random_pass = data_blob_null;
1609 if (!test_SetupCredentials2(
1613 machine_credentials,
1614 cli_credentials_get_secure_channel_type(machine_credentials),
1619 if (!test_SetupCredentialsPipe(
1622 machine_credentials,
1624 DCERPC_SIGN | DCERPC_SEAL,
1629 b = p->binding_handle;
1631 r.in.server_name = talloc_asprintf(
1633 "\\\\%s", dcerpc_server_name(p));
1634 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1635 r.in.secure_channel_type =
1636 cli_credentials_get_secure_channel_type(machine_credentials);
1637 r.in.computer_name = TEST_MACHINE_NAME;
1638 r.in.credential = &credential;
1639 r.in.new_password = &new_password;
1640 r.out.return_authenticator = &return_authenticator;
1642 new_random_pass = netlogon_very_rand_pass(tctx, 256);
1643 set_pw_in_buffer(password_buf.data, &new_random_pass);
1644 SIVAL(password_buf.data, 512, 512);
1645 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1646 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1648 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1651 memcpy(new_password.data, password_buf.data, 512);
1652 new_password.length = IVAL(password_buf.data, 512);
1656 "Testing ServerPasswordSet2 on machine account\n");
1658 netlogon_creds_client_authenticator(creds, &credential);
1660 torture_assert_ntstatus_ok(
1662 dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1663 "ServerPasswordSet2 zero length check failed");
1664 torture_assert_ntstatus_equal(
1665 tctx, r.out.result, NT_STATUS_OK, "");
1671 try a change password for our machine account, using a password of
1672 all zeros, and a non zero password length.
1674 This test relies on the buffer being encrypted with ARC4, to
1675 trigger the appropriate check in the rpc server code
1677 static bool test_SetPassword2_all_zero_password(
1678 struct torture_context *tctx,
1679 struct dcerpc_pipe *p1,
1680 struct cli_credentials *machine_credentials)
1682 struct netr_ServerPasswordSet2 r;
1683 struct netlogon_creds_CredentialState *creds;
1684 struct samr_CryptPassword password_buf;
1685 struct netr_Authenticator credential, return_authenticator;
1686 struct netr_CryptPassword new_password;
1687 struct dcerpc_pipe *p = NULL;
1688 struct dcerpc_binding_handle *b = NULL;
1689 uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
1691 if (!test_SetupCredentials2(
1695 machine_credentials,
1696 cli_credentials_get_secure_channel_type(machine_credentials),
1701 if (!test_SetupCredentialsPipe(
1704 machine_credentials,
1706 DCERPC_SIGN | DCERPC_SEAL,
1711 b = p->binding_handle;
1713 r.in.server_name = talloc_asprintf(
1715 "\\\\%s", dcerpc_server_name(p));
1716 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1717 r.in.secure_channel_type =
1718 cli_credentials_get_secure_channel_type(machine_credentials);
1719 r.in.computer_name = TEST_MACHINE_NAME;
1720 r.in.credential = &credential;
1721 r.in.new_password = &new_password;
1722 r.out.return_authenticator = &return_authenticator;
1724 ZERO_STRUCT(password_buf.data);
1725 SIVAL(password_buf.data, 512, 128);
1726 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1727 torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES set");
1729 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1731 memcpy(new_password.data, password_buf.data, 512);
1732 new_password.length = IVAL(password_buf.data, 512);
1736 "Testing ServerPasswordSet2 on machine account\n");
1738 netlogon_creds_client_authenticator(creds, &credential);
1740 torture_assert_ntstatus_ok(
1742 dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1743 "ServerPasswordSet2 all zero password check failed");
1744 torture_assert_ntstatus_equal(
1745 tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
1751 static bool test_SetPassword2(struct torture_context *tctx,
1752 struct dcerpc_pipe *p,
1753 struct cli_credentials *machine_credentials)
1755 return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS);
1758 static bool test_SetPassword2_AES(struct torture_context *tctx,
1759 struct dcerpc_pipe *p,
1760 struct cli_credentials *machine_credentials)
1762 return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
1765 static bool test_GetPassword(struct torture_context *tctx,
1766 struct dcerpc_pipe *p,
1767 struct cli_credentials *machine_credentials)
1769 struct netr_ServerPasswordGet r;
1770 struct netlogon_creds_CredentialState *creds;
1771 struct netr_Authenticator credential;
1773 struct netr_Authenticator return_authenticator;
1774 struct samr_Password password;
1775 struct dcerpc_binding_handle *b = p->binding_handle;
1777 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1781 netlogon_creds_client_authenticator(creds, &credential);
1783 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1784 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1785 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1786 r.in.computer_name = TEST_MACHINE_NAME;
1787 r.in.credential = &credential;
1788 r.out.return_authenticator = &return_authenticator;
1789 r.out.password = &password;
1791 status = dcerpc_netr_ServerPasswordGet_r(b, tctx, &r);
1792 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
1793 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordGet");
1798 static bool test_GetTrustPasswords(struct torture_context *tctx,
1799 struct dcerpc_pipe *p,
1800 struct cli_credentials *machine_credentials)
1802 struct netr_ServerTrustPasswordsGet r;
1803 struct netlogon_creds_CredentialState *creds;
1804 struct netr_Authenticator credential;
1805 struct netr_Authenticator return_authenticator;
1806 struct samr_Password password, password2;
1807 struct dcerpc_binding_handle *b = p->binding_handle;
1809 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1813 netlogon_creds_client_authenticator(creds, &credential);
1815 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1816 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1817 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1818 r.in.computer_name = TEST_MACHINE_NAME;
1819 r.in.credential = &credential;
1820 r.out.return_authenticator = &return_authenticator;
1821 r.out.new_owf_password = &password;
1822 r.out.old_owf_password = &password2;
1824 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerTrustPasswordsGet_r(b, tctx, &r),
1825 "ServerTrustPasswordsGet failed");
1826 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerTrustPasswordsGet failed");
1832 try a netlogon SamLogon
1834 static bool test_netlogon_ops_args(struct dcerpc_pipe *p, struct torture_context *tctx,
1835 struct cli_credentials *credentials,
1836 struct netlogon_creds_CredentialState *creds,
1840 struct netr_LogonSamLogon r;
1841 struct netr_Authenticator auth, auth2;
1842 union netr_LogonLevel logon;
1843 union netr_Validation validation;
1844 uint8_t authoritative;
1845 struct netr_NetworkInfo ninfo;
1846 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
1848 struct dcerpc_binding_handle *b = p->binding_handle;
1849 int flags = CLI_CRED_NTLM_AUTH;
1850 if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
1851 flags |= CLI_CRED_LANMAN_AUTH;
1854 if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx) && !null_domain) {
1855 flags |= CLI_CRED_NTLMv2_AUTH;
1858 cli_credentials_get_ntlm_username_domain(popt_get_cmdline_credentials(),
1860 &ninfo.identity_info.account_name.string,
1861 &ninfo.identity_info.domain_name.string);
1864 ninfo.identity_info.domain_name.string = NULL;
1867 generate_random_buffer(ninfo.challenge,
1868 sizeof(ninfo.challenge));
1869 chal = data_blob_const(ninfo.challenge,
1870 sizeof(ninfo.challenge));
1872 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials),
1873 cli_credentials_get_domain(credentials));
1875 status = cli_credentials_get_ntlm_response(
1876 popt_get_cmdline_credentials(), tctx,
1879 NULL, /* server_timestamp */
1883 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
1885 ninfo.lm.data = lm_resp.data;
1886 ninfo.lm.length = lm_resp.length;
1888 ninfo.nt.data = nt_resp.data;
1889 ninfo.nt.length = nt_resp.length;
1891 ninfo.identity_info.parameter_control = 0;
1892 ninfo.identity_info.logon_id = 0;
1893 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
1895 logon.network = &ninfo;
1897 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1898 r.in.computer_name = cli_credentials_get_workstation(credentials);
1899 r.in.credential = &auth;
1900 r.in.return_authenticator = &auth2;
1901 r.in.logon_level = NetlogonNetworkInformation;
1902 r.in.logon = &logon;
1903 r.out.validation = &validation;
1904 r.out.authoritative = &authoritative;
1906 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
1908 for (i=2;i<=3;i++) {
1910 netlogon_creds_client_authenticator(creds, &auth);
1912 r.in.validation_level = i;
1914 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1915 "LogonSamLogon failed");
1916 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
1918 torture_assert(tctx, netlogon_creds_client_check(creds,
1919 &r.out.return_authenticator->cred),
1920 "Credential chaining failed");
1921 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1922 "LogonSamLogon invalid *r.out.authoritative");
1925 /* this makes sure we get the unmarshalling right for invalid levels */
1926 for (i=52;i<53;i++) {
1928 /* the authenticator should be ignored by the server */
1929 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
1931 r.in.validation_level = i;
1933 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1934 "LogonSamLogon failed");
1935 torture_assert_ntstatus_equal(tctx, r.out.result,
1936 NT_STATUS_INVALID_INFO_CLASS,
1937 "LogonSamLogon failed");
1939 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1940 "LogonSamLogon invalid *r.out.authoritative");
1941 torture_assert(tctx,
1942 all_zero((uint8_t *)&auth2, sizeof(auth2)),
1943 "Return authenticator non zero");
1946 for (i=2;i<=3;i++) {
1948 netlogon_creds_client_authenticator(creds, &auth);
1950 r.in.validation_level = i;
1952 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1953 "LogonSamLogon failed");
1954 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
1956 torture_assert(tctx, netlogon_creds_client_check(creds,
1957 &r.out.return_authenticator->cred),
1958 "Credential chaining failed");
1959 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1960 "LogonSamLogon invalid *r.out.authoritative");
1963 r.in.logon_level = 52;
1965 for (i=2;i<=3;i++) {
1967 /* the authenticator should be ignored by the server */
1968 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
1970 r.in.validation_level = i;
1972 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
1974 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1975 "LogonSamLogon failed");
1976 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
1977 "LogonSamLogon expected INVALID_PARAMETER");
1979 torture_assert(tctx,
1980 all_zero((uint8_t *)&auth2, sizeof(auth2)),
1981 "Return authenticator non zero");
1982 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1983 "LogonSamLogon invalid *r.out.authoritative");
1986 r.in.credential = NULL;
1988 for (i=2;i<=3;i++) {
1991 r.in.validation_level = i;
1993 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
1995 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1996 "LogonSamLogon failed");
1997 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
1998 "LogonSamLogon expected INVALID_PARAMETER");
2000 torture_assert(tctx,
2001 all_zero((uint8_t *)&auth2, sizeof(auth2)),
2002 "Return authenticator non zero");
2003 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
2004 "LogonSamLogon invalid *r.out.authoritative");
2007 r.in.logon_level = NetlogonNetworkInformation;
2008 r.in.credential = &auth;
2010 for (i=2;i<=3;i++) {
2012 netlogon_creds_client_authenticator(creds, &auth);
2014 r.in.validation_level = i;
2016 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
2017 "LogonSamLogon failed");
2018 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
2020 torture_assert(tctx, netlogon_creds_client_check(creds,
2021 &r.out.return_authenticator->cred),
2022 "Credential chaining failed");
2023 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
2024 "LogonSamLogon invalid *r.out.authoritative");
2030 bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2031 struct cli_credentials *credentials,
2032 struct netlogon_creds_CredentialState *creds)
2034 return test_netlogon_ops_args(p, tctx, credentials, creds, false);
2038 try a netlogon GetCapabilities
2040 bool test_netlogon_capabilities(struct dcerpc_pipe *p, struct torture_context *tctx,
2041 struct cli_credentials *credentials,
2042 struct netlogon_creds_CredentialState *creds)
2045 struct netr_LogonGetCapabilities r;
2046 union netr_Capabilities capabilities;
2047 struct netr_Authenticator auth, return_auth;
2048 struct netlogon_creds_CredentialState tmp_creds;
2049 struct dcerpc_binding_handle *b = p->binding_handle;
2051 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2052 r.in.computer_name = cli_credentials_get_workstation(credentials);
2053 r.in.credential = &auth;
2054 r.in.return_authenticator = &return_auth;
2055 r.in.query_level = 1;
2056 r.out.capabilities = &capabilities;
2057 r.out.return_authenticator = &return_auth;
2059 torture_comment(tctx, "Testing LogonGetCapabilities\n");
2061 ZERO_STRUCT(return_auth);
2064 * we need to operate on a temporary copy of creds
2065 * because dcerpc_netr_LogonGetCapabilities was
2066 * dcerpc_netr_DummyFunction and returns NT_STATUS_NOT_IMPLEMENTED
2067 * without looking a the authenticator.
2070 netlogon_creds_client_authenticator(&tmp_creds, &auth);
2072 status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
2073 torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities failed");
2074 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2080 torture_assert(tctx, netlogon_creds_client_check(creds,
2081 &r.out.return_authenticator->cred),
2082 "Credential chaining failed");
2084 torture_assert_int_equal(tctx, creds->negotiate_flags,
2085 capabilities.server_capabilities,
2092 try a netlogon SamLogon
2094 static bool test_SamLogon(struct torture_context *tctx,
2095 struct dcerpc_pipe *p,
2096 struct cli_credentials *credentials)
2098 struct netlogon_creds_CredentialState *creds;
2100 if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
2104 return test_netlogon_ops(p, tctx, credentials, creds);
2107 static bool test_invalidAuthenticate2(struct torture_context *tctx,
2108 struct dcerpc_pipe *p,
2109 struct cli_credentials *credentials)
2111 struct netlogon_creds_CredentialState *creds;
2112 uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2114 torture_comment(tctx, "Testing invalidAuthenticate2\n");
2116 if (!test_SetupCredentials2(p, tctx, flags,
2118 cli_credentials_get_secure_channel_type(credentials),
2123 if (!test_SetupCredentials2ex(p, tctx, flags,
2126 cli_credentials_get_secure_channel_type(credentials),
2127 STATUS_BUFFER_OVERFLOW,
2132 if (!test_SetupCredentials2ex(p, tctx, flags,
2135 cli_credentials_get_secure_channel_type(credentials),
2144 static bool test_ServerReqChallengeGlobal(struct torture_context *tctx,
2145 struct dcerpc_pipe *p1,
2146 struct cli_credentials *machine_credentials)
2148 uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2149 struct netr_ServerReqChallenge r;
2150 struct netr_ServerAuthenticate3 a;
2151 struct netr_Credential credentials1, credentials2, credentials3;
2152 struct netlogon_creds_CredentialState *creds;
2153 struct samr_Password mach_password;
2155 const char *machine_name;
2156 const char *plain_pass;
2157 struct dcerpc_binding_handle *b1 = p1->binding_handle;
2158 struct dcerpc_pipe *p2 = NULL;
2159 struct dcerpc_binding_handle *b2 = NULL;
2161 machine_name = cli_credentials_get_workstation(machine_credentials);
2162 torture_assert(tctx, machine_name != NULL, "machine_name");
2163 plain_pass = cli_credentials_get_password(machine_credentials);
2164 torture_assert(tctx, plain_pass != NULL, "plain_pass");
2166 torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2168 torture_assert_ntstatus_ok(tctx,
2169 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
2170 &ndr_table_netlogon,
2171 machine_credentials,
2172 tctx->ev, tctx->lp_ctx),
2173 "dcerpc_pipe_connect_b failed");
2174 b2 = p2->binding_handle;
2176 r.in.server_name = NULL;
2177 r.in.computer_name = machine_name;
2178 r.in.credentials = &credentials1;
2179 r.out.return_credentials = &credentials2;
2181 netlogon_creds_random_challenge(&credentials1);
2183 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2184 "ServerReqChallenge failed on b1");
2185 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2187 E_md4hash(plain_pass, mach_password.hash);
2189 a.in.server_name = NULL;
2190 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2191 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2192 a.in.computer_name = machine_name;
2193 a.in.negotiate_flags = &flags;
2194 a.in.credentials = &credentials3;
2195 a.out.return_credentials = &credentials3;
2196 a.out.negotiate_flags = &flags;
2199 creds = netlogon_creds_client_init(tctx, a.in.account_name,
2201 a.in.secure_channel_type,
2202 &credentials1, &credentials2,
2203 &mach_password, &credentials3,
2206 torture_assert(tctx, creds != NULL, "memory allocation");
2208 torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
2210 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2211 "ServerAuthenticate3 failed on b2");
2212 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
2213 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2219 * Test the re-use of the challenge is not possible on a third
2220 * connection, after first useing it second one.
2223 static bool test_ServerReqChallengeReuseGlobal(struct torture_context *tctx,
2224 struct dcerpc_pipe *p1,
2225 struct cli_credentials *machine_credentials)
2227 uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2228 struct netr_ServerReqChallenge r;
2229 struct netr_ServerAuthenticate3 a;
2230 struct netr_Credential credentials1, credentials2, credentials3;
2231 struct netlogon_creds_CredentialState *creds;
2232 struct samr_Password mach_password;
2234 const char *machine_name;
2235 const char *plain_pass;
2236 struct dcerpc_binding_handle *b1 = p1->binding_handle;
2237 struct dcerpc_pipe *p2 = NULL;
2238 struct dcerpc_binding_handle *b2 = NULL;
2239 struct dcerpc_pipe *p3 = NULL;
2240 struct dcerpc_binding_handle *b3 = NULL;
2242 machine_name = cli_credentials_get_workstation(machine_credentials);
2243 torture_assert(tctx, machine_name != NULL, "machine_name");
2244 plain_pass = cli_credentials_get_password(machine_credentials);
2245 torture_assert(tctx, plain_pass != NULL, "plain_pass");
2247 torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2249 torture_assert_ntstatus_ok(tctx,
2250 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
2251 &ndr_table_netlogon,
2252 machine_credentials,
2253 tctx->ev, tctx->lp_ctx),
2254 "dcerpc_pipe_connect_b failed");
2255 b2 = p2->binding_handle;
2257 torture_assert_ntstatus_ok(tctx,
2258 dcerpc_pipe_connect_b(tctx, &p3, p1->binding,
2259 &ndr_table_netlogon,
2260 machine_credentials,
2261 tctx->ev, tctx->lp_ctx),
2262 "dcerpc_pipe_connect_b failed");
2263 b3 = p3->binding_handle;
2265 r.in.server_name = NULL;
2266 r.in.computer_name = machine_name;
2267 r.in.credentials = &credentials1;
2268 r.out.return_credentials = &credentials2;
2270 netlogon_creds_random_challenge(&credentials1);
2272 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2273 "ServerReqChallenge failed on b1");
2274 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2276 E_md4hash(plain_pass, mach_password.hash);
2278 a.in.server_name = NULL;
2279 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2280 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2281 a.in.computer_name = machine_name;
2282 a.in.negotiate_flags = &flags;
2283 a.in.credentials = &credentials3;
2284 a.out.return_credentials = &credentials3;
2285 a.out.negotiate_flags = &flags;
2288 creds = netlogon_creds_client_init(tctx, a.in.account_name,
2290 a.in.secure_channel_type,
2291 &credentials1, &credentials2,
2292 &mach_password, &credentials3,
2295 torture_assert(tctx, creds != NULL, "memory allocation");
2297 torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
2299 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2300 "ServerAuthenticate3 failed on b2");
2301 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
2302 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2304 /* We have to re-run this part */
2305 creds = netlogon_creds_client_init(tctx, a.in.account_name,
2307 a.in.secure_channel_type,
2308 &credentials1, &credentials2,
2309 &mach_password, &credentials3,
2312 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b3, tctx, &a),
2313 "ServerAuthenticate3 failed on b3");
2314 torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2315 "ServerAuthenticate3 should have failed on b3, due to credential reuse");
2320 * Test if use of the per-pipe challenge will wipe out the globally cached challenge
2322 static bool test_ServerReqChallengeReuseGlobal2(struct torture_context *tctx,
2323 struct dcerpc_pipe *p1,
2324 struct cli_credentials *machine_credentials)
2326 uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2327 struct netr_ServerReqChallenge r;
2328 struct netr_ServerAuthenticate3 a;
2329 struct netr_Credential credentials1, credentials2, credentials3;
2330 struct netlogon_creds_CredentialState *creds;
2331 struct samr_Password mach_password;
2333 const char *machine_name;
2334 const char *plain_pass;
2335 struct dcerpc_binding_handle *b1 = p1->binding_handle;
2336 struct dcerpc_pipe *p2 = NULL;
2337 struct dcerpc_binding_handle *b2 = NULL;
2339 machine_name = cli_credentials_get_workstation(machine_credentials);
2340 torture_assert(tctx, machine_name != NULL, "machine_name");
2341 plain_pass = cli_credentials_get_password(machine_credentials);
2342 torture_assert(tctx, plain_pass != NULL, "plain_pass");
2344 torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2346 torture_assert_ntstatus_ok(tctx,
2347 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
2348 &ndr_table_netlogon,
2349 machine_credentials,
2350 tctx->ev, tctx->lp_ctx),
2351 "dcerpc_pipe_connect_b failed");
2352 b2 = p2->binding_handle;
2354 r.in.server_name = NULL;
2355 r.in.computer_name = machine_name;
2356 r.in.credentials = &credentials1;
2357 r.out.return_credentials = &credentials2;
2359 netlogon_creds_random_challenge(&credentials1);
2361 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2362 "ServerReqChallenge failed on b1");
2363 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2365 E_md4hash(plain_pass, mach_password.hash);
2367 a.in.server_name = NULL;
2368 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2369 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2370 a.in.computer_name = machine_name;
2371 a.in.negotiate_flags = &flags;
2372 a.in.credentials = &credentials3;
2373 a.out.return_credentials = &credentials3;
2374 a.out.negotiate_flags = &flags;
2377 creds = netlogon_creds_client_init(tctx, a.in.account_name,
2379 a.in.secure_channel_type,
2380 &credentials1, &credentials2,
2381 &mach_password, &credentials3,
2384 torture_assert(tctx, creds != NULL, "memory allocation");
2386 torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
2388 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
2389 "ServerAuthenticate3 failed on b");
2390 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b");
2391 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2393 /* We have to re-run this part */
2394 creds = netlogon_creds_client_init(tctx, a.in.account_name,
2396 a.in.secure_channel_type,
2397 &credentials1, &credentials2,
2398 &mach_password, &credentials3,
2401 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2402 "ServerAuthenticate3 failed on b2");
2403 torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2404 "ServerAuthenticate3 should have failed on b2, due to credential reuse");
2409 * Test if use of the globally cached challenge will wipe out the
2410 * per-pipe challenge
2412 static bool test_ServerReqChallengeReuseGlobal3(struct torture_context *tctx,
2413 struct dcerpc_pipe *p1,
2414 struct cli_credentials *machine_credentials)
2416 uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2417 struct netr_ServerReqChallenge r;
2418 struct netr_ServerAuthenticate3 a;
2419 struct netr_Credential credentials1, credentials2, credentials3;
2420 struct netlogon_creds_CredentialState *creds;
2421 struct samr_Password mach_password;
2423 const char *machine_name;
2424 const char *plain_pass;
2425 struct dcerpc_binding_handle *b1 = p1->binding_handle;
2426 struct dcerpc_pipe *p2 = NULL;
2427 struct dcerpc_binding_handle *b2 = NULL;
2429 machine_name = cli_credentials_get_workstation(machine_credentials);
2430 torture_assert(tctx, machine_name != NULL, "machine_name");
2431 plain_pass = cli_credentials_get_password(machine_credentials);
2432 torture_assert(tctx, plain_pass != NULL, "plain_pass");
2434 torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2436 torture_assert_ntstatus_ok(tctx,
2437 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
2438 &ndr_table_netlogon,
2439 machine_credentials,
2440 tctx->ev, tctx->lp_ctx),
2441 "dcerpc_pipe_connect_b failed");
2442 b2 = p2->binding_handle;
2444 r.in.server_name = NULL;
2445 r.in.computer_name = machine_name;
2446 r.in.credentials = &credentials1;
2447 r.out.return_credentials = &credentials2;
2449 netlogon_creds_random_challenge(&credentials1);
2451 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2452 "ServerReqChallenge failed on b1");
2453 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2455 E_md4hash(plain_pass, mach_password.hash);
2457 a.in.server_name = NULL;
2458 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2459 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2460 a.in.computer_name = machine_name;
2461 a.in.negotiate_flags = &flags;
2462 a.in.credentials = &credentials3;
2463 a.out.return_credentials = &credentials3;
2464 a.out.negotiate_flags = &flags;
2467 creds = netlogon_creds_client_init(tctx, a.in.account_name,
2469 a.in.secure_channel_type,
2470 &credentials1, &credentials2,
2471 &mach_password, &credentials3,
2474 torture_assert(tctx, creds != NULL, "memory allocation");
2476 torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
2478 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2479 "ServerAuthenticate3 failed on b2");
2480 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b");
2481 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2483 /* We have to re-run this part */
2484 creds = netlogon_creds_client_init(tctx, a.in.account_name,
2486 a.in.secure_channel_type,
2487 &credentials1, &credentials2,
2488 &mach_password, &credentials3,
2491 torture_assert(tctx, creds != NULL, "memory allocation");
2493 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
2494 "ServerAuthenticate3 failed on b1");
2495 torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2496 "ServerAuthenticate3 should have failed on b1, due to credential reuse");
2501 * Test if more than one globally cached challenge works
2503 static bool test_ServerReqChallengeReuseGlobal4(struct torture_context *tctx,
2504 struct dcerpc_pipe *p1,
2505 struct cli_credentials *machine_credentials)
2507 uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2508 struct netr_ServerReqChallenge r;
2509 struct netr_ServerAuthenticate3 a;
2510 struct netr_Credential credentials1, credentials1_random,
2511 credentials2, credentials3, credentials_discard;
2512 struct netlogon_creds_CredentialState *creds;
2513 struct samr_Password mach_password;
2515 const char *machine_name;
2516 const char *plain_pass;
2517 struct dcerpc_binding_handle *b1 = p1->binding_handle;
2518 struct dcerpc_pipe *p2 = NULL;
2519 struct dcerpc_binding_handle *b2 = NULL;
2521 machine_name = cli_credentials_get_workstation(machine_credentials);
2522 torture_assert(tctx, machine_name != NULL, "machine_name");
2523 plain_pass = cli_credentials_get_password(machine_credentials);
2524 torture_assert(tctx, plain_pass != NULL, "plain_pass");
2526 torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2528 torture_assert_ntstatus_ok(tctx,
2529 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
2530 &ndr_table_netlogon,
2531 machine_credentials,
2532 tctx->ev, tctx->lp_ctx),
2533 "dcerpc_pipe_connect_b failed");
2534 b2 = p2->binding_handle;
2536 r.in.server_name = NULL;
2537 r.in.computer_name = "CHALTEST1";
2538 r.in.credentials = &credentials1_random;
2539 r.out.return_credentials = &credentials_discard;
2541 netlogon_creds_random_challenge(&credentials1_random);
2543 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2544 "ServerReqChallenge failed on b1");
2545 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2547 /* Now ask for the actual client name */
2548 r.in.server_name = NULL;
2549 r.in.computer_name = machine_name;
2550 r.in.credentials = &credentials1;
2551 r.out.return_credentials = &credentials2;
2553 netlogon_creds_random_challenge(&credentials1);
2555 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2556 "ServerReqChallenge failed on b1");
2557 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2559 r.in.server_name = NULL;
2560 r.in.computer_name = "CHALTEST2";
2561 r.in.credentials = &credentials1_random;
2562 r.out.return_credentials = &credentials_discard;
2564 netlogon_creds_random_challenge(&credentials1_random);
2566 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2567 "ServerReqChallenge failed on b1");
2568 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2570 E_md4hash(plain_pass, mach_password.hash);
2572 a.in.server_name = NULL;
2573 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2574 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2575 a.in.computer_name = machine_name;
2576 a.in.negotiate_flags = &flags;
2577 a.in.credentials = &credentials3;
2578 a.out.return_credentials = &credentials3;
2579 a.out.negotiate_flags = &flags;
2582 creds = netlogon_creds_client_init(tctx, a.in.account_name,
2584 a.in.secure_channel_type,
2585 &credentials1, &credentials2,
2586 &mach_password, &credentials3,
2589 torture_assert(tctx, creds != NULL, "memory allocation");
2591 torture_comment(tctx, "Testing ServerAuthenticate3 on b2 (must use global credentials)\n");
2593 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2594 "ServerAuthenticate3 failed on b2");
2595 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
2596 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2598 /* We have to re-run this part */
2599 creds = netlogon_creds_client_init(tctx, a.in.account_name,
2601 a.in.secure_channel_type,
2602 &credentials1, &credentials2,
2603 &mach_password, &credentials3,
2606 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
2607 "ServerAuthenticate3 failed on b1");
2608 torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2609 "ServerAuthenticate3 should have failed on b1, due to credential reuse");
2613 static bool test_ServerReqChallengeReuse(struct torture_context *tctx,
2614 struct dcerpc_pipe *p,
2615 struct cli_credentials *machine_credentials)
2617 uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2618 struct netr_ServerReqChallenge r;
2619 struct netr_ServerAuthenticate3 a;
2620 struct netr_Credential credentials1, credentials2, credentials3;
2621 struct netlogon_creds_CredentialState *creds;
2622 struct samr_Password mach_password;
2624 const char *machine_name;
2625 const char *plain_pass;
2626 struct dcerpc_binding_handle *b = p->binding_handle;
2628 machine_name = cli_credentials_get_workstation(machine_credentials);
2629 torture_assert(tctx, machine_name != NULL, "machine_name");
2630 plain_pass = cli_credentials_get_password(machine_credentials);
2631 torture_assert(tctx, plain_pass != NULL, "plain_pass");
2633 torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2635 r.in.server_name = NULL;
2636 r.in.computer_name = machine_name;
2637 r.in.credentials = &credentials1;
2638 r.out.return_credentials = &credentials2;
2640 netlogon_creds_random_challenge(&credentials1);
2642 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2643 "ServerReqChallenge");
2644 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2646 E_md4hash(plain_pass, mach_password.hash);
2648 a.in.server_name = NULL;
2649 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2650 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2651 a.in.computer_name = machine_name;
2652 a.in.negotiate_flags = &flags;
2653 a.in.credentials = &credentials3;
2654 a.out.return_credentials = &credentials3;
2655 a.out.negotiate_flags = &flags;
2658 creds = netlogon_creds_client_init(tctx, a.in.account_name,
2660 a.in.secure_channel_type,
2661 &credentials1, &credentials2,
2662 &mach_password, &credentials3,
2665 torture_assert(tctx, creds != NULL, "memory allocation");
2667 torture_comment(tctx, "Testing ServerAuthenticate3\n");
2669 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2670 "ServerAuthenticate3 failed");
2671 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed");
2672 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2674 /* We have to re-run this part */
2675 creds = netlogon_creds_client_init(tctx, a.in.account_name,
2677 a.in.secure_channel_type,
2678 &credentials1, &credentials2,
2679 &mach_password, &credentials3,
2682 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2683 "ServerAuthenticate3 failed");
2684 torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2685 "ServerAuthenticate3 should have failed on b3, due to credential reuse");
2687 ZERO_STRUCT(credentials1.data);
2688 ZERO_STRUCT(credentials2.data);
2689 creds = netlogon_creds_client_init(tctx, a.in.account_name,
2691 a.in.secure_channel_type,
2692 &credentials1, &credentials2,
2693 &mach_password, &credentials3,
2696 torture_assert(tctx, creds != NULL, "memory allocation");
2698 torture_comment(tctx, "Testing ServerAuthenticate3 with zero'ed challenge\n");
2700 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2701 "ServerAuthenticate3 failed");
2702 torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2703 "ServerAuthenticate3 should have failed on b3, due to credential reuse");
2707 static bool test_SamLogon_NULL_domain(struct torture_context *tctx,
2708 struct dcerpc_pipe *p,
2709 struct cli_credentials *credentials)
2711 struct netlogon_creds_CredentialState *creds;
2713 if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
2717 return test_netlogon_ops_args(p, tctx, credentials, creds, true);
2720 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
2721 static uint64_t sequence_nums[3];
2724 try a netlogon DatabaseSync
2726 static bool test_DatabaseSync(struct torture_context *tctx,
2727 struct dcerpc_pipe *p,
2728 struct cli_credentials *machine_credentials)
2730 struct netr_DatabaseSync r;
2731 struct netlogon_creds_CredentialState *creds;
2732 const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
2734 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2735 struct netr_Authenticator credential, return_authenticator;
2736 struct dcerpc_binding_handle *b = p->binding_handle;
2738 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2742 ZERO_STRUCT(return_authenticator);
2744 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2745 r.in.computername = TEST_MACHINE_NAME;
2746 r.in.preferredmaximumlength = (uint32_t)-1;
2747 r.in.return_authenticator = &return_authenticator;
2748 r.out.delta_enum_array = &delta_enum_array;
2749 r.out.return_authenticator = &return_authenticator;
2751 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2753 uint32_t sync_context = 0;
2755 r.in.database_id = database_ids[i];
2756 r.in.sync_context = &sync_context;
2757 r.out.sync_context = &sync_context;
2759 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
2762 netlogon_creds_client_authenticator(creds, &credential);
2764 r.in.credential = &credential;
2766 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync_r(b, tctx, &r),
2767 "DatabaseSync failed");
2768 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2771 /* Native mode servers don't do this */
2772 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
2775 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync");
2777 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
2778 torture_comment(tctx, "Credential chaining failed\n");
2781 if (delta_enum_array &&
2782 delta_enum_array->num_deltas > 0 &&
2783 delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
2784 delta_enum_array->delta_enum[0].delta_union.domain) {
2785 sequence_nums[r.in.database_id] =
2786 delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
2787 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
2789 (unsigned long long)sequence_nums[r.in.database_id]);
2791 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2799 try a netlogon DatabaseDeltas
2801 static bool test_DatabaseDeltas(struct torture_context *tctx,
2802 struct dcerpc_pipe *p,
2803 struct cli_credentials *machine_credentials)
2805 struct netr_DatabaseDeltas r;
2806 struct netlogon_creds_CredentialState *creds;
2807 struct netr_Authenticator credential;
2808 struct netr_Authenticator return_authenticator;
2809 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2810 const uint32_t database_ids[] = {0, 1, 2};
2812 struct dcerpc_binding_handle *b = p->binding_handle;
2814 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2818 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2819 r.in.computername = TEST_MACHINE_NAME;
2820 r.in.preferredmaximumlength = (uint32_t)-1;
2821 ZERO_STRUCT(r.in.return_authenticator);
2822 r.out.return_authenticator = &return_authenticator;
2823 r.out.delta_enum_array = &delta_enum_array;
2825 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2826 r.in.database_id = database_ids[i];
2827 r.in.sequence_num = &sequence_nums[r.in.database_id];
2829 if (*r.in.sequence_num == 0) continue;
2831 *r.in.sequence_num -= 1;
2833 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n",
2834 r.in.database_id, (unsigned long long)*r.in.sequence_num);
2837 netlogon_creds_client_authenticator(creds, &credential);
2839 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseDeltas_r(b, tctx, &r),
2840 "DatabaseDeltas failed");
2841 if (NT_STATUS_EQUAL(r.out.result,
2842 NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
2843 torture_comment(tctx, "not considering %s to be an error\n",
2844 nt_errstr(r.out.result));
2847 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2850 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseDeltas");
2852 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
2853 torture_comment(tctx, "Credential chaining failed\n");
2856 (*r.in.sequence_num)++;
2857 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2863 static bool test_DatabaseRedo(struct torture_context *tctx,
2864 struct dcerpc_pipe *p,
2865 struct cli_credentials *machine_credentials)
2867 struct netr_DatabaseRedo r;
2868 struct netlogon_creds_CredentialState *creds;
2869 struct netr_Authenticator credential;
2870 struct netr_Authenticator return_authenticator;
2871 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2872 struct netr_ChangeLogEntry e;
2873 struct dom_sid null_sid, *sid;
2875 struct dcerpc_binding_handle *b = p->binding_handle;
2877 ZERO_STRUCT(null_sid);
2879 sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
2890 NTSTATUS expected_error;
2891 uint32_t expected_num_results;
2892 uint8_t expected_delta_type_1;
2893 uint8_t expected_delta_type_2;
2894 const char *comment;
2897 /* SAM_DATABASE_DOMAIN */
2902 .db_index = SAM_DATABASE_DOMAIN,
2903 .delta_type = NETR_DELTA_MODIFY_COUNT,
2906 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
2907 .expected_num_results = 0,
2908 .comment = "NETR_DELTA_MODIFY_COUNT"
2913 .db_index = SAM_DATABASE_DOMAIN,
2917 .expected_error = NT_STATUS_OK,
2918 .expected_num_results = 1,
2919 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
2920 .comment = "NULL DELTA"
2925 .db_index = SAM_DATABASE_DOMAIN,
2926 .delta_type = NETR_DELTA_DOMAIN,
2929 .expected_error = NT_STATUS_OK,
2930 .expected_num_results = 1,
2931 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
2932 .comment = "NETR_DELTA_DOMAIN"
2935 .rid = DOMAIN_RID_ADMINISTRATOR,
2937 .db_index = SAM_DATABASE_DOMAIN,
2938 .delta_type = NETR_DELTA_USER,
2941 .expected_error = NT_STATUS_OK,
2942 .expected_num_results = 1,
2943 .expected_delta_type_1 = NETR_DELTA_USER,
2944 .comment = "NETR_DELTA_USER by rid 500"
2947 .rid = DOMAIN_RID_GUEST,
2949 .db_index = SAM_DATABASE_DOMAIN,
2950 .delta_type = NETR_DELTA_USER,
2953 .expected_error = NT_STATUS_OK,
2954 .expected_num_results = 1,
2955 .expected_delta_type_1 = NETR_DELTA_USER,
2956 .comment = "NETR_DELTA_USER by rid 501"
2960 .flags = NETR_CHANGELOG_SID_INCLUDED,
2961 .db_index = SAM_DATABASE_DOMAIN,
2962 .delta_type = NETR_DELTA_USER,
2965 .expected_error = NT_STATUS_OK,
2966 .expected_num_results = 1,
2967 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
2968 .comment = "NETR_DELTA_USER by sid and flags"
2972 .flags = NETR_CHANGELOG_SID_INCLUDED,
2973 .db_index = SAM_DATABASE_DOMAIN,
2974 .delta_type = NETR_DELTA_USER,
2977 .expected_error = NT_STATUS_OK,
2978 .expected_num_results = 1,
2979 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
2980 .comment = "NETR_DELTA_USER by null_sid and flags"
2984 .flags = NETR_CHANGELOG_NAME_INCLUDED,
2985 .db_index = SAM_DATABASE_DOMAIN,
2986 .delta_type = NETR_DELTA_USER,
2988 .name = "administrator",
2989 .expected_error = NT_STATUS_OK,
2990 .expected_num_results = 1,
2991 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
2992 .comment = "NETR_DELTA_USER by name 'administrator'"
2995 .rid = DOMAIN_RID_ADMINS,
2997 .db_index = SAM_DATABASE_DOMAIN,
2998 .delta_type = NETR_DELTA_GROUP,
3001 .expected_error = NT_STATUS_OK,
3002 .expected_num_results = 2,
3003 .expected_delta_type_1 = NETR_DELTA_GROUP,
3004 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
3005 .comment = "NETR_DELTA_GROUP by rid 512"
3008 .rid = DOMAIN_RID_ADMINS,
3010 .db_index = SAM_DATABASE_DOMAIN,
3011 .delta_type = NETR_DELTA_GROUP_MEMBER,
3014 .expected_error = NT_STATUS_OK,
3015 .expected_num_results = 2,
3016 .expected_delta_type_1 = NETR_DELTA_GROUP,
3017 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
3018 .comment = "NETR_DELTA_GROUP_MEMBER by rid 512"
3022 /* SAM_DATABASE_BUILTIN */
3027 .db_index = SAM_DATABASE_BUILTIN,
3028 .delta_type = NETR_DELTA_MODIFY_COUNT,
3031 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
3032 .expected_num_results = 0,
3033 .comment = "NETR_DELTA_MODIFY_COUNT"
3038 .db_index = SAM_DATABASE_BUILTIN,
3039 .delta_type = NETR_DELTA_DOMAIN,
3042 .expected_error = NT_STATUS_OK,
3043 .expected_num_results = 1,
3044 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
3045 .comment = "NETR_DELTA_DOMAIN"
3048 .rid = DOMAIN_RID_ADMINISTRATOR,
3050 .db_index = SAM_DATABASE_BUILTIN,
3051 .delta_type = NETR_DELTA_USER,
3054 .expected_error = NT_STATUS_OK,
3055 .expected_num_results = 1,
3056 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
3057 .comment = "NETR_DELTA_USER by rid 500"
3062 .db_index = SAM_DATABASE_BUILTIN,
3063 .delta_type = NETR_DELTA_USER,
3066 .expected_error = NT_STATUS_OK,
3067 .expected_num_results = 1,
3068 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
3069 .comment = "NETR_DELTA_USER"
3074 .db_index = SAM_DATABASE_BUILTIN,
3075 .delta_type = NETR_DELTA_ALIAS,
3078 .expected_error = NT_STATUS_OK,
3079 .expected_num_results = 2,
3080 .expected_delta_type_1 = NETR_DELTA_ALIAS,
3081 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
3082 .comment = "NETR_DELTA_ALIAS by rid 544"
3087 .db_index = SAM_DATABASE_BUILTIN,
3088 .delta_type = NETR_DELTA_ALIAS_MEMBER,
3091 .expected_error = NT_STATUS_OK,
3092 .expected_num_results = 2,
3093 .expected_delta_type_1 = NETR_DELTA_ALIAS,
3094 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
3095 .comment = "NETR_DELTA_ALIAS_MEMBER by rid 544"
3100 .db_index = SAM_DATABASE_BUILTIN,
3104 .expected_error = NT_STATUS_OK,
3105 .expected_num_results = 1,
3106 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
3107 .comment = "NULL DELTA by rid 544"
3111 .flags = NETR_CHANGELOG_SID_INCLUDED,
3112 .db_index = SAM_DATABASE_BUILTIN,
3114 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
3116 .expected_error = NT_STATUS_OK,
3117 .expected_num_results = 1,
3118 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
3119 .comment = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
3123 .flags = NETR_CHANGELOG_SID_INCLUDED,
3124 .db_index = SAM_DATABASE_BUILTIN,
3125 .delta_type = NETR_DELTA_ALIAS,
3126 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
3128 .expected_error = NT_STATUS_OK,
3129 .expected_num_results = 2,
3130 .expected_delta_type_1 = NETR_DELTA_ALIAS,
3131 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
3132 .comment = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
3136 .flags = NETR_CHANGELOG_SID_INCLUDED,
3137 .db_index = SAM_DATABASE_BUILTIN,
3138 .delta_type = NETR_DELTA_ALIAS,
3139 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
3141 .expected_error = NT_STATUS_OK,
3142 .expected_num_results = 1,
3143 .expected_delta_type_1 = NETR_DELTA_DELETE_ALIAS,
3144 .comment = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
3147 /* SAM_DATABASE_PRIVS */
3152 .db_index = SAM_DATABASE_PRIVS,
3156 .expected_error = NT_STATUS_ACCESS_DENIED,
3157 .expected_num_results = 0,
3158 .comment = "NULL DELTA"
3163 .db_index = SAM_DATABASE_PRIVS,
3164 .delta_type = NETR_DELTA_MODIFY_COUNT,
3167 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
3168 .expected_num_results = 0,
3169 .comment = "NETR_DELTA_MODIFY_COUNT"
3174 .db_index = SAM_DATABASE_PRIVS,
3175 .delta_type = NETR_DELTA_POLICY,
3178 .expected_error = NT_STATUS_OK,
3179 .expected_num_results = 1,
3180 .expected_delta_type_1 = NETR_DELTA_POLICY,
3181 .comment = "NETR_DELTA_POLICY"
3185 .flags = NETR_CHANGELOG_SID_INCLUDED,
3186 .db_index = SAM_DATABASE_PRIVS,
3187 .delta_type = NETR_DELTA_POLICY,
3190 .expected_error = NT_STATUS_OK,
3191 .expected_num_results = 1,
3192 .expected_delta_type_1 = NETR_DELTA_POLICY,
3193 .comment = "NETR_DELTA_POLICY by null sid and flags"
3197 .flags = NETR_CHANGELOG_SID_INCLUDED,
3198 .db_index = SAM_DATABASE_PRIVS,
3199 .delta_type = NETR_DELTA_POLICY,
3200 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
3202 .expected_error = NT_STATUS_OK,
3203 .expected_num_results = 1,
3204 .expected_delta_type_1 = NETR_DELTA_POLICY,
3205 .comment = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
3208 .rid = DOMAIN_RID_ADMINISTRATOR,
3210 .db_index = SAM_DATABASE_PRIVS,
3211 .delta_type = NETR_DELTA_ACCOUNT,
3214 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
3215 .expected_num_results = 0,
3216 .comment = "NETR_DELTA_ACCOUNT by rid 500"
3220 .flags = NETR_CHANGELOG_SID_INCLUDED,
3221 .db_index = SAM_DATABASE_PRIVS,
3222 .delta_type = NETR_DELTA_ACCOUNT,
3223 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
3225 .expected_error = NT_STATUS_OK,
3226 .expected_num_results = 1,
3227 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
3228 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
3232 .flags = NETR_CHANGELOG_SID_INCLUDED |
3233 NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
3234 .db_index = SAM_DATABASE_PRIVS,
3235 .delta_type = NETR_DELTA_ACCOUNT,
3236 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
3238 .expected_error = NT_STATUS_OK,
3239 .expected_num_results = 1,
3240 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
3241 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
3245 .flags = NETR_CHANGELOG_SID_INCLUDED |
3246 NETR_CHANGELOG_NAME_INCLUDED,
3247 .db_index = SAM_DATABASE_PRIVS,
3248 .delta_type = NETR_DELTA_ACCOUNT,
3249 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
3251 .expected_error = NT_STATUS_INVALID_PARAMETER,
3252 .expected_num_results = 0,
3253 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
3256 .rid = DOMAIN_RID_ADMINISTRATOR,
3257 .flags = NETR_CHANGELOG_SID_INCLUDED,
3258 .db_index = SAM_DATABASE_PRIVS,
3259 .delta_type = NETR_DELTA_ACCOUNT,
3262 .expected_error = NT_STATUS_OK,
3263 .expected_num_results = 1,
3264 .expected_delta_type_1 = NETR_DELTA_DELETE_ACCOUNT,
3265 .comment = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
3269 .flags = NETR_CHANGELOG_NAME_INCLUDED,
3270 .db_index = SAM_DATABASE_PRIVS,
3271 .delta_type = NETR_DELTA_SECRET,
3273 .name = "IsurelydontexistIhope",
3274 .expected_error = NT_STATUS_OK,
3275 .expected_num_results = 1,
3276 .expected_delta_type_1 = NETR_DELTA_DELETE_SECRET,
3277 .comment = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
3281 .flags = NETR_CHANGELOG_NAME_INCLUDED,
3282 .db_index = SAM_DATABASE_PRIVS,
3283 .delta_type = NETR_DELTA_SECRET,
3285 .name = "G$BCKUPKEY_P",
3286 .expected_error = NT_STATUS_OK,
3287 .expected_num_results = 1,
3288 .expected_delta_type_1 = NETR_DELTA_SECRET,
3289 .comment = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
3293 ZERO_STRUCT(return_authenticator);
3295 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3296 r.in.computername = TEST_MACHINE_NAME;
3297 r.in.return_authenticator = &return_authenticator;
3298 r.out.return_authenticator = &return_authenticator;
3299 r.out.delta_enum_array = &delta_enum_array;
3301 for (d=0; d<3; d++) {
3302 const char *database = NULL;
3309 database = "BUILTIN";
3318 torture_comment(tctx, "Testing DatabaseRedo\n");
3320 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
3324 for (i=0;i<ARRAY_SIZE(changes);i++) {
3326 if (d != changes[i].db_index) {
3330 netlogon_creds_client_authenticator(creds, &credential);
3332 r.in.credential = &credential;
3334 e.serial_number1 = 0;
3335 e.serial_number2 = 0;
3336 e.object_rid = changes[i].rid;
3337 e.flags = changes[i].flags;
3338 e.db_index = changes[i].db_index;
3339 e.delta_type = changes[i].delta_type;
3341 switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
3342 case NETR_CHANGELOG_SID_INCLUDED:
3343 e.object.object_sid = changes[i].sid;
3345 case NETR_CHANGELOG_NAME_INCLUDED:
3346 e.object.object_name = changes[i].name;
3352 r.in.change_log_entry = e;
3354 torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
3355 database, changes[i].comment);
3357 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseRedo_r(b, tctx, &r),
3358 "DatabaseRedo failed");
3359 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
3363 torture_assert_ntstatus_equal(tctx, r.out.result, changes[i].expected_error, changes[i].comment);
3364 if (delta_enum_array) {
3365 torture_assert_int_equal(tctx,
3366 delta_enum_array->num_deltas,
3367 changes[i].expected_num_results,
3368 changes[i].comment);
3369 if (delta_enum_array->num_deltas > 0) {
3370 torture_assert_int_equal(tctx,
3371 delta_enum_array->delta_enum[0].delta_type,
3372 changes[i].expected_delta_type_1,
3373 changes[i].comment);
3375 if (delta_enum_array->num_deltas > 1) {
3376 torture_assert_int_equal(tctx,
3377 delta_enum_array->delta_enum[1].delta_type,
3378 changes[i].expected_delta_type_2,
3379 changes[i].comment);
3383 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
3384 torture_comment(tctx, "Credential chaining failed\n");
3385 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
3397 try a netlogon AccountDeltas
3399 static bool test_AccountDeltas(struct torture_context *tctx,
3400 struct dcerpc_pipe *p,
3401 struct cli_credentials *machine_credentials)
3403 struct netr_AccountDeltas r;
3404 struct netlogon_creds_CredentialState *creds;
3406 struct netr_AccountBuffer buffer;
3407 uint32_t count_returned = 0;
3408 uint32_t total_entries = 0;
3409 struct netr_UAS_INFO_0 recordid;
3410 struct netr_Authenticator return_authenticator;
3411 struct dcerpc_binding_handle *b = p->binding_handle;
3413 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
3417 ZERO_STRUCT(return_authenticator);
3419 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3420 r.in.computername = TEST_MACHINE_NAME;
3421 r.in.return_authenticator = &return_authenticator;
3422 netlogon_creds_client_authenticator(creds, &r.in.credential);
3423 ZERO_STRUCT(r.in.uas);
3426 r.in.buffersize=100;
3427 r.out.buffer = &buffer;
3428 r.out.count_returned = &count_returned;
3429 r.out.total_entries = &total_entries;
3430 r.out.recordid = &recordid;
3431 r.out.return_authenticator = &return_authenticator;
3433 /* w2k3 returns "NOT IMPLEMENTED" for this call */
3434 torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountDeltas_r(b, tctx, &r),
3435 "AccountDeltas failed");
3436 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
3442 try a netlogon AccountSync
3444 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
3445 struct cli_credentials *machine_credentials)
3447 struct netr_AccountSync r;
3448 struct netlogon_creds_CredentialState *creds;
3450 struct netr_AccountBuffer buffer;
3451 uint32_t count_returned = 0;
3452 uint32_t total_entries = 0;
3453 uint32_t next_reference = 0;
3454 struct netr_UAS_INFO_0 recordid;
3455 struct netr_Authenticator return_authenticator;
3456 struct dcerpc_binding_handle *b = p->binding_handle;
3458 ZERO_STRUCT(recordid);
3459 ZERO_STRUCT(return_authenticator);
3461 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
3465 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3466 r.in.computername = TEST_MACHINE_NAME;
3467 r.in.return_authenticator = &return_authenticator;
3468 netlogon_creds_client_authenticator(creds, &r.in.credential);
3469 r.in.recordid = &recordid;
3472 r.in.buffersize=100;
3473 r.out.buffer = &buffer;
3474 r.out.count_returned = &count_returned;
3475 r.out.total_entries = &total_entries;
3476 r.out.next_reference = &next_reference;
3477 r.out.recordid = &recordid;
3478 r.out.return_authenticator = &return_authenticator;
3480 /* w2k3 returns "NOT IMPLEMENTED" for this call */
3481 torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountSync_r(b, tctx, &r),
3482 "AccountSync failed");
3483 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
3489 try a netlogon GetDcName
3491 static bool test_GetDcName(struct torture_context *tctx,
3492 struct dcerpc_pipe *p)
3494 struct netr_GetDcName r;
3495 const char *dcname = NULL;
3496 struct dcerpc_binding_handle *b = p->binding_handle;
3498 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3499 r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
3500 r.out.dcname = &dcname;
3502 torture_assert_ntstatus_ok(tctx, dcerpc_netr_GetDcName_r(b, tctx, &r),
3503 "GetDcName failed");
3504 torture_assert_werr_ok(tctx, r.out.result, "GetDcName failed");
3506 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
3511 static const char *function_code_str(TALLOC_CTX *mem_ctx,
3512 enum netr_LogonControlCode function_code)
3514 switch (function_code) {
3515 case NETLOGON_CONTROL_QUERY:
3516 return "NETLOGON_CONTROL_QUERY";
3517 case NETLOGON_CONTROL_REPLICATE:
3518 return "NETLOGON_CONTROL_REPLICATE";
3519 case NETLOGON_CONTROL_SYNCHRONIZE:
3520 return "NETLOGON_CONTROL_SYNCHRONIZE";
3521 case NETLOGON_CONTROL_PDC_REPLICATE:
3522 return "NETLOGON_CONTROL_PDC_REPLICATE";
3523 case NETLOGON_CONTROL_REDISCOVER:
3524 return "NETLOGON_CONTROL_REDISCOVER";
3525 case NETLOGON_CONTROL_TC_QUERY:
3526 return "NETLOGON_CONTROL_TC_QUERY";
3527 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
3528 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
3529 case NETLOGON_CONTROL_FIND_USER:
3530 return "NETLOGON_CONTROL_FIND_USER";
3531 case NETLOGON_CONTROL_CHANGE_PASSWORD:
3532 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
3533 case NETLOGON_CONTROL_TC_VERIFY:
3534 return "NETLOGON_CONTROL_TC_VERIFY";
3535 case NETLOGON_CONTROL_FORCE_DNS_REG:
3536 return "NETLOGON_CONTROL_FORCE_DNS_REG";
3537 case NETLOGON_CONTROL_QUERY_DNS_REG:
3538 return "NETLOGON_CONTROL_QUERY_DNS_REG";
3539 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
3540 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
3541 case NETLOGON_CONTROL_TRUNCATE_LOG:
3542 return "NETLOGON_CONTROL_TRUNCATE_LOG";
3543 case NETLOGON_CONTROL_SET_DBFLAG:
3544 return "NETLOGON_CONTROL_SET_DBFLAG";
3545 case NETLOGON_CONTROL_BREAKPOINT:
3546 return "NETLOGON_CONTROL_BREAKPOINT";
3548 return talloc_asprintf(mem_ctx, "unknown function code: %d",
3555 try a netlogon LogonControl
3557 static bool test_LogonControl(struct torture_context *tctx,
3558 struct dcerpc_pipe *p,
3559 struct cli_credentials *machine_credentials)
3563 struct netr_LogonControl r;
3564 union netr_CONTROL_QUERY_INFORMATION query;
3566 enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
3567 struct dcerpc_binding_handle *b = p->binding_handle;
3569 uint32_t function_codes[] = {
3570 NETLOGON_CONTROL_QUERY,
3571 NETLOGON_CONTROL_REPLICATE,
3572 NETLOGON_CONTROL_SYNCHRONIZE,
3573 NETLOGON_CONTROL_PDC_REPLICATE,
3574 NETLOGON_CONTROL_REDISCOVER,
3575 NETLOGON_CONTROL_TC_QUERY,
3576 NETLOGON_CONTROL_TRANSPORT_NOTIFY,
3577 NETLOGON_CONTROL_FIND_USER,
3578 NETLOGON_CONTROL_CHANGE_PASSWORD,
3579 NETLOGON_CONTROL_TC_VERIFY,
3580 NETLOGON_CONTROL_FORCE_DNS_REG,
3581 NETLOGON_CONTROL_QUERY_DNS_REG,
3582 NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
3583 NETLOGON_CONTROL_TRUNCATE_LOG,
3584 NETLOGON_CONTROL_SET_DBFLAG,
3585 NETLOGON_CONTROL_BREAKPOINT
3588 if (machine_credentials) {
3589 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
3592 torture_comment(tctx, "Testing LogonControl with secure channel type: %d\n",
3593 secure_channel_type);
3595 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3596 r.in.function_code = 1;
3597 r.out.query = &query;
3599 for (f=0;f<ARRAY_SIZE(function_codes); f++) {
3602 r.in.function_code = function_codes[f];
3605 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
3606 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3608 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
3609 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
3611 switch (r.in.level) {
3613 switch (r.in.function_code) {
3614 case NETLOGON_CONTROL_REPLICATE:
3615 case NETLOGON_CONTROL_SYNCHRONIZE:
3616 case NETLOGON_CONTROL_PDC_REPLICATE:
3617 case NETLOGON_CONTROL_BREAKPOINT:
3618 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
3619 if ((secure_channel_type == SEC_CHAN_BDC) ||
3620 (secure_channel_type == SEC_CHAN_WKSTA)) {
3621 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
3622 "LogonControl returned unexpected error code");
3624 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
3625 "LogonControl returned unexpected error code");
3629 case NETLOGON_CONTROL_REDISCOVER:
3630 case NETLOGON_CONTROL_TC_QUERY:
3631 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
3632 case NETLOGON_CONTROL_FIND_USER:
3633 case NETLOGON_CONTROL_CHANGE_PASSWORD:
3634 case NETLOGON_CONTROL_TC_VERIFY:
3635 case NETLOGON_CONTROL_FORCE_DNS_REG:
3636 case NETLOGON_CONTROL_QUERY_DNS_REG:
3637 case NETLOGON_CONTROL_SET_DBFLAG:
3638 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
3639 "LogonControl returned unexpected error code");
3641 case NETLOGON_CONTROL_TRUNCATE_LOG:
3642 if ((secure_channel_type == SEC_CHAN_BDC) ||
3643 (secure_channel_type == SEC_CHAN_WKSTA)) {
3644 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
3645 "LogonControl returned unexpected error code");
3646 } else if (!W_ERROR_EQUAL(r.out.result, WERR_NOT_SUPPORTED)) {
3647 torture_assert_werr_ok(tctx, r.out.result,
3648 "LogonControl returned unexpected result");
3652 torture_assert_werr_ok(tctx, r.out.result,
3653 "LogonControl returned unexpected result");
3658 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
3659 "LogonControl returned unexpected error code");
3662 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL,
3663 "LogonControl returned unexpected error code");
3670 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
3671 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3672 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
3673 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
3674 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl");
3681 try a netlogon GetAnyDCName
3683 static bool test_GetAnyDCName(struct torture_context *tctx,
3684 struct dcerpc_pipe *p)
3687 struct netr_GetAnyDCName r;
3688 const char *dcname = NULL;
3689 struct dcerpc_binding_handle *b = p->binding_handle;
3691 r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
3692 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3693 r.out.dcname = &dcname;
3695 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
3696 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3697 if ((!W_ERROR_IS_OK(r.out.result)) &&
3698 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
3703 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
3706 r.in.domainname = NULL;
3708 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
3709 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3710 if ((!W_ERROR_IS_OK(r.out.result)) &&
3711 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
3715 r.in.domainname = "";
3717 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
3718 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3719 if ((!W_ERROR_IS_OK(r.out.result)) &&
3720 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
3729 try a netlogon LogonControl2
3731 static bool test_LogonControl2(struct torture_context *tctx,
3732 struct dcerpc_pipe *p,
3733 struct cli_credentials *machine_credentials)
3737 struct netr_LogonControl2 r;
3738 union netr_CONTROL_DATA_INFORMATION data;
3739 union netr_CONTROL_QUERY_INFORMATION query;
3740 enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
3742 struct dcerpc_binding_handle *b = p->binding_handle;
3744 data.domain = lpcfg_workgroup(tctx->lp_ctx);
3746 if (machine_credentials) {
3747 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
3750 torture_comment(tctx, "Testing LogonControl2 with secure channel type: %d\n",
3751 secure_channel_type);
3753 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3755 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
3757 r.out.query = &query;
3762 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3763 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3765 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3766 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3769 data.domain = lpcfg_workgroup(tctx->lp_ctx);
3771 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
3777 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3778 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3780 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3781 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3784 data.domain = lpcfg_workgroup(tctx->lp_ctx);
3786 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
3792 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3793 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3795 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3796 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3799 data.debug_level = ~0;
3801 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
3807 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3808 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3810 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3811 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3815 r.in.function_code = 52;
3818 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3819 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3821 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3822 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3823 switch (secure_channel_type) {
3825 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2");
3828 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2");
3831 data.debug_level = ~0;
3833 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
3837 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3838 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3840 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3841 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3842 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl2");
3848 try a netlogon DatabaseSync2
3850 static bool test_DatabaseSync2(struct torture_context *tctx,
3851 struct dcerpc_pipe *p,
3852 struct cli_credentials *machine_credentials)
3854 struct netr_DatabaseSync2 r;
3855 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
3856 struct netr_Authenticator return_authenticator, credential;
3858 struct netlogon_creds_CredentialState *creds;
3859 const uint32_t database_ids[] = {0, 1, 2};
3861 struct dcerpc_binding_handle *b = p->binding_handle;
3863 if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
3864 machine_credentials,
3865 cli_credentials_get_secure_channel_type(machine_credentials),
3870 ZERO_STRUCT(return_authenticator);
3872 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3873 r.in.computername = TEST_MACHINE_NAME;
3874 r.in.preferredmaximumlength = (uint32_t)-1;
3875 r.in.return_authenticator = &return_authenticator;
3876 r.out.return_authenticator = &return_authenticator;
3877 r.out.delta_enum_array = &delta_enum_array;
3879 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
3881 uint32_t sync_context = 0;
3883 r.in.database_id = database_ids[i];
3884 r.in.sync_context = &sync_context;
3885 r.out.sync_context = &sync_context;
3886 r.in.restart_state = 0;
3888 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
3891 netlogon_creds_client_authenticator(creds, &credential);
3893 r.in.credential = &credential;
3895 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync2_r(b, tctx, &r),
3896 "DatabaseSync2 failed");
3897 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
3900 /* Native mode servers don't do this */
3901 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
3905 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync2");
3907 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
3908 torture_comment(tctx, "Credential chaining failed\n");
3911 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
3919 try a netlogon LogonControl2Ex
3921 static bool test_LogonControl2Ex(struct torture_context *tctx,
3922 struct dcerpc_pipe *p,
3923 struct cli_credentials *machine_credentials)
3927 struct netr_LogonControl2Ex r;
3928 union netr_CONTROL_DATA_INFORMATION data;
3929 union netr_CONTROL_QUERY_INFORMATION query;
3930 enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
3932 struct dcerpc_binding_handle *b = p->binding_handle;
3934 data.domain = lpcfg_workgroup(tctx->lp_ctx);
3936 if (machine_credentials) {
3937 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
3940 torture_comment(tctx, "Testing LogonControl2Ex with secure channel type: %d\n",
3941 secure_channel_type);
3943 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3945 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
3947 r.out.query = &query;
3952 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
3953 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3955 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
3956 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
3959 data.domain = lpcfg_workgroup(tctx->lp_ctx);
3961 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
3967 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
3968 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3970 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
3971 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
3974 data.domain = lpcfg_workgroup(tctx->lp_ctx);
3976 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
3982 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
3983 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3985 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
3986 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
3989 data.debug_level = ~0;
3991 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
3997 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
3998 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
4000 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4001 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4005 r.in.function_code = 52;
4008 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4009 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
4011 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4012 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4013 switch (secure_channel_type) {
4015 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2Ex");
4018 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2Ex");
4021 data.debug_level = ~0;
4023 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
4027 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4028 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
4030 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4031 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4032 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl2Ex");
4037 static bool test_netr_GetForestTrustInformation(struct torture_context *tctx,
4038 struct dcerpc_pipe *p1,
4039 struct cli_credentials *machine_credentials)
4041 struct netr_GetForestTrustInformation r;
4042 struct netlogon_creds_CredentialState *creds;
4043 struct netr_Authenticator a;
4044 struct netr_Authenticator return_authenticator;
4045 struct lsa_ForestTrustInformation *forest_trust_info;
4046 struct dcerpc_pipe *p = NULL;
4047 struct dcerpc_binding_handle *b = NULL;
4049 if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
4050 machine_credentials, &creds)) {
4053 if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
4054 DCERPC_SIGN | DCERPC_SEAL, &p)) {
4057 b = p->binding_handle;
4059 netlogon_creds_client_authenticator(creds, &a);
4061 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4062 r.in.computer_name = TEST_MACHINE_NAME;
4063 r.in.credential = &a;
4065 r.out.return_authenticator = &return_authenticator;
4066 r.out.forest_trust_info = &forest_trust_info;
4068 torture_assert_ntstatus_ok(tctx,
4069 dcerpc_netr_GetForestTrustInformation_r(b, tctx, &r),
4070 "netr_GetForestTrustInformation failed");
4071 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
4072 torture_comment(tctx, "not considering NT_STATUS_NOT_IMPLEMENTED as an error\n");
4074 torture_assert_ntstatus_ok(tctx, r.out.result,
4075 "netr_GetForestTrustInformation failed");
4078 torture_assert(tctx,
4079 netlogon_creds_client_check(creds, &return_authenticator.cred),
4080 "Credential chaining failed");
4085 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
4086 struct dcerpc_pipe *p, const char *trusted_domain_name)
4089 struct netr_DsRGetForestTrustInformation r;
4090 struct lsa_ForestTrustInformation info, *info_ptr;
4091 struct dcerpc_binding_handle *b = p->binding_handle;
4095 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4096 r.in.trusted_domain_name = trusted_domain_name;
4098 r.out.forest_trust_info = &info_ptr;
4100 torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
4102 status = dcerpc_netr_DsRGetForestTrustInformation_r(b, tctx, &r);
4103 torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
4104 torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
4110 try a netlogon netr_DsrEnumerateDomainTrusts
4112 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
4113 struct dcerpc_pipe *p)
4116 struct netr_DsrEnumerateDomainTrusts r;
4117 struct netr_DomainTrustList trusts;
4119 struct dcerpc_binding_handle *b = p->binding_handle;
4121 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4122 r.in.trust_flags = 0x3f;
4123 r.out.trusts = &trusts;
4125 status = dcerpc_netr_DsrEnumerateDomainTrusts_r(b, tctx, &r);
4126 torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
4127 torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
4129 /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
4130 * will show non-forest trusts and all UPN suffixes of the own forest
4131 * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
4133 if (r.out.trusts->count) {
4134 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
4139 for (i=0; i<r.out.trusts->count; i++) {
4141 /* get info for transitive forest trusts */
4143 if (r.out.trusts->array[i].trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
4144 if (!test_netr_DsRGetForestTrustInformation(tctx, p,
4145 r.out.trusts->array[i].dns_name)) {
4154 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
4155 struct dcerpc_pipe *p)
4158 struct netr_NetrEnumerateTrustedDomains r;
4159 struct netr_Blob trusted_domains_blob;
4160 struct dcerpc_binding_handle *b = p->binding_handle;
4162 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4163 r.out.trusted_domains_blob = &trusted_domains_blob;
4165 status = dcerpc_netr_NetrEnumerateTrustedDomains_r(b, tctx, &r);
4166 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
4167 torture_assert_ntstatus_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
4172 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
4173 struct dcerpc_pipe *p)
4176 struct netr_NetrEnumerateTrustedDomainsEx r;
4177 struct netr_DomainTrustList dom_trust_list;
4178 struct dcerpc_binding_handle *b = p->binding_handle;
4180 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4181 r.out.dom_trust_list = &dom_trust_list;
4183 status = dcerpc_netr_NetrEnumerateTrustedDomainsEx_r(b, tctx, &r);
4184 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
4185 torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
4191 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
4192 const char *computer_name,
4193 const char *expected_site)
4196 struct netr_DsRGetSiteName r;
4197 const char *site = NULL;
4198 struct dcerpc_binding_handle *b = p->binding_handle;
4200 r.in.computer_name = computer_name;
4202 torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
4204 status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
4205 torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
4206 torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
4207 torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
4213 try a netlogon netr_DsRGetDCName
4215 static bool test_netr_DsRGetDCName(struct torture_context *tctx,
4216 struct dcerpc_pipe *p)
4219 struct netr_DsRGetDCName r;
4220 struct netr_DsRGetDCNameInfo *info = NULL;
4221 struct dcerpc_binding_handle *b = p->binding_handle;
4223 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4224 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
4225 r.in.domain_guid = NULL;
4226 r.in.site_guid = NULL;
4227 r.in.flags = DS_RETURN_DNS_NAME;
4230 status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
4231 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
4232 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
4234 torture_assert_int_equal(tctx,
4235 (info->dc_flags & (DS_DNS_CONTROLLER)),
4238 torture_assert_int_equal(tctx,
4239 (info->dc_flags & (DS_DNS_DOMAIN)),
4242 torture_assert_int_equal(tctx,
4243 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4247 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
4250 status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
4251 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
4252 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
4254 torture_assert_int_equal(tctx,
4255 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
4257 torture_assert_int_equal(tctx,
4258 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
4260 torture_assert_int_equal(tctx,
4261 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4265 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
4266 torture_assert_int_equal(tctx,
4267 (info->dc_flags & (DS_SERVER_CLOSEST)),
4272 return test_netr_DsRGetSiteName(p, tctx,
4274 info->dc_site_name);
4278 try a netlogon netr_DsRGetDCNameEx
4280 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
4281 struct dcerpc_pipe *p)
4284 struct netr_DsRGetDCNameEx r;
4285 struct netr_DsRGetDCNameInfo *info = NULL;
4286 struct dcerpc_binding_handle *b = p->binding_handle;
4288 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4289 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
4290 r.in.domain_guid = NULL;
4291 r.in.site_name = NULL;
4292 r.in.flags = DS_RETURN_DNS_NAME;
4295 status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
4296 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
4297 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
4299 torture_assert_int_equal(tctx,
4300 (info->dc_flags & (DS_DNS_CONTROLLER)),
4303 torture_assert_int_equal(tctx,
4304 (info->dc_flags & (DS_DNS_DOMAIN)),
4307 torture_assert_int_equal(tctx,
4308 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4312 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
4315 status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
4316 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
4317 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
4319 torture_assert_int_equal(tctx,
4320 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
4322 torture_assert_int_equal(tctx,
4323 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
4325 torture_assert_int_equal(tctx,
4326 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4330 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
4331 torture_assert_int_equal(tctx,
4332 (info->dc_flags & (DS_SERVER_CLOSEST)),
4337 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
4338 info->dc_site_name);
4342 try a netlogon netr_DsRGetDCNameEx2
4344 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
4345 struct dcerpc_pipe *p)
4348 struct netr_DsRGetDCNameEx2 r;
4349 struct netr_DsRGetDCNameInfo *info = NULL;
4350 struct dcerpc_binding_handle *b = p->binding_handle;
4352 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with no inputs\n");
4354 r.in.flags = DS_RETURN_DNS_NAME;
4357 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
4358 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
4359 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
4361 torture_assert_int_equal(tctx,
4362 (info->dc_flags & (DS_DNS_CONTROLLER)),
4365 torture_assert_int_equal(tctx,
4366 (info->dc_flags & (DS_DNS_DOMAIN)),
4369 torture_assert_int_equal(tctx,
4370 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4374 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4375 r.in.client_account = NULL;
4376 r.in.mask = 0x00000000;
4377 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
4378 r.in.domain_guid = NULL;
4379 r.in.site_name = NULL;
4380 r.in.flags = DS_RETURN_DNS_NAME;
4383 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
4385 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
4386 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
4387 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
4389 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
4392 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
4393 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
4394 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
4396 torture_assert_int_equal(tctx,
4397 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
4399 torture_assert_int_equal(tctx,
4400 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
4402 torture_assert_int_equal(tctx,
4403 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4407 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
4408 torture_assert_int_equal(tctx,
4409 (info->dc_flags & (DS_SERVER_CLOSEST)),
4414 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client account\n");
4415 r.in.client_account = TEST_MACHINE_NAME"$";
4416 r.in.mask = ACB_SVRTRUST;
4417 r.in.flags = DS_RETURN_FLAT_NAME;
4420 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
4421 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
4422 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
4424 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
4425 info->dc_site_name);
4428 /* This is a substitution for "samdb_server_site_name" which relies on the
4429 * correct "lp_ctx" and therefore can't be used here. */
4430 static const char *server_site_name(struct torture_context *tctx,
4431 struct ldb_context *ldb)
4433 TALLOC_CTX *tmp_ctx;
4434 struct ldb_dn *dn, *server_dn;
4435 const struct ldb_val *site_name_val;
4436 const char *server_dn_str, *site_name;
4438 tmp_ctx = talloc_new(ldb);
4439 if (tmp_ctx == NULL) {
4443 dn = ldb_dn_new(tmp_ctx, ldb, "");
4448 server_dn_str = samdb_search_string(ldb, tmp_ctx, dn, "serverName",
4450 if (server_dn_str == NULL) {
4454 server_dn = ldb_dn_new(tmp_ctx, ldb, server_dn_str);
4455 if (server_dn == NULL) {
4459 /* CN=<Server name>, CN=Servers, CN=<Site name>, CN=Sites, ... */
4460 site_name_val = ldb_dn_get_component_val(server_dn, 2);
4461 if (site_name_val == NULL) {
4465 site_name = (const char *) site_name_val->data;
4467 talloc_steal(tctx, site_name);
4468 talloc_free(tmp_ctx);
4473 talloc_free(tmp_ctx);
4477 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
4478 struct dcerpc_pipe *p)
4481 struct ldb_context *sam_ctx = NULL;
4483 struct netr_DsrGetDcSiteCoverageW r;
4484 struct DcSitesCtr *ctr = NULL;
4485 struct dcerpc_binding_handle *b = p->binding_handle;
4487 torture_comment(tctx, "This does only pass with the default site\n");
4489 /* We won't double-check this when we are over 'local' transports */
4490 if (dcerpc_server_name(p)) {
4491 /* Set up connection to SAMDB on DC */
4492 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
4493 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
4495 popt_get_cmdline_credentials(),
4498 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
4501 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4504 status = dcerpc_netr_DsrGetDcSiteCoverageW_r(b, tctx, &r);
4505 torture_assert_ntstatus_ok(tctx, status, "failed");
4506 torture_assert_werr_ok(tctx, r.out.result, "failed");
4508 torture_assert(tctx, ctr->num_sites == 1,
4509 "we should per default only get the default site");
4510 if (sam_ctx != NULL) {
4511 torture_assert_casestr_equal(tctx, ctr->sites[0].string,
4512 server_site_name(tctx, sam_ctx),
4513 "didn't return default site");
4519 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
4520 struct dcerpc_pipe *p)
4523 struct ldb_context *sam_ctx = NULL;
4525 struct netr_DsRAddressToSitenamesW r;
4526 struct netr_DsRAddress addrs[6];
4527 struct sockaddr_in *addr;
4529 struct sockaddr_in6 *addr6;
4531 struct netr_DsRAddressToSitenamesWCtr *ctr;
4532 struct dcerpc_binding_handle *b = p->binding_handle;
4536 torture_comment(tctx, "This does only pass with the default site\n");
4538 /* We won't double-check this when we are over 'local' transports */
4539 if (dcerpc_server_name(p)) {
4540 /* Set up connection to SAMDB on DC */
4541 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
4542 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
4544 popt_get_cmdline_credentials(),
4547 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
4550 /* First try valid IP addresses */
4552 addrs[0].size = sizeof(struct sockaddr_in);
4553 addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
4554 addr = (struct sockaddr_in *) addrs[0].buffer;
4555 addrs[0].buffer[0] = AF_INET;
4556 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
4557 torture_assert(tctx, ret > 0, "inet_pton failed");
4559 addrs[1].size = sizeof(struct sockaddr_in);
4560 addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
4561 addr = (struct sockaddr_in *) addrs[1].buffer;
4562 addrs[1].buffer[0] = AF_INET;
4563 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
4564 torture_assert(tctx, ret > 0, "inet_pton failed");
4566 addrs[2].size = sizeof(struct sockaddr_in);
4567 addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
4568 addr = (struct sockaddr_in *) addrs[2].buffer;
4569 addrs[2].buffer[0] = AF_INET;
4570 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
4571 torture_assert(tctx, ret > 0, "inet_pton failed");
4574 addrs[3].size = sizeof(struct sockaddr_in6);
4575 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
4576 addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
4577 addrs[3].buffer[0] = AF_INET6;
4578 ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
4579 torture_assert(tctx, ret > 0, "inet_pton failed");
4581 addrs[4].size = sizeof(struct sockaddr_in6);
4582 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
4583 addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
4584 addrs[4].buffer[0] = AF_INET6;
4585 ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
4586 torture_assert(tctx, ret > 0, "inet_pton failed");
4588 addrs[5].size = sizeof(struct sockaddr_in6);
4589 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
4590 addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
4591 addrs[5].buffer[0] = AF_INET6;
4592 ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
4593 torture_assert(tctx, ret > 0, "inet_pton failed");
4595 /* the test cases are repeated to have exactly 6. This is for
4596 * compatibility with IPv4-only machines */
4597 addrs[3].size = sizeof(struct sockaddr_in);
4598 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
4599 addr = (struct sockaddr_in *) addrs[3].buffer;
4600 addrs[3].buffer[0] = AF_INET;
4601 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
4602 torture_assert(tctx, ret > 0, "inet_pton failed");
4604 addrs[4].size = sizeof(struct sockaddr_in);
4605 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
4606 addr = (struct sockaddr_in *) addrs[4].buffer;
4607 addrs[4].buffer[0] = AF_INET;
4608 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
4609 torture_assert(tctx, ret > 0, "inet_pton failed");
4611 addrs[5].size = sizeof(struct sockaddr_in);
4612 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
4613 addr = (struct sockaddr_in *) addrs[5].buffer;
4614 addrs[5].buffer[0] = AF_INET;
4615 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
4616 torture_assert(tctx, ret > 0, "inet_pton failed");
4619 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
4621 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4623 r.in.addresses = addrs;
4626 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
4627 torture_assert_ntstatus_ok(tctx, status, "failed");
4628 torture_assert_werr_ok(tctx, r.out.result, "failed");
4630 if (sam_ctx != NULL) {
4631 for (i = 0; i < 3; i++) {
4632 torture_assert_casestr_equal(tctx,
4633 ctr->sitename[i].string,
4634 server_site_name(tctx, sam_ctx),
4635 "didn't return default site");
4637 for (i = 3; i < 6; i++) {
4638 /* Windows returns "NULL" for the sitename if it isn't
4639 * IPv6 configured */
4640 if (torture_setting_bool(tctx, "samba4", false)) {
4641 torture_assert_casestr_equal(tctx,
4642 ctr->sitename[i].string,
4643 server_site_name(tctx, sam_ctx),
4644 "didn't return default site");
4649 /* Now try invalid ones (too short buffers) */
4659 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
4660 torture_assert_ntstatus_ok(tctx, status, "failed");
4661 torture_assert_werr_ok(tctx, r.out.result, "failed");
4663 for (i = 0; i < 6; i++) {
4664 torture_assert(tctx, ctr->sitename[i].string == NULL,
4665 "sitename should be null");
4668 /* Now try invalid ones (wrong address types) */
4671 addrs[0].buffer[0] = AF_UNSPEC;
4673 addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
4675 addrs[2].buffer[0] = AF_UNIX;
4678 addrs[3].buffer[0] = 250;
4680 addrs[4].buffer[0] = 251;
4682 addrs[5].buffer[0] = 252;
4684 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
4685 torture_assert_ntstatus_ok(tctx, status, "failed");
4686 torture_assert_werr_ok(tctx, r.out.result, "failed");
4688 for (i = 0; i < 6; i++) {
4689 torture_assert(tctx, ctr->sitename[i].string == NULL,
4690 "sitename should be null");
4696 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
4697 struct dcerpc_pipe *p)
4700 struct ldb_context *sam_ctx = NULL;
4702 struct netr_DsRAddressToSitenamesExW r;
4703 struct netr_DsRAddress addrs[6];
4704 struct sockaddr_in *addr;
4706 struct sockaddr_in6 *addr6;
4708 struct netr_DsRAddressToSitenamesExWCtr *ctr;
4709 struct dcerpc_binding_handle *b = p->binding_handle;
4713 torture_comment(tctx, "This does pass with the default site\n");
4715 /* We won't double-check this when we are over 'local' transports */
4716 if (dcerpc_server_name(p)) {
4717 /* Set up connection to SAMDB on DC */
4718 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
4719 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
4721 popt_get_cmdline_credentials(),
4724 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
4727 /* First try valid IP addresses */
4729 addrs[0].size = sizeof(struct sockaddr_in);
4730 addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
4731 addr = (struct sockaddr_in *) addrs[0].buffer;
4732 addrs[0].buffer[0] = AF_INET;
4733 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
4734 torture_assert(tctx, ret > 0, "inet_pton failed");
4736 addrs[1].size = sizeof(struct sockaddr_in);
4737 addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
4738 addr = (struct sockaddr_in *) addrs[1].buffer;
4739 addrs[1].buffer[0] = AF_INET;
4740 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
4741 torture_assert(tctx, ret > 0, "inet_pton failed");
4743 addrs[2].size = sizeof(struct sockaddr_in);
4744 addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
4745 addr = (struct sockaddr_in *) addrs[2].buffer;
4746 addrs[2].buffer[0] = AF_INET;
4747 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
4748 torture_assert(tctx, ret > 0, "inet_pton failed");
4751 addrs[3].size = sizeof(struct sockaddr_in6);
4752 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
4753 addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
4754 addrs[3].buffer[0] = AF_INET6;
4755 ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
4756 torture_assert(tctx, ret > 0, "inet_pton failed");
4758 addrs[4].size = sizeof(struct sockaddr_in6);
4759 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
4760 addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
4761 addrs[4].buffer[0] = AF_INET6;
4762 ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
4763 torture_assert(tctx, ret > 0, "inet_pton failed");
4765 addrs[5].size = sizeof(struct sockaddr_in6);
4766 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
4767 addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
4768 addrs[5].buffer[0] = AF_INET6;
4769 ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
4770 torture_assert(tctx, ret > 0, "inet_pton failed");
4772 /* the test cases are repeated to have exactly 6. This is for
4773 * compatibility with IPv4-only machines */
4774 addrs[3].size = sizeof(struct sockaddr_in);
4775 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
4776 addr = (struct sockaddr_in *) addrs[3].buffer;
4777 addrs[3].buffer[0] = AF_INET;
4778 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
4779 torture_assert(tctx, ret > 0, "inet_pton failed");
4781 addrs[4].size = sizeof(struct sockaddr_in);
4782 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
4783 addr = (struct sockaddr_in *) addrs[4].buffer;
4784 addrs[4].buffer[0] = AF_INET;
4785 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
4786 torture_assert(tctx, ret > 0, "inet_pton failed");
4788 addrs[5].size = sizeof(struct sockaddr_in);
4789 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
4790 addr = (struct sockaddr_in *) addrs[5].buffer;
4791 addrs[5].buffer[0] = AF_INET;
4792 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
4793 torture_assert(tctx, ret > 0, "inet_pton failed");
4796 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
4798 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4800 r.in.addresses = addrs;
4803 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
4804 torture_assert_ntstatus_ok(tctx, status, "failed");
4805 torture_assert_werr_ok(tctx, r.out.result, "failed");
4807 if (sam_ctx != NULL) {
4808 for (i = 0; i < 3; i++) {
4809 torture_assert_casestr_equal(tctx,
4810 ctr->sitename[i].string,
4811 server_site_name(tctx, sam_ctx),
4812 "didn't return default site");
4813 torture_assert(tctx, ctr->subnetname[i].string == NULL,
4814 "subnet should be null");
4816 for (i = 3; i < 6; i++) {
4817 /* Windows returns "NULL" for the sitename if it isn't
4818 * IPv6 configured */
4819 if (torture_setting_bool(tctx, "samba4", false)) {
4820 torture_assert_casestr_equal(tctx,
4821 ctr->sitename[i].string,
4822 server_site_name(tctx, sam_ctx),
4823 "didn't return default site");
4825 torture_assert(tctx, ctr->subnetname[i].string == NULL,
4826 "subnet should be null");
4830 /* Now try invalid ones (too short buffers) */
4840 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
4841 torture_assert_ntstatus_ok(tctx, status, "failed");
4842 torture_assert_werr_ok(tctx, r.out.result, "failed");
4844 for (i = 0; i < 6; i++) {
4845 torture_assert(tctx, ctr->sitename[i].string == NULL,
4846 "sitename should be null");
4847 torture_assert(tctx, ctr->subnetname[i].string == NULL,
4848 "subnet should be null");
4852 addrs[0].buffer[0] = AF_UNSPEC;
4854 addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
4856 addrs[2].buffer[0] = AF_UNIX;
4859 addrs[3].buffer[0] = 250;
4861 addrs[4].buffer[0] = 251;
4863 addrs[5].buffer[0] = 252;
4865 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
4866 torture_assert_ntstatus_ok(tctx, status, "failed");
4867 torture_assert_werr_ok(tctx, r.out.result, "failed");
4869 for (i = 0; i < 6; i++) {
4870 torture_assert(tctx, ctr->sitename[i].string == NULL,
4871 "sitename should be null");
4872 torture_assert(tctx, ctr->subnetname[i].string == NULL,
4873 "subnet should be null");
4879 static bool test_netr_ServerGetTrustInfo_flags(struct torture_context *tctx,
4880 struct dcerpc_pipe *p1,
4881 struct cli_credentials *machine_credentials,
4882 uint32_t negotiate_flags)
4884 struct netr_ServerGetTrustInfo r;
4886 struct netr_Authenticator a;
4887 struct netr_Authenticator return_authenticator;
4888 struct samr_Password new_owf_password;
4889 struct samr_Password old_owf_password;
4890 struct netr_TrustInfo *trust_info;
4892 struct netlogon_creds_CredentialState *creds;
4893 struct dcerpc_pipe *p = NULL;
4894 struct dcerpc_binding_handle *b = NULL;
4896 struct samr_Password nt_hash;
4898 if (!test_SetupCredentials3(p1, tctx, negotiate_flags,
4899 machine_credentials, &creds)) {
4902 if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
4903 DCERPC_SIGN | DCERPC_SEAL, &p)) {
4906 b = p->binding_handle;
4908 netlogon_creds_client_authenticator(creds, &a);
4910 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4911 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
4912 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
4913 r.in.computer_name = TEST_MACHINE_NAME;
4914 r.in.credential = &a;
4916 r.out.return_authenticator = &return_authenticator;
4917 r.out.new_owf_password = &new_owf_password;
4918 r.out.old_owf_password = &old_owf_password;
4919 r.out.trust_info = &trust_info;
4921 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerGetTrustInfo_r(b, tctx, &r),
4922 "ServerGetTrustInfo failed");
4923 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerGetTrustInfo failed");
4924 torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
4926 E_md4hash(cli_credentials_get_password(machine_credentials), nt_hash.hash);
4928 netlogon_creds_des_decrypt(creds, &new_owf_password);
4930 dump_data(1, new_owf_password.hash, 16);
4931 dump_data(1, nt_hash.hash, 16);
4933 torture_assert_mem_equal(tctx, new_owf_password.hash, nt_hash.hash, 16,
4934 "received unexpected owf password\n");
4939 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
4940 struct dcerpc_pipe *p,
4941 struct cli_credentials *machine_credentials)
4943 return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
4944 NETLOGON_NEG_AUTH2_ADS_FLAGS);
4947 static bool test_netr_ServerGetTrustInfo_AES(struct torture_context *tctx,
4948 struct dcerpc_pipe *p,
4949 struct cli_credentials *machine_credentials)
4951 return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
4952 NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
4955 static bool test_GetDomainInfo(struct torture_context *tctx,
4956 struct dcerpc_pipe *p1,
4957 struct cli_credentials *machine_credentials)
4959 struct netr_LogonGetDomainInfo r;
4960 struct netr_WorkstationInformation q1;
4961 struct netr_Authenticator a;
4962 struct netlogon_creds_CredentialState *creds;
4963 struct netr_OsVersion os;
4964 union netr_WorkstationInfo query;
4965 union netr_DomainInfo info;
4966 const char* const attrs[] = { "dNSHostName", "operatingSystem",
4967 "operatingSystemServicePack", "operatingSystemVersion",
4968 "servicePrincipalName", NULL };
4970 struct ldb_context *sam_ctx = NULL;
4971 struct ldb_message **res;
4972 struct ldb_message_element *spn_el;
4975 const char *old_dnsname = NULL;
4978 char *temp_str = NULL;
4979 char *temp_str2 = NULL;
4980 struct dcerpc_pipe *p = NULL;
4981 struct dcerpc_binding_handle *b = NULL;
4982 struct netr_OneDomainInfo *odi1 = NULL;
4983 struct netr_OneDomainInfo *odi2 = NULL;
4984 struct netr_trust_extension_info *tex2 = NULL;
4986 torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
4988 if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
4989 machine_credentials, &creds)) {
4992 if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
4993 DCERPC_SIGN | DCERPC_SEAL, &p)) {
4996 b = p->binding_handle;
4998 /* We won't double-check this when we are over 'local' transports */
4999 if (dcerpc_server_name(p)) {
5000 /* Set up connection to SAMDB on DC */
5001 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
5002 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
5004 popt_get_cmdline_credentials(),
5007 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
5010 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
5011 netlogon_creds_client_authenticator(creds, &a);
5014 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
5015 r.in.computer_name = TEST_MACHINE_NAME;
5016 r.in.credential = &a;
5018 r.in.return_authenticator = &a;
5019 r.in.query = &query;
5020 r.out.return_authenticator = &a;
5024 os.os.MajorVersion = 123;
5025 os.os.MinorVersion = 456;
5026 os.os.BuildNumber = 789;
5027 os.os.CSDVersion = "Service Pack 10";
5028 os.os.ServicePackMajor = 10;
5029 os.os.ServicePackMinor = 1;
5030 os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
5031 os.os.ProductType = NETR_VER_NT_SERVER;
5034 version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
5035 os.os.MinorVersion, os.os.BuildNumber);
5038 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
5039 lpcfg_dnsdomain(tctx->lp_ctx));
5040 q1.sitename = "Default-First-Site-Name";
5041 q1.os_version.os = &os;
5042 q1.os_name.string = talloc_asprintf(tctx,
5043 "Tortured by Samba4 RPC-NETLOGON: %s",
5044 timestring(tctx, time(NULL)));
5046 /* The workstation handles the "servicePrincipalName" and DNS hostname
5048 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
5050 query.workstation_info = &q1;
5053 /* Gets back the old DNS hostname in AD */
5054 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
5055 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
5057 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
5059 /* Gets back the "servicePrincipalName"s in AD */
5060 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5061 if (spn_el != NULL) {
5062 for (i=0; i < spn_el->num_values; i++) {
5063 spns = talloc_realloc(tctx, spns, char *, i + 1);
5064 spns[i] = (char *) spn_el->values[i].data;
5070 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5071 "LogonGetDomainInfo failed");
5072 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5073 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5078 /* AD workstation infos entry check */
5079 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
5080 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
5081 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
5082 torture_assert_str_equal(tctx,
5083 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
5084 q1.os_name.string, "'operatingSystem' wrong!");
5085 torture_assert_str_equal(tctx,
5086 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
5087 os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
5088 torture_assert_str_equal(tctx,
5089 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
5090 version_str, "'operatingSystemVersion' wrong!");
5092 if (old_dnsname != NULL) {
5093 /* If before a DNS hostname was set then it should remain
5094 the same in combination with the "servicePrincipalName"s.
5095 The DNS hostname should also be returned by our
5096 "LogonGetDomainInfo" call (in the domain info structure). */
5098 torture_assert_str_equal(tctx,
5099 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
5100 old_dnsname, "'DNS hostname' was not set!");
5102 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5103 torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
5104 "'servicePrincipalName's not set!");
5105 torture_assert(tctx, spn_el->num_values == num_spns,
5106 "'servicePrincipalName's incorrect!");
5107 for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
5108 torture_assert_str_equal(tctx,
5109 (char *) spn_el->values[i].data,
5110 spns[i], "'servicePrincipalName's incorrect!");
5112 torture_assert_str_equal(tctx,
5113 info.domain_info->dns_hostname.string,
5115 "Out 'DNS hostname' doesn't match the old one!");
5117 /* If no DNS hostname was set then also now none should be set,
5118 the "servicePrincipalName"s should remain empty and no DNS
5119 hostname should be returned by our "LogonGetDomainInfo"
5120 call (in the domain info structure). */
5122 torture_assert(tctx,
5123 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
5124 "'DNS hostname' was set!");
5126 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5127 torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
5128 "'servicePrincipalName's were set!");
5130 torture_assert(tctx,
5131 info.domain_info->dns_hostname.string == NULL,
5132 "Out 'DNS host name' was set!");
5136 /* Checks "workstation flags" */
5137 torture_assert(tctx,
5138 info.domain_info->workstation_flags
5139 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
5140 "Out 'workstation flags' don't match!");
5143 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname doesn't work)\n");
5144 netlogon_creds_client_authenticator(creds, &a);
5146 /* Wipe out the osVersion, and prove which values still 'stick' */
5147 q1.os_version.os = NULL;
5149 /* Change also the DNS hostname to test differences in behaviour */
5150 talloc_free(discard_const_p(char, q1.dns_hostname));
5151 q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
5152 lpcfg_dnsdomain(tctx->lp_ctx));
5154 /* The workstation handles the "servicePrincipalName" and DNS hostname
5156 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
5158 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5159 "LogonGetDomainInfo failed");
5160 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5162 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5167 /* AD workstation infos entry check */
5168 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
5169 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
5170 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
5172 torture_assert_str_equal(tctx,
5173 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
5174 q1.os_name.string, "'operatingSystem' should stick!");
5175 torture_assert(tctx,
5176 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
5177 "'operatingSystemServicePack' shouldn't stick!");
5178 torture_assert(tctx,
5179 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
5180 "'operatingSystemVersion' shouldn't stick!");
5182 /* The DNS host name shouldn't have been updated by the server */
5184 torture_assert_str_equal(tctx,
5185 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
5186 old_dnsname, "'DNS host name' did change!");
5188 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
5189 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
5191 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5192 torture_assert(tctx, spn_el != NULL,
5193 "There should exist 'servicePrincipalName's in AD!");
5194 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
5195 for (i=0; i < spn_el->num_values; i++)
5196 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
5198 torture_assert(tctx, i != spn_el->num_values,
5199 "'servicePrincipalName' HOST/<Netbios name> not found!");
5200 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
5201 for (i=0; i < spn_el->num_values; i++)
5202 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
5204 torture_assert(tctx, i != spn_el->num_values,
5205 "'servicePrincipalName' HOST/<FQDN name> not found!");
5207 /* Check that the out DNS hostname was set properly */
5208 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
5209 old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
5212 /* Checks "workstation flags" */
5213 torture_assert(tctx,
5214 info.domain_info->workstation_flags == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
5215 "Out 'workstation flags' don't match!");
5218 /* Now try the same but the workstation flags set to 0 */
5220 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (variation of DNS hostname doesn't work)\n");
5221 netlogon_creds_client_authenticator(creds, &a);
5223 /* Change also the DNS hostname to test differences in behaviour */
5224 talloc_free(discard_const_p(char, q1.dns_hostname));
5225 q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
5226 lpcfg_dnsdomain(tctx->lp_ctx));
5228 /* Wipe out the osVersion, and prove which values still 'stick' */
5229 q1.os_version.os = NULL;
5231 /* Let the DC handle the "servicePrincipalName" and DNS hostname
5233 q1.workstation_flags = 0;
5235 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5236 "LogonGetDomainInfo failed");
5237 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5238 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5243 /* AD workstation infos entry check */
5244 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
5245 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
5246 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
5248 torture_assert_str_equal(tctx,
5249 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
5250 q1.os_name.string, "'operatingSystem' should stick!");
5251 torture_assert(tctx,
5252 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
5253 "'operatingSystemServicePack' shouldn't stick!");
5254 torture_assert(tctx,
5255 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
5256 "'operatingSystemVersion' shouldn't stick!");
5258 /* The DNS host name shouldn't have been updated by the server */
5260 torture_assert_str_equal(tctx,
5261 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
5262 old_dnsname, "'DNS host name' did change!");
5264 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
5265 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
5267 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5268 torture_assert(tctx, spn_el != NULL,
5269 "There should exist 'servicePrincipalName's in AD!");
5270 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
5271 for (i=0; i < spn_el->num_values; i++)
5272 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
5274 torture_assert(tctx, i != spn_el->num_values,
5275 "'servicePrincipalName' HOST/<Netbios name> not found!");
5276 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
5277 for (i=0; i < spn_el->num_values; i++)
5278 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
5280 torture_assert(tctx, i != spn_el->num_values,
5281 "'servicePrincipalName' HOST/<FQDN name> not found!");
5283 /* Here the server gives us NULL as the out DNS hostname */
5284 torture_assert(tctx, info.domain_info->dns_hostname.string == NULL,
5285 "Out 'DNS hostname' should be NULL!");
5288 /* Checks "workstation flags" */
5289 torture_assert(tctx,
5290 info.domain_info->workstation_flags == 0,
5291 "Out 'workstation flags' don't match!");
5294 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (verification of DNS hostname and check for trusted domains)\n");
5295 netlogon_creds_client_authenticator(creds, &a);
5297 /* Put the DNS hostname back */
5298 talloc_free(discard_const_p(char, q1.dns_hostname));
5299 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
5300 lpcfg_dnsdomain(tctx->lp_ctx));
5302 /* The workstation handles the "servicePrincipalName" and DNS hostname
5304 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
5306 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5307 "LogonGetDomainInfo failed");
5308 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5309 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5313 /* Now the in/out DNS hostnames should be the same */
5314 torture_assert_str_equal(tctx,
5315 info.domain_info->dns_hostname.string,
5316 query.workstation_info->dns_hostname,
5317 "In/Out 'DNS hostnames' don't match!");
5318 old_dnsname = info.domain_info->dns_hostname.string;
5320 /* Checks "workstation flags" */
5321 torture_assert(tctx,
5322 info.domain_info->workstation_flags
5323 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
5324 "Out 'workstation flags' don't match!");
5326 /* Checks for trusted domains */
5327 torture_assert(tctx,
5328 (info.domain_info->trusted_domain_count != 0)
5329 && (info.domain_info->trusted_domains != NULL),
5330 "Trusted domains have been requested!");
5333 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 5th call (check for trusted domains)\n");
5334 netlogon_creds_client_authenticator(creds, &a);
5336 /* The workstation handles the "servicePrincipalName" and DNS hostname
5337 updates and requests inbound trusts */
5338 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
5339 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
5341 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5342 "LogonGetDomainInfo failed");
5343 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5344 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5348 /* Checks "workstation flags" */
5349 torture_assert(tctx,
5350 info.domain_info->workstation_flags
5351 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
5352 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
5353 "Out 'workstation flags' don't match!");
5355 /* Checks for trusted domains */
5356 torture_assert(tctx,
5357 (info.domain_info->trusted_domain_count != 0)
5358 && (info.domain_info->trusted_domains != NULL),
5359 "Trusted domains have been requested!");
5361 odi1 = &info.domain_info->primary_domain;
5363 torture_assert(tctx, !GUID_all_zero(&odi1->domain_guid),
5364 "primary domain_guid needs to be valid");
5366 for (i=0; i < info.domain_info->trusted_domain_count; i++) {
5367 struct netr_OneDomainInfo *odiT =
5368 &info.domain_info->trusted_domains[i];
5369 struct netr_trust_extension_info *texT = NULL;
5371 torture_assert_int_equal(tctx, odiT->trust_extension.length, 16,
5372 "trust_list should have extension");
5373 torture_assert(tctx, odiT->trust_extension.info != NULL,
5374 "trust_list should have extension");
5375 texT = &odiT->trust_extension.info->info;
5377 if (GUID_equal(&odiT->domain_guid, &odi1->domain_guid)) {
5383 torture_assert_int_equal(tctx,
5384 texT->flags & NETR_TRUST_FLAG_PRIMARY,
5386 "trust_list flags should not have PRIMARY");
5388 torture_assert(tctx, odiT->domainname.string != NULL,
5389 "trust_list domainname should be valid");
5390 if (texT->trust_type == LSA_TRUST_TYPE_DOWNLEVEL) {
5391 torture_assert(tctx, odiT->dns_domainname.string == NULL,
5392 "trust_list dns_domainname should be NULL for downlevel");
5394 torture_assert(tctx, odiT->dns_domainname.string != NULL,
5395 "trust_list dns_domainname should be valid for uplevel");
5397 torture_assert(tctx, odiT->dns_forestname.string == NULL,
5398 "trust_list dns_forestname needs to be NULL");
5400 torture_assert(tctx, odiT->domain_sid != NULL,
5401 "trust_list domain_sid needs to be valid");
5404 torture_assert(tctx, odi2 != NULL,
5405 "trust_list primary domain not found.");
5407 torture_assert_str_equal(tctx,
5408 odi1->domainname.string,
5409 odi2->domainname.string,
5410 "netbios name should match");
5412 temp_str = talloc_strdup(tctx, odi1->dns_domainname.string);
5413 torture_assert(tctx, temp_str != NULL,
5414 "primary_domain dns_domainname copy");
5415 temp_str2 = strrchr(temp_str, '.');
5416 torture_assert(tctx, temp_str2 != NULL && temp_str2[1] == '\0',
5417 "primary_domain dns_domainname needs trailing '.'");
5418 temp_str2[0] = '\0';
5419 torture_assert_str_equal(tctx,
5421 odi2->dns_domainname.string,
5422 "dns domainname should match "
5423 "(without trailing '.')");
5425 temp_str = talloc_strdup(tctx, odi1->dns_forestname.string);
5426 torture_assert(tctx, temp_str != NULL,
5427 "primary_domain dns_forestname copy");
5428 temp_str2 = strrchr(temp_str, '.');
5429 torture_assert(tctx, temp_str2 != NULL && temp_str2[1] == '\0',
5430 "primary_domain dns_forestname needs trailing '.'");
5431 temp_str2[0] = '\0';
5432 torture_assert(tctx, odi2->dns_forestname.string == NULL,
5433 "trust_list dns_forestname needs to be NULL");
5435 torture_assert_guid_equal(tctx, odi1->domain_guid, odi2->domain_guid,
5436 "domain_guid should match");
5437 torture_assert(tctx, odi1->domain_sid != NULL,
5438 "primary domain_sid needs to be valid");
5439 torture_assert(tctx, odi2->domain_sid != NULL,
5440 "trust_list domain_sid needs to be valid");
5441 torture_assert_sid_equal(tctx, odi1->domain_sid, odi2->domain_sid,
5442 "domain_sid should match");
5444 torture_assert_int_equal(tctx, odi1->trust_extension.length, 0,
5445 "primary_domain should not have extension");
5446 torture_assert_int_equal(tctx, odi2->trust_extension.length, 16,
5447 "trust_list should have extension");
5448 torture_assert(tctx, odi2->trust_extension.info != NULL,
5449 "trust_list should have extension");
5450 tex2 = &odi2->trust_extension.info->info;
5451 torture_assert_int_equal(tctx,
5452 tex2->flags & NETR_TRUST_FLAG_PRIMARY,
5453 NETR_TRUST_FLAG_PRIMARY,
5454 "trust_list flags should have PRIMARY");
5455 torture_assert_int_equal(tctx,
5456 tex2->flags & NETR_TRUST_FLAG_IN_FOREST,
5457 NETR_TRUST_FLAG_IN_FOREST,
5458 "trust_list flags should have IN_FOREST");
5459 torture_assert_int_equal(tctx,
5460 tex2->flags & NETR_TRUST_FLAG_NATIVE,
5461 NETR_TRUST_FLAG_NATIVE,
5462 "trust_list flags should have NATIVE");
5463 torture_assert_int_equal(tctx,
5464 tex2->flags & ~NETR_TRUST_FLAG_TREEROOT,
5465 NETR_TRUST_FLAG_IN_FOREST |
5466 NETR_TRUST_FLAG_PRIMARY |
5467 NETR_TRUST_FLAG_NATIVE,
5468 "trust_list flags IN_FOREST, PRIMARY, NATIVE "
5469 "(TREEROOT optional)");
5470 if (strcmp(odi1->dns_domainname.string, odi1->dns_forestname.string) == 0) {
5471 torture_assert_int_equal(tctx,
5472 tex2->flags & NETR_TRUST_FLAG_TREEROOT,
5473 NETR_TRUST_FLAG_TREEROOT,
5474 "trust_list flags TREEROOT on forest root");
5475 torture_assert_int_equal(tctx,
5476 tex2->parent_index, 0,
5477 "trust_list no parent on foreset root");
5479 torture_assert_int_equal(tctx,
5480 tex2->trust_type, LSA_TRUST_TYPE_UPLEVEL,
5481 "trust_list uplevel");
5482 torture_assert_int_equal(tctx,
5483 tex2->trust_attributes, 0,
5484 "trust_list no attributes");
5486 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
5487 netlogon_creds_client_authenticator(creds, &a);
5489 query.workstation_info->dns_hostname = NULL;
5491 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5492 "LogonGetDomainInfo failed");
5493 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5494 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5496 /* The old DNS hostname should stick */
5497 torture_assert_str_equal(tctx,
5498 info.domain_info->dns_hostname.string,
5500 "'DNS hostname' changed!");
5502 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (extra workstation flags)\n");
5503 netlogon_creds_client_authenticator(creds, &a);
5505 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
5506 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | 0x4;
5508 /* Put the DNS hostname back */
5509 talloc_free(discard_const_p(char, q1.dns_hostname));
5510 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
5511 lpcfg_dnsdomain(tctx->lp_ctx));
5513 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5514 "LogonGetDomainInfo failed");
5515 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5516 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5518 /* Checks "workstation flags" */
5519 torture_assert(tctx,
5520 info.domain_info->workstation_flags
5521 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
5522 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
5523 "Out 'workstation flags' don't match!");
5525 if (!torture_setting_bool(tctx, "dangerous", false)) {
5526 torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 8th call (no workstation info) - enable dangerous tests in order to do so\n");
5528 /* Try a call without the workstation information structure */
5530 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 8th call (no workstation info)\n");
5531 netlogon_creds_client_authenticator(creds, &a);
5533 query.workstation_info = NULL;
5535 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5536 "LogonGetDomainInfo failed");
5537 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5538 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5544 static bool test_GetDomainInfo_async(struct torture_context *tctx,
5545 struct dcerpc_pipe *p1,
5546 struct cli_credentials *machine_credentials)
5549 struct netr_LogonGetDomainInfo r;
5550 struct netr_WorkstationInformation q1;
5551 struct netr_Authenticator a;
5552 #define ASYNC_COUNT 100
5553 struct netlogon_creds_CredentialState *creds;
5554 struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
5555 struct tevent_req *req[ASYNC_COUNT];
5557 union netr_WorkstationInfo query;
5558 union netr_DomainInfo info;
5559 struct dcerpc_pipe *p = NULL;
5561 torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
5563 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
5564 machine_credentials, &creds)) {
5567 if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
5568 DCERPC_SIGN | DCERPC_SEAL, &p)) {
5573 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
5574 r.in.computer_name = TEST_MACHINE_NAME;
5575 r.in.credential = &a;
5577 r.in.return_authenticator = &a;
5578 r.in.query = &query;
5579 r.out.return_authenticator = &a;
5583 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
5584 lpcfg_dnsdomain(tctx->lp_ctx));
5585 q1.sitename = "Default-First-Site-Name";
5586 q1.os_name.string = "UNIX/Linux or similar";
5588 query.workstation_info = &q1;
5590 for (i=0;i<ASYNC_COUNT;i++) {
5591 netlogon_creds_client_authenticator(creds, &a);
5593 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
5594 req[i] = dcerpc_netr_LogonGetDomainInfo_r_send(tctx, tctx->ev, p->binding_handle, &r);
5596 /* even with this flush per request a w2k3 server seems to
5597 clag with multiple outstanding requests. bleergh. */
5598 torture_assert_int_equal(tctx, tevent_loop_once(tctx->ev), 0,
5599 "tevent_loop_once failed");
5602 for (i=0;i<ASYNC_COUNT;i++) {
5603 torture_assert_int_equal(tctx, tevent_req_poll(req[i], tctx->ev), true,
5604 "tevent_req_poll() failed");
5606 status = dcerpc_netr_LogonGetDomainInfo_r_recv(req[i], tctx);
5608 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
5609 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
5611 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred),
5612 "Credential chaining failed at async");
5615 torture_comment(tctx,
5616 "Testing netr_LogonGetDomainInfo - async count %d OK\n", ASYNC_COUNT);
5621 static bool test_ManyGetDCName(struct torture_context *tctx,
5622 struct dcerpc_pipe *p)
5625 struct cli_credentials *anon_creds;
5626 struct dcerpc_binding *binding2;
5627 struct dcerpc_pipe *p2;
5628 struct lsa_ObjectAttribute attr;
5629 struct lsa_QosInfo qos;
5630 struct lsa_OpenPolicy2 o;
5631 struct policy_handle lsa_handle;
5632 struct lsa_DomainList domains;
5634 struct lsa_EnumTrustDom t;
5635 uint32_t resume_handle = 0;
5636 struct netr_GetAnyDCName d;
5637 const char *dcname = NULL;
5638 struct dcerpc_binding_handle *b = p->binding_handle;
5639 struct dcerpc_binding_handle *b2;
5643 if (p->conn->transport.transport != NCACN_NP) {
5644 torture_skip(tctx, "test_ManyGetDCName works only with NCACN_NP");
5647 torture_comment(tctx, "Torturing GetDCName\n");
5649 anon_creds = cli_credentials_init_anon(tctx);
5650 torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed");
5652 binding2 = dcerpc_binding_dup(tctx, p->binding);
5653 /* Swap the binding details from NETLOGON to LSA */
5654 status = dcerpc_epm_map_binding(tctx, binding2, &ndr_table_lsarpc, tctx->ev, tctx->lp_ctx);
5655 dcerpc_binding_set_assoc_group_id(binding2, 0);
5656 torture_assert_ntstatus_ok(tctx, status, "epm map");
5658 status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_lsarpc,
5659 anon_creds, tctx->lp_ctx,
5661 torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
5662 b2 = p2->binding_handle;
5665 qos.impersonation_level = 2;
5666 qos.context_mode = 1;
5667 qos.effective_only = 0;
5670 attr.root_dir = NULL;
5671 attr.object_name = NULL;
5672 attr.attributes = 0;
5673 attr.sec_desc = NULL;
5674 attr.sec_qos = &qos;
5676 o.in.system_name = "\\";
5678 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5679 o.out.handle = &lsa_handle;
5681 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
5682 "OpenPolicy2 failed");
5683 torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
5685 t.in.handle = &lsa_handle;
5686 t.in.resume_handle = &resume_handle;
5687 t.in.max_size = 1000;
5688 t.out.domains = &domains;
5689 t.out.resume_handle = &resume_handle;
5691 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b2, tctx, &t),
5692 "EnumTrustDom failed");
5694 if ((!NT_STATUS_IS_OK(t.out.result) &&
5695 (!NT_STATUS_EQUAL(t.out.result, NT_STATUS_NO_MORE_ENTRIES))))
5696 torture_fail(tctx, "Could not list domains");
5700 d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
5701 dcerpc_server_name(p));
5702 d.out.dcname = &dcname;
5704 for (i=0; i<domains.count * 4; i++) {
5705 struct lsa_DomainInfo *info =
5706 &domains.domains[rand()%domains.count];
5708 d.in.domainname = info->name.string;
5710 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &d);
5711 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
5713 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
5714 dcname ? dcname : "unknown");
5720 static bool test_lsa_over_netlogon(struct torture_context *tctx,
5721 struct dcerpc_pipe *p)
5724 struct cli_credentials *anon_creds;
5725 const struct dcerpc_binding *binding2;
5726 struct dcerpc_pipe *p2;
5727 struct lsa_ObjectAttribute attr;
5728 struct lsa_QosInfo qos;
5729 struct lsa_OpenPolicy2 o;
5730 struct policy_handle lsa_handle;
5732 struct dcerpc_binding_handle *b2;
5735 if (p->conn->transport.transport != NCACN_NP) {
5736 torture_skip(tctx, "test_lsa_over_netlogon works only with NCACN_NP");
5739 torture_comment(tctx, "Testing if we can access the LSA server over\n"
5740 " \\\\pipe\\netlogon rather than \\\\pipe\\lsarpc\n");
5742 anon_creds = cli_credentials_init_anon(tctx);
5743 torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed");
5745 binding2 = p->binding;
5747 status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_lsarpc,
5748 anon_creds, tctx->lp_ctx,
5750 torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
5751 b2 = p2->binding_handle;
5754 qos.impersonation_level = 2;
5755 qos.context_mode = 1;
5756 qos.effective_only = 0;
5759 attr.root_dir = NULL;
5760 attr.object_name = NULL;
5761 attr.attributes = 0;
5762 attr.sec_desc = NULL;
5763 attr.sec_qos = &qos;
5765 o.in.system_name = "\\";
5767 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5768 o.out.handle = &lsa_handle;
5770 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
5771 "OpenPolicy2 failed");
5772 torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
5779 static bool test_SetPassword_with_flags(struct torture_context *tctx,
5780 struct dcerpc_pipe *p,
5781 struct cli_credentials *machine_credentials)
5783 uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
5784 struct netlogon_creds_CredentialState *creds;
5787 if (!test_SetupCredentials2(p, tctx, 0,
5788 machine_credentials,
5789 cli_credentials_get_secure_channel_type(machine_credentials),
5791 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
5794 for (i=0; i < ARRAY_SIZE(flags); i++) {
5795 torture_assert(tctx,
5796 test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
5797 talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
5803 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
5805 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon");
5806 struct torture_rpc_tcase *tcase;
5807 struct torture_test *test;
5809 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
5810 &ndr_table_netlogon, TEST_MACHINE_NAME);
5812 torture_rpc_tcase_add_test_creds(tcase, "SetupCredentialsDowngrade", test_SetupCredentialsDowngrade);
5813 torture_rpc_tcase_add_test(tcase, "lsa_over_netlogon", test_lsa_over_netlogon);
5815 torture_rpc_tcase_add_test_creds(tcase, "GetForestTrustInformation", test_netr_GetForestTrustInformation);
5816 torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo_AES", test_netr_ServerGetTrustInfo_AES);
5817 torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
5818 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
5819 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
5820 torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
5821 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
5822 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
5823 torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
5824 test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
5825 test->dangerous = true;
5826 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
5827 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
5828 torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
5829 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
5830 torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
5831 torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
5832 torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
5833 torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
5834 torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
5835 torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
5836 torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
5837 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
5838 torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
5839 torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
5840 torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
5841 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
5842 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
5843 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
5844 torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuse", test_ServerReqChallengeReuse);
5845 torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal4", test_ServerReqChallengeReuseGlobal4);
5846 torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal3", test_ServerReqChallengeReuseGlobal3);
5847 torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal2", test_ServerReqChallengeReuseGlobal2);
5848 torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal", test_ServerReqChallengeReuseGlobal);
5849 torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeGlobal", test_ServerReqChallengeGlobal);
5850 torture_rpc_tcase_add_test_creds(tcase, "invalidAuthenticate2", test_invalidAuthenticate2);
5851 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
5852 torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
5853 torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
5855 torture_rpc_tcase_add_test(tcase, "Broken RPC binding handle",
5856 test_netr_broken_binding_handle);
5861 struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
5863 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon-s3");
5864 struct torture_rpc_tcase *tcase;
5866 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
5867 &ndr_table_netlogon, TEST_MACHINE_NAME);
5869 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
5870 torture_rpc_tcase_add_test_creds(tcase, "SamLogon_NULL_domain", test_SamLogon_NULL_domain);
5871 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
5872 torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
5873 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
5874 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
5875 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
5880 struct torture_suite *torture_rpc_netlogon_zerologon(TALLOC_CTX *mem_ctx)
5882 struct torture_suite *suite = torture_suite_create(
5884 "netlogon.zerologon");
5885 struct torture_rpc_tcase *tcase;
5887 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(
5890 &ndr_table_netlogon,
5893 torture_rpc_tcase_add_test_creds(
5895 "ServerReqChallenge",
5896 test_ServerReqChallenge);
5897 torture_rpc_tcase_add_test_creds(
5899 "ServerReqChallenge_zero_challenge",
5900 test_ServerReqChallenge_zero_challenge);
5901 torture_rpc_tcase_add_test_creds(
5903 "ServerReqChallenge_5_repeats",
5904 test_ServerReqChallenge_5_repeats);
5905 torture_rpc_tcase_add_test_creds(
5907 "ServerReqChallenge_4_repeats",
5908 test_ServerReqChallenge_4_repeats);
5909 torture_rpc_tcase_add_test_creds(
5911 "test_SetPassword2_encrypted_to_all_zeros",
5912 test_SetPassword2_encrypted_to_all_zeros);
5913 torture_rpc_tcase_add_test_creds(
5915 "test_SetPassword2_password_encrypts_to_zero",
5916 test_SetPassword2_password_encrypts_to_zero);
5917 torture_rpc_tcase_add_test_creds(
5919 "test_SetPassword2_confounder",
5920 test_SetPassword2_confounder);
5921 torture_rpc_tcase_add_test_creds(
5923 "test_SetPassword2_all_zeros",
5924 test_SetPassword2_all_zeros);
5925 torture_rpc_tcase_add_test_creds(
5927 "test_SetPassword2_all_zero_password",
5928 test_SetPassword2_all_zero_password);
5929 torture_rpc_tcase_add_test_creds(
5931 "test_SetPassword2_maximum_length_password",
5932 test_SetPassword2_maximum_length_password);
5937 struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
5939 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon.admin");
5940 struct torture_rpc_tcase *tcase;
5942 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "bdc",
5943 &ndr_table_netlogon, TEST_MACHINE_NAME);
5944 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
5945 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
5946 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
5948 tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "wkst",
5949 &ndr_table_netlogon, TEST_MACHINE_NAME);
5950 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
5951 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
5952 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
5954 tcase = torture_suite_add_rpc_iface_tcase(suite, "admin",
5955 &ndr_table_netlogon);
5956 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
5957 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
5958 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);