s4-torture: add AES support for netr_ServerPasswordSet2 tests.
[Samba/gebeck_regimport.git] / source4 / torture / rpc / netlogon.c
blob9340dde791848ba245426df07402a966f4b5f520
1 /*
2 Unix SMB/CIFS implementation.
4 test suite for netlogon rpc operations
6 Copyright (C) Andrew Tridgell 2003
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2004
8 Copyright (C) Tim Potter 2003
9 Copyright (C) Matthias Dieter Wallnöfer 2009-2010
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "includes.h"
26 #include "lib/events/events.h"
27 #include "lib/cmdline/popt_common.h"
28 #include "torture/rpc/torture_rpc.h"
29 #include "../lib/crypto/crypto.h"
30 #include "libcli/auth/libcli_auth.h"
31 #include "librpc/gen_ndr/ndr_netlogon_c.h"
32 #include "librpc/gen_ndr/ndr_lsa_c.h"
33 #include "param/param.h"
34 #include "libcli/security/security.h"
35 #include <ldb.h>
36 #include "lib/util/util_ldb.h"
37 #include "ldb_wrap.h"
38 #include "lib/replace/system/network.h"
39 #include "dsdb/samdb/samdb.h"
41 #define TEST_MACHINE_NAME "torturetest"
43 static bool test_netr_broken_binding_handle(struct torture_context *tctx,
44 struct dcerpc_pipe *p)
46 NTSTATUS status;
47 struct netr_DsRGetSiteName r;
48 const char *site = NULL;
49 struct dcerpc_binding_handle *b = p->binding_handle;
51 r.in.computer_name = talloc_asprintf(tctx, "\\\\%s",
52 dcerpc_server_name(p));
53 r.out.site = &site;
55 torture_comment(tctx,
56 "Testing netlogon request with correct binding handle: %s\n",
57 r.in.computer_name);
59 status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
60 torture_assert_ntstatus_ok(tctx, status,
61 "Netlogon request with broken binding handle");
62 torture_assert_werr_ok(tctx, r.out.result,
63 "Netlogon request with broken binding handle");
65 if (torture_setting_bool(tctx, "samba3", false) ||
66 torture_setting_bool(tctx, "samba4", false)) {
67 torture_skip(tctx,
68 "Skipping broken binding handle check against Samba");
71 r.in.computer_name = talloc_asprintf(tctx, "\\\\\\\\%s",
72 dcerpc_server_name(p));
74 torture_comment(tctx,
75 "Testing netlogon request with broken binding handle: %s\n",
76 r.in.computer_name);
78 status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
79 torture_assert_ntstatus_ok(tctx, status,
80 "Netlogon request with broken binding handle");
81 torture_assert_werr_equal(tctx, r.out.result,
82 WERR_INVALID_COMPUTERNAME,
83 "Netlogon request with broken binding handle");
85 r.in.computer_name = "\\\\\\\\THIS_IS_NOT_VALID";
87 torture_comment(tctx,
88 "Testing netlogon request with broken binding handle: %s\n",
89 r.in.computer_name);
91 status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
92 torture_assert_ntstatus_ok(tctx, status,
93 "Netlogon request with broken binding handle");
94 torture_assert_werr_equal(tctx, r.out.result,
95 WERR_INVALID_COMPUTERNAME,
96 "Netlogon request with broken binding handle");
98 return true;
101 static bool test_LogonUasLogon(struct torture_context *tctx,
102 struct dcerpc_pipe *p)
104 NTSTATUS status;
105 struct netr_LogonUasLogon r;
106 struct netr_UasInfo *info = NULL;
107 struct dcerpc_binding_handle *b = p->binding_handle;
109 r.in.server_name = NULL;
110 r.in.account_name = cli_credentials_get_username(cmdline_credentials);
111 r.in.workstation = TEST_MACHINE_NAME;
112 r.out.info = &info;
114 status = dcerpc_netr_LogonUasLogon_r(b, tctx, &r);
115 torture_assert_ntstatus_ok(tctx, status, "LogonUasLogon");
117 return true;
120 static bool test_LogonUasLogoff(struct torture_context *tctx,
121 struct dcerpc_pipe *p)
123 NTSTATUS status;
124 struct netr_LogonUasLogoff r;
125 struct netr_UasLogoffInfo info;
126 struct dcerpc_binding_handle *b = p->binding_handle;
128 r.in.server_name = NULL;
129 r.in.account_name = cli_credentials_get_username(cmdline_credentials);
130 r.in.workstation = TEST_MACHINE_NAME;
131 r.out.info = &info;
133 status = dcerpc_netr_LogonUasLogoff_r(b, tctx, &r);
134 torture_assert_ntstatus_ok(tctx, status, "LogonUasLogoff");
136 return true;
139 bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
140 struct cli_credentials *credentials,
141 struct netlogon_creds_CredentialState **creds_out)
143 struct netr_ServerReqChallenge r;
144 struct netr_ServerAuthenticate a;
145 struct netr_Credential credentials1, credentials2, credentials3;
146 struct netlogon_creds_CredentialState *creds;
147 const struct samr_Password *mach_password;
148 const char *machine_name;
149 struct dcerpc_binding_handle *b = p->binding_handle;
151 mach_password = cli_credentials_get_nt_hash(credentials, tctx);
152 machine_name = cli_credentials_get_workstation(credentials);
154 torture_comment(tctx, "Testing ServerReqChallenge\n");
156 r.in.server_name = NULL;
157 r.in.computer_name = machine_name;
158 r.in.credentials = &credentials1;
159 r.out.return_credentials = &credentials2;
161 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
163 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
164 "ServerReqChallenge failed");
165 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
167 a.in.server_name = NULL;
168 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
169 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(credentials);
170 a.in.computer_name = machine_name;
171 a.in.credentials = &credentials3;
172 a.out.return_credentials = &credentials3;
174 creds = netlogon_creds_client_init(tctx, a.in.account_name,
175 a.in.computer_name,
176 &credentials1, &credentials2,
177 mach_password, &credentials3,
179 torture_assert(tctx, creds != NULL, "memory allocation");
182 torture_comment(tctx, "Testing ServerAuthenticate\n");
184 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate_r(b, tctx, &a),
185 "ServerAuthenticate failed");
187 /* This allows the tests to continue against the more fussy windows 2008 */
188 if (NT_STATUS_EQUAL(a.out.result, NT_STATUS_DOWNGRADE_DETECTED)) {
189 return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
190 credentials,
191 cli_credentials_get_secure_channel_type(credentials),
192 creds_out);
195 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate");
197 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
198 "Credential chaining failed");
200 *creds_out = creds;
201 return true;
204 bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx,
205 uint32_t negotiate_flags,
206 struct cli_credentials *machine_credentials,
207 enum netr_SchannelType sec_chan_type,
208 struct netlogon_creds_CredentialState **creds_out)
210 struct netr_ServerReqChallenge r;
211 struct netr_ServerAuthenticate2 a;
212 struct netr_Credential credentials1, credentials2, credentials3;
213 struct netlogon_creds_CredentialState *creds;
214 const struct samr_Password *mach_password;
215 const char *machine_name;
216 struct dcerpc_binding_handle *b = p->binding_handle;
218 mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
219 machine_name = cli_credentials_get_workstation(machine_credentials);
221 torture_comment(tctx, "Testing ServerReqChallenge\n");
224 r.in.server_name = NULL;
225 r.in.computer_name = machine_name;
226 r.in.credentials = &credentials1;
227 r.out.return_credentials = &credentials2;
229 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
231 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
232 "ServerReqChallenge failed");
233 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
235 a.in.server_name = NULL;
236 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
237 a.in.secure_channel_type = sec_chan_type;
238 a.in.computer_name = machine_name;
239 a.in.negotiate_flags = &negotiate_flags;
240 a.out.negotiate_flags = &negotiate_flags;
241 a.in.credentials = &credentials3;
242 a.out.return_credentials = &credentials3;
244 creds = netlogon_creds_client_init(tctx, a.in.account_name,
245 a.in.computer_name,
246 &credentials1, &credentials2,
247 mach_password, &credentials3,
248 negotiate_flags);
250 torture_assert(tctx, creds != NULL, "memory allocation");
252 torture_comment(tctx, "Testing ServerAuthenticate2\n");
254 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
255 "ServerAuthenticate2 failed");
256 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate2 failed");
258 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
259 "Credential chaining failed");
261 torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
263 *creds_out = creds;
264 return true;
268 bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx,
269 uint32_t negotiate_flags,
270 struct cli_credentials *machine_credentials,
271 struct netlogon_creds_CredentialState **creds_out)
273 struct netr_ServerReqChallenge r;
274 struct netr_ServerAuthenticate3 a;
275 struct netr_Credential credentials1, credentials2, credentials3;
276 struct netlogon_creds_CredentialState *creds;
277 struct samr_Password mach_password;
278 uint32_t rid;
279 const char *machine_name;
280 const char *plain_pass;
281 struct dcerpc_binding_handle *b = p->binding_handle;
283 machine_name = cli_credentials_get_workstation(machine_credentials);
284 plain_pass = cli_credentials_get_password(machine_credentials);
286 torture_comment(tctx, "Testing ServerReqChallenge\n");
288 r.in.server_name = NULL;
289 r.in.computer_name = machine_name;
290 r.in.credentials = &credentials1;
291 r.out.return_credentials = &credentials2;
293 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
295 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
296 "ServerReqChallenge failed");
297 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
299 E_md4hash(plain_pass, mach_password.hash);
301 a.in.server_name = NULL;
302 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
303 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
304 a.in.computer_name = machine_name;
305 a.in.negotiate_flags = &negotiate_flags;
306 a.in.credentials = &credentials3;
307 a.out.return_credentials = &credentials3;
308 a.out.negotiate_flags = &negotiate_flags;
309 a.out.rid = &rid;
311 creds = netlogon_creds_client_init(tctx, a.in.account_name,
312 a.in.computer_name,
313 &credentials1, &credentials2,
314 &mach_password, &credentials3,
315 negotiate_flags);
317 torture_assert(tctx, creds != NULL, "memory allocation");
319 torture_comment(tctx, "Testing ServerAuthenticate3\n");
321 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
322 "ServerAuthenticate3 failed");
323 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed");
324 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
326 torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
328 /* Prove that requesting a challenge again won't break it */
329 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
330 "ServerReqChallenge failed");
331 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
333 *creds_out = creds;
334 return true;
338 try a change password for our machine account
340 static bool test_SetPassword(struct torture_context *tctx,
341 struct dcerpc_pipe *p,
342 struct cli_credentials *machine_credentials)
344 struct netr_ServerPasswordSet r;
345 const char *password;
346 struct netlogon_creds_CredentialState *creds;
347 struct netr_Authenticator credential, return_authenticator;
348 struct samr_Password new_password;
349 struct dcerpc_binding_handle *b = p->binding_handle;
351 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
352 return false;
355 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
356 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
357 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
358 r.in.computer_name = TEST_MACHINE_NAME;
359 r.in.credential = &credential;
360 r.in.new_password = &new_password;
361 r.out.return_authenticator = &return_authenticator;
363 password = generate_random_password(tctx, 8, 255);
364 E_md4hash(password, new_password.hash);
366 netlogon_creds_des_encrypt(creds, &new_password);
368 torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
369 torture_comment(tctx, "Changing machine account password to '%s'\n",
370 password);
372 netlogon_creds_client_authenticator(creds, &credential);
374 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
375 "ServerPasswordSet failed");
376 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
378 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
379 torture_comment(tctx, "Credential chaining failed\n");
382 /* by changing the machine password twice we test the
383 credentials chaining fully, and we verify that the server
384 allows the password to be set to the same value twice in a
385 row (match win2k3) */
386 torture_comment(tctx,
387 "Testing a second ServerPasswordSet on machine account\n");
388 torture_comment(tctx,
389 "Changing machine account password to '%s' (same as previous run)\n", password);
391 netlogon_creds_client_authenticator(creds, &credential);
393 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
394 "ServerPasswordSet (2) failed");
395 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
397 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
398 torture_comment(tctx, "Credential chaining failed\n");
401 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
403 torture_assert(tctx,
404 test_SetupCredentials(p, tctx, machine_credentials, &creds),
405 "ServerPasswordSet failed to actually change the password");
407 return true;
411 try a change password for our machine account
413 static bool test_SetPassword_flags(struct torture_context *tctx,
414 struct dcerpc_pipe *p,
415 struct cli_credentials *machine_credentials,
416 uint32_t negotiate_flags)
418 struct netr_ServerPasswordSet r;
419 const char *password;
420 struct netlogon_creds_CredentialState *creds;
421 struct netr_Authenticator credential, return_authenticator;
422 struct samr_Password new_password;
423 struct dcerpc_binding_handle *b = p->binding_handle;
425 if (!test_SetupCredentials2(p, tctx, negotiate_flags,
426 machine_credentials,
427 cli_credentials_get_secure_channel_type(machine_credentials),
428 &creds)) {
429 return false;
432 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
433 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
434 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
435 r.in.computer_name = TEST_MACHINE_NAME;
436 r.in.credential = &credential;
437 r.in.new_password = &new_password;
438 r.out.return_authenticator = &return_authenticator;
440 password = generate_random_password(tctx, 8, 255);
441 E_md4hash(password, new_password.hash);
443 netlogon_creds_des_encrypt(creds, &new_password);
445 torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
446 torture_comment(tctx, "Changing machine account password to '%s'\n",
447 password);
449 netlogon_creds_client_authenticator(creds, &credential);
451 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
452 "ServerPasswordSet failed");
453 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
455 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
456 torture_comment(tctx, "Credential chaining failed\n");
459 /* by changing the machine password twice we test the
460 credentials chaining fully, and we verify that the server
461 allows the password to be set to the same value twice in a
462 row (match win2k3) */
463 torture_comment(tctx,
464 "Testing a second ServerPasswordSet on machine account\n");
465 torture_comment(tctx,
466 "Changing machine account password to '%s' (same as previous run)\n", password);
468 netlogon_creds_client_authenticator(creds, &credential);
470 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
471 "ServerPasswordSet (2) failed");
472 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
474 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
475 torture_comment(tctx, "Credential chaining failed\n");
478 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
480 torture_assert(tctx,
481 test_SetupCredentials(p, tctx, machine_credentials, &creds),
482 "ServerPasswordSet failed to actually change the password");
484 return true;
489 generate a random password for password change tests
491 static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
493 int i;
494 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
495 generate_random_buffer(password.data, password.length);
497 for (i=0; i < len; i++) {
498 if (((uint16_t *)password.data)[i] == 0) {
499 ((uint16_t *)password.data)[i] = 1;
503 return password;
507 try a change password for our machine account
509 static bool test_SetPassword2_with_flags(struct torture_context *tctx,
510 struct dcerpc_pipe *p,
511 struct cli_credentials *machine_credentials,
512 uint32_t flags)
514 struct netr_ServerPasswordSet2 r;
515 const char *password;
516 DATA_BLOB new_random_pass;
517 struct netlogon_creds_CredentialState *creds;
518 struct samr_CryptPassword password_buf;
519 struct samr_Password nt_hash;
520 struct netr_Authenticator credential, return_authenticator;
521 struct netr_CryptPassword new_password;
522 struct dcerpc_binding_handle *b = p->binding_handle;
524 if (!test_SetupCredentials2(p, tctx, flags, machine_credentials, cli_credentials_get_secure_channel_type(machine_credentials), &creds)) {
525 return false;
528 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
529 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
530 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
531 r.in.computer_name = TEST_MACHINE_NAME;
532 r.in.credential = &credential;
533 r.in.new_password = &new_password;
534 r.out.return_authenticator = &return_authenticator;
536 password = generate_random_password(tctx, 8, 255);
537 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
538 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
539 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
540 } else {
541 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
544 memcpy(new_password.data, password_buf.data, 512);
545 new_password.length = IVAL(password_buf.data, 512);
547 torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
548 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
550 netlogon_creds_client_authenticator(creds, &credential);
552 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
553 "ServerPasswordSet2 failed");
554 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
556 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
557 torture_comment(tctx, "Credential chaining failed\n");
560 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
562 if (!torture_setting_bool(tctx, "dangerous", false)) {
563 torture_comment(tctx,
564 "Not testing ability to set password to '', enable dangerous tests to perform this test\n");
565 } else {
566 /* by changing the machine password to ""
567 * we check if the server uses password restrictions
568 * for ServerPasswordSet2
569 * (win2k3 accepts "")
571 password = "";
572 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
573 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
574 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
575 } else {
576 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
578 memcpy(new_password.data, password_buf.data, 512);
579 new_password.length = IVAL(password_buf.data, 512);
581 torture_comment(tctx,
582 "Testing ServerPasswordSet2 on machine account\n");
583 torture_comment(tctx,
584 "Changing machine account password to '%s'\n", password);
586 netlogon_creds_client_authenticator(creds, &credential);
588 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
589 "ServerPasswordSet2 failed");
590 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
592 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
593 torture_comment(tctx, "Credential chaining failed\n");
596 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
599 torture_assert(tctx, test_SetupCredentials(p, tctx, machine_credentials, &creds),
600 "ServerPasswordSet failed to actually change the password");
602 /* now try a random password */
603 password = generate_random_password(tctx, 8, 255);
604 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
605 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
606 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
607 } else {
608 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
610 memcpy(new_password.data, password_buf.data, 512);
611 new_password.length = IVAL(password_buf.data, 512);
613 torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
614 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
616 netlogon_creds_client_authenticator(creds, &credential);
618 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
619 "ServerPasswordSet2 (2) failed");
620 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 (2) failed");
622 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
623 torture_comment(tctx, "Credential chaining failed\n");
626 /* by changing the machine password twice we test the
627 credentials chaining fully, and we verify that the server
628 allows the password to be set to the same value twice in a
629 row (match win2k3) */
630 torture_comment(tctx,
631 "Testing a second ServerPasswordSet2 on machine account\n");
632 torture_comment(tctx,
633 "Changing machine account password to '%s' (same as previous run)\n", password);
635 netlogon_creds_client_authenticator(creds, &credential);
637 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
638 "ServerPasswordSet (3) failed");
639 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
641 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
642 torture_comment(tctx, "Credential chaining failed\n");
645 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
647 torture_assert (tctx,
648 test_SetupCredentials(p, tctx, machine_credentials, &creds),
649 "ServerPasswordSet failed to actually change the password");
651 new_random_pass = netlogon_very_rand_pass(tctx, 128);
653 /* now try a random stream of bytes for a password */
654 set_pw_in_buffer(password_buf.data, &new_random_pass);
656 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
657 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
658 } else {
659 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
662 memcpy(new_password.data, password_buf.data, 512);
663 new_password.length = IVAL(password_buf.data, 512);
665 torture_comment(tctx,
666 "Testing a third ServerPasswordSet2 on machine account, with a completely random password\n");
668 netlogon_creds_client_authenticator(creds, &credential);
670 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
671 "ServerPasswordSet (3) failed");
672 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
674 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
675 torture_comment(tctx, "Credential chaining failed\n");
678 mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
680 cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
681 cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
683 torture_assert (tctx,
684 test_SetupCredentials(p, tctx, machine_credentials, &creds),
685 "ServerPasswordSet failed to actually change the password");
687 return true;
690 static bool test_SetPassword2(struct torture_context *tctx,
691 struct dcerpc_pipe *p,
692 struct cli_credentials *machine_credentials)
694 return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS);
697 static bool test_SetPassword2_AES(struct torture_context *tctx,
698 struct dcerpc_pipe *p,
699 struct cli_credentials *machine_credentials)
701 return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
704 static bool test_GetPassword(struct torture_context *tctx,
705 struct dcerpc_pipe *p,
706 struct cli_credentials *machine_credentials)
708 struct netr_ServerPasswordGet r;
709 struct netlogon_creds_CredentialState *creds;
710 struct netr_Authenticator credential;
711 NTSTATUS status;
712 struct netr_Authenticator return_authenticator;
713 struct samr_Password password;
714 struct dcerpc_binding_handle *b = p->binding_handle;
716 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
717 return false;
720 netlogon_creds_client_authenticator(creds, &credential);
722 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
723 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
724 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
725 r.in.computer_name = TEST_MACHINE_NAME;
726 r.in.credential = &credential;
727 r.out.return_authenticator = &return_authenticator;
728 r.out.password = &password;
730 status = dcerpc_netr_ServerPasswordGet_r(b, tctx, &r);
731 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
733 return true;
736 static bool test_GetTrustPasswords(struct torture_context *tctx,
737 struct dcerpc_pipe *p,
738 struct cli_credentials *machine_credentials)
740 struct netr_ServerTrustPasswordsGet r;
741 struct netlogon_creds_CredentialState *creds;
742 struct netr_Authenticator credential;
743 struct netr_Authenticator return_authenticator;
744 struct samr_Password password, password2;
745 struct dcerpc_binding_handle *b = p->binding_handle;
747 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
748 return false;
751 netlogon_creds_client_authenticator(creds, &credential);
753 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
754 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
755 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
756 r.in.computer_name = TEST_MACHINE_NAME;
757 r.in.credential = &credential;
758 r.out.return_authenticator = &return_authenticator;
759 r.out.password = &password;
760 r.out.password2 = &password2;
762 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerTrustPasswordsGet_r(b, tctx, &r),
763 "ServerTrustPasswordsGet failed");
764 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerTrustPasswordsGet failed");
766 return true;
770 try a netlogon SamLogon
772 static bool test_netlogon_ops_args(struct dcerpc_pipe *p, struct torture_context *tctx,
773 struct cli_credentials *credentials,
774 struct netlogon_creds_CredentialState *creds,
775 bool null_domain)
777 NTSTATUS status;
778 struct netr_LogonSamLogon r;
779 struct netr_Authenticator auth, auth2;
780 static const struct netr_Authenticator auth_zero;
781 union netr_LogonLevel logon;
782 union netr_Validation validation;
783 uint8_t authoritative;
784 struct netr_NetworkInfo ninfo;
785 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
786 int i;
787 struct dcerpc_binding_handle *b = p->binding_handle;
788 int flags = CLI_CRED_NTLM_AUTH;
789 if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
790 flags |= CLI_CRED_LANMAN_AUTH;
793 if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx) && !null_domain) {
794 flags |= CLI_CRED_NTLMv2_AUTH;
797 cli_credentials_get_ntlm_username_domain(cmdline_credentials, tctx,
798 &ninfo.identity_info.account_name.string,
799 &ninfo.identity_info.domain_name.string);
801 if (null_domain) {
802 ninfo.identity_info.domain_name.string = NULL;
805 generate_random_buffer(ninfo.challenge,
806 sizeof(ninfo.challenge));
807 chal = data_blob_const(ninfo.challenge,
808 sizeof(ninfo.challenge));
810 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials),
811 cli_credentials_get_domain(credentials));
813 status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx,
814 &flags,
815 chal,
816 names_blob,
817 &lm_resp, &nt_resp,
818 NULL, NULL);
819 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
821 ninfo.lm.data = lm_resp.data;
822 ninfo.lm.length = lm_resp.length;
824 ninfo.nt.data = nt_resp.data;
825 ninfo.nt.length = nt_resp.length;
827 ninfo.identity_info.parameter_control = 0;
828 ninfo.identity_info.logon_id_low = 0;
829 ninfo.identity_info.logon_id_high = 0;
830 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
832 logon.network = &ninfo;
834 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
835 r.in.computer_name = cli_credentials_get_workstation(credentials);
836 r.in.credential = &auth;
837 r.in.return_authenticator = &auth2;
838 r.in.logon_level = 2;
839 r.in.logon = &logon;
840 r.out.validation = &validation;
841 r.out.authoritative = &authoritative;
843 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
845 for (i=2;i<=3;i++) {
846 ZERO_STRUCT(auth2);
847 netlogon_creds_client_authenticator(creds, &auth);
849 r.in.validation_level = i;
851 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
852 "LogonSamLogon failed");
853 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
855 torture_assert(tctx, netlogon_creds_client_check(creds,
856 &r.out.return_authenticator->cred),
857 "Credential chaining failed");
858 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
859 "LogonSamLogon invalid *r.out.authoritative");
862 /* this makes sure we get the unmarshalling right for invalid levels */
863 for (i=52;i<53;i++) {
864 ZERO_STRUCT(auth2);
865 /* the authenticator should be ignored by the server */
866 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
868 r.in.validation_level = i;
870 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
871 "LogonSamLogon failed");
872 torture_assert_ntstatus_equal(tctx, r.out.result,
873 NT_STATUS_INVALID_INFO_CLASS,
874 "LogonSamLogon failed");
876 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
877 "LogonSamLogon invalid *r.out.authoritative");
878 torture_assert(tctx,
879 memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
880 "Return authenticator non zero");
883 for (i=2;i<=3;i++) {
884 ZERO_STRUCT(auth2);
885 netlogon_creds_client_authenticator(creds, &auth);
887 r.in.validation_level = i;
889 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
890 "LogonSamLogon failed");
891 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
893 torture_assert(tctx, netlogon_creds_client_check(creds,
894 &r.out.return_authenticator->cred),
895 "Credential chaining failed");
896 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
897 "LogonSamLogon invalid *r.out.authoritative");
900 r.in.logon_level = 52;
902 for (i=2;i<=3;i++) {
903 ZERO_STRUCT(auth2);
904 /* the authenticator should be ignored by the server */
905 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
907 r.in.validation_level = i;
909 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
911 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
912 "LogonSamLogon failed");
913 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
914 "LogonSamLogon expected INVALID_PARAMETER");
916 torture_assert(tctx,
917 memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
918 "Return authenticator non zero");
919 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
920 "LogonSamLogon invalid *r.out.authoritative");
923 r.in.credential = NULL;
925 for (i=2;i<=3;i++) {
926 ZERO_STRUCT(auth2);
928 r.in.validation_level = i;
930 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
932 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
933 "LogonSamLogon failed");
934 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
935 "LogonSamLogon expected INVALID_PARAMETER");
937 torture_assert(tctx,
938 memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
939 "Return authenticator non zero");
940 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
941 "LogonSamLogon invalid *r.out.authoritative");
944 r.in.logon_level = 2;
945 r.in.credential = &auth;
947 for (i=2;i<=3;i++) {
948 ZERO_STRUCT(auth2);
949 netlogon_creds_client_authenticator(creds, &auth);
951 r.in.validation_level = i;
953 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
954 "LogonSamLogon failed");
955 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
957 torture_assert(tctx, netlogon_creds_client_check(creds,
958 &r.out.return_authenticator->cred),
959 "Credential chaining failed");
960 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
961 "LogonSamLogon invalid *r.out.authoritative");
964 return true;
967 bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
968 struct cli_credentials *credentials,
969 struct netlogon_creds_CredentialState *creds)
971 return test_netlogon_ops_args(p, tctx, credentials, creds, false);
975 try a netlogon GetCapabilities
977 bool test_netlogon_capabilities(struct dcerpc_pipe *p, struct torture_context *tctx,
978 struct cli_credentials *credentials,
979 struct netlogon_creds_CredentialState *creds)
981 NTSTATUS status;
982 struct netr_LogonGetCapabilities r;
983 union netr_Capabilities capabilities;
984 struct netr_Authenticator auth, return_auth;
985 struct netlogon_creds_CredentialState tmp_creds;
986 struct dcerpc_binding_handle *b = p->binding_handle;
988 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
989 r.in.computer_name = cli_credentials_get_workstation(credentials);
990 r.in.credential = &auth;
991 r.in.return_authenticator = &return_auth;
992 r.in.query_level = 1;
993 r.out.capabilities = &capabilities;
994 r.out.return_authenticator = &return_auth;
996 torture_comment(tctx, "Testing LogonGetCapabilities\n");
998 ZERO_STRUCT(return_auth);
1001 * we need to operate on a temporary copy of creds
1002 * because dcerpc_netr_LogonGetCapabilities was
1003 * dcerpc_netr_DummyFunction and returns NT_STATUS_NOT_IMPLEMENTED
1004 * without looking a the authenticator.
1006 tmp_creds = *creds;
1007 netlogon_creds_client_authenticator(&tmp_creds, &auth);
1009 status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
1010 torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities failed");
1011 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
1012 return true;
1015 *creds = tmp_creds;
1017 torture_assert(tctx, netlogon_creds_client_check(creds,
1018 &r.out.return_authenticator->cred),
1019 "Credential chaining failed");
1021 torture_assert_int_equal(tctx, creds->negotiate_flags,
1022 capabilities.server_capabilities,
1023 "negotiate flags");
1025 return true;
1029 try a netlogon SamLogon
1031 static bool test_SamLogon(struct torture_context *tctx,
1032 struct dcerpc_pipe *p,
1033 struct cli_credentials *credentials)
1035 struct netlogon_creds_CredentialState *creds;
1037 if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
1038 return false;
1041 return test_netlogon_ops(p, tctx, credentials, creds);
1044 static bool test_SamLogon_NULL_domain(struct torture_context *tctx,
1045 struct dcerpc_pipe *p,
1046 struct cli_credentials *credentials)
1048 struct netlogon_creds_CredentialState *creds;
1050 if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
1051 return false;
1054 return test_netlogon_ops_args(p, tctx, credentials, creds, true);
1057 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
1058 static uint64_t sequence_nums[3];
1061 try a netlogon DatabaseSync
1063 static bool test_DatabaseSync(struct torture_context *tctx,
1064 struct dcerpc_pipe *p,
1065 struct cli_credentials *machine_credentials)
1067 struct netr_DatabaseSync r;
1068 struct netlogon_creds_CredentialState *creds;
1069 const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
1070 int i;
1071 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1072 struct netr_Authenticator credential, return_authenticator;
1073 struct dcerpc_binding_handle *b = p->binding_handle;
1075 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1076 return false;
1079 ZERO_STRUCT(return_authenticator);
1081 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1082 r.in.computername = TEST_MACHINE_NAME;
1083 r.in.preferredmaximumlength = (uint32_t)-1;
1084 r.in.return_authenticator = &return_authenticator;
1085 r.out.delta_enum_array = &delta_enum_array;
1086 r.out.return_authenticator = &return_authenticator;
1088 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1090 uint32_t sync_context = 0;
1092 r.in.database_id = database_ids[i];
1093 r.in.sync_context = &sync_context;
1094 r.out.sync_context = &sync_context;
1096 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
1098 do {
1099 netlogon_creds_client_authenticator(creds, &credential);
1101 r.in.credential = &credential;
1103 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync_r(b, tctx, &r),
1104 "DatabaseSync failed");
1105 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1106 break;
1108 /* Native mode servers don't do this */
1109 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1110 return true;
1112 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync");
1114 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1115 torture_comment(tctx, "Credential chaining failed\n");
1118 if (delta_enum_array &&
1119 delta_enum_array->num_deltas > 0 &&
1120 delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
1121 delta_enum_array->delta_enum[0].delta_union.domain) {
1122 sequence_nums[r.in.database_id] =
1123 delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
1124 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
1125 r.in.database_id,
1126 (unsigned long long)sequence_nums[r.in.database_id]);
1128 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1131 return true;
1136 try a netlogon DatabaseDeltas
1138 static bool test_DatabaseDeltas(struct torture_context *tctx,
1139 struct dcerpc_pipe *p,
1140 struct cli_credentials *machine_credentials)
1142 struct netr_DatabaseDeltas r;
1143 struct netlogon_creds_CredentialState *creds;
1144 struct netr_Authenticator credential;
1145 struct netr_Authenticator return_authenticator;
1146 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1147 const uint32_t database_ids[] = {0, 1, 2};
1148 int i;
1149 struct dcerpc_binding_handle *b = p->binding_handle;
1151 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1152 return false;
1155 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1156 r.in.computername = TEST_MACHINE_NAME;
1157 r.in.preferredmaximumlength = (uint32_t)-1;
1158 ZERO_STRUCT(r.in.return_authenticator);
1159 r.out.return_authenticator = &return_authenticator;
1160 r.out.delta_enum_array = &delta_enum_array;
1162 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1163 r.in.database_id = database_ids[i];
1164 r.in.sequence_num = &sequence_nums[r.in.database_id];
1166 if (*r.in.sequence_num == 0) continue;
1168 *r.in.sequence_num -= 1;
1170 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n",
1171 r.in.database_id, (unsigned long long)*r.in.sequence_num);
1173 do {
1174 netlogon_creds_client_authenticator(creds, &credential);
1176 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseDeltas_r(b, tctx, &r),
1177 "DatabaseDeltas failed");
1178 if (NT_STATUS_EQUAL(r.out.result,
1179 NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
1180 torture_comment(tctx, "not considering %s to be an error\n",
1181 nt_errstr(r.out.result));
1182 return true;
1184 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1185 break;
1187 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseDeltas");
1189 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1190 torture_comment(tctx, "Credential chaining failed\n");
1193 (*r.in.sequence_num)++;
1194 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1197 return true;
1200 static bool test_DatabaseRedo(struct torture_context *tctx,
1201 struct dcerpc_pipe *p,
1202 struct cli_credentials *machine_credentials)
1204 struct netr_DatabaseRedo r;
1205 struct netlogon_creds_CredentialState *creds;
1206 struct netr_Authenticator credential;
1207 struct netr_Authenticator return_authenticator;
1208 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1209 struct netr_ChangeLogEntry e;
1210 struct dom_sid null_sid, *sid;
1211 int i,d;
1212 struct dcerpc_binding_handle *b = p->binding_handle;
1214 ZERO_STRUCT(null_sid);
1216 sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
1220 struct {
1221 uint32_t rid;
1222 uint16_t flags;
1223 uint8_t db_index;
1224 uint8_t delta_type;
1225 struct dom_sid sid;
1226 const char *name;
1227 NTSTATUS expected_error;
1228 uint32_t expected_num_results;
1229 uint8_t expected_delta_type_1;
1230 uint8_t expected_delta_type_2;
1231 const char *comment;
1232 } changes[] = {
1234 /* SAM_DATABASE_DOMAIN */
1237 .rid = 0,
1238 .flags = 0,
1239 .db_index = SAM_DATABASE_DOMAIN,
1240 .delta_type = NETR_DELTA_MODIFY_COUNT,
1241 .sid = null_sid,
1242 .name = NULL,
1243 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1244 .expected_num_results = 0,
1245 .comment = "NETR_DELTA_MODIFY_COUNT"
1248 .rid = 0,
1249 .flags = 0,
1250 .db_index = SAM_DATABASE_DOMAIN,
1251 .delta_type = 0,
1252 .sid = null_sid,
1253 .name = NULL,
1254 .expected_error = NT_STATUS_OK,
1255 .expected_num_results = 1,
1256 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1257 .comment = "NULL DELTA"
1260 .rid = 0,
1261 .flags = 0,
1262 .db_index = SAM_DATABASE_DOMAIN,
1263 .delta_type = NETR_DELTA_DOMAIN,
1264 .sid = null_sid,
1265 .name = NULL,
1266 .expected_error = NT_STATUS_OK,
1267 .expected_num_results = 1,
1268 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1269 .comment = "NETR_DELTA_DOMAIN"
1272 .rid = DOMAIN_RID_ADMINISTRATOR,
1273 .flags = 0,
1274 .db_index = SAM_DATABASE_DOMAIN,
1275 .delta_type = NETR_DELTA_USER,
1276 .sid = null_sid,
1277 .name = NULL,
1278 .expected_error = NT_STATUS_OK,
1279 .expected_num_results = 1,
1280 .expected_delta_type_1 = NETR_DELTA_USER,
1281 .comment = "NETR_DELTA_USER by rid 500"
1284 .rid = DOMAIN_RID_GUEST,
1285 .flags = 0,
1286 .db_index = SAM_DATABASE_DOMAIN,
1287 .delta_type = NETR_DELTA_USER,
1288 .sid = null_sid,
1289 .name = NULL,
1290 .expected_error = NT_STATUS_OK,
1291 .expected_num_results = 1,
1292 .expected_delta_type_1 = NETR_DELTA_USER,
1293 .comment = "NETR_DELTA_USER by rid 501"
1296 .rid = 0,
1297 .flags = NETR_CHANGELOG_SID_INCLUDED,
1298 .db_index = SAM_DATABASE_DOMAIN,
1299 .delta_type = NETR_DELTA_USER,
1300 .sid = *sid,
1301 .name = NULL,
1302 .expected_error = NT_STATUS_OK,
1303 .expected_num_results = 1,
1304 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1305 .comment = "NETR_DELTA_USER by sid and flags"
1308 .rid = 0,
1309 .flags = NETR_CHANGELOG_SID_INCLUDED,
1310 .db_index = SAM_DATABASE_DOMAIN,
1311 .delta_type = NETR_DELTA_USER,
1312 .sid = null_sid,
1313 .name = NULL,
1314 .expected_error = NT_STATUS_OK,
1315 .expected_num_results = 1,
1316 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1317 .comment = "NETR_DELTA_USER by null_sid and flags"
1320 .rid = 0,
1321 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1322 .db_index = SAM_DATABASE_DOMAIN,
1323 .delta_type = NETR_DELTA_USER,
1324 .sid = null_sid,
1325 .name = "administrator",
1326 .expected_error = NT_STATUS_OK,
1327 .expected_num_results = 1,
1328 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1329 .comment = "NETR_DELTA_USER by name 'administrator'"
1332 .rid = DOMAIN_RID_ADMINS,
1333 .flags = 0,
1334 .db_index = SAM_DATABASE_DOMAIN,
1335 .delta_type = NETR_DELTA_GROUP,
1336 .sid = null_sid,
1337 .name = NULL,
1338 .expected_error = NT_STATUS_OK,
1339 .expected_num_results = 2,
1340 .expected_delta_type_1 = NETR_DELTA_GROUP,
1341 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
1342 .comment = "NETR_DELTA_GROUP by rid 512"
1345 .rid = DOMAIN_RID_ADMINS,
1346 .flags = 0,
1347 .db_index = SAM_DATABASE_DOMAIN,
1348 .delta_type = NETR_DELTA_GROUP_MEMBER,
1349 .sid = null_sid,
1350 .name = NULL,
1351 .expected_error = NT_STATUS_OK,
1352 .expected_num_results = 2,
1353 .expected_delta_type_1 = NETR_DELTA_GROUP,
1354 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
1355 .comment = "NETR_DELTA_GROUP_MEMBER by rid 512"
1359 /* SAM_DATABASE_BUILTIN */
1362 .rid = 0,
1363 .flags = 0,
1364 .db_index = SAM_DATABASE_BUILTIN,
1365 .delta_type = NETR_DELTA_MODIFY_COUNT,
1366 .sid = null_sid,
1367 .name = NULL,
1368 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1369 .expected_num_results = 0,
1370 .comment = "NETR_DELTA_MODIFY_COUNT"
1373 .rid = 0,
1374 .flags = 0,
1375 .db_index = SAM_DATABASE_BUILTIN,
1376 .delta_type = NETR_DELTA_DOMAIN,
1377 .sid = null_sid,
1378 .name = NULL,
1379 .expected_error = NT_STATUS_OK,
1380 .expected_num_results = 1,
1381 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1382 .comment = "NETR_DELTA_DOMAIN"
1385 .rid = DOMAIN_RID_ADMINISTRATOR,
1386 .flags = 0,
1387 .db_index = SAM_DATABASE_BUILTIN,
1388 .delta_type = NETR_DELTA_USER,
1389 .sid = null_sid,
1390 .name = NULL,
1391 .expected_error = NT_STATUS_OK,
1392 .expected_num_results = 1,
1393 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1394 .comment = "NETR_DELTA_USER by rid 500"
1397 .rid = 0,
1398 .flags = 0,
1399 .db_index = SAM_DATABASE_BUILTIN,
1400 .delta_type = NETR_DELTA_USER,
1401 .sid = null_sid,
1402 .name = NULL,
1403 .expected_error = NT_STATUS_OK,
1404 .expected_num_results = 1,
1405 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1406 .comment = "NETR_DELTA_USER"
1409 .rid = 544,
1410 .flags = 0,
1411 .db_index = SAM_DATABASE_BUILTIN,
1412 .delta_type = NETR_DELTA_ALIAS,
1413 .sid = null_sid,
1414 .name = NULL,
1415 .expected_error = NT_STATUS_OK,
1416 .expected_num_results = 2,
1417 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1418 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1419 .comment = "NETR_DELTA_ALIAS by rid 544"
1422 .rid = 544,
1423 .flags = 0,
1424 .db_index = SAM_DATABASE_BUILTIN,
1425 .delta_type = NETR_DELTA_ALIAS_MEMBER,
1426 .sid = null_sid,
1427 .name = NULL,
1428 .expected_error = NT_STATUS_OK,
1429 .expected_num_results = 2,
1430 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1431 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1432 .comment = "NETR_DELTA_ALIAS_MEMBER by rid 544"
1435 .rid = 544,
1436 .flags = 0,
1437 .db_index = SAM_DATABASE_BUILTIN,
1438 .delta_type = 0,
1439 .sid = null_sid,
1440 .name = NULL,
1441 .expected_error = NT_STATUS_OK,
1442 .expected_num_results = 1,
1443 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1444 .comment = "NULL DELTA by rid 544"
1447 .rid = 544,
1448 .flags = NETR_CHANGELOG_SID_INCLUDED,
1449 .db_index = SAM_DATABASE_BUILTIN,
1450 .delta_type = 0,
1451 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1452 .name = NULL,
1453 .expected_error = NT_STATUS_OK,
1454 .expected_num_results = 1,
1455 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1456 .comment = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
1459 .rid = 544,
1460 .flags = NETR_CHANGELOG_SID_INCLUDED,
1461 .db_index = SAM_DATABASE_BUILTIN,
1462 .delta_type = NETR_DELTA_ALIAS,
1463 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1464 .name = NULL,
1465 .expected_error = NT_STATUS_OK,
1466 .expected_num_results = 2,
1467 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1468 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1469 .comment = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
1472 .rid = 0,
1473 .flags = NETR_CHANGELOG_SID_INCLUDED,
1474 .db_index = SAM_DATABASE_BUILTIN,
1475 .delta_type = NETR_DELTA_ALIAS,
1476 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1477 .name = NULL,
1478 .expected_error = NT_STATUS_OK,
1479 .expected_num_results = 1,
1480 .expected_delta_type_1 = NETR_DELTA_DELETE_ALIAS,
1481 .comment = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
1484 /* SAM_DATABASE_PRIVS */
1487 .rid = 0,
1488 .flags = 0,
1489 .db_index = SAM_DATABASE_PRIVS,
1490 .delta_type = 0,
1491 .sid = null_sid,
1492 .name = NULL,
1493 .expected_error = NT_STATUS_ACCESS_DENIED,
1494 .expected_num_results = 0,
1495 .comment = "NULL DELTA"
1498 .rid = 0,
1499 .flags = 0,
1500 .db_index = SAM_DATABASE_PRIVS,
1501 .delta_type = NETR_DELTA_MODIFY_COUNT,
1502 .sid = null_sid,
1503 .name = NULL,
1504 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1505 .expected_num_results = 0,
1506 .comment = "NETR_DELTA_MODIFY_COUNT"
1509 .rid = 0,
1510 .flags = 0,
1511 .db_index = SAM_DATABASE_PRIVS,
1512 .delta_type = NETR_DELTA_POLICY,
1513 .sid = null_sid,
1514 .name = NULL,
1515 .expected_error = NT_STATUS_OK,
1516 .expected_num_results = 1,
1517 .expected_delta_type_1 = NETR_DELTA_POLICY,
1518 .comment = "NETR_DELTA_POLICY"
1521 .rid = 0,
1522 .flags = NETR_CHANGELOG_SID_INCLUDED,
1523 .db_index = SAM_DATABASE_PRIVS,
1524 .delta_type = NETR_DELTA_POLICY,
1525 .sid = null_sid,
1526 .name = NULL,
1527 .expected_error = NT_STATUS_OK,
1528 .expected_num_results = 1,
1529 .expected_delta_type_1 = NETR_DELTA_POLICY,
1530 .comment = "NETR_DELTA_POLICY by null sid and flags"
1533 .rid = 0,
1534 .flags = NETR_CHANGELOG_SID_INCLUDED,
1535 .db_index = SAM_DATABASE_PRIVS,
1536 .delta_type = NETR_DELTA_POLICY,
1537 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
1538 .name = NULL,
1539 .expected_error = NT_STATUS_OK,
1540 .expected_num_results = 1,
1541 .expected_delta_type_1 = NETR_DELTA_POLICY,
1542 .comment = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
1545 .rid = DOMAIN_RID_ADMINISTRATOR,
1546 .flags = 0,
1547 .db_index = SAM_DATABASE_PRIVS,
1548 .delta_type = NETR_DELTA_ACCOUNT,
1549 .sid = null_sid,
1550 .name = NULL,
1551 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
1552 .expected_num_results = 0,
1553 .comment = "NETR_DELTA_ACCOUNT by rid 500"
1556 .rid = 0,
1557 .flags = NETR_CHANGELOG_SID_INCLUDED,
1558 .db_index = SAM_DATABASE_PRIVS,
1559 .delta_type = NETR_DELTA_ACCOUNT,
1560 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1561 .name = NULL,
1562 .expected_error = NT_STATUS_OK,
1563 .expected_num_results = 1,
1564 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
1565 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
1568 .rid = 0,
1569 .flags = NETR_CHANGELOG_SID_INCLUDED |
1570 NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
1571 .db_index = SAM_DATABASE_PRIVS,
1572 .delta_type = NETR_DELTA_ACCOUNT,
1573 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1574 .name = NULL,
1575 .expected_error = NT_STATUS_OK,
1576 .expected_num_results = 1,
1577 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
1578 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
1581 .rid = 0,
1582 .flags = NETR_CHANGELOG_SID_INCLUDED |
1583 NETR_CHANGELOG_NAME_INCLUDED,
1584 .db_index = SAM_DATABASE_PRIVS,
1585 .delta_type = NETR_DELTA_ACCOUNT,
1586 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1587 .name = NULL,
1588 .expected_error = NT_STATUS_INVALID_PARAMETER,
1589 .expected_num_results = 0,
1590 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
1593 .rid = DOMAIN_RID_ADMINISTRATOR,
1594 .flags = NETR_CHANGELOG_SID_INCLUDED,
1595 .db_index = SAM_DATABASE_PRIVS,
1596 .delta_type = NETR_DELTA_ACCOUNT,
1597 .sid = *sid,
1598 .name = NULL,
1599 .expected_error = NT_STATUS_OK,
1600 .expected_num_results = 1,
1601 .expected_delta_type_1 = NETR_DELTA_DELETE_ACCOUNT,
1602 .comment = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
1605 .rid = 0,
1606 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1607 .db_index = SAM_DATABASE_PRIVS,
1608 .delta_type = NETR_DELTA_SECRET,
1609 .sid = null_sid,
1610 .name = "IsurelydontexistIhope",
1611 .expected_error = NT_STATUS_OK,
1612 .expected_num_results = 1,
1613 .expected_delta_type_1 = NETR_DELTA_DELETE_SECRET,
1614 .comment = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
1617 .rid = 0,
1618 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1619 .db_index = SAM_DATABASE_PRIVS,
1620 .delta_type = NETR_DELTA_SECRET,
1621 .sid = null_sid,
1622 .name = "G$BCKUPKEY_P",
1623 .expected_error = NT_STATUS_OK,
1624 .expected_num_results = 1,
1625 .expected_delta_type_1 = NETR_DELTA_SECRET,
1626 .comment = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
1630 ZERO_STRUCT(return_authenticator);
1632 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1633 r.in.computername = TEST_MACHINE_NAME;
1634 r.in.return_authenticator = &return_authenticator;
1635 r.out.return_authenticator = &return_authenticator;
1636 r.out.delta_enum_array = &delta_enum_array;
1638 for (d=0; d<3; d++) {
1639 const char *database = NULL;
1641 switch (d) {
1642 case 0:
1643 database = "SAM";
1644 break;
1645 case 1:
1646 database = "BUILTIN";
1647 break;
1648 case 2:
1649 database = "LSA";
1650 break;
1651 default:
1652 break;
1655 torture_comment(tctx, "Testing DatabaseRedo\n");
1657 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1658 return false;
1661 for (i=0;i<ARRAY_SIZE(changes);i++) {
1663 if (d != changes[i].db_index) {
1664 continue;
1667 netlogon_creds_client_authenticator(creds, &credential);
1669 r.in.credential = &credential;
1671 e.serial_number1 = 0;
1672 e.serial_number2 = 0;
1673 e.object_rid = changes[i].rid;
1674 e.flags = changes[i].flags;
1675 e.db_index = changes[i].db_index;
1676 e.delta_type = changes[i].delta_type;
1678 switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
1679 case NETR_CHANGELOG_SID_INCLUDED:
1680 e.object.object_sid = changes[i].sid;
1681 break;
1682 case NETR_CHANGELOG_NAME_INCLUDED:
1683 e.object.object_name = changes[i].name;
1684 break;
1685 default:
1686 break;
1689 r.in.change_log_entry = e;
1691 torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
1692 database, changes[i].comment);
1694 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseRedo_r(b, tctx, &r),
1695 "DatabaseRedo failed");
1696 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1697 return true;
1700 torture_assert_ntstatus_equal(tctx, r.out.result, changes[i].expected_error, changes[i].comment);
1701 if (delta_enum_array) {
1702 torture_assert_int_equal(tctx,
1703 delta_enum_array->num_deltas,
1704 changes[i].expected_num_results,
1705 changes[i].comment);
1706 if (delta_enum_array->num_deltas > 0) {
1707 torture_assert_int_equal(tctx,
1708 delta_enum_array->delta_enum[0].delta_type,
1709 changes[i].expected_delta_type_1,
1710 changes[i].comment);
1712 if (delta_enum_array->num_deltas > 1) {
1713 torture_assert_int_equal(tctx,
1714 delta_enum_array->delta_enum[1].delta_type,
1715 changes[i].expected_delta_type_2,
1716 changes[i].comment);
1720 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1721 torture_comment(tctx, "Credential chaining failed\n");
1722 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1723 return false;
1730 return true;
1734 try a netlogon AccountDeltas
1736 static bool test_AccountDeltas(struct torture_context *tctx,
1737 struct dcerpc_pipe *p,
1738 struct cli_credentials *machine_credentials)
1740 struct netr_AccountDeltas r;
1741 struct netlogon_creds_CredentialState *creds;
1743 struct netr_AccountBuffer buffer;
1744 uint32_t count_returned = 0;
1745 uint32_t total_entries = 0;
1746 struct netr_UAS_INFO_0 recordid;
1747 struct netr_Authenticator return_authenticator;
1748 struct dcerpc_binding_handle *b = p->binding_handle;
1750 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1751 return false;
1754 ZERO_STRUCT(return_authenticator);
1756 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1757 r.in.computername = TEST_MACHINE_NAME;
1758 r.in.return_authenticator = &return_authenticator;
1759 netlogon_creds_client_authenticator(creds, &r.in.credential);
1760 ZERO_STRUCT(r.in.uas);
1761 r.in.count=10;
1762 r.in.level=0;
1763 r.in.buffersize=100;
1764 r.out.buffer = &buffer;
1765 r.out.count_returned = &count_returned;
1766 r.out.total_entries = &total_entries;
1767 r.out.recordid = &recordid;
1768 r.out.return_authenticator = &return_authenticator;
1770 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1771 torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountDeltas_r(b, tctx, &r),
1772 "AccountDeltas failed");
1773 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
1775 return true;
1779 try a netlogon AccountSync
1781 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
1782 struct cli_credentials *machine_credentials)
1784 struct netr_AccountSync r;
1785 struct netlogon_creds_CredentialState *creds;
1787 struct netr_AccountBuffer buffer;
1788 uint32_t count_returned = 0;
1789 uint32_t total_entries = 0;
1790 uint32_t next_reference = 0;
1791 struct netr_UAS_INFO_0 recordid;
1792 struct netr_Authenticator return_authenticator;
1793 struct dcerpc_binding_handle *b = p->binding_handle;
1795 ZERO_STRUCT(recordid);
1796 ZERO_STRUCT(return_authenticator);
1798 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1799 return false;
1802 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1803 r.in.computername = TEST_MACHINE_NAME;
1804 r.in.return_authenticator = &return_authenticator;
1805 netlogon_creds_client_authenticator(creds, &r.in.credential);
1806 r.in.recordid = &recordid;
1807 r.in.reference=0;
1808 r.in.level=0;
1809 r.in.buffersize=100;
1810 r.out.buffer = &buffer;
1811 r.out.count_returned = &count_returned;
1812 r.out.total_entries = &total_entries;
1813 r.out.next_reference = &next_reference;
1814 r.out.recordid = &recordid;
1815 r.out.return_authenticator = &return_authenticator;
1817 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1818 torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountSync_r(b, tctx, &r),
1819 "AccountSync failed");
1820 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
1822 return true;
1826 try a netlogon GetDcName
1828 static bool test_GetDcName(struct torture_context *tctx,
1829 struct dcerpc_pipe *p)
1831 struct netr_GetDcName r;
1832 const char *dcname = NULL;
1833 struct dcerpc_binding_handle *b = p->binding_handle;
1835 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1836 r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
1837 r.out.dcname = &dcname;
1839 torture_assert_ntstatus_ok(tctx, dcerpc_netr_GetDcName_r(b, tctx, &r),
1840 "GetDcName failed");
1841 torture_assert_werr_ok(tctx, r.out.result, "GetDcName failed");
1843 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1845 return true;
1848 static const char *function_code_str(TALLOC_CTX *mem_ctx,
1849 enum netr_LogonControlCode function_code)
1851 switch (function_code) {
1852 case NETLOGON_CONTROL_QUERY:
1853 return "NETLOGON_CONTROL_QUERY";
1854 case NETLOGON_CONTROL_REPLICATE:
1855 return "NETLOGON_CONTROL_REPLICATE";
1856 case NETLOGON_CONTROL_SYNCHRONIZE:
1857 return "NETLOGON_CONTROL_SYNCHRONIZE";
1858 case NETLOGON_CONTROL_PDC_REPLICATE:
1859 return "NETLOGON_CONTROL_PDC_REPLICATE";
1860 case NETLOGON_CONTROL_REDISCOVER:
1861 return "NETLOGON_CONTROL_REDISCOVER";
1862 case NETLOGON_CONTROL_TC_QUERY:
1863 return "NETLOGON_CONTROL_TC_QUERY";
1864 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1865 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
1866 case NETLOGON_CONTROL_FIND_USER:
1867 return "NETLOGON_CONTROL_FIND_USER";
1868 case NETLOGON_CONTROL_CHANGE_PASSWORD:
1869 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
1870 case NETLOGON_CONTROL_TC_VERIFY:
1871 return "NETLOGON_CONTROL_TC_VERIFY";
1872 case NETLOGON_CONTROL_FORCE_DNS_REG:
1873 return "NETLOGON_CONTROL_FORCE_DNS_REG";
1874 case NETLOGON_CONTROL_QUERY_DNS_REG:
1875 return "NETLOGON_CONTROL_QUERY_DNS_REG";
1876 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1877 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
1878 case NETLOGON_CONTROL_TRUNCATE_LOG:
1879 return "NETLOGON_CONTROL_TRUNCATE_LOG";
1880 case NETLOGON_CONTROL_SET_DBFLAG:
1881 return "NETLOGON_CONTROL_SET_DBFLAG";
1882 case NETLOGON_CONTROL_BREAKPOINT:
1883 return "NETLOGON_CONTROL_BREAKPOINT";
1884 default:
1885 return talloc_asprintf(mem_ctx, "unknown function code: %d",
1886 function_code);
1892 try a netlogon LogonControl
1894 static bool test_LogonControl(struct torture_context *tctx,
1895 struct dcerpc_pipe *p,
1896 struct cli_credentials *machine_credentials)
1899 NTSTATUS status;
1900 struct netr_LogonControl r;
1901 union netr_CONTROL_QUERY_INFORMATION query;
1902 int i,f;
1903 enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
1904 struct dcerpc_binding_handle *b = p->binding_handle;
1906 uint32_t function_codes[] = {
1907 NETLOGON_CONTROL_QUERY,
1908 NETLOGON_CONTROL_REPLICATE,
1909 NETLOGON_CONTROL_SYNCHRONIZE,
1910 NETLOGON_CONTROL_PDC_REPLICATE,
1911 NETLOGON_CONTROL_REDISCOVER,
1912 NETLOGON_CONTROL_TC_QUERY,
1913 NETLOGON_CONTROL_TRANSPORT_NOTIFY,
1914 NETLOGON_CONTROL_FIND_USER,
1915 NETLOGON_CONTROL_CHANGE_PASSWORD,
1916 NETLOGON_CONTROL_TC_VERIFY,
1917 NETLOGON_CONTROL_FORCE_DNS_REG,
1918 NETLOGON_CONTROL_QUERY_DNS_REG,
1919 NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
1920 NETLOGON_CONTROL_TRUNCATE_LOG,
1921 NETLOGON_CONTROL_SET_DBFLAG,
1922 NETLOGON_CONTROL_BREAKPOINT
1925 if (machine_credentials) {
1926 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1929 torture_comment(tctx, "Testing LogonControl with secure channel type: %d\n",
1930 secure_channel_type);
1932 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1933 r.in.function_code = 1;
1934 r.out.query = &query;
1936 for (f=0;f<ARRAY_SIZE(function_codes); f++) {
1937 for (i=1;i<5;i++) {
1939 r.in.function_code = function_codes[f];
1940 r.in.level = i;
1942 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
1943 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1945 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
1946 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1948 switch (r.in.level) {
1949 case 1:
1950 switch (r.in.function_code) {
1951 case NETLOGON_CONTROL_REPLICATE:
1952 case NETLOGON_CONTROL_SYNCHRONIZE:
1953 case NETLOGON_CONTROL_PDC_REPLICATE:
1954 case NETLOGON_CONTROL_BREAKPOINT:
1955 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1956 if ((secure_channel_type == SEC_CHAN_BDC) ||
1957 (secure_channel_type == SEC_CHAN_WKSTA)) {
1958 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1959 "LogonControl returned unexpected error code");
1960 } else {
1961 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1962 "LogonControl returned unexpected error code");
1964 break;
1966 case NETLOGON_CONTROL_REDISCOVER:
1967 case NETLOGON_CONTROL_TC_QUERY:
1968 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1969 case NETLOGON_CONTROL_FIND_USER:
1970 case NETLOGON_CONTROL_CHANGE_PASSWORD:
1971 case NETLOGON_CONTROL_TC_VERIFY:
1972 case NETLOGON_CONTROL_FORCE_DNS_REG:
1973 case NETLOGON_CONTROL_QUERY_DNS_REG:
1974 case NETLOGON_CONTROL_SET_DBFLAG:
1975 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1976 "LogonControl returned unexpected error code");
1977 break;
1978 case NETLOGON_CONTROL_TRUNCATE_LOG:
1979 if ((secure_channel_type == SEC_CHAN_BDC) ||
1980 (secure_channel_type == SEC_CHAN_WKSTA)) {
1981 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1982 "LogonControl returned unexpected error code");
1983 } else {
1984 torture_assert_werr_ok(tctx, r.out.result,
1985 "LogonControl returned unexpected result");
1987 break;
1988 default:
1989 torture_assert_werr_ok(tctx, r.out.result,
1990 "LogonControl returned unexpected result");
1991 break;
1993 break;
1994 case 2:
1995 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1996 "LogonControl returned unexpected error code");
1997 break;
1998 default:
1999 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL,
2000 "LogonControl returned unexpected error code");
2001 break;
2006 r.in.level = 52;
2007 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
2008 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2009 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
2010 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2011 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl");
2013 return true;
2018 try a netlogon GetAnyDCName
2020 static bool test_GetAnyDCName(struct torture_context *tctx,
2021 struct dcerpc_pipe *p)
2023 NTSTATUS status;
2024 struct netr_GetAnyDCName r;
2025 const char *dcname = NULL;
2026 struct dcerpc_binding_handle *b = p->binding_handle;
2028 r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
2029 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2030 r.out.dcname = &dcname;
2032 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2033 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2034 if ((!W_ERROR_IS_OK(r.out.result)) &&
2035 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2036 return false;
2039 if (dcname) {
2040 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
2043 r.in.domainname = NULL;
2045 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2046 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2047 if ((!W_ERROR_IS_OK(r.out.result)) &&
2048 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2049 return false;
2052 r.in.domainname = "";
2054 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
2055 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2056 if ((!W_ERROR_IS_OK(r.out.result)) &&
2057 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
2058 return false;
2061 return true;
2066 try a netlogon LogonControl2
2068 static bool test_LogonControl2(struct torture_context *tctx,
2069 struct dcerpc_pipe *p,
2070 struct cli_credentials *machine_credentials)
2073 NTSTATUS status;
2074 struct netr_LogonControl2 r;
2075 union netr_CONTROL_DATA_INFORMATION data;
2076 union netr_CONTROL_QUERY_INFORMATION query;
2077 int i;
2078 struct dcerpc_binding_handle *b = p->binding_handle;
2080 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2082 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2084 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2085 r.in.data = &data;
2086 r.out.query = &query;
2088 for (i=1;i<4;i++) {
2089 r.in.level = i;
2091 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2092 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2094 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2095 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2098 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2100 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2101 r.in.data = &data;
2103 for (i=1;i<4;i++) {
2104 r.in.level = i;
2106 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2107 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2109 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2110 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2113 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2115 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2116 r.in.data = &data;
2118 for (i=1;i<4;i++) {
2119 r.in.level = i;
2121 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2122 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2124 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2125 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2128 data.debug_level = ~0;
2130 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2131 r.in.data = &data;
2133 for (i=1;i<4;i++) {
2134 r.in.level = i;
2136 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2137 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2139 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2140 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2143 ZERO_STRUCT(data);
2144 r.in.function_code = 52;
2145 r.in.data = &data;
2147 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2148 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2150 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2151 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2152 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "LogonControl2");
2154 data.debug_level = ~0;
2156 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2157 r.in.data = &data;
2159 r.in.level = 52;
2160 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2161 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2163 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2164 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2165 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "LogonControl2");
2167 return true;
2171 try a netlogon DatabaseSync2
2173 static bool test_DatabaseSync2(struct torture_context *tctx,
2174 struct dcerpc_pipe *p,
2175 struct cli_credentials *machine_credentials)
2177 struct netr_DatabaseSync2 r;
2178 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2179 struct netr_Authenticator return_authenticator, credential;
2181 struct netlogon_creds_CredentialState *creds;
2182 const uint32_t database_ids[] = {0, 1, 2};
2183 int i;
2184 struct dcerpc_binding_handle *b = p->binding_handle;
2186 if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
2187 machine_credentials,
2188 cli_credentials_get_secure_channel_type(machine_credentials),
2189 &creds)) {
2190 return false;
2193 ZERO_STRUCT(return_authenticator);
2195 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2196 r.in.computername = TEST_MACHINE_NAME;
2197 r.in.preferredmaximumlength = (uint32_t)-1;
2198 r.in.return_authenticator = &return_authenticator;
2199 r.out.return_authenticator = &return_authenticator;
2200 r.out.delta_enum_array = &delta_enum_array;
2202 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2204 uint32_t sync_context = 0;
2206 r.in.database_id = database_ids[i];
2207 r.in.sync_context = &sync_context;
2208 r.out.sync_context = &sync_context;
2209 r.in.restart_state = 0;
2211 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
2213 do {
2214 netlogon_creds_client_authenticator(creds, &credential);
2216 r.in.credential = &credential;
2218 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync2_r(b, tctx, &r),
2219 "DatabaseSync2 failed");
2220 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2221 break;
2223 /* Native mode servers don't do this */
2224 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
2225 return true;
2228 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync2");
2230 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
2231 torture_comment(tctx, "Credential chaining failed\n");
2234 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2237 return true;
2242 try a netlogon LogonControl2Ex
2244 static bool test_LogonControl2Ex(struct torture_context *tctx,
2245 struct dcerpc_pipe *p,
2246 struct cli_credentials *machine_credentials)
2249 NTSTATUS status;
2250 struct netr_LogonControl2Ex r;
2251 union netr_CONTROL_DATA_INFORMATION data;
2252 union netr_CONTROL_QUERY_INFORMATION query;
2253 int i;
2254 struct dcerpc_binding_handle *b = p->binding_handle;
2256 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2258 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2260 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2261 r.in.data = &data;
2262 r.out.query = &query;
2264 for (i=1;i<4;i++) {
2265 r.in.level = i;
2267 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2268 i, r.in.function_code);
2270 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2271 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2274 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2276 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2277 r.in.data = &data;
2279 for (i=1;i<4;i++) {
2280 r.in.level = i;
2282 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2283 i, r.in.function_code);
2285 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2286 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2289 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2291 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2292 r.in.data = &data;
2294 for (i=1;i<4;i++) {
2295 r.in.level = i;
2297 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2298 i, r.in.function_code);
2300 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2301 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2304 data.debug_level = ~0;
2306 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2307 r.in.data = &data;
2309 for (i=1;i<4;i++) {
2310 r.in.level = i;
2312 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2313 i, r.in.function_code);
2315 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2316 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2319 return true;
2322 static bool test_netr_GetForestTrustInformation(struct torture_context *tctx,
2323 struct dcerpc_pipe *p,
2324 struct cli_credentials *machine_credentials)
2326 struct netr_GetForestTrustInformation r;
2327 struct netlogon_creds_CredentialState *creds;
2328 struct netr_Authenticator a;
2329 struct netr_Authenticator return_authenticator;
2330 struct lsa_ForestTrustInformation *forest_trust_info;
2331 struct dcerpc_binding_handle *b = p->binding_handle;
2333 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2334 machine_credentials, &creds)) {
2335 return false;
2338 netlogon_creds_client_authenticator(creds, &a);
2340 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2341 r.in.computer_name = TEST_MACHINE_NAME;
2342 r.in.credential = &a;
2343 r.in.flags = 0;
2344 r.out.return_authenticator = &return_authenticator;
2345 r.out.forest_trust_info = &forest_trust_info;
2347 torture_assert_ntstatus_ok(tctx,
2348 dcerpc_netr_GetForestTrustInformation_r(b, tctx, &r),
2349 "netr_GetForestTrustInformation failed");
2350 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2351 torture_comment(tctx, "not considering NT_STATUS_NOT_IMPLEMENTED as an error\n");
2352 } else {
2353 torture_assert_ntstatus_ok(tctx, r.out.result,
2354 "netr_GetForestTrustInformation failed");
2357 torture_assert(tctx,
2358 netlogon_creds_client_check(creds, &return_authenticator.cred),
2359 "Credential chaining failed");
2361 return true;
2364 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
2365 struct dcerpc_pipe *p, const char *trusted_domain_name)
2367 NTSTATUS status;
2368 struct netr_DsRGetForestTrustInformation r;
2369 struct lsa_ForestTrustInformation info, *info_ptr;
2370 struct dcerpc_binding_handle *b = p->binding_handle;
2372 info_ptr = &info;
2374 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2375 r.in.trusted_domain_name = trusted_domain_name;
2376 r.in.flags = 0;
2377 r.out.forest_trust_info = &info_ptr;
2379 torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
2381 status = dcerpc_netr_DsRGetForestTrustInformation_r(b, tctx, &r);
2382 torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
2383 torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
2385 return true;
2389 try a netlogon netr_DsrEnumerateDomainTrusts
2391 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
2392 struct dcerpc_pipe *p)
2394 NTSTATUS status;
2395 struct netr_DsrEnumerateDomainTrusts r;
2396 struct netr_DomainTrustList trusts;
2397 int i;
2398 struct dcerpc_binding_handle *b = p->binding_handle;
2400 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2401 r.in.trust_flags = 0x3f;
2402 r.out.trusts = &trusts;
2404 status = dcerpc_netr_DsrEnumerateDomainTrusts_r(b, tctx, &r);
2405 torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
2406 torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
2408 /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
2409 * will show non-forest trusts and all UPN suffixes of the own forest
2410 * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
2412 if (r.out.trusts->count) {
2413 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
2414 return false;
2418 for (i=0; i<r.out.trusts->count; i++) {
2420 /* get info for transitive forest trusts */
2422 if (r.out.trusts->array[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2423 if (!test_netr_DsRGetForestTrustInformation(tctx, p,
2424 r.out.trusts->array[i].dns_name)) {
2425 return false;
2430 return true;
2433 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
2434 struct dcerpc_pipe *p)
2436 NTSTATUS status;
2437 struct netr_NetrEnumerateTrustedDomains r;
2438 struct netr_Blob trusted_domains_blob;
2439 struct dcerpc_binding_handle *b = p->binding_handle;
2441 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2442 r.out.trusted_domains_blob = &trusted_domains_blob;
2444 status = dcerpc_netr_NetrEnumerateTrustedDomains_r(b, tctx, &r);
2445 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
2446 torture_assert_ntstatus_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
2448 return true;
2451 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
2452 struct dcerpc_pipe *p)
2454 NTSTATUS status;
2455 struct netr_NetrEnumerateTrustedDomainsEx r;
2456 struct netr_DomainTrustList dom_trust_list;
2457 struct dcerpc_binding_handle *b = p->binding_handle;
2459 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2460 r.out.dom_trust_list = &dom_trust_list;
2462 status = dcerpc_netr_NetrEnumerateTrustedDomainsEx_r(b, tctx, &r);
2463 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
2464 torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
2466 return true;
2470 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
2471 const char *computer_name,
2472 const char *expected_site)
2474 NTSTATUS status;
2475 struct netr_DsRGetSiteName r;
2476 const char *site = NULL;
2477 struct dcerpc_binding_handle *b = p->binding_handle;
2479 r.in.computer_name = computer_name;
2480 r.out.site = &site;
2481 torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
2483 status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
2484 torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2485 torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
2486 torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
2488 return true;
2492 try a netlogon netr_DsRGetDCName
2494 static bool test_netr_DsRGetDCName(struct torture_context *tctx,
2495 struct dcerpc_pipe *p)
2497 NTSTATUS status;
2498 struct netr_DsRGetDCName r;
2499 struct netr_DsRGetDCNameInfo *info = NULL;
2500 struct dcerpc_binding_handle *b = p->binding_handle;
2502 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2503 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
2504 r.in.domain_guid = NULL;
2505 r.in.site_guid = NULL;
2506 r.in.flags = DS_RETURN_DNS_NAME;
2507 r.out.info = &info;
2509 status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2510 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2511 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2513 torture_assert_int_equal(tctx,
2514 (info->dc_flags & (DS_DNS_CONTROLLER)),
2515 DS_DNS_CONTROLLER,
2516 "DsRGetDCName");
2517 torture_assert_int_equal(tctx,
2518 (info->dc_flags & (DS_DNS_DOMAIN)),
2519 DS_DNS_DOMAIN,
2520 "DsRGetDCName");
2521 torture_assert_int_equal(tctx,
2522 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2523 DS_DNS_FOREST_ROOT,
2524 "DsRGetDCName");
2526 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
2527 r.in.flags = 0;
2529 status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2530 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2531 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2533 torture_assert_int_equal(tctx,
2534 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2535 "DsRGetDCName");
2536 torture_assert_int_equal(tctx,
2537 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2538 "DsRGetDCName");
2539 torture_assert_int_equal(tctx,
2540 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2541 DS_DNS_FOREST_ROOT,
2542 "DsRGetDCName");
2544 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2545 torture_assert_int_equal(tctx,
2546 (info->dc_flags & (DS_SERVER_CLOSEST)),
2547 DS_SERVER_CLOSEST,
2548 "DsRGetDCName");
2551 return test_netr_DsRGetSiteName(p, tctx,
2552 info->dc_unc,
2553 info->dc_site_name);
2557 try a netlogon netr_DsRGetDCNameEx
2559 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
2560 struct dcerpc_pipe *p)
2562 NTSTATUS status;
2563 struct netr_DsRGetDCNameEx r;
2564 struct netr_DsRGetDCNameInfo *info = NULL;
2565 struct dcerpc_binding_handle *b = p->binding_handle;
2567 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2568 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
2569 r.in.domain_guid = NULL;
2570 r.in.site_name = NULL;
2571 r.in.flags = DS_RETURN_DNS_NAME;
2572 r.out.info = &info;
2574 status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2575 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2576 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2578 torture_assert_int_equal(tctx,
2579 (info->dc_flags & (DS_DNS_CONTROLLER)),
2580 DS_DNS_CONTROLLER,
2581 "DsRGetDCNameEx");
2582 torture_assert_int_equal(tctx,
2583 (info->dc_flags & (DS_DNS_DOMAIN)),
2584 DS_DNS_DOMAIN,
2585 "DsRGetDCNameEx");
2586 torture_assert_int_equal(tctx,
2587 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2588 DS_DNS_FOREST_ROOT,
2589 "DsRGetDCNameEx");
2591 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
2592 r.in.flags = 0;
2594 status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2595 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2596 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2598 torture_assert_int_equal(tctx,
2599 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2600 "DsRGetDCNameEx");
2601 torture_assert_int_equal(tctx,
2602 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2603 "DsRGetDCNameEx");
2604 torture_assert_int_equal(tctx,
2605 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2606 DS_DNS_FOREST_ROOT,
2607 "DsRGetDCNameEx");
2609 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2610 torture_assert_int_equal(tctx,
2611 (info->dc_flags & (DS_SERVER_CLOSEST)),
2612 DS_SERVER_CLOSEST,
2613 "DsRGetDCNameEx");
2616 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2617 info->dc_site_name);
2621 try a netlogon netr_DsRGetDCNameEx2
2623 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
2624 struct dcerpc_pipe *p)
2626 NTSTATUS status;
2627 struct netr_DsRGetDCNameEx2 r;
2628 struct netr_DsRGetDCNameInfo *info = NULL;
2629 struct dcerpc_binding_handle *b = p->binding_handle;
2631 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with no inputs\n");
2632 ZERO_STRUCT(r.in);
2633 r.in.flags = DS_RETURN_DNS_NAME;
2634 r.out.info = &info;
2636 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2637 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2638 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2640 torture_assert_int_equal(tctx,
2641 (info->dc_flags & (DS_DNS_CONTROLLER)),
2642 DS_DNS_CONTROLLER,
2643 "DsRGetDCNameEx2");
2644 torture_assert_int_equal(tctx,
2645 (info->dc_flags & (DS_DNS_DOMAIN)),
2646 DS_DNS_DOMAIN,
2647 "DsRGetDCNameEx2");
2648 torture_assert_int_equal(tctx,
2649 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2650 DS_DNS_FOREST_ROOT,
2651 "DsRGetDCNameEx2");
2653 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2654 r.in.client_account = NULL;
2655 r.in.mask = 0x00000000;
2656 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
2657 r.in.domain_guid = NULL;
2658 r.in.site_name = NULL;
2659 r.in.flags = DS_RETURN_DNS_NAME;
2660 r.out.info = &info;
2662 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
2664 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2665 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2666 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2668 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
2669 r.in.flags = 0;
2671 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2672 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2673 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2675 torture_assert_int_equal(tctx,
2676 (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
2677 "DsRGetDCNameEx2");
2678 torture_assert_int_equal(tctx,
2679 (info->dc_flags & (DS_DNS_DOMAIN)), 0,
2680 "DsRGetDCNameEx2");
2681 torture_assert_int_equal(tctx,
2682 (info->dc_flags & (DS_DNS_FOREST_ROOT)),
2683 DS_DNS_FOREST_ROOT,
2684 "DsRGetDCNameEx2");
2686 if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
2687 torture_assert_int_equal(tctx,
2688 (info->dc_flags & (DS_SERVER_CLOSEST)),
2689 DS_SERVER_CLOSEST,
2690 "DsRGetDCNameEx2");
2693 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client account\n");
2694 r.in.client_account = TEST_MACHINE_NAME"$";
2695 r.in.mask = ACB_SVRTRUST;
2696 r.in.flags = DS_RETURN_FLAT_NAME;
2697 r.out.info = &info;
2699 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2700 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2701 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2703 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2704 info->dc_site_name);
2707 /* This is a substitution for "samdb_server_site_name" which relies on the
2708 * correct "lp_ctx" and therefore can't be used here. */
2709 static const char *server_site_name(struct torture_context *tctx,
2710 struct ldb_context *ldb)
2712 TALLOC_CTX *tmp_ctx;
2713 struct ldb_dn *dn, *server_dn;
2714 const struct ldb_val *site_name_val;
2715 const char *server_dn_str, *site_name;
2717 tmp_ctx = talloc_new(ldb);
2718 if (tmp_ctx == NULL) {
2719 goto failed;
2722 dn = ldb_dn_new(tmp_ctx, ldb, "");
2723 if (dn == NULL) {
2724 goto failed;
2727 server_dn_str = samdb_search_string(ldb, tmp_ctx, dn, "serverName",
2728 NULL);
2729 if (server_dn_str == NULL) {
2730 goto failed;
2733 server_dn = ldb_dn_new(tmp_ctx, ldb, server_dn_str);
2734 if (server_dn == NULL) {
2735 goto failed;
2738 /* CN=<Server name>, CN=Servers, CN=<Site name>, CN=Sites, ... */
2739 site_name_val = ldb_dn_get_component_val(server_dn, 2);
2740 if (site_name_val == NULL) {
2741 goto failed;
2744 site_name = (const char *) site_name_val->data;
2746 talloc_steal(tctx, site_name);
2747 talloc_free(tmp_ctx);
2749 return site_name;
2751 failed:
2752 talloc_free(tmp_ctx);
2753 return NULL;
2756 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
2757 struct dcerpc_pipe *p)
2759 char *url;
2760 struct ldb_context *sam_ctx = NULL;
2761 NTSTATUS status;
2762 struct netr_DsrGetDcSiteCoverageW r;
2763 struct DcSitesCtr *ctr = NULL;
2764 struct dcerpc_binding_handle *b = p->binding_handle;
2766 torture_comment(tctx, "This does only pass with the default site\n");
2768 /* We won't double-check this when we are over 'local' transports */
2769 if (dcerpc_server_name(p)) {
2770 /* Set up connection to SAMDB on DC */
2771 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2772 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2773 NULL,
2774 cmdline_credentials,
2777 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2780 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2781 r.out.ctr = &ctr;
2783 status = dcerpc_netr_DsrGetDcSiteCoverageW_r(b, tctx, &r);
2784 torture_assert_ntstatus_ok(tctx, status, "failed");
2785 torture_assert_werr_ok(tctx, r.out.result, "failed");
2787 torture_assert(tctx, ctr->num_sites == 1,
2788 "we should per default only get the default site");
2789 if (sam_ctx != NULL) {
2790 torture_assert_casestr_equal(tctx, ctr->sites[0].string,
2791 server_site_name(tctx, sam_ctx),
2792 "didn't return default site");
2795 return true;
2798 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
2799 struct dcerpc_pipe *p)
2801 char *url;
2802 struct ldb_context *sam_ctx = NULL;
2803 NTSTATUS status;
2804 struct netr_DsRAddressToSitenamesW r;
2805 struct netr_DsRAddress addrs[6];
2806 struct sockaddr_in *addr;
2807 #ifdef HAVE_IPV6
2808 struct sockaddr_in6 *addr6;
2809 #endif
2810 struct netr_DsRAddressToSitenamesWCtr *ctr;
2811 struct dcerpc_binding_handle *b = p->binding_handle;
2812 uint32_t i;
2813 int ret;
2815 torture_comment(tctx, "This does only pass with the default site\n");
2817 /* We won't double-check this when we are over 'local' transports */
2818 if (dcerpc_server_name(p)) {
2819 /* Set up connection to SAMDB on DC */
2820 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2821 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2822 NULL,
2823 cmdline_credentials,
2826 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2829 /* First try valid IP addresses */
2831 addrs[0].size = sizeof(struct sockaddr_in);
2832 addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
2833 addr = (struct sockaddr_in *) addrs[0].buffer;
2834 addrs[0].buffer[0] = AF_INET;
2835 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2836 torture_assert(tctx, ret > 0, "inet_pton failed");
2838 addrs[1].size = sizeof(struct sockaddr_in);
2839 addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
2840 addr = (struct sockaddr_in *) addrs[1].buffer;
2841 addrs[1].buffer[0] = AF_INET;
2842 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2843 torture_assert(tctx, ret > 0, "inet_pton failed");
2845 addrs[2].size = sizeof(struct sockaddr_in);
2846 addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
2847 addr = (struct sockaddr_in *) addrs[2].buffer;
2848 addrs[2].buffer[0] = AF_INET;
2849 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2850 torture_assert(tctx, ret > 0, "inet_pton failed");
2852 #ifdef HAVE_IPV6
2853 addrs[3].size = sizeof(struct sockaddr_in6);
2854 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2855 addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
2856 addrs[3].buffer[0] = AF_INET6;
2857 ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
2858 torture_assert(tctx, ret > 0, "inet_pton failed");
2860 addrs[4].size = sizeof(struct sockaddr_in6);
2861 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2862 addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
2863 addrs[4].buffer[0] = AF_INET6;
2864 ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
2865 torture_assert(tctx, ret > 0, "inet_pton failed");
2867 addrs[5].size = sizeof(struct sockaddr_in6);
2868 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2869 addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
2870 addrs[5].buffer[0] = AF_INET6;
2871 ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
2872 torture_assert(tctx, ret > 0, "inet_pton failed");
2873 #else
2874 /* the test cases are repeated to have exactly 6. This is for
2875 * compatibility with IPv4-only machines */
2876 addrs[3].size = sizeof(struct sockaddr_in);
2877 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2878 addr = (struct sockaddr_in *) addrs[3].buffer;
2879 addrs[3].buffer[0] = AF_INET;
2880 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2881 torture_assert(tctx, ret > 0, "inet_pton failed");
2883 addrs[4].size = sizeof(struct sockaddr_in);
2884 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2885 addr = (struct sockaddr_in *) addrs[4].buffer;
2886 addrs[4].buffer[0] = AF_INET;
2887 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2888 torture_assert(tctx, ret > 0, "inet_pton failed");
2890 addrs[5].size = sizeof(struct sockaddr_in);
2891 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2892 addr = (struct sockaddr_in *) addrs[5].buffer;
2893 addrs[5].buffer[0] = AF_INET;
2894 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2895 torture_assert(tctx, ret > 0, "inet_pton failed");
2896 #endif
2898 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
2900 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2901 r.in.count = 6;
2902 r.in.addresses = addrs;
2903 r.out.ctr = &ctr;
2905 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2906 torture_assert_ntstatus_ok(tctx, status, "failed");
2907 torture_assert_werr_ok(tctx, r.out.result, "failed");
2909 if (sam_ctx != NULL) {
2910 for (i = 0; i < 3; i++) {
2911 torture_assert_casestr_equal(tctx,
2912 ctr->sitename[i].string,
2913 server_site_name(tctx, sam_ctx),
2914 "didn't return default site");
2916 for (i = 3; i < 6; i++) {
2917 /* Windows returns "NULL" for the sitename if it isn't
2918 * IPv6 configured */
2919 if (torture_setting_bool(tctx, "samba4", false)) {
2920 torture_assert_casestr_equal(tctx,
2921 ctr->sitename[i].string,
2922 server_site_name(tctx, sam_ctx),
2923 "didn't return default site");
2928 /* Now try invalid ones (too short buffers) */
2930 addrs[0].size = 0;
2931 addrs[1].size = 1;
2932 addrs[2].size = 4;
2934 addrs[3].size = 0;
2935 addrs[4].size = 1;
2936 addrs[5].size = 4;
2938 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2939 torture_assert_ntstatus_ok(tctx, status, "failed");
2940 torture_assert_werr_ok(tctx, r.out.result, "failed");
2942 for (i = 0; i < 6; i++) {
2943 torture_assert(tctx, ctr->sitename[i].string == NULL,
2944 "sitename should be null");
2947 /* Now try invalid ones (wrong address types) */
2949 addrs[0].size = 10;
2950 addrs[0].buffer[0] = AF_UNSPEC;
2951 addrs[1].size = 10;
2952 addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
2953 addrs[2].size = 10;
2954 addrs[2].buffer[0] = AF_UNIX;
2956 addrs[3].size = 10;
2957 addrs[3].buffer[0] = 250;
2958 addrs[4].size = 10;
2959 addrs[4].buffer[0] = 251;
2960 addrs[5].size = 10;
2961 addrs[5].buffer[0] = 252;
2963 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2964 torture_assert_ntstatus_ok(tctx, status, "failed");
2965 torture_assert_werr_ok(tctx, r.out.result, "failed");
2967 for (i = 0; i < 6; i++) {
2968 torture_assert(tctx, ctr->sitename[i].string == NULL,
2969 "sitename should be null");
2972 return true;
2975 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
2976 struct dcerpc_pipe *p)
2978 char *url;
2979 struct ldb_context *sam_ctx = NULL;
2980 NTSTATUS status;
2981 struct netr_DsRAddressToSitenamesExW r;
2982 struct netr_DsRAddress addrs[6];
2983 struct sockaddr_in *addr;
2984 #ifdef HAVE_IPV6
2985 struct sockaddr_in6 *addr6;
2986 #endif
2987 struct netr_DsRAddressToSitenamesExWCtr *ctr;
2988 struct dcerpc_binding_handle *b = p->binding_handle;
2989 uint32_t i;
2990 int ret;
2992 torture_comment(tctx, "This does pass with the default site\n");
2994 /* We won't double-check this when we are over 'local' transports */
2995 if (dcerpc_server_name(p)) {
2996 /* Set up connection to SAMDB on DC */
2997 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2998 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2999 NULL,
3000 cmdline_credentials,
3003 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3006 /* First try valid IP addresses */
3008 addrs[0].size = sizeof(struct sockaddr_in);
3009 addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
3010 addr = (struct sockaddr_in *) addrs[0].buffer;
3011 addrs[0].buffer[0] = AF_INET;
3012 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3013 torture_assert(tctx, ret > 0, "inet_pton failed");
3015 addrs[1].size = sizeof(struct sockaddr_in);
3016 addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
3017 addr = (struct sockaddr_in *) addrs[1].buffer;
3018 addrs[1].buffer[0] = AF_INET;
3019 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3020 torture_assert(tctx, ret > 0, "inet_pton failed");
3022 addrs[2].size = sizeof(struct sockaddr_in);
3023 addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
3024 addr = (struct sockaddr_in *) addrs[2].buffer;
3025 addrs[2].buffer[0] = AF_INET;
3026 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3027 torture_assert(tctx, ret > 0, "inet_pton failed");
3029 #ifdef HAVE_IPV6
3030 addrs[3].size = sizeof(struct sockaddr_in6);
3031 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3032 addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
3033 addrs[3].buffer[0] = AF_INET6;
3034 ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
3035 torture_assert(tctx, ret > 0, "inet_pton failed");
3037 addrs[4].size = sizeof(struct sockaddr_in6);
3038 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3039 addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
3040 addrs[4].buffer[0] = AF_INET6;
3041 ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
3042 torture_assert(tctx, ret > 0, "inet_pton failed");
3044 addrs[5].size = sizeof(struct sockaddr_in6);
3045 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3046 addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
3047 addrs[5].buffer[0] = AF_INET6;
3048 ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
3049 torture_assert(tctx, ret > 0, "inet_pton failed");
3050 #else
3051 /* the test cases are repeated to have exactly 6. This is for
3052 * compatibility with IPv4-only machines */
3053 addrs[3].size = sizeof(struct sockaddr_in);
3054 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
3055 addr = (struct sockaddr_in *) addrs[3].buffer;
3056 addrs[3].buffer[0] = AF_INET;
3057 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
3058 torture_assert(tctx, ret > 0, "inet_pton failed");
3060 addrs[4].size = sizeof(struct sockaddr_in);
3061 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
3062 addr = (struct sockaddr_in *) addrs[4].buffer;
3063 addrs[4].buffer[0] = AF_INET;
3064 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
3065 torture_assert(tctx, ret > 0, "inet_pton failed");
3067 addrs[5].size = sizeof(struct sockaddr_in);
3068 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
3069 addr = (struct sockaddr_in *) addrs[5].buffer;
3070 addrs[5].buffer[0] = AF_INET;
3071 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
3072 torture_assert(tctx, ret > 0, "inet_pton failed");
3073 #endif
3075 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
3077 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3078 r.in.count = 6;
3079 r.in.addresses = addrs;
3080 r.out.ctr = &ctr;
3082 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3083 torture_assert_ntstatus_ok(tctx, status, "failed");
3084 torture_assert_werr_ok(tctx, r.out.result, "failed");
3086 if (sam_ctx != NULL) {
3087 for (i = 0; i < 3; i++) {
3088 torture_assert_casestr_equal(tctx,
3089 ctr->sitename[i].string,
3090 server_site_name(tctx, sam_ctx),
3091 "didn't return default site");
3092 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3093 "subnet should be null");
3095 for (i = 3; i < 6; i++) {
3096 /* Windows returns "NULL" for the sitename if it isn't
3097 * IPv6 configured */
3098 if (torture_setting_bool(tctx, "samba4", false)) {
3099 torture_assert_casestr_equal(tctx,
3100 ctr->sitename[i].string,
3101 server_site_name(tctx, sam_ctx),
3102 "didn't return default site");
3104 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3105 "subnet should be null");
3109 /* Now try invalid ones (too short buffers) */
3111 addrs[0].size = 0;
3112 addrs[1].size = 1;
3113 addrs[2].size = 4;
3115 addrs[3].size = 0;
3116 addrs[4].size = 1;
3117 addrs[5].size = 4;
3119 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3120 torture_assert_ntstatus_ok(tctx, status, "failed");
3121 torture_assert_werr_ok(tctx, r.out.result, "failed");
3123 for (i = 0; i < 6; i++) {
3124 torture_assert(tctx, ctr->sitename[i].string == NULL,
3125 "sitename should be null");
3126 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3127 "subnet should be null");
3130 addrs[0].size = 10;
3131 addrs[0].buffer[0] = AF_UNSPEC;
3132 addrs[1].size = 10;
3133 addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
3134 addrs[2].size = 10;
3135 addrs[2].buffer[0] = AF_UNIX;
3137 addrs[3].size = 10;
3138 addrs[3].buffer[0] = 250;
3139 addrs[4].size = 10;
3140 addrs[4].buffer[0] = 251;
3141 addrs[5].size = 10;
3142 addrs[5].buffer[0] = 252;
3144 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
3145 torture_assert_ntstatus_ok(tctx, status, "failed");
3146 torture_assert_werr_ok(tctx, r.out.result, "failed");
3148 for (i = 0; i < 6; i++) {
3149 torture_assert(tctx, ctr->sitename[i].string == NULL,
3150 "sitename should be null");
3151 torture_assert(tctx, ctr->subnetname[i].string == NULL,
3152 "subnet should be null");
3155 return true;
3158 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
3159 struct dcerpc_pipe *p,
3160 struct cli_credentials *machine_credentials)
3162 struct netr_ServerGetTrustInfo r;
3164 struct netr_Authenticator a;
3165 struct netr_Authenticator return_authenticator;
3166 struct samr_Password new_owf_password;
3167 struct samr_Password old_owf_password;
3168 struct netr_TrustInfo *trust_info;
3170 struct netlogon_creds_CredentialState *creds;
3171 struct dcerpc_binding_handle *b = p->binding_handle;
3173 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3174 machine_credentials, &creds)) {
3175 return false;
3178 netlogon_creds_client_authenticator(creds, &a);
3180 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3181 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
3182 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
3183 r.in.computer_name = TEST_MACHINE_NAME;
3184 r.in.credential = &a;
3186 r.out.return_authenticator = &return_authenticator;
3187 r.out.new_owf_password = &new_owf_password;
3188 r.out.old_owf_password = &old_owf_password;
3189 r.out.trust_info = &trust_info;
3191 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerGetTrustInfo_r(b, tctx, &r),
3192 "ServerGetTrustInfo failed");
3193 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerGetTrustInfo failed");
3194 torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
3196 return true;
3200 static bool test_GetDomainInfo(struct torture_context *tctx,
3201 struct dcerpc_pipe *p,
3202 struct cli_credentials *machine_credentials)
3204 struct netr_LogonGetDomainInfo r;
3205 struct netr_WorkstationInformation q1;
3206 struct netr_Authenticator a;
3207 struct netlogon_creds_CredentialState *creds;
3208 struct netr_OsVersion os;
3209 union netr_WorkstationInfo query;
3210 union netr_DomainInfo info;
3211 const char* const attrs[] = { "dNSHostName", "operatingSystem",
3212 "operatingSystemServicePack", "operatingSystemVersion",
3213 "servicePrincipalName", NULL };
3214 char *url;
3215 struct ldb_context *sam_ctx = NULL;
3216 struct ldb_message **res;
3217 struct ldb_message_element *spn_el;
3218 int ret, i;
3219 char *version_str;
3220 const char *old_dnsname = NULL;
3221 char **spns = NULL;
3222 int num_spns = 0;
3223 char *temp_str;
3224 struct dcerpc_binding_handle *b = p->binding_handle;
3226 torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
3228 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3229 machine_credentials, &creds)) {
3230 return false;
3233 /* We won't double-check this when we are over 'local' transports */
3234 if (dcerpc_server_name(p)) {
3235 /* Set up connection to SAMDB on DC */
3236 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3237 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3238 NULL,
3239 cmdline_credentials,
3242 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3245 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
3246 netlogon_creds_client_authenticator(creds, &a);
3248 ZERO_STRUCT(r);
3249 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3250 r.in.computer_name = TEST_MACHINE_NAME;
3251 r.in.credential = &a;
3252 r.in.level = 1;
3253 r.in.return_authenticator = &a;
3254 r.in.query = &query;
3255 r.out.return_authenticator = &a;
3256 r.out.info = &info;
3258 ZERO_STRUCT(os);
3259 os.os.MajorVersion = 123;
3260 os.os.MinorVersion = 456;
3261 os.os.BuildNumber = 789;
3262 os.os.CSDVersion = "Service Pack 10";
3263 os.os.ServicePackMajor = 10;
3264 os.os.ServicePackMinor = 1;
3265 os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
3266 os.os.ProductType = NETR_VER_NT_SERVER;
3267 os.os.Reserved = 0;
3269 version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
3270 os.os.MinorVersion, os.os.BuildNumber);
3272 ZERO_STRUCT(q1);
3273 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3274 lpcfg_dnsdomain(tctx->lp_ctx));
3275 q1.sitename = "Default-First-Site-Name";
3276 q1.os_version.os = &os;
3277 q1.os_name.string = talloc_asprintf(tctx,
3278 "Tortured by Samba4 RPC-NETLOGON: %s",
3279 timestring(tctx, time(NULL)));
3281 /* The workstation handles the "servicePrincipalName" and DNS hostname
3282 updates */
3283 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3285 query.workstation_info = &q1;
3287 if (sam_ctx) {
3288 /* Gets back the old DNS hostname in AD */
3289 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3290 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3291 old_dnsname =
3292 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
3294 /* Gets back the "servicePrincipalName"s in AD */
3295 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3296 if (spn_el != NULL) {
3297 for (i=0; i < spn_el->num_values; i++) {
3298 spns = talloc_realloc(tctx, spns, char *, i + 1);
3299 spns[i] = (char *) spn_el->values[i].data;
3301 num_spns = i;
3305 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3306 "LogonGetDomainInfo failed");
3307 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3308 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3310 smb_msleep(250);
3312 if (sam_ctx) {
3313 /* AD workstation infos entry check */
3314 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3315 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3316 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3317 torture_assert_str_equal(tctx,
3318 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3319 q1.os_name.string, "'operatingSystem' wrong!");
3320 torture_assert_str_equal(tctx,
3321 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
3322 os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
3323 torture_assert_str_equal(tctx,
3324 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
3325 version_str, "'operatingSystemVersion' wrong!");
3327 if (old_dnsname != NULL) {
3328 /* If before a DNS hostname was set then it should remain
3329 the same in combination with the "servicePrincipalName"s.
3330 The DNS hostname should also be returned by our
3331 "LogonGetDomainInfo" call (in the domain info structure). */
3333 torture_assert_str_equal(tctx,
3334 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3335 old_dnsname, "'DNS hostname' was not set!");
3337 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3338 torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
3339 "'servicePrincipalName's not set!");
3340 torture_assert(tctx, spn_el->num_values == num_spns,
3341 "'servicePrincipalName's incorrect!");
3342 for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
3343 torture_assert_str_equal(tctx,
3344 (char *) spn_el->values[i].data,
3345 spns[i], "'servicePrincipalName's incorrect!");
3347 torture_assert_str_equal(tctx,
3348 info.domain_info->dns_hostname.string,
3349 old_dnsname,
3350 "Out 'DNS hostname' doesn't match the old one!");
3351 } else {
3352 /* If no DNS hostname was set then also now none should be set,
3353 the "servicePrincipalName"s should remain empty and no DNS
3354 hostname should be returned by our "LogonGetDomainInfo"
3355 call (in the domain info structure). */
3357 torture_assert(tctx,
3358 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
3359 "'DNS hostname' was set!");
3361 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3362 torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
3363 "'servicePrincipalName's were set!");
3365 torture_assert(tctx,
3366 info.domain_info->dns_hostname.string == NULL,
3367 "Out 'DNS host name' was set!");
3371 /* Checks "workstation flags" */
3372 torture_assert(tctx,
3373 info.domain_info->workstation_flags
3374 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3375 "Out 'workstation flags' don't match!");
3378 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname doesn't work)\n");
3379 netlogon_creds_client_authenticator(creds, &a);
3381 /* Wipe out the osVersion, and prove which values still 'stick' */
3382 q1.os_version.os = NULL;
3384 /* Change also the DNS hostname to test differences in behaviour */
3385 talloc_free(discard_const_p(char, q1.dns_hostname));
3386 q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3387 lpcfg_dnsdomain(tctx->lp_ctx));
3389 /* The workstation handles the "servicePrincipalName" and DNS hostname
3390 updates */
3391 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3393 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3394 "LogonGetDomainInfo failed");
3395 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3397 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3399 smb_msleep(250);
3401 if (sam_ctx) {
3402 /* AD workstation infos entry check */
3403 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3404 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3405 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3407 torture_assert_str_equal(tctx,
3408 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3409 q1.os_name.string, "'operatingSystem' should stick!");
3410 torture_assert(tctx,
3411 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3412 "'operatingSystemServicePack' shouldn't stick!");
3413 torture_assert(tctx,
3414 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3415 "'operatingSystemVersion' shouldn't stick!");
3417 /* The DNS host name shouldn't have been updated by the server */
3419 torture_assert_str_equal(tctx,
3420 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3421 old_dnsname, "'DNS host name' did change!");
3423 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3424 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3425 3.5.4.3.9 */
3426 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3427 torture_assert(tctx, spn_el != NULL,
3428 "There should exist 'servicePrincipalName's in AD!");
3429 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3430 for (i=0; i < spn_el->num_values; i++)
3431 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3432 break;
3433 torture_assert(tctx, i != spn_el->num_values,
3434 "'servicePrincipalName' HOST/<Netbios name> not found!");
3435 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3436 for (i=0; i < spn_el->num_values; i++)
3437 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3438 break;
3439 torture_assert(tctx, i != spn_el->num_values,
3440 "'servicePrincipalName' HOST/<FQDN name> not found!");
3442 /* Check that the out DNS hostname was set properly */
3443 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
3444 old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
3447 /* Checks "workstation flags" */
3448 torture_assert(tctx,
3449 info.domain_info->workstation_flags == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3450 "Out 'workstation flags' don't match!");
3453 /* Now try the same but the workstation flags set to 0 */
3455 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (variation of DNS hostname doesn't work)\n");
3456 netlogon_creds_client_authenticator(creds, &a);
3458 /* Change also the DNS hostname to test differences in behaviour */
3459 talloc_free(discard_const_p(char, q1.dns_hostname));
3460 q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3461 lpcfg_dnsdomain(tctx->lp_ctx));
3463 /* Wipe out the osVersion, and prove which values still 'stick' */
3464 q1.os_version.os = NULL;
3466 /* Let the DC handle the "servicePrincipalName" and DNS hostname
3467 updates */
3468 q1.workstation_flags = 0;
3470 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3471 "LogonGetDomainInfo failed");
3472 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3473 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3475 smb_msleep(250);
3477 if (sam_ctx) {
3478 /* AD workstation infos entry check */
3479 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3480 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3481 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3483 torture_assert_str_equal(tctx,
3484 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3485 q1.os_name.string, "'operatingSystem' should stick!");
3486 torture_assert(tctx,
3487 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3488 "'operatingSystemServicePack' shouldn't stick!");
3489 torture_assert(tctx,
3490 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3491 "'operatingSystemVersion' shouldn't stick!");
3493 /* The DNS host name shouldn't have been updated by the server */
3495 torture_assert_str_equal(tctx,
3496 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3497 old_dnsname, "'DNS host name' did change!");
3499 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3500 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3501 3.5.4.3.9 */
3502 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3503 torture_assert(tctx, spn_el != NULL,
3504 "There should exist 'servicePrincipalName's in AD!");
3505 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3506 for (i=0; i < spn_el->num_values; i++)
3507 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3508 break;
3509 torture_assert(tctx, i != spn_el->num_values,
3510 "'servicePrincipalName' HOST/<Netbios name> not found!");
3511 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3512 for (i=0; i < spn_el->num_values; i++)
3513 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3514 break;
3515 torture_assert(tctx, i != spn_el->num_values,
3516 "'servicePrincipalName' HOST/<FQDN name> not found!");
3518 /* Here the server gives us NULL as the out DNS hostname */
3519 torture_assert(tctx, info.domain_info->dns_hostname.string == NULL,
3520 "Out 'DNS hostname' should be NULL!");
3523 /* Checks "workstation flags" */
3524 torture_assert(tctx,
3525 info.domain_info->workstation_flags == 0,
3526 "Out 'workstation flags' don't match!");
3529 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (verification of DNS hostname and check for trusted domains)\n");
3530 netlogon_creds_client_authenticator(creds, &a);
3532 /* Put the DNS hostname back */
3533 talloc_free(discard_const_p(char, q1.dns_hostname));
3534 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3535 lpcfg_dnsdomain(tctx->lp_ctx));
3537 /* The workstation handles the "servicePrincipalName" and DNS hostname
3538 updates */
3539 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3541 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3542 "LogonGetDomainInfo failed");
3543 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3544 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3546 smb_msleep(250);
3548 /* Now the in/out DNS hostnames should be the same */
3549 torture_assert_str_equal(tctx,
3550 info.domain_info->dns_hostname.string,
3551 query.workstation_info->dns_hostname,
3552 "In/Out 'DNS hostnames' don't match!");
3553 old_dnsname = info.domain_info->dns_hostname.string;
3555 /* Checks "workstation flags" */
3556 torture_assert(tctx,
3557 info.domain_info->workstation_flags
3558 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
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 5th call (check for trusted domains)\n");
3569 netlogon_creds_client_authenticator(creds, &a);
3571 /* The workstation handles the "servicePrincipalName" and DNS hostname
3572 updates and requests inbound trusts */
3573 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
3574 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
3576 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3577 "LogonGetDomainInfo failed");
3578 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3579 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3581 smb_msleep(250);
3583 /* Checks "workstation flags" */
3584 torture_assert(tctx,
3585 info.domain_info->workstation_flags
3586 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
3587 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
3588 "Out 'workstation flags' don't match!");
3590 /* Checks for trusted domains */
3591 torture_assert(tctx,
3592 (info.domain_info->trusted_domain_count != 0)
3593 && (info.domain_info->trusted_domains != NULL),
3594 "Trusted domains have been requested!");
3597 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
3598 netlogon_creds_client_authenticator(creds, &a);
3600 query.workstation_info->dns_hostname = NULL;
3602 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3603 "LogonGetDomainInfo failed");
3604 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3605 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3607 /* The old DNS hostname should stick */
3608 torture_assert_str_equal(tctx,
3609 info.domain_info->dns_hostname.string,
3610 old_dnsname,
3611 "'DNS hostname' changed!");
3613 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (extra workstation flags)\n");
3614 netlogon_creds_client_authenticator(creds, &a);
3616 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
3617 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | 0x4;
3619 /* Put the DNS hostname back */
3620 talloc_free(discard_const_p(char, q1.dns_hostname));
3621 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3622 lpcfg_dnsdomain(tctx->lp_ctx));
3624 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3625 "LogonGetDomainInfo failed");
3626 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3627 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3629 /* Checks "workstation flags" */
3630 torture_assert(tctx,
3631 info.domain_info->workstation_flags
3632 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
3633 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
3634 "Out 'workstation flags' don't match!");
3636 if (!torture_setting_bool(tctx, "dangerous", false)) {
3637 torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 8th call (no workstation info) - enable dangerous tests in order to do so\n");
3638 } else {
3639 /* Try a call without the workstation information structure */
3641 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 8th call (no workstation info)\n");
3642 netlogon_creds_client_authenticator(creds, &a);
3644 query.workstation_info = NULL;
3646 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3647 "LogonGetDomainInfo failed");
3648 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3649 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3652 return true;
3655 static bool test_GetDomainInfo_async(struct torture_context *tctx,
3656 struct dcerpc_pipe *p,
3657 struct cli_credentials *machine_credentials)
3659 NTSTATUS status;
3660 struct netr_LogonGetDomainInfo r;
3661 struct netr_WorkstationInformation q1;
3662 struct netr_Authenticator a;
3663 #define ASYNC_COUNT 100
3664 struct netlogon_creds_CredentialState *creds;
3665 struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
3666 struct tevent_req *req[ASYNC_COUNT];
3667 int i;
3668 union netr_WorkstationInfo query;
3669 union netr_DomainInfo info;
3671 torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
3673 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3674 machine_credentials, &creds)) {
3675 return false;
3678 ZERO_STRUCT(r);
3679 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3680 r.in.computer_name = TEST_MACHINE_NAME;
3681 r.in.credential = &a;
3682 r.in.level = 1;
3683 r.in.return_authenticator = &a;
3684 r.in.query = &query;
3685 r.out.return_authenticator = &a;
3686 r.out.info = &info;
3688 ZERO_STRUCT(q1);
3689 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3690 lpcfg_dnsdomain(tctx->lp_ctx));
3691 q1.sitename = "Default-First-Site-Name";
3692 q1.os_name.string = "UNIX/Linux or similar";
3694 query.workstation_info = &q1;
3696 for (i=0;i<ASYNC_COUNT;i++) {
3697 netlogon_creds_client_authenticator(creds, &a);
3699 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
3700 req[i] = dcerpc_netr_LogonGetDomainInfo_r_send(tctx, tctx->ev, p->binding_handle, &r);
3702 /* even with this flush per request a w2k3 server seems to
3703 clag with multiple outstanding requests. bleergh. */
3704 torture_assert_int_equal(tctx, tevent_loop_once(dcerpc_event_context(p)), 0,
3705 "tevent_loop_once failed");
3708 for (i=0;i<ASYNC_COUNT;i++) {
3709 torture_assert_int_equal(tctx, tevent_req_poll(req[i], tctx->ev), true,
3710 "tevent_req_poll() failed");
3712 status = dcerpc_netr_LogonGetDomainInfo_r_recv(req[i], tctx);
3714 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
3715 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
3717 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred),
3718 "Credential chaining failed at async");
3721 torture_comment(tctx,
3722 "Testing netr_LogonGetDomainInfo - async count %d OK\n", ASYNC_COUNT);
3724 return true;
3727 static bool test_ManyGetDCName(struct torture_context *tctx,
3728 struct dcerpc_pipe *p)
3730 NTSTATUS status;
3731 struct dcerpc_pipe *p2;
3732 struct lsa_ObjectAttribute attr;
3733 struct lsa_QosInfo qos;
3734 struct lsa_OpenPolicy2 o;
3735 struct policy_handle lsa_handle;
3736 struct lsa_DomainList domains;
3738 struct lsa_EnumTrustDom t;
3739 uint32_t resume_handle = 0;
3740 struct netr_GetAnyDCName d;
3741 const char *dcname = NULL;
3742 struct dcerpc_binding_handle *b = p->binding_handle;
3743 struct dcerpc_binding_handle *b2;
3745 int i;
3747 if (p->conn->transport.transport != NCACN_NP) {
3748 return true;
3751 torture_comment(tctx, "Torturing GetDCName\n");
3753 status = dcerpc_secondary_connection(p, &p2, p->binding);
3754 torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
3756 status = dcerpc_bind_auth_none(p2, &ndr_table_lsarpc);
3757 torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
3758 b2 = p2->binding_handle;
3760 qos.len = 0;
3761 qos.impersonation_level = 2;
3762 qos.context_mode = 1;
3763 qos.effective_only = 0;
3765 attr.len = 0;
3766 attr.root_dir = NULL;
3767 attr.object_name = NULL;
3768 attr.attributes = 0;
3769 attr.sec_desc = NULL;
3770 attr.sec_qos = &qos;
3772 o.in.system_name = "\\";
3773 o.in.attr = &attr;
3774 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3775 o.out.handle = &lsa_handle;
3777 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
3778 "OpenPolicy2 failed");
3779 torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
3781 t.in.handle = &lsa_handle;
3782 t.in.resume_handle = &resume_handle;
3783 t.in.max_size = 1000;
3784 t.out.domains = &domains;
3785 t.out.resume_handle = &resume_handle;
3787 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b2, tctx, &t),
3788 "EnumTrustDom failed");
3790 if ((!NT_STATUS_IS_OK(t.out.result) &&
3791 (!NT_STATUS_EQUAL(t.out.result, NT_STATUS_NO_MORE_ENTRIES))))
3792 torture_fail(tctx, "Could not list domains");
3794 talloc_free(p2);
3796 d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
3797 dcerpc_server_name(p));
3798 d.out.dcname = &dcname;
3800 for (i=0; i<domains.count * 4; i++) {
3801 struct lsa_DomainInfo *info =
3802 &domains.domains[rand()%domains.count];
3804 d.in.domainname = info->name.string;
3806 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &d);
3807 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3809 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
3810 dcname ? dcname : "unknown");
3813 return true;
3816 static bool test_SetPassword_with_flags(struct torture_context *tctx,
3817 struct dcerpc_pipe *p,
3818 struct cli_credentials *machine_credentials)
3820 uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
3821 struct netlogon_creds_CredentialState *creds;
3822 int i;
3824 if (!test_SetupCredentials2(p, tctx, 0,
3825 machine_credentials,
3826 cli_credentials_get_secure_channel_type(machine_credentials),
3827 &creds)) {
3828 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
3831 for (i=0; i < ARRAY_SIZE(flags); i++) {
3832 torture_assert(tctx,
3833 test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
3834 talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
3837 return true;
3840 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
3842 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon");
3843 struct torture_rpc_tcase *tcase;
3844 struct torture_test *test;
3846 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3847 &ndr_table_netlogon, TEST_MACHINE_NAME);
3849 torture_rpc_tcase_add_test(tcase, "Broken RPC binding handle",
3850 test_netr_broken_binding_handle);
3852 torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
3853 torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
3854 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
3855 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
3856 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
3857 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
3858 torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
3859 torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
3860 torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
3861 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
3862 torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
3863 torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
3864 torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
3865 torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
3866 torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
3867 torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
3868 torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
3869 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
3870 torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
3871 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
3872 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
3873 test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
3874 test->dangerous = true;
3875 torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
3876 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
3877 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
3878 torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
3879 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
3880 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
3881 torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
3882 torture_rpc_tcase_add_test_creds(tcase, "GetForestTrustInformation", test_netr_GetForestTrustInformation);
3884 return suite;
3887 struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
3889 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon-s3");
3890 struct torture_rpc_tcase *tcase;
3892 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3893 &ndr_table_netlogon, TEST_MACHINE_NAME);
3895 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
3896 torture_rpc_tcase_add_test_creds(tcase, "SamLogon_NULL_domain", test_SamLogon_NULL_domain);
3897 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
3898 torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
3899 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
3900 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
3901 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
3903 return suite;
3906 struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
3908 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon.admin");
3909 struct torture_rpc_tcase *tcase;
3911 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3912 &ndr_table_netlogon, TEST_MACHINE_NAME);
3913 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3914 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3915 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3917 tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netlogon",
3918 &ndr_table_netlogon, TEST_MACHINE_NAME);
3919 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3920 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3921 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3923 tcase = torture_suite_add_rpc_iface_tcase(suite, "netlogon",
3924 &ndr_table_netlogon);
3925 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3926 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3927 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3929 return suite;