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");
363 try a change password for our machine account
365 static bool test_SetPassword(struct torture_context *tctx,
366 struct dcerpc_pipe *p,
367 struct cli_credentials *machine_credentials)
369 struct netr_ServerPasswordSet r;
370 const char *password;
371 struct netlogon_creds_CredentialState *creds;
372 struct netr_Authenticator credential, return_authenticator;
373 struct samr_Password new_password;
374 struct dcerpc_binding_handle *b = p->binding_handle;
376 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
380 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
381 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
382 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
383 r.in.computer_name = TEST_MACHINE_NAME;
384 r.in.credential = &credential;
385 r.in.new_password = &new_password;
386 r.out.return_authenticator = &return_authenticator;
388 password = generate_random_password(tctx, 8, 255);
389 E_md4hash(password, new_password.hash);
391 netlogon_creds_des_encrypt(creds, &new_password);
393 torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
394 torture_comment(tctx, "Changing machine account password to '%s'\n",
397 netlogon_creds_client_authenticator(creds, &credential);
399 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
400 "ServerPasswordSet failed");
401 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
403 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
404 torture_comment(tctx, "Credential chaining failed\n");
407 /* by changing the machine password twice we test the
408 credentials chaining fully, and we verify that the server
409 allows the password to be set to the same value twice in a
410 row (match win2k3) */
411 torture_comment(tctx,
412 "Testing a second ServerPasswordSet on machine account\n");
413 torture_comment(tctx,
414 "Changing machine account password to '%s' (same as previous run)\n", password);
416 netlogon_creds_client_authenticator(creds, &credential);
418 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
419 "ServerPasswordSet (2) failed");
420 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
422 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
423 torture_comment(tctx, "Credential chaining failed\n");
426 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
429 test_SetupCredentials(p, tctx, machine_credentials, &creds),
430 "ServerPasswordSet failed to actually change the password");
436 try a change password for our machine account
438 static bool test_SetPassword_flags(struct torture_context *tctx,
439 struct dcerpc_pipe *p,
440 struct cli_credentials *machine_credentials,
441 uint32_t negotiate_flags)
443 struct netr_ServerPasswordSet r;
444 const char *password;
445 struct netlogon_creds_CredentialState *creds;
446 struct netr_Authenticator credential, return_authenticator;
447 struct samr_Password new_password;
448 struct dcerpc_binding_handle *b = p->binding_handle;
450 if (!test_SetupCredentials2(p, tctx, negotiate_flags,
452 cli_credentials_get_secure_channel_type(machine_credentials),
457 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
458 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
459 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
460 r.in.computer_name = TEST_MACHINE_NAME;
461 r.in.credential = &credential;
462 r.in.new_password = &new_password;
463 r.out.return_authenticator = &return_authenticator;
465 password = generate_random_password(tctx, 8, 255);
466 E_md4hash(password, new_password.hash);
468 netlogon_creds_des_encrypt(creds, &new_password);
470 torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
471 torture_comment(tctx, "Changing machine account password to '%s'\n",
474 netlogon_creds_client_authenticator(creds, &credential);
476 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
477 "ServerPasswordSet failed");
478 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
480 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
481 torture_comment(tctx, "Credential chaining failed\n");
484 /* by changing the machine password twice we test the
485 credentials chaining fully, and we verify that the server
486 allows the password to be set to the same value twice in a
487 row (match win2k3) */
488 torture_comment(tctx,
489 "Testing a second ServerPasswordSet on machine account\n");
490 torture_comment(tctx,
491 "Changing machine account password to '%s' (same as previous run)\n", password);
493 netlogon_creds_client_authenticator(creds, &credential);
495 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
496 "ServerPasswordSet (2) failed");
497 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
499 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
500 torture_comment(tctx, "Credential chaining failed\n");
503 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
506 test_SetupCredentials(p, tctx, machine_credentials, &creds),
507 "ServerPasswordSet failed to actually change the password");
514 generate a random password for password change tests
516 static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
519 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
520 generate_random_buffer(password.data, password.length);
522 for (i=0; i < len; i++) {
523 if (((uint16_t *)password.data)[i] == 0) {
524 ((uint16_t *)password.data)[i] = 1;
532 try a change password for our machine account
534 static bool test_SetPassword2_with_flags(struct torture_context *tctx,
535 struct dcerpc_pipe *p,
536 struct cli_credentials *machine_credentials,
539 struct netr_ServerPasswordSet2 r;
540 const char *password;
541 DATA_BLOB new_random_pass;
542 struct netlogon_creds_CredentialState *creds;
543 struct samr_CryptPassword password_buf;
544 struct samr_Password nt_hash;
545 struct netr_Authenticator credential, return_authenticator;
546 struct netr_CryptPassword new_password;
547 struct dcerpc_binding_handle *b = p->binding_handle;
549 if (!test_SetupCredentials2(p, tctx, flags, machine_credentials, cli_credentials_get_secure_channel_type(machine_credentials), &creds)) {
553 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
554 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
555 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
556 r.in.computer_name = TEST_MACHINE_NAME;
557 r.in.credential = &credential;
558 r.in.new_password = &new_password;
559 r.out.return_authenticator = &return_authenticator;
561 password = generate_random_password(tctx, 8, 255);
562 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
563 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
564 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
566 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
569 memcpy(new_password.data, password_buf.data, 512);
570 new_password.length = IVAL(password_buf.data, 512);
572 torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
573 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
575 netlogon_creds_client_authenticator(creds, &credential);
577 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
578 "ServerPasswordSet2 failed");
579 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
581 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
582 torture_comment(tctx, "Credential chaining failed\n");
585 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
587 if (!torture_setting_bool(tctx, "dangerous", false)) {
588 torture_comment(tctx,
589 "Not testing ability to set password to '', enable dangerous tests to perform this test\n");
591 /* by changing the machine password to ""
592 * we check if the server uses password restrictions
593 * for ServerPasswordSet2
594 * (win2k3 accepts "")
597 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
598 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
599 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
601 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
603 memcpy(new_password.data, password_buf.data, 512);
604 new_password.length = IVAL(password_buf.data, 512);
606 torture_comment(tctx,
607 "Testing ServerPasswordSet2 on machine account\n");
608 torture_comment(tctx,
609 "Changing machine account password to '%s'\n", password);
611 netlogon_creds_client_authenticator(creds, &credential);
613 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
614 "ServerPasswordSet2 failed");
615 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
617 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
618 torture_comment(tctx, "Credential chaining failed\n");
621 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
624 torture_assert(tctx, test_SetupCredentials(p, tctx, machine_credentials, &creds),
625 "ServerPasswordSet failed to actually change the password");
627 /* now try a random password */
628 password = generate_random_password(tctx, 8, 255);
629 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
630 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
631 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
633 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
635 memcpy(new_password.data, password_buf.data, 512);
636 new_password.length = IVAL(password_buf.data, 512);
638 torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
639 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
641 netlogon_creds_client_authenticator(creds, &credential);
643 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
644 "ServerPasswordSet2 (2) failed");
645 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 (2) failed");
647 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
648 torture_comment(tctx, "Credential chaining failed\n");
651 /* by changing the machine password twice we test the
652 credentials chaining fully, and we verify that the server
653 allows the password to be set to the same value twice in a
654 row (match win2k3) */
655 torture_comment(tctx,
656 "Testing a second ServerPasswordSet2 on machine account\n");
657 torture_comment(tctx,
658 "Changing machine account password to '%s' (same as previous run)\n", password);
660 netlogon_creds_client_authenticator(creds, &credential);
662 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
663 "ServerPasswordSet (3) failed");
664 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
666 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
667 torture_comment(tctx, "Credential chaining failed\n");
670 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
672 torture_assert (tctx,
673 test_SetupCredentials(p, tctx, machine_credentials, &creds),
674 "ServerPasswordSet failed to actually change the password");
676 new_random_pass = netlogon_very_rand_pass(tctx, 128);
678 /* now try a random stream of bytes for a password */
679 set_pw_in_buffer(password_buf.data, &new_random_pass);
681 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
682 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
684 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
687 memcpy(new_password.data, password_buf.data, 512);
688 new_password.length = IVAL(password_buf.data, 512);
690 torture_comment(tctx,
691 "Testing a third ServerPasswordSet2 on machine account, with a completely random password\n");
693 netlogon_creds_client_authenticator(creds, &credential);
695 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
696 "ServerPasswordSet (3) failed");
697 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
699 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
700 torture_comment(tctx, "Credential chaining failed\n");
703 mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
705 cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
706 cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
708 torture_assert (tctx,
709 test_SetupCredentials(p, tctx, machine_credentials, &creds),
710 "ServerPasswordSet failed to actually change the password");
715 static bool test_SetPassword2(struct torture_context *tctx,
716 struct dcerpc_pipe *p,
717 struct cli_credentials *machine_credentials)
719 return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS);
722 static bool test_SetPassword2_AES(struct torture_context *tctx,
723 struct dcerpc_pipe *p,
724 struct cli_credentials *machine_credentials)
726 return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
729 static bool test_GetPassword(struct torture_context *tctx,
730 struct dcerpc_pipe *p,
731 struct cli_credentials *machine_credentials)
733 struct netr_ServerPasswordGet r;
734 struct netlogon_creds_CredentialState *creds;
735 struct netr_Authenticator credential;
737 struct netr_Authenticator return_authenticator;
738 struct samr_Password password;
739 struct dcerpc_binding_handle *b = p->binding_handle;
741 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
745 netlogon_creds_client_authenticator(creds, &credential);
747 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
748 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
749 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
750 r.in.computer_name = TEST_MACHINE_NAME;
751 r.in.credential = &credential;
752 r.out.return_authenticator = &return_authenticator;
753 r.out.password = &password;
755 status = dcerpc_netr_ServerPasswordGet_r(b, tctx, &r);
756 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
757 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordGet");
762 static bool test_GetTrustPasswords(struct torture_context *tctx,
763 struct dcerpc_pipe *p,
764 struct cli_credentials *machine_credentials)
766 struct netr_ServerTrustPasswordsGet r;
767 struct netlogon_creds_CredentialState *creds;
768 struct netr_Authenticator credential;
769 struct netr_Authenticator return_authenticator;
770 struct samr_Password password, password2;
771 struct dcerpc_binding_handle *b = p->binding_handle;
773 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
777 netlogon_creds_client_authenticator(creds, &credential);
779 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
780 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
781 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
782 r.in.computer_name = TEST_MACHINE_NAME;
783 r.in.credential = &credential;
784 r.out.return_authenticator = &return_authenticator;
785 r.out.new_owf_password = &password;
786 r.out.old_owf_password = &password2;
788 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerTrustPasswordsGet_r(b, tctx, &r),
789 "ServerTrustPasswordsGet failed");
790 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerTrustPasswordsGet failed");
796 try a netlogon SamLogon
798 static bool test_netlogon_ops_args(struct dcerpc_pipe *p, struct torture_context *tctx,
799 struct cli_credentials *credentials,
800 struct netlogon_creds_CredentialState *creds,
804 struct netr_LogonSamLogon r;
805 struct netr_Authenticator auth, auth2;
806 static const struct netr_Authenticator auth_zero;
807 union netr_LogonLevel logon;
808 union netr_Validation validation;
809 uint8_t authoritative;
810 struct netr_NetworkInfo ninfo;
811 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
813 struct dcerpc_binding_handle *b = p->binding_handle;
814 int flags = CLI_CRED_NTLM_AUTH;
815 if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
816 flags |= CLI_CRED_LANMAN_AUTH;
819 if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx) && !null_domain) {
820 flags |= CLI_CRED_NTLMv2_AUTH;
823 cli_credentials_get_ntlm_username_domain(cmdline_credentials, tctx,
824 &ninfo.identity_info.account_name.string,
825 &ninfo.identity_info.domain_name.string);
828 ninfo.identity_info.domain_name.string = NULL;
831 generate_random_buffer(ninfo.challenge,
832 sizeof(ninfo.challenge));
833 chal = data_blob_const(ninfo.challenge,
834 sizeof(ninfo.challenge));
836 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials),
837 cli_credentials_get_domain(credentials));
839 status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx,
845 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
847 ninfo.lm.data = lm_resp.data;
848 ninfo.lm.length = lm_resp.length;
850 ninfo.nt.data = nt_resp.data;
851 ninfo.nt.length = nt_resp.length;
853 ninfo.identity_info.parameter_control = 0;
854 ninfo.identity_info.logon_id_low = 0;
855 ninfo.identity_info.logon_id_high = 0;
856 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
858 logon.network = &ninfo;
860 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
861 r.in.computer_name = cli_credentials_get_workstation(credentials);
862 r.in.credential = &auth;
863 r.in.return_authenticator = &auth2;
864 r.in.logon_level = NetlogonNetworkInformation;
866 r.out.validation = &validation;
867 r.out.authoritative = &authoritative;
869 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
873 netlogon_creds_client_authenticator(creds, &auth);
875 r.in.validation_level = i;
877 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
878 "LogonSamLogon failed");
879 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
881 torture_assert(tctx, netlogon_creds_client_check(creds,
882 &r.out.return_authenticator->cred),
883 "Credential chaining failed");
884 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
885 "LogonSamLogon invalid *r.out.authoritative");
888 /* this makes sure we get the unmarshalling right for invalid levels */
889 for (i=52;i<53;i++) {
891 /* the authenticator should be ignored by the server */
892 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
894 r.in.validation_level = i;
896 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
897 "LogonSamLogon failed");
898 torture_assert_ntstatus_equal(tctx, r.out.result,
899 NT_STATUS_INVALID_INFO_CLASS,
900 "LogonSamLogon failed");
902 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
903 "LogonSamLogon invalid *r.out.authoritative");
905 memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
906 "Return authenticator non zero");
911 netlogon_creds_client_authenticator(creds, &auth);
913 r.in.validation_level = i;
915 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
916 "LogonSamLogon failed");
917 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
919 torture_assert(tctx, netlogon_creds_client_check(creds,
920 &r.out.return_authenticator->cred),
921 "Credential chaining failed");
922 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
923 "LogonSamLogon invalid *r.out.authoritative");
926 r.in.logon_level = 52;
930 /* the authenticator should be ignored by the server */
931 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
933 r.in.validation_level = i;
935 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
937 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
938 "LogonSamLogon failed");
939 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
940 "LogonSamLogon expected INVALID_PARAMETER");
943 memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
944 "Return authenticator non zero");
945 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
946 "LogonSamLogon invalid *r.out.authoritative");
949 r.in.credential = NULL;
954 r.in.validation_level = i;
956 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
958 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
959 "LogonSamLogon failed");
960 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
961 "LogonSamLogon expected INVALID_PARAMETER");
964 memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
965 "Return authenticator non zero");
966 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
967 "LogonSamLogon invalid *r.out.authoritative");
970 r.in.logon_level = NetlogonNetworkInformation;
971 r.in.credential = &auth;
975 netlogon_creds_client_authenticator(creds, &auth);
977 r.in.validation_level = i;
979 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
980 "LogonSamLogon failed");
981 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
983 torture_assert(tctx, netlogon_creds_client_check(creds,
984 &r.out.return_authenticator->cred),
985 "Credential chaining failed");
986 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
987 "LogonSamLogon invalid *r.out.authoritative");
993 bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
994 struct cli_credentials *credentials,
995 struct netlogon_creds_CredentialState *creds)
997 return test_netlogon_ops_args(p, tctx, credentials, creds, false);
1001 try a netlogon GetCapabilities
1003 bool test_netlogon_capabilities(struct dcerpc_pipe *p, struct torture_context *tctx,
1004 struct cli_credentials *credentials,
1005 struct netlogon_creds_CredentialState *creds)
1008 struct netr_LogonGetCapabilities r;
1009 union netr_Capabilities capabilities;
1010 struct netr_Authenticator auth, return_auth;
1011 struct netlogon_creds_CredentialState tmp_creds;
1012 struct dcerpc_binding_handle *b = p->binding_handle;
1014 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1015 r.in.computer_name = cli_credentials_get_workstation(credentials);
1016 r.in.credential = &auth;
1017 r.in.return_authenticator = &return_auth;
1018 r.in.query_level = 1;
1019 r.out.capabilities = &capabilities;
1020 r.out.return_authenticator = &return_auth;
1022 torture_comment(tctx, "Testing LogonGetCapabilities\n");
1024 ZERO_STRUCT(return_auth);
1027 * we need to operate on a temporary copy of creds
1028 * because dcerpc_netr_LogonGetCapabilities was
1029 * dcerpc_netr_DummyFunction and returns NT_STATUS_NOT_IMPLEMENTED
1030 * without looking a the authenticator.
1033 netlogon_creds_client_authenticator(&tmp_creds, &auth);
1035 status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
1036 torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities failed");
1037 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
1043 torture_assert(tctx, netlogon_creds_client_check(creds,
1044 &r.out.return_authenticator->cred),
1045 "Credential chaining failed");
1047 torture_assert_int_equal(tctx, creds->negotiate_flags,
1048 capabilities.server_capabilities,
1055 try a netlogon SamLogon
1057 static bool test_SamLogon(struct torture_context *tctx,
1058 struct dcerpc_pipe *p,
1059 struct cli_credentials *credentials)
1061 struct netlogon_creds_CredentialState *creds;
1063 if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
1067 return test_netlogon_ops(p, tctx, credentials, creds);
1070 static bool test_invalidAuthenticate2(struct torture_context *tctx,
1071 struct dcerpc_pipe *p,
1072 struct cli_credentials *credentials)
1074 struct netlogon_creds_CredentialState *creds;
1075 uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
1077 torture_comment(tctx, "Testing invalidAuthenticate2\n");
1079 if (!test_SetupCredentials2(p, tctx, flags,
1081 cli_credentials_get_secure_channel_type(credentials),
1086 if (!test_SetupCredentials2ex(p, tctx, flags,
1089 cli_credentials_get_secure_channel_type(credentials),
1090 STATUS_BUFFER_OVERFLOW,
1095 if (!test_SetupCredentials2ex(p, tctx, flags,
1098 cli_credentials_get_secure_channel_type(credentials),
1107 static bool test_ServerReqChallengeGlobal(struct torture_context *tctx,
1108 struct dcerpc_pipe *p1,
1109 struct cli_credentials *machine_credentials)
1111 uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
1112 struct netr_ServerReqChallenge r;
1113 struct netr_ServerAuthenticate3 a;
1114 struct netr_Credential credentials1, credentials2, credentials3;
1115 struct netlogon_creds_CredentialState *creds;
1116 struct samr_Password mach_password;
1118 const char *machine_name;
1119 const char *plain_pass;
1120 struct dcerpc_binding_handle *b1 = p1->binding_handle;
1121 struct dcerpc_pipe *p2 = NULL;
1122 struct dcerpc_binding_handle *b2 = NULL;
1124 machine_name = cli_credentials_get_workstation(machine_credentials);
1125 plain_pass = cli_credentials_get_password(machine_credentials);
1127 torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
1129 torture_assert_ntstatus_ok(tctx,
1130 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
1131 &ndr_table_netlogon,
1132 machine_credentials,
1133 tctx->ev, tctx->lp_ctx),
1134 "dcerpc_pipe_connect_b failed");
1135 b2 = p2->binding_handle;
1137 r.in.server_name = NULL;
1138 r.in.computer_name = machine_name;
1139 r.in.credentials = &credentials1;
1140 r.out.return_credentials = &credentials2;
1142 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
1144 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
1145 "ServerReqChallenge failed on b1");
1146 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
1148 E_md4hash(plain_pass, mach_password.hash);
1150 a.in.server_name = NULL;
1151 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
1152 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1153 a.in.computer_name = machine_name;
1154 a.in.negotiate_flags = &flags;
1155 a.in.credentials = &credentials3;
1156 a.out.return_credentials = &credentials3;
1157 a.out.negotiate_flags = &flags;
1160 creds = netlogon_creds_client_init(tctx, a.in.account_name,
1162 a.in.secure_channel_type,
1163 &credentials1, &credentials2,
1164 &mach_password, &credentials3,
1167 torture_assert(tctx, creds != NULL, "memory allocation");
1169 torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
1171 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
1172 "ServerAuthenticate3 failed on b2");
1173 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
1174 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
1179 static bool test_SamLogon_NULL_domain(struct torture_context *tctx,
1180 struct dcerpc_pipe *p,
1181 struct cli_credentials *credentials)
1183 struct netlogon_creds_CredentialState *creds;
1185 if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
1189 return test_netlogon_ops_args(p, tctx, credentials, creds, true);
1192 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
1193 static uint64_t sequence_nums[3];
1196 try a netlogon DatabaseSync
1198 static bool test_DatabaseSync(struct torture_context *tctx,
1199 struct dcerpc_pipe *p,
1200 struct cli_credentials *machine_credentials)
1202 struct netr_DatabaseSync r;
1203 struct netlogon_creds_CredentialState *creds;
1204 const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
1206 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1207 struct netr_Authenticator credential, return_authenticator;
1208 struct dcerpc_binding_handle *b = p->binding_handle;
1210 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1214 ZERO_STRUCT(return_authenticator);
1216 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1217 r.in.computername = TEST_MACHINE_NAME;
1218 r.in.preferredmaximumlength = (uint32_t)-1;
1219 r.in.return_authenticator = &return_authenticator;
1220 r.out.delta_enum_array = &delta_enum_array;
1221 r.out.return_authenticator = &return_authenticator;
1223 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1225 uint32_t sync_context = 0;
1227 r.in.database_id = database_ids[i];
1228 r.in.sync_context = &sync_context;
1229 r.out.sync_context = &sync_context;
1231 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
1234 netlogon_creds_client_authenticator(creds, &credential);
1236 r.in.credential = &credential;
1238 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync_r(b, tctx, &r),
1239 "DatabaseSync failed");
1240 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1243 /* Native mode servers don't do this */
1244 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1247 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync");
1249 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1250 torture_comment(tctx, "Credential chaining failed\n");
1253 if (delta_enum_array &&
1254 delta_enum_array->num_deltas > 0 &&
1255 delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
1256 delta_enum_array->delta_enum[0].delta_union.domain) {
1257 sequence_nums[r.in.database_id] =
1258 delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
1259 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
1261 (unsigned long long)sequence_nums[r.in.database_id]);
1263 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1271 try a netlogon DatabaseDeltas
1273 static bool test_DatabaseDeltas(struct torture_context *tctx,
1274 struct dcerpc_pipe *p,
1275 struct cli_credentials *machine_credentials)
1277 struct netr_DatabaseDeltas r;
1278 struct netlogon_creds_CredentialState *creds;
1279 struct netr_Authenticator credential;
1280 struct netr_Authenticator return_authenticator;
1281 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1282 const uint32_t database_ids[] = {0, 1, 2};
1284 struct dcerpc_binding_handle *b = p->binding_handle;
1286 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1290 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1291 r.in.computername = TEST_MACHINE_NAME;
1292 r.in.preferredmaximumlength = (uint32_t)-1;
1293 ZERO_STRUCT(r.in.return_authenticator);
1294 r.out.return_authenticator = &return_authenticator;
1295 r.out.delta_enum_array = &delta_enum_array;
1297 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1298 r.in.database_id = database_ids[i];
1299 r.in.sequence_num = &sequence_nums[r.in.database_id];
1301 if (*r.in.sequence_num == 0) continue;
1303 *r.in.sequence_num -= 1;
1305 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n",
1306 r.in.database_id, (unsigned long long)*r.in.sequence_num);
1309 netlogon_creds_client_authenticator(creds, &credential);
1311 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseDeltas_r(b, tctx, &r),
1312 "DatabaseDeltas failed");
1313 if (NT_STATUS_EQUAL(r.out.result,
1314 NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
1315 torture_comment(tctx, "not considering %s to be an error\n",
1316 nt_errstr(r.out.result));
1319 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1322 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseDeltas");
1324 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1325 torture_comment(tctx, "Credential chaining failed\n");
1328 (*r.in.sequence_num)++;
1329 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1335 static bool test_DatabaseRedo(struct torture_context *tctx,
1336 struct dcerpc_pipe *p,
1337 struct cli_credentials *machine_credentials)
1339 struct netr_DatabaseRedo r;
1340 struct netlogon_creds_CredentialState *creds;
1341 struct netr_Authenticator credential;
1342 struct netr_Authenticator return_authenticator;
1343 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1344 struct netr_ChangeLogEntry e;
1345 struct dom_sid null_sid, *sid;
1347 struct dcerpc_binding_handle *b = p->binding_handle;
1349 ZERO_STRUCT(null_sid);
1351 sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
1362 NTSTATUS expected_error;
1363 uint32_t expected_num_results;
1364 uint8_t expected_delta_type_1;
1365 uint8_t expected_delta_type_2;
1366 const char *comment;
1369 /* SAM_DATABASE_DOMAIN */
1374 .db_index = SAM_DATABASE_DOMAIN,
1375 .delta_type = NETR_DELTA_MODIFY_COUNT,
1378 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1379 .expected_num_results = 0,
1380 .comment = "NETR_DELTA_MODIFY_COUNT"
1385 .db_index = SAM_DATABASE_DOMAIN,
1389 .expected_error = NT_STATUS_OK,
1390 .expected_num_results = 1,
1391 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1392 .comment = "NULL DELTA"
1397 .db_index = SAM_DATABASE_DOMAIN,
1398 .delta_type = NETR_DELTA_DOMAIN,
1401 .expected_error = NT_STATUS_OK,
1402 .expected_num_results = 1,
1403 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1404 .comment = "NETR_DELTA_DOMAIN"
1407 .rid = DOMAIN_RID_ADMINISTRATOR,
1409 .db_index = SAM_DATABASE_DOMAIN,
1410 .delta_type = NETR_DELTA_USER,
1413 .expected_error = NT_STATUS_OK,
1414 .expected_num_results = 1,
1415 .expected_delta_type_1 = NETR_DELTA_USER,
1416 .comment = "NETR_DELTA_USER by rid 500"
1419 .rid = DOMAIN_RID_GUEST,
1421 .db_index = SAM_DATABASE_DOMAIN,
1422 .delta_type = NETR_DELTA_USER,
1425 .expected_error = NT_STATUS_OK,
1426 .expected_num_results = 1,
1427 .expected_delta_type_1 = NETR_DELTA_USER,
1428 .comment = "NETR_DELTA_USER by rid 501"
1432 .flags = NETR_CHANGELOG_SID_INCLUDED,
1433 .db_index = SAM_DATABASE_DOMAIN,
1434 .delta_type = NETR_DELTA_USER,
1437 .expected_error = NT_STATUS_OK,
1438 .expected_num_results = 1,
1439 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1440 .comment = "NETR_DELTA_USER by sid and flags"
1444 .flags = NETR_CHANGELOG_SID_INCLUDED,
1445 .db_index = SAM_DATABASE_DOMAIN,
1446 .delta_type = NETR_DELTA_USER,
1449 .expected_error = NT_STATUS_OK,
1450 .expected_num_results = 1,
1451 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1452 .comment = "NETR_DELTA_USER by null_sid and flags"
1456 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1457 .db_index = SAM_DATABASE_DOMAIN,
1458 .delta_type = NETR_DELTA_USER,
1460 .name = "administrator",
1461 .expected_error = NT_STATUS_OK,
1462 .expected_num_results = 1,
1463 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1464 .comment = "NETR_DELTA_USER by name 'administrator'"
1467 .rid = DOMAIN_RID_ADMINS,
1469 .db_index = SAM_DATABASE_DOMAIN,
1470 .delta_type = NETR_DELTA_GROUP,
1473 .expected_error = NT_STATUS_OK,
1474 .expected_num_results = 2,
1475 .expected_delta_type_1 = NETR_DELTA_GROUP,
1476 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
1477 .comment = "NETR_DELTA_GROUP by rid 512"
1480 .rid = DOMAIN_RID_ADMINS,
1482 .db_index = SAM_DATABASE_DOMAIN,
1483 .delta_type = NETR_DELTA_GROUP_MEMBER,
1486 .expected_error = NT_STATUS_OK,
1487 .expected_num_results = 2,
1488 .expected_delta_type_1 = NETR_DELTA_GROUP,
1489 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
1490 .comment = "NETR_DELTA_GROUP_MEMBER by rid 512"
1494 /* SAM_DATABASE_BUILTIN */
1499 .db_index = SAM_DATABASE_BUILTIN,
1500 .delta_type = NETR_DELTA_MODIFY_COUNT,
1503 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1504 .expected_num_results = 0,
1505 .comment = "NETR_DELTA_MODIFY_COUNT"
1510 .db_index = SAM_DATABASE_BUILTIN,
1511 .delta_type = NETR_DELTA_DOMAIN,
1514 .expected_error = NT_STATUS_OK,
1515 .expected_num_results = 1,
1516 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1517 .comment = "NETR_DELTA_DOMAIN"
1520 .rid = DOMAIN_RID_ADMINISTRATOR,
1522 .db_index = SAM_DATABASE_BUILTIN,
1523 .delta_type = NETR_DELTA_USER,
1526 .expected_error = NT_STATUS_OK,
1527 .expected_num_results = 1,
1528 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1529 .comment = "NETR_DELTA_USER by rid 500"
1534 .db_index = SAM_DATABASE_BUILTIN,
1535 .delta_type = NETR_DELTA_USER,
1538 .expected_error = NT_STATUS_OK,
1539 .expected_num_results = 1,
1540 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1541 .comment = "NETR_DELTA_USER"
1546 .db_index = SAM_DATABASE_BUILTIN,
1547 .delta_type = NETR_DELTA_ALIAS,
1550 .expected_error = NT_STATUS_OK,
1551 .expected_num_results = 2,
1552 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1553 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1554 .comment = "NETR_DELTA_ALIAS by rid 544"
1559 .db_index = SAM_DATABASE_BUILTIN,
1560 .delta_type = NETR_DELTA_ALIAS_MEMBER,
1563 .expected_error = NT_STATUS_OK,
1564 .expected_num_results = 2,
1565 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1566 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1567 .comment = "NETR_DELTA_ALIAS_MEMBER by rid 544"
1572 .db_index = SAM_DATABASE_BUILTIN,
1576 .expected_error = NT_STATUS_OK,
1577 .expected_num_results = 1,
1578 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1579 .comment = "NULL DELTA by rid 544"
1583 .flags = NETR_CHANGELOG_SID_INCLUDED,
1584 .db_index = SAM_DATABASE_BUILTIN,
1586 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1588 .expected_error = NT_STATUS_OK,
1589 .expected_num_results = 1,
1590 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1591 .comment = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
1595 .flags = NETR_CHANGELOG_SID_INCLUDED,
1596 .db_index = SAM_DATABASE_BUILTIN,
1597 .delta_type = NETR_DELTA_ALIAS,
1598 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1600 .expected_error = NT_STATUS_OK,
1601 .expected_num_results = 2,
1602 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1603 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1604 .comment = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
1608 .flags = NETR_CHANGELOG_SID_INCLUDED,
1609 .db_index = SAM_DATABASE_BUILTIN,
1610 .delta_type = NETR_DELTA_ALIAS,
1611 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1613 .expected_error = NT_STATUS_OK,
1614 .expected_num_results = 1,
1615 .expected_delta_type_1 = NETR_DELTA_DELETE_ALIAS,
1616 .comment = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
1619 /* SAM_DATABASE_PRIVS */
1624 .db_index = SAM_DATABASE_PRIVS,
1628 .expected_error = NT_STATUS_ACCESS_DENIED,
1629 .expected_num_results = 0,
1630 .comment = "NULL DELTA"
1635 .db_index = SAM_DATABASE_PRIVS,
1636 .delta_type = NETR_DELTA_MODIFY_COUNT,
1639 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1640 .expected_num_results = 0,
1641 .comment = "NETR_DELTA_MODIFY_COUNT"
1646 .db_index = SAM_DATABASE_PRIVS,
1647 .delta_type = NETR_DELTA_POLICY,
1650 .expected_error = NT_STATUS_OK,
1651 .expected_num_results = 1,
1652 .expected_delta_type_1 = NETR_DELTA_POLICY,
1653 .comment = "NETR_DELTA_POLICY"
1657 .flags = NETR_CHANGELOG_SID_INCLUDED,
1658 .db_index = SAM_DATABASE_PRIVS,
1659 .delta_type = NETR_DELTA_POLICY,
1662 .expected_error = NT_STATUS_OK,
1663 .expected_num_results = 1,
1664 .expected_delta_type_1 = NETR_DELTA_POLICY,
1665 .comment = "NETR_DELTA_POLICY by null sid and flags"
1669 .flags = NETR_CHANGELOG_SID_INCLUDED,
1670 .db_index = SAM_DATABASE_PRIVS,
1671 .delta_type = NETR_DELTA_POLICY,
1672 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
1674 .expected_error = NT_STATUS_OK,
1675 .expected_num_results = 1,
1676 .expected_delta_type_1 = NETR_DELTA_POLICY,
1677 .comment = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
1680 .rid = DOMAIN_RID_ADMINISTRATOR,
1682 .db_index = SAM_DATABASE_PRIVS,
1683 .delta_type = NETR_DELTA_ACCOUNT,
1686 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
1687 .expected_num_results = 0,
1688 .comment = "NETR_DELTA_ACCOUNT by rid 500"
1692 .flags = NETR_CHANGELOG_SID_INCLUDED,
1693 .db_index = SAM_DATABASE_PRIVS,
1694 .delta_type = NETR_DELTA_ACCOUNT,
1695 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1697 .expected_error = NT_STATUS_OK,
1698 .expected_num_results = 1,
1699 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
1700 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
1704 .flags = NETR_CHANGELOG_SID_INCLUDED |
1705 NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
1706 .db_index = SAM_DATABASE_PRIVS,
1707 .delta_type = NETR_DELTA_ACCOUNT,
1708 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1710 .expected_error = NT_STATUS_OK,
1711 .expected_num_results = 1,
1712 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
1713 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
1717 .flags = NETR_CHANGELOG_SID_INCLUDED |
1718 NETR_CHANGELOG_NAME_INCLUDED,
1719 .db_index = SAM_DATABASE_PRIVS,
1720 .delta_type = NETR_DELTA_ACCOUNT,
1721 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1723 .expected_error = NT_STATUS_INVALID_PARAMETER,
1724 .expected_num_results = 0,
1725 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
1728 .rid = DOMAIN_RID_ADMINISTRATOR,
1729 .flags = NETR_CHANGELOG_SID_INCLUDED,
1730 .db_index = SAM_DATABASE_PRIVS,
1731 .delta_type = NETR_DELTA_ACCOUNT,
1734 .expected_error = NT_STATUS_OK,
1735 .expected_num_results = 1,
1736 .expected_delta_type_1 = NETR_DELTA_DELETE_ACCOUNT,
1737 .comment = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
1741 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1742 .db_index = SAM_DATABASE_PRIVS,
1743 .delta_type = NETR_DELTA_SECRET,
1745 .name = "IsurelydontexistIhope",
1746 .expected_error = NT_STATUS_OK,
1747 .expected_num_results = 1,
1748 .expected_delta_type_1 = NETR_DELTA_DELETE_SECRET,
1749 .comment = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
1753 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1754 .db_index = SAM_DATABASE_PRIVS,
1755 .delta_type = NETR_DELTA_SECRET,
1757 .name = "G$BCKUPKEY_P",
1758 .expected_error = NT_STATUS_OK,
1759 .expected_num_results = 1,
1760 .expected_delta_type_1 = NETR_DELTA_SECRET,
1761 .comment = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
1765 ZERO_STRUCT(return_authenticator);
1767 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1768 r.in.computername = TEST_MACHINE_NAME;
1769 r.in.return_authenticator = &return_authenticator;
1770 r.out.return_authenticator = &return_authenticator;
1771 r.out.delta_enum_array = &delta_enum_array;
1773 for (d=0; d<3; d++) {
1774 const char *database = NULL;
1781 database = "BUILTIN";
1790 torture_comment(tctx, "Testing DatabaseRedo\n");
1792 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1796 for (i=0;i<ARRAY_SIZE(changes);i++) {
1798 if (d != changes[i].db_index) {
1802 netlogon_creds_client_authenticator(creds, &credential);
1804 r.in.credential = &credential;
1806 e.serial_number1 = 0;
1807 e.serial_number2 = 0;
1808 e.object_rid = changes[i].rid;
1809 e.flags = changes[i].flags;
1810 e.db_index = changes[i].db_index;
1811 e.delta_type = changes[i].delta_type;
1813 switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
1814 case NETR_CHANGELOG_SID_INCLUDED:
1815 e.object.object_sid = changes[i].sid;
1817 case NETR_CHANGELOG_NAME_INCLUDED:
1818 e.object.object_name = changes[i].name;
1824 r.in.change_log_entry = e;
1826 torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
1827 database, changes[i].comment);
1829 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseRedo_r(b, tctx, &r),
1830 "DatabaseRedo failed");
1831 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1835 torture_assert_ntstatus_equal(tctx, r.out.result, changes[i].expected_error, changes[i].comment);
1836 if (delta_enum_array) {
1837 torture_assert_int_equal(tctx,
1838 delta_enum_array->num_deltas,
1839 changes[i].expected_num_results,
1840 changes[i].comment);
1841 if (delta_enum_array->num_deltas > 0) {
1842 torture_assert_int_equal(tctx,
1843 delta_enum_array->delta_enum[0].delta_type,
1844 changes[i].expected_delta_type_1,
1845 changes[i].comment);
1847 if (delta_enum_array->num_deltas > 1) {
1848 torture_assert_int_equal(tctx,
1849 delta_enum_array->delta_enum[1].delta_type,
1850 changes[i].expected_delta_type_2,
1851 changes[i].comment);
1855 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1856 torture_comment(tctx, "Credential chaining failed\n");
1857 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1869 try a netlogon AccountDeltas
1871 static bool test_AccountDeltas(struct torture_context *tctx,
1872 struct dcerpc_pipe *p,
1873 struct cli_credentials *machine_credentials)
1875 struct netr_AccountDeltas r;
1876 struct netlogon_creds_CredentialState *creds;
1878 struct netr_AccountBuffer buffer;
1879 uint32_t count_returned = 0;
1880 uint32_t total_entries = 0;
1881 struct netr_UAS_INFO_0 recordid;
1882 struct netr_Authenticator return_authenticator;
1883 struct dcerpc_binding_handle *b = p->binding_handle;
1885 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1889 ZERO_STRUCT(return_authenticator);
1891 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1892 r.in.computername = TEST_MACHINE_NAME;
1893 r.in.return_authenticator = &return_authenticator;
1894 netlogon_creds_client_authenticator(creds, &r.in.credential);
1895 ZERO_STRUCT(r.in.uas);
1898 r.in.buffersize=100;
1899 r.out.buffer = &buffer;
1900 r.out.count_returned = &count_returned;
1901 r.out.total_entries = &total_entries;
1902 r.out.recordid = &recordid;
1903 r.out.return_authenticator = &return_authenticator;
1905 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1906 torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountDeltas_r(b, tctx, &r),
1907 "AccountDeltas failed");
1908 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
1914 try a netlogon AccountSync
1916 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
1917 struct cli_credentials *machine_credentials)
1919 struct netr_AccountSync 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 uint32_t next_reference = 0;
1926 struct netr_UAS_INFO_0 recordid;
1927 struct netr_Authenticator return_authenticator;
1928 struct dcerpc_binding_handle *b = p->binding_handle;
1930 ZERO_STRUCT(recordid);
1931 ZERO_STRUCT(return_authenticator);
1933 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1937 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1938 r.in.computername = TEST_MACHINE_NAME;
1939 r.in.return_authenticator = &return_authenticator;
1940 netlogon_creds_client_authenticator(creds, &r.in.credential);
1941 r.in.recordid = &recordid;
1944 r.in.buffersize=100;
1945 r.out.buffer = &buffer;
1946 r.out.count_returned = &count_returned;
1947 r.out.total_entries = &total_entries;
1948 r.out.next_reference = &next_reference;
1949 r.out.recordid = &recordid;
1950 r.out.return_authenticator = &return_authenticator;
1952 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1953 torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountSync_r(b, tctx, &r),
1954 "AccountSync failed");
1955 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
1961 try a netlogon GetDcName
1963 static bool test_GetDcName(struct torture_context *tctx,
1964 struct dcerpc_pipe *p)
1966 struct netr_GetDcName r;
1967 const char *dcname = NULL;
1968 struct dcerpc_binding_handle *b = p->binding_handle;
1970 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1971 r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
1972 r.out.dcname = &dcname;
1974 torture_assert_ntstatus_ok(tctx, dcerpc_netr_GetDcName_r(b, tctx, &r),
1975 "GetDcName failed");
1976 torture_assert_werr_ok(tctx, r.out.result, "GetDcName failed");
1978 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1983 static const char *function_code_str(TALLOC_CTX *mem_ctx,
1984 enum netr_LogonControlCode function_code)
1986 switch (function_code) {
1987 case NETLOGON_CONTROL_QUERY:
1988 return "NETLOGON_CONTROL_QUERY";
1989 case NETLOGON_CONTROL_REPLICATE:
1990 return "NETLOGON_CONTROL_REPLICATE";
1991 case NETLOGON_CONTROL_SYNCHRONIZE:
1992 return "NETLOGON_CONTROL_SYNCHRONIZE";
1993 case NETLOGON_CONTROL_PDC_REPLICATE:
1994 return "NETLOGON_CONTROL_PDC_REPLICATE";
1995 case NETLOGON_CONTROL_REDISCOVER:
1996 return "NETLOGON_CONTROL_REDISCOVER";
1997 case NETLOGON_CONTROL_TC_QUERY:
1998 return "NETLOGON_CONTROL_TC_QUERY";
1999 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
2000 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
2001 case NETLOGON_CONTROL_FIND_USER:
2002 return "NETLOGON_CONTROL_FIND_USER";
2003 case NETLOGON_CONTROL_CHANGE_PASSWORD:
2004 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
2005 case NETLOGON_CONTROL_TC_VERIFY:
2006 return "NETLOGON_CONTROL_TC_VERIFY";
2007 case NETLOGON_CONTROL_FORCE_DNS_REG:
2008 return "NETLOGON_CONTROL_FORCE_DNS_REG";
2009 case NETLOGON_CONTROL_QUERY_DNS_REG:
2010 return "NETLOGON_CONTROL_QUERY_DNS_REG";
2011 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
2012 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
2013 case NETLOGON_CONTROL_TRUNCATE_LOG:
2014 return "NETLOGON_CONTROL_TRUNCATE_LOG";
2015 case NETLOGON_CONTROL_SET_DBFLAG:
2016 return "NETLOGON_CONTROL_SET_DBFLAG";
2017 case NETLOGON_CONTROL_BREAKPOINT:
2018 return "NETLOGON_CONTROL_BREAKPOINT";
2020 return talloc_asprintf(mem_ctx, "unknown function code: %d",
2027 try a netlogon LogonControl
2029 static bool test_LogonControl(struct torture_context *tctx,
2030 struct dcerpc_pipe *p,
2031 struct cli_credentials *machine_credentials)
2035 struct netr_LogonControl r;
2036 union netr_CONTROL_QUERY_INFORMATION query;
2038 enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
2039 struct dcerpc_binding_handle *b = p->binding_handle;
2041 uint32_t function_codes[] = {
2042 NETLOGON_CONTROL_QUERY,
2043 NETLOGON_CONTROL_REPLICATE,
2044 NETLOGON_CONTROL_SYNCHRONIZE,
2045 NETLOGON_CONTROL_PDC_REPLICATE,
2046 NETLOGON_CONTROL_REDISCOVER,
2047 NETLOGON_CONTROL_TC_QUERY,
2048 NETLOGON_CONTROL_TRANSPORT_NOTIFY,
2049 NETLOGON_CONTROL_FIND_USER,
2050 NETLOGON_CONTROL_CHANGE_PASSWORD,
2051 NETLOGON_CONTROL_TC_VERIFY,
2052 NETLOGON_CONTROL_FORCE_DNS_REG,
2053 NETLOGON_CONTROL_QUERY_DNS_REG,
2054 NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
2055 NETLOGON_CONTROL_TRUNCATE_LOG,
2056 NETLOGON_CONTROL_SET_DBFLAG,
2057 NETLOGON_CONTROL_BREAKPOINT
2060 if (machine_credentials) {
2061 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2064 torture_comment(tctx, "Testing LogonControl with secure channel type: %d\n",
2065 secure_channel_type);
2067 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2068 r.in.function_code = 1;
2069 r.out.query = &query;
2071 for (f=0;f<ARRAY_SIZE(function_codes); f++) {
2074 r.in.function_code = function_codes[f];
2077 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
2078 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2080 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
2081 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2083 switch (r.in.level) {
2085 switch (r.in.function_code) {
2086 case NETLOGON_CONTROL_REPLICATE:
2087 case NETLOGON_CONTROL_SYNCHRONIZE:
2088 case NETLOGON_CONTROL_PDC_REPLICATE:
2089 case NETLOGON_CONTROL_BREAKPOINT:
2090 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
2091 if ((secure_channel_type == SEC_CHAN_BDC) ||
2092 (secure_channel_type == SEC_CHAN_WKSTA)) {
2093 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
2094 "LogonControl returned unexpected error code");
2096 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
2097 "LogonControl returned unexpected error code");
2101 case NETLOGON_CONTROL_REDISCOVER:
2102 case NETLOGON_CONTROL_TC_QUERY:
2103 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
2104 case NETLOGON_CONTROL_FIND_USER:
2105 case NETLOGON_CONTROL_CHANGE_PASSWORD:
2106 case NETLOGON_CONTROL_TC_VERIFY:
2107 case NETLOGON_CONTROL_FORCE_DNS_REG:
2108 case NETLOGON_CONTROL_QUERY_DNS_REG:
2109 case NETLOGON_CONTROL_SET_DBFLAG:
2110 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
2111 "LogonControl returned unexpected error code");
2113 case NETLOGON_CONTROL_TRUNCATE_LOG:
2114 if ((secure_channel_type == SEC_CHAN_BDC) ||
2115 (secure_channel_type == SEC_CHAN_WKSTA)) {
2116 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
2117 "LogonControl returned unexpected error code");
2118 } else if (!W_ERROR_EQUAL(r.out.result, WERR_NOT_SUPPORTED)) {
2119 torture_assert_werr_ok(tctx, r.out.result,
2120 "LogonControl returned unexpected result");
2124 torture_assert_werr_ok(tctx, r.out.result,
2125 "LogonControl returned unexpected result");
2130 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
2131 "LogonControl returned unexpected error code");
2134 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL,
2135 "LogonControl returned unexpected error code");
2142 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
2143 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2144 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
2145 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2146 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl");
2153 try a netlogon GetAnyDCName
2155 static bool test_GetAnyDCName(struct torture_context *tctx,
2156 struct dcerpc_pipe *p)
2159 struct netr_GetAnyDCName r;
2160 const char *dcname = NULL;
2161 struct dcerpc_binding_handle *b = p->binding_handle;
2163 r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
2164 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2165 r.out.dcname = &dcname;
2167 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2168 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2169 if ((!W_ERROR_IS_OK(r.out.result)) &&
2170 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2175 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
2178 r.in.domainname = NULL;
2180 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2181 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2182 if ((!W_ERROR_IS_OK(r.out.result)) &&
2183 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2187 r.in.domainname = "";
2189 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2190 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2191 if ((!W_ERROR_IS_OK(r.out.result)) &&
2192 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2201 try a netlogon LogonControl2
2203 static bool test_LogonControl2(struct torture_context *tctx,
2204 struct dcerpc_pipe *p,
2205 struct cli_credentials *machine_credentials)
2209 struct netr_LogonControl2 r;
2210 union netr_CONTROL_DATA_INFORMATION data;
2211 union netr_CONTROL_QUERY_INFORMATION query;
2212 enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
2214 struct dcerpc_binding_handle *b = p->binding_handle;
2216 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2218 if (machine_credentials) {
2219 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2222 torture_comment(tctx, "Testing LogonControl2 with secure channel type: %d\n",
2223 secure_channel_type);
2225 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2227 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2229 r.out.query = &query;
2234 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2235 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2237 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2238 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2241 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2243 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2249 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2250 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2252 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2253 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2256 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2258 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2264 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2265 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2267 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2268 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2271 data.debug_level = ~0;
2273 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2279 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2280 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2282 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2283 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2287 r.in.function_code = 52;
2290 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2291 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2293 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2294 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2295 switch (secure_channel_type) {
2297 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2");
2300 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2");
2303 data.debug_level = ~0;
2305 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2309 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2310 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2312 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2313 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2314 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "LogonControl2");
2320 try a netlogon DatabaseSync2
2322 static bool test_DatabaseSync2(struct torture_context *tctx,
2323 struct dcerpc_pipe *p,
2324 struct cli_credentials *machine_credentials)
2326 struct netr_DatabaseSync2 r;
2327 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2328 struct netr_Authenticator return_authenticator, credential;
2330 struct netlogon_creds_CredentialState *creds;
2331 const uint32_t database_ids[] = {0, 1, 2};
2333 struct dcerpc_binding_handle *b = p->binding_handle;
2335 if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
2336 machine_credentials,
2337 cli_credentials_get_secure_channel_type(machine_credentials),
2342 ZERO_STRUCT(return_authenticator);
2344 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2345 r.in.computername = TEST_MACHINE_NAME;
2346 r.in.preferredmaximumlength = (uint32_t)-1;
2347 r.in.return_authenticator = &return_authenticator;
2348 r.out.return_authenticator = &return_authenticator;
2349 r.out.delta_enum_array = &delta_enum_array;
2351 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2353 uint32_t sync_context = 0;
2355 r.in.database_id = database_ids[i];
2356 r.in.sync_context = &sync_context;
2357 r.out.sync_context = &sync_context;
2358 r.in.restart_state = 0;
2360 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
2363 netlogon_creds_client_authenticator(creds, &credential);
2365 r.in.credential = &credential;
2367 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync2_r(b, tctx, &r),
2368 "DatabaseSync2 failed");
2369 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2372 /* Native mode servers don't do this */
2373 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
2377 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync2");
2379 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
2380 torture_comment(tctx, "Credential chaining failed\n");
2383 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2391 try a netlogon LogonControl2Ex
2393 static bool test_LogonControl2Ex(struct torture_context *tctx,
2394 struct dcerpc_pipe *p,
2395 struct cli_credentials *machine_credentials)
2399 struct netr_LogonControl2Ex r;
2400 union netr_CONTROL_DATA_INFORMATION data;
2401 union netr_CONTROL_QUERY_INFORMATION query;
2402 enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
2404 struct dcerpc_binding_handle *b = p->binding_handle;
2406 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2408 if (machine_credentials) {
2409 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2412 torture_comment(tctx, "Testing LogonControl2Ex with secure channel type: %d\n",
2413 secure_channel_type);
2415 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2417 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2419 r.out.query = &query;
2424 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2425 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2427 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2428 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2431 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2433 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2439 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2440 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2442 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2443 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2446 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2448 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2454 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2455 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2457 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2458 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2461 data.debug_level = ~0;
2463 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2469 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2470 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2472 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2473 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2477 r.in.function_code = 52;
2480 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2481 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2483 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2484 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2485 switch (secure_channel_type) {
2487 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2Ex");
2490 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2Ex");
2493 data.debug_level = ~0;
2495 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2499 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
2500 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2502 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2503 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
2504 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "LogonControl2Ex");
2509 static bool test_netr_GetForestTrustInformation(struct torture_context *tctx,
2510 struct dcerpc_pipe *p,
2511 struct cli_credentials *machine_credentials)
2513 struct netr_GetForestTrustInformation r;
2514 struct netlogon_creds_CredentialState *creds;
2515 struct netr_Authenticator a;
2516 struct netr_Authenticator return_authenticator;
2517 struct lsa_ForestTrustInformation *forest_trust_info;
2518 struct dcerpc_binding_handle *b = p->binding_handle;
2520 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2521 machine_credentials, &creds)) {
2525 netlogon_creds_client_authenticator(creds, &a);
2527 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2528 r.in.computer_name = TEST_MACHINE_NAME;
2529 r.in.credential = &a;
2531 r.out.return_authenticator = &return_authenticator;
2532 r.out.forest_trust_info = &forest_trust_info;
2534 torture_assert_ntstatus_ok(tctx,
2535 dcerpc_netr_GetForestTrustInformation_r(b, tctx, &r),
2536 "netr_GetForestTrustInformation failed");
2537 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2538 torture_comment(tctx, "not considering NT_STATUS_NOT_IMPLEMENTED as an error\n");
2540 torture_assert_ntstatus_ok(tctx, r.out.result,
2541 "netr_GetForestTrustInformation failed");
2544 torture_assert(tctx,
2545 netlogon_creds_client_check(creds, &return_authenticator.cred),
2546 "Credential chaining failed");
2551 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
2552 struct dcerpc_pipe *p, const char *trusted_domain_name)
2555 struct netr_DsRGetForestTrustInformation r;
2556 struct lsa_ForestTrustInformation info, *info_ptr;
2557 struct dcerpc_binding_handle *b = p->binding_handle;
2561 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2562 r.in.trusted_domain_name = trusted_domain_name;
2564 r.out.forest_trust_info = &info_ptr;
2566 torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
2568 status = dcerpc_netr_DsRGetForestTrustInformation_r(b, tctx, &r);
2569 torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
2570 torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
2576 try a netlogon netr_DsrEnumerateDomainTrusts
2578 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
2579 struct dcerpc_pipe *p)
2582 struct netr_DsrEnumerateDomainTrusts r;
2583 struct netr_DomainTrustList trusts;
2585 struct dcerpc_binding_handle *b = p->binding_handle;
2587 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2588 r.in.trust_flags = 0x3f;
2589 r.out.trusts = &trusts;
2591 status = dcerpc_netr_DsrEnumerateDomainTrusts_r(b, tctx, &r);
2592 torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
2593 torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
2595 /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
2596 * will show non-forest trusts and all UPN suffixes of the own forest
2597 * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
2599 if (r.out.trusts->count) {
2600 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
2605 for (i=0; i<r.out.trusts->count; i++) {
2607 /* get info for transitive forest trusts */
2609 if (r.out.trusts->array[i].trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2610 if (!test_netr_DsRGetForestTrustInformation(tctx, p,
2611 r.out.trusts->array[i].dns_name)) {
2620 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
2621 struct dcerpc_pipe *p)
2624 struct netr_NetrEnumerateTrustedDomains r;
2625 struct netr_Blob trusted_domains_blob;
2626 struct dcerpc_binding_handle *b = p->binding_handle;
2628 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2629 r.out.trusted_domains_blob = &trusted_domains_blob;
2631 status = dcerpc_netr_NetrEnumerateTrustedDomains_r(b, tctx, &r);
2632 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
2633 torture_assert_ntstatus_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
2638 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
2639 struct dcerpc_pipe *p)
2642 struct netr_NetrEnumerateTrustedDomainsEx r;
2643 struct netr_DomainTrustList dom_trust_list;
2644 struct dcerpc_binding_handle *b = p->binding_handle;
2646 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2647 r.out.dom_trust_list = &dom_trust_list;
2649 status = dcerpc_netr_NetrEnumerateTrustedDomainsEx_r(b, tctx, &r);
2650 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
2651 torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
2657 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
2658 const char *computer_name,
2659 const char *expected_site)
2662 struct netr_DsRGetSiteName r;
2663 const char *site = NULL;
2664 struct dcerpc_binding_handle *b = p->binding_handle;
2666 r.in.computer_name = computer_name;
2668 torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
2670 status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
2671 torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2672 torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
2673 torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
2679 try a netlogon netr_DsRGetDCName
2681 static bool test_netr_DsRGetDCName(struct torture_context *tctx,
2682 struct dcerpc_pipe *p)
2685 struct netr_DsRGetDCName r;
2686 struct netr_DsRGetDCNameInfo *info = NULL;
2687 struct dcerpc_binding_handle *b = p->binding_handle;
2689 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2690 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
2691 r.in.domain_guid = NULL;
2692 r.in.site_guid = NULL;
2693 r.in.flags = DS_RETURN_DNS_NAME;
2696 status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2697 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2698 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2700 torture_assert_int_equal(tctx,
2701 (info->dc_flags & (DS_DNS_CONTROLLER)),
2704 torture_assert_int_equal(tctx,
2705 (info->dc_flags & (DS_DNS_DOMAIN)),
2708 torture_assert_int_equal(tctx,
2709 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2713 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
2716 status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2717 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2718 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2720 torture_assert_int_equal(tctx,
2721 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2723 torture_assert_int_equal(tctx,
2724 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2726 torture_assert_int_equal(tctx,
2727 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2731 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2732 torture_assert_int_equal(tctx,
2733 (info->dc_flags & (DS_SERVER_CLOSEST)),
2738 return test_netr_DsRGetSiteName(p, tctx,
2740 info->dc_site_name);
2744 try a netlogon netr_DsRGetDCNameEx
2746 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
2747 struct dcerpc_pipe *p)
2750 struct netr_DsRGetDCNameEx r;
2751 struct netr_DsRGetDCNameInfo *info = NULL;
2752 struct dcerpc_binding_handle *b = p->binding_handle;
2754 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2755 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
2756 r.in.domain_guid = NULL;
2757 r.in.site_name = NULL;
2758 r.in.flags = DS_RETURN_DNS_NAME;
2761 status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2762 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2763 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2765 torture_assert_int_equal(tctx,
2766 (info->dc_flags & (DS_DNS_CONTROLLER)),
2769 torture_assert_int_equal(tctx,
2770 (info->dc_flags & (DS_DNS_DOMAIN)),
2773 torture_assert_int_equal(tctx,
2774 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2778 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
2781 status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2782 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2783 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2785 torture_assert_int_equal(tctx,
2786 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2788 torture_assert_int_equal(tctx,
2789 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2791 torture_assert_int_equal(tctx,
2792 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2796 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2797 torture_assert_int_equal(tctx,
2798 (info->dc_flags & (DS_SERVER_CLOSEST)),
2803 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2804 info->dc_site_name);
2808 try a netlogon netr_DsRGetDCNameEx2
2810 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
2811 struct dcerpc_pipe *p)
2814 struct netr_DsRGetDCNameEx2 r;
2815 struct netr_DsRGetDCNameInfo *info = NULL;
2816 struct dcerpc_binding_handle *b = p->binding_handle;
2818 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with no inputs\n");
2820 r.in.flags = DS_RETURN_DNS_NAME;
2823 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2824 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2825 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2827 torture_assert_int_equal(tctx,
2828 (info->dc_flags & (DS_DNS_CONTROLLER)),
2831 torture_assert_int_equal(tctx,
2832 (info->dc_flags & (DS_DNS_DOMAIN)),
2835 torture_assert_int_equal(tctx,
2836 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2840 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2841 r.in.client_account = NULL;
2842 r.in.mask = 0x00000000;
2843 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
2844 r.in.domain_guid = NULL;
2845 r.in.site_name = NULL;
2846 r.in.flags = DS_RETURN_DNS_NAME;
2849 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
2851 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2852 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2853 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2855 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
2858 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2859 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2860 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2862 torture_assert_int_equal(tctx,
2863 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2865 torture_assert_int_equal(tctx,
2866 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2868 torture_assert_int_equal(tctx,
2869 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2873 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2874 torture_assert_int_equal(tctx,
2875 (info->dc_flags & (DS_SERVER_CLOSEST)),
2880 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client account\n");
2881 r.in.client_account = TEST_MACHINE_NAME"$";
2882 r.in.mask = ACB_SVRTRUST;
2883 r.in.flags = DS_RETURN_FLAT_NAME;
2886 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2887 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2888 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2890 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2891 info->dc_site_name);
2894 /* This is a substitution for "samdb_server_site_name" which relies on the
2895 * correct "lp_ctx" and therefore can't be used here. */
2896 static const char *server_site_name(struct torture_context *tctx,
2897 struct ldb_context *ldb)
2899 TALLOC_CTX *tmp_ctx;
2900 struct ldb_dn *dn, *server_dn;
2901 const struct ldb_val *site_name_val;
2902 const char *server_dn_str, *site_name;
2904 tmp_ctx = talloc_new(ldb);
2905 if (tmp_ctx == NULL) {
2909 dn = ldb_dn_new(tmp_ctx, ldb, "");
2914 server_dn_str = samdb_search_string(ldb, tmp_ctx, dn, "serverName",
2916 if (server_dn_str == NULL) {
2920 server_dn = ldb_dn_new(tmp_ctx, ldb, server_dn_str);
2921 if (server_dn == NULL) {
2925 /* CN=<Server name>, CN=Servers, CN=<Site name>, CN=Sites, ... */
2926 site_name_val = ldb_dn_get_component_val(server_dn, 2);
2927 if (site_name_val == NULL) {
2931 site_name = (const char *) site_name_val->data;
2933 talloc_steal(tctx, site_name);
2934 talloc_free(tmp_ctx);
2939 talloc_free(tmp_ctx);
2943 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
2944 struct dcerpc_pipe *p)
2947 struct ldb_context *sam_ctx = NULL;
2949 struct netr_DsrGetDcSiteCoverageW r;
2950 struct DcSitesCtr *ctr = NULL;
2951 struct dcerpc_binding_handle *b = p->binding_handle;
2953 torture_comment(tctx, "This does only pass with the default site\n");
2955 /* We won't double-check this when we are over 'local' transports */
2956 if (dcerpc_server_name(p)) {
2957 /* Set up connection to SAMDB on DC */
2958 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2959 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2961 cmdline_credentials,
2964 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2967 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2970 status = dcerpc_netr_DsrGetDcSiteCoverageW_r(b, tctx, &r);
2971 torture_assert_ntstatus_ok(tctx, status, "failed");
2972 torture_assert_werr_ok(tctx, r.out.result, "failed");
2974 torture_assert(tctx, ctr->num_sites == 1,
2975 "we should per default only get the default site");
2976 if (sam_ctx != NULL) {
2977 torture_assert_casestr_equal(tctx, ctr->sites[0].string,
2978 server_site_name(tctx, sam_ctx),
2979 "didn't return default site");
2985 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
2986 struct dcerpc_pipe *p)
2989 struct ldb_context *sam_ctx = NULL;
2991 struct netr_DsRAddressToSitenamesW r;
2992 struct netr_DsRAddress addrs[6];
2993 struct sockaddr_in *addr;
2995 struct sockaddr_in6 *addr6;
2997 struct netr_DsRAddressToSitenamesWCtr *ctr;
2998 struct dcerpc_binding_handle *b = p->binding_handle;
3002 torture_comment(tctx, "This does only pass with the default site\n");
3004 /* We won't double-check this when we are over 'local' transports */
3005 if (dcerpc_server_name(p)) {
3006 /* Set up connection to SAMDB on DC */
3007 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3008 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3010 cmdline_credentials,
3013 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3016 /* First try valid IP addresses */
3018 addrs[0].size = sizeof(struct sockaddr_in);
3019 addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
3020 addr = (struct sockaddr_in *) addrs[0].buffer;
3021 addrs[0].buffer[0] = AF_INET;
3022 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3023 torture_assert(tctx, ret > 0, "inet_pton failed");
3025 addrs[1].size = sizeof(struct sockaddr_in);
3026 addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
3027 addr = (struct sockaddr_in *) addrs[1].buffer;
3028 addrs[1].buffer[0] = AF_INET;
3029 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3030 torture_assert(tctx, ret > 0, "inet_pton failed");
3032 addrs[2].size = sizeof(struct sockaddr_in);
3033 addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
3034 addr = (struct sockaddr_in *) addrs[2].buffer;
3035 addrs[2].buffer[0] = AF_INET;
3036 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3037 torture_assert(tctx, ret > 0, "inet_pton failed");
3040 addrs[3].size = sizeof(struct sockaddr_in6);
3041 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3042 addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
3043 addrs[3].buffer[0] = AF_INET6;
3044 ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
3045 torture_assert(tctx, ret > 0, "inet_pton failed");
3047 addrs[4].size = sizeof(struct sockaddr_in6);
3048 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3049 addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
3050 addrs[4].buffer[0] = AF_INET6;
3051 ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
3052 torture_assert(tctx, ret > 0, "inet_pton failed");
3054 addrs[5].size = sizeof(struct sockaddr_in6);
3055 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3056 addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
3057 addrs[5].buffer[0] = AF_INET6;
3058 ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
3059 torture_assert(tctx, ret > 0, "inet_pton failed");
3061 /* the test cases are repeated to have exactly 6. This is for
3062 * compatibility with IPv4-only machines */
3063 addrs[3].size = sizeof(struct sockaddr_in);
3064 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3065 addr = (struct sockaddr_in *) addrs[3].buffer;
3066 addrs[3].buffer[0] = AF_INET;
3067 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3068 torture_assert(tctx, ret > 0, "inet_pton failed");
3070 addrs[4].size = sizeof(struct sockaddr_in);
3071 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3072 addr = (struct sockaddr_in *) addrs[4].buffer;
3073 addrs[4].buffer[0] = AF_INET;
3074 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3075 torture_assert(tctx, ret > 0, "inet_pton failed");
3077 addrs[5].size = sizeof(struct sockaddr_in);
3078 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3079 addr = (struct sockaddr_in *) addrs[5].buffer;
3080 addrs[5].buffer[0] = AF_INET;
3081 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3082 torture_assert(tctx, ret > 0, "inet_pton failed");
3085 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
3087 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3089 r.in.addresses = addrs;
3092 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
3093 torture_assert_ntstatus_ok(tctx, status, "failed");
3094 torture_assert_werr_ok(tctx, r.out.result, "failed");
3096 if (sam_ctx != NULL) {
3097 for (i = 0; i < 3; i++) {
3098 torture_assert_casestr_equal(tctx,
3099 ctr->sitename[i].string,
3100 server_site_name(tctx, sam_ctx),
3101 "didn't return default site");
3103 for (i = 3; i < 6; i++) {
3104 /* Windows returns "NULL" for the sitename if it isn't
3105 * IPv6 configured */
3106 if (torture_setting_bool(tctx, "samba4", false)) {
3107 torture_assert_casestr_equal(tctx,
3108 ctr->sitename[i].string,
3109 server_site_name(tctx, sam_ctx),
3110 "didn't return default site");
3115 /* Now try invalid ones (too short buffers) */
3125 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
3126 torture_assert_ntstatus_ok(tctx, status, "failed");
3127 torture_assert_werr_ok(tctx, r.out.result, "failed");
3129 for (i = 0; i < 6; i++) {
3130 torture_assert(tctx, ctr->sitename[i].string == NULL,
3131 "sitename should be null");
3134 /* Now try invalid ones (wrong address types) */
3137 addrs[0].buffer[0] = AF_UNSPEC;
3139 addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
3141 addrs[2].buffer[0] = AF_UNIX;
3144 addrs[3].buffer[0] = 250;
3146 addrs[4].buffer[0] = 251;
3148 addrs[5].buffer[0] = 252;
3150 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
3151 torture_assert_ntstatus_ok(tctx, status, "failed");
3152 torture_assert_werr_ok(tctx, r.out.result, "failed");
3154 for (i = 0; i < 6; i++) {
3155 torture_assert(tctx, ctr->sitename[i].string == NULL,
3156 "sitename should be null");
3162 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
3163 struct dcerpc_pipe *p)
3166 struct ldb_context *sam_ctx = NULL;
3168 struct netr_DsRAddressToSitenamesExW r;
3169 struct netr_DsRAddress addrs[6];
3170 struct sockaddr_in *addr;
3172 struct sockaddr_in6 *addr6;
3174 struct netr_DsRAddressToSitenamesExWCtr *ctr;
3175 struct dcerpc_binding_handle *b = p->binding_handle;
3179 torture_comment(tctx, "This does pass with the default site\n");
3181 /* We won't double-check this when we are over 'local' transports */
3182 if (dcerpc_server_name(p)) {
3183 /* Set up connection to SAMDB on DC */
3184 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3185 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3187 cmdline_credentials,
3190 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3193 /* First try valid IP addresses */
3195 addrs[0].size = sizeof(struct sockaddr_in);
3196 addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
3197 addr = (struct sockaddr_in *) addrs[0].buffer;
3198 addrs[0].buffer[0] = AF_INET;
3199 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3200 torture_assert(tctx, ret > 0, "inet_pton failed");
3202 addrs[1].size = sizeof(struct sockaddr_in);
3203 addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
3204 addr = (struct sockaddr_in *) addrs[1].buffer;
3205 addrs[1].buffer[0] = AF_INET;
3206 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3207 torture_assert(tctx, ret > 0, "inet_pton failed");
3209 addrs[2].size = sizeof(struct sockaddr_in);
3210 addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
3211 addr = (struct sockaddr_in *) addrs[2].buffer;
3212 addrs[2].buffer[0] = AF_INET;
3213 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3214 torture_assert(tctx, ret > 0, "inet_pton failed");
3217 addrs[3].size = sizeof(struct sockaddr_in6);
3218 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3219 addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
3220 addrs[3].buffer[0] = AF_INET6;
3221 ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
3222 torture_assert(tctx, ret > 0, "inet_pton failed");
3224 addrs[4].size = sizeof(struct sockaddr_in6);
3225 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3226 addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
3227 addrs[4].buffer[0] = AF_INET6;
3228 ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
3229 torture_assert(tctx, ret > 0, "inet_pton failed");
3231 addrs[5].size = sizeof(struct sockaddr_in6);
3232 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3233 addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
3234 addrs[5].buffer[0] = AF_INET6;
3235 ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
3236 torture_assert(tctx, ret > 0, "inet_pton failed");
3238 /* the test cases are repeated to have exactly 6. This is for
3239 * compatibility with IPv4-only machines */
3240 addrs[3].size = sizeof(struct sockaddr_in);
3241 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3242 addr = (struct sockaddr_in *) addrs[3].buffer;
3243 addrs[3].buffer[0] = AF_INET;
3244 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3245 torture_assert(tctx, ret > 0, "inet_pton failed");
3247 addrs[4].size = sizeof(struct sockaddr_in);
3248 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3249 addr = (struct sockaddr_in *) addrs[4].buffer;
3250 addrs[4].buffer[0] = AF_INET;
3251 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3252 torture_assert(tctx, ret > 0, "inet_pton failed");
3254 addrs[5].size = sizeof(struct sockaddr_in);
3255 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3256 addr = (struct sockaddr_in *) addrs[5].buffer;
3257 addrs[5].buffer[0] = AF_INET;
3258 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3259 torture_assert(tctx, ret > 0, "inet_pton failed");
3262 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
3264 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3266 r.in.addresses = addrs;
3269 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3270 torture_assert_ntstatus_ok(tctx, status, "failed");
3271 torture_assert_werr_ok(tctx, r.out.result, "failed");
3273 if (sam_ctx != NULL) {
3274 for (i = 0; i < 3; i++) {
3275 torture_assert_casestr_equal(tctx,
3276 ctr->sitename[i].string,
3277 server_site_name(tctx, sam_ctx),
3278 "didn't return default site");
3279 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3280 "subnet should be null");
3282 for (i = 3; i < 6; i++) {
3283 /* Windows returns "NULL" for the sitename if it isn't
3284 * IPv6 configured */
3285 if (torture_setting_bool(tctx, "samba4", false)) {
3286 torture_assert_casestr_equal(tctx,
3287 ctr->sitename[i].string,
3288 server_site_name(tctx, sam_ctx),
3289 "didn't return default site");
3291 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3292 "subnet should be null");
3296 /* Now try invalid ones (too short buffers) */
3306 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3307 torture_assert_ntstatus_ok(tctx, status, "failed");
3308 torture_assert_werr_ok(tctx, r.out.result, "failed");
3310 for (i = 0; i < 6; i++) {
3311 torture_assert(tctx, ctr->sitename[i].string == NULL,
3312 "sitename should be null");
3313 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3314 "subnet should be null");
3318 addrs[0].buffer[0] = AF_UNSPEC;
3320 addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
3322 addrs[2].buffer[0] = AF_UNIX;
3325 addrs[3].buffer[0] = 250;
3327 addrs[4].buffer[0] = 251;
3329 addrs[5].buffer[0] = 252;
3331 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3332 torture_assert_ntstatus_ok(tctx, status, "failed");
3333 torture_assert_werr_ok(tctx, r.out.result, "failed");
3335 for (i = 0; i < 6; i++) {
3336 torture_assert(tctx, ctr->sitename[i].string == NULL,
3337 "sitename should be null");
3338 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3339 "subnet should be null");
3345 static bool test_netr_ServerGetTrustInfo_flags(struct torture_context *tctx,
3346 struct dcerpc_pipe *p,
3347 struct cli_credentials *machine_credentials,
3348 uint32_t negotiate_flags)
3350 struct netr_ServerGetTrustInfo r;
3352 struct netr_Authenticator a;
3353 struct netr_Authenticator return_authenticator;
3354 struct samr_Password new_owf_password;
3355 struct samr_Password old_owf_password;
3356 struct netr_TrustInfo *trust_info;
3358 struct netlogon_creds_CredentialState *creds;
3359 struct dcerpc_binding_handle *b = p->binding_handle;
3361 struct samr_Password nt_hash;
3363 if (!test_SetupCredentials3(p, tctx, negotiate_flags,
3364 machine_credentials, &creds)) {
3368 netlogon_creds_client_authenticator(creds, &a);
3370 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3371 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
3372 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
3373 r.in.computer_name = TEST_MACHINE_NAME;
3374 r.in.credential = &a;
3376 r.out.return_authenticator = &return_authenticator;
3377 r.out.new_owf_password = &new_owf_password;
3378 r.out.old_owf_password = &old_owf_password;
3379 r.out.trust_info = &trust_info;
3381 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerGetTrustInfo_r(b, tctx, &r),
3382 "ServerGetTrustInfo failed");
3383 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerGetTrustInfo failed");
3384 torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
3386 E_md4hash(cli_credentials_get_password(machine_credentials), nt_hash.hash);
3388 netlogon_creds_des_decrypt(creds, &new_owf_password);
3390 dump_data(1, new_owf_password.hash, 16);
3391 dump_data(1, nt_hash.hash, 16);
3393 torture_assert_mem_equal(tctx, new_owf_password.hash, nt_hash.hash, 16,
3394 "received unexpected owf password\n");
3399 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
3400 struct dcerpc_pipe *p,
3401 struct cli_credentials *machine_credentials)
3403 return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
3404 NETLOGON_NEG_AUTH2_ADS_FLAGS);
3407 static bool test_netr_ServerGetTrustInfo_AES(struct torture_context *tctx,
3408 struct dcerpc_pipe *p,
3409 struct cli_credentials *machine_credentials)
3411 return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
3412 NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
3415 static bool test_GetDomainInfo(struct torture_context *tctx,
3416 struct dcerpc_pipe *p,
3417 struct cli_credentials *machine_credentials)
3419 struct netr_LogonGetDomainInfo r;
3420 struct netr_WorkstationInformation q1;
3421 struct netr_Authenticator a;
3422 struct netlogon_creds_CredentialState *creds;
3423 struct netr_OsVersion os;
3424 union netr_WorkstationInfo query;
3425 union netr_DomainInfo info;
3426 const char* const attrs[] = { "dNSHostName", "operatingSystem",
3427 "operatingSystemServicePack", "operatingSystemVersion",
3428 "servicePrincipalName", NULL };
3430 struct ldb_context *sam_ctx = NULL;
3431 struct ldb_message **res;
3432 struct ldb_message_element *spn_el;
3435 const char *old_dnsname = NULL;
3439 struct dcerpc_binding_handle *b = p->binding_handle;
3441 torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
3443 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3444 machine_credentials, &creds)) {
3448 /* We won't double-check this when we are over 'local' transports */
3449 if (dcerpc_server_name(p)) {
3450 /* Set up connection to SAMDB on DC */
3451 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3452 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3454 cmdline_credentials,
3457 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3460 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
3461 netlogon_creds_client_authenticator(creds, &a);
3464 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3465 r.in.computer_name = TEST_MACHINE_NAME;
3466 r.in.credential = &a;
3468 r.in.return_authenticator = &a;
3469 r.in.query = &query;
3470 r.out.return_authenticator = &a;
3474 os.os.MajorVersion = 123;
3475 os.os.MinorVersion = 456;
3476 os.os.BuildNumber = 789;
3477 os.os.CSDVersion = "Service Pack 10";
3478 os.os.ServicePackMajor = 10;
3479 os.os.ServicePackMinor = 1;
3480 os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
3481 os.os.ProductType = NETR_VER_NT_SERVER;
3484 version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
3485 os.os.MinorVersion, os.os.BuildNumber);
3488 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3489 lpcfg_dnsdomain(tctx->lp_ctx));
3490 q1.sitename = "Default-First-Site-Name";
3491 q1.os_version.os = &os;
3492 q1.os_name.string = talloc_asprintf(tctx,
3493 "Tortured by Samba4 RPC-NETLOGON: %s",
3494 timestring(tctx, time(NULL)));
3496 /* The workstation handles the "servicePrincipalName" and DNS hostname
3498 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3500 query.workstation_info = &q1;
3503 /* Gets back the old DNS hostname in AD */
3504 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3505 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3507 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
3509 /* Gets back the "servicePrincipalName"s in AD */
3510 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3511 if (spn_el != NULL) {
3512 for (i=0; i < spn_el->num_values; i++) {
3513 spns = talloc_realloc(tctx, spns, char *, i + 1);
3514 spns[i] = (char *) spn_el->values[i].data;
3520 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3521 "LogonGetDomainInfo failed");
3522 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3523 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3528 /* AD workstation infos entry check */
3529 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3530 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3531 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3532 torture_assert_str_equal(tctx,
3533 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3534 q1.os_name.string, "'operatingSystem' wrong!");
3535 torture_assert_str_equal(tctx,
3536 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
3537 os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
3538 torture_assert_str_equal(tctx,
3539 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
3540 version_str, "'operatingSystemVersion' wrong!");
3542 if (old_dnsname != NULL) {
3543 /* If before a DNS hostname was set then it should remain
3544 the same in combination with the "servicePrincipalName"s.
3545 The DNS hostname should also be returned by our
3546 "LogonGetDomainInfo" call (in the domain info structure). */
3548 torture_assert_str_equal(tctx,
3549 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3550 old_dnsname, "'DNS hostname' was not set!");
3552 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3553 torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
3554 "'servicePrincipalName's not set!");
3555 torture_assert(tctx, spn_el->num_values == num_spns,
3556 "'servicePrincipalName's incorrect!");
3557 for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
3558 torture_assert_str_equal(tctx,
3559 (char *) spn_el->values[i].data,
3560 spns[i], "'servicePrincipalName's incorrect!");
3562 torture_assert_str_equal(tctx,
3563 info.domain_info->dns_hostname.string,
3565 "Out 'DNS hostname' doesn't match the old one!");
3567 /* If no DNS hostname was set then also now none should be set,
3568 the "servicePrincipalName"s should remain empty and no DNS
3569 hostname should be returned by our "LogonGetDomainInfo"
3570 call (in the domain info structure). */
3572 torture_assert(tctx,
3573 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
3574 "'DNS hostname' was set!");
3576 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3577 torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
3578 "'servicePrincipalName's were set!");
3580 torture_assert(tctx,
3581 info.domain_info->dns_hostname.string == NULL,
3582 "Out 'DNS host name' was set!");
3586 /* Checks "workstation flags" */
3587 torture_assert(tctx,
3588 info.domain_info->workstation_flags
3589 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3590 "Out 'workstation flags' don't match!");
3593 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname doesn't work)\n");
3594 netlogon_creds_client_authenticator(creds, &a);
3596 /* Wipe out the osVersion, and prove which values still 'stick' */
3597 q1.os_version.os = NULL;
3599 /* Change also the DNS hostname to test differences in behaviour */
3600 talloc_free(discard_const_p(char, q1.dns_hostname));
3601 q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3602 lpcfg_dnsdomain(tctx->lp_ctx));
3604 /* The workstation handles the "servicePrincipalName" and DNS hostname
3606 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3608 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3609 "LogonGetDomainInfo failed");
3610 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3612 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3617 /* AD workstation infos entry check */
3618 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3619 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3620 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3622 torture_assert_str_equal(tctx,
3623 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3624 q1.os_name.string, "'operatingSystem' should stick!");
3625 torture_assert(tctx,
3626 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3627 "'operatingSystemServicePack' shouldn't stick!");
3628 torture_assert(tctx,
3629 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3630 "'operatingSystemVersion' shouldn't stick!");
3632 /* The DNS host name shouldn't have been updated by the server */
3634 torture_assert_str_equal(tctx,
3635 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3636 old_dnsname, "'DNS host name' did change!");
3638 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3639 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3641 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3642 torture_assert(tctx, spn_el != NULL,
3643 "There should exist 'servicePrincipalName's in AD!");
3644 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3645 for (i=0; i < spn_el->num_values; i++)
3646 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3648 torture_assert(tctx, i != spn_el->num_values,
3649 "'servicePrincipalName' HOST/<Netbios name> not found!");
3650 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3651 for (i=0; i < spn_el->num_values; i++)
3652 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3654 torture_assert(tctx, i != spn_el->num_values,
3655 "'servicePrincipalName' HOST/<FQDN name> not found!");
3657 /* Check that the out DNS hostname was set properly */
3658 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
3659 old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
3662 /* Checks "workstation flags" */
3663 torture_assert(tctx,
3664 info.domain_info->workstation_flags == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3665 "Out 'workstation flags' don't match!");
3668 /* Now try the same but the workstation flags set to 0 */
3670 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (variation of DNS hostname doesn't work)\n");
3671 netlogon_creds_client_authenticator(creds, &a);
3673 /* Change also the DNS hostname to test differences in behaviour */
3674 talloc_free(discard_const_p(char, q1.dns_hostname));
3675 q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3676 lpcfg_dnsdomain(tctx->lp_ctx));
3678 /* Wipe out the osVersion, and prove which values still 'stick' */
3679 q1.os_version.os = NULL;
3681 /* Let the DC handle the "servicePrincipalName" and DNS hostname
3683 q1.workstation_flags = 0;
3685 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3686 "LogonGetDomainInfo failed");
3687 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3688 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3693 /* AD workstation infos entry check */
3694 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3695 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3696 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3698 torture_assert_str_equal(tctx,
3699 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3700 q1.os_name.string, "'operatingSystem' should stick!");
3701 torture_assert(tctx,
3702 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3703 "'operatingSystemServicePack' shouldn't stick!");
3704 torture_assert(tctx,
3705 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3706 "'operatingSystemVersion' shouldn't stick!");
3708 /* The DNS host name shouldn't have been updated by the server */
3710 torture_assert_str_equal(tctx,
3711 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3712 old_dnsname, "'DNS host name' did change!");
3714 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3715 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3717 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3718 torture_assert(tctx, spn_el != NULL,
3719 "There should exist 'servicePrincipalName's in AD!");
3720 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3721 for (i=0; i < spn_el->num_values; i++)
3722 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3724 torture_assert(tctx, i != spn_el->num_values,
3725 "'servicePrincipalName' HOST/<Netbios name> not found!");
3726 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3727 for (i=0; i < spn_el->num_values; i++)
3728 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3730 torture_assert(tctx, i != spn_el->num_values,
3731 "'servicePrincipalName' HOST/<FQDN name> not found!");
3733 /* Here the server gives us NULL as the out DNS hostname */
3734 torture_assert(tctx, info.domain_info->dns_hostname.string == NULL,
3735 "Out 'DNS hostname' should be NULL!");
3738 /* Checks "workstation flags" */
3739 torture_assert(tctx,
3740 info.domain_info->workstation_flags == 0,
3741 "Out 'workstation flags' don't match!");
3744 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (verification of DNS hostname and check for trusted domains)\n");
3745 netlogon_creds_client_authenticator(creds, &a);
3747 /* Put the DNS hostname back */
3748 talloc_free(discard_const_p(char, q1.dns_hostname));
3749 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3750 lpcfg_dnsdomain(tctx->lp_ctx));
3752 /* The workstation handles the "servicePrincipalName" and DNS hostname
3754 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3756 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3757 "LogonGetDomainInfo failed");
3758 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3759 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3763 /* Now the in/out DNS hostnames should be the same */
3764 torture_assert_str_equal(tctx,
3765 info.domain_info->dns_hostname.string,
3766 query.workstation_info->dns_hostname,
3767 "In/Out 'DNS hostnames' don't match!");
3768 old_dnsname = info.domain_info->dns_hostname.string;
3770 /* Checks "workstation flags" */
3771 torture_assert(tctx,
3772 info.domain_info->workstation_flags
3773 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3774 "Out 'workstation flags' don't match!");
3776 /* Checks for trusted domains */
3777 torture_assert(tctx,
3778 (info.domain_info->trusted_domain_count != 0)
3779 && (info.domain_info->trusted_domains != NULL),
3780 "Trusted domains have been requested!");
3783 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 5th call (check for trusted domains)\n");
3784 netlogon_creds_client_authenticator(creds, &a);
3786 /* The workstation handles the "servicePrincipalName" and DNS hostname
3787 updates and requests inbound trusts */
3788 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
3789 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
3791 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3792 "LogonGetDomainInfo failed");
3793 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3794 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3798 /* Checks "workstation flags" */
3799 torture_assert(tctx,
3800 info.domain_info->workstation_flags
3801 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
3802 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
3803 "Out 'workstation flags' don't match!");
3805 /* Checks for trusted domains */
3806 torture_assert(tctx,
3807 (info.domain_info->trusted_domain_count != 0)
3808 && (info.domain_info->trusted_domains != NULL),
3809 "Trusted domains have been requested!");
3812 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
3813 netlogon_creds_client_authenticator(creds, &a);
3815 query.workstation_info->dns_hostname = NULL;
3817 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3818 "LogonGetDomainInfo failed");
3819 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3820 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3822 /* The old DNS hostname should stick */
3823 torture_assert_str_equal(tctx,
3824 info.domain_info->dns_hostname.string,
3826 "'DNS hostname' changed!");
3828 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (extra workstation flags)\n");
3829 netlogon_creds_client_authenticator(creds, &a);
3831 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
3832 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | 0x4;
3834 /* Put the DNS hostname back */
3835 talloc_free(discard_const_p(char, q1.dns_hostname));
3836 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3837 lpcfg_dnsdomain(tctx->lp_ctx));
3839 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3840 "LogonGetDomainInfo failed");
3841 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3842 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3844 /* Checks "workstation flags" */
3845 torture_assert(tctx,
3846 info.domain_info->workstation_flags
3847 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
3848 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
3849 "Out 'workstation flags' don't match!");
3851 if (!torture_setting_bool(tctx, "dangerous", false)) {
3852 torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 8th call (no workstation info) - enable dangerous tests in order to do so\n");
3854 /* Try a call without the workstation information structure */
3856 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 8th call (no workstation info)\n");
3857 netlogon_creds_client_authenticator(creds, &a);
3859 query.workstation_info = NULL;
3861 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3862 "LogonGetDomainInfo failed");
3863 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3864 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3870 static bool test_GetDomainInfo_async(struct torture_context *tctx,
3871 struct dcerpc_pipe *p,
3872 struct cli_credentials *machine_credentials)
3875 struct netr_LogonGetDomainInfo r;
3876 struct netr_WorkstationInformation q1;
3877 struct netr_Authenticator a;
3878 #define ASYNC_COUNT 100
3879 struct netlogon_creds_CredentialState *creds;
3880 struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
3881 struct tevent_req *req[ASYNC_COUNT];
3883 union netr_WorkstationInfo query;
3884 union netr_DomainInfo info;
3886 torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
3888 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3889 machine_credentials, &creds)) {
3894 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3895 r.in.computer_name = TEST_MACHINE_NAME;
3896 r.in.credential = &a;
3898 r.in.return_authenticator = &a;
3899 r.in.query = &query;
3900 r.out.return_authenticator = &a;
3904 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3905 lpcfg_dnsdomain(tctx->lp_ctx));
3906 q1.sitename = "Default-First-Site-Name";
3907 q1.os_name.string = "UNIX/Linux or similar";
3909 query.workstation_info = &q1;
3911 for (i=0;i<ASYNC_COUNT;i++) {
3912 netlogon_creds_client_authenticator(creds, &a);
3914 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
3915 req[i] = dcerpc_netr_LogonGetDomainInfo_r_send(tctx, tctx->ev, p->binding_handle, &r);
3917 /* even with this flush per request a w2k3 server seems to
3918 clag with multiple outstanding requests. bleergh. */
3919 torture_assert_int_equal(tctx, tevent_loop_once(tctx->ev), 0,
3920 "tevent_loop_once failed");
3923 for (i=0;i<ASYNC_COUNT;i++) {
3924 torture_assert_int_equal(tctx, tevent_req_poll(req[i], tctx->ev), true,
3925 "tevent_req_poll() failed");
3927 status = dcerpc_netr_LogonGetDomainInfo_r_recv(req[i], tctx);
3929 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
3930 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
3932 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred),
3933 "Credential chaining failed at async");
3936 torture_comment(tctx,
3937 "Testing netr_LogonGetDomainInfo - async count %d OK\n", ASYNC_COUNT);
3942 static bool test_ManyGetDCName(struct torture_context *tctx,
3943 struct dcerpc_pipe *p)
3946 struct dcerpc_pipe *p2;
3947 struct lsa_ObjectAttribute attr;
3948 struct lsa_QosInfo qos;
3949 struct lsa_OpenPolicy2 o;
3950 struct policy_handle lsa_handle;
3951 struct lsa_DomainList domains;
3953 struct lsa_EnumTrustDom t;
3954 uint32_t resume_handle = 0;
3955 struct netr_GetAnyDCName d;
3956 const char *dcname = NULL;
3957 struct dcerpc_binding_handle *b = p->binding_handle;
3958 struct dcerpc_binding_handle *b2;
3962 if (p->conn->transport.transport != NCACN_NP) {
3966 torture_comment(tctx, "Torturing GetDCName\n");
3968 status = dcerpc_secondary_connection(p, &p2, p->binding);
3969 torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
3971 status = dcerpc_bind_auth_none(p2, &ndr_table_lsarpc);
3972 torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
3973 b2 = p2->binding_handle;
3976 qos.impersonation_level = 2;
3977 qos.context_mode = 1;
3978 qos.effective_only = 0;
3981 attr.root_dir = NULL;
3982 attr.object_name = NULL;
3983 attr.attributes = 0;
3984 attr.sec_desc = NULL;
3985 attr.sec_qos = &qos;
3987 o.in.system_name = "\\";
3989 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3990 o.out.handle = &lsa_handle;
3992 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
3993 "OpenPolicy2 failed");
3994 torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
3996 t.in.handle = &lsa_handle;
3997 t.in.resume_handle = &resume_handle;
3998 t.in.max_size = 1000;
3999 t.out.domains = &domains;
4000 t.out.resume_handle = &resume_handle;
4002 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b2, tctx, &t),
4003 "EnumTrustDom failed");
4005 if ((!NT_STATUS_IS_OK(t.out.result) &&
4006 (!NT_STATUS_EQUAL(t.out.result, NT_STATUS_NO_MORE_ENTRIES))))
4007 torture_fail(tctx, "Could not list domains");
4011 d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
4012 dcerpc_server_name(p));
4013 d.out.dcname = &dcname;
4015 for (i=0; i<domains.count * 4; i++) {
4016 struct lsa_DomainInfo *info =
4017 &domains.domains[rand()%domains.count];
4019 d.in.domainname = info->name.string;
4021 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &d);
4022 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
4024 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
4025 dcname ? dcname : "unknown");
4031 static bool test_SetPassword_with_flags(struct torture_context *tctx,
4032 struct dcerpc_pipe *p,
4033 struct cli_credentials *machine_credentials)
4035 uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
4036 struct netlogon_creds_CredentialState *creds;
4039 if (!test_SetupCredentials2(p, tctx, 0,
4040 machine_credentials,
4041 cli_credentials_get_secure_channel_type(machine_credentials),
4043 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
4046 for (i=0; i < ARRAY_SIZE(flags); i++) {
4047 torture_assert(tctx,
4048 test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
4049 talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
4055 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
4057 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon");
4058 struct torture_rpc_tcase *tcase;
4059 struct torture_test *test;
4061 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
4062 &ndr_table_netlogon, TEST_MACHINE_NAME);
4064 torture_rpc_tcase_add_test(tcase, "Broken RPC binding handle",
4065 test_netr_broken_binding_handle);
4067 torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
4068 torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
4069 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
4070 torture_rpc_tcase_add_test_creds(tcase, "invalidAuthenticate2", test_invalidAuthenticate2);
4071 torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeGlobal", test_ServerReqChallengeGlobal);
4072 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
4073 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
4074 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
4075 torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
4076 torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
4077 torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
4078 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
4079 torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
4080 torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
4081 torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
4082 torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
4083 torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
4084 torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
4085 torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
4086 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
4087 torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
4088 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
4089 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
4090 test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
4091 test->dangerous = true;
4092 torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
4093 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
4094 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
4095 torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
4096 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
4097 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
4098 torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
4099 torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo_AES", test_netr_ServerGetTrustInfo_AES);
4100 torture_rpc_tcase_add_test_creds(tcase, "GetForestTrustInformation", test_netr_GetForestTrustInformation);
4105 struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
4107 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon-s3");
4108 struct torture_rpc_tcase *tcase;
4110 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
4111 &ndr_table_netlogon, TEST_MACHINE_NAME);
4113 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
4114 torture_rpc_tcase_add_test_creds(tcase, "SamLogon_NULL_domain", test_SamLogon_NULL_domain);
4115 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
4116 torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
4117 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
4118 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
4119 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
4124 struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
4126 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon.admin");
4127 struct torture_rpc_tcase *tcase;
4129 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "bdc",
4130 &ndr_table_netlogon, TEST_MACHINE_NAME);
4131 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
4132 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
4133 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
4135 tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "wkst",
4136 &ndr_table_netlogon, TEST_MACHINE_NAME);
4137 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
4138 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
4139 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
4141 tcase = torture_suite_add_rpc_iface_tcase(suite, "admin",
4142 &ndr_table_netlogon);
4143 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
4144 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
4145 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);