s4:torture/rpc/netlogon - Fix uninitialised variable
[Samba/cd1.git] / source4 / torture / rpc / netlogon.c
blob2806cca52b2e65f4344749f41fe380c202f992de
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++) {
1357 const char *database = NULL;
1359 switch (d) {
1360 case 0:
1361 database = "SAM";
1362 break;
1363 case 1:
1364 database = "BUILTIN";
1365 break;
1366 case 2:
1367 database = "LSA";
1368 break;
1369 default:
1370 break;
1373 torture_comment(tctx, "Testing DatabaseRedo\n");
1375 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1376 return false;
1379 for (i=0;i<ARRAY_SIZE(changes);i++) {
1381 if (d != changes[i].db_index) {
1382 continue;
1385 netlogon_creds_client_authenticator(creds, &credential);
1387 r.in.credential = &credential;
1389 e.serial_number1 = 0;
1390 e.serial_number2 = 0;
1391 e.object_rid = changes[i].rid;
1392 e.flags = changes[i].flags;
1393 e.db_index = changes[i].db_index;
1394 e.delta_type = changes[i].delta_type;
1396 switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
1397 case NETR_CHANGELOG_SID_INCLUDED:
1398 e.object.object_sid = changes[i].sid;
1399 break;
1400 case NETR_CHANGELOG_NAME_INCLUDED:
1401 e.object.object_name = changes[i].name;
1402 break;
1403 default:
1404 break;
1407 r.in.change_log_entry = e;
1409 torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
1410 database, changes[i].comment);
1412 status = dcerpc_netr_DatabaseRedo(p, tctx, &r);
1413 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1414 return true;
1417 torture_assert_ntstatus_equal(tctx, status, changes[i].expected_error, changes[i].comment);
1418 if (delta_enum_array) {
1419 torture_assert_int_equal(tctx,
1420 delta_enum_array->num_deltas,
1421 changes[i].expected_num_results,
1422 changes[i].comment);
1423 if (delta_enum_array->num_deltas > 0) {
1424 torture_assert_int_equal(tctx,
1425 delta_enum_array->delta_enum[0].delta_type,
1426 changes[i].expected_delta_type_1,
1427 changes[i].comment);
1429 if (delta_enum_array->num_deltas > 1) {
1430 torture_assert_int_equal(tctx,
1431 delta_enum_array->delta_enum[1].delta_type,
1432 changes[i].expected_delta_type_2,
1433 changes[i].comment);
1437 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1438 torture_comment(tctx, "Credential chaining failed\n");
1439 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1440 return false;
1447 return true;
1451 try a netlogon AccountDeltas
1453 static bool test_AccountDeltas(struct torture_context *tctx,
1454 struct dcerpc_pipe *p,
1455 struct cli_credentials *machine_credentials)
1457 NTSTATUS status;
1458 struct netr_AccountDeltas r;
1459 struct netlogon_creds_CredentialState *creds;
1461 struct netr_AccountBuffer buffer;
1462 uint32_t count_returned = 0;
1463 uint32_t total_entries = 0;
1464 struct netr_UAS_INFO_0 recordid;
1465 struct netr_Authenticator return_authenticator;
1467 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1468 return false;
1471 ZERO_STRUCT(return_authenticator);
1473 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1474 r.in.computername = TEST_MACHINE_NAME;
1475 r.in.return_authenticator = &return_authenticator;
1476 netlogon_creds_client_authenticator(creds, &r.in.credential);
1477 ZERO_STRUCT(r.in.uas);
1478 r.in.count=10;
1479 r.in.level=0;
1480 r.in.buffersize=100;
1481 r.out.buffer = &buffer;
1482 r.out.count_returned = &count_returned;
1483 r.out.total_entries = &total_entries;
1484 r.out.recordid = &recordid;
1485 r.out.return_authenticator = &return_authenticator;
1487 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1488 status = dcerpc_netr_AccountDeltas(p, tctx, &r);
1489 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
1491 return true;
1495 try a netlogon AccountSync
1497 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
1498 struct cli_credentials *machine_credentials)
1500 NTSTATUS status;
1501 struct netr_AccountSync r;
1502 struct netlogon_creds_CredentialState *creds;
1504 struct netr_AccountBuffer buffer;
1505 uint32_t count_returned = 0;
1506 uint32_t total_entries = 0;
1507 uint32_t next_reference = 0;
1508 struct netr_UAS_INFO_0 recordid;
1509 struct netr_Authenticator return_authenticator;
1511 ZERO_STRUCT(recordid);
1512 ZERO_STRUCT(return_authenticator);
1514 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1515 return false;
1518 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1519 r.in.computername = TEST_MACHINE_NAME;
1520 r.in.return_authenticator = &return_authenticator;
1521 netlogon_creds_client_authenticator(creds, &r.in.credential);
1522 r.in.recordid = &recordid;
1523 r.in.reference=0;
1524 r.in.level=0;
1525 r.in.buffersize=100;
1526 r.out.buffer = &buffer;
1527 r.out.count_returned = &count_returned;
1528 r.out.total_entries = &total_entries;
1529 r.out.next_reference = &next_reference;
1530 r.out.recordid = &recordid;
1531 r.out.return_authenticator = &return_authenticator;
1533 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1534 status = dcerpc_netr_AccountSync(p, tctx, &r);
1535 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
1537 return true;
1541 try a netlogon GetDcName
1543 static bool test_GetDcName(struct torture_context *tctx,
1544 struct dcerpc_pipe *p)
1546 NTSTATUS status;
1547 struct netr_GetDcName r;
1548 const char *dcname = NULL;
1550 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1551 r.in.domainname = lp_workgroup(tctx->lp_ctx);
1552 r.out.dcname = &dcname;
1554 status = dcerpc_netr_GetDcName(p, tctx, &r);
1555 torture_assert_ntstatus_ok(tctx, status, "GetDcName");
1556 torture_assert_werr_ok(tctx, r.out.result, "GetDcName");
1558 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1560 return true;
1563 static const char *function_code_str(TALLOC_CTX *mem_ctx,
1564 enum netr_LogonControlCode function_code)
1566 switch (function_code) {
1567 case NETLOGON_CONTROL_QUERY:
1568 return "NETLOGON_CONTROL_QUERY";
1569 case NETLOGON_CONTROL_REPLICATE:
1570 return "NETLOGON_CONTROL_REPLICATE";
1571 case NETLOGON_CONTROL_SYNCHRONIZE:
1572 return "NETLOGON_CONTROL_SYNCHRONIZE";
1573 case NETLOGON_CONTROL_PDC_REPLICATE:
1574 return "NETLOGON_CONTROL_PDC_REPLICATE";
1575 case NETLOGON_CONTROL_REDISCOVER:
1576 return "NETLOGON_CONTROL_REDISCOVER";
1577 case NETLOGON_CONTROL_TC_QUERY:
1578 return "NETLOGON_CONTROL_TC_QUERY";
1579 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1580 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
1581 case NETLOGON_CONTROL_FIND_USER:
1582 return "NETLOGON_CONTROL_FIND_USER";
1583 case NETLOGON_CONTROL_CHANGE_PASSWORD:
1584 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
1585 case NETLOGON_CONTROL_TC_VERIFY:
1586 return "NETLOGON_CONTROL_TC_VERIFY";
1587 case NETLOGON_CONTROL_FORCE_DNS_REG:
1588 return "NETLOGON_CONTROL_FORCE_DNS_REG";
1589 case NETLOGON_CONTROL_QUERY_DNS_REG:
1590 return "NETLOGON_CONTROL_QUERY_DNS_REG";
1591 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1592 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
1593 case NETLOGON_CONTROL_TRUNCATE_LOG:
1594 return "NETLOGON_CONTROL_TRUNCATE_LOG";
1595 case NETLOGON_CONTROL_SET_DBFLAG:
1596 return "NETLOGON_CONTROL_SET_DBFLAG";
1597 case NETLOGON_CONTROL_BREAKPOINT:
1598 return "NETLOGON_CONTROL_BREAKPOINT";
1599 default:
1600 return talloc_asprintf(mem_ctx, "unknown function code: %d",
1601 function_code);
1607 try a netlogon LogonControl
1609 static bool test_LogonControl(struct torture_context *tctx,
1610 struct dcerpc_pipe *p,
1611 struct cli_credentials *machine_credentials)
1614 NTSTATUS status;
1615 struct netr_LogonControl r;
1616 union netr_CONTROL_QUERY_INFORMATION query;
1617 int i,f;
1618 enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
1620 uint32_t function_codes[] = {
1621 NETLOGON_CONTROL_QUERY,
1622 NETLOGON_CONTROL_REPLICATE,
1623 NETLOGON_CONTROL_SYNCHRONIZE,
1624 NETLOGON_CONTROL_PDC_REPLICATE,
1625 NETLOGON_CONTROL_REDISCOVER,
1626 NETLOGON_CONTROL_TC_QUERY,
1627 NETLOGON_CONTROL_TRANSPORT_NOTIFY,
1628 NETLOGON_CONTROL_FIND_USER,
1629 NETLOGON_CONTROL_CHANGE_PASSWORD,
1630 NETLOGON_CONTROL_TC_VERIFY,
1631 NETLOGON_CONTROL_FORCE_DNS_REG,
1632 NETLOGON_CONTROL_QUERY_DNS_REG,
1633 NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
1634 NETLOGON_CONTROL_TRUNCATE_LOG,
1635 NETLOGON_CONTROL_SET_DBFLAG,
1636 NETLOGON_CONTROL_BREAKPOINT
1639 if (machine_credentials) {
1640 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1643 torture_comment(tctx, "testing LogonControl with secure channel type: %d\n",
1644 secure_channel_type);
1646 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1647 r.in.function_code = 1;
1648 r.out.query = &query;
1650 for (f=0;f<ARRAY_SIZE(function_codes); f++) {
1651 for (i=1;i<5;i++) {
1653 r.in.function_code = function_codes[f];
1654 r.in.level = i;
1656 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
1657 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1659 status = dcerpc_netr_LogonControl(p, tctx, &r);
1660 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1662 switch (r.in.level) {
1663 case 1:
1664 switch (r.in.function_code) {
1665 case NETLOGON_CONTROL_REPLICATE:
1666 case NETLOGON_CONTROL_SYNCHRONIZE:
1667 case NETLOGON_CONTROL_PDC_REPLICATE:
1668 case NETLOGON_CONTROL_BREAKPOINT:
1669 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1670 if ((secure_channel_type == SEC_CHAN_BDC) ||
1671 (secure_channel_type == SEC_CHAN_WKSTA)) {
1672 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1673 "LogonControl returned unexpected error code");
1674 } else {
1675 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1676 "LogonControl returned unexpected error code");
1678 break;
1680 case NETLOGON_CONTROL_REDISCOVER:
1681 case NETLOGON_CONTROL_TC_QUERY:
1682 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1683 case NETLOGON_CONTROL_FIND_USER:
1684 case NETLOGON_CONTROL_CHANGE_PASSWORD:
1685 case NETLOGON_CONTROL_TC_VERIFY:
1686 case NETLOGON_CONTROL_FORCE_DNS_REG:
1687 case NETLOGON_CONTROL_QUERY_DNS_REG:
1688 case NETLOGON_CONTROL_SET_DBFLAG:
1689 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1690 "LogonControl returned unexpected error code");
1691 break;
1692 case NETLOGON_CONTROL_TRUNCATE_LOG:
1693 if ((secure_channel_type == SEC_CHAN_BDC) ||
1694 (secure_channel_type == SEC_CHAN_WKSTA)) {
1695 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1696 "LogonControl returned unexpected error code");
1697 } else {
1698 torture_assert_werr_ok(tctx, r.out.result,
1699 "LogonControl returned unexpected result");
1701 break;
1702 default:
1703 torture_assert_werr_ok(tctx, r.out.result,
1704 "LogonControl returned unexpected result");
1705 break;
1707 break;
1708 case 2:
1709 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1710 "LogonControl returned unexpected error code");
1711 break;
1712 default:
1713 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL,
1714 "LogonControl returned unexpected error code");
1715 break;
1720 return true;
1725 try a netlogon GetAnyDCName
1727 static bool test_GetAnyDCName(struct torture_context *tctx,
1728 struct dcerpc_pipe *p)
1730 NTSTATUS status;
1731 struct netr_GetAnyDCName r;
1732 const char *dcname = NULL;
1734 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1735 r.in.domainname = lp_workgroup(tctx->lp_ctx);
1736 r.out.dcname = &dcname;
1738 status = dcerpc_netr_GetAnyDCName(p, tctx, &r);
1739 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
1740 torture_assert_werr_ok(tctx, r.out.result, "GetAnyDCName");
1742 if (dcname) {
1743 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1746 return true;
1751 try a netlogon LogonControl2
1753 static bool test_LogonControl2(struct torture_context *tctx,
1754 struct dcerpc_pipe *p,
1755 struct cli_credentials *machine_credentials)
1758 NTSTATUS status;
1759 struct netr_LogonControl2 r;
1760 union netr_CONTROL_DATA_INFORMATION data;
1761 union netr_CONTROL_QUERY_INFORMATION query;
1762 int i;
1764 data.domain = lp_workgroup(tctx->lp_ctx);
1766 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1768 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1769 r.in.data = &data;
1770 r.out.query = &query;
1772 for (i=1;i<4;i++) {
1773 r.in.level = i;
1775 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1776 i, r.in.function_code);
1778 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1779 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1782 data.domain = lp_workgroup(tctx->lp_ctx);
1784 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1785 r.in.data = &data;
1787 for (i=1;i<4;i++) {
1788 r.in.level = i;
1790 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1791 i, r.in.function_code);
1793 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1794 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1797 data.domain = lp_workgroup(tctx->lp_ctx);
1799 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1800 r.in.data = &data;
1802 for (i=1;i<4;i++) {
1803 r.in.level = i;
1805 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1806 i, r.in.function_code);
1808 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1809 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1812 data.debug_level = ~0;
1814 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1815 r.in.data = &data;
1817 for (i=1;i<4;i++) {
1818 r.in.level = i;
1820 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1821 i, r.in.function_code);
1823 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1824 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1827 return true;
1831 try a netlogon DatabaseSync2
1833 static bool test_DatabaseSync2(struct torture_context *tctx,
1834 struct dcerpc_pipe *p,
1835 struct cli_credentials *machine_credentials)
1837 NTSTATUS status;
1838 struct netr_DatabaseSync2 r;
1839 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1840 struct netr_Authenticator return_authenticator, credential;
1842 struct netlogon_creds_CredentialState *creds;
1843 const uint32_t database_ids[] = {0, 1, 2};
1844 int i;
1846 if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
1847 machine_credentials,
1848 cli_credentials_get_secure_channel_type(machine_credentials),
1849 &creds)) {
1850 return false;
1853 ZERO_STRUCT(return_authenticator);
1855 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1856 r.in.computername = TEST_MACHINE_NAME;
1857 r.in.preferredmaximumlength = (uint32_t)-1;
1858 r.in.return_authenticator = &return_authenticator;
1859 r.out.return_authenticator = &return_authenticator;
1860 r.out.delta_enum_array = &delta_enum_array;
1862 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1864 uint32_t sync_context = 0;
1866 r.in.database_id = database_ids[i];
1867 r.in.sync_context = &sync_context;
1868 r.out.sync_context = &sync_context;
1869 r.in.restart_state = 0;
1871 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
1873 do {
1874 netlogon_creds_client_authenticator(creds, &credential);
1876 r.in.credential = &credential;
1878 status = dcerpc_netr_DatabaseSync2(p, tctx, &r);
1879 if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
1880 break;
1882 /* Native mode servers don't do this */
1883 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1884 return true;
1887 torture_assert_ntstatus_ok(tctx, status, "DatabaseSync2");
1889 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1890 torture_comment(tctx, "Credential chaining failed\n");
1893 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
1896 return true;
1901 try a netlogon LogonControl2Ex
1903 static bool test_LogonControl2Ex(struct torture_context *tctx,
1904 struct dcerpc_pipe *p,
1905 struct cli_credentials *machine_credentials)
1908 NTSTATUS status;
1909 struct netr_LogonControl2Ex r;
1910 union netr_CONTROL_DATA_INFORMATION data;
1911 union netr_CONTROL_QUERY_INFORMATION query;
1912 int i;
1914 data.domain = lp_workgroup(tctx->lp_ctx);
1916 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1918 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1919 r.in.data = &data;
1920 r.out.query = &query;
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.domain = lp_workgroup(tctx->lp_ctx);
1934 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
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 data.domain = lp_workgroup(tctx->lp_ctx);
1949 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1950 r.in.data = &data;
1952 for (i=1;i<4;i++) {
1953 r.in.level = i;
1955 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
1956 i, r.in.function_code);
1958 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1959 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1962 data.debug_level = ~0;
1964 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1965 r.in.data = &data;
1967 for (i=1;i<4;i++) {
1968 r.in.level = i;
1970 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
1971 i, r.in.function_code);
1973 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1974 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1977 return true;
1980 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
1981 struct dcerpc_pipe *p, const char *trusted_domain_name)
1983 NTSTATUS status;
1984 struct netr_DsRGetForestTrustInformation r;
1985 struct lsa_ForestTrustInformation info, *info_ptr;
1987 info_ptr = &info;
1989 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1990 r.in.trusted_domain_name = trusted_domain_name;
1991 r.in.flags = 0;
1992 r.out.forest_trust_info = &info_ptr;
1994 torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
1996 status = dcerpc_netr_DsRGetForestTrustInformation(p, tctx, &r);
1997 torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
1998 torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
2000 return true;
2004 try a netlogon netr_DsrEnumerateDomainTrusts
2006 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
2007 struct dcerpc_pipe *p)
2009 NTSTATUS status;
2010 struct netr_DsrEnumerateDomainTrusts r;
2011 struct netr_DomainTrustList trusts;
2012 int i;
2014 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2015 r.in.trust_flags = 0x3f;
2016 r.out.trusts = &trusts;
2018 status = dcerpc_netr_DsrEnumerateDomainTrusts(p, tctx, &r);
2019 torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
2020 torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
2022 /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
2023 * will show non-forest trusts and all UPN suffixes of the own forest
2024 * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
2026 if (r.out.trusts->count) {
2027 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
2028 return false;
2032 for (i=0; i<r.out.trusts->count; i++) {
2034 /* get info for transitive forest trusts */
2036 if (r.out.trusts->array[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2037 if (!test_netr_DsRGetForestTrustInformation(tctx, p,
2038 r.out.trusts->array[i].dns_name)) {
2039 return false;
2044 return true;
2047 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
2048 struct dcerpc_pipe *p)
2050 NTSTATUS status;
2051 struct netr_NetrEnumerateTrustedDomains r;
2052 struct netr_Blob trusted_domains_blob;
2054 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2055 r.out.trusted_domains_blob = &trusted_domains_blob;
2057 status = dcerpc_netr_NetrEnumerateTrustedDomains(p, tctx, &r);
2058 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
2059 torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
2061 return true;
2064 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
2065 struct dcerpc_pipe *p)
2067 NTSTATUS status;
2068 struct netr_NetrEnumerateTrustedDomainsEx r;
2069 struct netr_DomainTrustList dom_trust_list;
2071 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2072 r.out.dom_trust_list = &dom_trust_list;
2074 status = dcerpc_netr_NetrEnumerateTrustedDomainsEx(p, tctx, &r);
2075 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
2076 torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
2078 return true;
2082 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
2083 const char *computer_name,
2084 const char *expected_site)
2086 NTSTATUS status;
2087 struct netr_DsRGetSiteName r;
2088 const char *site = NULL;
2090 if (torture_setting_bool(tctx, "samba4", false))
2091 torture_skip(tctx, "skipping DsRGetSiteName test against Samba4");
2093 r.in.computer_name = computer_name;
2094 r.out.site = &site;
2095 torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
2097 status = dcerpc_netr_DsRGetSiteName(p, tctx, &r);
2098 torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2099 torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
2100 torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
2102 r.in.computer_name = talloc_asprintf(tctx, "\\\\%s", computer_name);
2103 torture_comment(tctx,
2104 "Testing netr_DsRGetSiteName with broken computer name: %s\n", r.in.computer_name);
2106 status = dcerpc_netr_DsRGetSiteName(p, tctx, &r);
2107 torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2108 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_COMPUTERNAME, "netr_DsRGetSiteName");
2110 return true;
2114 try a netlogon netr_DsRGetDCName
2116 static bool test_netr_DsRGetDCName(struct torture_context *tctx,
2117 struct dcerpc_pipe *p)
2119 NTSTATUS status;
2120 struct netr_DsRGetDCName r;
2121 struct netr_DsRGetDCNameInfo *info = NULL;
2123 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2124 r.in.domain_name = lp_dnsdomain(tctx->lp_ctx);
2125 r.in.domain_guid = NULL;
2126 r.in.site_guid = NULL;
2127 r.in.flags = DS_RETURN_DNS_NAME;
2128 r.out.info = &info;
2130 status = dcerpc_netr_DsRGetDCName(p, tctx, &r);
2131 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2132 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2133 return test_netr_DsRGetSiteName(p, tctx,
2134 info->dc_unc,
2135 info->dc_site_name);
2139 try a netlogon netr_DsRGetDCNameEx
2141 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
2142 struct dcerpc_pipe *p)
2144 NTSTATUS status;
2145 struct netr_DsRGetDCNameEx r;
2146 struct netr_DsRGetDCNameInfo *info = NULL;
2148 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2149 r.in.domain_name = lp_dnsdomain(tctx->lp_ctx);
2150 r.in.domain_guid = NULL;
2151 r.in.site_name = NULL;
2152 r.in.flags = DS_RETURN_DNS_NAME;
2153 r.out.info = &info;
2155 status = dcerpc_netr_DsRGetDCNameEx(p, tctx, &r);
2156 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2157 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2159 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2160 info->dc_site_name);
2164 try a netlogon netr_DsRGetDCNameEx2
2166 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
2167 struct dcerpc_pipe *p)
2169 NTSTATUS status;
2170 struct netr_DsRGetDCNameEx2 r;
2171 struct netr_DsRGetDCNameInfo *info = NULL;
2173 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2174 r.in.client_account = NULL;
2175 r.in.mask = 0x00000000;
2176 r.in.domain_name = lp_dnsdomain(tctx->lp_ctx);
2177 r.in.domain_guid = NULL;
2178 r.in.site_name = NULL;
2179 r.in.flags = DS_RETURN_DNS_NAME;
2180 r.out.info = &info;
2182 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
2184 status = dcerpc_netr_DsRGetDCNameEx2(p, tctx, &r);
2185 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2186 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2188 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client acount\n");
2189 r.in.client_account = TEST_MACHINE_NAME"$";
2190 r.in.mask = ACB_SVRTRUST;
2191 r.in.flags = DS_RETURN_FLAT_NAME;
2192 r.out.info = &info;
2194 status = dcerpc_netr_DsRGetDCNameEx2(p, tctx, &r);
2195 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2196 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2197 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2198 info->dc_site_name);
2201 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
2202 struct dcerpc_pipe *p)
2204 NTSTATUS status;
2205 struct netr_DsrGetDcSiteCoverageW r;
2206 struct DcSitesCtr *ctr = NULL;
2208 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2209 r.out.ctr = &ctr;
2211 status = dcerpc_netr_DsrGetDcSiteCoverageW(p, tctx, &r);
2212 torture_assert_ntstatus_ok(tctx, status, "failed");
2213 torture_assert_werr_ok(tctx, r.out.result, "failed");
2215 return true;
2218 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
2219 struct dcerpc_pipe *p)
2221 NTSTATUS status;
2222 struct netr_DsRAddressToSitenamesW r;
2223 struct netr_DsRAddress addr;
2224 struct netr_DsRAddressToSitenamesWCtr *ctr;
2226 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
2228 addr.size = 16;
2229 addr.buffer = talloc_zero_array(tctx, uint8_t, addr.size);
2231 addr.buffer[0] = 2; /* AF_INET */
2232 addr.buffer[4] = 127;
2233 addr.buffer[5] = 0;
2234 addr.buffer[6] = 0;
2235 addr.buffer[7] = 1;
2237 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2238 r.in.count = 1;
2239 r.in.addresses = talloc_zero_array(tctx, struct netr_DsRAddress, r.in.count);
2240 r.in.addresses[0] = addr;
2241 r.out.ctr = &ctr;
2243 status = dcerpc_netr_DsRAddressToSitenamesW(p, tctx, &r);
2244 torture_assert_ntstatus_ok(tctx, status, "failed");
2245 torture_assert_werr_ok(tctx, r.out.result, "failed");
2247 return true;
2250 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
2251 struct dcerpc_pipe *p)
2253 NTSTATUS status;
2254 struct netr_DsRAddressToSitenamesExW r;
2255 struct netr_DsRAddress addr;
2256 struct netr_DsRAddressToSitenamesExWCtr *ctr;
2258 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
2260 addr.size = 16;
2261 addr.buffer = talloc_zero_array(tctx, uint8_t, addr.size);
2263 addr.buffer[0] = 2; /* AF_INET */
2264 addr.buffer[4] = 127;
2265 addr.buffer[5] = 0;
2266 addr.buffer[6] = 0;
2267 addr.buffer[7] = 1;
2269 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2270 r.in.count = 1;
2271 r.in.addresses = talloc_zero_array(tctx, struct netr_DsRAddress, r.in.count);
2272 r.in.addresses[0] = addr;
2273 r.out.ctr = &ctr;
2275 status = dcerpc_netr_DsRAddressToSitenamesExW(p, tctx, &r);
2276 torture_assert_ntstatus_ok(tctx, status, "failed");
2277 torture_assert_werr_ok(tctx, r.out.result, "failed");
2279 return true;
2282 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
2283 struct dcerpc_pipe *p,
2284 struct cli_credentials *machine_credentials)
2286 NTSTATUS status;
2287 struct netr_ServerGetTrustInfo r;
2289 struct netr_Authenticator a;
2290 struct netr_Authenticator return_authenticator;
2291 struct samr_Password new_owf_password;
2292 struct samr_Password old_owf_password;
2293 struct netr_TrustInfo *trust_info;
2295 struct netlogon_creds_CredentialState *creds;
2297 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2298 machine_credentials, &creds)) {
2299 return false;
2302 netlogon_creds_client_authenticator(creds, &a);
2304 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2305 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
2306 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2307 r.in.computer_name = TEST_MACHINE_NAME;
2308 r.in.credential = &a;
2310 r.out.return_authenticator = &return_authenticator;
2311 r.out.new_owf_password = &new_owf_password;
2312 r.out.old_owf_password = &old_owf_password;
2313 r.out.trust_info = &trust_info;
2315 status = dcerpc_netr_ServerGetTrustInfo(p, tctx, &r);
2316 torture_assert_ntstatus_ok(tctx, status, "failed");
2317 torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
2319 return true;
2323 static bool test_GetDomainInfo(struct torture_context *tctx,
2324 struct dcerpc_pipe *p,
2325 struct cli_credentials *machine_credentials)
2327 NTSTATUS status;
2328 struct netr_LogonGetDomainInfo r;
2329 struct netr_WorkstationInformation q1;
2330 struct netr_Authenticator a;
2331 struct netlogon_creds_CredentialState *creds;
2332 struct netr_OsVersion os;
2333 union netr_WorkstationInfo query;
2334 union netr_DomainInfo info;
2335 const char* const attrs[] = { "dNSHostName", "operatingSystem",
2336 "operatingSystemServicePack", "operatingSystemVersion",
2337 "servicePrincipalName", NULL };
2338 char *url;
2339 struct ldb_context *sam_ctx = NULL;
2340 struct ldb_message **res;
2341 struct ldb_message_element *spn_el;
2342 int ret, i;
2343 char *version_str;
2344 const char *old_dnsname = NULL;
2345 char **spns = NULL;
2346 int num_spns = 0;
2347 char *temp_str;
2349 torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
2351 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2352 machine_credentials, &creds)) {
2353 return false;
2356 /* We won't double-check this when we are over 'local' transports */
2357 if (dcerpc_server_name(p)) {
2358 /* Set up connection to SAMDB on DC */
2359 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2360 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2361 NULL,
2362 cmdline_credentials,
2365 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2368 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
2369 netlogon_creds_client_authenticator(creds, &a);
2371 ZERO_STRUCT(r);
2372 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2373 r.in.computer_name = TEST_MACHINE_NAME;
2374 r.in.credential = &a;
2375 r.in.level = 1;
2376 r.in.return_authenticator = &a;
2377 r.in.query = &query;
2378 r.out.return_authenticator = &a;
2379 r.out.info = &info;
2381 ZERO_STRUCT(os);
2382 os.os.MajorVersion = 123;
2383 os.os.MinorVersion = 456;
2384 os.os.BuildNumber = 789;
2385 os.os.CSDVersion = "Service Pack 10";
2386 os.os.ServicePackMajor = 10;
2387 os.os.ServicePackMinor = 1;
2388 os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
2389 os.os.ProductType = NETR_VER_NT_SERVER;
2390 os.os.Reserved = 0;
2392 version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
2393 os.os.MinorVersion, os.os.BuildNumber);
2395 ZERO_STRUCT(q1);
2396 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
2397 TEST_MACHINE_DNS_SUFFIX);
2398 q1.sitename = "Default-First-Site-Name";
2399 q1.os_version.os = &os;
2400 q1.os_name.string = talloc_asprintf(tctx,
2401 "Tortured by Samba4 RPC-NETLOGON: %s",
2402 timestring(tctx, time(NULL)));
2404 /* The workstation handles the "servicePrincipalName" and DNS hostname
2405 updates */
2406 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
2408 query.workstation_info = &q1;
2410 if (sam_ctx) {
2411 /* Gets back the old DNS hostname in AD */
2412 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2413 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2414 old_dnsname =
2415 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
2417 /* Gets back the "servicePrincipalName"s in AD */
2418 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2419 if (spn_el != NULL) {
2420 for (i=0; i < spn_el->num_values; i++) {
2421 spns = talloc_realloc(tctx, spns, char *, i + 1);
2422 spns[i] = (char *) spn_el->values[i].data;
2424 num_spns = i;
2428 status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2429 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2430 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2432 msleep(250);
2434 if (sam_ctx) {
2435 /* AD workstation infos entry check */
2436 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2437 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2438 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
2439 torture_assert_str_equal(tctx,
2440 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
2441 q1.os_name.string, "'operatingSystem' wrong!");
2442 torture_assert_str_equal(tctx,
2443 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
2444 os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
2445 torture_assert_str_equal(tctx,
2446 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
2447 version_str, "'operatingSystemVersion' wrong!");
2449 if (old_dnsname != NULL) {
2450 /* If before a DNS hostname was set then it should remain
2451 the same in combination with the "servicePrincipalName"s.
2452 The DNS hostname should also be returned by our
2453 "LogonGetDomainInfo" call (in the domain info structure). */
2455 torture_assert_str_equal(tctx,
2456 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
2457 old_dnsname, "'DNS hostname' was not set!");
2459 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2460 torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
2461 "'servicePrincipalName's not set!");
2462 torture_assert(tctx, spn_el->num_values == num_spns,
2463 "'servicePrincipalName's incorrect!");
2464 for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
2465 torture_assert_str_equal(tctx,
2466 (char *) spn_el->values[i].data,
2467 spns[i], "'servicePrincipalName's incorrect!");
2469 torture_assert_str_equal(tctx,
2470 info.domain_info->dns_hostname.string,
2471 old_dnsname,
2472 "Out 'DNS hostname' doesn't match the old one!");
2473 } else {
2474 /* If no DNS hostname was set then also now none should be set,
2475 the "servicePrincipalName"s should remain empty and no DNS
2476 hostname should be returned by our "LogonGetDomainInfo"
2477 call (in the domain info structure). */
2479 torture_assert(tctx,
2480 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
2481 "'DNS hostname' was set!");
2483 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2484 torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
2485 "'servicePrincipalName's were set!");
2487 torture_assert(tctx,
2488 info.domain_info->dns_hostname.string == NULL,
2489 "Out 'DNS host name' was set!");
2493 /* Checks "workstation flags" */
2494 torture_assert(tctx,
2495 info.domain_info->workstation_flags
2496 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
2497 "Out 'workstation flags' don't match!");
2500 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname)\n");
2501 netlogon_creds_client_authenticator(creds, &a);
2503 /* Wipe out the osVersion, and prove which values still 'stick' */
2504 q1.os_version.os = NULL;
2506 /* Change also the DNS hostname to test differences in behaviour */
2507 q1.dns_hostname = talloc_asprintf(tctx, "%s.newdomain",
2508 TEST_MACHINE_NAME);
2510 /* Let the DC handle the "servicePrincipalName" and DNS hostname
2511 updates */
2512 q1.workstation_flags = 0;
2514 status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2515 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2516 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2518 msleep(250);
2520 if (sam_ctx) {
2521 /* AD workstation infos entry check */
2522 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2523 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2524 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
2525 torture_assert_str_equal(tctx,
2526 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
2527 q1.os_name.string, "'operatingSystem' should stick!");
2528 torture_assert(tctx,
2529 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
2530 "'operatingSystemServicePack' shouldn't stick!");
2531 torture_assert(tctx,
2532 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
2533 "'operatingSystemVersion' shouldn't stick!");
2535 /* The DNS host name should have been updated now by the server */
2536 torture_assert_str_equal(tctx,
2537 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
2538 q1.dns_hostname, "'DNS host name' didn't change!");
2540 /* Find the two "servicePrincipalName"s which the DC should have been
2541 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
2542 3.5.4.3.9 */
2543 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2544 torture_assert(tctx, spn_el != NULL,
2545 "There should exist 'servicePrincipalName's in AD!");
2546 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
2547 for (i=0; i < spn_el->num_values; i++)
2548 if (strcmp((char *) spn_el->values[i].data, temp_str) == 0)
2549 break;
2550 torture_assert(tctx, i != spn_el->num_values,
2551 "'servicePrincipalName' HOST/<Netbios name> not found!");
2552 temp_str = talloc_asprintf(tctx, "HOST/%s", q1.dns_hostname);
2553 for (i=0; i < spn_el->num_values; i++)
2554 if (strcmp((char *) spn_el->values[i].data, temp_str) == 0)
2555 break;
2556 torture_assert(tctx, i != spn_el->num_values,
2557 "'servicePrincipalName' HOST/<FQDN name> not found!");
2559 /* Check that the out DNS hostname was set properly */
2560 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
2561 old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
2564 /* Checks "workstation flags" */
2565 torture_assert(tctx,
2566 info.domain_info->workstation_flags == 0,
2567 "Out 'workstation flags' don't match!");
2570 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (verification of DNS hostname and check for trusted domains)\n");
2571 netlogon_creds_client_authenticator(creds, &a);
2573 /* The workstation handles the "servicePrincipalName" and DNS hostname
2574 updates */
2575 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
2577 status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2578 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2579 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2581 msleep(250);
2583 /* Now the in/out DNS hostnames should be the same */
2584 torture_assert_str_equal(tctx,
2585 info.domain_info->dns_hostname.string,
2586 query.workstation_info->dns_hostname,
2587 "In/Out 'DNS hostnames' don't match!");
2589 /* Checks "workstation flags" */
2590 torture_assert(tctx,
2591 info.domain_info->workstation_flags
2592 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
2593 "Out 'workstation flags' don't match!");
2595 /* Checks for trusted domains */
2596 torture_assert(tctx,
2597 (info.domain_info->trusted_domain_count != 0)
2598 && (info.domain_info->trusted_domains != NULL),
2599 "Trusted domains have been requested!");
2602 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (check for trusted domains)\n");
2603 netlogon_creds_client_authenticator(creds, &a);
2605 /* The workstation handles the "servicePrincipalName" and DNS hostname
2606 updates and requests inbound trusts */
2607 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
2608 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
2610 status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2611 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2612 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2614 msleep(250);
2616 /* Checks "workstation flags" */
2617 torture_assert(tctx,
2618 info.domain_info->workstation_flags
2619 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
2620 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
2621 "Out 'workstation flags' don't match!");
2623 /* Checks for trusted domains */
2624 torture_assert(tctx,
2625 (info.domain_info->trusted_domain_count != 0)
2626 && (info.domain_info->trusted_domains != NULL),
2627 "Trusted domains have been requested!");
2629 return true;
2633 static void async_callback(struct rpc_request *req)
2635 int *counter = (int *)req->async.private_data;
2636 if (NT_STATUS_IS_OK(req->status)) {
2637 (*counter)++;
2641 static bool test_GetDomainInfo_async(struct torture_context *tctx,
2642 struct dcerpc_pipe *p,
2643 struct cli_credentials *machine_credentials)
2645 NTSTATUS status;
2646 struct netr_LogonGetDomainInfo r;
2647 struct netr_WorkstationInformation q1;
2648 struct netr_Authenticator a;
2649 #define ASYNC_COUNT 100
2650 struct netlogon_creds_CredentialState *creds;
2651 struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
2652 struct rpc_request *req[ASYNC_COUNT];
2653 int i;
2654 int *async_counter = talloc(tctx, int);
2655 union netr_WorkstationInfo query;
2656 union netr_DomainInfo info;
2658 torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
2660 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2661 machine_credentials, &creds)) {
2662 return false;
2665 ZERO_STRUCT(r);
2666 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2667 r.in.computer_name = TEST_MACHINE_NAME;
2668 r.in.credential = &a;
2669 r.in.level = 1;
2670 r.in.return_authenticator = &a;
2671 r.in.query = &query;
2672 r.out.return_authenticator = &a;
2673 r.out.info = &info;
2675 ZERO_STRUCT(q1);
2676 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
2677 TEST_MACHINE_DNS_SUFFIX);
2678 q1.sitename = "Default-First-Site-Name";
2679 q1.os_name.string = "UNIX/Linux or similar";
2681 query.workstation_info = &q1;
2683 *async_counter = 0;
2685 for (i=0;i<ASYNC_COUNT;i++) {
2686 netlogon_creds_client_authenticator(creds, &a);
2688 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
2689 req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, tctx, &r);
2691 req[i]->async.callback = async_callback;
2692 req[i]->async.private_data = async_counter;
2694 /* even with this flush per request a w2k3 server seems to
2695 clag with multiple outstanding requests. bleergh. */
2696 torture_assert_int_equal(tctx, event_loop_once(dcerpc_event_context(p)), 0,
2697 "event_loop_once failed");
2700 for (i=0;i<ASYNC_COUNT;i++) {
2701 status = dcerpc_ndr_request_recv(req[i]);
2703 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
2704 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
2706 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred),
2707 "Credential chaining failed at async");
2710 torture_comment(tctx,
2711 "Testing netr_LogonGetDomainInfo - async count %d OK\n", *async_counter);
2713 torture_assert_int_equal(tctx, (*async_counter), ASYNC_COUNT, "int");
2715 return true;
2718 static bool test_ManyGetDCName(struct torture_context *tctx,
2719 struct dcerpc_pipe *p)
2721 NTSTATUS status;
2722 struct dcerpc_pipe *p2;
2723 struct lsa_ObjectAttribute attr;
2724 struct lsa_QosInfo qos;
2725 struct lsa_OpenPolicy2 o;
2726 struct policy_handle lsa_handle;
2727 struct lsa_DomainList domains;
2729 struct lsa_EnumTrustDom t;
2730 uint32_t resume_handle = 0;
2731 struct netr_GetAnyDCName d;
2732 const char *dcname = NULL;
2734 int i;
2736 if (p->conn->transport.transport != NCACN_NP) {
2737 return true;
2740 torture_comment(tctx, "Torturing GetDCName\n");
2742 status = dcerpc_secondary_connection(p, &p2, p->binding);
2743 torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
2745 status = dcerpc_bind_auth_none(p2, &ndr_table_lsarpc);
2746 torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
2748 qos.len = 0;
2749 qos.impersonation_level = 2;
2750 qos.context_mode = 1;
2751 qos.effective_only = 0;
2753 attr.len = 0;
2754 attr.root_dir = NULL;
2755 attr.object_name = NULL;
2756 attr.attributes = 0;
2757 attr.sec_desc = NULL;
2758 attr.sec_qos = &qos;
2760 o.in.system_name = "\\";
2761 o.in.attr = &attr;
2762 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2763 o.out.handle = &lsa_handle;
2765 status = dcerpc_lsa_OpenPolicy2(p2, tctx, &o);
2766 torture_assert_ntstatus_ok(tctx, status, "OpenPolicy2 failed");
2768 t.in.handle = &lsa_handle;
2769 t.in.resume_handle = &resume_handle;
2770 t.in.max_size = 1000;
2771 t.out.domains = &domains;
2772 t.out.resume_handle = &resume_handle;
2774 status = dcerpc_lsa_EnumTrustDom(p2, tctx, &t);
2776 if ((!NT_STATUS_IS_OK(status) &&
2777 (!NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES))))
2778 torture_fail(tctx, "Could not list domains");
2780 talloc_free(p2);
2782 d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
2783 dcerpc_server_name(p));
2784 d.out.dcname = &dcname;
2786 for (i=0; i<domains.count * 4; i++) {
2787 struct lsa_DomainInfo *info =
2788 &domains.domains[rand()%domains.count];
2790 d.in.domainname = info->name.string;
2792 status = dcerpc_netr_GetAnyDCName(p, tctx, &d);
2793 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2795 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
2796 dcname ? dcname : "unknown");
2799 return true;
2802 static bool test_SetPassword_with_flags(struct torture_context *tctx,
2803 struct dcerpc_pipe *p,
2804 struct cli_credentials *machine_credentials)
2806 uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
2807 struct netlogon_creds_CredentialState *creds;
2808 int i;
2810 if (!test_SetupCredentials2(p, tctx, 0,
2811 machine_credentials,
2812 cli_credentials_get_secure_channel_type(machine_credentials),
2813 &creds)) {
2814 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
2817 for (i=0; i < ARRAY_SIZE(flags); i++) {
2818 torture_assert(tctx,
2819 test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
2820 talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
2823 return true;
2826 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
2828 struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON");
2829 struct torture_rpc_tcase *tcase;
2830 struct torture_test *test;
2832 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
2833 &ndr_table_netlogon, TEST_MACHINE_NAME);
2835 torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
2836 torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
2837 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
2838 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
2839 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
2840 torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
2841 torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
2842 torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
2843 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
2844 torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
2845 torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
2846 torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
2847 torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
2848 torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
2849 torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
2850 torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
2851 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
2852 torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
2853 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
2854 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
2855 test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
2856 test->dangerous = true;
2857 torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
2858 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
2859 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
2860 torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
2861 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
2862 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
2863 torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
2865 return suite;
2868 struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
2870 struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON-S3");
2871 struct torture_rpc_tcase *tcase;
2873 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
2874 &ndr_table_netlogon, TEST_MACHINE_NAME);
2876 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
2877 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
2878 torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
2879 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
2880 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
2882 return suite;
2885 struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
2887 struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON-ADMIN");
2888 struct torture_rpc_tcase *tcase;
2890 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
2891 &ndr_table_netlogon, TEST_MACHINE_NAME);
2892 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
2893 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
2894 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
2896 tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netlogon",
2897 &ndr_table_netlogon, TEST_MACHINE_NAME);
2898 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
2899 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
2900 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
2902 tcase = torture_suite_add_rpc_iface_tcase(suite, "netlogon",
2903 &ndr_table_netlogon);
2904 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
2905 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
2906 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
2908 return suite;