s4-torture: validate owf password hash and negotiate AES ServerGetTrustInfo test.
[Samba/bb.git] / source4 / torture / rpc / netlogon.c
blobdadf8bc4f9880957a995d9d0902f49a72faa2a55
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 = NetlogonNetworkInformation;
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 = NetlogonNetworkInformation;
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_flags(struct torture_context *tctx,
3159 struct dcerpc_pipe *p,
3160 struct cli_credentials *machine_credentials,
3161 uint32_t negotiate_flags)
3163 struct netr_ServerGetTrustInfo r;
3165 struct netr_Authenticator a;
3166 struct netr_Authenticator return_authenticator;
3167 struct samr_Password new_owf_password;
3168 struct samr_Password old_owf_password;
3169 struct netr_TrustInfo *trust_info;
3171 struct netlogon_creds_CredentialState *creds;
3172 struct dcerpc_binding_handle *b = p->binding_handle;
3174 struct samr_Password nt_hash;
3176 if (!test_SetupCredentials3(p, tctx, negotiate_flags,
3177 machine_credentials, &creds)) {
3178 return false;
3181 netlogon_creds_client_authenticator(creds, &a);
3183 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3184 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
3185 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
3186 r.in.computer_name = TEST_MACHINE_NAME;
3187 r.in.credential = &a;
3189 r.out.return_authenticator = &return_authenticator;
3190 r.out.new_owf_password = &new_owf_password;
3191 r.out.old_owf_password = &old_owf_password;
3192 r.out.trust_info = &trust_info;
3194 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerGetTrustInfo_r(b, tctx, &r),
3195 "ServerGetTrustInfo failed");
3196 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerGetTrustInfo failed");
3197 torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
3199 E_md4hash(cli_credentials_get_password(machine_credentials), nt_hash.hash);
3201 netlogon_creds_des_decrypt(creds, &new_owf_password);
3203 dump_data(1, new_owf_password.hash, 16);
3204 dump_data(1, nt_hash.hash, 16);
3206 torture_assert_mem_equal(tctx, new_owf_password.hash, nt_hash.hash, 16,
3207 "received unexpected owf password\n");
3209 return true;
3212 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
3213 struct dcerpc_pipe *p,
3214 struct cli_credentials *machine_credentials)
3216 return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
3217 NETLOGON_NEG_AUTH2_ADS_FLAGS);
3220 static bool test_netr_ServerGetTrustInfo_AES(struct torture_context *tctx,
3221 struct dcerpc_pipe *p,
3222 struct cli_credentials *machine_credentials)
3224 return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
3225 NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
3228 static bool test_GetDomainInfo(struct torture_context *tctx,
3229 struct dcerpc_pipe *p,
3230 struct cli_credentials *machine_credentials)
3232 struct netr_LogonGetDomainInfo r;
3233 struct netr_WorkstationInformation q1;
3234 struct netr_Authenticator a;
3235 struct netlogon_creds_CredentialState *creds;
3236 struct netr_OsVersion os;
3237 union netr_WorkstationInfo query;
3238 union netr_DomainInfo info;
3239 const char* const attrs[] = { "dNSHostName", "operatingSystem",
3240 "operatingSystemServicePack", "operatingSystemVersion",
3241 "servicePrincipalName", NULL };
3242 char *url;
3243 struct ldb_context *sam_ctx = NULL;
3244 struct ldb_message **res;
3245 struct ldb_message_element *spn_el;
3246 int ret, i;
3247 char *version_str;
3248 const char *old_dnsname = NULL;
3249 char **spns = NULL;
3250 int num_spns = 0;
3251 char *temp_str;
3252 struct dcerpc_binding_handle *b = p->binding_handle;
3254 torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
3256 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3257 machine_credentials, &creds)) {
3258 return false;
3261 /* We won't double-check this when we are over 'local' transports */
3262 if (dcerpc_server_name(p)) {
3263 /* Set up connection to SAMDB on DC */
3264 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3265 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3266 NULL,
3267 cmdline_credentials,
3270 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3273 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
3274 netlogon_creds_client_authenticator(creds, &a);
3276 ZERO_STRUCT(r);
3277 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3278 r.in.computer_name = TEST_MACHINE_NAME;
3279 r.in.credential = &a;
3280 r.in.level = 1;
3281 r.in.return_authenticator = &a;
3282 r.in.query = &query;
3283 r.out.return_authenticator = &a;
3284 r.out.info = &info;
3286 ZERO_STRUCT(os);
3287 os.os.MajorVersion = 123;
3288 os.os.MinorVersion = 456;
3289 os.os.BuildNumber = 789;
3290 os.os.CSDVersion = "Service Pack 10";
3291 os.os.ServicePackMajor = 10;
3292 os.os.ServicePackMinor = 1;
3293 os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
3294 os.os.ProductType = NETR_VER_NT_SERVER;
3295 os.os.Reserved = 0;
3297 version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
3298 os.os.MinorVersion, os.os.BuildNumber);
3300 ZERO_STRUCT(q1);
3301 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3302 lpcfg_dnsdomain(tctx->lp_ctx));
3303 q1.sitename = "Default-First-Site-Name";
3304 q1.os_version.os = &os;
3305 q1.os_name.string = talloc_asprintf(tctx,
3306 "Tortured by Samba4 RPC-NETLOGON: %s",
3307 timestring(tctx, time(NULL)));
3309 /* The workstation handles the "servicePrincipalName" and DNS hostname
3310 updates */
3311 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3313 query.workstation_info = &q1;
3315 if (sam_ctx) {
3316 /* Gets back the old DNS hostname in AD */
3317 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3318 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3319 old_dnsname =
3320 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
3322 /* Gets back the "servicePrincipalName"s in AD */
3323 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3324 if (spn_el != NULL) {
3325 for (i=0; i < spn_el->num_values; i++) {
3326 spns = talloc_realloc(tctx, spns, char *, i + 1);
3327 spns[i] = (char *) spn_el->values[i].data;
3329 num_spns = i;
3333 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3334 "LogonGetDomainInfo failed");
3335 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3336 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3338 smb_msleep(250);
3340 if (sam_ctx) {
3341 /* AD workstation infos entry check */
3342 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3343 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3344 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3345 torture_assert_str_equal(tctx,
3346 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3347 q1.os_name.string, "'operatingSystem' wrong!");
3348 torture_assert_str_equal(tctx,
3349 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
3350 os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
3351 torture_assert_str_equal(tctx,
3352 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
3353 version_str, "'operatingSystemVersion' wrong!");
3355 if (old_dnsname != NULL) {
3356 /* If before a DNS hostname was set then it should remain
3357 the same in combination with the "servicePrincipalName"s.
3358 The DNS hostname should also be returned by our
3359 "LogonGetDomainInfo" call (in the domain info structure). */
3361 torture_assert_str_equal(tctx,
3362 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3363 old_dnsname, "'DNS hostname' was not set!");
3365 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3366 torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
3367 "'servicePrincipalName's not set!");
3368 torture_assert(tctx, spn_el->num_values == num_spns,
3369 "'servicePrincipalName's incorrect!");
3370 for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
3371 torture_assert_str_equal(tctx,
3372 (char *) spn_el->values[i].data,
3373 spns[i], "'servicePrincipalName's incorrect!");
3375 torture_assert_str_equal(tctx,
3376 info.domain_info->dns_hostname.string,
3377 old_dnsname,
3378 "Out 'DNS hostname' doesn't match the old one!");
3379 } else {
3380 /* If no DNS hostname was set then also now none should be set,
3381 the "servicePrincipalName"s should remain empty and no DNS
3382 hostname should be returned by our "LogonGetDomainInfo"
3383 call (in the domain info structure). */
3385 torture_assert(tctx,
3386 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
3387 "'DNS hostname' was set!");
3389 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3390 torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
3391 "'servicePrincipalName's were set!");
3393 torture_assert(tctx,
3394 info.domain_info->dns_hostname.string == NULL,
3395 "Out 'DNS host name' was set!");
3399 /* Checks "workstation flags" */
3400 torture_assert(tctx,
3401 info.domain_info->workstation_flags
3402 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3403 "Out 'workstation flags' don't match!");
3406 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname doesn't work)\n");
3407 netlogon_creds_client_authenticator(creds, &a);
3409 /* Wipe out the osVersion, and prove which values still 'stick' */
3410 q1.os_version.os = NULL;
3412 /* Change also the DNS hostname to test differences in behaviour */
3413 talloc_free(discard_const_p(char, q1.dns_hostname));
3414 q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3415 lpcfg_dnsdomain(tctx->lp_ctx));
3417 /* The workstation handles the "servicePrincipalName" and DNS hostname
3418 updates */
3419 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3421 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3422 "LogonGetDomainInfo failed");
3423 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3425 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3427 smb_msleep(250);
3429 if (sam_ctx) {
3430 /* AD workstation infos entry check */
3431 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3432 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3433 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3435 torture_assert_str_equal(tctx,
3436 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3437 q1.os_name.string, "'operatingSystem' should stick!");
3438 torture_assert(tctx,
3439 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3440 "'operatingSystemServicePack' shouldn't stick!");
3441 torture_assert(tctx,
3442 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3443 "'operatingSystemVersion' shouldn't stick!");
3445 /* The DNS host name shouldn't have been updated by the server */
3447 torture_assert_str_equal(tctx,
3448 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3449 old_dnsname, "'DNS host name' did change!");
3451 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3452 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3453 3.5.4.3.9 */
3454 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3455 torture_assert(tctx, spn_el != NULL,
3456 "There should exist 'servicePrincipalName's in AD!");
3457 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3458 for (i=0; i < spn_el->num_values; i++)
3459 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3460 break;
3461 torture_assert(tctx, i != spn_el->num_values,
3462 "'servicePrincipalName' HOST/<Netbios name> not found!");
3463 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3464 for (i=0; i < spn_el->num_values; i++)
3465 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3466 break;
3467 torture_assert(tctx, i != spn_el->num_values,
3468 "'servicePrincipalName' HOST/<FQDN name> not found!");
3470 /* Check that the out DNS hostname was set properly */
3471 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
3472 old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
3475 /* Checks "workstation flags" */
3476 torture_assert(tctx,
3477 info.domain_info->workstation_flags == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3478 "Out 'workstation flags' don't match!");
3481 /* Now try the same but the workstation flags set to 0 */
3483 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (variation of DNS hostname doesn't work)\n");
3484 netlogon_creds_client_authenticator(creds, &a);
3486 /* Change also the DNS hostname to test differences in behaviour */
3487 talloc_free(discard_const_p(char, q1.dns_hostname));
3488 q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3489 lpcfg_dnsdomain(tctx->lp_ctx));
3491 /* Wipe out the osVersion, and prove which values still 'stick' */
3492 q1.os_version.os = NULL;
3494 /* Let the DC handle the "servicePrincipalName" and DNS hostname
3495 updates */
3496 q1.workstation_flags = 0;
3498 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3499 "LogonGetDomainInfo failed");
3500 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3501 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3503 smb_msleep(250);
3505 if (sam_ctx) {
3506 /* AD workstation infos entry check */
3507 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3508 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3509 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3511 torture_assert_str_equal(tctx,
3512 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3513 q1.os_name.string, "'operatingSystem' should stick!");
3514 torture_assert(tctx,
3515 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3516 "'operatingSystemServicePack' shouldn't stick!");
3517 torture_assert(tctx,
3518 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3519 "'operatingSystemVersion' shouldn't stick!");
3521 /* The DNS host name shouldn't have been updated by the server */
3523 torture_assert_str_equal(tctx,
3524 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3525 old_dnsname, "'DNS host name' did change!");
3527 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3528 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3529 3.5.4.3.9 */
3530 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3531 torture_assert(tctx, spn_el != NULL,
3532 "There should exist 'servicePrincipalName's in AD!");
3533 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3534 for (i=0; i < spn_el->num_values; i++)
3535 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3536 break;
3537 torture_assert(tctx, i != spn_el->num_values,
3538 "'servicePrincipalName' HOST/<Netbios name> not found!");
3539 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3540 for (i=0; i < spn_el->num_values; i++)
3541 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3542 break;
3543 torture_assert(tctx, i != spn_el->num_values,
3544 "'servicePrincipalName' HOST/<FQDN name> not found!");
3546 /* Here the server gives us NULL as the out DNS hostname */
3547 torture_assert(tctx, info.domain_info->dns_hostname.string == NULL,
3548 "Out 'DNS hostname' should be NULL!");
3551 /* Checks "workstation flags" */
3552 torture_assert(tctx,
3553 info.domain_info->workstation_flags == 0,
3554 "Out 'workstation flags' don't match!");
3557 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (verification of DNS hostname and check for trusted domains)\n");
3558 netlogon_creds_client_authenticator(creds, &a);
3560 /* Put the DNS hostname back */
3561 talloc_free(discard_const_p(char, q1.dns_hostname));
3562 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3563 lpcfg_dnsdomain(tctx->lp_ctx));
3565 /* The workstation handles the "servicePrincipalName" and DNS hostname
3566 updates */
3567 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3569 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3570 "LogonGetDomainInfo failed");
3571 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3572 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3574 smb_msleep(250);
3576 /* Now the in/out DNS hostnames should be the same */
3577 torture_assert_str_equal(tctx,
3578 info.domain_info->dns_hostname.string,
3579 query.workstation_info->dns_hostname,
3580 "In/Out 'DNS hostnames' don't match!");
3581 old_dnsname = info.domain_info->dns_hostname.string;
3583 /* Checks "workstation flags" */
3584 torture_assert(tctx,
3585 info.domain_info->workstation_flags
3586 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3587 "Out 'workstation flags' don't match!");
3589 /* Checks for trusted domains */
3590 torture_assert(tctx,
3591 (info.domain_info->trusted_domain_count != 0)
3592 && (info.domain_info->trusted_domains != NULL),
3593 "Trusted domains have been requested!");
3596 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 5th call (check for trusted domains)\n");
3597 netlogon_creds_client_authenticator(creds, &a);
3599 /* The workstation handles the "servicePrincipalName" and DNS hostname
3600 updates and requests inbound trusts */
3601 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
3602 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
3604 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3605 "LogonGetDomainInfo failed");
3606 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3607 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3609 smb_msleep(250);
3611 /* Checks "workstation flags" */
3612 torture_assert(tctx,
3613 info.domain_info->workstation_flags
3614 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
3615 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
3616 "Out 'workstation flags' don't match!");
3618 /* Checks for trusted domains */
3619 torture_assert(tctx,
3620 (info.domain_info->trusted_domain_count != 0)
3621 && (info.domain_info->trusted_domains != NULL),
3622 "Trusted domains have been requested!");
3625 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
3626 netlogon_creds_client_authenticator(creds, &a);
3628 query.workstation_info->dns_hostname = NULL;
3630 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3631 "LogonGetDomainInfo failed");
3632 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3633 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3635 /* The old DNS hostname should stick */
3636 torture_assert_str_equal(tctx,
3637 info.domain_info->dns_hostname.string,
3638 old_dnsname,
3639 "'DNS hostname' changed!");
3641 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (extra workstation flags)\n");
3642 netlogon_creds_client_authenticator(creds, &a);
3644 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
3645 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | 0x4;
3647 /* Put the DNS hostname back */
3648 talloc_free(discard_const_p(char, q1.dns_hostname));
3649 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3650 lpcfg_dnsdomain(tctx->lp_ctx));
3652 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3653 "LogonGetDomainInfo failed");
3654 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3655 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3657 /* Checks "workstation flags" */
3658 torture_assert(tctx,
3659 info.domain_info->workstation_flags
3660 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
3661 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
3662 "Out 'workstation flags' don't match!");
3664 if (!torture_setting_bool(tctx, "dangerous", false)) {
3665 torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 8th call (no workstation info) - enable dangerous tests in order to do so\n");
3666 } else {
3667 /* Try a call without the workstation information structure */
3669 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 8th call (no workstation info)\n");
3670 netlogon_creds_client_authenticator(creds, &a);
3672 query.workstation_info = NULL;
3674 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3675 "LogonGetDomainInfo failed");
3676 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3677 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3680 return true;
3683 static bool test_GetDomainInfo_async(struct torture_context *tctx,
3684 struct dcerpc_pipe *p,
3685 struct cli_credentials *machine_credentials)
3687 NTSTATUS status;
3688 struct netr_LogonGetDomainInfo r;
3689 struct netr_WorkstationInformation q1;
3690 struct netr_Authenticator a;
3691 #define ASYNC_COUNT 100
3692 struct netlogon_creds_CredentialState *creds;
3693 struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
3694 struct tevent_req *req[ASYNC_COUNT];
3695 int i;
3696 union netr_WorkstationInfo query;
3697 union netr_DomainInfo info;
3699 torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
3701 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3702 machine_credentials, &creds)) {
3703 return false;
3706 ZERO_STRUCT(r);
3707 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3708 r.in.computer_name = TEST_MACHINE_NAME;
3709 r.in.credential = &a;
3710 r.in.level = 1;
3711 r.in.return_authenticator = &a;
3712 r.in.query = &query;
3713 r.out.return_authenticator = &a;
3714 r.out.info = &info;
3716 ZERO_STRUCT(q1);
3717 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3718 lpcfg_dnsdomain(tctx->lp_ctx));
3719 q1.sitename = "Default-First-Site-Name";
3720 q1.os_name.string = "UNIX/Linux or similar";
3722 query.workstation_info = &q1;
3724 for (i=0;i<ASYNC_COUNT;i++) {
3725 netlogon_creds_client_authenticator(creds, &a);
3727 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
3728 req[i] = dcerpc_netr_LogonGetDomainInfo_r_send(tctx, tctx->ev, p->binding_handle, &r);
3730 /* even with this flush per request a w2k3 server seems to
3731 clag with multiple outstanding requests. bleergh. */
3732 torture_assert_int_equal(tctx, tevent_loop_once(dcerpc_event_context(p)), 0,
3733 "tevent_loop_once failed");
3736 for (i=0;i<ASYNC_COUNT;i++) {
3737 torture_assert_int_equal(tctx, tevent_req_poll(req[i], tctx->ev), true,
3738 "tevent_req_poll() failed");
3740 status = dcerpc_netr_LogonGetDomainInfo_r_recv(req[i], tctx);
3742 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
3743 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
3745 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred),
3746 "Credential chaining failed at async");
3749 torture_comment(tctx,
3750 "Testing netr_LogonGetDomainInfo - async count %d OK\n", ASYNC_COUNT);
3752 return true;
3755 static bool test_ManyGetDCName(struct torture_context *tctx,
3756 struct dcerpc_pipe *p)
3758 NTSTATUS status;
3759 struct dcerpc_pipe *p2;
3760 struct lsa_ObjectAttribute attr;
3761 struct lsa_QosInfo qos;
3762 struct lsa_OpenPolicy2 o;
3763 struct policy_handle lsa_handle;
3764 struct lsa_DomainList domains;
3766 struct lsa_EnumTrustDom t;
3767 uint32_t resume_handle = 0;
3768 struct netr_GetAnyDCName d;
3769 const char *dcname = NULL;
3770 struct dcerpc_binding_handle *b = p->binding_handle;
3771 struct dcerpc_binding_handle *b2;
3773 int i;
3775 if (p->conn->transport.transport != NCACN_NP) {
3776 return true;
3779 torture_comment(tctx, "Torturing GetDCName\n");
3781 status = dcerpc_secondary_connection(p, &p2, p->binding);
3782 torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
3784 status = dcerpc_bind_auth_none(p2, &ndr_table_lsarpc);
3785 torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
3786 b2 = p2->binding_handle;
3788 qos.len = 0;
3789 qos.impersonation_level = 2;
3790 qos.context_mode = 1;
3791 qos.effective_only = 0;
3793 attr.len = 0;
3794 attr.root_dir = NULL;
3795 attr.object_name = NULL;
3796 attr.attributes = 0;
3797 attr.sec_desc = NULL;
3798 attr.sec_qos = &qos;
3800 o.in.system_name = "\\";
3801 o.in.attr = &attr;
3802 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3803 o.out.handle = &lsa_handle;
3805 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
3806 "OpenPolicy2 failed");
3807 torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
3809 t.in.handle = &lsa_handle;
3810 t.in.resume_handle = &resume_handle;
3811 t.in.max_size = 1000;
3812 t.out.domains = &domains;
3813 t.out.resume_handle = &resume_handle;
3815 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b2, tctx, &t),
3816 "EnumTrustDom failed");
3818 if ((!NT_STATUS_IS_OK(t.out.result) &&
3819 (!NT_STATUS_EQUAL(t.out.result, NT_STATUS_NO_MORE_ENTRIES))))
3820 torture_fail(tctx, "Could not list domains");
3822 talloc_free(p2);
3824 d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
3825 dcerpc_server_name(p));
3826 d.out.dcname = &dcname;
3828 for (i=0; i<domains.count * 4; i++) {
3829 struct lsa_DomainInfo *info =
3830 &domains.domains[rand()%domains.count];
3832 d.in.domainname = info->name.string;
3834 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &d);
3835 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3837 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
3838 dcname ? dcname : "unknown");
3841 return true;
3844 static bool test_SetPassword_with_flags(struct torture_context *tctx,
3845 struct dcerpc_pipe *p,
3846 struct cli_credentials *machine_credentials)
3848 uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
3849 struct netlogon_creds_CredentialState *creds;
3850 int i;
3852 if (!test_SetupCredentials2(p, tctx, 0,
3853 machine_credentials,
3854 cli_credentials_get_secure_channel_type(machine_credentials),
3855 &creds)) {
3856 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
3859 for (i=0; i < ARRAY_SIZE(flags); i++) {
3860 torture_assert(tctx,
3861 test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
3862 talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
3865 return true;
3868 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
3870 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon");
3871 struct torture_rpc_tcase *tcase;
3872 struct torture_test *test;
3874 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3875 &ndr_table_netlogon, TEST_MACHINE_NAME);
3877 torture_rpc_tcase_add_test(tcase, "Broken RPC binding handle",
3878 test_netr_broken_binding_handle);
3880 torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
3881 torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
3882 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
3883 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
3884 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
3885 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
3886 torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
3887 torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
3888 torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
3889 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
3890 torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
3891 torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
3892 torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
3893 torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
3894 torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
3895 torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
3896 torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
3897 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
3898 torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
3899 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
3900 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
3901 test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
3902 test->dangerous = true;
3903 torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
3904 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
3905 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
3906 torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
3907 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
3908 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
3909 torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
3910 torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo_AES", test_netr_ServerGetTrustInfo_AES);
3911 torture_rpc_tcase_add_test_creds(tcase, "GetForestTrustInformation", test_netr_GetForestTrustInformation);
3913 return suite;
3916 struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
3918 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon-s3");
3919 struct torture_rpc_tcase *tcase;
3921 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3922 &ndr_table_netlogon, TEST_MACHINE_NAME);
3924 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
3925 torture_rpc_tcase_add_test_creds(tcase, "SamLogon_NULL_domain", test_SamLogon_NULL_domain);
3926 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
3927 torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
3928 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
3929 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
3930 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
3932 return suite;
3935 struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
3937 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon.admin");
3938 struct torture_rpc_tcase *tcase;
3940 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3941 &ndr_table_netlogon, TEST_MACHINE_NAME);
3942 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3943 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3944 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3946 tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netlogon",
3947 &ndr_table_netlogon, TEST_MACHINE_NAME);
3948 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3949 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3950 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3952 tcase = torture_suite_add_rpc_iface_tcase(suite, "netlogon",
3953 &ndr_table_netlogon);
3954 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3955 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3956 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3958 return suite;