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_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx,
206 uint32_t negotiate_flags,
207 struct cli_credentials *machine_credentials,
208 enum netr_SchannelType sec_chan_type,
209 struct netlogon_creds_CredentialState **creds_out)
211 struct netr_ServerReqChallenge r;
212 struct netr_ServerAuthenticate2 a;
213 struct netr_Credential credentials1, credentials2, credentials3;
214 struct netlogon_creds_CredentialState *creds;
215 const struct samr_Password *mach_password;
216 const char *machine_name;
217 struct dcerpc_binding_handle *b = p->binding_handle;
219 mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
220 machine_name = cli_credentials_get_workstation(machine_credentials);
222 torture_comment(tctx, "Testing ServerReqChallenge\n");
225 r.in.server_name = NULL;
226 r.in.computer_name = machine_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 = talloc_asprintf(tctx, "%s$", machine_name);
238 a.in.secure_channel_type = sec_chan_type;
239 a.in.computer_name = machine_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_ok(tctx, a.out.result, "ServerAuthenticate2 failed");
260 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
261 "Credential chaining failed");
263 torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
270 bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx,
271 uint32_t negotiate_flags,
272 struct cli_credentials *machine_credentials,
273 struct netlogon_creds_CredentialState **creds_out)
275 struct netr_ServerReqChallenge r;
276 struct netr_ServerAuthenticate3 a;
277 struct netr_Credential credentials1, credentials2, credentials3;
278 struct netlogon_creds_CredentialState *creds;
279 struct samr_Password mach_password;
281 const char *machine_name;
282 const char *plain_pass;
283 struct dcerpc_binding_handle *b = p->binding_handle;
285 machine_name = cli_credentials_get_workstation(machine_credentials);
286 plain_pass = cli_credentials_get_password(machine_credentials);
288 torture_comment(tctx, "Testing ServerReqChallenge\n");
290 r.in.server_name = NULL;
291 r.in.computer_name = machine_name;
292 r.in.credentials = &credentials1;
293 r.out.return_credentials = &credentials2;
295 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
297 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
298 "ServerReqChallenge failed");
299 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
301 E_md4hash(plain_pass, mach_password.hash);
303 a.in.server_name = NULL;
304 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
305 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
306 a.in.computer_name = machine_name;
307 a.in.negotiate_flags = &negotiate_flags;
308 a.in.credentials = &credentials3;
309 a.out.return_credentials = &credentials3;
310 a.out.negotiate_flags = &negotiate_flags;
313 creds = netlogon_creds_client_init(tctx, a.in.account_name,
315 a.in.secure_channel_type,
316 &credentials1, &credentials2,
317 &mach_password, &credentials3,
320 torture_assert(tctx, creds != NULL, "memory allocation");
322 torture_comment(tctx, "Testing ServerAuthenticate3\n");
324 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
325 "ServerAuthenticate3 failed");
326 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed");
327 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
329 torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
331 /* Prove that requesting a challenge again won't break it */
332 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
333 "ServerReqChallenge failed");
334 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
341 try a change password for our machine account
343 static bool test_SetPassword(struct torture_context *tctx,
344 struct dcerpc_pipe *p,
345 struct cli_credentials *machine_credentials)
347 struct netr_ServerPasswordSet r;
348 const char *password;
349 struct netlogon_creds_CredentialState *creds;
350 struct netr_Authenticator credential, return_authenticator;
351 struct samr_Password new_password;
352 struct dcerpc_binding_handle *b = p->binding_handle;
354 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
358 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
359 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
360 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
361 r.in.computer_name = TEST_MACHINE_NAME;
362 r.in.credential = &credential;
363 r.in.new_password = &new_password;
364 r.out.return_authenticator = &return_authenticator;
366 password = generate_random_password(tctx, 8, 255);
367 E_md4hash(password, new_password.hash);
369 netlogon_creds_des_encrypt(creds, &new_password);
371 torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
372 torture_comment(tctx, "Changing machine account password to '%s'\n",
375 netlogon_creds_client_authenticator(creds, &credential);
377 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
378 "ServerPasswordSet failed");
379 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
381 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
382 torture_comment(tctx, "Credential chaining failed\n");
385 /* by changing the machine password twice we test the
386 credentials chaining fully, and we verify that the server
387 allows the password to be set to the same value twice in a
388 row (match win2k3) */
389 torture_comment(tctx,
390 "Testing a second ServerPasswordSet on machine account\n");
391 torture_comment(tctx,
392 "Changing machine account password to '%s' (same as previous run)\n", password);
394 netlogon_creds_client_authenticator(creds, &credential);
396 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
397 "ServerPasswordSet (2) failed");
398 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
400 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
401 torture_comment(tctx, "Credential chaining failed\n");
404 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
407 test_SetupCredentials(p, tctx, machine_credentials, &creds),
408 "ServerPasswordSet failed to actually change the password");
414 try a change password for our machine account
416 static bool test_SetPassword_flags(struct torture_context *tctx,
417 struct dcerpc_pipe *p,
418 struct cli_credentials *machine_credentials,
419 uint32_t negotiate_flags)
421 struct netr_ServerPasswordSet r;
422 const char *password;
423 struct netlogon_creds_CredentialState *creds;
424 struct netr_Authenticator credential, return_authenticator;
425 struct samr_Password new_password;
426 struct dcerpc_binding_handle *b = p->binding_handle;
428 if (!test_SetupCredentials2(p, tctx, negotiate_flags,
430 cli_credentials_get_secure_channel_type(machine_credentials),
435 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
436 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
437 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
438 r.in.computer_name = TEST_MACHINE_NAME;
439 r.in.credential = &credential;
440 r.in.new_password = &new_password;
441 r.out.return_authenticator = &return_authenticator;
443 password = generate_random_password(tctx, 8, 255);
444 E_md4hash(password, new_password.hash);
446 netlogon_creds_des_encrypt(creds, &new_password);
448 torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
449 torture_comment(tctx, "Changing machine account password to '%s'\n",
452 netlogon_creds_client_authenticator(creds, &credential);
454 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
455 "ServerPasswordSet failed");
456 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
458 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
459 torture_comment(tctx, "Credential chaining failed\n");
462 /* by changing the machine password twice we test the
463 credentials chaining fully, and we verify that the server
464 allows the password to be set to the same value twice in a
465 row (match win2k3) */
466 torture_comment(tctx,
467 "Testing a second ServerPasswordSet on machine account\n");
468 torture_comment(tctx,
469 "Changing machine account password to '%s' (same as previous run)\n", password);
471 netlogon_creds_client_authenticator(creds, &credential);
473 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
474 "ServerPasswordSet (2) failed");
475 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
477 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
478 torture_comment(tctx, "Credential chaining failed\n");
481 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
484 test_SetupCredentials(p, tctx, machine_credentials, &creds),
485 "ServerPasswordSet failed to actually change the password");
492 generate a random password for password change tests
494 static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
497 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
498 generate_random_buffer(password.data, password.length);
500 for (i=0; i < len; i++) {
501 if (((uint16_t *)password.data)[i] == 0) {
502 ((uint16_t *)password.data)[i] = 1;
510 try a change password for our machine account
512 static bool test_SetPassword2_with_flags(struct torture_context *tctx,
513 struct dcerpc_pipe *p,
514 struct cli_credentials *machine_credentials,
517 struct netr_ServerPasswordSet2 r;
518 const char *password;
519 DATA_BLOB new_random_pass;
520 struct netlogon_creds_CredentialState *creds;
521 struct samr_CryptPassword password_buf;
522 struct samr_Password nt_hash;
523 struct netr_Authenticator credential, return_authenticator;
524 struct netr_CryptPassword new_password;
525 struct dcerpc_binding_handle *b = p->binding_handle;
527 if (!test_SetupCredentials2(p, tctx, flags, machine_credentials, cli_credentials_get_secure_channel_type(machine_credentials), &creds)) {
531 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
532 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
533 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
534 r.in.computer_name = TEST_MACHINE_NAME;
535 r.in.credential = &credential;
536 r.in.new_password = &new_password;
537 r.out.return_authenticator = &return_authenticator;
539 password = generate_random_password(tctx, 8, 255);
540 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
541 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
542 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
544 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
547 memcpy(new_password.data, password_buf.data, 512);
548 new_password.length = IVAL(password_buf.data, 512);
550 torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
551 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
553 netlogon_creds_client_authenticator(creds, &credential);
555 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
556 "ServerPasswordSet2 failed");
557 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
559 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
560 torture_comment(tctx, "Credential chaining failed\n");
563 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
565 if (!torture_setting_bool(tctx, "dangerous", false)) {
566 torture_comment(tctx,
567 "Not testing ability to set password to '', enable dangerous tests to perform this test\n");
569 /* by changing the machine password to ""
570 * we check if the server uses password restrictions
571 * for ServerPasswordSet2
572 * (win2k3 accepts "")
575 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
576 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
577 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
579 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
581 memcpy(new_password.data, password_buf.data, 512);
582 new_password.length = IVAL(password_buf.data, 512);
584 torture_comment(tctx,
585 "Testing ServerPasswordSet2 on machine account\n");
586 torture_comment(tctx,
587 "Changing machine account password to '%s'\n", password);
589 netlogon_creds_client_authenticator(creds, &credential);
591 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
592 "ServerPasswordSet2 failed");
593 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
595 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
596 torture_comment(tctx, "Credential chaining failed\n");
599 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
602 torture_assert(tctx, test_SetupCredentials(p, tctx, machine_credentials, &creds),
603 "ServerPasswordSet failed to actually change the password");
605 /* now try a random password */
606 password = generate_random_password(tctx, 8, 255);
607 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
608 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
609 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
611 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
613 memcpy(new_password.data, password_buf.data, 512);
614 new_password.length = IVAL(password_buf.data, 512);
616 torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
617 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
619 netlogon_creds_client_authenticator(creds, &credential);
621 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
622 "ServerPasswordSet2 (2) failed");
623 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 (2) failed");
625 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
626 torture_comment(tctx, "Credential chaining failed\n");
629 /* by changing the machine password twice we test the
630 credentials chaining fully, and we verify that the server
631 allows the password to be set to the same value twice in a
632 row (match win2k3) */
633 torture_comment(tctx,
634 "Testing a second ServerPasswordSet2 on machine account\n");
635 torture_comment(tctx,
636 "Changing machine account password to '%s' (same as previous run)\n", password);
638 netlogon_creds_client_authenticator(creds, &credential);
640 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
641 "ServerPasswordSet (3) failed");
642 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
644 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
645 torture_comment(tctx, "Credential chaining failed\n");
648 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
650 torture_assert (tctx,
651 test_SetupCredentials(p, tctx, machine_credentials, &creds),
652 "ServerPasswordSet failed to actually change the password");
654 new_random_pass = netlogon_very_rand_pass(tctx, 128);
656 /* now try a random stream of bytes for a password */
657 set_pw_in_buffer(password_buf.data, &new_random_pass);
659 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
660 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
662 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
665 memcpy(new_password.data, password_buf.data, 512);
666 new_password.length = IVAL(password_buf.data, 512);
668 torture_comment(tctx,
669 "Testing a third ServerPasswordSet2 on machine account, with a completely random password\n");
671 netlogon_creds_client_authenticator(creds, &credential);
673 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
674 "ServerPasswordSet (3) failed");
675 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
677 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
678 torture_comment(tctx, "Credential chaining failed\n");
681 mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
683 cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
684 cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
686 torture_assert (tctx,
687 test_SetupCredentials(p, tctx, machine_credentials, &creds),
688 "ServerPasswordSet failed to actually change the password");
693 static bool test_SetPassword2(struct torture_context *tctx,
694 struct dcerpc_pipe *p,
695 struct cli_credentials *machine_credentials)
697 return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS);
700 static bool test_SetPassword2_AES(struct torture_context *tctx,
701 struct dcerpc_pipe *p,
702 struct cli_credentials *machine_credentials)
704 return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
707 static bool test_GetPassword(struct torture_context *tctx,
708 struct dcerpc_pipe *p,
709 struct cli_credentials *machine_credentials)
711 struct netr_ServerPasswordGet r;
712 struct netlogon_creds_CredentialState *creds;
713 struct netr_Authenticator credential;
715 struct netr_Authenticator return_authenticator;
716 struct samr_Password password;
717 struct dcerpc_binding_handle *b = p->binding_handle;
719 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
723 netlogon_creds_client_authenticator(creds, &credential);
725 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
726 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
727 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
728 r.in.computer_name = TEST_MACHINE_NAME;
729 r.in.credential = &credential;
730 r.out.return_authenticator = &return_authenticator;
731 r.out.password = &password;
733 status = dcerpc_netr_ServerPasswordGet_r(b, tctx, &r);
734 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
739 static bool test_GetTrustPasswords(struct torture_context *tctx,
740 struct dcerpc_pipe *p,
741 struct cli_credentials *machine_credentials)
743 struct netr_ServerTrustPasswordsGet r;
744 struct netlogon_creds_CredentialState *creds;
745 struct netr_Authenticator credential;
746 struct netr_Authenticator return_authenticator;
747 struct samr_Password password, password2;
748 struct dcerpc_binding_handle *b = p->binding_handle;
750 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
754 netlogon_creds_client_authenticator(creds, &credential);
756 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
757 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
758 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
759 r.in.computer_name = TEST_MACHINE_NAME;
760 r.in.credential = &credential;
761 r.out.return_authenticator = &return_authenticator;
762 r.out.password = &password;
763 r.out.password2 = &password2;
765 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerTrustPasswordsGet_r(b, tctx, &r),
766 "ServerTrustPasswordsGet failed");
767 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerTrustPasswordsGet failed");
773 try a netlogon SamLogon
775 static bool test_netlogon_ops_args(struct dcerpc_pipe *p, struct torture_context *tctx,
776 struct cli_credentials *credentials,
777 struct netlogon_creds_CredentialState *creds,
781 struct netr_LogonSamLogon r;
782 struct netr_Authenticator auth, auth2;
783 static const struct netr_Authenticator auth_zero;
784 union netr_LogonLevel logon;
785 union netr_Validation validation;
786 uint8_t authoritative;
787 struct netr_NetworkInfo ninfo;
788 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
790 struct dcerpc_binding_handle *b = p->binding_handle;
791 int flags = CLI_CRED_NTLM_AUTH;
792 if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
793 flags |= CLI_CRED_LANMAN_AUTH;
796 if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx) && !null_domain) {
797 flags |= CLI_CRED_NTLMv2_AUTH;
800 cli_credentials_get_ntlm_username_domain(cmdline_credentials, tctx,
801 &ninfo.identity_info.account_name.string,
802 &ninfo.identity_info.domain_name.string);
805 ninfo.identity_info.domain_name.string = NULL;
808 generate_random_buffer(ninfo.challenge,
809 sizeof(ninfo.challenge));
810 chal = data_blob_const(ninfo.challenge,
811 sizeof(ninfo.challenge));
813 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials),
814 cli_credentials_get_domain(credentials));
816 status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx,
822 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
824 ninfo.lm.data = lm_resp.data;
825 ninfo.lm.length = lm_resp.length;
827 ninfo.nt.data = nt_resp.data;
828 ninfo.nt.length = nt_resp.length;
830 ninfo.identity_info.parameter_control = 0;
831 ninfo.identity_info.logon_id_low = 0;
832 ninfo.identity_info.logon_id_high = 0;
833 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
835 logon.network = &ninfo;
837 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
838 r.in.computer_name = cli_credentials_get_workstation(credentials);
839 r.in.credential = &auth;
840 r.in.return_authenticator = &auth2;
841 r.in.logon_level = NetlogonNetworkInformation;
843 r.out.validation = &validation;
844 r.out.authoritative = &authoritative;
846 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
850 netlogon_creds_client_authenticator(creds, &auth);
852 r.in.validation_level = i;
854 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
855 "LogonSamLogon failed");
856 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
858 torture_assert(tctx, netlogon_creds_client_check(creds,
859 &r.out.return_authenticator->cred),
860 "Credential chaining failed");
861 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
862 "LogonSamLogon invalid *r.out.authoritative");
865 /* this makes sure we get the unmarshalling right for invalid levels */
866 for (i=52;i<53;i++) {
868 /* the authenticator should be ignored by the server */
869 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
871 r.in.validation_level = i;
873 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
874 "LogonSamLogon failed");
875 torture_assert_ntstatus_equal(tctx, r.out.result,
876 NT_STATUS_INVALID_INFO_CLASS,
877 "LogonSamLogon failed");
879 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
880 "LogonSamLogon invalid *r.out.authoritative");
882 memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
883 "Return authenticator non zero");
888 netlogon_creds_client_authenticator(creds, &auth);
890 r.in.validation_level = i;
892 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
893 "LogonSamLogon failed");
894 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
896 torture_assert(tctx, netlogon_creds_client_check(creds,
897 &r.out.return_authenticator->cred),
898 "Credential chaining failed");
899 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
900 "LogonSamLogon invalid *r.out.authoritative");
903 r.in.logon_level = 52;
907 /* the authenticator should be ignored by the server */
908 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
910 r.in.validation_level = i;
912 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
914 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
915 "LogonSamLogon failed");
916 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
917 "LogonSamLogon expected INVALID_PARAMETER");
920 memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
921 "Return authenticator non zero");
922 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
923 "LogonSamLogon invalid *r.out.authoritative");
926 r.in.credential = NULL;
931 r.in.validation_level = i;
933 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
935 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
936 "LogonSamLogon failed");
937 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
938 "LogonSamLogon expected INVALID_PARAMETER");
941 memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
942 "Return authenticator non zero");
943 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
944 "LogonSamLogon invalid *r.out.authoritative");
947 r.in.logon_level = NetlogonNetworkInformation;
948 r.in.credential = &auth;
952 netlogon_creds_client_authenticator(creds, &auth);
954 r.in.validation_level = i;
956 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
957 "LogonSamLogon failed");
958 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
960 torture_assert(tctx, netlogon_creds_client_check(creds,
961 &r.out.return_authenticator->cred),
962 "Credential chaining failed");
963 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
964 "LogonSamLogon invalid *r.out.authoritative");
970 bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
971 struct cli_credentials *credentials,
972 struct netlogon_creds_CredentialState *creds)
974 return test_netlogon_ops_args(p, tctx, credentials, creds, false);
978 try a netlogon GetCapabilities
980 bool test_netlogon_capabilities(struct dcerpc_pipe *p, struct torture_context *tctx,
981 struct cli_credentials *credentials,
982 struct netlogon_creds_CredentialState *creds)
985 struct netr_LogonGetCapabilities r;
986 union netr_Capabilities capabilities;
987 struct netr_Authenticator auth, return_auth;
988 struct netlogon_creds_CredentialState tmp_creds;
989 struct dcerpc_binding_handle *b = p->binding_handle;
991 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
992 r.in.computer_name = cli_credentials_get_workstation(credentials);
993 r.in.credential = &auth;
994 r.in.return_authenticator = &return_auth;
995 r.in.query_level = 1;
996 r.out.capabilities = &capabilities;
997 r.out.return_authenticator = &return_auth;
999 torture_comment(tctx, "Testing LogonGetCapabilities\n");
1001 ZERO_STRUCT(return_auth);
1004 * we need to operate on a temporary copy of creds
1005 * because dcerpc_netr_LogonGetCapabilities was
1006 * dcerpc_netr_DummyFunction and returns NT_STATUS_NOT_IMPLEMENTED
1007 * without looking a the authenticator.
1010 netlogon_creds_client_authenticator(&tmp_creds, &auth);
1012 status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
1013 torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities failed");
1014 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
1020 torture_assert(tctx, netlogon_creds_client_check(creds,
1021 &r.out.return_authenticator->cred),
1022 "Credential chaining failed");
1024 torture_assert_int_equal(tctx, creds->negotiate_flags,
1025 capabilities.server_capabilities,
1032 try a netlogon SamLogon
1034 static bool test_SamLogon(struct torture_context *tctx,
1035 struct dcerpc_pipe *p,
1036 struct cli_credentials *credentials)
1038 struct netlogon_creds_CredentialState *creds;
1040 if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
1044 return test_netlogon_ops(p, tctx, credentials, creds);
1047 static bool test_SamLogon_NULL_domain(struct torture_context *tctx,
1048 struct dcerpc_pipe *p,
1049 struct cli_credentials *credentials)
1051 struct netlogon_creds_CredentialState *creds;
1053 if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
1057 return test_netlogon_ops_args(p, tctx, credentials, creds, true);
1060 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
1061 static uint64_t sequence_nums[3];
1064 try a netlogon DatabaseSync
1066 static bool test_DatabaseSync(struct torture_context *tctx,
1067 struct dcerpc_pipe *p,
1068 struct cli_credentials *machine_credentials)
1070 struct netr_DatabaseSync r;
1071 struct netlogon_creds_CredentialState *creds;
1072 const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
1074 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1075 struct netr_Authenticator credential, return_authenticator;
1076 struct dcerpc_binding_handle *b = p->binding_handle;
1078 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1082 ZERO_STRUCT(return_authenticator);
1084 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1085 r.in.computername = TEST_MACHINE_NAME;
1086 r.in.preferredmaximumlength = (uint32_t)-1;
1087 r.in.return_authenticator = &return_authenticator;
1088 r.out.delta_enum_array = &delta_enum_array;
1089 r.out.return_authenticator = &return_authenticator;
1091 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1093 uint32_t sync_context = 0;
1095 r.in.database_id = database_ids[i];
1096 r.in.sync_context = &sync_context;
1097 r.out.sync_context = &sync_context;
1099 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
1102 netlogon_creds_client_authenticator(creds, &credential);
1104 r.in.credential = &credential;
1106 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync_r(b, tctx, &r),
1107 "DatabaseSync failed");
1108 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1111 /* Native mode servers don't do this */
1112 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1115 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync");
1117 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1118 torture_comment(tctx, "Credential chaining failed\n");
1121 if (delta_enum_array &&
1122 delta_enum_array->num_deltas > 0 &&
1123 delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
1124 delta_enum_array->delta_enum[0].delta_union.domain) {
1125 sequence_nums[r.in.database_id] =
1126 delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
1127 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
1129 (unsigned long long)sequence_nums[r.in.database_id]);
1131 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1139 try a netlogon DatabaseDeltas
1141 static bool test_DatabaseDeltas(struct torture_context *tctx,
1142 struct dcerpc_pipe *p,
1143 struct cli_credentials *machine_credentials)
1145 struct netr_DatabaseDeltas r;
1146 struct netlogon_creds_CredentialState *creds;
1147 struct netr_Authenticator credential;
1148 struct netr_Authenticator return_authenticator;
1149 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1150 const uint32_t database_ids[] = {0, 1, 2};
1152 struct dcerpc_binding_handle *b = p->binding_handle;
1154 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1158 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1159 r.in.computername = TEST_MACHINE_NAME;
1160 r.in.preferredmaximumlength = (uint32_t)-1;
1161 ZERO_STRUCT(r.in.return_authenticator);
1162 r.out.return_authenticator = &return_authenticator;
1163 r.out.delta_enum_array = &delta_enum_array;
1165 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1166 r.in.database_id = database_ids[i];
1167 r.in.sequence_num = &sequence_nums[r.in.database_id];
1169 if (*r.in.sequence_num == 0) continue;
1171 *r.in.sequence_num -= 1;
1173 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n",
1174 r.in.database_id, (unsigned long long)*r.in.sequence_num);
1177 netlogon_creds_client_authenticator(creds, &credential);
1179 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseDeltas_r(b, tctx, &r),
1180 "DatabaseDeltas failed");
1181 if (NT_STATUS_EQUAL(r.out.result,
1182 NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
1183 torture_comment(tctx, "not considering %s to be an error\n",
1184 nt_errstr(r.out.result));
1187 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1190 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseDeltas");
1192 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1193 torture_comment(tctx, "Credential chaining failed\n");
1196 (*r.in.sequence_num)++;
1197 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1203 static bool test_DatabaseRedo(struct torture_context *tctx,
1204 struct dcerpc_pipe *p,
1205 struct cli_credentials *machine_credentials)
1207 struct netr_DatabaseRedo r;
1208 struct netlogon_creds_CredentialState *creds;
1209 struct netr_Authenticator credential;
1210 struct netr_Authenticator return_authenticator;
1211 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1212 struct netr_ChangeLogEntry e;
1213 struct dom_sid null_sid, *sid;
1215 struct dcerpc_binding_handle *b = p->binding_handle;
1217 ZERO_STRUCT(null_sid);
1219 sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
1230 NTSTATUS expected_error;
1231 uint32_t expected_num_results;
1232 uint8_t expected_delta_type_1;
1233 uint8_t expected_delta_type_2;
1234 const char *comment;
1237 /* SAM_DATABASE_DOMAIN */
1242 .db_index = SAM_DATABASE_DOMAIN,
1243 .delta_type = NETR_DELTA_MODIFY_COUNT,
1246 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1247 .expected_num_results = 0,
1248 .comment = "NETR_DELTA_MODIFY_COUNT"
1253 .db_index = SAM_DATABASE_DOMAIN,
1257 .expected_error = NT_STATUS_OK,
1258 .expected_num_results = 1,
1259 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1260 .comment = "NULL DELTA"
1265 .db_index = SAM_DATABASE_DOMAIN,
1266 .delta_type = NETR_DELTA_DOMAIN,
1269 .expected_error = NT_STATUS_OK,
1270 .expected_num_results = 1,
1271 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1272 .comment = "NETR_DELTA_DOMAIN"
1275 .rid = DOMAIN_RID_ADMINISTRATOR,
1277 .db_index = SAM_DATABASE_DOMAIN,
1278 .delta_type = NETR_DELTA_USER,
1281 .expected_error = NT_STATUS_OK,
1282 .expected_num_results = 1,
1283 .expected_delta_type_1 = NETR_DELTA_USER,
1284 .comment = "NETR_DELTA_USER by rid 500"
1287 .rid = DOMAIN_RID_GUEST,
1289 .db_index = SAM_DATABASE_DOMAIN,
1290 .delta_type = NETR_DELTA_USER,
1293 .expected_error = NT_STATUS_OK,
1294 .expected_num_results = 1,
1295 .expected_delta_type_1 = NETR_DELTA_USER,
1296 .comment = "NETR_DELTA_USER by rid 501"
1300 .flags = NETR_CHANGELOG_SID_INCLUDED,
1301 .db_index = SAM_DATABASE_DOMAIN,
1302 .delta_type = NETR_DELTA_USER,
1305 .expected_error = NT_STATUS_OK,
1306 .expected_num_results = 1,
1307 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1308 .comment = "NETR_DELTA_USER by sid and flags"
1312 .flags = NETR_CHANGELOG_SID_INCLUDED,
1313 .db_index = SAM_DATABASE_DOMAIN,
1314 .delta_type = NETR_DELTA_USER,
1317 .expected_error = NT_STATUS_OK,
1318 .expected_num_results = 1,
1319 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1320 .comment = "NETR_DELTA_USER by null_sid and flags"
1324 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1325 .db_index = SAM_DATABASE_DOMAIN,
1326 .delta_type = NETR_DELTA_USER,
1328 .name = "administrator",
1329 .expected_error = NT_STATUS_OK,
1330 .expected_num_results = 1,
1331 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1332 .comment = "NETR_DELTA_USER by name 'administrator'"
1335 .rid = DOMAIN_RID_ADMINS,
1337 .db_index = SAM_DATABASE_DOMAIN,
1338 .delta_type = NETR_DELTA_GROUP,
1341 .expected_error = NT_STATUS_OK,
1342 .expected_num_results = 2,
1343 .expected_delta_type_1 = NETR_DELTA_GROUP,
1344 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
1345 .comment = "NETR_DELTA_GROUP by rid 512"
1348 .rid = DOMAIN_RID_ADMINS,
1350 .db_index = SAM_DATABASE_DOMAIN,
1351 .delta_type = NETR_DELTA_GROUP_MEMBER,
1354 .expected_error = NT_STATUS_OK,
1355 .expected_num_results = 2,
1356 .expected_delta_type_1 = NETR_DELTA_GROUP,
1357 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
1358 .comment = "NETR_DELTA_GROUP_MEMBER by rid 512"
1362 /* SAM_DATABASE_BUILTIN */
1367 .db_index = SAM_DATABASE_BUILTIN,
1368 .delta_type = NETR_DELTA_MODIFY_COUNT,
1371 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1372 .expected_num_results = 0,
1373 .comment = "NETR_DELTA_MODIFY_COUNT"
1378 .db_index = SAM_DATABASE_BUILTIN,
1379 .delta_type = NETR_DELTA_DOMAIN,
1382 .expected_error = NT_STATUS_OK,
1383 .expected_num_results = 1,
1384 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1385 .comment = "NETR_DELTA_DOMAIN"
1388 .rid = DOMAIN_RID_ADMINISTRATOR,
1390 .db_index = SAM_DATABASE_BUILTIN,
1391 .delta_type = NETR_DELTA_USER,
1394 .expected_error = NT_STATUS_OK,
1395 .expected_num_results = 1,
1396 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1397 .comment = "NETR_DELTA_USER by rid 500"
1402 .db_index = SAM_DATABASE_BUILTIN,
1403 .delta_type = NETR_DELTA_USER,
1406 .expected_error = NT_STATUS_OK,
1407 .expected_num_results = 1,
1408 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1409 .comment = "NETR_DELTA_USER"
1414 .db_index = SAM_DATABASE_BUILTIN,
1415 .delta_type = NETR_DELTA_ALIAS,
1418 .expected_error = NT_STATUS_OK,
1419 .expected_num_results = 2,
1420 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1421 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1422 .comment = "NETR_DELTA_ALIAS by rid 544"
1427 .db_index = SAM_DATABASE_BUILTIN,
1428 .delta_type = NETR_DELTA_ALIAS_MEMBER,
1431 .expected_error = NT_STATUS_OK,
1432 .expected_num_results = 2,
1433 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1434 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1435 .comment = "NETR_DELTA_ALIAS_MEMBER by rid 544"
1440 .db_index = SAM_DATABASE_BUILTIN,
1444 .expected_error = NT_STATUS_OK,
1445 .expected_num_results = 1,
1446 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1447 .comment = "NULL DELTA by rid 544"
1451 .flags = NETR_CHANGELOG_SID_INCLUDED,
1452 .db_index = SAM_DATABASE_BUILTIN,
1454 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1456 .expected_error = NT_STATUS_OK,
1457 .expected_num_results = 1,
1458 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1459 .comment = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
1463 .flags = NETR_CHANGELOG_SID_INCLUDED,
1464 .db_index = SAM_DATABASE_BUILTIN,
1465 .delta_type = NETR_DELTA_ALIAS,
1466 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1468 .expected_error = NT_STATUS_OK,
1469 .expected_num_results = 2,
1470 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1471 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1472 .comment = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
1476 .flags = NETR_CHANGELOG_SID_INCLUDED,
1477 .db_index = SAM_DATABASE_BUILTIN,
1478 .delta_type = NETR_DELTA_ALIAS,
1479 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1481 .expected_error = NT_STATUS_OK,
1482 .expected_num_results = 1,
1483 .expected_delta_type_1 = NETR_DELTA_DELETE_ALIAS,
1484 .comment = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
1487 /* SAM_DATABASE_PRIVS */
1492 .db_index = SAM_DATABASE_PRIVS,
1496 .expected_error = NT_STATUS_ACCESS_DENIED,
1497 .expected_num_results = 0,
1498 .comment = "NULL DELTA"
1503 .db_index = SAM_DATABASE_PRIVS,
1504 .delta_type = NETR_DELTA_MODIFY_COUNT,
1507 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1508 .expected_num_results = 0,
1509 .comment = "NETR_DELTA_MODIFY_COUNT"
1514 .db_index = SAM_DATABASE_PRIVS,
1515 .delta_type = NETR_DELTA_POLICY,
1518 .expected_error = NT_STATUS_OK,
1519 .expected_num_results = 1,
1520 .expected_delta_type_1 = NETR_DELTA_POLICY,
1521 .comment = "NETR_DELTA_POLICY"
1525 .flags = NETR_CHANGELOG_SID_INCLUDED,
1526 .db_index = SAM_DATABASE_PRIVS,
1527 .delta_type = NETR_DELTA_POLICY,
1530 .expected_error = NT_STATUS_OK,
1531 .expected_num_results = 1,
1532 .expected_delta_type_1 = NETR_DELTA_POLICY,
1533 .comment = "NETR_DELTA_POLICY by null sid and flags"
1537 .flags = NETR_CHANGELOG_SID_INCLUDED,
1538 .db_index = SAM_DATABASE_PRIVS,
1539 .delta_type = NETR_DELTA_POLICY,
1540 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
1542 .expected_error = NT_STATUS_OK,
1543 .expected_num_results = 1,
1544 .expected_delta_type_1 = NETR_DELTA_POLICY,
1545 .comment = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
1548 .rid = DOMAIN_RID_ADMINISTRATOR,
1550 .db_index = SAM_DATABASE_PRIVS,
1551 .delta_type = NETR_DELTA_ACCOUNT,
1554 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
1555 .expected_num_results = 0,
1556 .comment = "NETR_DELTA_ACCOUNT by rid 500"
1560 .flags = NETR_CHANGELOG_SID_INCLUDED,
1561 .db_index = SAM_DATABASE_PRIVS,
1562 .delta_type = NETR_DELTA_ACCOUNT,
1563 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1565 .expected_error = NT_STATUS_OK,
1566 .expected_num_results = 1,
1567 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
1568 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
1572 .flags = NETR_CHANGELOG_SID_INCLUDED |
1573 NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
1574 .db_index = SAM_DATABASE_PRIVS,
1575 .delta_type = NETR_DELTA_ACCOUNT,
1576 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1578 .expected_error = NT_STATUS_OK,
1579 .expected_num_results = 1,
1580 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
1581 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
1585 .flags = NETR_CHANGELOG_SID_INCLUDED |
1586 NETR_CHANGELOG_NAME_INCLUDED,
1587 .db_index = SAM_DATABASE_PRIVS,
1588 .delta_type = NETR_DELTA_ACCOUNT,
1589 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1591 .expected_error = NT_STATUS_INVALID_PARAMETER,
1592 .expected_num_results = 0,
1593 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
1596 .rid = DOMAIN_RID_ADMINISTRATOR,
1597 .flags = NETR_CHANGELOG_SID_INCLUDED,
1598 .db_index = SAM_DATABASE_PRIVS,
1599 .delta_type = NETR_DELTA_ACCOUNT,
1602 .expected_error = NT_STATUS_OK,
1603 .expected_num_results = 1,
1604 .expected_delta_type_1 = NETR_DELTA_DELETE_ACCOUNT,
1605 .comment = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
1609 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1610 .db_index = SAM_DATABASE_PRIVS,
1611 .delta_type = NETR_DELTA_SECRET,
1613 .name = "IsurelydontexistIhope",
1614 .expected_error = NT_STATUS_OK,
1615 .expected_num_results = 1,
1616 .expected_delta_type_1 = NETR_DELTA_DELETE_SECRET,
1617 .comment = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
1621 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1622 .db_index = SAM_DATABASE_PRIVS,
1623 .delta_type = NETR_DELTA_SECRET,
1625 .name = "G$BCKUPKEY_P",
1626 .expected_error = NT_STATUS_OK,
1627 .expected_num_results = 1,
1628 .expected_delta_type_1 = NETR_DELTA_SECRET,
1629 .comment = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
1633 ZERO_STRUCT(return_authenticator);
1635 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1636 r.in.computername = TEST_MACHINE_NAME;
1637 r.in.return_authenticator = &return_authenticator;
1638 r.out.return_authenticator = &return_authenticator;
1639 r.out.delta_enum_array = &delta_enum_array;
1641 for (d=0; d<3; d++) {
1642 const char *database = NULL;
1649 database = "BUILTIN";
1658 torture_comment(tctx, "Testing DatabaseRedo\n");
1660 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1664 for (i=0;i<ARRAY_SIZE(changes);i++) {
1666 if (d != changes[i].db_index) {
1670 netlogon_creds_client_authenticator(creds, &credential);
1672 r.in.credential = &credential;
1674 e.serial_number1 = 0;
1675 e.serial_number2 = 0;
1676 e.object_rid = changes[i].rid;
1677 e.flags = changes[i].flags;
1678 e.db_index = changes[i].db_index;
1679 e.delta_type = changes[i].delta_type;
1681 switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
1682 case NETR_CHANGELOG_SID_INCLUDED:
1683 e.object.object_sid = changes[i].sid;
1685 case NETR_CHANGELOG_NAME_INCLUDED:
1686 e.object.object_name = changes[i].name;
1692 r.in.change_log_entry = e;
1694 torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
1695 database, changes[i].comment);
1697 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseRedo_r(b, tctx, &r),
1698 "DatabaseRedo failed");
1699 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1703 torture_assert_ntstatus_equal(tctx, r.out.result, changes[i].expected_error, changes[i].comment);
1704 if (delta_enum_array) {
1705 torture_assert_int_equal(tctx,
1706 delta_enum_array->num_deltas,
1707 changes[i].expected_num_results,
1708 changes[i].comment);
1709 if (delta_enum_array->num_deltas > 0) {
1710 torture_assert_int_equal(tctx,
1711 delta_enum_array->delta_enum[0].delta_type,
1712 changes[i].expected_delta_type_1,
1713 changes[i].comment);
1715 if (delta_enum_array->num_deltas > 1) {
1716 torture_assert_int_equal(tctx,
1717 delta_enum_array->delta_enum[1].delta_type,
1718 changes[i].expected_delta_type_2,
1719 changes[i].comment);
1723 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1724 torture_comment(tctx, "Credential chaining failed\n");
1725 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1737 try a netlogon AccountDeltas
1739 static bool test_AccountDeltas(struct torture_context *tctx,
1740 struct dcerpc_pipe *p,
1741 struct cli_credentials *machine_credentials)
1743 struct netr_AccountDeltas r;
1744 struct netlogon_creds_CredentialState *creds;
1746 struct netr_AccountBuffer buffer;
1747 uint32_t count_returned = 0;
1748 uint32_t total_entries = 0;
1749 struct netr_UAS_INFO_0 recordid;
1750 struct netr_Authenticator return_authenticator;
1751 struct dcerpc_binding_handle *b = p->binding_handle;
1753 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1757 ZERO_STRUCT(return_authenticator);
1759 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1760 r.in.computername = TEST_MACHINE_NAME;
1761 r.in.return_authenticator = &return_authenticator;
1762 netlogon_creds_client_authenticator(creds, &r.in.credential);
1763 ZERO_STRUCT(r.in.uas);
1766 r.in.buffersize=100;
1767 r.out.buffer = &buffer;
1768 r.out.count_returned = &count_returned;
1769 r.out.total_entries = &total_entries;
1770 r.out.recordid = &recordid;
1771 r.out.return_authenticator = &return_authenticator;
1773 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1774 torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountDeltas_r(b, tctx, &r),
1775 "AccountDeltas failed");
1776 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
1782 try a netlogon AccountSync
1784 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
1785 struct cli_credentials *machine_credentials)
1787 struct netr_AccountSync r;
1788 struct netlogon_creds_CredentialState *creds;
1790 struct netr_AccountBuffer buffer;
1791 uint32_t count_returned = 0;
1792 uint32_t total_entries = 0;
1793 uint32_t next_reference = 0;
1794 struct netr_UAS_INFO_0 recordid;
1795 struct netr_Authenticator return_authenticator;
1796 struct dcerpc_binding_handle *b = p->binding_handle;
1798 ZERO_STRUCT(recordid);
1799 ZERO_STRUCT(return_authenticator);
1801 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1805 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1806 r.in.computername = TEST_MACHINE_NAME;
1807 r.in.return_authenticator = &return_authenticator;
1808 netlogon_creds_client_authenticator(creds, &r.in.credential);
1809 r.in.recordid = &recordid;
1812 r.in.buffersize=100;
1813 r.out.buffer = &buffer;
1814 r.out.count_returned = &count_returned;
1815 r.out.total_entries = &total_entries;
1816 r.out.next_reference = &next_reference;
1817 r.out.recordid = &recordid;
1818 r.out.return_authenticator = &return_authenticator;
1820 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1821 torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountSync_r(b, tctx, &r),
1822 "AccountSync failed");
1823 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
1829 try a netlogon GetDcName
1831 static bool test_GetDcName(struct torture_context *tctx,
1832 struct dcerpc_pipe *p)
1834 struct netr_GetDcName r;
1835 const char *dcname = NULL;
1836 struct dcerpc_binding_handle *b = p->binding_handle;
1838 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1839 r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
1840 r.out.dcname = &dcname;
1842 torture_assert_ntstatus_ok(tctx, dcerpc_netr_GetDcName_r(b, tctx, &r),
1843 "GetDcName failed");
1844 torture_assert_werr_ok(tctx, r.out.result, "GetDcName failed");
1846 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1851 static const char *function_code_str(TALLOC_CTX *mem_ctx,
1852 enum netr_LogonControlCode function_code)
1854 switch (function_code) {
1855 case NETLOGON_CONTROL_QUERY:
1856 return "NETLOGON_CONTROL_QUERY";
1857 case NETLOGON_CONTROL_REPLICATE:
1858 return "NETLOGON_CONTROL_REPLICATE";
1859 case NETLOGON_CONTROL_SYNCHRONIZE:
1860 return "NETLOGON_CONTROL_SYNCHRONIZE";
1861 case NETLOGON_CONTROL_PDC_REPLICATE:
1862 return "NETLOGON_CONTROL_PDC_REPLICATE";
1863 case NETLOGON_CONTROL_REDISCOVER:
1864 return "NETLOGON_CONTROL_REDISCOVER";
1865 case NETLOGON_CONTROL_TC_QUERY:
1866 return "NETLOGON_CONTROL_TC_QUERY";
1867 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1868 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
1869 case NETLOGON_CONTROL_FIND_USER:
1870 return "NETLOGON_CONTROL_FIND_USER";
1871 case NETLOGON_CONTROL_CHANGE_PASSWORD:
1872 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
1873 case NETLOGON_CONTROL_TC_VERIFY:
1874 return "NETLOGON_CONTROL_TC_VERIFY";
1875 case NETLOGON_CONTROL_FORCE_DNS_REG:
1876 return "NETLOGON_CONTROL_FORCE_DNS_REG";
1877 case NETLOGON_CONTROL_QUERY_DNS_REG:
1878 return "NETLOGON_CONTROL_QUERY_DNS_REG";
1879 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1880 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
1881 case NETLOGON_CONTROL_TRUNCATE_LOG:
1882 return "NETLOGON_CONTROL_TRUNCATE_LOG";
1883 case NETLOGON_CONTROL_SET_DBFLAG:
1884 return "NETLOGON_CONTROL_SET_DBFLAG";
1885 case NETLOGON_CONTROL_BREAKPOINT:
1886 return "NETLOGON_CONTROL_BREAKPOINT";
1888 return talloc_asprintf(mem_ctx, "unknown function code: %d",
1895 try a netlogon LogonControl
1897 static bool test_LogonControl(struct torture_context *tctx,
1898 struct dcerpc_pipe *p,
1899 struct cli_credentials *machine_credentials)
1903 struct netr_LogonControl r;
1904 union netr_CONTROL_QUERY_INFORMATION query;
1906 enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
1907 struct dcerpc_binding_handle *b = p->binding_handle;
1909 uint32_t function_codes[] = {
1910 NETLOGON_CONTROL_QUERY,
1911 NETLOGON_CONTROL_REPLICATE,
1912 NETLOGON_CONTROL_SYNCHRONIZE,
1913 NETLOGON_CONTROL_PDC_REPLICATE,
1914 NETLOGON_CONTROL_REDISCOVER,
1915 NETLOGON_CONTROL_TC_QUERY,
1916 NETLOGON_CONTROL_TRANSPORT_NOTIFY,
1917 NETLOGON_CONTROL_FIND_USER,
1918 NETLOGON_CONTROL_CHANGE_PASSWORD,
1919 NETLOGON_CONTROL_TC_VERIFY,
1920 NETLOGON_CONTROL_FORCE_DNS_REG,
1921 NETLOGON_CONTROL_QUERY_DNS_REG,
1922 NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
1923 NETLOGON_CONTROL_TRUNCATE_LOG,
1924 NETLOGON_CONTROL_SET_DBFLAG,
1925 NETLOGON_CONTROL_BREAKPOINT
1928 if (machine_credentials) {
1929 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1932 torture_comment(tctx, "Testing LogonControl with secure channel type: %d\n",
1933 secure_channel_type);
1935 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1936 r.in.function_code = 1;
1937 r.out.query = &query;
1939 for (f=0;f<ARRAY_SIZE(function_codes); f++) {
1942 r.in.function_code = function_codes[f];
1945 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
1946 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1948 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
1949 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1951 switch (r.in.level) {
1953 switch (r.in.function_code) {
1954 case NETLOGON_CONTROL_REPLICATE:
1955 case NETLOGON_CONTROL_SYNCHRONIZE:
1956 case NETLOGON_CONTROL_PDC_REPLICATE:
1957 case NETLOGON_CONTROL_BREAKPOINT:
1958 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1959 if ((secure_channel_type == SEC_CHAN_BDC) ||
1960 (secure_channel_type == SEC_CHAN_WKSTA)) {
1961 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1962 "LogonControl returned unexpected error code");
1964 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1965 "LogonControl returned unexpected error code");
1969 case NETLOGON_CONTROL_REDISCOVER:
1970 case NETLOGON_CONTROL_TC_QUERY:
1971 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1972 case NETLOGON_CONTROL_FIND_USER:
1973 case NETLOGON_CONTROL_CHANGE_PASSWORD:
1974 case NETLOGON_CONTROL_TC_VERIFY:
1975 case NETLOGON_CONTROL_FORCE_DNS_REG:
1976 case NETLOGON_CONTROL_QUERY_DNS_REG:
1977 case NETLOGON_CONTROL_SET_DBFLAG:
1978 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1979 "LogonControl returned unexpected error code");
1981 case NETLOGON_CONTROL_TRUNCATE_LOG:
1982 if ((secure_channel_type == SEC_CHAN_BDC) ||
1983 (secure_channel_type == SEC_CHAN_WKSTA)) {
1984 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1985 "LogonControl returned unexpected error code");
1987 torture_assert_werr_ok(tctx, r.out.result,
1988 "LogonControl returned unexpected result");
1992 torture_assert_werr_ok(tctx, r.out.result,
1993 "LogonControl returned unexpected result");
1998 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1999 "LogonControl returned unexpected error code");
2002 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL,
2003 "LogonControl returned unexpected error code");
2010 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
2011 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2012 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
2013 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2014 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl");
2021 try a netlogon GetAnyDCName
2023 static bool test_GetAnyDCName(struct torture_context *tctx,
2024 struct dcerpc_pipe *p)
2027 struct netr_GetAnyDCName r;
2028 const char *dcname = NULL;
2029 struct dcerpc_binding_handle *b = p->binding_handle;
2031 r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
2032 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2033 r.out.dcname = &dcname;
2035 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2036 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2037 if ((!W_ERROR_IS_OK(r.out.result)) &&
2038 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2043 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
2046 r.in.domainname = NULL;
2048 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2049 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2050 if ((!W_ERROR_IS_OK(r.out.result)) &&
2051 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2055 r.in.domainname = "";
2057 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2058 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2059 if ((!W_ERROR_IS_OK(r.out.result)) &&
2060 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2069 try a netlogon LogonControl2
2071 static bool test_LogonControl2(struct torture_context *tctx,
2072 struct dcerpc_pipe *p,
2073 struct cli_credentials *machine_credentials)
2077 struct netr_LogonControl2 r;
2078 union netr_CONTROL_DATA_INFORMATION data;
2079 union netr_CONTROL_QUERY_INFORMATION query;
2081 struct dcerpc_binding_handle *b = p->binding_handle;
2083 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2085 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2087 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2089 r.out.query = &query;
2094 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2095 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2097 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2098 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2101 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2103 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2109 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2110 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2112 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2113 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2116 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2118 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2124 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2125 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2127 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2128 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2131 data.debug_level = ~0;
2133 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2139 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2140 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2142 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2143 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2147 r.in.function_code = 52;
2150 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2151 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2153 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2154 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2155 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "LogonControl2");
2157 data.debug_level = ~0;
2159 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2163 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2164 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2166 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2167 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2168 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "LogonControl2");
2174 try a netlogon DatabaseSync2
2176 static bool test_DatabaseSync2(struct torture_context *tctx,
2177 struct dcerpc_pipe *p,
2178 struct cli_credentials *machine_credentials)
2180 struct netr_DatabaseSync2 r;
2181 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2182 struct netr_Authenticator return_authenticator, credential;
2184 struct netlogon_creds_CredentialState *creds;
2185 const uint32_t database_ids[] = {0, 1, 2};
2187 struct dcerpc_binding_handle *b = p->binding_handle;
2189 if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
2190 machine_credentials,
2191 cli_credentials_get_secure_channel_type(machine_credentials),
2196 ZERO_STRUCT(return_authenticator);
2198 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2199 r.in.computername = TEST_MACHINE_NAME;
2200 r.in.preferredmaximumlength = (uint32_t)-1;
2201 r.in.return_authenticator = &return_authenticator;
2202 r.out.return_authenticator = &return_authenticator;
2203 r.out.delta_enum_array = &delta_enum_array;
2205 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2207 uint32_t sync_context = 0;
2209 r.in.database_id = database_ids[i];
2210 r.in.sync_context = &sync_context;
2211 r.out.sync_context = &sync_context;
2212 r.in.restart_state = 0;
2214 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
2217 netlogon_creds_client_authenticator(creds, &credential);
2219 r.in.credential = &credential;
2221 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync2_r(b, tctx, &r),
2222 "DatabaseSync2 failed");
2223 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2226 /* Native mode servers don't do this */
2227 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
2231 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync2");
2233 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
2234 torture_comment(tctx, "Credential chaining failed\n");
2237 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2245 try a netlogon LogonControl2Ex
2247 static bool test_LogonControl2Ex(struct torture_context *tctx,
2248 struct dcerpc_pipe *p,
2249 struct cli_credentials *machine_credentials)
2253 struct netr_LogonControl2Ex r;
2254 union netr_CONTROL_DATA_INFORMATION data;
2255 union netr_CONTROL_QUERY_INFORMATION query;
2257 struct dcerpc_binding_handle *b = p->binding_handle;
2259 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2261 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2263 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2265 r.out.query = &query;
2270 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2271 i, r.in.function_code);
2273 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2274 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2277 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2279 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2285 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2286 i, r.in.function_code);
2288 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2289 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2292 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2294 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2300 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2301 i, r.in.function_code);
2303 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2304 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2307 data.debug_level = ~0;
2309 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2315 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2316 i, r.in.function_code);
2318 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2319 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2325 static bool test_netr_GetForestTrustInformation(struct torture_context *tctx,
2326 struct dcerpc_pipe *p,
2327 struct cli_credentials *machine_credentials)
2329 struct netr_GetForestTrustInformation r;
2330 struct netlogon_creds_CredentialState *creds;
2331 struct netr_Authenticator a;
2332 struct netr_Authenticator return_authenticator;
2333 struct lsa_ForestTrustInformation *forest_trust_info;
2334 struct dcerpc_binding_handle *b = p->binding_handle;
2336 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2337 machine_credentials, &creds)) {
2341 netlogon_creds_client_authenticator(creds, &a);
2343 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2344 r.in.computer_name = TEST_MACHINE_NAME;
2345 r.in.credential = &a;
2347 r.out.return_authenticator = &return_authenticator;
2348 r.out.forest_trust_info = &forest_trust_info;
2350 torture_assert_ntstatus_ok(tctx,
2351 dcerpc_netr_GetForestTrustInformation_r(b, tctx, &r),
2352 "netr_GetForestTrustInformation failed");
2353 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2354 torture_comment(tctx, "not considering NT_STATUS_NOT_IMPLEMENTED as an error\n");
2356 torture_assert_ntstatus_ok(tctx, r.out.result,
2357 "netr_GetForestTrustInformation failed");
2360 torture_assert(tctx,
2361 netlogon_creds_client_check(creds, &return_authenticator.cred),
2362 "Credential chaining failed");
2367 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
2368 struct dcerpc_pipe *p, const char *trusted_domain_name)
2371 struct netr_DsRGetForestTrustInformation r;
2372 struct lsa_ForestTrustInformation info, *info_ptr;
2373 struct dcerpc_binding_handle *b = p->binding_handle;
2377 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2378 r.in.trusted_domain_name = trusted_domain_name;
2380 r.out.forest_trust_info = &info_ptr;
2382 torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
2384 status = dcerpc_netr_DsRGetForestTrustInformation_r(b, tctx, &r);
2385 torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
2386 torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
2392 try a netlogon netr_DsrEnumerateDomainTrusts
2394 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
2395 struct dcerpc_pipe *p)
2398 struct netr_DsrEnumerateDomainTrusts r;
2399 struct netr_DomainTrustList trusts;
2401 struct dcerpc_binding_handle *b = p->binding_handle;
2403 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2404 r.in.trust_flags = 0x3f;
2405 r.out.trusts = &trusts;
2407 status = dcerpc_netr_DsrEnumerateDomainTrusts_r(b, tctx, &r);
2408 torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
2409 torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
2411 /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
2412 * will show non-forest trusts and all UPN suffixes of the own forest
2413 * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
2415 if (r.out.trusts->count) {
2416 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
2421 for (i=0; i<r.out.trusts->count; i++) {
2423 /* get info for transitive forest trusts */
2425 if (r.out.trusts->array[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2426 if (!test_netr_DsRGetForestTrustInformation(tctx, p,
2427 r.out.trusts->array[i].dns_name)) {
2436 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
2437 struct dcerpc_pipe *p)
2440 struct netr_NetrEnumerateTrustedDomains r;
2441 struct netr_Blob trusted_domains_blob;
2442 struct dcerpc_binding_handle *b = p->binding_handle;
2444 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2445 r.out.trusted_domains_blob = &trusted_domains_blob;
2447 status = dcerpc_netr_NetrEnumerateTrustedDomains_r(b, tctx, &r);
2448 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
2449 torture_assert_ntstatus_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
2454 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
2455 struct dcerpc_pipe *p)
2458 struct netr_NetrEnumerateTrustedDomainsEx r;
2459 struct netr_DomainTrustList dom_trust_list;
2460 struct dcerpc_binding_handle *b = p->binding_handle;
2462 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2463 r.out.dom_trust_list = &dom_trust_list;
2465 status = dcerpc_netr_NetrEnumerateTrustedDomainsEx_r(b, tctx, &r);
2466 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
2467 torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
2473 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
2474 const char *computer_name,
2475 const char *expected_site)
2478 struct netr_DsRGetSiteName r;
2479 const char *site = NULL;
2480 struct dcerpc_binding_handle *b = p->binding_handle;
2482 r.in.computer_name = computer_name;
2484 torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
2486 status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
2487 torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2488 torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
2489 torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
2495 try a netlogon netr_DsRGetDCName
2497 static bool test_netr_DsRGetDCName(struct torture_context *tctx,
2498 struct dcerpc_pipe *p)
2501 struct netr_DsRGetDCName r;
2502 struct netr_DsRGetDCNameInfo *info = NULL;
2503 struct dcerpc_binding_handle *b = p->binding_handle;
2505 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2506 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
2507 r.in.domain_guid = NULL;
2508 r.in.site_guid = NULL;
2509 r.in.flags = DS_RETURN_DNS_NAME;
2512 status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2513 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2514 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2516 torture_assert_int_equal(tctx,
2517 (info->dc_flags & (DS_DNS_CONTROLLER)),
2520 torture_assert_int_equal(tctx,
2521 (info->dc_flags & (DS_DNS_DOMAIN)),
2524 torture_assert_int_equal(tctx,
2525 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2529 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
2532 status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2533 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2534 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2536 torture_assert_int_equal(tctx,
2537 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2539 torture_assert_int_equal(tctx,
2540 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2542 torture_assert_int_equal(tctx,
2543 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2547 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2548 torture_assert_int_equal(tctx,
2549 (info->dc_flags & (DS_SERVER_CLOSEST)),
2554 return test_netr_DsRGetSiteName(p, tctx,
2556 info->dc_site_name);
2560 try a netlogon netr_DsRGetDCNameEx
2562 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
2563 struct dcerpc_pipe *p)
2566 struct netr_DsRGetDCNameEx r;
2567 struct netr_DsRGetDCNameInfo *info = NULL;
2568 struct dcerpc_binding_handle *b = p->binding_handle;
2570 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2571 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
2572 r.in.domain_guid = NULL;
2573 r.in.site_name = NULL;
2574 r.in.flags = DS_RETURN_DNS_NAME;
2577 status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2578 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2579 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2581 torture_assert_int_equal(tctx,
2582 (info->dc_flags & (DS_DNS_CONTROLLER)),
2585 torture_assert_int_equal(tctx,
2586 (info->dc_flags & (DS_DNS_DOMAIN)),
2589 torture_assert_int_equal(tctx,
2590 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2594 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
2597 status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2598 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2599 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2601 torture_assert_int_equal(tctx,
2602 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2604 torture_assert_int_equal(tctx,
2605 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2607 torture_assert_int_equal(tctx,
2608 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2612 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2613 torture_assert_int_equal(tctx,
2614 (info->dc_flags & (DS_SERVER_CLOSEST)),
2619 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2620 info->dc_site_name);
2624 try a netlogon netr_DsRGetDCNameEx2
2626 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
2627 struct dcerpc_pipe *p)
2630 struct netr_DsRGetDCNameEx2 r;
2631 struct netr_DsRGetDCNameInfo *info = NULL;
2632 struct dcerpc_binding_handle *b = p->binding_handle;
2634 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with no inputs\n");
2636 r.in.flags = DS_RETURN_DNS_NAME;
2639 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2640 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2641 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2643 torture_assert_int_equal(tctx,
2644 (info->dc_flags & (DS_DNS_CONTROLLER)),
2647 torture_assert_int_equal(tctx,
2648 (info->dc_flags & (DS_DNS_DOMAIN)),
2651 torture_assert_int_equal(tctx,
2652 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2656 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2657 r.in.client_account = NULL;
2658 r.in.mask = 0x00000000;
2659 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
2660 r.in.domain_guid = NULL;
2661 r.in.site_name = NULL;
2662 r.in.flags = DS_RETURN_DNS_NAME;
2665 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
2667 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2668 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2669 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2671 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
2674 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2675 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2676 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2678 torture_assert_int_equal(tctx,
2679 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2681 torture_assert_int_equal(tctx,
2682 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2684 torture_assert_int_equal(tctx,
2685 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2689 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2690 torture_assert_int_equal(tctx,
2691 (info->dc_flags & (DS_SERVER_CLOSEST)),
2696 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client account\n");
2697 r.in.client_account = TEST_MACHINE_NAME"$";
2698 r.in.mask = ACB_SVRTRUST;
2699 r.in.flags = DS_RETURN_FLAT_NAME;
2702 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2703 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2704 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2706 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2707 info->dc_site_name);
2710 /* This is a substitution for "samdb_server_site_name" which relies on the
2711 * correct "lp_ctx" and therefore can't be used here. */
2712 static const char *server_site_name(struct torture_context *tctx,
2713 struct ldb_context *ldb)
2715 TALLOC_CTX *tmp_ctx;
2716 struct ldb_dn *dn, *server_dn;
2717 const struct ldb_val *site_name_val;
2718 const char *server_dn_str, *site_name;
2720 tmp_ctx = talloc_new(ldb);
2721 if (tmp_ctx == NULL) {
2725 dn = ldb_dn_new(tmp_ctx, ldb, "");
2730 server_dn_str = samdb_search_string(ldb, tmp_ctx, dn, "serverName",
2732 if (server_dn_str == NULL) {
2736 server_dn = ldb_dn_new(tmp_ctx, ldb, server_dn_str);
2737 if (server_dn == NULL) {
2741 /* CN=<Server name>, CN=Servers, CN=<Site name>, CN=Sites, ... */
2742 site_name_val = ldb_dn_get_component_val(server_dn, 2);
2743 if (site_name_val == NULL) {
2747 site_name = (const char *) site_name_val->data;
2749 talloc_steal(tctx, site_name);
2750 talloc_free(tmp_ctx);
2755 talloc_free(tmp_ctx);
2759 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
2760 struct dcerpc_pipe *p)
2763 struct ldb_context *sam_ctx = NULL;
2765 struct netr_DsrGetDcSiteCoverageW r;
2766 struct DcSitesCtr *ctr = NULL;
2767 struct dcerpc_binding_handle *b = p->binding_handle;
2769 torture_comment(tctx, "This does only pass with the default site\n");
2771 /* We won't double-check this when we are over 'local' transports */
2772 if (dcerpc_server_name(p)) {
2773 /* Set up connection to SAMDB on DC */
2774 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2775 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2777 cmdline_credentials,
2780 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2783 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2786 status = dcerpc_netr_DsrGetDcSiteCoverageW_r(b, tctx, &r);
2787 torture_assert_ntstatus_ok(tctx, status, "failed");
2788 torture_assert_werr_ok(tctx, r.out.result, "failed");
2790 torture_assert(tctx, ctr->num_sites == 1,
2791 "we should per default only get the default site");
2792 if (sam_ctx != NULL) {
2793 torture_assert_casestr_equal(tctx, ctr->sites[0].string,
2794 server_site_name(tctx, sam_ctx),
2795 "didn't return default site");
2801 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
2802 struct dcerpc_pipe *p)
2805 struct ldb_context *sam_ctx = NULL;
2807 struct netr_DsRAddressToSitenamesW r;
2808 struct netr_DsRAddress addrs[6];
2809 struct sockaddr_in *addr;
2811 struct sockaddr_in6 *addr6;
2813 struct netr_DsRAddressToSitenamesWCtr *ctr;
2814 struct dcerpc_binding_handle *b = p->binding_handle;
2818 torture_comment(tctx, "This does only pass with the default site\n");
2820 /* We won't double-check this when we are over 'local' transports */
2821 if (dcerpc_server_name(p)) {
2822 /* Set up connection to SAMDB on DC */
2823 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2824 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2826 cmdline_credentials,
2829 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2832 /* First try valid IP addresses */
2834 addrs[0].size = sizeof(struct sockaddr_in);
2835 addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
2836 addr = (struct sockaddr_in *) addrs[0].buffer;
2837 addrs[0].buffer[0] = AF_INET;
2838 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2839 torture_assert(tctx, ret > 0, "inet_pton failed");
2841 addrs[1].size = sizeof(struct sockaddr_in);
2842 addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
2843 addr = (struct sockaddr_in *) addrs[1].buffer;
2844 addrs[1].buffer[0] = AF_INET;
2845 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2846 torture_assert(tctx, ret > 0, "inet_pton failed");
2848 addrs[2].size = sizeof(struct sockaddr_in);
2849 addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
2850 addr = (struct sockaddr_in *) addrs[2].buffer;
2851 addrs[2].buffer[0] = AF_INET;
2852 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2853 torture_assert(tctx, ret > 0, "inet_pton failed");
2856 addrs[3].size = sizeof(struct sockaddr_in6);
2857 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2858 addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
2859 addrs[3].buffer[0] = AF_INET6;
2860 ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
2861 torture_assert(tctx, ret > 0, "inet_pton failed");
2863 addrs[4].size = sizeof(struct sockaddr_in6);
2864 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2865 addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
2866 addrs[4].buffer[0] = AF_INET6;
2867 ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
2868 torture_assert(tctx, ret > 0, "inet_pton failed");
2870 addrs[5].size = sizeof(struct sockaddr_in6);
2871 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2872 addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
2873 addrs[5].buffer[0] = AF_INET6;
2874 ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
2875 torture_assert(tctx, ret > 0, "inet_pton failed");
2877 /* the test cases are repeated to have exactly 6. This is for
2878 * compatibility with IPv4-only machines */
2879 addrs[3].size = sizeof(struct sockaddr_in);
2880 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2881 addr = (struct sockaddr_in *) addrs[3].buffer;
2882 addrs[3].buffer[0] = AF_INET;
2883 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2884 torture_assert(tctx, ret > 0, "inet_pton failed");
2886 addrs[4].size = sizeof(struct sockaddr_in);
2887 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2888 addr = (struct sockaddr_in *) addrs[4].buffer;
2889 addrs[4].buffer[0] = AF_INET;
2890 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2891 torture_assert(tctx, ret > 0, "inet_pton failed");
2893 addrs[5].size = sizeof(struct sockaddr_in);
2894 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2895 addr = (struct sockaddr_in *) addrs[5].buffer;
2896 addrs[5].buffer[0] = AF_INET;
2897 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2898 torture_assert(tctx, ret > 0, "inet_pton failed");
2901 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
2903 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2905 r.in.addresses = addrs;
2908 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2909 torture_assert_ntstatus_ok(tctx, status, "failed");
2910 torture_assert_werr_ok(tctx, r.out.result, "failed");
2912 if (sam_ctx != NULL) {
2913 for (i = 0; i < 3; i++) {
2914 torture_assert_casestr_equal(tctx,
2915 ctr->sitename[i].string,
2916 server_site_name(tctx, sam_ctx),
2917 "didn't return default site");
2919 for (i = 3; i < 6; i++) {
2920 /* Windows returns "NULL" for the sitename if it isn't
2921 * IPv6 configured */
2922 if (torture_setting_bool(tctx, "samba4", false)) {
2923 torture_assert_casestr_equal(tctx,
2924 ctr->sitename[i].string,
2925 server_site_name(tctx, sam_ctx),
2926 "didn't return default site");
2931 /* Now try invalid ones (too short buffers) */
2941 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2942 torture_assert_ntstatus_ok(tctx, status, "failed");
2943 torture_assert_werr_ok(tctx, r.out.result, "failed");
2945 for (i = 0; i < 6; i++) {
2946 torture_assert(tctx, ctr->sitename[i].string == NULL,
2947 "sitename should be null");
2950 /* Now try invalid ones (wrong address types) */
2953 addrs[0].buffer[0] = AF_UNSPEC;
2955 addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
2957 addrs[2].buffer[0] = AF_UNIX;
2960 addrs[3].buffer[0] = 250;
2962 addrs[4].buffer[0] = 251;
2964 addrs[5].buffer[0] = 252;
2966 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2967 torture_assert_ntstatus_ok(tctx, status, "failed");
2968 torture_assert_werr_ok(tctx, r.out.result, "failed");
2970 for (i = 0; i < 6; i++) {
2971 torture_assert(tctx, ctr->sitename[i].string == NULL,
2972 "sitename should be null");
2978 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
2979 struct dcerpc_pipe *p)
2982 struct ldb_context *sam_ctx = NULL;
2984 struct netr_DsRAddressToSitenamesExW r;
2985 struct netr_DsRAddress addrs[6];
2986 struct sockaddr_in *addr;
2988 struct sockaddr_in6 *addr6;
2990 struct netr_DsRAddressToSitenamesExWCtr *ctr;
2991 struct dcerpc_binding_handle *b = p->binding_handle;
2995 torture_comment(tctx, "This does pass with the default site\n");
2997 /* We won't double-check this when we are over 'local' transports */
2998 if (dcerpc_server_name(p)) {
2999 /* Set up connection to SAMDB on DC */
3000 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3001 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3003 cmdline_credentials,
3006 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3009 /* First try valid IP addresses */
3011 addrs[0].size = sizeof(struct sockaddr_in);
3012 addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
3013 addr = (struct sockaddr_in *) addrs[0].buffer;
3014 addrs[0].buffer[0] = AF_INET;
3015 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3016 torture_assert(tctx, ret > 0, "inet_pton failed");
3018 addrs[1].size = sizeof(struct sockaddr_in);
3019 addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
3020 addr = (struct sockaddr_in *) addrs[1].buffer;
3021 addrs[1].buffer[0] = AF_INET;
3022 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3023 torture_assert(tctx, ret > 0, "inet_pton failed");
3025 addrs[2].size = sizeof(struct sockaddr_in);
3026 addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
3027 addr = (struct sockaddr_in *) addrs[2].buffer;
3028 addrs[2].buffer[0] = AF_INET;
3029 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3030 torture_assert(tctx, ret > 0, "inet_pton failed");
3033 addrs[3].size = sizeof(struct sockaddr_in6);
3034 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3035 addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
3036 addrs[3].buffer[0] = AF_INET6;
3037 ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
3038 torture_assert(tctx, ret > 0, "inet_pton failed");
3040 addrs[4].size = sizeof(struct sockaddr_in6);
3041 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3042 addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
3043 addrs[4].buffer[0] = AF_INET6;
3044 ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
3045 torture_assert(tctx, ret > 0, "inet_pton failed");
3047 addrs[5].size = sizeof(struct sockaddr_in6);
3048 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3049 addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
3050 addrs[5].buffer[0] = AF_INET6;
3051 ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
3052 torture_assert(tctx, ret > 0, "inet_pton failed");
3054 /* the test cases are repeated to have exactly 6. This is for
3055 * compatibility with IPv4-only machines */
3056 addrs[3].size = sizeof(struct sockaddr_in);
3057 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3058 addr = (struct sockaddr_in *) addrs[3].buffer;
3059 addrs[3].buffer[0] = AF_INET;
3060 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3061 torture_assert(tctx, ret > 0, "inet_pton failed");
3063 addrs[4].size = sizeof(struct sockaddr_in);
3064 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3065 addr = (struct sockaddr_in *) addrs[4].buffer;
3066 addrs[4].buffer[0] = AF_INET;
3067 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3068 torture_assert(tctx, ret > 0, "inet_pton failed");
3070 addrs[5].size = sizeof(struct sockaddr_in);
3071 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3072 addr = (struct sockaddr_in *) addrs[5].buffer;
3073 addrs[5].buffer[0] = AF_INET;
3074 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3075 torture_assert(tctx, ret > 0, "inet_pton failed");
3078 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
3080 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3082 r.in.addresses = addrs;
3085 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3086 torture_assert_ntstatus_ok(tctx, status, "failed");
3087 torture_assert_werr_ok(tctx, r.out.result, "failed");
3089 if (sam_ctx != NULL) {
3090 for (i = 0; i < 3; i++) {
3091 torture_assert_casestr_equal(tctx,
3092 ctr->sitename[i].string,
3093 server_site_name(tctx, sam_ctx),
3094 "didn't return default site");
3095 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3096 "subnet should be null");
3098 for (i = 3; i < 6; i++) {
3099 /* Windows returns "NULL" for the sitename if it isn't
3100 * IPv6 configured */
3101 if (torture_setting_bool(tctx, "samba4", false)) {
3102 torture_assert_casestr_equal(tctx,
3103 ctr->sitename[i].string,
3104 server_site_name(tctx, sam_ctx),
3105 "didn't return default site");
3107 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3108 "subnet should be null");
3112 /* Now try invalid ones (too short buffers) */
3122 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3123 torture_assert_ntstatus_ok(tctx, status, "failed");
3124 torture_assert_werr_ok(tctx, r.out.result, "failed");
3126 for (i = 0; i < 6; i++) {
3127 torture_assert(tctx, ctr->sitename[i].string == NULL,
3128 "sitename should be null");
3129 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3130 "subnet should be null");
3134 addrs[0].buffer[0] = AF_UNSPEC;
3136 addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
3138 addrs[2].buffer[0] = AF_UNIX;
3141 addrs[3].buffer[0] = 250;
3143 addrs[4].buffer[0] = 251;
3145 addrs[5].buffer[0] = 252;
3147 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3148 torture_assert_ntstatus_ok(tctx, status, "failed");
3149 torture_assert_werr_ok(tctx, r.out.result, "failed");
3151 for (i = 0; i < 6; i++) {
3152 torture_assert(tctx, ctr->sitename[i].string == NULL,
3153 "sitename should be null");
3154 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3155 "subnet should be null");
3161 static bool test_netr_ServerGetTrustInfo_flags(struct torture_context *tctx,
3162 struct dcerpc_pipe *p,
3163 struct cli_credentials *machine_credentials,
3164 uint32_t negotiate_flags)
3166 struct netr_ServerGetTrustInfo r;
3168 struct netr_Authenticator a;
3169 struct netr_Authenticator return_authenticator;
3170 struct samr_Password new_owf_password;
3171 struct samr_Password old_owf_password;
3172 struct netr_TrustInfo *trust_info;
3174 struct netlogon_creds_CredentialState *creds;
3175 struct dcerpc_binding_handle *b = p->binding_handle;
3177 struct samr_Password nt_hash;
3179 if (!test_SetupCredentials3(p, tctx, negotiate_flags,
3180 machine_credentials, &creds)) {
3184 netlogon_creds_client_authenticator(creds, &a);
3186 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3187 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
3188 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
3189 r.in.computer_name = TEST_MACHINE_NAME;
3190 r.in.credential = &a;
3192 r.out.return_authenticator = &return_authenticator;
3193 r.out.new_owf_password = &new_owf_password;
3194 r.out.old_owf_password = &old_owf_password;
3195 r.out.trust_info = &trust_info;
3197 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerGetTrustInfo_r(b, tctx, &r),
3198 "ServerGetTrustInfo failed");
3199 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerGetTrustInfo failed");
3200 torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
3202 E_md4hash(cli_credentials_get_password(machine_credentials), nt_hash.hash);
3204 netlogon_creds_des_decrypt(creds, &new_owf_password);
3206 dump_data(1, new_owf_password.hash, 16);
3207 dump_data(1, nt_hash.hash, 16);
3209 torture_assert_mem_equal(tctx, new_owf_password.hash, nt_hash.hash, 16,
3210 "received unexpected owf password\n");
3215 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
3216 struct dcerpc_pipe *p,
3217 struct cli_credentials *machine_credentials)
3219 return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
3220 NETLOGON_NEG_AUTH2_ADS_FLAGS);
3223 static bool test_netr_ServerGetTrustInfo_AES(struct torture_context *tctx,
3224 struct dcerpc_pipe *p,
3225 struct cli_credentials *machine_credentials)
3227 return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
3228 NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
3231 static bool test_GetDomainInfo(struct torture_context *tctx,
3232 struct dcerpc_pipe *p,
3233 struct cli_credentials *machine_credentials)
3235 struct netr_LogonGetDomainInfo r;
3236 struct netr_WorkstationInformation q1;
3237 struct netr_Authenticator a;
3238 struct netlogon_creds_CredentialState *creds;
3239 struct netr_OsVersion os;
3240 union netr_WorkstationInfo query;
3241 union netr_DomainInfo info;
3242 const char* const attrs[] = { "dNSHostName", "operatingSystem",
3243 "operatingSystemServicePack", "operatingSystemVersion",
3244 "servicePrincipalName", NULL };
3246 struct ldb_context *sam_ctx = NULL;
3247 struct ldb_message **res;
3248 struct ldb_message_element *spn_el;
3251 const char *old_dnsname = NULL;
3255 struct dcerpc_binding_handle *b = p->binding_handle;
3257 torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
3259 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3260 machine_credentials, &creds)) {
3264 /* We won't double-check this when we are over 'local' transports */
3265 if (dcerpc_server_name(p)) {
3266 /* Set up connection to SAMDB on DC */
3267 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3268 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3270 cmdline_credentials,
3273 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3276 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
3277 netlogon_creds_client_authenticator(creds, &a);
3280 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3281 r.in.computer_name = TEST_MACHINE_NAME;
3282 r.in.credential = &a;
3284 r.in.return_authenticator = &a;
3285 r.in.query = &query;
3286 r.out.return_authenticator = &a;
3290 os.os.MajorVersion = 123;
3291 os.os.MinorVersion = 456;
3292 os.os.BuildNumber = 789;
3293 os.os.CSDVersion = "Service Pack 10";
3294 os.os.ServicePackMajor = 10;
3295 os.os.ServicePackMinor = 1;
3296 os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
3297 os.os.ProductType = NETR_VER_NT_SERVER;
3300 version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
3301 os.os.MinorVersion, os.os.BuildNumber);
3304 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3305 lpcfg_dnsdomain(tctx->lp_ctx));
3306 q1.sitename = "Default-First-Site-Name";
3307 q1.os_version.os = &os;
3308 q1.os_name.string = talloc_asprintf(tctx,
3309 "Tortured by Samba4 RPC-NETLOGON: %s",
3310 timestring(tctx, time(NULL)));
3312 /* The workstation handles the "servicePrincipalName" and DNS hostname
3314 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3316 query.workstation_info = &q1;
3319 /* Gets back the old DNS hostname in AD */
3320 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3321 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3323 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
3325 /* Gets back the "servicePrincipalName"s in AD */
3326 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3327 if (spn_el != NULL) {
3328 for (i=0; i < spn_el->num_values; i++) {
3329 spns = talloc_realloc(tctx, spns, char *, i + 1);
3330 spns[i] = (char *) spn_el->values[i].data;
3336 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3337 "LogonGetDomainInfo failed");
3338 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3339 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3344 /* AD workstation infos entry check */
3345 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3346 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3347 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3348 torture_assert_str_equal(tctx,
3349 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3350 q1.os_name.string, "'operatingSystem' wrong!");
3351 torture_assert_str_equal(tctx,
3352 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
3353 os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
3354 torture_assert_str_equal(tctx,
3355 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
3356 version_str, "'operatingSystemVersion' wrong!");
3358 if (old_dnsname != NULL) {
3359 /* If before a DNS hostname was set then it should remain
3360 the same in combination with the "servicePrincipalName"s.
3361 The DNS hostname should also be returned by our
3362 "LogonGetDomainInfo" call (in the domain info structure). */
3364 torture_assert_str_equal(tctx,
3365 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3366 old_dnsname, "'DNS hostname' was not set!");
3368 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3369 torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
3370 "'servicePrincipalName's not set!");
3371 torture_assert(tctx, spn_el->num_values == num_spns,
3372 "'servicePrincipalName's incorrect!");
3373 for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
3374 torture_assert_str_equal(tctx,
3375 (char *) spn_el->values[i].data,
3376 spns[i], "'servicePrincipalName's incorrect!");
3378 torture_assert_str_equal(tctx,
3379 info.domain_info->dns_hostname.string,
3381 "Out 'DNS hostname' doesn't match the old one!");
3383 /* If no DNS hostname was set then also now none should be set,
3384 the "servicePrincipalName"s should remain empty and no DNS
3385 hostname should be returned by our "LogonGetDomainInfo"
3386 call (in the domain info structure). */
3388 torture_assert(tctx,
3389 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
3390 "'DNS hostname' was set!");
3392 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3393 torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
3394 "'servicePrincipalName's were set!");
3396 torture_assert(tctx,
3397 info.domain_info->dns_hostname.string == NULL,
3398 "Out 'DNS host name' was set!");
3402 /* Checks "workstation flags" */
3403 torture_assert(tctx,
3404 info.domain_info->workstation_flags
3405 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3406 "Out 'workstation flags' don't match!");
3409 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname doesn't work)\n");
3410 netlogon_creds_client_authenticator(creds, &a);
3412 /* Wipe out the osVersion, and prove which values still 'stick' */
3413 q1.os_version.os = NULL;
3415 /* Change also the DNS hostname to test differences in behaviour */
3416 talloc_free(discard_const_p(char, q1.dns_hostname));
3417 q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3418 lpcfg_dnsdomain(tctx->lp_ctx));
3420 /* The workstation handles the "servicePrincipalName" and DNS hostname
3422 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3424 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3425 "LogonGetDomainInfo failed");
3426 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3428 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3433 /* AD workstation infos entry check */
3434 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3435 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3436 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3438 torture_assert_str_equal(tctx,
3439 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3440 q1.os_name.string, "'operatingSystem' should stick!");
3441 torture_assert(tctx,
3442 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3443 "'operatingSystemServicePack' shouldn't stick!");
3444 torture_assert(tctx,
3445 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3446 "'operatingSystemVersion' shouldn't stick!");
3448 /* The DNS host name shouldn't have been updated by the server */
3450 torture_assert_str_equal(tctx,
3451 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3452 old_dnsname, "'DNS host name' did change!");
3454 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3455 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3457 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3458 torture_assert(tctx, spn_el != NULL,
3459 "There should exist 'servicePrincipalName's in AD!");
3460 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3461 for (i=0; i < spn_el->num_values; i++)
3462 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3464 torture_assert(tctx, i != spn_el->num_values,
3465 "'servicePrincipalName' HOST/<Netbios name> not found!");
3466 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3467 for (i=0; i < spn_el->num_values; i++)
3468 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3470 torture_assert(tctx, i != spn_el->num_values,
3471 "'servicePrincipalName' HOST/<FQDN name> not found!");
3473 /* Check that the out DNS hostname was set properly */
3474 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
3475 old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
3478 /* Checks "workstation flags" */
3479 torture_assert(tctx,
3480 info.domain_info->workstation_flags == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3481 "Out 'workstation flags' don't match!");
3484 /* Now try the same but the workstation flags set to 0 */
3486 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (variation of DNS hostname doesn't work)\n");
3487 netlogon_creds_client_authenticator(creds, &a);
3489 /* Change also the DNS hostname to test differences in behaviour */
3490 talloc_free(discard_const_p(char, q1.dns_hostname));
3491 q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3492 lpcfg_dnsdomain(tctx->lp_ctx));
3494 /* Wipe out the osVersion, and prove which values still 'stick' */
3495 q1.os_version.os = NULL;
3497 /* Let the DC handle the "servicePrincipalName" and DNS hostname
3499 q1.workstation_flags = 0;
3501 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3502 "LogonGetDomainInfo failed");
3503 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3504 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3509 /* AD workstation infos entry check */
3510 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3511 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3512 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3514 torture_assert_str_equal(tctx,
3515 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3516 q1.os_name.string, "'operatingSystem' should stick!");
3517 torture_assert(tctx,
3518 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3519 "'operatingSystemServicePack' shouldn't stick!");
3520 torture_assert(tctx,
3521 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3522 "'operatingSystemVersion' shouldn't stick!");
3524 /* The DNS host name shouldn't have been updated by the server */
3526 torture_assert_str_equal(tctx,
3527 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3528 old_dnsname, "'DNS host name' did change!");
3530 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3531 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3533 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3534 torture_assert(tctx, spn_el != NULL,
3535 "There should exist 'servicePrincipalName's in AD!");
3536 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3537 for (i=0; i < spn_el->num_values; i++)
3538 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3540 torture_assert(tctx, i != spn_el->num_values,
3541 "'servicePrincipalName' HOST/<Netbios name> not found!");
3542 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3543 for (i=0; i < spn_el->num_values; i++)
3544 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3546 torture_assert(tctx, i != spn_el->num_values,
3547 "'servicePrincipalName' HOST/<FQDN name> not found!");
3549 /* Here the server gives us NULL as the out DNS hostname */
3550 torture_assert(tctx, info.domain_info->dns_hostname.string == NULL,
3551 "Out 'DNS hostname' should be NULL!");
3554 /* Checks "workstation flags" */
3555 torture_assert(tctx,
3556 info.domain_info->workstation_flags == 0,
3557 "Out 'workstation flags' don't match!");
3560 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (verification of DNS hostname and check for trusted domains)\n");
3561 netlogon_creds_client_authenticator(creds, &a);
3563 /* Put the DNS hostname back */
3564 talloc_free(discard_const_p(char, q1.dns_hostname));
3565 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3566 lpcfg_dnsdomain(tctx->lp_ctx));
3568 /* The workstation handles the "servicePrincipalName" and DNS hostname
3570 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3572 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3573 "LogonGetDomainInfo failed");
3574 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3575 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3579 /* Now the in/out DNS hostnames should be the same */
3580 torture_assert_str_equal(tctx,
3581 info.domain_info->dns_hostname.string,
3582 query.workstation_info->dns_hostname,
3583 "In/Out 'DNS hostnames' don't match!");
3584 old_dnsname = info.domain_info->dns_hostname.string;
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!");
3592 /* Checks for trusted domains */
3593 torture_assert(tctx,
3594 (info.domain_info->trusted_domain_count != 0)
3595 && (info.domain_info->trusted_domains != NULL),
3596 "Trusted domains have been requested!");
3599 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 5th call (check for trusted domains)\n");
3600 netlogon_creds_client_authenticator(creds, &a);
3602 /* The workstation handles the "servicePrincipalName" and DNS hostname
3603 updates and requests inbound trusts */
3604 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
3605 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
3607 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3608 "LogonGetDomainInfo failed");
3609 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3610 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3614 /* Checks "workstation flags" */
3615 torture_assert(tctx,
3616 info.domain_info->workstation_flags
3617 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
3618 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
3619 "Out 'workstation flags' don't match!");
3621 /* Checks for trusted domains */
3622 torture_assert(tctx,
3623 (info.domain_info->trusted_domain_count != 0)
3624 && (info.domain_info->trusted_domains != NULL),
3625 "Trusted domains have been requested!");
3628 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
3629 netlogon_creds_client_authenticator(creds, &a);
3631 query.workstation_info->dns_hostname = NULL;
3633 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3634 "LogonGetDomainInfo failed");
3635 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3636 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3638 /* The old DNS hostname should stick */
3639 torture_assert_str_equal(tctx,
3640 info.domain_info->dns_hostname.string,
3642 "'DNS hostname' changed!");
3644 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (extra workstation flags)\n");
3645 netlogon_creds_client_authenticator(creds, &a);
3647 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
3648 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | 0x4;
3650 /* Put the DNS hostname back */
3651 talloc_free(discard_const_p(char, q1.dns_hostname));
3652 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3653 lpcfg_dnsdomain(tctx->lp_ctx));
3655 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3656 "LogonGetDomainInfo failed");
3657 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3658 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3660 /* Checks "workstation flags" */
3661 torture_assert(tctx,
3662 info.domain_info->workstation_flags
3663 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
3664 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
3665 "Out 'workstation flags' don't match!");
3667 if (!torture_setting_bool(tctx, "dangerous", false)) {
3668 torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 8th call (no workstation info) - enable dangerous tests in order to do so\n");
3670 /* Try a call without the workstation information structure */
3672 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 8th call (no workstation info)\n");
3673 netlogon_creds_client_authenticator(creds, &a);
3675 query.workstation_info = NULL;
3677 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3678 "LogonGetDomainInfo failed");
3679 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3680 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3686 static bool test_GetDomainInfo_async(struct torture_context *tctx,
3687 struct dcerpc_pipe *p,
3688 struct cli_credentials *machine_credentials)
3691 struct netr_LogonGetDomainInfo r;
3692 struct netr_WorkstationInformation q1;
3693 struct netr_Authenticator a;
3694 #define ASYNC_COUNT 100
3695 struct netlogon_creds_CredentialState *creds;
3696 struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
3697 struct tevent_req *req[ASYNC_COUNT];
3699 union netr_WorkstationInfo query;
3700 union netr_DomainInfo info;
3702 torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
3704 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3705 machine_credentials, &creds)) {
3710 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3711 r.in.computer_name = TEST_MACHINE_NAME;
3712 r.in.credential = &a;
3714 r.in.return_authenticator = &a;
3715 r.in.query = &query;
3716 r.out.return_authenticator = &a;
3720 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3721 lpcfg_dnsdomain(tctx->lp_ctx));
3722 q1.sitename = "Default-First-Site-Name";
3723 q1.os_name.string = "UNIX/Linux or similar";
3725 query.workstation_info = &q1;
3727 for (i=0;i<ASYNC_COUNT;i++) {
3728 netlogon_creds_client_authenticator(creds, &a);
3730 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
3731 req[i] = dcerpc_netr_LogonGetDomainInfo_r_send(tctx, tctx->ev, p->binding_handle, &r);
3733 /* even with this flush per request a w2k3 server seems to
3734 clag with multiple outstanding requests. bleergh. */
3735 torture_assert_int_equal(tctx, tevent_loop_once(dcerpc_event_context(p)), 0,
3736 "tevent_loop_once failed");
3739 for (i=0;i<ASYNC_COUNT;i++) {
3740 torture_assert_int_equal(tctx, tevent_req_poll(req[i], tctx->ev), true,
3741 "tevent_req_poll() failed");
3743 status = dcerpc_netr_LogonGetDomainInfo_r_recv(req[i], tctx);
3745 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
3746 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
3748 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred),
3749 "Credential chaining failed at async");
3752 torture_comment(tctx,
3753 "Testing netr_LogonGetDomainInfo - async count %d OK\n", ASYNC_COUNT);
3758 static bool test_ManyGetDCName(struct torture_context *tctx,
3759 struct dcerpc_pipe *p)
3762 struct dcerpc_pipe *p2;
3763 struct lsa_ObjectAttribute attr;
3764 struct lsa_QosInfo qos;
3765 struct lsa_OpenPolicy2 o;
3766 struct policy_handle lsa_handle;
3767 struct lsa_DomainList domains;
3769 struct lsa_EnumTrustDom t;
3770 uint32_t resume_handle = 0;
3771 struct netr_GetAnyDCName d;
3772 const char *dcname = NULL;
3773 struct dcerpc_binding_handle *b = p->binding_handle;
3774 struct dcerpc_binding_handle *b2;
3778 if (p->conn->transport.transport != NCACN_NP) {
3782 torture_comment(tctx, "Torturing GetDCName\n");
3784 status = dcerpc_secondary_connection(p, &p2, p->binding);
3785 torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
3787 status = dcerpc_bind_auth_none(p2, &ndr_table_lsarpc);
3788 torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
3789 b2 = p2->binding_handle;
3792 qos.impersonation_level = 2;
3793 qos.context_mode = 1;
3794 qos.effective_only = 0;
3797 attr.root_dir = NULL;
3798 attr.object_name = NULL;
3799 attr.attributes = 0;
3800 attr.sec_desc = NULL;
3801 attr.sec_qos = &qos;
3803 o.in.system_name = "\\";
3805 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3806 o.out.handle = &lsa_handle;
3808 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
3809 "OpenPolicy2 failed");
3810 torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
3812 t.in.handle = &lsa_handle;
3813 t.in.resume_handle = &resume_handle;
3814 t.in.max_size = 1000;
3815 t.out.domains = &domains;
3816 t.out.resume_handle = &resume_handle;
3818 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b2, tctx, &t),
3819 "EnumTrustDom failed");
3821 if ((!NT_STATUS_IS_OK(t.out.result) &&
3822 (!NT_STATUS_EQUAL(t.out.result, NT_STATUS_NO_MORE_ENTRIES))))
3823 torture_fail(tctx, "Could not list domains");
3827 d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
3828 dcerpc_server_name(p));
3829 d.out.dcname = &dcname;
3831 for (i=0; i<domains.count * 4; i++) {
3832 struct lsa_DomainInfo *info =
3833 &domains.domains[rand()%domains.count];
3835 d.in.domainname = info->name.string;
3837 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &d);
3838 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3840 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
3841 dcname ? dcname : "unknown");
3847 static bool test_SetPassword_with_flags(struct torture_context *tctx,
3848 struct dcerpc_pipe *p,
3849 struct cli_credentials *machine_credentials)
3851 uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
3852 struct netlogon_creds_CredentialState *creds;
3855 if (!test_SetupCredentials2(p, tctx, 0,
3856 machine_credentials,
3857 cli_credentials_get_secure_channel_type(machine_credentials),
3859 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
3862 for (i=0; i < ARRAY_SIZE(flags); i++) {
3863 torture_assert(tctx,
3864 test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
3865 talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
3871 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
3873 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon");
3874 struct torture_rpc_tcase *tcase;
3875 struct torture_test *test;
3877 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3878 &ndr_table_netlogon, TEST_MACHINE_NAME);
3880 torture_rpc_tcase_add_test(tcase, "Broken RPC binding handle",
3881 test_netr_broken_binding_handle);
3883 torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
3884 torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
3885 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
3886 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
3887 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
3888 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
3889 torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
3890 torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
3891 torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
3892 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
3893 torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
3894 torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
3895 torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
3896 torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
3897 torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
3898 torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
3899 torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
3900 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
3901 torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
3902 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
3903 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
3904 test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
3905 test->dangerous = true;
3906 torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
3907 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
3908 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
3909 torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
3910 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
3911 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
3912 torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
3913 torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo_AES", test_netr_ServerGetTrustInfo_AES);
3914 torture_rpc_tcase_add_test_creds(tcase, "GetForestTrustInformation", test_netr_GetForestTrustInformation);
3919 struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
3921 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon-s3");
3922 struct torture_rpc_tcase *tcase;
3924 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3925 &ndr_table_netlogon, TEST_MACHINE_NAME);
3927 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
3928 torture_rpc_tcase_add_test_creds(tcase, "SamLogon_NULL_domain", test_SamLogon_NULL_domain);
3929 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
3930 torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
3931 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
3932 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
3933 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
3938 struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
3940 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon.admin");
3941 struct torture_rpc_tcase *tcase;
3943 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3944 &ndr_table_netlogon, TEST_MACHINE_NAME);
3945 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3946 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3947 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3949 tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netlogon",
3950 &ndr_table_netlogon, TEST_MACHINE_NAME);
3951 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3952 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3953 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3955 tcase = torture_suite_add_rpc_iface_tcase(suite, "netlogon",
3956 &ndr_table_netlogon);
3957 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3958 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3959 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);