source: trunk/server/source4/torture/rpc/netlogon.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 122.9 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3
4 test suite for netlogon rpc operations
5
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
10
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.
15
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.
20
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/>.
23*/
24
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"
40
41#define TEST_MACHINE_NAME "torturetest"
42
43static bool test_LogonUasLogon(struct torture_context *tctx,
44 struct dcerpc_pipe *p)
45{
46 NTSTATUS status;
47 struct netr_LogonUasLogon r;
48 struct netr_UasInfo *info = NULL;
49 struct dcerpc_binding_handle *b = p->binding_handle;
50
51 r.in.server_name = NULL;
52 r.in.account_name = cli_credentials_get_username(cmdline_credentials);
53 r.in.workstation = TEST_MACHINE_NAME;
54 r.out.info = &info;
55
56 status = dcerpc_netr_LogonUasLogon_r(b, tctx, &r);
57 torture_assert_ntstatus_ok(tctx, status, "LogonUasLogon");
58
59 return true;
60}
61
62static bool test_LogonUasLogoff(struct torture_context *tctx,
63 struct dcerpc_pipe *p)
64{
65 NTSTATUS status;
66 struct netr_LogonUasLogoff r;
67 struct netr_UasLogoffInfo info;
68 struct dcerpc_binding_handle *b = p->binding_handle;
69
70 r.in.server_name = NULL;
71 r.in.account_name = cli_credentials_get_username(cmdline_credentials);
72 r.in.workstation = TEST_MACHINE_NAME;
73 r.out.info = &info;
74
75 status = dcerpc_netr_LogonUasLogoff_r(b, tctx, &r);
76 torture_assert_ntstatus_ok(tctx, status, "LogonUasLogoff");
77
78 return true;
79}
80
81bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
82 struct cli_credentials *credentials,
83 struct netlogon_creds_CredentialState **creds_out)
84{
85 struct netr_ServerReqChallenge r;
86 struct netr_ServerAuthenticate a;
87 struct netr_Credential credentials1, credentials2, credentials3;
88 struct netlogon_creds_CredentialState *creds;
89 const struct samr_Password *mach_password;
90 const char *machine_name;
91 struct dcerpc_binding_handle *b = p->binding_handle;
92
93 mach_password = cli_credentials_get_nt_hash(credentials, tctx);
94 machine_name = cli_credentials_get_workstation(credentials);
95
96 torture_comment(tctx, "Testing ServerReqChallenge\n");
97
98 r.in.server_name = NULL;
99 r.in.computer_name = machine_name;
100 r.in.credentials = &credentials1;
101 r.out.return_credentials = &credentials2;
102
103 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
104
105 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
106 "ServerReqChallenge failed");
107 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
108
109 a.in.server_name = NULL;
110 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
111 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(credentials);
112 a.in.computer_name = machine_name;
113 a.in.credentials = &credentials3;
114 a.out.return_credentials = &credentials3;
115
116 creds = netlogon_creds_client_init(tctx, a.in.account_name,
117 a.in.computer_name,
118 &credentials1, &credentials2,
119 mach_password, &credentials3,
120 0);
121 torture_assert(tctx, creds != NULL, "memory allocation");
122
123
124 torture_comment(tctx, "Testing ServerAuthenticate\n");
125
126 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate_r(b, tctx, &a),
127 "ServerAuthenticate failed");
128
129 /* This allows the tests to continue against the more fussy windows 2008 */
130 if (NT_STATUS_EQUAL(a.out.result, NT_STATUS_DOWNGRADE_DETECTED)) {
131 return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
132 credentials,
133 cli_credentials_get_secure_channel_type(credentials),
134 creds_out);
135 }
136
137 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate");
138
139 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
140 "Credential chaining failed");
141
142 *creds_out = creds;
143 return true;
144}
145
146bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx,
147 uint32_t negotiate_flags,
148 struct cli_credentials *machine_credentials,
149 enum netr_SchannelType sec_chan_type,
150 struct netlogon_creds_CredentialState **creds_out)
151{
152 struct netr_ServerReqChallenge r;
153 struct netr_ServerAuthenticate2 a;
154 struct netr_Credential credentials1, credentials2, credentials3;
155 struct netlogon_creds_CredentialState *creds;
156 const struct samr_Password *mach_password;
157 const char *machine_name;
158 struct dcerpc_binding_handle *b = p->binding_handle;
159
160 mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
161 machine_name = cli_credentials_get_workstation(machine_credentials);
162
163 torture_comment(tctx, "Testing ServerReqChallenge\n");
164
165
166 r.in.server_name = NULL;
167 r.in.computer_name = machine_name;
168 r.in.credentials = &credentials1;
169 r.out.return_credentials = &credentials2;
170
171 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
172
173 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
174 "ServerReqChallenge failed");
175 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
176
177 a.in.server_name = NULL;
178 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
179 a.in.secure_channel_type = sec_chan_type;
180 a.in.computer_name = machine_name;
181 a.in.negotiate_flags = &negotiate_flags;
182 a.out.negotiate_flags = &negotiate_flags;
183 a.in.credentials = &credentials3;
184 a.out.return_credentials = &credentials3;
185
186 creds = netlogon_creds_client_init(tctx, a.in.account_name,
187 a.in.computer_name,
188 &credentials1, &credentials2,
189 mach_password, &credentials3,
190 negotiate_flags);
191
192 torture_assert(tctx, creds != NULL, "memory allocation");
193
194 torture_comment(tctx, "Testing ServerAuthenticate2\n");
195
196 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
197 "ServerAuthenticate2 failed");
198 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate2 failed");
199
200 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
201 "Credential chaining failed");
202
203 torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
204
205 *creds_out = creds;
206 return true;
207}
208
209
210bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx,
211 uint32_t negotiate_flags,
212 struct cli_credentials *machine_credentials,
213 struct netlogon_creds_CredentialState **creds_out)
214{
215 struct netr_ServerReqChallenge r;
216 struct netr_ServerAuthenticate3 a;
217 struct netr_Credential credentials1, credentials2, credentials3;
218 struct netlogon_creds_CredentialState *creds;
219 struct samr_Password mach_password;
220 uint32_t rid;
221 const char *machine_name;
222 const char *plain_pass;
223 struct dcerpc_binding_handle *b = p->binding_handle;
224
225 machine_name = cli_credentials_get_workstation(machine_credentials);
226 plain_pass = cli_credentials_get_password(machine_credentials);
227
228 torture_comment(tctx, "Testing ServerReqChallenge\n");
229
230 r.in.server_name = NULL;
231 r.in.computer_name = machine_name;
232 r.in.credentials = &credentials1;
233 r.out.return_credentials = &credentials2;
234
235 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
236
237 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
238 "ServerReqChallenge failed");
239 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
240
241 E_md4hash(plain_pass, mach_password.hash);
242
243 a.in.server_name = NULL;
244 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
245 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
246 a.in.computer_name = machine_name;
247 a.in.negotiate_flags = &negotiate_flags;
248 a.in.credentials = &credentials3;
249 a.out.return_credentials = &credentials3;
250 a.out.negotiate_flags = &negotiate_flags;
251 a.out.rid = &rid;
252
253 creds = netlogon_creds_client_init(tctx, a.in.account_name,
254 a.in.computer_name,
255 &credentials1, &credentials2,
256 &mach_password, &credentials3,
257 negotiate_flags);
258
259 torture_assert(tctx, creds != NULL, "memory allocation");
260
261 torture_comment(tctx, "Testing ServerAuthenticate3\n");
262
263 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
264 "ServerAuthenticate3 failed");
265 torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed");
266 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
267
268 torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
269
270 /* Prove that requesting a challenge again won't break it */
271 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
272 "ServerReqChallenge failed");
273 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
274
275 *creds_out = creds;
276 return true;
277}
278
279/*
280 try a change password for our machine account
281*/
282static bool test_SetPassword(struct torture_context *tctx,
283 struct dcerpc_pipe *p,
284 struct cli_credentials *machine_credentials)
285{
286 struct netr_ServerPasswordSet r;
287 const char *password;
288 struct netlogon_creds_CredentialState *creds;
289 struct netr_Authenticator credential, return_authenticator;
290 struct samr_Password new_password;
291 struct dcerpc_binding_handle *b = p->binding_handle;
292
293 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
294 return false;
295 }
296
297 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
298 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
299 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
300 r.in.computer_name = TEST_MACHINE_NAME;
301 r.in.credential = &credential;
302 r.in.new_password = &new_password;
303 r.out.return_authenticator = &return_authenticator;
304
305 password = generate_random_password(tctx, 8, 255);
306 E_md4hash(password, new_password.hash);
307
308 netlogon_creds_des_encrypt(creds, &new_password);
309
310 torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
311 torture_comment(tctx, "Changing machine account password to '%s'\n",
312 password);
313
314 netlogon_creds_client_authenticator(creds, &credential);
315
316 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
317 "ServerPasswordSet failed");
318 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
319
320 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
321 torture_comment(tctx, "Credential chaining failed\n");
322 }
323
324 /* by changing the machine password twice we test the
325 credentials chaining fully, and we verify that the server
326 allows the password to be set to the same value twice in a
327 row (match win2k3) */
328 torture_comment(tctx,
329 "Testing a second ServerPasswordSet on machine account\n");
330 torture_comment(tctx,
331 "Changing machine account password to '%s' (same as previous run)\n", password);
332
333 netlogon_creds_client_authenticator(creds, &credential);
334
335 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
336 "ServerPasswordSet (2) failed");
337 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
338
339 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
340 torture_comment(tctx, "Credential chaining failed\n");
341 }
342
343 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
344
345 torture_assert(tctx,
346 test_SetupCredentials(p, tctx, machine_credentials, &creds),
347 "ServerPasswordSet failed to actually change the password");
348
349 return true;
350}
351
352/*
353 try a change password for our machine account
354*/
355static bool test_SetPassword_flags(struct torture_context *tctx,
356 struct dcerpc_pipe *p,
357 struct cli_credentials *machine_credentials,
358 uint32_t negotiate_flags)
359{
360 struct netr_ServerPasswordSet r;
361 const char *password;
362 struct netlogon_creds_CredentialState *creds;
363 struct netr_Authenticator credential, return_authenticator;
364 struct samr_Password new_password;
365 struct dcerpc_binding_handle *b = p->binding_handle;
366
367 if (!test_SetupCredentials2(p, tctx, negotiate_flags,
368 machine_credentials,
369 cli_credentials_get_secure_channel_type(machine_credentials),
370 &creds)) {
371 return false;
372 }
373
374 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
375 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
376 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
377 r.in.computer_name = TEST_MACHINE_NAME;
378 r.in.credential = &credential;
379 r.in.new_password = &new_password;
380 r.out.return_authenticator = &return_authenticator;
381
382 password = generate_random_password(tctx, 8, 255);
383 E_md4hash(password, new_password.hash);
384
385 netlogon_creds_des_encrypt(creds, &new_password);
386
387 torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
388 torture_comment(tctx, "Changing machine account password to '%s'\n",
389 password);
390
391 netlogon_creds_client_authenticator(creds, &credential);
392
393 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
394 "ServerPasswordSet failed");
395 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
396
397 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
398 torture_comment(tctx, "Credential chaining failed\n");
399 }
400
401 /* by changing the machine password twice we test the
402 credentials chaining fully, and we verify that the server
403 allows the password to be set to the same value twice in a
404 row (match win2k3) */
405 torture_comment(tctx,
406 "Testing a second ServerPasswordSet on machine account\n");
407 torture_comment(tctx,
408 "Changing machine account password to '%s' (same as previous run)\n", password);
409
410 netlogon_creds_client_authenticator(creds, &credential);
411
412 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
413 "ServerPasswordSet (2) failed");
414 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
415
416 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
417 torture_comment(tctx, "Credential chaining failed\n");
418 }
419
420 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
421
422 torture_assert(tctx,
423 test_SetupCredentials(p, tctx, machine_credentials, &creds),
424 "ServerPasswordSet failed to actually change the password");
425
426 return true;
427}
428
429
430/*
431 generate a random password for password change tests
432*/
433static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
434{
435 int i;
436 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
437 generate_random_buffer(password.data, password.length);
438
439 for (i=0; i < len; i++) {
440 if (((uint16_t *)password.data)[i] == 0) {
441 ((uint16_t *)password.data)[i] = 1;
442 }
443 }
444
445 return password;
446}
447
448/*
449 try a change password for our machine account
450*/
451static bool test_SetPassword2(struct torture_context *tctx,
452 struct dcerpc_pipe *p,
453 struct cli_credentials *machine_credentials)
454{
455 struct netr_ServerPasswordSet2 r;
456 const char *password;
457 DATA_BLOB new_random_pass;
458 struct netlogon_creds_CredentialState *creds;
459 struct samr_CryptPassword password_buf;
460 struct samr_Password nt_hash;
461 struct netr_Authenticator credential, return_authenticator;
462 struct netr_CryptPassword new_password;
463 struct dcerpc_binding_handle *b = p->binding_handle;
464
465 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
466 return false;
467 }
468
469 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
470 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
471 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
472 r.in.computer_name = TEST_MACHINE_NAME;
473 r.in.credential = &credential;
474 r.in.new_password = &new_password;
475 r.out.return_authenticator = &return_authenticator;
476
477 password = generate_random_password(tctx, 8, 255);
478 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
479 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
480
481 memcpy(new_password.data, password_buf.data, 512);
482 new_password.length = IVAL(password_buf.data, 512);
483
484 torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
485 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
486
487 netlogon_creds_client_authenticator(creds, &credential);
488
489 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
490 "ServerPasswordSet2 failed");
491 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
492
493 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
494 torture_comment(tctx, "Credential chaining failed\n");
495 }
496
497 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
498
499 if (!torture_setting_bool(tctx, "dangerous", false)) {
500 torture_comment(tctx,
501 "Not testing ability to set password to '', enable dangerous tests to perform this test\n");
502 } else {
503 /* by changing the machine password to ""
504 * we check if the server uses password restrictions
505 * for ServerPasswordSet2
506 * (win2k3 accepts "")
507 */
508 password = "";
509 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
510 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
511
512 memcpy(new_password.data, password_buf.data, 512);
513 new_password.length = IVAL(password_buf.data, 512);
514
515 torture_comment(tctx,
516 "Testing ServerPasswordSet2 on machine account\n");
517 torture_comment(tctx,
518 "Changing machine account password to '%s'\n", password);
519
520 netlogon_creds_client_authenticator(creds, &credential);
521
522 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
523 "ServerPasswordSet2 failed");
524 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
525
526 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
527 torture_comment(tctx, "Credential chaining failed\n");
528 }
529
530 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
531 }
532
533 torture_assert(tctx, test_SetupCredentials(p, tctx, machine_credentials, &creds),
534 "ServerPasswordSet failed to actually change the password");
535
536 /* now try a random password */
537 password = generate_random_password(tctx, 8, 255);
538 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
539 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
540
541 memcpy(new_password.data, password_buf.data, 512);
542 new_password.length = IVAL(password_buf.data, 512);
543
544 torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
545 torture_comment(tctx, "Changing machine account password to '%s'\n", password);
546
547 netlogon_creds_client_authenticator(creds, &credential);
548
549 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
550 "ServerPasswordSet2 (2) failed");
551 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 (2) failed");
552
553 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
554 torture_comment(tctx, "Credential chaining failed\n");
555 }
556
557 /* by changing the machine password twice we test the
558 credentials chaining fully, and we verify that the server
559 allows the password to be set to the same value twice in a
560 row (match win2k3) */
561 torture_comment(tctx,
562 "Testing a second ServerPasswordSet2 on machine account\n");
563 torture_comment(tctx,
564 "Changing machine account password to '%s' (same as previous run)\n", password);
565
566 netlogon_creds_client_authenticator(creds, &credential);
567
568 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
569 "ServerPasswordSet (3) failed");
570 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
571
572 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
573 torture_comment(tctx, "Credential chaining failed\n");
574 }
575
576 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
577
578 torture_assert (tctx,
579 test_SetupCredentials(p, tctx, machine_credentials, &creds),
580 "ServerPasswordSet failed to actually change the password");
581
582 new_random_pass = netlogon_very_rand_pass(tctx, 128);
583
584 /* now try a random stream of bytes for a password */
585 set_pw_in_buffer(password_buf.data, &new_random_pass);
586
587 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
588
589 memcpy(new_password.data, password_buf.data, 512);
590 new_password.length = IVAL(password_buf.data, 512);
591
592 torture_comment(tctx,
593 "Testing a third ServerPasswordSet2 on machine account, with a completely random password\n");
594
595 netlogon_creds_client_authenticator(creds, &credential);
596
597 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
598 "ServerPasswordSet (3) failed");
599 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
600
601 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
602 torture_comment(tctx, "Credential chaining failed\n");
603 }
604
605 mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
606
607 cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
608 cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
609
610 torture_assert (tctx,
611 test_SetupCredentials(p, tctx, machine_credentials, &creds),
612 "ServerPasswordSet failed to actually change the password");
613
614 return true;
615}
616
617static bool test_GetPassword(struct torture_context *tctx,
618 struct dcerpc_pipe *p,
619 struct cli_credentials *machine_credentials)
620{
621 struct netr_ServerPasswordGet r;
622 struct netlogon_creds_CredentialState *creds;
623 struct netr_Authenticator credential;
624 NTSTATUS status;
625 struct netr_Authenticator return_authenticator;
626 struct samr_Password password;
627 struct dcerpc_binding_handle *b = p->binding_handle;
628
629 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
630 return false;
631 }
632
633 netlogon_creds_client_authenticator(creds, &credential);
634
635 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
636 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
637 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
638 r.in.computer_name = TEST_MACHINE_NAME;
639 r.in.credential = &credential;
640 r.out.return_authenticator = &return_authenticator;
641 r.out.password = &password;
642
643 status = dcerpc_netr_ServerPasswordGet_r(b, tctx, &r);
644 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
645
646 return true;
647}
648
649static bool test_GetTrustPasswords(struct torture_context *tctx,
650 struct dcerpc_pipe *p,
651 struct cli_credentials *machine_credentials)
652{
653 struct netr_ServerTrustPasswordsGet r;
654 struct netlogon_creds_CredentialState *creds;
655 struct netr_Authenticator credential;
656 struct netr_Authenticator return_authenticator;
657 struct samr_Password password, password2;
658 struct dcerpc_binding_handle *b = p->binding_handle;
659
660 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
661 return false;
662 }
663
664 netlogon_creds_client_authenticator(creds, &credential);
665
666 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
667 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
668 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
669 r.in.computer_name = TEST_MACHINE_NAME;
670 r.in.credential = &credential;
671 r.out.return_authenticator = &return_authenticator;
672 r.out.password = &password;
673 r.out.password2 = &password2;
674
675 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerTrustPasswordsGet_r(b, tctx, &r),
676 "ServerTrustPasswordsGet failed");
677 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerTrustPasswordsGet failed");
678
679 return true;
680}
681
682/*
683 try a netlogon SamLogon
684*/
685static bool test_netlogon_ops_args(struct dcerpc_pipe *p, struct torture_context *tctx,
686 struct cli_credentials *credentials,
687 struct netlogon_creds_CredentialState *creds,
688 bool null_domain)
689{
690 NTSTATUS status;
691 struct netr_LogonSamLogon r;
692 struct netr_Authenticator auth, auth2;
693 static const struct netr_Authenticator auth_zero;
694 union netr_LogonLevel logon;
695 union netr_Validation validation;
696 uint8_t authoritative;
697 struct netr_NetworkInfo ninfo;
698 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
699 int i;
700 struct dcerpc_binding_handle *b = p->binding_handle;
701 int flags = CLI_CRED_NTLM_AUTH;
702 if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
703 flags |= CLI_CRED_LANMAN_AUTH;
704 }
705
706 if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx) && !null_domain) {
707 flags |= CLI_CRED_NTLMv2_AUTH;
708 }
709
710 cli_credentials_get_ntlm_username_domain(cmdline_credentials, tctx,
711 &ninfo.identity_info.account_name.string,
712 &ninfo.identity_info.domain_name.string);
713
714 if (null_domain) {
715 ninfo.identity_info.domain_name.string = NULL;
716 }
717
718 generate_random_buffer(ninfo.challenge,
719 sizeof(ninfo.challenge));
720 chal = data_blob_const(ninfo.challenge,
721 sizeof(ninfo.challenge));
722
723 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials),
724 cli_credentials_get_domain(credentials));
725
726 status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx,
727 &flags,
728 chal,
729 names_blob,
730 &lm_resp, &nt_resp,
731 NULL, NULL);
732 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
733
734 ninfo.lm.data = lm_resp.data;
735 ninfo.lm.length = lm_resp.length;
736
737 ninfo.nt.data = nt_resp.data;
738 ninfo.nt.length = nt_resp.length;
739
740 ninfo.identity_info.parameter_control = 0;
741 ninfo.identity_info.logon_id_low = 0;
742 ninfo.identity_info.logon_id_high = 0;
743 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
744
745 logon.network = &ninfo;
746
747 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
748 r.in.computer_name = cli_credentials_get_workstation(credentials);
749 r.in.credential = &auth;
750 r.in.return_authenticator = &auth2;
751 r.in.logon_level = 2;
752 r.in.logon = &logon;
753 r.out.validation = &validation;
754 r.out.authoritative = &authoritative;
755
756 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
757
758 for (i=2;i<=3;i++) {
759 ZERO_STRUCT(auth2);
760 netlogon_creds_client_authenticator(creds, &auth);
761
762 r.in.validation_level = i;
763
764 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
765 "LogonSamLogon failed");
766 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
767
768 torture_assert(tctx, netlogon_creds_client_check(creds,
769 &r.out.return_authenticator->cred),
770 "Credential chaining failed");
771 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
772 "LogonSamLogon invalid *r.out.authoritative");
773 }
774
775 /* this makes sure we get the unmarshalling right for invalid levels */
776 for (i=52;i<53;i++) {
777 ZERO_STRUCT(auth2);
778 /* the authenticator should be ignored by the server */
779 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
780
781 r.in.validation_level = i;
782
783 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
784 "LogonSamLogon failed");
785 torture_assert_ntstatus_equal(tctx, r.out.result,
786 NT_STATUS_INVALID_INFO_CLASS,
787 "LogonSamLogon failed");
788
789 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
790 "LogonSamLogon invalid *r.out.authoritative");
791 torture_assert(tctx,
792 memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
793 "Return authenticator non zero");
794 }
795
796 for (i=2;i<=3;i++) {
797 ZERO_STRUCT(auth2);
798 netlogon_creds_client_authenticator(creds, &auth);
799
800 r.in.validation_level = i;
801
802 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
803 "LogonSamLogon failed");
804 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
805
806 torture_assert(tctx, netlogon_creds_client_check(creds,
807 &r.out.return_authenticator->cred),
808 "Credential chaining failed");
809 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
810 "LogonSamLogon invalid *r.out.authoritative");
811 }
812
813 r.in.logon_level = 52;
814
815 for (i=2;i<=3;i++) {
816 ZERO_STRUCT(auth2);
817 /* the authenticator should be ignored by the server */
818 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
819
820 r.in.validation_level = i;
821
822 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
823
824 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
825 "LogonSamLogon failed");
826 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
827 "LogonSamLogon expected INVALID_PARAMETER");
828
829 torture_assert(tctx,
830 memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
831 "Return authenticator non zero");
832 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
833 "LogonSamLogon invalid *r.out.authoritative");
834 }
835
836 r.in.credential = NULL;
837
838 for (i=2;i<=3;i++) {
839 ZERO_STRUCT(auth2);
840
841 r.in.validation_level = i;
842
843 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
844
845 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
846 "LogonSamLogon failed");
847 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
848 "LogonSamLogon expected INVALID_PARAMETER");
849
850 torture_assert(tctx,
851 memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
852 "Return authenticator non zero");
853 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
854 "LogonSamLogon invalid *r.out.authoritative");
855 }
856
857 r.in.logon_level = 2;
858 r.in.credential = &auth;
859
860 for (i=2;i<=3;i++) {
861 ZERO_STRUCT(auth2);
862 netlogon_creds_client_authenticator(creds, &auth);
863
864 r.in.validation_level = i;
865
866 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
867 "LogonSamLogon failed");
868 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
869
870 torture_assert(tctx, netlogon_creds_client_check(creds,
871 &r.out.return_authenticator->cred),
872 "Credential chaining failed");
873 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
874 "LogonSamLogon invalid *r.out.authoritative");
875 }
876
877 return true;
878}
879
880bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
881 struct cli_credentials *credentials,
882 struct netlogon_creds_CredentialState *creds)
883{
884 return test_netlogon_ops_args(p, tctx, credentials, creds, false);
885}
886
887/*
888 try a netlogon SamLogon
889*/
890static bool test_SamLogon(struct torture_context *tctx,
891 struct dcerpc_pipe *p,
892 struct cli_credentials *credentials)
893{
894 struct netlogon_creds_CredentialState *creds;
895
896 if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
897 return false;
898 }
899
900 return test_netlogon_ops(p, tctx, credentials, creds);
901}
902
903static bool test_SamLogon_NULL_domain(struct torture_context *tctx,
904 struct dcerpc_pipe *p,
905 struct cli_credentials *credentials)
906{
907 struct netlogon_creds_CredentialState *creds;
908
909 if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
910 return false;
911 }
912
913 return test_netlogon_ops_args(p, tctx, credentials, creds, true);
914}
915
916/* we remember the sequence numbers so we can easily do a DatabaseDelta */
917static uint64_t sequence_nums[3];
918
919/*
920 try a netlogon DatabaseSync
921*/
922static bool test_DatabaseSync(struct torture_context *tctx,
923 struct dcerpc_pipe *p,
924 struct cli_credentials *machine_credentials)
925{
926 struct netr_DatabaseSync r;
927 struct netlogon_creds_CredentialState *creds;
928 const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
929 int i;
930 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
931 struct netr_Authenticator credential, return_authenticator;
932 struct dcerpc_binding_handle *b = p->binding_handle;
933
934 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
935 return false;
936 }
937
938 ZERO_STRUCT(return_authenticator);
939
940 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
941 r.in.computername = TEST_MACHINE_NAME;
942 r.in.preferredmaximumlength = (uint32_t)-1;
943 r.in.return_authenticator = &return_authenticator;
944 r.out.delta_enum_array = &delta_enum_array;
945 r.out.return_authenticator = &return_authenticator;
946
947 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
948
949 uint32_t sync_context = 0;
950
951 r.in.database_id = database_ids[i];
952 r.in.sync_context = &sync_context;
953 r.out.sync_context = &sync_context;
954
955 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
956
957 do {
958 netlogon_creds_client_authenticator(creds, &credential);
959
960 r.in.credential = &credential;
961
962 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync_r(b, tctx, &r),
963 "DatabaseSync failed");
964 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
965 break;
966
967 /* Native mode servers don't do this */
968 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
969 return true;
970 }
971 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync");
972
973 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
974 torture_comment(tctx, "Credential chaining failed\n");
975 }
976
977 if (delta_enum_array &&
978 delta_enum_array->num_deltas > 0 &&
979 delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
980 delta_enum_array->delta_enum[0].delta_union.domain) {
981 sequence_nums[r.in.database_id] =
982 delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
983 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
984 r.in.database_id,
985 (unsigned long long)sequence_nums[r.in.database_id]);
986 }
987 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
988 }
989
990 return true;
991}
992
993
994/*
995 try a netlogon DatabaseDeltas
996*/
997static bool test_DatabaseDeltas(struct torture_context *tctx,
998 struct dcerpc_pipe *p,
999 struct cli_credentials *machine_credentials)
1000{
1001 struct netr_DatabaseDeltas r;
1002 struct netlogon_creds_CredentialState *creds;
1003 struct netr_Authenticator credential;
1004 struct netr_Authenticator return_authenticator;
1005 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1006 const uint32_t database_ids[] = {0, 1, 2};
1007 int i;
1008 struct dcerpc_binding_handle *b = p->binding_handle;
1009
1010 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1011 return false;
1012 }
1013
1014 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1015 r.in.computername = TEST_MACHINE_NAME;
1016 r.in.preferredmaximumlength = (uint32_t)-1;
1017 ZERO_STRUCT(r.in.return_authenticator);
1018 r.out.return_authenticator = &return_authenticator;
1019 r.out.delta_enum_array = &delta_enum_array;
1020
1021 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1022 r.in.database_id = database_ids[i];
1023 r.in.sequence_num = &sequence_nums[r.in.database_id];
1024
1025 if (*r.in.sequence_num == 0) continue;
1026
1027 *r.in.sequence_num -= 1;
1028
1029 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n",
1030 r.in.database_id, (unsigned long long)*r.in.sequence_num);
1031
1032 do {
1033 netlogon_creds_client_authenticator(creds, &credential);
1034
1035 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseDeltas_r(b, tctx, &r),
1036 "DatabaseDeltas failed");
1037 if (NT_STATUS_EQUAL(r.out.result,
1038 NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
1039 torture_comment(tctx, "not considering %s to be an error\n",
1040 nt_errstr(r.out.result));
1041 return true;
1042 }
1043 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1044 break;
1045
1046 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseDeltas");
1047
1048 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1049 torture_comment(tctx, "Credential chaining failed\n");
1050 }
1051
1052 (*r.in.sequence_num)++;
1053 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1054 }
1055
1056 return true;
1057}
1058
1059static bool test_DatabaseRedo(struct torture_context *tctx,
1060 struct dcerpc_pipe *p,
1061 struct cli_credentials *machine_credentials)
1062{
1063 struct netr_DatabaseRedo r;
1064 struct netlogon_creds_CredentialState *creds;
1065 struct netr_Authenticator credential;
1066 struct netr_Authenticator return_authenticator;
1067 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1068 struct netr_ChangeLogEntry e;
1069 struct dom_sid null_sid, *sid;
1070 int i,d;
1071 struct dcerpc_binding_handle *b = p->binding_handle;
1072
1073 ZERO_STRUCT(null_sid);
1074
1075 sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
1076
1077 {
1078
1079 struct {
1080 uint32_t rid;
1081 uint16_t flags;
1082 uint8_t db_index;
1083 uint8_t delta_type;
1084 struct dom_sid sid;
1085 const char *name;
1086 NTSTATUS expected_error;
1087 uint32_t expected_num_results;
1088 uint8_t expected_delta_type_1;
1089 uint8_t expected_delta_type_2;
1090 const char *comment;
1091 } changes[] = {
1092
1093 /* SAM_DATABASE_DOMAIN */
1094
1095 {
1096 .rid = 0,
1097 .flags = 0,
1098 .db_index = SAM_DATABASE_DOMAIN,
1099 .delta_type = NETR_DELTA_MODIFY_COUNT,
1100 .sid = null_sid,
1101 .name = NULL,
1102 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1103 .expected_num_results = 0,
1104 .comment = "NETR_DELTA_MODIFY_COUNT"
1105 },
1106 {
1107 .rid = 0,
1108 .flags = 0,
1109 .db_index = SAM_DATABASE_DOMAIN,
1110 .delta_type = 0,
1111 .sid = null_sid,
1112 .name = NULL,
1113 .expected_error = NT_STATUS_OK,
1114 .expected_num_results = 1,
1115 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1116 .comment = "NULL DELTA"
1117 },
1118 {
1119 .rid = 0,
1120 .flags = 0,
1121 .db_index = SAM_DATABASE_DOMAIN,
1122 .delta_type = NETR_DELTA_DOMAIN,
1123 .sid = null_sid,
1124 .name = NULL,
1125 .expected_error = NT_STATUS_OK,
1126 .expected_num_results = 1,
1127 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1128 .comment = "NETR_DELTA_DOMAIN"
1129 },
1130 {
1131 .rid = DOMAIN_RID_ADMINISTRATOR,
1132 .flags = 0,
1133 .db_index = SAM_DATABASE_DOMAIN,
1134 .delta_type = NETR_DELTA_USER,
1135 .sid = null_sid,
1136 .name = NULL,
1137 .expected_error = NT_STATUS_OK,
1138 .expected_num_results = 1,
1139 .expected_delta_type_1 = NETR_DELTA_USER,
1140 .comment = "NETR_DELTA_USER by rid 500"
1141 },
1142 {
1143 .rid = DOMAIN_RID_GUEST,
1144 .flags = 0,
1145 .db_index = SAM_DATABASE_DOMAIN,
1146 .delta_type = NETR_DELTA_USER,
1147 .sid = null_sid,
1148 .name = NULL,
1149 .expected_error = NT_STATUS_OK,
1150 .expected_num_results = 1,
1151 .expected_delta_type_1 = NETR_DELTA_USER,
1152 .comment = "NETR_DELTA_USER by rid 501"
1153 },
1154 {
1155 .rid = 0,
1156 .flags = NETR_CHANGELOG_SID_INCLUDED,
1157 .db_index = SAM_DATABASE_DOMAIN,
1158 .delta_type = NETR_DELTA_USER,
1159 .sid = *sid,
1160 .name = NULL,
1161 .expected_error = NT_STATUS_OK,
1162 .expected_num_results = 1,
1163 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1164 .comment = "NETR_DELTA_USER by sid and flags"
1165 },
1166 {
1167 .rid = 0,
1168 .flags = NETR_CHANGELOG_SID_INCLUDED,
1169 .db_index = SAM_DATABASE_DOMAIN,
1170 .delta_type = NETR_DELTA_USER,
1171 .sid = null_sid,
1172 .name = NULL,
1173 .expected_error = NT_STATUS_OK,
1174 .expected_num_results = 1,
1175 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1176 .comment = "NETR_DELTA_USER by null_sid and flags"
1177 },
1178 {
1179 .rid = 0,
1180 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1181 .db_index = SAM_DATABASE_DOMAIN,
1182 .delta_type = NETR_DELTA_USER,
1183 .sid = null_sid,
1184 .name = "administrator",
1185 .expected_error = NT_STATUS_OK,
1186 .expected_num_results = 1,
1187 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1188 .comment = "NETR_DELTA_USER by name 'administrator'"
1189 },
1190 {
1191 .rid = DOMAIN_RID_ADMINS,
1192 .flags = 0,
1193 .db_index = SAM_DATABASE_DOMAIN,
1194 .delta_type = NETR_DELTA_GROUP,
1195 .sid = null_sid,
1196 .name = NULL,
1197 .expected_error = NT_STATUS_OK,
1198 .expected_num_results = 2,
1199 .expected_delta_type_1 = NETR_DELTA_GROUP,
1200 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
1201 .comment = "NETR_DELTA_GROUP by rid 512"
1202 },
1203 {
1204 .rid = DOMAIN_RID_ADMINS,
1205 .flags = 0,
1206 .db_index = SAM_DATABASE_DOMAIN,
1207 .delta_type = NETR_DELTA_GROUP_MEMBER,
1208 .sid = null_sid,
1209 .name = NULL,
1210 .expected_error = NT_STATUS_OK,
1211 .expected_num_results = 2,
1212 .expected_delta_type_1 = NETR_DELTA_GROUP,
1213 .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
1214 .comment = "NETR_DELTA_GROUP_MEMBER by rid 512"
1215 },
1216
1217
1218 /* SAM_DATABASE_BUILTIN */
1219
1220 {
1221 .rid = 0,
1222 .flags = 0,
1223 .db_index = SAM_DATABASE_BUILTIN,
1224 .delta_type = NETR_DELTA_MODIFY_COUNT,
1225 .sid = null_sid,
1226 .name = NULL,
1227 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1228 .expected_num_results = 0,
1229 .comment = "NETR_DELTA_MODIFY_COUNT"
1230 },
1231 {
1232 .rid = 0,
1233 .flags = 0,
1234 .db_index = SAM_DATABASE_BUILTIN,
1235 .delta_type = NETR_DELTA_DOMAIN,
1236 .sid = null_sid,
1237 .name = NULL,
1238 .expected_error = NT_STATUS_OK,
1239 .expected_num_results = 1,
1240 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1241 .comment = "NETR_DELTA_DOMAIN"
1242 },
1243 {
1244 .rid = DOMAIN_RID_ADMINISTRATOR,
1245 .flags = 0,
1246 .db_index = SAM_DATABASE_BUILTIN,
1247 .delta_type = NETR_DELTA_USER,
1248 .sid = null_sid,
1249 .name = NULL,
1250 .expected_error = NT_STATUS_OK,
1251 .expected_num_results = 1,
1252 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1253 .comment = "NETR_DELTA_USER by rid 500"
1254 },
1255 {
1256 .rid = 0,
1257 .flags = 0,
1258 .db_index = SAM_DATABASE_BUILTIN,
1259 .delta_type = NETR_DELTA_USER,
1260 .sid = null_sid,
1261 .name = NULL,
1262 .expected_error = NT_STATUS_OK,
1263 .expected_num_results = 1,
1264 .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
1265 .comment = "NETR_DELTA_USER"
1266 },
1267 {
1268 .rid = 544,
1269 .flags = 0,
1270 .db_index = SAM_DATABASE_BUILTIN,
1271 .delta_type = NETR_DELTA_ALIAS,
1272 .sid = null_sid,
1273 .name = NULL,
1274 .expected_error = NT_STATUS_OK,
1275 .expected_num_results = 2,
1276 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1277 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1278 .comment = "NETR_DELTA_ALIAS by rid 544"
1279 },
1280 {
1281 .rid = 544,
1282 .flags = 0,
1283 .db_index = SAM_DATABASE_BUILTIN,
1284 .delta_type = NETR_DELTA_ALIAS_MEMBER,
1285 .sid = null_sid,
1286 .name = NULL,
1287 .expected_error = NT_STATUS_OK,
1288 .expected_num_results = 2,
1289 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1290 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1291 .comment = "NETR_DELTA_ALIAS_MEMBER by rid 544"
1292 },
1293 {
1294 .rid = 544,
1295 .flags = 0,
1296 .db_index = SAM_DATABASE_BUILTIN,
1297 .delta_type = 0,
1298 .sid = null_sid,
1299 .name = NULL,
1300 .expected_error = NT_STATUS_OK,
1301 .expected_num_results = 1,
1302 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1303 .comment = "NULL DELTA by rid 544"
1304 },
1305 {
1306 .rid = 544,
1307 .flags = NETR_CHANGELOG_SID_INCLUDED,
1308 .db_index = SAM_DATABASE_BUILTIN,
1309 .delta_type = 0,
1310 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1311 .name = NULL,
1312 .expected_error = NT_STATUS_OK,
1313 .expected_num_results = 1,
1314 .expected_delta_type_1 = NETR_DELTA_DOMAIN,
1315 .comment = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
1316 },
1317 {
1318 .rid = 544,
1319 .flags = NETR_CHANGELOG_SID_INCLUDED,
1320 .db_index = SAM_DATABASE_BUILTIN,
1321 .delta_type = NETR_DELTA_ALIAS,
1322 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1323 .name = NULL,
1324 .expected_error = NT_STATUS_OK,
1325 .expected_num_results = 2,
1326 .expected_delta_type_1 = NETR_DELTA_ALIAS,
1327 .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
1328 .comment = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
1329 },
1330 {
1331 .rid = 0,
1332 .flags = NETR_CHANGELOG_SID_INCLUDED,
1333 .db_index = SAM_DATABASE_BUILTIN,
1334 .delta_type = NETR_DELTA_ALIAS,
1335 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1336 .name = NULL,
1337 .expected_error = NT_STATUS_OK,
1338 .expected_num_results = 1,
1339 .expected_delta_type_1 = NETR_DELTA_DELETE_ALIAS,
1340 .comment = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
1341 },
1342
1343 /* SAM_DATABASE_PRIVS */
1344
1345 {
1346 .rid = 0,
1347 .flags = 0,
1348 .db_index = SAM_DATABASE_PRIVS,
1349 .delta_type = 0,
1350 .sid = null_sid,
1351 .name = NULL,
1352 .expected_error = NT_STATUS_ACCESS_DENIED,
1353 .expected_num_results = 0,
1354 .comment = "NULL DELTA"
1355 },
1356 {
1357 .rid = 0,
1358 .flags = 0,
1359 .db_index = SAM_DATABASE_PRIVS,
1360 .delta_type = NETR_DELTA_MODIFY_COUNT,
1361 .sid = null_sid,
1362 .name = NULL,
1363 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1364 .expected_num_results = 0,
1365 .comment = "NETR_DELTA_MODIFY_COUNT"
1366 },
1367 {
1368 .rid = 0,
1369 .flags = 0,
1370 .db_index = SAM_DATABASE_PRIVS,
1371 .delta_type = NETR_DELTA_POLICY,
1372 .sid = null_sid,
1373 .name = NULL,
1374 .expected_error = NT_STATUS_OK,
1375 .expected_num_results = 1,
1376 .expected_delta_type_1 = NETR_DELTA_POLICY,
1377 .comment = "NETR_DELTA_POLICY"
1378 },
1379 {
1380 .rid = 0,
1381 .flags = NETR_CHANGELOG_SID_INCLUDED,
1382 .db_index = SAM_DATABASE_PRIVS,
1383 .delta_type = NETR_DELTA_POLICY,
1384 .sid = null_sid,
1385 .name = NULL,
1386 .expected_error = NT_STATUS_OK,
1387 .expected_num_results = 1,
1388 .expected_delta_type_1 = NETR_DELTA_POLICY,
1389 .comment = "NETR_DELTA_POLICY by null sid and flags"
1390 },
1391 {
1392 .rid = 0,
1393 .flags = NETR_CHANGELOG_SID_INCLUDED,
1394 .db_index = SAM_DATABASE_PRIVS,
1395 .delta_type = NETR_DELTA_POLICY,
1396 .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
1397 .name = NULL,
1398 .expected_error = NT_STATUS_OK,
1399 .expected_num_results = 1,
1400 .expected_delta_type_1 = NETR_DELTA_POLICY,
1401 .comment = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
1402 },
1403 {
1404 .rid = DOMAIN_RID_ADMINISTRATOR,
1405 .flags = 0,
1406 .db_index = SAM_DATABASE_PRIVS,
1407 .delta_type = NETR_DELTA_ACCOUNT,
1408 .sid = null_sid,
1409 .name = NULL,
1410 .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
1411 .expected_num_results = 0,
1412 .comment = "NETR_DELTA_ACCOUNT by rid 500"
1413 },
1414 {
1415 .rid = 0,
1416 .flags = NETR_CHANGELOG_SID_INCLUDED,
1417 .db_index = SAM_DATABASE_PRIVS,
1418 .delta_type = NETR_DELTA_ACCOUNT,
1419 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1420 .name = NULL,
1421 .expected_error = NT_STATUS_OK,
1422 .expected_num_results = 1,
1423 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
1424 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
1425 },
1426 {
1427 .rid = 0,
1428 .flags = NETR_CHANGELOG_SID_INCLUDED |
1429 NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
1430 .db_index = SAM_DATABASE_PRIVS,
1431 .delta_type = NETR_DELTA_ACCOUNT,
1432 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1433 .name = NULL,
1434 .expected_error = NT_STATUS_OK,
1435 .expected_num_results = 1,
1436 .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
1437 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
1438 },
1439 {
1440 .rid = 0,
1441 .flags = NETR_CHANGELOG_SID_INCLUDED |
1442 NETR_CHANGELOG_NAME_INCLUDED,
1443 .db_index = SAM_DATABASE_PRIVS,
1444 .delta_type = NETR_DELTA_ACCOUNT,
1445 .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1446 .name = NULL,
1447 .expected_error = NT_STATUS_INVALID_PARAMETER,
1448 .expected_num_results = 0,
1449 .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
1450 },
1451 {
1452 .rid = DOMAIN_RID_ADMINISTRATOR,
1453 .flags = NETR_CHANGELOG_SID_INCLUDED,
1454 .db_index = SAM_DATABASE_PRIVS,
1455 .delta_type = NETR_DELTA_ACCOUNT,
1456 .sid = *sid,
1457 .name = NULL,
1458 .expected_error = NT_STATUS_OK,
1459 .expected_num_results = 1,
1460 .expected_delta_type_1 = NETR_DELTA_DELETE_ACCOUNT,
1461 .comment = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
1462 },
1463 {
1464 .rid = 0,
1465 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1466 .db_index = SAM_DATABASE_PRIVS,
1467 .delta_type = NETR_DELTA_SECRET,
1468 .sid = null_sid,
1469 .name = "IsurelydontexistIhope",
1470 .expected_error = NT_STATUS_OK,
1471 .expected_num_results = 1,
1472 .expected_delta_type_1 = NETR_DELTA_DELETE_SECRET,
1473 .comment = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
1474 },
1475 {
1476 .rid = 0,
1477 .flags = NETR_CHANGELOG_NAME_INCLUDED,
1478 .db_index = SAM_DATABASE_PRIVS,
1479 .delta_type = NETR_DELTA_SECRET,
1480 .sid = null_sid,
1481 .name = "G$BCKUPKEY_P",
1482 .expected_error = NT_STATUS_OK,
1483 .expected_num_results = 1,
1484 .expected_delta_type_1 = NETR_DELTA_SECRET,
1485 .comment = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
1486 }
1487 };
1488
1489 ZERO_STRUCT(return_authenticator);
1490
1491 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1492 r.in.computername = TEST_MACHINE_NAME;
1493 r.in.return_authenticator = &return_authenticator;
1494 r.out.return_authenticator = &return_authenticator;
1495 r.out.delta_enum_array = &delta_enum_array;
1496
1497 for (d=0; d<3; d++) {
1498 const char *database = NULL;
1499
1500 switch (d) {
1501 case 0:
1502 database = "SAM";
1503 break;
1504 case 1:
1505 database = "BUILTIN";
1506 break;
1507 case 2:
1508 database = "LSA";
1509 break;
1510 default:
1511 break;
1512 }
1513
1514 torture_comment(tctx, "Testing DatabaseRedo\n");
1515
1516 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1517 return false;
1518 }
1519
1520 for (i=0;i<ARRAY_SIZE(changes);i++) {
1521
1522 if (d != changes[i].db_index) {
1523 continue;
1524 }
1525
1526 netlogon_creds_client_authenticator(creds, &credential);
1527
1528 r.in.credential = &credential;
1529
1530 e.serial_number1 = 0;
1531 e.serial_number2 = 0;
1532 e.object_rid = changes[i].rid;
1533 e.flags = changes[i].flags;
1534 e.db_index = changes[i].db_index;
1535 e.delta_type = changes[i].delta_type;
1536
1537 switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
1538 case NETR_CHANGELOG_SID_INCLUDED:
1539 e.object.object_sid = changes[i].sid;
1540 break;
1541 case NETR_CHANGELOG_NAME_INCLUDED:
1542 e.object.object_name = changes[i].name;
1543 break;
1544 default:
1545 break;
1546 }
1547
1548 r.in.change_log_entry = e;
1549
1550 torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
1551 database, changes[i].comment);
1552
1553 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseRedo_r(b, tctx, &r),
1554 "DatabaseRedo failed");
1555 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1556 return true;
1557 }
1558
1559 torture_assert_ntstatus_equal(tctx, r.out.result, changes[i].expected_error, changes[i].comment);
1560 if (delta_enum_array) {
1561 torture_assert_int_equal(tctx,
1562 delta_enum_array->num_deltas,
1563 changes[i].expected_num_results,
1564 changes[i].comment);
1565 if (delta_enum_array->num_deltas > 0) {
1566 torture_assert_int_equal(tctx,
1567 delta_enum_array->delta_enum[0].delta_type,
1568 changes[i].expected_delta_type_1,
1569 changes[i].comment);
1570 }
1571 if (delta_enum_array->num_deltas > 1) {
1572 torture_assert_int_equal(tctx,
1573 delta_enum_array->delta_enum[1].delta_type,
1574 changes[i].expected_delta_type_2,
1575 changes[i].comment);
1576 }
1577 }
1578
1579 if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1580 torture_comment(tctx, "Credential chaining failed\n");
1581 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1582 return false;
1583 }
1584 }
1585 }
1586 }
1587 }
1588
1589 return true;
1590}
1591
1592/*
1593 try a netlogon AccountDeltas
1594*/
1595static bool test_AccountDeltas(struct torture_context *tctx,
1596 struct dcerpc_pipe *p,
1597 struct cli_credentials *machine_credentials)
1598{
1599 struct netr_AccountDeltas r;
1600 struct netlogon_creds_CredentialState *creds;
1601
1602 struct netr_AccountBuffer buffer;
1603 uint32_t count_returned = 0;
1604 uint32_t total_entries = 0;
1605 struct netr_UAS_INFO_0 recordid;
1606 struct netr_Authenticator return_authenticator;
1607 struct dcerpc_binding_handle *b = p->binding_handle;
1608
1609 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1610 return false;
1611 }
1612
1613 ZERO_STRUCT(return_authenticator);
1614
1615 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1616 r.in.computername = TEST_MACHINE_NAME;
1617 r.in.return_authenticator = &return_authenticator;
1618 netlogon_creds_client_authenticator(creds, &r.in.credential);
1619 ZERO_STRUCT(r.in.uas);
1620 r.in.count=10;
1621 r.in.level=0;
1622 r.in.buffersize=100;
1623 r.out.buffer = &buffer;
1624 r.out.count_returned = &count_returned;
1625 r.out.total_entries = &total_entries;
1626 r.out.recordid = &recordid;
1627 r.out.return_authenticator = &return_authenticator;
1628
1629 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1630 torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountDeltas_r(b, tctx, &r),
1631 "AccountDeltas failed");
1632 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
1633
1634 return true;
1635}
1636
1637/*
1638 try a netlogon AccountSync
1639*/
1640static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
1641 struct cli_credentials *machine_credentials)
1642{
1643 struct netr_AccountSync r;
1644 struct netlogon_creds_CredentialState *creds;
1645
1646 struct netr_AccountBuffer buffer;
1647 uint32_t count_returned = 0;
1648 uint32_t total_entries = 0;
1649 uint32_t next_reference = 0;
1650 struct netr_UAS_INFO_0 recordid;
1651 struct netr_Authenticator return_authenticator;
1652 struct dcerpc_binding_handle *b = p->binding_handle;
1653
1654 ZERO_STRUCT(recordid);
1655 ZERO_STRUCT(return_authenticator);
1656
1657 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1658 return false;
1659 }
1660
1661 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1662 r.in.computername = TEST_MACHINE_NAME;
1663 r.in.return_authenticator = &return_authenticator;
1664 netlogon_creds_client_authenticator(creds, &r.in.credential);
1665 r.in.recordid = &recordid;
1666 r.in.reference=0;
1667 r.in.level=0;
1668 r.in.buffersize=100;
1669 r.out.buffer = &buffer;
1670 r.out.count_returned = &count_returned;
1671 r.out.total_entries = &total_entries;
1672 r.out.next_reference = &next_reference;
1673 r.out.recordid = &recordid;
1674 r.out.return_authenticator = &return_authenticator;
1675
1676 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1677 torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountSync_r(b, tctx, &r),
1678 "AccountSync failed");
1679 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
1680
1681 return true;
1682}
1683
1684/*
1685 try a netlogon GetDcName
1686*/
1687static bool test_GetDcName(struct torture_context *tctx,
1688 struct dcerpc_pipe *p)
1689{
1690 struct netr_GetDcName r;
1691 const char *dcname = NULL;
1692 struct dcerpc_binding_handle *b = p->binding_handle;
1693
1694 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1695 r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
1696 r.out.dcname = &dcname;
1697
1698 torture_assert_ntstatus_ok(tctx, dcerpc_netr_GetDcName_r(b, tctx, &r),
1699 "GetDcName failed");
1700 torture_assert_werr_ok(tctx, r.out.result, "GetDcName failed");
1701
1702 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1703
1704 return true;
1705}
1706
1707static const char *function_code_str(TALLOC_CTX *mem_ctx,
1708 enum netr_LogonControlCode function_code)
1709{
1710 switch (function_code) {
1711 case NETLOGON_CONTROL_QUERY:
1712 return "NETLOGON_CONTROL_QUERY";
1713 case NETLOGON_CONTROL_REPLICATE:
1714 return "NETLOGON_CONTROL_REPLICATE";
1715 case NETLOGON_CONTROL_SYNCHRONIZE:
1716 return "NETLOGON_CONTROL_SYNCHRONIZE";
1717 case NETLOGON_CONTROL_PDC_REPLICATE:
1718 return "NETLOGON_CONTROL_PDC_REPLICATE";
1719 case NETLOGON_CONTROL_REDISCOVER:
1720 return "NETLOGON_CONTROL_REDISCOVER";
1721 case NETLOGON_CONTROL_TC_QUERY:
1722 return "NETLOGON_CONTROL_TC_QUERY";
1723 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1724 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
1725 case NETLOGON_CONTROL_FIND_USER:
1726 return "NETLOGON_CONTROL_FIND_USER";
1727 case NETLOGON_CONTROL_CHANGE_PASSWORD:
1728 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
1729 case NETLOGON_CONTROL_TC_VERIFY:
1730 return "NETLOGON_CONTROL_TC_VERIFY";
1731 case NETLOGON_CONTROL_FORCE_DNS_REG:
1732 return "NETLOGON_CONTROL_FORCE_DNS_REG";
1733 case NETLOGON_CONTROL_QUERY_DNS_REG:
1734 return "NETLOGON_CONTROL_QUERY_DNS_REG";
1735 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1736 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
1737 case NETLOGON_CONTROL_TRUNCATE_LOG:
1738 return "NETLOGON_CONTROL_TRUNCATE_LOG";
1739 case NETLOGON_CONTROL_SET_DBFLAG:
1740 return "NETLOGON_CONTROL_SET_DBFLAG";
1741 case NETLOGON_CONTROL_BREAKPOINT:
1742 return "NETLOGON_CONTROL_BREAKPOINT";
1743 default:
1744 return talloc_asprintf(mem_ctx, "unknown function code: %d",
1745 function_code);
1746 }
1747}
1748
1749
1750/*
1751 try a netlogon LogonControl
1752*/
1753static bool test_LogonControl(struct torture_context *tctx,
1754 struct dcerpc_pipe *p,
1755 struct cli_credentials *machine_credentials)
1756
1757{
1758 NTSTATUS status;
1759 struct netr_LogonControl r;
1760 union netr_CONTROL_QUERY_INFORMATION query;
1761 int i,f;
1762 enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
1763 struct dcerpc_binding_handle *b = p->binding_handle;
1764
1765 uint32_t function_codes[] = {
1766 NETLOGON_CONTROL_QUERY,
1767 NETLOGON_CONTROL_REPLICATE,
1768 NETLOGON_CONTROL_SYNCHRONIZE,
1769 NETLOGON_CONTROL_PDC_REPLICATE,
1770 NETLOGON_CONTROL_REDISCOVER,
1771 NETLOGON_CONTROL_TC_QUERY,
1772 NETLOGON_CONTROL_TRANSPORT_NOTIFY,
1773 NETLOGON_CONTROL_FIND_USER,
1774 NETLOGON_CONTROL_CHANGE_PASSWORD,
1775 NETLOGON_CONTROL_TC_VERIFY,
1776 NETLOGON_CONTROL_FORCE_DNS_REG,
1777 NETLOGON_CONTROL_QUERY_DNS_REG,
1778 NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
1779 NETLOGON_CONTROL_TRUNCATE_LOG,
1780 NETLOGON_CONTROL_SET_DBFLAG,
1781 NETLOGON_CONTROL_BREAKPOINT
1782 };
1783
1784 if (machine_credentials) {
1785 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1786 }
1787
1788 torture_comment(tctx, "Testing LogonControl with secure channel type: %d\n",
1789 secure_channel_type);
1790
1791 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1792 r.in.function_code = 1;
1793 r.out.query = &query;
1794
1795 for (f=0;f<ARRAY_SIZE(function_codes); f++) {
1796 for (i=1;i<5;i++) {
1797
1798 r.in.function_code = function_codes[f];
1799 r.in.level = i;
1800
1801 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
1802 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1803
1804 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
1805 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1806
1807 switch (r.in.level) {
1808 case 1:
1809 switch (r.in.function_code) {
1810 case NETLOGON_CONTROL_REPLICATE:
1811 case NETLOGON_CONTROL_SYNCHRONIZE:
1812 case NETLOGON_CONTROL_PDC_REPLICATE:
1813 case NETLOGON_CONTROL_BREAKPOINT:
1814 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1815 if ((secure_channel_type == SEC_CHAN_BDC) ||
1816 (secure_channel_type == SEC_CHAN_WKSTA)) {
1817 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1818 "LogonControl returned unexpected error code");
1819 } else {
1820 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1821 "LogonControl returned unexpected error code");
1822 }
1823 break;
1824
1825 case NETLOGON_CONTROL_REDISCOVER:
1826 case NETLOGON_CONTROL_TC_QUERY:
1827 case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1828 case NETLOGON_CONTROL_FIND_USER:
1829 case NETLOGON_CONTROL_CHANGE_PASSWORD:
1830 case NETLOGON_CONTROL_TC_VERIFY:
1831 case NETLOGON_CONTROL_FORCE_DNS_REG:
1832 case NETLOGON_CONTROL_QUERY_DNS_REG:
1833 case NETLOGON_CONTROL_SET_DBFLAG:
1834 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1835 "LogonControl returned unexpected error code");
1836 break;
1837 case NETLOGON_CONTROL_TRUNCATE_LOG:
1838 if ((secure_channel_type == SEC_CHAN_BDC) ||
1839 (secure_channel_type == SEC_CHAN_WKSTA)) {
1840 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1841 "LogonControl returned unexpected error code");
1842 } else {
1843 torture_assert_werr_ok(tctx, r.out.result,
1844 "LogonControl returned unexpected result");
1845 }
1846 break;
1847 default:
1848 torture_assert_werr_ok(tctx, r.out.result,
1849 "LogonControl returned unexpected result");
1850 break;
1851 }
1852 break;
1853 case 2:
1854 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1855 "LogonControl returned unexpected error code");
1856 break;
1857 default:
1858 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL,
1859 "LogonControl returned unexpected error code");
1860 break;
1861 }
1862 }
1863 }
1864
1865 r.in.level = 52;
1866 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
1867 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1868 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
1869 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1870 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl");
1871
1872 return true;
1873}
1874
1875
1876/*
1877 try a netlogon GetAnyDCName
1878*/
1879static bool test_GetAnyDCName(struct torture_context *tctx,
1880 struct dcerpc_pipe *p)
1881{
1882 NTSTATUS status;
1883 struct netr_GetAnyDCName r;
1884 const char *dcname = NULL;
1885 struct dcerpc_binding_handle *b = p->binding_handle;
1886
1887 r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
1888 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1889 r.out.dcname = &dcname;
1890
1891 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
1892 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
1893 if ((!W_ERROR_IS_OK(r.out.result)) &&
1894 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
1895 return false;
1896 }
1897
1898 if (dcname) {
1899 torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1900 }
1901
1902 r.in.domainname = NULL;
1903
1904 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
1905 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
1906 if ((!W_ERROR_IS_OK(r.out.result)) &&
1907 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
1908 return false;
1909 }
1910
1911 r.in.domainname = "";
1912
1913 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
1914 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
1915 if ((!W_ERROR_IS_OK(r.out.result)) &&
1916 (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
1917 return false;
1918 }
1919
1920 return true;
1921}
1922
1923
1924/*
1925 try a netlogon LogonControl2
1926*/
1927static bool test_LogonControl2(struct torture_context *tctx,
1928 struct dcerpc_pipe *p,
1929 struct cli_credentials *machine_credentials)
1930
1931{
1932 NTSTATUS status;
1933 struct netr_LogonControl2 r;
1934 union netr_CONTROL_DATA_INFORMATION data;
1935 union netr_CONTROL_QUERY_INFORMATION query;
1936 int i;
1937 struct dcerpc_binding_handle *b = p->binding_handle;
1938
1939 data.domain = lpcfg_workgroup(tctx->lp_ctx);
1940
1941 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1942
1943 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1944 r.in.data = &data;
1945 r.out.query = &query;
1946
1947 for (i=1;i<4;i++) {
1948 r.in.level = i;
1949
1950 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
1951 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1952
1953 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
1954 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
1955 }
1956
1957 data.domain = lpcfg_workgroup(tctx->lp_ctx);
1958
1959 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1960 r.in.data = &data;
1961
1962 for (i=1;i<4;i++) {
1963 r.in.level = i;
1964
1965 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
1966 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1967
1968 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
1969 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
1970 }
1971
1972 data.domain = lpcfg_workgroup(tctx->lp_ctx);
1973
1974 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1975 r.in.data = &data;
1976
1977 for (i=1;i<4;i++) {
1978 r.in.level = i;
1979
1980 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
1981 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1982
1983 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
1984 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
1985 }
1986
1987 data.debug_level = ~0;
1988
1989 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1990 r.in.data = &data;
1991
1992 for (i=1;i<4;i++) {
1993 r.in.level = i;
1994
1995 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
1996 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1997
1998 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
1999 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2000 }
2001
2002 ZERO_STRUCT(data);
2003 r.in.function_code = 52;
2004 r.in.data = &data;
2005
2006 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2007 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2008
2009 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2010 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2011 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "LogonControl2");
2012
2013 data.debug_level = ~0;
2014
2015 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2016 r.in.data = &data;
2017
2018 r.in.level = 52;
2019 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2020 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2021
2022 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2023 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2024 torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "LogonControl2");
2025
2026 return true;
2027}
2028
2029/*
2030 try a netlogon DatabaseSync2
2031*/
2032static bool test_DatabaseSync2(struct torture_context *tctx,
2033 struct dcerpc_pipe *p,
2034 struct cli_credentials *machine_credentials)
2035{
2036 struct netr_DatabaseSync2 r;
2037 struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2038 struct netr_Authenticator return_authenticator, credential;
2039
2040 struct netlogon_creds_CredentialState *creds;
2041 const uint32_t database_ids[] = {0, 1, 2};
2042 int i;
2043 struct dcerpc_binding_handle *b = p->binding_handle;
2044
2045 if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
2046 machine_credentials,
2047 cli_credentials_get_secure_channel_type(machine_credentials),
2048 &creds)) {
2049 return false;
2050 }
2051
2052 ZERO_STRUCT(return_authenticator);
2053
2054 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2055 r.in.computername = TEST_MACHINE_NAME;
2056 r.in.preferredmaximumlength = (uint32_t)-1;
2057 r.in.return_authenticator = &return_authenticator;
2058 r.out.return_authenticator = &return_authenticator;
2059 r.out.delta_enum_array = &delta_enum_array;
2060
2061 for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2062
2063 uint32_t sync_context = 0;
2064
2065 r.in.database_id = database_ids[i];
2066 r.in.sync_context = &sync_context;
2067 r.out.sync_context = &sync_context;
2068 r.in.restart_state = 0;
2069
2070 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
2071
2072 do {
2073 netlogon_creds_client_authenticator(creds, &credential);
2074
2075 r.in.credential = &credential;
2076
2077 torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync2_r(b, tctx, &r),
2078 "DatabaseSync2 failed");
2079 if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2080 break;
2081
2082 /* Native mode servers don't do this */
2083 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
2084 return true;
2085 }
2086
2087 torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync2");
2088
2089 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
2090 torture_comment(tctx, "Credential chaining failed\n");
2091 }
2092
2093 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2094 }
2095
2096 return true;
2097}
2098
2099
2100/*
2101 try a netlogon LogonControl2Ex
2102*/
2103static bool test_LogonControl2Ex(struct torture_context *tctx,
2104 struct dcerpc_pipe *p,
2105 struct cli_credentials *machine_credentials)
2106
2107{
2108 NTSTATUS status;
2109 struct netr_LogonControl2Ex r;
2110 union netr_CONTROL_DATA_INFORMATION data;
2111 union netr_CONTROL_QUERY_INFORMATION query;
2112 int i;
2113 struct dcerpc_binding_handle *b = p->binding_handle;
2114
2115 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2116
2117 r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2118
2119 r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2120 r.in.data = &data;
2121 r.out.query = &query;
2122
2123 for (i=1;i<4;i++) {
2124 r.in.level = i;
2125
2126 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2127 i, r.in.function_code);
2128
2129 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2130 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2131 }
2132
2133 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2134
2135 r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2136 r.in.data = &data;
2137
2138 for (i=1;i<4;i++) {
2139 r.in.level = i;
2140
2141 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2142 i, r.in.function_code);
2143
2144 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2145 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2146 }
2147
2148 data.domain = lpcfg_workgroup(tctx->lp_ctx);
2149
2150 r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2151 r.in.data = &data;
2152
2153 for (i=1;i<4;i++) {
2154 r.in.level = i;
2155
2156 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2157 i, r.in.function_code);
2158
2159 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2160 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2161 }
2162
2163 data.debug_level = ~0;
2164
2165 r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2166 r.in.data = &data;
2167
2168 for (i=1;i<4;i++) {
2169 r.in.level = i;
2170
2171 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
2172 i, r.in.function_code);
2173
2174 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2175 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2176 }
2177
2178 return true;
2179}
2180
2181static bool test_netr_GetForestTrustInformation(struct torture_context *tctx,
2182 struct dcerpc_pipe *p,
2183 struct cli_credentials *machine_credentials)
2184{
2185 struct netr_GetForestTrustInformation r;
2186 struct netlogon_creds_CredentialState *creds;
2187 struct netr_Authenticator a;
2188 struct netr_Authenticator return_authenticator;
2189 struct lsa_ForestTrustInformation *forest_trust_info;
2190 struct dcerpc_binding_handle *b = p->binding_handle;
2191
2192 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2193 machine_credentials, &creds)) {
2194 return false;
2195 }
2196
2197 netlogon_creds_client_authenticator(creds, &a);
2198
2199 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2200 r.in.computer_name = TEST_MACHINE_NAME;
2201 r.in.credential = &a;
2202 r.in.flags = 0;
2203 r.out.return_authenticator = &return_authenticator;
2204 r.out.forest_trust_info = &forest_trust_info;
2205
2206 torture_assert_ntstatus_ok(tctx,
2207 dcerpc_netr_GetForestTrustInformation_r(b, tctx, &r),
2208 "netr_GetForestTrustInformation failed");
2209 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2210 torture_comment(tctx, "not considering NT_STATUS_NOT_IMPLEMENTED as an error\n");
2211 } else {
2212 torture_assert_ntstatus_ok(tctx, r.out.result,
2213 "netr_GetForestTrustInformation failed");
2214 }
2215
2216 torture_assert(tctx,
2217 netlogon_creds_client_check(creds, &return_authenticator.cred),
2218 "Credential chaining failed");
2219
2220 return true;
2221}
2222
2223static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
2224 struct dcerpc_pipe *p, const char *trusted_domain_name)
2225{
2226 NTSTATUS status;
2227 struct netr_DsRGetForestTrustInformation r;
2228 struct lsa_ForestTrustInformation info, *info_ptr;
2229 struct dcerpc_binding_handle *b = p->binding_handle;
2230
2231 info_ptr = &info;
2232
2233 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2234 r.in.trusted_domain_name = trusted_domain_name;
2235 r.in.flags = 0;
2236 r.out.forest_trust_info = &info_ptr;
2237
2238 torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
2239
2240 status = dcerpc_netr_DsRGetForestTrustInformation_r(b, tctx, &r);
2241 torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
2242 torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
2243
2244 return true;
2245}
2246
2247/*
2248 try a netlogon netr_DsrEnumerateDomainTrusts
2249*/
2250static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
2251 struct dcerpc_pipe *p)
2252{
2253 NTSTATUS status;
2254 struct netr_DsrEnumerateDomainTrusts r;
2255 struct netr_DomainTrustList trusts;
2256 int i;
2257 struct dcerpc_binding_handle *b = p->binding_handle;
2258
2259 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2260 r.in.trust_flags = 0x3f;
2261 r.out.trusts = &trusts;
2262
2263 status = dcerpc_netr_DsrEnumerateDomainTrusts_r(b, tctx, &r);
2264 torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
2265 torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
2266
2267 /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
2268 * will show non-forest trusts and all UPN suffixes of the own forest
2269 * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
2270
2271 if (r.out.trusts->count) {
2272 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
2273 return false;
2274 }
2275 }
2276
2277 for (i=0; i<r.out.trusts->count; i++) {
2278
2279 /* get info for transitive forest trusts */
2280
2281 if (r.out.trusts->array[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2282 if (!test_netr_DsRGetForestTrustInformation(tctx, p,
2283 r.out.trusts->array[i].dns_name)) {
2284 return false;
2285 }
2286 }
2287 }
2288
2289 return true;
2290}
2291
2292static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
2293 struct dcerpc_pipe *p)
2294{
2295 NTSTATUS status;
2296 struct netr_NetrEnumerateTrustedDomains r;
2297 struct netr_Blob trusted_domains_blob;
2298 struct dcerpc_binding_handle *b = p->binding_handle;
2299
2300 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2301 r.out.trusted_domains_blob = &trusted_domains_blob;
2302
2303 status = dcerpc_netr_NetrEnumerateTrustedDomains_r(b, tctx, &r);
2304 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
2305 torture_assert_ntstatus_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
2306
2307 return true;
2308}
2309
2310static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
2311 struct dcerpc_pipe *p)
2312{
2313 NTSTATUS status;
2314 struct netr_NetrEnumerateTrustedDomainsEx r;
2315 struct netr_DomainTrustList dom_trust_list;
2316 struct dcerpc_binding_handle *b = p->binding_handle;
2317
2318 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2319 r.out.dom_trust_list = &dom_trust_list;
2320
2321 status = dcerpc_netr_NetrEnumerateTrustedDomainsEx_r(b, tctx, &r);
2322 torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
2323 torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
2324
2325 return true;
2326}
2327
2328
2329static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
2330 const char *computer_name,
2331 const char *expected_site)
2332{
2333 NTSTATUS status;
2334 struct netr_DsRGetSiteName r;
2335 const char *site = NULL;
2336 struct dcerpc_binding_handle *b = p->binding_handle;
2337
2338 r.in.computer_name = computer_name;
2339 r.out.site = &site;
2340 torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
2341
2342 status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
2343 torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2344 torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
2345 torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
2346
2347 if (torture_setting_bool(tctx, "samba4", false))
2348 torture_skip(tctx, "skipping computer name check against Samba4");
2349
2350 r.in.computer_name = talloc_asprintf(tctx, "\\\\%s", computer_name);
2351 torture_comment(tctx,
2352 "Testing netr_DsRGetSiteName with broken computer name: %s\n", r.in.computer_name);
2353
2354 status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
2355 torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2356 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_COMPUTERNAME, "netr_DsRGetSiteName");
2357
2358 return true;
2359}
2360
2361/*
2362 try a netlogon netr_DsRGetDCName
2363*/
2364static bool test_netr_DsRGetDCName(struct torture_context *tctx,
2365 struct dcerpc_pipe *p)
2366{
2367 NTSTATUS status;
2368 struct netr_DsRGetDCName r;
2369 struct netr_DsRGetDCNameInfo *info = NULL;
2370 struct dcerpc_binding_handle *b = p->binding_handle;
2371
2372 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2373 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
2374 r.in.domain_guid = NULL;
2375 r.in.site_guid = NULL;
2376 r.in.flags = DS_RETURN_DNS_NAME;
2377 r.out.info = &info;
2378
2379 status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2380 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2381 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2382
2383 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
2384
2385 status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2386 torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2387 torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2388
2389 return test_netr_DsRGetSiteName(p, tctx,
2390 info->dc_unc,
2391 info->dc_site_name);
2392}
2393
2394/*
2395 try a netlogon netr_DsRGetDCNameEx
2396*/
2397static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
2398 struct dcerpc_pipe *p)
2399{
2400 NTSTATUS status;
2401 struct netr_DsRGetDCNameEx r;
2402 struct netr_DsRGetDCNameInfo *info = NULL;
2403 struct dcerpc_binding_handle *b = p->binding_handle;
2404
2405 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2406 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
2407 r.in.domain_guid = NULL;
2408 r.in.site_name = NULL;
2409 r.in.flags = DS_RETURN_DNS_NAME;
2410 r.out.info = &info;
2411
2412 status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2413 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2414 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2415
2416 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
2417
2418 status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2419 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2420 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2421
2422 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2423 info->dc_site_name);
2424}
2425
2426/*
2427 try a netlogon netr_DsRGetDCNameEx2
2428*/
2429static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
2430 struct dcerpc_pipe *p)
2431{
2432 NTSTATUS status;
2433 struct netr_DsRGetDCNameEx2 r;
2434 struct netr_DsRGetDCNameInfo *info = NULL;
2435 struct dcerpc_binding_handle *b = p->binding_handle;
2436
2437 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with no inputs\n");
2438 ZERO_STRUCT(r.in);
2439 r.in.flags = DS_RETURN_DNS_NAME;
2440 r.out.info = &info;
2441
2442 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2443 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2444 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2445
2446 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2447 r.in.client_account = NULL;
2448 r.in.mask = 0x00000000;
2449 r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
2450 r.in.domain_guid = NULL;
2451 r.in.site_name = NULL;
2452 r.in.flags = DS_RETURN_DNS_NAME;
2453 r.out.info = &info;
2454
2455 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
2456
2457 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2458 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2459 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2460
2461 r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
2462
2463 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2464 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2465 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2466
2467 torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client account\n");
2468 r.in.client_account = TEST_MACHINE_NAME"$";
2469 r.in.mask = ACB_SVRTRUST;
2470 r.in.flags = DS_RETURN_FLAT_NAME;
2471 r.out.info = &info;
2472
2473 status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2474 torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2475 torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2476
2477 return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2478 info->dc_site_name);
2479}
2480
2481/* This is a substitution for "samdb_server_site_name" which relies on the
2482 * correct "lp_ctx" and therefore can't be used here. */
2483static const char *server_site_name(struct torture_context *tctx,
2484 struct ldb_context *ldb)
2485{
2486 TALLOC_CTX *tmp_ctx;
2487 struct ldb_dn *dn, *server_dn;
2488 const struct ldb_val *site_name_val;
2489 const char *server_dn_str, *site_name;
2490
2491 tmp_ctx = talloc_new(ldb);
2492 if (tmp_ctx == NULL) {
2493 goto failed;
2494 }
2495
2496 dn = ldb_dn_new(tmp_ctx, ldb, "");
2497 if (dn == NULL) {
2498 goto failed;
2499 }
2500
2501 server_dn_str = samdb_search_string(ldb, tmp_ctx, dn, "serverName",
2502 NULL);
2503 if (server_dn_str == NULL) {
2504 goto failed;
2505 }
2506
2507 server_dn = ldb_dn_new(tmp_ctx, ldb, server_dn_str);
2508 if (server_dn == NULL) {
2509 goto failed;
2510 }
2511
2512 /* CN=<Server name>, CN=Servers, CN=<Site name>, CN=Sites, ... */
2513 site_name_val = ldb_dn_get_component_val(server_dn, 2);
2514 if (site_name_val == NULL) {
2515 goto failed;
2516 }
2517
2518 site_name = (const char *) site_name_val->data;
2519
2520 talloc_steal(tctx, site_name);
2521 talloc_free(tmp_ctx);
2522
2523 return site_name;
2524
2525failed:
2526 talloc_free(tmp_ctx);
2527 return NULL;
2528}
2529
2530static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
2531 struct dcerpc_pipe *p)
2532{
2533 char *url;
2534 struct ldb_context *sam_ctx = NULL;
2535 NTSTATUS status;
2536 struct netr_DsrGetDcSiteCoverageW r;
2537 struct DcSitesCtr *ctr = NULL;
2538 struct dcerpc_binding_handle *b = p->binding_handle;
2539
2540 torture_comment(tctx, "This does only pass with the default site\n");
2541
2542 /* We won't double-check this when we are over 'local' transports */
2543 if (dcerpc_server_name(p)) {
2544 /* Set up connection to SAMDB on DC */
2545 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2546 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2547 NULL,
2548 cmdline_credentials,
2549 0);
2550
2551 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2552 }
2553
2554 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2555 r.out.ctr = &ctr;
2556
2557 status = dcerpc_netr_DsrGetDcSiteCoverageW_r(b, tctx, &r);
2558 torture_assert_ntstatus_ok(tctx, status, "failed");
2559 torture_assert_werr_ok(tctx, r.out.result, "failed");
2560
2561 torture_assert(tctx, ctr->num_sites == 1,
2562 "we should per default only get the default site");
2563 if (sam_ctx != NULL) {
2564 torture_assert_casestr_equal(tctx, ctr->sites[0].string,
2565 server_site_name(tctx, sam_ctx),
2566 "didn't return default site");
2567 }
2568
2569 return true;
2570}
2571
2572static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
2573 struct dcerpc_pipe *p)
2574{
2575 char *url;
2576 struct ldb_context *sam_ctx = NULL;
2577 NTSTATUS status;
2578 struct netr_DsRAddressToSitenamesW r;
2579 struct netr_DsRAddress addrs[6];
2580 struct sockaddr_in *addr;
2581#ifdef HAVE_IPV6
2582 struct sockaddr_in6 *addr6;
2583#endif
2584 struct netr_DsRAddressToSitenamesWCtr *ctr;
2585 struct dcerpc_binding_handle *b = p->binding_handle;
2586 uint32_t i;
2587 int ret;
2588
2589 torture_comment(tctx, "This does only pass with the default site\n");
2590
2591 /* We won't double-check this when we are over 'local' transports */
2592 if (dcerpc_server_name(p)) {
2593 /* Set up connection to SAMDB on DC */
2594 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2595 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2596 NULL,
2597 cmdline_credentials,
2598 0);
2599
2600 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2601 }
2602
2603 /* First try valid IP addresses */
2604
2605 addrs[0].size = sizeof(struct sockaddr_in);
2606 addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
2607 addr = (struct sockaddr_in *) addrs[0].buffer;
2608 addrs[0].buffer[0] = AF_INET;
2609 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2610 torture_assert(tctx, ret > 0, "inet_pton failed");
2611
2612 addrs[1].size = sizeof(struct sockaddr_in);
2613 addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
2614 addr = (struct sockaddr_in *) addrs[1].buffer;
2615 addrs[1].buffer[0] = AF_INET;
2616 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2617 torture_assert(tctx, ret > 0, "inet_pton failed");
2618
2619 addrs[2].size = sizeof(struct sockaddr_in);
2620 addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
2621 addr = (struct sockaddr_in *) addrs[2].buffer;
2622 addrs[2].buffer[0] = AF_INET;
2623 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2624 torture_assert(tctx, ret > 0, "inet_pton failed");
2625
2626#ifdef HAVE_IPV6
2627 addrs[3].size = sizeof(struct sockaddr_in6);
2628 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2629 addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
2630 addrs[3].buffer[0] = AF_INET6;
2631 ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
2632 torture_assert(tctx, ret > 0, "inet_pton failed");
2633
2634 addrs[4].size = sizeof(struct sockaddr_in6);
2635 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2636 addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
2637 addrs[4].buffer[0] = AF_INET6;
2638 ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
2639 torture_assert(tctx, ret > 0, "inet_pton failed");
2640
2641 addrs[5].size = sizeof(struct sockaddr_in6);
2642 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2643 addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
2644 addrs[5].buffer[0] = AF_INET6;
2645 ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
2646 torture_assert(tctx, ret > 0, "inet_pton failed");
2647#else
2648 /* the test cases are repeated to have exactly 6. This is for
2649 * compatibility with IPv4-only machines */
2650 addrs[3].size = sizeof(struct sockaddr_in);
2651 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2652 addr = (struct sockaddr_in *) addrs[3].buffer;
2653 addrs[3].buffer[0] = AF_INET;
2654 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2655 torture_assert(tctx, ret > 0, "inet_pton failed");
2656
2657 addrs[4].size = sizeof(struct sockaddr_in);
2658 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2659 addr = (struct sockaddr_in *) addrs[4].buffer;
2660 addrs[4].buffer[0] = AF_INET;
2661 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2662 torture_assert(tctx, ret > 0, "inet_pton failed");
2663
2664 addrs[5].size = sizeof(struct sockaddr_in);
2665 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2666 addr = (struct sockaddr_in *) addrs[5].buffer;
2667 addrs[5].buffer[0] = AF_INET;
2668 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2669 torture_assert(tctx, ret > 0, "inet_pton failed");
2670#endif
2671
2672 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
2673
2674 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2675 r.in.count = 6;
2676 r.in.addresses = addrs;
2677 r.out.ctr = &ctr;
2678
2679 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2680 torture_assert_ntstatus_ok(tctx, status, "failed");
2681 torture_assert_werr_ok(tctx, r.out.result, "failed");
2682
2683 if (sam_ctx != NULL) {
2684 for (i = 0; i < 3; i++) {
2685 torture_assert_casestr_equal(tctx,
2686 ctr->sitename[i].string,
2687 server_site_name(tctx, sam_ctx),
2688 "didn't return default site");
2689 }
2690 for (i = 3; i < 6; i++) {
2691 /* Windows returns "NULL" for the sitename if it isn't
2692 * IPv6 configured */
2693 if (torture_setting_bool(tctx, "samba4", false)) {
2694 torture_assert_casestr_equal(tctx,
2695 ctr->sitename[i].string,
2696 server_site_name(tctx, sam_ctx),
2697 "didn't return default site");
2698 }
2699 }
2700 }
2701
2702 /* Now try invalid ones (too short buffers) */
2703
2704 addrs[0].size = 0;
2705 addrs[1].size = 1;
2706 addrs[2].size = 4;
2707
2708 addrs[3].size = 0;
2709 addrs[4].size = 1;
2710 addrs[5].size = 4;
2711
2712 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2713 torture_assert_ntstatus_ok(tctx, status, "failed");
2714 torture_assert_werr_ok(tctx, r.out.result, "failed");
2715
2716 for (i = 0; i < 6; i++) {
2717 torture_assert(tctx, ctr->sitename[i].string == NULL,
2718 "sitename should be null");
2719 }
2720
2721 /* Now try invalid ones (wrong address types) */
2722
2723 addrs[0].size = 10;
2724 addrs[0].buffer[0] = AF_UNSPEC;
2725 addrs[1].size = 10;
2726 addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
2727 addrs[2].size = 10;
2728 addrs[2].buffer[0] = AF_UNIX;
2729
2730 addrs[3].size = 10;
2731 addrs[3].buffer[0] = 250;
2732 addrs[4].size = 10;
2733 addrs[4].buffer[0] = 251;
2734 addrs[5].size = 10;
2735 addrs[5].buffer[0] = 252;
2736
2737 status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2738 torture_assert_ntstatus_ok(tctx, status, "failed");
2739 torture_assert_werr_ok(tctx, r.out.result, "failed");
2740
2741 for (i = 0; i < 6; i++) {
2742 torture_assert(tctx, ctr->sitename[i].string == NULL,
2743 "sitename should be null");
2744 }
2745
2746 return true;
2747}
2748
2749static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
2750 struct dcerpc_pipe *p)
2751{
2752 char *url;
2753 struct ldb_context *sam_ctx = NULL;
2754 NTSTATUS status;
2755 struct netr_DsRAddressToSitenamesExW r;
2756 struct netr_DsRAddress addrs[6];
2757 struct sockaddr_in *addr;
2758#ifdef HAVE_IPV6
2759 struct sockaddr_in6 *addr6;
2760#endif
2761 struct netr_DsRAddressToSitenamesExWCtr *ctr;
2762 struct dcerpc_binding_handle *b = p->binding_handle;
2763 uint32_t i;
2764 int ret;
2765
2766 torture_comment(tctx, "This does pass with the default site\n");
2767
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,
2775 0);
2776
2777 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2778 }
2779
2780 /* First try valid IP addresses */
2781
2782 addrs[0].size = sizeof(struct sockaddr_in);
2783 addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
2784 addr = (struct sockaddr_in *) addrs[0].buffer;
2785 addrs[0].buffer[0] = AF_INET;
2786 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2787 torture_assert(tctx, ret > 0, "inet_pton failed");
2788
2789 addrs[1].size = sizeof(struct sockaddr_in);
2790 addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
2791 addr = (struct sockaddr_in *) addrs[1].buffer;
2792 addrs[1].buffer[0] = AF_INET;
2793 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2794 torture_assert(tctx, ret > 0, "inet_pton failed");
2795
2796 addrs[2].size = sizeof(struct sockaddr_in);
2797 addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
2798 addr = (struct sockaddr_in *) addrs[2].buffer;
2799 addrs[2].buffer[0] = AF_INET;
2800 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2801 torture_assert(tctx, ret > 0, "inet_pton failed");
2802
2803#ifdef HAVE_IPV6
2804 addrs[3].size = sizeof(struct sockaddr_in6);
2805 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2806 addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
2807 addrs[3].buffer[0] = AF_INET6;
2808 ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
2809 torture_assert(tctx, ret > 0, "inet_pton failed");
2810
2811 addrs[4].size = sizeof(struct sockaddr_in6);
2812 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2813 addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
2814 addrs[4].buffer[0] = AF_INET6;
2815 ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
2816 torture_assert(tctx, ret > 0, "inet_pton failed");
2817
2818 addrs[5].size = sizeof(struct sockaddr_in6);
2819 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2820 addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
2821 addrs[5].buffer[0] = AF_INET6;
2822 ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
2823 torture_assert(tctx, ret > 0, "inet_pton failed");
2824#else
2825 /* the test cases are repeated to have exactly 6. This is for
2826 * compatibility with IPv4-only machines */
2827 addrs[3].size = sizeof(struct sockaddr_in);
2828 addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2829 addr = (struct sockaddr_in *) addrs[3].buffer;
2830 addrs[3].buffer[0] = AF_INET;
2831 ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2832 torture_assert(tctx, ret > 0, "inet_pton failed");
2833
2834 addrs[4].size = sizeof(struct sockaddr_in);
2835 addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2836 addr = (struct sockaddr_in *) addrs[4].buffer;
2837 addrs[4].buffer[0] = AF_INET;
2838 ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2839 torture_assert(tctx, ret > 0, "inet_pton failed");
2840
2841 addrs[5].size = sizeof(struct sockaddr_in);
2842 addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2843 addr = (struct sockaddr_in *) addrs[5].buffer;
2844 addrs[5].buffer[0] = AF_INET;
2845 ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2846 torture_assert(tctx, ret > 0, "inet_pton failed");
2847#endif
2848
2849 ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
2850
2851 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2852 r.in.count = 6;
2853 r.in.addresses = addrs;
2854 r.out.ctr = &ctr;
2855
2856 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
2857 torture_assert_ntstatus_ok(tctx, status, "failed");
2858 torture_assert_werr_ok(tctx, r.out.result, "failed");
2859
2860 if (sam_ctx != NULL) {
2861 for (i = 0; i < 3; i++) {
2862 torture_assert_casestr_equal(tctx,
2863 ctr->sitename[i].string,
2864 server_site_name(tctx, sam_ctx),
2865 "didn't return default site");
2866 torture_assert(tctx, ctr->subnetname[i].string == NULL,
2867 "subnet should be null");
2868 }
2869 for (i = 3; i < 6; i++) {
2870 /* Windows returns "NULL" for the sitename if it isn't
2871 * IPv6 configured */
2872 if (torture_setting_bool(tctx, "samba4", false)) {
2873 torture_assert_casestr_equal(tctx,
2874 ctr->sitename[i].string,
2875 server_site_name(tctx, sam_ctx),
2876 "didn't return default site");
2877 }
2878 torture_assert(tctx, ctr->subnetname[i].string == NULL,
2879 "subnet should be null");
2880 }
2881 }
2882
2883 /* Now try invalid ones (too short buffers) */
2884
2885 addrs[0].size = 0;
2886 addrs[1].size = 1;
2887 addrs[2].size = 4;
2888
2889 addrs[3].size = 0;
2890 addrs[4].size = 1;
2891 addrs[5].size = 4;
2892
2893 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
2894 torture_assert_ntstatus_ok(tctx, status, "failed");
2895 torture_assert_werr_ok(tctx, r.out.result, "failed");
2896
2897 for (i = 0; i < 6; i++) {
2898 torture_assert(tctx, ctr->sitename[i].string == NULL,
2899 "sitename should be null");
2900 torture_assert(tctx, ctr->subnetname[i].string == NULL,
2901 "subnet should be null");
2902 }
2903
2904 addrs[0].size = 10;
2905 addrs[0].buffer[0] = AF_UNSPEC;
2906 addrs[1].size = 10;
2907 addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
2908 addrs[2].size = 10;
2909 addrs[2].buffer[0] = AF_UNIX;
2910
2911 addrs[3].size = 10;
2912 addrs[3].buffer[0] = 250;
2913 addrs[4].size = 10;
2914 addrs[4].buffer[0] = 251;
2915 addrs[5].size = 10;
2916 addrs[5].buffer[0] = 252;
2917
2918 status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
2919 torture_assert_ntstatus_ok(tctx, status, "failed");
2920 torture_assert_werr_ok(tctx, r.out.result, "failed");
2921
2922 for (i = 0; i < 6; i++) {
2923 torture_assert(tctx, ctr->sitename[i].string == NULL,
2924 "sitename should be null");
2925 torture_assert(tctx, ctr->subnetname[i].string == NULL,
2926 "subnet should be null");
2927 }
2928
2929 return true;
2930}
2931
2932static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
2933 struct dcerpc_pipe *p,
2934 struct cli_credentials *machine_credentials)
2935{
2936 struct netr_ServerGetTrustInfo r;
2937
2938 struct netr_Authenticator a;
2939 struct netr_Authenticator return_authenticator;
2940 struct samr_Password new_owf_password;
2941 struct samr_Password old_owf_password;
2942 struct netr_TrustInfo *trust_info;
2943
2944 struct netlogon_creds_CredentialState *creds;
2945 struct dcerpc_binding_handle *b = p->binding_handle;
2946
2947 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2948 machine_credentials, &creds)) {
2949 return false;
2950 }
2951
2952 netlogon_creds_client_authenticator(creds, &a);
2953
2954 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2955 r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
2956 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2957 r.in.computer_name = TEST_MACHINE_NAME;
2958 r.in.credential = &a;
2959
2960 r.out.return_authenticator = &return_authenticator;
2961 r.out.new_owf_password = &new_owf_password;
2962 r.out.old_owf_password = &old_owf_password;
2963 r.out.trust_info = &trust_info;
2964
2965 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerGetTrustInfo_r(b, tctx, &r),
2966 "ServerGetTrustInfo failed");
2967 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerGetTrustInfo failed");
2968 torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
2969
2970 return true;
2971}
2972
2973
2974static bool test_GetDomainInfo(struct torture_context *tctx,
2975 struct dcerpc_pipe *p,
2976 struct cli_credentials *machine_credentials)
2977{
2978 struct netr_LogonGetDomainInfo r;
2979 struct netr_WorkstationInformation q1;
2980 struct netr_Authenticator a;
2981 struct netlogon_creds_CredentialState *creds;
2982 struct netr_OsVersion os;
2983 union netr_WorkstationInfo query;
2984 union netr_DomainInfo info;
2985 const char* const attrs[] = { "dNSHostName", "operatingSystem",
2986 "operatingSystemServicePack", "operatingSystemVersion",
2987 "servicePrincipalName", NULL };
2988 char *url;
2989 struct ldb_context *sam_ctx = NULL;
2990 struct ldb_message **res;
2991 struct ldb_message_element *spn_el;
2992 int ret, i;
2993 char *version_str;
2994 const char *old_dnsname = NULL;
2995 char **spns = NULL;
2996 int num_spns = 0;
2997 char *temp_str;
2998 struct dcerpc_binding_handle *b = p->binding_handle;
2999
3000 torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
3001
3002 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3003 machine_credentials, &creds)) {
3004 return false;
3005 }
3006
3007 /* We won't double-check this when we are over 'local' transports */
3008 if (dcerpc_server_name(p)) {
3009 /* Set up connection to SAMDB on DC */
3010 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3011 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3012 NULL,
3013 cmdline_credentials,
3014 0);
3015
3016 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3017 }
3018
3019 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
3020 netlogon_creds_client_authenticator(creds, &a);
3021
3022 ZERO_STRUCT(r);
3023 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3024 r.in.computer_name = TEST_MACHINE_NAME;
3025 r.in.credential = &a;
3026 r.in.level = 1;
3027 r.in.return_authenticator = &a;
3028 r.in.query = &query;
3029 r.out.return_authenticator = &a;
3030 r.out.info = &info;
3031
3032 ZERO_STRUCT(os);
3033 os.os.MajorVersion = 123;
3034 os.os.MinorVersion = 456;
3035 os.os.BuildNumber = 789;
3036 os.os.CSDVersion = "Service Pack 10";
3037 os.os.ServicePackMajor = 10;
3038 os.os.ServicePackMinor = 1;
3039 os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
3040 os.os.ProductType = NETR_VER_NT_SERVER;
3041 os.os.Reserved = 0;
3042
3043 version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
3044 os.os.MinorVersion, os.os.BuildNumber);
3045
3046 ZERO_STRUCT(q1);
3047 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3048 lpcfg_dnsdomain(tctx->lp_ctx));
3049 q1.sitename = "Default-First-Site-Name";
3050 q1.os_version.os = &os;
3051 q1.os_name.string = talloc_asprintf(tctx,
3052 "Tortured by Samba4 RPC-NETLOGON: %s",
3053 timestring(tctx, time(NULL)));
3054
3055 /* The workstation handles the "servicePrincipalName" and DNS hostname
3056 updates */
3057 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3058
3059 query.workstation_info = &q1;
3060
3061 if (sam_ctx) {
3062 /* Gets back the old DNS hostname in AD */
3063 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3064 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3065 old_dnsname =
3066 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
3067
3068 /* Gets back the "servicePrincipalName"s in AD */
3069 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3070 if (spn_el != NULL) {
3071 for (i=0; i < spn_el->num_values; i++) {
3072 spns = talloc_realloc(tctx, spns, char *, i + 1);
3073 spns[i] = (char *) spn_el->values[i].data;
3074 }
3075 num_spns = i;
3076 }
3077 }
3078
3079 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3080 "LogonGetDomainInfo failed");
3081 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3082 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3083
3084 smb_msleep(250);
3085
3086 if (sam_ctx) {
3087 /* AD workstation infos entry check */
3088 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3089 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3090 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3091 torture_assert_str_equal(tctx,
3092 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3093 q1.os_name.string, "'operatingSystem' wrong!");
3094 torture_assert_str_equal(tctx,
3095 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
3096 os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
3097 torture_assert_str_equal(tctx,
3098 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
3099 version_str, "'operatingSystemVersion' wrong!");
3100
3101 if (old_dnsname != NULL) {
3102 /* If before a DNS hostname was set then it should remain
3103 the same in combination with the "servicePrincipalName"s.
3104 The DNS hostname should also be returned by our
3105 "LogonGetDomainInfo" call (in the domain info structure). */
3106
3107 torture_assert_str_equal(tctx,
3108 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3109 old_dnsname, "'DNS hostname' was not set!");
3110
3111 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3112 torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
3113 "'servicePrincipalName's not set!");
3114 torture_assert(tctx, spn_el->num_values == num_spns,
3115 "'servicePrincipalName's incorrect!");
3116 for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
3117 torture_assert_str_equal(tctx,
3118 (char *) spn_el->values[i].data,
3119 spns[i], "'servicePrincipalName's incorrect!");
3120
3121 torture_assert_str_equal(tctx,
3122 info.domain_info->dns_hostname.string,
3123 old_dnsname,
3124 "Out 'DNS hostname' doesn't match the old one!");
3125 } else {
3126 /* If no DNS hostname was set then also now none should be set,
3127 the "servicePrincipalName"s should remain empty and no DNS
3128 hostname should be returned by our "LogonGetDomainInfo"
3129 call (in the domain info structure). */
3130
3131 torture_assert(tctx,
3132 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
3133 "'DNS hostname' was set!");
3134
3135 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3136 torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
3137 "'servicePrincipalName's were set!");
3138
3139 torture_assert(tctx,
3140 info.domain_info->dns_hostname.string == NULL,
3141 "Out 'DNS host name' was set!");
3142 }
3143 }
3144
3145 /* Checks "workstation flags" */
3146 torture_assert(tctx,
3147 info.domain_info->workstation_flags
3148 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3149 "Out 'workstation flags' don't match!");
3150
3151
3152 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname doesn't work)\n");
3153 netlogon_creds_client_authenticator(creds, &a);
3154
3155 /* Wipe out the osVersion, and prove which values still 'stick' */
3156 q1.os_version.os = NULL;
3157
3158 /* Change also the DNS hostname to test differences in behaviour */
3159 talloc_free(discard_const_p(char, q1.dns_hostname));
3160 q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3161 lpcfg_dnsdomain(tctx->lp_ctx));
3162
3163 /* The workstation handles the "servicePrincipalName" and DNS hostname
3164 updates */
3165 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3166
3167 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3168 "LogonGetDomainInfo failed");
3169 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3170
3171 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3172
3173 smb_msleep(250);
3174
3175 if (sam_ctx) {
3176 /* AD workstation infos entry check */
3177 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3178 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3179 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3180
3181 torture_assert_str_equal(tctx,
3182 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3183 q1.os_name.string, "'operatingSystem' should stick!");
3184 torture_assert(tctx,
3185 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3186 "'operatingSystemServicePack' shouldn't stick!");
3187 torture_assert(tctx,
3188 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3189 "'operatingSystemVersion' shouldn't stick!");
3190
3191 /* The DNS host name shouldn't have been updated by the server */
3192
3193 torture_assert_str_equal(tctx,
3194 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3195 old_dnsname, "'DNS host name' did change!");
3196
3197 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3198 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3199 3.5.4.3.9 */
3200 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3201 torture_assert(tctx, spn_el != NULL,
3202 "There should exist 'servicePrincipalName's in AD!");
3203 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3204 for (i=0; i < spn_el->num_values; i++)
3205 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3206 break;
3207 torture_assert(tctx, i != spn_el->num_values,
3208 "'servicePrincipalName' HOST/<Netbios name> not found!");
3209 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3210 for (i=0; i < spn_el->num_values; i++)
3211 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3212 break;
3213 torture_assert(tctx, i != spn_el->num_values,
3214 "'servicePrincipalName' HOST/<FQDN name> not found!");
3215
3216 /* Check that the out DNS hostname was set properly */
3217 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
3218 old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
3219 }
3220
3221 /* Checks "workstation flags" */
3222 torture_assert(tctx,
3223 info.domain_info->workstation_flags == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3224 "Out 'workstation flags' don't match!");
3225
3226
3227 /* Now try the same but the workstation flags set to 0 */
3228
3229 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (variation of DNS hostname doesn't work)\n");
3230 netlogon_creds_client_authenticator(creds, &a);
3231
3232 /* Change also the DNS hostname to test differences in behaviour */
3233 talloc_free(discard_const_p(char, q1.dns_hostname));
3234 q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3235 lpcfg_dnsdomain(tctx->lp_ctx));
3236
3237 /* Wipe out the osVersion, and prove which values still 'stick' */
3238 q1.os_version.os = NULL;
3239
3240 /* Let the DC handle the "servicePrincipalName" and DNS hostname
3241 updates */
3242 q1.workstation_flags = 0;
3243
3244 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3245 "LogonGetDomainInfo failed");
3246 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3247 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3248
3249 smb_msleep(250);
3250
3251 if (sam_ctx) {
3252 /* AD workstation infos entry check */
3253 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3254 "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3255 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3256
3257 torture_assert_str_equal(tctx,
3258 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3259 q1.os_name.string, "'operatingSystem' should stick!");
3260 torture_assert(tctx,
3261 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3262 "'operatingSystemServicePack' shouldn't stick!");
3263 torture_assert(tctx,
3264 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3265 "'operatingSystemVersion' shouldn't stick!");
3266
3267 /* The DNS host name shouldn't have been updated by the server */
3268
3269 torture_assert_str_equal(tctx,
3270 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3271 old_dnsname, "'DNS host name' did change!");
3272
3273 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3274 updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3275 3.5.4.3.9 */
3276 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3277 torture_assert(tctx, spn_el != NULL,
3278 "There should exist 'servicePrincipalName's in AD!");
3279 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3280 for (i=0; i < spn_el->num_values; i++)
3281 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3282 break;
3283 torture_assert(tctx, i != spn_el->num_values,
3284 "'servicePrincipalName' HOST/<Netbios name> not found!");
3285 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3286 for (i=0; i < spn_el->num_values; i++)
3287 if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3288 break;
3289 torture_assert(tctx, i != spn_el->num_values,
3290 "'servicePrincipalName' HOST/<FQDN name> not found!");
3291
3292 /* Here the server gives us NULL as the out DNS hostname */
3293 torture_assert(tctx, info.domain_info->dns_hostname.string == NULL,
3294 "Out 'DNS hostname' should be NULL!");
3295 }
3296
3297 /* Checks "workstation flags" */
3298 torture_assert(tctx,
3299 info.domain_info->workstation_flags == 0,
3300 "Out 'workstation flags' don't match!");
3301
3302
3303 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (verification of DNS hostname and check for trusted domains)\n");
3304 netlogon_creds_client_authenticator(creds, &a);
3305
3306 /* Put the DNS hostname back */
3307 talloc_free(discard_const_p(char, q1.dns_hostname));
3308 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3309 lpcfg_dnsdomain(tctx->lp_ctx));
3310
3311 /* The workstation handles the "servicePrincipalName" and DNS hostname
3312 updates */
3313 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3314
3315 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3316 "LogonGetDomainInfo failed");
3317 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3318 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3319
3320 smb_msleep(250);
3321
3322 /* Now the in/out DNS hostnames should be the same */
3323 torture_assert_str_equal(tctx,
3324 info.domain_info->dns_hostname.string,
3325 query.workstation_info->dns_hostname,
3326 "In/Out 'DNS hostnames' don't match!");
3327 old_dnsname = info.domain_info->dns_hostname.string;
3328
3329 /* Checks "workstation flags" */
3330 torture_assert(tctx,
3331 info.domain_info->workstation_flags
3332 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3333 "Out 'workstation flags' don't match!");
3334
3335 /* Checks for trusted domains */
3336 torture_assert(tctx,
3337 (info.domain_info->trusted_domain_count != 0)
3338 && (info.domain_info->trusted_domains != NULL),
3339 "Trusted domains have been requested!");
3340
3341
3342 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 5th call (check for trusted domains)\n");
3343 netlogon_creds_client_authenticator(creds, &a);
3344
3345 /* The workstation handles the "servicePrincipalName" and DNS hostname
3346 updates and requests inbound trusts */
3347 q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
3348 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
3349
3350 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3351 "LogonGetDomainInfo failed");
3352 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3353 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3354
3355 smb_msleep(250);
3356
3357 /* Checks "workstation flags" */
3358 torture_assert(tctx,
3359 info.domain_info->workstation_flags
3360 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
3361 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
3362 "Out 'workstation flags' don't match!");
3363
3364 /* Checks for trusted domains */
3365 torture_assert(tctx,
3366 (info.domain_info->trusted_domain_count != 0)
3367 && (info.domain_info->trusted_domains != NULL),
3368 "Trusted domains have been requested!");
3369
3370
3371 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
3372 netlogon_creds_client_authenticator(creds, &a);
3373
3374 query.workstation_info->dns_hostname = NULL;
3375
3376 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3377 "LogonGetDomainInfo failed");
3378 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3379 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3380
3381 /* The old DNS hostname should stick */
3382 torture_assert_str_equal(tctx,
3383 info.domain_info->dns_hostname.string,
3384 old_dnsname,
3385 "'DNS hostname' changed!");
3386
3387
3388 if (!torture_setting_bool(tctx, "dangerous", false)) {
3389 torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 7th call (no workstation info) - enable dangerous tests in order to do so\n");
3390 } else {
3391 /* Try a call without the workstation information structure */
3392
3393 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (no workstation info)\n");
3394 netlogon_creds_client_authenticator(creds, &a);
3395
3396 query.workstation_info = NULL;
3397
3398 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3399 "LogonGetDomainInfo failed");
3400 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3401 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3402 }
3403
3404 return true;
3405}
3406
3407static bool test_GetDomainInfo_async(struct torture_context *tctx,
3408 struct dcerpc_pipe *p,
3409 struct cli_credentials *machine_credentials)
3410{
3411 NTSTATUS status;
3412 struct netr_LogonGetDomainInfo r;
3413 struct netr_WorkstationInformation q1;
3414 struct netr_Authenticator a;
3415#define ASYNC_COUNT 100
3416 struct netlogon_creds_CredentialState *creds;
3417 struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
3418 struct tevent_req *req[ASYNC_COUNT];
3419 int i;
3420 union netr_WorkstationInfo query;
3421 union netr_DomainInfo info;
3422
3423 torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
3424
3425 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3426 machine_credentials, &creds)) {
3427 return false;
3428 }
3429
3430 ZERO_STRUCT(r);
3431 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3432 r.in.computer_name = TEST_MACHINE_NAME;
3433 r.in.credential = &a;
3434 r.in.level = 1;
3435 r.in.return_authenticator = &a;
3436 r.in.query = &query;
3437 r.out.return_authenticator = &a;
3438 r.out.info = &info;
3439
3440 ZERO_STRUCT(q1);
3441 q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3442 lpcfg_dnsdomain(tctx->lp_ctx));
3443 q1.sitename = "Default-First-Site-Name";
3444 q1.os_name.string = "UNIX/Linux or similar";
3445
3446 query.workstation_info = &q1;
3447
3448 for (i=0;i<ASYNC_COUNT;i++) {
3449 netlogon_creds_client_authenticator(creds, &a);
3450
3451 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
3452 req[i] = dcerpc_netr_LogonGetDomainInfo_r_send(tctx, tctx->ev, p->binding_handle, &r);
3453
3454 /* even with this flush per request a w2k3 server seems to
3455 clag with multiple outstanding requests. bleergh. */
3456 torture_assert_int_equal(tctx, event_loop_once(dcerpc_event_context(p)), 0,
3457 "event_loop_once failed");
3458 }
3459
3460 for (i=0;i<ASYNC_COUNT;i++) {
3461 torture_assert_int_equal(tctx, tevent_req_poll(req[i], tctx->ev), true,
3462 "tevent_req_poll() failed");
3463
3464 status = dcerpc_netr_LogonGetDomainInfo_r_recv(req[i], tctx);
3465
3466 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
3467 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
3468
3469 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred),
3470 "Credential chaining failed at async");
3471 }
3472
3473 torture_comment(tctx,
3474 "Testing netr_LogonGetDomainInfo - async count %d OK\n", ASYNC_COUNT);
3475
3476 return true;
3477}
3478
3479static bool test_ManyGetDCName(struct torture_context *tctx,
3480 struct dcerpc_pipe *p)
3481{
3482 NTSTATUS status;
3483 struct dcerpc_pipe *p2;
3484 struct lsa_ObjectAttribute attr;
3485 struct lsa_QosInfo qos;
3486 struct lsa_OpenPolicy2 o;
3487 struct policy_handle lsa_handle;
3488 struct lsa_DomainList domains;
3489
3490 struct lsa_EnumTrustDom t;
3491 uint32_t resume_handle = 0;
3492 struct netr_GetAnyDCName d;
3493 const char *dcname = NULL;
3494 struct dcerpc_binding_handle *b = p->binding_handle;
3495 struct dcerpc_binding_handle *b2;
3496
3497 int i;
3498
3499 if (p->conn->transport.transport != NCACN_NP) {
3500 return true;
3501 }
3502
3503 torture_comment(tctx, "Torturing GetDCName\n");
3504
3505 status = dcerpc_secondary_connection(p, &p2, p->binding);
3506 torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
3507
3508 status = dcerpc_bind_auth_none(p2, &ndr_table_lsarpc);
3509 torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
3510 b2 = p2->binding_handle;
3511
3512 qos.len = 0;
3513 qos.impersonation_level = 2;
3514 qos.context_mode = 1;
3515 qos.effective_only = 0;
3516
3517 attr.len = 0;
3518 attr.root_dir = NULL;
3519 attr.object_name = NULL;
3520 attr.attributes = 0;
3521 attr.sec_desc = NULL;
3522 attr.sec_qos = &qos;
3523
3524 o.in.system_name = "\\";
3525 o.in.attr = &attr;
3526 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3527 o.out.handle = &lsa_handle;
3528
3529 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
3530 "OpenPolicy2 failed");
3531 torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
3532
3533 t.in.handle = &lsa_handle;
3534 t.in.resume_handle = &resume_handle;
3535 t.in.max_size = 1000;
3536 t.out.domains = &domains;
3537 t.out.resume_handle = &resume_handle;
3538
3539 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b2, tctx, &t),
3540 "EnumTrustDom failed");
3541
3542 if ((!NT_STATUS_IS_OK(t.out.result) &&
3543 (!NT_STATUS_EQUAL(t.out.result, NT_STATUS_NO_MORE_ENTRIES))))
3544 torture_fail(tctx, "Could not list domains");
3545
3546 talloc_free(p2);
3547
3548 d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
3549 dcerpc_server_name(p));
3550 d.out.dcname = &dcname;
3551
3552 for (i=0; i<domains.count * 4; i++) {
3553 struct lsa_DomainInfo *info =
3554 &domains.domains[rand()%domains.count];
3555
3556 d.in.domainname = info->name.string;
3557
3558 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &d);
3559 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3560
3561 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
3562 dcname ? dcname : "unknown");
3563 }
3564
3565 return true;
3566}
3567
3568static bool test_SetPassword_with_flags(struct torture_context *tctx,
3569 struct dcerpc_pipe *p,
3570 struct cli_credentials *machine_credentials)
3571{
3572 uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
3573 struct netlogon_creds_CredentialState *creds;
3574 int i;
3575
3576 if (!test_SetupCredentials2(p, tctx, 0,
3577 machine_credentials,
3578 cli_credentials_get_secure_channel_type(machine_credentials),
3579 &creds)) {
3580 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
3581 }
3582
3583 for (i=0; i < ARRAY_SIZE(flags); i++) {
3584 torture_assert(tctx,
3585 test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
3586 talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
3587 }
3588
3589 return true;
3590}
3591
3592struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
3593{
3594 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon");
3595 struct torture_rpc_tcase *tcase;
3596 struct torture_test *test;
3597
3598 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3599 &ndr_table_netlogon, TEST_MACHINE_NAME);
3600
3601 torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
3602 torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
3603 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
3604 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
3605 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
3606 torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
3607 torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
3608 torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
3609 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
3610 torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
3611 torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
3612 torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
3613 torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
3614 torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
3615 torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
3616 torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
3617 torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
3618 torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
3619 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
3620 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
3621 test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
3622 test->dangerous = true;
3623 torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
3624 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
3625 torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
3626 torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
3627 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
3628 torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
3629 torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
3630 torture_rpc_tcase_add_test_creds(tcase, "GetForestTrustInformation", test_netr_GetForestTrustInformation);
3631
3632 return suite;
3633}
3634
3635struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
3636{
3637 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon-s3");
3638 struct torture_rpc_tcase *tcase;
3639
3640 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3641 &ndr_table_netlogon, TEST_MACHINE_NAME);
3642
3643 torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
3644 torture_rpc_tcase_add_test_creds(tcase, "SamLogon_NULL_domain", test_SamLogon_NULL_domain);
3645 torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
3646 torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
3647 torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
3648 torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
3649
3650 return suite;
3651}
3652
3653struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
3654{
3655 struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon.admin");
3656 struct torture_rpc_tcase *tcase;
3657
3658 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3659 &ndr_table_netlogon, TEST_MACHINE_NAME);
3660 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3661 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3662 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3663
3664 tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netlogon",
3665 &ndr_table_netlogon, TEST_MACHINE_NAME);
3666 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3667 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3668 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3669
3670 tcase = torture_suite_add_rpc_iface_tcase(suite, "netlogon",
3671 &ndr_table_netlogon);
3672 torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3673 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3674 torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3675
3676 return suite;
3677}
Note: See TracBrowser for help on using the repository browser.