s4-ldbwrap: added re-use of ldb contexts in ldb_wrap_connect()
[Samba/cd1.git] / source4 / torture / rpc / netlogon.c
blobdb949ada2a92fc34ddec07b3babd36de1dec32e5
1 /*
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
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/>.
25 #include "includes.h"
26 #include "lib/events/events.h"
27 #include "lib/cmdline/popt_common.h"
28 #include "torture/rpc/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"
35 #include "lib/ldb/include/ldb.h"
36 #include "lib/util/util_ldb.h"
37 #include "lib/ldb_wrap.h"
39 #define TEST_MACHINE_NAME "torturetest"
40 #define TEST_MACHINE_DNS_SUFFIX "torturedomain"
42 static bool test_LogonUasLogon(struct torture_context *tctx,
43 struct dcerpc_pipe *p)
45 NTSTATUS status;
46 struct netr_LogonUasLogon r;
47 struct netr_UasInfo *info = NULL;
49 r.in.server_name = NULL;
50 r.in.account_name = cli_credentials_get_username(cmdline_credentials);
51 r.in.workstation = TEST_MACHINE_NAME;
52 r.out.info = &info;
54 status = dcerpc_netr_LogonUasLogon(p, tctx, &r);
55 torture_assert_ntstatus_ok(tctx, status, "LogonUasLogon");
57 return true;
60 static bool test_LogonUasLogoff(struct torture_context *tctx,
61 struct dcerpc_pipe *p)
63 NTSTATUS status;
64 struct netr_LogonUasLogoff r;
65 struct netr_UasLogoffInfo info;
67 r.in.server_name = NULL;
68 r.in.account_name = cli_credentials_get_username(cmdline_credentials);
69 r.in.workstation = TEST_MACHINE_NAME;
70 r.out.info = &info;
72 status = dcerpc_netr_LogonUasLogoff(p, tctx, &r);
73 torture_assert_ntstatus_ok(tctx, status, "LogonUasLogoff");
75 return true;
78 bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
79 struct cli_credentials *credentials,
80 struct netlogon_creds_CredentialState **creds_out)
82 NTSTATUS status;
83 struct netr_ServerReqChallenge r;
84 struct netr_ServerAuthenticate a;
85 struct netr_Credential credentials1, credentials2, credentials3;
86 struct netlogon_creds_CredentialState *creds;
87 const struct samr_Password *mach_password;
88 const char *machine_name;
90 mach_password = cli_credentials_get_nt_hash(credentials, tctx);
91 machine_name = cli_credentials_get_workstation(credentials);
93 torture_comment(tctx, "Testing ServerReqChallenge\n");
95 r.in.server_name = NULL;
96 r.in.computer_name = machine_name;
97 r.in.credentials = &credentials1;
98 r.out.return_credentials = &credentials2;
100 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
102 status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
103 torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
105 a.in.server_name = NULL;
106 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
107 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(credentials);
108 a.in.computer_name = machine_name;
109 a.in.credentials = &credentials3;
110 a.out.return_credentials = &credentials3;
112 creds = netlogon_creds_client_init(tctx, a.in.account_name,
113 a.in.computer_name,
114 &credentials1, &credentials2,
115 mach_password, &credentials3,
117 torture_assert(tctx, creds != NULL, "memory allocation");
120 torture_comment(tctx, "Testing ServerAuthenticate\n");
122 status = dcerpc_netr_ServerAuthenticate(p, tctx, &a);
124 /* This allows the tests to continue against the more fussy windows 2008 */
125 if (NT_STATUS_EQUAL(status, NT_STATUS_DOWNGRADE_DETECTED)) {
126 return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
127 credentials,
128 cli_credentials_get_secure_channel_type(credentials),
129 creds_out);
132 torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate");
134 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
135 "Credential chaining failed");
137 *creds_out = creds;
138 return true;
141 bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx,
142 uint32_t negotiate_flags,
143 struct cli_credentials *machine_credentials,
144 int sec_chan_type,
145 struct netlogon_creds_CredentialState **creds_out)
147 NTSTATUS status;
148 struct netr_ServerReqChallenge r;
149 struct netr_ServerAuthenticate2 a;
150 struct netr_Credential credentials1, credentials2, credentials3;
151 struct netlogon_creds_CredentialState *creds;
152 const struct samr_Password *mach_password;
153 const char *machine_name;
155 mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
156 machine_name = cli_credentials_get_workstation(machine_credentials);
158 torture_comment(tctx, "Testing ServerReqChallenge\n");
161 r.in.server_name = NULL;
162 r.in.computer_name = machine_name;
163 r.in.credentials = &credentials1;
164 r.out.return_credentials = &credentials2;
166 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
168 status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
169 torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
171 a.in.server_name = NULL;
172 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
173 a.in.secure_channel_type = sec_chan_type;
174 a.in.computer_name = machine_name;
175 a.in.negotiate_flags = &negotiate_flags;
176 a.out.negotiate_flags = &negotiate_flags;
177 a.in.credentials = &credentials3;
178 a.out.return_credentials = &credentials3;
180 creds = netlogon_creds_client_init(tctx, a.in.account_name,
181 a.in.computer_name,
182 &credentials1, &credentials2,
183 mach_password, &credentials3,
184 negotiate_flags);
186 torture_assert(tctx, creds != NULL, "memory allocation");
188 torture_comment(tctx, "Testing ServerAuthenticate2\n");
190 status = dcerpc_netr_ServerAuthenticate2(p, tctx, &a);
191 torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate2");
193 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
194 "Credential chaining failed");
196 torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
198 *creds_out = creds;
199 return true;
203 static bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx,
204 uint32_t negotiate_flags,
205 struct cli_credentials *machine_credentials,
206 struct netlogon_creds_CredentialState **creds_out)
208 NTSTATUS status;
209 struct netr_ServerReqChallenge r;
210 struct netr_ServerAuthenticate3 a;
211 struct netr_Credential credentials1, credentials2, credentials3;
212 struct netlogon_creds_CredentialState *creds;
213 struct samr_Password mach_password;
214 uint32_t rid;
215 const char *machine_name;
216 const char *plain_pass;
218 machine_name = cli_credentials_get_workstation(machine_credentials);
219 plain_pass = cli_credentials_get_password(machine_credentials);
221 torture_comment(tctx, "Testing ServerReqChallenge\n");
223 r.in.server_name = NULL;
224 r.in.computer_name = machine_name;
225 r.in.credentials = &credentials1;
226 r.out.return_credentials = &credentials2;
228 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
230 status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
231 torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
233 E_md4hash(plain_pass, mach_password.hash);
235 a.in.server_name = NULL;
236 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
237 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
238 a.in.computer_name = machine_name;
239 a.in.negotiate_flags = &negotiate_flags;
240 a.in.credentials = &credentials3;
241 a.out.return_credentials = &credentials3;
242 a.out.negotiate_flags = &negotiate_flags;
243 a.out.rid = &rid;
245 creds = netlogon_creds_client_init(tctx, a.in.account_name,
246 a.in.computer_name,
247 &credentials1, &credentials2,
248 &mach_password, &credentials3,
249 negotiate_flags);
251 torture_assert(tctx, creds != NULL, "memory allocation");
253 torture_comment(tctx, "Testing ServerAuthenticate3\n");
255 status = dcerpc_netr_ServerAuthenticate3(p, tctx, &a);
256 torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate3");
257 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
259 torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
261 /* Prove that requesting a challenge again won't break it */
262 status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
263 torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
265 *creds_out = creds;
266 return true;
270 try a change password for our machine account
272 static bool test_SetPassword(struct torture_context *tctx,
273 struct dcerpc_pipe *p,
274 struct cli_credentials *machine_credentials)
276 NTSTATUS status;
277 struct netr_ServerPasswordSet r;
278 const char *password;
279 struct netlogon_creds_CredentialState *creds;
280 struct netr_Authenticator credential, return_authenticator;
281 struct samr_Password new_password;
283 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
284 return false;
287 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
288 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
289 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
290 r.in.computer_name = TEST_MACHINE_NAME;
291 r.in.credential = &credential;
292 r.in.new_password = &new_password;
293 r.out.return_authenticator = &return_authenticator;
295 password = generate_random_str(tctx, 8);
296 E_md4hash(password, new_password.hash);
298 netlogon_creds_des_encrypt(creds, &new_password);
300 torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
301 torture_comment(tctx, "Changing machine account password to '%s'\n",
302 password);
304 netlogon_creds_client_authenticator(creds, &credential);
306 status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
307 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet");
309 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
310 torture_comment(tctx, "Credential chaining failed\n");
313 /* by changing the machine password twice we test the
314 credentials chaining fully, and we verify that the server
315 allows the password to be set to the same value twice in a
316 row (match win2k3) */
317 torture_comment(tctx,
318 "Testing a second ServerPasswordSet on machine account\n");
319 torture_comment(tctx,
320 "Changing machine account password to '%s' (same as previous run)\n", password);
322 netlogon_creds_client_authenticator(creds, &credential);
324 status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
325 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (2)");
327 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
328 torture_comment(tctx, "Credential chaining failed\n");
331 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
333 torture_assert(tctx,
334 test_SetupCredentials(p, tctx, machine_credentials, &creds),
335 "ServerPasswordSet failed to actually change the password");
337 return true;
341 try a change password for our machine account
343 static bool test_SetPassword_flags(struct torture_context *tctx,
344 struct dcerpc_pipe *p,
345 struct cli_credentials *machine_credentials,
346 uint32_t negotiate_flags)
348 NTSTATUS status;
349 struct netr_ServerPasswordSet r;
350 const char *password;
351 struct netlogon_creds_CredentialState *creds;
352 struct netr_Authenticator credential, return_authenticator;
353 struct samr_Password new_password;
355 if (!test_SetupCredentials2(p, tctx, negotiate_flags,
356 machine_credentials,
357 cli_credentials_get_secure_channel_type(machine_credentials),
358 &creds)) {
359 return false;
362 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
363 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
364 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
365 r.in.computer_name = TEST_MACHINE_NAME;
366 r.in.credential = &credential;
367 r.in.new_password = &new_password;
368 r.out.return_authenticator = &return_authenticator;
370 password = generate_random_str(tctx, 8);
371 E_md4hash(password, new_password.hash);
373 netlogon_creds_des_encrypt(creds, &new_password);
375 torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
376 torture_comment(tctx, "Changing machine account password to '%s'\n",
377 password);
379 netlogon_creds_client_authenticator(creds, &credential);
381 status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
382 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet");
384 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
385 torture_comment(tctx, "Credential chaining failed\n");
388 /* by changing the machine password twice we test the
389 credentials chaining fully, and we verify that the server
390 allows the password to be set to the same value twice in a
391 row (match win2k3) */
392 torture_comment(tctx,
393 "Testing a second ServerPasswordSet on machine account\n");
394 torture_comment(tctx,
395 "Changing machine account password to '%s' (same as previous run)\n", password);
397 netlogon_creds_client_authenticator(creds, &credential);
399 status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
400 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (2)");
402 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
403 torture_comment(tctx, "Credential chaining failed\n");
406 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
408 torture_assert(tctx,
409 test_SetupCredentials(p, tctx, machine_credentials, &creds),
410 "ServerPasswordSet failed to actually change the password");
412 return true;
417 generate a random password for password change tests
419 static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
421 int i;
422 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
423 generate_random_buffer(password.data, password.length);
425 for (i=0; i < len; i++) {
426 if (((uint16_t *)password.data)[i] == 0) {
427 ((uint16_t *)password.data)[i] = 1;
431 return password;
435 try a change password for our machine account
437 static bool test_SetPassword2(struct torture_context *tctx,
438 struct dcerpc_pipe *p,
439 struct cli_credentials *machine_credentials)
441 NTSTATUS status;
442 struct netr_ServerPasswordSet2 r;
443 const char *password;
444 DATA_BLOB new_random_pass;
445 struct netlogon_creds_CredentialState *creds;
446 struct samr_CryptPassword password_buf;
447 struct samr_Password nt_hash;
448 struct netr_Authenticator credential, return_authenticator;
449 struct netr_CryptPassword new_password;
451 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
452 return false;
455 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
456 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
457 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
458 r.in.computer_name = TEST_MACHINE_NAME;
459 r.in.credential = &credential;
460 r.in.new_password = &new_password;
461 r.out.return_authenticator = &return_authenticator;
463 password = generate_random_str(tctx, 8);
464 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
465 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
467 memcpy(new_password.data, password_buf.data, 512);
468 new_password.length = IVAL(password_buf.data, 512);
470 torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
471 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
473 netlogon_creds_client_authenticator(creds, &credential);
475 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
476 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2");
478 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
479 torture_comment(tctx, "Credential chaining failed\n");
482 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
484 if (!torture_setting_bool(tctx, "dangerous", false)) {
485 torture_comment(tctx,
486 "Not testing ability to set password to '', enable dangerous tests to perform this test\n");
487 } else {
488 /* by changing the machine password to ""
489 * we check if the server uses password restrictions
490 * for ServerPasswordSet2
491 * (win2k3 accepts "")
493 password = "";
494 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
495 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
497 memcpy(new_password.data, password_buf.data, 512);
498 new_password.length = IVAL(password_buf.data, 512);
500 torture_comment(tctx,
501 "Testing ServerPasswordSet2 on machine account\n");
502 torture_comment(tctx,
503 "Changing machine account password to '%s'\n", password);
505 netlogon_creds_client_authenticator(creds, &credential);
507 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
508 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2");
510 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
511 torture_comment(tctx, "Credential chaining failed\n");
514 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
517 torture_assert(tctx, test_SetupCredentials(p, tctx, machine_credentials, &creds),
518 "ServerPasswordSet failed to actually change the password");
520 /* now try a random password */
521 password = generate_random_str(tctx, 8);
522 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
523 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
525 memcpy(new_password.data, password_buf.data, 512);
526 new_password.length = IVAL(password_buf.data, 512);
528 torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
529 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
531 netlogon_creds_client_authenticator(creds, &credential);
533 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
534 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2 (2)");
536 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
537 torture_comment(tctx, "Credential chaining failed\n");
540 /* by changing the machine password twice we test the
541 credentials chaining fully, and we verify that the server
542 allows the password to be set to the same value twice in a
543 row (match win2k3) */
544 torture_comment(tctx,
545 "Testing a second ServerPasswordSet2 on machine account\n");
546 torture_comment(tctx,
547 "Changing machine account password to '%s' (same as previous run)\n", password);
549 netlogon_creds_client_authenticator(creds, &credential);
551 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
552 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (3)");
554 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
555 torture_comment(tctx, "Credential chaining failed\n");
558 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
560 torture_assert (tctx,
561 test_SetupCredentials(p, tctx, machine_credentials, &creds),
562 "ServerPasswordSet failed to actually change the password");
564 new_random_pass = netlogon_very_rand_pass(tctx, 128);
566 /* now try a random stream of bytes for a password */
567 set_pw_in_buffer(password_buf.data, &new_random_pass);
569 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
571 memcpy(new_password.data, password_buf.data, 512);
572 new_password.length = IVAL(password_buf.data, 512);
574 torture_comment(tctx,
575 "Testing a third ServerPasswordSet2 on machine account, with a compleatly random password\n");
577 netlogon_creds_client_authenticator(creds, &credential);
579 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
580 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (3)");
582 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
583 torture_comment(tctx, "Credential chaining failed\n");
586 mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
588 cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
589 cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
591 torture_assert (tctx,
592 test_SetupCredentials(p, tctx, machine_credentials, &creds),
593 "ServerPasswordSet failed to actually change the password");
595 return true;
598 static bool test_GetPassword(struct torture_context *tctx,
599 struct dcerpc_pipe *p,
600 struct cli_credentials *machine_credentials)
602 struct netr_ServerPasswordGet r;
603 struct netlogon_creds_CredentialState *creds;
604 struct netr_Authenticator credential;
605 NTSTATUS status;
606 struct netr_Authenticator return_authenticator;
607 struct samr_Password password;
609 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
610 return false;
613 netlogon_creds_client_authenticator(creds, &credential);
615 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
616 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
617 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
618 r.in.computer_name = TEST_MACHINE_NAME;
619 r.in.credential = &credential;
620 r.out.return_authenticator = &return_authenticator;
621 r.out.password = &password;
623 status = dcerpc_netr_ServerPasswordGet(p, tctx, &r);
624 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
626 return true;
629 static bool test_GetTrustPasswords(struct torture_context *tctx,
630 struct dcerpc_pipe *p,
631 struct cli_credentials *machine_credentials)
633 struct netr_ServerTrustPasswordsGet r;
634 struct netlogon_creds_CredentialState *creds;
635 struct netr_Authenticator credential;
636 NTSTATUS status;
637 struct netr_Authenticator return_authenticator;
638 struct samr_Password password, password2;
640 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
641 return false;
644 netlogon_creds_client_authenticator(creds, &credential);
646 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
647 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
648 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
649 r.in.computer_name = TEST_MACHINE_NAME;
650 r.in.credential = &credential;
651 r.out.return_authenticator = &return_authenticator;
652 r.out.password = &password;
653 r.out.password2 = &password2;
655 status = dcerpc_netr_ServerTrustPasswordsGet(p, tctx, &r);
656 torture_assert_ntstatus_ok(tctx, status, "ServerTrustPasswordsGet");
658 return true;
662 try a netlogon SamLogon
664 bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
665 struct cli_credentials *credentials,
666 struct netlogon_creds_CredentialState *creds)
668 NTSTATUS status;
669 struct netr_LogonSamLogon r;
670 struct netr_Authenticator auth, auth2;
671 union netr_LogonLevel logon;
672 union netr_Validation validation;
673 uint8_t authoritative;
674 struct netr_NetworkInfo ninfo;
675 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
676 int i;
677 int flags = CLI_CRED_NTLM_AUTH;
678 if (lp_client_lanman_auth(tctx->lp_ctx)) {
679 flags |= CLI_CRED_LANMAN_AUTH;
682 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
683 flags |= CLI_CRED_NTLMv2_AUTH;
686 cli_credentials_get_ntlm_username_domain(cmdline_credentials, tctx,
687 &ninfo.identity_info.account_name.string,
688 &ninfo.identity_info.domain_name.string);
690 generate_random_buffer(ninfo.challenge,
691 sizeof(ninfo.challenge));
692 chal = data_blob_const(ninfo.challenge,
693 sizeof(ninfo.challenge));
695 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials),
696 cli_credentials_get_domain(credentials));
698 status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx,
699 &flags,
700 chal,
701 names_blob,
702 &lm_resp, &nt_resp,
703 NULL, NULL);
704 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
706 ninfo.lm.data = lm_resp.data;
707 ninfo.lm.length = lm_resp.length;
709 ninfo.nt.data = nt_resp.data;
710 ninfo.nt.length = nt_resp.length;
712 ninfo.identity_info.parameter_control = 0;
713 ninfo.identity_info.logon_id_low = 0;
714 ninfo.identity_info.logon_id_high = 0;
715 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
717 logon.network = &ninfo;
719 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
720 r.in.computer_name = cli_credentials_get_workstation(credentials);
721 r.in.credential = &auth;
722 r.in.return_authenticator = &auth2;
723 r.in.logon_level = 2;
724 r.in.logon = &logon;
725 r.out.validation = &validation;
726 r.out.authoritative = &authoritative;
728 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
730 for (i=2;i<3;i++) {
731 ZERO_STRUCT(auth2);
732 netlogon_creds_client_authenticator(creds, &auth);
734 r.in.validation_level = i;
736 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
737 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
739 torture_assert(tctx, netlogon_creds_client_check(creds,
740 &r.out.return_authenticator->cred),
741 "Credential chaining failed");
744 r.in.credential = NULL;
746 for (i=2;i<=3;i++) {
748 r.in.validation_level = i;
750 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
752 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
753 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_INVALID_PARAMETER,
754 "LogonSamLogon expected INVALID_PARAMETER");
758 return true;
762 try a netlogon SamLogon
764 static bool test_SamLogon(struct torture_context *tctx,
765 struct dcerpc_pipe *p,
766 struct cli_credentials *credentials)
768 struct netlogon_creds_CredentialState *creds;
770 if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
771 return false;
774 return test_netlogon_ops(p, tctx, credentials, creds);
777 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
778 static uint64_t sequence_nums[3];
781 try a netlogon DatabaseSync
783 static bool test_DatabaseSync(struct torture_context *tctx,
784 struct dcerpc_pipe *p,
785 struct cli_credentials *machine_credentials)
787 NTSTATUS status;
788 struct netr_DatabaseSync r;
789 struct netlogon_creds_CredentialState *creds;
790 const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
791 int i;
792 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
793 struct netr_Authenticator credential, return_authenticator;
795 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
796 return false;
799 ZERO_STRUCT(return_authenticator);
801 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
802 r.in.computername = TEST_MACHINE_NAME;
803 r.in.preferredmaximumlength = (uint32_t)-1;
804 r.in.return_authenticator = &return_authenticator;
805 r.out.delta_enum_array = &delta_enum_array;
806 r.out.return_authenticator = &return_authenticator;
808 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
810 uint32_t sync_context = 0;
812 r.in.database_id = database_ids[i];
813 r.in.sync_context = &sync_context;
814 r.out.sync_context = &sync_context;
816 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
818 do {
819 netlogon_creds_client_authenticator(creds, &credential);
821 r.in.credential = &credential;
823 status = dcerpc_netr_DatabaseSync(p, tctx, &r);
824 if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
825 break;
827 /* Native mode servers don't do this */
828 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
829 return true;
831 torture_assert_ntstatus_ok(tctx, status, "DatabaseSync");
833 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
834 torture_comment(tctx, "Credential chaining failed\n");
837 if (delta_enum_array &&
838 delta_enum_array->num_deltas > 0 &&
839 delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
840 delta_enum_array->delta_enum[0].delta_union.domain) {
841 sequence_nums[r.in.database_id] =
842 delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
843 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
844 r.in.database_id,
845 (unsigned long long)sequence_nums[r.in.database_id]);
847 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
850 return true;
855 try a netlogon DatabaseDeltas
857 static bool test_DatabaseDeltas(struct torture_context *tctx,
858 struct dcerpc_pipe *p,
859 struct cli_credentials *machine_credentials)
861 NTSTATUS status;
862 struct netr_DatabaseDeltas r;
863 struct netlogon_creds_CredentialState *creds;
864 struct netr_Authenticator credential;
865 struct netr_Authenticator return_authenticator;
866 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
867 const uint32_t database_ids[] = {0, 1, 2};
868 int i;
870 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
871 return false;
874 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
875 r.in.computername = TEST_MACHINE_NAME;
876 r.in.preferredmaximumlength = (uint32_t)-1;
877 ZERO_STRUCT(r.in.return_authenticator);
878 r.out.return_authenticator = &return_authenticator;
879 r.out.delta_enum_array = &delta_enum_array;
881 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
882 r.in.database_id = database_ids[i];
883 r.in.sequence_num = &sequence_nums[r.in.database_id];
885 if (*r.in.sequence_num == 0) continue;
887 *r.in.sequence_num -= 1;
889 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n",
890 r.in.database_id, (unsigned long long)*r.in.sequence_num);
892 do {
893 netlogon_creds_client_authenticator(creds, &credential);
895 status = dcerpc_netr_DatabaseDeltas(p, tctx, &r);
896 if (NT_STATUS_EQUAL(status,
897 NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
898 torture_comment(tctx, "not considering %s to be an error\n",
899 nt_errstr(status));
900 return true;
902 if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
903 break;
905 torture_assert_ntstatus_ok(tctx, status, "DatabaseDeltas");
907 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
908 torture_comment(tctx, "Credential chaining failed\n");
911 (*r.in.sequence_num)++;
912 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
915 return true;
918 static bool test_DatabaseRedo(struct torture_context *tctx,
919 struct dcerpc_pipe *p,
920 struct cli_credentials *machine_credentials)
922 NTSTATUS status;
923 struct netr_DatabaseRedo r;
924 struct netlogon_creds_CredentialState *creds;
925 struct netr_Authenticator credential;
926 struct netr_Authenticator return_authenticator;
927 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
928 struct netr_ChangeLogEntry e;
929 struct dom_sid null_sid, *sid;
930 int i,d;
932 ZERO_STRUCT(null_sid);
934 sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
938 struct {
939 uint32_t rid;
940 uint16_t flags;
941 uint8_t db_index;
942 uint8_t delta_type;
943 struct dom_sid sid;
944 const char *name;
945 NTSTATUS expected_error;
946 uint32_t expected_num_results;
947 uint8_t expected_delta_type_1;
948 uint8_t expected_delta_type_2;
949 const char *comment;
950 } changes[] = {
952 /* SAM_DATABASE_DOMAIN */
955 .rid = 0,
956 .flags = 0,
957 .db_index = SAM_DATABASE_DOMAIN,
958 .delta_type = NETR_DELTA_MODIFY_COUNT,
959 .sid = null_sid,
960 .name = NULL,
961 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
962 .expected_num_results = 0,
963 .comment = "NETR_DELTA_MODIFY_COUNT"
966 .rid = 0,
967 .flags = 0,
968 .db_index = SAM_DATABASE_DOMAIN,
969 .delta_type = 0,
970 .sid = null_sid,
971 .name = NULL,
972 .expected_error = NT_STATUS_OK,
973 .expected_num_results = 1,
974 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
975 .comment = "NULL DELTA"
978 .rid = 0,
979 .flags = 0,
980 .db_index = SAM_DATABASE_DOMAIN,
981 .delta_type = NETR_DELTA_DOMAIN,
982 .sid = null_sid,
983 .name = NULL,
984 .expected_error = NT_STATUS_OK,
985 .expected_num_results = 1,
986 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
987 .comment = "NETR_DELTA_DOMAIN"
990 .rid = DOMAIN_RID_ADMINISTRATOR,
991 .flags = 0,
992 .db_index = SAM_DATABASE_DOMAIN,
993 .delta_type = NETR_DELTA_USER,
994 .sid = null_sid,
995 .name = NULL,
996 .expected_error = NT_STATUS_OK,
997 .expected_num_results = 1,
998 .expected_delta_type_1 = NETR_DELTA_USER,
999 .comment = "NETR_DELTA_USER by rid 500"
1002 .rid = DOMAIN_RID_GUEST,
1003 .flags = 0,
1004 .db_index = SAM_DATABASE_DOMAIN,
1005 .delta_type = NETR_DELTA_USER,
1006 .sid = null_sid,
1007 .name = NULL,
1008 .expected_error = NT_STATUS_OK,
1009 .expected_num_results = 1,
1010 .expected_delta_type_1 = NETR_DELTA_USER,
1011 .comment = "NETR_DELTA_USER by rid 501"
1014 .rid = 0,
1015 .flags = NETR_CHANGELOG_SID_INCLUDED,
1016 .db_index = SAM_DATABASE_DOMAIN,
1017 .delta_type = NETR_DELTA_USER,
1018 .sid = *sid,
1019 .name = NULL,
1020 .expected_error = NT_STATUS_OK,
1021 .expected_num_results = 1,
1022 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1023 .comment = "NETR_DELTA_USER by sid and flags"
1026 .rid = 0,
1027 .flags = NETR_CHANGELOG_SID_INCLUDED,
1028 .db_index = SAM_DATABASE_DOMAIN,
1029 .delta_type = NETR_DELTA_USER,
1030 .sid = null_sid,
1031 .name = NULL,
1032 .expected_error = NT_STATUS_OK,
1033 .expected_num_results = 1,
1034 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1035 .comment = "NETR_DELTA_USER by null_sid and flags"
1038 .rid = 0,
1039 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1040 .db_index = SAM_DATABASE_DOMAIN,
1041 .delta_type = NETR_DELTA_USER,
1042 .sid = null_sid,
1043 .name = "administrator",
1044 .expected_error = NT_STATUS_OK,
1045 .expected_num_results = 1,
1046 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1047 .comment = "NETR_DELTA_USER by name 'administrator'"
1050 .rid = DOMAIN_RID_ADMINS,
1051 .flags = 0,
1052 .db_index = SAM_DATABASE_DOMAIN,
1053 .delta_type = NETR_DELTA_GROUP,
1054 .sid = null_sid,
1055 .name = NULL,
1056 .expected_error = NT_STATUS_OK,
1057 .expected_num_results = 2,
1058 .expected_delta_type_1 = NETR_DELTA_GROUP,
1059 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
1060 .comment = "NETR_DELTA_GROUP by rid 512"
1063 .rid = DOMAIN_RID_ADMINS,
1064 .flags = 0,
1065 .db_index = SAM_DATABASE_DOMAIN,
1066 .delta_type = NETR_DELTA_GROUP_MEMBER,
1067 .sid = null_sid,
1068 .name = NULL,
1069 .expected_error = NT_STATUS_OK,
1070 .expected_num_results = 2,
1071 .expected_delta_type_1 = NETR_DELTA_GROUP,
1072 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
1073 .comment = "NETR_DELTA_GROUP_MEMBER by rid 512"
1077 /* SAM_DATABASE_BUILTIN */
1080 .rid = 0,
1081 .flags = 0,
1082 .db_index = SAM_DATABASE_BUILTIN,
1083 .delta_type = NETR_DELTA_MODIFY_COUNT,
1084 .sid = null_sid,
1085 .name = NULL,
1086 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1087 .expected_num_results = 0,
1088 .comment = "NETR_DELTA_MODIFY_COUNT"
1091 .rid = 0,
1092 .flags = 0,
1093 .db_index = SAM_DATABASE_BUILTIN,
1094 .delta_type = NETR_DELTA_DOMAIN,
1095 .sid = null_sid,
1096 .name = NULL,
1097 .expected_error = NT_STATUS_OK,
1098 .expected_num_results = 1,
1099 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1100 .comment = "NETR_DELTA_DOMAIN"
1103 .rid = DOMAIN_RID_ADMINISTRATOR,
1104 .flags = 0,
1105 .db_index = SAM_DATABASE_BUILTIN,
1106 .delta_type = NETR_DELTA_USER,
1107 .sid = null_sid,
1108 .name = NULL,
1109 .expected_error = NT_STATUS_OK,
1110 .expected_num_results = 1,
1111 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1112 .comment = "NETR_DELTA_USER by rid 500"
1115 .rid = 0,
1116 .flags = 0,
1117 .db_index = SAM_DATABASE_BUILTIN,
1118 .delta_type = NETR_DELTA_USER,
1119 .sid = null_sid,
1120 .name = NULL,
1121 .expected_error = NT_STATUS_OK,
1122 .expected_num_results = 1,
1123 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1124 .comment = "NETR_DELTA_USER"
1127 .rid = 544,
1128 .flags = 0,
1129 .db_index = SAM_DATABASE_BUILTIN,
1130 .delta_type = NETR_DELTA_ALIAS,
1131 .sid = null_sid,
1132 .name = NULL,
1133 .expected_error = NT_STATUS_OK,
1134 .expected_num_results = 2,
1135 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1136 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1137 .comment = "NETR_DELTA_ALIAS by rid 544"
1140 .rid = 544,
1141 .flags = 0,
1142 .db_index = SAM_DATABASE_BUILTIN,
1143 .delta_type = NETR_DELTA_ALIAS_MEMBER,
1144 .sid = null_sid,
1145 .name = NULL,
1146 .expected_error = NT_STATUS_OK,
1147 .expected_num_results = 2,
1148 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1149 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1150 .comment = "NETR_DELTA_ALIAS_MEMBER by rid 544"
1153 .rid = 544,
1154 .flags = 0,
1155 .db_index = SAM_DATABASE_BUILTIN,
1156 .delta_type = 0,
1157 .sid = null_sid,
1158 .name = NULL,
1159 .expected_error = NT_STATUS_OK,
1160 .expected_num_results = 1,
1161 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1162 .comment = "NULL DELTA by rid 544"
1165 .rid = 544,
1166 .flags = NETR_CHANGELOG_SID_INCLUDED,
1167 .db_index = SAM_DATABASE_BUILTIN,
1168 .delta_type = 0,
1169 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1170 .name = NULL,
1171 .expected_error = NT_STATUS_OK,
1172 .expected_num_results = 1,
1173 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1174 .comment = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
1177 .rid = 544,
1178 .flags = NETR_CHANGELOG_SID_INCLUDED,
1179 .db_index = SAM_DATABASE_BUILTIN,
1180 .delta_type = NETR_DELTA_ALIAS,
1181 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1182 .name = NULL,
1183 .expected_error = NT_STATUS_OK,
1184 .expected_num_results = 2,
1185 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1186 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1187 .comment = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
1190 .rid = 0,
1191 .flags = NETR_CHANGELOG_SID_INCLUDED,
1192 .db_index = SAM_DATABASE_BUILTIN,
1193 .delta_type = NETR_DELTA_ALIAS,
1194 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1195 .name = NULL,
1196 .expected_error = NT_STATUS_OK,
1197 .expected_num_results = 1,
1198 .expected_delta_type_1 = NETR_DELTA_DELETE_ALIAS,
1199 .comment = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
1202 /* SAM_DATABASE_PRIVS */
1205 .rid = 0,
1206 .flags = 0,
1207 .db_index = SAM_DATABASE_PRIVS,
1208 .delta_type = 0,
1209 .sid = null_sid,
1210 .name = NULL,
1211 .expected_error = NT_STATUS_ACCESS_DENIED,
1212 .expected_num_results = 0,
1213 .comment = "NULL DELTA"
1216 .rid = 0,
1217 .flags = 0,
1218 .db_index = SAM_DATABASE_PRIVS,
1219 .delta_type = NETR_DELTA_MODIFY_COUNT,
1220 .sid = null_sid,
1221 .name = NULL,
1222 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1223 .expected_num_results = 0,
1224 .comment = "NETR_DELTA_MODIFY_COUNT"
1227 .rid = 0,
1228 .flags = 0,
1229 .db_index = SAM_DATABASE_PRIVS,
1230 .delta_type = NETR_DELTA_POLICY,
1231 .sid = null_sid,
1232 .name = NULL,
1233 .expected_error = NT_STATUS_OK,
1234 .expected_num_results = 1,
1235 .expected_delta_type_1 = NETR_DELTA_POLICY,
1236 .comment = "NETR_DELTA_POLICY"
1239 .rid = 0,
1240 .flags = NETR_CHANGELOG_SID_INCLUDED,
1241 .db_index = SAM_DATABASE_PRIVS,
1242 .delta_type = NETR_DELTA_POLICY,
1243 .sid = null_sid,
1244 .name = NULL,
1245 .expected_error = NT_STATUS_OK,
1246 .expected_num_results = 1,
1247 .expected_delta_type_1 = NETR_DELTA_POLICY,
1248 .comment = "NETR_DELTA_POLICY by null sid and flags"
1251 .rid = 0,
1252 .flags = NETR_CHANGELOG_SID_INCLUDED,
1253 .db_index = SAM_DATABASE_PRIVS,
1254 .delta_type = NETR_DELTA_POLICY,
1255 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
1256 .name = NULL,
1257 .expected_error = NT_STATUS_OK,
1258 .expected_num_results = 1,
1259 .expected_delta_type_1 = NETR_DELTA_POLICY,
1260 .comment = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
1263 .rid = DOMAIN_RID_ADMINISTRATOR,
1264 .flags = 0,
1265 .db_index = SAM_DATABASE_PRIVS,
1266 .delta_type = NETR_DELTA_ACCOUNT,
1267 .sid = null_sid,
1268 .name = NULL,
1269 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
1270 .expected_num_results = 0,
1271 .comment = "NETR_DELTA_ACCOUNT by rid 500"
1274 .rid = 0,
1275 .flags = NETR_CHANGELOG_SID_INCLUDED,
1276 .db_index = SAM_DATABASE_PRIVS,
1277 .delta_type = NETR_DELTA_ACCOUNT,
1278 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1279 .name = NULL,
1280 .expected_error = NT_STATUS_OK,
1281 .expected_num_results = 1,
1282 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
1283 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
1286 .rid = 0,
1287 .flags = NETR_CHANGELOG_SID_INCLUDED |
1288 NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
1289 .db_index = SAM_DATABASE_PRIVS,
1290 .delta_type = NETR_DELTA_ACCOUNT,
1291 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1292 .name = NULL,
1293 .expected_error = NT_STATUS_OK,
1294 .expected_num_results = 1,
1295 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
1296 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
1299 .rid = 0,
1300 .flags = NETR_CHANGELOG_SID_INCLUDED |
1301 NETR_CHANGELOG_NAME_INCLUDED,
1302 .db_index = SAM_DATABASE_PRIVS,
1303 .delta_type = NETR_DELTA_ACCOUNT,
1304 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1305 .name = NULL,
1306 .expected_error = NT_STATUS_INVALID_PARAMETER,
1307 .expected_num_results = 0,
1308 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
1311 .rid = DOMAIN_RID_ADMINISTRATOR,
1312 .flags = NETR_CHANGELOG_SID_INCLUDED,
1313 .db_index = SAM_DATABASE_PRIVS,
1314 .delta_type = NETR_DELTA_ACCOUNT,
1315 .sid = *sid,
1316 .name = NULL,
1317 .expected_error = NT_STATUS_OK,
1318 .expected_num_results = 1,
1319 .expected_delta_type_1 = NETR_DELTA_DELETE_ACCOUNT,
1320 .comment = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
1323 .rid = 0,
1324 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1325 .db_index = SAM_DATABASE_PRIVS,
1326 .delta_type = NETR_DELTA_SECRET,
1327 .sid = null_sid,
1328 .name = "IsurelydontexistIhope",
1329 .expected_error = NT_STATUS_OK,
1330 .expected_num_results = 1,
1331 .expected_delta_type_1 = NETR_DELTA_DELETE_SECRET,
1332 .comment = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
1335 .rid = 0,
1336 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1337 .db_index = SAM_DATABASE_PRIVS,
1338 .delta_type = NETR_DELTA_SECRET,
1339 .sid = null_sid,
1340 .name = "G$BCKUPKEY_P",
1341 .expected_error = NT_STATUS_OK,
1342 .expected_num_results = 1,
1343 .expected_delta_type_1 = NETR_DELTA_SECRET,
1344 .comment = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
1348 ZERO_STRUCT(return_authenticator);
1350 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1351 r.in.computername = TEST_MACHINE_NAME;
1352 r.in.return_authenticator = &return_authenticator;
1353 r.out.return_authenticator = &return_authenticator;
1354 r.out.delta_enum_array = &delta_enum_array;
1356 for (d=0; d<3; d++) {
1358 const char *database;
1360 switch (d) {
1361 case 0:
1362 database = "SAM";
1363 break;
1364 case 1:
1365 database = "BUILTIN";
1366 break;
1367 case 2:
1368 database = "LSA";
1369 break;
1370 default:
1371 break;
1374 torture_comment(tctx, "Testing DatabaseRedo\n");
1376 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1377 return false;
1380 for (i=0;i<ARRAY_SIZE(changes);i++) {
1382 if (d != changes[i].db_index) {
1383 continue;
1386 netlogon_creds_client_authenticator(creds, &credential);
1388 r.in.credential = &credential;
1390 e.serial_number1 = 0;
1391 e.serial_number2 = 0;
1392 e.object_rid = changes[i].rid;
1393 e.flags = changes[i].flags;
1394 e.db_index = changes[i].db_index;
1395 e.delta_type = changes[i].delta_type;
1397 switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
1398 case NETR_CHANGELOG_SID_INCLUDED:
1399 e.object.object_sid = changes[i].sid;
1400 break;
1401 case NETR_CHANGELOG_NAME_INCLUDED:
1402 e.object.object_name = changes[i].name;
1403 break;
1404 default:
1405 break;
1408 r.in.change_log_entry = e;
1410 torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
1411 database, changes[i].comment);
1413 status = dcerpc_netr_DatabaseRedo(p, tctx, &r);
1414 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1415 return true;
1418 torture_assert_ntstatus_equal(tctx, status, changes[i].expected_error, changes[i].comment);
1419 if (delta_enum_array) {
1420 torture_assert_int_equal(tctx,
1421 delta_enum_array->num_deltas,
1422 changes[i].expected_num_results,
1423 changes[i].comment);
1424 if (delta_enum_array->num_deltas > 0) {
1425 torture_assert_int_equal(tctx,
1426 delta_enum_array->delta_enum[0].delta_type,
1427 changes[i].expected_delta_type_1,
1428 changes[i].comment);
1430 if (delta_enum_array->num_deltas > 1) {
1431 torture_assert_int_equal(tctx,
1432 delta_enum_array->delta_enum[1].delta_type,
1433 changes[i].expected_delta_type_2,
1434 changes[i].comment);
1438 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1439 torture_comment(tctx, "Credential chaining failed\n");
1440 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1441 return false;
1448 return true;
1452 try a netlogon AccountDeltas
1454 static bool test_AccountDeltas(struct torture_context *tctx,
1455 struct dcerpc_pipe *p,
1456 struct cli_credentials *machine_credentials)
1458 NTSTATUS status;
1459 struct netr_AccountDeltas r;
1460 struct netlogon_creds_CredentialState *creds;
1462 struct netr_AccountBuffer buffer;
1463 uint32_t count_returned = 0;
1464 uint32_t total_entries = 0;
1465 struct netr_UAS_INFO_0 recordid;
1466 struct netr_Authenticator return_authenticator;
1468 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1469 return false;
1472 ZERO_STRUCT(return_authenticator);
1474 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1475 r.in.computername = TEST_MACHINE_NAME;
1476 r.in.return_authenticator = &return_authenticator;
1477 netlogon_creds_client_authenticator(creds, &r.in.credential);
1478 ZERO_STRUCT(r.in.uas);
1479 r.in.count=10;
1480 r.in.level=0;
1481 r.in.buffersize=100;
1482 r.out.buffer = &buffer;
1483 r.out.count_returned = &count_returned;
1484 r.out.total_entries = &total_entries;
1485 r.out.recordid = &recordid;
1486 r.out.return_authenticator = &return_authenticator;
1488 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1489 status = dcerpc_netr_AccountDeltas(p, tctx, &r);
1490 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
1492 return true;
1496 try a netlogon AccountSync
1498 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
1499 struct cli_credentials *machine_credentials)
1501 NTSTATUS status;
1502 struct netr_AccountSync r;
1503 struct netlogon_creds_CredentialState *creds;
1505 struct netr_AccountBuffer buffer;
1506 uint32_t count_returned = 0;
1507 uint32_t total_entries = 0;
1508 uint32_t next_reference = 0;
1509 struct netr_UAS_INFO_0 recordid;
1510 struct netr_Authenticator return_authenticator;
1512 ZERO_STRUCT(recordid);
1513 ZERO_STRUCT(return_authenticator);
1515 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1516 return false;
1519 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1520 r.in.computername = TEST_MACHINE_NAME;
1521 r.in.return_authenticator = &return_authenticator;
1522 netlogon_creds_client_authenticator(creds, &r.in.credential);
1523 r.in.recordid = &recordid;
1524 r.in.reference=0;
1525 r.in.level=0;
1526 r.in.buffersize=100;
1527 r.out.buffer = &buffer;
1528 r.out.count_returned = &count_returned;
1529 r.out.total_entries = &total_entries;
1530 r.out.next_reference = &next_reference;
1531 r.out.recordid = &recordid;
1532 r.out.return_authenticator = &return_authenticator;
1534 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1535 status = dcerpc_netr_AccountSync(p, tctx, &r);
1536 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
1538 return true;
1542 try a netlogon GetDcName
1544 static bool test_GetDcName(struct torture_context *tctx,
1545 struct dcerpc_pipe *p)
1547 NTSTATUS status;
1548 struct netr_GetDcName r;
1549 const char *dcname = NULL;
1551 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1552 r.in.domainname = lp_workgroup(tctx->lp_ctx);
1553 r.out.dcname = &dcname;
1555 status = dcerpc_netr_GetDcName(p, tctx, &r);
1556 torture_assert_ntstatus_ok(tctx, status, "GetDcName");
1557 torture_assert_werr_ok(tctx, r.out.result, "GetDcName");
1559 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1561 return true;
1564 static const char *function_code_str(TALLOC_CTX *mem_ctx,
1565 enum netr_LogonControlCode function_code)
1567 switch (function_code) {
1568 case NETLOGON_CONTROL_QUERY:
1569 return "NETLOGON_CONTROL_QUERY";
1570 case NETLOGON_CONTROL_REPLICATE:
1571 return "NETLOGON_CONTROL_REPLICATE";
1572 case NETLOGON_CONTROL_SYNCHRONIZE:
1573 return "NETLOGON_CONTROL_SYNCHRONIZE";
1574 case NETLOGON_CONTROL_PDC_REPLICATE:
1575 return "NETLOGON_CONTROL_PDC_REPLICATE";
1576 case NETLOGON_CONTROL_REDISCOVER:
1577 return "NETLOGON_CONTROL_REDISCOVER";
1578 case NETLOGON_CONTROL_TC_QUERY:
1579 return "NETLOGON_CONTROL_TC_QUERY";
1580 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1581 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
1582 case NETLOGON_CONTROL_FIND_USER:
1583 return "NETLOGON_CONTROL_FIND_USER";
1584 case NETLOGON_CONTROL_CHANGE_PASSWORD:
1585 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
1586 case NETLOGON_CONTROL_TC_VERIFY:
1587 return "NETLOGON_CONTROL_TC_VERIFY";
1588 case NETLOGON_CONTROL_FORCE_DNS_REG:
1589 return "NETLOGON_CONTROL_FORCE_DNS_REG";
1590 case NETLOGON_CONTROL_QUERY_DNS_REG:
1591 return "NETLOGON_CONTROL_QUERY_DNS_REG";
1592 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1593 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
1594 case NETLOGON_CONTROL_TRUNCATE_LOG:
1595 return "NETLOGON_CONTROL_TRUNCATE_LOG";
1596 case NETLOGON_CONTROL_SET_DBFLAG:
1597 return "NETLOGON_CONTROL_SET_DBFLAG";
1598 case NETLOGON_CONTROL_BREAKPOINT:
1599 return "NETLOGON_CONTROL_BREAKPOINT";
1600 default:
1601 return talloc_asprintf(mem_ctx, "unknown function code: %d",
1602 function_code);
1608 try a netlogon LogonControl
1610 static bool test_LogonControl(struct torture_context *tctx,
1611 struct dcerpc_pipe *p)
1613 NTSTATUS status;
1614 struct netr_LogonControl r;
1615 union netr_CONTROL_QUERY_INFORMATION query;
1616 int i,f;
1617 uint32_t function_codes[] = {
1618 NETLOGON_CONTROL_QUERY,
1619 NETLOGON_CONTROL_REPLICATE,
1620 NETLOGON_CONTROL_SYNCHRONIZE,
1621 NETLOGON_CONTROL_PDC_REPLICATE,
1622 NETLOGON_CONTROL_REDISCOVER,
1623 NETLOGON_CONTROL_TC_QUERY,
1624 NETLOGON_CONTROL_TRANSPORT_NOTIFY,
1625 NETLOGON_CONTROL_FIND_USER,
1626 NETLOGON_CONTROL_CHANGE_PASSWORD,
1627 NETLOGON_CONTROL_TC_VERIFY,
1628 NETLOGON_CONTROL_FORCE_DNS_REG,
1629 NETLOGON_CONTROL_QUERY_DNS_REG,
1630 NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
1631 NETLOGON_CONTROL_TRUNCATE_LOG,
1632 NETLOGON_CONTROL_SET_DBFLAG,
1633 NETLOGON_CONTROL_BREAKPOINT
1636 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1637 r.in.function_code = 1;
1638 r.out.query = &query;
1640 for (f=0;f<ARRAY_SIZE(function_codes); f++) {
1641 for (i=1;i<5;i++) {
1643 r.in.function_code = function_codes[f];
1644 r.in.level = i;
1646 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
1647 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1649 status = dcerpc_netr_LogonControl(p, tctx, &r);
1650 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1652 switch (r.in.level) {
1653 case 1:
1654 switch (r.in.function_code) {
1655 case NETLOGON_CONTROL_REPLICATE:
1656 case NETLOGON_CONTROL_SYNCHRONIZE:
1657 case NETLOGON_CONTROL_PDC_REPLICATE:
1658 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1659 case NETLOGON_CONTROL_TRUNCATE_LOG:
1660 case NETLOGON_CONTROL_BREAKPOINT:
1661 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1662 "LogonControl returned unexpected error code");
1663 break;
1664 case NETLOGON_CONTROL_REDISCOVER:
1665 case NETLOGON_CONTROL_TC_QUERY:
1666 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1667 case NETLOGON_CONTROL_FIND_USER:
1668 case NETLOGON_CONTROL_CHANGE_PASSWORD:
1669 case NETLOGON_CONTROL_TC_VERIFY:
1670 case NETLOGON_CONTROL_FORCE_DNS_REG:
1671 case NETLOGON_CONTROL_QUERY_DNS_REG:
1672 case NETLOGON_CONTROL_SET_DBFLAG:
1673 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1674 "LogonControl returned unexpected error code");
1675 break;
1676 default:
1677 torture_assert_werr_ok(tctx, r.out.result,
1678 "LogonControl returned unexpected result");
1679 break;
1681 break;
1682 case 2:
1683 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1684 "LogonControl returned unexpected error code");
1685 break;
1686 default:
1687 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL,
1688 "LogonControl returned unexpected error code");
1689 break;
1694 return true;
1699 try a netlogon GetAnyDCName
1701 static bool test_GetAnyDCName(struct torture_context *tctx,
1702 struct dcerpc_pipe *p)
1704 NTSTATUS status;
1705 struct netr_GetAnyDCName r;
1706 const char *dcname = NULL;
1708 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1709 r.in.domainname = lp_workgroup(tctx->lp_ctx);
1710 r.out.dcname = &dcname;
1712 status = dcerpc_netr_GetAnyDCName(p, tctx, &r);
1713 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
1714 torture_assert_werr_ok(tctx, r.out.result, "GetAnyDCName");
1716 if (dcname) {
1717 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1720 return true;
1725 try a netlogon LogonControl2
1727 static bool test_LogonControl2(struct torture_context *tctx,
1728 struct dcerpc_pipe *p)
1730 NTSTATUS status;
1731 struct netr_LogonControl2 r;
1732 union netr_CONTROL_DATA_INFORMATION data;
1733 union netr_CONTROL_QUERY_INFORMATION query;
1734 int i;
1736 data.domain = lp_workgroup(tctx->lp_ctx);
1738 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1740 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1741 r.in.data = &data;
1742 r.out.query = &query;
1744 for (i=1;i<4;i++) {
1745 r.in.level = i;
1747 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1748 i, r.in.function_code);
1750 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1751 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1754 data.domain = lp_workgroup(tctx->lp_ctx);
1756 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1757 r.in.data = &data;
1759 for (i=1;i<4;i++) {
1760 r.in.level = i;
1762 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1763 i, r.in.function_code);
1765 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1766 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1769 data.domain = lp_workgroup(tctx->lp_ctx);
1771 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1772 r.in.data = &data;
1774 for (i=1;i<4;i++) {
1775 r.in.level = i;
1777 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1778 i, r.in.function_code);
1780 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1781 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1784 data.debug_level = ~0;
1786 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1787 r.in.data = &data;
1789 for (i=1;i<4;i++) {
1790 r.in.level = i;
1792 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1793 i, r.in.function_code);
1795 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1796 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1799 return true;
1803 try a netlogon DatabaseSync2
1805 static bool test_DatabaseSync2(struct torture_context *tctx,
1806 struct dcerpc_pipe *p,
1807 struct cli_credentials *machine_credentials)
1809 NTSTATUS status;
1810 struct netr_DatabaseSync2 r;
1811 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1812 struct netr_Authenticator return_authenticator, credential;
1814 struct netlogon_creds_CredentialState *creds;
1815 const uint32_t database_ids[] = {0, 1, 2};
1816 int i;
1818 if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
1819 machine_credentials,
1820 cli_credentials_get_secure_channel_type(machine_credentials),
1821 &creds)) {
1822 return false;
1825 ZERO_STRUCT(return_authenticator);
1827 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1828 r.in.computername = TEST_MACHINE_NAME;
1829 r.in.preferredmaximumlength = (uint32_t)-1;
1830 r.in.return_authenticator = &return_authenticator;
1831 r.out.return_authenticator = &return_authenticator;
1832 r.out.delta_enum_array = &delta_enum_array;
1834 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1836 uint32_t sync_context = 0;
1838 r.in.database_id = database_ids[i];
1839 r.in.sync_context = &sync_context;
1840 r.out.sync_context = &sync_context;
1841 r.in.restart_state = 0;
1843 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
1845 do {
1846 netlogon_creds_client_authenticator(creds, &credential);
1848 r.in.credential = &credential;
1850 status = dcerpc_netr_DatabaseSync2(p, tctx, &r);
1851 if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
1852 break;
1854 /* Native mode servers don't do this */
1855 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1856 return true;
1859 torture_assert_ntstatus_ok(tctx, status, "DatabaseSync2");
1861 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1862 torture_comment(tctx, "Credential chaining failed\n");
1865 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
1868 return true;
1873 try a netlogon LogonControl2Ex
1875 static bool test_LogonControl2Ex(struct torture_context *tctx,
1876 struct dcerpc_pipe *p)
1878 NTSTATUS status;
1879 struct netr_LogonControl2Ex r;
1880 union netr_CONTROL_DATA_INFORMATION data;
1881 union netr_CONTROL_QUERY_INFORMATION query;
1882 int i;
1884 data.domain = lp_workgroup(tctx->lp_ctx);
1886 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1888 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1889 r.in.data = &data;
1890 r.out.query = &query;
1892 for (i=1;i<4;i++) {
1893 r.in.level = i;
1895 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
1896 i, r.in.function_code);
1898 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1899 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1902 data.domain = lp_workgroup(tctx->lp_ctx);
1904 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1905 r.in.data = &data;
1907 for (i=1;i<4;i++) {
1908 r.in.level = i;
1910 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
1911 i, r.in.function_code);
1913 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1914 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1917 data.domain = lp_workgroup(tctx->lp_ctx);
1919 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1920 r.in.data = &data;
1922 for (i=1;i<4;i++) {
1923 r.in.level = i;
1925 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
1926 i, r.in.function_code);
1928 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1929 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1932 data.debug_level = ~0;
1934 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1935 r.in.data = &data;
1937 for (i=1;i<4;i++) {
1938 r.in.level = i;
1940 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
1941 i, r.in.function_code);
1943 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1944 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1947 return true;
1950 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
1951 struct dcerpc_pipe *p, const char *trusted_domain_name)
1953 NTSTATUS status;
1954 struct netr_DsRGetForestTrustInformation r;
1955 struct lsa_ForestTrustInformation info, *info_ptr;
1957 info_ptr = &info;
1959 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1960 r.in.trusted_domain_name = trusted_domain_name;
1961 r.in.flags = 0;
1962 r.out.forest_trust_info = &info_ptr;
1964 torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
1966 status = dcerpc_netr_DsRGetForestTrustInformation(p, tctx, &r);
1967 torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
1968 torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
1970 return true;
1974 try a netlogon netr_DsrEnumerateDomainTrusts
1976 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
1977 struct dcerpc_pipe *p)
1979 NTSTATUS status;
1980 struct netr_DsrEnumerateDomainTrusts r;
1981 struct netr_DomainTrustList trusts;
1982 int i;
1984 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1985 r.in.trust_flags = 0x3f;
1986 r.out.trusts = &trusts;
1988 status = dcerpc_netr_DsrEnumerateDomainTrusts(p, tctx, &r);
1989 torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
1990 torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
1992 /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
1993 * will show non-forest trusts and all UPN suffixes of the own forest
1994 * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
1996 if (r.out.trusts->count) {
1997 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
1998 return false;
2002 for (i=0; i<r.out.trusts->count; i++) {
2004 /* get info for transitive forest trusts */
2006 if (r.out.trusts->array[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2007 if (!test_netr_DsRGetForestTrustInformation(tctx, p,
2008 r.out.trusts->array[i].dns_name)) {
2009 return false;
2014 return true;
2017 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
2018 struct dcerpc_pipe *p)
2020 NTSTATUS status;
2021 struct netr_NetrEnumerateTrustedDomains r;
2022 struct netr_Blob trusted_domains_blob;
2024 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2025 r.out.trusted_domains_blob = &trusted_domains_blob;
2027 status = dcerpc_netr_NetrEnumerateTrustedDomains(p, tctx, &r);
2028 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
2029 torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
2031 return true;
2034 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
2035 struct dcerpc_pipe *p)
2037 NTSTATUS status;
2038 struct netr_NetrEnumerateTrustedDomainsEx r;
2039 struct netr_DomainTrustList dom_trust_list;
2041 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2042 r.out.dom_trust_list = &dom_trust_list;
2044 status = dcerpc_netr_NetrEnumerateTrustedDomainsEx(p, tctx, &r);
2045 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
2046 torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
2048 return true;
2052 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
2053 const char *computer_name,
2054 const char *expected_site)
2056 NTSTATUS status;
2057 struct netr_DsRGetSiteName r;
2058 const char *site = NULL;
2060 if (torture_setting_bool(tctx, "samba4", false))
2061 torture_skip(tctx, "skipping DsRGetSiteName test against Samba4");
2063 r.in.computer_name = computer_name;
2064 r.out.site = &site;
2065 torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
2067 status = dcerpc_netr_DsRGetSiteName(p, tctx, &r);
2068 torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2069 torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
2070 torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
2072 r.in.computer_name = talloc_asprintf(tctx, "\\\\%s", computer_name);
2073 torture_comment(tctx,
2074 "Testing netr_DsRGetSiteName with broken computer name: %s\n", r.in.computer_name);
2076 status = dcerpc_netr_DsRGetSiteName(p, tctx, &r);
2077 torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2078 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_COMPUTERNAME, "netr_DsRGetSiteName");
2080 return true;
2084 try a netlogon netr_DsRGetDCName
2086 static bool test_netr_DsRGetDCName(struct torture_context *tctx,
2087 struct dcerpc_pipe *p)
2089 NTSTATUS status;
2090 struct netr_DsRGetDCName r;
2091 struct netr_DsRGetDCNameInfo *info = NULL;
2093 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2094 r.in.domain_name = lp_dnsdomain(tctx->lp_ctx);
2095 r.in.domain_guid = NULL;
2096 r.in.site_guid = NULL;
2097 r.in.flags = DS_RETURN_DNS_NAME;
2098 r.out.info = &info;
2100 status = dcerpc_netr_DsRGetDCName(p, tctx, &r);
2101 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2102 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2103 return test_netr_DsRGetSiteName(p, tctx,
2104 info->dc_unc,
2105 info->dc_site_name);
2109 try a netlogon netr_DsRGetDCNameEx
2111 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
2112 struct dcerpc_pipe *p)
2114 NTSTATUS status;
2115 struct netr_DsRGetDCNameEx r;
2116 struct netr_DsRGetDCNameInfo *info = NULL;
2118 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2119 r.in.domain_name = lp_dnsdomain(tctx->lp_ctx);
2120 r.in.domain_guid = NULL;
2121 r.in.site_name = NULL;
2122 r.in.flags = DS_RETURN_DNS_NAME;
2123 r.out.info = &info;
2125 status = dcerpc_netr_DsRGetDCNameEx(p, tctx, &r);
2126 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2127 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2129 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2130 info->dc_site_name);
2134 try a netlogon netr_DsRGetDCNameEx2
2136 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
2137 struct dcerpc_pipe *p)
2139 NTSTATUS status;
2140 struct netr_DsRGetDCNameEx2 r;
2141 struct netr_DsRGetDCNameInfo *info = NULL;
2143 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2144 r.in.client_account = NULL;
2145 r.in.mask = 0x00000000;
2146 r.in.domain_name = lp_dnsdomain(tctx->lp_ctx);
2147 r.in.domain_guid = NULL;
2148 r.in.site_name = NULL;
2149 r.in.flags = DS_RETURN_DNS_NAME;
2150 r.out.info = &info;
2152 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
2154 status = dcerpc_netr_DsRGetDCNameEx2(p, tctx, &r);
2155 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2156 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2158 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client acount\n");
2159 r.in.client_account = TEST_MACHINE_NAME"$";
2160 r.in.mask = ACB_SVRTRUST;
2161 r.in.flags = DS_RETURN_FLAT_NAME;
2162 r.out.info = &info;
2164 status = dcerpc_netr_DsRGetDCNameEx2(p, tctx, &r);
2165 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2166 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2167 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2168 info->dc_site_name);
2171 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
2172 struct dcerpc_pipe *p)
2174 NTSTATUS status;
2175 struct netr_DsrGetDcSiteCoverageW r;
2176 struct DcSitesCtr *ctr = NULL;
2178 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2179 r.out.ctr = &ctr;
2181 status = dcerpc_netr_DsrGetDcSiteCoverageW(p, tctx, &r);
2182 torture_assert_ntstatus_ok(tctx, status, "failed");
2183 torture_assert_werr_ok(tctx, r.out.result, "failed");
2185 return true;
2188 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
2189 struct dcerpc_pipe *p)
2191 NTSTATUS status;
2192 struct netr_DsRAddressToSitenamesW r;
2193 struct netr_DsRAddress addr;
2194 struct netr_DsRAddressToSitenamesWCtr *ctr;
2196 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
2198 addr.size = 16;
2199 addr.buffer = talloc_zero_array(tctx, uint8_t, addr.size);
2201 addr.buffer[0] = 2; /* AF_INET */
2202 addr.buffer[4] = 127;
2203 addr.buffer[5] = 0;
2204 addr.buffer[6] = 0;
2205 addr.buffer[7] = 1;
2207 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2208 r.in.count = 1;
2209 r.in.addresses = talloc_zero_array(tctx, struct netr_DsRAddress, r.in.count);
2210 r.in.addresses[0] = addr;
2211 r.out.ctr = &ctr;
2213 status = dcerpc_netr_DsRAddressToSitenamesW(p, tctx, &r);
2214 torture_assert_ntstatus_ok(tctx, status, "failed");
2215 torture_assert_werr_ok(tctx, r.out.result, "failed");
2217 return true;
2220 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
2221 struct dcerpc_pipe *p)
2223 NTSTATUS status;
2224 struct netr_DsRAddressToSitenamesExW r;
2225 struct netr_DsRAddress addr;
2226 struct netr_DsRAddressToSitenamesExWCtr *ctr;
2228 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
2230 addr.size = 16;
2231 addr.buffer = talloc_zero_array(tctx, uint8_t, addr.size);
2233 addr.buffer[0] = 2; /* AF_INET */
2234 addr.buffer[4] = 127;
2235 addr.buffer[5] = 0;
2236 addr.buffer[6] = 0;
2237 addr.buffer[7] = 1;
2239 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2240 r.in.count = 1;
2241 r.in.addresses = talloc_zero_array(tctx, struct netr_DsRAddress, r.in.count);
2242 r.in.addresses[0] = addr;
2243 r.out.ctr = &ctr;
2245 status = dcerpc_netr_DsRAddressToSitenamesExW(p, tctx, &r);
2246 torture_assert_ntstatus_ok(tctx, status, "failed");
2247 torture_assert_werr_ok(tctx, r.out.result, "failed");
2249 return true;
2252 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
2253 struct dcerpc_pipe *p,
2254 struct cli_credentials *machine_credentials)
2256 NTSTATUS status;
2257 struct netr_ServerGetTrustInfo r;
2259 struct netr_Authenticator a;
2260 struct netr_Authenticator return_authenticator;
2261 struct samr_Password new_owf_password;
2262 struct samr_Password old_owf_password;
2263 struct netr_TrustInfo *trust_info;
2265 struct netlogon_creds_CredentialState *creds;
2267 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2268 machine_credentials, &creds)) {
2269 return false;
2272 netlogon_creds_client_authenticator(creds, &a);
2274 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2275 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
2276 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2277 r.in.computer_name = TEST_MACHINE_NAME;
2278 r.in.credential = &a;
2280 r.out.return_authenticator = &return_authenticator;
2281 r.out.new_owf_password = &new_owf_password;
2282 r.out.old_owf_password = &old_owf_password;
2283 r.out.trust_info = &trust_info;
2285 status = dcerpc_netr_ServerGetTrustInfo(p, tctx, &r);
2286 torture_assert_ntstatus_ok(tctx, status, "failed");
2287 torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
2289 return true;
2293 static bool test_GetDomainInfo(struct torture_context *tctx,
2294 struct dcerpc_pipe *p,
2295 struct cli_credentials *machine_credentials)
2297 NTSTATUS status;
2298 struct netr_LogonGetDomainInfo r;
2299 struct netr_WorkstationInformation q1;
2300 struct netr_Authenticator a;
2301 struct netlogon_creds_CredentialState *creds;
2302 struct netr_OsVersion os;
2303 union netr_WorkstationInfo query;
2304 union netr_DomainInfo info;
2305 const char* const attrs[] = { "dNSHostName", "operatingSystem",
2306 "operatingSystemServicePack", "operatingSystemVersion",
2307 "servicePrincipalName", NULL };
2308 char *url;
2309 struct ldb_context *sam_ctx = NULL;
2310 struct ldb_message **res;
2311 struct ldb_message_element *spn_el;
2312 int ret, i;
2313 char *version_str;
2314 const char *old_dnsname = NULL;
2315 char **spns = NULL;
2316 int num_spns = 0;
2317 char *temp_str;
2319 torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
2321 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2322 machine_credentials, &creds)) {
2323 return false;
2326 /* We won't double-check this when we are over 'local' transports */
2327 if (dcerpc_server_name(p)) {
2328 /* Set up connection to SAMDB on DC */
2329 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2330 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2331 NULL,
2332 cmdline_credentials,
2335 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2338 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
2339 netlogon_creds_client_authenticator(creds, &a);
2341 ZERO_STRUCT(r);
2342 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2343 r.in.computer_name = TEST_MACHINE_NAME;
2344 r.in.credential = &a;
2345 r.in.level = 1;
2346 r.in.return_authenticator = &a;
2347 r.in.query = &query;
2348 r.out.return_authenticator = &a;
2349 r.out.info = &info;
2351 ZERO_STRUCT(os);
2352 os.os.MajorVersion = 123;
2353 os.os.MinorVersion = 456;
2354 os.os.BuildNumber = 789;
2355 os.os.CSDVersion = "Service Pack 10";
2356 os.os.ServicePackMajor = 10;
2357 os.os.ServicePackMinor = 1;
2358 os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
2359 os.os.ProductType = NETR_VER_NT_SERVER;
2360 os.os.Reserved = 0;
2362 version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
2363 os.os.MinorVersion, os.os.BuildNumber);
2365 ZERO_STRUCT(q1);
2366 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
2367 TEST_MACHINE_DNS_SUFFIX);
2368 q1.sitename = "Default-First-Site-Name";
2369 q1.os_version.os = &os;
2370 q1.os_name.string = talloc_asprintf(tctx,
2371 "Tortured by Samba4 RPC-NETLOGON: %s",
2372 timestring(tctx, time(NULL)));
2374 /* The workstation handles the "servicePrincipalName" and DNS hostname
2375 updates */
2376 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
2378 query.workstation_info = &q1;
2380 if (sam_ctx) {
2381 /* Gets back the old DNS hostname in AD */
2382 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2383 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2384 old_dnsname =
2385 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
2387 /* Gets back the "servicePrincipalName"s in AD */
2388 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2389 if (spn_el != NULL) {
2390 for (i=0; i < spn_el->num_values; i++) {
2391 spns = talloc_realloc(tctx, spns, char *, i + 1);
2392 spns[i] = (char *) spn_el->values[i].data;
2394 num_spns = i;
2398 status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2399 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2400 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2402 msleep(250);
2404 if (sam_ctx) {
2405 /* AD workstation infos entry check */
2406 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2407 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2408 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
2409 torture_assert_str_equal(tctx,
2410 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
2411 q1.os_name.string, "'operatingSystem' wrong!");
2412 torture_assert_str_equal(tctx,
2413 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
2414 os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
2415 torture_assert_str_equal(tctx,
2416 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
2417 version_str, "'operatingSystemVersion' wrong!");
2419 if (old_dnsname != NULL) {
2420 /* If before a DNS hostname was set then it should remain
2421 the same in combination with the "servicePrincipalName"s.
2422 The DNS hostname should also be returned by our
2423 "LogonGetDomainInfo" call (in the domain info structure). */
2425 torture_assert_str_equal(tctx,
2426 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
2427 old_dnsname, "'DNS hostname' was not set!");
2429 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2430 torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
2431 "'servicePrincipalName's not set!");
2432 torture_assert(tctx, spn_el->num_values == num_spns,
2433 "'servicePrincipalName's incorrect!");
2434 for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
2435 torture_assert_str_equal(tctx,
2436 (char *) spn_el->values[i].data,
2437 spns[i], "'servicePrincipalName's incorrect!");
2439 torture_assert_str_equal(tctx,
2440 info.domain_info->dns_hostname.string,
2441 old_dnsname,
2442 "Out 'DNS hostname' doesn't match the old one!");
2443 } else {
2444 /* If no DNS hostname was set then also now none should be set,
2445 the "servicePrincipalName"s should remain empty and no DNS
2446 hostname should be returned by our "LogonGetDomainInfo"
2447 call (in the domain info structure). */
2449 torture_assert(tctx,
2450 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
2451 "'DNS hostname' was set!");
2453 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2454 torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
2455 "'servicePrincipalName's were set!");
2457 torture_assert(tctx,
2458 info.domain_info->dns_hostname.string == NULL,
2459 "Out 'DNS host name' was set!");
2463 /* Checks "workstation flags" */
2464 torture_assert(tctx,
2465 info.domain_info->workstation_flags
2466 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
2467 "Out 'workstation flags' don't match!");
2470 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname)\n");
2471 netlogon_creds_client_authenticator(creds, &a);
2473 /* Wipe out the osVersion, and prove which values still 'stick' */
2474 q1.os_version.os = NULL;
2476 /* Change also the DNS hostname to test differences in behaviour */
2477 q1.dns_hostname = talloc_asprintf(tctx, "%s.newdomain",
2478 TEST_MACHINE_NAME);
2480 /* Let the DC handle the "servicePrincipalName" and DNS hostname
2481 updates */
2482 q1.workstation_flags = 0;
2484 status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2485 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2486 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2488 msleep(250);
2490 if (sam_ctx) {
2491 /* AD workstation infos entry check */
2492 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2493 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2494 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
2495 torture_assert_str_equal(tctx,
2496 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
2497 q1.os_name.string, "'operatingSystem' should stick!");
2498 torture_assert(tctx,
2499 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
2500 "'operatingSystemServicePack' shouldn't stick!");
2501 torture_assert(tctx,
2502 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
2503 "'operatingSystemVersion' shouldn't stick!");
2505 /* The DNS host name should have been updated now by the server */
2506 torture_assert_str_equal(tctx,
2507 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
2508 q1.dns_hostname, "'DNS host name' didn't change!");
2510 /* Find the two "servicePrincipalName"s which the DC should have been
2511 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
2512 3.5.4.3.9 */
2513 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2514 torture_assert(tctx, spn_el != NULL,
2515 "There should exist 'servicePrincipalName's in AD!");
2516 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
2517 for (i=0; i < spn_el->num_values; i++)
2518 if (strcmp((char *) spn_el->values[i].data, temp_str) == 0)
2519 break;
2520 torture_assert(tctx, i != spn_el->num_values,
2521 "'servicePrincipalName' HOST/<Netbios name> not found!");
2522 temp_str = talloc_asprintf(tctx, "HOST/%s", q1.dns_hostname);
2523 for (i=0; i < spn_el->num_values; i++)
2524 if (strcmp((char *) spn_el->values[i].data, temp_str) == 0)
2525 break;
2526 torture_assert(tctx, i != spn_el->num_values,
2527 "'servicePrincipalName' HOST/<FQDN name> not found!");
2529 /* Check that the out DNS hostname was set properly */
2530 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
2531 old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
2534 /* Checks "workstation flags" */
2535 torture_assert(tctx,
2536 info.domain_info->workstation_flags == 0,
2537 "Out 'workstation flags' don't match!");
2540 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (verification of DNS hostname and check for trusted domains)\n");
2541 netlogon_creds_client_authenticator(creds, &a);
2543 /* The workstation handles the "servicePrincipalName" and DNS hostname
2544 updates */
2545 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
2547 status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2548 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2549 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2551 msleep(250);
2553 /* Now the in/out DNS hostnames should be the same */
2554 torture_assert_str_equal(tctx,
2555 info.domain_info->dns_hostname.string,
2556 query.workstation_info->dns_hostname,
2557 "In/Out 'DNS hostnames' don't match!");
2559 /* Checks "workstation flags" */
2560 torture_assert(tctx,
2561 info.domain_info->workstation_flags
2562 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
2563 "Out 'workstation flags' don't match!");
2565 /* Checks for trusted domains */
2566 torture_assert(tctx,
2567 (info.domain_info->trusted_domain_count != 0)
2568 && (info.domain_info->trusted_domains != NULL),
2569 "Trusted domains have been requested!");
2572 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (check for trusted domains)\n");
2573 netlogon_creds_client_authenticator(creds, &a);
2575 /* The workstation handles the "servicePrincipalName" and DNS hostname
2576 updates and requests inbound trusts */
2577 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
2578 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
2580 status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2581 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2582 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2584 msleep(250);
2586 /* Checks "workstation flags" */
2587 torture_assert(tctx,
2588 info.domain_info->workstation_flags
2589 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
2590 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
2591 "Out 'workstation flags' don't match!");
2593 /* Checks for trusted domains */
2594 torture_assert(tctx,
2595 (info.domain_info->trusted_domain_count != 0)
2596 && (info.domain_info->trusted_domains != NULL),
2597 "Trusted domains have been requested!");
2599 return true;
2603 static void async_callback(struct rpc_request *req)
2605 int *counter = (int *)req->async.private_data;
2606 if (NT_STATUS_IS_OK(req->status)) {
2607 (*counter)++;
2611 static bool test_GetDomainInfo_async(struct torture_context *tctx,
2612 struct dcerpc_pipe *p,
2613 struct cli_credentials *machine_credentials)
2615 NTSTATUS status;
2616 struct netr_LogonGetDomainInfo r;
2617 struct netr_WorkstationInformation q1;
2618 struct netr_Authenticator a;
2619 #define ASYNC_COUNT 100
2620 struct netlogon_creds_CredentialState *creds;
2621 struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
2622 struct rpc_request *req[ASYNC_COUNT];
2623 int i;
2624 int *async_counter = talloc(tctx, int);
2625 union netr_WorkstationInfo query;
2626 union netr_DomainInfo info;
2628 torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
2630 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2631 machine_credentials, &creds)) {
2632 return false;
2635 ZERO_STRUCT(r);
2636 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2637 r.in.computer_name = TEST_MACHINE_NAME;
2638 r.in.credential = &a;
2639 r.in.level = 1;
2640 r.in.return_authenticator = &a;
2641 r.in.query = &query;
2642 r.out.return_authenticator = &a;
2643 r.out.info = &info;
2645 ZERO_STRUCT(q1);
2646 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
2647 TEST_MACHINE_DNS_SUFFIX);
2648 q1.sitename = "Default-First-Site-Name";
2649 q1.os_name.string = "UNIX/Linux or similar";
2651 query.workstation_info = &q1;
2653 *async_counter = 0;
2655 for (i=0;i<ASYNC_COUNT;i++) {
2656 netlogon_creds_client_authenticator(creds, &a);
2658 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
2659 req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, tctx, &r);
2661 req[i]->async.callback = async_callback;
2662 req[i]->async.private_data = async_counter;
2664 /* even with this flush per request a w2k3 server seems to
2665 clag with multiple outstanding requests. bleergh. */
2666 torture_assert_int_equal(tctx, event_loop_once(dcerpc_event_context(p)), 0,
2667 "event_loop_once failed");
2670 for (i=0;i<ASYNC_COUNT;i++) {
2671 status = dcerpc_ndr_request_recv(req[i]);
2673 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
2674 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
2676 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred),
2677 "Credential chaining failed at async");
2680 torture_comment(tctx,
2681 "Testing netr_LogonGetDomainInfo - async count %d OK\n", *async_counter);
2683 torture_assert_int_equal(tctx, (*async_counter), ASYNC_COUNT, "int");
2685 return true;
2688 static bool test_ManyGetDCName(struct torture_context *tctx,
2689 struct dcerpc_pipe *p)
2691 NTSTATUS status;
2692 struct dcerpc_pipe *p2;
2693 struct lsa_ObjectAttribute attr;
2694 struct lsa_QosInfo qos;
2695 struct lsa_OpenPolicy2 o;
2696 struct policy_handle lsa_handle;
2697 struct lsa_DomainList domains;
2699 struct lsa_EnumTrustDom t;
2700 uint32_t resume_handle = 0;
2701 struct netr_GetAnyDCName d;
2702 const char *dcname = NULL;
2704 int i;
2706 if (p->conn->transport.transport != NCACN_NP) {
2707 return true;
2710 torture_comment(tctx, "Torturing GetDCName\n");
2712 status = dcerpc_secondary_connection(p, &p2, p->binding);
2713 torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
2715 status = dcerpc_bind_auth_none(p2, &ndr_table_lsarpc);
2716 torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
2718 qos.len = 0;
2719 qos.impersonation_level = 2;
2720 qos.context_mode = 1;
2721 qos.effective_only = 0;
2723 attr.len = 0;
2724 attr.root_dir = NULL;
2725 attr.object_name = NULL;
2726 attr.attributes = 0;
2727 attr.sec_desc = NULL;
2728 attr.sec_qos = &qos;
2730 o.in.system_name = "\\";
2731 o.in.attr = &attr;
2732 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2733 o.out.handle = &lsa_handle;
2735 status = dcerpc_lsa_OpenPolicy2(p2, tctx, &o);
2736 torture_assert_ntstatus_ok(tctx, status, "OpenPolicy2 failed");
2738 t.in.handle = &lsa_handle;
2739 t.in.resume_handle = &resume_handle;
2740 t.in.max_size = 1000;
2741 t.out.domains = &domains;
2742 t.out.resume_handle = &resume_handle;
2744 status = dcerpc_lsa_EnumTrustDom(p2, tctx, &t);
2746 if ((!NT_STATUS_IS_OK(status) &&
2747 (!NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES))))
2748 torture_fail(tctx, "Could not list domains");
2750 talloc_free(p2);
2752 d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
2753 dcerpc_server_name(p));
2754 d.out.dcname = &dcname;
2756 for (i=0; i<domains.count * 4; i++) {
2757 struct lsa_DomainInfo *info =
2758 &domains.domains[rand()%domains.count];
2760 d.in.domainname = info->name.string;
2762 status = dcerpc_netr_GetAnyDCName(p, tctx, &d);
2763 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2765 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
2766 dcname ? dcname : "unknown");
2769 return true;
2772 static bool test_SetPassword_with_flags(struct torture_context *tctx,
2773 struct dcerpc_pipe *p,
2774 struct cli_credentials *machine_credentials)
2776 uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
2777 struct netlogon_creds_CredentialState *creds;
2778 int i;
2780 if (!test_SetupCredentials2(p, tctx, 0,
2781 machine_credentials,
2782 cli_credentials_get_secure_channel_type(machine_credentials),
2783 &creds)) {
2784 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
2787 for (i=0; i < ARRAY_SIZE(flags); i++) {
2788 torture_assert(tctx,
2789 test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
2790 talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
2793 return true;
2796 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
2798 struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON");
2799 struct torture_rpc_tcase *tcase;
2800 struct torture_test *test;
2802 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
2803 &ndr_table_netlogon, TEST_MACHINE_NAME);
2805 torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
2806 torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
2807 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
2808 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
2809 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
2810 torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
2811 torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
2812 torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
2813 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
2814 torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
2815 torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
2816 torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
2817 torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
2818 torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
2819 torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
2820 torture_rpc_tcase_add_test(tcase, "LogonControl", test_LogonControl);
2821 torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
2822 torture_rpc_tcase_add_test(tcase, "LogonControl2", test_LogonControl2);
2823 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
2824 torture_rpc_tcase_add_test(tcase, "LogonControl2Ex", test_LogonControl2Ex);
2825 torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
2826 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
2827 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
2828 test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
2829 test->dangerous = true;
2830 torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
2831 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
2832 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
2833 torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
2834 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
2835 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
2836 torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
2838 return suite;
2841 struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
2843 struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON-S3");
2844 struct torture_rpc_tcase *tcase;
2846 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
2847 &ndr_table_netlogon, TEST_MACHINE_NAME);
2849 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
2850 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
2851 torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
2852 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
2853 torture_rpc_tcase_add_test(tcase, "LogonControl", test_LogonControl);
2854 torture_rpc_tcase_add_test(tcase, "LogonControl2", test_LogonControl2);
2855 torture_rpc_tcase_add_test(tcase, "LogonControl2Ex", test_LogonControl2Ex);
2856 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
2858 return suite;