2 Unix SMB/CIFS implementation.
4 test suite for netlogon rpc operations
6 Copyright (C) Andrew Tridgell 2003
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2004
8 Copyright (C) Tim Potter 2003
9 Copyright (C) Matthias Dieter Wallnöfer 2009-2010
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "lib/events/events.h"
27 #include "lib/cmdline/popt_common.h"
28 #include "torture/rpc/torture_rpc.h"
29 #include "../lib/crypto/crypto.h"
30 #include "libcli/auth/libcli_auth.h"
31 #include "librpc/gen_ndr/ndr_netlogon_c.h"
32 #include "librpc/gen_ndr/ndr_lsa_c.h"
33 #include "param/param.h"
34 #include "libcli/security/security.h"
36 #include "lib/util/util_ldb.h"
38 #include "lib/replace/system/network.h"
39 #include "dsdb/samdb/samdb.h"
41 #define TEST_MACHINE_NAME "torturetest"
43 static bool test_netr_broken_binding_handle(struct torture_context *tctx,
44 struct dcerpc_pipe *p)
47 struct netr_DsRGetSiteName r;
48 const char *site = NULL;
49 struct dcerpc_binding_handle *b = p->binding_handle;
51 r.in.computer_name = talloc_asprintf(tctx, "\\\\%s",
52 dcerpc_server_name(p));
56 "Testing netlogon request with correct binding handle: %s\n",
59 status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
60 torture_assert_ntstatus_ok(tctx, status,
61 "Netlogon request with broken binding handle");
62 torture_assert_werr_ok(tctx, r.out.result,
63 "Netlogon request with broken binding handle");
65 if (torture_setting_bool(tctx, "samba3", false) ||
66 torture_setting_bool(tctx, "samba4", false)) {
68 "Skipping broken binding handle check against Samba");
71 r.in.computer_name = talloc_asprintf(tctx, "\\\\\\\\%s",
72 dcerpc_server_name(p));
75 "Testing netlogon request with broken binding handle: %s\n",
78 status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
79 torture_assert_ntstatus_ok(tctx, status,
80 "Netlogon request with broken binding handle");
81 torture_assert_werr_equal(tctx, r.out.result,
82 WERR_INVALID_COMPUTERNAME,
83 "Netlogon request with broken binding handle");
85 r.in.computer_name = "\\\\\\\\THIS_IS_NOT_VALID";
88 "Testing netlogon request with broken binding handle: %s\n",
91 status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
92 torture_assert_ntstatus_ok(tctx, status,
93 "Netlogon request with broken binding handle");
94 torture_assert_werr_equal(tctx, r.out.result,
95 WERR_INVALID_COMPUTERNAME,
96 "Netlogon request with broken binding handle");
101 static bool test_LogonUasLogon(struct torture_context *tctx,
102 struct dcerpc_pipe *p)
105 struct netr_LogonUasLogon r;
106 struct netr_UasInfo *info = NULL;
107 struct dcerpc_binding_handle *b = p->binding_handle;
109 r.in.server_name = NULL;
110 r.in.account_name = cli_credentials_get_username(cmdline_credentials);
111 r.in.workstation = TEST_MACHINE_NAME;
114 status = dcerpc_netr_LogonUasLogon_r(b, tctx, &r);
115 torture_assert_ntstatus_ok(tctx, status, "LogonUasLogon");
120 static bool test_LogonUasLogoff(struct torture_context *tctx,
121 struct dcerpc_pipe *p)
124 struct netr_LogonUasLogoff r;
125 struct netr_UasLogoffInfo info;
126 struct dcerpc_binding_handle *b = p->binding_handle;
128 r.in.server_name = NULL;
129 r.in.account_name = cli_credentials_get_username(cmdline_credentials);
130 r.in.workstation = TEST_MACHINE_NAME;
133 status = dcerpc_netr_LogonUasLogoff_r(b, tctx, &r);
134 torture_assert_ntstatus_ok(tctx, status, "LogonUasLogoff");
139 bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
140 struct cli_credentials *credentials,
141 struct netlogon_creds_CredentialState **creds_out)
143 struct netr_ServerReqChallenge r;
144 struct netr_ServerAuthenticate a;
145 struct netr_Credential credentials1, credentials2, credentials3;
146 struct netlogon_creds_CredentialState *creds;
147 const struct samr_Password *mach_password;
148 const char *machine_name;
149 struct dcerpc_binding_handle *b = p->binding_handle;
151 mach_password = cli_credentials_get_nt_hash(credentials, tctx);
152 machine_name = cli_credentials_get_workstation(credentials);
154 torture_comment(tctx, "Testing ServerReqChallenge\n");
156 r.in.server_name = NULL;
157 r.in.computer_name = machine_name;
158 r.in.credentials = &credentials1;
159 r.out.return_credentials = &credentials2;
161 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
163 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
164 "ServerReqChallenge failed");
165 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
167 a.in.server_name = NULL;
168 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
169 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(credentials);
170 a.in.computer_name = machine_name;
171 a.in.credentials = &credentials3;
172 a.out.return_credentials = &credentials3;
174 creds = netlogon_creds_client_init(tctx, a.in.account_name,
176 a.in.secure_channel_type,
177 &credentials1, &credentials2,
178 mach_password, &credentials3,
180 torture_assert(tctx, creds != NULL, "memory allocation");
183 torture_comment(tctx, "Testing ServerAuthenticate\n");
185 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate_r(b, tctx, &a),
186 "ServerAuthenticate failed");
188 /* This allows the tests to continue against the more fussy windows 2008 */
189 if (NT_STATUS_EQUAL(a.out.result, NT_STATUS_DOWNGRADE_DETECTED)) {
190 return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
192 cli_credentials_get_secure_channel_type(credentials),
196 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate");
198 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
199 "Credential chaining failed");
205 bool test_SetupCredentials2ex(struct dcerpc_pipe *p, struct torture_context *tctx,
206 uint32_t negotiate_flags,
207 struct cli_credentials *machine_credentials,
208 const char *computer_name,
209 enum netr_SchannelType sec_chan_type,
210 NTSTATUS expected_result,
211 struct netlogon_creds_CredentialState **creds_out)
213 struct netr_ServerReqChallenge r;
214 struct netr_ServerAuthenticate2 a;
215 struct netr_Credential credentials1, credentials2, credentials3;
216 struct netlogon_creds_CredentialState *creds;
217 const struct samr_Password *mach_password;
218 struct dcerpc_binding_handle *b = p->binding_handle;
219 const char *account_name = cli_credentials_get_username(machine_credentials);
221 mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
223 torture_comment(tctx, "Testing ServerReqChallenge\n");
225 r.in.server_name = NULL;
226 r.in.computer_name = computer_name;
227 r.in.credentials = &credentials1;
228 r.out.return_credentials = &credentials2;
230 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
232 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
233 "ServerReqChallenge failed");
234 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
236 a.in.server_name = NULL;
237 a.in.account_name = account_name;
238 a.in.secure_channel_type = sec_chan_type;
239 a.in.computer_name = computer_name;
240 a.in.negotiate_flags = &negotiate_flags;
241 a.out.negotiate_flags = &negotiate_flags;
242 a.in.credentials = &credentials3;
243 a.out.return_credentials = &credentials3;
245 creds = netlogon_creds_client_init(tctx, a.in.account_name,
247 a.in.secure_channel_type,
248 &credentials1, &credentials2,
249 mach_password, &credentials3,
252 torture_assert(tctx, creds != NULL, "memory allocation");
254 torture_comment(tctx, "Testing ServerAuthenticate2\n");
256 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
257 "ServerAuthenticate2 failed");
258 torture_assert_ntstatus_equal(tctx, a.out.result, expected_result,
259 "ServerAuthenticate2 unexpected");
261 if (NT_STATUS_IS_OK(expected_result)) {
262 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
263 "Credential chaining failed");
265 torture_assert(tctx, !netlogon_creds_client_check(creds, &credentials3),
266 "Credential chaining passed unexptected");
269 torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
275 bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx,
276 uint32_t negotiate_flags,
277 struct cli_credentials *machine_credentials,
278 enum netr_SchannelType sec_chan_type,
279 struct netlogon_creds_CredentialState **creds_out)
281 const char *computer_name =
282 cli_credentials_get_workstation(machine_credentials);
284 return test_SetupCredentials2ex(p, tctx, negotiate_flags,
292 bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx,
293 uint32_t negotiate_flags,
294 struct cli_credentials *machine_credentials,
295 struct netlogon_creds_CredentialState **creds_out)
297 struct netr_ServerReqChallenge r;
298 struct netr_ServerAuthenticate3 a;
299 struct netr_Credential credentials1, credentials2, credentials3;
300 struct netlogon_creds_CredentialState *creds;
301 struct samr_Password mach_password;
303 const char *machine_name;
304 const char *plain_pass;
305 struct dcerpc_binding_handle *b = p->binding_handle;
307 machine_name = cli_credentials_get_workstation(machine_credentials);
308 plain_pass = cli_credentials_get_password(machine_credentials);
310 torture_comment(tctx, "Testing ServerReqChallenge\n");
312 r.in.server_name = NULL;
313 r.in.computer_name = machine_name;
314 r.in.credentials = &credentials1;
315 r.out.return_credentials = &credentials2;
317 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
319 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
320 "ServerReqChallenge failed");
321 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
323 E_md4hash(plain_pass, mach_password.hash);
325 a.in.server_name = NULL;
326 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
327 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
328 a.in.computer_name = machine_name;
329 a.in.negotiate_flags = &negotiate_flags;
330 a.in.credentials = &credentials3;
331 a.out.return_credentials = &credentials3;
332 a.out.negotiate_flags = &negotiate_flags;
335 creds = netlogon_creds_client_init(tctx, a.in.account_name,
337 a.in.secure_channel_type,
338 &credentials1, &credentials2,
339 &mach_password, &credentials3,
342 torture_assert(tctx, creds != NULL, "memory allocation");
344 torture_comment(tctx, "Testing ServerAuthenticate3\n");
346 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
347 "ServerAuthenticate3 failed");
348 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed");
349 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
351 torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
353 /* Prove that requesting a challenge again won't break it */
354 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
355 "ServerReqChallenge failed");
356 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
362 bool test_SetupCredentialsDowngrade(struct torture_context *tctx,
363 struct dcerpc_pipe *p,
364 struct cli_credentials *machine_credentials)
366 struct netr_ServerReqChallenge r;
367 struct netr_ServerAuthenticate3 a;
368 struct netr_Credential credentials1, credentials2, credentials3;
369 struct netlogon_creds_CredentialState *creds;
370 struct samr_Password mach_password;
372 const char *machine_name;
373 const char *plain_pass;
374 struct dcerpc_binding_handle *b = p->binding_handle;
375 uint32_t negotiate_flags = 0;
377 machine_name = cli_credentials_get_workstation(machine_credentials);
378 plain_pass = cli_credentials_get_password(machine_credentials);
380 torture_comment(tctx, "Testing ServerReqChallenge\n");
382 r.in.server_name = NULL;
383 r.in.computer_name = machine_name;
384 r.in.credentials = &credentials1;
385 r.out.return_credentials = &credentials2;
387 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
389 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
390 "ServerReqChallenge failed");
391 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
393 E_md4hash(plain_pass, mach_password.hash);
395 a.in.server_name = NULL;
396 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
397 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
398 a.in.computer_name = machine_name;
399 a.in.negotiate_flags = &negotiate_flags;
400 a.in.credentials = &credentials3;
401 a.out.return_credentials = &credentials3;
402 a.out.negotiate_flags = &negotiate_flags;
405 creds = netlogon_creds_client_init(tctx, a.in.account_name,
407 a.in.secure_channel_type,
408 &credentials1, &credentials2,
409 &mach_password, &credentials3,
412 torture_assert(tctx, creds != NULL, "memory allocation");
414 torture_comment(tctx, "Testing ServerAuthenticate3\n");
416 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
417 "ServerAuthenticate3 failed");
418 torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_DOWNGRADE_DETECTED, "ServerAuthenticate3 should have failed");
420 negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
421 creds = netlogon_creds_client_init(tctx, a.in.account_name,
423 a.in.secure_channel_type,
424 &credentials1, &credentials2,
425 &mach_password, &credentials3,
428 torture_assert(tctx, creds != NULL, "memory allocation");
430 torture_comment(tctx, "Testing ServerAuthenticate3\n");
432 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
433 "ServerAuthenticate3 failed");
434 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 should succeed");
436 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
438 torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
440 /* Prove that requesting a challenge again won't break it */
441 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
442 "ServerReqChallenge failed");
443 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
448 bool test_SetupCredentialsPipe(const struct dcerpc_pipe *p1,
449 struct torture_context *tctx,
450 struct cli_credentials *machine_credentials,
451 struct netlogon_creds_CredentialState *creds,
452 uint32_t additional_flags,
453 struct dcerpc_pipe **_p2)
456 struct dcerpc_binding *b2 = NULL;
457 struct dcerpc_pipe *p2 = NULL;
459 b2 = dcerpc_binding_dup(tctx, p1->binding);
460 torture_assert(tctx, b2 != NULL, "dcerpc_binding_dup");
461 dcerpc_binding_set_flags(b2,
462 DCERPC_SCHANNEL | additional_flags,
463 DCERPC_AUTH_OPTIONS);
465 cli_credentials_set_netlogon_creds(machine_credentials, creds);
466 status = dcerpc_pipe_connect_b(tctx, &p2, b2,
469 tctx->ev, tctx->lp_ctx);
470 cli_credentials_set_netlogon_creds(machine_credentials, NULL);
471 torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b schannel");
478 try a change password for our machine account
480 static bool test_SetPassword(struct torture_context *tctx,
481 struct dcerpc_pipe *p,
482 struct cli_credentials *machine_credentials)
484 struct netr_ServerPasswordSet r;
485 const char *password;
486 struct netlogon_creds_CredentialState *creds;
487 struct netr_Authenticator credential, return_authenticator;
488 struct samr_Password new_password;
489 struct dcerpc_binding_handle *b = p->binding_handle;
491 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
495 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
496 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
497 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
498 r.in.computer_name = TEST_MACHINE_NAME;
499 r.in.credential = &credential;
500 r.in.new_password = &new_password;
501 r.out.return_authenticator = &return_authenticator;
503 password = generate_random_password(tctx, 8, 255);
504 E_md4hash(password, new_password.hash);
506 netlogon_creds_des_encrypt(creds, &new_password);
508 torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
509 torture_comment(tctx, "Changing machine account password to '%s'\n",
512 netlogon_creds_client_authenticator(creds, &credential);
514 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
515 "ServerPasswordSet failed");
516 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
518 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
519 torture_comment(tctx, "Credential chaining failed\n");
522 /* by changing the machine password twice we test the
523 credentials chaining fully, and we verify that the server
524 allows the password to be set to the same value twice in a
525 row (match win2k3) */
526 torture_comment(tctx,
527 "Testing a second ServerPasswordSet on machine account\n");
528 torture_comment(tctx,
529 "Changing machine account password to '%s' (same as previous run)\n", password);
531 netlogon_creds_client_authenticator(creds, &credential);
533 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
534 "ServerPasswordSet (2) failed");
535 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
537 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
538 torture_comment(tctx, "Credential chaining failed\n");
541 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
544 test_SetupCredentials(p, tctx, machine_credentials, &creds),
545 "ServerPasswordSet failed to actually change the password");
551 try a change password for our machine account
553 static bool test_SetPassword_flags(struct torture_context *tctx,
554 struct dcerpc_pipe *p1,
555 struct cli_credentials *machine_credentials,
556 uint32_t negotiate_flags)
558 struct netr_ServerPasswordSet r;
559 const char *password;
560 struct netlogon_creds_CredentialState *creds;
561 struct netr_Authenticator credential, return_authenticator;
562 struct samr_Password new_password;
563 struct dcerpc_pipe *p = NULL;
564 struct dcerpc_binding_handle *b = NULL;
566 if (!test_SetupCredentials2(p1, tctx, negotiate_flags,
568 cli_credentials_get_secure_channel_type(machine_credentials),
572 if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
573 DCERPC_SIGN | DCERPC_SEAL, &p)) {
576 b = p->binding_handle;
578 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
579 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
580 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
581 r.in.computer_name = TEST_MACHINE_NAME;
582 r.in.credential = &credential;
583 r.in.new_password = &new_password;
584 r.out.return_authenticator = &return_authenticator;
586 password = generate_random_password(tctx, 8, 255);
587 E_md4hash(password, new_password.hash);
589 netlogon_creds_des_encrypt(creds, &new_password);
591 torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
592 torture_comment(tctx, "Changing machine account password to '%s'\n",
595 netlogon_creds_client_authenticator(creds, &credential);
597 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
598 "ServerPasswordSet failed");
599 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
601 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
602 torture_comment(tctx, "Credential chaining failed\n");
605 /* by changing the machine password twice we test the
606 credentials chaining fully, and we verify that the server
607 allows the password to be set to the same value twice in a
608 row (match win2k3) */
609 torture_comment(tctx,
610 "Testing a second ServerPasswordSet on machine account\n");
611 torture_comment(tctx,
612 "Changing machine account password to '%s' (same as previous run)\n", password);
614 netlogon_creds_client_authenticator(creds, &credential);
616 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
617 "ServerPasswordSet (2) failed");
618 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
620 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
621 torture_comment(tctx, "Credential chaining failed\n");
624 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
627 test_SetupCredentials(p, tctx, machine_credentials, &creds),
628 "ServerPasswordSet failed to actually change the password");
635 generate a random password for password change tests
637 static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
640 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
641 generate_random_buffer(password.data, password.length);
643 for (i=0; i < len; i++) {
644 if (((uint16_t *)password.data)[i] == 0) {
645 ((uint16_t *)password.data)[i] = 1;
653 try a change password for our machine account
655 static bool test_SetPassword2_with_flags(struct torture_context *tctx,
656 struct dcerpc_pipe *p1,
657 struct cli_credentials *machine_credentials,
660 struct netr_ServerPasswordSet2 r;
661 const char *password;
662 DATA_BLOB new_random_pass;
663 struct netlogon_creds_CredentialState *creds;
664 struct samr_CryptPassword password_buf;
665 struct samr_Password nt_hash;
666 struct netr_Authenticator credential, return_authenticator;
667 struct netr_CryptPassword new_password;
668 struct dcerpc_pipe *p = NULL;
669 struct dcerpc_binding_handle *b = NULL;
671 if (!test_SetupCredentials2(p1, tctx, flags, machine_credentials,
672 cli_credentials_get_secure_channel_type(machine_credentials),
676 if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
677 DCERPC_SIGN | DCERPC_SEAL, &p)) {
680 b = p->binding_handle;
682 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
683 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
684 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
685 r.in.computer_name = TEST_MACHINE_NAME;
686 r.in.credential = &credential;
687 r.in.new_password = &new_password;
688 r.out.return_authenticator = &return_authenticator;
690 password = generate_random_password(tctx, 8, 255);
691 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
692 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
693 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
695 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
698 memcpy(new_password.data, password_buf.data, 512);
699 new_password.length = IVAL(password_buf.data, 512);
701 torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
702 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
704 netlogon_creds_client_authenticator(creds, &credential);
706 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
707 "ServerPasswordSet2 failed");
708 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
710 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
711 torture_comment(tctx, "Credential chaining failed\n");
714 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
716 if (!torture_setting_bool(tctx, "dangerous", false)) {
717 torture_comment(tctx,
718 "Not testing ability to set password to '', enable dangerous tests to perform this test\n");
720 /* by changing the machine password to ""
721 * we check if the server uses password restrictions
722 * for ServerPasswordSet2
723 * (win2k3 accepts "")
726 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
727 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
728 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
730 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
732 memcpy(new_password.data, password_buf.data, 512);
733 new_password.length = IVAL(password_buf.data, 512);
735 torture_comment(tctx,
736 "Testing ServerPasswordSet2 on machine account\n");
737 torture_comment(tctx,
738 "Changing machine account password to '%s'\n", password);
740 netlogon_creds_client_authenticator(creds, &credential);
742 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
743 "ServerPasswordSet2 failed");
744 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
746 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
747 torture_comment(tctx, "Credential chaining failed\n");
750 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
753 torture_assert(tctx, test_SetupCredentials(p, tctx, machine_credentials, &creds),
754 "ServerPasswordSet failed to actually change the password");
756 /* now try a random password */
757 password = generate_random_password(tctx, 8, 255);
758 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
759 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
760 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
762 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
764 memcpy(new_password.data, password_buf.data, 512);
765 new_password.length = IVAL(password_buf.data, 512);
767 torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
768 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
770 netlogon_creds_client_authenticator(creds, &credential);
772 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
773 "ServerPasswordSet2 (2) failed");
774 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 (2) failed");
776 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
777 torture_comment(tctx, "Credential chaining failed\n");
780 /* by changing the machine password twice we test the
781 credentials chaining fully, and we verify that the server
782 allows the password to be set to the same value twice in a
783 row (match win2k3) */
784 torture_comment(tctx,
785 "Testing a second ServerPasswordSet2 on machine account\n");
786 torture_comment(tctx,
787 "Changing machine account password to '%s' (same as previous run)\n", password);
789 netlogon_creds_client_authenticator(creds, &credential);
791 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
792 "ServerPasswordSet (3) failed");
793 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
795 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
796 torture_comment(tctx, "Credential chaining failed\n");
799 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
801 torture_assert (tctx,
802 test_SetupCredentials(p, tctx, machine_credentials, &creds),
803 "ServerPasswordSet failed to actually change the password");
805 new_random_pass = netlogon_very_rand_pass(tctx, 128);
807 /* now try a random stream of bytes for a password */
808 set_pw_in_buffer(password_buf.data, &new_random_pass);
810 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
811 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
813 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
816 memcpy(new_password.data, password_buf.data, 512);
817 new_password.length = IVAL(password_buf.data, 512);
819 torture_comment(tctx,
820 "Testing a third ServerPasswordSet2 on machine account, with a completely random password\n");
822 netlogon_creds_client_authenticator(creds, &credential);
824 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
825 "ServerPasswordSet (3) failed");
826 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
828 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
829 torture_comment(tctx, "Credential chaining failed\n");
832 mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
834 cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
835 cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
837 torture_assert (tctx,
838 test_SetupCredentials(p, tctx, machine_credentials, &creds),
839 "ServerPasswordSet failed to actually change the password");
844 static bool test_SetPassword2(struct torture_context *tctx,
845 struct dcerpc_pipe *p,
846 struct cli_credentials *machine_credentials)
848 return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS);
851 static bool test_SetPassword2_AES(struct torture_context *tctx,
852 struct dcerpc_pipe *p,
853 struct cli_credentials *machine_credentials)
855 return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
858 static bool test_GetPassword(struct torture_context *tctx,
859 struct dcerpc_pipe *p,
860 struct cli_credentials *machine_credentials)
862 struct netr_ServerPasswordGet r;
863 struct netlogon_creds_CredentialState *creds;
864 struct netr_Authenticator credential;
866 struct netr_Authenticator return_authenticator;
867 struct samr_Password password;
868 struct dcerpc_binding_handle *b = p->binding_handle;
870 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
874 netlogon_creds_client_authenticator(creds, &credential);
876 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
877 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
878 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
879 r.in.computer_name = TEST_MACHINE_NAME;
880 r.in.credential = &credential;
881 r.out.return_authenticator = &return_authenticator;
882 r.out.password = &password;
884 status = dcerpc_netr_ServerPasswordGet_r(b, tctx, &r);
885 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
886 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordGet");
891 static bool test_GetTrustPasswords(struct torture_context *tctx,
892 struct dcerpc_pipe *p,
893 struct cli_credentials *machine_credentials)
895 struct netr_ServerTrustPasswordsGet r;
896 struct netlogon_creds_CredentialState *creds;
897 struct netr_Authenticator credential;
898 struct netr_Authenticator return_authenticator;
899 struct samr_Password password, password2;
900 struct dcerpc_binding_handle *b = p->binding_handle;
902 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
906 netlogon_creds_client_authenticator(creds, &credential);
908 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
909 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
910 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
911 r.in.computer_name = TEST_MACHINE_NAME;
912 r.in.credential = &credential;
913 r.out.return_authenticator = &return_authenticator;
914 r.out.new_owf_password = &password;
915 r.out.old_owf_password = &password2;
917 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerTrustPasswordsGet_r(b, tctx, &r),
918 "ServerTrustPasswordsGet failed");
919 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerTrustPasswordsGet failed");
925 try a netlogon SamLogon
927 static bool test_netlogon_ops_args(struct dcerpc_pipe *p, struct torture_context *tctx,
928 struct cli_credentials *credentials,
929 struct netlogon_creds_CredentialState *creds,
933 struct netr_LogonSamLogon r;
934 struct netr_Authenticator auth, auth2;
935 union netr_LogonLevel logon;
936 union netr_Validation validation;
937 uint8_t authoritative;
938 struct netr_NetworkInfo ninfo;
939 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
941 struct dcerpc_binding_handle *b = p->binding_handle;
942 int flags = CLI_CRED_NTLM_AUTH;
943 if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
944 flags |= CLI_CRED_LANMAN_AUTH;
947 if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx) && !null_domain) {
948 flags |= CLI_CRED_NTLMv2_AUTH;
951 cli_credentials_get_ntlm_username_domain(cmdline_credentials, tctx,
952 &ninfo.identity_info.account_name.string,
953 &ninfo.identity_info.domain_name.string);
956 ninfo.identity_info.domain_name.string = NULL;
959 generate_random_buffer(ninfo.challenge,
960 sizeof(ninfo.challenge));
961 chal = data_blob_const(ninfo.challenge,
962 sizeof(ninfo.challenge));
964 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials),
965 cli_credentials_get_domain(credentials));
967 status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx,
970 NULL, /* server_timestamp */
974 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
976 ninfo.lm.data = lm_resp.data;
977 ninfo.lm.length = lm_resp.length;
979 ninfo.nt.data = nt_resp.data;
980 ninfo.nt.length = nt_resp.length;
982 ninfo.identity_info.parameter_control = 0;
983 ninfo.identity_info.logon_id_low = 0;
984 ninfo.identity_info.logon_id_high = 0;
985 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
987 logon.network = &ninfo;
989 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
990 r.in.computer_name = cli_credentials_get_workstation(credentials);
991 r.in.credential = &auth;
992 r.in.return_authenticator = &auth2;
993 r.in.logon_level = NetlogonNetworkInformation;
995 r.out.validation = &validation;
996 r.out.authoritative = &authoritative;
998 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
1000 for (i=2;i<=3;i++) {
1002 netlogon_creds_client_authenticator(creds, &auth);
1004 r.in.validation_level = i;
1006 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1007 "LogonSamLogon failed");
1008 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
1010 torture_assert(tctx, netlogon_creds_client_check(creds,
1011 &r.out.return_authenticator->cred),
1012 "Credential chaining failed");
1013 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1014 "LogonSamLogon invalid *r.out.authoritative");
1017 /* this makes sure we get the unmarshalling right for invalid levels */
1018 for (i=52;i<53;i++) {
1020 /* the authenticator should be ignored by the server */
1021 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
1023 r.in.validation_level = i;
1025 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1026 "LogonSamLogon failed");
1027 torture_assert_ntstatus_equal(tctx, r.out.result,
1028 NT_STATUS_INVALID_INFO_CLASS,
1029 "LogonSamLogon failed");
1031 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1032 "LogonSamLogon invalid *r.out.authoritative");
1033 torture_assert(tctx,
1034 all_zero((uint8_t *)&auth2, sizeof(auth2)),
1035 "Return authenticator non zero");
1038 for (i=2;i<=3;i++) {
1040 netlogon_creds_client_authenticator(creds, &auth);
1042 r.in.validation_level = i;
1044 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1045 "LogonSamLogon failed");
1046 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
1048 torture_assert(tctx, netlogon_creds_client_check(creds,
1049 &r.out.return_authenticator->cred),
1050 "Credential chaining failed");
1051 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1052 "LogonSamLogon invalid *r.out.authoritative");
1055 r.in.logon_level = 52;
1057 for (i=2;i<=3;i++) {
1059 /* the authenticator should be ignored by the server */
1060 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
1062 r.in.validation_level = i;
1064 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
1066 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1067 "LogonSamLogon failed");
1068 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
1069 "LogonSamLogon expected INVALID_PARAMETER");
1071 torture_assert(tctx,
1072 all_zero((uint8_t *)&auth2, sizeof(auth2)),
1073 "Return authenticator non zero");
1074 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1075 "LogonSamLogon invalid *r.out.authoritative");
1078 r.in.credential = NULL;
1080 for (i=2;i<=3;i++) {
1083 r.in.validation_level = i;
1085 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
1087 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1088 "LogonSamLogon failed");
1089 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
1090 "LogonSamLogon expected INVALID_PARAMETER");
1092 torture_assert(tctx,
1093 all_zero((uint8_t *)&auth2, sizeof(auth2)),
1094 "Return authenticator non zero");
1095 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1096 "LogonSamLogon invalid *r.out.authoritative");
1099 r.in.logon_level = NetlogonNetworkInformation;
1100 r.in.credential = &auth;
1102 for (i=2;i<=3;i++) {
1104 netlogon_creds_client_authenticator(creds, &auth);
1106 r.in.validation_level = i;
1108 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1109 "LogonSamLogon failed");
1110 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
1112 torture_assert(tctx, netlogon_creds_client_check(creds,
1113 &r.out.return_authenticator->cred),
1114 "Credential chaining failed");
1115 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1116 "LogonSamLogon invalid *r.out.authoritative");
1122 bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
1123 struct cli_credentials *credentials,
1124 struct netlogon_creds_CredentialState *creds)
1126 return test_netlogon_ops_args(p, tctx, credentials, creds, false);
1130 try a netlogon GetCapabilities
1132 bool test_netlogon_capabilities(struct dcerpc_pipe *p, struct torture_context *tctx,
1133 struct cli_credentials *credentials,
1134 struct netlogon_creds_CredentialState *creds)
1137 struct netr_LogonGetCapabilities r;
1138 union netr_Capabilities capabilities;
1139 struct netr_Authenticator auth, return_auth;
1140 struct netlogon_creds_CredentialState tmp_creds;
1141 struct dcerpc_binding_handle *b = p->binding_handle;
1143 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1144 r.in.computer_name = cli_credentials_get_workstation(credentials);
1145 r.in.credential = &auth;
1146 r.in.return_authenticator = &return_auth;
1147 r.in.query_level = 1;
1148 r.out.capabilities = &capabilities;
1149 r.out.return_authenticator = &return_auth;
1151 torture_comment(tctx, "Testing LogonGetCapabilities\n");
1153 ZERO_STRUCT(return_auth);
1156 * we need to operate on a temporary copy of creds
1157 * because dcerpc_netr_LogonGetCapabilities was
1158 * dcerpc_netr_DummyFunction and returns NT_STATUS_NOT_IMPLEMENTED
1159 * without looking a the authenticator.
1162 netlogon_creds_client_authenticator(&tmp_creds, &auth);
1164 status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
1165 torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities failed");
1166 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
1172 torture_assert(tctx, netlogon_creds_client_check(creds,
1173 &r.out.return_authenticator->cred),
1174 "Credential chaining failed");
1176 torture_assert_int_equal(tctx, creds->negotiate_flags,
1177 capabilities.server_capabilities,
1184 try a netlogon SamLogon
1186 static bool test_SamLogon(struct torture_context *tctx,
1187 struct dcerpc_pipe *p,
1188 struct cli_credentials *credentials)
1190 struct netlogon_creds_CredentialState *creds;
1192 if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
1196 return test_netlogon_ops(p, tctx, credentials, creds);
1199 static bool test_invalidAuthenticate2(struct torture_context *tctx,
1200 struct dcerpc_pipe *p,
1201 struct cli_credentials *credentials)
1203 struct netlogon_creds_CredentialState *creds;
1204 uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
1206 torture_comment(tctx, "Testing invalidAuthenticate2\n");
1208 if (!test_SetupCredentials2(p, tctx, flags,
1210 cli_credentials_get_secure_channel_type(credentials),
1215 if (!test_SetupCredentials2ex(p, tctx, flags,
1218 cli_credentials_get_secure_channel_type(credentials),
1219 STATUS_BUFFER_OVERFLOW,
1224 if (!test_SetupCredentials2ex(p, tctx, flags,
1227 cli_credentials_get_secure_channel_type(credentials),
1236 static bool test_ServerReqChallengeGlobal(struct torture_context *tctx,
1237 struct dcerpc_pipe *p1,
1238 struct cli_credentials *machine_credentials)
1240 uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
1241 struct netr_ServerReqChallenge r;
1242 struct netr_ServerAuthenticate3 a;
1243 struct netr_Credential credentials1, credentials2, credentials3;
1244 struct netlogon_creds_CredentialState *creds;
1245 struct samr_Password mach_password;
1247 const char *machine_name;
1248 const char *plain_pass;
1249 struct dcerpc_binding_handle *b1 = p1->binding_handle;
1250 struct dcerpc_pipe *p2 = NULL;
1251 struct dcerpc_binding_handle *b2 = NULL;
1253 machine_name = cli_credentials_get_workstation(machine_credentials);
1254 plain_pass = cli_credentials_get_password(machine_credentials);
1256 torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
1258 torture_assert_ntstatus_ok(tctx,
1259 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
1260 &ndr_table_netlogon,
1261 machine_credentials,
1262 tctx->ev, tctx->lp_ctx),
1263 "dcerpc_pipe_connect_b failed");
1264 b2 = p2->binding_handle;
1266 r.in.server_name = NULL;
1267 r.in.computer_name = machine_name;
1268 r.in.credentials = &credentials1;
1269 r.out.return_credentials = &credentials2;
1271 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
1273 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
1274 "ServerReqChallenge failed on b1");
1275 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
1277 E_md4hash(plain_pass, mach_password.hash);
1279 a.in.server_name = NULL;
1280 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
1281 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1282 a.in.computer_name = machine_name;
1283 a.in.negotiate_flags = &flags;
1284 a.in.credentials = &credentials3;
1285 a.out.return_credentials = &credentials3;
1286 a.out.negotiate_flags = &flags;
1289 creds = netlogon_creds_client_init(tctx, a.in.account_name,
1291 a.in.secure_channel_type,
1292 &credentials1, &credentials2,
1293 &mach_password, &credentials3,
1296 torture_assert(tctx, creds != NULL, "memory allocation");
1298 torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
1300 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
1301 "ServerAuthenticate3 failed on b2");
1302 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
1303 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
1309 * Test the re-use of the challenge is not possible on a third
1310 * connection, after first useing it second one.
1313 static bool test_ServerReqChallengeReuseGlobal(struct torture_context *tctx,
1314 struct dcerpc_pipe *p1,
1315 struct cli_credentials *machine_credentials)
1317 uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
1318 struct netr_ServerReqChallenge r;
1319 struct netr_ServerAuthenticate3 a;
1320 struct netr_Credential credentials1, credentials2, credentials3;
1321 struct netlogon_creds_CredentialState *creds;
1322 struct samr_Password mach_password;
1324 const char *machine_name;
1325 const char *plain_pass;
1326 struct dcerpc_binding_handle *b1 = p1->binding_handle;
1327 struct dcerpc_pipe *p2 = NULL;
1328 struct dcerpc_binding_handle *b2 = NULL;
1329 struct dcerpc_pipe *p3 = NULL;
1330 struct dcerpc_binding_handle *b3 = NULL;
1332 machine_name = cli_credentials_get_workstation(machine_credentials);
1333 plain_pass = cli_credentials_get_password(machine_credentials);
1335 torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
1337 torture_assert_ntstatus_ok(tctx,
1338 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
1339 &ndr_table_netlogon,
1340 machine_credentials,
1341 tctx->ev, tctx->lp_ctx),
1342 "dcerpc_pipe_connect_b failed");
1343 b2 = p2->binding_handle;
1345 torture_assert_ntstatus_ok(tctx,
1346 dcerpc_pipe_connect_b(tctx, &p3, p1->binding,
1347 &ndr_table_netlogon,
1348 machine_credentials,
1349 tctx->ev, tctx->lp_ctx),
1350 "dcerpc_pipe_connect_b failed");
1351 b3 = p3->binding_handle;
1353 r.in.server_name = NULL;
1354 r.in.computer_name = machine_name;
1355 r.in.credentials = &credentials1;
1356 r.out.return_credentials = &credentials2;
1358 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
1360 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
1361 "ServerReqChallenge failed on b1");
1362 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
1364 E_md4hash(plain_pass, mach_password.hash);
1366 a.in.server_name = NULL;
1367 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
1368 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1369 a.in.computer_name = machine_name;
1370 a.in.negotiate_flags = &flags;
1371 a.in.credentials = &credentials3;
1372 a.out.return_credentials = &credentials3;
1373 a.out.negotiate_flags = &flags;
1376 creds = netlogon_creds_client_init(tctx, a.in.account_name,
1378 a.in.secure_channel_type,
1379 &credentials1, &credentials2,
1380 &mach_password, &credentials3,
1383 torture_assert(tctx, creds != NULL, "memory allocation");
1385 torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
1387 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
1388 "ServerAuthenticate3 failed on b2");
1389 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
1390 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
1392 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b3, tctx, &a),
1393 "ServerAuthenticate3 failed on b3");
1394 torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
1395 "ServerAuthenticate3 should have failed on b3, due to credential reuse");
1400 * Test if use of the per-pipe challenge will wipe out the globally cached challenge
1402 static bool test_ServerReqChallengeReuseGlobal2(struct torture_context *tctx,
1403 struct dcerpc_pipe *p1,
1404 struct cli_credentials *machine_credentials)
1406 uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
1407 struct netr_ServerReqChallenge r;
1408 struct netr_ServerAuthenticate3 a;
1409 struct netr_Credential credentials1, credentials2, credentials3;
1410 struct netlogon_creds_CredentialState *creds;
1411 struct samr_Password mach_password;
1413 const char *machine_name;
1414 const char *plain_pass;
1415 struct dcerpc_binding_handle *b1 = p1->binding_handle;
1416 struct dcerpc_pipe *p2 = NULL;
1417 struct dcerpc_binding_handle *b2 = NULL;
1419 machine_name = cli_credentials_get_workstation(machine_credentials);
1420 plain_pass = cli_credentials_get_password(machine_credentials);
1422 torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
1424 torture_assert_ntstatus_ok(tctx,
1425 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
1426 &ndr_table_netlogon,
1427 machine_credentials,
1428 tctx->ev, tctx->lp_ctx),
1429 "dcerpc_pipe_connect_b failed");
1430 b2 = p2->binding_handle;
1432 r.in.server_name = NULL;
1433 r.in.computer_name = machine_name;
1434 r.in.credentials = &credentials1;
1435 r.out.return_credentials = &credentials2;
1437 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
1439 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
1440 "ServerReqChallenge failed on b1");
1441 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
1443 E_md4hash(plain_pass, mach_password.hash);
1445 a.in.server_name = NULL;
1446 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
1447 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1448 a.in.computer_name = machine_name;
1449 a.in.negotiate_flags = &flags;
1450 a.in.credentials = &credentials3;
1451 a.out.return_credentials = &credentials3;
1452 a.out.negotiate_flags = &flags;
1455 creds = netlogon_creds_client_init(tctx, a.in.account_name,
1457 a.in.secure_channel_type,
1458 &credentials1, &credentials2,
1459 &mach_password, &credentials3,
1462 torture_assert(tctx, creds != NULL, "memory allocation");
1464 torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
1466 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
1467 "ServerAuthenticate3 failed on b");
1468 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b");
1469 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
1471 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
1472 "ServerAuthenticate3 failed on b2");
1473 torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
1474 "ServerAuthenticate3 should have failed on b2, due to credential reuse");
1478 static bool test_ServerReqChallengeReuse(struct torture_context *tctx,
1479 struct dcerpc_pipe *p,
1480 struct cli_credentials *machine_credentials)
1482 uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
1483 struct netr_ServerReqChallenge r;
1484 struct netr_ServerAuthenticate3 a;
1485 struct netr_Credential credentials1, credentials2, credentials3;
1486 struct netlogon_creds_CredentialState *creds;
1487 struct samr_Password mach_password;
1489 const char *machine_name;
1490 const char *plain_pass;
1491 struct dcerpc_binding_handle *b = p->binding_handle;
1493 machine_name = cli_credentials_get_workstation(machine_credentials);
1494 plain_pass = cli_credentials_get_password(machine_credentials);
1496 torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
1498 r.in.server_name = NULL;
1499 r.in.computer_name = machine_name;
1500 r.in.credentials = &credentials1;
1501 r.out.return_credentials = &credentials2;
1503 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
1505 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
1506 "ServerReqChallenge");
1507 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
1509 E_md4hash(plain_pass, mach_password.hash);
1511 a.in.server_name = NULL;
1512 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
1513 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1514 a.in.computer_name = machine_name;
1515 a.in.negotiate_flags = &flags;
1516 a.in.credentials = &credentials3;
1517 a.out.return_credentials = &credentials3;
1518 a.out.negotiate_flags = &flags;
1521 creds = netlogon_creds_client_init(tctx, a.in.account_name,
1523 a.in.secure_channel_type,
1524 &credentials1, &credentials2,
1525 &mach_password, &credentials3,
1528 torture_assert(tctx, creds != NULL, "memory allocation");
1530 torture_comment(tctx, "Testing ServerAuthenticate3\n");
1532 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
1533 "ServerAuthenticate3 failed");
1534 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed");
1535 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
1537 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
1538 "ServerAuthenticate3 failed");
1539 torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
1540 "ServerAuthenticate3 should have failed on b3, due to credential reuse");
1542 ZERO_STRUCT(credentials1.data);
1543 ZERO_STRUCT(credentials2.data);
1544 creds = netlogon_creds_client_init(tctx, a.in.account_name,
1546 a.in.secure_channel_type,
1547 &credentials1, &credentials2,
1548 &mach_password, &credentials3,
1551 torture_assert(tctx, creds != NULL, "memory allocation");
1553 torture_comment(tctx, "Testing ServerAuthenticate3 with zero'ed challenge\n");
1555 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
1556 "ServerAuthenticate3 failed");
1557 torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
1558 "ServerAuthenticate3 should have failed on b3, due to credential reuse");
1562 static bool test_SamLogon_NULL_domain(struct torture_context *tctx,
1563 struct dcerpc_pipe *p,
1564 struct cli_credentials *credentials)
1566 struct netlogon_creds_CredentialState *creds;
1568 if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
1572 return test_netlogon_ops_args(p, tctx, credentials, creds, true);
1575 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
1576 static uint64_t sequence_nums[3];
1579 try a netlogon DatabaseSync
1581 static bool test_DatabaseSync(struct torture_context *tctx,
1582 struct dcerpc_pipe *p,
1583 struct cli_credentials *machine_credentials)
1585 struct netr_DatabaseSync r;
1586 struct netlogon_creds_CredentialState *creds;
1587 const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
1589 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1590 struct netr_Authenticator credential, return_authenticator;
1591 struct dcerpc_binding_handle *b = p->binding_handle;
1593 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1597 ZERO_STRUCT(return_authenticator);
1599 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1600 r.in.computername = TEST_MACHINE_NAME;
1601 r.in.preferredmaximumlength = (uint32_t)-1;
1602 r.in.return_authenticator = &return_authenticator;
1603 r.out.delta_enum_array = &delta_enum_array;
1604 r.out.return_authenticator = &return_authenticator;
1606 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1608 uint32_t sync_context = 0;
1610 r.in.database_id = database_ids[i];
1611 r.in.sync_context = &sync_context;
1612 r.out.sync_context = &sync_context;
1614 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
1617 netlogon_creds_client_authenticator(creds, &credential);
1619 r.in.credential = &credential;
1621 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync_r(b, tctx, &r),
1622 "DatabaseSync failed");
1623 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1626 /* Native mode servers don't do this */
1627 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1630 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync");
1632 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1633 torture_comment(tctx, "Credential chaining failed\n");
1636 if (delta_enum_array &&
1637 delta_enum_array->num_deltas > 0 &&
1638 delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
1639 delta_enum_array->delta_enum[0].delta_union.domain) {
1640 sequence_nums[r.in.database_id] =
1641 delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
1642 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
1644 (unsigned long long)sequence_nums[r.in.database_id]);
1646 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1654 try a netlogon DatabaseDeltas
1656 static bool test_DatabaseDeltas(struct torture_context *tctx,
1657 struct dcerpc_pipe *p,
1658 struct cli_credentials *machine_credentials)
1660 struct netr_DatabaseDeltas r;
1661 struct netlogon_creds_CredentialState *creds;
1662 struct netr_Authenticator credential;
1663 struct netr_Authenticator return_authenticator;
1664 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1665 const uint32_t database_ids[] = {0, 1, 2};
1667 struct dcerpc_binding_handle *b = p->binding_handle;
1669 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1673 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1674 r.in.computername = TEST_MACHINE_NAME;
1675 r.in.preferredmaximumlength = (uint32_t)-1;
1676 ZERO_STRUCT(r.in.return_authenticator);
1677 r.out.return_authenticator = &return_authenticator;
1678 r.out.delta_enum_array = &delta_enum_array;
1680 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1681 r.in.database_id = database_ids[i];
1682 r.in.sequence_num = &sequence_nums[r.in.database_id];
1684 if (*r.in.sequence_num == 0) continue;
1686 *r.in.sequence_num -= 1;
1688 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n",
1689 r.in.database_id, (unsigned long long)*r.in.sequence_num);
1692 netlogon_creds_client_authenticator(creds, &credential);
1694 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseDeltas_r(b, tctx, &r),
1695 "DatabaseDeltas failed");
1696 if (NT_STATUS_EQUAL(r.out.result,
1697 NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
1698 torture_comment(tctx, "not considering %s to be an error\n",
1699 nt_errstr(r.out.result));
1702 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1705 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseDeltas");
1707 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1708 torture_comment(tctx, "Credential chaining failed\n");
1711 (*r.in.sequence_num)++;
1712 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1718 static bool test_DatabaseRedo(struct torture_context *tctx,
1719 struct dcerpc_pipe *p,
1720 struct cli_credentials *machine_credentials)
1722 struct netr_DatabaseRedo r;
1723 struct netlogon_creds_CredentialState *creds;
1724 struct netr_Authenticator credential;
1725 struct netr_Authenticator return_authenticator;
1726 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1727 struct netr_ChangeLogEntry e;
1728 struct dom_sid null_sid, *sid;
1730 struct dcerpc_binding_handle *b = p->binding_handle;
1732 ZERO_STRUCT(null_sid);
1734 sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
1745 NTSTATUS expected_error;
1746 uint32_t expected_num_results;
1747 uint8_t expected_delta_type_1;
1748 uint8_t expected_delta_type_2;
1749 const char *comment;
1752 /* SAM_DATABASE_DOMAIN */
1757 .db_index = SAM_DATABASE_DOMAIN,
1758 .delta_type = NETR_DELTA_MODIFY_COUNT,
1761 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1762 .expected_num_results = 0,
1763 .comment = "NETR_DELTA_MODIFY_COUNT"
1768 .db_index = SAM_DATABASE_DOMAIN,
1772 .expected_error = NT_STATUS_OK,
1773 .expected_num_results = 1,
1774 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1775 .comment = "NULL DELTA"
1780 .db_index = SAM_DATABASE_DOMAIN,
1781 .delta_type = NETR_DELTA_DOMAIN,
1784 .expected_error = NT_STATUS_OK,
1785 .expected_num_results = 1,
1786 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1787 .comment = "NETR_DELTA_DOMAIN"
1790 .rid = DOMAIN_RID_ADMINISTRATOR,
1792 .db_index = SAM_DATABASE_DOMAIN,
1793 .delta_type = NETR_DELTA_USER,
1796 .expected_error = NT_STATUS_OK,
1797 .expected_num_results = 1,
1798 .expected_delta_type_1 = NETR_DELTA_USER,
1799 .comment = "NETR_DELTA_USER by rid 500"
1802 .rid = DOMAIN_RID_GUEST,
1804 .db_index = SAM_DATABASE_DOMAIN,
1805 .delta_type = NETR_DELTA_USER,
1808 .expected_error = NT_STATUS_OK,
1809 .expected_num_results = 1,
1810 .expected_delta_type_1 = NETR_DELTA_USER,
1811 .comment = "NETR_DELTA_USER by rid 501"
1815 .flags = NETR_CHANGELOG_SID_INCLUDED,
1816 .db_index = SAM_DATABASE_DOMAIN,
1817 .delta_type = NETR_DELTA_USER,
1820 .expected_error = NT_STATUS_OK,
1821 .expected_num_results = 1,
1822 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1823 .comment = "NETR_DELTA_USER by sid and flags"
1827 .flags = NETR_CHANGELOG_SID_INCLUDED,
1828 .db_index = SAM_DATABASE_DOMAIN,
1829 .delta_type = NETR_DELTA_USER,
1832 .expected_error = NT_STATUS_OK,
1833 .expected_num_results = 1,
1834 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1835 .comment = "NETR_DELTA_USER by null_sid and flags"
1839 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1840 .db_index = SAM_DATABASE_DOMAIN,
1841 .delta_type = NETR_DELTA_USER,
1843 .name = "administrator",
1844 .expected_error = NT_STATUS_OK,
1845 .expected_num_results = 1,
1846 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1847 .comment = "NETR_DELTA_USER by name 'administrator'"
1850 .rid = DOMAIN_RID_ADMINS,
1852 .db_index = SAM_DATABASE_DOMAIN,
1853 .delta_type = NETR_DELTA_GROUP,
1856 .expected_error = NT_STATUS_OK,
1857 .expected_num_results = 2,
1858 .expected_delta_type_1 = NETR_DELTA_GROUP,
1859 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
1860 .comment = "NETR_DELTA_GROUP by rid 512"
1863 .rid = DOMAIN_RID_ADMINS,
1865 .db_index = SAM_DATABASE_DOMAIN,
1866 .delta_type = NETR_DELTA_GROUP_MEMBER,
1869 .expected_error = NT_STATUS_OK,
1870 .expected_num_results = 2,
1871 .expected_delta_type_1 = NETR_DELTA_GROUP,
1872 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
1873 .comment = "NETR_DELTA_GROUP_MEMBER by rid 512"
1877 /* SAM_DATABASE_BUILTIN */
1882 .db_index = SAM_DATABASE_BUILTIN,
1883 .delta_type = NETR_DELTA_MODIFY_COUNT,
1886 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1887 .expected_num_results = 0,
1888 .comment = "NETR_DELTA_MODIFY_COUNT"
1893 .db_index = SAM_DATABASE_BUILTIN,
1894 .delta_type = NETR_DELTA_DOMAIN,
1897 .expected_error = NT_STATUS_OK,
1898 .expected_num_results = 1,
1899 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1900 .comment = "NETR_DELTA_DOMAIN"
1903 .rid = DOMAIN_RID_ADMINISTRATOR,
1905 .db_index = SAM_DATABASE_BUILTIN,
1906 .delta_type = NETR_DELTA_USER,
1909 .expected_error = NT_STATUS_OK,
1910 .expected_num_results = 1,
1911 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1912 .comment = "NETR_DELTA_USER by rid 500"
1917 .db_index = SAM_DATABASE_BUILTIN,
1918 .delta_type = NETR_DELTA_USER,
1921 .expected_error = NT_STATUS_OK,
1922 .expected_num_results = 1,
1923 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1924 .comment = "NETR_DELTA_USER"
1929 .db_index = SAM_DATABASE_BUILTIN,
1930 .delta_type = NETR_DELTA_ALIAS,
1933 .expected_error = NT_STATUS_OK,
1934 .expected_num_results = 2,
1935 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1936 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1937 .comment = "NETR_DELTA_ALIAS by rid 544"
1942 .db_index = SAM_DATABASE_BUILTIN,
1943 .delta_type = NETR_DELTA_ALIAS_MEMBER,
1946 .expected_error = NT_STATUS_OK,
1947 .expected_num_results = 2,
1948 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1949 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1950 .comment = "NETR_DELTA_ALIAS_MEMBER by rid 544"
1955 .db_index = SAM_DATABASE_BUILTIN,
1959 .expected_error = NT_STATUS_OK,
1960 .expected_num_results = 1,
1961 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1962 .comment = "NULL DELTA by rid 544"
1966 .flags = NETR_CHANGELOG_SID_INCLUDED,
1967 .db_index = SAM_DATABASE_BUILTIN,
1969 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1971 .expected_error = NT_STATUS_OK,
1972 .expected_num_results = 1,
1973 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1974 .comment = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
1978 .flags = NETR_CHANGELOG_SID_INCLUDED,
1979 .db_index = SAM_DATABASE_BUILTIN,
1980 .delta_type = NETR_DELTA_ALIAS,
1981 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1983 .expected_error = NT_STATUS_OK,
1984 .expected_num_results = 2,
1985 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1986 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1987 .comment = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
1991 .flags = NETR_CHANGELOG_SID_INCLUDED,
1992 .db_index = SAM_DATABASE_BUILTIN,
1993 .delta_type = NETR_DELTA_ALIAS,
1994 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1996 .expected_error = NT_STATUS_OK,
1997 .expected_num_results = 1,
1998 .expected_delta_type_1 = NETR_DELTA_DELETE_ALIAS,
1999 .comment = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
2002 /* SAM_DATABASE_PRIVS */
2007 .db_index = SAM_DATABASE_PRIVS,
2011 .expected_error = NT_STATUS_ACCESS_DENIED,
2012 .expected_num_results = 0,
2013 .comment = "NULL DELTA"
2018 .db_index = SAM_DATABASE_PRIVS,
2019 .delta_type = NETR_DELTA_MODIFY_COUNT,
2022 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
2023 .expected_num_results = 0,
2024 .comment = "NETR_DELTA_MODIFY_COUNT"
2029 .db_index = SAM_DATABASE_PRIVS,
2030 .delta_type = NETR_DELTA_POLICY,
2033 .expected_error = NT_STATUS_OK,
2034 .expected_num_results = 1,
2035 .expected_delta_type_1 = NETR_DELTA_POLICY,
2036 .comment = "NETR_DELTA_POLICY"
2040 .flags = NETR_CHANGELOG_SID_INCLUDED,
2041 .db_index = SAM_DATABASE_PRIVS,
2042 .delta_type = NETR_DELTA_POLICY,
2045 .expected_error = NT_STATUS_OK,
2046 .expected_num_results = 1,
2047 .expected_delta_type_1 = NETR_DELTA_POLICY,
2048 .comment = "NETR_DELTA_POLICY by null sid and flags"
2052 .flags = NETR_CHANGELOG_SID_INCLUDED,
2053 .db_index = SAM_DATABASE_PRIVS,
2054 .delta_type = NETR_DELTA_POLICY,
2055 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
2057 .expected_error = NT_STATUS_OK,
2058 .expected_num_results = 1,
2059 .expected_delta_type_1 = NETR_DELTA_POLICY,
2060 .comment = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
2063 .rid = DOMAIN_RID_ADMINISTRATOR,
2065 .db_index = SAM_DATABASE_PRIVS,
2066 .delta_type = NETR_DELTA_ACCOUNT,
2069 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
2070 .expected_num_results = 0,
2071 .comment = "NETR_DELTA_ACCOUNT by rid 500"
2075 .flags = NETR_CHANGELOG_SID_INCLUDED,
2076 .db_index = SAM_DATABASE_PRIVS,
2077 .delta_type = NETR_DELTA_ACCOUNT,
2078 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
2080 .expected_error = NT_STATUS_OK,
2081 .expected_num_results = 1,
2082 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
2083 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
2087 .flags = NETR_CHANGELOG_SID_INCLUDED |
2088 NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
2089 .db_index = SAM_DATABASE_PRIVS,
2090 .delta_type = NETR_DELTA_ACCOUNT,
2091 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
2093 .expected_error = NT_STATUS_OK,
2094 .expected_num_results = 1,
2095 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
2096 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
2100 .flags = NETR_CHANGELOG_SID_INCLUDED |
2101 NETR_CHANGELOG_NAME_INCLUDED,
2102 .db_index = SAM_DATABASE_PRIVS,
2103 .delta_type = NETR_DELTA_ACCOUNT,
2104 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
2106 .expected_error = NT_STATUS_INVALID_PARAMETER,
2107 .expected_num_results = 0,
2108 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
2111 .rid = DOMAIN_RID_ADMINISTRATOR,
2112 .flags = NETR_CHANGELOG_SID_INCLUDED,
2113 .db_index = SAM_DATABASE_PRIVS,
2114 .delta_type = NETR_DELTA_ACCOUNT,
2117 .expected_error = NT_STATUS_OK,
2118 .expected_num_results = 1,
2119 .expected_delta_type_1 = NETR_DELTA_DELETE_ACCOUNT,
2120 .comment = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
2124 .flags = NETR_CHANGELOG_NAME_INCLUDED,
2125 .db_index = SAM_DATABASE_PRIVS,
2126 .delta_type = NETR_DELTA_SECRET,
2128 .name = "IsurelydontexistIhope",
2129 .expected_error = NT_STATUS_OK,
2130 .expected_num_results = 1,
2131 .expected_delta_type_1 = NETR_DELTA_DELETE_SECRET,
2132 .comment = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
2136 .flags = NETR_CHANGELOG_NAME_INCLUDED,
2137 .db_index = SAM_DATABASE_PRIVS,
2138 .delta_type = NETR_DELTA_SECRET,
2140 .name = "G$BCKUPKEY_P",
2141 .expected_error = NT_STATUS_OK,
2142 .expected_num_results = 1,
2143 .expected_delta_type_1 = NETR_DELTA_SECRET,
2144 .comment = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
2148 ZERO_STRUCT(return_authenticator);
2150 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2151 r.in.computername = TEST_MACHINE_NAME;
2152 r.in.return_authenticator = &return_authenticator;
2153 r.out.return_authenticator = &return_authenticator;
2154 r.out.delta_enum_array = &delta_enum_array;
2156 for (d=0; d<3; d++) {
2157 const char *database = NULL;
2164 database = "BUILTIN";
2173 torture_comment(tctx, "Testing DatabaseRedo\n");
2175 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2179 for (i=0;i<ARRAY_SIZE(changes);i++) {
2181 if (d != changes[i].db_index) {
2185 netlogon_creds_client_authenticator(creds, &credential);
2187 r.in.credential = &credential;
2189 e.serial_number1 = 0;
2190 e.serial_number2 = 0;
2191 e.object_rid = changes[i].rid;
2192 e.flags = changes[i].flags;
2193 e.db_index = changes[i].db_index;
2194 e.delta_type = changes[i].delta_type;
2196 switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
2197 case NETR_CHANGELOG_SID_INCLUDED:
2198 e.object.object_sid = changes[i].sid;
2200 case NETR_CHANGELOG_NAME_INCLUDED:
2201 e.object.object_name = changes[i].name;
2207 r.in.change_log_entry = e;
2209 torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
2210 database, changes[i].comment);
2212 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseRedo_r(b, tctx, &r),
2213 "DatabaseRedo failed");
2214 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
2218 torture_assert_ntstatus_equal(tctx, r.out.result, changes[i].expected_error, changes[i].comment);
2219 if (delta_enum_array) {
2220 torture_assert_int_equal(tctx,
2221 delta_enum_array->num_deltas,
2222 changes[i].expected_num_results,
2223 changes[i].comment);
2224 if (delta_enum_array->num_deltas > 0) {
2225 torture_assert_int_equal(tctx,
2226 delta_enum_array->delta_enum[0].delta_type,
2227 changes[i].expected_delta_type_1,
2228 changes[i].comment);
2230 if (delta_enum_array->num_deltas > 1) {
2231 torture_assert_int_equal(tctx,
2232 delta_enum_array->delta_enum[1].delta_type,
2233 changes[i].expected_delta_type_2,
2234 changes[i].comment);
2238 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
2239 torture_comment(tctx, "Credential chaining failed\n");
2240 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2252 try a netlogon AccountDeltas
2254 static bool test_AccountDeltas(struct torture_context *tctx,
2255 struct dcerpc_pipe *p,
2256 struct cli_credentials *machine_credentials)
2258 struct netr_AccountDeltas r;
2259 struct netlogon_creds_CredentialState *creds;
2261 struct netr_AccountBuffer buffer;
2262 uint32_t count_returned = 0;
2263 uint32_t total_entries = 0;
2264 struct netr_UAS_INFO_0 recordid;
2265 struct netr_Authenticator return_authenticator;
2266 struct dcerpc_binding_handle *b = p->binding_handle;
2268 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2272 ZERO_STRUCT(return_authenticator);
2274 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2275 r.in.computername = TEST_MACHINE_NAME;
2276 r.in.return_authenticator = &return_authenticator;
2277 netlogon_creds_client_authenticator(creds, &r.in.credential);
2278 ZERO_STRUCT(r.in.uas);
2281 r.in.buffersize=100;
2282 r.out.buffer = &buffer;
2283 r.out.count_returned = &count_returned;
2284 r.out.total_entries = &total_entries;
2285 r.out.recordid = &recordid;
2286 r.out.return_authenticator = &return_authenticator;
2288 /* w2k3 returns "NOT IMPLEMENTED" for this call */
2289 torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountDeltas_r(b, tctx, &r),
2290 "AccountDeltas failed");
2291 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
2297 try a netlogon AccountSync
2299 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
2300 struct cli_credentials *machine_credentials)
2302 struct netr_AccountSync r;
2303 struct netlogon_creds_CredentialState *creds;
2305 struct netr_AccountBuffer buffer;
2306 uint32_t count_returned = 0;
2307 uint32_t total_entries = 0;
2308 uint32_t next_reference = 0;
2309 struct netr_UAS_INFO_0 recordid;
2310 struct netr_Authenticator return_authenticator;
2311 struct dcerpc_binding_handle *b = p->binding_handle;
2313 ZERO_STRUCT(recordid);
2314 ZERO_STRUCT(return_authenticator);
2316 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2320 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2321 r.in.computername = TEST_MACHINE_NAME;
2322 r.in.return_authenticator = &return_authenticator;
2323 netlogon_creds_client_authenticator(creds, &r.in.credential);
2324 r.in.recordid = &recordid;
2327 r.in.buffersize=100;
2328 r.out.buffer = &buffer;
2329 r.out.count_returned = &count_returned;
2330 r.out.total_entries = &total_entries;
2331 r.out.next_reference = &next_reference;
2332 r.out.recordid = &recordid;
2333 r.out.return_authenticator = &return_authenticator;
2335 /* w2k3 returns "NOT IMPLEMENTED" for this call */
2336 torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountSync_r(b, tctx, &r),
2337 "AccountSync failed");
2338 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
2344 try a netlogon GetDcName
2346 static bool test_GetDcName(struct torture_context *tctx,
2347 struct dcerpc_pipe *p)
2349 struct netr_GetDcName r;
2350 const char *dcname = NULL;
2351 struct dcerpc_binding_handle *b = p->binding_handle;
2353 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2354 r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
2355 r.out.dcname = &dcname;
2357 torture_assert_ntstatus_ok(tctx, dcerpc_netr_GetDcName_r(b, tctx, &r),
2358 "GetDcName failed");
2359 torture_assert_werr_ok(tctx, r.out.result, "GetDcName failed");
2361 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
2366 static const char *function_code_str(TALLOC_CTX *mem_ctx,
2367 enum netr_LogonControlCode function_code)
2369 switch (function_code) {
2370 case NETLOGON_CONTROL_QUERY:
2371 return "NETLOGON_CONTROL_QUERY";
2372 case NETLOGON_CONTROL_REPLICATE:
2373 return "NETLOGON_CONTROL_REPLICATE";
2374 case NETLOGON_CONTROL_SYNCHRONIZE:
2375 return "NETLOGON_CONTROL_SYNCHRONIZE";
2376 case NETLOGON_CONTROL_PDC_REPLICATE:
2377 return "NETLOGON_CONTROL_PDC_REPLICATE";
2378 case NETLOGON_CONTROL_REDISCOVER:
2379 return "NETLOGON_CONTROL_REDISCOVER";
2380 case NETLOGON_CONTROL_TC_QUERY:
2381 return "NETLOGON_CONTROL_TC_QUERY";
2382 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
2383 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
2384 case NETLOGON_CONTROL_FIND_USER:
2385 return "NETLOGON_CONTROL_FIND_USER";
2386 case NETLOGON_CONTROL_CHANGE_PASSWORD:
2387 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
2388 case NETLOGON_CONTROL_TC_VERIFY:
2389 return "NETLOGON_CONTROL_TC_VERIFY";
2390 case NETLOGON_CONTROL_FORCE_DNS_REG:
2391 return "NETLOGON_CONTROL_FORCE_DNS_REG";
2392 case NETLOGON_CONTROL_QUERY_DNS_REG:
2393 return "NETLOGON_CONTROL_QUERY_DNS_REG";
2394 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
2395 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
2396 case NETLOGON_CONTROL_TRUNCATE_LOG:
2397 return "NETLOGON_CONTROL_TRUNCATE_LOG";
2398 case NETLOGON_CONTROL_SET_DBFLAG:
2399 return "NETLOGON_CONTROL_SET_DBFLAG";
2400 case NETLOGON_CONTROL_BREAKPOINT:
2401 return "NETLOGON_CONTROL_BREAKPOINT";
2403 return talloc_asprintf(mem_ctx, "unknown function code: %d",
2410 try a netlogon LogonControl
2412 static bool test_LogonControl(struct torture_context *tctx,
2413 struct dcerpc_pipe *p,
2414 struct cli_credentials *machine_credentials)
2418 struct netr_LogonControl r;
2419 union netr_CONTROL_QUERY_INFORMATION query;
2421 enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
2422 struct dcerpc_binding_handle *b = p->binding_handle;
2424 uint32_t function_codes[] = {
2425 NETLOGON_CONTROL_QUERY,
2426 NETLOGON_CONTROL_REPLICATE,
2427 NETLOGON_CONTROL_SYNCHRONIZE,
2428 NETLOGON_CONTROL_PDC_REPLICATE,
2429 NETLOGON_CONTROL_REDISCOVER,
2430 NETLOGON_CONTROL_TC_QUERY,
2431 NETLOGON_CONTROL_TRANSPORT_NOTIFY,
2432 NETLOGON_CONTROL_FIND_USER,
2433 NETLOGON_CONTROL_CHANGE_PASSWORD,
2434 NETLOGON_CONTROL_TC_VERIFY,
2435 NETLOGON_CONTROL_FORCE_DNS_REG,
2436 NETLOGON_CONTROL_QUERY_DNS_REG,
2437 NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
2438 NETLOGON_CONTROL_TRUNCATE_LOG,
2439 NETLOGON_CONTROL_SET_DBFLAG,
2440 NETLOGON_CONTROL_BREAKPOINT
2443 if (machine_credentials) {
2444 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2447 torture_comment(tctx, "Testing LogonControl with secure channel type: %d\n",
2448 secure_channel_type);
2450 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2451 r.in.function_code = 1;
2452 r.out.query = &query;
2454 for (f=0;f<ARRAY_SIZE(function_codes); f++) {
2457 r.in.function_code = function_codes[f];
2460 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
2461 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2463 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
2464 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2466 switch (r.in.level) {
2468 switch (r.in.function_code) {
2469 case NETLOGON_CONTROL_REPLICATE:
2470 case NETLOGON_CONTROL_SYNCHRONIZE:
2471 case NETLOGON_CONTROL_PDC_REPLICATE:
2472 case NETLOGON_CONTROL_BREAKPOINT:
2473 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
2474 if ((secure_channel_type == SEC_CHAN_BDC) ||
2475 (secure_channel_type == SEC_CHAN_WKSTA)) {
2476 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
2477 "LogonControl returned unexpected error code");
2479 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
2480 "LogonControl returned unexpected error code");
2484 case NETLOGON_CONTROL_REDISCOVER:
2485 case NETLOGON_CONTROL_TC_QUERY:
2486 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
2487 case NETLOGON_CONTROL_FIND_USER:
2488 case NETLOGON_CONTROL_CHANGE_PASSWORD:
2489 case NETLOGON_CONTROL_TC_VERIFY:
2490 case NETLOGON_CONTROL_FORCE_DNS_REG:
2491 case NETLOGON_CONTROL_QUERY_DNS_REG:
2492 case NETLOGON_CONTROL_SET_DBFLAG:
2493 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
2494 "LogonControl returned unexpected error code");
2496 case NETLOGON_CONTROL_TRUNCATE_LOG:
2497 if ((secure_channel_type == SEC_CHAN_BDC) ||
2498 (secure_channel_type == SEC_CHAN_WKSTA)) {
2499 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
2500 "LogonControl returned unexpected error code");
2501 } else if (!W_ERROR_EQUAL(r.out.result, WERR_NOT_SUPPORTED)) {
2502 torture_assert_werr_ok(tctx, r.out.result,
2503 "LogonControl returned unexpected result");
2507 torture_assert_werr_ok(tctx, r.out.result,
2508 "LogonControl returned unexpected result");
2513 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
2514 "LogonControl returned unexpected error code");
2517 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL,
2518 "LogonControl returned unexpected error code");
2525 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
2526 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2527 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
2528 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2529 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl");
2536 try a netlogon GetAnyDCName
2538 static bool test_GetAnyDCName(struct torture_context *tctx,
2539 struct dcerpc_pipe *p)
2542 struct netr_GetAnyDCName r;
2543 const char *dcname = NULL;
2544 struct dcerpc_binding_handle *b = p->binding_handle;
2546 r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
2547 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2548 r.out.dcname = &dcname;
2550 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2551 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2552 if ((!W_ERROR_IS_OK(r.out.result)) &&
2553 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2558 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
2561 r.in.domainname = NULL;
2563 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2564 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2565 if ((!W_ERROR_IS_OK(r.out.result)) &&
2566 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2570 r.in.domainname = "";
2572 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2573 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2574 if ((!W_ERROR_IS_OK(r.out.result)) &&
2575 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2584 try a netlogon LogonControl2
2586 static bool test_LogonControl2(struct torture_context *tctx,
2587 struct dcerpc_pipe *p,
2588 struct cli_credentials *machine_credentials)
2592 struct netr_LogonControl2 r;
2593 union netr_CONTROL_DATA_INFORMATION data;
2594 union netr_CONTROL_QUERY_INFORMATION query;
2595 enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
2597 struct dcerpc_binding_handle *b = p->binding_handle;
2599 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2601 if (machine_credentials) {
2602 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2605 torture_comment(tctx, "Testing LogonControl2 with secure channel type: %d\n",
2606 secure_channel_type);
2608 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2610 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2612 r.out.query = &query;
2617 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2618 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2620 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2621 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2624 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2626 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2632 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2633 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2635 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2636 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2639 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2641 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2647 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2648 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2650 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2651 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2654 data.debug_level = ~0;
2656 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2662 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2663 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2665 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2666 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2670 r.in.function_code = 52;
2673 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2674 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2676 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2677 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2678 switch (secure_channel_type) {
2680 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2");
2683 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2");
2686 data.debug_level = ~0;
2688 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2692 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2693 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2695 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2696 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2697 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl2");
2703 try a netlogon DatabaseSync2
2705 static bool test_DatabaseSync2(struct torture_context *tctx,
2706 struct dcerpc_pipe *p,
2707 struct cli_credentials *machine_credentials)
2709 struct netr_DatabaseSync2 r;
2710 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2711 struct netr_Authenticator return_authenticator, credential;
2713 struct netlogon_creds_CredentialState *creds;
2714 const uint32_t database_ids[] = {0, 1, 2};
2716 struct dcerpc_binding_handle *b = p->binding_handle;
2718 if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
2719 machine_credentials,
2720 cli_credentials_get_secure_channel_type(machine_credentials),
2725 ZERO_STRUCT(return_authenticator);
2727 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2728 r.in.computername = TEST_MACHINE_NAME;
2729 r.in.preferredmaximumlength = (uint32_t)-1;
2730 r.in.return_authenticator = &return_authenticator;
2731 r.out.return_authenticator = &return_authenticator;
2732 r.out.delta_enum_array = &delta_enum_array;
2734 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2736 uint32_t sync_context = 0;
2738 r.in.database_id = database_ids[i];
2739 r.in.sync_context = &sync_context;
2740 r.out.sync_context = &sync_context;
2741 r.in.restart_state = 0;
2743 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
2746 netlogon_creds_client_authenticator(creds, &credential);
2748 r.in.credential = &credential;
2750 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync2_r(b, tctx, &r),
2751 "DatabaseSync2 failed");
2752 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2755 /* Native mode servers don't do this */
2756 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
2760 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync2");
2762 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
2763 torture_comment(tctx, "Credential chaining failed\n");
2766 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2774 try a netlogon LogonControl2Ex
2776 static bool test_LogonControl2Ex(struct torture_context *tctx,
2777 struct dcerpc_pipe *p,
2778 struct cli_credentials *machine_credentials)
2782 struct netr_LogonControl2Ex r;
2783 union netr_CONTROL_DATA_INFORMATION data;
2784 union netr_CONTROL_QUERY_INFORMATION query;
2785 enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
2787 struct dcerpc_binding_handle *b = p->binding_handle;
2789 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2791 if (machine_credentials) {
2792 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2795 torture_comment(tctx, "Testing LogonControl2Ex with secure channel type: %d\n",
2796 secure_channel_type);
2798 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2800 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2802 r.out.query = &query;
2807 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2808 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2810 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2811 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2814 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2816 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2822 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2823 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2825 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2826 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2829 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2831 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2837 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2838 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2840 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2841 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2844 data.debug_level = ~0;
2846 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2852 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2853 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2855 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2856 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2860 r.in.function_code = 52;
2863 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2864 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2866 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2867 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2868 switch (secure_channel_type) {
2870 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2Ex");
2873 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2Ex");
2876 data.debug_level = ~0;
2878 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2882 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2883 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2885 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2886 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2887 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl2Ex");
2892 static bool test_netr_GetForestTrustInformation(struct torture_context *tctx,
2893 struct dcerpc_pipe *p1,
2894 struct cli_credentials *machine_credentials)
2896 struct netr_GetForestTrustInformation r;
2897 struct netlogon_creds_CredentialState *creds;
2898 struct netr_Authenticator a;
2899 struct netr_Authenticator return_authenticator;
2900 struct lsa_ForestTrustInformation *forest_trust_info;
2901 struct dcerpc_pipe *p = NULL;
2902 struct dcerpc_binding_handle *b = NULL;
2904 if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2905 machine_credentials, &creds)) {
2908 if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
2909 DCERPC_SIGN | DCERPC_SEAL, &p)) {
2912 b = p->binding_handle;
2914 netlogon_creds_client_authenticator(creds, &a);
2916 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2917 r.in.computer_name = TEST_MACHINE_NAME;
2918 r.in.credential = &a;
2920 r.out.return_authenticator = &return_authenticator;
2921 r.out.forest_trust_info = &forest_trust_info;
2923 torture_assert_ntstatus_ok(tctx,
2924 dcerpc_netr_GetForestTrustInformation_r(b, tctx, &r),
2925 "netr_GetForestTrustInformation failed");
2926 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2927 torture_comment(tctx, "not considering NT_STATUS_NOT_IMPLEMENTED as an error\n");
2929 torture_assert_ntstatus_ok(tctx, r.out.result,
2930 "netr_GetForestTrustInformation failed");
2933 torture_assert(tctx,
2934 netlogon_creds_client_check(creds, &return_authenticator.cred),
2935 "Credential chaining failed");
2940 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
2941 struct dcerpc_pipe *p, const char *trusted_domain_name)
2944 struct netr_DsRGetForestTrustInformation r;
2945 struct lsa_ForestTrustInformation info, *info_ptr;
2946 struct dcerpc_binding_handle *b = p->binding_handle;
2950 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2951 r.in.trusted_domain_name = trusted_domain_name;
2953 r.out.forest_trust_info = &info_ptr;
2955 torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
2957 status = dcerpc_netr_DsRGetForestTrustInformation_r(b, tctx, &r);
2958 torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
2959 torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
2965 try a netlogon netr_DsrEnumerateDomainTrusts
2967 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
2968 struct dcerpc_pipe *p)
2971 struct netr_DsrEnumerateDomainTrusts r;
2972 struct netr_DomainTrustList trusts;
2974 struct dcerpc_binding_handle *b = p->binding_handle;
2976 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2977 r.in.trust_flags = 0x3f;
2978 r.out.trusts = &trusts;
2980 status = dcerpc_netr_DsrEnumerateDomainTrusts_r(b, tctx, &r);
2981 torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
2982 torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
2984 /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
2985 * will show non-forest trusts and all UPN suffixes of the own forest
2986 * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
2988 if (r.out.trusts->count) {
2989 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
2994 for (i=0; i<r.out.trusts->count; i++) {
2996 /* get info for transitive forest trusts */
2998 if (r.out.trusts->array[i].trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2999 if (!test_netr_DsRGetForestTrustInformation(tctx, p,
3000 r.out.trusts->array[i].dns_name)) {
3009 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
3010 struct dcerpc_pipe *p)
3013 struct netr_NetrEnumerateTrustedDomains r;
3014 struct netr_Blob trusted_domains_blob;
3015 struct dcerpc_binding_handle *b = p->binding_handle;
3017 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3018 r.out.trusted_domains_blob = &trusted_domains_blob;
3020 status = dcerpc_netr_NetrEnumerateTrustedDomains_r(b, tctx, &r);
3021 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
3022 torture_assert_ntstatus_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
3027 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
3028 struct dcerpc_pipe *p)
3031 struct netr_NetrEnumerateTrustedDomainsEx r;
3032 struct netr_DomainTrustList dom_trust_list;
3033 struct dcerpc_binding_handle *b = p->binding_handle;
3035 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3036 r.out.dom_trust_list = &dom_trust_list;
3038 status = dcerpc_netr_NetrEnumerateTrustedDomainsEx_r(b, tctx, &r);
3039 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
3040 torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
3046 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
3047 const char *computer_name,
3048 const char *expected_site)
3051 struct netr_DsRGetSiteName r;
3052 const char *site = NULL;
3053 struct dcerpc_binding_handle *b = p->binding_handle;
3055 r.in.computer_name = computer_name;
3057 torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
3059 status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
3060 torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
3061 torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
3062 torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
3068 try a netlogon netr_DsRGetDCName
3070 static bool test_netr_DsRGetDCName(struct torture_context *tctx,
3071 struct dcerpc_pipe *p)
3074 struct netr_DsRGetDCName r;
3075 struct netr_DsRGetDCNameInfo *info = NULL;
3076 struct dcerpc_binding_handle *b = p->binding_handle;
3078 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3079 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
3080 r.in.domain_guid = NULL;
3081 r.in.site_guid = NULL;
3082 r.in.flags = DS_RETURN_DNS_NAME;
3085 status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
3086 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
3087 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
3089 torture_assert_int_equal(tctx,
3090 (info->dc_flags & (DS_DNS_CONTROLLER)),
3093 torture_assert_int_equal(tctx,
3094 (info->dc_flags & (DS_DNS_DOMAIN)),
3097 torture_assert_int_equal(tctx,
3098 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
3102 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
3105 status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
3106 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
3107 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
3109 torture_assert_int_equal(tctx,
3110 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
3112 torture_assert_int_equal(tctx,
3113 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
3115 torture_assert_int_equal(tctx,
3116 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
3120 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
3121 torture_assert_int_equal(tctx,
3122 (info->dc_flags & (DS_SERVER_CLOSEST)),
3127 return test_netr_DsRGetSiteName(p, tctx,
3129 info->dc_site_name);
3133 try a netlogon netr_DsRGetDCNameEx
3135 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
3136 struct dcerpc_pipe *p)
3139 struct netr_DsRGetDCNameEx r;
3140 struct netr_DsRGetDCNameInfo *info = NULL;
3141 struct dcerpc_binding_handle *b = p->binding_handle;
3143 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3144 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
3145 r.in.domain_guid = NULL;
3146 r.in.site_name = NULL;
3147 r.in.flags = DS_RETURN_DNS_NAME;
3150 status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
3151 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
3152 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
3154 torture_assert_int_equal(tctx,
3155 (info->dc_flags & (DS_DNS_CONTROLLER)),
3158 torture_assert_int_equal(tctx,
3159 (info->dc_flags & (DS_DNS_DOMAIN)),
3162 torture_assert_int_equal(tctx,
3163 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
3167 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
3170 status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
3171 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
3172 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
3174 torture_assert_int_equal(tctx,
3175 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
3177 torture_assert_int_equal(tctx,
3178 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
3180 torture_assert_int_equal(tctx,
3181 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
3185 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
3186 torture_assert_int_equal(tctx,
3187 (info->dc_flags & (DS_SERVER_CLOSEST)),
3192 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
3193 info->dc_site_name);
3197 try a netlogon netr_DsRGetDCNameEx2
3199 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
3200 struct dcerpc_pipe *p)
3203 struct netr_DsRGetDCNameEx2 r;
3204 struct netr_DsRGetDCNameInfo *info = NULL;
3205 struct dcerpc_binding_handle *b = p->binding_handle;
3207 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with no inputs\n");
3209 r.in.flags = DS_RETURN_DNS_NAME;
3212 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
3213 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
3214 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
3216 torture_assert_int_equal(tctx,
3217 (info->dc_flags & (DS_DNS_CONTROLLER)),
3220 torture_assert_int_equal(tctx,
3221 (info->dc_flags & (DS_DNS_DOMAIN)),
3224 torture_assert_int_equal(tctx,
3225 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
3229 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3230 r.in.client_account = NULL;
3231 r.in.mask = 0x00000000;
3232 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
3233 r.in.domain_guid = NULL;
3234 r.in.site_name = NULL;
3235 r.in.flags = DS_RETURN_DNS_NAME;
3238 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
3240 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
3241 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
3242 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
3244 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
3247 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
3248 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
3249 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
3251 torture_assert_int_equal(tctx,
3252 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
3254 torture_assert_int_equal(tctx,
3255 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
3257 torture_assert_int_equal(tctx,
3258 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
3262 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
3263 torture_assert_int_equal(tctx,
3264 (info->dc_flags & (DS_SERVER_CLOSEST)),
3269 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client account\n");
3270 r.in.client_account = TEST_MACHINE_NAME"$";
3271 r.in.mask = ACB_SVRTRUST;
3272 r.in.flags = DS_RETURN_FLAT_NAME;
3275 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
3276 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
3277 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
3279 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
3280 info->dc_site_name);
3283 /* This is a substitution for "samdb_server_site_name" which relies on the
3284 * correct "lp_ctx" and therefore can't be used here. */
3285 static const char *server_site_name(struct torture_context *tctx,
3286 struct ldb_context *ldb)
3288 TALLOC_CTX *tmp_ctx;
3289 struct ldb_dn *dn, *server_dn;
3290 const struct ldb_val *site_name_val;
3291 const char *server_dn_str, *site_name;
3293 tmp_ctx = talloc_new(ldb);
3294 if (tmp_ctx == NULL) {
3298 dn = ldb_dn_new(tmp_ctx, ldb, "");
3303 server_dn_str = samdb_search_string(ldb, tmp_ctx, dn, "serverName",
3305 if (server_dn_str == NULL) {
3309 server_dn = ldb_dn_new(tmp_ctx, ldb, server_dn_str);
3310 if (server_dn == NULL) {
3314 /* CN=<Server name>, CN=Servers, CN=<Site name>, CN=Sites, ... */
3315 site_name_val = ldb_dn_get_component_val(server_dn, 2);
3316 if (site_name_val == NULL) {
3320 site_name = (const char *) site_name_val->data;
3322 talloc_steal(tctx, site_name);
3323 talloc_free(tmp_ctx);
3328 talloc_free(tmp_ctx);
3332 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
3333 struct dcerpc_pipe *p)
3336 struct ldb_context *sam_ctx = NULL;
3338 struct netr_DsrGetDcSiteCoverageW r;
3339 struct DcSitesCtr *ctr = NULL;
3340 struct dcerpc_binding_handle *b = p->binding_handle;
3342 torture_comment(tctx, "This does only pass with the default site\n");
3344 /* We won't double-check this when we are over 'local' transports */
3345 if (dcerpc_server_name(p)) {
3346 /* Set up connection to SAMDB on DC */
3347 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3348 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3350 cmdline_credentials,
3353 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3356 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3359 status = dcerpc_netr_DsrGetDcSiteCoverageW_r(b, tctx, &r);
3360 torture_assert_ntstatus_ok(tctx, status, "failed");
3361 torture_assert_werr_ok(tctx, r.out.result, "failed");
3363 torture_assert(tctx, ctr->num_sites == 1,
3364 "we should per default only get the default site");
3365 if (sam_ctx != NULL) {
3366 torture_assert_casestr_equal(tctx, ctr->sites[0].string,
3367 server_site_name(tctx, sam_ctx),
3368 "didn't return default site");
3374 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
3375 struct dcerpc_pipe *p)
3378 struct ldb_context *sam_ctx = NULL;
3380 struct netr_DsRAddressToSitenamesW r;
3381 struct netr_DsRAddress addrs[6];
3382 struct sockaddr_in *addr;
3384 struct sockaddr_in6 *addr6;
3386 struct netr_DsRAddressToSitenamesWCtr *ctr;
3387 struct dcerpc_binding_handle *b = p->binding_handle;
3391 torture_comment(tctx, "This does only pass with the default site\n");
3393 /* We won't double-check this when we are over 'local' transports */
3394 if (dcerpc_server_name(p)) {
3395 /* Set up connection to SAMDB on DC */
3396 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3397 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3399 cmdline_credentials,
3402 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3405 /* First try valid IP addresses */
3407 addrs[0].size = sizeof(struct sockaddr_in);
3408 addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
3409 addr = (struct sockaddr_in *) addrs[0].buffer;
3410 addrs[0].buffer[0] = AF_INET;
3411 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3412 torture_assert(tctx, ret > 0, "inet_pton failed");
3414 addrs[1].size = sizeof(struct sockaddr_in);
3415 addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
3416 addr = (struct sockaddr_in *) addrs[1].buffer;
3417 addrs[1].buffer[0] = AF_INET;
3418 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3419 torture_assert(tctx, ret > 0, "inet_pton failed");
3421 addrs[2].size = sizeof(struct sockaddr_in);
3422 addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
3423 addr = (struct sockaddr_in *) addrs[2].buffer;
3424 addrs[2].buffer[0] = AF_INET;
3425 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3426 torture_assert(tctx, ret > 0, "inet_pton failed");
3429 addrs[3].size = sizeof(struct sockaddr_in6);
3430 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3431 addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
3432 addrs[3].buffer[0] = AF_INET6;
3433 ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
3434 torture_assert(tctx, ret > 0, "inet_pton failed");
3436 addrs[4].size = sizeof(struct sockaddr_in6);
3437 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3438 addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
3439 addrs[4].buffer[0] = AF_INET6;
3440 ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
3441 torture_assert(tctx, ret > 0, "inet_pton failed");
3443 addrs[5].size = sizeof(struct sockaddr_in6);
3444 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3445 addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
3446 addrs[5].buffer[0] = AF_INET6;
3447 ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
3448 torture_assert(tctx, ret > 0, "inet_pton failed");
3450 /* the test cases are repeated to have exactly 6. This is for
3451 * compatibility with IPv4-only machines */
3452 addrs[3].size = sizeof(struct sockaddr_in);
3453 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3454 addr = (struct sockaddr_in *) addrs[3].buffer;
3455 addrs[3].buffer[0] = AF_INET;
3456 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3457 torture_assert(tctx, ret > 0, "inet_pton failed");
3459 addrs[4].size = sizeof(struct sockaddr_in);
3460 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3461 addr = (struct sockaddr_in *) addrs[4].buffer;
3462 addrs[4].buffer[0] = AF_INET;
3463 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3464 torture_assert(tctx, ret > 0, "inet_pton failed");
3466 addrs[5].size = sizeof(struct sockaddr_in);
3467 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3468 addr = (struct sockaddr_in *) addrs[5].buffer;
3469 addrs[5].buffer[0] = AF_INET;
3470 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3471 torture_assert(tctx, ret > 0, "inet_pton failed");
3474 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
3476 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3478 r.in.addresses = addrs;
3481 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
3482 torture_assert_ntstatus_ok(tctx, status, "failed");
3483 torture_assert_werr_ok(tctx, r.out.result, "failed");
3485 if (sam_ctx != NULL) {
3486 for (i = 0; i < 3; i++) {
3487 torture_assert_casestr_equal(tctx,
3488 ctr->sitename[i].string,
3489 server_site_name(tctx, sam_ctx),
3490 "didn't return default site");
3492 for (i = 3; i < 6; i++) {
3493 /* Windows returns "NULL" for the sitename if it isn't
3494 * IPv6 configured */
3495 if (torture_setting_bool(tctx, "samba4", false)) {
3496 torture_assert_casestr_equal(tctx,
3497 ctr->sitename[i].string,
3498 server_site_name(tctx, sam_ctx),
3499 "didn't return default site");
3504 /* Now try invalid ones (too short buffers) */
3514 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
3515 torture_assert_ntstatus_ok(tctx, status, "failed");
3516 torture_assert_werr_ok(tctx, r.out.result, "failed");
3518 for (i = 0; i < 6; i++) {
3519 torture_assert(tctx, ctr->sitename[i].string == NULL,
3520 "sitename should be null");
3523 /* Now try invalid ones (wrong address types) */
3526 addrs[0].buffer[0] = AF_UNSPEC;
3528 addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
3530 addrs[2].buffer[0] = AF_UNIX;
3533 addrs[3].buffer[0] = 250;
3535 addrs[4].buffer[0] = 251;
3537 addrs[5].buffer[0] = 252;
3539 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
3540 torture_assert_ntstatus_ok(tctx, status, "failed");
3541 torture_assert_werr_ok(tctx, r.out.result, "failed");
3543 for (i = 0; i < 6; i++) {
3544 torture_assert(tctx, ctr->sitename[i].string == NULL,
3545 "sitename should be null");
3551 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
3552 struct dcerpc_pipe *p)
3555 struct ldb_context *sam_ctx = NULL;
3557 struct netr_DsRAddressToSitenamesExW r;
3558 struct netr_DsRAddress addrs[6];
3559 struct sockaddr_in *addr;
3561 struct sockaddr_in6 *addr6;
3563 struct netr_DsRAddressToSitenamesExWCtr *ctr;
3564 struct dcerpc_binding_handle *b = p->binding_handle;
3568 torture_comment(tctx, "This does pass with the default site\n");
3570 /* We won't double-check this when we are over 'local' transports */
3571 if (dcerpc_server_name(p)) {
3572 /* Set up connection to SAMDB on DC */
3573 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3574 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3576 cmdline_credentials,
3579 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3582 /* First try valid IP addresses */
3584 addrs[0].size = sizeof(struct sockaddr_in);
3585 addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
3586 addr = (struct sockaddr_in *) addrs[0].buffer;
3587 addrs[0].buffer[0] = AF_INET;
3588 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3589 torture_assert(tctx, ret > 0, "inet_pton failed");
3591 addrs[1].size = sizeof(struct sockaddr_in);
3592 addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
3593 addr = (struct sockaddr_in *) addrs[1].buffer;
3594 addrs[1].buffer[0] = AF_INET;
3595 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3596 torture_assert(tctx, ret > 0, "inet_pton failed");
3598 addrs[2].size = sizeof(struct sockaddr_in);
3599 addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
3600 addr = (struct sockaddr_in *) addrs[2].buffer;
3601 addrs[2].buffer[0] = AF_INET;
3602 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3603 torture_assert(tctx, ret > 0, "inet_pton failed");
3606 addrs[3].size = sizeof(struct sockaddr_in6);
3607 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3608 addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
3609 addrs[3].buffer[0] = AF_INET6;
3610 ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
3611 torture_assert(tctx, ret > 0, "inet_pton failed");
3613 addrs[4].size = sizeof(struct sockaddr_in6);
3614 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3615 addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
3616 addrs[4].buffer[0] = AF_INET6;
3617 ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
3618 torture_assert(tctx, ret > 0, "inet_pton failed");
3620 addrs[5].size = sizeof(struct sockaddr_in6);
3621 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3622 addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
3623 addrs[5].buffer[0] = AF_INET6;
3624 ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
3625 torture_assert(tctx, ret > 0, "inet_pton failed");
3627 /* the test cases are repeated to have exactly 6. This is for
3628 * compatibility with IPv4-only machines */
3629 addrs[3].size = sizeof(struct sockaddr_in);
3630 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3631 addr = (struct sockaddr_in *) addrs[3].buffer;
3632 addrs[3].buffer[0] = AF_INET;
3633 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3634 torture_assert(tctx, ret > 0, "inet_pton failed");
3636 addrs[4].size = sizeof(struct sockaddr_in);
3637 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3638 addr = (struct sockaddr_in *) addrs[4].buffer;
3639 addrs[4].buffer[0] = AF_INET;
3640 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3641 torture_assert(tctx, ret > 0, "inet_pton failed");
3643 addrs[5].size = sizeof(struct sockaddr_in);
3644 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3645 addr = (struct sockaddr_in *) addrs[5].buffer;
3646 addrs[5].buffer[0] = AF_INET;
3647 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3648 torture_assert(tctx, ret > 0, "inet_pton failed");
3651 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
3653 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3655 r.in.addresses = addrs;
3658 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3659 torture_assert_ntstatus_ok(tctx, status, "failed");
3660 torture_assert_werr_ok(tctx, r.out.result, "failed");
3662 if (sam_ctx != NULL) {
3663 for (i = 0; i < 3; i++) {
3664 torture_assert_casestr_equal(tctx,
3665 ctr->sitename[i].string,
3666 server_site_name(tctx, sam_ctx),
3667 "didn't return default site");
3668 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3669 "subnet should be null");
3671 for (i = 3; i < 6; i++) {
3672 /* Windows returns "NULL" for the sitename if it isn't
3673 * IPv6 configured */
3674 if (torture_setting_bool(tctx, "samba4", false)) {
3675 torture_assert_casestr_equal(tctx,
3676 ctr->sitename[i].string,
3677 server_site_name(tctx, sam_ctx),
3678 "didn't return default site");
3680 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3681 "subnet should be null");
3685 /* Now try invalid ones (too short buffers) */
3695 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3696 torture_assert_ntstatus_ok(tctx, status, "failed");
3697 torture_assert_werr_ok(tctx, r.out.result, "failed");
3699 for (i = 0; i < 6; i++) {
3700 torture_assert(tctx, ctr->sitename[i].string == NULL,
3701 "sitename should be null");
3702 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3703 "subnet should be null");
3707 addrs[0].buffer[0] = AF_UNSPEC;
3709 addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
3711 addrs[2].buffer[0] = AF_UNIX;
3714 addrs[3].buffer[0] = 250;
3716 addrs[4].buffer[0] = 251;
3718 addrs[5].buffer[0] = 252;
3720 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3721 torture_assert_ntstatus_ok(tctx, status, "failed");
3722 torture_assert_werr_ok(tctx, r.out.result, "failed");
3724 for (i = 0; i < 6; i++) {
3725 torture_assert(tctx, ctr->sitename[i].string == NULL,
3726 "sitename should be null");
3727 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3728 "subnet should be null");
3734 static bool test_netr_ServerGetTrustInfo_flags(struct torture_context *tctx,
3735 struct dcerpc_pipe *p1,
3736 struct cli_credentials *machine_credentials,
3737 uint32_t negotiate_flags)
3739 struct netr_ServerGetTrustInfo r;
3741 struct netr_Authenticator a;
3742 struct netr_Authenticator return_authenticator;
3743 struct samr_Password new_owf_password;
3744 struct samr_Password old_owf_password;
3745 struct netr_TrustInfo *trust_info;
3747 struct netlogon_creds_CredentialState *creds;
3748 struct dcerpc_pipe *p = NULL;
3749 struct dcerpc_binding_handle *b = NULL;
3751 struct samr_Password nt_hash;
3753 if (!test_SetupCredentials3(p1, tctx, negotiate_flags,
3754 machine_credentials, &creds)) {
3757 if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
3758 DCERPC_SIGN | DCERPC_SEAL, &p)) {
3761 b = p->binding_handle;
3763 netlogon_creds_client_authenticator(creds, &a);
3765 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3766 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
3767 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
3768 r.in.computer_name = TEST_MACHINE_NAME;
3769 r.in.credential = &a;
3771 r.out.return_authenticator = &return_authenticator;
3772 r.out.new_owf_password = &new_owf_password;
3773 r.out.old_owf_password = &old_owf_password;
3774 r.out.trust_info = &trust_info;
3776 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerGetTrustInfo_r(b, tctx, &r),
3777 "ServerGetTrustInfo failed");
3778 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerGetTrustInfo failed");
3779 torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
3781 E_md4hash(cli_credentials_get_password(machine_credentials), nt_hash.hash);
3783 netlogon_creds_des_decrypt(creds, &new_owf_password);
3785 dump_data(1, new_owf_password.hash, 16);
3786 dump_data(1, nt_hash.hash, 16);
3788 torture_assert_mem_equal(tctx, new_owf_password.hash, nt_hash.hash, 16,
3789 "received unexpected owf password\n");
3794 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
3795 struct dcerpc_pipe *p,
3796 struct cli_credentials *machine_credentials)
3798 return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
3799 NETLOGON_NEG_AUTH2_ADS_FLAGS);
3802 static bool test_netr_ServerGetTrustInfo_AES(struct torture_context *tctx,
3803 struct dcerpc_pipe *p,
3804 struct cli_credentials *machine_credentials)
3806 return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
3807 NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
3810 static bool test_GetDomainInfo(struct torture_context *tctx,
3811 struct dcerpc_pipe *p1,
3812 struct cli_credentials *machine_credentials)
3814 struct netr_LogonGetDomainInfo r;
3815 struct netr_WorkstationInformation q1;
3816 struct netr_Authenticator a;
3817 struct netlogon_creds_CredentialState *creds;
3818 struct netr_OsVersion os;
3819 union netr_WorkstationInfo query;
3820 union netr_DomainInfo info;
3821 const char* const attrs[] = { "dNSHostName", "operatingSystem",
3822 "operatingSystemServicePack", "operatingSystemVersion",
3823 "servicePrincipalName", NULL };
3825 struct ldb_context *sam_ctx = NULL;
3826 struct ldb_message **res;
3827 struct ldb_message_element *spn_el;
3830 const char *old_dnsname = NULL;
3834 struct dcerpc_pipe *p = NULL;
3835 struct dcerpc_binding_handle *b = NULL;
3837 torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
3839 if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3840 machine_credentials, &creds)) {
3843 if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
3844 DCERPC_SIGN | DCERPC_SEAL, &p)) {
3847 b = p->binding_handle;
3849 /* We won't double-check this when we are over 'local' transports */
3850 if (dcerpc_server_name(p)) {
3851 /* Set up connection to SAMDB on DC */
3852 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3853 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3855 cmdline_credentials,
3858 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3861 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
3862 netlogon_creds_client_authenticator(creds, &a);
3865 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3866 r.in.computer_name = TEST_MACHINE_NAME;
3867 r.in.credential = &a;
3869 r.in.return_authenticator = &a;
3870 r.in.query = &query;
3871 r.out.return_authenticator = &a;
3875 os.os.MajorVersion = 123;
3876 os.os.MinorVersion = 456;
3877 os.os.BuildNumber = 789;
3878 os.os.CSDVersion = "Service Pack 10";
3879 os.os.ServicePackMajor = 10;
3880 os.os.ServicePackMinor = 1;
3881 os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
3882 os.os.ProductType = NETR_VER_NT_SERVER;
3885 version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
3886 os.os.MinorVersion, os.os.BuildNumber);
3889 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3890 lpcfg_dnsdomain(tctx->lp_ctx));
3891 q1.sitename = "Default-First-Site-Name";
3892 q1.os_version.os = &os;
3893 q1.os_name.string = talloc_asprintf(tctx,
3894 "Tortured by Samba4 RPC-NETLOGON: %s",
3895 timestring(tctx, time(NULL)));
3897 /* The workstation handles the "servicePrincipalName" and DNS hostname
3899 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3901 query.workstation_info = &q1;
3904 /* Gets back the old DNS hostname in AD */
3905 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3906 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3908 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
3910 /* Gets back the "servicePrincipalName"s in AD */
3911 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3912 if (spn_el != NULL) {
3913 for (i=0; i < spn_el->num_values; i++) {
3914 spns = talloc_realloc(tctx, spns, char *, i + 1);
3915 spns[i] = (char *) spn_el->values[i].data;
3921 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3922 "LogonGetDomainInfo failed");
3923 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3924 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3929 /* AD workstation infos entry check */
3930 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3931 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3932 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3933 torture_assert_str_equal(tctx,
3934 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3935 q1.os_name.string, "'operatingSystem' wrong!");
3936 torture_assert_str_equal(tctx,
3937 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
3938 os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
3939 torture_assert_str_equal(tctx,
3940 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
3941 version_str, "'operatingSystemVersion' wrong!");
3943 if (old_dnsname != NULL) {
3944 /* If before a DNS hostname was set then it should remain
3945 the same in combination with the "servicePrincipalName"s.
3946 The DNS hostname should also be returned by our
3947 "LogonGetDomainInfo" call (in the domain info structure). */
3949 torture_assert_str_equal(tctx,
3950 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3951 old_dnsname, "'DNS hostname' was not set!");
3953 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3954 torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
3955 "'servicePrincipalName's not set!");
3956 torture_assert(tctx, spn_el->num_values == num_spns,
3957 "'servicePrincipalName's incorrect!");
3958 for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
3959 torture_assert_str_equal(tctx,
3960 (char *) spn_el->values[i].data,
3961 spns[i], "'servicePrincipalName's incorrect!");
3963 torture_assert_str_equal(tctx,
3964 info.domain_info->dns_hostname.string,
3966 "Out 'DNS hostname' doesn't match the old one!");
3968 /* If no DNS hostname was set then also now none should be set,
3969 the "servicePrincipalName"s should remain empty and no DNS
3970 hostname should be returned by our "LogonGetDomainInfo"
3971 call (in the domain info structure). */
3973 torture_assert(tctx,
3974 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
3975 "'DNS hostname' was set!");
3977 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3978 torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
3979 "'servicePrincipalName's were set!");
3981 torture_assert(tctx,
3982 info.domain_info->dns_hostname.string == NULL,
3983 "Out 'DNS host name' was set!");
3987 /* Checks "workstation flags" */
3988 torture_assert(tctx,
3989 info.domain_info->workstation_flags
3990 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3991 "Out 'workstation flags' don't match!");
3994 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname doesn't work)\n");
3995 netlogon_creds_client_authenticator(creds, &a);
3997 /* Wipe out the osVersion, and prove which values still 'stick' */
3998 q1.os_version.os = NULL;
4000 /* Change also the DNS hostname to test differences in behaviour */
4001 talloc_free(discard_const_p(char, q1.dns_hostname));
4002 q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
4003 lpcfg_dnsdomain(tctx->lp_ctx));
4005 /* The workstation handles the "servicePrincipalName" and DNS hostname
4007 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
4009 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
4010 "LogonGetDomainInfo failed");
4011 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
4013 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
4018 /* AD workstation infos entry check */
4019 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
4020 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
4021 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
4023 torture_assert_str_equal(tctx,
4024 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
4025 q1.os_name.string, "'operatingSystem' should stick!");
4026 torture_assert(tctx,
4027 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
4028 "'operatingSystemServicePack' shouldn't stick!");
4029 torture_assert(tctx,
4030 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
4031 "'operatingSystemVersion' shouldn't stick!");
4033 /* The DNS host name shouldn't have been updated by the server */
4035 torture_assert_str_equal(tctx,
4036 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
4037 old_dnsname, "'DNS host name' did change!");
4039 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
4040 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
4042 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
4043 torture_assert(tctx, spn_el != NULL,
4044 "There should exist 'servicePrincipalName's in AD!");
4045 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
4046 for (i=0; i < spn_el->num_values; i++)
4047 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
4049 torture_assert(tctx, i != spn_el->num_values,
4050 "'servicePrincipalName' HOST/<Netbios name> not found!");
4051 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
4052 for (i=0; i < spn_el->num_values; i++)
4053 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
4055 torture_assert(tctx, i != spn_el->num_values,
4056 "'servicePrincipalName' HOST/<FQDN name> not found!");
4058 /* Check that the out DNS hostname was set properly */
4059 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
4060 old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
4063 /* Checks "workstation flags" */
4064 torture_assert(tctx,
4065 info.domain_info->workstation_flags == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
4066 "Out 'workstation flags' don't match!");
4069 /* Now try the same but the workstation flags set to 0 */
4071 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (variation of DNS hostname doesn't work)\n");
4072 netlogon_creds_client_authenticator(creds, &a);
4074 /* Change also the DNS hostname to test differences in behaviour */
4075 talloc_free(discard_const_p(char, q1.dns_hostname));
4076 q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
4077 lpcfg_dnsdomain(tctx->lp_ctx));
4079 /* Wipe out the osVersion, and prove which values still 'stick' */
4080 q1.os_version.os = NULL;
4082 /* Let the DC handle the "servicePrincipalName" and DNS hostname
4084 q1.workstation_flags = 0;
4086 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
4087 "LogonGetDomainInfo failed");
4088 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
4089 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
4094 /* AD workstation infos entry check */
4095 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
4096 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
4097 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
4099 torture_assert_str_equal(tctx,
4100 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
4101 q1.os_name.string, "'operatingSystem' should stick!");
4102 torture_assert(tctx,
4103 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
4104 "'operatingSystemServicePack' shouldn't stick!");
4105 torture_assert(tctx,
4106 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
4107 "'operatingSystemVersion' shouldn't stick!");
4109 /* The DNS host name shouldn't have been updated by the server */
4111 torture_assert_str_equal(tctx,
4112 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
4113 old_dnsname, "'DNS host name' did change!");
4115 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
4116 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
4118 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
4119 torture_assert(tctx, spn_el != NULL,
4120 "There should exist 'servicePrincipalName's in AD!");
4121 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
4122 for (i=0; i < spn_el->num_values; i++)
4123 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
4125 torture_assert(tctx, i != spn_el->num_values,
4126 "'servicePrincipalName' HOST/<Netbios name> not found!");
4127 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
4128 for (i=0; i < spn_el->num_values; i++)
4129 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
4131 torture_assert(tctx, i != spn_el->num_values,
4132 "'servicePrincipalName' HOST/<FQDN name> not found!");
4134 /* Here the server gives us NULL as the out DNS hostname */
4135 torture_assert(tctx, info.domain_info->dns_hostname.string == NULL,
4136 "Out 'DNS hostname' should be NULL!");
4139 /* Checks "workstation flags" */
4140 torture_assert(tctx,
4141 info.domain_info->workstation_flags == 0,
4142 "Out 'workstation flags' don't match!");
4145 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (verification of DNS hostname and check for trusted domains)\n");
4146 netlogon_creds_client_authenticator(creds, &a);
4148 /* Put the DNS hostname back */
4149 talloc_free(discard_const_p(char, q1.dns_hostname));
4150 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
4151 lpcfg_dnsdomain(tctx->lp_ctx));
4153 /* The workstation handles the "servicePrincipalName" and DNS hostname
4155 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
4157 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
4158 "LogonGetDomainInfo failed");
4159 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
4160 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
4164 /* Now the in/out DNS hostnames should be the same */
4165 torture_assert_str_equal(tctx,
4166 info.domain_info->dns_hostname.string,
4167 query.workstation_info->dns_hostname,
4168 "In/Out 'DNS hostnames' don't match!");
4169 old_dnsname = info.domain_info->dns_hostname.string;
4171 /* Checks "workstation flags" */
4172 torture_assert(tctx,
4173 info.domain_info->workstation_flags
4174 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
4175 "Out 'workstation flags' don't match!");
4177 /* Checks for trusted domains */
4178 torture_assert(tctx,
4179 (info.domain_info->trusted_domain_count != 0)
4180 && (info.domain_info->trusted_domains != NULL),
4181 "Trusted domains have been requested!");
4184 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 5th call (check for trusted domains)\n");
4185 netlogon_creds_client_authenticator(creds, &a);
4187 /* The workstation handles the "servicePrincipalName" and DNS hostname
4188 updates and requests inbound trusts */
4189 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
4190 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
4192 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
4193 "LogonGetDomainInfo failed");
4194 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
4195 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
4199 /* Checks "workstation flags" */
4200 torture_assert(tctx,
4201 info.domain_info->workstation_flags
4202 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
4203 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
4204 "Out 'workstation flags' don't match!");
4206 /* Checks for trusted domains */
4207 torture_assert(tctx,
4208 (info.domain_info->trusted_domain_count != 0)
4209 && (info.domain_info->trusted_domains != NULL),
4210 "Trusted domains have been requested!");
4213 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
4214 netlogon_creds_client_authenticator(creds, &a);
4216 query.workstation_info->dns_hostname = NULL;
4218 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
4219 "LogonGetDomainInfo failed");
4220 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
4221 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
4223 /* The old DNS hostname should stick */
4224 torture_assert_str_equal(tctx,
4225 info.domain_info->dns_hostname.string,
4227 "'DNS hostname' changed!");
4229 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (extra workstation flags)\n");
4230 netlogon_creds_client_authenticator(creds, &a);
4232 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
4233 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | 0x4;
4235 /* Put the DNS hostname back */
4236 talloc_free(discard_const_p(char, q1.dns_hostname));
4237 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
4238 lpcfg_dnsdomain(tctx->lp_ctx));
4240 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
4241 "LogonGetDomainInfo failed");
4242 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
4243 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
4245 /* Checks "workstation flags" */
4246 torture_assert(tctx,
4247 info.domain_info->workstation_flags
4248 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
4249 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
4250 "Out 'workstation flags' don't match!");
4252 if (!torture_setting_bool(tctx, "dangerous", false)) {
4253 torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 8th call (no workstation info) - enable dangerous tests in order to do so\n");
4255 /* Try a call without the workstation information structure */
4257 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 8th call (no workstation info)\n");
4258 netlogon_creds_client_authenticator(creds, &a);
4260 query.workstation_info = NULL;
4262 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
4263 "LogonGetDomainInfo failed");
4264 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
4265 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
4271 static bool test_GetDomainInfo_async(struct torture_context *tctx,
4272 struct dcerpc_pipe *p1,
4273 struct cli_credentials *machine_credentials)
4276 struct netr_LogonGetDomainInfo r;
4277 struct netr_WorkstationInformation q1;
4278 struct netr_Authenticator a;
4279 #define ASYNC_COUNT 100
4280 struct netlogon_creds_CredentialState *creds;
4281 struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
4282 struct tevent_req *req[ASYNC_COUNT];
4284 union netr_WorkstationInfo query;
4285 union netr_DomainInfo info;
4286 struct dcerpc_pipe *p = NULL;
4288 torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
4290 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
4291 machine_credentials, &creds)) {
4294 if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
4295 DCERPC_SIGN | DCERPC_SEAL, &p)) {
4300 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4301 r.in.computer_name = TEST_MACHINE_NAME;
4302 r.in.credential = &a;
4304 r.in.return_authenticator = &a;
4305 r.in.query = &query;
4306 r.out.return_authenticator = &a;
4310 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
4311 lpcfg_dnsdomain(tctx->lp_ctx));
4312 q1.sitename = "Default-First-Site-Name";
4313 q1.os_name.string = "UNIX/Linux or similar";
4315 query.workstation_info = &q1;
4317 for (i=0;i<ASYNC_COUNT;i++) {
4318 netlogon_creds_client_authenticator(creds, &a);
4320 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
4321 req[i] = dcerpc_netr_LogonGetDomainInfo_r_send(tctx, tctx->ev, p->binding_handle, &r);
4323 /* even with this flush per request a w2k3 server seems to
4324 clag with multiple outstanding requests. bleergh. */
4325 torture_assert_int_equal(tctx, tevent_loop_once(tctx->ev), 0,
4326 "tevent_loop_once failed");
4329 for (i=0;i<ASYNC_COUNT;i++) {
4330 torture_assert_int_equal(tctx, tevent_req_poll(req[i], tctx->ev), true,
4331 "tevent_req_poll() failed");
4333 status = dcerpc_netr_LogonGetDomainInfo_r_recv(req[i], tctx);
4335 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
4336 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
4338 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred),
4339 "Credential chaining failed at async");
4342 torture_comment(tctx,
4343 "Testing netr_LogonGetDomainInfo - async count %d OK\n", ASYNC_COUNT);
4348 static bool test_ManyGetDCName(struct torture_context *tctx,
4349 struct dcerpc_pipe *p)
4352 struct cli_credentials *anon_creds;
4353 struct dcerpc_binding *binding2;
4354 struct dcerpc_pipe *p2;
4355 struct lsa_ObjectAttribute attr;
4356 struct lsa_QosInfo qos;
4357 struct lsa_OpenPolicy2 o;
4358 struct policy_handle lsa_handle;
4359 struct lsa_DomainList domains;
4361 struct lsa_EnumTrustDom t;
4362 uint32_t resume_handle = 0;
4363 struct netr_GetAnyDCName d;
4364 const char *dcname = NULL;
4365 struct dcerpc_binding_handle *b = p->binding_handle;
4366 struct dcerpc_binding_handle *b2;
4370 if (p->conn->transport.transport != NCACN_NP) {
4371 torture_skip(tctx, "test_ManyGetDCName works only with NCACN_NP");
4374 torture_comment(tctx, "Torturing GetDCName\n");
4376 anon_creds = cli_credentials_init_anon(tctx);
4377 torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed");
4379 binding2 = dcerpc_binding_dup(tctx, p->binding);
4380 /* Swap the binding details from NETLOGON to LSA */
4381 status = dcerpc_epm_map_binding(tctx, binding2, &ndr_table_lsarpc, tctx->ev, tctx->lp_ctx);
4382 dcerpc_binding_set_assoc_group_id(binding2, 0);
4383 torture_assert_ntstatus_ok(tctx, status, "epm map");
4385 status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_lsarpc,
4386 anon_creds, tctx->lp_ctx,
4388 torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
4389 b2 = p2->binding_handle;
4392 qos.impersonation_level = 2;
4393 qos.context_mode = 1;
4394 qos.effective_only = 0;
4397 attr.root_dir = NULL;
4398 attr.object_name = NULL;
4399 attr.attributes = 0;
4400 attr.sec_desc = NULL;
4401 attr.sec_qos = &qos;
4403 o.in.system_name = "\\";
4405 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4406 o.out.handle = &lsa_handle;
4408 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
4409 "OpenPolicy2 failed");
4410 torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
4412 t.in.handle = &lsa_handle;
4413 t.in.resume_handle = &resume_handle;
4414 t.in.max_size = 1000;
4415 t.out.domains = &domains;
4416 t.out.resume_handle = &resume_handle;
4418 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b2, tctx, &t),
4419 "EnumTrustDom failed");
4421 if ((!NT_STATUS_IS_OK(t.out.result) &&
4422 (!NT_STATUS_EQUAL(t.out.result, NT_STATUS_NO_MORE_ENTRIES))))
4423 torture_fail(tctx, "Could not list domains");
4427 d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
4428 dcerpc_server_name(p));
4429 d.out.dcname = &dcname;
4431 for (i=0; i<domains.count * 4; i++) {
4432 struct lsa_DomainInfo *info =
4433 &domains.domains[rand()%domains.count];
4435 d.in.domainname = info->name.string;
4437 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &d);
4438 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
4440 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
4441 dcname ? dcname : "unknown");
4447 static bool test_lsa_over_netlogon(struct torture_context *tctx,
4448 struct dcerpc_pipe *p)
4451 struct cli_credentials *anon_creds;
4452 const struct dcerpc_binding *binding2;
4453 struct dcerpc_pipe *p2;
4454 struct lsa_ObjectAttribute attr;
4455 struct lsa_QosInfo qos;
4456 struct lsa_OpenPolicy2 o;
4457 struct policy_handle lsa_handle;
4459 struct dcerpc_binding_handle *b2;
4462 if (p->conn->transport.transport != NCACN_NP) {
4463 torture_skip(tctx, "test_lsa_over_netlogon works only with NCACN_NP");
4466 torture_comment(tctx, "Testing if we can access the LSA server over\n"
4467 " \\\\pipe\\netlogon rather than \\\\pipe\\lsarpc\n");
4469 anon_creds = cli_credentials_init_anon(tctx);
4470 torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed");
4472 binding2 = p->binding;
4474 status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_lsarpc,
4475 anon_creds, tctx->lp_ctx,
4477 torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
4478 b2 = p2->binding_handle;
4481 qos.impersonation_level = 2;
4482 qos.context_mode = 1;
4483 qos.effective_only = 0;
4486 attr.root_dir = NULL;
4487 attr.object_name = NULL;
4488 attr.attributes = 0;
4489 attr.sec_desc = NULL;
4490 attr.sec_qos = &qos;
4492 o.in.system_name = "\\";
4494 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4495 o.out.handle = &lsa_handle;
4497 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
4498 "OpenPolicy2 failed");
4499 torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
4506 static bool test_SetPassword_with_flags(struct torture_context *tctx,
4507 struct dcerpc_pipe *p,
4508 struct cli_credentials *machine_credentials)
4510 uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
4511 struct netlogon_creds_CredentialState *creds;
4514 if (!test_SetupCredentials2(p, tctx, 0,
4515 machine_credentials,
4516 cli_credentials_get_secure_channel_type(machine_credentials),
4518 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
4521 for (i=0; i < ARRAY_SIZE(flags); i++) {
4522 torture_assert(tctx,
4523 test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
4524 talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
4530 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
4532 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon");
4533 struct torture_rpc_tcase *tcase;
4534 struct torture_test *test;
4536 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
4537 &ndr_table_netlogon, TEST_MACHINE_NAME);
4539 torture_rpc_tcase_add_test(tcase, "Broken RPC binding handle",
4540 test_netr_broken_binding_handle);
4542 torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
4543 torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
4544 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
4545 torture_rpc_tcase_add_test_creds(tcase, "invalidAuthenticate2", test_invalidAuthenticate2);
4546 torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeGlobal", test_ServerReqChallengeGlobal);
4547 torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal", test_ServerReqChallengeReuseGlobal);
4548 torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal2", test_ServerReqChallengeReuseGlobal2);
4549 torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuse", test_ServerReqChallengeReuse);
4550 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
4551 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
4552 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
4553 torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
4554 torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
4555 torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
4556 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
4557 torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
4558 torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
4559 torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
4560 torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
4561 torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
4562 torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
4563 torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
4564 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
4565 torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
4566 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
4567 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
4568 test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
4569 test->dangerous = true;
4570 torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
4571 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
4572 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
4573 torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
4574 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
4575 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
4576 torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
4577 torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo_AES", test_netr_ServerGetTrustInfo_AES);
4578 torture_rpc_tcase_add_test_creds(tcase, "GetForestTrustInformation", test_netr_GetForestTrustInformation);
4580 torture_rpc_tcase_add_test(tcase, "lsa_over_netlogon", test_lsa_over_netlogon);
4581 torture_rpc_tcase_add_test_creds(tcase, "SetupCredentialsDowngrade", test_SetupCredentialsDowngrade);
4586 struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
4588 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon-s3");
4589 struct torture_rpc_tcase *tcase;
4591 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
4592 &ndr_table_netlogon, TEST_MACHINE_NAME);
4594 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
4595 torture_rpc_tcase_add_test_creds(tcase, "SamLogon_NULL_domain", test_SamLogon_NULL_domain);
4596 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
4597 torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
4598 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
4599 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
4600 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
4605 struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
4607 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon.admin");
4608 struct torture_rpc_tcase *tcase;
4610 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "bdc",
4611 &ndr_table_netlogon, TEST_MACHINE_NAME);
4612 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
4613 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
4614 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
4616 tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "wkst",
4617 &ndr_table_netlogon, TEST_MACHINE_NAME);
4618 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
4619 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
4620 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
4622 tcase = torture_suite_add_rpc_iface_tcase(suite, "admin",
4623 &ndr_table_netlogon);
4624 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
4625 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
4626 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);