s4-smbtorture: do not hard code BDC secure channel type into RPC-NETLOGON tests.
[Samba/gbeck.git] / source4 / torture / rpc / netlogon.c
blob9a73cfec5dd500aa111649d9fc43765f8e827f59
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 "version.h"
27 #include "torture/torture.h"
28 #include "lib/events/events.h"
29 #include "auth/auth.h"
30 #include "auth/gensec/gensec.h"
31 #include "lib/cmdline/popt_common.h"
32 #include "torture/rpc/rpc.h"
33 #include "torture/rpc/netlogon.h"
34 #include "../lib/crypto/crypto.h"
35 #include "libcli/auth/libcli_auth.h"
36 #include "librpc/gen_ndr/ndr_netlogon_c.h"
37 #include "librpc/gen_ndr/ndr_netlogon.h"
38 #include "librpc/gen_ndr/ndr_lsa_c.h"
39 #include "param/param.h"
40 #include "libcli/security/security.h"
41 #include "lib/ldb/include/ldb.h"
42 #include "lib/util/util_ldb.h"
43 #include "lib/ldb_wrap.h"
45 #define TEST_MACHINE_NAME "torturetest"
46 #define TEST_MACHINE_DNS_SUFFIX "torturedomain"
48 static bool test_LogonUasLogon(struct torture_context *tctx,
49 struct dcerpc_pipe *p)
51 NTSTATUS status;
52 struct netr_LogonUasLogon r;
53 struct netr_UasInfo *info = NULL;
55 r.in.server_name = NULL;
56 r.in.account_name = cli_credentials_get_username(cmdline_credentials);
57 r.in.workstation = TEST_MACHINE_NAME;
58 r.out.info = &info;
60 status = dcerpc_netr_LogonUasLogon(p, tctx, &r);
61 torture_assert_ntstatus_ok(tctx, status, "LogonUasLogon");
63 return true;
66 static bool test_LogonUasLogoff(struct torture_context *tctx,
67 struct dcerpc_pipe *p)
69 NTSTATUS status;
70 struct netr_LogonUasLogoff r;
71 struct netr_UasLogoffInfo info;
73 r.in.server_name = NULL;
74 r.in.account_name = cli_credentials_get_username(cmdline_credentials);
75 r.in.workstation = TEST_MACHINE_NAME;
76 r.out.info = &info;
78 status = dcerpc_netr_LogonUasLogoff(p, tctx, &r);
79 torture_assert_ntstatus_ok(tctx, status, "LogonUasLogoff");
81 return true;
84 bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
85 struct cli_credentials *credentials,
86 struct netlogon_creds_CredentialState **creds_out)
88 NTSTATUS status;
89 struct netr_ServerReqChallenge r;
90 struct netr_ServerAuthenticate a;
91 struct netr_Credential credentials1, credentials2, credentials3;
92 struct netlogon_creds_CredentialState *creds;
93 const struct samr_Password *mach_password;
94 const char *machine_name;
96 mach_password = cli_credentials_get_nt_hash(credentials, tctx);
97 machine_name = cli_credentials_get_workstation(credentials);
99 torture_comment(tctx, "Testing ServerReqChallenge\n");
101 r.in.server_name = NULL;
102 r.in.computer_name = machine_name;
103 r.in.credentials = &credentials1;
104 r.out.return_credentials = &credentials2;
106 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
108 status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
109 torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
111 a.in.server_name = NULL;
112 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
113 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(credentials);
114 a.in.computer_name = machine_name;
115 a.in.credentials = &credentials3;
116 a.out.return_credentials = &credentials3;
118 creds = netlogon_creds_client_init(tctx, a.in.account_name,
119 a.in.computer_name,
120 &credentials1, &credentials2,
121 mach_password, &credentials3,
123 torture_assert(tctx, creds != NULL, "memory allocation");
126 torture_comment(tctx, "Testing ServerAuthenticate\n");
128 status = dcerpc_netr_ServerAuthenticate(p, tctx, &a);
130 /* This allows the tests to continue against the more fussy windows 2008 */
131 if (NT_STATUS_EQUAL(status, NT_STATUS_DOWNGRADE_DETECTED)) {
132 return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
133 credentials,
134 cli_credentials_get_secure_channel_type(credentials),
135 creds_out);
138 torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate");
140 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
141 "Credential chaining failed");
143 *creds_out = creds;
144 return true;
147 bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx,
148 uint32_t negotiate_flags,
149 struct cli_credentials *machine_credentials,
150 int sec_chan_type,
151 struct netlogon_creds_CredentialState **creds_out)
153 NTSTATUS status;
154 struct netr_ServerReqChallenge r;
155 struct netr_ServerAuthenticate2 a;
156 struct netr_Credential credentials1, credentials2, credentials3;
157 struct netlogon_creds_CredentialState *creds;
158 const struct samr_Password *mach_password;
159 const char *machine_name;
161 mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
162 machine_name = cli_credentials_get_workstation(machine_credentials);
164 torture_comment(tctx, "Testing ServerReqChallenge\n");
167 r.in.server_name = NULL;
168 r.in.computer_name = machine_name;
169 r.in.credentials = &credentials1;
170 r.out.return_credentials = &credentials2;
172 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
174 status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
175 torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
177 a.in.server_name = NULL;
178 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
179 a.in.secure_channel_type = sec_chan_type;
180 a.in.computer_name = machine_name;
181 a.in.negotiate_flags = &negotiate_flags;
182 a.out.negotiate_flags = &negotiate_flags;
183 a.in.credentials = &credentials3;
184 a.out.return_credentials = &credentials3;
186 creds = netlogon_creds_client_init(tctx, a.in.account_name,
187 a.in.computer_name,
188 &credentials1, &credentials2,
189 mach_password, &credentials3,
190 negotiate_flags);
192 torture_assert(tctx, creds != NULL, "memory allocation");
194 torture_comment(tctx, "Testing ServerAuthenticate2\n");
196 status = dcerpc_netr_ServerAuthenticate2(p, tctx, &a);
197 torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate2");
199 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
200 "Credential chaining failed");
202 torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
204 *creds_out = creds;
205 return true;
209 static bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx,
210 uint32_t negotiate_flags,
211 struct cli_credentials *machine_credentials,
212 struct netlogon_creds_CredentialState **creds_out)
214 NTSTATUS status;
215 struct netr_ServerReqChallenge r;
216 struct netr_ServerAuthenticate3 a;
217 struct netr_Credential credentials1, credentials2, credentials3;
218 struct netlogon_creds_CredentialState *creds;
219 struct samr_Password mach_password;
220 uint32_t rid;
221 const char *machine_name;
222 const char *plain_pass;
224 machine_name = cli_credentials_get_workstation(machine_credentials);
225 plain_pass = cli_credentials_get_password(machine_credentials);
227 torture_comment(tctx, "Testing ServerReqChallenge\n");
229 r.in.server_name = NULL;
230 r.in.computer_name = machine_name;
231 r.in.credentials = &credentials1;
232 r.out.return_credentials = &credentials2;
234 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
236 status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
237 torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
239 E_md4hash(plain_pass, mach_password.hash);
241 a.in.server_name = NULL;
242 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
243 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
244 a.in.computer_name = machine_name;
245 a.in.negotiate_flags = &negotiate_flags;
246 a.in.credentials = &credentials3;
247 a.out.return_credentials = &credentials3;
248 a.out.negotiate_flags = &negotiate_flags;
249 a.out.rid = &rid;
251 creds = netlogon_creds_client_init(tctx, a.in.account_name,
252 a.in.computer_name,
253 &credentials1, &credentials2,
254 &mach_password, &credentials3,
255 negotiate_flags);
257 torture_assert(tctx, creds != NULL, "memory allocation");
259 torture_comment(tctx, "Testing ServerAuthenticate3\n");
261 status = dcerpc_netr_ServerAuthenticate3(p, tctx, &a);
262 torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate3");
263 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
265 torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
267 /* Prove that requesting a challenge again won't break it */
268 status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
269 torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
271 *creds_out = creds;
272 return true;
276 try a change password for our machine account
278 static bool test_SetPassword(struct torture_context *tctx,
279 struct dcerpc_pipe *p,
280 struct cli_credentials *machine_credentials)
282 NTSTATUS status;
283 struct netr_ServerPasswordSet r;
284 const char *password;
285 struct netlogon_creds_CredentialState *creds;
286 struct netr_Authenticator credential, return_authenticator;
287 struct samr_Password new_password;
289 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
290 return false;
293 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
294 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
295 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
296 r.in.computer_name = TEST_MACHINE_NAME;
297 r.in.credential = &credential;
298 r.in.new_password = &new_password;
299 r.out.return_authenticator = &return_authenticator;
301 password = generate_random_str(tctx, 8);
302 E_md4hash(password, new_password.hash);
304 netlogon_creds_des_encrypt(creds, &new_password);
306 torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
307 torture_comment(tctx, "Changing machine account password to '%s'\n",
308 password);
310 netlogon_creds_client_authenticator(creds, &credential);
312 status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
313 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet");
315 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
316 torture_comment(tctx, "Credential chaining failed\n");
319 /* by changing the machine password twice we test the
320 credentials chaining fully, and we verify that the server
321 allows the password to be set to the same value twice in a
322 row (match win2k3) */
323 torture_comment(tctx,
324 "Testing a second ServerPasswordSet on machine account\n");
325 torture_comment(tctx,
326 "Changing machine account password to '%s' (same as previous run)\n", password);
328 netlogon_creds_client_authenticator(creds, &credential);
330 status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
331 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (2)");
333 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
334 torture_comment(tctx, "Credential chaining failed\n");
337 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
339 torture_assert(tctx,
340 test_SetupCredentials(p, tctx, machine_credentials, &creds),
341 "ServerPasswordSet failed to actually change the password");
343 return true;
347 try a change password for our machine account
349 static bool test_SetPassword_flags(struct torture_context *tctx,
350 struct dcerpc_pipe *p,
351 struct cli_credentials *machine_credentials,
352 uint32_t negotiate_flags)
354 NTSTATUS status;
355 struct netr_ServerPasswordSet r;
356 const char *password;
357 struct netlogon_creds_CredentialState *creds;
358 struct netr_Authenticator credential, return_authenticator;
359 struct samr_Password new_password;
361 if (!test_SetupCredentials2(p, tctx, negotiate_flags,
362 machine_credentials,
363 cli_credentials_get_secure_channel_type(machine_credentials),
364 &creds)) {
365 return false;
368 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
369 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
370 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
371 r.in.computer_name = TEST_MACHINE_NAME;
372 r.in.credential = &credential;
373 r.in.new_password = &new_password;
374 r.out.return_authenticator = &return_authenticator;
376 password = generate_random_str(tctx, 8);
377 E_md4hash(password, new_password.hash);
379 netlogon_creds_des_encrypt(creds, &new_password);
381 torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
382 torture_comment(tctx, "Changing machine account password to '%s'\n",
383 password);
385 netlogon_creds_client_authenticator(creds, &credential);
387 status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
388 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet");
390 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
391 torture_comment(tctx, "Credential chaining failed\n");
394 /* by changing the machine password twice we test the
395 credentials chaining fully, and we verify that the server
396 allows the password to be set to the same value twice in a
397 row (match win2k3) */
398 torture_comment(tctx,
399 "Testing a second ServerPasswordSet on machine account\n");
400 torture_comment(tctx,
401 "Changing machine account password to '%s' (same as previous run)\n", password);
403 netlogon_creds_client_authenticator(creds, &credential);
405 status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
406 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (2)");
408 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
409 torture_comment(tctx, "Credential chaining failed\n");
412 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
414 torture_assert(tctx,
415 test_SetupCredentials(p, tctx, machine_credentials, &creds),
416 "ServerPasswordSet failed to actually change the password");
418 return true;
423 generate a random password for password change tests
425 static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
427 int i;
428 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
429 generate_random_buffer(password.data, password.length);
431 for (i=0; i < len; i++) {
432 if (((uint16_t *)password.data)[i] == 0) {
433 ((uint16_t *)password.data)[i] = 1;
437 return password;
441 try a change password for our machine account
443 static bool test_SetPassword2(struct torture_context *tctx,
444 struct dcerpc_pipe *p,
445 struct cli_credentials *machine_credentials)
447 NTSTATUS status;
448 struct netr_ServerPasswordSet2 r;
449 const char *password;
450 DATA_BLOB new_random_pass;
451 struct netlogon_creds_CredentialState *creds;
452 struct samr_CryptPassword password_buf;
453 struct samr_Password nt_hash;
454 struct netr_Authenticator credential, return_authenticator;
455 struct netr_CryptPassword new_password;
457 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
458 return false;
461 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
462 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
463 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
464 r.in.computer_name = TEST_MACHINE_NAME;
465 r.in.credential = &credential;
466 r.in.new_password = &new_password;
467 r.out.return_authenticator = &return_authenticator;
469 password = generate_random_str(tctx, 8);
470 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
471 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
473 memcpy(new_password.data, password_buf.data, 512);
474 new_password.length = IVAL(password_buf.data, 512);
476 torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
477 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
479 netlogon_creds_client_authenticator(creds, &credential);
481 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
482 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2");
484 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
485 torture_comment(tctx, "Credential chaining failed\n");
488 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
490 if (!torture_setting_bool(tctx, "dangerous", false)) {
491 torture_comment(tctx,
492 "Not testing ability to set password to '', enable dangerous tests to perform this test\n");
493 } else {
494 /* by changing the machine password to ""
495 * we check if the server uses password restrictions
496 * for ServerPasswordSet2
497 * (win2k3 accepts "")
499 password = "";
500 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
501 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
503 memcpy(new_password.data, password_buf.data, 512);
504 new_password.length = IVAL(password_buf.data, 512);
506 torture_comment(tctx,
507 "Testing ServerPasswordSet2 on machine account\n");
508 torture_comment(tctx,
509 "Changing machine account password to '%s'\n", password);
511 netlogon_creds_client_authenticator(creds, &credential);
513 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
514 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2");
516 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
517 torture_comment(tctx, "Credential chaining failed\n");
520 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
523 torture_assert(tctx, test_SetupCredentials(p, tctx, machine_credentials, &creds),
524 "ServerPasswordSet failed to actually change the password");
526 /* now try a random password */
527 password = generate_random_str(tctx, 8);
528 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
529 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
531 memcpy(new_password.data, password_buf.data, 512);
532 new_password.length = IVAL(password_buf.data, 512);
534 torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
535 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
537 netlogon_creds_client_authenticator(creds, &credential);
539 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
540 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2 (2)");
542 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
543 torture_comment(tctx, "Credential chaining failed\n");
546 /* by changing the machine password twice we test the
547 credentials chaining fully, and we verify that the server
548 allows the password to be set to the same value twice in a
549 row (match win2k3) */
550 torture_comment(tctx,
551 "Testing a second ServerPasswordSet2 on machine account\n");
552 torture_comment(tctx,
553 "Changing machine account password to '%s' (same as previous run)\n", password);
555 netlogon_creds_client_authenticator(creds, &credential);
557 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
558 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (3)");
560 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
561 torture_comment(tctx, "Credential chaining failed\n");
564 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
566 torture_assert (tctx,
567 test_SetupCredentials(p, tctx, machine_credentials, &creds),
568 "ServerPasswordSet failed to actually change the password");
570 new_random_pass = netlogon_very_rand_pass(tctx, 128);
572 /* now try a random stream of bytes for a password */
573 set_pw_in_buffer(password_buf.data, &new_random_pass);
575 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
577 memcpy(new_password.data, password_buf.data, 512);
578 new_password.length = IVAL(password_buf.data, 512);
580 torture_comment(tctx,
581 "Testing a third ServerPasswordSet2 on machine account, with a compleatly random password\n");
583 netlogon_creds_client_authenticator(creds, &credential);
585 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
586 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (3)");
588 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
589 torture_comment(tctx, "Credential chaining failed\n");
592 mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
594 cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
595 cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
597 torture_assert (tctx,
598 test_SetupCredentials(p, tctx, machine_credentials, &creds),
599 "ServerPasswordSet failed to actually change the password");
601 return true;
604 static bool test_GetPassword(struct torture_context *tctx,
605 struct dcerpc_pipe *p,
606 struct cli_credentials *machine_credentials)
608 struct netr_ServerPasswordGet r;
609 struct netlogon_creds_CredentialState *creds;
610 struct netr_Authenticator credential;
611 NTSTATUS status;
612 struct netr_Authenticator return_authenticator;
613 struct samr_Password password;
615 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
616 return false;
619 netlogon_creds_client_authenticator(creds, &credential);
621 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
622 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
623 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
624 r.in.computer_name = TEST_MACHINE_NAME;
625 r.in.credential = &credential;
626 r.out.return_authenticator = &return_authenticator;
627 r.out.password = &password;
629 status = dcerpc_netr_ServerPasswordGet(p, tctx, &r);
630 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
632 return true;
635 static bool test_GetTrustPasswords(struct torture_context *tctx,
636 struct dcerpc_pipe *p,
637 struct cli_credentials *machine_credentials)
639 struct netr_ServerTrustPasswordsGet r;
640 struct netlogon_creds_CredentialState *creds;
641 struct netr_Authenticator credential;
642 NTSTATUS status;
643 struct netr_Authenticator return_authenticator;
644 struct samr_Password password, password2;
646 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
647 return false;
650 netlogon_creds_client_authenticator(creds, &credential);
652 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
653 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
654 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
655 r.in.computer_name = TEST_MACHINE_NAME;
656 r.in.credential = &credential;
657 r.out.return_authenticator = &return_authenticator;
658 r.out.password = &password;
659 r.out.password2 = &password2;
661 status = dcerpc_netr_ServerTrustPasswordsGet(p, tctx, &r);
662 torture_assert_ntstatus_ok(tctx, status, "ServerTrustPasswordsGet");
664 return true;
668 try a netlogon SamLogon
670 bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
671 struct cli_credentials *credentials,
672 struct netlogon_creds_CredentialState *creds)
674 NTSTATUS status;
675 struct netr_LogonSamLogon r;
676 struct netr_Authenticator auth, auth2;
677 union netr_LogonLevel logon;
678 union netr_Validation validation;
679 uint8_t authoritative;
680 struct netr_NetworkInfo ninfo;
681 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
682 int i;
683 int flags = CLI_CRED_NTLM_AUTH;
684 if (lp_client_lanman_auth(tctx->lp_ctx)) {
685 flags |= CLI_CRED_LANMAN_AUTH;
688 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
689 flags |= CLI_CRED_NTLMv2_AUTH;
692 cli_credentials_get_ntlm_username_domain(cmdline_credentials, tctx,
693 &ninfo.identity_info.account_name.string,
694 &ninfo.identity_info.domain_name.string);
696 generate_random_buffer(ninfo.challenge,
697 sizeof(ninfo.challenge));
698 chal = data_blob_const(ninfo.challenge,
699 sizeof(ninfo.challenge));
701 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials),
702 cli_credentials_get_domain(credentials));
704 status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx,
705 &flags,
706 chal,
707 names_blob,
708 &lm_resp, &nt_resp,
709 NULL, NULL);
710 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
712 ninfo.lm.data = lm_resp.data;
713 ninfo.lm.length = lm_resp.length;
715 ninfo.nt.data = nt_resp.data;
716 ninfo.nt.length = nt_resp.length;
718 ninfo.identity_info.parameter_control = 0;
719 ninfo.identity_info.logon_id_low = 0;
720 ninfo.identity_info.logon_id_high = 0;
721 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
723 logon.network = &ninfo;
725 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
726 r.in.computer_name = cli_credentials_get_workstation(credentials);
727 r.in.credential = &auth;
728 r.in.return_authenticator = &auth2;
729 r.in.logon_level = 2;
730 r.in.logon = &logon;
731 r.out.validation = &validation;
732 r.out.authoritative = &authoritative;
734 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
736 for (i=2;i<3;i++) {
737 ZERO_STRUCT(auth2);
738 netlogon_creds_client_authenticator(creds, &auth);
740 r.in.validation_level = i;
742 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
743 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
745 torture_assert(tctx, netlogon_creds_client_check(creds,
746 &r.out.return_authenticator->cred),
747 "Credential chaining failed");
750 r.in.credential = NULL;
752 for (i=2;i<=3;i++) {
754 r.in.validation_level = i;
756 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
758 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
759 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_INVALID_PARAMETER,
760 "LogonSamLogon expected INVALID_PARAMETER");
764 return true;
768 try a netlogon SamLogon
770 static bool test_SamLogon(struct torture_context *tctx,
771 struct dcerpc_pipe *p,
772 struct cli_credentials *credentials)
774 struct netlogon_creds_CredentialState *creds;
776 if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
777 return false;
780 return test_netlogon_ops(p, tctx, credentials, creds);
783 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
784 static uint64_t sequence_nums[3];
787 try a netlogon DatabaseSync
789 static bool test_DatabaseSync(struct torture_context *tctx,
790 struct dcerpc_pipe *p,
791 struct cli_credentials *machine_credentials)
793 NTSTATUS status;
794 struct netr_DatabaseSync r;
795 struct netlogon_creds_CredentialState *creds;
796 const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
797 int i;
798 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
799 struct netr_Authenticator credential, return_authenticator;
801 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
802 return false;
805 ZERO_STRUCT(return_authenticator);
807 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
808 r.in.computername = TEST_MACHINE_NAME;
809 r.in.preferredmaximumlength = (uint32_t)-1;
810 r.in.return_authenticator = &return_authenticator;
811 r.out.delta_enum_array = &delta_enum_array;
812 r.out.return_authenticator = &return_authenticator;
814 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
816 uint32_t sync_context = 0;
818 r.in.database_id = database_ids[i];
819 r.in.sync_context = &sync_context;
820 r.out.sync_context = &sync_context;
822 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
824 do {
825 netlogon_creds_client_authenticator(creds, &credential);
827 r.in.credential = &credential;
829 status = dcerpc_netr_DatabaseSync(p, tctx, &r);
830 if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
831 break;
833 /* Native mode servers don't do this */
834 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
835 return true;
837 torture_assert_ntstatus_ok(tctx, status, "DatabaseSync");
839 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
840 torture_comment(tctx, "Credential chaining failed\n");
843 if (delta_enum_array &&
844 delta_enum_array->num_deltas > 0 &&
845 delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
846 delta_enum_array->delta_enum[0].delta_union.domain) {
847 sequence_nums[r.in.database_id] =
848 delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
849 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
850 r.in.database_id,
851 (unsigned long long)sequence_nums[r.in.database_id]);
853 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
856 return true;
861 try a netlogon DatabaseDeltas
863 static bool test_DatabaseDeltas(struct torture_context *tctx,
864 struct dcerpc_pipe *p,
865 struct cli_credentials *machine_credentials)
867 NTSTATUS status;
868 struct netr_DatabaseDeltas r;
869 struct netlogon_creds_CredentialState *creds;
870 struct netr_Authenticator credential;
871 struct netr_Authenticator return_authenticator;
872 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
873 const uint32_t database_ids[] = {0, 1, 2};
874 int i;
876 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
877 return false;
880 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
881 r.in.computername = TEST_MACHINE_NAME;
882 r.in.preferredmaximumlength = (uint32_t)-1;
883 ZERO_STRUCT(r.in.return_authenticator);
884 r.out.return_authenticator = &return_authenticator;
885 r.out.delta_enum_array = &delta_enum_array;
887 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
888 r.in.database_id = database_ids[i];
889 r.in.sequence_num = &sequence_nums[r.in.database_id];
891 if (*r.in.sequence_num == 0) continue;
893 *r.in.sequence_num -= 1;
895 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n",
896 r.in.database_id, (unsigned long long)*r.in.sequence_num);
898 do {
899 netlogon_creds_client_authenticator(creds, &credential);
901 status = dcerpc_netr_DatabaseDeltas(p, tctx, &r);
902 if (NT_STATUS_EQUAL(status,
903 NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
904 torture_comment(tctx, "not considering %s to be an error\n",
905 nt_errstr(status));
906 return true;
908 if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
909 break;
911 torture_assert_ntstatus_ok(tctx, status, "DatabaseDeltas");
913 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
914 torture_comment(tctx, "Credential chaining failed\n");
917 (*r.in.sequence_num)++;
918 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
921 return true;
924 static bool test_DatabaseRedo(struct torture_context *tctx,
925 struct dcerpc_pipe *p,
926 struct cli_credentials *machine_credentials)
928 NTSTATUS status;
929 struct netr_DatabaseRedo r;
930 struct netlogon_creds_CredentialState *creds;
931 struct netr_Authenticator credential;
932 struct netr_Authenticator return_authenticator;
933 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
934 struct netr_ChangeLogEntry e;
935 struct dom_sid null_sid, *sid;
936 int i,d;
938 ZERO_STRUCT(null_sid);
940 sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
944 struct {
945 uint32_t rid;
946 uint16_t flags;
947 uint8_t db_index;
948 uint8_t delta_type;
949 struct dom_sid sid;
950 const char *name;
951 NTSTATUS expected_error;
952 uint32_t expected_num_results;
953 uint8_t expected_delta_type_1;
954 uint8_t expected_delta_type_2;
955 const char *comment;
956 } changes[] = {
958 /* SAM_DATABASE_DOMAIN */
961 .rid = 0,
962 .flags = 0,
963 .db_index = SAM_DATABASE_DOMAIN,
964 .delta_type = NETR_DELTA_MODIFY_COUNT,
965 .sid = null_sid,
966 .name = NULL,
967 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
968 .expected_num_results = 0,
969 .comment = "NETR_DELTA_MODIFY_COUNT"
972 .rid = 0,
973 .flags = 0,
974 .db_index = SAM_DATABASE_DOMAIN,
975 .delta_type = 0,
976 .sid = null_sid,
977 .name = NULL,
978 .expected_error = NT_STATUS_OK,
979 .expected_num_results = 1,
980 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
981 .comment = "NULL DELTA"
984 .rid = 0,
985 .flags = 0,
986 .db_index = SAM_DATABASE_DOMAIN,
987 .delta_type = NETR_DELTA_DOMAIN,
988 .sid = null_sid,
989 .name = NULL,
990 .expected_error = NT_STATUS_OK,
991 .expected_num_results = 1,
992 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
993 .comment = "NETR_DELTA_DOMAIN"
996 .rid = DOMAIN_RID_ADMINISTRATOR,
997 .flags = 0,
998 .db_index = SAM_DATABASE_DOMAIN,
999 .delta_type = NETR_DELTA_USER,
1000 .sid = null_sid,
1001 .name = NULL,
1002 .expected_error = NT_STATUS_OK,
1003 .expected_num_results = 1,
1004 .expected_delta_type_1 = NETR_DELTA_USER,
1005 .comment = "NETR_DELTA_USER by rid 500"
1008 .rid = DOMAIN_RID_GUEST,
1009 .flags = 0,
1010 .db_index = SAM_DATABASE_DOMAIN,
1011 .delta_type = NETR_DELTA_USER,
1012 .sid = null_sid,
1013 .name = NULL,
1014 .expected_error = NT_STATUS_OK,
1015 .expected_num_results = 1,
1016 .expected_delta_type_1 = NETR_DELTA_USER,
1017 .comment = "NETR_DELTA_USER by rid 501"
1020 .rid = 0,
1021 .flags = NETR_CHANGELOG_SID_INCLUDED,
1022 .db_index = SAM_DATABASE_DOMAIN,
1023 .delta_type = NETR_DELTA_USER,
1024 .sid = *sid,
1025 .name = NULL,
1026 .expected_error = NT_STATUS_OK,
1027 .expected_num_results = 1,
1028 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1029 .comment = "NETR_DELTA_USER by sid and flags"
1032 .rid = 0,
1033 .flags = NETR_CHANGELOG_SID_INCLUDED,
1034 .db_index = SAM_DATABASE_DOMAIN,
1035 .delta_type = NETR_DELTA_USER,
1036 .sid = null_sid,
1037 .name = NULL,
1038 .expected_error = NT_STATUS_OK,
1039 .expected_num_results = 1,
1040 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1041 .comment = "NETR_DELTA_USER by null_sid and flags"
1044 .rid = 0,
1045 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1046 .db_index = SAM_DATABASE_DOMAIN,
1047 .delta_type = NETR_DELTA_USER,
1048 .sid = null_sid,
1049 .name = "administrator",
1050 .expected_error = NT_STATUS_OK,
1051 .expected_num_results = 1,
1052 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1053 .comment = "NETR_DELTA_USER by name 'administrator'"
1056 .rid = DOMAIN_RID_ADMINS,
1057 .flags = 0,
1058 .db_index = SAM_DATABASE_DOMAIN,
1059 .delta_type = NETR_DELTA_GROUP,
1060 .sid = null_sid,
1061 .name = NULL,
1062 .expected_error = NT_STATUS_OK,
1063 .expected_num_results = 2,
1064 .expected_delta_type_1 = NETR_DELTA_GROUP,
1065 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
1066 .comment = "NETR_DELTA_GROUP by rid 512"
1069 .rid = DOMAIN_RID_ADMINS,
1070 .flags = 0,
1071 .db_index = SAM_DATABASE_DOMAIN,
1072 .delta_type = NETR_DELTA_GROUP_MEMBER,
1073 .sid = null_sid,
1074 .name = NULL,
1075 .expected_error = NT_STATUS_OK,
1076 .expected_num_results = 2,
1077 .expected_delta_type_1 = NETR_DELTA_GROUP,
1078 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
1079 .comment = "NETR_DELTA_GROUP_MEMBER by rid 512"
1083 /* SAM_DATABASE_BUILTIN */
1086 .rid = 0,
1087 .flags = 0,
1088 .db_index = SAM_DATABASE_BUILTIN,
1089 .delta_type = NETR_DELTA_MODIFY_COUNT,
1090 .sid = null_sid,
1091 .name = NULL,
1092 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1093 .expected_num_results = 0,
1094 .comment = "NETR_DELTA_MODIFY_COUNT"
1097 .rid = 0,
1098 .flags = 0,
1099 .db_index = SAM_DATABASE_BUILTIN,
1100 .delta_type = NETR_DELTA_DOMAIN,
1101 .sid = null_sid,
1102 .name = NULL,
1103 .expected_error = NT_STATUS_OK,
1104 .expected_num_results = 1,
1105 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1106 .comment = "NETR_DELTA_DOMAIN"
1109 .rid = DOMAIN_RID_ADMINISTRATOR,
1110 .flags = 0,
1111 .db_index = SAM_DATABASE_BUILTIN,
1112 .delta_type = NETR_DELTA_USER,
1113 .sid = null_sid,
1114 .name = NULL,
1115 .expected_error = NT_STATUS_OK,
1116 .expected_num_results = 1,
1117 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1118 .comment = "NETR_DELTA_USER by rid 500"
1121 .rid = 0,
1122 .flags = 0,
1123 .db_index = SAM_DATABASE_BUILTIN,
1124 .delta_type = NETR_DELTA_USER,
1125 .sid = null_sid,
1126 .name = NULL,
1127 .expected_error = NT_STATUS_OK,
1128 .expected_num_results = 1,
1129 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1130 .comment = "NETR_DELTA_USER"
1133 .rid = 544,
1134 .flags = 0,
1135 .db_index = SAM_DATABASE_BUILTIN,
1136 .delta_type = NETR_DELTA_ALIAS,
1137 .sid = null_sid,
1138 .name = NULL,
1139 .expected_error = NT_STATUS_OK,
1140 .expected_num_results = 2,
1141 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1142 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1143 .comment = "NETR_DELTA_ALIAS by rid 544"
1146 .rid = 544,
1147 .flags = 0,
1148 .db_index = SAM_DATABASE_BUILTIN,
1149 .delta_type = NETR_DELTA_ALIAS_MEMBER,
1150 .sid = null_sid,
1151 .name = NULL,
1152 .expected_error = NT_STATUS_OK,
1153 .expected_num_results = 2,
1154 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1155 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1156 .comment = "NETR_DELTA_ALIAS_MEMBER by rid 544"
1159 .rid = 544,
1160 .flags = 0,
1161 .db_index = SAM_DATABASE_BUILTIN,
1162 .delta_type = 0,
1163 .sid = null_sid,
1164 .name = NULL,
1165 .expected_error = NT_STATUS_OK,
1166 .expected_num_results = 1,
1167 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1168 .comment = "NULL DELTA by rid 544"
1171 .rid = 544,
1172 .flags = NETR_CHANGELOG_SID_INCLUDED,
1173 .db_index = SAM_DATABASE_BUILTIN,
1174 .delta_type = 0,
1175 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1176 .name = NULL,
1177 .expected_error = NT_STATUS_OK,
1178 .expected_num_results = 1,
1179 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1180 .comment = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
1183 .rid = 544,
1184 .flags = NETR_CHANGELOG_SID_INCLUDED,
1185 .db_index = SAM_DATABASE_BUILTIN,
1186 .delta_type = NETR_DELTA_ALIAS,
1187 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1188 .name = NULL,
1189 .expected_error = NT_STATUS_OK,
1190 .expected_num_results = 2,
1191 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1192 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1193 .comment = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
1196 .rid = 0,
1197 .flags = NETR_CHANGELOG_SID_INCLUDED,
1198 .db_index = SAM_DATABASE_BUILTIN,
1199 .delta_type = NETR_DELTA_ALIAS,
1200 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1201 .name = NULL,
1202 .expected_error = NT_STATUS_OK,
1203 .expected_num_results = 1,
1204 .expected_delta_type_1 = NETR_DELTA_DELETE_ALIAS,
1205 .comment = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
1208 /* SAM_DATABASE_PRIVS */
1211 .rid = 0,
1212 .flags = 0,
1213 .db_index = SAM_DATABASE_PRIVS,
1214 .delta_type = 0,
1215 .sid = null_sid,
1216 .name = NULL,
1217 .expected_error = NT_STATUS_ACCESS_DENIED,
1218 .expected_num_results = 0,
1219 .comment = "NULL DELTA"
1222 .rid = 0,
1223 .flags = 0,
1224 .db_index = SAM_DATABASE_PRIVS,
1225 .delta_type = NETR_DELTA_MODIFY_COUNT,
1226 .sid = null_sid,
1227 .name = NULL,
1228 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1229 .expected_num_results = 0,
1230 .comment = "NETR_DELTA_MODIFY_COUNT"
1233 .rid = 0,
1234 .flags = 0,
1235 .db_index = SAM_DATABASE_PRIVS,
1236 .delta_type = NETR_DELTA_POLICY,
1237 .sid = null_sid,
1238 .name = NULL,
1239 .expected_error = NT_STATUS_OK,
1240 .expected_num_results = 1,
1241 .expected_delta_type_1 = NETR_DELTA_POLICY,
1242 .comment = "NETR_DELTA_POLICY"
1245 .rid = 0,
1246 .flags = NETR_CHANGELOG_SID_INCLUDED,
1247 .db_index = SAM_DATABASE_PRIVS,
1248 .delta_type = NETR_DELTA_POLICY,
1249 .sid = null_sid,
1250 .name = NULL,
1251 .expected_error = NT_STATUS_OK,
1252 .expected_num_results = 1,
1253 .expected_delta_type_1 = NETR_DELTA_POLICY,
1254 .comment = "NETR_DELTA_POLICY by null sid and flags"
1257 .rid = 0,
1258 .flags = NETR_CHANGELOG_SID_INCLUDED,
1259 .db_index = SAM_DATABASE_PRIVS,
1260 .delta_type = NETR_DELTA_POLICY,
1261 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
1262 .name = NULL,
1263 .expected_error = NT_STATUS_OK,
1264 .expected_num_results = 1,
1265 .expected_delta_type_1 = NETR_DELTA_POLICY,
1266 .comment = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
1269 .rid = DOMAIN_RID_ADMINISTRATOR,
1270 .flags = 0,
1271 .db_index = SAM_DATABASE_PRIVS,
1272 .delta_type = NETR_DELTA_ACCOUNT,
1273 .sid = null_sid,
1274 .name = NULL,
1275 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
1276 .expected_num_results = 0,
1277 .comment = "NETR_DELTA_ACCOUNT by rid 500"
1280 .rid = 0,
1281 .flags = NETR_CHANGELOG_SID_INCLUDED,
1282 .db_index = SAM_DATABASE_PRIVS,
1283 .delta_type = NETR_DELTA_ACCOUNT,
1284 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1285 .name = NULL,
1286 .expected_error = NT_STATUS_OK,
1287 .expected_num_results = 1,
1288 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
1289 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
1292 .rid = 0,
1293 .flags = NETR_CHANGELOG_SID_INCLUDED |
1294 NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
1295 .db_index = SAM_DATABASE_PRIVS,
1296 .delta_type = NETR_DELTA_ACCOUNT,
1297 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1298 .name = NULL,
1299 .expected_error = NT_STATUS_OK,
1300 .expected_num_results = 1,
1301 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
1302 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
1305 .rid = 0,
1306 .flags = NETR_CHANGELOG_SID_INCLUDED |
1307 NETR_CHANGELOG_NAME_INCLUDED,
1308 .db_index = SAM_DATABASE_PRIVS,
1309 .delta_type = NETR_DELTA_ACCOUNT,
1310 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1311 .name = NULL,
1312 .expected_error = NT_STATUS_INVALID_PARAMETER,
1313 .expected_num_results = 0,
1314 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
1317 .rid = DOMAIN_RID_ADMINISTRATOR,
1318 .flags = NETR_CHANGELOG_SID_INCLUDED,
1319 .db_index = SAM_DATABASE_PRIVS,
1320 .delta_type = NETR_DELTA_ACCOUNT,
1321 .sid = *sid,
1322 .name = NULL,
1323 .expected_error = NT_STATUS_OK,
1324 .expected_num_results = 1,
1325 .expected_delta_type_1 = NETR_DELTA_DELETE_ACCOUNT,
1326 .comment = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
1329 .rid = 0,
1330 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1331 .db_index = SAM_DATABASE_PRIVS,
1332 .delta_type = NETR_DELTA_SECRET,
1333 .sid = null_sid,
1334 .name = "IsurelydontexistIhope",
1335 .expected_error = NT_STATUS_OK,
1336 .expected_num_results = 1,
1337 .expected_delta_type_1 = NETR_DELTA_DELETE_SECRET,
1338 .comment = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
1341 .rid = 0,
1342 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1343 .db_index = SAM_DATABASE_PRIVS,
1344 .delta_type = NETR_DELTA_SECRET,
1345 .sid = null_sid,
1346 .name = "G$BCKUPKEY_P",
1347 .expected_error = NT_STATUS_OK,
1348 .expected_num_results = 1,
1349 .expected_delta_type_1 = NETR_DELTA_SECRET,
1350 .comment = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
1354 ZERO_STRUCT(return_authenticator);
1356 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1357 r.in.computername = TEST_MACHINE_NAME;
1358 r.in.return_authenticator = &return_authenticator;
1359 r.out.return_authenticator = &return_authenticator;
1360 r.out.delta_enum_array = &delta_enum_array;
1362 for (d=0; d<3; d++) {
1364 const char *database;
1366 switch (d) {
1367 case 0:
1368 database = "SAM";
1369 break;
1370 case 1:
1371 database = "BUILTIN";
1372 break;
1373 case 2:
1374 database = "LSA";
1375 break;
1376 default:
1377 break;
1380 torture_comment(tctx, "Testing DatabaseRedo\n");
1382 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1383 return false;
1386 for (i=0;i<ARRAY_SIZE(changes);i++) {
1388 if (d != changes[i].db_index) {
1389 continue;
1392 netlogon_creds_client_authenticator(creds, &credential);
1394 r.in.credential = &credential;
1396 e.serial_number1 = 0;
1397 e.serial_number2 = 0;
1398 e.object_rid = changes[i].rid;
1399 e.flags = changes[i].flags;
1400 e.db_index = changes[i].db_index;
1401 e.delta_type = changes[i].delta_type;
1403 switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
1404 case NETR_CHANGELOG_SID_INCLUDED:
1405 e.object.object_sid = changes[i].sid;
1406 break;
1407 case NETR_CHANGELOG_NAME_INCLUDED:
1408 e.object.object_name = changes[i].name;
1409 break;
1410 default:
1411 break;
1414 r.in.change_log_entry = e;
1416 torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
1417 database, changes[i].comment);
1419 status = dcerpc_netr_DatabaseRedo(p, tctx, &r);
1420 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1421 return true;
1424 torture_assert_ntstatus_equal(tctx, status, changes[i].expected_error, changes[i].comment);
1425 if (delta_enum_array) {
1426 torture_assert_int_equal(tctx,
1427 delta_enum_array->num_deltas,
1428 changes[i].expected_num_results,
1429 changes[i].comment);
1430 if (delta_enum_array->num_deltas > 0) {
1431 torture_assert_int_equal(tctx,
1432 delta_enum_array->delta_enum[0].delta_type,
1433 changes[i].expected_delta_type_1,
1434 changes[i].comment);
1436 if (delta_enum_array->num_deltas > 1) {
1437 torture_assert_int_equal(tctx,
1438 delta_enum_array->delta_enum[1].delta_type,
1439 changes[i].expected_delta_type_2,
1440 changes[i].comment);
1444 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1445 torture_comment(tctx, "Credential chaining failed\n");
1446 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1447 return false;
1454 return true;
1458 try a netlogon AccountDeltas
1460 static bool test_AccountDeltas(struct torture_context *tctx,
1461 struct dcerpc_pipe *p,
1462 struct cli_credentials *machine_credentials)
1464 NTSTATUS status;
1465 struct netr_AccountDeltas r;
1466 struct netlogon_creds_CredentialState *creds;
1468 struct netr_AccountBuffer buffer;
1469 uint32_t count_returned = 0;
1470 uint32_t total_entries = 0;
1471 struct netr_UAS_INFO_0 recordid;
1472 struct netr_Authenticator return_authenticator;
1474 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1475 return false;
1478 ZERO_STRUCT(return_authenticator);
1480 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1481 r.in.computername = TEST_MACHINE_NAME;
1482 r.in.return_authenticator = &return_authenticator;
1483 netlogon_creds_client_authenticator(creds, &r.in.credential);
1484 ZERO_STRUCT(r.in.uas);
1485 r.in.count=10;
1486 r.in.level=0;
1487 r.in.buffersize=100;
1488 r.out.buffer = &buffer;
1489 r.out.count_returned = &count_returned;
1490 r.out.total_entries = &total_entries;
1491 r.out.recordid = &recordid;
1492 r.out.return_authenticator = &return_authenticator;
1494 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1495 status = dcerpc_netr_AccountDeltas(p, tctx, &r);
1496 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
1498 return true;
1502 try a netlogon AccountSync
1504 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
1505 struct cli_credentials *machine_credentials)
1507 NTSTATUS status;
1508 struct netr_AccountSync r;
1509 struct netlogon_creds_CredentialState *creds;
1511 struct netr_AccountBuffer buffer;
1512 uint32_t count_returned = 0;
1513 uint32_t total_entries = 0;
1514 uint32_t next_reference = 0;
1515 struct netr_UAS_INFO_0 recordid;
1516 struct netr_Authenticator return_authenticator;
1518 ZERO_STRUCT(recordid);
1519 ZERO_STRUCT(return_authenticator);
1521 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1522 return false;
1525 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1526 r.in.computername = TEST_MACHINE_NAME;
1527 r.in.return_authenticator = &return_authenticator;
1528 netlogon_creds_client_authenticator(creds, &r.in.credential);
1529 r.in.recordid = &recordid;
1530 r.in.reference=0;
1531 r.in.level=0;
1532 r.in.buffersize=100;
1533 r.out.buffer = &buffer;
1534 r.out.count_returned = &count_returned;
1535 r.out.total_entries = &total_entries;
1536 r.out.next_reference = &next_reference;
1537 r.out.recordid = &recordid;
1538 r.out.return_authenticator = &return_authenticator;
1540 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1541 status = dcerpc_netr_AccountSync(p, tctx, &r);
1542 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
1544 return true;
1548 try a netlogon GetDcName
1550 static bool test_GetDcName(struct torture_context *tctx,
1551 struct dcerpc_pipe *p)
1553 NTSTATUS status;
1554 struct netr_GetDcName r;
1555 const char *dcname = NULL;
1557 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1558 r.in.domainname = lp_workgroup(tctx->lp_ctx);
1559 r.out.dcname = &dcname;
1561 status = dcerpc_netr_GetDcName(p, tctx, &r);
1562 torture_assert_ntstatus_ok(tctx, status, "GetDcName");
1563 torture_assert_werr_ok(tctx, r.out.result, "GetDcName");
1565 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1567 return true;
1571 try a netlogon LogonControl
1573 static bool test_LogonControl(struct torture_context *tctx,
1574 struct dcerpc_pipe *p)
1576 NTSTATUS status;
1577 struct netr_LogonControl r;
1578 union netr_CONTROL_QUERY_INFORMATION query;
1579 int i;
1581 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1582 r.in.function_code = 1;
1583 r.out.query = &query;
1585 for (i=1;i<4;i++) {
1586 r.in.level = i;
1588 torture_comment(tctx, "Testing LogonControl level %d\n", i);
1590 status = dcerpc_netr_LogonControl(p, tctx, &r);
1591 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1594 return true;
1599 try a netlogon GetAnyDCName
1601 static bool test_GetAnyDCName(struct torture_context *tctx,
1602 struct dcerpc_pipe *p)
1604 NTSTATUS status;
1605 struct netr_GetAnyDCName r;
1606 const char *dcname = NULL;
1608 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1609 r.in.domainname = lp_workgroup(tctx->lp_ctx);
1610 r.out.dcname = &dcname;
1612 status = dcerpc_netr_GetAnyDCName(p, tctx, &r);
1613 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
1614 torture_assert_werr_ok(tctx, r.out.result, "GetAnyDCName");
1616 if (dcname) {
1617 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1620 return true;
1625 try a netlogon LogonControl2
1627 static bool test_LogonControl2(struct torture_context *tctx,
1628 struct dcerpc_pipe *p)
1630 NTSTATUS status;
1631 struct netr_LogonControl2 r;
1632 union netr_CONTROL_DATA_INFORMATION data;
1633 union netr_CONTROL_QUERY_INFORMATION query;
1634 int i;
1636 data.domain = lp_workgroup(tctx->lp_ctx);
1638 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1640 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1641 r.in.data = &data;
1642 r.out.query = &query;
1644 for (i=1;i<4;i++) {
1645 r.in.level = i;
1647 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1648 i, r.in.function_code);
1650 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1651 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1654 data.domain = lp_workgroup(tctx->lp_ctx);
1656 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1657 r.in.data = &data;
1659 for (i=1;i<4;i++) {
1660 r.in.level = i;
1662 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1663 i, r.in.function_code);
1665 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1666 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1669 data.domain = lp_workgroup(tctx->lp_ctx);
1671 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1672 r.in.data = &data;
1674 for (i=1;i<4;i++) {
1675 r.in.level = i;
1677 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1678 i, r.in.function_code);
1680 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1681 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1684 data.debug_level = ~0;
1686 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1687 r.in.data = &data;
1689 for (i=1;i<4;i++) {
1690 r.in.level = i;
1692 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1693 i, r.in.function_code);
1695 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1696 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1699 return true;
1703 try a netlogon DatabaseSync2
1705 static bool test_DatabaseSync2(struct torture_context *tctx,
1706 struct dcerpc_pipe *p,
1707 struct cli_credentials *machine_credentials)
1709 NTSTATUS status;
1710 struct netr_DatabaseSync2 r;
1711 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1712 struct netr_Authenticator return_authenticator, credential;
1714 struct netlogon_creds_CredentialState *creds;
1715 const uint32_t database_ids[] = {0, 1, 2};
1716 int i;
1718 if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
1719 machine_credentials,
1720 cli_credentials_get_secure_channel_type(machine_credentials),
1721 &creds)) {
1722 return false;
1725 ZERO_STRUCT(return_authenticator);
1727 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1728 r.in.computername = TEST_MACHINE_NAME;
1729 r.in.preferredmaximumlength = (uint32_t)-1;
1730 r.in.return_authenticator = &return_authenticator;
1731 r.out.return_authenticator = &return_authenticator;
1732 r.out.delta_enum_array = &delta_enum_array;
1734 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1736 uint32_t sync_context = 0;
1738 r.in.database_id = database_ids[i];
1739 r.in.sync_context = &sync_context;
1740 r.out.sync_context = &sync_context;
1741 r.in.restart_state = 0;
1743 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
1745 do {
1746 netlogon_creds_client_authenticator(creds, &credential);
1748 r.in.credential = &credential;
1750 status = dcerpc_netr_DatabaseSync2(p, tctx, &r);
1751 if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
1752 break;
1754 /* Native mode servers don't do this */
1755 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1756 return true;
1759 torture_assert_ntstatus_ok(tctx, status, "DatabaseSync2");
1761 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1762 torture_comment(tctx, "Credential chaining failed\n");
1765 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
1768 return true;
1773 try a netlogon LogonControl2Ex
1775 static bool test_LogonControl2Ex(struct torture_context *tctx,
1776 struct dcerpc_pipe *p)
1778 NTSTATUS status;
1779 struct netr_LogonControl2Ex r;
1780 union netr_CONTROL_DATA_INFORMATION data;
1781 union netr_CONTROL_QUERY_INFORMATION query;
1782 int i;
1784 data.domain = lp_workgroup(tctx->lp_ctx);
1786 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1788 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1789 r.in.data = &data;
1790 r.out.query = &query;
1792 for (i=1;i<4;i++) {
1793 r.in.level = i;
1795 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
1796 i, r.in.function_code);
1798 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1799 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1802 data.domain = lp_workgroup(tctx->lp_ctx);
1804 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1805 r.in.data = &data;
1807 for (i=1;i<4;i++) {
1808 r.in.level = i;
1810 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
1811 i, r.in.function_code);
1813 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1814 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1817 data.domain = lp_workgroup(tctx->lp_ctx);
1819 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1820 r.in.data = &data;
1822 for (i=1;i<4;i++) {
1823 r.in.level = i;
1825 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
1826 i, r.in.function_code);
1828 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1829 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1832 data.debug_level = ~0;
1834 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1835 r.in.data = &data;
1837 for (i=1;i<4;i++) {
1838 r.in.level = i;
1840 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
1841 i, r.in.function_code);
1843 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1844 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1847 return true;
1850 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
1851 struct dcerpc_pipe *p, const char *trusted_domain_name)
1853 NTSTATUS status;
1854 struct netr_DsRGetForestTrustInformation r;
1855 struct lsa_ForestTrustInformation info, *info_ptr;
1857 info_ptr = &info;
1859 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1860 r.in.trusted_domain_name = trusted_domain_name;
1861 r.in.flags = 0;
1862 r.out.forest_trust_info = &info_ptr;
1864 torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
1866 status = dcerpc_netr_DsRGetForestTrustInformation(p, tctx, &r);
1867 torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
1868 torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
1870 return true;
1874 try a netlogon netr_DsrEnumerateDomainTrusts
1876 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
1877 struct dcerpc_pipe *p)
1879 NTSTATUS status;
1880 struct netr_DsrEnumerateDomainTrusts r;
1881 struct netr_DomainTrustList trusts;
1882 int i;
1884 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1885 r.in.trust_flags = 0x3f;
1886 r.out.trusts = &trusts;
1888 status = dcerpc_netr_DsrEnumerateDomainTrusts(p, tctx, &r);
1889 torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
1890 torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
1892 /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
1893 * will show non-forest trusts and all UPN suffixes of the own forest
1894 * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
1896 if (r.out.trusts->count) {
1897 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
1898 return false;
1902 for (i=0; i<r.out.trusts->count; i++) {
1904 /* get info for transitive forest trusts */
1906 if (r.out.trusts->array[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
1907 if (!test_netr_DsRGetForestTrustInformation(tctx, p,
1908 r.out.trusts->array[i].dns_name)) {
1909 return false;
1914 return true;
1917 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
1918 struct dcerpc_pipe *p)
1920 NTSTATUS status;
1921 struct netr_NetrEnumerateTrustedDomains r;
1922 struct netr_Blob trusted_domains_blob;
1924 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1925 r.out.trusted_domains_blob = &trusted_domains_blob;
1927 status = dcerpc_netr_NetrEnumerateTrustedDomains(p, tctx, &r);
1928 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
1929 torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
1931 return true;
1934 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
1935 struct dcerpc_pipe *p)
1937 NTSTATUS status;
1938 struct netr_NetrEnumerateTrustedDomainsEx r;
1939 struct netr_DomainTrustList dom_trust_list;
1941 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1942 r.out.dom_trust_list = &dom_trust_list;
1944 status = dcerpc_netr_NetrEnumerateTrustedDomainsEx(p, tctx, &r);
1945 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
1946 torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
1948 return true;
1952 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
1953 const char *computer_name,
1954 const char *expected_site)
1956 NTSTATUS status;
1957 struct netr_DsRGetSiteName r;
1958 const char *site = NULL;
1960 if (torture_setting_bool(tctx, "samba4", false))
1961 torture_skip(tctx, "skipping DsRGetSiteName test against Samba4");
1963 r.in.computer_name = computer_name;
1964 r.out.site = &site;
1965 torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
1967 status = dcerpc_netr_DsRGetSiteName(p, tctx, &r);
1968 torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
1969 torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
1970 torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
1972 r.in.computer_name = talloc_asprintf(tctx, "\\\\%s", computer_name);
1973 torture_comment(tctx,
1974 "Testing netr_DsRGetSiteName with broken computer name: %s\n", r.in.computer_name);
1976 status = dcerpc_netr_DsRGetSiteName(p, tctx, &r);
1977 torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
1978 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_COMPUTERNAME, "netr_DsRGetSiteName");
1980 return true;
1984 try a netlogon netr_DsRGetDCName
1986 static bool test_netr_DsRGetDCName(struct torture_context *tctx,
1987 struct dcerpc_pipe *p)
1989 NTSTATUS status;
1990 struct netr_DsRGetDCName r;
1991 struct netr_DsRGetDCNameInfo *info = NULL;
1993 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1994 r.in.domain_name = talloc_asprintf(tctx, "%s", lp_realm(tctx->lp_ctx));
1995 r.in.domain_guid = NULL;
1996 r.in.site_guid = NULL;
1997 r.in.flags = DS_RETURN_DNS_NAME;
1998 r.out.info = &info;
2000 status = dcerpc_netr_DsRGetDCName(p, tctx, &r);
2001 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2002 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2003 return test_netr_DsRGetSiteName(p, tctx,
2004 info->dc_unc,
2005 info->dc_site_name);
2009 try a netlogon netr_DsRGetDCNameEx
2011 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
2012 struct dcerpc_pipe *p)
2014 NTSTATUS status;
2015 struct netr_DsRGetDCNameEx r;
2016 struct netr_DsRGetDCNameInfo *info = NULL;
2018 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2019 r.in.domain_name = talloc_asprintf(tctx, "%s", lp_realm(tctx->lp_ctx));
2020 r.in.domain_guid = NULL;
2021 r.in.site_name = NULL;
2022 r.in.flags = DS_RETURN_DNS_NAME;
2023 r.out.info = &info;
2025 status = dcerpc_netr_DsRGetDCNameEx(p, tctx, &r);
2026 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2027 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2029 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2030 info->dc_site_name);
2034 try a netlogon netr_DsRGetDCNameEx2
2036 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
2037 struct dcerpc_pipe *p)
2039 NTSTATUS status;
2040 struct netr_DsRGetDCNameEx2 r;
2041 struct netr_DsRGetDCNameInfo *info = NULL;
2043 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2044 r.in.client_account = NULL;
2045 r.in.mask = 0x00000000;
2046 r.in.domain_name = talloc_asprintf(tctx, "%s", lp_realm(tctx->lp_ctx));
2047 r.in.domain_guid = NULL;
2048 r.in.site_name = NULL;
2049 r.in.flags = DS_RETURN_DNS_NAME;
2050 r.out.info = &info;
2052 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
2054 status = dcerpc_netr_DsRGetDCNameEx2(p, tctx, &r);
2055 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2056 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2058 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client acount\n");
2059 r.in.client_account = TEST_MACHINE_NAME"$";
2060 r.in.mask = ACB_SVRTRUST;
2061 r.in.flags = DS_RETURN_FLAT_NAME;
2062 r.out.info = &info;
2064 status = dcerpc_netr_DsRGetDCNameEx2(p, tctx, &r);
2065 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2066 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2067 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2068 info->dc_site_name);
2071 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
2072 struct dcerpc_pipe *p)
2074 NTSTATUS status;
2075 struct netr_DsrGetDcSiteCoverageW r;
2076 struct DcSitesCtr *ctr = NULL;
2078 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2079 r.out.ctr = &ctr;
2081 status = dcerpc_netr_DsrGetDcSiteCoverageW(p, tctx, &r);
2082 torture_assert_ntstatus_ok(tctx, status, "failed");
2083 torture_assert_werr_ok(tctx, r.out.result, "failed");
2085 return true;
2088 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
2089 struct dcerpc_pipe *p)
2091 NTSTATUS status;
2092 struct netr_DsRAddressToSitenamesW r;
2093 struct netr_DsRAddress addr;
2094 struct netr_DsRAddressToSitenamesWCtr *ctr;
2096 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
2098 addr.size = 16;
2099 addr.buffer = talloc_zero_array(tctx, uint8_t, addr.size);
2101 addr.buffer[0] = 2; /* AF_INET */
2102 addr.buffer[4] = 127;
2103 addr.buffer[5] = 0;
2104 addr.buffer[6] = 0;
2105 addr.buffer[7] = 1;
2107 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2108 r.in.count = 1;
2109 r.in.addresses = talloc_zero_array(tctx, struct netr_DsRAddress, r.in.count);
2110 r.in.addresses[0] = addr;
2111 r.out.ctr = &ctr;
2113 status = dcerpc_netr_DsRAddressToSitenamesW(p, tctx, &r);
2114 torture_assert_ntstatus_ok(tctx, status, "failed");
2115 torture_assert_werr_ok(tctx, r.out.result, "failed");
2117 return true;
2120 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
2121 struct dcerpc_pipe *p)
2123 NTSTATUS status;
2124 struct netr_DsRAddressToSitenamesExW r;
2125 struct netr_DsRAddress addr;
2126 struct netr_DsRAddressToSitenamesExWCtr *ctr;
2128 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
2130 addr.size = 16;
2131 addr.buffer = talloc_zero_array(tctx, uint8_t, addr.size);
2133 addr.buffer[0] = 2; /* AF_INET */
2134 addr.buffer[4] = 127;
2135 addr.buffer[5] = 0;
2136 addr.buffer[6] = 0;
2137 addr.buffer[7] = 1;
2139 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2140 r.in.count = 1;
2141 r.in.addresses = talloc_zero_array(tctx, struct netr_DsRAddress, r.in.count);
2142 r.in.addresses[0] = addr;
2143 r.out.ctr = &ctr;
2145 status = dcerpc_netr_DsRAddressToSitenamesExW(p, tctx, &r);
2146 torture_assert_ntstatus_ok(tctx, status, "failed");
2147 torture_assert_werr_ok(tctx, r.out.result, "failed");
2149 return true;
2152 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
2153 struct dcerpc_pipe *p,
2154 struct cli_credentials *machine_credentials)
2156 NTSTATUS status;
2157 struct netr_ServerGetTrustInfo r;
2159 struct netr_Authenticator a;
2160 struct netr_Authenticator return_authenticator;
2161 struct samr_Password new_owf_password;
2162 struct samr_Password old_owf_password;
2163 struct netr_TrustInfo *trust_info;
2165 struct netlogon_creds_CredentialState *creds;
2167 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2168 machine_credentials, &creds)) {
2169 return false;
2172 netlogon_creds_client_authenticator(creds, &a);
2174 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2175 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
2176 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2177 r.in.computer_name = TEST_MACHINE_NAME;
2178 r.in.credential = &a;
2180 r.out.return_authenticator = &return_authenticator;
2181 r.out.new_owf_password = &new_owf_password;
2182 r.out.old_owf_password = &old_owf_password;
2183 r.out.trust_info = &trust_info;
2185 status = dcerpc_netr_ServerGetTrustInfo(p, tctx, &r);
2186 torture_assert_ntstatus_ok(tctx, status, "failed");
2187 torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
2189 return true;
2193 static bool test_GetDomainInfo(struct torture_context *tctx,
2194 struct dcerpc_pipe *p,
2195 struct cli_credentials *machine_credentials)
2197 NTSTATUS status;
2198 struct netr_LogonGetDomainInfo r;
2199 struct netr_WorkstationInformation q1;
2200 struct netr_Authenticator a;
2201 struct netlogon_creds_CredentialState *creds;
2202 struct netr_OsVersion os;
2203 union netr_WorkstationInfo query;
2204 union netr_DomainInfo info;
2205 const char* const attrs[] = { "dNSHostName", "operatingSystem",
2206 "operatingSystemServicePack", "operatingSystemVersion",
2207 "servicePrincipalName", NULL };
2208 char *url;
2209 struct ldb_context *sam_ctx = NULL;
2210 struct ldb_message **res;
2211 struct ldb_message_element *spn_el;
2212 int ret, i;
2213 char *version_str;
2214 const char *old_dnsname;
2215 char **spns = NULL;
2216 int num_spns = 0;
2217 char *temp_str;
2219 torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
2221 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2222 machine_credentials, &creds)) {
2223 return false;
2226 /* We won't double-check this when we are over 'local' transports */
2227 if (dcerpc_server_name(p)) {
2228 /* Set up connection to SAMDB on DC */
2229 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2230 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2231 NULL,
2232 cmdline_credentials,
2233 0, NULL);
2235 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2238 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
2239 netlogon_creds_client_authenticator(creds, &a);
2241 ZERO_STRUCT(r);
2242 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2243 r.in.computer_name = TEST_MACHINE_NAME;
2244 r.in.credential = &a;
2245 r.in.level = 1;
2246 r.in.return_authenticator = &a;
2247 r.in.query = &query;
2248 r.out.return_authenticator = &a;
2249 r.out.info = &info;
2251 ZERO_STRUCT(os);
2252 os.os.MajorVersion = 123;
2253 os.os.MinorVersion = 456;
2254 os.os.BuildNumber = 789;
2255 os.os.CSDVersion = "Service Pack 10";
2256 os.os.ServicePackMajor = 10;
2257 os.os.ServicePackMinor = 1;
2258 os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
2259 os.os.ProductType = NETR_VER_NT_SERVER;
2260 os.os.Reserved = 0;
2262 version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
2263 os.os.MinorVersion, os.os.BuildNumber);
2265 ZERO_STRUCT(q1);
2266 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
2267 TEST_MACHINE_DNS_SUFFIX);
2268 q1.sitename = "Default-First-Site-Name";
2269 q1.os_version.os = &os;
2270 q1.os_name.string = talloc_asprintf(tctx,
2271 "Tortured by Samba4 RPC-NETLOGON: %s",
2272 timestring(tctx, time(NULL)));
2274 /* The workstation handles the "servicePrincipalName" and DNS hostname
2275 updates */
2276 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
2278 query.workstation_info = &q1;
2280 if (sam_ctx) {
2281 /* Gets back the old DNS hostname in AD */
2282 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2283 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2284 old_dnsname =
2285 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
2287 /* Gets back the "servicePrincipalName"s in AD */
2288 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2289 if (spn_el != NULL) {
2290 for (i=0; i < spn_el->num_values; i++) {
2291 spns = talloc_realloc(tctx, spns, char *, i + 1);
2292 spns[i] = (char *) spn_el->values[i].data;
2294 num_spns = i;
2298 status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2299 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2300 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2302 msleep(250);
2304 if (sam_ctx) {
2305 /* AD workstation infos entry check */
2306 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2307 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2308 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
2309 torture_assert_str_equal(tctx,
2310 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
2311 q1.os_name.string, "'operatingSystem' wrong!");
2312 torture_assert_str_equal(tctx,
2313 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
2314 os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
2315 torture_assert_str_equal(tctx,
2316 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
2317 version_str, "'operatingSystemVersion' wrong!");
2319 if (old_dnsname != NULL) {
2320 /* If before a DNS hostname was set then it should remain
2321 the same in combination with the "servicePrincipalName"s.
2322 The DNS hostname should also be returned by our
2323 "LogonGetDomainInfo" call (in the domain info structure). */
2325 torture_assert_str_equal(tctx,
2326 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
2327 old_dnsname, "'DNS hostname' was not set!");
2329 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2330 torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
2331 "'servicePrincipalName's not set!");
2332 torture_assert(tctx, spn_el->num_values == num_spns,
2333 "'servicePrincipalName's incorrect!");
2334 for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
2335 torture_assert_str_equal(tctx,
2336 (char *) spn_el->values[i].data,
2337 spns[i], "'servicePrincipalName's incorrect!");
2339 torture_assert_str_equal(tctx,
2340 info.domain_info->dns_hostname.string,
2341 old_dnsname,
2342 "Out 'DNS hostname' doesn't match the old one!");
2343 } else {
2344 /* If no DNS hostname was set then also now none should be set,
2345 the "servicePrincipalName"s should remain empty and no DNS
2346 hostname should be returned by our "LogonGetDomainInfo"
2347 call (in the domain info structure). */
2349 torture_assert(tctx,
2350 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
2351 "'DNS hostname' was set!");
2353 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2354 torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
2355 "'servicePrincipalName's were set!");
2357 torture_assert(tctx,
2358 info.domain_info->dns_hostname.string == NULL,
2359 "Out 'DNS host name' was set!");
2363 /* Checks "workstation flags" */
2364 torture_assert(tctx,
2365 info.domain_info->workstation_flags
2366 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
2367 "Out 'workstation flags' don't match!");
2370 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname)\n");
2371 netlogon_creds_client_authenticator(creds, &a);
2373 /* Wipe out the osVersion, and prove which values still 'stick' */
2374 q1.os_version.os = NULL;
2376 /* Change also the DNS hostname to test differences in behaviour */
2377 q1.dns_hostname = talloc_asprintf(tctx, "%s.newdomain",
2378 TEST_MACHINE_NAME);
2380 /* Let the DC handle the "servicePrincipalName" and DNS hostname
2381 updates */
2382 q1.workstation_flags = 0;
2384 status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2385 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2386 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2388 msleep(250);
2390 if (sam_ctx) {
2391 /* AD workstation infos entry check */
2392 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2393 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2394 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
2395 torture_assert_str_equal(tctx,
2396 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
2397 q1.os_name.string, "'operatingSystem' should stick!");
2398 torture_assert(tctx,
2399 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
2400 "'operatingSystemServicePack' shouldn't stick!");
2401 torture_assert(tctx,
2402 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
2403 "'operatingSystemVersion' shouldn't stick!");
2405 /* The DNS host name should have been updated now by the server */
2406 torture_assert_str_equal(tctx,
2407 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
2408 q1.dns_hostname, "'DNS host name' didn't change!");
2410 /* Find the two "servicePrincipalName"s which the DC should have been
2411 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
2412 3.5.4.3.9 */
2413 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2414 torture_assert(tctx, spn_el != NULL,
2415 "There should exist 'servicePrincipalName's in AD!");
2416 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
2417 for (i=0; i < spn_el->num_values; i++)
2418 if (strcmp((char *) spn_el->values[i].data, temp_str) == 0)
2419 break;
2420 torture_assert(tctx, i != spn_el->num_values,
2421 "'servicePrincipalName' HOST/<Netbios name> not found!");
2422 temp_str = talloc_asprintf(tctx, "HOST/%s", q1.dns_hostname);
2423 for (i=0; i < spn_el->num_values; i++)
2424 if (strcmp((char *) spn_el->values[i].data, temp_str) == 0)
2425 break;
2426 torture_assert(tctx, i != spn_el->num_values,
2427 "'servicePrincipalName' HOST/<FQDN name> not found!");
2429 /* Check that the out DNS hostname was set properly */
2430 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
2431 old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
2434 /* Checks "workstation flags" */
2435 torture_assert(tctx,
2436 info.domain_info->workstation_flags == 0,
2437 "Out 'workstation flags' don't match!");
2440 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (verification of DNS hostname and check for trusted domains)\n");
2441 netlogon_creds_client_authenticator(creds, &a);
2443 /* The workstation handles the "servicePrincipalName" and DNS hostname
2444 updates */
2445 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
2447 status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2448 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2449 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2451 msleep(250);
2453 /* Now the in/out DNS hostnames should be the same */
2454 torture_assert_str_equal(tctx,
2455 info.domain_info->dns_hostname.string,
2456 query.workstation_info->dns_hostname,
2457 "In/Out 'DNS hostnames' don't match!");
2459 /* Checks "workstation flags" */
2460 torture_assert(tctx,
2461 info.domain_info->workstation_flags
2462 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
2463 "Out 'workstation flags' don't match!");
2465 /* Checks for trusted domains */
2466 torture_assert(tctx,
2467 (info.domain_info->trusted_domain_count != 0)
2468 && (info.domain_info->trusted_domains != NULL),
2469 "Trusted domains have been requested!");
2472 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (check for trusted domains)\n");
2473 netlogon_creds_client_authenticator(creds, &a);
2475 /* The workstation handles the "servicePrincipalName" and DNS hostname
2476 updates and requests inbound trusts */
2477 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
2478 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
2480 status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2481 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2482 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2484 msleep(250);
2486 /* Checks "workstation flags" */
2487 torture_assert(tctx,
2488 info.domain_info->workstation_flags
2489 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
2490 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
2491 "Out 'workstation flags' don't match!");
2493 /* Checks for trusted domains */
2494 torture_assert(tctx,
2495 (info.domain_info->trusted_domain_count != 0)
2496 && (info.domain_info->trusted_domains != NULL),
2497 "Trusted domains have been requested!");
2499 return true;
2503 static void async_callback(struct rpc_request *req)
2505 int *counter = (int *)req->async.private_data;
2506 if (NT_STATUS_IS_OK(req->status)) {
2507 (*counter)++;
2511 static bool test_GetDomainInfo_async(struct torture_context *tctx,
2512 struct dcerpc_pipe *p,
2513 struct cli_credentials *machine_credentials)
2515 NTSTATUS status;
2516 struct netr_LogonGetDomainInfo r;
2517 struct netr_WorkstationInformation q1;
2518 struct netr_Authenticator a;
2519 #define ASYNC_COUNT 100
2520 struct netlogon_creds_CredentialState *creds;
2521 struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
2522 struct rpc_request *req[ASYNC_COUNT];
2523 int i;
2524 int *async_counter = talloc(tctx, int);
2525 union netr_WorkstationInfo query;
2526 union netr_DomainInfo info;
2528 torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
2530 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2531 machine_credentials, &creds)) {
2532 return false;
2535 ZERO_STRUCT(r);
2536 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2537 r.in.computer_name = TEST_MACHINE_NAME;
2538 r.in.credential = &a;
2539 r.in.level = 1;
2540 r.in.return_authenticator = &a;
2541 r.in.query = &query;
2542 r.out.return_authenticator = &a;
2543 r.out.info = &info;
2545 ZERO_STRUCT(q1);
2546 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
2547 TEST_MACHINE_DNS_SUFFIX);
2548 q1.sitename = "Default-First-Site-Name";
2549 q1.os_name.string = "UNIX/Linux or similar";
2551 query.workstation_info = &q1;
2553 *async_counter = 0;
2555 for (i=0;i<ASYNC_COUNT;i++) {
2556 netlogon_creds_client_authenticator(creds, &a);
2558 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
2559 req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, tctx, &r);
2561 req[i]->async.callback = async_callback;
2562 req[i]->async.private_data = async_counter;
2564 /* even with this flush per request a w2k3 server seems to
2565 clag with multiple outstanding requests. bleergh. */
2566 torture_assert_int_equal(tctx, event_loop_once(dcerpc_event_context(p)), 0,
2567 "event_loop_once failed");
2570 for (i=0;i<ASYNC_COUNT;i++) {
2571 status = dcerpc_ndr_request_recv(req[i]);
2573 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
2574 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
2576 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred),
2577 "Credential chaining failed at async");
2580 torture_comment(tctx,
2581 "Testing netr_LogonGetDomainInfo - async count %d OK\n", *async_counter);
2583 torture_assert_int_equal(tctx, (*async_counter), ASYNC_COUNT, "int");
2585 return true;
2588 static bool test_ManyGetDCName(struct torture_context *tctx,
2589 struct dcerpc_pipe *p)
2591 NTSTATUS status;
2592 struct dcerpc_pipe *p2;
2593 struct lsa_ObjectAttribute attr;
2594 struct lsa_QosInfo qos;
2595 struct lsa_OpenPolicy2 o;
2596 struct policy_handle lsa_handle;
2597 struct lsa_DomainList domains;
2599 struct lsa_EnumTrustDom t;
2600 uint32_t resume_handle = 0;
2601 struct netr_GetAnyDCName d;
2602 const char *dcname = NULL;
2604 int i;
2606 if (p->conn->transport.transport != NCACN_NP) {
2607 return true;
2610 torture_comment(tctx, "Torturing GetDCName\n");
2612 status = dcerpc_secondary_connection(p, &p2, p->binding);
2613 torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
2615 status = dcerpc_bind_auth_none(p2, &ndr_table_lsarpc);
2616 torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
2618 qos.len = 0;
2619 qos.impersonation_level = 2;
2620 qos.context_mode = 1;
2621 qos.effective_only = 0;
2623 attr.len = 0;
2624 attr.root_dir = NULL;
2625 attr.object_name = NULL;
2626 attr.attributes = 0;
2627 attr.sec_desc = NULL;
2628 attr.sec_qos = &qos;
2630 o.in.system_name = "\\";
2631 o.in.attr = &attr;
2632 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2633 o.out.handle = &lsa_handle;
2635 status = dcerpc_lsa_OpenPolicy2(p2, tctx, &o);
2636 torture_assert_ntstatus_ok(tctx, status, "OpenPolicy2 failed");
2638 t.in.handle = &lsa_handle;
2639 t.in.resume_handle = &resume_handle;
2640 t.in.max_size = 1000;
2641 t.out.domains = &domains;
2642 t.out.resume_handle = &resume_handle;
2644 status = dcerpc_lsa_EnumTrustDom(p2, tctx, &t);
2646 if ((!NT_STATUS_IS_OK(status) &&
2647 (!NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES))))
2648 torture_fail(tctx, "Could not list domains");
2650 talloc_free(p2);
2652 d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
2653 dcerpc_server_name(p));
2654 d.out.dcname = &dcname;
2656 for (i=0; i<domains.count * 4; i++) {
2657 struct lsa_DomainInfo *info =
2658 &domains.domains[rand()%domains.count];
2660 d.in.domainname = info->name.string;
2662 status = dcerpc_netr_GetAnyDCName(p, tctx, &d);
2663 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2665 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
2666 dcname ? dcname : "unknown");
2669 return true;
2672 static bool test_SetPassword_with_flags(struct torture_context *tctx,
2673 struct dcerpc_pipe *p,
2674 struct cli_credentials *machine_credentials)
2676 uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
2677 struct netlogon_creds_CredentialState *creds;
2678 int i;
2680 if (!test_SetupCredentials2(p, tctx, 0,
2681 machine_credentials,
2682 cli_credentials_get_secure_channel_type(machine_credentials),
2683 &creds)) {
2684 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
2687 for (i=0; i < ARRAY_SIZE(flags); i++) {
2688 torture_assert(tctx,
2689 test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
2690 talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
2693 return true;
2696 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
2698 struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON");
2699 struct torture_rpc_tcase *tcase;
2700 struct torture_test *test;
2702 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
2703 &ndr_table_netlogon, TEST_MACHINE_NAME);
2705 torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
2706 torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
2707 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
2708 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
2709 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
2710 torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
2711 torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
2712 torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
2713 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
2714 torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
2715 torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
2716 torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
2717 torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
2718 torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
2719 torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
2720 torture_rpc_tcase_add_test(tcase, "LogonControl", test_LogonControl);
2721 torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
2722 torture_rpc_tcase_add_test(tcase, "LogonControl2", test_LogonControl2);
2723 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
2724 torture_rpc_tcase_add_test(tcase, "LogonControl2Ex", test_LogonControl2Ex);
2725 torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
2726 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
2727 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
2728 test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
2729 test->dangerous = true;
2730 torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
2731 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
2732 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
2733 torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
2734 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
2735 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
2736 torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
2738 return suite;
2741 struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
2743 struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON-S3");
2744 struct torture_rpc_tcase *tcase;
2746 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
2747 &ndr_table_netlogon, TEST_MACHINE_NAME);
2749 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
2750 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
2751 torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
2752 torture_rpc_tcase_add_test(tcase, "LogonControl", test_LogonControl);
2753 torture_rpc_tcase_add_test(tcase, "LogonControl2", test_LogonControl2);
2754 torture_rpc_tcase_add_test(tcase, "LogonControl2Ex", test_LogonControl2Ex);
2755 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
2757 return suite;