docs: man smbtorture: Add missing meta data.
[Samba/gebeck_regimport.git] / source4 / torture / rpc / netlogon.c
blobd217db20c83c6c51816071b759e9c56ab286d749
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(struct torture_context *tctx,
510 struct dcerpc_pipe *p,
511 struct cli_credentials *machine_credentials)
513 struct netr_ServerPasswordSet2 r;
514 const char *password;
515 DATA_BLOB new_random_pass;
516 struct netlogon_creds_CredentialState *creds;
517 struct samr_CryptPassword password_buf;
518 struct samr_Password nt_hash;
519 struct netr_Authenticator credential, return_authenticator;
520 struct netr_CryptPassword new_password;
521 struct dcerpc_binding_handle *b = p->binding_handle;
523 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
524 return false;
527 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
528 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
529 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
530 r.in.computer_name = TEST_MACHINE_NAME;
531 r.in.credential = &credential;
532 r.in.new_password = &new_password;
533 r.out.return_authenticator = &return_authenticator;
535 password = generate_random_password(tctx, 8, 255);
536 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
537 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
539 memcpy(new_password.data, password_buf.data, 512);
540 new_password.length = IVAL(password_buf.data, 512);
542 torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
543 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
545 netlogon_creds_client_authenticator(creds, &credential);
547 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
548 "ServerPasswordSet2 failed");
549 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
551 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
552 torture_comment(tctx, "Credential chaining failed\n");
555 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
557 if (!torture_setting_bool(tctx, "dangerous", false)) {
558 torture_comment(tctx,
559 "Not testing ability to set password to '', enable dangerous tests to perform this test\n");
560 } else {
561 /* by changing the machine password to ""
562 * we check if the server uses password restrictions
563 * for ServerPasswordSet2
564 * (win2k3 accepts "")
566 password = "";
567 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
568 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
570 memcpy(new_password.data, password_buf.data, 512);
571 new_password.length = IVAL(password_buf.data, 512);
573 torture_comment(tctx,
574 "Testing ServerPasswordSet2 on machine account\n");
575 torture_comment(tctx,
576 "Changing machine account password to '%s'\n", password);
578 netlogon_creds_client_authenticator(creds, &credential);
580 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
581 "ServerPasswordSet2 failed");
582 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
584 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
585 torture_comment(tctx, "Credential chaining failed\n");
588 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
591 torture_assert(tctx, test_SetupCredentials(p, tctx, machine_credentials, &creds),
592 "ServerPasswordSet failed to actually change the password");
594 /* now try a random password */
595 password = generate_random_password(tctx, 8, 255);
596 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
597 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
599 memcpy(new_password.data, password_buf.data, 512);
600 new_password.length = IVAL(password_buf.data, 512);
602 torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
603 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
605 netlogon_creds_client_authenticator(creds, &credential);
607 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
608 "ServerPasswordSet2 (2) failed");
609 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 (2) failed");
611 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
612 torture_comment(tctx, "Credential chaining failed\n");
615 /* by changing the machine password twice we test the
616 credentials chaining fully, and we verify that the server
617 allows the password to be set to the same value twice in a
618 row (match win2k3) */
619 torture_comment(tctx,
620 "Testing a second ServerPasswordSet2 on machine account\n");
621 torture_comment(tctx,
622 "Changing machine account password to '%s' (same as previous run)\n", password);
624 netlogon_creds_client_authenticator(creds, &credential);
626 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
627 "ServerPasswordSet (3) failed");
628 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
630 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
631 torture_comment(tctx, "Credential chaining failed\n");
634 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
636 torture_assert (tctx,
637 test_SetupCredentials(p, tctx, machine_credentials, &creds),
638 "ServerPasswordSet failed to actually change the password");
640 new_random_pass = netlogon_very_rand_pass(tctx, 128);
642 /* now try a random stream of bytes for a password */
643 set_pw_in_buffer(password_buf.data, &new_random_pass);
645 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
647 memcpy(new_password.data, password_buf.data, 512);
648 new_password.length = IVAL(password_buf.data, 512);
650 torture_comment(tctx,
651 "Testing a third ServerPasswordSet2 on machine account, with a completely random password\n");
653 netlogon_creds_client_authenticator(creds, &credential);
655 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
656 "ServerPasswordSet (3) failed");
657 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
659 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
660 torture_comment(tctx, "Credential chaining failed\n");
663 mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
665 cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
666 cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
668 torture_assert (tctx,
669 test_SetupCredentials(p, tctx, machine_credentials, &creds),
670 "ServerPasswordSet failed to actually change the password");
672 return true;
675 static bool test_GetPassword(struct torture_context *tctx,
676 struct dcerpc_pipe *p,
677 struct cli_credentials *machine_credentials)
679 struct netr_ServerPasswordGet r;
680 struct netlogon_creds_CredentialState *creds;
681 struct netr_Authenticator credential;
682 NTSTATUS status;
683 struct netr_Authenticator return_authenticator;
684 struct samr_Password password;
685 struct dcerpc_binding_handle *b = p->binding_handle;
687 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
688 return false;
691 netlogon_creds_client_authenticator(creds, &credential);
693 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
694 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
695 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
696 r.in.computer_name = TEST_MACHINE_NAME;
697 r.in.credential = &credential;
698 r.out.return_authenticator = &return_authenticator;
699 r.out.password = &password;
701 status = dcerpc_netr_ServerPasswordGet_r(b, tctx, &r);
702 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
704 return true;
707 static bool test_GetTrustPasswords(struct torture_context *tctx,
708 struct dcerpc_pipe *p,
709 struct cli_credentials *machine_credentials)
711 struct netr_ServerTrustPasswordsGet r;
712 struct netlogon_creds_CredentialState *creds;
713 struct netr_Authenticator credential;
714 struct netr_Authenticator return_authenticator;
715 struct samr_Password password, password2;
716 struct dcerpc_binding_handle *b = p->binding_handle;
718 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
719 return false;
722 netlogon_creds_client_authenticator(creds, &credential);
724 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
725 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
726 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
727 r.in.computer_name = TEST_MACHINE_NAME;
728 r.in.credential = &credential;
729 r.out.return_authenticator = &return_authenticator;
730 r.out.password = &password;
731 r.out.password2 = &password2;
733 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerTrustPasswordsGet_r(b, tctx, &r),
734 "ServerTrustPasswordsGet failed");
735 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerTrustPasswordsGet failed");
737 return true;
741 try a netlogon SamLogon
743 static bool test_netlogon_ops_args(struct dcerpc_pipe *p, struct torture_context *tctx,
744 struct cli_credentials *credentials,
745 struct netlogon_creds_CredentialState *creds,
746 bool null_domain)
748 NTSTATUS status;
749 struct netr_LogonSamLogon r;
750 struct netr_Authenticator auth, auth2;
751 static const struct netr_Authenticator auth_zero;
752 union netr_LogonLevel logon;
753 union netr_Validation validation;
754 uint8_t authoritative;
755 struct netr_NetworkInfo ninfo;
756 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
757 int i;
758 struct dcerpc_binding_handle *b = p->binding_handle;
759 int flags = CLI_CRED_NTLM_AUTH;
760 if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
761 flags |= CLI_CRED_LANMAN_AUTH;
764 if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx) && !null_domain) {
765 flags |= CLI_CRED_NTLMv2_AUTH;
768 cli_credentials_get_ntlm_username_domain(cmdline_credentials, tctx,
769 &ninfo.identity_info.account_name.string,
770 &ninfo.identity_info.domain_name.string);
772 if (null_domain) {
773 ninfo.identity_info.domain_name.string = NULL;
776 generate_random_buffer(ninfo.challenge,
777 sizeof(ninfo.challenge));
778 chal = data_blob_const(ninfo.challenge,
779 sizeof(ninfo.challenge));
781 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials),
782 cli_credentials_get_domain(credentials));
784 status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx,
785 &flags,
786 chal,
787 names_blob,
788 &lm_resp, &nt_resp,
789 NULL, NULL);
790 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
792 ninfo.lm.data = lm_resp.data;
793 ninfo.lm.length = lm_resp.length;
795 ninfo.nt.data = nt_resp.data;
796 ninfo.nt.length = nt_resp.length;
798 ninfo.identity_info.parameter_control = 0;
799 ninfo.identity_info.logon_id_low = 0;
800 ninfo.identity_info.logon_id_high = 0;
801 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
803 logon.network = &ninfo;
805 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
806 r.in.computer_name = cli_credentials_get_workstation(credentials);
807 r.in.credential = &auth;
808 r.in.return_authenticator = &auth2;
809 r.in.logon_level = 2;
810 r.in.logon = &logon;
811 r.out.validation = &validation;
812 r.out.authoritative = &authoritative;
814 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
816 for (i=2;i<=3;i++) {
817 ZERO_STRUCT(auth2);
818 netlogon_creds_client_authenticator(creds, &auth);
820 r.in.validation_level = i;
822 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
823 "LogonSamLogon failed");
824 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
826 torture_assert(tctx, netlogon_creds_client_check(creds,
827 &r.out.return_authenticator->cred),
828 "Credential chaining failed");
829 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
830 "LogonSamLogon invalid *r.out.authoritative");
833 /* this makes sure we get the unmarshalling right for invalid levels */
834 for (i=52;i<53;i++) {
835 ZERO_STRUCT(auth2);
836 /* the authenticator should be ignored by the server */
837 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
839 r.in.validation_level = i;
841 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
842 "LogonSamLogon failed");
843 torture_assert_ntstatus_equal(tctx, r.out.result,
844 NT_STATUS_INVALID_INFO_CLASS,
845 "LogonSamLogon failed");
847 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
848 "LogonSamLogon invalid *r.out.authoritative");
849 torture_assert(tctx,
850 memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
851 "Return authenticator non zero");
854 for (i=2;i<=3;i++) {
855 ZERO_STRUCT(auth2);
856 netlogon_creds_client_authenticator(creds, &auth);
858 r.in.validation_level = i;
860 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
861 "LogonSamLogon failed");
862 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
864 torture_assert(tctx, netlogon_creds_client_check(creds,
865 &r.out.return_authenticator->cred),
866 "Credential chaining failed");
867 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
868 "LogonSamLogon invalid *r.out.authoritative");
871 r.in.logon_level = 52;
873 for (i=2;i<=3;i++) {
874 ZERO_STRUCT(auth2);
875 /* the authenticator should be ignored by the server */
876 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
878 r.in.validation_level = i;
880 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
882 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
883 "LogonSamLogon failed");
884 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
885 "LogonSamLogon expected INVALID_PARAMETER");
887 torture_assert(tctx,
888 memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
889 "Return authenticator non zero");
890 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
891 "LogonSamLogon invalid *r.out.authoritative");
894 r.in.credential = NULL;
896 for (i=2;i<=3;i++) {
897 ZERO_STRUCT(auth2);
899 r.in.validation_level = i;
901 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
903 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
904 "LogonSamLogon failed");
905 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
906 "LogonSamLogon expected INVALID_PARAMETER");
908 torture_assert(tctx,
909 memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
910 "Return authenticator non zero");
911 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
912 "LogonSamLogon invalid *r.out.authoritative");
915 r.in.logon_level = 2;
916 r.in.credential = &auth;
918 for (i=2;i<=3;i++) {
919 ZERO_STRUCT(auth2);
920 netlogon_creds_client_authenticator(creds, &auth);
922 r.in.validation_level = i;
924 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
925 "LogonSamLogon failed");
926 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
928 torture_assert(tctx, netlogon_creds_client_check(creds,
929 &r.out.return_authenticator->cred),
930 "Credential chaining failed");
931 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
932 "LogonSamLogon invalid *r.out.authoritative");
935 return true;
938 bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
939 struct cli_credentials *credentials,
940 struct netlogon_creds_CredentialState *creds)
942 return test_netlogon_ops_args(p, tctx, credentials, creds, false);
946 try a netlogon GetCapabilities
948 bool test_netlogon_capabilities(struct dcerpc_pipe *p, struct torture_context *tctx,
949 struct cli_credentials *credentials,
950 struct netlogon_creds_CredentialState *creds)
952 NTSTATUS status;
953 struct netr_LogonGetCapabilities r;
954 union netr_Capabilities capabilities;
955 struct netr_Authenticator auth, return_auth;
956 struct netlogon_creds_CredentialState tmp_creds;
957 struct dcerpc_binding_handle *b = p->binding_handle;
959 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
960 r.in.computer_name = cli_credentials_get_workstation(credentials);
961 r.in.credential = &auth;
962 r.in.return_authenticator = &return_auth;
963 r.in.query_level = 1;
964 r.out.capabilities = &capabilities;
965 r.out.return_authenticator = &return_auth;
967 torture_comment(tctx, "Testing LogonGetCapabilities\n");
969 ZERO_STRUCT(return_auth);
972 * we need to operate on a temporary copy of creds
973 * because dcerpc_netr_LogonGetCapabilities was
974 * dcerpc_netr_DummyFunction and returns NT_STATUS_NOT_IMPLEMENTED
975 * without looking a the authenticator.
977 tmp_creds = *creds;
978 netlogon_creds_client_authenticator(&tmp_creds, &auth);
980 status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
981 torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities failed");
982 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
983 return true;
986 *creds = tmp_creds;
988 torture_assert(tctx, netlogon_creds_client_check(creds,
989 &r.out.return_authenticator->cred),
990 "Credential chaining failed");
992 torture_assert_int_equal(tctx, creds->negotiate_flags,
993 capabilities.server_capabilities,
994 "negotiate flags");
996 return true;
1000 try a netlogon SamLogon
1002 static bool test_SamLogon(struct torture_context *tctx,
1003 struct dcerpc_pipe *p,
1004 struct cli_credentials *credentials)
1006 struct netlogon_creds_CredentialState *creds;
1008 if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
1009 return false;
1012 return test_netlogon_ops(p, tctx, credentials, creds);
1015 static bool test_SamLogon_NULL_domain(struct torture_context *tctx,
1016 struct dcerpc_pipe *p,
1017 struct cli_credentials *credentials)
1019 struct netlogon_creds_CredentialState *creds;
1021 if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
1022 return false;
1025 return test_netlogon_ops_args(p, tctx, credentials, creds, true);
1028 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
1029 static uint64_t sequence_nums[3];
1032 try a netlogon DatabaseSync
1034 static bool test_DatabaseSync(struct torture_context *tctx,
1035 struct dcerpc_pipe *p,
1036 struct cli_credentials *machine_credentials)
1038 struct netr_DatabaseSync r;
1039 struct netlogon_creds_CredentialState *creds;
1040 const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
1041 int i;
1042 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1043 struct netr_Authenticator credential, return_authenticator;
1044 struct dcerpc_binding_handle *b = p->binding_handle;
1046 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1047 return false;
1050 ZERO_STRUCT(return_authenticator);
1052 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1053 r.in.computername = TEST_MACHINE_NAME;
1054 r.in.preferredmaximumlength = (uint32_t)-1;
1055 r.in.return_authenticator = &return_authenticator;
1056 r.out.delta_enum_array = &delta_enum_array;
1057 r.out.return_authenticator = &return_authenticator;
1059 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1061 uint32_t sync_context = 0;
1063 r.in.database_id = database_ids[i];
1064 r.in.sync_context = &sync_context;
1065 r.out.sync_context = &sync_context;
1067 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
1069 do {
1070 netlogon_creds_client_authenticator(creds, &credential);
1072 r.in.credential = &credential;
1074 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync_r(b, tctx, &r),
1075 "DatabaseSync failed");
1076 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1077 break;
1079 /* Native mode servers don't do this */
1080 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1081 return true;
1083 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync");
1085 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1086 torture_comment(tctx, "Credential chaining failed\n");
1089 if (delta_enum_array &&
1090 delta_enum_array->num_deltas > 0 &&
1091 delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
1092 delta_enum_array->delta_enum[0].delta_union.domain) {
1093 sequence_nums[r.in.database_id] =
1094 delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
1095 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
1096 r.in.database_id,
1097 (unsigned long long)sequence_nums[r.in.database_id]);
1099 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1102 return true;
1107 try a netlogon DatabaseDeltas
1109 static bool test_DatabaseDeltas(struct torture_context *tctx,
1110 struct dcerpc_pipe *p,
1111 struct cli_credentials *machine_credentials)
1113 struct netr_DatabaseDeltas r;
1114 struct netlogon_creds_CredentialState *creds;
1115 struct netr_Authenticator credential;
1116 struct netr_Authenticator return_authenticator;
1117 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1118 const uint32_t database_ids[] = {0, 1, 2};
1119 int i;
1120 struct dcerpc_binding_handle *b = p->binding_handle;
1122 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1123 return false;
1126 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1127 r.in.computername = TEST_MACHINE_NAME;
1128 r.in.preferredmaximumlength = (uint32_t)-1;
1129 ZERO_STRUCT(r.in.return_authenticator);
1130 r.out.return_authenticator = &return_authenticator;
1131 r.out.delta_enum_array = &delta_enum_array;
1133 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1134 r.in.database_id = database_ids[i];
1135 r.in.sequence_num = &sequence_nums[r.in.database_id];
1137 if (*r.in.sequence_num == 0) continue;
1139 *r.in.sequence_num -= 1;
1141 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n",
1142 r.in.database_id, (unsigned long long)*r.in.sequence_num);
1144 do {
1145 netlogon_creds_client_authenticator(creds, &credential);
1147 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseDeltas_r(b, tctx, &r),
1148 "DatabaseDeltas failed");
1149 if (NT_STATUS_EQUAL(r.out.result,
1150 NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
1151 torture_comment(tctx, "not considering %s to be an error\n",
1152 nt_errstr(r.out.result));
1153 return true;
1155 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1156 break;
1158 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseDeltas");
1160 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1161 torture_comment(tctx, "Credential chaining failed\n");
1164 (*r.in.sequence_num)++;
1165 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1168 return true;
1171 static bool test_DatabaseRedo(struct torture_context *tctx,
1172 struct dcerpc_pipe *p,
1173 struct cli_credentials *machine_credentials)
1175 struct netr_DatabaseRedo r;
1176 struct netlogon_creds_CredentialState *creds;
1177 struct netr_Authenticator credential;
1178 struct netr_Authenticator return_authenticator;
1179 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1180 struct netr_ChangeLogEntry e;
1181 struct dom_sid null_sid, *sid;
1182 int i,d;
1183 struct dcerpc_binding_handle *b = p->binding_handle;
1185 ZERO_STRUCT(null_sid);
1187 sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
1191 struct {
1192 uint32_t rid;
1193 uint16_t flags;
1194 uint8_t db_index;
1195 uint8_t delta_type;
1196 struct dom_sid sid;
1197 const char *name;
1198 NTSTATUS expected_error;
1199 uint32_t expected_num_results;
1200 uint8_t expected_delta_type_1;
1201 uint8_t expected_delta_type_2;
1202 const char *comment;
1203 } changes[] = {
1205 /* SAM_DATABASE_DOMAIN */
1208 .rid = 0,
1209 .flags = 0,
1210 .db_index = SAM_DATABASE_DOMAIN,
1211 .delta_type = NETR_DELTA_MODIFY_COUNT,
1212 .sid = null_sid,
1213 .name = NULL,
1214 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1215 .expected_num_results = 0,
1216 .comment = "NETR_DELTA_MODIFY_COUNT"
1219 .rid = 0,
1220 .flags = 0,
1221 .db_index = SAM_DATABASE_DOMAIN,
1222 .delta_type = 0,
1223 .sid = null_sid,
1224 .name = NULL,
1225 .expected_error = NT_STATUS_OK,
1226 .expected_num_results = 1,
1227 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1228 .comment = "NULL DELTA"
1231 .rid = 0,
1232 .flags = 0,
1233 .db_index = SAM_DATABASE_DOMAIN,
1234 .delta_type = NETR_DELTA_DOMAIN,
1235 .sid = null_sid,
1236 .name = NULL,
1237 .expected_error = NT_STATUS_OK,
1238 .expected_num_results = 1,
1239 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1240 .comment = "NETR_DELTA_DOMAIN"
1243 .rid = DOMAIN_RID_ADMINISTRATOR,
1244 .flags = 0,
1245 .db_index = SAM_DATABASE_DOMAIN,
1246 .delta_type = NETR_DELTA_USER,
1247 .sid = null_sid,
1248 .name = NULL,
1249 .expected_error = NT_STATUS_OK,
1250 .expected_num_results = 1,
1251 .expected_delta_type_1 = NETR_DELTA_USER,
1252 .comment = "NETR_DELTA_USER by rid 500"
1255 .rid = DOMAIN_RID_GUEST,
1256 .flags = 0,
1257 .db_index = SAM_DATABASE_DOMAIN,
1258 .delta_type = NETR_DELTA_USER,
1259 .sid = null_sid,
1260 .name = NULL,
1261 .expected_error = NT_STATUS_OK,
1262 .expected_num_results = 1,
1263 .expected_delta_type_1 = NETR_DELTA_USER,
1264 .comment = "NETR_DELTA_USER by rid 501"
1267 .rid = 0,
1268 .flags = NETR_CHANGELOG_SID_INCLUDED,
1269 .db_index = SAM_DATABASE_DOMAIN,
1270 .delta_type = NETR_DELTA_USER,
1271 .sid = *sid,
1272 .name = NULL,
1273 .expected_error = NT_STATUS_OK,
1274 .expected_num_results = 1,
1275 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1276 .comment = "NETR_DELTA_USER by sid and flags"
1279 .rid = 0,
1280 .flags = NETR_CHANGELOG_SID_INCLUDED,
1281 .db_index = SAM_DATABASE_DOMAIN,
1282 .delta_type = NETR_DELTA_USER,
1283 .sid = null_sid,
1284 .name = NULL,
1285 .expected_error = NT_STATUS_OK,
1286 .expected_num_results = 1,
1287 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1288 .comment = "NETR_DELTA_USER by null_sid and flags"
1291 .rid = 0,
1292 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1293 .db_index = SAM_DATABASE_DOMAIN,
1294 .delta_type = NETR_DELTA_USER,
1295 .sid = null_sid,
1296 .name = "administrator",
1297 .expected_error = NT_STATUS_OK,
1298 .expected_num_results = 1,
1299 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1300 .comment = "NETR_DELTA_USER by name 'administrator'"
1303 .rid = DOMAIN_RID_ADMINS,
1304 .flags = 0,
1305 .db_index = SAM_DATABASE_DOMAIN,
1306 .delta_type = NETR_DELTA_GROUP,
1307 .sid = null_sid,
1308 .name = NULL,
1309 .expected_error = NT_STATUS_OK,
1310 .expected_num_results = 2,
1311 .expected_delta_type_1 = NETR_DELTA_GROUP,
1312 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
1313 .comment = "NETR_DELTA_GROUP by rid 512"
1316 .rid = DOMAIN_RID_ADMINS,
1317 .flags = 0,
1318 .db_index = SAM_DATABASE_DOMAIN,
1319 .delta_type = NETR_DELTA_GROUP_MEMBER,
1320 .sid = null_sid,
1321 .name = NULL,
1322 .expected_error = NT_STATUS_OK,
1323 .expected_num_results = 2,
1324 .expected_delta_type_1 = NETR_DELTA_GROUP,
1325 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
1326 .comment = "NETR_DELTA_GROUP_MEMBER by rid 512"
1330 /* SAM_DATABASE_BUILTIN */
1333 .rid = 0,
1334 .flags = 0,
1335 .db_index = SAM_DATABASE_BUILTIN,
1336 .delta_type = NETR_DELTA_MODIFY_COUNT,
1337 .sid = null_sid,
1338 .name = NULL,
1339 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1340 .expected_num_results = 0,
1341 .comment = "NETR_DELTA_MODIFY_COUNT"
1344 .rid = 0,
1345 .flags = 0,
1346 .db_index = SAM_DATABASE_BUILTIN,
1347 .delta_type = NETR_DELTA_DOMAIN,
1348 .sid = null_sid,
1349 .name = NULL,
1350 .expected_error = NT_STATUS_OK,
1351 .expected_num_results = 1,
1352 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1353 .comment = "NETR_DELTA_DOMAIN"
1356 .rid = DOMAIN_RID_ADMINISTRATOR,
1357 .flags = 0,
1358 .db_index = SAM_DATABASE_BUILTIN,
1359 .delta_type = NETR_DELTA_USER,
1360 .sid = null_sid,
1361 .name = NULL,
1362 .expected_error = NT_STATUS_OK,
1363 .expected_num_results = 1,
1364 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1365 .comment = "NETR_DELTA_USER by rid 500"
1368 .rid = 0,
1369 .flags = 0,
1370 .db_index = SAM_DATABASE_BUILTIN,
1371 .delta_type = NETR_DELTA_USER,
1372 .sid = null_sid,
1373 .name = NULL,
1374 .expected_error = NT_STATUS_OK,
1375 .expected_num_results = 1,
1376 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1377 .comment = "NETR_DELTA_USER"
1380 .rid = 544,
1381 .flags = 0,
1382 .db_index = SAM_DATABASE_BUILTIN,
1383 .delta_type = NETR_DELTA_ALIAS,
1384 .sid = null_sid,
1385 .name = NULL,
1386 .expected_error = NT_STATUS_OK,
1387 .expected_num_results = 2,
1388 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1389 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1390 .comment = "NETR_DELTA_ALIAS by rid 544"
1393 .rid = 544,
1394 .flags = 0,
1395 .db_index = SAM_DATABASE_BUILTIN,
1396 .delta_type = NETR_DELTA_ALIAS_MEMBER,
1397 .sid = null_sid,
1398 .name = NULL,
1399 .expected_error = NT_STATUS_OK,
1400 .expected_num_results = 2,
1401 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1402 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1403 .comment = "NETR_DELTA_ALIAS_MEMBER by rid 544"
1406 .rid = 544,
1407 .flags = 0,
1408 .db_index = SAM_DATABASE_BUILTIN,
1409 .delta_type = 0,
1410 .sid = null_sid,
1411 .name = NULL,
1412 .expected_error = NT_STATUS_OK,
1413 .expected_num_results = 1,
1414 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1415 .comment = "NULL DELTA by rid 544"
1418 .rid = 544,
1419 .flags = NETR_CHANGELOG_SID_INCLUDED,
1420 .db_index = SAM_DATABASE_BUILTIN,
1421 .delta_type = 0,
1422 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1423 .name = NULL,
1424 .expected_error = NT_STATUS_OK,
1425 .expected_num_results = 1,
1426 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1427 .comment = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
1430 .rid = 544,
1431 .flags = NETR_CHANGELOG_SID_INCLUDED,
1432 .db_index = SAM_DATABASE_BUILTIN,
1433 .delta_type = NETR_DELTA_ALIAS,
1434 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1435 .name = NULL,
1436 .expected_error = NT_STATUS_OK,
1437 .expected_num_results = 2,
1438 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1439 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1440 .comment = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
1443 .rid = 0,
1444 .flags = NETR_CHANGELOG_SID_INCLUDED,
1445 .db_index = SAM_DATABASE_BUILTIN,
1446 .delta_type = NETR_DELTA_ALIAS,
1447 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1448 .name = NULL,
1449 .expected_error = NT_STATUS_OK,
1450 .expected_num_results = 1,
1451 .expected_delta_type_1 = NETR_DELTA_DELETE_ALIAS,
1452 .comment = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
1455 /* SAM_DATABASE_PRIVS */
1458 .rid = 0,
1459 .flags = 0,
1460 .db_index = SAM_DATABASE_PRIVS,
1461 .delta_type = 0,
1462 .sid = null_sid,
1463 .name = NULL,
1464 .expected_error = NT_STATUS_ACCESS_DENIED,
1465 .expected_num_results = 0,
1466 .comment = "NULL DELTA"
1469 .rid = 0,
1470 .flags = 0,
1471 .db_index = SAM_DATABASE_PRIVS,
1472 .delta_type = NETR_DELTA_MODIFY_COUNT,
1473 .sid = null_sid,
1474 .name = NULL,
1475 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1476 .expected_num_results = 0,
1477 .comment = "NETR_DELTA_MODIFY_COUNT"
1480 .rid = 0,
1481 .flags = 0,
1482 .db_index = SAM_DATABASE_PRIVS,
1483 .delta_type = NETR_DELTA_POLICY,
1484 .sid = null_sid,
1485 .name = NULL,
1486 .expected_error = NT_STATUS_OK,
1487 .expected_num_results = 1,
1488 .expected_delta_type_1 = NETR_DELTA_POLICY,
1489 .comment = "NETR_DELTA_POLICY"
1492 .rid = 0,
1493 .flags = NETR_CHANGELOG_SID_INCLUDED,
1494 .db_index = SAM_DATABASE_PRIVS,
1495 .delta_type = NETR_DELTA_POLICY,
1496 .sid = null_sid,
1497 .name = NULL,
1498 .expected_error = NT_STATUS_OK,
1499 .expected_num_results = 1,
1500 .expected_delta_type_1 = NETR_DELTA_POLICY,
1501 .comment = "NETR_DELTA_POLICY by null sid and flags"
1504 .rid = 0,
1505 .flags = NETR_CHANGELOG_SID_INCLUDED,
1506 .db_index = SAM_DATABASE_PRIVS,
1507 .delta_type = NETR_DELTA_POLICY,
1508 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
1509 .name = NULL,
1510 .expected_error = NT_STATUS_OK,
1511 .expected_num_results = 1,
1512 .expected_delta_type_1 = NETR_DELTA_POLICY,
1513 .comment = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
1516 .rid = DOMAIN_RID_ADMINISTRATOR,
1517 .flags = 0,
1518 .db_index = SAM_DATABASE_PRIVS,
1519 .delta_type = NETR_DELTA_ACCOUNT,
1520 .sid = null_sid,
1521 .name = NULL,
1522 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
1523 .expected_num_results = 0,
1524 .comment = "NETR_DELTA_ACCOUNT by rid 500"
1527 .rid = 0,
1528 .flags = NETR_CHANGELOG_SID_INCLUDED,
1529 .db_index = SAM_DATABASE_PRIVS,
1530 .delta_type = NETR_DELTA_ACCOUNT,
1531 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1532 .name = NULL,
1533 .expected_error = NT_STATUS_OK,
1534 .expected_num_results = 1,
1535 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
1536 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
1539 .rid = 0,
1540 .flags = NETR_CHANGELOG_SID_INCLUDED |
1541 NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
1542 .db_index = SAM_DATABASE_PRIVS,
1543 .delta_type = NETR_DELTA_ACCOUNT,
1544 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1545 .name = NULL,
1546 .expected_error = NT_STATUS_OK,
1547 .expected_num_results = 1,
1548 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
1549 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
1552 .rid = 0,
1553 .flags = NETR_CHANGELOG_SID_INCLUDED |
1554 NETR_CHANGELOG_NAME_INCLUDED,
1555 .db_index = SAM_DATABASE_PRIVS,
1556 .delta_type = NETR_DELTA_ACCOUNT,
1557 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1558 .name = NULL,
1559 .expected_error = NT_STATUS_INVALID_PARAMETER,
1560 .expected_num_results = 0,
1561 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
1564 .rid = DOMAIN_RID_ADMINISTRATOR,
1565 .flags = NETR_CHANGELOG_SID_INCLUDED,
1566 .db_index = SAM_DATABASE_PRIVS,
1567 .delta_type = NETR_DELTA_ACCOUNT,
1568 .sid = *sid,
1569 .name = NULL,
1570 .expected_error = NT_STATUS_OK,
1571 .expected_num_results = 1,
1572 .expected_delta_type_1 = NETR_DELTA_DELETE_ACCOUNT,
1573 .comment = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
1576 .rid = 0,
1577 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1578 .db_index = SAM_DATABASE_PRIVS,
1579 .delta_type = NETR_DELTA_SECRET,
1580 .sid = null_sid,
1581 .name = "IsurelydontexistIhope",
1582 .expected_error = NT_STATUS_OK,
1583 .expected_num_results = 1,
1584 .expected_delta_type_1 = NETR_DELTA_DELETE_SECRET,
1585 .comment = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
1588 .rid = 0,
1589 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1590 .db_index = SAM_DATABASE_PRIVS,
1591 .delta_type = NETR_DELTA_SECRET,
1592 .sid = null_sid,
1593 .name = "G$BCKUPKEY_P",
1594 .expected_error = NT_STATUS_OK,
1595 .expected_num_results = 1,
1596 .expected_delta_type_1 = NETR_DELTA_SECRET,
1597 .comment = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
1601 ZERO_STRUCT(return_authenticator);
1603 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1604 r.in.computername = TEST_MACHINE_NAME;
1605 r.in.return_authenticator = &return_authenticator;
1606 r.out.return_authenticator = &return_authenticator;
1607 r.out.delta_enum_array = &delta_enum_array;
1609 for (d=0; d<3; d++) {
1610 const char *database = NULL;
1612 switch (d) {
1613 case 0:
1614 database = "SAM";
1615 break;
1616 case 1:
1617 database = "BUILTIN";
1618 break;
1619 case 2:
1620 database = "LSA";
1621 break;
1622 default:
1623 break;
1626 torture_comment(tctx, "Testing DatabaseRedo\n");
1628 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1629 return false;
1632 for (i=0;i<ARRAY_SIZE(changes);i++) {
1634 if (d != changes[i].db_index) {
1635 continue;
1638 netlogon_creds_client_authenticator(creds, &credential);
1640 r.in.credential = &credential;
1642 e.serial_number1 = 0;
1643 e.serial_number2 = 0;
1644 e.object_rid = changes[i].rid;
1645 e.flags = changes[i].flags;
1646 e.db_index = changes[i].db_index;
1647 e.delta_type = changes[i].delta_type;
1649 switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
1650 case NETR_CHANGELOG_SID_INCLUDED:
1651 e.object.object_sid = changes[i].sid;
1652 break;
1653 case NETR_CHANGELOG_NAME_INCLUDED:
1654 e.object.object_name = changes[i].name;
1655 break;
1656 default:
1657 break;
1660 r.in.change_log_entry = e;
1662 torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
1663 database, changes[i].comment);
1665 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseRedo_r(b, tctx, &r),
1666 "DatabaseRedo failed");
1667 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1668 return true;
1671 torture_assert_ntstatus_equal(tctx, r.out.result, changes[i].expected_error, changes[i].comment);
1672 if (delta_enum_array) {
1673 torture_assert_int_equal(tctx,
1674 delta_enum_array->num_deltas,
1675 changes[i].expected_num_results,
1676 changes[i].comment);
1677 if (delta_enum_array->num_deltas > 0) {
1678 torture_assert_int_equal(tctx,
1679 delta_enum_array->delta_enum[0].delta_type,
1680 changes[i].expected_delta_type_1,
1681 changes[i].comment);
1683 if (delta_enum_array->num_deltas > 1) {
1684 torture_assert_int_equal(tctx,
1685 delta_enum_array->delta_enum[1].delta_type,
1686 changes[i].expected_delta_type_2,
1687 changes[i].comment);
1691 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1692 torture_comment(tctx, "Credential chaining failed\n");
1693 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1694 return false;
1701 return true;
1705 try a netlogon AccountDeltas
1707 static bool test_AccountDeltas(struct torture_context *tctx,
1708 struct dcerpc_pipe *p,
1709 struct cli_credentials *machine_credentials)
1711 struct netr_AccountDeltas r;
1712 struct netlogon_creds_CredentialState *creds;
1714 struct netr_AccountBuffer buffer;
1715 uint32_t count_returned = 0;
1716 uint32_t total_entries = 0;
1717 struct netr_UAS_INFO_0 recordid;
1718 struct netr_Authenticator return_authenticator;
1719 struct dcerpc_binding_handle *b = p->binding_handle;
1721 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1722 return false;
1725 ZERO_STRUCT(return_authenticator);
1727 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1728 r.in.computername = TEST_MACHINE_NAME;
1729 r.in.return_authenticator = &return_authenticator;
1730 netlogon_creds_client_authenticator(creds, &r.in.credential);
1731 ZERO_STRUCT(r.in.uas);
1732 r.in.count=10;
1733 r.in.level=0;
1734 r.in.buffersize=100;
1735 r.out.buffer = &buffer;
1736 r.out.count_returned = &count_returned;
1737 r.out.total_entries = &total_entries;
1738 r.out.recordid = &recordid;
1739 r.out.return_authenticator = &return_authenticator;
1741 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1742 torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountDeltas_r(b, tctx, &r),
1743 "AccountDeltas failed");
1744 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
1746 return true;
1750 try a netlogon AccountSync
1752 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
1753 struct cli_credentials *machine_credentials)
1755 struct netr_AccountSync r;
1756 struct netlogon_creds_CredentialState *creds;
1758 struct netr_AccountBuffer buffer;
1759 uint32_t count_returned = 0;
1760 uint32_t total_entries = 0;
1761 uint32_t next_reference = 0;
1762 struct netr_UAS_INFO_0 recordid;
1763 struct netr_Authenticator return_authenticator;
1764 struct dcerpc_binding_handle *b = p->binding_handle;
1766 ZERO_STRUCT(recordid);
1767 ZERO_STRUCT(return_authenticator);
1769 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1770 return false;
1773 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1774 r.in.computername = TEST_MACHINE_NAME;
1775 r.in.return_authenticator = &return_authenticator;
1776 netlogon_creds_client_authenticator(creds, &r.in.credential);
1777 r.in.recordid = &recordid;
1778 r.in.reference=0;
1779 r.in.level=0;
1780 r.in.buffersize=100;
1781 r.out.buffer = &buffer;
1782 r.out.count_returned = &count_returned;
1783 r.out.total_entries = &total_entries;
1784 r.out.next_reference = &next_reference;
1785 r.out.recordid = &recordid;
1786 r.out.return_authenticator = &return_authenticator;
1788 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1789 torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountSync_r(b, tctx, &r),
1790 "AccountSync failed");
1791 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
1793 return true;
1797 try a netlogon GetDcName
1799 static bool test_GetDcName(struct torture_context *tctx,
1800 struct dcerpc_pipe *p)
1802 struct netr_GetDcName r;
1803 const char *dcname = NULL;
1804 struct dcerpc_binding_handle *b = p->binding_handle;
1806 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1807 r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
1808 r.out.dcname = &dcname;
1810 torture_assert_ntstatus_ok(tctx, dcerpc_netr_GetDcName_r(b, tctx, &r),
1811 "GetDcName failed");
1812 torture_assert_werr_ok(tctx, r.out.result, "GetDcName failed");
1814 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1816 return true;
1819 static const char *function_code_str(TALLOC_CTX *mem_ctx,
1820 enum netr_LogonControlCode function_code)
1822 switch (function_code) {
1823 case NETLOGON_CONTROL_QUERY:
1824 return "NETLOGON_CONTROL_QUERY";
1825 case NETLOGON_CONTROL_REPLICATE:
1826 return "NETLOGON_CONTROL_REPLICATE";
1827 case NETLOGON_CONTROL_SYNCHRONIZE:
1828 return "NETLOGON_CONTROL_SYNCHRONIZE";
1829 case NETLOGON_CONTROL_PDC_REPLICATE:
1830 return "NETLOGON_CONTROL_PDC_REPLICATE";
1831 case NETLOGON_CONTROL_REDISCOVER:
1832 return "NETLOGON_CONTROL_REDISCOVER";
1833 case NETLOGON_CONTROL_TC_QUERY:
1834 return "NETLOGON_CONTROL_TC_QUERY";
1835 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1836 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
1837 case NETLOGON_CONTROL_FIND_USER:
1838 return "NETLOGON_CONTROL_FIND_USER";
1839 case NETLOGON_CONTROL_CHANGE_PASSWORD:
1840 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
1841 case NETLOGON_CONTROL_TC_VERIFY:
1842 return "NETLOGON_CONTROL_TC_VERIFY";
1843 case NETLOGON_CONTROL_FORCE_DNS_REG:
1844 return "NETLOGON_CONTROL_FORCE_DNS_REG";
1845 case NETLOGON_CONTROL_QUERY_DNS_REG:
1846 return "NETLOGON_CONTROL_QUERY_DNS_REG";
1847 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1848 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
1849 case NETLOGON_CONTROL_TRUNCATE_LOG:
1850 return "NETLOGON_CONTROL_TRUNCATE_LOG";
1851 case NETLOGON_CONTROL_SET_DBFLAG:
1852 return "NETLOGON_CONTROL_SET_DBFLAG";
1853 case NETLOGON_CONTROL_BREAKPOINT:
1854 return "NETLOGON_CONTROL_BREAKPOINT";
1855 default:
1856 return talloc_asprintf(mem_ctx, "unknown function code: %d",
1857 function_code);
1863 try a netlogon LogonControl
1865 static bool test_LogonControl(struct torture_context *tctx,
1866 struct dcerpc_pipe *p,
1867 struct cli_credentials *machine_credentials)
1870 NTSTATUS status;
1871 struct netr_LogonControl r;
1872 union netr_CONTROL_QUERY_INFORMATION query;
1873 int i,f;
1874 enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
1875 struct dcerpc_binding_handle *b = p->binding_handle;
1877 uint32_t function_codes[] = {
1878 NETLOGON_CONTROL_QUERY,
1879 NETLOGON_CONTROL_REPLICATE,
1880 NETLOGON_CONTROL_SYNCHRONIZE,
1881 NETLOGON_CONTROL_PDC_REPLICATE,
1882 NETLOGON_CONTROL_REDISCOVER,
1883 NETLOGON_CONTROL_TC_QUERY,
1884 NETLOGON_CONTROL_TRANSPORT_NOTIFY,
1885 NETLOGON_CONTROL_FIND_USER,
1886 NETLOGON_CONTROL_CHANGE_PASSWORD,
1887 NETLOGON_CONTROL_TC_VERIFY,
1888 NETLOGON_CONTROL_FORCE_DNS_REG,
1889 NETLOGON_CONTROL_QUERY_DNS_REG,
1890 NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
1891 NETLOGON_CONTROL_TRUNCATE_LOG,
1892 NETLOGON_CONTROL_SET_DBFLAG,
1893 NETLOGON_CONTROL_BREAKPOINT
1896 if (machine_credentials) {
1897 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1900 torture_comment(tctx, "Testing LogonControl with secure channel type: %d\n",
1901 secure_channel_type);
1903 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1904 r.in.function_code = 1;
1905 r.out.query = &query;
1907 for (f=0;f<ARRAY_SIZE(function_codes); f++) {
1908 for (i=1;i<5;i++) {
1910 r.in.function_code = function_codes[f];
1911 r.in.level = i;
1913 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
1914 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1916 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
1917 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1919 switch (r.in.level) {
1920 case 1:
1921 switch (r.in.function_code) {
1922 case NETLOGON_CONTROL_REPLICATE:
1923 case NETLOGON_CONTROL_SYNCHRONIZE:
1924 case NETLOGON_CONTROL_PDC_REPLICATE:
1925 case NETLOGON_CONTROL_BREAKPOINT:
1926 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1927 if ((secure_channel_type == SEC_CHAN_BDC) ||
1928 (secure_channel_type == SEC_CHAN_WKSTA)) {
1929 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1930 "LogonControl returned unexpected error code");
1931 } else {
1932 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1933 "LogonControl returned unexpected error code");
1935 break;
1937 case NETLOGON_CONTROL_REDISCOVER:
1938 case NETLOGON_CONTROL_TC_QUERY:
1939 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1940 case NETLOGON_CONTROL_FIND_USER:
1941 case NETLOGON_CONTROL_CHANGE_PASSWORD:
1942 case NETLOGON_CONTROL_TC_VERIFY:
1943 case NETLOGON_CONTROL_FORCE_DNS_REG:
1944 case NETLOGON_CONTROL_QUERY_DNS_REG:
1945 case NETLOGON_CONTROL_SET_DBFLAG:
1946 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1947 "LogonControl returned unexpected error code");
1948 break;
1949 case NETLOGON_CONTROL_TRUNCATE_LOG:
1950 if ((secure_channel_type == SEC_CHAN_BDC) ||
1951 (secure_channel_type == SEC_CHAN_WKSTA)) {
1952 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1953 "LogonControl returned unexpected error code");
1954 } else {
1955 torture_assert_werr_ok(tctx, r.out.result,
1956 "LogonControl returned unexpected result");
1958 break;
1959 default:
1960 torture_assert_werr_ok(tctx, r.out.result,
1961 "LogonControl returned unexpected result");
1962 break;
1964 break;
1965 case 2:
1966 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1967 "LogonControl returned unexpected error code");
1968 break;
1969 default:
1970 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL,
1971 "LogonControl returned unexpected error code");
1972 break;
1977 r.in.level = 52;
1978 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
1979 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1980 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
1981 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1982 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl");
1984 return true;
1989 try a netlogon GetAnyDCName
1991 static bool test_GetAnyDCName(struct torture_context *tctx,
1992 struct dcerpc_pipe *p)
1994 NTSTATUS status;
1995 struct netr_GetAnyDCName r;
1996 const char *dcname = NULL;
1997 struct dcerpc_binding_handle *b = p->binding_handle;
1999 r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
2000 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2001 r.out.dcname = &dcname;
2003 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2004 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2005 if ((!W_ERROR_IS_OK(r.out.result)) &&
2006 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2007 return false;
2010 if (dcname) {
2011 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
2014 r.in.domainname = NULL;
2016 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2017 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2018 if ((!W_ERROR_IS_OK(r.out.result)) &&
2019 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2020 return false;
2023 r.in.domainname = "";
2025 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2026 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2027 if ((!W_ERROR_IS_OK(r.out.result)) &&
2028 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2029 return false;
2032 return true;
2037 try a netlogon LogonControl2
2039 static bool test_LogonControl2(struct torture_context *tctx,
2040 struct dcerpc_pipe *p,
2041 struct cli_credentials *machine_credentials)
2044 NTSTATUS status;
2045 struct netr_LogonControl2 r;
2046 union netr_CONTROL_DATA_INFORMATION data;
2047 union netr_CONTROL_QUERY_INFORMATION query;
2048 int i;
2049 struct dcerpc_binding_handle *b = p->binding_handle;
2051 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2053 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2055 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2056 r.in.data = &data;
2057 r.out.query = &query;
2059 for (i=1;i<4;i++) {
2060 r.in.level = i;
2062 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2063 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2065 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2066 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2069 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2071 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2072 r.in.data = &data;
2074 for (i=1;i<4;i++) {
2075 r.in.level = i;
2077 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2078 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2080 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2081 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2084 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2086 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2087 r.in.data = &data;
2089 for (i=1;i<4;i++) {
2090 r.in.level = i;
2092 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2093 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2095 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2096 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2099 data.debug_level = ~0;
2101 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2102 r.in.data = &data;
2104 for (i=1;i<4;i++) {
2105 r.in.level = i;
2107 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2108 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2110 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2111 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2114 ZERO_STRUCT(data);
2115 r.in.function_code = 52;
2116 r.in.data = &data;
2118 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2119 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2121 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2122 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2123 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "LogonControl2");
2125 data.debug_level = ~0;
2127 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2128 r.in.data = &data;
2130 r.in.level = 52;
2131 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2132 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2134 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2135 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2136 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "LogonControl2");
2138 return true;
2142 try a netlogon DatabaseSync2
2144 static bool test_DatabaseSync2(struct torture_context *tctx,
2145 struct dcerpc_pipe *p,
2146 struct cli_credentials *machine_credentials)
2148 struct netr_DatabaseSync2 r;
2149 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2150 struct netr_Authenticator return_authenticator, credential;
2152 struct netlogon_creds_CredentialState *creds;
2153 const uint32_t database_ids[] = {0, 1, 2};
2154 int i;
2155 struct dcerpc_binding_handle *b = p->binding_handle;
2157 if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
2158 machine_credentials,
2159 cli_credentials_get_secure_channel_type(machine_credentials),
2160 &creds)) {
2161 return false;
2164 ZERO_STRUCT(return_authenticator);
2166 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2167 r.in.computername = TEST_MACHINE_NAME;
2168 r.in.preferredmaximumlength = (uint32_t)-1;
2169 r.in.return_authenticator = &return_authenticator;
2170 r.out.return_authenticator = &return_authenticator;
2171 r.out.delta_enum_array = &delta_enum_array;
2173 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2175 uint32_t sync_context = 0;
2177 r.in.database_id = database_ids[i];
2178 r.in.sync_context = &sync_context;
2179 r.out.sync_context = &sync_context;
2180 r.in.restart_state = 0;
2182 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
2184 do {
2185 netlogon_creds_client_authenticator(creds, &credential);
2187 r.in.credential = &credential;
2189 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync2_r(b, tctx, &r),
2190 "DatabaseSync2 failed");
2191 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2192 break;
2194 /* Native mode servers don't do this */
2195 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
2196 return true;
2199 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync2");
2201 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
2202 torture_comment(tctx, "Credential chaining failed\n");
2205 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2208 return true;
2213 try a netlogon LogonControl2Ex
2215 static bool test_LogonControl2Ex(struct torture_context *tctx,
2216 struct dcerpc_pipe *p,
2217 struct cli_credentials *machine_credentials)
2220 NTSTATUS status;
2221 struct netr_LogonControl2Ex r;
2222 union netr_CONTROL_DATA_INFORMATION data;
2223 union netr_CONTROL_QUERY_INFORMATION query;
2224 int i;
2225 struct dcerpc_binding_handle *b = p->binding_handle;
2227 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2229 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2231 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2232 r.in.data = &data;
2233 r.out.query = &query;
2235 for (i=1;i<4;i++) {
2236 r.in.level = i;
2238 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2239 i, r.in.function_code);
2241 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2242 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2245 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2247 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2248 r.in.data = &data;
2250 for (i=1;i<4;i++) {
2251 r.in.level = i;
2253 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2254 i, r.in.function_code);
2256 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2257 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2260 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2262 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2263 r.in.data = &data;
2265 for (i=1;i<4;i++) {
2266 r.in.level = i;
2268 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2269 i, r.in.function_code);
2271 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2272 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2275 data.debug_level = ~0;
2277 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2278 r.in.data = &data;
2280 for (i=1;i<4;i++) {
2281 r.in.level = i;
2283 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2284 i, r.in.function_code);
2286 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2287 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2290 return true;
2293 static bool test_netr_GetForestTrustInformation(struct torture_context *tctx,
2294 struct dcerpc_pipe *p,
2295 struct cli_credentials *machine_credentials)
2297 struct netr_GetForestTrustInformation r;
2298 struct netlogon_creds_CredentialState *creds;
2299 struct netr_Authenticator a;
2300 struct netr_Authenticator return_authenticator;
2301 struct lsa_ForestTrustInformation *forest_trust_info;
2302 struct dcerpc_binding_handle *b = p->binding_handle;
2304 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2305 machine_credentials, &creds)) {
2306 return false;
2309 netlogon_creds_client_authenticator(creds, &a);
2311 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2312 r.in.computer_name = TEST_MACHINE_NAME;
2313 r.in.credential = &a;
2314 r.in.flags = 0;
2315 r.out.return_authenticator = &return_authenticator;
2316 r.out.forest_trust_info = &forest_trust_info;
2318 torture_assert_ntstatus_ok(tctx,
2319 dcerpc_netr_GetForestTrustInformation_r(b, tctx, &r),
2320 "netr_GetForestTrustInformation failed");
2321 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2322 torture_comment(tctx, "not considering NT_STATUS_NOT_IMPLEMENTED as an error\n");
2323 } else {
2324 torture_assert_ntstatus_ok(tctx, r.out.result,
2325 "netr_GetForestTrustInformation failed");
2328 torture_assert(tctx,
2329 netlogon_creds_client_check(creds, &return_authenticator.cred),
2330 "Credential chaining failed");
2332 return true;
2335 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
2336 struct dcerpc_pipe *p, const char *trusted_domain_name)
2338 NTSTATUS status;
2339 struct netr_DsRGetForestTrustInformation r;
2340 struct lsa_ForestTrustInformation info, *info_ptr;
2341 struct dcerpc_binding_handle *b = p->binding_handle;
2343 info_ptr = &info;
2345 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2346 r.in.trusted_domain_name = trusted_domain_name;
2347 r.in.flags = 0;
2348 r.out.forest_trust_info = &info_ptr;
2350 torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
2352 status = dcerpc_netr_DsRGetForestTrustInformation_r(b, tctx, &r);
2353 torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
2354 torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
2356 return true;
2360 try a netlogon netr_DsrEnumerateDomainTrusts
2362 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
2363 struct dcerpc_pipe *p)
2365 NTSTATUS status;
2366 struct netr_DsrEnumerateDomainTrusts r;
2367 struct netr_DomainTrustList trusts;
2368 int i;
2369 struct dcerpc_binding_handle *b = p->binding_handle;
2371 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2372 r.in.trust_flags = 0x3f;
2373 r.out.trusts = &trusts;
2375 status = dcerpc_netr_DsrEnumerateDomainTrusts_r(b, tctx, &r);
2376 torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
2377 torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
2379 /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
2380 * will show non-forest trusts and all UPN suffixes of the own forest
2381 * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
2383 if (r.out.trusts->count) {
2384 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
2385 return false;
2389 for (i=0; i<r.out.trusts->count; i++) {
2391 /* get info for transitive forest trusts */
2393 if (r.out.trusts->array[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2394 if (!test_netr_DsRGetForestTrustInformation(tctx, p,
2395 r.out.trusts->array[i].dns_name)) {
2396 return false;
2401 return true;
2404 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
2405 struct dcerpc_pipe *p)
2407 NTSTATUS status;
2408 struct netr_NetrEnumerateTrustedDomains r;
2409 struct netr_Blob trusted_domains_blob;
2410 struct dcerpc_binding_handle *b = p->binding_handle;
2412 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2413 r.out.trusted_domains_blob = &trusted_domains_blob;
2415 status = dcerpc_netr_NetrEnumerateTrustedDomains_r(b, tctx, &r);
2416 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
2417 torture_assert_ntstatus_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
2419 return true;
2422 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
2423 struct dcerpc_pipe *p)
2425 NTSTATUS status;
2426 struct netr_NetrEnumerateTrustedDomainsEx r;
2427 struct netr_DomainTrustList dom_trust_list;
2428 struct dcerpc_binding_handle *b = p->binding_handle;
2430 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2431 r.out.dom_trust_list = &dom_trust_list;
2433 status = dcerpc_netr_NetrEnumerateTrustedDomainsEx_r(b, tctx, &r);
2434 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
2435 torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
2437 return true;
2441 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
2442 const char *computer_name,
2443 const char *expected_site)
2445 NTSTATUS status;
2446 struct netr_DsRGetSiteName r;
2447 const char *site = NULL;
2448 struct dcerpc_binding_handle *b = p->binding_handle;
2450 r.in.computer_name = computer_name;
2451 r.out.site = &site;
2452 torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
2454 status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
2455 torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2456 torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
2457 torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
2459 return true;
2463 try a netlogon netr_DsRGetDCName
2465 static bool test_netr_DsRGetDCName(struct torture_context *tctx,
2466 struct dcerpc_pipe *p)
2468 NTSTATUS status;
2469 struct netr_DsRGetDCName r;
2470 struct netr_DsRGetDCNameInfo *info = NULL;
2471 struct dcerpc_binding_handle *b = p->binding_handle;
2473 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2474 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
2475 r.in.domain_guid = NULL;
2476 r.in.site_guid = NULL;
2477 r.in.flags = DS_RETURN_DNS_NAME;
2478 r.out.info = &info;
2480 status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2481 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2482 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2484 torture_assert_int_equal(tctx,
2485 (info->dc_flags & (DS_DNS_CONTROLLER)),
2486 DS_DNS_CONTROLLER,
2487 "DsRGetDCName");
2488 torture_assert_int_equal(tctx,
2489 (info->dc_flags & (DS_DNS_DOMAIN)),
2490 DS_DNS_DOMAIN,
2491 "DsRGetDCName");
2492 torture_assert_int_equal(tctx,
2493 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2494 DS_DNS_FOREST_ROOT,
2495 "DsRGetDCName");
2497 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
2498 r.in.flags = 0;
2500 status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2501 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2502 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2504 torture_assert_int_equal(tctx,
2505 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2506 "DsRGetDCName");
2507 torture_assert_int_equal(tctx,
2508 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2509 "DsRGetDCName");
2510 torture_assert_int_equal(tctx,
2511 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2512 DS_DNS_FOREST_ROOT,
2513 "DsRGetDCName");
2515 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2516 torture_assert_int_equal(tctx,
2517 (info->dc_flags & (DS_SERVER_CLOSEST)),
2518 DS_SERVER_CLOSEST,
2519 "DsRGetDCName");
2522 return test_netr_DsRGetSiteName(p, tctx,
2523 info->dc_unc,
2524 info->dc_site_name);
2528 try a netlogon netr_DsRGetDCNameEx
2530 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
2531 struct dcerpc_pipe *p)
2533 NTSTATUS status;
2534 struct netr_DsRGetDCNameEx r;
2535 struct netr_DsRGetDCNameInfo *info = NULL;
2536 struct dcerpc_binding_handle *b = p->binding_handle;
2538 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2539 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
2540 r.in.domain_guid = NULL;
2541 r.in.site_name = NULL;
2542 r.in.flags = DS_RETURN_DNS_NAME;
2543 r.out.info = &info;
2545 status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2546 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2547 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2549 torture_assert_int_equal(tctx,
2550 (info->dc_flags & (DS_DNS_CONTROLLER)),
2551 DS_DNS_CONTROLLER,
2552 "DsRGetDCNameEx");
2553 torture_assert_int_equal(tctx,
2554 (info->dc_flags & (DS_DNS_DOMAIN)),
2555 DS_DNS_DOMAIN,
2556 "DsRGetDCNameEx");
2557 torture_assert_int_equal(tctx,
2558 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2559 DS_DNS_FOREST_ROOT,
2560 "DsRGetDCNameEx");
2562 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
2563 r.in.flags = 0;
2565 status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2566 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2567 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2569 torture_assert_int_equal(tctx,
2570 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2571 "DsRGetDCNameEx");
2572 torture_assert_int_equal(tctx,
2573 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2574 "DsRGetDCNameEx");
2575 torture_assert_int_equal(tctx,
2576 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2577 DS_DNS_FOREST_ROOT,
2578 "DsRGetDCNameEx");
2580 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2581 torture_assert_int_equal(tctx,
2582 (info->dc_flags & (DS_SERVER_CLOSEST)),
2583 DS_SERVER_CLOSEST,
2584 "DsRGetDCNameEx");
2587 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2588 info->dc_site_name);
2592 try a netlogon netr_DsRGetDCNameEx2
2594 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
2595 struct dcerpc_pipe *p)
2597 NTSTATUS status;
2598 struct netr_DsRGetDCNameEx2 r;
2599 struct netr_DsRGetDCNameInfo *info = NULL;
2600 struct dcerpc_binding_handle *b = p->binding_handle;
2602 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with no inputs\n");
2603 ZERO_STRUCT(r.in);
2604 r.in.flags = DS_RETURN_DNS_NAME;
2605 r.out.info = &info;
2607 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2608 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2609 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2611 torture_assert_int_equal(tctx,
2612 (info->dc_flags & (DS_DNS_CONTROLLER)),
2613 DS_DNS_CONTROLLER,
2614 "DsRGetDCNameEx2");
2615 torture_assert_int_equal(tctx,
2616 (info->dc_flags & (DS_DNS_DOMAIN)),
2617 DS_DNS_DOMAIN,
2618 "DsRGetDCNameEx2");
2619 torture_assert_int_equal(tctx,
2620 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2621 DS_DNS_FOREST_ROOT,
2622 "DsRGetDCNameEx2");
2624 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2625 r.in.client_account = NULL;
2626 r.in.mask = 0x00000000;
2627 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
2628 r.in.domain_guid = NULL;
2629 r.in.site_name = NULL;
2630 r.in.flags = DS_RETURN_DNS_NAME;
2631 r.out.info = &info;
2633 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
2635 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2636 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2637 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2639 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
2640 r.in.flags = 0;
2642 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2643 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2644 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2646 torture_assert_int_equal(tctx,
2647 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2648 "DsRGetDCNameEx2");
2649 torture_assert_int_equal(tctx,
2650 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2651 "DsRGetDCNameEx2");
2652 torture_assert_int_equal(tctx,
2653 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2654 DS_DNS_FOREST_ROOT,
2655 "DsRGetDCNameEx2");
2657 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2658 torture_assert_int_equal(tctx,
2659 (info->dc_flags & (DS_SERVER_CLOSEST)),
2660 DS_SERVER_CLOSEST,
2661 "DsRGetDCNameEx2");
2664 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client account\n");
2665 r.in.client_account = TEST_MACHINE_NAME"$";
2666 r.in.mask = ACB_SVRTRUST;
2667 r.in.flags = DS_RETURN_FLAT_NAME;
2668 r.out.info = &info;
2670 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2671 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2672 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2674 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2675 info->dc_site_name);
2678 /* This is a substitution for "samdb_server_site_name" which relies on the
2679 * correct "lp_ctx" and therefore can't be used here. */
2680 static const char *server_site_name(struct torture_context *tctx,
2681 struct ldb_context *ldb)
2683 TALLOC_CTX *tmp_ctx;
2684 struct ldb_dn *dn, *server_dn;
2685 const struct ldb_val *site_name_val;
2686 const char *server_dn_str, *site_name;
2688 tmp_ctx = talloc_new(ldb);
2689 if (tmp_ctx == NULL) {
2690 goto failed;
2693 dn = ldb_dn_new(tmp_ctx, ldb, "");
2694 if (dn == NULL) {
2695 goto failed;
2698 server_dn_str = samdb_search_string(ldb, tmp_ctx, dn, "serverName",
2699 NULL);
2700 if (server_dn_str == NULL) {
2701 goto failed;
2704 server_dn = ldb_dn_new(tmp_ctx, ldb, server_dn_str);
2705 if (server_dn == NULL) {
2706 goto failed;
2709 /* CN=<Server name>, CN=Servers, CN=<Site name>, CN=Sites, ... */
2710 site_name_val = ldb_dn_get_component_val(server_dn, 2);
2711 if (site_name_val == NULL) {
2712 goto failed;
2715 site_name = (const char *) site_name_val->data;
2717 talloc_steal(tctx, site_name);
2718 talloc_free(tmp_ctx);
2720 return site_name;
2722 failed:
2723 talloc_free(tmp_ctx);
2724 return NULL;
2727 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
2728 struct dcerpc_pipe *p)
2730 char *url;
2731 struct ldb_context *sam_ctx = NULL;
2732 NTSTATUS status;
2733 struct netr_DsrGetDcSiteCoverageW r;
2734 struct DcSitesCtr *ctr = NULL;
2735 struct dcerpc_binding_handle *b = p->binding_handle;
2737 torture_comment(tctx, "This does only pass with the default site\n");
2739 /* We won't double-check this when we are over 'local' transports */
2740 if (dcerpc_server_name(p)) {
2741 /* Set up connection to SAMDB on DC */
2742 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2743 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2744 NULL,
2745 cmdline_credentials,
2748 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2751 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2752 r.out.ctr = &ctr;
2754 status = dcerpc_netr_DsrGetDcSiteCoverageW_r(b, tctx, &r);
2755 torture_assert_ntstatus_ok(tctx, status, "failed");
2756 torture_assert_werr_ok(tctx, r.out.result, "failed");
2758 torture_assert(tctx, ctr->num_sites == 1,
2759 "we should per default only get the default site");
2760 if (sam_ctx != NULL) {
2761 torture_assert_casestr_equal(tctx, ctr->sites[0].string,
2762 server_site_name(tctx, sam_ctx),
2763 "didn't return default site");
2766 return true;
2769 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
2770 struct dcerpc_pipe *p)
2772 char *url;
2773 struct ldb_context *sam_ctx = NULL;
2774 NTSTATUS status;
2775 struct netr_DsRAddressToSitenamesW r;
2776 struct netr_DsRAddress addrs[6];
2777 struct sockaddr_in *addr;
2778 #ifdef HAVE_IPV6
2779 struct sockaddr_in6 *addr6;
2780 #endif
2781 struct netr_DsRAddressToSitenamesWCtr *ctr;
2782 struct dcerpc_binding_handle *b = p->binding_handle;
2783 uint32_t i;
2784 int ret;
2786 torture_comment(tctx, "This does only pass with the default site\n");
2788 /* We won't double-check this when we are over 'local' transports */
2789 if (dcerpc_server_name(p)) {
2790 /* Set up connection to SAMDB on DC */
2791 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2792 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2793 NULL,
2794 cmdline_credentials,
2797 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2800 /* First try valid IP addresses */
2802 addrs[0].size = sizeof(struct sockaddr_in);
2803 addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
2804 addr = (struct sockaddr_in *) addrs[0].buffer;
2805 addrs[0].buffer[0] = AF_INET;
2806 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2807 torture_assert(tctx, ret > 0, "inet_pton failed");
2809 addrs[1].size = sizeof(struct sockaddr_in);
2810 addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
2811 addr = (struct sockaddr_in *) addrs[1].buffer;
2812 addrs[1].buffer[0] = AF_INET;
2813 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2814 torture_assert(tctx, ret > 0, "inet_pton failed");
2816 addrs[2].size = sizeof(struct sockaddr_in);
2817 addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
2818 addr = (struct sockaddr_in *) addrs[2].buffer;
2819 addrs[2].buffer[0] = AF_INET;
2820 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2821 torture_assert(tctx, ret > 0, "inet_pton failed");
2823 #ifdef HAVE_IPV6
2824 addrs[3].size = sizeof(struct sockaddr_in6);
2825 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2826 addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
2827 addrs[3].buffer[0] = AF_INET6;
2828 ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
2829 torture_assert(tctx, ret > 0, "inet_pton failed");
2831 addrs[4].size = sizeof(struct sockaddr_in6);
2832 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2833 addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
2834 addrs[4].buffer[0] = AF_INET6;
2835 ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
2836 torture_assert(tctx, ret > 0, "inet_pton failed");
2838 addrs[5].size = sizeof(struct sockaddr_in6);
2839 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2840 addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
2841 addrs[5].buffer[0] = AF_INET6;
2842 ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
2843 torture_assert(tctx, ret > 0, "inet_pton failed");
2844 #else
2845 /* the test cases are repeated to have exactly 6. This is for
2846 * compatibility with IPv4-only machines */
2847 addrs[3].size = sizeof(struct sockaddr_in);
2848 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2849 addr = (struct sockaddr_in *) addrs[3].buffer;
2850 addrs[3].buffer[0] = AF_INET;
2851 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2852 torture_assert(tctx, ret > 0, "inet_pton failed");
2854 addrs[4].size = sizeof(struct sockaddr_in);
2855 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2856 addr = (struct sockaddr_in *) addrs[4].buffer;
2857 addrs[4].buffer[0] = AF_INET;
2858 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2859 torture_assert(tctx, ret > 0, "inet_pton failed");
2861 addrs[5].size = sizeof(struct sockaddr_in);
2862 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2863 addr = (struct sockaddr_in *) addrs[5].buffer;
2864 addrs[5].buffer[0] = AF_INET;
2865 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2866 torture_assert(tctx, ret > 0, "inet_pton failed");
2867 #endif
2869 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
2871 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2872 r.in.count = 6;
2873 r.in.addresses = addrs;
2874 r.out.ctr = &ctr;
2876 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2877 torture_assert_ntstatus_ok(tctx, status, "failed");
2878 torture_assert_werr_ok(tctx, r.out.result, "failed");
2880 if (sam_ctx != NULL) {
2881 for (i = 0; i < 3; i++) {
2882 torture_assert_casestr_equal(tctx,
2883 ctr->sitename[i].string,
2884 server_site_name(tctx, sam_ctx),
2885 "didn't return default site");
2887 for (i = 3; i < 6; i++) {
2888 /* Windows returns "NULL" for the sitename if it isn't
2889 * IPv6 configured */
2890 if (torture_setting_bool(tctx, "samba4", false)) {
2891 torture_assert_casestr_equal(tctx,
2892 ctr->sitename[i].string,
2893 server_site_name(tctx, sam_ctx),
2894 "didn't return default site");
2899 /* Now try invalid ones (too short buffers) */
2901 addrs[0].size = 0;
2902 addrs[1].size = 1;
2903 addrs[2].size = 4;
2905 addrs[3].size = 0;
2906 addrs[4].size = 1;
2907 addrs[5].size = 4;
2909 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2910 torture_assert_ntstatus_ok(tctx, status, "failed");
2911 torture_assert_werr_ok(tctx, r.out.result, "failed");
2913 for (i = 0; i < 6; i++) {
2914 torture_assert(tctx, ctr->sitename[i].string == NULL,
2915 "sitename should be null");
2918 /* Now try invalid ones (wrong address types) */
2920 addrs[0].size = 10;
2921 addrs[0].buffer[0] = AF_UNSPEC;
2922 addrs[1].size = 10;
2923 addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
2924 addrs[2].size = 10;
2925 addrs[2].buffer[0] = AF_UNIX;
2927 addrs[3].size = 10;
2928 addrs[3].buffer[0] = 250;
2929 addrs[4].size = 10;
2930 addrs[4].buffer[0] = 251;
2931 addrs[5].size = 10;
2932 addrs[5].buffer[0] = 252;
2934 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2935 torture_assert_ntstatus_ok(tctx, status, "failed");
2936 torture_assert_werr_ok(tctx, r.out.result, "failed");
2938 for (i = 0; i < 6; i++) {
2939 torture_assert(tctx, ctr->sitename[i].string == NULL,
2940 "sitename should be null");
2943 return true;
2946 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
2947 struct dcerpc_pipe *p)
2949 char *url;
2950 struct ldb_context *sam_ctx = NULL;
2951 NTSTATUS status;
2952 struct netr_DsRAddressToSitenamesExW r;
2953 struct netr_DsRAddress addrs[6];
2954 struct sockaddr_in *addr;
2955 #ifdef HAVE_IPV6
2956 struct sockaddr_in6 *addr6;
2957 #endif
2958 struct netr_DsRAddressToSitenamesExWCtr *ctr;
2959 struct dcerpc_binding_handle *b = p->binding_handle;
2960 uint32_t i;
2961 int ret;
2963 torture_comment(tctx, "This does pass with the default site\n");
2965 /* We won't double-check this when we are over 'local' transports */
2966 if (dcerpc_server_name(p)) {
2967 /* Set up connection to SAMDB on DC */
2968 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2969 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2970 NULL,
2971 cmdline_credentials,
2974 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2977 /* First try valid IP addresses */
2979 addrs[0].size = sizeof(struct sockaddr_in);
2980 addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
2981 addr = (struct sockaddr_in *) addrs[0].buffer;
2982 addrs[0].buffer[0] = AF_INET;
2983 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2984 torture_assert(tctx, ret > 0, "inet_pton failed");
2986 addrs[1].size = sizeof(struct sockaddr_in);
2987 addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
2988 addr = (struct sockaddr_in *) addrs[1].buffer;
2989 addrs[1].buffer[0] = AF_INET;
2990 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2991 torture_assert(tctx, ret > 0, "inet_pton failed");
2993 addrs[2].size = sizeof(struct sockaddr_in);
2994 addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
2995 addr = (struct sockaddr_in *) addrs[2].buffer;
2996 addrs[2].buffer[0] = AF_INET;
2997 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2998 torture_assert(tctx, ret > 0, "inet_pton failed");
3000 #ifdef HAVE_IPV6
3001 addrs[3].size = sizeof(struct sockaddr_in6);
3002 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3003 addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
3004 addrs[3].buffer[0] = AF_INET6;
3005 ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
3006 torture_assert(tctx, ret > 0, "inet_pton failed");
3008 addrs[4].size = sizeof(struct sockaddr_in6);
3009 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3010 addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
3011 addrs[4].buffer[0] = AF_INET6;
3012 ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
3013 torture_assert(tctx, ret > 0, "inet_pton failed");
3015 addrs[5].size = sizeof(struct sockaddr_in6);
3016 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3017 addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
3018 addrs[5].buffer[0] = AF_INET6;
3019 ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
3020 torture_assert(tctx, ret > 0, "inet_pton failed");
3021 #else
3022 /* the test cases are repeated to have exactly 6. This is for
3023 * compatibility with IPv4-only machines */
3024 addrs[3].size = sizeof(struct sockaddr_in);
3025 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3026 addr = (struct sockaddr_in *) addrs[3].buffer;
3027 addrs[3].buffer[0] = AF_INET;
3028 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3029 torture_assert(tctx, ret > 0, "inet_pton failed");
3031 addrs[4].size = sizeof(struct sockaddr_in);
3032 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3033 addr = (struct sockaddr_in *) addrs[4].buffer;
3034 addrs[4].buffer[0] = AF_INET;
3035 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3036 torture_assert(tctx, ret > 0, "inet_pton failed");
3038 addrs[5].size = sizeof(struct sockaddr_in);
3039 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3040 addr = (struct sockaddr_in *) addrs[5].buffer;
3041 addrs[5].buffer[0] = AF_INET;
3042 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3043 torture_assert(tctx, ret > 0, "inet_pton failed");
3044 #endif
3046 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
3048 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3049 r.in.count = 6;
3050 r.in.addresses = addrs;
3051 r.out.ctr = &ctr;
3053 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3054 torture_assert_ntstatus_ok(tctx, status, "failed");
3055 torture_assert_werr_ok(tctx, r.out.result, "failed");
3057 if (sam_ctx != NULL) {
3058 for (i = 0; i < 3; i++) {
3059 torture_assert_casestr_equal(tctx,
3060 ctr->sitename[i].string,
3061 server_site_name(tctx, sam_ctx),
3062 "didn't return default site");
3063 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3064 "subnet should be null");
3066 for (i = 3; i < 6; i++) {
3067 /* Windows returns "NULL" for the sitename if it isn't
3068 * IPv6 configured */
3069 if (torture_setting_bool(tctx, "samba4", false)) {
3070 torture_assert_casestr_equal(tctx,
3071 ctr->sitename[i].string,
3072 server_site_name(tctx, sam_ctx),
3073 "didn't return default site");
3075 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3076 "subnet should be null");
3080 /* Now try invalid ones (too short buffers) */
3082 addrs[0].size = 0;
3083 addrs[1].size = 1;
3084 addrs[2].size = 4;
3086 addrs[3].size = 0;
3087 addrs[4].size = 1;
3088 addrs[5].size = 4;
3090 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3091 torture_assert_ntstatus_ok(tctx, status, "failed");
3092 torture_assert_werr_ok(tctx, r.out.result, "failed");
3094 for (i = 0; i < 6; i++) {
3095 torture_assert(tctx, ctr->sitename[i].string == NULL,
3096 "sitename should be null");
3097 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3098 "subnet should be null");
3101 addrs[0].size = 10;
3102 addrs[0].buffer[0] = AF_UNSPEC;
3103 addrs[1].size = 10;
3104 addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
3105 addrs[2].size = 10;
3106 addrs[2].buffer[0] = AF_UNIX;
3108 addrs[3].size = 10;
3109 addrs[3].buffer[0] = 250;
3110 addrs[4].size = 10;
3111 addrs[4].buffer[0] = 251;
3112 addrs[5].size = 10;
3113 addrs[5].buffer[0] = 252;
3115 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3116 torture_assert_ntstatus_ok(tctx, status, "failed");
3117 torture_assert_werr_ok(tctx, r.out.result, "failed");
3119 for (i = 0; i < 6; i++) {
3120 torture_assert(tctx, ctr->sitename[i].string == NULL,
3121 "sitename should be null");
3122 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3123 "subnet should be null");
3126 return true;
3129 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
3130 struct dcerpc_pipe *p,
3131 struct cli_credentials *machine_credentials)
3133 struct netr_ServerGetTrustInfo r;
3135 struct netr_Authenticator a;
3136 struct netr_Authenticator return_authenticator;
3137 struct samr_Password new_owf_password;
3138 struct samr_Password old_owf_password;
3139 struct netr_TrustInfo *trust_info;
3141 struct netlogon_creds_CredentialState *creds;
3142 struct dcerpc_binding_handle *b = p->binding_handle;
3144 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3145 machine_credentials, &creds)) {
3146 return false;
3149 netlogon_creds_client_authenticator(creds, &a);
3151 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3152 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
3153 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
3154 r.in.computer_name = TEST_MACHINE_NAME;
3155 r.in.credential = &a;
3157 r.out.return_authenticator = &return_authenticator;
3158 r.out.new_owf_password = &new_owf_password;
3159 r.out.old_owf_password = &old_owf_password;
3160 r.out.trust_info = &trust_info;
3162 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerGetTrustInfo_r(b, tctx, &r),
3163 "ServerGetTrustInfo failed");
3164 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerGetTrustInfo failed");
3165 torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
3167 return true;
3171 static bool test_GetDomainInfo(struct torture_context *tctx,
3172 struct dcerpc_pipe *p,
3173 struct cli_credentials *machine_credentials)
3175 struct netr_LogonGetDomainInfo r;
3176 struct netr_WorkstationInformation q1;
3177 struct netr_Authenticator a;
3178 struct netlogon_creds_CredentialState *creds;
3179 struct netr_OsVersion os;
3180 union netr_WorkstationInfo query;
3181 union netr_DomainInfo info;
3182 const char* const attrs[] = { "dNSHostName", "operatingSystem",
3183 "operatingSystemServicePack", "operatingSystemVersion",
3184 "servicePrincipalName", NULL };
3185 char *url;
3186 struct ldb_context *sam_ctx = NULL;
3187 struct ldb_message **res;
3188 struct ldb_message_element *spn_el;
3189 int ret, i;
3190 char *version_str;
3191 const char *old_dnsname = NULL;
3192 char **spns = NULL;
3193 int num_spns = 0;
3194 char *temp_str;
3195 struct dcerpc_binding_handle *b = p->binding_handle;
3197 torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
3199 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3200 machine_credentials, &creds)) {
3201 return false;
3204 /* We won't double-check this when we are over 'local' transports */
3205 if (dcerpc_server_name(p)) {
3206 /* Set up connection to SAMDB on DC */
3207 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3208 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3209 NULL,
3210 cmdline_credentials,
3213 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3216 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
3217 netlogon_creds_client_authenticator(creds, &a);
3219 ZERO_STRUCT(r);
3220 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3221 r.in.computer_name = TEST_MACHINE_NAME;
3222 r.in.credential = &a;
3223 r.in.level = 1;
3224 r.in.return_authenticator = &a;
3225 r.in.query = &query;
3226 r.out.return_authenticator = &a;
3227 r.out.info = &info;
3229 ZERO_STRUCT(os);
3230 os.os.MajorVersion = 123;
3231 os.os.MinorVersion = 456;
3232 os.os.BuildNumber = 789;
3233 os.os.CSDVersion = "Service Pack 10";
3234 os.os.ServicePackMajor = 10;
3235 os.os.ServicePackMinor = 1;
3236 os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
3237 os.os.ProductType = NETR_VER_NT_SERVER;
3238 os.os.Reserved = 0;
3240 version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
3241 os.os.MinorVersion, os.os.BuildNumber);
3243 ZERO_STRUCT(q1);
3244 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3245 lpcfg_dnsdomain(tctx->lp_ctx));
3246 q1.sitename = "Default-First-Site-Name";
3247 q1.os_version.os = &os;
3248 q1.os_name.string = talloc_asprintf(tctx,
3249 "Tortured by Samba4 RPC-NETLOGON: %s",
3250 timestring(tctx, time(NULL)));
3252 /* The workstation handles the "servicePrincipalName" and DNS hostname
3253 updates */
3254 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3256 query.workstation_info = &q1;
3258 if (sam_ctx) {
3259 /* Gets back the old DNS hostname in AD */
3260 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3261 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3262 old_dnsname =
3263 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
3265 /* Gets back the "servicePrincipalName"s in AD */
3266 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3267 if (spn_el != NULL) {
3268 for (i=0; i < spn_el->num_values; i++) {
3269 spns = talloc_realloc(tctx, spns, char *, i + 1);
3270 spns[i] = (char *) spn_el->values[i].data;
3272 num_spns = i;
3276 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3277 "LogonGetDomainInfo failed");
3278 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3279 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3281 smb_msleep(250);
3283 if (sam_ctx) {
3284 /* AD workstation infos entry check */
3285 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3286 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3287 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3288 torture_assert_str_equal(tctx,
3289 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3290 q1.os_name.string, "'operatingSystem' wrong!");
3291 torture_assert_str_equal(tctx,
3292 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
3293 os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
3294 torture_assert_str_equal(tctx,
3295 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
3296 version_str, "'operatingSystemVersion' wrong!");
3298 if (old_dnsname != NULL) {
3299 /* If before a DNS hostname was set then it should remain
3300 the same in combination with the "servicePrincipalName"s.
3301 The DNS hostname should also be returned by our
3302 "LogonGetDomainInfo" call (in the domain info structure). */
3304 torture_assert_str_equal(tctx,
3305 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3306 old_dnsname, "'DNS hostname' was not set!");
3308 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3309 torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
3310 "'servicePrincipalName's not set!");
3311 torture_assert(tctx, spn_el->num_values == num_spns,
3312 "'servicePrincipalName's incorrect!");
3313 for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
3314 torture_assert_str_equal(tctx,
3315 (char *) spn_el->values[i].data,
3316 spns[i], "'servicePrincipalName's incorrect!");
3318 torture_assert_str_equal(tctx,
3319 info.domain_info->dns_hostname.string,
3320 old_dnsname,
3321 "Out 'DNS hostname' doesn't match the old one!");
3322 } else {
3323 /* If no DNS hostname was set then also now none should be set,
3324 the "servicePrincipalName"s should remain empty and no DNS
3325 hostname should be returned by our "LogonGetDomainInfo"
3326 call (in the domain info structure). */
3328 torture_assert(tctx,
3329 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
3330 "'DNS hostname' was set!");
3332 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3333 torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
3334 "'servicePrincipalName's were set!");
3336 torture_assert(tctx,
3337 info.domain_info->dns_hostname.string == NULL,
3338 "Out 'DNS host name' was set!");
3342 /* Checks "workstation flags" */
3343 torture_assert(tctx,
3344 info.domain_info->workstation_flags
3345 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3346 "Out 'workstation flags' don't match!");
3349 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname doesn't work)\n");
3350 netlogon_creds_client_authenticator(creds, &a);
3352 /* Wipe out the osVersion, and prove which values still 'stick' */
3353 q1.os_version.os = NULL;
3355 /* Change also the DNS hostname to test differences in behaviour */
3356 talloc_free(discard_const_p(char, q1.dns_hostname));
3357 q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3358 lpcfg_dnsdomain(tctx->lp_ctx));
3360 /* The workstation handles the "servicePrincipalName" and DNS hostname
3361 updates */
3362 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3364 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3365 "LogonGetDomainInfo failed");
3366 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3368 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3370 smb_msleep(250);
3372 if (sam_ctx) {
3373 /* AD workstation infos entry check */
3374 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3375 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3376 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3378 torture_assert_str_equal(tctx,
3379 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3380 q1.os_name.string, "'operatingSystem' should stick!");
3381 torture_assert(tctx,
3382 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3383 "'operatingSystemServicePack' shouldn't stick!");
3384 torture_assert(tctx,
3385 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3386 "'operatingSystemVersion' shouldn't stick!");
3388 /* The DNS host name shouldn't have been updated by the server */
3390 torture_assert_str_equal(tctx,
3391 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3392 old_dnsname, "'DNS host name' did change!");
3394 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3395 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3396 3.5.4.3.9 */
3397 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3398 torture_assert(tctx, spn_el != NULL,
3399 "There should exist 'servicePrincipalName's in AD!");
3400 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3401 for (i=0; i < spn_el->num_values; i++)
3402 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3403 break;
3404 torture_assert(tctx, i != spn_el->num_values,
3405 "'servicePrincipalName' HOST/<Netbios name> not found!");
3406 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3407 for (i=0; i < spn_el->num_values; i++)
3408 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3409 break;
3410 torture_assert(tctx, i != spn_el->num_values,
3411 "'servicePrincipalName' HOST/<FQDN name> not found!");
3413 /* Check that the out DNS hostname was set properly */
3414 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
3415 old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
3418 /* Checks "workstation flags" */
3419 torture_assert(tctx,
3420 info.domain_info->workstation_flags == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3421 "Out 'workstation flags' don't match!");
3424 /* Now try the same but the workstation flags set to 0 */
3426 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (variation of DNS hostname doesn't work)\n");
3427 netlogon_creds_client_authenticator(creds, &a);
3429 /* Change also the DNS hostname to test differences in behaviour */
3430 talloc_free(discard_const_p(char, q1.dns_hostname));
3431 q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3432 lpcfg_dnsdomain(tctx->lp_ctx));
3434 /* Wipe out the osVersion, and prove which values still 'stick' */
3435 q1.os_version.os = NULL;
3437 /* Let the DC handle the "servicePrincipalName" and DNS hostname
3438 updates */
3439 q1.workstation_flags = 0;
3441 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3442 "LogonGetDomainInfo failed");
3443 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3444 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3446 smb_msleep(250);
3448 if (sam_ctx) {
3449 /* AD workstation infos entry check */
3450 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3451 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3452 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3454 torture_assert_str_equal(tctx,
3455 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3456 q1.os_name.string, "'operatingSystem' should stick!");
3457 torture_assert(tctx,
3458 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3459 "'operatingSystemServicePack' shouldn't stick!");
3460 torture_assert(tctx,
3461 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3462 "'operatingSystemVersion' shouldn't stick!");
3464 /* The DNS host name shouldn't have been updated by the server */
3466 torture_assert_str_equal(tctx,
3467 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3468 old_dnsname, "'DNS host name' did change!");
3470 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3471 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3472 3.5.4.3.9 */
3473 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3474 torture_assert(tctx, spn_el != NULL,
3475 "There should exist 'servicePrincipalName's in AD!");
3476 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3477 for (i=0; i < spn_el->num_values; i++)
3478 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3479 break;
3480 torture_assert(tctx, i != spn_el->num_values,
3481 "'servicePrincipalName' HOST/<Netbios name> not found!");
3482 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3483 for (i=0; i < spn_el->num_values; i++)
3484 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3485 break;
3486 torture_assert(tctx, i != spn_el->num_values,
3487 "'servicePrincipalName' HOST/<FQDN name> not found!");
3489 /* Here the server gives us NULL as the out DNS hostname */
3490 torture_assert(tctx, info.domain_info->dns_hostname.string == NULL,
3491 "Out 'DNS hostname' should be NULL!");
3494 /* Checks "workstation flags" */
3495 torture_assert(tctx,
3496 info.domain_info->workstation_flags == 0,
3497 "Out 'workstation flags' don't match!");
3500 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (verification of DNS hostname and check for trusted domains)\n");
3501 netlogon_creds_client_authenticator(creds, &a);
3503 /* Put the DNS hostname back */
3504 talloc_free(discard_const_p(char, q1.dns_hostname));
3505 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3506 lpcfg_dnsdomain(tctx->lp_ctx));
3508 /* The workstation handles the "servicePrincipalName" and DNS hostname
3509 updates */
3510 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3512 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3513 "LogonGetDomainInfo failed");
3514 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3515 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3517 smb_msleep(250);
3519 /* Now the in/out DNS hostnames should be the same */
3520 torture_assert_str_equal(tctx,
3521 info.domain_info->dns_hostname.string,
3522 query.workstation_info->dns_hostname,
3523 "In/Out 'DNS hostnames' don't match!");
3524 old_dnsname = info.domain_info->dns_hostname.string;
3526 /* Checks "workstation flags" */
3527 torture_assert(tctx,
3528 info.domain_info->workstation_flags
3529 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3530 "Out 'workstation flags' don't match!");
3532 /* Checks for trusted domains */
3533 torture_assert(tctx,
3534 (info.domain_info->trusted_domain_count != 0)
3535 && (info.domain_info->trusted_domains != NULL),
3536 "Trusted domains have been requested!");
3539 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 5th call (check for trusted domains)\n");
3540 netlogon_creds_client_authenticator(creds, &a);
3542 /* The workstation handles the "servicePrincipalName" and DNS hostname
3543 updates and requests inbound trusts */
3544 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
3545 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
3547 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3548 "LogonGetDomainInfo failed");
3549 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3550 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3552 smb_msleep(250);
3554 /* Checks "workstation flags" */
3555 torture_assert(tctx,
3556 info.domain_info->workstation_flags
3557 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
3558 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
3559 "Out 'workstation flags' don't match!");
3561 /* Checks for trusted domains */
3562 torture_assert(tctx,
3563 (info.domain_info->trusted_domain_count != 0)
3564 && (info.domain_info->trusted_domains != NULL),
3565 "Trusted domains have been requested!");
3568 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
3569 netlogon_creds_client_authenticator(creds, &a);
3571 query.workstation_info->dns_hostname = NULL;
3573 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3574 "LogonGetDomainInfo failed");
3575 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3576 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3578 /* The old DNS hostname should stick */
3579 torture_assert_str_equal(tctx,
3580 info.domain_info->dns_hostname.string,
3581 old_dnsname,
3582 "'DNS hostname' changed!");
3584 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (extra workstation flags)\n");
3585 netlogon_creds_client_authenticator(creds, &a);
3587 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
3588 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | 0x4;
3590 /* Put the DNS hostname back */
3591 talloc_free(discard_const_p(char, q1.dns_hostname));
3592 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3593 lpcfg_dnsdomain(tctx->lp_ctx));
3595 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3596 "LogonGetDomainInfo failed");
3597 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3598 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3600 /* Checks "workstation flags" */
3601 torture_assert(tctx,
3602 info.domain_info->workstation_flags
3603 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
3604 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
3605 "Out 'workstation flags' don't match!");
3607 if (!torture_setting_bool(tctx, "dangerous", false)) {
3608 torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 8th call (no workstation info) - enable dangerous tests in order to do so\n");
3609 } else {
3610 /* Try a call without the workstation information structure */
3612 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 8th call (no workstation info)\n");
3613 netlogon_creds_client_authenticator(creds, &a);
3615 query.workstation_info = NULL;
3617 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3618 "LogonGetDomainInfo failed");
3619 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3620 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3623 return true;
3626 static bool test_GetDomainInfo_async(struct torture_context *tctx,
3627 struct dcerpc_pipe *p,
3628 struct cli_credentials *machine_credentials)
3630 NTSTATUS status;
3631 struct netr_LogonGetDomainInfo r;
3632 struct netr_WorkstationInformation q1;
3633 struct netr_Authenticator a;
3634 #define ASYNC_COUNT 100
3635 struct netlogon_creds_CredentialState *creds;
3636 struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
3637 struct tevent_req *req[ASYNC_COUNT];
3638 int i;
3639 union netr_WorkstationInfo query;
3640 union netr_DomainInfo info;
3642 torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
3644 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3645 machine_credentials, &creds)) {
3646 return false;
3649 ZERO_STRUCT(r);
3650 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3651 r.in.computer_name = TEST_MACHINE_NAME;
3652 r.in.credential = &a;
3653 r.in.level = 1;
3654 r.in.return_authenticator = &a;
3655 r.in.query = &query;
3656 r.out.return_authenticator = &a;
3657 r.out.info = &info;
3659 ZERO_STRUCT(q1);
3660 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3661 lpcfg_dnsdomain(tctx->lp_ctx));
3662 q1.sitename = "Default-First-Site-Name";
3663 q1.os_name.string = "UNIX/Linux or similar";
3665 query.workstation_info = &q1;
3667 for (i=0;i<ASYNC_COUNT;i++) {
3668 netlogon_creds_client_authenticator(creds, &a);
3670 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
3671 req[i] = dcerpc_netr_LogonGetDomainInfo_r_send(tctx, tctx->ev, p->binding_handle, &r);
3673 /* even with this flush per request a w2k3 server seems to
3674 clag with multiple outstanding requests. bleergh. */
3675 torture_assert_int_equal(tctx, tevent_loop_once(dcerpc_event_context(p)), 0,
3676 "tevent_loop_once failed");
3679 for (i=0;i<ASYNC_COUNT;i++) {
3680 torture_assert_int_equal(tctx, tevent_req_poll(req[i], tctx->ev), true,
3681 "tevent_req_poll() failed");
3683 status = dcerpc_netr_LogonGetDomainInfo_r_recv(req[i], tctx);
3685 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
3686 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
3688 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred),
3689 "Credential chaining failed at async");
3692 torture_comment(tctx,
3693 "Testing netr_LogonGetDomainInfo - async count %d OK\n", ASYNC_COUNT);
3695 return true;
3698 static bool test_ManyGetDCName(struct torture_context *tctx,
3699 struct dcerpc_pipe *p)
3701 NTSTATUS status;
3702 struct dcerpc_pipe *p2;
3703 struct lsa_ObjectAttribute attr;
3704 struct lsa_QosInfo qos;
3705 struct lsa_OpenPolicy2 o;
3706 struct policy_handle lsa_handle;
3707 struct lsa_DomainList domains;
3709 struct lsa_EnumTrustDom t;
3710 uint32_t resume_handle = 0;
3711 struct netr_GetAnyDCName d;
3712 const char *dcname = NULL;
3713 struct dcerpc_binding_handle *b = p->binding_handle;
3714 struct dcerpc_binding_handle *b2;
3716 int i;
3718 if (p->conn->transport.transport != NCACN_NP) {
3719 return true;
3722 torture_comment(tctx, "Torturing GetDCName\n");
3724 status = dcerpc_secondary_connection(p, &p2, p->binding);
3725 torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
3727 status = dcerpc_bind_auth_none(p2, &ndr_table_lsarpc);
3728 torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
3729 b2 = p2->binding_handle;
3731 qos.len = 0;
3732 qos.impersonation_level = 2;
3733 qos.context_mode = 1;
3734 qos.effective_only = 0;
3736 attr.len = 0;
3737 attr.root_dir = NULL;
3738 attr.object_name = NULL;
3739 attr.attributes = 0;
3740 attr.sec_desc = NULL;
3741 attr.sec_qos = &qos;
3743 o.in.system_name = "\\";
3744 o.in.attr = &attr;
3745 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3746 o.out.handle = &lsa_handle;
3748 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
3749 "OpenPolicy2 failed");
3750 torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
3752 t.in.handle = &lsa_handle;
3753 t.in.resume_handle = &resume_handle;
3754 t.in.max_size = 1000;
3755 t.out.domains = &domains;
3756 t.out.resume_handle = &resume_handle;
3758 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b2, tctx, &t),
3759 "EnumTrustDom failed");
3761 if ((!NT_STATUS_IS_OK(t.out.result) &&
3762 (!NT_STATUS_EQUAL(t.out.result, NT_STATUS_NO_MORE_ENTRIES))))
3763 torture_fail(tctx, "Could not list domains");
3765 talloc_free(p2);
3767 d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
3768 dcerpc_server_name(p));
3769 d.out.dcname = &dcname;
3771 for (i=0; i<domains.count * 4; i++) {
3772 struct lsa_DomainInfo *info =
3773 &domains.domains[rand()%domains.count];
3775 d.in.domainname = info->name.string;
3777 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &d);
3778 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3780 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
3781 dcname ? dcname : "unknown");
3784 return true;
3787 static bool test_SetPassword_with_flags(struct torture_context *tctx,
3788 struct dcerpc_pipe *p,
3789 struct cli_credentials *machine_credentials)
3791 uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
3792 struct netlogon_creds_CredentialState *creds;
3793 int i;
3795 if (!test_SetupCredentials2(p, tctx, 0,
3796 machine_credentials,
3797 cli_credentials_get_secure_channel_type(machine_credentials),
3798 &creds)) {
3799 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
3802 for (i=0; i < ARRAY_SIZE(flags); i++) {
3803 torture_assert(tctx,
3804 test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
3805 talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
3808 return true;
3811 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
3813 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon");
3814 struct torture_rpc_tcase *tcase;
3815 struct torture_test *test;
3817 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3818 &ndr_table_netlogon, TEST_MACHINE_NAME);
3820 torture_rpc_tcase_add_test(tcase, "Broken RPC binding handle",
3821 test_netr_broken_binding_handle);
3823 torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
3824 torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
3825 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
3826 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
3827 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
3828 torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
3829 torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
3830 torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
3831 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
3832 torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
3833 torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
3834 torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
3835 torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
3836 torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
3837 torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
3838 torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
3839 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
3840 torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
3841 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
3842 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
3843 test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
3844 test->dangerous = true;
3845 torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
3846 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
3847 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
3848 torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
3849 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
3850 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
3851 torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
3852 torture_rpc_tcase_add_test_creds(tcase, "GetForestTrustInformation", test_netr_GetForestTrustInformation);
3854 return suite;
3857 struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
3859 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon-s3");
3860 struct torture_rpc_tcase *tcase;
3862 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3863 &ndr_table_netlogon, TEST_MACHINE_NAME);
3865 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
3866 torture_rpc_tcase_add_test_creds(tcase, "SamLogon_NULL_domain", test_SamLogon_NULL_domain);
3867 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
3868 torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
3869 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
3870 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
3872 return suite;
3875 struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
3877 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon.admin");
3878 struct torture_rpc_tcase *tcase;
3880 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3881 &ndr_table_netlogon, TEST_MACHINE_NAME);
3882 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3883 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3884 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3886 tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netlogon",
3887 &ndr_table_netlogon, TEST_MACHINE_NAME);
3888 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3889 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3890 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3892 tcase = torture_suite_add_rpc_iface_tcase(suite, "netlogon",
3893 &ndr_table_netlogon);
3894 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3895 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3896 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3898 return suite;