2 Unix SMB/CIFS implementation.
4 test suite for netlogon rpc operations
6 Copyright (C) Andrew Tridgell 2003
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2004
8 Copyright (C) Tim Potter 2003
9 Copyright (C) Matthias Dieter Wallnöfer 2009
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "lib/events/events.h"
27 #include "lib/cmdline/popt_common.h"
28 #include "torture/rpc/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 "lib/ldb/include/ldb.h"
36 #include "lib/util/util_ldb.h"
37 #include "lib/ldb_wrap.h"
39 #define TEST_MACHINE_NAME "torturetest"
40 #define TEST_MACHINE_DNS_SUFFIX "torturedomain"
42 static bool test_LogonUasLogon(struct torture_context
*tctx
,
43 struct dcerpc_pipe
*p
)
46 struct netr_LogonUasLogon r
;
47 struct netr_UasInfo
*info
= NULL
;
49 r
.in
.server_name
= NULL
;
50 r
.in
.account_name
= cli_credentials_get_username(cmdline_credentials
);
51 r
.in
.workstation
= TEST_MACHINE_NAME
;
54 status
= dcerpc_netr_LogonUasLogon(p
, tctx
, &r
);
55 torture_assert_ntstatus_ok(tctx
, status
, "LogonUasLogon");
60 static bool test_LogonUasLogoff(struct torture_context
*tctx
,
61 struct dcerpc_pipe
*p
)
64 struct netr_LogonUasLogoff r
;
65 struct netr_UasLogoffInfo info
;
67 r
.in
.server_name
= NULL
;
68 r
.in
.account_name
= cli_credentials_get_username(cmdline_credentials
);
69 r
.in
.workstation
= TEST_MACHINE_NAME
;
72 status
= dcerpc_netr_LogonUasLogoff(p
, tctx
, &r
);
73 torture_assert_ntstatus_ok(tctx
, status
, "LogonUasLogoff");
78 bool test_SetupCredentials(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
79 struct cli_credentials
*credentials
,
80 struct netlogon_creds_CredentialState
**creds_out
)
83 struct netr_ServerReqChallenge r
;
84 struct netr_ServerAuthenticate a
;
85 struct netr_Credential credentials1
, credentials2
, credentials3
;
86 struct netlogon_creds_CredentialState
*creds
;
87 const struct samr_Password
*mach_password
;
88 const char *machine_name
;
90 mach_password
= cli_credentials_get_nt_hash(credentials
, tctx
);
91 machine_name
= cli_credentials_get_workstation(credentials
);
93 torture_comment(tctx
, "Testing ServerReqChallenge\n");
95 r
.in
.server_name
= NULL
;
96 r
.in
.computer_name
= machine_name
;
97 r
.in
.credentials
= &credentials1
;
98 r
.out
.return_credentials
= &credentials2
;
100 generate_random_buffer(credentials1
.data
, sizeof(credentials1
.data
));
102 status
= dcerpc_netr_ServerReqChallenge(p
, tctx
, &r
);
103 torture_assert_ntstatus_ok(tctx
, status
, "ServerReqChallenge");
105 a
.in
.server_name
= NULL
;
106 a
.in
.account_name
= talloc_asprintf(tctx
, "%s$", machine_name
);
107 a
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(credentials
);
108 a
.in
.computer_name
= machine_name
;
109 a
.in
.credentials
= &credentials3
;
110 a
.out
.return_credentials
= &credentials3
;
112 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
114 &credentials1
, &credentials2
,
115 mach_password
, &credentials3
,
117 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
120 torture_comment(tctx
, "Testing ServerAuthenticate\n");
122 status
= dcerpc_netr_ServerAuthenticate(p
, tctx
, &a
);
124 /* This allows the tests to continue against the more fussy windows 2008 */
125 if (NT_STATUS_EQUAL(status
, NT_STATUS_DOWNGRADE_DETECTED
)) {
126 return test_SetupCredentials2(p
, tctx
, NETLOGON_NEG_AUTH2_ADS_FLAGS
,
128 cli_credentials_get_secure_channel_type(credentials
),
132 torture_assert_ntstatus_ok(tctx
, status
, "ServerAuthenticate");
134 torture_assert(tctx
, netlogon_creds_client_check(creds
, &credentials3
),
135 "Credential chaining failed");
141 bool test_SetupCredentials2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
142 uint32_t negotiate_flags
,
143 struct cli_credentials
*machine_credentials
,
145 struct netlogon_creds_CredentialState
**creds_out
)
148 struct netr_ServerReqChallenge r
;
149 struct netr_ServerAuthenticate2 a
;
150 struct netr_Credential credentials1
, credentials2
, credentials3
;
151 struct netlogon_creds_CredentialState
*creds
;
152 const struct samr_Password
*mach_password
;
153 const char *machine_name
;
155 mach_password
= cli_credentials_get_nt_hash(machine_credentials
, tctx
);
156 machine_name
= cli_credentials_get_workstation(machine_credentials
);
158 torture_comment(tctx
, "Testing ServerReqChallenge\n");
161 r
.in
.server_name
= NULL
;
162 r
.in
.computer_name
= machine_name
;
163 r
.in
.credentials
= &credentials1
;
164 r
.out
.return_credentials
= &credentials2
;
166 generate_random_buffer(credentials1
.data
, sizeof(credentials1
.data
));
168 status
= dcerpc_netr_ServerReqChallenge(p
, tctx
, &r
);
169 torture_assert_ntstatus_ok(tctx
, status
, "ServerReqChallenge");
171 a
.in
.server_name
= NULL
;
172 a
.in
.account_name
= talloc_asprintf(tctx
, "%s$", machine_name
);
173 a
.in
.secure_channel_type
= sec_chan_type
;
174 a
.in
.computer_name
= machine_name
;
175 a
.in
.negotiate_flags
= &negotiate_flags
;
176 a
.out
.negotiate_flags
= &negotiate_flags
;
177 a
.in
.credentials
= &credentials3
;
178 a
.out
.return_credentials
= &credentials3
;
180 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
182 &credentials1
, &credentials2
,
183 mach_password
, &credentials3
,
186 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
188 torture_comment(tctx
, "Testing ServerAuthenticate2\n");
190 status
= dcerpc_netr_ServerAuthenticate2(p
, tctx
, &a
);
191 torture_assert_ntstatus_ok(tctx
, status
, "ServerAuthenticate2");
193 torture_assert(tctx
, netlogon_creds_client_check(creds
, &credentials3
),
194 "Credential chaining failed");
196 torture_comment(tctx
, "negotiate_flags=0x%08x\n", negotiate_flags
);
203 static bool test_SetupCredentials3(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
204 uint32_t negotiate_flags
,
205 struct cli_credentials
*machine_credentials
,
206 struct netlogon_creds_CredentialState
**creds_out
)
209 struct netr_ServerReqChallenge r
;
210 struct netr_ServerAuthenticate3 a
;
211 struct netr_Credential credentials1
, credentials2
, credentials3
;
212 struct netlogon_creds_CredentialState
*creds
;
213 struct samr_Password mach_password
;
215 const char *machine_name
;
216 const char *plain_pass
;
218 machine_name
= cli_credentials_get_workstation(machine_credentials
);
219 plain_pass
= cli_credentials_get_password(machine_credentials
);
221 torture_comment(tctx
, "Testing ServerReqChallenge\n");
223 r
.in
.server_name
= NULL
;
224 r
.in
.computer_name
= machine_name
;
225 r
.in
.credentials
= &credentials1
;
226 r
.out
.return_credentials
= &credentials2
;
228 generate_random_buffer(credentials1
.data
, sizeof(credentials1
.data
));
230 status
= dcerpc_netr_ServerReqChallenge(p
, tctx
, &r
);
231 torture_assert_ntstatus_ok(tctx
, status
, "ServerReqChallenge");
233 E_md4hash(plain_pass
, mach_password
.hash
);
235 a
.in
.server_name
= NULL
;
236 a
.in
.account_name
= talloc_asprintf(tctx
, "%s$", machine_name
);
237 a
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
238 a
.in
.computer_name
= machine_name
;
239 a
.in
.negotiate_flags
= &negotiate_flags
;
240 a
.in
.credentials
= &credentials3
;
241 a
.out
.return_credentials
= &credentials3
;
242 a
.out
.negotiate_flags
= &negotiate_flags
;
245 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
247 &credentials1
, &credentials2
,
248 &mach_password
, &credentials3
,
251 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
253 torture_comment(tctx
, "Testing ServerAuthenticate3\n");
255 status
= dcerpc_netr_ServerAuthenticate3(p
, tctx
, &a
);
256 torture_assert_ntstatus_ok(tctx
, status
, "ServerAuthenticate3");
257 torture_assert(tctx
, netlogon_creds_client_check(creds
, &credentials3
), "Credential chaining failed");
259 torture_comment(tctx
, "negotiate_flags=0x%08x\n", negotiate_flags
);
261 /* Prove that requesting a challenge again won't break it */
262 status
= dcerpc_netr_ServerReqChallenge(p
, tctx
, &r
);
263 torture_assert_ntstatus_ok(tctx
, status
, "ServerReqChallenge");
270 try a change password for our machine account
272 static bool test_SetPassword(struct torture_context
*tctx
,
273 struct dcerpc_pipe
*p
,
274 struct cli_credentials
*machine_credentials
)
277 struct netr_ServerPasswordSet r
;
278 const char *password
;
279 struct netlogon_creds_CredentialState
*creds
;
280 struct netr_Authenticator credential
, return_authenticator
;
281 struct samr_Password new_password
;
283 if (!test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
)) {
287 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
288 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", TEST_MACHINE_NAME
);
289 r
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
290 r
.in
.computer_name
= TEST_MACHINE_NAME
;
291 r
.in
.credential
= &credential
;
292 r
.in
.new_password
= &new_password
;
293 r
.out
.return_authenticator
= &return_authenticator
;
295 password
= generate_random_str(tctx
, 8);
296 E_md4hash(password
, new_password
.hash
);
298 netlogon_creds_des_encrypt(creds
, &new_password
);
300 torture_comment(tctx
, "Testing ServerPasswordSet on machine account\n");
301 torture_comment(tctx
, "Changing machine account password to '%s'\n",
304 netlogon_creds_client_authenticator(creds
, &credential
);
306 status
= dcerpc_netr_ServerPasswordSet(p
, tctx
, &r
);
307 torture_assert_ntstatus_ok(tctx
, status
, "ServerPasswordSet");
309 if (!netlogon_creds_client_check(creds
, &r
.out
.return_authenticator
->cred
)) {
310 torture_comment(tctx
, "Credential chaining failed\n");
313 /* by changing the machine password twice we test the
314 credentials chaining fully, and we verify that the server
315 allows the password to be set to the same value twice in a
316 row (match win2k3) */
317 torture_comment(tctx
,
318 "Testing a second ServerPasswordSet on machine account\n");
319 torture_comment(tctx
,
320 "Changing machine account password to '%s' (same as previous run)\n", password
);
322 netlogon_creds_client_authenticator(creds
, &credential
);
324 status
= dcerpc_netr_ServerPasswordSet(p
, tctx
, &r
);
325 torture_assert_ntstatus_ok(tctx
, status
, "ServerPasswordSet (2)");
327 if (!netlogon_creds_client_check(creds
, &r
.out
.return_authenticator
->cred
)) {
328 torture_comment(tctx
, "Credential chaining failed\n");
331 cli_credentials_set_password(machine_credentials
, password
, CRED_SPECIFIED
);
334 test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
),
335 "ServerPasswordSet failed to actually change the password");
341 try a change password for our machine account
343 static bool test_SetPassword_flags(struct torture_context
*tctx
,
344 struct dcerpc_pipe
*p
,
345 struct cli_credentials
*machine_credentials
,
346 uint32_t negotiate_flags
)
349 struct netr_ServerPasswordSet r
;
350 const char *password
;
351 struct netlogon_creds_CredentialState
*creds
;
352 struct netr_Authenticator credential
, return_authenticator
;
353 struct samr_Password new_password
;
355 if (!test_SetupCredentials2(p
, tctx
, negotiate_flags
,
357 cli_credentials_get_secure_channel_type(machine_credentials
),
362 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
363 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", TEST_MACHINE_NAME
);
364 r
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
365 r
.in
.computer_name
= TEST_MACHINE_NAME
;
366 r
.in
.credential
= &credential
;
367 r
.in
.new_password
= &new_password
;
368 r
.out
.return_authenticator
= &return_authenticator
;
370 password
= generate_random_str(tctx
, 8);
371 E_md4hash(password
, new_password
.hash
);
373 netlogon_creds_des_encrypt(creds
, &new_password
);
375 torture_comment(tctx
, "Testing ServerPasswordSet on machine account\n");
376 torture_comment(tctx
, "Changing machine account password to '%s'\n",
379 netlogon_creds_client_authenticator(creds
, &credential
);
381 status
= dcerpc_netr_ServerPasswordSet(p
, tctx
, &r
);
382 torture_assert_ntstatus_ok(tctx
, status
, "ServerPasswordSet");
384 if (!netlogon_creds_client_check(creds
, &r
.out
.return_authenticator
->cred
)) {
385 torture_comment(tctx
, "Credential chaining failed\n");
388 /* by changing the machine password twice we test the
389 credentials chaining fully, and we verify that the server
390 allows the password to be set to the same value twice in a
391 row (match win2k3) */
392 torture_comment(tctx
,
393 "Testing a second ServerPasswordSet on machine account\n");
394 torture_comment(tctx
,
395 "Changing machine account password to '%s' (same as previous run)\n", password
);
397 netlogon_creds_client_authenticator(creds
, &credential
);
399 status
= dcerpc_netr_ServerPasswordSet(p
, tctx
, &r
);
400 torture_assert_ntstatus_ok(tctx
, status
, "ServerPasswordSet (2)");
402 if (!netlogon_creds_client_check(creds
, &r
.out
.return_authenticator
->cred
)) {
403 torture_comment(tctx
, "Credential chaining failed\n");
406 cli_credentials_set_password(machine_credentials
, password
, CRED_SPECIFIED
);
409 test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
),
410 "ServerPasswordSet failed to actually change the password");
417 generate a random password for password change tests
419 static DATA_BLOB
netlogon_very_rand_pass(TALLOC_CTX
*mem_ctx
, int len
)
422 DATA_BLOB password
= data_blob_talloc(mem_ctx
, NULL
, len
* 2 /* number of unicode chars */);
423 generate_random_buffer(password
.data
, password
.length
);
425 for (i
=0; i
< len
; i
++) {
426 if (((uint16_t *)password
.data
)[i
] == 0) {
427 ((uint16_t *)password
.data
)[i
] = 1;
435 try a change password for our machine account
437 static bool test_SetPassword2(struct torture_context
*tctx
,
438 struct dcerpc_pipe
*p
,
439 struct cli_credentials
*machine_credentials
)
442 struct netr_ServerPasswordSet2 r
;
443 const char *password
;
444 DATA_BLOB new_random_pass
;
445 struct netlogon_creds_CredentialState
*creds
;
446 struct samr_CryptPassword password_buf
;
447 struct samr_Password nt_hash
;
448 struct netr_Authenticator credential
, return_authenticator
;
449 struct netr_CryptPassword new_password
;
451 if (!test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
)) {
455 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
456 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", TEST_MACHINE_NAME
);
457 r
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
458 r
.in
.computer_name
= TEST_MACHINE_NAME
;
459 r
.in
.credential
= &credential
;
460 r
.in
.new_password
= &new_password
;
461 r
.out
.return_authenticator
= &return_authenticator
;
463 password
= generate_random_str(tctx
, 8);
464 encode_pw_buffer(password_buf
.data
, password
, STR_UNICODE
);
465 netlogon_creds_arcfour_crypt(creds
, password_buf
.data
, 516);
467 memcpy(new_password
.data
, password_buf
.data
, 512);
468 new_password
.length
= IVAL(password_buf
.data
, 512);
470 torture_comment(tctx
, "Testing ServerPasswordSet2 on machine account\n");
471 torture_comment(tctx
, "Changing machine account password to '%s'\n", password
);
473 netlogon_creds_client_authenticator(creds
, &credential
);
475 status
= dcerpc_netr_ServerPasswordSet2(p
, tctx
, &r
);
476 torture_assert_ntstatus_ok(tctx
, status
, "ServerPasswordSet2");
478 if (!netlogon_creds_client_check(creds
, &r
.out
.return_authenticator
->cred
)) {
479 torture_comment(tctx
, "Credential chaining failed\n");
482 cli_credentials_set_password(machine_credentials
, password
, CRED_SPECIFIED
);
484 if (!torture_setting_bool(tctx
, "dangerous", false)) {
485 torture_comment(tctx
,
486 "Not testing ability to set password to '', enable dangerous tests to perform this test\n");
488 /* by changing the machine password to ""
489 * we check if the server uses password restrictions
490 * for ServerPasswordSet2
491 * (win2k3 accepts "")
494 encode_pw_buffer(password_buf
.data
, password
, STR_UNICODE
);
495 netlogon_creds_arcfour_crypt(creds
, password_buf
.data
, 516);
497 memcpy(new_password
.data
, password_buf
.data
, 512);
498 new_password
.length
= IVAL(password_buf
.data
, 512);
500 torture_comment(tctx
,
501 "Testing ServerPasswordSet2 on machine account\n");
502 torture_comment(tctx
,
503 "Changing machine account password to '%s'\n", password
);
505 netlogon_creds_client_authenticator(creds
, &credential
);
507 status
= dcerpc_netr_ServerPasswordSet2(p
, tctx
, &r
);
508 torture_assert_ntstatus_ok(tctx
, status
, "ServerPasswordSet2");
510 if (!netlogon_creds_client_check(creds
, &r
.out
.return_authenticator
->cred
)) {
511 torture_comment(tctx
, "Credential chaining failed\n");
514 cli_credentials_set_password(machine_credentials
, password
, CRED_SPECIFIED
);
517 torture_assert(tctx
, test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
),
518 "ServerPasswordSet failed to actually change the password");
520 /* now try a random password */
521 password
= generate_random_str(tctx
, 8);
522 encode_pw_buffer(password_buf
.data
, password
, STR_UNICODE
);
523 netlogon_creds_arcfour_crypt(creds
, password_buf
.data
, 516);
525 memcpy(new_password
.data
, password_buf
.data
, 512);
526 new_password
.length
= IVAL(password_buf
.data
, 512);
528 torture_comment(tctx
, "Testing second ServerPasswordSet2 on machine account\n");
529 torture_comment(tctx
, "Changing machine account password to '%s'\n", password
);
531 netlogon_creds_client_authenticator(creds
, &credential
);
533 status
= dcerpc_netr_ServerPasswordSet2(p
, tctx
, &r
);
534 torture_assert_ntstatus_ok(tctx
, status
, "ServerPasswordSet2 (2)");
536 if (!netlogon_creds_client_check(creds
, &r
.out
.return_authenticator
->cred
)) {
537 torture_comment(tctx
, "Credential chaining failed\n");
540 /* by changing the machine password twice we test the
541 credentials chaining fully, and we verify that the server
542 allows the password to be set to the same value twice in a
543 row (match win2k3) */
544 torture_comment(tctx
,
545 "Testing a second ServerPasswordSet2 on machine account\n");
546 torture_comment(tctx
,
547 "Changing machine account password to '%s' (same as previous run)\n", password
);
549 netlogon_creds_client_authenticator(creds
, &credential
);
551 status
= dcerpc_netr_ServerPasswordSet2(p
, tctx
, &r
);
552 torture_assert_ntstatus_ok(tctx
, status
, "ServerPasswordSet (3)");
554 if (!netlogon_creds_client_check(creds
, &r
.out
.return_authenticator
->cred
)) {
555 torture_comment(tctx
, "Credential chaining failed\n");
558 cli_credentials_set_password(machine_credentials
, password
, CRED_SPECIFIED
);
560 torture_assert (tctx
,
561 test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
),
562 "ServerPasswordSet failed to actually change the password");
564 new_random_pass
= netlogon_very_rand_pass(tctx
, 128);
566 /* now try a random stream of bytes for a password */
567 set_pw_in_buffer(password_buf
.data
, &new_random_pass
);
569 netlogon_creds_arcfour_crypt(creds
, password_buf
.data
, 516);
571 memcpy(new_password
.data
, password_buf
.data
, 512);
572 new_password
.length
= IVAL(password_buf
.data
, 512);
574 torture_comment(tctx
,
575 "Testing a third ServerPasswordSet2 on machine account, with a compleatly random password\n");
577 netlogon_creds_client_authenticator(creds
, &credential
);
579 status
= dcerpc_netr_ServerPasswordSet2(p
, tctx
, &r
);
580 torture_assert_ntstatus_ok(tctx
, status
, "ServerPasswordSet (3)");
582 if (!netlogon_creds_client_check(creds
, &r
.out
.return_authenticator
->cred
)) {
583 torture_comment(tctx
, "Credential chaining failed\n");
586 mdfour(nt_hash
.hash
, new_random_pass
.data
, new_random_pass
.length
);
588 cli_credentials_set_password(machine_credentials
, NULL
, CRED_UNINITIALISED
);
589 cli_credentials_set_nt_hash(machine_credentials
, &nt_hash
, CRED_SPECIFIED
);
591 torture_assert (tctx
,
592 test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
),
593 "ServerPasswordSet failed to actually change the password");
598 static bool test_GetPassword(struct torture_context
*tctx
,
599 struct dcerpc_pipe
*p
,
600 struct cli_credentials
*machine_credentials
)
602 struct netr_ServerPasswordGet r
;
603 struct netlogon_creds_CredentialState
*creds
;
604 struct netr_Authenticator credential
;
606 struct netr_Authenticator return_authenticator
;
607 struct samr_Password password
;
609 if (!test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
)) {
613 netlogon_creds_client_authenticator(creds
, &credential
);
615 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
616 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", TEST_MACHINE_NAME
);
617 r
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
618 r
.in
.computer_name
= TEST_MACHINE_NAME
;
619 r
.in
.credential
= &credential
;
620 r
.out
.return_authenticator
= &return_authenticator
;
621 r
.out
.password
= &password
;
623 status
= dcerpc_netr_ServerPasswordGet(p
, tctx
, &r
);
624 torture_assert_ntstatus_ok(tctx
, status
, "ServerPasswordGet");
629 static bool test_GetTrustPasswords(struct torture_context
*tctx
,
630 struct dcerpc_pipe
*p
,
631 struct cli_credentials
*machine_credentials
)
633 struct netr_ServerTrustPasswordsGet r
;
634 struct netlogon_creds_CredentialState
*creds
;
635 struct netr_Authenticator credential
;
637 struct netr_Authenticator return_authenticator
;
638 struct samr_Password password
, password2
;
640 if (!test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
)) {
644 netlogon_creds_client_authenticator(creds
, &credential
);
646 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
647 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", TEST_MACHINE_NAME
);
648 r
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
649 r
.in
.computer_name
= TEST_MACHINE_NAME
;
650 r
.in
.credential
= &credential
;
651 r
.out
.return_authenticator
= &return_authenticator
;
652 r
.out
.password
= &password
;
653 r
.out
.password2
= &password2
;
655 status
= dcerpc_netr_ServerTrustPasswordsGet(p
, tctx
, &r
);
656 torture_assert_ntstatus_ok(tctx
, status
, "ServerTrustPasswordsGet");
662 try a netlogon SamLogon
664 bool test_netlogon_ops(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
665 struct cli_credentials
*credentials
,
666 struct netlogon_creds_CredentialState
*creds
)
669 struct netr_LogonSamLogon r
;
670 struct netr_Authenticator auth
, auth2
;
671 union netr_LogonLevel logon
;
672 union netr_Validation validation
;
673 uint8_t authoritative
;
674 struct netr_NetworkInfo ninfo
;
675 DATA_BLOB names_blob
, chal
, lm_resp
, nt_resp
;
677 int flags
= CLI_CRED_NTLM_AUTH
;
678 if (lp_client_lanman_auth(tctx
->lp_ctx
)) {
679 flags
|= CLI_CRED_LANMAN_AUTH
;
682 if (lp_client_ntlmv2_auth(tctx
->lp_ctx
)) {
683 flags
|= CLI_CRED_NTLMv2_AUTH
;
686 cli_credentials_get_ntlm_username_domain(cmdline_credentials
, tctx
,
687 &ninfo
.identity_info
.account_name
.string
,
688 &ninfo
.identity_info
.domain_name
.string
);
690 generate_random_buffer(ninfo
.challenge
,
691 sizeof(ninfo
.challenge
));
692 chal
= data_blob_const(ninfo
.challenge
,
693 sizeof(ninfo
.challenge
));
695 names_blob
= NTLMv2_generate_names_blob(tctx
, cli_credentials_get_workstation(credentials
),
696 cli_credentials_get_domain(credentials
));
698 status
= cli_credentials_get_ntlm_response(cmdline_credentials
, tctx
,
704 torture_assert_ntstatus_ok(tctx
, status
, "cli_credentials_get_ntlm_response failed");
706 ninfo
.lm
.data
= lm_resp
.data
;
707 ninfo
.lm
.length
= lm_resp
.length
;
709 ninfo
.nt
.data
= nt_resp
.data
;
710 ninfo
.nt
.length
= nt_resp
.length
;
712 ninfo
.identity_info
.parameter_control
= 0;
713 ninfo
.identity_info
.logon_id_low
= 0;
714 ninfo
.identity_info
.logon_id_high
= 0;
715 ninfo
.identity_info
.workstation
.string
= cli_credentials_get_workstation(credentials
);
717 logon
.network
= &ninfo
;
719 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
720 r
.in
.computer_name
= cli_credentials_get_workstation(credentials
);
721 r
.in
.credential
= &auth
;
722 r
.in
.return_authenticator
= &auth2
;
723 r
.in
.logon_level
= 2;
725 r
.out
.validation
= &validation
;
726 r
.out
.authoritative
= &authoritative
;
728 d_printf("Testing LogonSamLogon with name %s\n", ninfo
.identity_info
.account_name
.string
);
732 netlogon_creds_client_authenticator(creds
, &auth
);
734 r
.in
.validation_level
= i
;
736 status
= dcerpc_netr_LogonSamLogon(p
, tctx
, &r
);
737 torture_assert_ntstatus_ok(tctx
, status
, "LogonSamLogon failed");
739 torture_assert(tctx
, netlogon_creds_client_check(creds
,
740 &r
.out
.return_authenticator
->cred
),
741 "Credential chaining failed");
744 r
.in
.credential
= NULL
;
748 r
.in
.validation_level
= i
;
750 torture_comment(tctx
, "Testing SamLogon with validation level %d and a NULL credential\n", i
);
752 status
= dcerpc_netr_LogonSamLogon(p
, tctx
, &r
);
753 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_INVALID_PARAMETER
,
754 "LogonSamLogon expected INVALID_PARAMETER");
762 try a netlogon SamLogon
764 static bool test_SamLogon(struct torture_context
*tctx
,
765 struct dcerpc_pipe
*p
,
766 struct cli_credentials
*credentials
)
768 struct netlogon_creds_CredentialState
*creds
;
770 if (!test_SetupCredentials(p
, tctx
, credentials
, &creds
)) {
774 return test_netlogon_ops(p
, tctx
, credentials
, creds
);
777 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
778 static uint64_t sequence_nums
[3];
781 try a netlogon DatabaseSync
783 static bool test_DatabaseSync(struct torture_context
*tctx
,
784 struct dcerpc_pipe
*p
,
785 struct cli_credentials
*machine_credentials
)
788 struct netr_DatabaseSync r
;
789 struct netlogon_creds_CredentialState
*creds
;
790 const uint32_t database_ids
[] = {SAM_DATABASE_DOMAIN
, SAM_DATABASE_BUILTIN
, SAM_DATABASE_PRIVS
};
792 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
793 struct netr_Authenticator credential
, return_authenticator
;
795 if (!test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
)) {
799 ZERO_STRUCT(return_authenticator
);
801 r
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
802 r
.in
.computername
= TEST_MACHINE_NAME
;
803 r
.in
.preferredmaximumlength
= (uint32_t)-1;
804 r
.in
.return_authenticator
= &return_authenticator
;
805 r
.out
.delta_enum_array
= &delta_enum_array
;
806 r
.out
.return_authenticator
= &return_authenticator
;
808 for (i
=0;i
<ARRAY_SIZE(database_ids
);i
++) {
810 uint32_t sync_context
= 0;
812 r
.in
.database_id
= database_ids
[i
];
813 r
.in
.sync_context
= &sync_context
;
814 r
.out
.sync_context
= &sync_context
;
816 torture_comment(tctx
, "Testing DatabaseSync of id %d\n", r
.in
.database_id
);
819 netlogon_creds_client_authenticator(creds
, &credential
);
821 r
.in
.credential
= &credential
;
823 status
= dcerpc_netr_DatabaseSync(p
, tctx
, &r
);
824 if (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
827 /* Native mode servers don't do this */
828 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_SUPPORTED
)) {
831 torture_assert_ntstatus_ok(tctx
, status
, "DatabaseSync");
833 if (!netlogon_creds_client_check(creds
, &r
.out
.return_authenticator
->cred
)) {
834 torture_comment(tctx
, "Credential chaining failed\n");
837 if (delta_enum_array
&&
838 delta_enum_array
->num_deltas
> 0 &&
839 delta_enum_array
->delta_enum
[0].delta_type
== NETR_DELTA_DOMAIN
&&
840 delta_enum_array
->delta_enum
[0].delta_union
.domain
) {
841 sequence_nums
[r
.in
.database_id
] =
842 delta_enum_array
->delta_enum
[0].delta_union
.domain
->sequence_num
;
843 torture_comment(tctx
, "\tsequence_nums[%d]=%llu\n",
845 (unsigned long long)sequence_nums
[r
.in
.database_id
]);
847 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
855 try a netlogon DatabaseDeltas
857 static bool test_DatabaseDeltas(struct torture_context
*tctx
,
858 struct dcerpc_pipe
*p
,
859 struct cli_credentials
*machine_credentials
)
862 struct netr_DatabaseDeltas r
;
863 struct netlogon_creds_CredentialState
*creds
;
864 struct netr_Authenticator credential
;
865 struct netr_Authenticator return_authenticator
;
866 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
867 const uint32_t database_ids
[] = {0, 1, 2};
870 if (!test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
)) {
874 r
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
875 r
.in
.computername
= TEST_MACHINE_NAME
;
876 r
.in
.preferredmaximumlength
= (uint32_t)-1;
877 ZERO_STRUCT(r
.in
.return_authenticator
);
878 r
.out
.return_authenticator
= &return_authenticator
;
879 r
.out
.delta_enum_array
= &delta_enum_array
;
881 for (i
=0;i
<ARRAY_SIZE(database_ids
);i
++) {
882 r
.in
.database_id
= database_ids
[i
];
883 r
.in
.sequence_num
= &sequence_nums
[r
.in
.database_id
];
885 if (*r
.in
.sequence_num
== 0) continue;
887 *r
.in
.sequence_num
-= 1;
889 torture_comment(tctx
, "Testing DatabaseDeltas of id %d at %llu\n",
890 r
.in
.database_id
, (unsigned long long)*r
.in
.sequence_num
);
893 netlogon_creds_client_authenticator(creds
, &credential
);
895 status
= dcerpc_netr_DatabaseDeltas(p
, tctx
, &r
);
896 if (NT_STATUS_EQUAL(status
,
897 NT_STATUS_SYNCHRONIZATION_REQUIRED
)) {
898 torture_comment(tctx
, "not considering %s to be an error\n",
902 if (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
905 torture_assert_ntstatus_ok(tctx
, status
, "DatabaseDeltas");
907 if (!netlogon_creds_client_check(creds
, &return_authenticator
.cred
)) {
908 torture_comment(tctx
, "Credential chaining failed\n");
911 (*r
.in
.sequence_num
)++;
912 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
918 static bool test_DatabaseRedo(struct torture_context
*tctx
,
919 struct dcerpc_pipe
*p
,
920 struct cli_credentials
*machine_credentials
)
923 struct netr_DatabaseRedo r
;
924 struct netlogon_creds_CredentialState
*creds
;
925 struct netr_Authenticator credential
;
926 struct netr_Authenticator return_authenticator
;
927 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
928 struct netr_ChangeLogEntry e
;
929 struct dom_sid null_sid
, *sid
;
932 ZERO_STRUCT(null_sid
);
934 sid
= dom_sid_parse_talloc(tctx
, "S-1-5-21-1111111111-2222222222-333333333-500");
945 NTSTATUS expected_error
;
946 uint32_t expected_num_results
;
947 uint8_t expected_delta_type_1
;
948 uint8_t expected_delta_type_2
;
952 /* SAM_DATABASE_DOMAIN */
957 .db_index
= SAM_DATABASE_DOMAIN
,
958 .delta_type
= NETR_DELTA_MODIFY_COUNT
,
961 .expected_error
= NT_STATUS_SYNCHRONIZATION_REQUIRED
,
962 .expected_num_results
= 0,
963 .comment
= "NETR_DELTA_MODIFY_COUNT"
968 .db_index
= SAM_DATABASE_DOMAIN
,
972 .expected_error
= NT_STATUS_OK
,
973 .expected_num_results
= 1,
974 .expected_delta_type_1
= NETR_DELTA_DOMAIN
,
975 .comment
= "NULL DELTA"
980 .db_index
= SAM_DATABASE_DOMAIN
,
981 .delta_type
= NETR_DELTA_DOMAIN
,
984 .expected_error
= NT_STATUS_OK
,
985 .expected_num_results
= 1,
986 .expected_delta_type_1
= NETR_DELTA_DOMAIN
,
987 .comment
= "NETR_DELTA_DOMAIN"
990 .rid
= DOMAIN_RID_ADMINISTRATOR
,
992 .db_index
= SAM_DATABASE_DOMAIN
,
993 .delta_type
= NETR_DELTA_USER
,
996 .expected_error
= NT_STATUS_OK
,
997 .expected_num_results
= 1,
998 .expected_delta_type_1
= NETR_DELTA_USER
,
999 .comment
= "NETR_DELTA_USER by rid 500"
1002 .rid
= DOMAIN_RID_GUEST
,
1004 .db_index
= SAM_DATABASE_DOMAIN
,
1005 .delta_type
= NETR_DELTA_USER
,
1008 .expected_error
= NT_STATUS_OK
,
1009 .expected_num_results
= 1,
1010 .expected_delta_type_1
= NETR_DELTA_USER
,
1011 .comment
= "NETR_DELTA_USER by rid 501"
1015 .flags
= NETR_CHANGELOG_SID_INCLUDED
,
1016 .db_index
= SAM_DATABASE_DOMAIN
,
1017 .delta_type
= NETR_DELTA_USER
,
1020 .expected_error
= NT_STATUS_OK
,
1021 .expected_num_results
= 1,
1022 .expected_delta_type_1
= NETR_DELTA_DELETE_USER
,
1023 .comment
= "NETR_DELTA_USER by sid and flags"
1027 .flags
= NETR_CHANGELOG_SID_INCLUDED
,
1028 .db_index
= SAM_DATABASE_DOMAIN
,
1029 .delta_type
= NETR_DELTA_USER
,
1032 .expected_error
= NT_STATUS_OK
,
1033 .expected_num_results
= 1,
1034 .expected_delta_type_1
= NETR_DELTA_DELETE_USER
,
1035 .comment
= "NETR_DELTA_USER by null_sid and flags"
1039 .flags
= NETR_CHANGELOG_NAME_INCLUDED
,
1040 .db_index
= SAM_DATABASE_DOMAIN
,
1041 .delta_type
= NETR_DELTA_USER
,
1043 .name
= "administrator",
1044 .expected_error
= NT_STATUS_OK
,
1045 .expected_num_results
= 1,
1046 .expected_delta_type_1
= NETR_DELTA_DELETE_USER
,
1047 .comment
= "NETR_DELTA_USER by name 'administrator'"
1050 .rid
= DOMAIN_RID_ADMINS
,
1052 .db_index
= SAM_DATABASE_DOMAIN
,
1053 .delta_type
= NETR_DELTA_GROUP
,
1056 .expected_error
= NT_STATUS_OK
,
1057 .expected_num_results
= 2,
1058 .expected_delta_type_1
= NETR_DELTA_GROUP
,
1059 .expected_delta_type_2
= NETR_DELTA_GROUP_MEMBER
,
1060 .comment
= "NETR_DELTA_GROUP by rid 512"
1063 .rid
= DOMAIN_RID_ADMINS
,
1065 .db_index
= SAM_DATABASE_DOMAIN
,
1066 .delta_type
= NETR_DELTA_GROUP_MEMBER
,
1069 .expected_error
= NT_STATUS_OK
,
1070 .expected_num_results
= 2,
1071 .expected_delta_type_1
= NETR_DELTA_GROUP
,
1072 .expected_delta_type_2
= NETR_DELTA_GROUP_MEMBER
,
1073 .comment
= "NETR_DELTA_GROUP_MEMBER by rid 512"
1077 /* SAM_DATABASE_BUILTIN */
1082 .db_index
= SAM_DATABASE_BUILTIN
,
1083 .delta_type
= NETR_DELTA_MODIFY_COUNT
,
1086 .expected_error
= NT_STATUS_SYNCHRONIZATION_REQUIRED
,
1087 .expected_num_results
= 0,
1088 .comment
= "NETR_DELTA_MODIFY_COUNT"
1093 .db_index
= SAM_DATABASE_BUILTIN
,
1094 .delta_type
= NETR_DELTA_DOMAIN
,
1097 .expected_error
= NT_STATUS_OK
,
1098 .expected_num_results
= 1,
1099 .expected_delta_type_1
= NETR_DELTA_DOMAIN
,
1100 .comment
= "NETR_DELTA_DOMAIN"
1103 .rid
= DOMAIN_RID_ADMINISTRATOR
,
1105 .db_index
= SAM_DATABASE_BUILTIN
,
1106 .delta_type
= NETR_DELTA_USER
,
1109 .expected_error
= NT_STATUS_OK
,
1110 .expected_num_results
= 1,
1111 .expected_delta_type_1
= NETR_DELTA_DELETE_USER
,
1112 .comment
= "NETR_DELTA_USER by rid 500"
1117 .db_index
= SAM_DATABASE_BUILTIN
,
1118 .delta_type
= NETR_DELTA_USER
,
1121 .expected_error
= NT_STATUS_OK
,
1122 .expected_num_results
= 1,
1123 .expected_delta_type_1
= NETR_DELTA_DELETE_USER
,
1124 .comment
= "NETR_DELTA_USER"
1129 .db_index
= SAM_DATABASE_BUILTIN
,
1130 .delta_type
= NETR_DELTA_ALIAS
,
1133 .expected_error
= NT_STATUS_OK
,
1134 .expected_num_results
= 2,
1135 .expected_delta_type_1
= NETR_DELTA_ALIAS
,
1136 .expected_delta_type_2
= NETR_DELTA_ALIAS_MEMBER
,
1137 .comment
= "NETR_DELTA_ALIAS by rid 544"
1142 .db_index
= SAM_DATABASE_BUILTIN
,
1143 .delta_type
= NETR_DELTA_ALIAS_MEMBER
,
1146 .expected_error
= NT_STATUS_OK
,
1147 .expected_num_results
= 2,
1148 .expected_delta_type_1
= NETR_DELTA_ALIAS
,
1149 .expected_delta_type_2
= NETR_DELTA_ALIAS_MEMBER
,
1150 .comment
= "NETR_DELTA_ALIAS_MEMBER by rid 544"
1155 .db_index
= SAM_DATABASE_BUILTIN
,
1159 .expected_error
= NT_STATUS_OK
,
1160 .expected_num_results
= 1,
1161 .expected_delta_type_1
= NETR_DELTA_DOMAIN
,
1162 .comment
= "NULL DELTA by rid 544"
1166 .flags
= NETR_CHANGELOG_SID_INCLUDED
,
1167 .db_index
= SAM_DATABASE_BUILTIN
,
1169 .sid
= *dom_sid_parse_talloc(tctx
, "S-1-5-32-544"),
1171 .expected_error
= NT_STATUS_OK
,
1172 .expected_num_results
= 1,
1173 .expected_delta_type_1
= NETR_DELTA_DOMAIN
,
1174 .comment
= "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
1178 .flags
= NETR_CHANGELOG_SID_INCLUDED
,
1179 .db_index
= SAM_DATABASE_BUILTIN
,
1180 .delta_type
= NETR_DELTA_ALIAS
,
1181 .sid
= *dom_sid_parse_talloc(tctx
, "S-1-5-32-544"),
1183 .expected_error
= NT_STATUS_OK
,
1184 .expected_num_results
= 2,
1185 .expected_delta_type_1
= NETR_DELTA_ALIAS
,
1186 .expected_delta_type_2
= NETR_DELTA_ALIAS_MEMBER
,
1187 .comment
= "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
1191 .flags
= NETR_CHANGELOG_SID_INCLUDED
,
1192 .db_index
= SAM_DATABASE_BUILTIN
,
1193 .delta_type
= NETR_DELTA_ALIAS
,
1194 .sid
= *dom_sid_parse_talloc(tctx
, "S-1-5-32-544"),
1196 .expected_error
= NT_STATUS_OK
,
1197 .expected_num_results
= 1,
1198 .expected_delta_type_1
= NETR_DELTA_DELETE_ALIAS
,
1199 .comment
= "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
1202 /* SAM_DATABASE_PRIVS */
1207 .db_index
= SAM_DATABASE_PRIVS
,
1211 .expected_error
= NT_STATUS_ACCESS_DENIED
,
1212 .expected_num_results
= 0,
1213 .comment
= "NULL DELTA"
1218 .db_index
= SAM_DATABASE_PRIVS
,
1219 .delta_type
= NETR_DELTA_MODIFY_COUNT
,
1222 .expected_error
= NT_STATUS_SYNCHRONIZATION_REQUIRED
,
1223 .expected_num_results
= 0,
1224 .comment
= "NETR_DELTA_MODIFY_COUNT"
1229 .db_index
= SAM_DATABASE_PRIVS
,
1230 .delta_type
= NETR_DELTA_POLICY
,
1233 .expected_error
= NT_STATUS_OK
,
1234 .expected_num_results
= 1,
1235 .expected_delta_type_1
= NETR_DELTA_POLICY
,
1236 .comment
= "NETR_DELTA_POLICY"
1240 .flags
= NETR_CHANGELOG_SID_INCLUDED
,
1241 .db_index
= SAM_DATABASE_PRIVS
,
1242 .delta_type
= NETR_DELTA_POLICY
,
1245 .expected_error
= NT_STATUS_OK
,
1246 .expected_num_results
= 1,
1247 .expected_delta_type_1
= NETR_DELTA_POLICY
,
1248 .comment
= "NETR_DELTA_POLICY by null sid and flags"
1252 .flags
= NETR_CHANGELOG_SID_INCLUDED
,
1253 .db_index
= SAM_DATABASE_PRIVS
,
1254 .delta_type
= NETR_DELTA_POLICY
,
1255 .sid
= *dom_sid_parse_talloc(tctx
, "S-1-5-32"),
1257 .expected_error
= NT_STATUS_OK
,
1258 .expected_num_results
= 1,
1259 .expected_delta_type_1
= NETR_DELTA_POLICY
,
1260 .comment
= "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
1263 .rid
= DOMAIN_RID_ADMINISTRATOR
,
1265 .db_index
= SAM_DATABASE_PRIVS
,
1266 .delta_type
= NETR_DELTA_ACCOUNT
,
1269 .expected_error
= NT_STATUS_SYNCHRONIZATION_REQUIRED
, /* strange */
1270 .expected_num_results
= 0,
1271 .comment
= "NETR_DELTA_ACCOUNT by rid 500"
1275 .flags
= NETR_CHANGELOG_SID_INCLUDED
,
1276 .db_index
= SAM_DATABASE_PRIVS
,
1277 .delta_type
= NETR_DELTA_ACCOUNT
,
1278 .sid
= *dom_sid_parse_talloc(tctx
, "S-1-1-0"),
1280 .expected_error
= NT_STATUS_OK
,
1281 .expected_num_results
= 1,
1282 .expected_delta_type_1
= NETR_DELTA_ACCOUNT
,
1283 .comment
= "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
1287 .flags
= NETR_CHANGELOG_SID_INCLUDED
|
1288 NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED
,
1289 .db_index
= SAM_DATABASE_PRIVS
,
1290 .delta_type
= NETR_DELTA_ACCOUNT
,
1291 .sid
= *dom_sid_parse_talloc(tctx
, "S-1-1-0"),
1293 .expected_error
= NT_STATUS_OK
,
1294 .expected_num_results
= 1,
1295 .expected_delta_type_1
= NETR_DELTA_ACCOUNT
,
1296 .comment
= "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
1300 .flags
= NETR_CHANGELOG_SID_INCLUDED
|
1301 NETR_CHANGELOG_NAME_INCLUDED
,
1302 .db_index
= SAM_DATABASE_PRIVS
,
1303 .delta_type
= NETR_DELTA_ACCOUNT
,
1304 .sid
= *dom_sid_parse_talloc(tctx
, "S-1-1-0"),
1306 .expected_error
= NT_STATUS_INVALID_PARAMETER
,
1307 .expected_num_results
= 0,
1308 .comment
= "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
1311 .rid
= DOMAIN_RID_ADMINISTRATOR
,
1312 .flags
= NETR_CHANGELOG_SID_INCLUDED
,
1313 .db_index
= SAM_DATABASE_PRIVS
,
1314 .delta_type
= NETR_DELTA_ACCOUNT
,
1317 .expected_error
= NT_STATUS_OK
,
1318 .expected_num_results
= 1,
1319 .expected_delta_type_1
= NETR_DELTA_DELETE_ACCOUNT
,
1320 .comment
= "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
1324 .flags
= NETR_CHANGELOG_NAME_INCLUDED
,
1325 .db_index
= SAM_DATABASE_PRIVS
,
1326 .delta_type
= NETR_DELTA_SECRET
,
1328 .name
= "IsurelydontexistIhope",
1329 .expected_error
= NT_STATUS_OK
,
1330 .expected_num_results
= 1,
1331 .expected_delta_type_1
= NETR_DELTA_DELETE_SECRET
,
1332 .comment
= "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
1336 .flags
= NETR_CHANGELOG_NAME_INCLUDED
,
1337 .db_index
= SAM_DATABASE_PRIVS
,
1338 .delta_type
= NETR_DELTA_SECRET
,
1340 .name
= "G$BCKUPKEY_P",
1341 .expected_error
= NT_STATUS_OK
,
1342 .expected_num_results
= 1,
1343 .expected_delta_type_1
= NETR_DELTA_SECRET
,
1344 .comment
= "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
1348 ZERO_STRUCT(return_authenticator
);
1350 r
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1351 r
.in
.computername
= TEST_MACHINE_NAME
;
1352 r
.in
.return_authenticator
= &return_authenticator
;
1353 r
.out
.return_authenticator
= &return_authenticator
;
1354 r
.out
.delta_enum_array
= &delta_enum_array
;
1356 for (d
=0; d
<3; d
++) {
1358 const char *database
;
1365 database
= "BUILTIN";
1374 torture_comment(tctx
, "Testing DatabaseRedo\n");
1376 if (!test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
)) {
1380 for (i
=0;i
<ARRAY_SIZE(changes
);i
++) {
1382 if (d
!= changes
[i
].db_index
) {
1386 netlogon_creds_client_authenticator(creds
, &credential
);
1388 r
.in
.credential
= &credential
;
1390 e
.serial_number1
= 0;
1391 e
.serial_number2
= 0;
1392 e
.object_rid
= changes
[i
].rid
;
1393 e
.flags
= changes
[i
].flags
;
1394 e
.db_index
= changes
[i
].db_index
;
1395 e
.delta_type
= changes
[i
].delta_type
;
1397 switch (changes
[i
].flags
& (NETR_CHANGELOG_NAME_INCLUDED
| NETR_CHANGELOG_SID_INCLUDED
)) {
1398 case NETR_CHANGELOG_SID_INCLUDED
:
1399 e
.object
.object_sid
= changes
[i
].sid
;
1401 case NETR_CHANGELOG_NAME_INCLUDED
:
1402 e
.object
.object_name
= changes
[i
].name
;
1408 r
.in
.change_log_entry
= e
;
1410 torture_comment(tctx
, "Testing DatabaseRedo with database %s and %s\n",
1411 database
, changes
[i
].comment
);
1413 status
= dcerpc_netr_DatabaseRedo(p
, tctx
, &r
);
1414 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_SUPPORTED
)) {
1418 torture_assert_ntstatus_equal(tctx
, status
, changes
[i
].expected_error
, changes
[i
].comment
);
1419 if (delta_enum_array
) {
1420 torture_assert_int_equal(tctx
,
1421 delta_enum_array
->num_deltas
,
1422 changes
[i
].expected_num_results
,
1423 changes
[i
].comment
);
1424 if (delta_enum_array
->num_deltas
> 0) {
1425 torture_assert_int_equal(tctx
,
1426 delta_enum_array
->delta_enum
[0].delta_type
,
1427 changes
[i
].expected_delta_type_1
,
1428 changes
[i
].comment
);
1430 if (delta_enum_array
->num_deltas
> 1) {
1431 torture_assert_int_equal(tctx
,
1432 delta_enum_array
->delta_enum
[1].delta_type
,
1433 changes
[i
].expected_delta_type_2
,
1434 changes
[i
].comment
);
1438 if (!netlogon_creds_client_check(creds
, &return_authenticator
.cred
)) {
1439 torture_comment(tctx
, "Credential chaining failed\n");
1440 if (!test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
)) {
1452 try a netlogon AccountDeltas
1454 static bool test_AccountDeltas(struct torture_context
*tctx
,
1455 struct dcerpc_pipe
*p
,
1456 struct cli_credentials
*machine_credentials
)
1459 struct netr_AccountDeltas r
;
1460 struct netlogon_creds_CredentialState
*creds
;
1462 struct netr_AccountBuffer buffer
;
1463 uint32_t count_returned
= 0;
1464 uint32_t total_entries
= 0;
1465 struct netr_UAS_INFO_0 recordid
;
1466 struct netr_Authenticator return_authenticator
;
1468 if (!test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
)) {
1472 ZERO_STRUCT(return_authenticator
);
1474 r
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1475 r
.in
.computername
= TEST_MACHINE_NAME
;
1476 r
.in
.return_authenticator
= &return_authenticator
;
1477 netlogon_creds_client_authenticator(creds
, &r
.in
.credential
);
1478 ZERO_STRUCT(r
.in
.uas
);
1481 r
.in
.buffersize
=100;
1482 r
.out
.buffer
= &buffer
;
1483 r
.out
.count_returned
= &count_returned
;
1484 r
.out
.total_entries
= &total_entries
;
1485 r
.out
.recordid
= &recordid
;
1486 r
.out
.return_authenticator
= &return_authenticator
;
1488 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1489 status
= dcerpc_netr_AccountDeltas(p
, tctx
, &r
);
1490 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_NOT_IMPLEMENTED
, "AccountDeltas");
1496 try a netlogon AccountSync
1498 static bool test_AccountSync(struct torture_context
*tctx
, struct dcerpc_pipe
*p
,
1499 struct cli_credentials
*machine_credentials
)
1502 struct netr_AccountSync r
;
1503 struct netlogon_creds_CredentialState
*creds
;
1505 struct netr_AccountBuffer buffer
;
1506 uint32_t count_returned
= 0;
1507 uint32_t total_entries
= 0;
1508 uint32_t next_reference
= 0;
1509 struct netr_UAS_INFO_0 recordid
;
1510 struct netr_Authenticator return_authenticator
;
1512 ZERO_STRUCT(recordid
);
1513 ZERO_STRUCT(return_authenticator
);
1515 if (!test_SetupCredentials(p
, tctx
, machine_credentials
, &creds
)) {
1519 r
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1520 r
.in
.computername
= TEST_MACHINE_NAME
;
1521 r
.in
.return_authenticator
= &return_authenticator
;
1522 netlogon_creds_client_authenticator(creds
, &r
.in
.credential
);
1523 r
.in
.recordid
= &recordid
;
1526 r
.in
.buffersize
=100;
1527 r
.out
.buffer
= &buffer
;
1528 r
.out
.count_returned
= &count_returned
;
1529 r
.out
.total_entries
= &total_entries
;
1530 r
.out
.next_reference
= &next_reference
;
1531 r
.out
.recordid
= &recordid
;
1532 r
.out
.return_authenticator
= &return_authenticator
;
1534 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1535 status
= dcerpc_netr_AccountSync(p
, tctx
, &r
);
1536 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_NOT_IMPLEMENTED
, "AccountSync");
1542 try a netlogon GetDcName
1544 static bool test_GetDcName(struct torture_context
*tctx
,
1545 struct dcerpc_pipe
*p
)
1548 struct netr_GetDcName r
;
1549 const char *dcname
= NULL
;
1551 r
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1552 r
.in
.domainname
= lp_workgroup(tctx
->lp_ctx
);
1553 r
.out
.dcname
= &dcname
;
1555 status
= dcerpc_netr_GetDcName(p
, tctx
, &r
);
1556 torture_assert_ntstatus_ok(tctx
, status
, "GetDcName");
1557 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetDcName");
1559 torture_comment(tctx
, "\tDC is at '%s'\n", dcname
);
1564 static const char *function_code_str(TALLOC_CTX
*mem_ctx
,
1565 enum netr_LogonControlCode function_code
)
1567 switch (function_code
) {
1568 case NETLOGON_CONTROL_QUERY
:
1569 return "NETLOGON_CONTROL_QUERY";
1570 case NETLOGON_CONTROL_REPLICATE
:
1571 return "NETLOGON_CONTROL_REPLICATE";
1572 case NETLOGON_CONTROL_SYNCHRONIZE
:
1573 return "NETLOGON_CONTROL_SYNCHRONIZE";
1574 case NETLOGON_CONTROL_PDC_REPLICATE
:
1575 return "NETLOGON_CONTROL_PDC_REPLICATE";
1576 case NETLOGON_CONTROL_REDISCOVER
:
1577 return "NETLOGON_CONTROL_REDISCOVER";
1578 case NETLOGON_CONTROL_TC_QUERY
:
1579 return "NETLOGON_CONTROL_TC_QUERY";
1580 case NETLOGON_CONTROL_TRANSPORT_NOTIFY
:
1581 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
1582 case NETLOGON_CONTROL_FIND_USER
:
1583 return "NETLOGON_CONTROL_FIND_USER";
1584 case NETLOGON_CONTROL_CHANGE_PASSWORD
:
1585 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
1586 case NETLOGON_CONTROL_TC_VERIFY
:
1587 return "NETLOGON_CONTROL_TC_VERIFY";
1588 case NETLOGON_CONTROL_FORCE_DNS_REG
:
1589 return "NETLOGON_CONTROL_FORCE_DNS_REG";
1590 case NETLOGON_CONTROL_QUERY_DNS_REG
:
1591 return "NETLOGON_CONTROL_QUERY_DNS_REG";
1592 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG
:
1593 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
1594 case NETLOGON_CONTROL_TRUNCATE_LOG
:
1595 return "NETLOGON_CONTROL_TRUNCATE_LOG";
1596 case NETLOGON_CONTROL_SET_DBFLAG
:
1597 return "NETLOGON_CONTROL_SET_DBFLAG";
1598 case NETLOGON_CONTROL_BREAKPOINT
:
1599 return "NETLOGON_CONTROL_BREAKPOINT";
1601 return talloc_asprintf(mem_ctx
, "unknown function code: %d",
1608 try a netlogon LogonControl
1610 static bool test_LogonControl(struct torture_context
*tctx
,
1611 struct dcerpc_pipe
*p
)
1614 struct netr_LogonControl r
;
1615 union netr_CONTROL_QUERY_INFORMATION query
;
1617 uint32_t function_codes
[] = {
1618 NETLOGON_CONTROL_QUERY
,
1619 NETLOGON_CONTROL_REPLICATE
,
1620 NETLOGON_CONTROL_SYNCHRONIZE
,
1621 NETLOGON_CONTROL_PDC_REPLICATE
,
1622 NETLOGON_CONTROL_REDISCOVER
,
1623 NETLOGON_CONTROL_TC_QUERY
,
1624 NETLOGON_CONTROL_TRANSPORT_NOTIFY
,
1625 NETLOGON_CONTROL_FIND_USER
,
1626 NETLOGON_CONTROL_CHANGE_PASSWORD
,
1627 NETLOGON_CONTROL_TC_VERIFY
,
1628 NETLOGON_CONTROL_FORCE_DNS_REG
,
1629 NETLOGON_CONTROL_QUERY_DNS_REG
,
1630 NETLOGON_CONTROL_BACKUP_CHANGE_LOG
,
1631 NETLOGON_CONTROL_TRUNCATE_LOG
,
1632 NETLOGON_CONTROL_SET_DBFLAG
,
1633 NETLOGON_CONTROL_BREAKPOINT
1636 r
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1637 r
.in
.function_code
= 1;
1638 r
.out
.query
= &query
;
1640 for (f
=0;f
<ARRAY_SIZE(function_codes
); f
++) {
1643 r
.in
.function_code
= function_codes
[f
];
1646 torture_comment(tctx
, "Testing LogonControl function code %s (%d) level %d\n",
1647 function_code_str(tctx
, r
.in
.function_code
), r
.in
.function_code
, r
.in
.level
);
1649 status
= dcerpc_netr_LogonControl(p
, tctx
, &r
);
1650 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl");
1652 switch (r
.in
.level
) {
1654 switch (r
.in
.function_code
) {
1655 case NETLOGON_CONTROL_REPLICATE
:
1656 case NETLOGON_CONTROL_SYNCHRONIZE
:
1657 case NETLOGON_CONTROL_PDC_REPLICATE
:
1658 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG
:
1659 case NETLOGON_CONTROL_TRUNCATE_LOG
:
1660 case NETLOGON_CONTROL_BREAKPOINT
:
1661 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_ACCESS_DENIED
,
1662 "LogonControl returned unexpected error code");
1664 case NETLOGON_CONTROL_REDISCOVER
:
1665 case NETLOGON_CONTROL_TC_QUERY
:
1666 case NETLOGON_CONTROL_TRANSPORT_NOTIFY
:
1667 case NETLOGON_CONTROL_FIND_USER
:
1668 case NETLOGON_CONTROL_CHANGE_PASSWORD
:
1669 case NETLOGON_CONTROL_TC_VERIFY
:
1670 case NETLOGON_CONTROL_FORCE_DNS_REG
:
1671 case NETLOGON_CONTROL_QUERY_DNS_REG
:
1672 case NETLOGON_CONTROL_SET_DBFLAG
:
1673 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_NOT_SUPPORTED
,
1674 "LogonControl returned unexpected error code");
1677 torture_assert_werr_ok(tctx
, r
.out
.result
,
1678 "LogonControl returned unexpected result");
1683 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_NOT_SUPPORTED
,
1684 "LogonControl returned unexpected error code");
1687 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_UNKNOWN_LEVEL
,
1688 "LogonControl returned unexpected error code");
1699 try a netlogon GetAnyDCName
1701 static bool test_GetAnyDCName(struct torture_context
*tctx
,
1702 struct dcerpc_pipe
*p
)
1705 struct netr_GetAnyDCName r
;
1706 const char *dcname
= NULL
;
1708 r
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1709 r
.in
.domainname
= lp_workgroup(tctx
->lp_ctx
);
1710 r
.out
.dcname
= &dcname
;
1712 status
= dcerpc_netr_GetAnyDCName(p
, tctx
, &r
);
1713 torture_assert_ntstatus_ok(tctx
, status
, "GetAnyDCName");
1714 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetAnyDCName");
1717 torture_comment(tctx
, "\tDC is at '%s'\n", dcname
);
1725 try a netlogon LogonControl2
1727 static bool test_LogonControl2(struct torture_context
*tctx
,
1728 struct dcerpc_pipe
*p
)
1731 struct netr_LogonControl2 r
;
1732 union netr_CONTROL_DATA_INFORMATION data
;
1733 union netr_CONTROL_QUERY_INFORMATION query
;
1736 data
.domain
= lp_workgroup(tctx
->lp_ctx
);
1738 r
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1740 r
.in
.function_code
= NETLOGON_CONTROL_REDISCOVER
;
1742 r
.out
.query
= &query
;
1747 torture_comment(tctx
, "Testing LogonControl2 level %d function %d\n",
1748 i
, r
.in
.function_code
);
1750 status
= dcerpc_netr_LogonControl2(p
, tctx
, &r
);
1751 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl");
1754 data
.domain
= lp_workgroup(tctx
->lp_ctx
);
1756 r
.in
.function_code
= NETLOGON_CONTROL_TC_QUERY
;
1762 torture_comment(tctx
, "Testing LogonControl2 level %d function %d\n",
1763 i
, r
.in
.function_code
);
1765 status
= dcerpc_netr_LogonControl2(p
, tctx
, &r
);
1766 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl");
1769 data
.domain
= lp_workgroup(tctx
->lp_ctx
);
1771 r
.in
.function_code
= NETLOGON_CONTROL_TRANSPORT_NOTIFY
;
1777 torture_comment(tctx
, "Testing LogonControl2 level %d function %d\n",
1778 i
, r
.in
.function_code
);
1780 status
= dcerpc_netr_LogonControl2(p
, tctx
, &r
);
1781 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl");
1784 data
.debug_level
= ~0;
1786 r
.in
.function_code
= NETLOGON_CONTROL_SET_DBFLAG
;
1792 torture_comment(tctx
, "Testing LogonControl2 level %d function %d\n",
1793 i
, r
.in
.function_code
);
1795 status
= dcerpc_netr_LogonControl2(p
, tctx
, &r
);
1796 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl");
1803 try a netlogon DatabaseSync2
1805 static bool test_DatabaseSync2(struct torture_context
*tctx
,
1806 struct dcerpc_pipe
*p
,
1807 struct cli_credentials
*machine_credentials
)
1810 struct netr_DatabaseSync2 r
;
1811 struct netr_DELTA_ENUM_ARRAY
*delta_enum_array
= NULL
;
1812 struct netr_Authenticator return_authenticator
, credential
;
1814 struct netlogon_creds_CredentialState
*creds
;
1815 const uint32_t database_ids
[] = {0, 1, 2};
1818 if (!test_SetupCredentials2(p
, tctx
, NETLOGON_NEG_AUTH2_FLAGS
,
1819 machine_credentials
,
1820 cli_credentials_get_secure_channel_type(machine_credentials
),
1825 ZERO_STRUCT(return_authenticator
);
1827 r
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1828 r
.in
.computername
= TEST_MACHINE_NAME
;
1829 r
.in
.preferredmaximumlength
= (uint32_t)-1;
1830 r
.in
.return_authenticator
= &return_authenticator
;
1831 r
.out
.return_authenticator
= &return_authenticator
;
1832 r
.out
.delta_enum_array
= &delta_enum_array
;
1834 for (i
=0;i
<ARRAY_SIZE(database_ids
);i
++) {
1836 uint32_t sync_context
= 0;
1838 r
.in
.database_id
= database_ids
[i
];
1839 r
.in
.sync_context
= &sync_context
;
1840 r
.out
.sync_context
= &sync_context
;
1841 r
.in
.restart_state
= 0;
1843 torture_comment(tctx
, "Testing DatabaseSync2 of id %d\n", r
.in
.database_id
);
1846 netlogon_creds_client_authenticator(creds
, &credential
);
1848 r
.in
.credential
= &credential
;
1850 status
= dcerpc_netr_DatabaseSync2(p
, tctx
, &r
);
1851 if (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
1854 /* Native mode servers don't do this */
1855 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_SUPPORTED
)) {
1859 torture_assert_ntstatus_ok(tctx
, status
, "DatabaseSync2");
1861 if (!netlogon_creds_client_check(creds
, &r
.out
.return_authenticator
->cred
)) {
1862 torture_comment(tctx
, "Credential chaining failed\n");
1865 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
1873 try a netlogon LogonControl2Ex
1875 static bool test_LogonControl2Ex(struct torture_context
*tctx
,
1876 struct dcerpc_pipe
*p
)
1879 struct netr_LogonControl2Ex r
;
1880 union netr_CONTROL_DATA_INFORMATION data
;
1881 union netr_CONTROL_QUERY_INFORMATION query
;
1884 data
.domain
= lp_workgroup(tctx
->lp_ctx
);
1886 r
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1888 r
.in
.function_code
= NETLOGON_CONTROL_REDISCOVER
;
1890 r
.out
.query
= &query
;
1895 torture_comment(tctx
, "Testing LogonControl2Ex level %d function %d\n",
1896 i
, r
.in
.function_code
);
1898 status
= dcerpc_netr_LogonControl2Ex(p
, tctx
, &r
);
1899 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl");
1902 data
.domain
= lp_workgroup(tctx
->lp_ctx
);
1904 r
.in
.function_code
= NETLOGON_CONTROL_TC_QUERY
;
1910 torture_comment(tctx
, "Testing LogonControl2Ex level %d function %d\n",
1911 i
, r
.in
.function_code
);
1913 status
= dcerpc_netr_LogonControl2Ex(p
, tctx
, &r
);
1914 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl");
1917 data
.domain
= lp_workgroup(tctx
->lp_ctx
);
1919 r
.in
.function_code
= NETLOGON_CONTROL_TRANSPORT_NOTIFY
;
1925 torture_comment(tctx
, "Testing LogonControl2Ex level %d function %d\n",
1926 i
, r
.in
.function_code
);
1928 status
= dcerpc_netr_LogonControl2Ex(p
, tctx
, &r
);
1929 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl");
1932 data
.debug_level
= ~0;
1934 r
.in
.function_code
= NETLOGON_CONTROL_SET_DBFLAG
;
1940 torture_comment(tctx
, "Testing LogonControl2Ex level %d function %d\n",
1941 i
, r
.in
.function_code
);
1943 status
= dcerpc_netr_LogonControl2Ex(p
, tctx
, &r
);
1944 torture_assert_ntstatus_ok(tctx
, status
, "LogonControl");
1950 static bool test_netr_DsRGetForestTrustInformation(struct torture_context
*tctx
,
1951 struct dcerpc_pipe
*p
, const char *trusted_domain_name
)
1954 struct netr_DsRGetForestTrustInformation r
;
1955 struct lsa_ForestTrustInformation info
, *info_ptr
;
1959 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1960 r
.in
.trusted_domain_name
= trusted_domain_name
;
1962 r
.out
.forest_trust_info
= &info_ptr
;
1964 torture_comment(tctx
,"Testing netr_DsRGetForestTrustInformation\n");
1966 status
= dcerpc_netr_DsRGetForestTrustInformation(p
, tctx
, &r
);
1967 torture_assert_ntstatus_ok(tctx
, status
, "DsRGetForestTrustInformation");
1968 torture_assert_werr_ok(tctx
, r
.out
.result
, "DsRGetForestTrustInformation");
1974 try a netlogon netr_DsrEnumerateDomainTrusts
1976 static bool test_DsrEnumerateDomainTrusts(struct torture_context
*tctx
,
1977 struct dcerpc_pipe
*p
)
1980 struct netr_DsrEnumerateDomainTrusts r
;
1981 struct netr_DomainTrustList trusts
;
1984 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1985 r
.in
.trust_flags
= 0x3f;
1986 r
.out
.trusts
= &trusts
;
1988 status
= dcerpc_netr_DsrEnumerateDomainTrusts(p
, tctx
, &r
);
1989 torture_assert_ntstatus_ok(tctx
, status
, "DsrEnumerateDomaintrusts");
1990 torture_assert_werr_ok(tctx
, r
.out
.result
, "DsrEnumerateDomaintrusts");
1992 /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
1993 * will show non-forest trusts and all UPN suffixes of the own forest
1994 * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
1996 if (r
.out
.trusts
->count
) {
1997 if (!test_netr_DsRGetForestTrustInformation(tctx
, p
, NULL
)) {
2002 for (i
=0; i
<r
.out
.trusts
->count
; i
++) {
2004 /* get info for transitive forest trusts */
2006 if (r
.out
.trusts
->array
[i
].trust_attributes
& NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE
) {
2007 if (!test_netr_DsRGetForestTrustInformation(tctx
, p
,
2008 r
.out
.trusts
->array
[i
].dns_name
)) {
2017 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context
*tctx
,
2018 struct dcerpc_pipe
*p
)
2021 struct netr_NetrEnumerateTrustedDomains r
;
2022 struct netr_Blob trusted_domains_blob
;
2024 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2025 r
.out
.trusted_domains_blob
= &trusted_domains_blob
;
2027 status
= dcerpc_netr_NetrEnumerateTrustedDomains(p
, tctx
, &r
);
2028 torture_assert_ntstatus_ok(tctx
, status
, "netr_NetrEnumerateTrustedDomains");
2029 torture_assert_werr_ok(tctx
, r
.out
.result
, "NetrEnumerateTrustedDomains");
2034 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context
*tctx
,
2035 struct dcerpc_pipe
*p
)
2038 struct netr_NetrEnumerateTrustedDomainsEx r
;
2039 struct netr_DomainTrustList dom_trust_list
;
2041 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2042 r
.out
.dom_trust_list
= &dom_trust_list
;
2044 status
= dcerpc_netr_NetrEnumerateTrustedDomainsEx(p
, tctx
, &r
);
2045 torture_assert_ntstatus_ok(tctx
, status
, "netr_NetrEnumerateTrustedDomainsEx");
2046 torture_assert_werr_ok(tctx
, r
.out
.result
, "NetrEnumerateTrustedDomainsEx");
2052 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2053 const char *computer_name
,
2054 const char *expected_site
)
2057 struct netr_DsRGetSiteName r
;
2058 const char *site
= NULL
;
2060 if (torture_setting_bool(tctx
, "samba4", false))
2061 torture_skip(tctx
, "skipping DsRGetSiteName test against Samba4");
2063 r
.in
.computer_name
= computer_name
;
2065 torture_comment(tctx
, "Testing netr_DsRGetSiteName\n");
2067 status
= dcerpc_netr_DsRGetSiteName(p
, tctx
, &r
);
2068 torture_assert_ntstatus_ok(tctx
, status
, "DsRGetSiteName");
2069 torture_assert_werr_ok(tctx
, r
.out
.result
, "DsRGetSiteName");
2070 torture_assert_str_equal(tctx
, expected_site
, site
, "netr_DsRGetSiteName");
2072 r
.in
.computer_name
= talloc_asprintf(tctx
, "\\\\%s", computer_name
);
2073 torture_comment(tctx
,
2074 "Testing netr_DsRGetSiteName with broken computer name: %s\n", r
.in
.computer_name
);
2076 status
= dcerpc_netr_DsRGetSiteName(p
, tctx
, &r
);
2077 torture_assert_ntstatus_ok(tctx
, status
, "DsRGetSiteName");
2078 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_COMPUTERNAME
, "netr_DsRGetSiteName");
2084 try a netlogon netr_DsRGetDCName
2086 static bool test_netr_DsRGetDCName(struct torture_context
*tctx
,
2087 struct dcerpc_pipe
*p
)
2090 struct netr_DsRGetDCName r
;
2091 struct netr_DsRGetDCNameInfo
*info
= NULL
;
2093 r
.in
.server_unc
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2094 r
.in
.domain_name
= lp_dnsdomain(tctx
->lp_ctx
);
2095 r
.in
.domain_guid
= NULL
;
2096 r
.in
.site_guid
= NULL
;
2097 r
.in
.flags
= DS_RETURN_DNS_NAME
;
2100 status
= dcerpc_netr_DsRGetDCName(p
, tctx
, &r
);
2101 torture_assert_ntstatus_ok(tctx
, status
, "DsRGetDCName");
2102 torture_assert_werr_ok(tctx
, r
.out
.result
, "DsRGetDCName");
2103 return test_netr_DsRGetSiteName(p
, tctx
,
2105 info
->dc_site_name
);
2109 try a netlogon netr_DsRGetDCNameEx
2111 static bool test_netr_DsRGetDCNameEx(struct torture_context
*tctx
,
2112 struct dcerpc_pipe
*p
)
2115 struct netr_DsRGetDCNameEx r
;
2116 struct netr_DsRGetDCNameInfo
*info
= NULL
;
2118 r
.in
.server_unc
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2119 r
.in
.domain_name
= lp_dnsdomain(tctx
->lp_ctx
);
2120 r
.in
.domain_guid
= NULL
;
2121 r
.in
.site_name
= NULL
;
2122 r
.in
.flags
= DS_RETURN_DNS_NAME
;
2125 status
= dcerpc_netr_DsRGetDCNameEx(p
, tctx
, &r
);
2126 torture_assert_ntstatus_ok(tctx
, status
, "netr_DsRGetDCNameEx");
2127 torture_assert_werr_ok(tctx
, r
.out
.result
, "netr_DsRGetDCNameEx");
2129 return test_netr_DsRGetSiteName(p
, tctx
, info
->dc_unc
,
2130 info
->dc_site_name
);
2134 try a netlogon netr_DsRGetDCNameEx2
2136 static bool test_netr_DsRGetDCNameEx2(struct torture_context
*tctx
,
2137 struct dcerpc_pipe
*p
)
2140 struct netr_DsRGetDCNameEx2 r
;
2141 struct netr_DsRGetDCNameInfo
*info
= NULL
;
2143 r
.in
.server_unc
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2144 r
.in
.client_account
= NULL
;
2145 r
.in
.mask
= 0x00000000;
2146 r
.in
.domain_name
= lp_dnsdomain(tctx
->lp_ctx
);
2147 r
.in
.domain_guid
= NULL
;
2148 r
.in
.site_name
= NULL
;
2149 r
.in
.flags
= DS_RETURN_DNS_NAME
;
2152 torture_comment(tctx
, "Testing netr_DsRGetDCNameEx2 without client account\n");
2154 status
= dcerpc_netr_DsRGetDCNameEx2(p
, tctx
, &r
);
2155 torture_assert_ntstatus_ok(tctx
, status
, "netr_DsRGetDCNameEx2");
2156 torture_assert_werr_ok(tctx
, r
.out
.result
, "netr_DsRGetDCNameEx2");
2158 torture_comment(tctx
, "Testing netr_DsRGetDCNameEx2 with client acount\n");
2159 r
.in
.client_account
= TEST_MACHINE_NAME
"$";
2160 r
.in
.mask
= ACB_SVRTRUST
;
2161 r
.in
.flags
= DS_RETURN_FLAT_NAME
;
2164 status
= dcerpc_netr_DsRGetDCNameEx2(p
, tctx
, &r
);
2165 torture_assert_ntstatus_ok(tctx
, status
, "netr_DsRGetDCNameEx2");
2166 torture_assert_werr_ok(tctx
, r
.out
.result
, "netr_DsRGetDCNameEx2");
2167 return test_netr_DsRGetSiteName(p
, tctx
, info
->dc_unc
,
2168 info
->dc_site_name
);
2171 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context
*tctx
,
2172 struct dcerpc_pipe
*p
)
2175 struct netr_DsrGetDcSiteCoverageW r
;
2176 struct DcSitesCtr
*ctr
= NULL
;
2178 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2181 status
= dcerpc_netr_DsrGetDcSiteCoverageW(p
, tctx
, &r
);
2182 torture_assert_ntstatus_ok(tctx
, status
, "failed");
2183 torture_assert_werr_ok(tctx
, r
.out
.result
, "failed");
2188 static bool test_netr_DsRAddressToSitenamesW(struct torture_context
*tctx
,
2189 struct dcerpc_pipe
*p
)
2192 struct netr_DsRAddressToSitenamesW r
;
2193 struct netr_DsRAddress addr
;
2194 struct netr_DsRAddressToSitenamesWCtr
*ctr
;
2196 ctr
= talloc(tctx
, struct netr_DsRAddressToSitenamesWCtr
);
2199 addr
.buffer
= talloc_zero_array(tctx
, uint8_t, addr
.size
);
2201 addr
.buffer
[0] = 2; /* AF_INET */
2202 addr
.buffer
[4] = 127;
2207 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2209 r
.in
.addresses
= talloc_zero_array(tctx
, struct netr_DsRAddress
, r
.in
.count
);
2210 r
.in
.addresses
[0] = addr
;
2213 status
= dcerpc_netr_DsRAddressToSitenamesW(p
, tctx
, &r
);
2214 torture_assert_ntstatus_ok(tctx
, status
, "failed");
2215 torture_assert_werr_ok(tctx
, r
.out
.result
, "failed");
2220 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context
*tctx
,
2221 struct dcerpc_pipe
*p
)
2224 struct netr_DsRAddressToSitenamesExW r
;
2225 struct netr_DsRAddress addr
;
2226 struct netr_DsRAddressToSitenamesExWCtr
*ctr
;
2228 ctr
= talloc(tctx
, struct netr_DsRAddressToSitenamesExWCtr
);
2231 addr
.buffer
= talloc_zero_array(tctx
, uint8_t, addr
.size
);
2233 addr
.buffer
[0] = 2; /* AF_INET */
2234 addr
.buffer
[4] = 127;
2239 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2241 r
.in
.addresses
= talloc_zero_array(tctx
, struct netr_DsRAddress
, r
.in
.count
);
2242 r
.in
.addresses
[0] = addr
;
2245 status
= dcerpc_netr_DsRAddressToSitenamesExW(p
, tctx
, &r
);
2246 torture_assert_ntstatus_ok(tctx
, status
, "failed");
2247 torture_assert_werr_ok(tctx
, r
.out
.result
, "failed");
2252 static bool test_netr_ServerGetTrustInfo(struct torture_context
*tctx
,
2253 struct dcerpc_pipe
*p
,
2254 struct cli_credentials
*machine_credentials
)
2257 struct netr_ServerGetTrustInfo r
;
2259 struct netr_Authenticator a
;
2260 struct netr_Authenticator return_authenticator
;
2261 struct samr_Password new_owf_password
;
2262 struct samr_Password old_owf_password
;
2263 struct netr_TrustInfo
*trust_info
;
2265 struct netlogon_creds_CredentialState
*creds
;
2267 if (!test_SetupCredentials3(p
, tctx
, NETLOGON_NEG_AUTH2_ADS_FLAGS
,
2268 machine_credentials
, &creds
)) {
2272 netlogon_creds_client_authenticator(creds
, &a
);
2274 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2275 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", TEST_MACHINE_NAME
);
2276 r
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
2277 r
.in
.computer_name
= TEST_MACHINE_NAME
;
2278 r
.in
.credential
= &a
;
2280 r
.out
.return_authenticator
= &return_authenticator
;
2281 r
.out
.new_owf_password
= &new_owf_password
;
2282 r
.out
.old_owf_password
= &old_owf_password
;
2283 r
.out
.trust_info
= &trust_info
;
2285 status
= dcerpc_netr_ServerGetTrustInfo(p
, tctx
, &r
);
2286 torture_assert_ntstatus_ok(tctx
, status
, "failed");
2287 torture_assert(tctx
, netlogon_creds_client_check(creds
, &return_authenticator
.cred
), "Credential chaining failed");
2293 static bool test_GetDomainInfo(struct torture_context
*tctx
,
2294 struct dcerpc_pipe
*p
,
2295 struct cli_credentials
*machine_credentials
)
2298 struct netr_LogonGetDomainInfo r
;
2299 struct netr_WorkstationInformation q1
;
2300 struct netr_Authenticator a
;
2301 struct netlogon_creds_CredentialState
*creds
;
2302 struct netr_OsVersion os
;
2303 union netr_WorkstationInfo query
;
2304 union netr_DomainInfo info
;
2305 const char* const attrs
[] = { "dNSHostName", "operatingSystem",
2306 "operatingSystemServicePack", "operatingSystemVersion",
2307 "servicePrincipalName", NULL
};
2309 struct ldb_context
*sam_ctx
= NULL
;
2310 struct ldb_message
**res
;
2311 struct ldb_message_element
*spn_el
;
2314 const char *old_dnsname
= NULL
;
2319 torture_comment(tctx
, "Testing netr_LogonGetDomainInfo\n");
2321 if (!test_SetupCredentials3(p
, tctx
, NETLOGON_NEG_AUTH2_ADS_FLAGS
,
2322 machine_credentials
, &creds
)) {
2326 /* We won't double-check this when we are over 'local' transports */
2327 if (dcerpc_server_name(p
)) {
2328 /* Set up connection to SAMDB on DC */
2329 url
= talloc_asprintf(tctx
, "ldap://%s", dcerpc_server_name(p
));
2330 sam_ctx
= ldb_wrap_connect(tctx
, tctx
->ev
, tctx
->lp_ctx
, url
,
2332 cmdline_credentials
,
2335 torture_assert(tctx
, sam_ctx
, "Connection to the SAMDB on DC failed!");
2338 torture_comment(tctx
, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
2339 netlogon_creds_client_authenticator(creds
, &a
);
2342 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2343 r
.in
.computer_name
= TEST_MACHINE_NAME
;
2344 r
.in
.credential
= &a
;
2346 r
.in
.return_authenticator
= &a
;
2347 r
.in
.query
= &query
;
2348 r
.out
.return_authenticator
= &a
;
2352 os
.os
.MajorVersion
= 123;
2353 os
.os
.MinorVersion
= 456;
2354 os
.os
.BuildNumber
= 789;
2355 os
.os
.CSDVersion
= "Service Pack 10";
2356 os
.os
.ServicePackMajor
= 10;
2357 os
.os
.ServicePackMinor
= 1;
2358 os
.os
.SuiteMask
= NETR_VER_SUITE_SINGLEUSERTS
;
2359 os
.os
.ProductType
= NETR_VER_NT_SERVER
;
2362 version_str
= talloc_asprintf(tctx
, "%d.%d (%d)", os
.os
.MajorVersion
,
2363 os
.os
.MinorVersion
, os
.os
.BuildNumber
);
2366 q1
.dns_hostname
= talloc_asprintf(tctx
, "%s.%s", TEST_MACHINE_NAME
,
2367 TEST_MACHINE_DNS_SUFFIX
);
2368 q1
.sitename
= "Default-First-Site-Name";
2369 q1
.os_version
.os
= &os
;
2370 q1
.os_name
.string
= talloc_asprintf(tctx
,
2371 "Tortured by Samba4 RPC-NETLOGON: %s",
2372 timestring(tctx
, time(NULL
)));
2374 /* The workstation handles the "servicePrincipalName" and DNS hostname
2376 q1
.workstation_flags
= NETR_WS_FLAG_HANDLES_SPN_UPDATE
;
2378 query
.workstation_info
= &q1
;
2381 /* Gets back the old DNS hostname in AD */
2382 ret
= gendb_search(sam_ctx
, tctx
, NULL
, &res
, attrs
,
2383 "(sAMAccountName=%s$)", TEST_MACHINE_NAME
);
2385 ldb_msg_find_attr_as_string(res
[0], "dNSHostName", NULL
);
2387 /* Gets back the "servicePrincipalName"s in AD */
2388 spn_el
= ldb_msg_find_element(res
[0], "servicePrincipalName");
2389 if (spn_el
!= NULL
) {
2390 for (i
=0; i
< spn_el
->num_values
; i
++) {
2391 spns
= talloc_realloc(tctx
, spns
, char *, i
+ 1);
2392 spns
[i
] = (char *) spn_el
->values
[i
].data
;
2398 status
= dcerpc_netr_LogonGetDomainInfo(p
, tctx
, &r
);
2399 torture_assert_ntstatus_ok(tctx
, status
, "netr_LogonGetDomainInfo");
2400 torture_assert(tctx
, netlogon_creds_client_check(creds
, &a
.cred
), "Credential chaining failed");
2405 /* AD workstation infos entry check */
2406 ret
= gendb_search(sam_ctx
, tctx
, NULL
, &res
, attrs
,
2407 "(sAMAccountName=%s$)", TEST_MACHINE_NAME
);
2408 torture_assert(tctx
, ret
== 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
2409 torture_assert_str_equal(tctx
,
2410 ldb_msg_find_attr_as_string(res
[0], "operatingSystem", NULL
),
2411 q1
.os_name
.string
, "'operatingSystem' wrong!");
2412 torture_assert_str_equal(tctx
,
2413 ldb_msg_find_attr_as_string(res
[0], "operatingSystemServicePack", NULL
),
2414 os
.os
.CSDVersion
, "'operatingSystemServicePack' wrong!");
2415 torture_assert_str_equal(tctx
,
2416 ldb_msg_find_attr_as_string(res
[0], "operatingSystemVersion", NULL
),
2417 version_str
, "'operatingSystemVersion' wrong!");
2419 if (old_dnsname
!= NULL
) {
2420 /* If before a DNS hostname was set then it should remain
2421 the same in combination with the "servicePrincipalName"s.
2422 The DNS hostname should also be returned by our
2423 "LogonGetDomainInfo" call (in the domain info structure). */
2425 torture_assert_str_equal(tctx
,
2426 ldb_msg_find_attr_as_string(res
[0], "dNSHostName", NULL
),
2427 old_dnsname
, "'DNS hostname' was not set!");
2429 spn_el
= ldb_msg_find_element(res
[0], "servicePrincipalName");
2430 torture_assert(tctx
, ((spns
!= NULL
) && (spn_el
!= NULL
)),
2431 "'servicePrincipalName's not set!");
2432 torture_assert(tctx
, spn_el
->num_values
== num_spns
,
2433 "'servicePrincipalName's incorrect!");
2434 for (i
=0; (i
< spn_el
->num_values
) && (i
< num_spns
); i
++)
2435 torture_assert_str_equal(tctx
,
2436 (char *) spn_el
->values
[i
].data
,
2437 spns
[i
], "'servicePrincipalName's incorrect!");
2439 torture_assert_str_equal(tctx
,
2440 info
.domain_info
->dns_hostname
.string
,
2442 "Out 'DNS hostname' doesn't match the old one!");
2444 /* If no DNS hostname was set then also now none should be set,
2445 the "servicePrincipalName"s should remain empty and no DNS
2446 hostname should be returned by our "LogonGetDomainInfo"
2447 call (in the domain info structure). */
2449 torture_assert(tctx
,
2450 ldb_msg_find_attr_as_string(res
[0], "dNSHostName", NULL
) == NULL
,
2451 "'DNS hostname' was set!");
2453 spn_el
= ldb_msg_find_element(res
[0], "servicePrincipalName");
2454 torture_assert(tctx
, ((spns
== NULL
) && (spn_el
== NULL
)),
2455 "'servicePrincipalName's were set!");
2457 torture_assert(tctx
,
2458 info
.domain_info
->dns_hostname
.string
== NULL
,
2459 "Out 'DNS host name' was set!");
2463 /* Checks "workstation flags" */
2464 torture_assert(tctx
,
2465 info
.domain_info
->workstation_flags
2466 == NETR_WS_FLAG_HANDLES_SPN_UPDATE
,
2467 "Out 'workstation flags' don't match!");
2470 torture_comment(tctx
, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname)\n");
2471 netlogon_creds_client_authenticator(creds
, &a
);
2473 /* Wipe out the osVersion, and prove which values still 'stick' */
2474 q1
.os_version
.os
= NULL
;
2476 /* Change also the DNS hostname to test differences in behaviour */
2477 q1
.dns_hostname
= talloc_asprintf(tctx
, "%s.newdomain",
2480 /* Let the DC handle the "servicePrincipalName" and DNS hostname
2482 q1
.workstation_flags
= 0;
2484 status
= dcerpc_netr_LogonGetDomainInfo(p
, tctx
, &r
);
2485 torture_assert_ntstatus_ok(tctx
, status
, "netr_LogonGetDomainInfo");
2486 torture_assert(tctx
, netlogon_creds_client_check(creds
, &a
.cred
), "Credential chaining failed");
2491 /* AD workstation infos entry check */
2492 ret
= gendb_search(sam_ctx
, tctx
, NULL
, &res
, attrs
,
2493 "(sAMAccountName=%s$)", TEST_MACHINE_NAME
);
2494 torture_assert(tctx
, ret
== 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
2495 torture_assert_str_equal(tctx
,
2496 ldb_msg_find_attr_as_string(res
[0], "operatingSystem", NULL
),
2497 q1
.os_name
.string
, "'operatingSystem' should stick!");
2498 torture_assert(tctx
,
2499 ldb_msg_find_attr_as_string(res
[0], "operatingSystemServicePack", NULL
) == NULL
,
2500 "'operatingSystemServicePack' shouldn't stick!");
2501 torture_assert(tctx
,
2502 ldb_msg_find_attr_as_string(res
[0], "operatingSystemVersion", NULL
) == NULL
,
2503 "'operatingSystemVersion' shouldn't stick!");
2505 /* The DNS host name should have been updated now by the server */
2506 torture_assert_str_equal(tctx
,
2507 ldb_msg_find_attr_as_string(res
[0], "dNSHostName", NULL
),
2508 q1
.dns_hostname
, "'DNS host name' didn't change!");
2510 /* Find the two "servicePrincipalName"s which the DC should have been
2511 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
2513 spn_el
= ldb_msg_find_element(res
[0], "servicePrincipalName");
2514 torture_assert(tctx
, spn_el
!= NULL
,
2515 "There should exist 'servicePrincipalName's in AD!");
2516 temp_str
= talloc_asprintf(tctx
, "HOST/%s", TEST_MACHINE_NAME
);
2517 for (i
=0; i
< spn_el
->num_values
; i
++)
2518 if (strcmp((char *) spn_el
->values
[i
].data
, temp_str
) == 0)
2520 torture_assert(tctx
, i
!= spn_el
->num_values
,
2521 "'servicePrincipalName' HOST/<Netbios name> not found!");
2522 temp_str
= talloc_asprintf(tctx
, "HOST/%s", q1
.dns_hostname
);
2523 for (i
=0; i
< spn_el
->num_values
; i
++)
2524 if (strcmp((char *) spn_el
->values
[i
].data
, temp_str
) == 0)
2526 torture_assert(tctx
, i
!= spn_el
->num_values
,
2527 "'servicePrincipalName' HOST/<FQDN name> not found!");
2529 /* Check that the out DNS hostname was set properly */
2530 torture_assert_str_equal(tctx
, info
.domain_info
->dns_hostname
.string
,
2531 old_dnsname
, "Out 'DNS hostname' doesn't match the old one!");
2534 /* Checks "workstation flags" */
2535 torture_assert(tctx
,
2536 info
.domain_info
->workstation_flags
== 0,
2537 "Out 'workstation flags' don't match!");
2540 torture_comment(tctx
, "Testing netr_LogonGetDomainInfo 3rd call (verification of DNS hostname and check for trusted domains)\n");
2541 netlogon_creds_client_authenticator(creds
, &a
);
2543 /* The workstation handles the "servicePrincipalName" and DNS hostname
2545 q1
.workstation_flags
= NETR_WS_FLAG_HANDLES_SPN_UPDATE
;
2547 status
= dcerpc_netr_LogonGetDomainInfo(p
, tctx
, &r
);
2548 torture_assert_ntstatus_ok(tctx
, status
, "netr_LogonGetDomainInfo");
2549 torture_assert(tctx
, netlogon_creds_client_check(creds
, &a
.cred
), "Credential chaining failed");
2553 /* Now the in/out DNS hostnames should be the same */
2554 torture_assert_str_equal(tctx
,
2555 info
.domain_info
->dns_hostname
.string
,
2556 query
.workstation_info
->dns_hostname
,
2557 "In/Out 'DNS hostnames' don't match!");
2559 /* Checks "workstation flags" */
2560 torture_assert(tctx
,
2561 info
.domain_info
->workstation_flags
2562 == NETR_WS_FLAG_HANDLES_SPN_UPDATE
,
2563 "Out 'workstation flags' don't match!");
2565 /* Checks for trusted domains */
2566 torture_assert(tctx
,
2567 (info
.domain_info
->trusted_domain_count
!= 0)
2568 && (info
.domain_info
->trusted_domains
!= NULL
),
2569 "Trusted domains have been requested!");
2572 torture_comment(tctx
, "Testing netr_LogonGetDomainInfo 4th call (check for trusted domains)\n");
2573 netlogon_creds_client_authenticator(creds
, &a
);
2575 /* The workstation handles the "servicePrincipalName" and DNS hostname
2576 updates and requests inbound trusts */
2577 q1
.workstation_flags
= NETR_WS_FLAG_HANDLES_SPN_UPDATE
2578 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS
;
2580 status
= dcerpc_netr_LogonGetDomainInfo(p
, tctx
, &r
);
2581 torture_assert_ntstatus_ok(tctx
, status
, "netr_LogonGetDomainInfo");
2582 torture_assert(tctx
, netlogon_creds_client_check(creds
, &a
.cred
), "Credential chaining failed");
2586 /* Checks "workstation flags" */
2587 torture_assert(tctx
,
2588 info
.domain_info
->workstation_flags
2589 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
2590 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS
),
2591 "Out 'workstation flags' don't match!");
2593 /* Checks for trusted domains */
2594 torture_assert(tctx
,
2595 (info
.domain_info
->trusted_domain_count
!= 0)
2596 && (info
.domain_info
->trusted_domains
!= NULL
),
2597 "Trusted domains have been requested!");
2603 static void async_callback(struct rpc_request
*req
)
2605 int *counter
= (int *)req
->async
.private_data
;
2606 if (NT_STATUS_IS_OK(req
->status
)) {
2611 static bool test_GetDomainInfo_async(struct torture_context
*tctx
,
2612 struct dcerpc_pipe
*p
,
2613 struct cli_credentials
*machine_credentials
)
2616 struct netr_LogonGetDomainInfo r
;
2617 struct netr_WorkstationInformation q1
;
2618 struct netr_Authenticator a
;
2619 #define ASYNC_COUNT 100
2620 struct netlogon_creds_CredentialState
*creds
;
2621 struct netlogon_creds_CredentialState
*creds_async
[ASYNC_COUNT
];
2622 struct rpc_request
*req
[ASYNC_COUNT
];
2624 int *async_counter
= talloc(tctx
, int);
2625 union netr_WorkstationInfo query
;
2626 union netr_DomainInfo info
;
2628 torture_comment(tctx
, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT
);
2630 if (!test_SetupCredentials3(p
, tctx
, NETLOGON_NEG_AUTH2_ADS_FLAGS
,
2631 machine_credentials
, &creds
)) {
2636 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2637 r
.in
.computer_name
= TEST_MACHINE_NAME
;
2638 r
.in
.credential
= &a
;
2640 r
.in
.return_authenticator
= &a
;
2641 r
.in
.query
= &query
;
2642 r
.out
.return_authenticator
= &a
;
2646 q1
.dns_hostname
= talloc_asprintf(tctx
, "%s.%s", TEST_MACHINE_NAME
,
2647 TEST_MACHINE_DNS_SUFFIX
);
2648 q1
.sitename
= "Default-First-Site-Name";
2649 q1
.os_name
.string
= "UNIX/Linux or similar";
2651 query
.workstation_info
= &q1
;
2655 for (i
=0;i
<ASYNC_COUNT
;i
++) {
2656 netlogon_creds_client_authenticator(creds
, &a
);
2658 creds_async
[i
] = (struct netlogon_creds_CredentialState
*)talloc_memdup(creds
, creds
, sizeof(*creds
));
2659 req
[i
] = dcerpc_netr_LogonGetDomainInfo_send(p
, tctx
, &r
);
2661 req
[i
]->async
.callback
= async_callback
;
2662 req
[i
]->async
.private_data
= async_counter
;
2664 /* even with this flush per request a w2k3 server seems to
2665 clag with multiple outstanding requests. bleergh. */
2666 torture_assert_int_equal(tctx
, event_loop_once(dcerpc_event_context(p
)), 0,
2667 "event_loop_once failed");
2670 for (i
=0;i
<ASYNC_COUNT
;i
++) {
2671 status
= dcerpc_ndr_request_recv(req
[i
]);
2673 torture_assert_ntstatus_ok(tctx
, status
, "netr_LogonGetDomainInfo_async");
2674 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "netr_LogonGetDomainInfo_async");
2676 torture_assert(tctx
, netlogon_creds_client_check(creds_async
[i
], &a
.cred
),
2677 "Credential chaining failed at async");
2680 torture_comment(tctx
,
2681 "Testing netr_LogonGetDomainInfo - async count %d OK\n", *async_counter
);
2683 torture_assert_int_equal(tctx
, (*async_counter
), ASYNC_COUNT
, "int");
2688 static bool test_ManyGetDCName(struct torture_context
*tctx
,
2689 struct dcerpc_pipe
*p
)
2692 struct dcerpc_pipe
*p2
;
2693 struct lsa_ObjectAttribute attr
;
2694 struct lsa_QosInfo qos
;
2695 struct lsa_OpenPolicy2 o
;
2696 struct policy_handle lsa_handle
;
2697 struct lsa_DomainList domains
;
2699 struct lsa_EnumTrustDom t
;
2700 uint32_t resume_handle
= 0;
2701 struct netr_GetAnyDCName d
;
2702 const char *dcname
= NULL
;
2706 if (p
->conn
->transport
.transport
!= NCACN_NP
) {
2710 torture_comment(tctx
, "Torturing GetDCName\n");
2712 status
= dcerpc_secondary_connection(p
, &p2
, p
->binding
);
2713 torture_assert_ntstatus_ok(tctx
, status
, "Failed to create secondary connection");
2715 status
= dcerpc_bind_auth_none(p2
, &ndr_table_lsarpc
);
2716 torture_assert_ntstatus_ok(tctx
, status
, "Failed to create bind on secondary connection");
2719 qos
.impersonation_level
= 2;
2720 qos
.context_mode
= 1;
2721 qos
.effective_only
= 0;
2724 attr
.root_dir
= NULL
;
2725 attr
.object_name
= NULL
;
2726 attr
.attributes
= 0;
2727 attr
.sec_desc
= NULL
;
2728 attr
.sec_qos
= &qos
;
2730 o
.in
.system_name
= "\\";
2732 o
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2733 o
.out
.handle
= &lsa_handle
;
2735 status
= dcerpc_lsa_OpenPolicy2(p2
, tctx
, &o
);
2736 torture_assert_ntstatus_ok(tctx
, status
, "OpenPolicy2 failed");
2738 t
.in
.handle
= &lsa_handle
;
2739 t
.in
.resume_handle
= &resume_handle
;
2740 t
.in
.max_size
= 1000;
2741 t
.out
.domains
= &domains
;
2742 t
.out
.resume_handle
= &resume_handle
;
2744 status
= dcerpc_lsa_EnumTrustDom(p2
, tctx
, &t
);
2746 if ((!NT_STATUS_IS_OK(status
) &&
2747 (!NT_STATUS_EQUAL(status
, NT_STATUS_NO_MORE_ENTRIES
))))
2748 torture_fail(tctx
, "Could not list domains");
2752 d
.in
.logon_server
= talloc_asprintf(tctx
, "\\\\%s",
2753 dcerpc_server_name(p
));
2754 d
.out
.dcname
= &dcname
;
2756 for (i
=0; i
<domains
.count
* 4; i
++) {
2757 struct lsa_DomainInfo
*info
=
2758 &domains
.domains
[rand()%domains
.count
];
2760 d
.in
.domainname
= info
->name
.string
;
2762 status
= dcerpc_netr_GetAnyDCName(p
, tctx
, &d
);
2763 torture_assert_ntstatus_ok(tctx
, status
, "GetAnyDCName");
2765 torture_comment(tctx
, "\tDC for domain %s is %s\n", info
->name
.string
,
2766 dcname
? dcname
: "unknown");
2772 static bool test_SetPassword_with_flags(struct torture_context
*tctx
,
2773 struct dcerpc_pipe
*p
,
2774 struct cli_credentials
*machine_credentials
)
2776 uint32_t flags
[] = { 0, NETLOGON_NEG_STRONG_KEYS
};
2777 struct netlogon_creds_CredentialState
*creds
;
2780 if (!test_SetupCredentials2(p
, tctx
, 0,
2781 machine_credentials
,
2782 cli_credentials_get_secure_channel_type(machine_credentials
),
2784 torture_skip(tctx
, "DC does not support negotiation of 64bit session keys");
2787 for (i
=0; i
< ARRAY_SIZE(flags
); i
++) {
2788 torture_assert(tctx
,
2789 test_SetPassword_flags(tctx
, p
, machine_credentials
, flags
[i
]),
2790 talloc_asprintf(tctx
, "failed to test SetPassword negotiating with 0x%08x flags", flags
[i
]));
2796 struct torture_suite
*torture_rpc_netlogon(TALLOC_CTX
*mem_ctx
)
2798 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "NETLOGON");
2799 struct torture_rpc_tcase
*tcase
;
2800 struct torture_test
*test
;
2802 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "netlogon",
2803 &ndr_table_netlogon
, TEST_MACHINE_NAME
);
2805 torture_rpc_tcase_add_test(tcase
, "LogonUasLogon", test_LogonUasLogon
);
2806 torture_rpc_tcase_add_test(tcase
, "LogonUasLogoff", test_LogonUasLogoff
);
2807 torture_rpc_tcase_add_test_creds(tcase
, "SamLogon", test_SamLogon
);
2808 torture_rpc_tcase_add_test_creds(tcase
, "SetPassword", test_SetPassword
);
2809 torture_rpc_tcase_add_test_creds(tcase
, "SetPassword2", test_SetPassword2
);
2810 torture_rpc_tcase_add_test_creds(tcase
, "GetPassword", test_GetPassword
);
2811 torture_rpc_tcase_add_test_creds(tcase
, "GetTrustPasswords", test_GetTrustPasswords
);
2812 torture_rpc_tcase_add_test_creds(tcase
, "GetDomainInfo", test_GetDomainInfo
);
2813 torture_rpc_tcase_add_test_creds(tcase
, "DatabaseSync", test_DatabaseSync
);
2814 torture_rpc_tcase_add_test_creds(tcase
, "DatabaseDeltas", test_DatabaseDeltas
);
2815 torture_rpc_tcase_add_test_creds(tcase
, "DatabaseRedo", test_DatabaseRedo
);
2816 torture_rpc_tcase_add_test_creds(tcase
, "AccountDeltas", test_AccountDeltas
);
2817 torture_rpc_tcase_add_test_creds(tcase
, "AccountSync", test_AccountSync
);
2818 torture_rpc_tcase_add_test(tcase
, "GetDcName", test_GetDcName
);
2819 torture_rpc_tcase_add_test(tcase
, "ManyGetDCName", test_ManyGetDCName
);
2820 torture_rpc_tcase_add_test(tcase
, "LogonControl", test_LogonControl
);
2821 torture_rpc_tcase_add_test(tcase
, "GetAnyDCName", test_GetAnyDCName
);
2822 torture_rpc_tcase_add_test(tcase
, "LogonControl2", test_LogonControl2
);
2823 torture_rpc_tcase_add_test_creds(tcase
, "DatabaseSync2", test_DatabaseSync2
);
2824 torture_rpc_tcase_add_test(tcase
, "LogonControl2Ex", test_LogonControl2Ex
);
2825 torture_rpc_tcase_add_test(tcase
, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts
);
2826 torture_rpc_tcase_add_test(tcase
, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains
);
2827 torture_rpc_tcase_add_test(tcase
, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx
);
2828 test
= torture_rpc_tcase_add_test_creds(tcase
, "GetDomainInfo_async", test_GetDomainInfo_async
);
2829 test
->dangerous
= true;
2830 torture_rpc_tcase_add_test(tcase
, "DsRGetDCName", test_netr_DsRGetDCName
);
2831 torture_rpc_tcase_add_test(tcase
, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx
);
2832 torture_rpc_tcase_add_test(tcase
, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2
);
2833 torture_rpc_tcase_add_test(tcase
, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW
);
2834 torture_rpc_tcase_add_test(tcase
, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW
);
2835 torture_rpc_tcase_add_test(tcase
, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW
);
2836 torture_rpc_tcase_add_test_creds(tcase
, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo
);
2841 struct torture_suite
*torture_rpc_netlogon_s3(TALLOC_CTX
*mem_ctx
)
2843 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "NETLOGON-S3");
2844 struct torture_rpc_tcase
*tcase
;
2846 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "netlogon",
2847 &ndr_table_netlogon
, TEST_MACHINE_NAME
);
2849 torture_rpc_tcase_add_test_creds(tcase
, "SamLogon", test_SamLogon
);
2850 torture_rpc_tcase_add_test_creds(tcase
, "SetPassword", test_SetPassword
);
2851 torture_rpc_tcase_add_test_creds(tcase
, "SetPassword_with_flags", test_SetPassword_with_flags
);
2852 torture_rpc_tcase_add_test_creds(tcase
, "SetPassword2", test_SetPassword2
);
2853 torture_rpc_tcase_add_test(tcase
, "LogonControl", test_LogonControl
);
2854 torture_rpc_tcase_add_test(tcase
, "LogonControl2", test_LogonControl2
);
2855 torture_rpc_tcase_add_test(tcase
, "LogonControl2Ex", test_LogonControl2Ex
);
2856 torture_rpc_tcase_add_test(tcase
, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains
);