s4-torture: pass down netlogon flags in netr_ServerPasswordSet2 tests.
[Samba/gebeck_regimport.git] / source4 / torture / rpc / netlogon.c
blobf6d7262d1d9f7580b5656b07e2af09ce5c0501eb
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-2010
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "includes.h"
26 #include "lib/events/events.h"
27 #include "lib/cmdline/popt_common.h"
28 #include "torture/rpc/torture_rpc.h"
29 #include "../lib/crypto/crypto.h"
30 #include "libcli/auth/libcli_auth.h"
31 #include "librpc/gen_ndr/ndr_netlogon_c.h"
32 #include "librpc/gen_ndr/ndr_lsa_c.h"
33 #include "param/param.h"
34 #include "libcli/security/security.h"
35 #include <ldb.h>
36 #include "lib/util/util_ldb.h"
37 #include "ldb_wrap.h"
38 #include "lib/replace/system/network.h"
39 #include "dsdb/samdb/samdb.h"
41 #define TEST_MACHINE_NAME "torturetest"
43 static bool test_netr_broken_binding_handle(struct torture_context *tctx,
44 struct dcerpc_pipe *p)
46 NTSTATUS status;
47 struct netr_DsRGetSiteName r;
48 const char *site = NULL;
49 struct dcerpc_binding_handle *b = p->binding_handle;
51 r.in.computer_name = talloc_asprintf(tctx, "\\\\%s",
52 dcerpc_server_name(p));
53 r.out.site = &site;
55 torture_comment(tctx,
56 "Testing netlogon request with correct binding handle: %s\n",
57 r.in.computer_name);
59 status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
60 torture_assert_ntstatus_ok(tctx, status,
61 "Netlogon request with broken binding handle");
62 torture_assert_werr_ok(tctx, r.out.result,
63 "Netlogon request with broken binding handle");
65 if (torture_setting_bool(tctx, "samba3", false) ||
66 torture_setting_bool(tctx, "samba4", false)) {
67 torture_skip(tctx,
68 "Skipping broken binding handle check against Samba");
71 r.in.computer_name = talloc_asprintf(tctx, "\\\\\\\\%s",
72 dcerpc_server_name(p));
74 torture_comment(tctx,
75 "Testing netlogon request with broken binding handle: %s\n",
76 r.in.computer_name);
78 status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
79 torture_assert_ntstatus_ok(tctx, status,
80 "Netlogon request with broken binding handle");
81 torture_assert_werr_equal(tctx, r.out.result,
82 WERR_INVALID_COMPUTERNAME,
83 "Netlogon request with broken binding handle");
85 r.in.computer_name = "\\\\\\\\THIS_IS_NOT_VALID";
87 torture_comment(tctx,
88 "Testing netlogon request with broken binding handle: %s\n",
89 r.in.computer_name);
91 status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
92 torture_assert_ntstatus_ok(tctx, status,
93 "Netlogon request with broken binding handle");
94 torture_assert_werr_equal(tctx, r.out.result,
95 WERR_INVALID_COMPUTERNAME,
96 "Netlogon request with broken binding handle");
98 return true;
101 static bool test_LogonUasLogon(struct torture_context *tctx,
102 struct dcerpc_pipe *p)
104 NTSTATUS status;
105 struct netr_LogonUasLogon r;
106 struct netr_UasInfo *info = NULL;
107 struct dcerpc_binding_handle *b = p->binding_handle;
109 r.in.server_name = NULL;
110 r.in.account_name = cli_credentials_get_username(cmdline_credentials);
111 r.in.workstation = TEST_MACHINE_NAME;
112 r.out.info = &info;
114 status = dcerpc_netr_LogonUasLogon_r(b, tctx, &r);
115 torture_assert_ntstatus_ok(tctx, status, "LogonUasLogon");
117 return true;
120 static bool test_LogonUasLogoff(struct torture_context *tctx,
121 struct dcerpc_pipe *p)
123 NTSTATUS status;
124 struct netr_LogonUasLogoff r;
125 struct netr_UasLogoffInfo info;
126 struct dcerpc_binding_handle *b = p->binding_handle;
128 r.in.server_name = NULL;
129 r.in.account_name = cli_credentials_get_username(cmdline_credentials);
130 r.in.workstation = TEST_MACHINE_NAME;
131 r.out.info = &info;
133 status = dcerpc_netr_LogonUasLogoff_r(b, tctx, &r);
134 torture_assert_ntstatus_ok(tctx, status, "LogonUasLogoff");
136 return true;
139 bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
140 struct cli_credentials *credentials,
141 struct netlogon_creds_CredentialState **creds_out)
143 struct netr_ServerReqChallenge r;
144 struct netr_ServerAuthenticate a;
145 struct netr_Credential credentials1, credentials2, credentials3;
146 struct netlogon_creds_CredentialState *creds;
147 const struct samr_Password *mach_password;
148 const char *machine_name;
149 struct dcerpc_binding_handle *b = p->binding_handle;
151 mach_password = cli_credentials_get_nt_hash(credentials, tctx);
152 machine_name = cli_credentials_get_workstation(credentials);
154 torture_comment(tctx, "Testing ServerReqChallenge\n");
156 r.in.server_name = NULL;
157 r.in.computer_name = machine_name;
158 r.in.credentials = &credentials1;
159 r.out.return_credentials = &credentials2;
161 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
163 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
164 "ServerReqChallenge failed");
165 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
167 a.in.server_name = NULL;
168 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
169 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(credentials);
170 a.in.computer_name = machine_name;
171 a.in.credentials = &credentials3;
172 a.out.return_credentials = &credentials3;
174 creds = netlogon_creds_client_init(tctx, a.in.account_name,
175 a.in.computer_name,
176 &credentials1, &credentials2,
177 mach_password, &credentials3,
179 torture_assert(tctx, creds != NULL, "memory allocation");
182 torture_comment(tctx, "Testing ServerAuthenticate\n");
184 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate_r(b, tctx, &a),
185 "ServerAuthenticate failed");
187 /* This allows the tests to continue against the more fussy windows 2008 */
188 if (NT_STATUS_EQUAL(a.out.result, NT_STATUS_DOWNGRADE_DETECTED)) {
189 return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
190 credentials,
191 cli_credentials_get_secure_channel_type(credentials),
192 creds_out);
195 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate");
197 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
198 "Credential chaining failed");
200 *creds_out = creds;
201 return true;
204 bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx,
205 uint32_t negotiate_flags,
206 struct cli_credentials *machine_credentials,
207 enum netr_SchannelType sec_chan_type,
208 struct netlogon_creds_CredentialState **creds_out)
210 struct netr_ServerReqChallenge r;
211 struct netr_ServerAuthenticate2 a;
212 struct netr_Credential credentials1, credentials2, credentials3;
213 struct netlogon_creds_CredentialState *creds;
214 const struct samr_Password *mach_password;
215 const char *machine_name;
216 struct dcerpc_binding_handle *b = p->binding_handle;
218 mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
219 machine_name = cli_credentials_get_workstation(machine_credentials);
221 torture_comment(tctx, "Testing ServerReqChallenge\n");
224 r.in.server_name = NULL;
225 r.in.computer_name = machine_name;
226 r.in.credentials = &credentials1;
227 r.out.return_credentials = &credentials2;
229 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
231 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
232 "ServerReqChallenge failed");
233 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
235 a.in.server_name = NULL;
236 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
237 a.in.secure_channel_type = sec_chan_type;
238 a.in.computer_name = machine_name;
239 a.in.negotiate_flags = &negotiate_flags;
240 a.out.negotiate_flags = &negotiate_flags;
241 a.in.credentials = &credentials3;
242 a.out.return_credentials = &credentials3;
244 creds = netlogon_creds_client_init(tctx, a.in.account_name,
245 a.in.computer_name,
246 &credentials1, &credentials2,
247 mach_password, &credentials3,
248 negotiate_flags);
250 torture_assert(tctx, creds != NULL, "memory allocation");
252 torture_comment(tctx, "Testing ServerAuthenticate2\n");
254 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
255 "ServerAuthenticate2 failed");
256 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate2 failed");
258 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
259 "Credential chaining failed");
261 torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
263 *creds_out = creds;
264 return true;
268 bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx,
269 uint32_t negotiate_flags,
270 struct cli_credentials *machine_credentials,
271 struct netlogon_creds_CredentialState **creds_out)
273 struct netr_ServerReqChallenge r;
274 struct netr_ServerAuthenticate3 a;
275 struct netr_Credential credentials1, credentials2, credentials3;
276 struct netlogon_creds_CredentialState *creds;
277 struct samr_Password mach_password;
278 uint32_t rid;
279 const char *machine_name;
280 const char *plain_pass;
281 struct dcerpc_binding_handle *b = p->binding_handle;
283 machine_name = cli_credentials_get_workstation(machine_credentials);
284 plain_pass = cli_credentials_get_password(machine_credentials);
286 torture_comment(tctx, "Testing ServerReqChallenge\n");
288 r.in.server_name = NULL;
289 r.in.computer_name = machine_name;
290 r.in.credentials = &credentials1;
291 r.out.return_credentials = &credentials2;
293 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
295 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
296 "ServerReqChallenge failed");
297 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
299 E_md4hash(plain_pass, mach_password.hash);
301 a.in.server_name = NULL;
302 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
303 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
304 a.in.computer_name = machine_name;
305 a.in.negotiate_flags = &negotiate_flags;
306 a.in.credentials = &credentials3;
307 a.out.return_credentials = &credentials3;
308 a.out.negotiate_flags = &negotiate_flags;
309 a.out.rid = &rid;
311 creds = netlogon_creds_client_init(tctx, a.in.account_name,
312 a.in.computer_name,
313 &credentials1, &credentials2,
314 &mach_password, &credentials3,
315 negotiate_flags);
317 torture_assert(tctx, creds != NULL, "memory allocation");
319 torture_comment(tctx, "Testing ServerAuthenticate3\n");
321 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
322 "ServerAuthenticate3 failed");
323 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed");
324 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
326 torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
328 /* Prove that requesting a challenge again won't break it */
329 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
330 "ServerReqChallenge failed");
331 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
333 *creds_out = creds;
334 return true;
338 try a change password for our machine account
340 static bool test_SetPassword(struct torture_context *tctx,
341 struct dcerpc_pipe *p,
342 struct cli_credentials *machine_credentials)
344 struct netr_ServerPasswordSet r;
345 const char *password;
346 struct netlogon_creds_CredentialState *creds;
347 struct netr_Authenticator credential, return_authenticator;
348 struct samr_Password new_password;
349 struct dcerpc_binding_handle *b = p->binding_handle;
351 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
352 return false;
355 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
356 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
357 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
358 r.in.computer_name = TEST_MACHINE_NAME;
359 r.in.credential = &credential;
360 r.in.new_password = &new_password;
361 r.out.return_authenticator = &return_authenticator;
363 password = generate_random_password(tctx, 8, 255);
364 E_md4hash(password, new_password.hash);
366 netlogon_creds_des_encrypt(creds, &new_password);
368 torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
369 torture_comment(tctx, "Changing machine account password to '%s'\n",
370 password);
372 netlogon_creds_client_authenticator(creds, &credential);
374 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
375 "ServerPasswordSet failed");
376 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
378 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
379 torture_comment(tctx, "Credential chaining failed\n");
382 /* by changing the machine password twice we test the
383 credentials chaining fully, and we verify that the server
384 allows the password to be set to the same value twice in a
385 row (match win2k3) */
386 torture_comment(tctx,
387 "Testing a second ServerPasswordSet on machine account\n");
388 torture_comment(tctx,
389 "Changing machine account password to '%s' (same as previous run)\n", password);
391 netlogon_creds_client_authenticator(creds, &credential);
393 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
394 "ServerPasswordSet (2) failed");
395 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
397 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
398 torture_comment(tctx, "Credential chaining failed\n");
401 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
403 torture_assert(tctx,
404 test_SetupCredentials(p, tctx, machine_credentials, &creds),
405 "ServerPasswordSet failed to actually change the password");
407 return true;
411 try a change password for our machine account
413 static bool test_SetPassword_flags(struct torture_context *tctx,
414 struct dcerpc_pipe *p,
415 struct cli_credentials *machine_credentials,
416 uint32_t negotiate_flags)
418 struct netr_ServerPasswordSet r;
419 const char *password;
420 struct netlogon_creds_CredentialState *creds;
421 struct netr_Authenticator credential, return_authenticator;
422 struct samr_Password new_password;
423 struct dcerpc_binding_handle *b = p->binding_handle;
425 if (!test_SetupCredentials2(p, tctx, negotiate_flags,
426 machine_credentials,
427 cli_credentials_get_secure_channel_type(machine_credentials),
428 &creds)) {
429 return false;
432 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
433 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
434 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
435 r.in.computer_name = TEST_MACHINE_NAME;
436 r.in.credential = &credential;
437 r.in.new_password = &new_password;
438 r.out.return_authenticator = &return_authenticator;
440 password = generate_random_password(tctx, 8, 255);
441 E_md4hash(password, new_password.hash);
443 netlogon_creds_des_encrypt(creds, &new_password);
445 torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
446 torture_comment(tctx, "Changing machine account password to '%s'\n",
447 password);
449 netlogon_creds_client_authenticator(creds, &credential);
451 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
452 "ServerPasswordSet failed");
453 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
455 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
456 torture_comment(tctx, "Credential chaining failed\n");
459 /* by changing the machine password twice we test the
460 credentials chaining fully, and we verify that the server
461 allows the password to be set to the same value twice in a
462 row (match win2k3) */
463 torture_comment(tctx,
464 "Testing a second ServerPasswordSet on machine account\n");
465 torture_comment(tctx,
466 "Changing machine account password to '%s' (same as previous run)\n", password);
468 netlogon_creds_client_authenticator(creds, &credential);
470 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
471 "ServerPasswordSet (2) failed");
472 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
474 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
475 torture_comment(tctx, "Credential chaining failed\n");
478 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
480 torture_assert(tctx,
481 test_SetupCredentials(p, tctx, machine_credentials, &creds),
482 "ServerPasswordSet failed to actually change the password");
484 return true;
489 generate a random password for password change tests
491 static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
493 int i;
494 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
495 generate_random_buffer(password.data, password.length);
497 for (i=0; i < len; i++) {
498 if (((uint16_t *)password.data)[i] == 0) {
499 ((uint16_t *)password.data)[i] = 1;
503 return password;
507 try a change password for our machine account
509 static bool test_SetPassword2_with_flags(struct torture_context *tctx,
510 struct dcerpc_pipe *p,
511 struct cli_credentials *machine_credentials,
512 uint32_t flags)
514 struct netr_ServerPasswordSet2 r;
515 const char *password;
516 DATA_BLOB new_random_pass;
517 struct netlogon_creds_CredentialState *creds;
518 struct samr_CryptPassword password_buf;
519 struct samr_Password nt_hash;
520 struct netr_Authenticator credential, return_authenticator;
521 struct netr_CryptPassword new_password;
522 struct dcerpc_binding_handle *b = p->binding_handle;
524 if (!test_SetupCredentials2(p, tctx, flags, machine_credentials, cli_credentials_get_secure_channel_type(machine_credentials), &creds)) {
525 return false;
528 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
529 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
530 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
531 r.in.computer_name = TEST_MACHINE_NAME;
532 r.in.credential = &credential;
533 r.in.new_password = &new_password;
534 r.out.return_authenticator = &return_authenticator;
536 password = generate_random_password(tctx, 8, 255);
537 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
538 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
540 memcpy(new_password.data, password_buf.data, 512);
541 new_password.length = IVAL(password_buf.data, 512);
543 torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
544 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
546 netlogon_creds_client_authenticator(creds, &credential);
548 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
549 "ServerPasswordSet2 failed");
550 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
552 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
553 torture_comment(tctx, "Credential chaining failed\n");
556 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
558 if (!torture_setting_bool(tctx, "dangerous", false)) {
559 torture_comment(tctx,
560 "Not testing ability to set password to '', enable dangerous tests to perform this test\n");
561 } else {
562 /* by changing the machine password to ""
563 * we check if the server uses password restrictions
564 * for ServerPasswordSet2
565 * (win2k3 accepts "")
567 password = "";
568 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
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 ServerPasswordSet2 on machine account\n");
576 torture_comment(tctx,
577 "Changing machine account password to '%s'\n", password);
579 netlogon_creds_client_authenticator(creds, &credential);
581 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
582 "ServerPasswordSet2 failed");
583 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
585 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
586 torture_comment(tctx, "Credential chaining failed\n");
589 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
592 torture_assert(tctx, test_SetupCredentials(p, tctx, machine_credentials, &creds),
593 "ServerPasswordSet failed to actually change the password");
595 /* now try a random password */
596 password = generate_random_password(tctx, 8, 255);
597 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
598 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
600 memcpy(new_password.data, password_buf.data, 512);
601 new_password.length = IVAL(password_buf.data, 512);
603 torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
604 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
606 netlogon_creds_client_authenticator(creds, &credential);
608 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
609 "ServerPasswordSet2 (2) failed");
610 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 (2) failed");
612 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
613 torture_comment(tctx, "Credential chaining failed\n");
616 /* by changing the machine password twice we test the
617 credentials chaining fully, and we verify that the server
618 allows the password to be set to the same value twice in a
619 row (match win2k3) */
620 torture_comment(tctx,
621 "Testing a second ServerPasswordSet2 on machine account\n");
622 torture_comment(tctx,
623 "Changing machine account password to '%s' (same as previous run)\n", password);
625 netlogon_creds_client_authenticator(creds, &credential);
627 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
628 "ServerPasswordSet (3) failed");
629 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
631 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
632 torture_comment(tctx, "Credential chaining failed\n");
635 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
637 torture_assert (tctx,
638 test_SetupCredentials(p, tctx, machine_credentials, &creds),
639 "ServerPasswordSet failed to actually change the password");
641 new_random_pass = netlogon_very_rand_pass(tctx, 128);
643 /* now try a random stream of bytes for a password */
644 set_pw_in_buffer(password_buf.data, &new_random_pass);
646 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
648 memcpy(new_password.data, password_buf.data, 512);
649 new_password.length = IVAL(password_buf.data, 512);
651 torture_comment(tctx,
652 "Testing a third ServerPasswordSet2 on machine account, with a completely random password\n");
654 netlogon_creds_client_authenticator(creds, &credential);
656 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
657 "ServerPasswordSet (3) failed");
658 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
660 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
661 torture_comment(tctx, "Credential chaining failed\n");
664 mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
666 cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
667 cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
669 torture_assert (tctx,
670 test_SetupCredentials(p, tctx, machine_credentials, &creds),
671 "ServerPasswordSet failed to actually change the password");
673 return true;
676 static bool test_SetPassword2(struct torture_context *tctx,
677 struct dcerpc_pipe *p,
678 struct cli_credentials *machine_credentials)
680 return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS);
683 static bool test_GetPassword(struct torture_context *tctx,
684 struct dcerpc_pipe *p,
685 struct cli_credentials *machine_credentials)
687 struct netr_ServerPasswordGet r;
688 struct netlogon_creds_CredentialState *creds;
689 struct netr_Authenticator credential;
690 NTSTATUS status;
691 struct netr_Authenticator return_authenticator;
692 struct samr_Password password;
693 struct dcerpc_binding_handle *b = p->binding_handle;
695 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
696 return false;
699 netlogon_creds_client_authenticator(creds, &credential);
701 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
702 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
703 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
704 r.in.computer_name = TEST_MACHINE_NAME;
705 r.in.credential = &credential;
706 r.out.return_authenticator = &return_authenticator;
707 r.out.password = &password;
709 status = dcerpc_netr_ServerPasswordGet_r(b, tctx, &r);
710 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
712 return true;
715 static bool test_GetTrustPasswords(struct torture_context *tctx,
716 struct dcerpc_pipe *p,
717 struct cli_credentials *machine_credentials)
719 struct netr_ServerTrustPasswordsGet r;
720 struct netlogon_creds_CredentialState *creds;
721 struct netr_Authenticator credential;
722 struct netr_Authenticator return_authenticator;
723 struct samr_Password password, password2;
724 struct dcerpc_binding_handle *b = p->binding_handle;
726 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
727 return false;
730 netlogon_creds_client_authenticator(creds, &credential);
732 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
733 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
734 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
735 r.in.computer_name = TEST_MACHINE_NAME;
736 r.in.credential = &credential;
737 r.out.return_authenticator = &return_authenticator;
738 r.out.password = &password;
739 r.out.password2 = &password2;
741 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerTrustPasswordsGet_r(b, tctx, &r),
742 "ServerTrustPasswordsGet failed");
743 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerTrustPasswordsGet failed");
745 return true;
749 try a netlogon SamLogon
751 static bool test_netlogon_ops_args(struct dcerpc_pipe *p, struct torture_context *tctx,
752 struct cli_credentials *credentials,
753 struct netlogon_creds_CredentialState *creds,
754 bool null_domain)
756 NTSTATUS status;
757 struct netr_LogonSamLogon r;
758 struct netr_Authenticator auth, auth2;
759 static const struct netr_Authenticator auth_zero;
760 union netr_LogonLevel logon;
761 union netr_Validation validation;
762 uint8_t authoritative;
763 struct netr_NetworkInfo ninfo;
764 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
765 int i;
766 struct dcerpc_binding_handle *b = p->binding_handle;
767 int flags = CLI_CRED_NTLM_AUTH;
768 if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
769 flags |= CLI_CRED_LANMAN_AUTH;
772 if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx) && !null_domain) {
773 flags |= CLI_CRED_NTLMv2_AUTH;
776 cli_credentials_get_ntlm_username_domain(cmdline_credentials, tctx,
777 &ninfo.identity_info.account_name.string,
778 &ninfo.identity_info.domain_name.string);
780 if (null_domain) {
781 ninfo.identity_info.domain_name.string = NULL;
784 generate_random_buffer(ninfo.challenge,
785 sizeof(ninfo.challenge));
786 chal = data_blob_const(ninfo.challenge,
787 sizeof(ninfo.challenge));
789 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials),
790 cli_credentials_get_domain(credentials));
792 status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx,
793 &flags,
794 chal,
795 names_blob,
796 &lm_resp, &nt_resp,
797 NULL, NULL);
798 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
800 ninfo.lm.data = lm_resp.data;
801 ninfo.lm.length = lm_resp.length;
803 ninfo.nt.data = nt_resp.data;
804 ninfo.nt.length = nt_resp.length;
806 ninfo.identity_info.parameter_control = 0;
807 ninfo.identity_info.logon_id_low = 0;
808 ninfo.identity_info.logon_id_high = 0;
809 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
811 logon.network = &ninfo;
813 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
814 r.in.computer_name = cli_credentials_get_workstation(credentials);
815 r.in.credential = &auth;
816 r.in.return_authenticator = &auth2;
817 r.in.logon_level = 2;
818 r.in.logon = &logon;
819 r.out.validation = &validation;
820 r.out.authoritative = &authoritative;
822 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
824 for (i=2;i<=3;i++) {
825 ZERO_STRUCT(auth2);
826 netlogon_creds_client_authenticator(creds, &auth);
828 r.in.validation_level = i;
830 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
831 "LogonSamLogon failed");
832 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
834 torture_assert(tctx, netlogon_creds_client_check(creds,
835 &r.out.return_authenticator->cred),
836 "Credential chaining failed");
837 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
838 "LogonSamLogon invalid *r.out.authoritative");
841 /* this makes sure we get the unmarshalling right for invalid levels */
842 for (i=52;i<53;i++) {
843 ZERO_STRUCT(auth2);
844 /* the authenticator should be ignored by the server */
845 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
847 r.in.validation_level = i;
849 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
850 "LogonSamLogon failed");
851 torture_assert_ntstatus_equal(tctx, r.out.result,
852 NT_STATUS_INVALID_INFO_CLASS,
853 "LogonSamLogon failed");
855 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
856 "LogonSamLogon invalid *r.out.authoritative");
857 torture_assert(tctx,
858 memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
859 "Return authenticator non zero");
862 for (i=2;i<=3;i++) {
863 ZERO_STRUCT(auth2);
864 netlogon_creds_client_authenticator(creds, &auth);
866 r.in.validation_level = i;
868 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
869 "LogonSamLogon failed");
870 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
872 torture_assert(tctx, netlogon_creds_client_check(creds,
873 &r.out.return_authenticator->cred),
874 "Credential chaining failed");
875 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
876 "LogonSamLogon invalid *r.out.authoritative");
879 r.in.logon_level = 52;
881 for (i=2;i<=3;i++) {
882 ZERO_STRUCT(auth2);
883 /* the authenticator should be ignored by the server */
884 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
886 r.in.validation_level = i;
888 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
890 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
891 "LogonSamLogon failed");
892 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
893 "LogonSamLogon expected INVALID_PARAMETER");
895 torture_assert(tctx,
896 memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
897 "Return authenticator non zero");
898 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
899 "LogonSamLogon invalid *r.out.authoritative");
902 r.in.credential = NULL;
904 for (i=2;i<=3;i++) {
905 ZERO_STRUCT(auth2);
907 r.in.validation_level = i;
909 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
911 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
912 "LogonSamLogon failed");
913 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
914 "LogonSamLogon expected INVALID_PARAMETER");
916 torture_assert(tctx,
917 memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
918 "Return authenticator non zero");
919 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
920 "LogonSamLogon invalid *r.out.authoritative");
923 r.in.logon_level = 2;
924 r.in.credential = &auth;
926 for (i=2;i<=3;i++) {
927 ZERO_STRUCT(auth2);
928 netlogon_creds_client_authenticator(creds, &auth);
930 r.in.validation_level = i;
932 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
933 "LogonSamLogon failed");
934 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
936 torture_assert(tctx, netlogon_creds_client_check(creds,
937 &r.out.return_authenticator->cred),
938 "Credential chaining failed");
939 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
940 "LogonSamLogon invalid *r.out.authoritative");
943 return true;
946 bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
947 struct cli_credentials *credentials,
948 struct netlogon_creds_CredentialState *creds)
950 return test_netlogon_ops_args(p, tctx, credentials, creds, false);
954 try a netlogon GetCapabilities
956 bool test_netlogon_capabilities(struct dcerpc_pipe *p, struct torture_context *tctx,
957 struct cli_credentials *credentials,
958 struct netlogon_creds_CredentialState *creds)
960 NTSTATUS status;
961 struct netr_LogonGetCapabilities r;
962 union netr_Capabilities capabilities;
963 struct netr_Authenticator auth, return_auth;
964 struct netlogon_creds_CredentialState tmp_creds;
965 struct dcerpc_binding_handle *b = p->binding_handle;
967 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
968 r.in.computer_name = cli_credentials_get_workstation(credentials);
969 r.in.credential = &auth;
970 r.in.return_authenticator = &return_auth;
971 r.in.query_level = 1;
972 r.out.capabilities = &capabilities;
973 r.out.return_authenticator = &return_auth;
975 torture_comment(tctx, "Testing LogonGetCapabilities\n");
977 ZERO_STRUCT(return_auth);
980 * we need to operate on a temporary copy of creds
981 * because dcerpc_netr_LogonGetCapabilities was
982 * dcerpc_netr_DummyFunction and returns NT_STATUS_NOT_IMPLEMENTED
983 * without looking a the authenticator.
985 tmp_creds = *creds;
986 netlogon_creds_client_authenticator(&tmp_creds, &auth);
988 status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
989 torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities failed");
990 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
991 return true;
994 *creds = tmp_creds;
996 torture_assert(tctx, netlogon_creds_client_check(creds,
997 &r.out.return_authenticator->cred),
998 "Credential chaining failed");
1000 torture_assert_int_equal(tctx, creds->negotiate_flags,
1001 capabilities.server_capabilities,
1002 "negotiate flags");
1004 return true;
1008 try a netlogon SamLogon
1010 static bool test_SamLogon(struct torture_context *tctx,
1011 struct dcerpc_pipe *p,
1012 struct cli_credentials *credentials)
1014 struct netlogon_creds_CredentialState *creds;
1016 if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
1017 return false;
1020 return test_netlogon_ops(p, tctx, credentials, creds);
1023 static bool test_SamLogon_NULL_domain(struct torture_context *tctx,
1024 struct dcerpc_pipe *p,
1025 struct cli_credentials *credentials)
1027 struct netlogon_creds_CredentialState *creds;
1029 if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
1030 return false;
1033 return test_netlogon_ops_args(p, tctx, credentials, creds, true);
1036 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
1037 static uint64_t sequence_nums[3];
1040 try a netlogon DatabaseSync
1042 static bool test_DatabaseSync(struct torture_context *tctx,
1043 struct dcerpc_pipe *p,
1044 struct cli_credentials *machine_credentials)
1046 struct netr_DatabaseSync r;
1047 struct netlogon_creds_CredentialState *creds;
1048 const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
1049 int i;
1050 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1051 struct netr_Authenticator credential, return_authenticator;
1052 struct dcerpc_binding_handle *b = p->binding_handle;
1054 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1055 return false;
1058 ZERO_STRUCT(return_authenticator);
1060 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1061 r.in.computername = TEST_MACHINE_NAME;
1062 r.in.preferredmaximumlength = (uint32_t)-1;
1063 r.in.return_authenticator = &return_authenticator;
1064 r.out.delta_enum_array = &delta_enum_array;
1065 r.out.return_authenticator = &return_authenticator;
1067 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1069 uint32_t sync_context = 0;
1071 r.in.database_id = database_ids[i];
1072 r.in.sync_context = &sync_context;
1073 r.out.sync_context = &sync_context;
1075 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
1077 do {
1078 netlogon_creds_client_authenticator(creds, &credential);
1080 r.in.credential = &credential;
1082 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync_r(b, tctx, &r),
1083 "DatabaseSync failed");
1084 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1085 break;
1087 /* Native mode servers don't do this */
1088 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1089 return true;
1091 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync");
1093 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1094 torture_comment(tctx, "Credential chaining failed\n");
1097 if (delta_enum_array &&
1098 delta_enum_array->num_deltas > 0 &&
1099 delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
1100 delta_enum_array->delta_enum[0].delta_union.domain) {
1101 sequence_nums[r.in.database_id] =
1102 delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
1103 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
1104 r.in.database_id,
1105 (unsigned long long)sequence_nums[r.in.database_id]);
1107 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1110 return true;
1115 try a netlogon DatabaseDeltas
1117 static bool test_DatabaseDeltas(struct torture_context *tctx,
1118 struct dcerpc_pipe *p,
1119 struct cli_credentials *machine_credentials)
1121 struct netr_DatabaseDeltas r;
1122 struct netlogon_creds_CredentialState *creds;
1123 struct netr_Authenticator credential;
1124 struct netr_Authenticator return_authenticator;
1125 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1126 const uint32_t database_ids[] = {0, 1, 2};
1127 int i;
1128 struct dcerpc_binding_handle *b = p->binding_handle;
1130 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1131 return false;
1134 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1135 r.in.computername = TEST_MACHINE_NAME;
1136 r.in.preferredmaximumlength = (uint32_t)-1;
1137 ZERO_STRUCT(r.in.return_authenticator);
1138 r.out.return_authenticator = &return_authenticator;
1139 r.out.delta_enum_array = &delta_enum_array;
1141 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1142 r.in.database_id = database_ids[i];
1143 r.in.sequence_num = &sequence_nums[r.in.database_id];
1145 if (*r.in.sequence_num == 0) continue;
1147 *r.in.sequence_num -= 1;
1149 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n",
1150 r.in.database_id, (unsigned long long)*r.in.sequence_num);
1152 do {
1153 netlogon_creds_client_authenticator(creds, &credential);
1155 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseDeltas_r(b, tctx, &r),
1156 "DatabaseDeltas failed");
1157 if (NT_STATUS_EQUAL(r.out.result,
1158 NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
1159 torture_comment(tctx, "not considering %s to be an error\n",
1160 nt_errstr(r.out.result));
1161 return true;
1163 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1164 break;
1166 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseDeltas");
1168 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1169 torture_comment(tctx, "Credential chaining failed\n");
1172 (*r.in.sequence_num)++;
1173 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1176 return true;
1179 static bool test_DatabaseRedo(struct torture_context *tctx,
1180 struct dcerpc_pipe *p,
1181 struct cli_credentials *machine_credentials)
1183 struct netr_DatabaseRedo r;
1184 struct netlogon_creds_CredentialState *creds;
1185 struct netr_Authenticator credential;
1186 struct netr_Authenticator return_authenticator;
1187 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1188 struct netr_ChangeLogEntry e;
1189 struct dom_sid null_sid, *sid;
1190 int i,d;
1191 struct dcerpc_binding_handle *b = p->binding_handle;
1193 ZERO_STRUCT(null_sid);
1195 sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
1199 struct {
1200 uint32_t rid;
1201 uint16_t flags;
1202 uint8_t db_index;
1203 uint8_t delta_type;
1204 struct dom_sid sid;
1205 const char *name;
1206 NTSTATUS expected_error;
1207 uint32_t expected_num_results;
1208 uint8_t expected_delta_type_1;
1209 uint8_t expected_delta_type_2;
1210 const char *comment;
1211 } changes[] = {
1213 /* SAM_DATABASE_DOMAIN */
1216 .rid = 0,
1217 .flags = 0,
1218 .db_index = SAM_DATABASE_DOMAIN,
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_DOMAIN,
1230 .delta_type = 0,
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_DOMAIN,
1236 .comment = "NULL DELTA"
1239 .rid = 0,
1240 .flags = 0,
1241 .db_index = SAM_DATABASE_DOMAIN,
1242 .delta_type = NETR_DELTA_DOMAIN,
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_DOMAIN,
1248 .comment = "NETR_DELTA_DOMAIN"
1251 .rid = DOMAIN_RID_ADMINISTRATOR,
1252 .flags = 0,
1253 .db_index = SAM_DATABASE_DOMAIN,
1254 .delta_type = NETR_DELTA_USER,
1255 .sid = null_sid,
1256 .name = NULL,
1257 .expected_error = NT_STATUS_OK,
1258 .expected_num_results = 1,
1259 .expected_delta_type_1 = NETR_DELTA_USER,
1260 .comment = "NETR_DELTA_USER by rid 500"
1263 .rid = DOMAIN_RID_GUEST,
1264 .flags = 0,
1265 .db_index = SAM_DATABASE_DOMAIN,
1266 .delta_type = NETR_DELTA_USER,
1267 .sid = null_sid,
1268 .name = NULL,
1269 .expected_error = NT_STATUS_OK,
1270 .expected_num_results = 1,
1271 .expected_delta_type_1 = NETR_DELTA_USER,
1272 .comment = "NETR_DELTA_USER by rid 501"
1275 .rid = 0,
1276 .flags = NETR_CHANGELOG_SID_INCLUDED,
1277 .db_index = SAM_DATABASE_DOMAIN,
1278 .delta_type = NETR_DELTA_USER,
1279 .sid = *sid,
1280 .name = NULL,
1281 .expected_error = NT_STATUS_OK,
1282 .expected_num_results = 1,
1283 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1284 .comment = "NETR_DELTA_USER by sid and flags"
1287 .rid = 0,
1288 .flags = NETR_CHANGELOG_SID_INCLUDED,
1289 .db_index = SAM_DATABASE_DOMAIN,
1290 .delta_type = NETR_DELTA_USER,
1291 .sid = null_sid,
1292 .name = NULL,
1293 .expected_error = NT_STATUS_OK,
1294 .expected_num_results = 1,
1295 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1296 .comment = "NETR_DELTA_USER by null_sid and flags"
1299 .rid = 0,
1300 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1301 .db_index = SAM_DATABASE_DOMAIN,
1302 .delta_type = NETR_DELTA_USER,
1303 .sid = null_sid,
1304 .name = "administrator",
1305 .expected_error = NT_STATUS_OK,
1306 .expected_num_results = 1,
1307 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1308 .comment = "NETR_DELTA_USER by name 'administrator'"
1311 .rid = DOMAIN_RID_ADMINS,
1312 .flags = 0,
1313 .db_index = SAM_DATABASE_DOMAIN,
1314 .delta_type = NETR_DELTA_GROUP,
1315 .sid = null_sid,
1316 .name = NULL,
1317 .expected_error = NT_STATUS_OK,
1318 .expected_num_results = 2,
1319 .expected_delta_type_1 = NETR_DELTA_GROUP,
1320 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
1321 .comment = "NETR_DELTA_GROUP by rid 512"
1324 .rid = DOMAIN_RID_ADMINS,
1325 .flags = 0,
1326 .db_index = SAM_DATABASE_DOMAIN,
1327 .delta_type = NETR_DELTA_GROUP_MEMBER,
1328 .sid = null_sid,
1329 .name = NULL,
1330 .expected_error = NT_STATUS_OK,
1331 .expected_num_results = 2,
1332 .expected_delta_type_1 = NETR_DELTA_GROUP,
1333 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
1334 .comment = "NETR_DELTA_GROUP_MEMBER by rid 512"
1338 /* SAM_DATABASE_BUILTIN */
1341 .rid = 0,
1342 .flags = 0,
1343 .db_index = SAM_DATABASE_BUILTIN,
1344 .delta_type = NETR_DELTA_MODIFY_COUNT,
1345 .sid = null_sid,
1346 .name = NULL,
1347 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1348 .expected_num_results = 0,
1349 .comment = "NETR_DELTA_MODIFY_COUNT"
1352 .rid = 0,
1353 .flags = 0,
1354 .db_index = SAM_DATABASE_BUILTIN,
1355 .delta_type = NETR_DELTA_DOMAIN,
1356 .sid = null_sid,
1357 .name = NULL,
1358 .expected_error = NT_STATUS_OK,
1359 .expected_num_results = 1,
1360 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1361 .comment = "NETR_DELTA_DOMAIN"
1364 .rid = DOMAIN_RID_ADMINISTRATOR,
1365 .flags = 0,
1366 .db_index = SAM_DATABASE_BUILTIN,
1367 .delta_type = NETR_DELTA_USER,
1368 .sid = null_sid,
1369 .name = NULL,
1370 .expected_error = NT_STATUS_OK,
1371 .expected_num_results = 1,
1372 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1373 .comment = "NETR_DELTA_USER by rid 500"
1376 .rid = 0,
1377 .flags = 0,
1378 .db_index = SAM_DATABASE_BUILTIN,
1379 .delta_type = NETR_DELTA_USER,
1380 .sid = null_sid,
1381 .name = NULL,
1382 .expected_error = NT_STATUS_OK,
1383 .expected_num_results = 1,
1384 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1385 .comment = "NETR_DELTA_USER"
1388 .rid = 544,
1389 .flags = 0,
1390 .db_index = SAM_DATABASE_BUILTIN,
1391 .delta_type = NETR_DELTA_ALIAS,
1392 .sid = null_sid,
1393 .name = NULL,
1394 .expected_error = NT_STATUS_OK,
1395 .expected_num_results = 2,
1396 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1397 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1398 .comment = "NETR_DELTA_ALIAS by rid 544"
1401 .rid = 544,
1402 .flags = 0,
1403 .db_index = SAM_DATABASE_BUILTIN,
1404 .delta_type = NETR_DELTA_ALIAS_MEMBER,
1405 .sid = null_sid,
1406 .name = NULL,
1407 .expected_error = NT_STATUS_OK,
1408 .expected_num_results = 2,
1409 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1410 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1411 .comment = "NETR_DELTA_ALIAS_MEMBER by rid 544"
1414 .rid = 544,
1415 .flags = 0,
1416 .db_index = SAM_DATABASE_BUILTIN,
1417 .delta_type = 0,
1418 .sid = null_sid,
1419 .name = NULL,
1420 .expected_error = NT_STATUS_OK,
1421 .expected_num_results = 1,
1422 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1423 .comment = "NULL DELTA by rid 544"
1426 .rid = 544,
1427 .flags = NETR_CHANGELOG_SID_INCLUDED,
1428 .db_index = SAM_DATABASE_BUILTIN,
1429 .delta_type = 0,
1430 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1431 .name = NULL,
1432 .expected_error = NT_STATUS_OK,
1433 .expected_num_results = 1,
1434 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1435 .comment = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
1438 .rid = 544,
1439 .flags = NETR_CHANGELOG_SID_INCLUDED,
1440 .db_index = SAM_DATABASE_BUILTIN,
1441 .delta_type = NETR_DELTA_ALIAS,
1442 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1443 .name = NULL,
1444 .expected_error = NT_STATUS_OK,
1445 .expected_num_results = 2,
1446 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1447 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1448 .comment = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
1451 .rid = 0,
1452 .flags = NETR_CHANGELOG_SID_INCLUDED,
1453 .db_index = SAM_DATABASE_BUILTIN,
1454 .delta_type = NETR_DELTA_ALIAS,
1455 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1456 .name = NULL,
1457 .expected_error = NT_STATUS_OK,
1458 .expected_num_results = 1,
1459 .expected_delta_type_1 = NETR_DELTA_DELETE_ALIAS,
1460 .comment = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
1463 /* SAM_DATABASE_PRIVS */
1466 .rid = 0,
1467 .flags = 0,
1468 .db_index = SAM_DATABASE_PRIVS,
1469 .delta_type = 0,
1470 .sid = null_sid,
1471 .name = NULL,
1472 .expected_error = NT_STATUS_ACCESS_DENIED,
1473 .expected_num_results = 0,
1474 .comment = "NULL DELTA"
1477 .rid = 0,
1478 .flags = 0,
1479 .db_index = SAM_DATABASE_PRIVS,
1480 .delta_type = NETR_DELTA_MODIFY_COUNT,
1481 .sid = null_sid,
1482 .name = NULL,
1483 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1484 .expected_num_results = 0,
1485 .comment = "NETR_DELTA_MODIFY_COUNT"
1488 .rid = 0,
1489 .flags = 0,
1490 .db_index = SAM_DATABASE_PRIVS,
1491 .delta_type = NETR_DELTA_POLICY,
1492 .sid = null_sid,
1493 .name = NULL,
1494 .expected_error = NT_STATUS_OK,
1495 .expected_num_results = 1,
1496 .expected_delta_type_1 = NETR_DELTA_POLICY,
1497 .comment = "NETR_DELTA_POLICY"
1500 .rid = 0,
1501 .flags = NETR_CHANGELOG_SID_INCLUDED,
1502 .db_index = SAM_DATABASE_PRIVS,
1503 .delta_type = NETR_DELTA_POLICY,
1504 .sid = null_sid,
1505 .name = NULL,
1506 .expected_error = NT_STATUS_OK,
1507 .expected_num_results = 1,
1508 .expected_delta_type_1 = NETR_DELTA_POLICY,
1509 .comment = "NETR_DELTA_POLICY by null sid and flags"
1512 .rid = 0,
1513 .flags = NETR_CHANGELOG_SID_INCLUDED,
1514 .db_index = SAM_DATABASE_PRIVS,
1515 .delta_type = NETR_DELTA_POLICY,
1516 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
1517 .name = NULL,
1518 .expected_error = NT_STATUS_OK,
1519 .expected_num_results = 1,
1520 .expected_delta_type_1 = NETR_DELTA_POLICY,
1521 .comment = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
1524 .rid = DOMAIN_RID_ADMINISTRATOR,
1525 .flags = 0,
1526 .db_index = SAM_DATABASE_PRIVS,
1527 .delta_type = NETR_DELTA_ACCOUNT,
1528 .sid = null_sid,
1529 .name = NULL,
1530 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
1531 .expected_num_results = 0,
1532 .comment = "NETR_DELTA_ACCOUNT by rid 500"
1535 .rid = 0,
1536 .flags = NETR_CHANGELOG_SID_INCLUDED,
1537 .db_index = SAM_DATABASE_PRIVS,
1538 .delta_type = NETR_DELTA_ACCOUNT,
1539 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1540 .name = NULL,
1541 .expected_error = NT_STATUS_OK,
1542 .expected_num_results = 1,
1543 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
1544 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
1547 .rid = 0,
1548 .flags = NETR_CHANGELOG_SID_INCLUDED |
1549 NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
1550 .db_index = SAM_DATABASE_PRIVS,
1551 .delta_type = NETR_DELTA_ACCOUNT,
1552 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1553 .name = NULL,
1554 .expected_error = NT_STATUS_OK,
1555 .expected_num_results = 1,
1556 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
1557 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
1560 .rid = 0,
1561 .flags = NETR_CHANGELOG_SID_INCLUDED |
1562 NETR_CHANGELOG_NAME_INCLUDED,
1563 .db_index = SAM_DATABASE_PRIVS,
1564 .delta_type = NETR_DELTA_ACCOUNT,
1565 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1566 .name = NULL,
1567 .expected_error = NT_STATUS_INVALID_PARAMETER,
1568 .expected_num_results = 0,
1569 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
1572 .rid = DOMAIN_RID_ADMINISTRATOR,
1573 .flags = NETR_CHANGELOG_SID_INCLUDED,
1574 .db_index = SAM_DATABASE_PRIVS,
1575 .delta_type = NETR_DELTA_ACCOUNT,
1576 .sid = *sid,
1577 .name = NULL,
1578 .expected_error = NT_STATUS_OK,
1579 .expected_num_results = 1,
1580 .expected_delta_type_1 = NETR_DELTA_DELETE_ACCOUNT,
1581 .comment = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
1584 .rid = 0,
1585 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1586 .db_index = SAM_DATABASE_PRIVS,
1587 .delta_type = NETR_DELTA_SECRET,
1588 .sid = null_sid,
1589 .name = "IsurelydontexistIhope",
1590 .expected_error = NT_STATUS_OK,
1591 .expected_num_results = 1,
1592 .expected_delta_type_1 = NETR_DELTA_DELETE_SECRET,
1593 .comment = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
1596 .rid = 0,
1597 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1598 .db_index = SAM_DATABASE_PRIVS,
1599 .delta_type = NETR_DELTA_SECRET,
1600 .sid = null_sid,
1601 .name = "G$BCKUPKEY_P",
1602 .expected_error = NT_STATUS_OK,
1603 .expected_num_results = 1,
1604 .expected_delta_type_1 = NETR_DELTA_SECRET,
1605 .comment = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
1609 ZERO_STRUCT(return_authenticator);
1611 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1612 r.in.computername = TEST_MACHINE_NAME;
1613 r.in.return_authenticator = &return_authenticator;
1614 r.out.return_authenticator = &return_authenticator;
1615 r.out.delta_enum_array = &delta_enum_array;
1617 for (d=0; d<3; d++) {
1618 const char *database = NULL;
1620 switch (d) {
1621 case 0:
1622 database = "SAM";
1623 break;
1624 case 1:
1625 database = "BUILTIN";
1626 break;
1627 case 2:
1628 database = "LSA";
1629 break;
1630 default:
1631 break;
1634 torture_comment(tctx, "Testing DatabaseRedo\n");
1636 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1637 return false;
1640 for (i=0;i<ARRAY_SIZE(changes);i++) {
1642 if (d != changes[i].db_index) {
1643 continue;
1646 netlogon_creds_client_authenticator(creds, &credential);
1648 r.in.credential = &credential;
1650 e.serial_number1 = 0;
1651 e.serial_number2 = 0;
1652 e.object_rid = changes[i].rid;
1653 e.flags = changes[i].flags;
1654 e.db_index = changes[i].db_index;
1655 e.delta_type = changes[i].delta_type;
1657 switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
1658 case NETR_CHANGELOG_SID_INCLUDED:
1659 e.object.object_sid = changes[i].sid;
1660 break;
1661 case NETR_CHANGELOG_NAME_INCLUDED:
1662 e.object.object_name = changes[i].name;
1663 break;
1664 default:
1665 break;
1668 r.in.change_log_entry = e;
1670 torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
1671 database, changes[i].comment);
1673 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseRedo_r(b, tctx, &r),
1674 "DatabaseRedo failed");
1675 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1676 return true;
1679 torture_assert_ntstatus_equal(tctx, r.out.result, changes[i].expected_error, changes[i].comment);
1680 if (delta_enum_array) {
1681 torture_assert_int_equal(tctx,
1682 delta_enum_array->num_deltas,
1683 changes[i].expected_num_results,
1684 changes[i].comment);
1685 if (delta_enum_array->num_deltas > 0) {
1686 torture_assert_int_equal(tctx,
1687 delta_enum_array->delta_enum[0].delta_type,
1688 changes[i].expected_delta_type_1,
1689 changes[i].comment);
1691 if (delta_enum_array->num_deltas > 1) {
1692 torture_assert_int_equal(tctx,
1693 delta_enum_array->delta_enum[1].delta_type,
1694 changes[i].expected_delta_type_2,
1695 changes[i].comment);
1699 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1700 torture_comment(tctx, "Credential chaining failed\n");
1701 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1702 return false;
1709 return true;
1713 try a netlogon AccountDeltas
1715 static bool test_AccountDeltas(struct torture_context *tctx,
1716 struct dcerpc_pipe *p,
1717 struct cli_credentials *machine_credentials)
1719 struct netr_AccountDeltas r;
1720 struct netlogon_creds_CredentialState *creds;
1722 struct netr_AccountBuffer buffer;
1723 uint32_t count_returned = 0;
1724 uint32_t total_entries = 0;
1725 struct netr_UAS_INFO_0 recordid;
1726 struct netr_Authenticator return_authenticator;
1727 struct dcerpc_binding_handle *b = p->binding_handle;
1729 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1730 return false;
1733 ZERO_STRUCT(return_authenticator);
1735 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1736 r.in.computername = TEST_MACHINE_NAME;
1737 r.in.return_authenticator = &return_authenticator;
1738 netlogon_creds_client_authenticator(creds, &r.in.credential);
1739 ZERO_STRUCT(r.in.uas);
1740 r.in.count=10;
1741 r.in.level=0;
1742 r.in.buffersize=100;
1743 r.out.buffer = &buffer;
1744 r.out.count_returned = &count_returned;
1745 r.out.total_entries = &total_entries;
1746 r.out.recordid = &recordid;
1747 r.out.return_authenticator = &return_authenticator;
1749 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1750 torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountDeltas_r(b, tctx, &r),
1751 "AccountDeltas failed");
1752 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
1754 return true;
1758 try a netlogon AccountSync
1760 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
1761 struct cli_credentials *machine_credentials)
1763 struct netr_AccountSync r;
1764 struct netlogon_creds_CredentialState *creds;
1766 struct netr_AccountBuffer buffer;
1767 uint32_t count_returned = 0;
1768 uint32_t total_entries = 0;
1769 uint32_t next_reference = 0;
1770 struct netr_UAS_INFO_0 recordid;
1771 struct netr_Authenticator return_authenticator;
1772 struct dcerpc_binding_handle *b = p->binding_handle;
1774 ZERO_STRUCT(recordid);
1775 ZERO_STRUCT(return_authenticator);
1777 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1778 return false;
1781 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1782 r.in.computername = TEST_MACHINE_NAME;
1783 r.in.return_authenticator = &return_authenticator;
1784 netlogon_creds_client_authenticator(creds, &r.in.credential);
1785 r.in.recordid = &recordid;
1786 r.in.reference=0;
1787 r.in.level=0;
1788 r.in.buffersize=100;
1789 r.out.buffer = &buffer;
1790 r.out.count_returned = &count_returned;
1791 r.out.total_entries = &total_entries;
1792 r.out.next_reference = &next_reference;
1793 r.out.recordid = &recordid;
1794 r.out.return_authenticator = &return_authenticator;
1796 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1797 torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountSync_r(b, tctx, &r),
1798 "AccountSync failed");
1799 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
1801 return true;
1805 try a netlogon GetDcName
1807 static bool test_GetDcName(struct torture_context *tctx,
1808 struct dcerpc_pipe *p)
1810 struct netr_GetDcName r;
1811 const char *dcname = NULL;
1812 struct dcerpc_binding_handle *b = p->binding_handle;
1814 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1815 r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
1816 r.out.dcname = &dcname;
1818 torture_assert_ntstatus_ok(tctx, dcerpc_netr_GetDcName_r(b, tctx, &r),
1819 "GetDcName failed");
1820 torture_assert_werr_ok(tctx, r.out.result, "GetDcName failed");
1822 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1824 return true;
1827 static const char *function_code_str(TALLOC_CTX *mem_ctx,
1828 enum netr_LogonControlCode function_code)
1830 switch (function_code) {
1831 case NETLOGON_CONTROL_QUERY:
1832 return "NETLOGON_CONTROL_QUERY";
1833 case NETLOGON_CONTROL_REPLICATE:
1834 return "NETLOGON_CONTROL_REPLICATE";
1835 case NETLOGON_CONTROL_SYNCHRONIZE:
1836 return "NETLOGON_CONTROL_SYNCHRONIZE";
1837 case NETLOGON_CONTROL_PDC_REPLICATE:
1838 return "NETLOGON_CONTROL_PDC_REPLICATE";
1839 case NETLOGON_CONTROL_REDISCOVER:
1840 return "NETLOGON_CONTROL_REDISCOVER";
1841 case NETLOGON_CONTROL_TC_QUERY:
1842 return "NETLOGON_CONTROL_TC_QUERY";
1843 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1844 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
1845 case NETLOGON_CONTROL_FIND_USER:
1846 return "NETLOGON_CONTROL_FIND_USER";
1847 case NETLOGON_CONTROL_CHANGE_PASSWORD:
1848 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
1849 case NETLOGON_CONTROL_TC_VERIFY:
1850 return "NETLOGON_CONTROL_TC_VERIFY";
1851 case NETLOGON_CONTROL_FORCE_DNS_REG:
1852 return "NETLOGON_CONTROL_FORCE_DNS_REG";
1853 case NETLOGON_CONTROL_QUERY_DNS_REG:
1854 return "NETLOGON_CONTROL_QUERY_DNS_REG";
1855 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1856 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
1857 case NETLOGON_CONTROL_TRUNCATE_LOG:
1858 return "NETLOGON_CONTROL_TRUNCATE_LOG";
1859 case NETLOGON_CONTROL_SET_DBFLAG:
1860 return "NETLOGON_CONTROL_SET_DBFLAG";
1861 case NETLOGON_CONTROL_BREAKPOINT:
1862 return "NETLOGON_CONTROL_BREAKPOINT";
1863 default:
1864 return talloc_asprintf(mem_ctx, "unknown function code: %d",
1865 function_code);
1871 try a netlogon LogonControl
1873 static bool test_LogonControl(struct torture_context *tctx,
1874 struct dcerpc_pipe *p,
1875 struct cli_credentials *machine_credentials)
1878 NTSTATUS status;
1879 struct netr_LogonControl r;
1880 union netr_CONTROL_QUERY_INFORMATION query;
1881 int i,f;
1882 enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
1883 struct dcerpc_binding_handle *b = p->binding_handle;
1885 uint32_t function_codes[] = {
1886 NETLOGON_CONTROL_QUERY,
1887 NETLOGON_CONTROL_REPLICATE,
1888 NETLOGON_CONTROL_SYNCHRONIZE,
1889 NETLOGON_CONTROL_PDC_REPLICATE,
1890 NETLOGON_CONTROL_REDISCOVER,
1891 NETLOGON_CONTROL_TC_QUERY,
1892 NETLOGON_CONTROL_TRANSPORT_NOTIFY,
1893 NETLOGON_CONTROL_FIND_USER,
1894 NETLOGON_CONTROL_CHANGE_PASSWORD,
1895 NETLOGON_CONTROL_TC_VERIFY,
1896 NETLOGON_CONTROL_FORCE_DNS_REG,
1897 NETLOGON_CONTROL_QUERY_DNS_REG,
1898 NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
1899 NETLOGON_CONTROL_TRUNCATE_LOG,
1900 NETLOGON_CONTROL_SET_DBFLAG,
1901 NETLOGON_CONTROL_BREAKPOINT
1904 if (machine_credentials) {
1905 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1908 torture_comment(tctx, "Testing LogonControl with secure channel type: %d\n",
1909 secure_channel_type);
1911 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1912 r.in.function_code = 1;
1913 r.out.query = &query;
1915 for (f=0;f<ARRAY_SIZE(function_codes); f++) {
1916 for (i=1;i<5;i++) {
1918 r.in.function_code = function_codes[f];
1919 r.in.level = i;
1921 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
1922 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1924 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
1925 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1927 switch (r.in.level) {
1928 case 1:
1929 switch (r.in.function_code) {
1930 case NETLOGON_CONTROL_REPLICATE:
1931 case NETLOGON_CONTROL_SYNCHRONIZE:
1932 case NETLOGON_CONTROL_PDC_REPLICATE:
1933 case NETLOGON_CONTROL_BREAKPOINT:
1934 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1935 if ((secure_channel_type == SEC_CHAN_BDC) ||
1936 (secure_channel_type == SEC_CHAN_WKSTA)) {
1937 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1938 "LogonControl returned unexpected error code");
1939 } else {
1940 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1941 "LogonControl returned unexpected error code");
1943 break;
1945 case NETLOGON_CONTROL_REDISCOVER:
1946 case NETLOGON_CONTROL_TC_QUERY:
1947 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1948 case NETLOGON_CONTROL_FIND_USER:
1949 case NETLOGON_CONTROL_CHANGE_PASSWORD:
1950 case NETLOGON_CONTROL_TC_VERIFY:
1951 case NETLOGON_CONTROL_FORCE_DNS_REG:
1952 case NETLOGON_CONTROL_QUERY_DNS_REG:
1953 case NETLOGON_CONTROL_SET_DBFLAG:
1954 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1955 "LogonControl returned unexpected error code");
1956 break;
1957 case NETLOGON_CONTROL_TRUNCATE_LOG:
1958 if ((secure_channel_type == SEC_CHAN_BDC) ||
1959 (secure_channel_type == SEC_CHAN_WKSTA)) {
1960 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1961 "LogonControl returned unexpected error code");
1962 } else {
1963 torture_assert_werr_ok(tctx, r.out.result,
1964 "LogonControl returned unexpected result");
1966 break;
1967 default:
1968 torture_assert_werr_ok(tctx, r.out.result,
1969 "LogonControl returned unexpected result");
1970 break;
1972 break;
1973 case 2:
1974 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1975 "LogonControl returned unexpected error code");
1976 break;
1977 default:
1978 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL,
1979 "LogonControl returned unexpected error code");
1980 break;
1985 r.in.level = 52;
1986 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
1987 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1988 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
1989 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1990 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl");
1992 return true;
1997 try a netlogon GetAnyDCName
1999 static bool test_GetAnyDCName(struct torture_context *tctx,
2000 struct dcerpc_pipe *p)
2002 NTSTATUS status;
2003 struct netr_GetAnyDCName r;
2004 const char *dcname = NULL;
2005 struct dcerpc_binding_handle *b = p->binding_handle;
2007 r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
2008 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2009 r.out.dcname = &dcname;
2011 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2012 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2013 if ((!W_ERROR_IS_OK(r.out.result)) &&
2014 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2015 return false;
2018 if (dcname) {
2019 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
2022 r.in.domainname = NULL;
2024 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2025 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2026 if ((!W_ERROR_IS_OK(r.out.result)) &&
2027 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2028 return false;
2031 r.in.domainname = "";
2033 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2034 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2035 if ((!W_ERROR_IS_OK(r.out.result)) &&
2036 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2037 return false;
2040 return true;
2045 try a netlogon LogonControl2
2047 static bool test_LogonControl2(struct torture_context *tctx,
2048 struct dcerpc_pipe *p,
2049 struct cli_credentials *machine_credentials)
2052 NTSTATUS status;
2053 struct netr_LogonControl2 r;
2054 union netr_CONTROL_DATA_INFORMATION data;
2055 union netr_CONTROL_QUERY_INFORMATION query;
2056 int i;
2057 struct dcerpc_binding_handle *b = p->binding_handle;
2059 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2061 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2063 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2064 r.in.data = &data;
2065 r.out.query = &query;
2067 for (i=1;i<4;i++) {
2068 r.in.level = i;
2070 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2071 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2073 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2074 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2077 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2079 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2080 r.in.data = &data;
2082 for (i=1;i<4;i++) {
2083 r.in.level = i;
2085 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2086 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2088 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2089 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2092 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2094 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2095 r.in.data = &data;
2097 for (i=1;i<4;i++) {
2098 r.in.level = i;
2100 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2101 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2103 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2104 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2107 data.debug_level = ~0;
2109 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2110 r.in.data = &data;
2112 for (i=1;i<4;i++) {
2113 r.in.level = i;
2115 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2116 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2118 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2119 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2122 ZERO_STRUCT(data);
2123 r.in.function_code = 52;
2124 r.in.data = &data;
2126 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2127 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2129 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2130 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2131 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "LogonControl2");
2133 data.debug_level = ~0;
2135 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2136 r.in.data = &data;
2138 r.in.level = 52;
2139 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2140 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2142 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2143 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2144 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "LogonControl2");
2146 return true;
2150 try a netlogon DatabaseSync2
2152 static bool test_DatabaseSync2(struct torture_context *tctx,
2153 struct dcerpc_pipe *p,
2154 struct cli_credentials *machine_credentials)
2156 struct netr_DatabaseSync2 r;
2157 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2158 struct netr_Authenticator return_authenticator, credential;
2160 struct netlogon_creds_CredentialState *creds;
2161 const uint32_t database_ids[] = {0, 1, 2};
2162 int i;
2163 struct dcerpc_binding_handle *b = p->binding_handle;
2165 if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
2166 machine_credentials,
2167 cli_credentials_get_secure_channel_type(machine_credentials),
2168 &creds)) {
2169 return false;
2172 ZERO_STRUCT(return_authenticator);
2174 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2175 r.in.computername = TEST_MACHINE_NAME;
2176 r.in.preferredmaximumlength = (uint32_t)-1;
2177 r.in.return_authenticator = &return_authenticator;
2178 r.out.return_authenticator = &return_authenticator;
2179 r.out.delta_enum_array = &delta_enum_array;
2181 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2183 uint32_t sync_context = 0;
2185 r.in.database_id = database_ids[i];
2186 r.in.sync_context = &sync_context;
2187 r.out.sync_context = &sync_context;
2188 r.in.restart_state = 0;
2190 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
2192 do {
2193 netlogon_creds_client_authenticator(creds, &credential);
2195 r.in.credential = &credential;
2197 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync2_r(b, tctx, &r),
2198 "DatabaseSync2 failed");
2199 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2200 break;
2202 /* Native mode servers don't do this */
2203 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
2204 return true;
2207 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync2");
2209 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
2210 torture_comment(tctx, "Credential chaining failed\n");
2213 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2216 return true;
2221 try a netlogon LogonControl2Ex
2223 static bool test_LogonControl2Ex(struct torture_context *tctx,
2224 struct dcerpc_pipe *p,
2225 struct cli_credentials *machine_credentials)
2228 NTSTATUS status;
2229 struct netr_LogonControl2Ex r;
2230 union netr_CONTROL_DATA_INFORMATION data;
2231 union netr_CONTROL_QUERY_INFORMATION query;
2232 int i;
2233 struct dcerpc_binding_handle *b = p->binding_handle;
2235 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2237 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2239 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2240 r.in.data = &data;
2241 r.out.query = &query;
2243 for (i=1;i<4;i++) {
2244 r.in.level = i;
2246 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2247 i, r.in.function_code);
2249 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2250 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2253 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2255 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2256 r.in.data = &data;
2258 for (i=1;i<4;i++) {
2259 r.in.level = i;
2261 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2262 i, r.in.function_code);
2264 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2265 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2268 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2270 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2271 r.in.data = &data;
2273 for (i=1;i<4;i++) {
2274 r.in.level = i;
2276 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2277 i, r.in.function_code);
2279 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2280 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2283 data.debug_level = ~0;
2285 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2286 r.in.data = &data;
2288 for (i=1;i<4;i++) {
2289 r.in.level = i;
2291 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2292 i, r.in.function_code);
2294 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2295 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2298 return true;
2301 static bool test_netr_GetForestTrustInformation(struct torture_context *tctx,
2302 struct dcerpc_pipe *p,
2303 struct cli_credentials *machine_credentials)
2305 struct netr_GetForestTrustInformation r;
2306 struct netlogon_creds_CredentialState *creds;
2307 struct netr_Authenticator a;
2308 struct netr_Authenticator return_authenticator;
2309 struct lsa_ForestTrustInformation *forest_trust_info;
2310 struct dcerpc_binding_handle *b = p->binding_handle;
2312 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2313 machine_credentials, &creds)) {
2314 return false;
2317 netlogon_creds_client_authenticator(creds, &a);
2319 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2320 r.in.computer_name = TEST_MACHINE_NAME;
2321 r.in.credential = &a;
2322 r.in.flags = 0;
2323 r.out.return_authenticator = &return_authenticator;
2324 r.out.forest_trust_info = &forest_trust_info;
2326 torture_assert_ntstatus_ok(tctx,
2327 dcerpc_netr_GetForestTrustInformation_r(b, tctx, &r),
2328 "netr_GetForestTrustInformation failed");
2329 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2330 torture_comment(tctx, "not considering NT_STATUS_NOT_IMPLEMENTED as an error\n");
2331 } else {
2332 torture_assert_ntstatus_ok(tctx, r.out.result,
2333 "netr_GetForestTrustInformation failed");
2336 torture_assert(tctx,
2337 netlogon_creds_client_check(creds, &return_authenticator.cred),
2338 "Credential chaining failed");
2340 return true;
2343 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
2344 struct dcerpc_pipe *p, const char *trusted_domain_name)
2346 NTSTATUS status;
2347 struct netr_DsRGetForestTrustInformation r;
2348 struct lsa_ForestTrustInformation info, *info_ptr;
2349 struct dcerpc_binding_handle *b = p->binding_handle;
2351 info_ptr = &info;
2353 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2354 r.in.trusted_domain_name = trusted_domain_name;
2355 r.in.flags = 0;
2356 r.out.forest_trust_info = &info_ptr;
2358 torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
2360 status = dcerpc_netr_DsRGetForestTrustInformation_r(b, tctx, &r);
2361 torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
2362 torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
2364 return true;
2368 try a netlogon netr_DsrEnumerateDomainTrusts
2370 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
2371 struct dcerpc_pipe *p)
2373 NTSTATUS status;
2374 struct netr_DsrEnumerateDomainTrusts r;
2375 struct netr_DomainTrustList trusts;
2376 int i;
2377 struct dcerpc_binding_handle *b = p->binding_handle;
2379 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2380 r.in.trust_flags = 0x3f;
2381 r.out.trusts = &trusts;
2383 status = dcerpc_netr_DsrEnumerateDomainTrusts_r(b, tctx, &r);
2384 torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
2385 torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
2387 /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
2388 * will show non-forest trusts and all UPN suffixes of the own forest
2389 * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
2391 if (r.out.trusts->count) {
2392 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
2393 return false;
2397 for (i=0; i<r.out.trusts->count; i++) {
2399 /* get info for transitive forest trusts */
2401 if (r.out.trusts->array[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2402 if (!test_netr_DsRGetForestTrustInformation(tctx, p,
2403 r.out.trusts->array[i].dns_name)) {
2404 return false;
2409 return true;
2412 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
2413 struct dcerpc_pipe *p)
2415 NTSTATUS status;
2416 struct netr_NetrEnumerateTrustedDomains r;
2417 struct netr_Blob trusted_domains_blob;
2418 struct dcerpc_binding_handle *b = p->binding_handle;
2420 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2421 r.out.trusted_domains_blob = &trusted_domains_blob;
2423 status = dcerpc_netr_NetrEnumerateTrustedDomains_r(b, tctx, &r);
2424 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
2425 torture_assert_ntstatus_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
2427 return true;
2430 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
2431 struct dcerpc_pipe *p)
2433 NTSTATUS status;
2434 struct netr_NetrEnumerateTrustedDomainsEx r;
2435 struct netr_DomainTrustList dom_trust_list;
2436 struct dcerpc_binding_handle *b = p->binding_handle;
2438 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2439 r.out.dom_trust_list = &dom_trust_list;
2441 status = dcerpc_netr_NetrEnumerateTrustedDomainsEx_r(b, tctx, &r);
2442 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
2443 torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
2445 return true;
2449 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
2450 const char *computer_name,
2451 const char *expected_site)
2453 NTSTATUS status;
2454 struct netr_DsRGetSiteName r;
2455 const char *site = NULL;
2456 struct dcerpc_binding_handle *b = p->binding_handle;
2458 r.in.computer_name = computer_name;
2459 r.out.site = &site;
2460 torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
2462 status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
2463 torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2464 torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
2465 torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
2467 return true;
2471 try a netlogon netr_DsRGetDCName
2473 static bool test_netr_DsRGetDCName(struct torture_context *tctx,
2474 struct dcerpc_pipe *p)
2476 NTSTATUS status;
2477 struct netr_DsRGetDCName r;
2478 struct netr_DsRGetDCNameInfo *info = NULL;
2479 struct dcerpc_binding_handle *b = p->binding_handle;
2481 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2482 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
2483 r.in.domain_guid = NULL;
2484 r.in.site_guid = NULL;
2485 r.in.flags = DS_RETURN_DNS_NAME;
2486 r.out.info = &info;
2488 status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2489 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2490 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2492 torture_assert_int_equal(tctx,
2493 (info->dc_flags & (DS_DNS_CONTROLLER)),
2494 DS_DNS_CONTROLLER,
2495 "DsRGetDCName");
2496 torture_assert_int_equal(tctx,
2497 (info->dc_flags & (DS_DNS_DOMAIN)),
2498 DS_DNS_DOMAIN,
2499 "DsRGetDCName");
2500 torture_assert_int_equal(tctx,
2501 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2502 DS_DNS_FOREST_ROOT,
2503 "DsRGetDCName");
2505 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
2506 r.in.flags = 0;
2508 status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2509 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2510 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2512 torture_assert_int_equal(tctx,
2513 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2514 "DsRGetDCName");
2515 torture_assert_int_equal(tctx,
2516 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2517 "DsRGetDCName");
2518 torture_assert_int_equal(tctx,
2519 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2520 DS_DNS_FOREST_ROOT,
2521 "DsRGetDCName");
2523 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2524 torture_assert_int_equal(tctx,
2525 (info->dc_flags & (DS_SERVER_CLOSEST)),
2526 DS_SERVER_CLOSEST,
2527 "DsRGetDCName");
2530 return test_netr_DsRGetSiteName(p, tctx,
2531 info->dc_unc,
2532 info->dc_site_name);
2536 try a netlogon netr_DsRGetDCNameEx
2538 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
2539 struct dcerpc_pipe *p)
2541 NTSTATUS status;
2542 struct netr_DsRGetDCNameEx r;
2543 struct netr_DsRGetDCNameInfo *info = NULL;
2544 struct dcerpc_binding_handle *b = p->binding_handle;
2546 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2547 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
2548 r.in.domain_guid = NULL;
2549 r.in.site_name = NULL;
2550 r.in.flags = DS_RETURN_DNS_NAME;
2551 r.out.info = &info;
2553 status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2554 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2555 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2557 torture_assert_int_equal(tctx,
2558 (info->dc_flags & (DS_DNS_CONTROLLER)),
2559 DS_DNS_CONTROLLER,
2560 "DsRGetDCNameEx");
2561 torture_assert_int_equal(tctx,
2562 (info->dc_flags & (DS_DNS_DOMAIN)),
2563 DS_DNS_DOMAIN,
2564 "DsRGetDCNameEx");
2565 torture_assert_int_equal(tctx,
2566 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2567 DS_DNS_FOREST_ROOT,
2568 "DsRGetDCNameEx");
2570 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
2571 r.in.flags = 0;
2573 status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2574 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2575 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2577 torture_assert_int_equal(tctx,
2578 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2579 "DsRGetDCNameEx");
2580 torture_assert_int_equal(tctx,
2581 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2582 "DsRGetDCNameEx");
2583 torture_assert_int_equal(tctx,
2584 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2585 DS_DNS_FOREST_ROOT,
2586 "DsRGetDCNameEx");
2588 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2589 torture_assert_int_equal(tctx,
2590 (info->dc_flags & (DS_SERVER_CLOSEST)),
2591 DS_SERVER_CLOSEST,
2592 "DsRGetDCNameEx");
2595 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2596 info->dc_site_name);
2600 try a netlogon netr_DsRGetDCNameEx2
2602 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
2603 struct dcerpc_pipe *p)
2605 NTSTATUS status;
2606 struct netr_DsRGetDCNameEx2 r;
2607 struct netr_DsRGetDCNameInfo *info = NULL;
2608 struct dcerpc_binding_handle *b = p->binding_handle;
2610 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with no inputs\n");
2611 ZERO_STRUCT(r.in);
2612 r.in.flags = DS_RETURN_DNS_NAME;
2613 r.out.info = &info;
2615 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2616 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2617 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2619 torture_assert_int_equal(tctx,
2620 (info->dc_flags & (DS_DNS_CONTROLLER)),
2621 DS_DNS_CONTROLLER,
2622 "DsRGetDCNameEx2");
2623 torture_assert_int_equal(tctx,
2624 (info->dc_flags & (DS_DNS_DOMAIN)),
2625 DS_DNS_DOMAIN,
2626 "DsRGetDCNameEx2");
2627 torture_assert_int_equal(tctx,
2628 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2629 DS_DNS_FOREST_ROOT,
2630 "DsRGetDCNameEx2");
2632 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2633 r.in.client_account = NULL;
2634 r.in.mask = 0x00000000;
2635 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
2636 r.in.domain_guid = NULL;
2637 r.in.site_name = NULL;
2638 r.in.flags = DS_RETURN_DNS_NAME;
2639 r.out.info = &info;
2641 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
2643 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2644 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2645 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2647 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
2648 r.in.flags = 0;
2650 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2651 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2652 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2654 torture_assert_int_equal(tctx,
2655 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2656 "DsRGetDCNameEx2");
2657 torture_assert_int_equal(tctx,
2658 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2659 "DsRGetDCNameEx2");
2660 torture_assert_int_equal(tctx,
2661 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2662 DS_DNS_FOREST_ROOT,
2663 "DsRGetDCNameEx2");
2665 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2666 torture_assert_int_equal(tctx,
2667 (info->dc_flags & (DS_SERVER_CLOSEST)),
2668 DS_SERVER_CLOSEST,
2669 "DsRGetDCNameEx2");
2672 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client account\n");
2673 r.in.client_account = TEST_MACHINE_NAME"$";
2674 r.in.mask = ACB_SVRTRUST;
2675 r.in.flags = DS_RETURN_FLAT_NAME;
2676 r.out.info = &info;
2678 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2679 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2680 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2682 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2683 info->dc_site_name);
2686 /* This is a substitution for "samdb_server_site_name" which relies on the
2687 * correct "lp_ctx" and therefore can't be used here. */
2688 static const char *server_site_name(struct torture_context *tctx,
2689 struct ldb_context *ldb)
2691 TALLOC_CTX *tmp_ctx;
2692 struct ldb_dn *dn, *server_dn;
2693 const struct ldb_val *site_name_val;
2694 const char *server_dn_str, *site_name;
2696 tmp_ctx = talloc_new(ldb);
2697 if (tmp_ctx == NULL) {
2698 goto failed;
2701 dn = ldb_dn_new(tmp_ctx, ldb, "");
2702 if (dn == NULL) {
2703 goto failed;
2706 server_dn_str = samdb_search_string(ldb, tmp_ctx, dn, "serverName",
2707 NULL);
2708 if (server_dn_str == NULL) {
2709 goto failed;
2712 server_dn = ldb_dn_new(tmp_ctx, ldb, server_dn_str);
2713 if (server_dn == NULL) {
2714 goto failed;
2717 /* CN=<Server name>, CN=Servers, CN=<Site name>, CN=Sites, ... */
2718 site_name_val = ldb_dn_get_component_val(server_dn, 2);
2719 if (site_name_val == NULL) {
2720 goto failed;
2723 site_name = (const char *) site_name_val->data;
2725 talloc_steal(tctx, site_name);
2726 talloc_free(tmp_ctx);
2728 return site_name;
2730 failed:
2731 talloc_free(tmp_ctx);
2732 return NULL;
2735 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
2736 struct dcerpc_pipe *p)
2738 char *url;
2739 struct ldb_context *sam_ctx = NULL;
2740 NTSTATUS status;
2741 struct netr_DsrGetDcSiteCoverageW r;
2742 struct DcSitesCtr *ctr = NULL;
2743 struct dcerpc_binding_handle *b = p->binding_handle;
2745 torture_comment(tctx, "This does only pass with the default site\n");
2747 /* We won't double-check this when we are over 'local' transports */
2748 if (dcerpc_server_name(p)) {
2749 /* Set up connection to SAMDB on DC */
2750 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2751 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2752 NULL,
2753 cmdline_credentials,
2756 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2759 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2760 r.out.ctr = &ctr;
2762 status = dcerpc_netr_DsrGetDcSiteCoverageW_r(b, tctx, &r);
2763 torture_assert_ntstatus_ok(tctx, status, "failed");
2764 torture_assert_werr_ok(tctx, r.out.result, "failed");
2766 torture_assert(tctx, ctr->num_sites == 1,
2767 "we should per default only get the default site");
2768 if (sam_ctx != NULL) {
2769 torture_assert_casestr_equal(tctx, ctr->sites[0].string,
2770 server_site_name(tctx, sam_ctx),
2771 "didn't return default site");
2774 return true;
2777 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
2778 struct dcerpc_pipe *p)
2780 char *url;
2781 struct ldb_context *sam_ctx = NULL;
2782 NTSTATUS status;
2783 struct netr_DsRAddressToSitenamesW r;
2784 struct netr_DsRAddress addrs[6];
2785 struct sockaddr_in *addr;
2786 #ifdef HAVE_IPV6
2787 struct sockaddr_in6 *addr6;
2788 #endif
2789 struct netr_DsRAddressToSitenamesWCtr *ctr;
2790 struct dcerpc_binding_handle *b = p->binding_handle;
2791 uint32_t i;
2792 int ret;
2794 torture_comment(tctx, "This does only pass with the default site\n");
2796 /* We won't double-check this when we are over 'local' transports */
2797 if (dcerpc_server_name(p)) {
2798 /* Set up connection to SAMDB on DC */
2799 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2800 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2801 NULL,
2802 cmdline_credentials,
2805 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2808 /* First try valid IP addresses */
2810 addrs[0].size = sizeof(struct sockaddr_in);
2811 addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
2812 addr = (struct sockaddr_in *) addrs[0].buffer;
2813 addrs[0].buffer[0] = AF_INET;
2814 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2815 torture_assert(tctx, ret > 0, "inet_pton failed");
2817 addrs[1].size = sizeof(struct sockaddr_in);
2818 addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
2819 addr = (struct sockaddr_in *) addrs[1].buffer;
2820 addrs[1].buffer[0] = AF_INET;
2821 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2822 torture_assert(tctx, ret > 0, "inet_pton failed");
2824 addrs[2].size = sizeof(struct sockaddr_in);
2825 addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
2826 addr = (struct sockaddr_in *) addrs[2].buffer;
2827 addrs[2].buffer[0] = AF_INET;
2828 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2829 torture_assert(tctx, ret > 0, "inet_pton failed");
2831 #ifdef HAVE_IPV6
2832 addrs[3].size = sizeof(struct sockaddr_in6);
2833 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2834 addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
2835 addrs[3].buffer[0] = AF_INET6;
2836 ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
2837 torture_assert(tctx, ret > 0, "inet_pton failed");
2839 addrs[4].size = sizeof(struct sockaddr_in6);
2840 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2841 addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
2842 addrs[4].buffer[0] = AF_INET6;
2843 ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
2844 torture_assert(tctx, ret > 0, "inet_pton failed");
2846 addrs[5].size = sizeof(struct sockaddr_in6);
2847 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2848 addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
2849 addrs[5].buffer[0] = AF_INET6;
2850 ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
2851 torture_assert(tctx, ret > 0, "inet_pton failed");
2852 #else
2853 /* the test cases are repeated to have exactly 6. This is for
2854 * compatibility with IPv4-only machines */
2855 addrs[3].size = sizeof(struct sockaddr_in);
2856 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2857 addr = (struct sockaddr_in *) addrs[3].buffer;
2858 addrs[3].buffer[0] = AF_INET;
2859 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2860 torture_assert(tctx, ret > 0, "inet_pton failed");
2862 addrs[4].size = sizeof(struct sockaddr_in);
2863 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2864 addr = (struct sockaddr_in *) addrs[4].buffer;
2865 addrs[4].buffer[0] = AF_INET;
2866 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2867 torture_assert(tctx, ret > 0, "inet_pton failed");
2869 addrs[5].size = sizeof(struct sockaddr_in);
2870 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2871 addr = (struct sockaddr_in *) addrs[5].buffer;
2872 addrs[5].buffer[0] = AF_INET;
2873 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2874 torture_assert(tctx, ret > 0, "inet_pton failed");
2875 #endif
2877 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
2879 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2880 r.in.count = 6;
2881 r.in.addresses = addrs;
2882 r.out.ctr = &ctr;
2884 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2885 torture_assert_ntstatus_ok(tctx, status, "failed");
2886 torture_assert_werr_ok(tctx, r.out.result, "failed");
2888 if (sam_ctx != NULL) {
2889 for (i = 0; i < 3; i++) {
2890 torture_assert_casestr_equal(tctx,
2891 ctr->sitename[i].string,
2892 server_site_name(tctx, sam_ctx),
2893 "didn't return default site");
2895 for (i = 3; i < 6; i++) {
2896 /* Windows returns "NULL" for the sitename if it isn't
2897 * IPv6 configured */
2898 if (torture_setting_bool(tctx, "samba4", false)) {
2899 torture_assert_casestr_equal(tctx,
2900 ctr->sitename[i].string,
2901 server_site_name(tctx, sam_ctx),
2902 "didn't return default site");
2907 /* Now try invalid ones (too short buffers) */
2909 addrs[0].size = 0;
2910 addrs[1].size = 1;
2911 addrs[2].size = 4;
2913 addrs[3].size = 0;
2914 addrs[4].size = 1;
2915 addrs[5].size = 4;
2917 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2918 torture_assert_ntstatus_ok(tctx, status, "failed");
2919 torture_assert_werr_ok(tctx, r.out.result, "failed");
2921 for (i = 0; i < 6; i++) {
2922 torture_assert(tctx, ctr->sitename[i].string == NULL,
2923 "sitename should be null");
2926 /* Now try invalid ones (wrong address types) */
2928 addrs[0].size = 10;
2929 addrs[0].buffer[0] = AF_UNSPEC;
2930 addrs[1].size = 10;
2931 addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
2932 addrs[2].size = 10;
2933 addrs[2].buffer[0] = AF_UNIX;
2935 addrs[3].size = 10;
2936 addrs[3].buffer[0] = 250;
2937 addrs[4].size = 10;
2938 addrs[4].buffer[0] = 251;
2939 addrs[5].size = 10;
2940 addrs[5].buffer[0] = 252;
2942 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2943 torture_assert_ntstatus_ok(tctx, status, "failed");
2944 torture_assert_werr_ok(tctx, r.out.result, "failed");
2946 for (i = 0; i < 6; i++) {
2947 torture_assert(tctx, ctr->sitename[i].string == NULL,
2948 "sitename should be null");
2951 return true;
2954 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
2955 struct dcerpc_pipe *p)
2957 char *url;
2958 struct ldb_context *sam_ctx = NULL;
2959 NTSTATUS status;
2960 struct netr_DsRAddressToSitenamesExW r;
2961 struct netr_DsRAddress addrs[6];
2962 struct sockaddr_in *addr;
2963 #ifdef HAVE_IPV6
2964 struct sockaddr_in6 *addr6;
2965 #endif
2966 struct netr_DsRAddressToSitenamesExWCtr *ctr;
2967 struct dcerpc_binding_handle *b = p->binding_handle;
2968 uint32_t i;
2969 int ret;
2971 torture_comment(tctx, "This does pass with the default site\n");
2973 /* We won't double-check this when we are over 'local' transports */
2974 if (dcerpc_server_name(p)) {
2975 /* Set up connection to SAMDB on DC */
2976 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2977 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2978 NULL,
2979 cmdline_credentials,
2982 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2985 /* First try valid IP addresses */
2987 addrs[0].size = sizeof(struct sockaddr_in);
2988 addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
2989 addr = (struct sockaddr_in *) addrs[0].buffer;
2990 addrs[0].buffer[0] = AF_INET;
2991 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2992 torture_assert(tctx, ret > 0, "inet_pton failed");
2994 addrs[1].size = sizeof(struct sockaddr_in);
2995 addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
2996 addr = (struct sockaddr_in *) addrs[1].buffer;
2997 addrs[1].buffer[0] = AF_INET;
2998 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2999 torture_assert(tctx, ret > 0, "inet_pton failed");
3001 addrs[2].size = sizeof(struct sockaddr_in);
3002 addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
3003 addr = (struct sockaddr_in *) addrs[2].buffer;
3004 addrs[2].buffer[0] = AF_INET;
3005 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3006 torture_assert(tctx, ret > 0, "inet_pton failed");
3008 #ifdef HAVE_IPV6
3009 addrs[3].size = sizeof(struct sockaddr_in6);
3010 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3011 addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
3012 addrs[3].buffer[0] = AF_INET6;
3013 ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
3014 torture_assert(tctx, ret > 0, "inet_pton failed");
3016 addrs[4].size = sizeof(struct sockaddr_in6);
3017 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3018 addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
3019 addrs[4].buffer[0] = AF_INET6;
3020 ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
3021 torture_assert(tctx, ret > 0, "inet_pton failed");
3023 addrs[5].size = sizeof(struct sockaddr_in6);
3024 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3025 addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
3026 addrs[5].buffer[0] = AF_INET6;
3027 ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
3028 torture_assert(tctx, ret > 0, "inet_pton failed");
3029 #else
3030 /* the test cases are repeated to have exactly 6. This is for
3031 * compatibility with IPv4-only machines */
3032 addrs[3].size = sizeof(struct sockaddr_in);
3033 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3034 addr = (struct sockaddr_in *) addrs[3].buffer;
3035 addrs[3].buffer[0] = AF_INET;
3036 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3037 torture_assert(tctx, ret > 0, "inet_pton failed");
3039 addrs[4].size = sizeof(struct sockaddr_in);
3040 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3041 addr = (struct sockaddr_in *) addrs[4].buffer;
3042 addrs[4].buffer[0] = AF_INET;
3043 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3044 torture_assert(tctx, ret > 0, "inet_pton failed");
3046 addrs[5].size = sizeof(struct sockaddr_in);
3047 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3048 addr = (struct sockaddr_in *) addrs[5].buffer;
3049 addrs[5].buffer[0] = AF_INET;
3050 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3051 torture_assert(tctx, ret > 0, "inet_pton failed");
3052 #endif
3054 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
3056 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3057 r.in.count = 6;
3058 r.in.addresses = addrs;
3059 r.out.ctr = &ctr;
3061 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3062 torture_assert_ntstatus_ok(tctx, status, "failed");
3063 torture_assert_werr_ok(tctx, r.out.result, "failed");
3065 if (sam_ctx != NULL) {
3066 for (i = 0; i < 3; i++) {
3067 torture_assert_casestr_equal(tctx,
3068 ctr->sitename[i].string,
3069 server_site_name(tctx, sam_ctx),
3070 "didn't return default site");
3071 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3072 "subnet should be null");
3074 for (i = 3; i < 6; i++) {
3075 /* Windows returns "NULL" for the sitename if it isn't
3076 * IPv6 configured */
3077 if (torture_setting_bool(tctx, "samba4", false)) {
3078 torture_assert_casestr_equal(tctx,
3079 ctr->sitename[i].string,
3080 server_site_name(tctx, sam_ctx),
3081 "didn't return default site");
3083 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3084 "subnet should be null");
3088 /* Now try invalid ones (too short buffers) */
3090 addrs[0].size = 0;
3091 addrs[1].size = 1;
3092 addrs[2].size = 4;
3094 addrs[3].size = 0;
3095 addrs[4].size = 1;
3096 addrs[5].size = 4;
3098 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3099 torture_assert_ntstatus_ok(tctx, status, "failed");
3100 torture_assert_werr_ok(tctx, r.out.result, "failed");
3102 for (i = 0; i < 6; i++) {
3103 torture_assert(tctx, ctr->sitename[i].string == NULL,
3104 "sitename should be null");
3105 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3106 "subnet should be null");
3109 addrs[0].size = 10;
3110 addrs[0].buffer[0] = AF_UNSPEC;
3111 addrs[1].size = 10;
3112 addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
3113 addrs[2].size = 10;
3114 addrs[2].buffer[0] = AF_UNIX;
3116 addrs[3].size = 10;
3117 addrs[3].buffer[0] = 250;
3118 addrs[4].size = 10;
3119 addrs[4].buffer[0] = 251;
3120 addrs[5].size = 10;
3121 addrs[5].buffer[0] = 252;
3123 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3124 torture_assert_ntstatus_ok(tctx, status, "failed");
3125 torture_assert_werr_ok(tctx, r.out.result, "failed");
3127 for (i = 0; i < 6; i++) {
3128 torture_assert(tctx, ctr->sitename[i].string == NULL,
3129 "sitename should be null");
3130 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3131 "subnet should be null");
3134 return true;
3137 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
3138 struct dcerpc_pipe *p,
3139 struct cli_credentials *machine_credentials)
3141 struct netr_ServerGetTrustInfo r;
3143 struct netr_Authenticator a;
3144 struct netr_Authenticator return_authenticator;
3145 struct samr_Password new_owf_password;
3146 struct samr_Password old_owf_password;
3147 struct netr_TrustInfo *trust_info;
3149 struct netlogon_creds_CredentialState *creds;
3150 struct dcerpc_binding_handle *b = p->binding_handle;
3152 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3153 machine_credentials, &creds)) {
3154 return false;
3157 netlogon_creds_client_authenticator(creds, &a);
3159 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3160 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
3161 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
3162 r.in.computer_name = TEST_MACHINE_NAME;
3163 r.in.credential = &a;
3165 r.out.return_authenticator = &return_authenticator;
3166 r.out.new_owf_password = &new_owf_password;
3167 r.out.old_owf_password = &old_owf_password;
3168 r.out.trust_info = &trust_info;
3170 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerGetTrustInfo_r(b, tctx, &r),
3171 "ServerGetTrustInfo failed");
3172 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerGetTrustInfo failed");
3173 torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
3175 return true;
3179 static bool test_GetDomainInfo(struct torture_context *tctx,
3180 struct dcerpc_pipe *p,
3181 struct cli_credentials *machine_credentials)
3183 struct netr_LogonGetDomainInfo r;
3184 struct netr_WorkstationInformation q1;
3185 struct netr_Authenticator a;
3186 struct netlogon_creds_CredentialState *creds;
3187 struct netr_OsVersion os;
3188 union netr_WorkstationInfo query;
3189 union netr_DomainInfo info;
3190 const char* const attrs[] = { "dNSHostName", "operatingSystem",
3191 "operatingSystemServicePack", "operatingSystemVersion",
3192 "servicePrincipalName", NULL };
3193 char *url;
3194 struct ldb_context *sam_ctx = NULL;
3195 struct ldb_message **res;
3196 struct ldb_message_element *spn_el;
3197 int ret, i;
3198 char *version_str;
3199 const char *old_dnsname = NULL;
3200 char **spns = NULL;
3201 int num_spns = 0;
3202 char *temp_str;
3203 struct dcerpc_binding_handle *b = p->binding_handle;
3205 torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
3207 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3208 machine_credentials, &creds)) {
3209 return false;
3212 /* We won't double-check this when we are over 'local' transports */
3213 if (dcerpc_server_name(p)) {
3214 /* Set up connection to SAMDB on DC */
3215 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3216 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3217 NULL,
3218 cmdline_credentials,
3221 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3224 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
3225 netlogon_creds_client_authenticator(creds, &a);
3227 ZERO_STRUCT(r);
3228 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3229 r.in.computer_name = TEST_MACHINE_NAME;
3230 r.in.credential = &a;
3231 r.in.level = 1;
3232 r.in.return_authenticator = &a;
3233 r.in.query = &query;
3234 r.out.return_authenticator = &a;
3235 r.out.info = &info;
3237 ZERO_STRUCT(os);
3238 os.os.MajorVersion = 123;
3239 os.os.MinorVersion = 456;
3240 os.os.BuildNumber = 789;
3241 os.os.CSDVersion = "Service Pack 10";
3242 os.os.ServicePackMajor = 10;
3243 os.os.ServicePackMinor = 1;
3244 os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
3245 os.os.ProductType = NETR_VER_NT_SERVER;
3246 os.os.Reserved = 0;
3248 version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
3249 os.os.MinorVersion, os.os.BuildNumber);
3251 ZERO_STRUCT(q1);
3252 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3253 lpcfg_dnsdomain(tctx->lp_ctx));
3254 q1.sitename = "Default-First-Site-Name";
3255 q1.os_version.os = &os;
3256 q1.os_name.string = talloc_asprintf(tctx,
3257 "Tortured by Samba4 RPC-NETLOGON: %s",
3258 timestring(tctx, time(NULL)));
3260 /* The workstation handles the "servicePrincipalName" and DNS hostname
3261 updates */
3262 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3264 query.workstation_info = &q1;
3266 if (sam_ctx) {
3267 /* Gets back the old DNS hostname in AD */
3268 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3269 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3270 old_dnsname =
3271 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
3273 /* Gets back the "servicePrincipalName"s in AD */
3274 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3275 if (spn_el != NULL) {
3276 for (i=0; i < spn_el->num_values; i++) {
3277 spns = talloc_realloc(tctx, spns, char *, i + 1);
3278 spns[i] = (char *) spn_el->values[i].data;
3280 num_spns = i;
3284 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3285 "LogonGetDomainInfo failed");
3286 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3287 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3289 smb_msleep(250);
3291 if (sam_ctx) {
3292 /* AD workstation infos entry check */
3293 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3294 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3295 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3296 torture_assert_str_equal(tctx,
3297 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3298 q1.os_name.string, "'operatingSystem' wrong!");
3299 torture_assert_str_equal(tctx,
3300 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
3301 os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
3302 torture_assert_str_equal(tctx,
3303 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
3304 version_str, "'operatingSystemVersion' wrong!");
3306 if (old_dnsname != NULL) {
3307 /* If before a DNS hostname was set then it should remain
3308 the same in combination with the "servicePrincipalName"s.
3309 The DNS hostname should also be returned by our
3310 "LogonGetDomainInfo" call (in the domain info structure). */
3312 torture_assert_str_equal(tctx,
3313 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3314 old_dnsname, "'DNS hostname' was not set!");
3316 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3317 torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
3318 "'servicePrincipalName's not set!");
3319 torture_assert(tctx, spn_el->num_values == num_spns,
3320 "'servicePrincipalName's incorrect!");
3321 for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
3322 torture_assert_str_equal(tctx,
3323 (char *) spn_el->values[i].data,
3324 spns[i], "'servicePrincipalName's incorrect!");
3326 torture_assert_str_equal(tctx,
3327 info.domain_info->dns_hostname.string,
3328 old_dnsname,
3329 "Out 'DNS hostname' doesn't match the old one!");
3330 } else {
3331 /* If no DNS hostname was set then also now none should be set,
3332 the "servicePrincipalName"s should remain empty and no DNS
3333 hostname should be returned by our "LogonGetDomainInfo"
3334 call (in the domain info structure). */
3336 torture_assert(tctx,
3337 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
3338 "'DNS hostname' was set!");
3340 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3341 torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
3342 "'servicePrincipalName's were set!");
3344 torture_assert(tctx,
3345 info.domain_info->dns_hostname.string == NULL,
3346 "Out 'DNS host name' was set!");
3350 /* Checks "workstation flags" */
3351 torture_assert(tctx,
3352 info.domain_info->workstation_flags
3353 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3354 "Out 'workstation flags' don't match!");
3357 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname doesn't work)\n");
3358 netlogon_creds_client_authenticator(creds, &a);
3360 /* Wipe out the osVersion, and prove which values still 'stick' */
3361 q1.os_version.os = NULL;
3363 /* Change also the DNS hostname to test differences in behaviour */
3364 talloc_free(discard_const_p(char, q1.dns_hostname));
3365 q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3366 lpcfg_dnsdomain(tctx->lp_ctx));
3368 /* The workstation handles the "servicePrincipalName" and DNS hostname
3369 updates */
3370 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3372 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3373 "LogonGetDomainInfo failed");
3374 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3376 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3378 smb_msleep(250);
3380 if (sam_ctx) {
3381 /* AD workstation infos entry check */
3382 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3383 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3384 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3386 torture_assert_str_equal(tctx,
3387 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3388 q1.os_name.string, "'operatingSystem' should stick!");
3389 torture_assert(tctx,
3390 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3391 "'operatingSystemServicePack' shouldn't stick!");
3392 torture_assert(tctx,
3393 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3394 "'operatingSystemVersion' shouldn't stick!");
3396 /* The DNS host name shouldn't have been updated by the server */
3398 torture_assert_str_equal(tctx,
3399 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3400 old_dnsname, "'DNS host name' did change!");
3402 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3403 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3404 3.5.4.3.9 */
3405 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3406 torture_assert(tctx, spn_el != NULL,
3407 "There should exist 'servicePrincipalName's in AD!");
3408 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3409 for (i=0; i < spn_el->num_values; i++)
3410 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3411 break;
3412 torture_assert(tctx, i != spn_el->num_values,
3413 "'servicePrincipalName' HOST/<Netbios name> not found!");
3414 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3415 for (i=0; i < spn_el->num_values; i++)
3416 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3417 break;
3418 torture_assert(tctx, i != spn_el->num_values,
3419 "'servicePrincipalName' HOST/<FQDN name> not found!");
3421 /* Check that the out DNS hostname was set properly */
3422 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
3423 old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
3426 /* Checks "workstation flags" */
3427 torture_assert(tctx,
3428 info.domain_info->workstation_flags == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3429 "Out 'workstation flags' don't match!");
3432 /* Now try the same but the workstation flags set to 0 */
3434 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (variation of DNS hostname doesn't work)\n");
3435 netlogon_creds_client_authenticator(creds, &a);
3437 /* Change also the DNS hostname to test differences in behaviour */
3438 talloc_free(discard_const_p(char, q1.dns_hostname));
3439 q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3440 lpcfg_dnsdomain(tctx->lp_ctx));
3442 /* Wipe out the osVersion, and prove which values still 'stick' */
3443 q1.os_version.os = NULL;
3445 /* Let the DC handle the "servicePrincipalName" and DNS hostname
3446 updates */
3447 q1.workstation_flags = 0;
3449 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3450 "LogonGetDomainInfo failed");
3451 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3452 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3454 smb_msleep(250);
3456 if (sam_ctx) {
3457 /* AD workstation infos entry check */
3458 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3459 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3460 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3462 torture_assert_str_equal(tctx,
3463 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3464 q1.os_name.string, "'operatingSystem' should stick!");
3465 torture_assert(tctx,
3466 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3467 "'operatingSystemServicePack' shouldn't stick!");
3468 torture_assert(tctx,
3469 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3470 "'operatingSystemVersion' shouldn't stick!");
3472 /* The DNS host name shouldn't have been updated by the server */
3474 torture_assert_str_equal(tctx,
3475 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3476 old_dnsname, "'DNS host name' did change!");
3478 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3479 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3480 3.5.4.3.9 */
3481 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3482 torture_assert(tctx, spn_el != NULL,
3483 "There should exist 'servicePrincipalName's in AD!");
3484 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3485 for (i=0; i < spn_el->num_values; i++)
3486 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3487 break;
3488 torture_assert(tctx, i != spn_el->num_values,
3489 "'servicePrincipalName' HOST/<Netbios name> not found!");
3490 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3491 for (i=0; i < spn_el->num_values; i++)
3492 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3493 break;
3494 torture_assert(tctx, i != spn_el->num_values,
3495 "'servicePrincipalName' HOST/<FQDN name> not found!");
3497 /* Here the server gives us NULL as the out DNS hostname */
3498 torture_assert(tctx, info.domain_info->dns_hostname.string == NULL,
3499 "Out 'DNS hostname' should be NULL!");
3502 /* Checks "workstation flags" */
3503 torture_assert(tctx,
3504 info.domain_info->workstation_flags == 0,
3505 "Out 'workstation flags' don't match!");
3508 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (verification of DNS hostname and check for trusted domains)\n");
3509 netlogon_creds_client_authenticator(creds, &a);
3511 /* Put the DNS hostname back */
3512 talloc_free(discard_const_p(char, q1.dns_hostname));
3513 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3514 lpcfg_dnsdomain(tctx->lp_ctx));
3516 /* The workstation handles the "servicePrincipalName" and DNS hostname
3517 updates */
3518 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3520 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3521 "LogonGetDomainInfo failed");
3522 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3523 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3525 smb_msleep(250);
3527 /* Now the in/out DNS hostnames should be the same */
3528 torture_assert_str_equal(tctx,
3529 info.domain_info->dns_hostname.string,
3530 query.workstation_info->dns_hostname,
3531 "In/Out 'DNS hostnames' don't match!");
3532 old_dnsname = info.domain_info->dns_hostname.string;
3534 /* Checks "workstation flags" */
3535 torture_assert(tctx,
3536 info.domain_info->workstation_flags
3537 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3538 "Out 'workstation flags' don't match!");
3540 /* Checks for trusted domains */
3541 torture_assert(tctx,
3542 (info.domain_info->trusted_domain_count != 0)
3543 && (info.domain_info->trusted_domains != NULL),
3544 "Trusted domains have been requested!");
3547 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 5th call (check for trusted domains)\n");
3548 netlogon_creds_client_authenticator(creds, &a);
3550 /* The workstation handles the "servicePrincipalName" and DNS hostname
3551 updates and requests inbound trusts */
3552 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
3553 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
3555 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3556 "LogonGetDomainInfo failed");
3557 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3558 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3560 smb_msleep(250);
3562 /* Checks "workstation flags" */
3563 torture_assert(tctx,
3564 info.domain_info->workstation_flags
3565 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
3566 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
3567 "Out 'workstation flags' don't match!");
3569 /* Checks for trusted domains */
3570 torture_assert(tctx,
3571 (info.domain_info->trusted_domain_count != 0)
3572 && (info.domain_info->trusted_domains != NULL),
3573 "Trusted domains have been requested!");
3576 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
3577 netlogon_creds_client_authenticator(creds, &a);
3579 query.workstation_info->dns_hostname = NULL;
3581 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3582 "LogonGetDomainInfo failed");
3583 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3584 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3586 /* The old DNS hostname should stick */
3587 torture_assert_str_equal(tctx,
3588 info.domain_info->dns_hostname.string,
3589 old_dnsname,
3590 "'DNS hostname' changed!");
3592 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (extra workstation flags)\n");
3593 netlogon_creds_client_authenticator(creds, &a);
3595 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
3596 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | 0x4;
3598 /* Put the DNS hostname back */
3599 talloc_free(discard_const_p(char, q1.dns_hostname));
3600 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3601 lpcfg_dnsdomain(tctx->lp_ctx));
3603 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3604 "LogonGetDomainInfo failed");
3605 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3606 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3608 /* Checks "workstation flags" */
3609 torture_assert(tctx,
3610 info.domain_info->workstation_flags
3611 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
3612 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
3613 "Out 'workstation flags' don't match!");
3615 if (!torture_setting_bool(tctx, "dangerous", false)) {
3616 torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 8th call (no workstation info) - enable dangerous tests in order to do so\n");
3617 } else {
3618 /* Try a call without the workstation information structure */
3620 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 8th call (no workstation info)\n");
3621 netlogon_creds_client_authenticator(creds, &a);
3623 query.workstation_info = NULL;
3625 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3626 "LogonGetDomainInfo failed");
3627 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3628 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3631 return true;
3634 static bool test_GetDomainInfo_async(struct torture_context *tctx,
3635 struct dcerpc_pipe *p,
3636 struct cli_credentials *machine_credentials)
3638 NTSTATUS status;
3639 struct netr_LogonGetDomainInfo r;
3640 struct netr_WorkstationInformation q1;
3641 struct netr_Authenticator a;
3642 #define ASYNC_COUNT 100
3643 struct netlogon_creds_CredentialState *creds;
3644 struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
3645 struct tevent_req *req[ASYNC_COUNT];
3646 int i;
3647 union netr_WorkstationInfo query;
3648 union netr_DomainInfo info;
3650 torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
3652 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3653 machine_credentials, &creds)) {
3654 return false;
3657 ZERO_STRUCT(r);
3658 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3659 r.in.computer_name = TEST_MACHINE_NAME;
3660 r.in.credential = &a;
3661 r.in.level = 1;
3662 r.in.return_authenticator = &a;
3663 r.in.query = &query;
3664 r.out.return_authenticator = &a;
3665 r.out.info = &info;
3667 ZERO_STRUCT(q1);
3668 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3669 lpcfg_dnsdomain(tctx->lp_ctx));
3670 q1.sitename = "Default-First-Site-Name";
3671 q1.os_name.string = "UNIX/Linux or similar";
3673 query.workstation_info = &q1;
3675 for (i=0;i<ASYNC_COUNT;i++) {
3676 netlogon_creds_client_authenticator(creds, &a);
3678 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
3679 req[i] = dcerpc_netr_LogonGetDomainInfo_r_send(tctx, tctx->ev, p->binding_handle, &r);
3681 /* even with this flush per request a w2k3 server seems to
3682 clag with multiple outstanding requests. bleergh. */
3683 torture_assert_int_equal(tctx, tevent_loop_once(dcerpc_event_context(p)), 0,
3684 "tevent_loop_once failed");
3687 for (i=0;i<ASYNC_COUNT;i++) {
3688 torture_assert_int_equal(tctx, tevent_req_poll(req[i], tctx->ev), true,
3689 "tevent_req_poll() failed");
3691 status = dcerpc_netr_LogonGetDomainInfo_r_recv(req[i], tctx);
3693 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
3694 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
3696 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred),
3697 "Credential chaining failed at async");
3700 torture_comment(tctx,
3701 "Testing netr_LogonGetDomainInfo - async count %d OK\n", ASYNC_COUNT);
3703 return true;
3706 static bool test_ManyGetDCName(struct torture_context *tctx,
3707 struct dcerpc_pipe *p)
3709 NTSTATUS status;
3710 struct dcerpc_pipe *p2;
3711 struct lsa_ObjectAttribute attr;
3712 struct lsa_QosInfo qos;
3713 struct lsa_OpenPolicy2 o;
3714 struct policy_handle lsa_handle;
3715 struct lsa_DomainList domains;
3717 struct lsa_EnumTrustDom t;
3718 uint32_t resume_handle = 0;
3719 struct netr_GetAnyDCName d;
3720 const char *dcname = NULL;
3721 struct dcerpc_binding_handle *b = p->binding_handle;
3722 struct dcerpc_binding_handle *b2;
3724 int i;
3726 if (p->conn->transport.transport != NCACN_NP) {
3727 return true;
3730 torture_comment(tctx, "Torturing GetDCName\n");
3732 status = dcerpc_secondary_connection(p, &p2, p->binding);
3733 torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
3735 status = dcerpc_bind_auth_none(p2, &ndr_table_lsarpc);
3736 torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
3737 b2 = p2->binding_handle;
3739 qos.len = 0;
3740 qos.impersonation_level = 2;
3741 qos.context_mode = 1;
3742 qos.effective_only = 0;
3744 attr.len = 0;
3745 attr.root_dir = NULL;
3746 attr.object_name = NULL;
3747 attr.attributes = 0;
3748 attr.sec_desc = NULL;
3749 attr.sec_qos = &qos;
3751 o.in.system_name = "\\";
3752 o.in.attr = &attr;
3753 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3754 o.out.handle = &lsa_handle;
3756 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
3757 "OpenPolicy2 failed");
3758 torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
3760 t.in.handle = &lsa_handle;
3761 t.in.resume_handle = &resume_handle;
3762 t.in.max_size = 1000;
3763 t.out.domains = &domains;
3764 t.out.resume_handle = &resume_handle;
3766 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b2, tctx, &t),
3767 "EnumTrustDom failed");
3769 if ((!NT_STATUS_IS_OK(t.out.result) &&
3770 (!NT_STATUS_EQUAL(t.out.result, NT_STATUS_NO_MORE_ENTRIES))))
3771 torture_fail(tctx, "Could not list domains");
3773 talloc_free(p2);
3775 d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
3776 dcerpc_server_name(p));
3777 d.out.dcname = &dcname;
3779 for (i=0; i<domains.count * 4; i++) {
3780 struct lsa_DomainInfo *info =
3781 &domains.domains[rand()%domains.count];
3783 d.in.domainname = info->name.string;
3785 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &d);
3786 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3788 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
3789 dcname ? dcname : "unknown");
3792 return true;
3795 static bool test_SetPassword_with_flags(struct torture_context *tctx,
3796 struct dcerpc_pipe *p,
3797 struct cli_credentials *machine_credentials)
3799 uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
3800 struct netlogon_creds_CredentialState *creds;
3801 int i;
3803 if (!test_SetupCredentials2(p, tctx, 0,
3804 machine_credentials,
3805 cli_credentials_get_secure_channel_type(machine_credentials),
3806 &creds)) {
3807 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
3810 for (i=0; i < ARRAY_SIZE(flags); i++) {
3811 torture_assert(tctx,
3812 test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
3813 talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
3816 return true;
3819 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
3821 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon");
3822 struct torture_rpc_tcase *tcase;
3823 struct torture_test *test;
3825 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3826 &ndr_table_netlogon, TEST_MACHINE_NAME);
3828 torture_rpc_tcase_add_test(tcase, "Broken RPC binding handle",
3829 test_netr_broken_binding_handle);
3831 torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
3832 torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
3833 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
3834 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
3835 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
3836 torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
3837 torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
3838 torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
3839 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
3840 torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
3841 torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
3842 torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
3843 torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
3844 torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
3845 torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
3846 torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
3847 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
3848 torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
3849 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
3850 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
3851 test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
3852 test->dangerous = true;
3853 torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
3854 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
3855 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
3856 torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
3857 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
3858 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
3859 torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
3860 torture_rpc_tcase_add_test_creds(tcase, "GetForestTrustInformation", test_netr_GetForestTrustInformation);
3862 return suite;
3865 struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
3867 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon-s3");
3868 struct torture_rpc_tcase *tcase;
3870 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3871 &ndr_table_netlogon, TEST_MACHINE_NAME);
3873 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
3874 torture_rpc_tcase_add_test_creds(tcase, "SamLogon_NULL_domain", test_SamLogon_NULL_domain);
3875 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
3876 torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
3877 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
3878 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
3880 return suite;
3883 struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
3885 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon.admin");
3886 struct torture_rpc_tcase *tcase;
3888 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3889 &ndr_table_netlogon, TEST_MACHINE_NAME);
3890 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3891 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3892 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3894 tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netlogon",
3895 &ndr_table_netlogon, TEST_MACHINE_NAME);
3896 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3897 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3898 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3900 tcase = torture_suite_add_rpc_iface_tcase(suite, "netlogon",
3901 &ndr_table_netlogon);
3902 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3903 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3904 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3906 return suite;