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/cmdline.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 samba_cmdline_get_creds());
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 samba_cmdline_get_creds());
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
,
185 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
188 torture_comment(tctx
, "Testing ServerAuthenticate\n");
190 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerAuthenticate_r(b
, tctx
, &a
),
191 "ServerAuthenticate failed");
193 /* This allows the tests to continue against the more fussy windows 2008 */
194 if (NT_STATUS_EQUAL(a
.out
.result
, NT_STATUS_DOWNGRADE_DETECTED
)) {
195 return test_SetupCredentials2(p
, tctx
, NETLOGON_NEG_AUTH2_ADS_FLAGS
| NETLOGON_NEG_SUPPORTS_AES
,
197 cli_credentials_get_secure_channel_type(credentials
),
201 torture_assert_ntstatus_ok(tctx
, a
.out
.result
, "ServerAuthenticate");
203 torture_assert(tctx
, netlogon_creds_client_check(creds
, &credentials3
),
204 "Credential chaining failed");
210 bool test_SetupCredentials2ex(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
211 uint32_t negotiate_flags
,
212 struct cli_credentials
*machine_credentials
,
213 const char *computer_name
,
214 enum netr_SchannelType sec_chan_type
,
215 NTSTATUS expected_result
,
216 struct netlogon_creds_CredentialState
**creds_out
)
218 struct netr_ServerReqChallenge r
;
219 struct netr_ServerAuthenticate2 a
;
220 struct netr_Credential credentials1
, credentials2
, credentials3
;
221 struct netlogon_creds_CredentialState
*creds
;
222 const struct samr_Password
*mach_password
;
223 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
224 const char *account_name
= cli_credentials_get_username(machine_credentials
);
226 mach_password
= cli_credentials_get_nt_hash(machine_credentials
, tctx
);
228 torture_comment(tctx
, "Testing ServerReqChallenge\n");
230 r
.in
.server_name
= NULL
;
231 r
.in
.computer_name
= computer_name
;
232 r
.in
.credentials
= &credentials1
;
233 r
.out
.return_credentials
= &credentials2
;
235 netlogon_creds_random_challenge(&credentials1
);
237 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerReqChallenge_r(b
, tctx
, &r
),
238 "ServerReqChallenge failed");
239 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerReqChallenge failed");
241 a
.in
.server_name
= NULL
;
242 a
.in
.account_name
= account_name
;
243 a
.in
.secure_channel_type
= sec_chan_type
;
244 a
.in
.computer_name
= computer_name
;
245 a
.in
.negotiate_flags
= &negotiate_flags
;
246 a
.out
.negotiate_flags
= &negotiate_flags
;
247 a
.in
.credentials
= &credentials3
;
248 a
.out
.return_credentials
= &credentials3
;
250 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
252 a
.in
.secure_channel_type
,
253 &credentials1
, &credentials2
,
254 mach_password
, &credentials3
,
258 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
260 torture_comment(tctx
, "Testing ServerAuthenticate2\n");
262 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerAuthenticate2_r(b
, tctx
, &a
),
263 "ServerAuthenticate2 failed");
264 torture_assert_ntstatus_equal(tctx
, a
.out
.result
, expected_result
,
265 "ServerAuthenticate2 unexpected");
267 if (NT_STATUS_IS_OK(expected_result
)) {
268 torture_assert(tctx
, netlogon_creds_client_check(creds
, &credentials3
),
269 "Credential chaining failed");
271 torture_assert(tctx
, !netlogon_creds_client_check(creds
, &credentials3
),
272 "Credential chaining passed unexpected");
275 torture_comment(tctx
, "negotiate_flags=0x%08x\n", negotiate_flags
);
281 bool test_SetupCredentials2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
282 uint32_t negotiate_flags
,
283 struct cli_credentials
*machine_credentials
,
284 enum netr_SchannelType sec_chan_type
,
285 struct netlogon_creds_CredentialState
**creds_out
)
287 const char *computer_name
=
288 cli_credentials_get_workstation(machine_credentials
);
290 return test_SetupCredentials2ex(p
, tctx
, negotiate_flags
,
298 bool test_SetupCredentials3(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
299 uint32_t negotiate_flags
,
300 struct cli_credentials
*machine_credentials
,
301 struct netlogon_creds_CredentialState
**creds_out
)
303 struct netr_ServerReqChallenge r
;
304 struct netr_ServerAuthenticate3 a
;
305 struct netr_Credential credentials1
, credentials2
, credentials3
;
306 struct netlogon_creds_CredentialState
*creds
;
307 struct samr_Password mach_password
;
309 const char *machine_name
;
310 const char *plain_pass
;
311 struct dcerpc_binding_handle
*b
= NULL
;
317 b
= p
->binding_handle
;
319 machine_name
= cli_credentials_get_workstation(machine_credentials
);
320 torture_assert(tctx
, machine_name
!= NULL
, "machine_name");
321 plain_pass
= cli_credentials_get_password(machine_credentials
);
322 torture_assert(tctx
, plain_pass
!= NULL
, "plain_pass");
324 torture_comment(tctx
, "Testing ServerReqChallenge\n");
326 r
.in
.server_name
= NULL
;
327 r
.in
.computer_name
= machine_name
;
328 r
.in
.credentials
= &credentials1
;
329 r
.out
.return_credentials
= &credentials2
;
331 netlogon_creds_random_challenge(&credentials1
);
333 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerReqChallenge_r(b
, tctx
, &r
),
334 "ServerReqChallenge failed");
335 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerReqChallenge failed");
337 E_md4hash(plain_pass
, mach_password
.hash
);
339 a
.in
.server_name
= NULL
;
340 a
.in
.account_name
= talloc_asprintf(tctx
, "%s$", machine_name
);
341 a
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
342 a
.in
.computer_name
= machine_name
;
343 a
.in
.negotiate_flags
= &negotiate_flags
;
344 a
.in
.credentials
= &credentials3
;
345 a
.out
.return_credentials
= &credentials3
;
346 a
.out
.negotiate_flags
= &negotiate_flags
;
349 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
351 a
.in
.secure_channel_type
,
352 &credentials1
, &credentials2
,
353 &mach_password
, &credentials3
,
357 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
359 torture_comment(tctx
, "Testing ServerAuthenticate3\n");
361 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerAuthenticate3_r(b
, tctx
, &a
),
362 "ServerAuthenticate3 failed");
363 torture_assert_ntstatus_ok(tctx
, a
.out
.result
, "ServerAuthenticate3 failed");
364 torture_assert(tctx
, netlogon_creds_client_check(creds
, &credentials3
), "Credential chaining failed");
366 torture_comment(tctx
, "negotiate_flags=0x%08x\n", negotiate_flags
);
368 /* Prove that requesting a challenge again won't break it */
369 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerReqChallenge_r(b
, tctx
, &r
),
370 "ServerReqChallenge failed");
371 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerReqChallenge failed");
377 bool test_SetupCredentialsDowngrade(struct torture_context
*tctx
,
378 struct dcerpc_pipe
*p
,
379 struct cli_credentials
*machine_credentials
)
381 struct netr_ServerReqChallenge r
;
382 struct netr_ServerAuthenticate3 a
;
383 struct netr_Credential credentials1
, credentials2
, credentials3
;
384 struct netlogon_creds_CredentialState
*creds
;
385 struct samr_Password mach_password
;
387 const char *machine_name
;
388 const char *plain_pass
;
389 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
390 uint32_t negotiate_flags
= 0;
392 machine_name
= cli_credentials_get_workstation(machine_credentials
);
393 torture_assert(tctx
, machine_name
!= NULL
, "machine_name");
394 plain_pass
= cli_credentials_get_password(machine_credentials
);
395 torture_assert(tctx
, plain_pass
!= NULL
, "plain_pass");
397 torture_comment(tctx
, "Testing ServerReqChallenge\n");
399 r
.in
.server_name
= NULL
;
400 r
.in
.computer_name
= machine_name
;
401 r
.in
.credentials
= &credentials1
;
402 r
.out
.return_credentials
= &credentials2
;
404 netlogon_creds_random_challenge(&credentials1
);
406 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerReqChallenge_r(b
, tctx
, &r
),
407 "ServerReqChallenge failed");
408 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerReqChallenge failed");
410 E_md4hash(plain_pass
, mach_password
.hash
);
412 a
.in
.server_name
= NULL
;
413 a
.in
.account_name
= talloc_asprintf(tctx
, "%s$", machine_name
);
414 a
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
415 a
.in
.computer_name
= machine_name
;
416 a
.in
.negotiate_flags
= &negotiate_flags
;
417 a
.in
.credentials
= &credentials3
;
418 a
.out
.return_credentials
= &credentials3
;
419 a
.out
.negotiate_flags
= &negotiate_flags
;
422 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
424 a
.in
.secure_channel_type
,
425 &credentials1
, &credentials2
,
426 &mach_password
, &credentials3
,
430 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
432 torture_comment(tctx
, "Testing ServerAuthenticate3\n");
434 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerAuthenticate3_r(b
, tctx
, &a
),
435 "ServerAuthenticate3 failed");
436 torture_assert_ntstatus_equal(tctx
, a
.out
.result
, NT_STATUS_DOWNGRADE_DETECTED
, "ServerAuthenticate3 should have failed");
438 negotiate_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
| NETLOGON_NEG_SUPPORTS_AES
;
439 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
441 a
.in
.secure_channel_type
,
442 &credentials1
, &credentials2
,
443 &mach_password
, &credentials3
,
447 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
449 torture_comment(tctx
, "Testing ServerAuthenticate3\n");
451 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerAuthenticate3_r(b
, tctx
, &a
),
452 "ServerAuthenticate3 failed");
453 torture_assert_ntstatus_ok(tctx
, a
.out
.result
, "ServerAuthenticate3 should succeed");
455 torture_assert(tctx
, netlogon_creds_client_check(creds
, &credentials3
), "Credential chaining failed");
457 torture_comment(tctx
, "negotiate_flags=0x%08x\n", negotiate_flags
);
459 /* Prove that requesting a challenge again won't break it */
460 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerReqChallenge_r(b
, tctx
, &r
),
461 "ServerReqChallenge failed");
462 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerReqChallenge failed");
467 bool test_SetupCredentialsPipe(const struct dcerpc_pipe
*p1
,
468 struct torture_context
*tctx
,
469 struct cli_credentials
*machine_credentials
,
470 struct netlogon_creds_CredentialState
*creds
,
471 uint32_t additional_flags
,
472 struct dcerpc_pipe
**_p2
)
475 const struct dcerpc_binding
*b1
=
476 dcerpc_binding_handle_get_binding(p1
->binding_handle
);
477 struct dcerpc_binding
*b2
= NULL
;
478 struct dcerpc_pipe
*p2
= NULL
;
480 b2
= dcerpc_binding_dup(tctx
, b1
);
481 torture_assert(tctx
, b2
!= NULL
, "dcerpc_binding_dup");
482 dcerpc_binding_set_flags(b2
,
483 DCERPC_SCHANNEL
| additional_flags
,
484 DCERPC_AUTH_OPTIONS
);
486 cli_credentials_set_netlogon_creds(machine_credentials
, creds
);
487 status
= dcerpc_pipe_connect_b(tctx
, &p2
, b2
,
490 tctx
->ev
, tctx
->lp_ctx
);
491 cli_credentials_set_netlogon_creds(machine_credentials
, NULL
);
492 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_pipe_connect_b schannel");
498 static bool test_ServerReqChallenge(
499 struct torture_context
*tctx
,
500 struct dcerpc_pipe
*p
,
501 struct cli_credentials
*credentials
)
503 struct netr_ServerReqChallenge r
;
504 struct netr_Credential credentials1
, credentials2
, credentials3
;
505 const char *machine_name
;
506 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
507 struct netr_ServerAuthenticate2 a
;
508 uint32_t in_negotiate_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
| NETLOGON_NEG_SUPPORTS_AES
;
509 uint32_t out_negotiate_flags
= 0;
510 const struct samr_Password
*mach_password
= NULL
;
511 enum netr_SchannelType sec_chan_type
= 0;
512 struct netlogon_creds_CredentialState
*creds
= NULL
;
513 const char *account_name
= NULL
;
515 machine_name
= cli_credentials_get_workstation(credentials
);
516 mach_password
= cli_credentials_get_nt_hash(credentials
, tctx
);
517 account_name
= cli_credentials_get_username(credentials
);
518 sec_chan_type
= cli_credentials_get_secure_channel_type(credentials
);
520 torture_comment(tctx
, "Testing ServerReqChallenge\n");
522 r
.in
.server_name
= NULL
;
523 r
.in
.computer_name
= machine_name
;
524 r
.in
.credentials
= &credentials1
;
525 r
.out
.return_credentials
= &credentials2
;
527 netlogon_creds_random_challenge(&credentials1
);
529 torture_assert_ntstatus_ok(
531 dcerpc_netr_ServerReqChallenge_r(b
, tctx
, &r
),
532 "ServerReqChallenge failed");
533 torture_assert_ntstatus_ok(
536 "ServerReqChallenge failed");
537 a
.in
.server_name
= NULL
;
538 a
.in
.account_name
= account_name
;
539 a
.in
.secure_channel_type
= sec_chan_type
;
540 a
.in
.computer_name
= machine_name
;
541 a
.in
.negotiate_flags
= &in_negotiate_flags
;
542 a
.out
.negotiate_flags
= &out_negotiate_flags
;
543 a
.in
.credentials
= &credentials3
;
544 a
.out
.return_credentials
= &credentials3
;
546 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
548 a
.in
.secure_channel_type
,
549 &credentials1
, &credentials2
,
550 mach_password
, &credentials3
,
554 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
556 torture_comment(tctx
, "Testing ServerAuthenticate2\n");
558 torture_assert_ntstatus_ok(
560 dcerpc_netr_ServerAuthenticate2_r(b
, tctx
, &a
),
561 "ServerAuthenticate2 failed");
562 torture_assert_ntstatus_equal(
566 "ServerAuthenticate2 unexpected");
571 static bool test_ServerReqChallenge_zero_challenge(
572 struct torture_context
*tctx
,
573 struct dcerpc_pipe
*p
,
574 struct cli_credentials
*credentials
)
576 struct netr_ServerReqChallenge r
;
577 struct netr_Credential credentials1
, credentials2
, credentials3
;
578 const char *machine_name
;
579 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
580 struct netr_ServerAuthenticate2 a
;
581 uint32_t in_negotiate_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
| NETLOGON_NEG_SUPPORTS_AES
;
582 uint32_t out_negotiate_flags
= 0;
583 const struct samr_Password
*mach_password
= NULL
;
584 enum netr_SchannelType sec_chan_type
= 0;
585 struct netlogon_creds_CredentialState
*creds
= NULL
;
586 const char *account_name
= NULL
;
588 machine_name
= cli_credentials_get_workstation(credentials
);
589 mach_password
= cli_credentials_get_nt_hash(credentials
, tctx
);
590 account_name
= cli_credentials_get_username(credentials
);
591 sec_chan_type
= cli_credentials_get_secure_channel_type(credentials
);
593 torture_comment(tctx
, "Testing ServerReqChallenge\n");
595 r
.in
.server_name
= NULL
;
596 r
.in
.computer_name
= machine_name
;
597 r
.in
.credentials
= &credentials1
;
598 r
.out
.return_credentials
= &credentials2
;
601 * Set the client challenge to zero, this should fail
602 * CVE-2020-1472(ZeroLogon)
603 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
605 ZERO_STRUCT(credentials1
);
607 torture_assert_ntstatus_ok(
609 dcerpc_netr_ServerReqChallenge_r(b
, tctx
, &r
),
610 "ServerReqChallenge failed");
611 torture_assert_ntstatus_ok(
614 "ServerReqChallenge failed");
615 a
.in
.server_name
= NULL
;
616 a
.in
.account_name
= account_name
;
617 a
.in
.secure_channel_type
= sec_chan_type
;
618 a
.in
.computer_name
= machine_name
;
619 a
.in
.negotiate_flags
= &in_negotiate_flags
;
620 a
.out
.negotiate_flags
= &out_negotiate_flags
;
621 a
.in
.credentials
= &credentials3
;
622 a
.out
.return_credentials
= &credentials3
;
624 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
626 a
.in
.secure_channel_type
,
627 &credentials1
, &credentials2
,
628 mach_password
, &credentials3
,
632 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
634 torture_comment(tctx
, "Testing ServerAuthenticate2\n");
636 torture_assert_ntstatus_ok(
638 dcerpc_netr_ServerAuthenticate2_r(b
, tctx
, &a
),
639 "ServerAuthenticate2 failed");
640 torture_assert_ntstatus_equal(
643 NT_STATUS_ACCESS_DENIED
,
644 "ServerAuthenticate2 unexpected");
649 static bool test_ServerReqChallenge_5_repeats(
650 struct torture_context
*tctx
,
651 struct dcerpc_pipe
*p
,
652 struct cli_credentials
*credentials
)
654 struct netr_ServerReqChallenge r
;
655 struct netr_Credential credentials1
, credentials2
, credentials3
;
656 const char *machine_name
;
657 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
658 struct netr_ServerAuthenticate2 a
;
659 uint32_t in_negotiate_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
| NETLOGON_NEG_SUPPORTS_AES
;
660 uint32_t out_negotiate_flags
= 0;
661 const struct samr_Password
*mach_password
= NULL
;
662 enum netr_SchannelType sec_chan_type
= 0;
663 struct netlogon_creds_CredentialState
*creds
= NULL
;
664 const char *account_name
= NULL
;
666 machine_name
= cli_credentials_get_workstation(credentials
);
667 mach_password
= cli_credentials_get_nt_hash(credentials
, tctx
);
668 account_name
= cli_credentials_get_username(credentials
);
669 sec_chan_type
= cli_credentials_get_secure_channel_type(credentials
);
671 torture_comment(tctx
, "Testing ServerReqChallenge\n");
673 r
.in
.server_name
= NULL
;
674 r
.in
.computer_name
= machine_name
;
675 r
.in
.credentials
= &credentials1
;
676 r
.out
.return_credentials
= &credentials2
;
679 * Set the first 5 bytes of the client challenge to the same value,
680 * this should fail CVE-2020-1472(ZeroLogon)
681 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
683 credentials1
.data
[0] = 'A';
684 credentials1
.data
[1] = 'A';
685 credentials1
.data
[2] = 'A';
686 credentials1
.data
[3] = 'A';
687 credentials1
.data
[4] = 'A';
688 credentials1
.data
[5] = 'B';
689 credentials1
.data
[6] = 'C';
690 credentials1
.data
[7] = 'D';
692 torture_assert_ntstatus_ok(
694 dcerpc_netr_ServerReqChallenge_r(b
, tctx
, &r
),
695 "ServerReqChallenge failed");
696 torture_assert_ntstatus_ok(
699 "ServerReqChallenge failed");
700 a
.in
.server_name
= NULL
;
701 a
.in
.account_name
= account_name
;
702 a
.in
.secure_channel_type
= sec_chan_type
;
703 a
.in
.computer_name
= machine_name
;
704 a
.in
.negotiate_flags
= &in_negotiate_flags
;
705 a
.out
.negotiate_flags
= &out_negotiate_flags
;
706 a
.in
.credentials
= &credentials3
;
707 a
.out
.return_credentials
= &credentials3
;
709 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
711 a
.in
.secure_channel_type
,
712 &credentials1
, &credentials2
,
713 mach_password
, &credentials3
,
717 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
719 torture_comment(tctx
, "Testing ServerAuthenticate2\n");
721 torture_assert_ntstatus_ok(
723 dcerpc_netr_ServerAuthenticate2_r(b
, tctx
, &a
),
724 "ServerAuthenticate2 failed");
725 torture_assert_ntstatus_equal(
728 NT_STATUS_ACCESS_DENIED
,
729 "ServerAuthenticate2 unexpected");
734 static bool test_ServerReqChallenge_4_repeats(
735 struct torture_context
*tctx
,
736 struct dcerpc_pipe
*p
,
737 struct cli_credentials
*credentials
)
739 struct netr_ServerReqChallenge r
;
740 struct netr_Credential credentials1
, credentials2
, credentials3
;
741 const char *machine_name
;
742 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
743 struct netr_ServerAuthenticate2 a
;
744 uint32_t in_negotiate_flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
| NETLOGON_NEG_SUPPORTS_AES
;
745 uint32_t out_negotiate_flags
= 0;
746 const struct samr_Password
*mach_password
= NULL
;
747 enum netr_SchannelType sec_chan_type
= 0;
748 struct netlogon_creds_CredentialState
*creds
= NULL
;
749 const char *account_name
= NULL
;
751 machine_name
= cli_credentials_get_workstation(credentials
);
752 mach_password
= cli_credentials_get_nt_hash(credentials
, tctx
);
753 account_name
= cli_credentials_get_username(credentials
);
754 sec_chan_type
= cli_credentials_get_secure_channel_type(credentials
);
756 torture_comment(tctx
, "Testing ServerReqChallenge\n");
758 r
.in
.server_name
= NULL
;
759 r
.in
.computer_name
= machine_name
;
760 r
.in
.credentials
= &credentials1
;
761 r
.out
.return_credentials
= &credentials2
;
764 * Set the first 4 bytes of the client challenge to the same
765 * value, this should pass as 5 bytes identical are needed to
766 * fail for CVE-2020-1472(ZeroLogon)
768 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
770 credentials1
.data
[0] = 'A';
771 credentials1
.data
[1] = 'A';
772 credentials1
.data
[2] = 'A';
773 credentials1
.data
[3] = 'A';
774 credentials1
.data
[4] = 'B';
775 credentials1
.data
[5] = 'C';
776 credentials1
.data
[6] = 'D';
777 credentials1
.data
[7] = 'E';
779 torture_assert_ntstatus_ok(
781 dcerpc_netr_ServerReqChallenge_r(b
, tctx
, &r
),
782 "ServerReqChallenge failed");
783 torture_assert_ntstatus_ok(
786 "ServerReqChallenge failed");
787 a
.in
.server_name
= NULL
;
788 a
.in
.account_name
= account_name
;
789 a
.in
.secure_channel_type
= sec_chan_type
;
790 a
.in
.computer_name
= machine_name
;
791 a
.in
.negotiate_flags
= &in_negotiate_flags
;
792 a
.out
.negotiate_flags
= &out_negotiate_flags
;
793 a
.in
.credentials
= &credentials3
;
794 a
.out
.return_credentials
= &credentials3
;
796 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
798 a
.in
.secure_channel_type
,
799 &credentials1
, &credentials2
,
800 mach_password
, &credentials3
,
804 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
806 torture_comment(tctx
, "Testing ServerAuthenticate2\n");
808 torture_assert_ntstatus_ok(
810 dcerpc_netr_ServerAuthenticate2_r(b
, tctx
, &a
),
811 "ServerAuthenticate2 failed");
812 torture_assert_ntstatus_equal(
816 "ServerAuthenticate2 unexpected");
822 * Establish a NetLogon session, using a session key that encrypts the
823 * target character to zero
825 static bool test_ServerAuthenticate2_encrypts_to_zero(
826 struct torture_context
*tctx
,
827 struct dcerpc_pipe
*p
,
828 struct cli_credentials
*machine_credentials
,
830 struct netlogon_creds_CredentialState
**creds_out
)
832 const char *computer_name
=
833 cli_credentials_get_workstation(machine_credentials
);
834 struct netr_ServerReqChallenge r
;
835 struct netr_ServerAuthenticate2 a
;
836 struct netr_Credential credentials1
, credentials2
, credentials3
;
837 struct netlogon_creds_CredentialState
*creds
= NULL
;
838 const struct samr_Password
*mach_password
;
839 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
840 const char *account_name
= cli_credentials_get_username(
841 machine_credentials
);
843 NETLOGON_NEG_AUTH2_ADS_FLAGS
|
844 NETLOGON_NEG_SUPPORTS_AES
;
845 enum netr_SchannelType sec_chan_type
=
846 cli_credentials_get_secure_channel_type(machine_credentials
);
848 * Limit the number of attempts to generate a suitable session key.
850 const unsigned MAX_ITER
= 4096;
853 mach_password
= cli_credentials_get_nt_hash(machine_credentials
, tctx
);
855 r
.in
.server_name
= NULL
;
856 r
.in
.computer_name
= computer_name
;
857 r
.in
.credentials
= &credentials1
;
858 r
.out
.return_credentials
= &credentials2
;
860 netlogon_creds_random_challenge(&credentials1
);
861 credentials1
.data
[0] = target
;
863 torture_comment(tctx
, "Generating candidate session keys\n");
868 torture_assert_ntstatus_ok(
870 dcerpc_netr_ServerReqChallenge_r(b
, tctx
, &r
),
871 "ServerReqChallenge failed");
872 torture_assert_ntstatus_ok(
875 "ServerReqChallenge failed");
877 a
.in
.server_name
= NULL
;
878 a
.in
.account_name
= account_name
;
879 a
.in
.secure_channel_type
= sec_chan_type
;
880 a
.in
.computer_name
= computer_name
;
881 a
.in
.negotiate_flags
= &flags
;
882 a
.out
.negotiate_flags
= &flags
;
883 a
.in
.credentials
= &credentials3
;
884 a
.out
.return_credentials
= &credentials3
;
886 creds
= netlogon_creds_client_init(
890 a
.in
.secure_channel_type
,
898 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
899 } while (credentials3
.data
[0] != 0 && i
< MAX_ITER
);
904 "Unable to obtain a suitable session key, "
905 "after [%u] attempts\n",
907 torture_fail(tctx
, "Unable to obtain suitable session key");
910 torture_assert_ntstatus_ok(
912 dcerpc_netr_ServerAuthenticate2_r(b
, tctx
, &a
),
913 "ServerAuthenticate2 failed");
914 torture_assert_ntstatus_equal(
918 "ServerAuthenticate2 unexpected result code");
925 try a change password for our machine account
927 static bool test_SetPassword(struct torture_context
*tctx
,
928 struct dcerpc_pipe
*p
,
929 struct cli_credentials
*machine_credentials
)
931 struct netr_ServerPasswordSet r
;
932 const char *password
;
933 struct netlogon_creds_CredentialState
*creds
;
934 struct netr_Authenticator credential
, return_authenticator
;
935 struct samr_Password new_password
;
936 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
937 enum dcerpc_AuthType auth_type
= DCERPC_AUTH_TYPE_NONE
;
938 enum dcerpc_AuthLevel auth_level
= DCERPC_AUTH_LEVEL_NONE
;
941 if (!test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
)) {
945 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
946 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", TEST_MACHINE_NAME
);
947 r
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
948 r
.in
.computer_name
= TEST_MACHINE_NAME
;
949 r
.in
.credential
= &credential
;
950 r
.in
.new_password
= &new_password
;
951 r
.out
.return_authenticator
= &return_authenticator
;
953 password
= generate_random_password(tctx
, 8, 255);
954 E_md4hash(password
, new_password
.hash
);
956 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
957 status
= netlogon_creds_encrypt_samr_Password(creds
,
961 torture_assert_ntstatus_ok(tctx
, status
, "encrypt_samr_Password");
963 torture_comment(tctx
, "Testing ServerPasswordSet on machine account\n");
964 torture_comment(tctx
, "Changing machine account password to '%s'\n",
967 netlogon_creds_client_authenticator(creds
, &credential
);
969 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerPasswordSet_r(b
, tctx
, &r
),
970 "ServerPasswordSet failed");
971 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerPasswordSet failed");
973 if (!netlogon_creds_client_check(creds
, &r
.out
.return_authenticator
->cred
)) {
974 torture_comment(tctx
, "Credential chaining failed\n");
977 /* by changing the machine password twice we test the
978 credentials chaining fully, and we verify that the server
979 allows the password to be set to the same value twice in a
980 row (match win2k3) */
981 torture_comment(tctx
,
982 "Testing a second ServerPasswordSet on machine account\n");
983 torture_comment(tctx
,
984 "Changing machine account password to '%s' (same as previous run)\n", password
);
986 netlogon_creds_client_authenticator(creds
, &credential
);
988 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerPasswordSet_r(b
, tctx
, &r
),
989 "ServerPasswordSet (2) failed");
990 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerPasswordSet (2) failed");
992 if (!netlogon_creds_client_check(creds
, &r
.out
.return_authenticator
->cred
)) {
993 torture_comment(tctx
, "Credential chaining failed\n");
996 cli_credentials_set_password(machine_credentials
, password
, CRED_SPECIFIED
);
999 test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
),
1000 "ServerPasswordSet failed to actually change the password");
1006 try a change password for our machine account
1008 static bool test_SetPassword_flags(struct torture_context
*tctx
,
1009 struct dcerpc_pipe
*p1
,
1010 struct cli_credentials
*machine_credentials
,
1011 uint32_t negotiate_flags
)
1013 struct netr_ServerPasswordSet r
;
1014 const char *password
;
1015 struct netlogon_creds_CredentialState
*creds
;
1016 struct netr_Authenticator credential
, return_authenticator
;
1017 struct samr_Password new_password
;
1018 struct dcerpc_pipe
*p
= NULL
;
1019 struct dcerpc_binding_handle
*b
= NULL
;
1020 enum dcerpc_AuthType auth_type
;
1021 enum dcerpc_AuthLevel auth_level
;
1024 if (!test_SetupCredentials2(p1
, tctx
, negotiate_flags
,
1025 machine_credentials
,
1026 cli_credentials_get_secure_channel_type(machine_credentials
),
1030 if (!test_SetupCredentialsPipe(p1
, tctx
, machine_credentials
, creds
,
1031 DCERPC_SIGN
| DCERPC_SEAL
, &p
)) {
1034 b
= p
->binding_handle
;
1036 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1037 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", TEST_MACHINE_NAME
);
1038 r
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
1039 r
.in
.computer_name
= TEST_MACHINE_NAME
;
1040 r
.in
.credential
= &credential
;
1041 r
.in
.new_password
= &new_password
;
1042 r
.out
.return_authenticator
= &return_authenticator
;
1044 password
= generate_random_password(tctx
, 8, 255);
1045 E_md4hash(password
, new_password
.hash
);
1047 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1048 status
= netlogon_creds_encrypt_samr_Password(creds
,
1052 torture_assert_ntstatus_ok(tctx
, status
, "encrypt_samr_Password");
1054 torture_comment(tctx
, "Testing ServerPasswordSet on machine account\n");
1055 torture_comment(tctx
, "Changing machine account password to '%s'\n",
1058 netlogon_creds_client_authenticator(creds
, &credential
);
1060 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerPasswordSet_r(b
, tctx
, &r
),
1061 "ServerPasswordSet failed");
1062 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerPasswordSet failed");
1064 if (!netlogon_creds_client_check(creds
, &r
.out
.return_authenticator
->cred
)) {
1065 torture_comment(tctx
, "Credential chaining failed\n");
1068 /* by changing the machine password twice we test the
1069 credentials chaining fully, and we verify that the server
1070 allows the password to be set to the same value twice in a
1071 row (match win2k3) */
1072 torture_comment(tctx
,
1073 "Testing a second ServerPasswordSet on machine account\n");
1074 torture_comment(tctx
,
1075 "Changing machine account password to '%s' (same as previous run)\n", password
);
1077 netlogon_creds_client_authenticator(creds
, &credential
);
1079 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerPasswordSet_r(b
, tctx
, &r
),
1080 "ServerPasswordSet (2) failed");
1081 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerPasswordSet (2) failed");
1083 if (!netlogon_creds_client_check(creds
, &r
.out
.return_authenticator
->cred
)) {
1084 torture_comment(tctx
, "Credential chaining failed\n");
1087 cli_credentials_set_password(machine_credentials
, password
, CRED_SPECIFIED
);
1089 torture_assert(tctx
,
1090 test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
),
1091 "ServerPasswordSet failed to actually change the password");
1098 generate a random password for password change tests
1100 static DATA_BLOB
netlogon_very_rand_pass(TALLOC_CTX
*mem_ctx
, int len
)
1103 DATA_BLOB password
= data_blob_talloc(mem_ctx
, NULL
, len
* 2 /* number of unicode chars */);
1104 generate_random_buffer(password
.data
, password
.length
);
1106 for (i
=0; i
< len
; i
++) {
1107 if (((uint16_t *)password
.data
)[i
] == 0) {
1108 ((uint16_t *)password
.data
)[i
] = 1;
1116 try a change password for our machine account
1118 static bool test_SetPassword2_with_flags(struct torture_context
*tctx
,
1119 struct dcerpc_pipe
*p1
,
1120 struct cli_credentials
*machine_credentials
,
1123 struct netr_ServerPasswordSet2 r
;
1124 const char *password
;
1125 DATA_BLOB new_random_pass
;
1126 struct netlogon_creds_CredentialState
*creds
;
1127 struct samr_CryptPassword password_buf
;
1128 struct samr_Password nt_hash
;
1129 struct netr_Authenticator credential
, return_authenticator
;
1130 struct netr_CryptPassword new_password
;
1131 struct dcerpc_pipe
*p
= NULL
;
1132 struct dcerpc_binding_handle
*b
= NULL
;
1133 enum dcerpc_AuthType auth_type
;
1134 enum dcerpc_AuthLevel auth_level
;
1137 if (!test_SetupCredentials2(p1
, tctx
, flags
, machine_credentials
,
1138 cli_credentials_get_secure_channel_type(machine_credentials
),
1142 if (!test_SetupCredentialsPipe(p1
, tctx
, machine_credentials
, creds
,
1143 DCERPC_SIGN
| DCERPC_SEAL
, &p
)) {
1146 b
= p
->binding_handle
;
1148 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1149 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", TEST_MACHINE_NAME
);
1150 r
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
1151 r
.in
.computer_name
= TEST_MACHINE_NAME
;
1152 r
.in
.credential
= &credential
;
1153 r
.in
.new_password
= &new_password
;
1154 r
.out
.return_authenticator
= &return_authenticator
;
1156 password
= generate_random_password(tctx
, 8, 255);
1157 encode_pw_buffer(password_buf
.data
, password
, STR_UNICODE
);
1158 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1159 status
= netlogon_creds_encrypt_samr_CryptPassword(creds
,
1163 torture_assert_ntstatus_ok(tctx
, status
, "encrypt_samr_CryptPassword");
1165 memcpy(new_password
.data
, password_buf
.data
, 512);
1166 new_password
.length
= IVAL(password_buf
.data
, 512);
1168 torture_comment(tctx
, "Testing ServerPasswordSet2 on machine account\n");
1169 torture_comment(tctx
, "Changing machine account password to '%s'\n", password
);
1171 netlogon_creds_client_authenticator(creds
, &credential
);
1173 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerPasswordSet2_r(b
, tctx
, &r
),
1174 "ServerPasswordSet2 failed");
1175 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerPasswordSet2 failed");
1177 if (!netlogon_creds_client_check(creds
, &r
.out
.return_authenticator
->cred
)) {
1178 torture_comment(tctx
, "Credential chaining failed\n");
1181 cli_credentials_set_password(machine_credentials
, password
, CRED_SPECIFIED
);
1184 * As a consequence of CVE-2020-1472(ZeroLogon)
1185 * Samba explicitly disallows the setting of an empty machine account
1188 * Note that this may fail against Windows, and leave a machine account
1189 * with an empty password.
1192 encode_pw_buffer(password_buf
.data
, password
, STR_UNICODE
);
1193 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1194 status
= netlogon_creds_encrypt_samr_CryptPassword(creds
,
1198 torture_assert_ntstatus_ok(tctx
, status
, "encrypt_samr_CryptPassword");
1199 memcpy(new_password
.data
, password_buf
.data
, 512);
1200 new_password
.length
= IVAL(password_buf
.data
, 512);
1202 torture_comment(tctx
,
1203 "Testing ServerPasswordSet2 on machine account\n");
1204 torture_comment(tctx
,
1205 "Changing machine account password to '%s'\n", password
);
1207 netlogon_creds_client_authenticator(creds
, &credential
);
1209 torture_assert_ntstatus_ok(
1210 tctx
, dcerpc_netr_ServerPasswordSet2_r(b
, tctx
, &r
),
1211 "ServerPasswordSet2 failed");
1212 torture_assert_ntstatus_equal(
1215 NT_STATUS_WRONG_PASSWORD
,
1216 "ServerPasswordSet2 did not return NT_STATUS_WRONG_PASSWORD");
1218 /* now try a random password */
1219 password
= generate_random_password(tctx
, 8, 255);
1220 encode_pw_buffer(password_buf
.data
, password
, STR_UNICODE
);
1221 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1222 status
= netlogon_creds_encrypt_samr_CryptPassword(creds
,
1226 torture_assert_ntstatus_ok(tctx
, status
, "encrypt_samr_CryptPassword");
1227 memcpy(new_password
.data
, password_buf
.data
, 512);
1228 new_password
.length
= IVAL(password_buf
.data
, 512);
1230 torture_comment(tctx
, "Testing second ServerPasswordSet2 on machine account\n");
1231 torture_comment(tctx
, "Changing machine account password to '%s'\n", password
);
1233 netlogon_creds_client_authenticator(creds
, &credential
);
1235 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerPasswordSet2_r(b
, tctx
, &r
),
1236 "ServerPasswordSet2 (2) failed");
1237 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerPasswordSet2 (2) failed");
1239 if (!netlogon_creds_client_check(creds
, &r
.out
.return_authenticator
->cred
)) {
1240 torture_comment(tctx
, "Credential chaining failed\n");
1243 /* by changing the machine password twice we test the
1244 credentials chaining fully, and we verify that the server
1245 allows the password to be set to the same value twice in a
1246 row (match win2k3) */
1247 torture_comment(tctx
,
1248 "Testing a second ServerPasswordSet2 on machine account\n");
1249 torture_comment(tctx
,
1250 "Changing machine account password to '%s' (same as previous run)\n", password
);
1252 netlogon_creds_client_authenticator(creds
, &credential
);
1254 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerPasswordSet2_r(b
, tctx
, &r
),
1255 "ServerPasswordSet (3) failed");
1256 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerPasswordSet (3) failed");
1258 if (!netlogon_creds_client_check(creds
, &r
.out
.return_authenticator
->cred
)) {
1259 torture_comment(tctx
, "Credential chaining failed\n");
1262 cli_credentials_set_password(machine_credentials
, password
, CRED_SPECIFIED
);
1264 torture_assert (tctx
,
1265 test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
),
1266 "ServerPasswordSet failed to actually change the password");
1268 new_random_pass
= netlogon_very_rand_pass(tctx
, 128);
1270 /* now try a random stream of bytes for a password */
1271 set_pw_in_buffer(password_buf
.data
, &new_random_pass
);
1273 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1274 status
= netlogon_creds_encrypt_samr_CryptPassword(creds
,
1278 torture_assert_ntstatus_ok(tctx
, status
, "encrypt_samr_CryptPassword");
1280 memcpy(new_password
.data
, password_buf
.data
, 512);
1281 new_password
.length
= IVAL(password_buf
.data
, 512);
1283 torture_comment(tctx
,
1284 "Testing a third ServerPasswordSet2 on machine account, with a completely random password\n");
1286 netlogon_creds_client_authenticator(creds
, &credential
);
1288 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerPasswordSet2_r(b
, tctx
, &r
),
1289 "ServerPasswordSet (3) failed");
1290 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerPasswordSet (3) failed");
1292 if (!netlogon_creds_client_check(creds
, &r
.out
.return_authenticator
->cred
)) {
1293 torture_comment(tctx
, "Credential chaining failed\n");
1296 mdfour(nt_hash
.hash
, new_random_pass
.data
, new_random_pass
.length
);
1298 cli_credentials_set_password(machine_credentials
, NULL
, CRED_UNINITIALISED
);
1299 cli_credentials_set_nt_hash(machine_credentials
, &nt_hash
, CRED_SPECIFIED
);
1301 torture_assert (tctx
,
1302 test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
),
1303 "ServerPasswordSet failed to actually change the password");
1309 try to change the password of our machine account using a buffer of all zeros,
1310 and a session key that encrypts that to all zeros.
1312 Note: The test does use sign and seal, it's purpose is to exercise
1313 the detection code in dcesrv_netr_ServerPasswordSet2
1315 static bool test_SetPassword2_encrypted_to_all_zeros(
1316 struct torture_context
*tctx
,
1317 struct dcerpc_pipe
*p1
,
1318 struct cli_credentials
*machine_credentials
)
1320 struct netr_ServerPasswordSet2 r
;
1321 struct netlogon_creds_CredentialState
*creds
;
1322 struct samr_CryptPassword password_buf
;
1323 struct netr_Authenticator credential
, return_authenticator
;
1324 struct netr_CryptPassword new_password
;
1325 struct dcerpc_pipe
*p
= NULL
;
1326 struct dcerpc_binding_handle
*b
= NULL
;
1327 enum dcerpc_AuthType auth_type
;
1328 enum dcerpc_AuthLevel auth_level
;
1331 if (!test_ServerAuthenticate2_encrypts_to_zero(
1334 machine_credentials
,
1341 if (!test_SetupCredentialsPipe(
1344 machine_credentials
,
1346 DCERPC_SIGN
| DCERPC_SEAL
,
1351 b
= p
->binding_handle
;
1353 r
.in
.server_name
= talloc_asprintf(
1355 "\\\\%s", dcerpc_server_name(p
));
1356 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", TEST_MACHINE_NAME
);
1357 r
.in
.secure_channel_type
=
1358 cli_credentials_get_secure_channel_type(machine_credentials
);
1359 r
.in
.computer_name
= TEST_MACHINE_NAME
;
1360 r
.in
.credential
= &credential
;
1361 r
.in
.new_password
= &new_password
;
1362 r
.out
.return_authenticator
= &return_authenticator
;
1364 ZERO_STRUCT(password_buf
);
1366 if (!(creds
->negotiate_flags
& NETLOGON_NEG_SUPPORTS_AES
)) {
1367 torture_fail(tctx
, "NETLOGON_NEG_SUPPORTS_AES not set");
1369 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1370 status
= netlogon_creds_encrypt_samr_CryptPassword(creds
,
1374 torture_assert_ntstatus_ok(tctx
, status
, "encrypt_samr_CryptPassword");
1375 if(!all_zero(password_buf
.data
, 516)) {
1376 torture_fail(tctx
, "Password did not encrypt to all zeros\n");
1379 memcpy(new_password
.data
, password_buf
.data
, 512);
1380 new_password
.length
= IVAL(password_buf
.data
, 512);
1381 torture_assert_int_equal(
1383 new_password
.length
,
1385 "Length should have encrypted to 0");
1387 netlogon_creds_client_authenticator(creds
, &credential
);
1389 torture_assert_ntstatus_ok(
1391 dcerpc_netr_ServerPasswordSet2_r(b
, tctx
, &r
),
1392 "ServerPasswordSet2 zero length check failed");
1393 torture_assert_ntstatus_equal(
1394 tctx
, r
.out
.result
, NT_STATUS_WRONG_PASSWORD
, "");
1400 * Choose a session key that encrypts a password of all zeros to all zeros.
1401 * Then try to set the password, using a zeroed buffer, with a non zero
1404 * This exercises the password self encryption check.
1406 * Note: The test does use sign and seal, it's purpose is to exercise
1407 * the detection code in dcesrv_netr_ServerPasswordSet2
1409 static bool test_SetPassword2_password_encrypts_to_zero(
1410 struct torture_context
*tctx
,
1411 struct dcerpc_pipe
*p1
,
1412 struct cli_credentials
*machine_credentials
)
1414 struct netr_ServerPasswordSet2 r
;
1415 struct netlogon_creds_CredentialState
*creds
;
1416 struct samr_CryptPassword password_buf
;
1417 struct netr_Authenticator credential
, return_authenticator
;
1418 struct netr_CryptPassword new_password
;
1419 struct dcerpc_pipe
*p
= NULL
;
1420 struct dcerpc_binding_handle
*b
= NULL
;
1421 enum dcerpc_AuthType auth_type
;
1422 enum dcerpc_AuthLevel auth_level
;
1425 if (!test_ServerAuthenticate2_encrypts_to_zero(
1428 machine_credentials
,
1435 if (!test_SetupCredentialsPipe(
1438 machine_credentials
,
1440 DCERPC_SIGN
| DCERPC_SEAL
,
1445 b
= p
->binding_handle
;
1447 r
.in
.server_name
= talloc_asprintf(
1449 "\\\\%s", dcerpc_server_name(p
));
1450 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", TEST_MACHINE_NAME
);
1451 r
.in
.secure_channel_type
=
1452 cli_credentials_get_secure_channel_type(machine_credentials
);
1453 r
.in
.computer_name
= TEST_MACHINE_NAME
;
1454 r
.in
.credential
= &credential
;
1455 r
.in
.new_password
= &new_password
;
1456 r
.out
.return_authenticator
= &return_authenticator
;
1458 ZERO_STRUCT(password_buf
);
1459 SIVAL(password_buf
.data
, 512, 512);
1461 if (!(creds
->negotiate_flags
& NETLOGON_NEG_SUPPORTS_AES
)) {
1462 torture_fail(tctx
, "NETLOGON_NEG_SUPPORTS_AES not set");
1464 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1465 status
= netlogon_creds_encrypt_samr_CryptPassword(creds
,
1469 torture_assert_ntstatus_ok(tctx
, status
, "encrypt_samr_CryptPassword");
1471 memcpy(new_password
.data
, password_buf
.data
, 512);
1472 new_password
.length
= IVAL(password_buf
.data
, 512);
1474 netlogon_creds_client_authenticator(creds
, &credential
);
1476 torture_assert_ntstatus_ok(
1478 dcerpc_netr_ServerPasswordSet2_r(b
, tctx
, &r
),
1479 "ServerPasswordSet2 password encrypts to zero check failed");
1480 torture_assert_ntstatus_equal(
1481 tctx
, r
.out
.result
, NT_STATUS_WRONG_PASSWORD
, "");
1487 * Check that an all zero confounder, that encrypts to all zeros is
1490 * Note: The test does use sign and seal, it's purpose is to exercise
1491 * the detection code in dcesrv_netr_ServerPasswordSet2
1493 static bool test_SetPassword2_confounder(
1494 struct torture_context
*tctx
,
1495 struct dcerpc_pipe
*p1
,
1496 struct cli_credentials
*machine_credentials
)
1498 struct netr_ServerPasswordSet2 r
;
1499 struct netlogon_creds_CredentialState
*creds
;
1500 struct samr_CryptPassword password_buf
;
1501 struct netr_Authenticator credential
, return_authenticator
;
1502 struct netr_CryptPassword new_password
;
1503 struct dcerpc_pipe
*p
= NULL
;
1504 struct dcerpc_binding_handle
*b
= NULL
;
1505 enum dcerpc_AuthType auth_type
;
1506 enum dcerpc_AuthLevel auth_level
;
1509 if (!test_ServerAuthenticate2_encrypts_to_zero(
1512 machine_credentials
,
1519 if (!test_SetupCredentialsPipe(
1522 machine_credentials
,
1524 DCERPC_SIGN
| DCERPC_SEAL
,
1529 b
= p
->binding_handle
;
1531 r
.in
.server_name
= talloc_asprintf(
1533 "\\\\%s", dcerpc_server_name(p
));
1534 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", TEST_MACHINE_NAME
);
1535 r
.in
.secure_channel_type
=
1536 cli_credentials_get_secure_channel_type(machine_credentials
);
1537 r
.in
.computer_name
= TEST_MACHINE_NAME
;
1538 r
.in
.credential
= &credential
;
1539 r
.in
.new_password
= &new_password
;
1540 r
.out
.return_authenticator
= &return_authenticator
;
1542 ZERO_STRUCT(password_buf
);
1543 password_buf
.data
[511] = 'A';
1544 SIVAL(password_buf
.data
, 512, 2);
1546 if (!(creds
->negotiate_flags
& NETLOGON_NEG_SUPPORTS_AES
)) {
1547 torture_fail(tctx
, "NETLOGON_NEG_SUPPORTS_AES not set");
1549 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1550 status
= netlogon_creds_encrypt_samr_CryptPassword(creds
,
1554 torture_assert_ntstatus_ok(tctx
, status
, "encrypt_samr_CryptPassword");
1556 memcpy(new_password
.data
, password_buf
.data
, 512);
1557 new_password
.length
= IVAL(password_buf
.data
, 512);
1559 netlogon_creds_client_authenticator(creds
, &credential
);
1561 torture_assert_ntstatus_ok(
1563 dcerpc_netr_ServerPasswordSet2_r(b
, tctx
, &r
),
1564 "ServerPasswordSet2 confounder check failed");
1565 torture_assert_ntstatus_equal(
1566 tctx
, r
.out
.result
, NT_STATUS_WRONG_PASSWORD
, "");
1572 * try a change password for our machine account, using an all zero
1573 * request. This should fail on the zero length check.
1575 * Note: This test uses ARC4 encryption to exercise the desired check.
1577 static bool test_SetPassword2_all_zeros(
1578 struct torture_context
*tctx
,
1579 struct dcerpc_pipe
*p1
,
1580 struct cli_credentials
*machine_credentials
)
1582 struct netr_ServerPasswordSet2 r
;
1583 struct netlogon_creds_CredentialState
*creds
;
1584 struct samr_CryptPassword password_buf
;
1585 struct netr_Authenticator credential
, return_authenticator
;
1586 struct netr_CryptPassword new_password
;
1587 struct dcerpc_pipe
*p
= NULL
;
1588 struct dcerpc_binding_handle
*b
= NULL
;
1589 uint32_t flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
; /* no AES desired here */
1590 enum dcerpc_AuthType auth_type
;
1591 enum dcerpc_AuthLevel auth_level
;
1594 if (!test_SetupCredentials2(
1598 machine_credentials
,
1599 cli_credentials_get_secure_channel_type(machine_credentials
),
1604 if (!test_SetupCredentialsPipe(
1607 machine_credentials
,
1609 DCERPC_SIGN
| DCERPC_SEAL
,
1614 b
= p
->binding_handle
;
1616 r
.in
.server_name
= talloc_asprintf(
1618 "\\\\%s", dcerpc_server_name(p
));
1619 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", TEST_MACHINE_NAME
);
1620 r
.in
.secure_channel_type
=
1621 cli_credentials_get_secure_channel_type(machine_credentials
);
1622 r
.in
.computer_name
= TEST_MACHINE_NAME
;
1623 r
.in
.credential
= &credential
;
1624 r
.in
.new_password
= &new_password
;
1625 r
.out
.return_authenticator
= &return_authenticator
;
1627 ZERO_STRUCT(password_buf
.data
);
1628 if (creds
->negotiate_flags
& NETLOGON_NEG_SUPPORTS_AES
) {
1629 torture_fail(tctx
, "NETLOGON_NEG_SUPPORTS_AES enabled\n");
1631 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1632 status
= netlogon_creds_encrypt_samr_CryptPassword(creds
,
1636 torture_assert_ntstatus_ok(tctx
, status
, "encrypt_samr_CryptPassword");
1638 memcpy(new_password
.data
, password_buf
.data
, 512);
1639 new_password
.length
= IVAL(password_buf
.data
, 512);
1643 "Testing ServerPasswordSet2 on machine account\n");
1645 netlogon_creds_client_authenticator(creds
, &credential
);
1647 torture_assert_ntstatus_ok(
1649 dcerpc_netr_ServerPasswordSet2_r(b
, tctx
, &r
),
1650 "ServerPasswordSet2 zero length check failed");
1651 torture_assert_ntstatus_equal(
1652 tctx
, r
.out
.result
, NT_STATUS_WRONG_PASSWORD
, "");
1658 try a change password for our machine account, using a maximum length
1661 static bool test_SetPassword2_maximum_length_password(
1662 struct torture_context
*tctx
,
1663 struct dcerpc_pipe
*p1
,
1664 struct cli_credentials
*machine_credentials
)
1666 struct netr_ServerPasswordSet2 r
;
1667 struct netlogon_creds_CredentialState
*creds
;
1668 struct samr_CryptPassword password_buf
;
1669 struct netr_Authenticator credential
, return_authenticator
;
1670 struct netr_CryptPassword new_password
;
1671 struct dcerpc_pipe
*p
= NULL
;
1672 struct dcerpc_binding_handle
*b
= NULL
;
1673 uint32_t flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
| NETLOGON_NEG_SUPPORTS_AES
;
1674 DATA_BLOB new_random_pass
= data_blob_null
;
1675 enum dcerpc_AuthType auth_type
;
1676 enum dcerpc_AuthLevel auth_level
;
1679 if (!test_SetupCredentials2(
1683 machine_credentials
,
1684 cli_credentials_get_secure_channel_type(machine_credentials
),
1689 if (!test_SetupCredentialsPipe(
1692 machine_credentials
,
1694 DCERPC_SIGN
| DCERPC_SEAL
,
1699 b
= p
->binding_handle
;
1701 r
.in
.server_name
= talloc_asprintf(
1703 "\\\\%s", dcerpc_server_name(p
));
1704 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", TEST_MACHINE_NAME
);
1705 r
.in
.secure_channel_type
=
1706 cli_credentials_get_secure_channel_type(machine_credentials
);
1707 r
.in
.computer_name
= TEST_MACHINE_NAME
;
1708 r
.in
.credential
= &credential
;
1709 r
.in
.new_password
= &new_password
;
1710 r
.out
.return_authenticator
= &return_authenticator
;
1712 new_random_pass
= netlogon_very_rand_pass(tctx
, 256);
1713 set_pw_in_buffer(password_buf
.data
, &new_random_pass
);
1714 SIVAL(password_buf
.data
, 512, 512);
1715 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1716 status
= netlogon_creds_encrypt_samr_CryptPassword(creds
,
1720 torture_assert_ntstatus_ok(tctx
, status
, "encrypt_samr_CryptPassword");
1722 memcpy(new_password
.data
, password_buf
.data
, 512);
1723 new_password
.length
= IVAL(password_buf
.data
, 512);
1727 "Testing ServerPasswordSet2 on machine account\n");
1729 netlogon_creds_client_authenticator(creds
, &credential
);
1731 torture_assert_ntstatus_ok(
1733 dcerpc_netr_ServerPasswordSet2_r(b
, tctx
, &r
),
1734 "ServerPasswordSet2 zero length check failed");
1735 torture_assert_ntstatus_equal(
1736 tctx
, r
.out
.result
, NT_STATUS_OK
, "");
1742 try a change password for our machine account, using a password of
1743 all zeros, and a non zero password length.
1745 This test relies on the buffer being encrypted with ARC4, to
1746 trigger the appropriate check in the rpc server code
1748 static bool test_SetPassword2_all_zero_password(
1749 struct torture_context
*tctx
,
1750 struct dcerpc_pipe
*p1
,
1751 struct cli_credentials
*machine_credentials
)
1753 struct netr_ServerPasswordSet2 r
;
1754 struct netlogon_creds_CredentialState
*creds
;
1755 struct samr_CryptPassword password_buf
;
1756 struct netr_Authenticator credential
, return_authenticator
;
1757 struct netr_CryptPassword new_password
;
1758 struct dcerpc_pipe
*p
= NULL
;
1759 struct dcerpc_binding_handle
*b
= NULL
;
1760 uint32_t flags
= NETLOGON_NEG_AUTH2_ADS_FLAGS
; /* no AES desired here */
1761 enum dcerpc_AuthType auth_type
;
1762 enum dcerpc_AuthLevel auth_level
;
1765 if (!test_SetupCredentials2(
1769 machine_credentials
,
1770 cli_credentials_get_secure_channel_type(machine_credentials
),
1775 if (!test_SetupCredentialsPipe(
1778 machine_credentials
,
1780 DCERPC_SIGN
| DCERPC_SEAL
,
1785 b
= p
->binding_handle
;
1787 r
.in
.server_name
= talloc_asprintf(
1789 "\\\\%s", dcerpc_server_name(p
));
1790 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", TEST_MACHINE_NAME
);
1791 r
.in
.secure_channel_type
=
1792 cli_credentials_get_secure_channel_type(machine_credentials
);
1793 r
.in
.computer_name
= TEST_MACHINE_NAME
;
1794 r
.in
.credential
= &credential
;
1795 r
.in
.new_password
= &new_password
;
1796 r
.out
.return_authenticator
= &return_authenticator
;
1798 ZERO_STRUCT(password_buf
.data
);
1799 SIVAL(password_buf
.data
, 512, 128);
1800 if (creds
->negotiate_flags
& NETLOGON_NEG_SUPPORTS_AES
) {
1801 torture_fail(tctx
, "NETLOGON_NEG_SUPPORTS_AES set");
1803 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1804 status
= netlogon_creds_encrypt_samr_CryptPassword(creds
,
1808 torture_assert_ntstatus_ok(tctx
, status
, "encrypt_samr_CryptPassword");
1810 memcpy(new_password
.data
, password_buf
.data
, 512);
1811 new_password
.length
= IVAL(password_buf
.data
, 512);
1815 "Testing ServerPasswordSet2 on machine account\n");
1817 netlogon_creds_client_authenticator(creds
, &credential
);
1819 torture_assert_ntstatus_ok(
1821 dcerpc_netr_ServerPasswordSet2_r(b
, tctx
, &r
),
1822 "ServerPasswordSet2 all zero password check failed");
1823 torture_assert_ntstatus_equal(
1824 tctx
, r
.out
.result
, NT_STATUS_WRONG_PASSWORD
, "");
1830 static bool test_SetPassword2(struct torture_context
*tctx
,
1831 struct dcerpc_pipe
*p
,
1832 struct cli_credentials
*machine_credentials
)
1834 return test_SetPassword2_with_flags(tctx
, p
, machine_credentials
, NETLOGON_NEG_AUTH2_ADS_FLAGS
);
1837 static bool test_SetPassword2_AES(struct torture_context
*tctx
,
1838 struct dcerpc_pipe
*p
,
1839 struct cli_credentials
*machine_credentials
)
1841 return test_SetPassword2_with_flags(tctx
, p
, machine_credentials
, NETLOGON_NEG_AUTH2_ADS_FLAGS
| NETLOGON_NEG_SUPPORTS_AES
);
1844 static bool test_GetPassword(struct torture_context
*tctx
,
1845 struct dcerpc_pipe
*p
,
1846 struct cli_credentials
*machine_credentials
)
1848 struct netr_ServerPasswordGet r
;
1849 struct netlogon_creds_CredentialState
*creds
;
1850 struct netr_Authenticator credential
;
1852 struct netr_Authenticator return_authenticator
;
1853 struct samr_Password password
;
1854 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1856 if (!test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
)) {
1860 netlogon_creds_client_authenticator(creds
, &credential
);
1862 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1863 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", TEST_MACHINE_NAME
);
1864 r
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
1865 r
.in
.computer_name
= TEST_MACHINE_NAME
;
1866 r
.in
.credential
= &credential
;
1867 r
.out
.return_authenticator
= &return_authenticator
;
1868 r
.out
.password
= &password
;
1870 status
= dcerpc_netr_ServerPasswordGet_r(b
, tctx
, &r
);
1871 torture_assert_ntstatus_ok(tctx
, status
, "ServerPasswordGet");
1872 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerPasswordGet");
1877 static bool test_GetTrustPasswords(struct torture_context
*tctx
,
1878 struct dcerpc_pipe
*p
,
1879 struct cli_credentials
*machine_credentials
)
1881 struct netr_ServerTrustPasswordsGet r
;
1882 struct netlogon_creds_CredentialState
*creds
;
1883 struct netr_Authenticator credential
;
1884 struct netr_Authenticator return_authenticator
;
1885 struct samr_Password password
, password2
;
1886 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1888 if (!test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
)) {
1892 netlogon_creds_client_authenticator(creds
, &credential
);
1894 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1895 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", TEST_MACHINE_NAME
);
1896 r
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
1897 r
.in
.computer_name
= TEST_MACHINE_NAME
;
1898 r
.in
.credential
= &credential
;
1899 r
.out
.return_authenticator
= &return_authenticator
;
1900 r
.out
.new_owf_password
= &password
;
1901 r
.out
.old_owf_password
= &password2
;
1903 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerTrustPasswordsGet_r(b
, tctx
, &r
),
1904 "ServerTrustPasswordsGet failed");
1905 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerTrustPasswordsGet failed");
1911 try a netlogon SamLogon
1913 static bool test_netlogon_ops_args(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1914 struct cli_credentials
*credentials
,
1915 struct netlogon_creds_CredentialState
*creds
,
1919 struct netr_LogonSamLogon r
;
1920 struct netr_Authenticator auth
, auth2
;
1921 union netr_LogonLevel logon
;
1922 union netr_Validation validation
;
1923 uint8_t authoritative
;
1924 struct netr_NetworkInfo ninfo
;
1925 DATA_BLOB names_blob
, chal
, lm_resp
, nt_resp
;
1927 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1928 int flags
= CLI_CRED_NTLM_AUTH
;
1929 if (lpcfg_client_lanman_auth(tctx
->lp_ctx
)) {
1930 flags
|= CLI_CRED_LANMAN_AUTH
;
1933 if (lpcfg_client_ntlmv2_auth(tctx
->lp_ctx
) && !null_domain
) {
1934 flags
|= CLI_CRED_NTLMv2_AUTH
;
1937 cli_credentials_get_ntlm_username_domain(samba_cmdline_get_creds(),
1939 &ninfo
.identity_info
.account_name
.string
,
1940 &ninfo
.identity_info
.domain_name
.string
);
1943 ninfo
.identity_info
.domain_name
.string
= NULL
;
1946 generate_random_buffer(ninfo
.challenge
,
1947 sizeof(ninfo
.challenge
));
1948 chal
= data_blob_const(ninfo
.challenge
,
1949 sizeof(ninfo
.challenge
));
1951 names_blob
= NTLMv2_generate_names_blob(tctx
, cli_credentials_get_workstation(credentials
),
1952 cli_credentials_get_domain(credentials
));
1954 status
= cli_credentials_get_ntlm_response(
1955 samba_cmdline_get_creds(), tctx
,
1958 NULL
, /* server_timestamp */
1962 torture_assert_ntstatus_ok(tctx
, status
, "cli_credentials_get_ntlm_response failed");
1964 ninfo
.lm
.data
= lm_resp
.data
;
1965 ninfo
.lm
.length
= lm_resp
.length
;
1967 ninfo
.nt
.data
= nt_resp
.data
;
1968 ninfo
.nt
.length
= nt_resp
.length
;
1970 ninfo
.identity_info
.parameter_control
= 0;
1971 ninfo
.identity_info
.logon_id
= 0;
1972 ninfo
.identity_info
.workstation
.string
= cli_credentials_get_workstation(credentials
);
1974 logon
.network
= &ninfo
;
1976 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1977 r
.in
.computer_name
= cli_credentials_get_workstation(credentials
);
1978 r
.in
.credential
= &auth
;
1979 r
.in
.return_authenticator
= &auth2
;
1980 r
.in
.logon_level
= NetlogonNetworkInformation
;
1981 r
.in
.logon
= &logon
;
1982 r
.out
.validation
= &validation
;
1983 r
.out
.authoritative
= &authoritative
;
1985 d_printf("Testing LogonSamLogon with name %s\n", ninfo
.identity_info
.account_name
.string
);
1987 for (i
=2;i
<=3;i
++) {
1989 netlogon_creds_client_authenticator(creds
, &auth
);
1991 r
.in
.validation_level
= i
;
1993 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonSamLogon_r(b
, tctx
, &r
),
1994 "LogonSamLogon failed");
1995 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LogonSamLogon failed");
1997 torture_assert(tctx
, netlogon_creds_client_check(creds
,
1998 &r
.out
.return_authenticator
->cred
),
1999 "Credential chaining failed");
2000 torture_assert_int_equal(tctx
, *r
.out
.authoritative
, 1,
2001 "LogonSamLogon invalid *r.out.authoritative");
2004 /* this makes sure we get the unmarshalling right for invalid levels */
2005 for (i
=52;i
<53;i
++) {
2007 /* the authenticator should be ignored by the server */
2008 generate_random_buffer((uint8_t *) &auth
, sizeof(auth
));
2010 r
.in
.validation_level
= i
;
2012 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonSamLogon_r(b
, tctx
, &r
),
2013 "LogonSamLogon failed");
2014 torture_assert_ntstatus_equal(tctx
, r
.out
.result
,
2015 NT_STATUS_INVALID_INFO_CLASS
,
2016 "LogonSamLogon failed");
2018 torture_assert_int_equal(tctx
, *r
.out
.authoritative
, 1,
2019 "LogonSamLogon invalid *r.out.authoritative");
2020 torture_assert(tctx
,
2021 all_zero((uint8_t *)&auth2
, sizeof(auth2
)),
2022 "Return authenticator non zero");
2025 for (i
=2;i
<=3;i
++) {
2027 netlogon_creds_client_authenticator(creds
, &auth
);
2029 r
.in
.validation_level
= i
;
2031 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonSamLogon_r(b
, tctx
, &r
),
2032 "LogonSamLogon failed");
2033 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LogonSamLogon failed");
2035 torture_assert(tctx
, netlogon_creds_client_check(creds
,
2036 &r
.out
.return_authenticator
->cred
),
2037 "Credential chaining failed");
2038 torture_assert_int_equal(tctx
, *r
.out
.authoritative
, 1,
2039 "LogonSamLogon invalid *r.out.authoritative");
2042 r
.in
.logon_level
= 52;
2044 for (i
=2;i
<=3;i
++) {
2046 /* the authenticator should be ignored by the server */
2047 generate_random_buffer((uint8_t *) &auth
, sizeof(auth
));
2049 r
.in
.validation_level
= i
;
2051 torture_comment(tctx
, "Testing SamLogon with validation level %d and a NULL credential\n", i
);
2053 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonSamLogon_r(b
, tctx
, &r
),
2054 "LogonSamLogon failed");
2055 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_INVALID_PARAMETER
,
2056 "LogonSamLogon expected INVALID_PARAMETER");
2058 torture_assert(tctx
,
2059 all_zero((uint8_t *)&auth2
, sizeof(auth2
)),
2060 "Return authenticator non zero");
2061 torture_assert_int_equal(tctx
, *r
.out
.authoritative
, 1,
2062 "LogonSamLogon invalid *r.out.authoritative");
2065 r
.in
.credential
= NULL
;
2067 for (i
=2;i
<=3;i
++) {
2070 r
.in
.validation_level
= i
;
2072 torture_comment(tctx
, "Testing SamLogon with validation level %d and a NULL credential\n", i
);
2074 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonSamLogon_r(b
, tctx
, &r
),
2075 "LogonSamLogon failed");
2076 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_INVALID_PARAMETER
,
2077 "LogonSamLogon expected INVALID_PARAMETER");
2079 torture_assert(tctx
,
2080 all_zero((uint8_t *)&auth2
, sizeof(auth2
)),
2081 "Return authenticator non zero");
2082 torture_assert_int_equal(tctx
, *r
.out
.authoritative
, 1,
2083 "LogonSamLogon invalid *r.out.authoritative");
2086 r
.in
.logon_level
= NetlogonNetworkInformation
;
2087 r
.in
.credential
= &auth
;
2089 for (i
=2;i
<=3;i
++) {
2091 netlogon_creds_client_authenticator(creds
, &auth
);
2093 r
.in
.validation_level
= i
;
2095 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonSamLogon_r(b
, tctx
, &r
),
2096 "LogonSamLogon failed");
2097 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LogonSamLogon failed");
2099 torture_assert(tctx
, netlogon_creds_client_check(creds
,
2100 &r
.out
.return_authenticator
->cred
),
2101 "Credential chaining failed");
2102 torture_assert_int_equal(tctx
, *r
.out
.authoritative
, 1,
2103 "LogonSamLogon invalid *r.out.authoritative");
2109 bool test_netlogon_ops(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2110 struct cli_credentials
*credentials
,
2111 struct netlogon_creds_CredentialState
*creds
)
2113 return test_netlogon_ops_args(p
, tctx
, credentials
, creds
, false);
2117 try a netlogon GetCapabilities
2119 bool test_netlogon_capabilities(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2120 struct cli_credentials
*credentials
,
2121 uint32_t requested_flags
,
2122 struct netlogon_creds_CredentialState
*creds
)
2125 struct netr_LogonGetCapabilities r
;
2126 union netr_Capabilities capabilities
;
2127 struct netr_Authenticator auth
, return_auth
;
2128 struct netlogon_creds_CredentialState tmp_creds
;
2129 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2131 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2132 r
.in
.computer_name
= cli_credentials_get_workstation(credentials
);
2133 r
.in
.credential
= &auth
;
2134 r
.in
.return_authenticator
= &return_auth
;
2135 r
.in
.query_level
= 1;
2136 r
.out
.capabilities
= &capabilities
;
2137 r
.out
.return_authenticator
= &return_auth
;
2139 torture_comment(tctx
, "Testing LogonGetCapabilities with query_level=0\n");
2141 r
.in
.query_level
= 0;
2142 ZERO_STRUCT(return_auth
);
2145 * we need to operate on a temporary copy of creds
2146 * because dcerpc_netr_LogonGetCapabilities with
2147 * an unknown query level returns DCERPC_NCA_S_FAULT_INVALID_TAG
2148 * => NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
2149 * without looking at the authenticator.
2152 netlogon_creds_client_authenticator(&tmp_creds
, &auth
);
2154 status
= dcerpc_netr_LogonGetCapabilities_r(b
, tctx
, &r
);
2155 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
,
2156 "LogonGetCapabilities query_level=0 failed");
2158 torture_comment(tctx
, "Testing LogonGetCapabilities with query_level=3\n");
2160 r
.in
.query_level
= 3;
2161 ZERO_STRUCT(return_auth
);
2164 * we need to operate on a temporary copy of creds
2165 * because dcerpc_netr_LogonGetCapabilities with
2166 * an unknown query level returns DCERPC_NCA_S_FAULT_INVALID_TAG
2167 * => NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
2168 * without looking at the authenticator.
2171 netlogon_creds_client_authenticator(&tmp_creds
, &auth
);
2173 status
= dcerpc_netr_LogonGetCapabilities_r(b
, tctx
, &r
);
2174 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
,
2175 "LogonGetCapabilities query_level=0 failed");
2177 torture_comment(tctx
, "Testing LogonGetCapabilities with query_level=1\n");
2179 r
.in
.query_level
= 1;
2180 ZERO_STRUCT(return_auth
);
2183 * we need to operate on a temporary copy of creds
2184 * because dcerpc_netr_LogonGetCapabilities was
2185 * dcerpc_netr_DummyFunction and returns NT_STATUS_NOT_IMPLEMENTED
2186 * without looking at the authenticator.
2189 netlogon_creds_client_authenticator(&tmp_creds
, &auth
);
2191 status
= dcerpc_netr_LogonGetCapabilities_r(b
, tctx
, &r
);
2192 torture_assert_ntstatus_ok(tctx
, status
,
2193 "LogonGetCapabilities query_level=1 failed");
2194 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
2195 "LogonGetCapabilities query_level=1 failed");
2199 torture_assert(tctx
, netlogon_creds_client_check(creds
,
2200 &r
.out
.return_authenticator
->cred
),
2201 "Credential chaining failed");
2203 torture_assert_int_equal(tctx
, creds
->negotiate_flags
,
2204 capabilities
.server_capabilities
,
2207 torture_comment(tctx
, "Testing LogonGetCapabilities with query_level=2\n");
2209 r
.in
.query_level
= 2;
2210 ZERO_STRUCT(return_auth
);
2213 * we need to operate on a temporary copy of creds
2214 * because dcerpc_netr_LogonGetCapabilities with
2215 * an query level 2 may returns DCERPC_NCA_S_FAULT_INVALID_TAG
2216 * => NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
2217 * without looking at the authenticator.
2220 netlogon_creds_client_authenticator(&tmp_creds
, &auth
);
2222 status
= dcerpc_netr_LogonGetCapabilities_r(b
, tctx
, &r
);
2223 torture_assert_ntstatus_ok(tctx
, status
,
2224 "LogonGetCapabilities query_level=2 failed");
2225 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
2226 "LogonGetCapabilities query_level=2 failed");
2230 torture_assert(tctx
, netlogon_creds_client_check(creds
,
2231 &r
.out
.return_authenticator
->cred
),
2232 "Credential chaining failed");
2234 torture_assert_int_equal(tctx
, requested_flags
,
2235 capabilities
.requested_flags
,
2242 try a netlogon SamLogon
2244 static bool test_SamLogon(struct torture_context
*tctx
,
2245 struct dcerpc_pipe
*p
,
2246 struct cli_credentials
*credentials
)
2248 struct netlogon_creds_CredentialState
*creds
;
2250 if (!test_SetupCredentials(p
, tctx
, credentials
, &creds
)) {
2254 return test_netlogon_ops(p
, tctx
, credentials
, creds
);
2257 static bool test_invalidAuthenticate2(struct torture_context
*tctx
,
2258 struct dcerpc_pipe
*p
,
2259 struct cli_credentials
*credentials
)
2261 struct netlogon_creds_CredentialState
*creds
;
2262 uint32_t flags
= NETLOGON_NEG_AUTH2_FLAGS
| NETLOGON_NEG_SUPPORTS_AES
;
2264 torture_comment(tctx
, "Testing invalidAuthenticate2\n");
2266 if (!test_SetupCredentials2(p
, tctx
, flags
,
2268 cli_credentials_get_secure_channel_type(credentials
),
2273 if (!test_SetupCredentials2ex(p
, tctx
, flags
,
2276 cli_credentials_get_secure_channel_type(credentials
),
2277 STATUS_BUFFER_OVERFLOW
,
2282 if (!test_SetupCredentials2ex(p
, tctx
, flags
,
2285 cli_credentials_get_secure_channel_type(credentials
),
2294 static bool test_ServerReqChallengeGlobal(struct torture_context
*tctx
,
2295 struct dcerpc_pipe
*p1
,
2296 struct cli_credentials
*machine_credentials
)
2298 uint32_t flags
= NETLOGON_NEG_AUTH2_FLAGS
| NETLOGON_NEG_SUPPORTS_AES
;
2299 struct netr_ServerReqChallenge r
;
2300 struct netr_ServerAuthenticate3 a
;
2301 struct netr_Credential credentials1
, credentials2
, credentials3
;
2302 struct netlogon_creds_CredentialState
*creds
;
2303 struct samr_Password mach_password
;
2305 const char *machine_name
;
2306 const char *plain_pass
;
2307 struct dcerpc_binding_handle
*b1
= p1
->binding_handle
;
2308 const struct dcerpc_binding
*bd1
= dcerpc_binding_handle_get_binding(b1
);
2309 struct dcerpc_pipe
*p2
= NULL
;
2310 struct dcerpc_binding_handle
*b2
= NULL
;
2312 machine_name
= cli_credentials_get_workstation(machine_credentials
);
2313 torture_assert(tctx
, machine_name
!= NULL
, "machine_name");
2314 plain_pass
= cli_credentials_get_password(machine_credentials
);
2315 torture_assert(tctx
, plain_pass
!= NULL
, "plain_pass");
2317 torture_comment(tctx
, "Testing ServerReqChallenge on b1\n");
2319 torture_assert_ntstatus_ok(tctx
,
2320 dcerpc_pipe_connect_b(tctx
, &p2
, bd1
,
2321 &ndr_table_netlogon
,
2322 machine_credentials
,
2323 tctx
->ev
, tctx
->lp_ctx
),
2324 "dcerpc_pipe_connect_b failed");
2325 b2
= p2
->binding_handle
;
2327 r
.in
.server_name
= NULL
;
2328 r
.in
.computer_name
= machine_name
;
2329 r
.in
.credentials
= &credentials1
;
2330 r
.out
.return_credentials
= &credentials2
;
2332 netlogon_creds_random_challenge(&credentials1
);
2334 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerReqChallenge_r(b1
, tctx
, &r
),
2335 "ServerReqChallenge failed on b1");
2336 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerReqChallenge failed on b1");
2338 E_md4hash(plain_pass
, mach_password
.hash
);
2340 a
.in
.server_name
= NULL
;
2341 a
.in
.account_name
= talloc_asprintf(tctx
, "%s$", machine_name
);
2342 a
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
2343 a
.in
.computer_name
= machine_name
;
2344 a
.in
.negotiate_flags
= &flags
;
2345 a
.in
.credentials
= &credentials3
;
2346 a
.out
.return_credentials
= &credentials3
;
2347 a
.out
.negotiate_flags
= &flags
;
2350 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
2352 a
.in
.secure_channel_type
,
2353 &credentials1
, &credentials2
,
2354 &mach_password
, &credentials3
,
2358 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
2360 torture_comment(tctx
, "Testing ServerAuthenticate3 on b2\n");
2362 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerAuthenticate3_r(b2
, tctx
, &a
),
2363 "ServerAuthenticate3 failed on b2");
2364 torture_assert_ntstatus_ok(tctx
, a
.out
.result
, "ServerAuthenticate3 failed on b2");
2365 torture_assert(tctx
, netlogon_creds_client_check(creds
, &credentials3
), "Credential chaining failed");
2371 * Test the re-use of the challenge is not possible on a third
2372 * connection, after first using it second one.
2375 static bool test_ServerReqChallengeReuseGlobal(struct torture_context
*tctx
,
2376 struct dcerpc_pipe
*p1
,
2377 struct cli_credentials
*machine_credentials
)
2379 uint32_t flags
= NETLOGON_NEG_AUTH2_FLAGS
| NETLOGON_NEG_SUPPORTS_AES
;
2380 struct netr_ServerReqChallenge r
;
2381 struct netr_ServerAuthenticate3 a
;
2382 struct netr_Credential credentials1
, credentials2
, credentials3
;
2383 struct netlogon_creds_CredentialState
*creds
;
2384 struct samr_Password mach_password
;
2386 const char *machine_name
;
2387 const char *plain_pass
;
2388 struct dcerpc_binding_handle
*b1
= p1
->binding_handle
;
2389 const struct dcerpc_binding
*bd1
= dcerpc_binding_handle_get_binding(b1
);
2390 struct dcerpc_pipe
*p2
= NULL
;
2391 struct dcerpc_binding_handle
*b2
= NULL
;
2392 struct dcerpc_pipe
*p3
= NULL
;
2393 struct dcerpc_binding_handle
*b3
= NULL
;
2395 machine_name
= cli_credentials_get_workstation(machine_credentials
);
2396 torture_assert(tctx
, machine_name
!= NULL
, "machine_name");
2397 plain_pass
= cli_credentials_get_password(machine_credentials
);
2398 torture_assert(tctx
, plain_pass
!= NULL
, "plain_pass");
2400 torture_comment(tctx
, "Testing ServerReqChallenge on b1\n");
2402 torture_assert_ntstatus_ok(tctx
,
2403 dcerpc_pipe_connect_b(tctx
, &p2
, bd1
,
2404 &ndr_table_netlogon
,
2405 machine_credentials
,
2406 tctx
->ev
, tctx
->lp_ctx
),
2407 "dcerpc_pipe_connect_b failed");
2408 b2
= p2
->binding_handle
;
2410 torture_assert_ntstatus_ok(tctx
,
2411 dcerpc_pipe_connect_b(tctx
, &p3
, bd1
,
2412 &ndr_table_netlogon
,
2413 machine_credentials
,
2414 tctx
->ev
, tctx
->lp_ctx
),
2415 "dcerpc_pipe_connect_b failed");
2416 b3
= p3
->binding_handle
;
2418 r
.in
.server_name
= NULL
;
2419 r
.in
.computer_name
= machine_name
;
2420 r
.in
.credentials
= &credentials1
;
2421 r
.out
.return_credentials
= &credentials2
;
2423 netlogon_creds_random_challenge(&credentials1
);
2425 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerReqChallenge_r(b1
, tctx
, &r
),
2426 "ServerReqChallenge failed on b1");
2427 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerReqChallenge failed on b1");
2429 E_md4hash(plain_pass
, mach_password
.hash
);
2431 a
.in
.server_name
= NULL
;
2432 a
.in
.account_name
= talloc_asprintf(tctx
, "%s$", machine_name
);
2433 a
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
2434 a
.in
.computer_name
= machine_name
;
2435 a
.in
.negotiate_flags
= &flags
;
2436 a
.in
.credentials
= &credentials3
;
2437 a
.out
.return_credentials
= &credentials3
;
2438 a
.out
.negotiate_flags
= &flags
;
2441 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
2443 a
.in
.secure_channel_type
,
2444 &credentials1
, &credentials2
,
2445 &mach_password
, &credentials3
,
2449 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
2451 torture_comment(tctx
, "Testing ServerAuthenticate3 on b2\n");
2453 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerAuthenticate3_r(b2
, tctx
, &a
),
2454 "ServerAuthenticate3 failed on b2");
2455 torture_assert_ntstatus_ok(tctx
, a
.out
.result
, "ServerAuthenticate3 failed on b2");
2456 torture_assert(tctx
, netlogon_creds_client_check(creds
, &credentials3
), "Credential chaining failed");
2458 /* We have to re-run this part */
2459 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
2461 a
.in
.secure_channel_type
,
2462 &credentials1
, &credentials2
,
2463 &mach_password
, &credentials3
,
2467 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerAuthenticate3_r(b3
, tctx
, &a
),
2468 "ServerAuthenticate3 failed on b3");
2469 torture_assert_ntstatus_equal(tctx
, a
.out
.result
, NT_STATUS_ACCESS_DENIED
,
2470 "ServerAuthenticate3 should have failed on b3, due to credential reuse");
2475 * Test if use of the per-pipe challenge will wipe out the globally cached challenge
2477 static bool test_ServerReqChallengeReuseGlobal2(struct torture_context
*tctx
,
2478 struct dcerpc_pipe
*p1
,
2479 struct cli_credentials
*machine_credentials
)
2481 uint32_t flags
= NETLOGON_NEG_AUTH2_FLAGS
| NETLOGON_NEG_SUPPORTS_AES
;
2482 struct netr_ServerReqChallenge r
;
2483 struct netr_ServerAuthenticate3 a
;
2484 struct netr_Credential credentials1
, credentials2
, credentials3
;
2485 struct netlogon_creds_CredentialState
*creds
;
2486 struct samr_Password mach_password
;
2488 const char *machine_name
;
2489 const char *plain_pass
;
2490 struct dcerpc_binding_handle
*b1
= p1
->binding_handle
;
2491 const struct dcerpc_binding
*bd1
= dcerpc_binding_handle_get_binding(b1
);
2492 struct dcerpc_pipe
*p2
= NULL
;
2493 struct dcerpc_binding_handle
*b2
= NULL
;
2495 machine_name
= cli_credentials_get_workstation(machine_credentials
);
2496 torture_assert(tctx
, machine_name
!= NULL
, "machine_name");
2497 plain_pass
= cli_credentials_get_password(machine_credentials
);
2498 torture_assert(tctx
, plain_pass
!= NULL
, "plain_pass");
2500 torture_comment(tctx
, "Testing ServerReqChallenge on b1\n");
2502 torture_assert_ntstatus_ok(tctx
,
2503 dcerpc_pipe_connect_b(tctx
, &p2
, bd1
,
2504 &ndr_table_netlogon
,
2505 machine_credentials
,
2506 tctx
->ev
, tctx
->lp_ctx
),
2507 "dcerpc_pipe_connect_b failed");
2508 b2
= p2
->binding_handle
;
2510 r
.in
.server_name
= NULL
;
2511 r
.in
.computer_name
= machine_name
;
2512 r
.in
.credentials
= &credentials1
;
2513 r
.out
.return_credentials
= &credentials2
;
2515 netlogon_creds_random_challenge(&credentials1
);
2517 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerReqChallenge_r(b1
, tctx
, &r
),
2518 "ServerReqChallenge failed on b1");
2519 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerReqChallenge failed on b1");
2521 E_md4hash(plain_pass
, mach_password
.hash
);
2523 a
.in
.server_name
= NULL
;
2524 a
.in
.account_name
= talloc_asprintf(tctx
, "%s$", machine_name
);
2525 a
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
2526 a
.in
.computer_name
= machine_name
;
2527 a
.in
.negotiate_flags
= &flags
;
2528 a
.in
.credentials
= &credentials3
;
2529 a
.out
.return_credentials
= &credentials3
;
2530 a
.out
.negotiate_flags
= &flags
;
2533 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
2535 a
.in
.secure_channel_type
,
2536 &credentials1
, &credentials2
,
2537 &mach_password
, &credentials3
,
2541 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
2543 torture_comment(tctx
, "Testing ServerAuthenticate3 on b2\n");
2545 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerAuthenticate3_r(b1
, tctx
, &a
),
2546 "ServerAuthenticate3 failed on b");
2547 torture_assert_ntstatus_ok(tctx
, a
.out
.result
, "ServerAuthenticate3 failed on b");
2548 torture_assert(tctx
, netlogon_creds_client_check(creds
, &credentials3
), "Credential chaining failed");
2550 /* We have to re-run this part */
2551 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
2553 a
.in
.secure_channel_type
,
2554 &credentials1
, &credentials2
,
2555 &mach_password
, &credentials3
,
2559 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerAuthenticate3_r(b2
, tctx
, &a
),
2560 "ServerAuthenticate3 failed on b2");
2561 torture_assert_ntstatus_equal(tctx
, a
.out
.result
, NT_STATUS_ACCESS_DENIED
,
2562 "ServerAuthenticate3 should have failed on b2, due to credential reuse");
2567 * Test if use of the globally cached challenge will wipe out the
2568 * per-pipe challenge
2570 static bool test_ServerReqChallengeReuseGlobal3(struct torture_context
*tctx
,
2571 struct dcerpc_pipe
*p1
,
2572 struct cli_credentials
*machine_credentials
)
2574 uint32_t flags
= NETLOGON_NEG_AUTH2_FLAGS
| NETLOGON_NEG_SUPPORTS_AES
;
2575 struct netr_ServerReqChallenge r
;
2576 struct netr_ServerAuthenticate3 a
;
2577 struct netr_Credential credentials1
, credentials2
, credentials3
;
2578 struct netlogon_creds_CredentialState
*creds
;
2579 struct samr_Password mach_password
;
2581 const char *machine_name
;
2582 const char *plain_pass
;
2583 struct dcerpc_binding_handle
*b1
= p1
->binding_handle
;
2584 const struct dcerpc_binding
*bd1
= dcerpc_binding_handle_get_binding(b1
);
2585 struct dcerpc_pipe
*p2
= NULL
;
2586 struct dcerpc_binding_handle
*b2
= NULL
;
2588 machine_name
= cli_credentials_get_workstation(machine_credentials
);
2589 torture_assert(tctx
, machine_name
!= NULL
, "machine_name");
2590 plain_pass
= cli_credentials_get_password(machine_credentials
);
2591 torture_assert(tctx
, plain_pass
!= NULL
, "plain_pass");
2593 torture_comment(tctx
, "Testing ServerReqChallenge on b1\n");
2595 torture_assert_ntstatus_ok(tctx
,
2596 dcerpc_pipe_connect_b(tctx
, &p2
, bd1
,
2597 &ndr_table_netlogon
,
2598 machine_credentials
,
2599 tctx
->ev
, tctx
->lp_ctx
),
2600 "dcerpc_pipe_connect_b failed");
2601 b2
= p2
->binding_handle
;
2603 r
.in
.server_name
= NULL
;
2604 r
.in
.computer_name
= machine_name
;
2605 r
.in
.credentials
= &credentials1
;
2606 r
.out
.return_credentials
= &credentials2
;
2608 netlogon_creds_random_challenge(&credentials1
);
2610 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerReqChallenge_r(b1
, tctx
, &r
),
2611 "ServerReqChallenge failed on b1");
2612 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerReqChallenge failed on b1");
2614 E_md4hash(plain_pass
, mach_password
.hash
);
2616 a
.in
.server_name
= NULL
;
2617 a
.in
.account_name
= talloc_asprintf(tctx
, "%s$", machine_name
);
2618 a
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
2619 a
.in
.computer_name
= machine_name
;
2620 a
.in
.negotiate_flags
= &flags
;
2621 a
.in
.credentials
= &credentials3
;
2622 a
.out
.return_credentials
= &credentials3
;
2623 a
.out
.negotiate_flags
= &flags
;
2626 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
2628 a
.in
.secure_channel_type
,
2629 &credentials1
, &credentials2
,
2630 &mach_password
, &credentials3
,
2634 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
2636 torture_comment(tctx
, "Testing ServerAuthenticate3 on b2\n");
2638 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerAuthenticate3_r(b2
, tctx
, &a
),
2639 "ServerAuthenticate3 failed on b2");
2640 torture_assert_ntstatus_ok(tctx
, a
.out
.result
, "ServerAuthenticate3 failed on b");
2641 torture_assert(tctx
, netlogon_creds_client_check(creds
, &credentials3
), "Credential chaining failed");
2643 /* We have to re-run this part */
2644 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
2646 a
.in
.secure_channel_type
,
2647 &credentials1
, &credentials2
,
2648 &mach_password
, &credentials3
,
2652 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
2654 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerAuthenticate3_r(b1
, tctx
, &a
),
2655 "ServerAuthenticate3 failed on b1");
2656 torture_assert_ntstatus_equal(tctx
, a
.out
.result
, NT_STATUS_ACCESS_DENIED
,
2657 "ServerAuthenticate3 should have failed on b1, due to credential reuse");
2662 * Test if more than one globally cached challenge works
2664 static bool test_ServerReqChallengeReuseGlobal4(struct torture_context
*tctx
,
2665 struct dcerpc_pipe
*p1
,
2666 struct cli_credentials
*machine_credentials
)
2668 uint32_t flags
= NETLOGON_NEG_AUTH2_FLAGS
| NETLOGON_NEG_SUPPORTS_AES
;
2669 struct netr_ServerReqChallenge r
;
2670 struct netr_ServerAuthenticate3 a
;
2671 struct netr_Credential credentials1
, credentials1_random
,
2672 credentials2
, credentials3
, credentials_discard
;
2673 struct netlogon_creds_CredentialState
*creds
;
2674 struct samr_Password mach_password
;
2676 const char *machine_name
;
2677 const char *plain_pass
;
2678 struct dcerpc_binding_handle
*b1
= p1
->binding_handle
;
2679 const struct dcerpc_binding
*bd1
= dcerpc_binding_handle_get_binding(b1
);
2680 struct dcerpc_pipe
*p2
= NULL
;
2681 struct dcerpc_binding_handle
*b2
= NULL
;
2683 machine_name
= cli_credentials_get_workstation(machine_credentials
);
2684 torture_assert(tctx
, machine_name
!= NULL
, "machine_name");
2685 plain_pass
= cli_credentials_get_password(machine_credentials
);
2686 torture_assert(tctx
, plain_pass
!= NULL
, "plain_pass");
2688 torture_comment(tctx
, "Testing ServerReqChallenge on b1\n");
2690 torture_assert_ntstatus_ok(tctx
,
2691 dcerpc_pipe_connect_b(tctx
, &p2
, bd1
,
2692 &ndr_table_netlogon
,
2693 machine_credentials
,
2694 tctx
->ev
, tctx
->lp_ctx
),
2695 "dcerpc_pipe_connect_b failed");
2696 b2
= p2
->binding_handle
;
2698 r
.in
.server_name
= NULL
;
2699 r
.in
.computer_name
= "CHALTEST1";
2700 r
.in
.credentials
= &credentials1_random
;
2701 r
.out
.return_credentials
= &credentials_discard
;
2703 netlogon_creds_random_challenge(&credentials1_random
);
2705 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerReqChallenge_r(b1
, tctx
, &r
),
2706 "ServerReqChallenge failed on b1");
2707 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerReqChallenge failed on b1");
2709 /* Now ask for the actual client name */
2710 r
.in
.server_name
= NULL
;
2711 r
.in
.computer_name
= machine_name
;
2712 r
.in
.credentials
= &credentials1
;
2713 r
.out
.return_credentials
= &credentials2
;
2715 netlogon_creds_random_challenge(&credentials1
);
2717 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerReqChallenge_r(b1
, tctx
, &r
),
2718 "ServerReqChallenge failed on b1");
2719 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerReqChallenge failed on b1");
2721 r
.in
.server_name
= NULL
;
2722 r
.in
.computer_name
= "CHALTEST2";
2723 r
.in
.credentials
= &credentials1_random
;
2724 r
.out
.return_credentials
= &credentials_discard
;
2726 netlogon_creds_random_challenge(&credentials1_random
);
2728 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerReqChallenge_r(b1
, tctx
, &r
),
2729 "ServerReqChallenge failed on b1");
2730 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerReqChallenge failed on b1");
2732 E_md4hash(plain_pass
, mach_password
.hash
);
2734 a
.in
.server_name
= NULL
;
2735 a
.in
.account_name
= talloc_asprintf(tctx
, "%s$", machine_name
);
2736 a
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
2737 a
.in
.computer_name
= machine_name
;
2738 a
.in
.negotiate_flags
= &flags
;
2739 a
.in
.credentials
= &credentials3
;
2740 a
.out
.return_credentials
= &credentials3
;
2741 a
.out
.negotiate_flags
= &flags
;
2744 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
2746 a
.in
.secure_channel_type
,
2747 &credentials1
, &credentials2
,
2748 &mach_password
, &credentials3
,
2752 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
2754 torture_comment(tctx
, "Testing ServerAuthenticate3 on b2 (must use global credentials)\n");
2756 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerAuthenticate3_r(b2
, tctx
, &a
),
2757 "ServerAuthenticate3 failed on b2");
2758 torture_assert_ntstatus_ok(tctx
, a
.out
.result
, "ServerAuthenticate3 failed on b2");
2759 torture_assert(tctx
, netlogon_creds_client_check(creds
, &credentials3
), "Credential chaining failed");
2761 /* We have to re-run this part */
2762 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
2764 a
.in
.secure_channel_type
,
2765 &credentials1
, &credentials2
,
2766 &mach_password
, &credentials3
,
2770 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerAuthenticate3_r(b1
, tctx
, &a
),
2771 "ServerAuthenticate3 failed on b1");
2772 torture_assert_ntstatus_equal(tctx
, a
.out
.result
, NT_STATUS_ACCESS_DENIED
,
2773 "ServerAuthenticate3 should have failed on b1, due to credential reuse");
2777 static bool test_ServerReqChallengeReuse(struct torture_context
*tctx
,
2778 struct dcerpc_pipe
*p
,
2779 struct cli_credentials
*machine_credentials
)
2781 uint32_t flags
= NETLOGON_NEG_AUTH2_FLAGS
| NETLOGON_NEG_SUPPORTS_AES
;
2782 struct netr_ServerReqChallenge r
;
2783 struct netr_ServerAuthenticate3 a
;
2784 struct netr_Credential credentials1
, credentials2
, credentials3
;
2785 struct netlogon_creds_CredentialState
*creds
;
2786 struct samr_Password mach_password
;
2788 const char *machine_name
;
2789 const char *plain_pass
;
2790 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2792 machine_name
= cli_credentials_get_workstation(machine_credentials
);
2793 torture_assert(tctx
, machine_name
!= NULL
, "machine_name");
2794 plain_pass
= cli_credentials_get_password(machine_credentials
);
2795 torture_assert(tctx
, plain_pass
!= NULL
, "plain_pass");
2797 torture_comment(tctx
, "Testing ServerReqChallenge on b1\n");
2799 r
.in
.server_name
= NULL
;
2800 r
.in
.computer_name
= machine_name
;
2801 r
.in
.credentials
= &credentials1
;
2802 r
.out
.return_credentials
= &credentials2
;
2804 netlogon_creds_random_challenge(&credentials1
);
2806 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerReqChallenge_r(b
, tctx
, &r
),
2807 "ServerReqChallenge");
2808 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerReqChallenge failed on b1");
2810 E_md4hash(plain_pass
, mach_password
.hash
);
2812 a
.in
.server_name
= NULL
;
2813 a
.in
.account_name
= talloc_asprintf(tctx
, "%s$", machine_name
);
2814 a
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
2815 a
.in
.computer_name
= machine_name
;
2816 a
.in
.negotiate_flags
= &flags
;
2817 a
.in
.credentials
= &credentials3
;
2818 a
.out
.return_credentials
= &credentials3
;
2819 a
.out
.negotiate_flags
= &flags
;
2822 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
2824 a
.in
.secure_channel_type
,
2825 &credentials1
, &credentials2
,
2826 &mach_password
, &credentials3
,
2830 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
2832 torture_comment(tctx
, "Testing ServerAuthenticate3\n");
2834 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerAuthenticate3_r(b
, tctx
, &a
),
2835 "ServerAuthenticate3 failed");
2836 torture_assert_ntstatus_ok(tctx
, a
.out
.result
, "ServerAuthenticate3 failed");
2837 torture_assert(tctx
, netlogon_creds_client_check(creds
, &credentials3
), "Credential chaining failed");
2839 /* We have to re-run this part */
2840 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
2842 a
.in
.secure_channel_type
,
2843 &credentials1
, &credentials2
,
2844 &mach_password
, &credentials3
,
2848 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerAuthenticate3_r(b
, tctx
, &a
),
2849 "ServerAuthenticate3 failed");
2850 torture_assert_ntstatus_equal(tctx
, a
.out
.result
, NT_STATUS_ACCESS_DENIED
,
2851 "ServerAuthenticate3 should have failed on b3, due to credential reuse");
2853 ZERO_STRUCT(credentials1
.data
);
2854 ZERO_STRUCT(credentials2
.data
);
2855 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
2857 a
.in
.secure_channel_type
,
2858 &credentials1
, &credentials2
,
2859 &mach_password
, &credentials3
,
2863 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
2865 torture_comment(tctx
, "Testing ServerAuthenticate3 with zero'ed challenge\n");
2867 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerAuthenticate3_r(b
, tctx
, &a
),
2868 "ServerAuthenticate3 failed");
2869 torture_assert_ntstatus_equal(tctx
, a
.out
.result
, NT_STATUS_ACCESS_DENIED
,
2870 "ServerAuthenticate3 should have failed on b3, due to credential reuse");
2874 static bool test_SamLogon_NULL_domain(struct torture_context
*tctx
,
2875 struct dcerpc_pipe
*p
,
2876 struct cli_credentials
*credentials
)
2878 struct netlogon_creds_CredentialState
*creds
;
2880 if (!test_SetupCredentials(p
, tctx
, credentials
, &creds
)) {
2884 return test_netlogon_ops_args(p
, tctx
, credentials
, creds
, true);
2887 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
2888 static uint64_t sequence_nums
[3];
2891 try a netlogon DatabaseSync
2893 static bool test_DatabaseSync(struct torture_context
*tctx
,
2894 struct dcerpc_pipe
*p
,
2895 struct cli_credentials
*machine_credentials
)
2897 struct netr_DatabaseSync r
;
2898 struct netlogon_creds_CredentialState
*creds
;
2899 const uint32_t database_ids
[] = {SAM_DATABASE_DOMAIN
, SAM_DATABASE_BUILTIN
, SAM_DATABASE_PRIVS
};
2901 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
2902 struct netr_Authenticator credential
, return_authenticator
;
2903 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2905 if (!test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
)) {
2909 ZERO_STRUCT(return_authenticator
);
2911 r
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2912 r
.in
.computername
= TEST_MACHINE_NAME
;
2913 r
.in
.preferredmaximumlength
= (uint32_t)-1;
2914 r
.in
.return_authenticator
= &return_authenticator
;
2915 r
.out
.delta_enum_array
= &delta_enum_array
;
2916 r
.out
.return_authenticator
= &return_authenticator
;
2918 for (i
=0;i
<ARRAY_SIZE(database_ids
);i
++) {
2920 uint32_t sync_context
= 0;
2922 r
.in
.database_id
= database_ids
[i
];
2923 r
.in
.sync_context
= &sync_context
;
2924 r
.out
.sync_context
= &sync_context
;
2926 torture_comment(tctx
, "Testing DatabaseSync of id %d\n", r
.in
.database_id
);
2929 netlogon_creds_client_authenticator(creds
, &credential
);
2931 r
.in
.credential
= &credential
;
2933 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_DatabaseSync_r(b
, tctx
, &r
),
2934 "DatabaseSync failed");
2935 if (NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
))
2938 /* Native mode servers don't do this */
2939 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_NOT_SUPPORTED
)) {
2942 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "DatabaseSync");
2944 if (!netlogon_creds_client_check(creds
, &r
.out
.return_authenticator
->cred
)) {
2945 torture_comment(tctx
, "Credential chaining failed\n");
2948 if (delta_enum_array
&&
2949 delta_enum_array
->num_deltas
> 0 &&
2950 delta_enum_array
->delta_enum
[0].delta_type
== NETR_DELTA_DOMAIN
&&
2951 delta_enum_array
->delta_enum
[0].delta_union
.domain
) {
2952 sequence_nums
[r
.in
.database_id
] =
2953 delta_enum_array
->delta_enum
[0].delta_union
.domain
->sequence_num
;
2954 torture_comment(tctx
, "\tsequence_nums[%d]=%llu\n",
2956 (unsigned long long)sequence_nums
[r
.in
.database_id
]);
2958 } while (NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
));
2966 try a netlogon DatabaseDeltas
2968 static bool test_DatabaseDeltas(struct torture_context
*tctx
,
2969 struct dcerpc_pipe
*p
,
2970 struct cli_credentials
*machine_credentials
)
2972 struct netr_DatabaseDeltas r
;
2973 struct netlogon_creds_CredentialState
*creds
;
2974 struct netr_Authenticator credential
;
2975 struct netr_Authenticator return_authenticator
;
2976 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
2977 const uint32_t database_ids
[] = {0, 1, 2};
2979 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2981 if (!test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
)) {
2985 r
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2986 r
.in
.computername
= TEST_MACHINE_NAME
;
2987 r
.in
.preferredmaximumlength
= (uint32_t)-1;
2988 ZERO_STRUCT(r
.in
.return_authenticator
);
2989 r
.out
.return_authenticator
= &return_authenticator
;
2990 r
.out
.delta_enum_array
= &delta_enum_array
;
2992 for (i
=0;i
<ARRAY_SIZE(database_ids
);i
++) {
2993 r
.in
.database_id
= database_ids
[i
];
2994 r
.in
.sequence_num
= &sequence_nums
[r
.in
.database_id
];
2996 if (*r
.in
.sequence_num
== 0) continue;
2998 *r
.in
.sequence_num
-= 1;
3000 torture_comment(tctx
, "Testing DatabaseDeltas of id %d at %llu\n",
3001 r
.in
.database_id
, (unsigned long long)*r
.in
.sequence_num
);
3004 netlogon_creds_client_authenticator(creds
, &credential
);
3006 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_DatabaseDeltas_r(b
, tctx
, &r
),
3007 "DatabaseDeltas failed");
3008 if (NT_STATUS_EQUAL(r
.out
.result
,
3009 NT_STATUS_SYNCHRONIZATION_REQUIRED
)) {
3010 torture_comment(tctx
, "not considering %s to be an error\n",
3011 nt_errstr(r
.out
.result
));
3014 if (NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
))
3017 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "DatabaseDeltas");
3019 if (!netlogon_creds_client_check(creds
, &return_authenticator
.cred
)) {
3020 torture_comment(tctx
, "Credential chaining failed\n");
3023 (*r
.in
.sequence_num
)++;
3024 } while (NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
));
3030 static bool test_DatabaseRedo(struct torture_context
*tctx
,
3031 struct dcerpc_pipe
*p
,
3032 struct cli_credentials
*machine_credentials
)
3034 struct netr_DatabaseRedo r
;
3035 struct netlogon_creds_CredentialState
*creds
;
3036 struct netr_Authenticator credential
;
3037 struct netr_Authenticator return_authenticator
;
3038 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
3039 struct netr_ChangeLogEntry e
;
3040 struct dom_sid null_sid
, *sid
;
3042 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3044 ZERO_STRUCT(null_sid
);
3046 sid
= dom_sid_parse_talloc(tctx
, "S-1-5-21-1111111111-2222222222-333333333-500");
3057 NTSTATUS expected_error
;
3058 uint32_t expected_num_results
;
3059 uint8_t expected_delta_type_1
;
3060 uint8_t expected_delta_type_2
;
3061 const char *comment
;
3064 /* SAM_DATABASE_DOMAIN */
3069 .db_index
= SAM_DATABASE_DOMAIN
,
3070 .delta_type
= NETR_DELTA_MODIFY_COUNT
,
3073 .expected_error
= NT_STATUS_SYNCHRONIZATION_REQUIRED
,
3074 .expected_num_results
= 0,
3075 .comment
= "NETR_DELTA_MODIFY_COUNT"
3080 .db_index
= SAM_DATABASE_DOMAIN
,
3084 .expected_error
= NT_STATUS_OK
,
3085 .expected_num_results
= 1,
3086 .expected_delta_type_1
= NETR_DELTA_DOMAIN
,
3087 .comment
= "NULL DELTA"
3092 .db_index
= SAM_DATABASE_DOMAIN
,
3093 .delta_type
= NETR_DELTA_DOMAIN
,
3096 .expected_error
= NT_STATUS_OK
,
3097 .expected_num_results
= 1,
3098 .expected_delta_type_1
= NETR_DELTA_DOMAIN
,
3099 .comment
= "NETR_DELTA_DOMAIN"
3102 .rid
= DOMAIN_RID_ADMINISTRATOR
,
3104 .db_index
= SAM_DATABASE_DOMAIN
,
3105 .delta_type
= NETR_DELTA_USER
,
3108 .expected_error
= NT_STATUS_OK
,
3109 .expected_num_results
= 1,
3110 .expected_delta_type_1
= NETR_DELTA_USER
,
3111 .comment
= "NETR_DELTA_USER by rid 500"
3114 .rid
= DOMAIN_RID_GUEST
,
3116 .db_index
= SAM_DATABASE_DOMAIN
,
3117 .delta_type
= NETR_DELTA_USER
,
3120 .expected_error
= NT_STATUS_OK
,
3121 .expected_num_results
= 1,
3122 .expected_delta_type_1
= NETR_DELTA_USER
,
3123 .comment
= "NETR_DELTA_USER by rid 501"
3127 .flags
= NETR_CHANGELOG_SID_INCLUDED
,
3128 .db_index
= SAM_DATABASE_DOMAIN
,
3129 .delta_type
= NETR_DELTA_USER
,
3132 .expected_error
= NT_STATUS_OK
,
3133 .expected_num_results
= 1,
3134 .expected_delta_type_1
= NETR_DELTA_DELETE_USER
,
3135 .comment
= "NETR_DELTA_USER by sid and flags"
3139 .flags
= NETR_CHANGELOG_SID_INCLUDED
,
3140 .db_index
= SAM_DATABASE_DOMAIN
,
3141 .delta_type
= NETR_DELTA_USER
,
3144 .expected_error
= NT_STATUS_OK
,
3145 .expected_num_results
= 1,
3146 .expected_delta_type_1
= NETR_DELTA_DELETE_USER
,
3147 .comment
= "NETR_DELTA_USER by null_sid and flags"
3151 .flags
= NETR_CHANGELOG_NAME_INCLUDED
,
3152 .db_index
= SAM_DATABASE_DOMAIN
,
3153 .delta_type
= NETR_DELTA_USER
,
3155 .name
= "administrator",
3156 .expected_error
= NT_STATUS_OK
,
3157 .expected_num_results
= 1,
3158 .expected_delta_type_1
= NETR_DELTA_DELETE_USER
,
3159 .comment
= "NETR_DELTA_USER by name 'administrator'"
3162 .rid
= DOMAIN_RID_ADMINS
,
3164 .db_index
= SAM_DATABASE_DOMAIN
,
3165 .delta_type
= NETR_DELTA_GROUP
,
3168 .expected_error
= NT_STATUS_OK
,
3169 .expected_num_results
= 2,
3170 .expected_delta_type_1
= NETR_DELTA_GROUP
,
3171 .expected_delta_type_2
= NETR_DELTA_GROUP_MEMBER
,
3172 .comment
= "NETR_DELTA_GROUP by rid 512"
3175 .rid
= DOMAIN_RID_ADMINS
,
3177 .db_index
= SAM_DATABASE_DOMAIN
,
3178 .delta_type
= NETR_DELTA_GROUP_MEMBER
,
3181 .expected_error
= NT_STATUS_OK
,
3182 .expected_num_results
= 2,
3183 .expected_delta_type_1
= NETR_DELTA_GROUP
,
3184 .expected_delta_type_2
= NETR_DELTA_GROUP_MEMBER
,
3185 .comment
= "NETR_DELTA_GROUP_MEMBER by rid 512"
3189 /* SAM_DATABASE_BUILTIN */
3194 .db_index
= SAM_DATABASE_BUILTIN
,
3195 .delta_type
= NETR_DELTA_MODIFY_COUNT
,
3198 .expected_error
= NT_STATUS_SYNCHRONIZATION_REQUIRED
,
3199 .expected_num_results
= 0,
3200 .comment
= "NETR_DELTA_MODIFY_COUNT"
3205 .db_index
= SAM_DATABASE_BUILTIN
,
3206 .delta_type
= NETR_DELTA_DOMAIN
,
3209 .expected_error
= NT_STATUS_OK
,
3210 .expected_num_results
= 1,
3211 .expected_delta_type_1
= NETR_DELTA_DOMAIN
,
3212 .comment
= "NETR_DELTA_DOMAIN"
3215 .rid
= DOMAIN_RID_ADMINISTRATOR
,
3217 .db_index
= SAM_DATABASE_BUILTIN
,
3218 .delta_type
= NETR_DELTA_USER
,
3221 .expected_error
= NT_STATUS_OK
,
3222 .expected_num_results
= 1,
3223 .expected_delta_type_1
= NETR_DELTA_DELETE_USER
,
3224 .comment
= "NETR_DELTA_USER by rid 500"
3229 .db_index
= SAM_DATABASE_BUILTIN
,
3230 .delta_type
= NETR_DELTA_USER
,
3233 .expected_error
= NT_STATUS_OK
,
3234 .expected_num_results
= 1,
3235 .expected_delta_type_1
= NETR_DELTA_DELETE_USER
,
3236 .comment
= "NETR_DELTA_USER"
3241 .db_index
= SAM_DATABASE_BUILTIN
,
3242 .delta_type
= NETR_DELTA_ALIAS
,
3245 .expected_error
= NT_STATUS_OK
,
3246 .expected_num_results
= 2,
3247 .expected_delta_type_1
= NETR_DELTA_ALIAS
,
3248 .expected_delta_type_2
= NETR_DELTA_ALIAS_MEMBER
,
3249 .comment
= "NETR_DELTA_ALIAS by rid 544"
3254 .db_index
= SAM_DATABASE_BUILTIN
,
3255 .delta_type
= NETR_DELTA_ALIAS_MEMBER
,
3258 .expected_error
= NT_STATUS_OK
,
3259 .expected_num_results
= 2,
3260 .expected_delta_type_1
= NETR_DELTA_ALIAS
,
3261 .expected_delta_type_2
= NETR_DELTA_ALIAS_MEMBER
,
3262 .comment
= "NETR_DELTA_ALIAS_MEMBER by rid 544"
3267 .db_index
= SAM_DATABASE_BUILTIN
,
3271 .expected_error
= NT_STATUS_OK
,
3272 .expected_num_results
= 1,
3273 .expected_delta_type_1
= NETR_DELTA_DOMAIN
,
3274 .comment
= "NULL DELTA by rid 544"
3278 .flags
= NETR_CHANGELOG_SID_INCLUDED
,
3279 .db_index
= SAM_DATABASE_BUILTIN
,
3281 .sid
= *dom_sid_parse_talloc(tctx
, "S-1-5-32-544"),
3283 .expected_error
= NT_STATUS_OK
,
3284 .expected_num_results
= 1,
3285 .expected_delta_type_1
= NETR_DELTA_DOMAIN
,
3286 .comment
= "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
3290 .flags
= NETR_CHANGELOG_SID_INCLUDED
,
3291 .db_index
= SAM_DATABASE_BUILTIN
,
3292 .delta_type
= NETR_DELTA_ALIAS
,
3293 .sid
= *dom_sid_parse_talloc(tctx
, "S-1-5-32-544"),
3295 .expected_error
= NT_STATUS_OK
,
3296 .expected_num_results
= 2,
3297 .expected_delta_type_1
= NETR_DELTA_ALIAS
,
3298 .expected_delta_type_2
= NETR_DELTA_ALIAS_MEMBER
,
3299 .comment
= "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
3303 .flags
= NETR_CHANGELOG_SID_INCLUDED
,
3304 .db_index
= SAM_DATABASE_BUILTIN
,
3305 .delta_type
= NETR_DELTA_ALIAS
,
3306 .sid
= *dom_sid_parse_talloc(tctx
, "S-1-5-32-544"),
3308 .expected_error
= NT_STATUS_OK
,
3309 .expected_num_results
= 1,
3310 .expected_delta_type_1
= NETR_DELTA_DELETE_ALIAS
,
3311 .comment
= "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
3314 /* SAM_DATABASE_PRIVS */
3319 .db_index
= SAM_DATABASE_PRIVS
,
3323 .expected_error
= NT_STATUS_ACCESS_DENIED
,
3324 .expected_num_results
= 0,
3325 .comment
= "NULL DELTA"
3330 .db_index
= SAM_DATABASE_PRIVS
,
3331 .delta_type
= NETR_DELTA_MODIFY_COUNT
,
3334 .expected_error
= NT_STATUS_SYNCHRONIZATION_REQUIRED
,
3335 .expected_num_results
= 0,
3336 .comment
= "NETR_DELTA_MODIFY_COUNT"
3341 .db_index
= SAM_DATABASE_PRIVS
,
3342 .delta_type
= NETR_DELTA_POLICY
,
3345 .expected_error
= NT_STATUS_OK
,
3346 .expected_num_results
= 1,
3347 .expected_delta_type_1
= NETR_DELTA_POLICY
,
3348 .comment
= "NETR_DELTA_POLICY"
3352 .flags
= NETR_CHANGELOG_SID_INCLUDED
,
3353 .db_index
= SAM_DATABASE_PRIVS
,
3354 .delta_type
= NETR_DELTA_POLICY
,
3357 .expected_error
= NT_STATUS_OK
,
3358 .expected_num_results
= 1,
3359 .expected_delta_type_1
= NETR_DELTA_POLICY
,
3360 .comment
= "NETR_DELTA_POLICY by null sid and flags"
3364 .flags
= NETR_CHANGELOG_SID_INCLUDED
,
3365 .db_index
= SAM_DATABASE_PRIVS
,
3366 .delta_type
= NETR_DELTA_POLICY
,
3367 .sid
= *dom_sid_parse_talloc(tctx
, "S-1-5-32"),
3369 .expected_error
= NT_STATUS_OK
,
3370 .expected_num_results
= 1,
3371 .expected_delta_type_1
= NETR_DELTA_POLICY
,
3372 .comment
= "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
3375 .rid
= DOMAIN_RID_ADMINISTRATOR
,
3377 .db_index
= SAM_DATABASE_PRIVS
,
3378 .delta_type
= NETR_DELTA_ACCOUNT
,
3381 .expected_error
= NT_STATUS_SYNCHRONIZATION_REQUIRED
, /* strange */
3382 .expected_num_results
= 0,
3383 .comment
= "NETR_DELTA_ACCOUNT by rid 500"
3387 .flags
= NETR_CHANGELOG_SID_INCLUDED
,
3388 .db_index
= SAM_DATABASE_PRIVS
,
3389 .delta_type
= NETR_DELTA_ACCOUNT
,
3390 .sid
= *dom_sid_parse_talloc(tctx
, "S-1-1-0"),
3392 .expected_error
= NT_STATUS_OK
,
3393 .expected_num_results
= 1,
3394 .expected_delta_type_1
= NETR_DELTA_ACCOUNT
,
3395 .comment
= "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
3399 .flags
= NETR_CHANGELOG_SID_INCLUDED
|
3400 NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED
,
3401 .db_index
= SAM_DATABASE_PRIVS
,
3402 .delta_type
= NETR_DELTA_ACCOUNT
,
3403 .sid
= *dom_sid_parse_talloc(tctx
, "S-1-1-0"),
3405 .expected_error
= NT_STATUS_OK
,
3406 .expected_num_results
= 1,
3407 .expected_delta_type_1
= NETR_DELTA_ACCOUNT
,
3408 .comment
= "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
3412 .flags
= NETR_CHANGELOG_SID_INCLUDED
|
3413 NETR_CHANGELOG_NAME_INCLUDED
,
3414 .db_index
= SAM_DATABASE_PRIVS
,
3415 .delta_type
= NETR_DELTA_ACCOUNT
,
3416 .sid
= *dom_sid_parse_talloc(tctx
, "S-1-1-0"),
3418 .expected_error
= NT_STATUS_INVALID_PARAMETER
,
3419 .expected_num_results
= 0,
3420 .comment
= "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
3423 .rid
= DOMAIN_RID_ADMINISTRATOR
,
3424 .flags
= NETR_CHANGELOG_SID_INCLUDED
,
3425 .db_index
= SAM_DATABASE_PRIVS
,
3426 .delta_type
= NETR_DELTA_ACCOUNT
,
3429 .expected_error
= NT_STATUS_OK
,
3430 .expected_num_results
= 1,
3431 .expected_delta_type_1
= NETR_DELTA_DELETE_ACCOUNT
,
3432 .comment
= "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
3436 .flags
= NETR_CHANGELOG_NAME_INCLUDED
,
3437 .db_index
= SAM_DATABASE_PRIVS
,
3438 .delta_type
= NETR_DELTA_SECRET
,
3440 .name
= "IsurelydontexistIhope",
3441 .expected_error
= NT_STATUS_OK
,
3442 .expected_num_results
= 1,
3443 .expected_delta_type_1
= NETR_DELTA_DELETE_SECRET
,
3444 .comment
= "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
3448 .flags
= NETR_CHANGELOG_NAME_INCLUDED
,
3449 .db_index
= SAM_DATABASE_PRIVS
,
3450 .delta_type
= NETR_DELTA_SECRET
,
3452 .name
= "G$BCKUPKEY_P",
3453 .expected_error
= NT_STATUS_OK
,
3454 .expected_num_results
= 1,
3455 .expected_delta_type_1
= NETR_DELTA_SECRET
,
3456 .comment
= "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
3460 ZERO_STRUCT(return_authenticator
);
3462 r
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
3463 r
.in
.computername
= TEST_MACHINE_NAME
;
3464 r
.in
.return_authenticator
= &return_authenticator
;
3465 r
.out
.return_authenticator
= &return_authenticator
;
3466 r
.out
.delta_enum_array
= &delta_enum_array
;
3468 for (d
=0; d
<3; d
++) {
3469 const char *database
= NULL
;
3476 database
= "BUILTIN";
3485 torture_comment(tctx
, "Testing DatabaseRedo\n");
3487 if (!test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
)) {
3491 for (i
=0;i
<ARRAY_SIZE(changes
);i
++) {
3493 if (d
!= changes
[i
].db_index
) {
3497 netlogon_creds_client_authenticator(creds
, &credential
);
3499 r
.in
.credential
= &credential
;
3501 e
.serial_number1
= 0;
3502 e
.serial_number2
= 0;
3503 e
.object_rid
= changes
[i
].rid
;
3504 e
.flags
= changes
[i
].flags
;
3505 e
.db_index
= changes
[i
].db_index
;
3506 e
.delta_type
= changes
[i
].delta_type
;
3508 switch (changes
[i
].flags
& (NETR_CHANGELOG_NAME_INCLUDED
| NETR_CHANGELOG_SID_INCLUDED
)) {
3509 case NETR_CHANGELOG_SID_INCLUDED
:
3510 e
.object
.object_sid
= changes
[i
].sid
;
3512 case NETR_CHANGELOG_NAME_INCLUDED
:
3513 e
.object
.object_name
= changes
[i
].name
;
3519 r
.in
.change_log_entry
= e
;
3521 torture_comment(tctx
, "Testing DatabaseRedo with database %s and %s\n",
3522 database
, changes
[i
].comment
);
3524 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_DatabaseRedo_r(b
, tctx
, &r
),
3525 "DatabaseRedo failed");
3526 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_NOT_SUPPORTED
)) {
3530 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, changes
[i
].expected_error
, changes
[i
].comment
);
3531 if (delta_enum_array
) {
3532 torture_assert_int_equal(tctx
,
3533 delta_enum_array
->num_deltas
,
3534 changes
[i
].expected_num_results
,
3535 changes
[i
].comment
);
3536 if (delta_enum_array
->num_deltas
> 0) {
3537 torture_assert_int_equal(tctx
,
3538 delta_enum_array
->delta_enum
[0].delta_type
,
3539 changes
[i
].expected_delta_type_1
,
3540 changes
[i
].comment
);
3542 if (delta_enum_array
->num_deltas
> 1) {
3543 torture_assert_int_equal(tctx
,
3544 delta_enum_array
->delta_enum
[1].delta_type
,
3545 changes
[i
].expected_delta_type_2
,
3546 changes
[i
].comment
);
3550 if (!netlogon_creds_client_check(creds
, &return_authenticator
.cred
)) {
3551 torture_comment(tctx
, "Credential chaining failed\n");
3552 if (!test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
)) {
3564 try a netlogon AccountDeltas
3566 static bool test_AccountDeltas(struct torture_context
*tctx
,
3567 struct dcerpc_pipe
*p
,
3568 struct cli_credentials
*machine_credentials
)
3570 struct netr_AccountDeltas r
;
3571 struct netlogon_creds_CredentialState
*creds
;
3573 struct netr_AccountBuffer buffer
;
3574 uint32_t count_returned
= 0;
3575 uint32_t total_entries
= 0;
3576 struct netr_UAS_INFO_0 recordid
;
3577 struct netr_Authenticator return_authenticator
;
3578 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3580 if (!test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
)) {
3584 ZERO_STRUCT(return_authenticator
);
3586 r
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
3587 r
.in
.computername
= TEST_MACHINE_NAME
;
3588 r
.in
.return_authenticator
= &return_authenticator
;
3589 netlogon_creds_client_authenticator(creds
, &r
.in
.credential
);
3590 ZERO_STRUCT(r
.in
.uas
);
3593 r
.in
.buffersize
=100;
3594 r
.out
.buffer
= &buffer
;
3595 r
.out
.count_returned
= &count_returned
;
3596 r
.out
.total_entries
= &total_entries
;
3597 r
.out
.recordid
= &recordid
;
3598 r
.out
.return_authenticator
= &return_authenticator
;
3600 /* w2k3 returns "NOT IMPLEMENTED" for this call */
3601 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_AccountDeltas_r(b
, tctx
, &r
),
3602 "AccountDeltas failed");
3603 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_NOT_IMPLEMENTED
, "AccountDeltas");
3609 try a netlogon AccountSync
3611 static bool test_AccountSync(struct torture_context
*tctx
, struct dcerpc_pipe
*p
,
3612 struct cli_credentials
*machine_credentials
)
3614 struct netr_AccountSync r
;
3615 struct netlogon_creds_CredentialState
*creds
;
3617 struct netr_AccountBuffer buffer
;
3618 uint32_t count_returned
= 0;
3619 uint32_t total_entries
= 0;
3620 uint32_t next_reference
= 0;
3621 struct netr_UAS_INFO_0 recordid
;
3622 struct netr_Authenticator return_authenticator
;
3623 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3625 ZERO_STRUCT(recordid
);
3626 ZERO_STRUCT(return_authenticator
);
3628 if (!test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
)) {
3632 r
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
3633 r
.in
.computername
= TEST_MACHINE_NAME
;
3634 r
.in
.return_authenticator
= &return_authenticator
;
3635 netlogon_creds_client_authenticator(creds
, &r
.in
.credential
);
3636 r
.in
.recordid
= &recordid
;
3639 r
.in
.buffersize
=100;
3640 r
.out
.buffer
= &buffer
;
3641 r
.out
.count_returned
= &count_returned
;
3642 r
.out
.total_entries
= &total_entries
;
3643 r
.out
.next_reference
= &next_reference
;
3644 r
.out
.recordid
= &recordid
;
3645 r
.out
.return_authenticator
= &return_authenticator
;
3647 /* w2k3 returns "NOT IMPLEMENTED" for this call */
3648 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_AccountSync_r(b
, tctx
, &r
),
3649 "AccountSync failed");
3650 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_NOT_IMPLEMENTED
, "AccountSync");
3656 try a netlogon GetDcName
3658 static bool test_GetDcName(struct torture_context
*tctx
,
3659 struct dcerpc_pipe
*p
)
3661 struct netr_GetDcName r
;
3662 const char *dcname
= NULL
;
3663 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3665 r
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
3666 r
.in
.domainname
= lpcfg_workgroup(tctx
->lp_ctx
);
3667 r
.out
.dcname
= &dcname
;
3669 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_GetDcName_r(b
, tctx
, &r
),
3670 "GetDcName failed");
3671 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetDcName failed");
3673 torture_comment(tctx
, "\tDC is at '%s'\n", dcname
);
3678 static const char *function_code_str(TALLOC_CTX
*mem_ctx
,
3679 enum netr_LogonControlCode function_code
)
3681 switch (function_code
) {
3682 case NETLOGON_CONTROL_QUERY
:
3683 return "NETLOGON_CONTROL_QUERY";
3684 case NETLOGON_CONTROL_REPLICATE
:
3685 return "NETLOGON_CONTROL_REPLICATE";
3686 case NETLOGON_CONTROL_SYNCHRONIZE
:
3687 return "NETLOGON_CONTROL_SYNCHRONIZE";
3688 case NETLOGON_CONTROL_PDC_REPLICATE
:
3689 return "NETLOGON_CONTROL_PDC_REPLICATE";
3690 case NETLOGON_CONTROL_REDISCOVER
:
3691 return "NETLOGON_CONTROL_REDISCOVER";
3692 case NETLOGON_CONTROL_TC_QUERY
:
3693 return "NETLOGON_CONTROL_TC_QUERY";
3694 case NETLOGON_CONTROL_TRANSPORT_NOTIFY
:
3695 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
3696 case NETLOGON_CONTROL_FIND_USER
:
3697 return "NETLOGON_CONTROL_FIND_USER";
3698 case NETLOGON_CONTROL_CHANGE_PASSWORD
:
3699 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
3700 case NETLOGON_CONTROL_TC_VERIFY
:
3701 return "NETLOGON_CONTROL_TC_VERIFY";
3702 case NETLOGON_CONTROL_FORCE_DNS_REG
:
3703 return "NETLOGON_CONTROL_FORCE_DNS_REG";
3704 case NETLOGON_CONTROL_QUERY_DNS_REG
:
3705 return "NETLOGON_CONTROL_QUERY_DNS_REG";
3706 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG
:
3707 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
3708 case NETLOGON_CONTROL_TRUNCATE_LOG
:
3709 return "NETLOGON_CONTROL_TRUNCATE_LOG";
3710 case NETLOGON_CONTROL_SET_DBFLAG
:
3711 return "NETLOGON_CONTROL_SET_DBFLAG";
3712 case NETLOGON_CONTROL_BREAKPOINT
:
3713 return "NETLOGON_CONTROL_BREAKPOINT";
3715 return talloc_asprintf(mem_ctx
, "unknown function code: %d",
3722 try a netlogon LogonControl
3724 static bool test_LogonControl(struct torture_context
*tctx
,
3725 struct dcerpc_pipe
*p
,
3726 struct cli_credentials
*machine_credentials
)
3730 struct netr_LogonControl r
;
3731 union netr_CONTROL_QUERY_INFORMATION query
;
3733 enum netr_SchannelType secure_channel_type
= SEC_CHAN_NULL
;
3734 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3736 uint32_t function_codes
[] = {
3737 NETLOGON_CONTROL_QUERY
,
3738 NETLOGON_CONTROL_REPLICATE
,
3739 NETLOGON_CONTROL_SYNCHRONIZE
,
3740 NETLOGON_CONTROL_PDC_REPLICATE
,
3741 NETLOGON_CONTROL_REDISCOVER
,
3742 NETLOGON_CONTROL_TC_QUERY
,
3743 NETLOGON_CONTROL_TRANSPORT_NOTIFY
,
3744 NETLOGON_CONTROL_FIND_USER
,
3745 NETLOGON_CONTROL_CHANGE_PASSWORD
,
3746 NETLOGON_CONTROL_TC_VERIFY
,
3747 NETLOGON_CONTROL_FORCE_DNS_REG
,
3748 NETLOGON_CONTROL_QUERY_DNS_REG
,
3749 NETLOGON_CONTROL_BACKUP_CHANGE_LOG
,
3750 NETLOGON_CONTROL_TRUNCATE_LOG
,
3751 NETLOGON_CONTROL_SET_DBFLAG
,
3752 NETLOGON_CONTROL_BREAKPOINT
3755 if (machine_credentials
) {
3756 secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
3759 torture_comment(tctx
, "Testing LogonControl with secure channel type: %d\n",
3760 secure_channel_type
);
3762 r
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
3763 r
.in
.function_code
= 1;
3764 r
.out
.query
= &query
;
3766 for (f
=0;f
<ARRAY_SIZE(function_codes
); f
++) {
3769 r
.in
.function_code
= function_codes
[f
];
3772 torture_comment(tctx
, "Testing LogonControl function code %s (%d) level %d\n",
3773 function_code_str(tctx
, r
.in
.function_code
), r
.in
.function_code
, r
.in
.level
);
3775 status
= dcerpc_netr_LogonControl_r(b
, tctx
, &r
);
3776 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl");
3778 switch (r
.in
.level
) {
3780 switch (r
.in
.function_code
) {
3781 case NETLOGON_CONTROL_REPLICATE
:
3782 case NETLOGON_CONTROL_SYNCHRONIZE
:
3783 case NETLOGON_CONTROL_PDC_REPLICATE
:
3784 case NETLOGON_CONTROL_BREAKPOINT
:
3785 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG
:
3786 if ((secure_channel_type
== SEC_CHAN_BDC
) ||
3787 (secure_channel_type
== SEC_CHAN_WKSTA
)) {
3788 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_ACCESS_DENIED
,
3789 "LogonControl returned unexpected error code");
3791 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_NOT_SUPPORTED
,
3792 "LogonControl returned unexpected error code");
3796 case NETLOGON_CONTROL_REDISCOVER
:
3797 case NETLOGON_CONTROL_TC_QUERY
:
3798 case NETLOGON_CONTROL_TRANSPORT_NOTIFY
:
3799 case NETLOGON_CONTROL_FIND_USER
:
3800 case NETLOGON_CONTROL_CHANGE_PASSWORD
:
3801 case NETLOGON_CONTROL_TC_VERIFY
:
3802 case NETLOGON_CONTROL_FORCE_DNS_REG
:
3803 case NETLOGON_CONTROL_QUERY_DNS_REG
:
3804 case NETLOGON_CONTROL_SET_DBFLAG
:
3805 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_NOT_SUPPORTED
,
3806 "LogonControl returned unexpected error code");
3808 case NETLOGON_CONTROL_TRUNCATE_LOG
:
3809 if ((secure_channel_type
== SEC_CHAN_BDC
) ||
3810 (secure_channel_type
== SEC_CHAN_WKSTA
)) {
3811 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_ACCESS_DENIED
,
3812 "LogonControl returned unexpected error code");
3813 } else if (!W_ERROR_EQUAL(r
.out
.result
, WERR_NOT_SUPPORTED
)) {
3814 torture_assert_werr_ok(tctx
, r
.out
.result
,
3815 "LogonControl returned unexpected result");
3819 torture_assert_werr_ok(tctx
, r
.out
.result
,
3820 "LogonControl returned unexpected result");
3825 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_NOT_SUPPORTED
,
3826 "LogonControl returned unexpected error code");
3829 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_LEVEL
,
3830 "LogonControl returned unexpected error code");
3837 torture_comment(tctx
, "Testing LogonControl function code %s (%d) level %d\n",
3838 function_code_str(tctx
, r
.in
.function_code
), r
.in
.function_code
, r
.in
.level
);
3839 status
= dcerpc_netr_LogonControl_r(b
, tctx
, &r
);
3840 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl");
3841 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_LEVEL
, "LogonControl");
3848 try a netlogon GetAnyDCName
3850 static bool test_GetAnyDCName(struct torture_context
*tctx
,
3851 struct dcerpc_pipe
*p
)
3854 struct netr_GetAnyDCName r
;
3855 const char *dcname
= NULL
;
3856 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3858 r
.in
.domainname
= lpcfg_workgroup(tctx
->lp_ctx
);
3859 r
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
3860 r
.out
.dcname
= &dcname
;
3862 status
= dcerpc_netr_GetAnyDCName_r(b
, tctx
, &r
);
3863 torture_assert_ntstatus_ok(tctx
, status
, "GetAnyDCName");
3864 if ((!W_ERROR_IS_OK(r
.out
.result
)) &&
3865 (!W_ERROR_EQUAL(r
.out
.result
, WERR_NO_SUCH_DOMAIN
))) {
3870 torture_comment(tctx
, "\tDC is at '%s'\n", dcname
);
3873 r
.in
.domainname
= NULL
;
3875 status
= dcerpc_netr_GetAnyDCName_r(b
, tctx
, &r
);
3876 torture_assert_ntstatus_ok(tctx
, status
, "GetAnyDCName");
3877 if ((!W_ERROR_IS_OK(r
.out
.result
)) &&
3878 (!W_ERROR_EQUAL(r
.out
.result
, WERR_NO_SUCH_DOMAIN
))) {
3882 r
.in
.domainname
= "";
3884 status
= dcerpc_netr_GetAnyDCName_r(b
, tctx
, &r
);
3885 torture_assert_ntstatus_ok(tctx
, status
, "GetAnyDCName");
3886 if ((!W_ERROR_IS_OK(r
.out
.result
)) &&
3887 (!W_ERROR_EQUAL(r
.out
.result
, WERR_NO_SUCH_DOMAIN
))) {
3896 try a netlogon LogonControl2
3898 static bool test_LogonControl2(struct torture_context
*tctx
,
3899 struct dcerpc_pipe
*p
,
3900 struct cli_credentials
*machine_credentials
)
3904 struct netr_LogonControl2 r
;
3905 union netr_CONTROL_DATA_INFORMATION data
;
3906 union netr_CONTROL_QUERY_INFORMATION query
;
3907 enum netr_SchannelType secure_channel_type
= SEC_CHAN_NULL
;
3909 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3911 data
.domain
= lpcfg_workgroup(tctx
->lp_ctx
);
3913 if (machine_credentials
) {
3914 secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
3917 torture_comment(tctx
, "Testing LogonControl2 with secure channel type: %d\n",
3918 secure_channel_type
);
3920 r
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
3922 r
.in
.function_code
= NETLOGON_CONTROL_REDISCOVER
;
3924 r
.out
.query
= &query
;
3929 torture_comment(tctx
, "Testing LogonControl2 function code %s (%d) level %d\n",
3930 function_code_str(tctx
, r
.in
.function_code
), r
.in
.function_code
, r
.in
.level
);
3932 status
= dcerpc_netr_LogonControl2_r(b
, tctx
, &r
);
3933 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl2");
3936 data
.domain
= lpcfg_workgroup(tctx
->lp_ctx
);
3938 r
.in
.function_code
= NETLOGON_CONTROL_TC_QUERY
;
3944 torture_comment(tctx
, "Testing LogonControl2 function code %s (%d) level %d\n",
3945 function_code_str(tctx
, r
.in
.function_code
), r
.in
.function_code
, r
.in
.level
);
3947 status
= dcerpc_netr_LogonControl2_r(b
, tctx
, &r
);
3948 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl2");
3951 data
.domain
= lpcfg_workgroup(tctx
->lp_ctx
);
3953 r
.in
.function_code
= NETLOGON_CONTROL_TRANSPORT_NOTIFY
;
3959 torture_comment(tctx
, "Testing LogonControl2 function code %s (%d) level %d\n",
3960 function_code_str(tctx
, r
.in
.function_code
), r
.in
.function_code
, r
.in
.level
);
3962 status
= dcerpc_netr_LogonControl2_r(b
, tctx
, &r
);
3963 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl2");
3966 data
.debug_level
= ~0;
3968 r
.in
.function_code
= NETLOGON_CONTROL_SET_DBFLAG
;
3974 torture_comment(tctx
, "Testing LogonControl2 function code %s (%d) level %d\n",
3975 function_code_str(tctx
, r
.in
.function_code
), r
.in
.function_code
, r
.in
.level
);
3977 status
= dcerpc_netr_LogonControl2_r(b
, tctx
, &r
);
3978 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl2");
3982 r
.in
.function_code
= 52;
3985 torture_comment(tctx
, "Testing LogonControl2 function code %s (%d) level %d\n",
3986 function_code_str(tctx
, r
.in
.function_code
), r
.in
.function_code
, r
.in
.level
);
3988 status
= dcerpc_netr_LogonControl2_r(b
, tctx
, &r
);
3989 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl2");
3990 switch (secure_channel_type
) {
3992 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_NOT_SUPPORTED
, "LogonControl2");
3995 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_ACCESS_DENIED
, "LogonControl2");
3998 data
.debug_level
= ~0;
4000 r
.in
.function_code
= NETLOGON_CONTROL_SET_DBFLAG
;
4004 torture_comment(tctx
, "Testing LogonControl2 function code %s (%d) level %d\n",
4005 function_code_str(tctx
, r
.in
.function_code
), r
.in
.function_code
, r
.in
.level
);
4007 status
= dcerpc_netr_LogonControl2_r(b
, tctx
, &r
);
4008 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl2");
4009 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_LEVEL
, "LogonControl2");
4015 try a netlogon DatabaseSync2
4017 static bool test_DatabaseSync2(struct torture_context
*tctx
,
4018 struct dcerpc_pipe
*p
,
4019 struct cli_credentials
*machine_credentials
)
4021 struct netr_DatabaseSync2 r
;
4022 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
4023 struct netr_Authenticator return_authenticator
, credential
;
4025 struct netlogon_creds_CredentialState
*creds
;
4026 const uint32_t database_ids
[] = {0, 1, 2};
4028 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4030 if (!test_SetupCredentials2(p
, tctx
, NETLOGON_NEG_AUTH2_FLAGS
,
4031 machine_credentials
,
4032 cli_credentials_get_secure_channel_type(machine_credentials
),
4037 ZERO_STRUCT(return_authenticator
);
4039 r
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
4040 r
.in
.computername
= TEST_MACHINE_NAME
;
4041 r
.in
.preferredmaximumlength
= (uint32_t)-1;
4042 r
.in
.return_authenticator
= &return_authenticator
;
4043 r
.out
.return_authenticator
= &return_authenticator
;
4044 r
.out
.delta_enum_array
= &delta_enum_array
;
4046 for (i
=0;i
<ARRAY_SIZE(database_ids
);i
++) {
4048 uint32_t sync_context
= 0;
4050 r
.in
.database_id
= database_ids
[i
];
4051 r
.in
.sync_context
= &sync_context
;
4052 r
.out
.sync_context
= &sync_context
;
4053 r
.in
.restart_state
= 0;
4055 torture_comment(tctx
, "Testing DatabaseSync2 of id %d\n", r
.in
.database_id
);
4058 netlogon_creds_client_authenticator(creds
, &credential
);
4060 r
.in
.credential
= &credential
;
4062 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_DatabaseSync2_r(b
, tctx
, &r
),
4063 "DatabaseSync2 failed");
4064 if (NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
))
4067 /* Native mode servers don't do this */
4068 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_NOT_SUPPORTED
)) {
4072 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "DatabaseSync2");
4074 if (!netlogon_creds_client_check(creds
, &r
.out
.return_authenticator
->cred
)) {
4075 torture_comment(tctx
, "Credential chaining failed\n");
4078 } while (NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
));
4086 try a netlogon LogonControl2Ex
4089 static bool test_LogonControl2Ex(struct torture_context
*tctx
,
4090 struct dcerpc_pipe
*p
,
4091 struct cli_credentials
*machine_credentials
)
4095 struct netr_LogonControl2Ex r
;
4096 union netr_CONTROL_DATA_INFORMATION data
;
4097 union netr_CONTROL_QUERY_INFORMATION query
;
4098 enum netr_SchannelType secure_channel_type
= SEC_CHAN_NULL
;
4100 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4102 data
.domain
= lpcfg_workgroup(tctx
->lp_ctx
);
4104 if (machine_credentials
) {
4105 secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
4108 torture_comment(tctx
, "Testing LogonControl2Ex with secure channel type: %d\n",
4109 secure_channel_type
);
4111 r
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
4113 r
.in
.function_code
= NETLOGON_CONTROL_REDISCOVER
;
4115 r
.out
.query
= &query
;
4120 torture_comment(tctx
, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4121 function_code_str(tctx
, r
.in
.function_code
), r
.in
.function_code
, r
.in
.level
);
4123 status
= dcerpc_netr_LogonControl2Ex_r(b
, tctx
, &r
);
4124 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl2Ex");
4127 data
.domain
= lpcfg_workgroup(tctx
->lp_ctx
);
4129 r
.in
.function_code
= NETLOGON_CONTROL_TC_QUERY
;
4135 torture_comment(tctx
, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4136 function_code_str(tctx
, r
.in
.function_code
), r
.in
.function_code
, r
.in
.level
);
4138 status
= dcerpc_netr_LogonControl2Ex_r(b
, tctx
, &r
);
4139 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl2Ex");
4142 data
.domain
= lpcfg_workgroup(tctx
->lp_ctx
);
4144 r
.in
.function_code
= NETLOGON_CONTROL_TRANSPORT_NOTIFY
;
4150 torture_comment(tctx
, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4151 function_code_str(tctx
, r
.in
.function_code
), r
.in
.function_code
, r
.in
.level
);
4153 status
= dcerpc_netr_LogonControl2Ex_r(b
, tctx
, &r
);
4154 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl2Ex");
4157 data
.debug_level
= ~0;
4159 r
.in
.function_code
= NETLOGON_CONTROL_SET_DBFLAG
;
4162 for (i
=1;i
<=4;i
++) {
4165 torture_comment(tctx
, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4166 function_code_str(tctx
, r
.in
.function_code
), r
.in
.function_code
, r
.in
.level
);
4168 status
= dcerpc_netr_LogonControl2Ex_r(b
, tctx
, &r
);
4169 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl2Ex");
4173 r
.in
.function_code
= 52;
4176 torture_comment(tctx
, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4177 function_code_str(tctx
, r
.in
.function_code
), r
.in
.function_code
, r
.in
.level
);
4179 status
= dcerpc_netr_LogonControl2Ex_r(b
, tctx
, &r
);
4180 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl2Ex");
4181 switch (secure_channel_type
) {
4183 torture_assert(tctx
,
4184 W_ERROR_EQUAL(r
.out
.result
, WERR_NOT_SUPPORTED
) ||
4185 W_ERROR_EQUAL(r
.out
.result
, WERR_INVALID_PARAMETER
),
4189 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_ACCESS_DENIED
, "LogonControl2Ex");
4192 data
.debug_level
= ~0;
4194 r
.in
.function_code
= NETLOGON_CONTROL_SET_DBFLAG
;
4198 torture_comment(tctx
, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4199 function_code_str(tctx
, r
.in
.function_code
), r
.in
.function_code
, r
.in
.level
);
4201 status
= dcerpc_netr_LogonControl2Ex_r(b
, tctx
, &r
);
4202 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl2Ex");
4203 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_LEVEL
, "LogonControl2Ex");
4208 static bool test_netr_GetForestTrustInformation(struct torture_context
*tctx
,
4209 struct dcerpc_pipe
*p1
,
4210 struct cli_credentials
*machine_credentials
)
4212 struct netr_GetForestTrustInformation r
;
4213 struct netlogon_creds_CredentialState
*creds
;
4214 struct netr_Authenticator a
;
4215 struct netr_Authenticator return_authenticator
;
4216 struct lsa_ForestTrustInformation
*forest_trust_info
;
4217 struct dcerpc_pipe
*p
= NULL
;
4218 struct dcerpc_binding_handle
*b
= NULL
;
4220 if (!test_SetupCredentials3(p1
, tctx
, NETLOGON_NEG_AUTH2_ADS_FLAGS
| NETLOGON_NEG_SUPPORTS_AES
,
4221 machine_credentials
, &creds
)) {
4224 if (!test_SetupCredentialsPipe(p1
, tctx
, machine_credentials
, creds
,
4225 DCERPC_SIGN
| DCERPC_SEAL
, &p
)) {
4228 b
= p
->binding_handle
;
4230 netlogon_creds_client_authenticator(creds
, &a
);
4232 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
4233 r
.in
.computer_name
= TEST_MACHINE_NAME
;
4234 r
.in
.credential
= &a
;
4236 r
.out
.return_authenticator
= &return_authenticator
;
4237 r
.out
.forest_trust_info
= &forest_trust_info
;
4239 torture_assert_ntstatus_ok(tctx
,
4240 dcerpc_netr_GetForestTrustInformation_r(b
, tctx
, &r
),
4241 "netr_GetForestTrustInformation failed");
4242 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_NOT_IMPLEMENTED
)) {
4243 torture_comment(tctx
, "not considering NT_STATUS_NOT_IMPLEMENTED as an error\n");
4245 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4246 "netr_GetForestTrustInformation failed");
4249 torture_assert(tctx
,
4250 netlogon_creds_client_check(creds
, &return_authenticator
.cred
),
4251 "Credential chaining failed");
4256 static bool test_netr_DsRGetForestTrustInformation(struct torture_context
*tctx
,
4257 struct dcerpc_pipe
*p
, const char *trusted_domain_name
)
4260 struct netr_DsRGetForestTrustInformation r
;
4261 struct lsa_ForestTrustInformation info
, *info_ptr
;
4262 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4266 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
4267 r
.in
.trusted_domain_name
= trusted_domain_name
;
4269 r
.out
.forest_trust_info
= &info_ptr
;
4271 torture_comment(tctx
,"Testing netr_DsRGetForestTrustInformation\n");
4273 status
= dcerpc_netr_DsRGetForestTrustInformation_r(b
, tctx
, &r
);
4274 torture_assert_ntstatus_ok(tctx
, status
, "DsRGetForestTrustInformation");
4275 torture_assert_werr_ok(tctx
, r
.out
.result
, "DsRGetForestTrustInformation");
4281 try a netlogon netr_DsrEnumerateDomainTrusts
4283 static bool test_DsrEnumerateDomainTrusts(struct torture_context
*tctx
,
4284 struct dcerpc_pipe
*p
)
4287 struct netr_DsrEnumerateDomainTrusts r
;
4288 struct netr_DomainTrustList trusts
;
4290 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4292 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
4293 r
.in
.trust_flags
= 0x3f;
4294 r
.out
.trusts
= &trusts
;
4296 status
= dcerpc_netr_DsrEnumerateDomainTrusts_r(b
, tctx
, &r
);
4297 torture_assert_ntstatus_ok(tctx
, status
, "DsrEnumerateDomaintrusts");
4298 torture_assert_werr_ok(tctx
, r
.out
.result
, "DsrEnumerateDomaintrusts");
4300 /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
4301 * will show non-forest trusts and all UPN suffixes of the own forest
4302 * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
4304 if (r
.out
.trusts
->count
) {
4305 if (!test_netr_DsRGetForestTrustInformation(tctx
, p
, NULL
)) {
4310 for (i
=0; i
<r
.out
.trusts
->count
; i
++) {
4312 /* get info for transitive forest trusts */
4314 if (r
.out
.trusts
->array
[i
].trust_attributes
& LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE
) {
4315 if (!test_netr_DsRGetForestTrustInformation(tctx
, p
,
4316 r
.out
.trusts
->array
[i
].dns_name
)) {
4325 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context
*tctx
,
4326 struct dcerpc_pipe
*p
)
4329 struct netr_NetrEnumerateTrustedDomains r
;
4330 struct netr_Blob trusted_domains_blob
;
4331 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4333 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
4334 r
.out
.trusted_domains_blob
= &trusted_domains_blob
;
4336 status
= dcerpc_netr_NetrEnumerateTrustedDomains_r(b
, tctx
, &r
);
4337 torture_assert_ntstatus_ok(tctx
, status
, "netr_NetrEnumerateTrustedDomains");
4338 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "NetrEnumerateTrustedDomains");
4343 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context
*tctx
,
4344 struct dcerpc_pipe
*p
)
4347 struct netr_NetrEnumerateTrustedDomainsEx r
;
4348 struct netr_DomainTrustList dom_trust_list
;
4349 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4351 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
4352 r
.out
.dom_trust_list
= &dom_trust_list
;
4354 status
= dcerpc_netr_NetrEnumerateTrustedDomainsEx_r(b
, tctx
, &r
);
4355 torture_assert_ntstatus_ok(tctx
, status
, "netr_NetrEnumerateTrustedDomainsEx");
4356 torture_assert_werr_ok(tctx
, r
.out
.result
, "NetrEnumerateTrustedDomainsEx");
4362 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4363 const char *computer_name
,
4364 const char *expected_site
)
4367 struct netr_DsRGetSiteName r
;
4368 const char *site
= NULL
;
4369 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4371 r
.in
.computer_name
= computer_name
;
4373 torture_comment(tctx
, "Testing netr_DsRGetSiteName\n");
4375 status
= dcerpc_netr_DsRGetSiteName_r(b
, tctx
, &r
);
4376 torture_assert_ntstatus_ok(tctx
, status
, "DsRGetSiteName");
4377 torture_assert_werr_ok(tctx
, r
.out
.result
, "DsRGetSiteName");
4378 torture_assert_str_equal(tctx
, expected_site
, site
, "netr_DsRGetSiteName");
4384 try a netlogon netr_DsRGetDCName
4386 static bool test_netr_DsRGetDCName(struct torture_context
*tctx
,
4387 struct dcerpc_pipe
*p
)
4390 struct netr_DsRGetDCName r
;
4391 struct netr_DsRGetDCNameInfo
*info
= NULL
;
4392 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4394 r
.in
.server_unc
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
4395 r
.in
.domain_name
= lpcfg_dnsdomain(tctx
->lp_ctx
);
4396 r
.in
.domain_guid
= NULL
;
4397 r
.in
.site_guid
= NULL
;
4398 r
.in
.flags
= DS_RETURN_DNS_NAME
;
4401 status
= dcerpc_netr_DsRGetDCName_r(b
, tctx
, &r
);
4402 torture_assert_ntstatus_ok(tctx
, status
, "DsRGetDCName");
4403 torture_assert_werr_ok(tctx
, r
.out
.result
, "DsRGetDCName");
4405 torture_assert_int_equal(tctx
,
4406 (info
->dc_flags
& (DS_DNS_CONTROLLER
)),
4409 torture_assert_int_equal(tctx
,
4410 (info
->dc_flags
& (DS_DNS_DOMAIN
)),
4413 torture_assert_int_equal(tctx
,
4414 (info
->dc_flags
& (DS_DNS_FOREST_ROOT
)),
4418 r
.in
.domain_name
= lpcfg_workgroup(tctx
->lp_ctx
);
4421 status
= dcerpc_netr_DsRGetDCName_r(b
, tctx
, &r
);
4422 torture_assert_ntstatus_ok(tctx
, status
, "DsRGetDCName");
4423 torture_assert_werr_ok(tctx
, r
.out
.result
, "DsRGetDCName");
4425 torture_assert_int_equal(tctx
,
4426 (info
->dc_flags
& (DS_DNS_CONTROLLER
)), 0,
4428 torture_assert_int_equal(tctx
,
4429 (info
->dc_flags
& (DS_DNS_DOMAIN
)), 0,
4431 torture_assert_int_equal(tctx
,
4432 (info
->dc_flags
& (DS_DNS_FOREST_ROOT
)),
4436 if (strcasecmp(info
->dc_site_name
, info
->client_site_name
) == 0) {
4437 torture_assert_int_equal(tctx
,
4438 (info
->dc_flags
& (DS_SERVER_CLOSEST
)),
4443 return test_netr_DsRGetSiteName(p
, tctx
,
4445 info
->dc_site_name
);
4449 try a netlogon netr_DsRGetDCNameEx
4451 static bool test_netr_DsRGetDCNameEx(struct torture_context
*tctx
,
4452 struct dcerpc_pipe
*p
)
4455 struct netr_DsRGetDCNameEx r
;
4456 struct netr_DsRGetDCNameInfo
*info
= NULL
;
4457 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4459 r
.in
.server_unc
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
4460 r
.in
.domain_name
= lpcfg_dnsdomain(tctx
->lp_ctx
);
4461 r
.in
.domain_guid
= NULL
;
4462 r
.in
.site_name
= NULL
;
4463 r
.in
.flags
= DS_RETURN_DNS_NAME
;
4466 status
= dcerpc_netr_DsRGetDCNameEx_r(b
, tctx
, &r
);
4467 torture_assert_ntstatus_ok(tctx
, status
, "netr_DsRGetDCNameEx");
4468 torture_assert_werr_ok(tctx
, r
.out
.result
, "netr_DsRGetDCNameEx");
4470 torture_assert_int_equal(tctx
,
4471 (info
->dc_flags
& (DS_DNS_CONTROLLER
)),
4474 torture_assert_int_equal(tctx
,
4475 (info
->dc_flags
& (DS_DNS_DOMAIN
)),
4478 torture_assert_int_equal(tctx
,
4479 (info
->dc_flags
& (DS_DNS_FOREST_ROOT
)),
4483 r
.in
.domain_name
= lpcfg_workgroup(tctx
->lp_ctx
);
4486 status
= dcerpc_netr_DsRGetDCNameEx_r(b
, tctx
, &r
);
4487 torture_assert_ntstatus_ok(tctx
, status
, "netr_DsRGetDCNameEx");
4488 torture_assert_werr_ok(tctx
, r
.out
.result
, "netr_DsRGetDCNameEx");
4490 torture_assert_int_equal(tctx
,
4491 (info
->dc_flags
& (DS_DNS_CONTROLLER
)), 0,
4493 torture_assert_int_equal(tctx
,
4494 (info
->dc_flags
& (DS_DNS_DOMAIN
)), 0,
4496 torture_assert_int_equal(tctx
,
4497 (info
->dc_flags
& (DS_DNS_FOREST_ROOT
)),
4501 if (strcasecmp(info
->dc_site_name
, info
->client_site_name
) == 0) {
4502 torture_assert_int_equal(tctx
,
4503 (info
->dc_flags
& (DS_SERVER_CLOSEST
)),
4508 return test_netr_DsRGetSiteName(p
, tctx
, info
->dc_unc
,
4509 info
->dc_site_name
);
4513 try a netlogon netr_DsRGetDCNameEx2
4515 static bool test_netr_DsRGetDCNameEx2(struct torture_context
*tctx
,
4516 struct dcerpc_pipe
*p
)
4519 struct netr_DsRGetDCNameEx2 r
;
4520 struct netr_DsRGetDCNameInfo
*info
= NULL
;
4521 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4523 torture_comment(tctx
, "Testing netr_DsRGetDCNameEx2 with no inputs\n");
4525 r
.in
.flags
= DS_RETURN_DNS_NAME
;
4528 status
= dcerpc_netr_DsRGetDCNameEx2_r(b
, tctx
, &r
);
4529 torture_assert_ntstatus_ok(tctx
, status
, "netr_DsRGetDCNameEx2");
4530 torture_assert_werr_ok(tctx
, r
.out
.result
, "netr_DsRGetDCNameEx2");
4532 torture_assert_int_equal(tctx
,
4533 (info
->dc_flags
& (DS_DNS_CONTROLLER
)),
4536 torture_assert_int_equal(tctx
,
4537 (info
->dc_flags
& (DS_DNS_DOMAIN
)),
4540 torture_assert_int_equal(tctx
,
4541 (info
->dc_flags
& (DS_DNS_FOREST_ROOT
)),
4545 r
.in
.server_unc
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
4546 r
.in
.client_account
= NULL
;
4547 r
.in
.mask
= 0x00000000;
4548 r
.in
.domain_name
= lpcfg_dnsdomain(tctx
->lp_ctx
);
4549 r
.in
.domain_guid
= NULL
;
4550 r
.in
.site_name
= NULL
;
4551 r
.in
.flags
= DS_RETURN_DNS_NAME
;
4554 torture_comment(tctx
, "Testing netr_DsRGetDCNameEx2 without client account\n");
4556 status
= dcerpc_netr_DsRGetDCNameEx2_r(b
, tctx
, &r
);
4557 torture_assert_ntstatus_ok(tctx
, status
, "netr_DsRGetDCNameEx2");
4558 torture_assert_werr_ok(tctx
, r
.out
.result
, "netr_DsRGetDCNameEx2");
4560 r
.in
.domain_name
= lpcfg_workgroup(tctx
->lp_ctx
);
4563 status
= dcerpc_netr_DsRGetDCNameEx2_r(b
, tctx
, &r
);
4564 torture_assert_ntstatus_ok(tctx
, status
, "netr_DsRGetDCNameEx2");
4565 torture_assert_werr_ok(tctx
, r
.out
.result
, "netr_DsRGetDCNameEx2");
4567 torture_assert_int_equal(tctx
,
4568 (info
->dc_flags
& (DS_DNS_CONTROLLER
)), 0,
4570 torture_assert_int_equal(tctx
,
4571 (info
->dc_flags
& (DS_DNS_DOMAIN
)), 0,
4573 torture_assert_int_equal(tctx
,
4574 (info
->dc_flags
& (DS_DNS_FOREST_ROOT
)),
4578 if (strcasecmp(info
->dc_site_name
, info
->client_site_name
) == 0) {
4579 torture_assert_int_equal(tctx
,
4580 (info
->dc_flags
& (DS_SERVER_CLOSEST
)),
4585 torture_comment(tctx
, "Testing netr_DsRGetDCNameEx2 with client account\n");
4586 r
.in
.client_account
= TEST_MACHINE_NAME
"$";
4587 r
.in
.mask
= ACB_SVRTRUST
;
4588 r
.in
.flags
= DS_RETURN_FLAT_NAME
;
4591 status
= dcerpc_netr_DsRGetDCNameEx2_r(b
, tctx
, &r
);
4592 torture_assert_ntstatus_ok(tctx
, status
, "netr_DsRGetDCNameEx2");
4593 torture_assert_werr_ok(tctx
, r
.out
.result
, "netr_DsRGetDCNameEx2");
4595 return test_netr_DsRGetSiteName(p
, tctx
, info
->dc_unc
,
4596 info
->dc_site_name
);
4599 /* This is a substitution for "samdb_server_site_name" which relies on the
4600 * correct "lp_ctx" and therefore can't be used here. */
4601 static const char *server_site_name(struct torture_context
*tctx
,
4602 struct ldb_context
*ldb
)
4604 TALLOC_CTX
*tmp_ctx
;
4605 struct ldb_dn
*dn
, *server_dn
;
4606 const struct ldb_val
*site_name_val
;
4607 const char *server_dn_str
, *site_name
;
4609 tmp_ctx
= talloc_new(ldb
);
4610 if (tmp_ctx
== NULL
) {
4614 dn
= ldb_dn_new(tmp_ctx
, ldb
, "");
4619 server_dn_str
= samdb_search_string(ldb
, tmp_ctx
, dn
, "serverName",
4621 if (server_dn_str
== NULL
) {
4625 server_dn
= ldb_dn_new(tmp_ctx
, ldb
, server_dn_str
);
4626 if (server_dn
== NULL
) {
4630 /* CN=<Server name>, CN=Servers, CN=<Site name>, CN=Sites, ... */
4631 site_name_val
= ldb_dn_get_component_val(server_dn
, 2);
4632 if (site_name_val
== NULL
) {
4636 site_name
= (const char *) site_name_val
->data
;
4638 talloc_steal(tctx
, site_name
);
4639 talloc_free(tmp_ctx
);
4644 talloc_free(tmp_ctx
);
4648 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context
*tctx
,
4649 struct dcerpc_pipe
*p
)
4652 struct ldb_context
*sam_ctx
= NULL
;
4654 struct netr_DsrGetDcSiteCoverageW r
;
4655 struct DcSitesCtr
*ctr
= NULL
;
4656 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4658 torture_comment(tctx
, "This does only pass with the default site\n");
4660 /* We won't double-check this when we are over 'local' transports */
4661 if (dcerpc_server_name(p
)) {
4662 /* Set up connection to SAMDB on DC */
4663 url
= talloc_asprintf(tctx
, "ldap://%s", dcerpc_server_name(p
));
4664 sam_ctx
= ldb_wrap_connect(tctx
, tctx
->ev
, tctx
->lp_ctx
, url
,
4666 samba_cmdline_get_creds(),
4669 torture_assert(tctx
, sam_ctx
, "Connection to the SAMDB on DC failed!");
4672 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
4675 status
= dcerpc_netr_DsrGetDcSiteCoverageW_r(b
, tctx
, &r
);
4676 torture_assert_ntstatus_ok(tctx
, status
, "failed");
4677 torture_assert_werr_ok(tctx
, r
.out
.result
, "failed");
4679 torture_assert(tctx
, ctr
->num_sites
== 1,
4680 "we should per default only get the default site");
4681 if (sam_ctx
!= NULL
) {
4682 torture_assert_casestr_equal(tctx
, ctr
->sites
[0].string
,
4683 server_site_name(tctx
, sam_ctx
),
4684 "didn't return default site");
4690 static bool test_netr_DsRAddressToSitenamesW(struct torture_context
*tctx
,
4691 struct dcerpc_pipe
*p
)
4694 struct ldb_context
*sam_ctx
= NULL
;
4696 struct netr_DsRAddressToSitenamesW r
;
4697 struct netr_DsRAddress addrs
[6];
4698 struct sockaddr_in
*addr
;
4700 struct sockaddr_in6
*addr6
;
4702 struct netr_DsRAddressToSitenamesWCtr
*ctr
;
4703 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4707 torture_comment(tctx
, "This does only pass with the default site\n");
4709 /* We won't double-check this when we are over 'local' transports */
4710 if (dcerpc_server_name(p
)) {
4711 /* Set up connection to SAMDB on DC */
4712 url
= talloc_asprintf(tctx
, "ldap://%s", dcerpc_server_name(p
));
4713 sam_ctx
= ldb_wrap_connect(tctx
, tctx
->ev
, tctx
->lp_ctx
, url
,
4715 samba_cmdline_get_creds(),
4718 torture_assert(tctx
, sam_ctx
, "Connection to the SAMDB on DC failed!");
4721 /* First try valid IP addresses */
4723 addrs
[0].size
= sizeof(struct sockaddr_in
);
4724 addrs
[0].buffer
= talloc_zero_array(tctx
, uint8_t, addrs
[0].size
);
4725 addr
= (struct sockaddr_in
*) addrs
[0].buffer
;
4726 addrs
[0].buffer
[0] = AF_INET
;
4727 ret
= inet_pton(AF_INET
, "127.0.0.1", &addr
->sin_addr
);
4728 torture_assert(tctx
, ret
> 0, "inet_pton failed");
4730 addrs
[1].size
= sizeof(struct sockaddr_in
);
4731 addrs
[1].buffer
= talloc_zero_array(tctx
, uint8_t, addrs
[1].size
);
4732 addr
= (struct sockaddr_in
*) addrs
[1].buffer
;
4733 addrs
[1].buffer
[0] = AF_INET
;
4734 ret
= inet_pton(AF_INET
, "0.0.0.0", &addr
->sin_addr
);
4735 torture_assert(tctx
, ret
> 0, "inet_pton failed");
4737 addrs
[2].size
= sizeof(struct sockaddr_in
);
4738 addrs
[2].buffer
= talloc_zero_array(tctx
, uint8_t, addrs
[2].size
);
4739 addr
= (struct sockaddr_in
*) addrs
[2].buffer
;
4740 addrs
[2].buffer
[0] = AF_INET
;
4741 ret
= inet_pton(AF_INET
, "255.255.255.255", &addr
->sin_addr
);
4742 torture_assert(tctx
, ret
> 0, "inet_pton failed");
4745 addrs
[3].size
= sizeof(struct sockaddr_in6
);
4746 addrs
[3].buffer
= talloc_zero_array(tctx
, uint8_t, addrs
[3].size
);
4747 addr6
= (struct sockaddr_in6
*) addrs
[3].buffer
;
4748 addrs
[3].buffer
[0] = AF_INET6
;
4749 ret
= inet_pton(AF_INET6
, "::1", &addr6
->sin6_addr
);
4750 torture_assert(tctx
, ret
> 0, "inet_pton failed");
4752 addrs
[4].size
= sizeof(struct sockaddr_in6
);
4753 addrs
[4].buffer
= talloc_zero_array(tctx
, uint8_t, addrs
[4].size
);
4754 addr6
= (struct sockaddr_in6
*) addrs
[4].buffer
;
4755 addrs
[4].buffer
[0] = AF_INET6
;
4756 ret
= inet_pton(AF_INET6
, "::", &addr6
->sin6_addr
);
4757 torture_assert(tctx
, ret
> 0, "inet_pton failed");
4759 addrs
[5].size
= sizeof(struct sockaddr_in6
);
4760 addrs
[5].buffer
= talloc_zero_array(tctx
, uint8_t, addrs
[5].size
);
4761 addr6
= (struct sockaddr_in6
*) addrs
[5].buffer
;
4762 addrs
[5].buffer
[0] = AF_INET6
;
4763 ret
= inet_pton(AF_INET6
, "ff02::1", &addr6
->sin6_addr
);
4764 torture_assert(tctx
, ret
> 0, "inet_pton failed");
4766 /* the test cases are repeated to have exactly 6. This is for
4767 * compatibility with IPv4-only machines */
4768 addrs
[3].size
= sizeof(struct sockaddr_in
);
4769 addrs
[3].buffer
= talloc_zero_array(tctx
, uint8_t, addrs
[3].size
);
4770 addr
= (struct sockaddr_in
*) addrs
[3].buffer
;
4771 addrs
[3].buffer
[0] = AF_INET
;
4772 ret
= inet_pton(AF_INET
, "127.0.0.1", &addr
->sin_addr
);
4773 torture_assert(tctx
, ret
> 0, "inet_pton failed");
4775 addrs
[4].size
= sizeof(struct sockaddr_in
);
4776 addrs
[4].buffer
= talloc_zero_array(tctx
, uint8_t, addrs
[4].size
);
4777 addr
= (struct sockaddr_in
*) addrs
[4].buffer
;
4778 addrs
[4].buffer
[0] = AF_INET
;
4779 ret
= inet_pton(AF_INET
, "0.0.0.0", &addr
->sin_addr
);
4780 torture_assert(tctx
, ret
> 0, "inet_pton failed");
4782 addrs
[5].size
= sizeof(struct sockaddr_in
);
4783 addrs
[5].buffer
= talloc_zero_array(tctx
, uint8_t, addrs
[5].size
);
4784 addr
= (struct sockaddr_in
*) addrs
[5].buffer
;
4785 addrs
[5].buffer
[0] = AF_INET
;
4786 ret
= inet_pton(AF_INET
, "255.255.255.255", &addr
->sin_addr
);
4787 torture_assert(tctx
, ret
> 0, "inet_pton failed");
4790 ctr
= talloc(tctx
, struct netr_DsRAddressToSitenamesWCtr
);
4792 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
4794 r
.in
.addresses
= addrs
;
4797 status
= dcerpc_netr_DsRAddressToSitenamesW_r(b
, tctx
, &r
);
4798 torture_assert_ntstatus_ok(tctx
, status
, "failed");
4799 torture_assert_werr_ok(tctx
, r
.out
.result
, "failed");
4801 if (sam_ctx
!= NULL
) {
4802 for (i
= 0; i
< 3; i
++) {
4803 torture_assert_casestr_equal(tctx
,
4804 ctr
->sitename
[i
].string
,
4805 server_site_name(tctx
, sam_ctx
),
4806 "didn't return default site");
4808 for (i
= 3; i
< 6; i
++) {
4809 /* Windows returns "NULL" for the sitename if it isn't
4810 * IPv6 configured */
4811 if (torture_setting_bool(tctx
, "samba4", false)) {
4812 torture_assert_casestr_equal(tctx
,
4813 ctr
->sitename
[i
].string
,
4814 server_site_name(tctx
, sam_ctx
),
4815 "didn't return default site");
4820 /* Now try invalid ones (too short buffers) */
4830 status
= dcerpc_netr_DsRAddressToSitenamesW_r(b
, tctx
, &r
);
4831 torture_assert_ntstatus_ok(tctx
, status
, "failed");
4832 torture_assert_werr_ok(tctx
, r
.out
.result
, "failed");
4834 for (i
= 0; i
< 6; i
++) {
4835 torture_assert(tctx
, ctr
->sitename
[i
].string
== NULL
,
4836 "sitename should be null");
4839 /* Now try invalid ones (wrong address types) */
4842 addrs
[0].buffer
[0] = AF_UNSPEC
;
4844 addrs
[1].buffer
[0] = AF_UNIX
; /* AF_LOCAL = AF_UNIX */
4846 addrs
[2].buffer
[0] = AF_UNIX
;
4849 addrs
[3].buffer
[0] = 250;
4851 addrs
[4].buffer
[0] = 251;
4853 addrs
[5].buffer
[0] = 252;
4855 status
= dcerpc_netr_DsRAddressToSitenamesW_r(b
, tctx
, &r
);
4856 torture_assert_ntstatus_ok(tctx
, status
, "failed");
4857 torture_assert_werr_ok(tctx
, r
.out
.result
, "failed");
4859 for (i
= 0; i
< 6; i
++) {
4860 torture_assert(tctx
, ctr
->sitename
[i
].string
== NULL
,
4861 "sitename should be null");
4867 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context
*tctx
,
4868 struct dcerpc_pipe
*p
)
4871 struct ldb_context
*sam_ctx
= NULL
;
4873 struct netr_DsRAddressToSitenamesExW r
;
4874 struct netr_DsRAddress addrs
[6];
4875 struct sockaddr_in
*addr
;
4877 struct sockaddr_in6
*addr6
;
4879 struct netr_DsRAddressToSitenamesExWCtr
*ctr
;
4880 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4884 torture_comment(tctx
, "This does pass with the default site\n");
4886 /* We won't double-check this when we are over 'local' transports */
4887 if (dcerpc_server_name(p
)) {
4888 /* Set up connection to SAMDB on DC */
4889 url
= talloc_asprintf(tctx
, "ldap://%s", dcerpc_server_name(p
));
4890 sam_ctx
= ldb_wrap_connect(tctx
, tctx
->ev
, tctx
->lp_ctx
, url
,
4892 samba_cmdline_get_creds(),
4895 torture_assert(tctx
, sam_ctx
, "Connection to the SAMDB on DC failed!");
4898 /* First try valid IP addresses */
4900 addrs
[0].size
= sizeof(struct sockaddr_in
);
4901 addrs
[0].buffer
= talloc_zero_array(tctx
, uint8_t, addrs
[0].size
);
4902 addr
= (struct sockaddr_in
*) addrs
[0].buffer
;
4903 addrs
[0].buffer
[0] = AF_INET
;
4904 ret
= inet_pton(AF_INET
, "127.0.0.1", &addr
->sin_addr
);
4905 torture_assert(tctx
, ret
> 0, "inet_pton failed");
4907 addrs
[1].size
= sizeof(struct sockaddr_in
);
4908 addrs
[1].buffer
= talloc_zero_array(tctx
, uint8_t, addrs
[1].size
);
4909 addr
= (struct sockaddr_in
*) addrs
[1].buffer
;
4910 addrs
[1].buffer
[0] = AF_INET
;
4911 ret
= inet_pton(AF_INET
, "0.0.0.0", &addr
->sin_addr
);
4912 torture_assert(tctx
, ret
> 0, "inet_pton failed");
4914 addrs
[2].size
= sizeof(struct sockaddr_in
);
4915 addrs
[2].buffer
= talloc_zero_array(tctx
, uint8_t, addrs
[2].size
);
4916 addr
= (struct sockaddr_in
*) addrs
[2].buffer
;
4917 addrs
[2].buffer
[0] = AF_INET
;
4918 ret
= inet_pton(AF_INET
, "255.255.255.255", &addr
->sin_addr
);
4919 torture_assert(tctx
, ret
> 0, "inet_pton failed");
4922 addrs
[3].size
= sizeof(struct sockaddr_in6
);
4923 addrs
[3].buffer
= talloc_zero_array(tctx
, uint8_t, addrs
[3].size
);
4924 addr6
= (struct sockaddr_in6
*) addrs
[3].buffer
;
4925 addrs
[3].buffer
[0] = AF_INET6
;
4926 ret
= inet_pton(AF_INET6
, "::1", &addr6
->sin6_addr
);
4927 torture_assert(tctx
, ret
> 0, "inet_pton failed");
4929 addrs
[4].size
= sizeof(struct sockaddr_in6
);
4930 addrs
[4].buffer
= talloc_zero_array(tctx
, uint8_t, addrs
[4].size
);
4931 addr6
= (struct sockaddr_in6
*) addrs
[4].buffer
;
4932 addrs
[4].buffer
[0] = AF_INET6
;
4933 ret
= inet_pton(AF_INET6
, "::", &addr6
->sin6_addr
);
4934 torture_assert(tctx
, ret
> 0, "inet_pton failed");
4936 addrs
[5].size
= sizeof(struct sockaddr_in6
);
4937 addrs
[5].buffer
= talloc_zero_array(tctx
, uint8_t, addrs
[5].size
);
4938 addr6
= (struct sockaddr_in6
*) addrs
[5].buffer
;
4939 addrs
[5].buffer
[0] = AF_INET6
;
4940 ret
= inet_pton(AF_INET6
, "ff02::1", &addr6
->sin6_addr
);
4941 torture_assert(tctx
, ret
> 0, "inet_pton failed");
4943 /* the test cases are repeated to have exactly 6. This is for
4944 * compatibility with IPv4-only machines */
4945 addrs
[3].size
= sizeof(struct sockaddr_in
);
4946 addrs
[3].buffer
= talloc_zero_array(tctx
, uint8_t, addrs
[3].size
);
4947 addr
= (struct sockaddr_in
*) addrs
[3].buffer
;
4948 addrs
[3].buffer
[0] = AF_INET
;
4949 ret
= inet_pton(AF_INET
, "127.0.0.1", &addr
->sin_addr
);
4950 torture_assert(tctx
, ret
> 0, "inet_pton failed");
4952 addrs
[4].size
= sizeof(struct sockaddr_in
);
4953 addrs
[4].buffer
= talloc_zero_array(tctx
, uint8_t, addrs
[4].size
);
4954 addr
= (struct sockaddr_in
*) addrs
[4].buffer
;
4955 addrs
[4].buffer
[0] = AF_INET
;
4956 ret
= inet_pton(AF_INET
, "0.0.0.0", &addr
->sin_addr
);
4957 torture_assert(tctx
, ret
> 0, "inet_pton failed");
4959 addrs
[5].size
= sizeof(struct sockaddr_in
);
4960 addrs
[5].buffer
= talloc_zero_array(tctx
, uint8_t, addrs
[5].size
);
4961 addr
= (struct sockaddr_in
*) addrs
[5].buffer
;
4962 addrs
[5].buffer
[0] = AF_INET
;
4963 ret
= inet_pton(AF_INET
, "255.255.255.255", &addr
->sin_addr
);
4964 torture_assert(tctx
, ret
> 0, "inet_pton failed");
4967 ctr
= talloc(tctx
, struct netr_DsRAddressToSitenamesExWCtr
);
4969 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
4971 r
.in
.addresses
= addrs
;
4974 status
= dcerpc_netr_DsRAddressToSitenamesExW_r(b
, tctx
, &r
);
4975 torture_assert_ntstatus_ok(tctx
, status
, "failed");
4976 torture_assert_werr_ok(tctx
, r
.out
.result
, "failed");
4978 if (sam_ctx
!= NULL
) {
4979 for (i
= 0; i
< 3; i
++) {
4980 torture_assert_casestr_equal(tctx
,
4981 ctr
->sitename
[i
].string
,
4982 server_site_name(tctx
, sam_ctx
),
4983 "didn't return default site");
4984 torture_assert(tctx
, ctr
->subnetname
[i
].string
== NULL
,
4985 "subnet should be null");
4987 for (i
= 3; i
< 6; i
++) {
4988 /* Windows returns "NULL" for the sitename if it isn't
4989 * IPv6 configured */
4990 if (torture_setting_bool(tctx
, "samba4", false)) {
4991 torture_assert_casestr_equal(tctx
,
4992 ctr
->sitename
[i
].string
,
4993 server_site_name(tctx
, sam_ctx
),
4994 "didn't return default site");
4996 torture_assert(tctx
, ctr
->subnetname
[i
].string
== NULL
,
4997 "subnet should be null");
5001 /* Now try invalid ones (too short buffers) */
5011 status
= dcerpc_netr_DsRAddressToSitenamesExW_r(b
, tctx
, &r
);
5012 torture_assert_ntstatus_ok(tctx
, status
, "failed");
5013 torture_assert_werr_ok(tctx
, r
.out
.result
, "failed");
5015 for (i
= 0; i
< 6; i
++) {
5016 torture_assert(tctx
, ctr
->sitename
[i
].string
== NULL
,
5017 "sitename should be null");
5018 torture_assert(tctx
, ctr
->subnetname
[i
].string
== NULL
,
5019 "subnet should be null");
5023 addrs
[0].buffer
[0] = AF_UNSPEC
;
5025 addrs
[1].buffer
[0] = AF_UNIX
; /* AF_LOCAL = AF_UNIX */
5027 addrs
[2].buffer
[0] = AF_UNIX
;
5030 addrs
[3].buffer
[0] = 250;
5032 addrs
[4].buffer
[0] = 251;
5034 addrs
[5].buffer
[0] = 252;
5036 status
= dcerpc_netr_DsRAddressToSitenamesExW_r(b
, tctx
, &r
);
5037 torture_assert_ntstatus_ok(tctx
, status
, "failed");
5038 torture_assert_werr_ok(tctx
, r
.out
.result
, "failed");
5040 for (i
= 0; i
< 6; i
++) {
5041 torture_assert(tctx
, ctr
->sitename
[i
].string
== NULL
,
5042 "sitename should be null");
5043 torture_assert(tctx
, ctr
->subnetname
[i
].string
== NULL
,
5044 "subnet should be null");
5050 static bool test_netr_ServerGetTrustInfo_flags(struct torture_context
*tctx
,
5051 struct dcerpc_pipe
*p1
,
5052 struct cli_credentials
*machine_credentials
,
5053 uint32_t negotiate_flags
)
5055 struct netr_ServerGetTrustInfo r
;
5057 struct netr_Authenticator a
;
5058 struct netr_Authenticator return_authenticator
;
5059 struct samr_Password new_owf_password
;
5060 struct samr_Password old_owf_password
;
5061 struct netr_TrustInfo
*trust_info
;
5063 struct netlogon_creds_CredentialState
*creds
;
5064 struct dcerpc_pipe
*p
= NULL
;
5065 struct dcerpc_binding_handle
*b
= NULL
;
5067 struct samr_Password nt_hash
;
5068 enum dcerpc_AuthType auth_type
= DCERPC_AUTH_TYPE_NONE
;
5069 enum dcerpc_AuthLevel auth_level
= DCERPC_AUTH_LEVEL_NONE
;
5072 if (!test_SetupCredentials3(p1
, tctx
, negotiate_flags
,
5073 machine_credentials
, &creds
)) {
5076 if (!test_SetupCredentialsPipe(p1
, tctx
, machine_credentials
, creds
,
5077 DCERPC_SIGN
| DCERPC_SEAL
, &p
)) {
5080 b
= p
->binding_handle
;
5082 netlogon_creds_client_authenticator(creds
, &a
);
5084 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
5085 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", TEST_MACHINE_NAME
);
5086 r
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
5087 r
.in
.computer_name
= TEST_MACHINE_NAME
;
5088 r
.in
.credential
= &a
;
5090 r
.out
.return_authenticator
= &return_authenticator
;
5091 r
.out
.new_owf_password
= &new_owf_password
;
5092 r
.out
.old_owf_password
= &old_owf_password
;
5093 r
.out
.trust_info
= &trust_info
;
5095 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerGetTrustInfo_r(b
, tctx
, &r
),
5096 "ServerGetTrustInfo failed");
5097 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerGetTrustInfo failed");
5098 torture_assert(tctx
, netlogon_creds_client_check(creds
, &return_authenticator
.cred
), "Credential chaining failed");
5100 E_md4hash(cli_credentials_get_password(machine_credentials
), nt_hash
.hash
);
5102 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
5103 status
= netlogon_creds_decrypt_samr_Password(creds
,
5107 torture_assert_ntstatus_ok(tctx
, status
, "decrypt_samr_Password");
5108 status
= netlogon_creds_decrypt_samr_Password(creds
,
5112 torture_assert_ntstatus_ok(tctx
, status
, "decrypt_samr_Password");
5114 dump_data(1, new_owf_password
.hash
, 16);
5115 dump_data(1, nt_hash
.hash
, 16);
5117 torture_assert_mem_equal(tctx
, new_owf_password
.hash
, nt_hash
.hash
, 16,
5118 "received unexpected owf password\n");
5123 static bool test_netr_ServerGetTrustInfo(struct torture_context
*tctx
,
5124 struct dcerpc_pipe
*p
,
5125 struct cli_credentials
*machine_credentials
)
5127 return test_netr_ServerGetTrustInfo_flags(tctx
, p
, machine_credentials
,
5128 NETLOGON_NEG_AUTH2_ADS_FLAGS
);
5131 static bool test_netr_ServerGetTrustInfo_AES(struct torture_context
*tctx
,
5132 struct dcerpc_pipe
*p
,
5133 struct cli_credentials
*machine_credentials
)
5135 return test_netr_ServerGetTrustInfo_flags(tctx
, p
, machine_credentials
,
5136 NETLOGON_NEG_AUTH2_ADS_FLAGS
| NETLOGON_NEG_SUPPORTS_AES
);
5139 static bool test_GetDomainInfo(struct torture_context
*tctx
,
5140 struct dcerpc_pipe
*p1
,
5141 struct cli_credentials
*machine_credentials
)
5143 struct netr_LogonGetDomainInfo r
;
5144 struct netr_WorkstationInformation q1
;
5145 struct netr_Authenticator a
;
5146 struct netlogon_creds_CredentialState
*creds
;
5147 struct netr_OsVersion os
;
5148 union netr_WorkstationInfo query
;
5149 union netr_DomainInfo info
;
5150 const char* const attrs
[] = { "dNSHostName", "operatingSystem",
5151 "operatingSystemServicePack", "operatingSystemVersion",
5152 "servicePrincipalName", NULL
};
5154 struct ldb_context
*sam_ctx
= NULL
;
5155 struct ldb_message
**res
;
5156 struct ldb_message_element
*spn_el
;
5159 const char *old_dnsname
= NULL
;
5162 char *temp_str
= NULL
;
5163 char *temp_str2
= NULL
;
5164 struct dcerpc_pipe
*p
= NULL
;
5165 struct dcerpc_binding_handle
*b
= NULL
;
5166 struct netr_OneDomainInfo
*odi1
= NULL
;
5167 struct netr_OneDomainInfo
*odi2
= NULL
;
5168 struct netr_trust_extension_info
*tex2
= NULL
;
5170 torture_comment(tctx
, "Testing netr_LogonGetDomainInfo\n");
5172 if (!test_SetupCredentials3(p1
, tctx
, NETLOGON_NEG_AUTH2_ADS_FLAGS
| NETLOGON_NEG_SUPPORTS_AES
,
5173 machine_credentials
, &creds
)) {
5176 if (!test_SetupCredentialsPipe(p1
, tctx
, machine_credentials
, creds
,
5177 DCERPC_SIGN
| DCERPC_SEAL
, &p
)) {
5180 b
= p
->binding_handle
;
5182 /* We won't double-check this when we are over 'local' transports */
5183 if (dcerpc_server_name(p
)) {
5184 /* Set up connection to SAMDB on DC */
5185 url
= talloc_asprintf(tctx
, "ldap://%s", dcerpc_server_name(p
));
5186 sam_ctx
= ldb_wrap_connect(tctx
, tctx
->ev
, tctx
->lp_ctx
, url
,
5188 samba_cmdline_get_creds(),
5191 torture_assert(tctx
, sam_ctx
, "Connection to the SAMDB on DC failed!");
5194 torture_comment(tctx
, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
5195 netlogon_creds_client_authenticator(creds
, &a
);
5198 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
5199 r
.in
.computer_name
= TEST_MACHINE_NAME
;
5200 r
.in
.credential
= &a
;
5202 r
.in
.return_authenticator
= &a
;
5203 r
.in
.query
= &query
;
5204 r
.out
.return_authenticator
= &a
;
5208 os
.os
.MajorVersion
= 123;
5209 os
.os
.MinorVersion
= 456;
5210 os
.os
.BuildNumber
= 789;
5211 os
.os
.CSDVersion
= "Service Pack 10";
5212 os
.os
.ServicePackMajor
= 10;
5213 os
.os
.ServicePackMinor
= 1;
5214 os
.os
.SuiteMask
= NETR_VER_SUITE_SINGLEUSERTS
;
5215 os
.os
.ProductType
= NETR_VER_NT_SERVER
;
5218 version_str
= talloc_asprintf(tctx
, "%d.%d (%d)", os
.os
.MajorVersion
,
5219 os
.os
.MinorVersion
, os
.os
.BuildNumber
);
5222 q1
.dns_hostname
= talloc_asprintf(tctx
, "%s.%s", TEST_MACHINE_NAME
,
5223 lpcfg_dnsdomain(tctx
->lp_ctx
));
5224 q1
.sitename
= "Default-First-Site-Name";
5225 q1
.os_version
.os
= &os
;
5226 q1
.os_name
.string
= talloc_asprintf(tctx
,
5227 "Tortured by Samba4 RPC-NETLOGON: %s",
5228 timestring(tctx
, time(NULL
)));
5230 /* The workstation handles the "servicePrincipalName" and DNS hostname
5232 q1
.workstation_flags
= NETR_WS_FLAG_HANDLES_SPN_UPDATE
;
5234 query
.workstation_info
= &q1
;
5237 /* Gets back the old DNS hostname in AD */
5238 ret
= gendb_search(sam_ctx
, tctx
, NULL
, &res
, attrs
,
5239 "(sAMAccountName=%s$)", TEST_MACHINE_NAME
);
5241 ldb_msg_find_attr_as_string(res
[0], "dNSHostName", NULL
);
5243 /* Gets back the "servicePrincipalName"s in AD */
5244 spn_el
= ldb_msg_find_element(res
[0], "servicePrincipalName");
5245 if (spn_el
!= NULL
) {
5246 for (i
=0; i
< spn_el
->num_values
; i
++) {
5247 spns
= talloc_realloc(tctx
, spns
, char *, i
+ 1);
5248 spns
[i
] = (char *) spn_el
->values
[i
].data
;
5254 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonGetDomainInfo_r(b
, tctx
, &r
),
5255 "LogonGetDomainInfo failed");
5256 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LogonGetDomainInfo failed");
5257 torture_assert(tctx
, netlogon_creds_client_check(creds
, &a
.cred
), "Credential chaining failed");
5262 /* AD workstation infos entry check */
5263 ret
= gendb_search(sam_ctx
, tctx
, NULL
, &res
, attrs
,
5264 "(sAMAccountName=%s$)", TEST_MACHINE_NAME
);
5265 torture_assert(tctx
, ret
== 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
5266 torture_assert_str_equal(tctx
,
5267 ldb_msg_find_attr_as_string(res
[0], "operatingSystem", NULL
),
5268 q1
.os_name
.string
, "'operatingSystem' wrong!");
5269 torture_assert_str_equal(tctx
,
5270 ldb_msg_find_attr_as_string(res
[0], "operatingSystemServicePack", NULL
),
5271 os
.os
.CSDVersion
, "'operatingSystemServicePack' wrong!");
5272 torture_assert_str_equal(tctx
,
5273 ldb_msg_find_attr_as_string(res
[0], "operatingSystemVersion", NULL
),
5274 version_str
, "'operatingSystemVersion' wrong!");
5276 if (old_dnsname
!= NULL
) {
5277 /* If before a DNS hostname was set then it should remain
5278 the same in combination with the "servicePrincipalName"s.
5279 The DNS hostname should also be returned by our
5280 "LogonGetDomainInfo" call (in the domain info structure). */
5282 torture_assert_str_equal(tctx
,
5283 ldb_msg_find_attr_as_string(res
[0], "dNSHostName", NULL
),
5284 old_dnsname
, "'DNS hostname' was not set!");
5286 spn_el
= ldb_msg_find_element(res
[0], "servicePrincipalName");
5287 torture_assert(tctx
, ((spns
!= NULL
) && (spn_el
!= NULL
)),
5288 "'servicePrincipalName's not set!");
5289 torture_assert(tctx
, spn_el
->num_values
== num_spns
,
5290 "'servicePrincipalName's incorrect!");
5291 for (i
=0; (i
< spn_el
->num_values
) && (i
< num_spns
); i
++)
5292 torture_assert_str_equal(tctx
,
5293 (char *) spn_el
->values
[i
].data
,
5294 spns
[i
], "'servicePrincipalName's incorrect!");
5296 torture_assert_str_equal(tctx
,
5297 info
.domain_info
->dns_hostname
.string
,
5299 "Out 'DNS hostname' doesn't match the old one!");
5301 /* If no DNS hostname was set then also now none should be set,
5302 the "servicePrincipalName"s should remain empty and no DNS
5303 hostname should be returned by our "LogonGetDomainInfo"
5304 call (in the domain info structure). */
5306 torture_assert(tctx
,
5307 ldb_msg_find_attr_as_string(res
[0], "dNSHostName", NULL
) == NULL
,
5308 "'DNS hostname' was set!");
5310 spn_el
= ldb_msg_find_element(res
[0], "servicePrincipalName");
5311 torture_assert(tctx
, ((spns
== NULL
) && (spn_el
== NULL
)),
5312 "'servicePrincipalName's were set!");
5314 torture_assert(tctx
,
5315 info
.domain_info
->dns_hostname
.string
== NULL
,
5316 "Out 'DNS host name' was set!");
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!");
5327 torture_comment(tctx
, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname doesn't work)\n");
5328 netlogon_creds_client_authenticator(creds
, &a
);
5330 /* Wipe out the CSDVersion, and prove which values still 'stick' */
5331 os
.os
.CSDVersion
= "";
5333 /* Change also the DNS hostname to test differences in behaviour */
5334 talloc_free(discard_const_p(char, q1
.dns_hostname
));
5335 q1
.dns_hostname
= talloc_asprintf(tctx
, "%s2.%s", TEST_MACHINE_NAME
,
5336 lpcfg_dnsdomain(tctx
->lp_ctx
));
5338 /* The workstation handles the "servicePrincipalName" and DNS hostname
5340 q1
.workstation_flags
= NETR_WS_FLAG_HANDLES_SPN_UPDATE
;
5342 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonGetDomainInfo_r(b
, tctx
, &r
),
5343 "LogonGetDomainInfo failed");
5344 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LogonGetDomainInfo failed");
5346 torture_assert(tctx
, netlogon_creds_client_check(creds
, &a
.cred
), "Credential chaining failed");
5351 /* AD workstation infos entry check */
5352 ret
= gendb_search(sam_ctx
, tctx
, NULL
, &res
, attrs
,
5353 "(sAMAccountName=%s$)", TEST_MACHINE_NAME
);
5354 torture_assert(tctx
, ret
== 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
5356 torture_assert_str_equal(tctx
,
5357 ldb_msg_find_attr_as_string(res
[0], "operatingSystem", NULL
),
5358 q1
.os_name
.string
, "'operatingSystem' should stick!");
5359 torture_assert(tctx
,
5360 ldb_msg_find_attr_as_string(res
[0], "operatingSystemServicePack", NULL
) == NULL
,
5361 "'operatingSystemServicePack' shouldn't stick!");
5362 torture_assert_str_equal(tctx
,
5363 ldb_msg_find_attr_as_string(res
[0], "operatingSystemVersion", NULL
),
5364 version_str
, "'operatingSystemVersion' wrong!");
5366 /* The DNS host name shouldn't have been updated by the server */
5368 torture_assert_str_equal(tctx
,
5369 ldb_msg_find_attr_as_string(res
[0], "dNSHostName", NULL
),
5370 old_dnsname
, "'DNS host name' did change!");
5372 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
5373 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
5375 spn_el
= ldb_msg_find_element(res
[0], "servicePrincipalName");
5376 torture_assert(tctx
, spn_el
!= NULL
,
5377 "There should exist 'servicePrincipalName's in AD!");
5378 temp_str
= talloc_asprintf(tctx
, "HOST/%s", TEST_MACHINE_NAME
);
5379 for (i
=0; i
< spn_el
->num_values
; i
++)
5380 if (strcasecmp((char *) spn_el
->values
[i
].data
, temp_str
) == 0)
5382 torture_assert(tctx
, i
!= spn_el
->num_values
,
5383 "'servicePrincipalName' HOST/<Netbios name> not found!");
5384 temp_str
= talloc_asprintf(tctx
, "HOST/%s", old_dnsname
);
5385 for (i
=0; i
< spn_el
->num_values
; i
++)
5386 if (strcasecmp((char *) spn_el
->values
[i
].data
, temp_str
) == 0)
5388 torture_assert(tctx
, i
!= spn_el
->num_values
,
5389 "'servicePrincipalName' HOST/<FQDN name> not found!");
5391 /* Check that the out DNS hostname was set properly */
5392 torture_assert_str_equal(tctx
, info
.domain_info
->dns_hostname
.string
,
5393 old_dnsname
, "Out 'DNS hostname' doesn't match the old one!");
5396 /* Checks "workstation flags" */
5397 torture_assert(tctx
,
5398 info
.domain_info
->workstation_flags
== NETR_WS_FLAG_HANDLES_SPN_UPDATE
,
5399 "Out 'workstation flags' don't match!");
5402 /* Now try the same but the workstation flags set to 0 */
5404 torture_comment(tctx
, "Testing netr_LogonGetDomainInfo 3rd call (variation of DNS hostname doesn't work)\n");
5405 netlogon_creds_client_authenticator(creds
, &a
);
5407 /* Change also the DNS hostname to test differences in behaviour */
5408 talloc_free(discard_const_p(char, q1
.dns_hostname
));
5409 q1
.dns_hostname
= talloc_asprintf(tctx
, "%s2.%s", TEST_MACHINE_NAME
,
5410 lpcfg_dnsdomain(tctx
->lp_ctx
));
5412 /* Wipe out the osVersion, and prove which values still 'stick' */
5413 q1
.os_version
.os
= NULL
;
5415 /* Let the DC handle the "servicePrincipalName" and DNS hostname
5417 q1
.workstation_flags
= 0;
5419 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonGetDomainInfo_r(b
, tctx
, &r
),
5420 "LogonGetDomainInfo failed");
5421 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LogonGetDomainInfo failed");
5422 torture_assert(tctx
, netlogon_creds_client_check(creds
, &a
.cred
), "Credential chaining failed");
5427 /* AD workstation infos entry check */
5428 ret
= gendb_search(sam_ctx
, tctx
, NULL
, &res
, attrs
,
5429 "(sAMAccountName=%s$)", TEST_MACHINE_NAME
);
5430 torture_assert(tctx
, ret
== 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
5432 torture_assert_str_equal(tctx
,
5433 ldb_msg_find_attr_as_string(res
[0], "operatingSystem", NULL
),
5434 q1
.os_name
.string
, "'operatingSystem' should stick!");
5435 torture_assert(tctx
,
5436 ldb_msg_find_attr_as_string(res
[0], "operatingSystemServicePack", NULL
) == NULL
,
5437 "'operatingSystemServicePack' shouldn't stick!");
5438 torture_assert_str_equal(tctx
,
5439 ldb_msg_find_attr_as_string(res
[0], "operatingSystemVersion", NULL
),
5440 version_str
, "'operatingSystemVersion' wrong!");
5442 /* The DNS host name shouldn't have been updated by the server */
5444 torture_assert_str_equal(tctx
,
5445 ldb_msg_find_attr_as_string(res
[0], "dNSHostName", NULL
),
5446 old_dnsname
, "'DNS host name' did change!");
5448 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
5449 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
5451 spn_el
= ldb_msg_find_element(res
[0], "servicePrincipalName");
5452 torture_assert(tctx
, spn_el
!= NULL
,
5453 "There should exist 'servicePrincipalName's in AD!");
5454 temp_str
= talloc_asprintf(tctx
, "HOST/%s", TEST_MACHINE_NAME
);
5455 for (i
=0; i
< spn_el
->num_values
; i
++)
5456 if (strcasecmp((char *) spn_el
->values
[i
].data
, temp_str
) == 0)
5458 torture_assert(tctx
, i
!= spn_el
->num_values
,
5459 "'servicePrincipalName' HOST/<Netbios name> not found!");
5460 temp_str
= talloc_asprintf(tctx
, "HOST/%s", old_dnsname
);
5461 for (i
=0; i
< spn_el
->num_values
; i
++)
5462 if (strcasecmp((char *) spn_el
->values
[i
].data
, temp_str
) == 0)
5464 torture_assert(tctx
, i
!= spn_el
->num_values
,
5465 "'servicePrincipalName' HOST/<FQDN name> not found!");
5467 /* Here the server gives us NULL as the out DNS hostname */
5468 torture_assert(tctx
, info
.domain_info
->dns_hostname
.string
== NULL
,
5469 "Out 'DNS hostname' should be NULL!");
5472 /* Checks "workstation flags" */
5473 torture_assert(tctx
,
5474 info
.domain_info
->workstation_flags
== 0,
5475 "Out 'workstation flags' don't match!");
5478 torture_comment(tctx
, "Testing netr_LogonGetDomainInfo 4th call (verification of DNS hostname and check for trusted domains)\n");
5479 netlogon_creds_client_authenticator(creds
, &a
);
5481 /* Put the DNS hostname back */
5482 talloc_free(discard_const_p(char, q1
.dns_hostname
));
5483 q1
.dns_hostname
= talloc_asprintf(tctx
, "%s.%s", TEST_MACHINE_NAME
,
5484 lpcfg_dnsdomain(tctx
->lp_ctx
));
5486 /* The workstation handles the "servicePrincipalName" and DNS hostname
5488 q1
.workstation_flags
= NETR_WS_FLAG_HANDLES_SPN_UPDATE
;
5490 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonGetDomainInfo_r(b
, tctx
, &r
),
5491 "LogonGetDomainInfo failed");
5492 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LogonGetDomainInfo failed");
5493 torture_assert(tctx
, netlogon_creds_client_check(creds
, &a
.cred
), "Credential chaining failed");
5497 /* Now the in/out DNS hostnames should be the same */
5498 torture_assert_str_equal(tctx
,
5499 info
.domain_info
->dns_hostname
.string
,
5500 query
.workstation_info
->dns_hostname
,
5501 "In/Out 'DNS hostnames' don't match!");
5502 old_dnsname
= info
.domain_info
->dns_hostname
.string
;
5504 /* Checks "workstation flags" */
5505 torture_assert(tctx
,
5506 info
.domain_info
->workstation_flags
5507 == NETR_WS_FLAG_HANDLES_SPN_UPDATE
,
5508 "Out 'workstation flags' don't match!");
5510 /* Checks for trusted domains */
5511 torture_assert(tctx
,
5512 (info
.domain_info
->trusted_domain_count
!= 0)
5513 && (info
.domain_info
->trusted_domains
!= NULL
),
5514 "Trusted domains have been requested!");
5517 torture_comment(tctx
, "Testing netr_LogonGetDomainInfo 5th call (check for trusted domains)\n");
5518 netlogon_creds_client_authenticator(creds
, &a
);
5520 /* The workstation handles the "servicePrincipalName" and DNS hostname
5521 updates and requests inbound trusts */
5522 q1
.workstation_flags
= NETR_WS_FLAG_HANDLES_SPN_UPDATE
5523 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS
;
5525 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonGetDomainInfo_r(b
, tctx
, &r
),
5526 "LogonGetDomainInfo failed");
5527 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LogonGetDomainInfo failed");
5528 torture_assert(tctx
, netlogon_creds_client_check(creds
, &a
.cred
), "Credential chaining failed");
5532 /* Checks "workstation flags" */
5533 torture_assert(tctx
,
5534 info
.domain_info
->workstation_flags
5535 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
5536 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS
),
5537 "Out 'workstation flags' don't match!");
5539 /* Checks for trusted domains */
5540 torture_assert(tctx
,
5541 (info
.domain_info
->trusted_domain_count
!= 0)
5542 && (info
.domain_info
->trusted_domains
!= NULL
),
5543 "Trusted domains have been requested!");
5545 odi1
= &info
.domain_info
->primary_domain
;
5547 torture_assert(tctx
, !GUID_all_zero(&odi1
->domain_guid
),
5548 "primary domain_guid needs to be valid");
5550 for (i
=0; i
< info
.domain_info
->trusted_domain_count
; i
++) {
5551 struct netr_OneDomainInfo
*odiT
=
5552 &info
.domain_info
->trusted_domains
[i
];
5553 struct netr_trust_extension_info
*texT
= NULL
;
5555 torture_assert_int_equal(tctx
, odiT
->trust_extension
.length
, 16,
5556 "trust_list should have extension");
5557 torture_assert(tctx
, odiT
->trust_extension
.info
!= NULL
,
5558 "trust_list should have extension");
5559 texT
= &odiT
->trust_extension
.info
->info
;
5561 if (GUID_equal(&odiT
->domain_guid
, &odi1
->domain_guid
)) {
5567 torture_assert_int_equal(tctx
,
5568 texT
->flags
& NETR_TRUST_FLAG_PRIMARY
,
5570 "trust_list flags should not have PRIMARY");
5572 torture_assert(tctx
, odiT
->domainname
.string
!= NULL
,
5573 "trust_list domainname should be valid");
5574 if (texT
->trust_type
== LSA_TRUST_TYPE_DOWNLEVEL
||
5575 texT
->trust_type
== LSA_TRUST_TYPE_MIT
)
5577 torture_assert(tctx
, odiT
->dns_domainname
.string
== NULL
,
5578 "trust_list dns_domainname should be NULL for downlevel or MIT");
5580 torture_assert(tctx
, odiT
->dns_domainname
.string
!= NULL
,
5581 "trust_list dns_domainname should be valid for uplevel");
5583 torture_assert(tctx
, odiT
->dns_forestname
.string
== NULL
,
5584 "trust_list dns_forestname needs to be NULL");
5586 torture_assert(tctx
, odiT
->domain_sid
!= NULL
,
5587 "trust_list domain_sid needs to be valid");
5590 torture_assert(tctx
, odi2
!= NULL
,
5591 "trust_list primary domain not found.");
5593 torture_assert_str_equal(tctx
,
5594 odi1
->domainname
.string
,
5595 odi2
->domainname
.string
,
5596 "netbios name should match");
5598 temp_str
= talloc_strdup(tctx
, odi1
->dns_domainname
.string
);
5599 torture_assert(tctx
, temp_str
!= NULL
,
5600 "primary_domain dns_domainname copy");
5601 temp_str2
= strrchr(temp_str
, '.');
5602 torture_assert(tctx
, temp_str2
!= NULL
&& temp_str2
[1] == '\0',
5603 "primary_domain dns_domainname needs trailing '.'");
5604 temp_str2
[0] = '\0';
5605 torture_assert_str_equal(tctx
,
5607 odi2
->dns_domainname
.string
,
5608 "dns domainname should match "
5609 "(without trailing '.')");
5611 temp_str
= talloc_strdup(tctx
, odi1
->dns_forestname
.string
);
5612 torture_assert(tctx
, temp_str
!= NULL
,
5613 "primary_domain dns_forestname copy");
5614 temp_str2
= strrchr(temp_str
, '.');
5615 torture_assert(tctx
, temp_str2
!= NULL
&& temp_str2
[1] == '\0',
5616 "primary_domain dns_forestname needs trailing '.'");
5617 temp_str2
[0] = '\0';
5618 torture_assert(tctx
, odi2
->dns_forestname
.string
== NULL
,
5619 "trust_list dns_forestname needs to be NULL");
5621 torture_assert_guid_equal(tctx
, odi1
->domain_guid
, odi2
->domain_guid
,
5622 "domain_guid should match");
5623 torture_assert(tctx
, odi1
->domain_sid
!= NULL
,
5624 "primary domain_sid needs to be valid");
5625 torture_assert(tctx
, odi2
->domain_sid
!= NULL
,
5626 "trust_list domain_sid needs to be valid");
5627 torture_assert_sid_equal(tctx
, odi1
->domain_sid
, odi2
->domain_sid
,
5628 "domain_sid should match");
5630 torture_assert_int_equal(tctx
, odi1
->trust_extension
.length
, 0,
5631 "primary_domain should not have extension");
5632 torture_assert_int_equal(tctx
, odi2
->trust_extension
.length
, 16,
5633 "trust_list should have extension");
5634 torture_assert(tctx
, odi2
->trust_extension
.info
!= NULL
,
5635 "trust_list should have extension");
5636 tex2
= &odi2
->trust_extension
.info
->info
;
5637 torture_assert_int_equal(tctx
,
5638 tex2
->flags
& NETR_TRUST_FLAG_PRIMARY
,
5639 NETR_TRUST_FLAG_PRIMARY
,
5640 "trust_list flags should have PRIMARY");
5641 torture_assert_int_equal(tctx
,
5642 tex2
->flags
& NETR_TRUST_FLAG_IN_FOREST
,
5643 NETR_TRUST_FLAG_IN_FOREST
,
5644 "trust_list flags should have IN_FOREST");
5645 torture_assert_int_equal(tctx
,
5646 tex2
->flags
& NETR_TRUST_FLAG_NATIVE
,
5647 NETR_TRUST_FLAG_NATIVE
,
5648 "trust_list flags should have NATIVE");
5649 torture_assert_int_equal(tctx
,
5650 tex2
->flags
& ~NETR_TRUST_FLAG_TREEROOT
,
5651 NETR_TRUST_FLAG_IN_FOREST
|
5652 NETR_TRUST_FLAG_PRIMARY
|
5653 NETR_TRUST_FLAG_NATIVE
,
5654 "trust_list flags IN_FOREST, PRIMARY, NATIVE "
5655 "(TREEROOT optional)");
5656 if (strcmp(odi1
->dns_domainname
.string
, odi1
->dns_forestname
.string
) == 0) {
5657 torture_assert_int_equal(tctx
,
5658 tex2
->flags
& NETR_TRUST_FLAG_TREEROOT
,
5659 NETR_TRUST_FLAG_TREEROOT
,
5660 "trust_list flags TREEROOT on forest root");
5661 torture_assert_int_equal(tctx
,
5662 tex2
->parent_index
, 0,
5663 "trust_list no parent on forest root");
5665 torture_assert_int_equal(tctx
,
5666 tex2
->trust_type
, LSA_TRUST_TYPE_UPLEVEL
,
5667 "trust_list uplevel");
5668 torture_assert_int_equal(tctx
,
5669 tex2
->trust_attributes
, 0,
5670 "trust_list no attributes");
5672 torture_comment(tctx
, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
5673 netlogon_creds_client_authenticator(creds
, &a
);
5675 query
.workstation_info
->dns_hostname
= NULL
;
5677 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonGetDomainInfo_r(b
, tctx
, &r
),
5678 "LogonGetDomainInfo failed");
5679 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LogonGetDomainInfo failed");
5680 torture_assert(tctx
, netlogon_creds_client_check(creds
, &a
.cred
), "Credential chaining failed");
5682 /* The old DNS hostname should stick */
5683 torture_assert_str_equal(tctx
,
5684 info
.domain_info
->dns_hostname
.string
,
5686 "'DNS hostname' changed!");
5688 torture_comment(tctx
, "Testing netr_LogonGetDomainInfo 7th call (extra workstation flags)\n");
5689 netlogon_creds_client_authenticator(creds
, &a
);
5691 q1
.workstation_flags
= NETR_WS_FLAG_HANDLES_SPN_UPDATE
5692 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS
| 0x4;
5694 /* Put the DNS hostname back */
5695 talloc_free(discard_const_p(char, q1
.dns_hostname
));
5696 q1
.dns_hostname
= talloc_asprintf(tctx
, "%s.%s", TEST_MACHINE_NAME
,
5697 lpcfg_dnsdomain(tctx
->lp_ctx
));
5699 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonGetDomainInfo_r(b
, tctx
, &r
),
5700 "LogonGetDomainInfo failed");
5701 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LogonGetDomainInfo failed");
5702 torture_assert(tctx
, netlogon_creds_client_check(creds
, &a
.cred
), "Credential chaining failed");
5704 /* Checks "workstation flags" */
5705 torture_assert(tctx
,
5706 info
.domain_info
->workstation_flags
5707 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
5708 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS
),
5709 "Out 'workstation flags' don't match!");
5711 if (!torture_setting_bool(tctx
, "dangerous", false)) {
5712 torture_comment(tctx
, "Not testing netr_LogonGetDomainInfo 8th call (no workstation info) - enable dangerous tests in order to do so\n");
5714 /* Try a call without the workstation information structure */
5716 torture_comment(tctx
, "Testing netr_LogonGetDomainInfo 8th call (no workstation info)\n");
5717 netlogon_creds_client_authenticator(creds
, &a
);
5719 query
.workstation_info
= NULL
;
5721 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonGetDomainInfo_r(b
, tctx
, &r
),
5722 "LogonGetDomainInfo failed");
5723 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LogonGetDomainInfo failed");
5724 torture_assert(tctx
, netlogon_creds_client_check(creds
, &a
.cred
), "Credential chaining failed");
5730 static bool test_GetDomainInfo_async(struct torture_context
*tctx
,
5731 struct dcerpc_pipe
*p1
,
5732 struct cli_credentials
*machine_credentials
)
5735 struct netr_LogonGetDomainInfo r
;
5736 struct netr_WorkstationInformation q1
;
5737 struct netr_Authenticator a
;
5738 #define ASYNC_COUNT 100
5739 struct netlogon_creds_CredentialState
*creds
;
5740 struct netlogon_creds_CredentialState
*creds_async
[ASYNC_COUNT
];
5741 struct tevent_req
*req
[ASYNC_COUNT
];
5743 union netr_WorkstationInfo query
;
5744 union netr_DomainInfo info
;
5745 struct dcerpc_pipe
*p
= NULL
;
5747 torture_comment(tctx
, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT
);
5749 if (!test_SetupCredentials3(p
, tctx
, NETLOGON_NEG_AUTH2_ADS_FLAGS
| NETLOGON_NEG_SUPPORTS_AES
,
5750 machine_credentials
, &creds
)) {
5753 if (!test_SetupCredentialsPipe(p1
, tctx
, machine_credentials
, creds
,
5754 DCERPC_SIGN
| DCERPC_SEAL
, &p
)) {
5759 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
5760 r
.in
.computer_name
= TEST_MACHINE_NAME
;
5761 r
.in
.credential
= &a
;
5763 r
.in
.return_authenticator
= &a
;
5764 r
.in
.query
= &query
;
5765 r
.out
.return_authenticator
= &a
;
5769 q1
.dns_hostname
= talloc_asprintf(tctx
, "%s.%s", TEST_MACHINE_NAME
,
5770 lpcfg_dnsdomain(tctx
->lp_ctx
));
5771 q1
.sitename
= "Default-First-Site-Name";
5772 q1
.os_name
.string
= "UNIX/Linux or similar";
5774 query
.workstation_info
= &q1
;
5776 for (i
=0;i
<ASYNC_COUNT
;i
++) {
5777 netlogon_creds_client_authenticator(creds
, &a
);
5779 creds_async
[i
] = (struct netlogon_creds_CredentialState
*)talloc_memdup(creds
, creds
, sizeof(*creds
));
5780 req
[i
] = dcerpc_netr_LogonGetDomainInfo_r_send(tctx
, tctx
->ev
, p
->binding_handle
, &r
);
5782 /* even with this flush per request a w2k3 server seems to
5783 clag with multiple outstanding requests. bleergh. */
5784 torture_assert_int_equal(tctx
, tevent_loop_once(tctx
->ev
), 0,
5785 "tevent_loop_once failed");
5788 for (i
=0;i
<ASYNC_COUNT
;i
++) {
5789 torture_assert_int_equal(tctx
, tevent_req_poll(req
[i
], tctx
->ev
), true,
5790 "tevent_req_poll() failed");
5792 status
= dcerpc_netr_LogonGetDomainInfo_r_recv(req
[i
], tctx
);
5794 torture_assert_ntstatus_ok(tctx
, status
, "netr_LogonGetDomainInfo_async");
5795 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "netr_LogonGetDomainInfo_async");
5797 torture_assert(tctx
, netlogon_creds_client_check(creds_async
[i
], &a
.cred
),
5798 "Credential chaining failed at async");
5801 torture_comment(tctx
,
5802 "Testing netr_LogonGetDomainInfo - async count %d OK\n", ASYNC_COUNT
);
5807 static bool test_ManyGetDCName(struct torture_context
*tctx
,
5808 struct dcerpc_pipe
*p
)
5811 struct cli_credentials
*anon_creds
;
5812 struct dcerpc_binding
*binding2
;
5813 struct dcerpc_pipe
*p2
;
5814 struct lsa_ObjectAttribute attr
;
5815 struct lsa_QosInfo qos
;
5816 struct lsa_OpenPolicy2 o
;
5817 struct policy_handle lsa_handle
;
5818 struct lsa_DomainList domains
;
5820 struct lsa_EnumTrustDom t
;
5821 uint32_t resume_handle
= 0;
5822 struct netr_GetAnyDCName d
;
5823 const char *dcname
= NULL
;
5824 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5825 const struct dcerpc_binding
*bd
= dcerpc_binding_handle_get_binding(b
);
5826 struct dcerpc_binding_handle
*b2
;
5830 if (dcerpc_binding_handle_get_transport(b
) != NCACN_NP
) {
5831 torture_skip(tctx
, "test_ManyGetDCName works only with NCACN_NP");
5834 torture_comment(tctx
, "Torturing GetDCName\n");
5836 anon_creds
= cli_credentials_init_anon(tctx
);
5837 torture_assert(tctx
, anon_creds
!= NULL
, "cli_credentials_init_anon failed");
5839 binding2
= dcerpc_binding_dup(tctx
, bd
);
5840 /* Swap the binding details from NETLOGON to LSA */
5841 status
= dcerpc_epm_map_binding(tctx
, binding2
, &ndr_table_lsarpc
, tctx
->ev
, tctx
->lp_ctx
);
5842 dcerpc_binding_set_assoc_group_id(binding2
, 0);
5843 torture_assert_ntstatus_ok(tctx
, status
, "epm map");
5845 status
= dcerpc_secondary_auth_connection(p
, binding2
, &ndr_table_lsarpc
,
5846 anon_creds
, tctx
->lp_ctx
,
5848 torture_assert_ntstatus_ok(tctx
, status
, "Failed to create secondary connection");
5849 b2
= p2
->binding_handle
;
5852 qos
.impersonation_level
= 2;
5853 qos
.context_mode
= 1;
5854 qos
.effective_only
= 0;
5857 attr
.root_dir
= NULL
;
5858 attr
.object_name
= NULL
;
5859 attr
.attributes
= 0;
5860 attr
.sec_desc
= NULL
;
5861 attr
.sec_qos
= &qos
;
5863 o
.in
.system_name
= "\\";
5865 o
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5866 o
.out
.handle
= &lsa_handle
;
5868 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenPolicy2_r(b2
, tctx
, &o
),
5869 "OpenPolicy2 failed");
5870 torture_assert_ntstatus_ok(tctx
, o
.out
.result
, "OpenPolicy2 failed");
5872 t
.in
.handle
= &lsa_handle
;
5873 t
.in
.resume_handle
= &resume_handle
;
5874 t
.in
.max_size
= 1000;
5875 t
.out
.domains
= &domains
;
5876 t
.out
.resume_handle
= &resume_handle
;
5878 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumTrustDom_r(b2
, tctx
, &t
),
5879 "EnumTrustDom failed");
5881 if ((!NT_STATUS_IS_OK(t
.out
.result
) &&
5882 (!NT_STATUS_EQUAL(t
.out
.result
, NT_STATUS_NO_MORE_ENTRIES
))))
5883 torture_fail(tctx
, "Could not list domains");
5887 d
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s",
5888 dcerpc_server_name(p
));
5889 d
.out
.dcname
= &dcname
;
5891 for (i
=0; i
<domains
.count
* 4; i
++) {
5892 struct lsa_DomainInfo
*info
=
5893 &domains
.domains
[rand()%domains
.count
];
5895 d
.in
.domainname
= info
->name
.string
;
5897 status
= dcerpc_netr_GetAnyDCName_r(b
, tctx
, &d
);
5898 torture_assert_ntstatus_ok(tctx
, status
, "GetAnyDCName");
5900 torture_comment(tctx
, "\tDC for domain %s is %s\n", info
->name
.string
,
5901 dcname
? dcname
: "unknown");
5907 static bool test_lsa_over_netlogon(struct torture_context
*tctx
,
5908 struct dcerpc_pipe
*p
)
5911 struct cli_credentials
*anon_creds
;
5912 const struct dcerpc_binding
*binding2
;
5913 struct dcerpc_pipe
*p2
;
5914 struct lsa_ObjectAttribute attr
;
5915 struct lsa_QosInfo qos
;
5916 struct lsa_OpenPolicy2 o
;
5917 struct policy_handle lsa_handle
;
5919 struct dcerpc_binding_handle
*b2
;
5922 if (dcerpc_binding_handle_get_transport(p
->binding_handle
) != NCACN_NP
) {
5923 torture_skip(tctx
, "test_lsa_over_netlogon works only with NCACN_NP");
5926 torture_comment(tctx
, "Testing if we can access the LSA server over\n"
5927 " \\\\pipe\\netlogon rather than \\\\pipe\\lsarpc\n");
5929 anon_creds
= cli_credentials_init_anon(tctx
);
5930 torture_assert(tctx
, anon_creds
!= NULL
, "cli_credentials_init_anon failed");
5932 binding2
= dcerpc_binding_handle_get_binding(p
->binding_handle
);
5934 status
= dcerpc_secondary_auth_connection(p
, binding2
, &ndr_table_lsarpc
,
5935 anon_creds
, tctx
->lp_ctx
,
5937 torture_assert_ntstatus_ok(tctx
, status
, "Failed to create secondary connection");
5938 b2
= p2
->binding_handle
;
5941 qos
.impersonation_level
= 2;
5942 qos
.context_mode
= 1;
5943 qos
.effective_only
= 0;
5946 attr
.root_dir
= NULL
;
5947 attr
.object_name
= NULL
;
5948 attr
.attributes
= 0;
5949 attr
.sec_desc
= NULL
;
5950 attr
.sec_qos
= &qos
;
5952 o
.in
.system_name
= "\\";
5954 o
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5955 o
.out
.handle
= &lsa_handle
;
5957 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenPolicy2_r(b2
, tctx
, &o
),
5958 "OpenPolicy2 failed");
5959 torture_assert_ntstatus_ok(tctx
, o
.out
.result
, "OpenPolicy2 failed");
5966 static bool test_SetPassword_with_flags(struct torture_context
*tctx
,
5967 struct dcerpc_pipe
*p
,
5968 struct cli_credentials
*machine_credentials
)
5970 uint32_t flags
[] = { 0, NETLOGON_NEG_STRONG_KEYS
};
5971 struct netlogon_creds_CredentialState
*creds
;
5974 if (!test_SetupCredentials2(p
, tctx
, 0,
5975 machine_credentials
,
5976 cli_credentials_get_secure_channel_type(machine_credentials
),
5978 torture_skip(tctx
, "DC does not support negotiation of 64bit session keys");
5981 for (i
=0; i
< ARRAY_SIZE(flags
); i
++) {
5982 torture_assert(tctx
,
5983 test_SetPassword_flags(tctx
, p
, machine_credentials
, flags
[i
]),
5984 talloc_asprintf(tctx
, "failed to test SetPassword negotiating with 0x%08x flags", flags
[i
]));
5990 struct torture_suite
*torture_rpc_netlogon(TALLOC_CTX
*mem_ctx
)
5992 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "netlogon");
5993 struct torture_rpc_tcase
*tcase
;
5994 struct torture_test
*test
;
5996 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "netlogon",
5997 &ndr_table_netlogon
, TEST_MACHINE_NAME
);
5999 torture_rpc_tcase_add_test_creds(tcase
, "SetupCredentialsDowngrade", test_SetupCredentialsDowngrade
);
6000 torture_rpc_tcase_add_test(tcase
, "lsa_over_netlogon", test_lsa_over_netlogon
);
6002 torture_rpc_tcase_add_test_creds(tcase
, "GetForestTrustInformation", test_netr_GetForestTrustInformation
);
6003 torture_rpc_tcase_add_test_creds(tcase
, "ServerGetTrustInfo_AES", test_netr_ServerGetTrustInfo_AES
);
6004 torture_rpc_tcase_add_test_creds(tcase
, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo
);
6005 torture_rpc_tcase_add_test(tcase
, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW
);
6006 torture_rpc_tcase_add_test(tcase
, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW
);
6007 torture_rpc_tcase_add_test(tcase
, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW
);
6008 torture_rpc_tcase_add_test(tcase
, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2
);
6009 torture_rpc_tcase_add_test(tcase
, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx
);
6010 torture_rpc_tcase_add_test(tcase
, "DsRGetDCName", test_netr_DsRGetDCName
);
6011 test
= torture_rpc_tcase_add_test_creds(tcase
, "GetDomainInfo_async", test_GetDomainInfo_async
);
6012 test
->dangerous
= true;
6013 torture_rpc_tcase_add_test(tcase
, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx
);
6014 torture_rpc_tcase_add_test(tcase
, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains
);
6015 torture_rpc_tcase_add_test(tcase
, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts
);
6016 torture_rpc_tcase_add_test_creds(tcase
, "DatabaseSync2", test_DatabaseSync2
);
6017 torture_rpc_tcase_add_test(tcase
, "GetAnyDCName", test_GetAnyDCName
);
6018 torture_rpc_tcase_add_test(tcase
, "ManyGetDCName", test_ManyGetDCName
);
6019 torture_rpc_tcase_add_test(tcase
, "GetDcName", test_GetDcName
);
6020 torture_rpc_tcase_add_test_creds(tcase
, "AccountSync", test_AccountSync
);
6021 torture_rpc_tcase_add_test_creds(tcase
, "AccountDeltas", test_AccountDeltas
);
6022 torture_rpc_tcase_add_test_creds(tcase
, "DatabaseRedo", test_DatabaseRedo
);
6023 torture_rpc_tcase_add_test_creds(tcase
, "DatabaseDeltas", test_DatabaseDeltas
);
6024 torture_rpc_tcase_add_test_creds(tcase
, "DatabaseSync", test_DatabaseSync
);
6025 torture_rpc_tcase_add_test_creds(tcase
, "GetDomainInfo", test_GetDomainInfo
);
6026 torture_rpc_tcase_add_test_creds(tcase
, "GetTrustPasswords", test_GetTrustPasswords
);
6027 torture_rpc_tcase_add_test_creds(tcase
, "GetPassword", test_GetPassword
);
6028 torture_rpc_tcase_add_test_creds(tcase
, "SetPassword2_AES", test_SetPassword2_AES
);
6029 torture_rpc_tcase_add_test_creds(tcase
, "SetPassword2", test_SetPassword2
);
6030 torture_rpc_tcase_add_test_creds(tcase
, "SetPassword", test_SetPassword
);
6031 torture_rpc_tcase_add_test_creds(tcase
, "ServerReqChallengeReuse", test_ServerReqChallengeReuse
);
6032 torture_rpc_tcase_add_test_creds(tcase
, "ServerReqChallengeReuseGlobal4", test_ServerReqChallengeReuseGlobal4
);
6033 torture_rpc_tcase_add_test_creds(tcase
, "ServerReqChallengeReuseGlobal3", test_ServerReqChallengeReuseGlobal3
);
6034 torture_rpc_tcase_add_test_creds(tcase
, "ServerReqChallengeReuseGlobal2", test_ServerReqChallengeReuseGlobal2
);
6035 torture_rpc_tcase_add_test_creds(tcase
, "ServerReqChallengeReuseGlobal", test_ServerReqChallengeReuseGlobal
);
6036 torture_rpc_tcase_add_test_creds(tcase
, "ServerReqChallengeGlobal", test_ServerReqChallengeGlobal
);
6037 torture_rpc_tcase_add_test_creds(tcase
, "invalidAuthenticate2", test_invalidAuthenticate2
);
6038 torture_rpc_tcase_add_test_creds(tcase
, "SamLogon", test_SamLogon
);
6039 torture_rpc_tcase_add_test(tcase
, "LogonUasLogoff", test_LogonUasLogoff
);
6040 torture_rpc_tcase_add_test(tcase
, "LogonUasLogon", test_LogonUasLogon
);
6042 torture_rpc_tcase_add_test(tcase
, "Broken RPC binding handle",
6043 test_netr_broken_binding_handle
);
6048 struct torture_suite
*torture_rpc_netlogon_s3(TALLOC_CTX
*mem_ctx
)
6050 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "netlogon-s3");
6051 struct torture_rpc_tcase
*tcase
;
6053 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "netlogon",
6054 &ndr_table_netlogon
, TEST_MACHINE_NAME
);
6056 torture_rpc_tcase_add_test_creds(tcase
, "SamLogon", test_SamLogon
);
6057 torture_rpc_tcase_add_test_creds(tcase
, "SamLogon_NULL_domain", test_SamLogon_NULL_domain
);
6058 torture_rpc_tcase_add_test_creds(tcase
, "SetPassword", test_SetPassword
);
6059 torture_rpc_tcase_add_test_creds(tcase
, "SetPassword_with_flags", test_SetPassword_with_flags
);
6060 torture_rpc_tcase_add_test_creds(tcase
, "SetPassword2", test_SetPassword2
);
6061 torture_rpc_tcase_add_test_creds(tcase
, "SetPassword2_AES", test_SetPassword2_AES
);
6062 torture_rpc_tcase_add_test(tcase
, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains
);
6067 struct torture_suite
*torture_rpc_netlogon_zerologon(TALLOC_CTX
*mem_ctx
)
6069 struct torture_suite
*suite
= torture_suite_create(
6071 "netlogon.zerologon");
6072 struct torture_rpc_tcase
*tcase
;
6074 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(
6077 &ndr_table_netlogon
,
6080 torture_rpc_tcase_add_test_creds(
6082 "ServerReqChallenge",
6083 test_ServerReqChallenge
);
6084 torture_rpc_tcase_add_test_creds(
6086 "ServerReqChallenge_zero_challenge",
6087 test_ServerReqChallenge_zero_challenge
);
6088 torture_rpc_tcase_add_test_creds(
6090 "ServerReqChallenge_5_repeats",
6091 test_ServerReqChallenge_5_repeats
);
6092 torture_rpc_tcase_add_test_creds(
6094 "ServerReqChallenge_4_repeats",
6095 test_ServerReqChallenge_4_repeats
);
6096 torture_rpc_tcase_add_test_creds(
6098 "test_SetPassword2_encrypted_to_all_zeros",
6099 test_SetPassword2_encrypted_to_all_zeros
);
6100 torture_rpc_tcase_add_test_creds(
6102 "test_SetPassword2_password_encrypts_to_zero",
6103 test_SetPassword2_password_encrypts_to_zero
);
6104 torture_rpc_tcase_add_test_creds(
6106 "test_SetPassword2_confounder",
6107 test_SetPassword2_confounder
);
6108 torture_rpc_tcase_add_test_creds(
6110 "test_SetPassword2_all_zeros",
6111 test_SetPassword2_all_zeros
);
6112 torture_rpc_tcase_add_test_creds(
6114 "test_SetPassword2_all_zero_password",
6115 test_SetPassword2_all_zero_password
);
6116 torture_rpc_tcase_add_test_creds(
6118 "test_SetPassword2_maximum_length_password",
6119 test_SetPassword2_maximum_length_password
);
6124 struct torture_suite
*torture_rpc_netlogon_admin(TALLOC_CTX
*mem_ctx
)
6126 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "netlogon.admin");
6127 struct torture_rpc_tcase
*tcase
;
6129 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "bdc",
6130 &ndr_table_netlogon
, TEST_MACHINE_NAME
);
6131 torture_rpc_tcase_add_test_creds(tcase
, "LogonControl", test_LogonControl
);
6132 torture_rpc_tcase_add_test_creds(tcase
, "LogonControl2", test_LogonControl2
);
6133 torture_rpc_tcase_add_test_creds(tcase
, "LogonControl2Ex", test_LogonControl2Ex
);
6135 tcase
= torture_suite_add_machine_workstation_rpc_iface_tcase(suite
, "wkst",
6136 &ndr_table_netlogon
, TEST_MACHINE_NAME
);
6137 torture_rpc_tcase_add_test_creds(tcase
, "LogonControl", test_LogonControl
);
6138 torture_rpc_tcase_add_test_creds(tcase
, "LogonControl2", test_LogonControl2
);
6139 torture_rpc_tcase_add_test_creds(tcase
, "LogonControl2Ex", test_LogonControl2Ex
);
6141 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "admin",
6142 &ndr_table_netlogon
);
6143 torture_rpc_tcase_add_test_creds(tcase
, "LogonControl", test_LogonControl
);
6144 torture_rpc_tcase_add_test_creds(tcase
, "LogonControl2", test_LogonControl2
);
6145 torture_rpc_tcase_add_test_creds(tcase
, "LogonControl2Ex", test_LogonControl2Ex
);