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_SetupCredentialsPipe(const struct dcerpc_pipe *p1,
363 struct torture_context *tctx,
364 struct cli_credentials *machine_credentials,
365 struct netlogon_creds_CredentialState *creds,
366 uint32_t additional_flags,
367 struct dcerpc_pipe **_p2)
370 struct dcerpc_binding *b2 = NULL;
371 struct dcerpc_pipe *p2 = NULL;
373 b2 = dcerpc_binding_dup(tctx, p1->binding);
374 torture_assert(tctx, b2 != NULL, "dcerpc_binding_dup");
375 dcerpc_binding_set_flags(b2,
376 DCERPC_SCHANNEL | additional_flags,
377 DCERPC_AUTH_OPTIONS);
379 cli_credentials_set_netlogon_creds(machine_credentials, creds);
380 status = dcerpc_pipe_connect_b(tctx, &p2, b2,
383 tctx->ev, tctx->lp_ctx);
384 cli_credentials_set_netlogon_creds(machine_credentials, NULL);
385 torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b schannel");
392 try a change password for our machine account
394 static bool test_SetPassword(struct torture_context *tctx,
395 struct dcerpc_pipe *p,
396 struct cli_credentials *machine_credentials)
398 struct netr_ServerPasswordSet r;
399 const char *password;
400 struct netlogon_creds_CredentialState *creds;
401 struct netr_Authenticator credential, return_authenticator;
402 struct samr_Password new_password;
403 struct dcerpc_binding_handle *b = p->binding_handle;
405 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
409 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
410 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
411 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
412 r.in.computer_name = TEST_MACHINE_NAME;
413 r.in.credential = &credential;
414 r.in.new_password = &new_password;
415 r.out.return_authenticator = &return_authenticator;
417 password = generate_random_password(tctx, 8, 255);
418 E_md4hash(password, new_password.hash);
420 netlogon_creds_des_encrypt(creds, &new_password);
422 torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
423 torture_comment(tctx, "Changing machine account password to '%s'\n",
426 netlogon_creds_client_authenticator(creds, &credential);
428 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
429 "ServerPasswordSet failed");
430 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
432 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
433 torture_comment(tctx, "Credential chaining failed\n");
436 /* by changing the machine password twice we test the
437 credentials chaining fully, and we verify that the server
438 allows the password to be set to the same value twice in a
439 row (match win2k3) */
440 torture_comment(tctx,
441 "Testing a second ServerPasswordSet on machine account\n");
442 torture_comment(tctx,
443 "Changing machine account password to '%s' (same as previous run)\n", password);
445 netlogon_creds_client_authenticator(creds, &credential);
447 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
448 "ServerPasswordSet (2) failed");
449 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
451 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
452 torture_comment(tctx, "Credential chaining failed\n");
455 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
458 test_SetupCredentials(p, tctx, machine_credentials, &creds),
459 "ServerPasswordSet failed to actually change the password");
465 try a change password for our machine account
467 static bool test_SetPassword_flags(struct torture_context *tctx,
468 struct dcerpc_pipe *p1,
469 struct cli_credentials *machine_credentials,
470 uint32_t negotiate_flags)
472 struct netr_ServerPasswordSet r;
473 const char *password;
474 struct netlogon_creds_CredentialState *creds;
475 struct netr_Authenticator credential, return_authenticator;
476 struct samr_Password new_password;
477 struct dcerpc_pipe *p = NULL;
478 struct dcerpc_binding_handle *b = NULL;
480 if (!test_SetupCredentials2(p1, tctx, negotiate_flags,
482 cli_credentials_get_secure_channel_type(machine_credentials),
486 if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
487 DCERPC_SIGN | DCERPC_SEAL, &p)) {
490 b = p->binding_handle;
492 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
493 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
494 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
495 r.in.computer_name = TEST_MACHINE_NAME;
496 r.in.credential = &credential;
497 r.in.new_password = &new_password;
498 r.out.return_authenticator = &return_authenticator;
500 password = generate_random_password(tctx, 8, 255);
501 E_md4hash(password, new_password.hash);
503 netlogon_creds_des_encrypt(creds, &new_password);
505 torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
506 torture_comment(tctx, "Changing machine account password to '%s'\n",
509 netlogon_creds_client_authenticator(creds, &credential);
511 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
512 "ServerPasswordSet failed");
513 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
515 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
516 torture_comment(tctx, "Credential chaining failed\n");
519 /* by changing the machine password twice we test the
520 credentials chaining fully, and we verify that the server
521 allows the password to be set to the same value twice in a
522 row (match win2k3) */
523 torture_comment(tctx,
524 "Testing a second ServerPasswordSet on machine account\n");
525 torture_comment(tctx,
526 "Changing machine account password to '%s' (same as previous run)\n", password);
528 netlogon_creds_client_authenticator(creds, &credential);
530 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
531 "ServerPasswordSet (2) failed");
532 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
534 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
535 torture_comment(tctx, "Credential chaining failed\n");
538 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
541 test_SetupCredentials(p, tctx, machine_credentials, &creds),
542 "ServerPasswordSet failed to actually change the password");
549 generate a random password for password change tests
551 static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
554 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
555 generate_random_buffer(password.data, password.length);
557 for (i=0; i < len; i++) {
558 if (((uint16_t *)password.data)[i] == 0) {
559 ((uint16_t *)password.data)[i] = 1;
567 try a change password for our machine account
569 static bool test_SetPassword2_with_flags(struct torture_context *tctx,
570 struct dcerpc_pipe *p1,
571 struct cli_credentials *machine_credentials,
574 struct netr_ServerPasswordSet2 r;
575 const char *password;
576 DATA_BLOB new_random_pass;
577 struct netlogon_creds_CredentialState *creds;
578 struct samr_CryptPassword password_buf;
579 struct samr_Password nt_hash;
580 struct netr_Authenticator credential, return_authenticator;
581 struct netr_CryptPassword new_password;
582 struct dcerpc_pipe *p = NULL;
583 struct dcerpc_binding_handle *b = NULL;
585 if (!test_SetupCredentials2(p1, tctx, flags, machine_credentials,
586 cli_credentials_get_secure_channel_type(machine_credentials),
590 if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
591 DCERPC_SIGN | DCERPC_SEAL, &p)) {
594 b = p->binding_handle;
596 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
597 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
598 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
599 r.in.computer_name = TEST_MACHINE_NAME;
600 r.in.credential = &credential;
601 r.in.new_password = &new_password;
602 r.out.return_authenticator = &return_authenticator;
604 password = generate_random_password(tctx, 8, 255);
605 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
606 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
607 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
609 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
612 memcpy(new_password.data, password_buf.data, 512);
613 new_password.length = IVAL(password_buf.data, 512);
615 torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
616 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
618 netlogon_creds_client_authenticator(creds, &credential);
620 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
621 "ServerPasswordSet2 failed");
622 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
624 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
625 torture_comment(tctx, "Credential chaining failed\n");
628 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
630 if (!torture_setting_bool(tctx, "dangerous", false)) {
631 torture_comment(tctx,
632 "Not testing ability to set password to '', enable dangerous tests to perform this test\n");
634 /* by changing the machine password to ""
635 * we check if the server uses password restrictions
636 * for ServerPasswordSet2
637 * (win2k3 accepts "")
640 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
641 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
642 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
644 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
646 memcpy(new_password.data, password_buf.data, 512);
647 new_password.length = IVAL(password_buf.data, 512);
649 torture_comment(tctx,
650 "Testing ServerPasswordSet2 on machine account\n");
651 torture_comment(tctx,
652 "Changing machine account password to '%s'\n", password);
654 netlogon_creds_client_authenticator(creds, &credential);
656 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
657 "ServerPasswordSet2 failed");
658 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
660 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
661 torture_comment(tctx, "Credential chaining failed\n");
664 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
667 torture_assert(tctx, test_SetupCredentials(p, tctx, machine_credentials, &creds),
668 "ServerPasswordSet failed to actually change the password");
670 /* now try a random password */
671 password = generate_random_password(tctx, 8, 255);
672 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
673 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
674 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
676 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
678 memcpy(new_password.data, password_buf.data, 512);
679 new_password.length = IVAL(password_buf.data, 512);
681 torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
682 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
684 netlogon_creds_client_authenticator(creds, &credential);
686 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
687 "ServerPasswordSet2 (2) failed");
688 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 (2) failed");
690 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
691 torture_comment(tctx, "Credential chaining failed\n");
694 /* by changing the machine password twice we test the
695 credentials chaining fully, and we verify that the server
696 allows the password to be set to the same value twice in a
697 row (match win2k3) */
698 torture_comment(tctx,
699 "Testing a second ServerPasswordSet2 on machine account\n");
700 torture_comment(tctx,
701 "Changing machine account password to '%s' (same as previous run)\n", password);
703 netlogon_creds_client_authenticator(creds, &credential);
705 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
706 "ServerPasswordSet (3) failed");
707 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
709 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
710 torture_comment(tctx, "Credential chaining failed\n");
713 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
715 torture_assert (tctx,
716 test_SetupCredentials(p, tctx, machine_credentials, &creds),
717 "ServerPasswordSet failed to actually change the password");
719 new_random_pass = netlogon_very_rand_pass(tctx, 128);
721 /* now try a random stream of bytes for a password */
722 set_pw_in_buffer(password_buf.data, &new_random_pass);
724 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
725 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
727 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
730 memcpy(new_password.data, password_buf.data, 512);
731 new_password.length = IVAL(password_buf.data, 512);
733 torture_comment(tctx,
734 "Testing a third ServerPasswordSet2 on machine account, with a completely random password\n");
736 netlogon_creds_client_authenticator(creds, &credential);
738 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
739 "ServerPasswordSet (3) failed");
740 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
742 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
743 torture_comment(tctx, "Credential chaining failed\n");
746 mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
748 cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
749 cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
751 torture_assert (tctx,
752 test_SetupCredentials(p, tctx, machine_credentials, &creds),
753 "ServerPasswordSet failed to actually change the password");
758 static bool test_SetPassword2(struct torture_context *tctx,
759 struct dcerpc_pipe *p,
760 struct cli_credentials *machine_credentials)
762 return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS);
765 static bool test_SetPassword2_AES(struct torture_context *tctx,
766 struct dcerpc_pipe *p,
767 struct cli_credentials *machine_credentials)
769 return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
772 static bool test_GetPassword(struct torture_context *tctx,
773 struct dcerpc_pipe *p,
774 struct cli_credentials *machine_credentials)
776 struct netr_ServerPasswordGet r;
777 struct netlogon_creds_CredentialState *creds;
778 struct netr_Authenticator credential;
780 struct netr_Authenticator return_authenticator;
781 struct samr_Password password;
782 struct dcerpc_binding_handle *b = p->binding_handle;
784 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
788 netlogon_creds_client_authenticator(creds, &credential);
790 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
791 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
792 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
793 r.in.computer_name = TEST_MACHINE_NAME;
794 r.in.credential = &credential;
795 r.out.return_authenticator = &return_authenticator;
796 r.out.password = &password;
798 status = dcerpc_netr_ServerPasswordGet_r(b, tctx, &r);
799 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
800 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordGet");
805 static bool test_GetTrustPasswords(struct torture_context *tctx,
806 struct dcerpc_pipe *p,
807 struct cli_credentials *machine_credentials)
809 struct netr_ServerTrustPasswordsGet r;
810 struct netlogon_creds_CredentialState *creds;
811 struct netr_Authenticator credential;
812 struct netr_Authenticator return_authenticator;
813 struct samr_Password password, password2;
814 struct dcerpc_binding_handle *b = p->binding_handle;
816 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
820 netlogon_creds_client_authenticator(creds, &credential);
822 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
823 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
824 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
825 r.in.computer_name = TEST_MACHINE_NAME;
826 r.in.credential = &credential;
827 r.out.return_authenticator = &return_authenticator;
828 r.out.new_owf_password = &password;
829 r.out.old_owf_password = &password2;
831 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerTrustPasswordsGet_r(b, tctx, &r),
832 "ServerTrustPasswordsGet failed");
833 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerTrustPasswordsGet failed");
839 try a netlogon SamLogon
841 static bool test_netlogon_ops_args(struct dcerpc_pipe *p, struct torture_context *tctx,
842 struct cli_credentials *credentials,
843 struct netlogon_creds_CredentialState *creds,
847 struct netr_LogonSamLogon r;
848 struct netr_Authenticator auth, auth2;
849 static const struct netr_Authenticator auth_zero;
850 union netr_LogonLevel logon;
851 union netr_Validation validation;
852 uint8_t authoritative;
853 struct netr_NetworkInfo ninfo;
854 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
856 struct dcerpc_binding_handle *b = p->binding_handle;
857 int flags = CLI_CRED_NTLM_AUTH;
858 if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
859 flags |= CLI_CRED_LANMAN_AUTH;
862 if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx) && !null_domain) {
863 flags |= CLI_CRED_NTLMv2_AUTH;
866 cli_credentials_get_ntlm_username_domain(cmdline_credentials, tctx,
867 &ninfo.identity_info.account_name.string,
868 &ninfo.identity_info.domain_name.string);
871 ninfo.identity_info.domain_name.string = NULL;
874 generate_random_buffer(ninfo.challenge,
875 sizeof(ninfo.challenge));
876 chal = data_blob_const(ninfo.challenge,
877 sizeof(ninfo.challenge));
879 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials),
880 cli_credentials_get_domain(credentials));
882 status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx,
885 NULL, /* server_timestamp */
889 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
891 ninfo.lm.data = lm_resp.data;
892 ninfo.lm.length = lm_resp.length;
894 ninfo.nt.data = nt_resp.data;
895 ninfo.nt.length = nt_resp.length;
897 ninfo.identity_info.parameter_control = 0;
898 ninfo.identity_info.logon_id_low = 0;
899 ninfo.identity_info.logon_id_high = 0;
900 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
902 logon.network = &ninfo;
904 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
905 r.in.computer_name = cli_credentials_get_workstation(credentials);
906 r.in.credential = &auth;
907 r.in.return_authenticator = &auth2;
908 r.in.logon_level = NetlogonNetworkInformation;
910 r.out.validation = &validation;
911 r.out.authoritative = &authoritative;
913 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
917 netlogon_creds_client_authenticator(creds, &auth);
919 r.in.validation_level = i;
921 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
922 "LogonSamLogon failed");
923 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
925 torture_assert(tctx, netlogon_creds_client_check(creds,
926 &r.out.return_authenticator->cred),
927 "Credential chaining failed");
928 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
929 "LogonSamLogon invalid *r.out.authoritative");
932 /* this makes sure we get the unmarshalling right for invalid levels */
933 for (i=52;i<53;i++) {
935 /* the authenticator should be ignored by the server */
936 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
938 r.in.validation_level = i;
940 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
941 "LogonSamLogon failed");
942 torture_assert_ntstatus_equal(tctx, r.out.result,
943 NT_STATUS_INVALID_INFO_CLASS,
944 "LogonSamLogon failed");
946 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
947 "LogonSamLogon invalid *r.out.authoritative");
949 memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
950 "Return authenticator non zero");
955 netlogon_creds_client_authenticator(creds, &auth);
957 r.in.validation_level = i;
959 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
960 "LogonSamLogon failed");
961 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
963 torture_assert(tctx, netlogon_creds_client_check(creds,
964 &r.out.return_authenticator->cred),
965 "Credential chaining failed");
966 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
967 "LogonSamLogon invalid *r.out.authoritative");
970 r.in.logon_level = 52;
974 /* the authenticator should be ignored by the server */
975 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
977 r.in.validation_level = i;
979 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
981 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
982 "LogonSamLogon failed");
983 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
984 "LogonSamLogon expected INVALID_PARAMETER");
987 memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
988 "Return authenticator non zero");
989 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
990 "LogonSamLogon invalid *r.out.authoritative");
993 r.in.credential = NULL;
998 r.in.validation_level = i;
1000 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
1002 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1003 "LogonSamLogon failed");
1004 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
1005 "LogonSamLogon expected INVALID_PARAMETER");
1007 torture_assert(tctx,
1008 memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
1009 "Return authenticator non zero");
1010 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1011 "LogonSamLogon invalid *r.out.authoritative");
1014 r.in.logon_level = NetlogonNetworkInformation;
1015 r.in.credential = &auth;
1017 for (i=2;i<=3;i++) {
1019 netlogon_creds_client_authenticator(creds, &auth);
1021 r.in.validation_level = i;
1023 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1024 "LogonSamLogon failed");
1025 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
1027 torture_assert(tctx, netlogon_creds_client_check(creds,
1028 &r.out.return_authenticator->cred),
1029 "Credential chaining failed");
1030 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1031 "LogonSamLogon invalid *r.out.authoritative");
1037 bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
1038 struct cli_credentials *credentials,
1039 struct netlogon_creds_CredentialState *creds)
1041 return test_netlogon_ops_args(p, tctx, credentials, creds, false);
1045 try a netlogon GetCapabilities
1047 bool test_netlogon_capabilities(struct dcerpc_pipe *p, struct torture_context *tctx,
1048 struct cli_credentials *credentials,
1049 struct netlogon_creds_CredentialState *creds)
1052 struct netr_LogonGetCapabilities r;
1053 union netr_Capabilities capabilities;
1054 struct netr_Authenticator auth, return_auth;
1055 struct netlogon_creds_CredentialState tmp_creds;
1056 struct dcerpc_binding_handle *b = p->binding_handle;
1058 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1059 r.in.computer_name = cli_credentials_get_workstation(credentials);
1060 r.in.credential = &auth;
1061 r.in.return_authenticator = &return_auth;
1062 r.in.query_level = 1;
1063 r.out.capabilities = &capabilities;
1064 r.out.return_authenticator = &return_auth;
1066 torture_comment(tctx, "Testing LogonGetCapabilities\n");
1068 ZERO_STRUCT(return_auth);
1071 * we need to operate on a temporary copy of creds
1072 * because dcerpc_netr_LogonGetCapabilities was
1073 * dcerpc_netr_DummyFunction and returns NT_STATUS_NOT_IMPLEMENTED
1074 * without looking a the authenticator.
1077 netlogon_creds_client_authenticator(&tmp_creds, &auth);
1079 status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
1080 torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities failed");
1081 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
1087 torture_assert(tctx, netlogon_creds_client_check(creds,
1088 &r.out.return_authenticator->cred),
1089 "Credential chaining failed");
1091 torture_assert_int_equal(tctx, creds->negotiate_flags,
1092 capabilities.server_capabilities,
1099 try a netlogon SamLogon
1101 static bool test_SamLogon(struct torture_context *tctx,
1102 struct dcerpc_pipe *p,
1103 struct cli_credentials *credentials)
1105 struct netlogon_creds_CredentialState *creds;
1107 if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
1111 return test_netlogon_ops(p, tctx, credentials, creds);
1114 static bool test_invalidAuthenticate2(struct torture_context *tctx,
1115 struct dcerpc_pipe *p,
1116 struct cli_credentials *credentials)
1118 struct netlogon_creds_CredentialState *creds;
1119 uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
1121 torture_comment(tctx, "Testing invalidAuthenticate2\n");
1123 if (!test_SetupCredentials2(p, tctx, flags,
1125 cli_credentials_get_secure_channel_type(credentials),
1130 if (!test_SetupCredentials2ex(p, tctx, flags,
1133 cli_credentials_get_secure_channel_type(credentials),
1134 STATUS_BUFFER_OVERFLOW,
1139 if (!test_SetupCredentials2ex(p, tctx, flags,
1142 cli_credentials_get_secure_channel_type(credentials),
1151 static bool test_ServerReqChallengeGlobal(struct torture_context *tctx,
1152 struct dcerpc_pipe *p1,
1153 struct cli_credentials *machine_credentials)
1155 uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
1156 struct netr_ServerReqChallenge r;
1157 struct netr_ServerAuthenticate3 a;
1158 struct netr_Credential credentials1, credentials2, credentials3;
1159 struct netlogon_creds_CredentialState *creds;
1160 struct samr_Password mach_password;
1162 const char *machine_name;
1163 const char *plain_pass;
1164 struct dcerpc_binding_handle *b1 = p1->binding_handle;
1165 struct dcerpc_pipe *p2 = NULL;
1166 struct dcerpc_binding_handle *b2 = NULL;
1168 machine_name = cli_credentials_get_workstation(machine_credentials);
1169 plain_pass = cli_credentials_get_password(machine_credentials);
1171 torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
1173 torture_assert_ntstatus_ok(tctx,
1174 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
1175 &ndr_table_netlogon,
1176 machine_credentials,
1177 tctx->ev, tctx->lp_ctx),
1178 "dcerpc_pipe_connect_b failed");
1179 b2 = p2->binding_handle;
1181 r.in.server_name = NULL;
1182 r.in.computer_name = machine_name;
1183 r.in.credentials = &credentials1;
1184 r.out.return_credentials = &credentials2;
1186 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
1188 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
1189 "ServerReqChallenge failed on b1");
1190 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
1192 E_md4hash(plain_pass, mach_password.hash);
1194 a.in.server_name = NULL;
1195 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
1196 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1197 a.in.computer_name = machine_name;
1198 a.in.negotiate_flags = &flags;
1199 a.in.credentials = &credentials3;
1200 a.out.return_credentials = &credentials3;
1201 a.out.negotiate_flags = &flags;
1204 creds = netlogon_creds_client_init(tctx, a.in.account_name,
1206 a.in.secure_channel_type,
1207 &credentials1, &credentials2,
1208 &mach_password, &credentials3,
1211 torture_assert(tctx, creds != NULL, "memory allocation");
1213 torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
1215 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
1216 "ServerAuthenticate3 failed on b2");
1217 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
1218 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
1223 static bool test_SamLogon_NULL_domain(struct torture_context *tctx,
1224 struct dcerpc_pipe *p,
1225 struct cli_credentials *credentials)
1227 struct netlogon_creds_CredentialState *creds;
1229 if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
1233 return test_netlogon_ops_args(p, tctx, credentials, creds, true);
1236 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
1237 static uint64_t sequence_nums[3];
1240 try a netlogon DatabaseSync
1242 static bool test_DatabaseSync(struct torture_context *tctx,
1243 struct dcerpc_pipe *p,
1244 struct cli_credentials *machine_credentials)
1246 struct netr_DatabaseSync r;
1247 struct netlogon_creds_CredentialState *creds;
1248 const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
1250 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1251 struct netr_Authenticator credential, return_authenticator;
1252 struct dcerpc_binding_handle *b = p->binding_handle;
1254 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1258 ZERO_STRUCT(return_authenticator);
1260 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1261 r.in.computername = TEST_MACHINE_NAME;
1262 r.in.preferredmaximumlength = (uint32_t)-1;
1263 r.in.return_authenticator = &return_authenticator;
1264 r.out.delta_enum_array = &delta_enum_array;
1265 r.out.return_authenticator = &return_authenticator;
1267 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1269 uint32_t sync_context = 0;
1271 r.in.database_id = database_ids[i];
1272 r.in.sync_context = &sync_context;
1273 r.out.sync_context = &sync_context;
1275 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
1278 netlogon_creds_client_authenticator(creds, &credential);
1280 r.in.credential = &credential;
1282 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync_r(b, tctx, &r),
1283 "DatabaseSync failed");
1284 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1287 /* Native mode servers don't do this */
1288 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1291 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync");
1293 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1294 torture_comment(tctx, "Credential chaining failed\n");
1297 if (delta_enum_array &&
1298 delta_enum_array->num_deltas > 0 &&
1299 delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
1300 delta_enum_array->delta_enum[0].delta_union.domain) {
1301 sequence_nums[r.in.database_id] =
1302 delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
1303 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
1305 (unsigned long long)sequence_nums[r.in.database_id]);
1307 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1315 try a netlogon DatabaseDeltas
1317 static bool test_DatabaseDeltas(struct torture_context *tctx,
1318 struct dcerpc_pipe *p,
1319 struct cli_credentials *machine_credentials)
1321 struct netr_DatabaseDeltas r;
1322 struct netlogon_creds_CredentialState *creds;
1323 struct netr_Authenticator credential;
1324 struct netr_Authenticator return_authenticator;
1325 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1326 const uint32_t database_ids[] = {0, 1, 2};
1328 struct dcerpc_binding_handle *b = p->binding_handle;
1330 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1334 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1335 r.in.computername = TEST_MACHINE_NAME;
1336 r.in.preferredmaximumlength = (uint32_t)-1;
1337 ZERO_STRUCT(r.in.return_authenticator);
1338 r.out.return_authenticator = &return_authenticator;
1339 r.out.delta_enum_array = &delta_enum_array;
1341 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1342 r.in.database_id = database_ids[i];
1343 r.in.sequence_num = &sequence_nums[r.in.database_id];
1345 if (*r.in.sequence_num == 0) continue;
1347 *r.in.sequence_num -= 1;
1349 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n",
1350 r.in.database_id, (unsigned long long)*r.in.sequence_num);
1353 netlogon_creds_client_authenticator(creds, &credential);
1355 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseDeltas_r(b, tctx, &r),
1356 "DatabaseDeltas failed");
1357 if (NT_STATUS_EQUAL(r.out.result,
1358 NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
1359 torture_comment(tctx, "not considering %s to be an error\n",
1360 nt_errstr(r.out.result));
1363 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1366 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseDeltas");
1368 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1369 torture_comment(tctx, "Credential chaining failed\n");
1372 (*r.in.sequence_num)++;
1373 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1379 static bool test_DatabaseRedo(struct torture_context *tctx,
1380 struct dcerpc_pipe *p,
1381 struct cli_credentials *machine_credentials)
1383 struct netr_DatabaseRedo r;
1384 struct netlogon_creds_CredentialState *creds;
1385 struct netr_Authenticator credential;
1386 struct netr_Authenticator return_authenticator;
1387 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1388 struct netr_ChangeLogEntry e;
1389 struct dom_sid null_sid, *sid;
1391 struct dcerpc_binding_handle *b = p->binding_handle;
1393 ZERO_STRUCT(null_sid);
1395 sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
1406 NTSTATUS expected_error;
1407 uint32_t expected_num_results;
1408 uint8_t expected_delta_type_1;
1409 uint8_t expected_delta_type_2;
1410 const char *comment;
1413 /* SAM_DATABASE_DOMAIN */
1418 .db_index = SAM_DATABASE_DOMAIN,
1419 .delta_type = NETR_DELTA_MODIFY_COUNT,
1422 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1423 .expected_num_results = 0,
1424 .comment = "NETR_DELTA_MODIFY_COUNT"
1429 .db_index = SAM_DATABASE_DOMAIN,
1433 .expected_error = NT_STATUS_OK,
1434 .expected_num_results = 1,
1435 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1436 .comment = "NULL DELTA"
1441 .db_index = SAM_DATABASE_DOMAIN,
1442 .delta_type = NETR_DELTA_DOMAIN,
1445 .expected_error = NT_STATUS_OK,
1446 .expected_num_results = 1,
1447 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1448 .comment = "NETR_DELTA_DOMAIN"
1451 .rid = DOMAIN_RID_ADMINISTRATOR,
1453 .db_index = SAM_DATABASE_DOMAIN,
1454 .delta_type = NETR_DELTA_USER,
1457 .expected_error = NT_STATUS_OK,
1458 .expected_num_results = 1,
1459 .expected_delta_type_1 = NETR_DELTA_USER,
1460 .comment = "NETR_DELTA_USER by rid 500"
1463 .rid = DOMAIN_RID_GUEST,
1465 .db_index = SAM_DATABASE_DOMAIN,
1466 .delta_type = NETR_DELTA_USER,
1469 .expected_error = NT_STATUS_OK,
1470 .expected_num_results = 1,
1471 .expected_delta_type_1 = NETR_DELTA_USER,
1472 .comment = "NETR_DELTA_USER by rid 501"
1476 .flags = NETR_CHANGELOG_SID_INCLUDED,
1477 .db_index = SAM_DATABASE_DOMAIN,
1478 .delta_type = NETR_DELTA_USER,
1481 .expected_error = NT_STATUS_OK,
1482 .expected_num_results = 1,
1483 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1484 .comment = "NETR_DELTA_USER by sid and flags"
1488 .flags = NETR_CHANGELOG_SID_INCLUDED,
1489 .db_index = SAM_DATABASE_DOMAIN,
1490 .delta_type = NETR_DELTA_USER,
1493 .expected_error = NT_STATUS_OK,
1494 .expected_num_results = 1,
1495 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1496 .comment = "NETR_DELTA_USER by null_sid and flags"
1500 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1501 .db_index = SAM_DATABASE_DOMAIN,
1502 .delta_type = NETR_DELTA_USER,
1504 .name = "administrator",
1505 .expected_error = NT_STATUS_OK,
1506 .expected_num_results = 1,
1507 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1508 .comment = "NETR_DELTA_USER by name 'administrator'"
1511 .rid = DOMAIN_RID_ADMINS,
1513 .db_index = SAM_DATABASE_DOMAIN,
1514 .delta_type = NETR_DELTA_GROUP,
1517 .expected_error = NT_STATUS_OK,
1518 .expected_num_results = 2,
1519 .expected_delta_type_1 = NETR_DELTA_GROUP,
1520 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
1521 .comment = "NETR_DELTA_GROUP by rid 512"
1524 .rid = DOMAIN_RID_ADMINS,
1526 .db_index = SAM_DATABASE_DOMAIN,
1527 .delta_type = NETR_DELTA_GROUP_MEMBER,
1530 .expected_error = NT_STATUS_OK,
1531 .expected_num_results = 2,
1532 .expected_delta_type_1 = NETR_DELTA_GROUP,
1533 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
1534 .comment = "NETR_DELTA_GROUP_MEMBER by rid 512"
1538 /* SAM_DATABASE_BUILTIN */
1543 .db_index = SAM_DATABASE_BUILTIN,
1544 .delta_type = NETR_DELTA_MODIFY_COUNT,
1547 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1548 .expected_num_results = 0,
1549 .comment = "NETR_DELTA_MODIFY_COUNT"
1554 .db_index = SAM_DATABASE_BUILTIN,
1555 .delta_type = NETR_DELTA_DOMAIN,
1558 .expected_error = NT_STATUS_OK,
1559 .expected_num_results = 1,
1560 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1561 .comment = "NETR_DELTA_DOMAIN"
1564 .rid = DOMAIN_RID_ADMINISTRATOR,
1566 .db_index = SAM_DATABASE_BUILTIN,
1567 .delta_type = NETR_DELTA_USER,
1570 .expected_error = NT_STATUS_OK,
1571 .expected_num_results = 1,
1572 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1573 .comment = "NETR_DELTA_USER by rid 500"
1578 .db_index = SAM_DATABASE_BUILTIN,
1579 .delta_type = NETR_DELTA_USER,
1582 .expected_error = NT_STATUS_OK,
1583 .expected_num_results = 1,
1584 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1585 .comment = "NETR_DELTA_USER"
1590 .db_index = SAM_DATABASE_BUILTIN,
1591 .delta_type = NETR_DELTA_ALIAS,
1594 .expected_error = NT_STATUS_OK,
1595 .expected_num_results = 2,
1596 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1597 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1598 .comment = "NETR_DELTA_ALIAS by rid 544"
1603 .db_index = SAM_DATABASE_BUILTIN,
1604 .delta_type = NETR_DELTA_ALIAS_MEMBER,
1607 .expected_error = NT_STATUS_OK,
1608 .expected_num_results = 2,
1609 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1610 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1611 .comment = "NETR_DELTA_ALIAS_MEMBER by rid 544"
1616 .db_index = SAM_DATABASE_BUILTIN,
1620 .expected_error = NT_STATUS_OK,
1621 .expected_num_results = 1,
1622 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1623 .comment = "NULL DELTA by rid 544"
1627 .flags = NETR_CHANGELOG_SID_INCLUDED,
1628 .db_index = SAM_DATABASE_BUILTIN,
1630 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1632 .expected_error = NT_STATUS_OK,
1633 .expected_num_results = 1,
1634 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1635 .comment = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
1639 .flags = NETR_CHANGELOG_SID_INCLUDED,
1640 .db_index = SAM_DATABASE_BUILTIN,
1641 .delta_type = NETR_DELTA_ALIAS,
1642 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1644 .expected_error = NT_STATUS_OK,
1645 .expected_num_results = 2,
1646 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1647 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1648 .comment = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
1652 .flags = NETR_CHANGELOG_SID_INCLUDED,
1653 .db_index = SAM_DATABASE_BUILTIN,
1654 .delta_type = NETR_DELTA_ALIAS,
1655 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1657 .expected_error = NT_STATUS_OK,
1658 .expected_num_results = 1,
1659 .expected_delta_type_1 = NETR_DELTA_DELETE_ALIAS,
1660 .comment = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
1663 /* SAM_DATABASE_PRIVS */
1668 .db_index = SAM_DATABASE_PRIVS,
1672 .expected_error = NT_STATUS_ACCESS_DENIED,
1673 .expected_num_results = 0,
1674 .comment = "NULL DELTA"
1679 .db_index = SAM_DATABASE_PRIVS,
1680 .delta_type = NETR_DELTA_MODIFY_COUNT,
1683 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1684 .expected_num_results = 0,
1685 .comment = "NETR_DELTA_MODIFY_COUNT"
1690 .db_index = SAM_DATABASE_PRIVS,
1691 .delta_type = NETR_DELTA_POLICY,
1694 .expected_error = NT_STATUS_OK,
1695 .expected_num_results = 1,
1696 .expected_delta_type_1 = NETR_DELTA_POLICY,
1697 .comment = "NETR_DELTA_POLICY"
1701 .flags = NETR_CHANGELOG_SID_INCLUDED,
1702 .db_index = SAM_DATABASE_PRIVS,
1703 .delta_type = NETR_DELTA_POLICY,
1706 .expected_error = NT_STATUS_OK,
1707 .expected_num_results = 1,
1708 .expected_delta_type_1 = NETR_DELTA_POLICY,
1709 .comment = "NETR_DELTA_POLICY by null sid and flags"
1713 .flags = NETR_CHANGELOG_SID_INCLUDED,
1714 .db_index = SAM_DATABASE_PRIVS,
1715 .delta_type = NETR_DELTA_POLICY,
1716 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
1718 .expected_error = NT_STATUS_OK,
1719 .expected_num_results = 1,
1720 .expected_delta_type_1 = NETR_DELTA_POLICY,
1721 .comment = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
1724 .rid = DOMAIN_RID_ADMINISTRATOR,
1726 .db_index = SAM_DATABASE_PRIVS,
1727 .delta_type = NETR_DELTA_ACCOUNT,
1730 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
1731 .expected_num_results = 0,
1732 .comment = "NETR_DELTA_ACCOUNT by rid 500"
1736 .flags = NETR_CHANGELOG_SID_INCLUDED,
1737 .db_index = SAM_DATABASE_PRIVS,
1738 .delta_type = NETR_DELTA_ACCOUNT,
1739 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1741 .expected_error = NT_STATUS_OK,
1742 .expected_num_results = 1,
1743 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
1744 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
1748 .flags = NETR_CHANGELOG_SID_INCLUDED |
1749 NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
1750 .db_index = SAM_DATABASE_PRIVS,
1751 .delta_type = NETR_DELTA_ACCOUNT,
1752 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1754 .expected_error = NT_STATUS_OK,
1755 .expected_num_results = 1,
1756 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
1757 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
1761 .flags = NETR_CHANGELOG_SID_INCLUDED |
1762 NETR_CHANGELOG_NAME_INCLUDED,
1763 .db_index = SAM_DATABASE_PRIVS,
1764 .delta_type = NETR_DELTA_ACCOUNT,
1765 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1767 .expected_error = NT_STATUS_INVALID_PARAMETER,
1768 .expected_num_results = 0,
1769 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
1772 .rid = DOMAIN_RID_ADMINISTRATOR,
1773 .flags = NETR_CHANGELOG_SID_INCLUDED,
1774 .db_index = SAM_DATABASE_PRIVS,
1775 .delta_type = NETR_DELTA_ACCOUNT,
1778 .expected_error = NT_STATUS_OK,
1779 .expected_num_results = 1,
1780 .expected_delta_type_1 = NETR_DELTA_DELETE_ACCOUNT,
1781 .comment = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
1785 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1786 .db_index = SAM_DATABASE_PRIVS,
1787 .delta_type = NETR_DELTA_SECRET,
1789 .name = "IsurelydontexistIhope",
1790 .expected_error = NT_STATUS_OK,
1791 .expected_num_results = 1,
1792 .expected_delta_type_1 = NETR_DELTA_DELETE_SECRET,
1793 .comment = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
1797 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1798 .db_index = SAM_DATABASE_PRIVS,
1799 .delta_type = NETR_DELTA_SECRET,
1801 .name = "G$BCKUPKEY_P",
1802 .expected_error = NT_STATUS_OK,
1803 .expected_num_results = 1,
1804 .expected_delta_type_1 = NETR_DELTA_SECRET,
1805 .comment = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
1809 ZERO_STRUCT(return_authenticator);
1811 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1812 r.in.computername = TEST_MACHINE_NAME;
1813 r.in.return_authenticator = &return_authenticator;
1814 r.out.return_authenticator = &return_authenticator;
1815 r.out.delta_enum_array = &delta_enum_array;
1817 for (d=0; d<3; d++) {
1818 const char *database = NULL;
1825 database = "BUILTIN";
1834 torture_comment(tctx, "Testing DatabaseRedo\n");
1836 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1840 for (i=0;i<ARRAY_SIZE(changes);i++) {
1842 if (d != changes[i].db_index) {
1846 netlogon_creds_client_authenticator(creds, &credential);
1848 r.in.credential = &credential;
1850 e.serial_number1 = 0;
1851 e.serial_number2 = 0;
1852 e.object_rid = changes[i].rid;
1853 e.flags = changes[i].flags;
1854 e.db_index = changes[i].db_index;
1855 e.delta_type = changes[i].delta_type;
1857 switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
1858 case NETR_CHANGELOG_SID_INCLUDED:
1859 e.object.object_sid = changes[i].sid;
1861 case NETR_CHANGELOG_NAME_INCLUDED:
1862 e.object.object_name = changes[i].name;
1868 r.in.change_log_entry = e;
1870 torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
1871 database, changes[i].comment);
1873 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseRedo_r(b, tctx, &r),
1874 "DatabaseRedo failed");
1875 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1879 torture_assert_ntstatus_equal(tctx, r.out.result, changes[i].expected_error, changes[i].comment);
1880 if (delta_enum_array) {
1881 torture_assert_int_equal(tctx,
1882 delta_enum_array->num_deltas,
1883 changes[i].expected_num_results,
1884 changes[i].comment);
1885 if (delta_enum_array->num_deltas > 0) {
1886 torture_assert_int_equal(tctx,
1887 delta_enum_array->delta_enum[0].delta_type,
1888 changes[i].expected_delta_type_1,
1889 changes[i].comment);
1891 if (delta_enum_array->num_deltas > 1) {
1892 torture_assert_int_equal(tctx,
1893 delta_enum_array->delta_enum[1].delta_type,
1894 changes[i].expected_delta_type_2,
1895 changes[i].comment);
1899 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1900 torture_comment(tctx, "Credential chaining failed\n");
1901 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1913 try a netlogon AccountDeltas
1915 static bool test_AccountDeltas(struct torture_context *tctx,
1916 struct dcerpc_pipe *p,
1917 struct cli_credentials *machine_credentials)
1919 struct netr_AccountDeltas r;
1920 struct netlogon_creds_CredentialState *creds;
1922 struct netr_AccountBuffer buffer;
1923 uint32_t count_returned = 0;
1924 uint32_t total_entries = 0;
1925 struct netr_UAS_INFO_0 recordid;
1926 struct netr_Authenticator return_authenticator;
1927 struct dcerpc_binding_handle *b = p->binding_handle;
1929 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1933 ZERO_STRUCT(return_authenticator);
1935 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1936 r.in.computername = TEST_MACHINE_NAME;
1937 r.in.return_authenticator = &return_authenticator;
1938 netlogon_creds_client_authenticator(creds, &r.in.credential);
1939 ZERO_STRUCT(r.in.uas);
1942 r.in.buffersize=100;
1943 r.out.buffer = &buffer;
1944 r.out.count_returned = &count_returned;
1945 r.out.total_entries = &total_entries;
1946 r.out.recordid = &recordid;
1947 r.out.return_authenticator = &return_authenticator;
1949 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1950 torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountDeltas_r(b, tctx, &r),
1951 "AccountDeltas failed");
1952 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
1958 try a netlogon AccountSync
1960 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
1961 struct cli_credentials *machine_credentials)
1963 struct netr_AccountSync r;
1964 struct netlogon_creds_CredentialState *creds;
1966 struct netr_AccountBuffer buffer;
1967 uint32_t count_returned = 0;
1968 uint32_t total_entries = 0;
1969 uint32_t next_reference = 0;
1970 struct netr_UAS_INFO_0 recordid;
1971 struct netr_Authenticator return_authenticator;
1972 struct dcerpc_binding_handle *b = p->binding_handle;
1974 ZERO_STRUCT(recordid);
1975 ZERO_STRUCT(return_authenticator);
1977 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1981 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1982 r.in.computername = TEST_MACHINE_NAME;
1983 r.in.return_authenticator = &return_authenticator;
1984 netlogon_creds_client_authenticator(creds, &r.in.credential);
1985 r.in.recordid = &recordid;
1988 r.in.buffersize=100;
1989 r.out.buffer = &buffer;
1990 r.out.count_returned = &count_returned;
1991 r.out.total_entries = &total_entries;
1992 r.out.next_reference = &next_reference;
1993 r.out.recordid = &recordid;
1994 r.out.return_authenticator = &return_authenticator;
1996 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1997 torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountSync_r(b, tctx, &r),
1998 "AccountSync failed");
1999 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
2005 try a netlogon GetDcName
2007 static bool test_GetDcName(struct torture_context *tctx,
2008 struct dcerpc_pipe *p)
2010 struct netr_GetDcName r;
2011 const char *dcname = NULL;
2012 struct dcerpc_binding_handle *b = p->binding_handle;
2014 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2015 r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
2016 r.out.dcname = &dcname;
2018 torture_assert_ntstatus_ok(tctx, dcerpc_netr_GetDcName_r(b, tctx, &r),
2019 "GetDcName failed");
2020 torture_assert_werr_ok(tctx, r.out.result, "GetDcName failed");
2022 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
2027 static const char *function_code_str(TALLOC_CTX *mem_ctx,
2028 enum netr_LogonControlCode function_code)
2030 switch (function_code) {
2031 case NETLOGON_CONTROL_QUERY:
2032 return "NETLOGON_CONTROL_QUERY";
2033 case NETLOGON_CONTROL_REPLICATE:
2034 return "NETLOGON_CONTROL_REPLICATE";
2035 case NETLOGON_CONTROL_SYNCHRONIZE:
2036 return "NETLOGON_CONTROL_SYNCHRONIZE";
2037 case NETLOGON_CONTROL_PDC_REPLICATE:
2038 return "NETLOGON_CONTROL_PDC_REPLICATE";
2039 case NETLOGON_CONTROL_REDISCOVER:
2040 return "NETLOGON_CONTROL_REDISCOVER";
2041 case NETLOGON_CONTROL_TC_QUERY:
2042 return "NETLOGON_CONTROL_TC_QUERY";
2043 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
2044 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
2045 case NETLOGON_CONTROL_FIND_USER:
2046 return "NETLOGON_CONTROL_FIND_USER";
2047 case NETLOGON_CONTROL_CHANGE_PASSWORD:
2048 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
2049 case NETLOGON_CONTROL_TC_VERIFY:
2050 return "NETLOGON_CONTROL_TC_VERIFY";
2051 case NETLOGON_CONTROL_FORCE_DNS_REG:
2052 return "NETLOGON_CONTROL_FORCE_DNS_REG";
2053 case NETLOGON_CONTROL_QUERY_DNS_REG:
2054 return "NETLOGON_CONTROL_QUERY_DNS_REG";
2055 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
2056 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
2057 case NETLOGON_CONTROL_TRUNCATE_LOG:
2058 return "NETLOGON_CONTROL_TRUNCATE_LOG";
2059 case NETLOGON_CONTROL_SET_DBFLAG:
2060 return "NETLOGON_CONTROL_SET_DBFLAG";
2061 case NETLOGON_CONTROL_BREAKPOINT:
2062 return "NETLOGON_CONTROL_BREAKPOINT";
2064 return talloc_asprintf(mem_ctx, "unknown function code: %d",
2071 try a netlogon LogonControl
2073 static bool test_LogonControl(struct torture_context *tctx,
2074 struct dcerpc_pipe *p,
2075 struct cli_credentials *machine_credentials)
2079 struct netr_LogonControl r;
2080 union netr_CONTROL_QUERY_INFORMATION query;
2082 enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
2083 struct dcerpc_binding_handle *b = p->binding_handle;
2085 uint32_t function_codes[] = {
2086 NETLOGON_CONTROL_QUERY,
2087 NETLOGON_CONTROL_REPLICATE,
2088 NETLOGON_CONTROL_SYNCHRONIZE,
2089 NETLOGON_CONTROL_PDC_REPLICATE,
2090 NETLOGON_CONTROL_REDISCOVER,
2091 NETLOGON_CONTROL_TC_QUERY,
2092 NETLOGON_CONTROL_TRANSPORT_NOTIFY,
2093 NETLOGON_CONTROL_FIND_USER,
2094 NETLOGON_CONTROL_CHANGE_PASSWORD,
2095 NETLOGON_CONTROL_TC_VERIFY,
2096 NETLOGON_CONTROL_FORCE_DNS_REG,
2097 NETLOGON_CONTROL_QUERY_DNS_REG,
2098 NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
2099 NETLOGON_CONTROL_TRUNCATE_LOG,
2100 NETLOGON_CONTROL_SET_DBFLAG,
2101 NETLOGON_CONTROL_BREAKPOINT
2104 if (machine_credentials) {
2105 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2108 torture_comment(tctx, "Testing LogonControl with secure channel type: %d\n",
2109 secure_channel_type);
2111 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2112 r.in.function_code = 1;
2113 r.out.query = &query;
2115 for (f=0;f<ARRAY_SIZE(function_codes); f++) {
2118 r.in.function_code = function_codes[f];
2121 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
2122 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2124 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
2125 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2127 switch (r.in.level) {
2129 switch (r.in.function_code) {
2130 case NETLOGON_CONTROL_REPLICATE:
2131 case NETLOGON_CONTROL_SYNCHRONIZE:
2132 case NETLOGON_CONTROL_PDC_REPLICATE:
2133 case NETLOGON_CONTROL_BREAKPOINT:
2134 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
2135 if ((secure_channel_type == SEC_CHAN_BDC) ||
2136 (secure_channel_type == SEC_CHAN_WKSTA)) {
2137 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
2138 "LogonControl returned unexpected error code");
2140 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
2141 "LogonControl returned unexpected error code");
2145 case NETLOGON_CONTROL_REDISCOVER:
2146 case NETLOGON_CONTROL_TC_QUERY:
2147 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
2148 case NETLOGON_CONTROL_FIND_USER:
2149 case NETLOGON_CONTROL_CHANGE_PASSWORD:
2150 case NETLOGON_CONTROL_TC_VERIFY:
2151 case NETLOGON_CONTROL_FORCE_DNS_REG:
2152 case NETLOGON_CONTROL_QUERY_DNS_REG:
2153 case NETLOGON_CONTROL_SET_DBFLAG:
2154 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
2155 "LogonControl returned unexpected error code");
2157 case NETLOGON_CONTROL_TRUNCATE_LOG:
2158 if ((secure_channel_type == SEC_CHAN_BDC) ||
2159 (secure_channel_type == SEC_CHAN_WKSTA)) {
2160 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
2161 "LogonControl returned unexpected error code");
2162 } else if (!W_ERROR_EQUAL(r.out.result, WERR_NOT_SUPPORTED)) {
2163 torture_assert_werr_ok(tctx, r.out.result,
2164 "LogonControl returned unexpected result");
2168 torture_assert_werr_ok(tctx, r.out.result,
2169 "LogonControl returned unexpected result");
2174 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
2175 "LogonControl returned unexpected error code");
2178 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL,
2179 "LogonControl returned unexpected error code");
2186 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
2187 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2188 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
2189 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2190 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl");
2197 try a netlogon GetAnyDCName
2199 static bool test_GetAnyDCName(struct torture_context *tctx,
2200 struct dcerpc_pipe *p)
2203 struct netr_GetAnyDCName r;
2204 const char *dcname = NULL;
2205 struct dcerpc_binding_handle *b = p->binding_handle;
2207 r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
2208 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2209 r.out.dcname = &dcname;
2211 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2212 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2213 if ((!W_ERROR_IS_OK(r.out.result)) &&
2214 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2219 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
2222 r.in.domainname = NULL;
2224 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2225 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2226 if ((!W_ERROR_IS_OK(r.out.result)) &&
2227 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2231 r.in.domainname = "";
2233 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2234 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2235 if ((!W_ERROR_IS_OK(r.out.result)) &&
2236 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2245 try a netlogon LogonControl2
2247 static bool test_LogonControl2(struct torture_context *tctx,
2248 struct dcerpc_pipe *p,
2249 struct cli_credentials *machine_credentials)
2253 struct netr_LogonControl2 r;
2254 union netr_CONTROL_DATA_INFORMATION data;
2255 union netr_CONTROL_QUERY_INFORMATION query;
2256 enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
2258 struct dcerpc_binding_handle *b = p->binding_handle;
2260 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2262 if (machine_credentials) {
2263 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2266 torture_comment(tctx, "Testing LogonControl2 with secure channel type: %d\n",
2267 secure_channel_type);
2269 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2271 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2273 r.out.query = &query;
2278 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2279 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2281 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2282 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2285 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2287 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2293 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2294 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2296 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2297 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2300 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2302 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2308 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2309 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2311 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2312 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2315 data.debug_level = ~0;
2317 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2323 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2324 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2326 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2327 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2331 r.in.function_code = 52;
2334 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2335 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2337 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2338 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2339 switch (secure_channel_type) {
2341 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2");
2344 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2");
2347 data.debug_level = ~0;
2349 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2353 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2354 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2356 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2357 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2358 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "LogonControl2");
2364 try a netlogon DatabaseSync2
2366 static bool test_DatabaseSync2(struct torture_context *tctx,
2367 struct dcerpc_pipe *p,
2368 struct cli_credentials *machine_credentials)
2370 struct netr_DatabaseSync2 r;
2371 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2372 struct netr_Authenticator return_authenticator, credential;
2374 struct netlogon_creds_CredentialState *creds;
2375 const uint32_t database_ids[] = {0, 1, 2};
2377 struct dcerpc_binding_handle *b = p->binding_handle;
2379 if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
2380 machine_credentials,
2381 cli_credentials_get_secure_channel_type(machine_credentials),
2386 ZERO_STRUCT(return_authenticator);
2388 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2389 r.in.computername = TEST_MACHINE_NAME;
2390 r.in.preferredmaximumlength = (uint32_t)-1;
2391 r.in.return_authenticator = &return_authenticator;
2392 r.out.return_authenticator = &return_authenticator;
2393 r.out.delta_enum_array = &delta_enum_array;
2395 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2397 uint32_t sync_context = 0;
2399 r.in.database_id = database_ids[i];
2400 r.in.sync_context = &sync_context;
2401 r.out.sync_context = &sync_context;
2402 r.in.restart_state = 0;
2404 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
2407 netlogon_creds_client_authenticator(creds, &credential);
2409 r.in.credential = &credential;
2411 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync2_r(b, tctx, &r),
2412 "DatabaseSync2 failed");
2413 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2416 /* Native mode servers don't do this */
2417 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
2421 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync2");
2423 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
2424 torture_comment(tctx, "Credential chaining failed\n");
2427 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2435 try a netlogon LogonControl2Ex
2437 static bool test_LogonControl2Ex(struct torture_context *tctx,
2438 struct dcerpc_pipe *p,
2439 struct cli_credentials *machine_credentials)
2443 struct netr_LogonControl2Ex r;
2444 union netr_CONTROL_DATA_INFORMATION data;
2445 union netr_CONTROL_QUERY_INFORMATION query;
2446 enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
2448 struct dcerpc_binding_handle *b = p->binding_handle;
2450 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2452 if (machine_credentials) {
2453 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2456 torture_comment(tctx, "Testing LogonControl2Ex with secure channel type: %d\n",
2457 secure_channel_type);
2459 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2461 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2463 r.out.query = &query;
2468 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2469 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2471 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2472 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2475 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2477 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2483 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2484 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2486 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2487 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2490 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2492 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2498 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2499 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2501 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2502 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2505 data.debug_level = ~0;
2507 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2513 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2514 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2516 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2517 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2521 r.in.function_code = 52;
2524 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2525 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2527 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2528 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2529 switch (secure_channel_type) {
2531 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2Ex");
2534 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2Ex");
2537 data.debug_level = ~0;
2539 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2543 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2544 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2546 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2547 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2548 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "LogonControl2Ex");
2553 static bool test_netr_GetForestTrustInformation(struct torture_context *tctx,
2554 struct dcerpc_pipe *p1,
2555 struct cli_credentials *machine_credentials)
2557 struct netr_GetForestTrustInformation r;
2558 struct netlogon_creds_CredentialState *creds;
2559 struct netr_Authenticator a;
2560 struct netr_Authenticator return_authenticator;
2561 struct lsa_ForestTrustInformation *forest_trust_info;
2562 struct dcerpc_pipe *p = NULL;
2563 struct dcerpc_binding_handle *b = NULL;
2565 if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2566 machine_credentials, &creds)) {
2569 if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
2570 DCERPC_SIGN | DCERPC_SEAL, &p)) {
2573 b = p->binding_handle;
2575 netlogon_creds_client_authenticator(creds, &a);
2577 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2578 r.in.computer_name = TEST_MACHINE_NAME;
2579 r.in.credential = &a;
2581 r.out.return_authenticator = &return_authenticator;
2582 r.out.forest_trust_info = &forest_trust_info;
2584 torture_assert_ntstatus_ok(tctx,
2585 dcerpc_netr_GetForestTrustInformation_r(b, tctx, &r),
2586 "netr_GetForestTrustInformation failed");
2587 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2588 torture_comment(tctx, "not considering NT_STATUS_NOT_IMPLEMENTED as an error\n");
2590 torture_assert_ntstatus_ok(tctx, r.out.result,
2591 "netr_GetForestTrustInformation failed");
2594 torture_assert(tctx,
2595 netlogon_creds_client_check(creds, &return_authenticator.cred),
2596 "Credential chaining failed");
2601 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
2602 struct dcerpc_pipe *p, const char *trusted_domain_name)
2605 struct netr_DsRGetForestTrustInformation r;
2606 struct lsa_ForestTrustInformation info, *info_ptr;
2607 struct dcerpc_binding_handle *b = p->binding_handle;
2611 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2612 r.in.trusted_domain_name = trusted_domain_name;
2614 r.out.forest_trust_info = &info_ptr;
2616 torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
2618 status = dcerpc_netr_DsRGetForestTrustInformation_r(b, tctx, &r);
2619 torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
2620 torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
2626 try a netlogon netr_DsrEnumerateDomainTrusts
2628 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
2629 struct dcerpc_pipe *p)
2632 struct netr_DsrEnumerateDomainTrusts r;
2633 struct netr_DomainTrustList trusts;
2635 struct dcerpc_binding_handle *b = p->binding_handle;
2637 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2638 r.in.trust_flags = 0x3f;
2639 r.out.trusts = &trusts;
2641 status = dcerpc_netr_DsrEnumerateDomainTrusts_r(b, tctx, &r);
2642 torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
2643 torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
2645 /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
2646 * will show non-forest trusts and all UPN suffixes of the own forest
2647 * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
2649 if (r.out.trusts->count) {
2650 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
2655 for (i=0; i<r.out.trusts->count; i++) {
2657 /* get info for transitive forest trusts */
2659 if (r.out.trusts->array[i].trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2660 if (!test_netr_DsRGetForestTrustInformation(tctx, p,
2661 r.out.trusts->array[i].dns_name)) {
2670 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
2671 struct dcerpc_pipe *p)
2674 struct netr_NetrEnumerateTrustedDomains r;
2675 struct netr_Blob trusted_domains_blob;
2676 struct dcerpc_binding_handle *b = p->binding_handle;
2678 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2679 r.out.trusted_domains_blob = &trusted_domains_blob;
2681 status = dcerpc_netr_NetrEnumerateTrustedDomains_r(b, tctx, &r);
2682 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
2683 torture_assert_ntstatus_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
2688 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
2689 struct dcerpc_pipe *p)
2692 struct netr_NetrEnumerateTrustedDomainsEx r;
2693 struct netr_DomainTrustList dom_trust_list;
2694 struct dcerpc_binding_handle *b = p->binding_handle;
2696 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2697 r.out.dom_trust_list = &dom_trust_list;
2699 status = dcerpc_netr_NetrEnumerateTrustedDomainsEx_r(b, tctx, &r);
2700 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
2701 torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
2707 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
2708 const char *computer_name,
2709 const char *expected_site)
2712 struct netr_DsRGetSiteName r;
2713 const char *site = NULL;
2714 struct dcerpc_binding_handle *b = p->binding_handle;
2716 r.in.computer_name = computer_name;
2718 torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
2720 status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
2721 torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2722 torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
2723 torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
2729 try a netlogon netr_DsRGetDCName
2731 static bool test_netr_DsRGetDCName(struct torture_context *tctx,
2732 struct dcerpc_pipe *p)
2735 struct netr_DsRGetDCName r;
2736 struct netr_DsRGetDCNameInfo *info = NULL;
2737 struct dcerpc_binding_handle *b = p->binding_handle;
2739 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2740 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
2741 r.in.domain_guid = NULL;
2742 r.in.site_guid = NULL;
2743 r.in.flags = DS_RETURN_DNS_NAME;
2746 status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2747 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2748 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2750 torture_assert_int_equal(tctx,
2751 (info->dc_flags & (DS_DNS_CONTROLLER)),
2754 torture_assert_int_equal(tctx,
2755 (info->dc_flags & (DS_DNS_DOMAIN)),
2758 torture_assert_int_equal(tctx,
2759 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2763 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
2766 status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2767 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2768 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2770 torture_assert_int_equal(tctx,
2771 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2773 torture_assert_int_equal(tctx,
2774 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2776 torture_assert_int_equal(tctx,
2777 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2781 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2782 torture_assert_int_equal(tctx,
2783 (info->dc_flags & (DS_SERVER_CLOSEST)),
2788 return test_netr_DsRGetSiteName(p, tctx,
2790 info->dc_site_name);
2794 try a netlogon netr_DsRGetDCNameEx
2796 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
2797 struct dcerpc_pipe *p)
2800 struct netr_DsRGetDCNameEx r;
2801 struct netr_DsRGetDCNameInfo *info = NULL;
2802 struct dcerpc_binding_handle *b = p->binding_handle;
2804 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2805 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
2806 r.in.domain_guid = NULL;
2807 r.in.site_name = NULL;
2808 r.in.flags = DS_RETURN_DNS_NAME;
2811 status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2812 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2813 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2815 torture_assert_int_equal(tctx,
2816 (info->dc_flags & (DS_DNS_CONTROLLER)),
2819 torture_assert_int_equal(tctx,
2820 (info->dc_flags & (DS_DNS_DOMAIN)),
2823 torture_assert_int_equal(tctx,
2824 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2828 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
2831 status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2832 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2833 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2835 torture_assert_int_equal(tctx,
2836 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2838 torture_assert_int_equal(tctx,
2839 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2841 torture_assert_int_equal(tctx,
2842 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2846 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2847 torture_assert_int_equal(tctx,
2848 (info->dc_flags & (DS_SERVER_CLOSEST)),
2853 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2854 info->dc_site_name);
2858 try a netlogon netr_DsRGetDCNameEx2
2860 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
2861 struct dcerpc_pipe *p)
2864 struct netr_DsRGetDCNameEx2 r;
2865 struct netr_DsRGetDCNameInfo *info = NULL;
2866 struct dcerpc_binding_handle *b = p->binding_handle;
2868 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with no inputs\n");
2870 r.in.flags = DS_RETURN_DNS_NAME;
2873 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2874 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2875 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2877 torture_assert_int_equal(tctx,
2878 (info->dc_flags & (DS_DNS_CONTROLLER)),
2881 torture_assert_int_equal(tctx,
2882 (info->dc_flags & (DS_DNS_DOMAIN)),
2885 torture_assert_int_equal(tctx,
2886 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2890 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2891 r.in.client_account = NULL;
2892 r.in.mask = 0x00000000;
2893 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
2894 r.in.domain_guid = NULL;
2895 r.in.site_name = NULL;
2896 r.in.flags = DS_RETURN_DNS_NAME;
2899 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
2901 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2902 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2903 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2905 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
2908 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2909 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2910 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2912 torture_assert_int_equal(tctx,
2913 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2915 torture_assert_int_equal(tctx,
2916 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2918 torture_assert_int_equal(tctx,
2919 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2923 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2924 torture_assert_int_equal(tctx,
2925 (info->dc_flags & (DS_SERVER_CLOSEST)),
2930 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client account\n");
2931 r.in.client_account = TEST_MACHINE_NAME"$";
2932 r.in.mask = ACB_SVRTRUST;
2933 r.in.flags = DS_RETURN_FLAT_NAME;
2936 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2937 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2938 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2940 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2941 info->dc_site_name);
2944 /* This is a substitution for "samdb_server_site_name" which relies on the
2945 * correct "lp_ctx" and therefore can't be used here. */
2946 static const char *server_site_name(struct torture_context *tctx,
2947 struct ldb_context *ldb)
2949 TALLOC_CTX *tmp_ctx;
2950 struct ldb_dn *dn, *server_dn;
2951 const struct ldb_val *site_name_val;
2952 const char *server_dn_str, *site_name;
2954 tmp_ctx = talloc_new(ldb);
2955 if (tmp_ctx == NULL) {
2959 dn = ldb_dn_new(tmp_ctx, ldb, "");
2964 server_dn_str = samdb_search_string(ldb, tmp_ctx, dn, "serverName",
2966 if (server_dn_str == NULL) {
2970 server_dn = ldb_dn_new(tmp_ctx, ldb, server_dn_str);
2971 if (server_dn == NULL) {
2975 /* CN=<Server name>, CN=Servers, CN=<Site name>, CN=Sites, ... */
2976 site_name_val = ldb_dn_get_component_val(server_dn, 2);
2977 if (site_name_val == NULL) {
2981 site_name = (const char *) site_name_val->data;
2983 talloc_steal(tctx, site_name);
2984 talloc_free(tmp_ctx);
2989 talloc_free(tmp_ctx);
2993 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
2994 struct dcerpc_pipe *p)
2997 struct ldb_context *sam_ctx = NULL;
2999 struct netr_DsrGetDcSiteCoverageW r;
3000 struct DcSitesCtr *ctr = NULL;
3001 struct dcerpc_binding_handle *b = p->binding_handle;
3003 torture_comment(tctx, "This does only pass with the default site\n");
3005 /* We won't double-check this when we are over 'local' transports */
3006 if (dcerpc_server_name(p)) {
3007 /* Set up connection to SAMDB on DC */
3008 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3009 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3011 cmdline_credentials,
3014 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3017 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3020 status = dcerpc_netr_DsrGetDcSiteCoverageW_r(b, tctx, &r);
3021 torture_assert_ntstatus_ok(tctx, status, "failed");
3022 torture_assert_werr_ok(tctx, r.out.result, "failed");
3024 torture_assert(tctx, ctr->num_sites == 1,
3025 "we should per default only get the default site");
3026 if (sam_ctx != NULL) {
3027 torture_assert_casestr_equal(tctx, ctr->sites[0].string,
3028 server_site_name(tctx, sam_ctx),
3029 "didn't return default site");
3035 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
3036 struct dcerpc_pipe *p)
3039 struct ldb_context *sam_ctx = NULL;
3041 struct netr_DsRAddressToSitenamesW r;
3042 struct netr_DsRAddress addrs[6];
3043 struct sockaddr_in *addr;
3045 struct sockaddr_in6 *addr6;
3047 struct netr_DsRAddressToSitenamesWCtr *ctr;
3048 struct dcerpc_binding_handle *b = p->binding_handle;
3052 torture_comment(tctx, "This does only pass with the default site\n");
3054 /* We won't double-check this when we are over 'local' transports */
3055 if (dcerpc_server_name(p)) {
3056 /* Set up connection to SAMDB on DC */
3057 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3058 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3060 cmdline_credentials,
3063 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3066 /* First try valid IP addresses */
3068 addrs[0].size = sizeof(struct sockaddr_in);
3069 addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
3070 addr = (struct sockaddr_in *) addrs[0].buffer;
3071 addrs[0].buffer[0] = AF_INET;
3072 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3073 torture_assert(tctx, ret > 0, "inet_pton failed");
3075 addrs[1].size = sizeof(struct sockaddr_in);
3076 addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
3077 addr = (struct sockaddr_in *) addrs[1].buffer;
3078 addrs[1].buffer[0] = AF_INET;
3079 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3080 torture_assert(tctx, ret > 0, "inet_pton failed");
3082 addrs[2].size = sizeof(struct sockaddr_in);
3083 addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
3084 addr = (struct sockaddr_in *) addrs[2].buffer;
3085 addrs[2].buffer[0] = AF_INET;
3086 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3087 torture_assert(tctx, ret > 0, "inet_pton failed");
3090 addrs[3].size = sizeof(struct sockaddr_in6);
3091 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3092 addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
3093 addrs[3].buffer[0] = AF_INET6;
3094 ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
3095 torture_assert(tctx, ret > 0, "inet_pton failed");
3097 addrs[4].size = sizeof(struct sockaddr_in6);
3098 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3099 addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
3100 addrs[4].buffer[0] = AF_INET6;
3101 ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
3102 torture_assert(tctx, ret > 0, "inet_pton failed");
3104 addrs[5].size = sizeof(struct sockaddr_in6);
3105 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3106 addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
3107 addrs[5].buffer[0] = AF_INET6;
3108 ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
3109 torture_assert(tctx, ret > 0, "inet_pton failed");
3111 /* the test cases are repeated to have exactly 6. This is for
3112 * compatibility with IPv4-only machines */
3113 addrs[3].size = sizeof(struct sockaddr_in);
3114 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3115 addr = (struct sockaddr_in *) addrs[3].buffer;
3116 addrs[3].buffer[0] = AF_INET;
3117 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3118 torture_assert(tctx, ret > 0, "inet_pton failed");
3120 addrs[4].size = sizeof(struct sockaddr_in);
3121 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3122 addr = (struct sockaddr_in *) addrs[4].buffer;
3123 addrs[4].buffer[0] = AF_INET;
3124 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3125 torture_assert(tctx, ret > 0, "inet_pton failed");
3127 addrs[5].size = sizeof(struct sockaddr_in);
3128 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3129 addr = (struct sockaddr_in *) addrs[5].buffer;
3130 addrs[5].buffer[0] = AF_INET;
3131 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3132 torture_assert(tctx, ret > 0, "inet_pton failed");
3135 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
3137 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3139 r.in.addresses = addrs;
3142 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
3143 torture_assert_ntstatus_ok(tctx, status, "failed");
3144 torture_assert_werr_ok(tctx, r.out.result, "failed");
3146 if (sam_ctx != NULL) {
3147 for (i = 0; i < 3; i++) {
3148 torture_assert_casestr_equal(tctx,
3149 ctr->sitename[i].string,
3150 server_site_name(tctx, sam_ctx),
3151 "didn't return default site");
3153 for (i = 3; i < 6; i++) {
3154 /* Windows returns "NULL" for the sitename if it isn't
3155 * IPv6 configured */
3156 if (torture_setting_bool(tctx, "samba4", false)) {
3157 torture_assert_casestr_equal(tctx,
3158 ctr->sitename[i].string,
3159 server_site_name(tctx, sam_ctx),
3160 "didn't return default site");
3165 /* Now try invalid ones (too short buffers) */
3175 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
3176 torture_assert_ntstatus_ok(tctx, status, "failed");
3177 torture_assert_werr_ok(tctx, r.out.result, "failed");
3179 for (i = 0; i < 6; i++) {
3180 torture_assert(tctx, ctr->sitename[i].string == NULL,
3181 "sitename should be null");
3184 /* Now try invalid ones (wrong address types) */
3187 addrs[0].buffer[0] = AF_UNSPEC;
3189 addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
3191 addrs[2].buffer[0] = AF_UNIX;
3194 addrs[3].buffer[0] = 250;
3196 addrs[4].buffer[0] = 251;
3198 addrs[5].buffer[0] = 252;
3200 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
3201 torture_assert_ntstatus_ok(tctx, status, "failed");
3202 torture_assert_werr_ok(tctx, r.out.result, "failed");
3204 for (i = 0; i < 6; i++) {
3205 torture_assert(tctx, ctr->sitename[i].string == NULL,
3206 "sitename should be null");
3212 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
3213 struct dcerpc_pipe *p)
3216 struct ldb_context *sam_ctx = NULL;
3218 struct netr_DsRAddressToSitenamesExW r;
3219 struct netr_DsRAddress addrs[6];
3220 struct sockaddr_in *addr;
3222 struct sockaddr_in6 *addr6;
3224 struct netr_DsRAddressToSitenamesExWCtr *ctr;
3225 struct dcerpc_binding_handle *b = p->binding_handle;
3229 torture_comment(tctx, "This does pass with the default site\n");
3231 /* We won't double-check this when we are over 'local' transports */
3232 if (dcerpc_server_name(p)) {
3233 /* Set up connection to SAMDB on DC */
3234 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3235 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3237 cmdline_credentials,
3240 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3243 /* First try valid IP addresses */
3245 addrs[0].size = sizeof(struct sockaddr_in);
3246 addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
3247 addr = (struct sockaddr_in *) addrs[0].buffer;
3248 addrs[0].buffer[0] = AF_INET;
3249 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3250 torture_assert(tctx, ret > 0, "inet_pton failed");
3252 addrs[1].size = sizeof(struct sockaddr_in);
3253 addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
3254 addr = (struct sockaddr_in *) addrs[1].buffer;
3255 addrs[1].buffer[0] = AF_INET;
3256 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3257 torture_assert(tctx, ret > 0, "inet_pton failed");
3259 addrs[2].size = sizeof(struct sockaddr_in);
3260 addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
3261 addr = (struct sockaddr_in *) addrs[2].buffer;
3262 addrs[2].buffer[0] = AF_INET;
3263 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3264 torture_assert(tctx, ret > 0, "inet_pton failed");
3267 addrs[3].size = sizeof(struct sockaddr_in6);
3268 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3269 addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
3270 addrs[3].buffer[0] = AF_INET6;
3271 ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
3272 torture_assert(tctx, ret > 0, "inet_pton failed");
3274 addrs[4].size = sizeof(struct sockaddr_in6);
3275 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3276 addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
3277 addrs[4].buffer[0] = AF_INET6;
3278 ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
3279 torture_assert(tctx, ret > 0, "inet_pton failed");
3281 addrs[5].size = sizeof(struct sockaddr_in6);
3282 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3283 addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
3284 addrs[5].buffer[0] = AF_INET6;
3285 ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
3286 torture_assert(tctx, ret > 0, "inet_pton failed");
3288 /* the test cases are repeated to have exactly 6. This is for
3289 * compatibility with IPv4-only machines */
3290 addrs[3].size = sizeof(struct sockaddr_in);
3291 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3292 addr = (struct sockaddr_in *) addrs[3].buffer;
3293 addrs[3].buffer[0] = AF_INET;
3294 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3295 torture_assert(tctx, ret > 0, "inet_pton failed");
3297 addrs[4].size = sizeof(struct sockaddr_in);
3298 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3299 addr = (struct sockaddr_in *) addrs[4].buffer;
3300 addrs[4].buffer[0] = AF_INET;
3301 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3302 torture_assert(tctx, ret > 0, "inet_pton failed");
3304 addrs[5].size = sizeof(struct sockaddr_in);
3305 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3306 addr = (struct sockaddr_in *) addrs[5].buffer;
3307 addrs[5].buffer[0] = AF_INET;
3308 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3309 torture_assert(tctx, ret > 0, "inet_pton failed");
3312 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
3314 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3316 r.in.addresses = addrs;
3319 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3320 torture_assert_ntstatus_ok(tctx, status, "failed");
3321 torture_assert_werr_ok(tctx, r.out.result, "failed");
3323 if (sam_ctx != NULL) {
3324 for (i = 0; i < 3; i++) {
3325 torture_assert_casestr_equal(tctx,
3326 ctr->sitename[i].string,
3327 server_site_name(tctx, sam_ctx),
3328 "didn't return default site");
3329 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3330 "subnet should be null");
3332 for (i = 3; i < 6; i++) {
3333 /* Windows returns "NULL" for the sitename if it isn't
3334 * IPv6 configured */
3335 if (torture_setting_bool(tctx, "samba4", false)) {
3336 torture_assert_casestr_equal(tctx,
3337 ctr->sitename[i].string,
3338 server_site_name(tctx, sam_ctx),
3339 "didn't return default site");
3341 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3342 "subnet should be null");
3346 /* Now try invalid ones (too short buffers) */
3356 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3357 torture_assert_ntstatus_ok(tctx, status, "failed");
3358 torture_assert_werr_ok(tctx, r.out.result, "failed");
3360 for (i = 0; i < 6; i++) {
3361 torture_assert(tctx, ctr->sitename[i].string == NULL,
3362 "sitename should be null");
3363 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3364 "subnet should be null");
3368 addrs[0].buffer[0] = AF_UNSPEC;
3370 addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
3372 addrs[2].buffer[0] = AF_UNIX;
3375 addrs[3].buffer[0] = 250;
3377 addrs[4].buffer[0] = 251;
3379 addrs[5].buffer[0] = 252;
3381 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3382 torture_assert_ntstatus_ok(tctx, status, "failed");
3383 torture_assert_werr_ok(tctx, r.out.result, "failed");
3385 for (i = 0; i < 6; i++) {
3386 torture_assert(tctx, ctr->sitename[i].string == NULL,
3387 "sitename should be null");
3388 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3389 "subnet should be null");
3395 static bool test_netr_ServerGetTrustInfo_flags(struct torture_context *tctx,
3396 struct dcerpc_pipe *p1,
3397 struct cli_credentials *machine_credentials,
3398 uint32_t negotiate_flags)
3400 struct netr_ServerGetTrustInfo r;
3402 struct netr_Authenticator a;
3403 struct netr_Authenticator return_authenticator;
3404 struct samr_Password new_owf_password;
3405 struct samr_Password old_owf_password;
3406 struct netr_TrustInfo *trust_info;
3408 struct netlogon_creds_CredentialState *creds;
3409 struct dcerpc_pipe *p = NULL;
3410 struct dcerpc_binding_handle *b = NULL;
3412 struct samr_Password nt_hash;
3414 if (!test_SetupCredentials3(p1, tctx, negotiate_flags,
3415 machine_credentials, &creds)) {
3418 if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
3419 DCERPC_SIGN | DCERPC_SEAL, &p)) {
3422 b = p->binding_handle;
3424 netlogon_creds_client_authenticator(creds, &a);
3426 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3427 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
3428 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
3429 r.in.computer_name = TEST_MACHINE_NAME;
3430 r.in.credential = &a;
3432 r.out.return_authenticator = &return_authenticator;
3433 r.out.new_owf_password = &new_owf_password;
3434 r.out.old_owf_password = &old_owf_password;
3435 r.out.trust_info = &trust_info;
3437 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerGetTrustInfo_r(b, tctx, &r),
3438 "ServerGetTrustInfo failed");
3439 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerGetTrustInfo failed");
3440 torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
3442 E_md4hash(cli_credentials_get_password(machine_credentials), nt_hash.hash);
3444 netlogon_creds_des_decrypt(creds, &new_owf_password);
3446 dump_data(1, new_owf_password.hash, 16);
3447 dump_data(1, nt_hash.hash, 16);
3449 torture_assert_mem_equal(tctx, new_owf_password.hash, nt_hash.hash, 16,
3450 "received unexpected owf password\n");
3455 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
3456 struct dcerpc_pipe *p,
3457 struct cli_credentials *machine_credentials)
3459 return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
3460 NETLOGON_NEG_AUTH2_ADS_FLAGS);
3463 static bool test_netr_ServerGetTrustInfo_AES(struct torture_context *tctx,
3464 struct dcerpc_pipe *p,
3465 struct cli_credentials *machine_credentials)
3467 return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
3468 NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
3471 static bool test_GetDomainInfo(struct torture_context *tctx,
3472 struct dcerpc_pipe *p1,
3473 struct cli_credentials *machine_credentials)
3475 struct netr_LogonGetDomainInfo r;
3476 struct netr_WorkstationInformation q1;
3477 struct netr_Authenticator a;
3478 struct netlogon_creds_CredentialState *creds;
3479 struct netr_OsVersion os;
3480 union netr_WorkstationInfo query;
3481 union netr_DomainInfo info;
3482 const char* const attrs[] = { "dNSHostName", "operatingSystem",
3483 "operatingSystemServicePack", "operatingSystemVersion",
3484 "servicePrincipalName", NULL };
3486 struct ldb_context *sam_ctx = NULL;
3487 struct ldb_message **res;
3488 struct ldb_message_element *spn_el;
3491 const char *old_dnsname = NULL;
3495 struct dcerpc_pipe *p = NULL;
3496 struct dcerpc_binding_handle *b = NULL;
3498 torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
3500 if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3501 machine_credentials, &creds)) {
3504 if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
3505 DCERPC_SIGN | DCERPC_SEAL, &p)) {
3508 b = p->binding_handle;
3510 /* We won't double-check this when we are over 'local' transports */
3511 if (dcerpc_server_name(p)) {
3512 /* Set up connection to SAMDB on DC */
3513 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3514 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3516 cmdline_credentials,
3519 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3522 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
3523 netlogon_creds_client_authenticator(creds, &a);
3526 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3527 r.in.computer_name = TEST_MACHINE_NAME;
3528 r.in.credential = &a;
3530 r.in.return_authenticator = &a;
3531 r.in.query = &query;
3532 r.out.return_authenticator = &a;
3536 os.os.MajorVersion = 123;
3537 os.os.MinorVersion = 456;
3538 os.os.BuildNumber = 789;
3539 os.os.CSDVersion = "Service Pack 10";
3540 os.os.ServicePackMajor = 10;
3541 os.os.ServicePackMinor = 1;
3542 os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
3543 os.os.ProductType = NETR_VER_NT_SERVER;
3546 version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
3547 os.os.MinorVersion, os.os.BuildNumber);
3550 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3551 lpcfg_dnsdomain(tctx->lp_ctx));
3552 q1.sitename = "Default-First-Site-Name";
3553 q1.os_version.os = &os;
3554 q1.os_name.string = talloc_asprintf(tctx,
3555 "Tortured by Samba4 RPC-NETLOGON: %s",
3556 timestring(tctx, time(NULL)));
3558 /* The workstation handles the "servicePrincipalName" and DNS hostname
3560 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3562 query.workstation_info = &q1;
3565 /* Gets back the old DNS hostname in AD */
3566 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3567 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3569 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
3571 /* Gets back the "servicePrincipalName"s in AD */
3572 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3573 if (spn_el != NULL) {
3574 for (i=0; i < spn_el->num_values; i++) {
3575 spns = talloc_realloc(tctx, spns, char *, i + 1);
3576 spns[i] = (char *) spn_el->values[i].data;
3582 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3583 "LogonGetDomainInfo failed");
3584 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3585 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3590 /* AD workstation infos entry check */
3591 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3592 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3593 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3594 torture_assert_str_equal(tctx,
3595 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3596 q1.os_name.string, "'operatingSystem' wrong!");
3597 torture_assert_str_equal(tctx,
3598 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
3599 os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
3600 torture_assert_str_equal(tctx,
3601 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
3602 version_str, "'operatingSystemVersion' wrong!");
3604 if (old_dnsname != NULL) {
3605 /* If before a DNS hostname was set then it should remain
3606 the same in combination with the "servicePrincipalName"s.
3607 The DNS hostname should also be returned by our
3608 "LogonGetDomainInfo" call (in the domain info structure). */
3610 torture_assert_str_equal(tctx,
3611 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3612 old_dnsname, "'DNS hostname' was not set!");
3614 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3615 torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
3616 "'servicePrincipalName's not set!");
3617 torture_assert(tctx, spn_el->num_values == num_spns,
3618 "'servicePrincipalName's incorrect!");
3619 for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
3620 torture_assert_str_equal(tctx,
3621 (char *) spn_el->values[i].data,
3622 spns[i], "'servicePrincipalName's incorrect!");
3624 torture_assert_str_equal(tctx,
3625 info.domain_info->dns_hostname.string,
3627 "Out 'DNS hostname' doesn't match the old one!");
3629 /* If no DNS hostname was set then also now none should be set,
3630 the "servicePrincipalName"s should remain empty and no DNS
3631 hostname should be returned by our "LogonGetDomainInfo"
3632 call (in the domain info structure). */
3634 torture_assert(tctx,
3635 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
3636 "'DNS hostname' was set!");
3638 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3639 torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
3640 "'servicePrincipalName's were set!");
3642 torture_assert(tctx,
3643 info.domain_info->dns_hostname.string == NULL,
3644 "Out 'DNS host name' was set!");
3648 /* Checks "workstation flags" */
3649 torture_assert(tctx,
3650 info.domain_info->workstation_flags
3651 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3652 "Out 'workstation flags' don't match!");
3655 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname doesn't work)\n");
3656 netlogon_creds_client_authenticator(creds, &a);
3658 /* Wipe out the osVersion, and prove which values still 'stick' */
3659 q1.os_version.os = NULL;
3661 /* Change also the DNS hostname to test differences in behaviour */
3662 talloc_free(discard_const_p(char, q1.dns_hostname));
3663 q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3664 lpcfg_dnsdomain(tctx->lp_ctx));
3666 /* The workstation handles the "servicePrincipalName" and DNS hostname
3668 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3670 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3671 "LogonGetDomainInfo failed");
3672 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3674 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3679 /* AD workstation infos entry check */
3680 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3681 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3682 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3684 torture_assert_str_equal(tctx,
3685 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3686 q1.os_name.string, "'operatingSystem' should stick!");
3687 torture_assert(tctx,
3688 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3689 "'operatingSystemServicePack' shouldn't stick!");
3690 torture_assert(tctx,
3691 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3692 "'operatingSystemVersion' shouldn't stick!");
3694 /* The DNS host name shouldn't have been updated by the server */
3696 torture_assert_str_equal(tctx,
3697 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3698 old_dnsname, "'DNS host name' did change!");
3700 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3701 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3703 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3704 torture_assert(tctx, spn_el != NULL,
3705 "There should exist 'servicePrincipalName's in AD!");
3706 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3707 for (i=0; i < spn_el->num_values; i++)
3708 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3710 torture_assert(tctx, i != spn_el->num_values,
3711 "'servicePrincipalName' HOST/<Netbios name> not found!");
3712 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3713 for (i=0; i < spn_el->num_values; i++)
3714 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3716 torture_assert(tctx, i != spn_el->num_values,
3717 "'servicePrincipalName' HOST/<FQDN name> not found!");
3719 /* Check that the out DNS hostname was set properly */
3720 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
3721 old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
3724 /* Checks "workstation flags" */
3725 torture_assert(tctx,
3726 info.domain_info->workstation_flags == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3727 "Out 'workstation flags' don't match!");
3730 /* Now try the same but the workstation flags set to 0 */
3732 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (variation of DNS hostname doesn't work)\n");
3733 netlogon_creds_client_authenticator(creds, &a);
3735 /* Change also the DNS hostname to test differences in behaviour */
3736 talloc_free(discard_const_p(char, q1.dns_hostname));
3737 q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3738 lpcfg_dnsdomain(tctx->lp_ctx));
3740 /* Wipe out the osVersion, and prove which values still 'stick' */
3741 q1.os_version.os = NULL;
3743 /* Let the DC handle the "servicePrincipalName" and DNS hostname
3745 q1.workstation_flags = 0;
3747 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3748 "LogonGetDomainInfo failed");
3749 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3750 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3755 /* AD workstation infos entry check */
3756 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3757 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3758 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3760 torture_assert_str_equal(tctx,
3761 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3762 q1.os_name.string, "'operatingSystem' should stick!");
3763 torture_assert(tctx,
3764 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3765 "'operatingSystemServicePack' shouldn't stick!");
3766 torture_assert(tctx,
3767 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3768 "'operatingSystemVersion' shouldn't stick!");
3770 /* The DNS host name shouldn't have been updated by the server */
3772 torture_assert_str_equal(tctx,
3773 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3774 old_dnsname, "'DNS host name' did change!");
3776 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3777 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3779 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3780 torture_assert(tctx, spn_el != NULL,
3781 "There should exist 'servicePrincipalName's in AD!");
3782 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3783 for (i=0; i < spn_el->num_values; i++)
3784 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3786 torture_assert(tctx, i != spn_el->num_values,
3787 "'servicePrincipalName' HOST/<Netbios name> not found!");
3788 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3789 for (i=0; i < spn_el->num_values; i++)
3790 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3792 torture_assert(tctx, i != spn_el->num_values,
3793 "'servicePrincipalName' HOST/<FQDN name> not found!");
3795 /* Here the server gives us NULL as the out DNS hostname */
3796 torture_assert(tctx, info.domain_info->dns_hostname.string == NULL,
3797 "Out 'DNS hostname' should be NULL!");
3800 /* Checks "workstation flags" */
3801 torture_assert(tctx,
3802 info.domain_info->workstation_flags == 0,
3803 "Out 'workstation flags' don't match!");
3806 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (verification of DNS hostname and check for trusted domains)\n");
3807 netlogon_creds_client_authenticator(creds, &a);
3809 /* Put the DNS hostname back */
3810 talloc_free(discard_const_p(char, q1.dns_hostname));
3811 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3812 lpcfg_dnsdomain(tctx->lp_ctx));
3814 /* The workstation handles the "servicePrincipalName" and DNS hostname
3816 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3818 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3819 "LogonGetDomainInfo failed");
3820 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3821 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3825 /* Now the in/out DNS hostnames should be the same */
3826 torture_assert_str_equal(tctx,
3827 info.domain_info->dns_hostname.string,
3828 query.workstation_info->dns_hostname,
3829 "In/Out 'DNS hostnames' don't match!");
3830 old_dnsname = info.domain_info->dns_hostname.string;
3832 /* Checks "workstation flags" */
3833 torture_assert(tctx,
3834 info.domain_info->workstation_flags
3835 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3836 "Out 'workstation flags' don't match!");
3838 /* Checks for trusted domains */
3839 torture_assert(tctx,
3840 (info.domain_info->trusted_domain_count != 0)
3841 && (info.domain_info->trusted_domains != NULL),
3842 "Trusted domains have been requested!");
3845 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 5th call (check for trusted domains)\n");
3846 netlogon_creds_client_authenticator(creds, &a);
3848 /* The workstation handles the "servicePrincipalName" and DNS hostname
3849 updates and requests inbound trusts */
3850 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
3851 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
3853 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3854 "LogonGetDomainInfo failed");
3855 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3856 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3860 /* Checks "workstation flags" */
3861 torture_assert(tctx,
3862 info.domain_info->workstation_flags
3863 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
3864 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
3865 "Out 'workstation flags' don't match!");
3867 /* Checks for trusted domains */
3868 torture_assert(tctx,
3869 (info.domain_info->trusted_domain_count != 0)
3870 && (info.domain_info->trusted_domains != NULL),
3871 "Trusted domains have been requested!");
3874 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
3875 netlogon_creds_client_authenticator(creds, &a);
3877 query.workstation_info->dns_hostname = NULL;
3879 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3880 "LogonGetDomainInfo failed");
3881 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3882 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3884 /* The old DNS hostname should stick */
3885 torture_assert_str_equal(tctx,
3886 info.domain_info->dns_hostname.string,
3888 "'DNS hostname' changed!");
3890 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (extra workstation flags)\n");
3891 netlogon_creds_client_authenticator(creds, &a);
3893 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
3894 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | 0x4;
3896 /* Put the DNS hostname back */
3897 talloc_free(discard_const_p(char, q1.dns_hostname));
3898 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3899 lpcfg_dnsdomain(tctx->lp_ctx));
3901 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3902 "LogonGetDomainInfo failed");
3903 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3904 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3906 /* Checks "workstation flags" */
3907 torture_assert(tctx,
3908 info.domain_info->workstation_flags
3909 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
3910 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
3911 "Out 'workstation flags' don't match!");
3913 if (!torture_setting_bool(tctx, "dangerous", false)) {
3914 torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 8th call (no workstation info) - enable dangerous tests in order to do so\n");
3916 /* Try a call without the workstation information structure */
3918 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 8th call (no workstation info)\n");
3919 netlogon_creds_client_authenticator(creds, &a);
3921 query.workstation_info = NULL;
3923 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3924 "LogonGetDomainInfo failed");
3925 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3926 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3932 static bool test_GetDomainInfo_async(struct torture_context *tctx,
3933 struct dcerpc_pipe *p1,
3934 struct cli_credentials *machine_credentials)
3937 struct netr_LogonGetDomainInfo r;
3938 struct netr_WorkstationInformation q1;
3939 struct netr_Authenticator a;
3940 #define ASYNC_COUNT 100
3941 struct netlogon_creds_CredentialState *creds;
3942 struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
3943 struct tevent_req *req[ASYNC_COUNT];
3945 union netr_WorkstationInfo query;
3946 union netr_DomainInfo info;
3947 struct dcerpc_pipe *p = NULL;
3949 torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
3951 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3952 machine_credentials, &creds)) {
3955 if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
3956 DCERPC_SIGN | DCERPC_SEAL, &p)) {
3961 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3962 r.in.computer_name = TEST_MACHINE_NAME;
3963 r.in.credential = &a;
3965 r.in.return_authenticator = &a;
3966 r.in.query = &query;
3967 r.out.return_authenticator = &a;
3971 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3972 lpcfg_dnsdomain(tctx->lp_ctx));
3973 q1.sitename = "Default-First-Site-Name";
3974 q1.os_name.string = "UNIX/Linux or similar";
3976 query.workstation_info = &q1;
3978 for (i=0;i<ASYNC_COUNT;i++) {
3979 netlogon_creds_client_authenticator(creds, &a);
3981 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
3982 req[i] = dcerpc_netr_LogonGetDomainInfo_r_send(tctx, tctx->ev, p->binding_handle, &r);
3984 /* even with this flush per request a w2k3 server seems to
3985 clag with multiple outstanding requests. bleergh. */
3986 torture_assert_int_equal(tctx, tevent_loop_once(tctx->ev), 0,
3987 "tevent_loop_once failed");
3990 for (i=0;i<ASYNC_COUNT;i++) {
3991 torture_assert_int_equal(tctx, tevent_req_poll(req[i], tctx->ev), true,
3992 "tevent_req_poll() failed");
3994 status = dcerpc_netr_LogonGetDomainInfo_r_recv(req[i], tctx);
3996 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
3997 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
3999 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred),
4000 "Credential chaining failed at async");
4003 torture_comment(tctx,
4004 "Testing netr_LogonGetDomainInfo - async count %d OK\n", ASYNC_COUNT);
4009 static bool test_ManyGetDCName(struct torture_context *tctx,
4010 struct dcerpc_pipe *p)
4013 struct cli_credentials *anon_creds;
4014 const struct dcerpc_binding *binding2;
4015 struct dcerpc_pipe *p2;
4016 struct lsa_ObjectAttribute attr;
4017 struct lsa_QosInfo qos;
4018 struct lsa_OpenPolicy2 o;
4019 struct policy_handle lsa_handle;
4020 struct lsa_DomainList domains;
4022 struct lsa_EnumTrustDom t;
4023 uint32_t resume_handle = 0;
4024 struct netr_GetAnyDCName d;
4025 const char *dcname = NULL;
4026 struct dcerpc_binding_handle *b = p->binding_handle;
4027 struct dcerpc_binding_handle *b2;
4031 if (p->conn->transport.transport != NCACN_NP) {
4032 torture_skip(tctx, "test_ManyGetDCName works only with NCACN_NP");
4035 torture_comment(tctx, "Torturing GetDCName\n");
4037 anon_creds = cli_credentials_init_anon(tctx);
4038 torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed");
4040 binding2 = p->binding;
4041 status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_lsarpc,
4042 anon_creds, tctx->lp_ctx,
4044 torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
4045 b2 = p2->binding_handle;
4048 qos.impersonation_level = 2;
4049 qos.context_mode = 1;
4050 qos.effective_only = 0;
4053 attr.root_dir = NULL;
4054 attr.object_name = NULL;
4055 attr.attributes = 0;
4056 attr.sec_desc = NULL;
4057 attr.sec_qos = &qos;
4059 o.in.system_name = "\\";
4061 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4062 o.out.handle = &lsa_handle;
4064 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
4065 "OpenPolicy2 failed");
4066 torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
4068 t.in.handle = &lsa_handle;
4069 t.in.resume_handle = &resume_handle;
4070 t.in.max_size = 1000;
4071 t.out.domains = &domains;
4072 t.out.resume_handle = &resume_handle;
4074 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b2, tctx, &t),
4075 "EnumTrustDom failed");
4077 if ((!NT_STATUS_IS_OK(t.out.result) &&
4078 (!NT_STATUS_EQUAL(t.out.result, NT_STATUS_NO_MORE_ENTRIES))))
4079 torture_fail(tctx, "Could not list domains");
4083 d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
4084 dcerpc_server_name(p));
4085 d.out.dcname = &dcname;
4087 for (i=0; i<domains.count * 4; i++) {
4088 struct lsa_DomainInfo *info =
4089 &domains.domains[rand()%domains.count];
4091 d.in.domainname = info->name.string;
4093 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &d);
4094 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
4096 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
4097 dcname ? dcname : "unknown");
4103 static bool test_SetPassword_with_flags(struct torture_context *tctx,
4104 struct dcerpc_pipe *p,
4105 struct cli_credentials *machine_credentials)
4107 uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
4108 struct netlogon_creds_CredentialState *creds;
4111 if (!test_SetupCredentials2(p, tctx, 0,
4112 machine_credentials,
4113 cli_credentials_get_secure_channel_type(machine_credentials),
4115 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
4118 for (i=0; i < ARRAY_SIZE(flags); i++) {
4119 torture_assert(tctx,
4120 test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
4121 talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
4127 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
4129 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon");
4130 struct torture_rpc_tcase *tcase;
4131 struct torture_test *test;
4133 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
4134 &ndr_table_netlogon, TEST_MACHINE_NAME);
4136 torture_rpc_tcase_add_test(tcase, "Broken RPC binding handle",
4137 test_netr_broken_binding_handle);
4139 torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
4140 torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
4141 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
4142 torture_rpc_tcase_add_test_creds(tcase, "invalidAuthenticate2", test_invalidAuthenticate2);
4143 torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeGlobal", test_ServerReqChallengeGlobal);
4144 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
4145 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
4146 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
4147 torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
4148 torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
4149 torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
4150 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
4151 torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
4152 torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
4153 torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
4154 torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
4155 torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
4156 torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
4157 torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
4158 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
4159 torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
4160 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
4161 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
4162 test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
4163 test->dangerous = true;
4164 torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
4165 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
4166 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
4167 torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
4168 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
4169 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
4170 torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
4171 torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo_AES", test_netr_ServerGetTrustInfo_AES);
4172 torture_rpc_tcase_add_test_creds(tcase, "GetForestTrustInformation", test_netr_GetForestTrustInformation);
4177 struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
4179 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon-s3");
4180 struct torture_rpc_tcase *tcase;
4182 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
4183 &ndr_table_netlogon, TEST_MACHINE_NAME);
4185 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
4186 torture_rpc_tcase_add_test_creds(tcase, "SamLogon_NULL_domain", test_SamLogon_NULL_domain);
4187 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
4188 torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
4189 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
4190 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
4191 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
4196 struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
4198 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon.admin");
4199 struct torture_rpc_tcase *tcase;
4201 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "bdc",
4202 &ndr_table_netlogon, TEST_MACHINE_NAME);
4203 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
4204 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
4205 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
4207 tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "wkst",
4208 &ndr_table_netlogon, TEST_MACHINE_NAME);
4209 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
4210 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
4211 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
4213 tcase = torture_suite_add_rpc_iface_tcase(suite, "admin",
4214 &ndr_table_netlogon);
4215 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
4216 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
4217 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);