Line data Source code
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/cmdline.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 : #undef strcasecmp
42 :
43 : #define TEST_MACHINE_NAME "torturetest"
44 :
45 18 : static bool test_netr_broken_binding_handle(struct torture_context *tctx,
46 : struct dcerpc_pipe *p)
47 : {
48 3 : NTSTATUS status;
49 3 : struct netr_DsRGetSiteName r;
50 18 : const char *site = NULL;
51 18 : struct dcerpc_binding_handle *b = p->binding_handle;
52 :
53 18 : r.in.computer_name = talloc_asprintf(tctx, "\\\\%s",
54 : dcerpc_server_name(p));
55 18 : r.out.site = &site;
56 :
57 18 : torture_comment(tctx,
58 : "Testing netlogon request with correct binding handle: %s\n",
59 : r.in.computer_name);
60 :
61 18 : status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
62 18 : torture_assert_ntstatus_ok(tctx, status,
63 : "Netlogon request with broken binding handle");
64 18 : torture_assert_werr_ok(tctx, r.out.result,
65 : "Netlogon request with broken binding handle");
66 :
67 36 : if (torture_setting_bool(tctx, "samba3", false) ||
68 18 : torture_setting_bool(tctx, "samba4", false)) {
69 18 : torture_skip(tctx,
70 : "Skipping broken binding handle check against Samba");
71 : }
72 :
73 0 : r.in.computer_name = talloc_asprintf(tctx, "\\\\\\\\%s",
74 : dcerpc_server_name(p));
75 :
76 0 : torture_comment(tctx,
77 : "Testing netlogon request with broken binding handle: %s\n",
78 : r.in.computer_name);
79 :
80 0 : status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
81 0 : torture_assert_ntstatus_ok(tctx, status,
82 : "Netlogon request with broken binding handle");
83 0 : torture_assert_werr_equal(tctx, r.out.result,
84 : WERR_INVALID_COMPUTERNAME,
85 : "Netlogon request with broken binding handle");
86 :
87 0 : r.in.computer_name = "\\\\\\\\THIS_IS_NOT_VALID";
88 :
89 0 : torture_comment(tctx,
90 : "Testing netlogon request with broken binding handle: %s\n",
91 : r.in.computer_name);
92 :
93 0 : status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
94 0 : torture_assert_ntstatus_ok(tctx, status,
95 : "Netlogon request with broken binding handle");
96 0 : torture_assert_werr_equal(tctx, r.out.result,
97 : WERR_INVALID_COMPUTERNAME,
98 : "Netlogon request with broken binding handle");
99 :
100 0 : return true;
101 : }
102 :
103 18 : static bool test_LogonUasLogon(struct torture_context *tctx,
104 : struct dcerpc_pipe *p)
105 : {
106 3 : NTSTATUS status;
107 3 : struct netr_LogonUasLogon r;
108 18 : struct netr_UasInfo *info = NULL;
109 18 : struct dcerpc_binding_handle *b = p->binding_handle;
110 :
111 18 : r.in.server_name = NULL;
112 18 : r.in.account_name = cli_credentials_get_username(
113 : samba_cmdline_get_creds());
114 18 : r.in.workstation = TEST_MACHINE_NAME;
115 18 : r.out.info = &info;
116 :
117 18 : status = dcerpc_netr_LogonUasLogon_r(b, tctx, &r);
118 18 : torture_assert_ntstatus_ok(tctx, status, "LogonUasLogon");
119 :
120 0 : return true;
121 : }
122 :
123 18 : static bool test_LogonUasLogoff(struct torture_context *tctx,
124 : struct dcerpc_pipe *p)
125 : {
126 3 : NTSTATUS status;
127 3 : struct netr_LogonUasLogoff r;
128 3 : struct netr_UasLogoffInfo info;
129 18 : struct dcerpc_binding_handle *b = p->binding_handle;
130 :
131 18 : r.in.server_name = NULL;
132 18 : r.in.account_name = cli_credentials_get_username(
133 : samba_cmdline_get_creds());
134 18 : r.in.workstation = TEST_MACHINE_NAME;
135 18 : r.out.info = &info;
136 :
137 18 : status = dcerpc_netr_LogonUasLogoff_r(b, tctx, &r);
138 18 : torture_assert_ntstatus_ok(tctx, status, "LogonUasLogoff");
139 :
140 0 : return true;
141 : }
142 :
143 276 : bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
144 : struct cli_credentials *credentials,
145 : struct netlogon_creds_CredentialState **creds_out)
146 : {
147 42 : struct netr_ServerReqChallenge r;
148 42 : struct netr_ServerAuthenticate a;
149 42 : struct netr_Credential credentials1, credentials2, credentials3;
150 42 : struct netlogon_creds_CredentialState *creds;
151 42 : const struct samr_Password *mach_password;
152 42 : const char *machine_name;
153 276 : struct dcerpc_binding_handle *b = p->binding_handle;
154 :
155 276 : mach_password = cli_credentials_get_nt_hash(credentials, tctx);
156 276 : machine_name = cli_credentials_get_workstation(credentials);
157 :
158 276 : torture_comment(tctx, "Testing ServerReqChallenge\n");
159 :
160 276 : r.in.server_name = NULL;
161 276 : r.in.computer_name = machine_name;
162 276 : r.in.credentials = &credentials1;
163 276 : r.out.return_credentials = &credentials2;
164 :
165 276 : netlogon_creds_random_challenge(&credentials1);
166 :
167 276 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
168 : "ServerReqChallenge failed");
169 276 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
170 :
171 276 : a.in.server_name = NULL;
172 276 : a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
173 276 : a.in.secure_channel_type = cli_credentials_get_secure_channel_type(credentials);
174 276 : a.in.computer_name = machine_name;
175 276 : a.in.credentials = &credentials3;
176 276 : a.out.return_credentials = &credentials3;
177 :
178 276 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
179 : a.in.computer_name,
180 234 : a.in.secure_channel_type,
181 : &credentials1, &credentials2,
182 : mach_password, &credentials3,
183 : 0);
184 276 : torture_assert(tctx, creds != NULL, "memory allocation");
185 :
186 :
187 276 : torture_comment(tctx, "Testing ServerAuthenticate\n");
188 :
189 276 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate_r(b, tctx, &a),
190 : "ServerAuthenticate failed");
191 :
192 : /* This allows the tests to continue against the more fussy windows 2008 */
193 276 : if (NT_STATUS_EQUAL(a.out.result, NT_STATUS_DOWNGRADE_DETECTED)) {
194 150 : return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
195 : credentials,
196 : cli_credentials_get_secure_channel_type(credentials),
197 : creds_out);
198 : }
199 :
200 126 : torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate");
201 :
202 126 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
203 : "Credential chaining failed");
204 :
205 126 : *creds_out = creds;
206 126 : return true;
207 : }
208 :
209 370 : bool test_SetupCredentials2ex(struct dcerpc_pipe *p, struct torture_context *tctx,
210 : uint32_t negotiate_flags,
211 : struct cli_credentials *machine_credentials,
212 : const char *computer_name,
213 : enum netr_SchannelType sec_chan_type,
214 : NTSTATUS expected_result,
215 : struct netlogon_creds_CredentialState **creds_out)
216 : {
217 63 : struct netr_ServerReqChallenge r;
218 63 : struct netr_ServerAuthenticate2 a;
219 63 : struct netr_Credential credentials1, credentials2, credentials3;
220 63 : struct netlogon_creds_CredentialState *creds;
221 63 : const struct samr_Password *mach_password;
222 370 : struct dcerpc_binding_handle *b = p->binding_handle;
223 370 : const char *account_name = cli_credentials_get_username(machine_credentials);
224 :
225 370 : mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
226 :
227 370 : torture_comment(tctx, "Testing ServerReqChallenge\n");
228 :
229 370 : r.in.server_name = NULL;
230 370 : r.in.computer_name = computer_name;
231 370 : r.in.credentials = &credentials1;
232 370 : r.out.return_credentials = &credentials2;
233 :
234 370 : netlogon_creds_random_challenge(&credentials1);
235 :
236 370 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
237 : "ServerReqChallenge failed");
238 370 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
239 :
240 370 : a.in.server_name = NULL;
241 370 : a.in.account_name = account_name;
242 370 : a.in.secure_channel_type = sec_chan_type;
243 370 : a.in.computer_name = computer_name;
244 370 : a.in.negotiate_flags = &negotiate_flags;
245 370 : a.out.negotiate_flags = &negotiate_flags;
246 370 : a.in.credentials = &credentials3;
247 370 : a.out.return_credentials = &credentials3;
248 :
249 370 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
250 : a.in.computer_name,
251 307 : a.in.secure_channel_type,
252 : &credentials1, &credentials2,
253 : mach_password, &credentials3,
254 : negotiate_flags);
255 :
256 370 : torture_assert(tctx, creds != NULL, "memory allocation");
257 :
258 370 : torture_comment(tctx, "Testing ServerAuthenticate2\n");
259 :
260 370 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
261 : "ServerAuthenticate2 failed");
262 370 : torture_assert_ntstatus_equal(tctx, a.out.result, expected_result,
263 : "ServerAuthenticate2 unexpected");
264 :
265 358 : if (NT_STATUS_IS_OK(expected_result)) {
266 340 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
267 : "Credential chaining failed");
268 : } else {
269 18 : torture_assert(tctx, !netlogon_creds_client_check(creds, &credentials3),
270 : "Credential chaining passed unexpected");
271 : }
272 :
273 358 : torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
274 :
275 358 : *creds_out = creds;
276 358 : return true;
277 : }
278 :
279 334 : bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx,
280 : uint32_t negotiate_flags,
281 : struct cli_credentials *machine_credentials,
282 : enum netr_SchannelType sec_chan_type,
283 : struct netlogon_creds_CredentialState **creds_out)
284 : {
285 57 : const char *computer_name =
286 334 : cli_credentials_get_workstation(machine_credentials);
287 :
288 668 : return test_SetupCredentials2ex(p, tctx, negotiate_flags,
289 : machine_credentials,
290 : computer_name,
291 : sec_chan_type,
292 334 : NT_STATUS_OK,
293 : creds_out);
294 : }
295 :
296 75 : bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx,
297 : uint32_t negotiate_flags,
298 : struct cli_credentials *machine_credentials,
299 : struct netlogon_creds_CredentialState **creds_out)
300 : {
301 12 : struct netr_ServerReqChallenge r;
302 12 : struct netr_ServerAuthenticate3 a;
303 12 : struct netr_Credential credentials1, credentials2, credentials3;
304 12 : struct netlogon_creds_CredentialState *creds;
305 12 : struct samr_Password mach_password;
306 12 : uint32_t rid;
307 12 : const char *machine_name;
308 12 : const char *plain_pass;
309 75 : struct dcerpc_binding_handle *b = NULL;
310 :
311 75 : if (p == NULL) {
312 0 : return false;
313 : }
314 :
315 75 : b = p->binding_handle;
316 :
317 75 : machine_name = cli_credentials_get_workstation(machine_credentials);
318 75 : torture_assert(tctx, machine_name != NULL, "machine_name");
319 75 : plain_pass = cli_credentials_get_password(machine_credentials);
320 75 : torture_assert(tctx, plain_pass != NULL, "plain_pass");
321 :
322 75 : torture_comment(tctx, "Testing ServerReqChallenge\n");
323 :
324 75 : r.in.server_name = NULL;
325 75 : r.in.computer_name = machine_name;
326 75 : r.in.credentials = &credentials1;
327 75 : r.out.return_credentials = &credentials2;
328 :
329 75 : netlogon_creds_random_challenge(&credentials1);
330 :
331 75 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
332 : "ServerReqChallenge failed");
333 75 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
334 :
335 75 : E_md4hash(plain_pass, mach_password.hash);
336 :
337 75 : a.in.server_name = NULL;
338 75 : a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
339 75 : a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
340 75 : a.in.computer_name = machine_name;
341 75 : a.in.negotiate_flags = &negotiate_flags;
342 75 : a.in.credentials = &credentials3;
343 75 : a.out.return_credentials = &credentials3;
344 75 : a.out.negotiate_flags = &negotiate_flags;
345 75 : a.out.rid = &rid;
346 :
347 75 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
348 : a.in.computer_name,
349 63 : a.in.secure_channel_type,
350 : &credentials1, &credentials2,
351 : &mach_password, &credentials3,
352 : negotiate_flags);
353 :
354 75 : torture_assert(tctx, creds != NULL, "memory allocation");
355 :
356 75 : torture_comment(tctx, "Testing ServerAuthenticate3\n");
357 :
358 75 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
359 : "ServerAuthenticate3 failed");
360 75 : torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed");
361 75 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
362 :
363 75 : torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
364 :
365 : /* Prove that requesting a challenge again won't break it */
366 75 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
367 : "ServerReqChallenge failed");
368 75 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
369 :
370 75 : *creds_out = creds;
371 75 : return true;
372 : }
373 :
374 18 : bool test_SetupCredentialsDowngrade(struct torture_context *tctx,
375 : struct dcerpc_pipe *p,
376 : struct cli_credentials *machine_credentials)
377 : {
378 3 : struct netr_ServerReqChallenge r;
379 3 : struct netr_ServerAuthenticate3 a;
380 3 : struct netr_Credential credentials1, credentials2, credentials3;
381 3 : struct netlogon_creds_CredentialState *creds;
382 3 : struct samr_Password mach_password;
383 3 : uint32_t rid;
384 3 : const char *machine_name;
385 3 : const char *plain_pass;
386 18 : struct dcerpc_binding_handle *b = p->binding_handle;
387 18 : uint32_t negotiate_flags = 0;
388 :
389 18 : machine_name = cli_credentials_get_workstation(machine_credentials);
390 18 : torture_assert(tctx, machine_name != NULL, "machine_name");
391 18 : plain_pass = cli_credentials_get_password(machine_credentials);
392 18 : torture_assert(tctx, plain_pass != NULL, "plain_pass");
393 :
394 18 : torture_comment(tctx, "Testing ServerReqChallenge\n");
395 :
396 18 : r.in.server_name = NULL;
397 18 : r.in.computer_name = machine_name;
398 18 : r.in.credentials = &credentials1;
399 18 : r.out.return_credentials = &credentials2;
400 :
401 18 : netlogon_creds_random_challenge(&credentials1);
402 :
403 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
404 : "ServerReqChallenge failed");
405 18 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
406 :
407 18 : E_md4hash(plain_pass, mach_password.hash);
408 :
409 18 : a.in.server_name = NULL;
410 18 : a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
411 18 : a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
412 18 : a.in.computer_name = machine_name;
413 18 : a.in.negotiate_flags = &negotiate_flags;
414 18 : a.in.credentials = &credentials3;
415 18 : a.out.return_credentials = &credentials3;
416 18 : a.out.negotiate_flags = &negotiate_flags;
417 18 : a.out.rid = &rid;
418 :
419 18 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
420 : a.in.computer_name,
421 15 : a.in.secure_channel_type,
422 : &credentials1, &credentials2,
423 : &mach_password, &credentials3,
424 : negotiate_flags);
425 :
426 18 : torture_assert(tctx, creds != NULL, "memory allocation");
427 :
428 18 : torture_comment(tctx, "Testing ServerAuthenticate3\n");
429 :
430 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
431 : "ServerAuthenticate3 failed");
432 18 : torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_DOWNGRADE_DETECTED, "ServerAuthenticate3 should have failed");
433 :
434 9 : negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
435 12 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
436 : a.in.computer_name,
437 9 : a.in.secure_channel_type,
438 : &credentials1, &credentials2,
439 : &mach_password, &credentials3,
440 : negotiate_flags);
441 :
442 9 : torture_assert(tctx, creds != NULL, "memory allocation");
443 :
444 9 : torture_comment(tctx, "Testing ServerAuthenticate3\n");
445 :
446 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
447 : "ServerAuthenticate3 failed");
448 9 : torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 should succeed");
449 :
450 9 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
451 :
452 9 : torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
453 :
454 : /* Prove that requesting a challenge again won't break it */
455 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
456 : "ServerReqChallenge failed");
457 9 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
458 :
459 6 : return true;
460 : }
461 :
462 361 : bool test_SetupCredentialsPipe(const struct dcerpc_pipe *p1,
463 : struct torture_context *tctx,
464 : struct cli_credentials *machine_credentials,
465 : struct netlogon_creds_CredentialState *creds,
466 : uint32_t additional_flags,
467 : struct dcerpc_pipe **_p2)
468 : {
469 24 : NTSTATUS status;
470 361 : struct dcerpc_binding *b2 = NULL;
471 361 : struct dcerpc_pipe *p2 = NULL;
472 :
473 361 : b2 = dcerpc_binding_dup(tctx, p1->binding);
474 361 : torture_assert(tctx, b2 != NULL, "dcerpc_binding_dup");
475 361 : dcerpc_binding_set_flags(b2,
476 : DCERPC_SCHANNEL | additional_flags,
477 : DCERPC_AUTH_OPTIONS);
478 :
479 361 : cli_credentials_set_netlogon_creds(machine_credentials, creds);
480 361 : status = dcerpc_pipe_connect_b(tctx, &p2, b2,
481 : &ndr_table_netlogon,
482 : machine_credentials,
483 : tctx->ev, tctx->lp_ctx);
484 361 : cli_credentials_set_netlogon_creds(machine_credentials, NULL);
485 361 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b schannel");
486 :
487 361 : *_p2 = p2;
488 361 : return true;
489 : }
490 :
491 11 : static bool test_ServerReqChallenge(
492 : struct torture_context *tctx,
493 : struct dcerpc_pipe *p,
494 : struct cli_credentials *credentials)
495 : {
496 1 : struct netr_ServerReqChallenge r;
497 1 : struct netr_Credential credentials1, credentials2, credentials3;
498 1 : const char *machine_name;
499 11 : struct dcerpc_binding_handle *b = p->binding_handle;
500 1 : struct netr_ServerAuthenticate2 a;
501 11 : uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
502 11 : uint32_t out_negotiate_flags = 0;
503 11 : const struct samr_Password *mach_password = NULL;
504 11 : enum netr_SchannelType sec_chan_type = 0;
505 11 : struct netlogon_creds_CredentialState *creds = NULL;
506 11 : const char *account_name = NULL;
507 :
508 11 : machine_name = cli_credentials_get_workstation(credentials);
509 11 : mach_password = cli_credentials_get_nt_hash(credentials, tctx);
510 11 : account_name = cli_credentials_get_username(credentials);
511 11 : sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
512 :
513 11 : torture_comment(tctx, "Testing ServerReqChallenge\n");
514 :
515 11 : r.in.server_name = NULL;
516 11 : r.in.computer_name = machine_name;
517 11 : r.in.credentials = &credentials1;
518 11 : r.out.return_credentials = &credentials2;
519 :
520 11 : netlogon_creds_random_challenge(&credentials1);
521 :
522 11 : torture_assert_ntstatus_ok(
523 : tctx,
524 : dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
525 : "ServerReqChallenge failed");
526 11 : torture_assert_ntstatus_ok(
527 : tctx,
528 : r.out.result,
529 : "ServerReqChallenge failed");
530 11 : a.in.server_name = NULL;
531 11 : a.in.account_name = account_name;
532 11 : a.in.secure_channel_type = sec_chan_type;
533 11 : a.in.computer_name = machine_name;
534 11 : a.in.negotiate_flags = &in_negotiate_flags;
535 11 : a.out.negotiate_flags = &out_negotiate_flags;
536 11 : a.in.credentials = &credentials3;
537 11 : a.out.return_credentials = &credentials3;
538 :
539 11 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
540 : a.in.computer_name,
541 10 : a.in.secure_channel_type,
542 : &credentials1, &credentials2,
543 : mach_password, &credentials3,
544 : in_negotiate_flags);
545 :
546 11 : torture_assert(tctx, creds != NULL, "memory allocation");
547 :
548 11 : torture_comment(tctx, "Testing ServerAuthenticate2\n");
549 :
550 11 : torture_assert_ntstatus_ok(
551 : tctx,
552 : dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
553 : "ServerAuthenticate2 failed");
554 11 : torture_assert_ntstatus_equal(
555 : tctx,
556 : a.out.result,
557 : NT_STATUS_OK,
558 : "ServerAuthenticate2 unexpected");
559 :
560 10 : return true;
561 : }
562 :
563 11 : static bool test_ServerReqChallenge_zero_challenge(
564 : struct torture_context *tctx,
565 : struct dcerpc_pipe *p,
566 : struct cli_credentials *credentials)
567 : {
568 1 : struct netr_ServerReqChallenge r;
569 1 : struct netr_Credential credentials1, credentials2, credentials3;
570 1 : const char *machine_name;
571 11 : struct dcerpc_binding_handle *b = p->binding_handle;
572 1 : struct netr_ServerAuthenticate2 a;
573 11 : uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
574 11 : uint32_t out_negotiate_flags = 0;
575 11 : const struct samr_Password *mach_password = NULL;
576 11 : enum netr_SchannelType sec_chan_type = 0;
577 11 : struct netlogon_creds_CredentialState *creds = NULL;
578 11 : const char *account_name = NULL;
579 :
580 11 : machine_name = cli_credentials_get_workstation(credentials);
581 11 : mach_password = cli_credentials_get_nt_hash(credentials, tctx);
582 11 : account_name = cli_credentials_get_username(credentials);
583 11 : sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
584 :
585 11 : torture_comment(tctx, "Testing ServerReqChallenge\n");
586 :
587 11 : r.in.server_name = NULL;
588 11 : r.in.computer_name = machine_name;
589 11 : r.in.credentials = &credentials1;
590 11 : r.out.return_credentials = &credentials2;
591 :
592 : /*
593 : * Set the client challenge to zero, this should fail
594 : * CVE-2020-1472(ZeroLogon)
595 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
596 : */
597 11 : ZERO_STRUCT(credentials1);
598 :
599 11 : torture_assert_ntstatus_ok(
600 : tctx,
601 : dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
602 : "ServerReqChallenge failed");
603 11 : torture_assert_ntstatus_ok(
604 : tctx,
605 : r.out.result,
606 : "ServerReqChallenge failed");
607 11 : a.in.server_name = NULL;
608 11 : a.in.account_name = account_name;
609 11 : a.in.secure_channel_type = sec_chan_type;
610 11 : a.in.computer_name = machine_name;
611 11 : a.in.negotiate_flags = &in_negotiate_flags;
612 11 : a.out.negotiate_flags = &out_negotiate_flags;
613 11 : a.in.credentials = &credentials3;
614 11 : a.out.return_credentials = &credentials3;
615 :
616 11 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
617 : a.in.computer_name,
618 10 : a.in.secure_channel_type,
619 : &credentials1, &credentials2,
620 : mach_password, &credentials3,
621 : in_negotiate_flags);
622 :
623 11 : torture_assert(tctx, creds != NULL, "memory allocation");
624 :
625 11 : torture_comment(tctx, "Testing ServerAuthenticate2\n");
626 :
627 11 : torture_assert_ntstatus_ok(
628 : tctx,
629 : dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
630 : "ServerAuthenticate2 failed");
631 11 : torture_assert_ntstatus_equal(
632 : tctx,
633 : a.out.result,
634 : NT_STATUS_ACCESS_DENIED,
635 : "ServerAuthenticate2 unexpected");
636 :
637 10 : return true;
638 : }
639 :
640 11 : static bool test_ServerReqChallenge_5_repeats(
641 : struct torture_context *tctx,
642 : struct dcerpc_pipe *p,
643 : struct cli_credentials *credentials)
644 : {
645 1 : struct netr_ServerReqChallenge r;
646 1 : struct netr_Credential credentials1, credentials2, credentials3;
647 1 : const char *machine_name;
648 11 : struct dcerpc_binding_handle *b = p->binding_handle;
649 1 : struct netr_ServerAuthenticate2 a;
650 11 : uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
651 11 : uint32_t out_negotiate_flags = 0;
652 11 : const struct samr_Password *mach_password = NULL;
653 11 : enum netr_SchannelType sec_chan_type = 0;
654 11 : struct netlogon_creds_CredentialState *creds = NULL;
655 11 : const char *account_name = NULL;
656 :
657 11 : machine_name = cli_credentials_get_workstation(credentials);
658 11 : mach_password = cli_credentials_get_nt_hash(credentials, tctx);
659 11 : account_name = cli_credentials_get_username(credentials);
660 11 : sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
661 :
662 11 : torture_comment(tctx, "Testing ServerReqChallenge\n");
663 :
664 11 : r.in.server_name = NULL;
665 11 : r.in.computer_name = machine_name;
666 11 : r.in.credentials = &credentials1;
667 11 : r.out.return_credentials = &credentials2;
668 :
669 : /*
670 : * Set the first 5 bytes of the client challenge to the same value,
671 : * this should fail CVE-2020-1472(ZeroLogon)
672 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
673 : */
674 11 : credentials1.data[0] = 'A';
675 11 : credentials1.data[1] = 'A';
676 11 : credentials1.data[2] = 'A';
677 11 : credentials1.data[3] = 'A';
678 11 : credentials1.data[4] = 'A';
679 11 : credentials1.data[5] = 'B';
680 11 : credentials1.data[6] = 'C';
681 11 : credentials1.data[7] = 'D';
682 :
683 11 : torture_assert_ntstatus_ok(
684 : tctx,
685 : dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
686 : "ServerReqChallenge failed");
687 11 : torture_assert_ntstatus_ok(
688 : tctx,
689 : r.out.result,
690 : "ServerReqChallenge failed");
691 11 : a.in.server_name = NULL;
692 11 : a.in.account_name = account_name;
693 11 : a.in.secure_channel_type = sec_chan_type;
694 11 : a.in.computer_name = machine_name;
695 11 : a.in.negotiate_flags = &in_negotiate_flags;
696 11 : a.out.negotiate_flags = &out_negotiate_flags;
697 11 : a.in.credentials = &credentials3;
698 11 : a.out.return_credentials = &credentials3;
699 :
700 11 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
701 : a.in.computer_name,
702 10 : a.in.secure_channel_type,
703 : &credentials1, &credentials2,
704 : mach_password, &credentials3,
705 : in_negotiate_flags);
706 :
707 11 : torture_assert(tctx, creds != NULL, "memory allocation");
708 :
709 11 : torture_comment(tctx, "Testing ServerAuthenticate2\n");
710 :
711 11 : torture_assert_ntstatus_ok(
712 : tctx,
713 : dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
714 : "ServerAuthenticate2 failed");
715 11 : torture_assert_ntstatus_equal(
716 : tctx,
717 : a.out.result,
718 : NT_STATUS_ACCESS_DENIED,
719 : "ServerAuthenticate2 unexpected");
720 :
721 10 : return true;
722 : }
723 :
724 11 : static bool test_ServerReqChallenge_4_repeats(
725 : struct torture_context *tctx,
726 : struct dcerpc_pipe *p,
727 : struct cli_credentials *credentials)
728 : {
729 1 : struct netr_ServerReqChallenge r;
730 1 : struct netr_Credential credentials1, credentials2, credentials3;
731 1 : const char *machine_name;
732 11 : struct dcerpc_binding_handle *b = p->binding_handle;
733 1 : struct netr_ServerAuthenticate2 a;
734 11 : uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
735 11 : uint32_t out_negotiate_flags = 0;
736 11 : const struct samr_Password *mach_password = NULL;
737 11 : enum netr_SchannelType sec_chan_type = 0;
738 11 : struct netlogon_creds_CredentialState *creds = NULL;
739 11 : const char *account_name = NULL;
740 :
741 11 : machine_name = cli_credentials_get_workstation(credentials);
742 11 : mach_password = cli_credentials_get_nt_hash(credentials, tctx);
743 11 : account_name = cli_credentials_get_username(credentials);
744 11 : sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
745 :
746 11 : torture_comment(tctx, "Testing ServerReqChallenge\n");
747 :
748 11 : r.in.server_name = NULL;
749 11 : r.in.computer_name = machine_name;
750 11 : r.in.credentials = &credentials1;
751 11 : r.out.return_credentials = &credentials2;
752 :
753 : /*
754 : * Set the first 4 bytes of the client challenge to the same
755 : * value, this should pass as 5 bytes identical are needed to
756 : * fail for CVE-2020-1472(ZeroLogon)
757 : *
758 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
759 : */
760 11 : credentials1.data[0] = 'A';
761 11 : credentials1.data[1] = 'A';
762 11 : credentials1.data[2] = 'A';
763 11 : credentials1.data[3] = 'A';
764 11 : credentials1.data[4] = 'B';
765 11 : credentials1.data[5] = 'C';
766 11 : credentials1.data[6] = 'D';
767 11 : credentials1.data[7] = 'E';
768 :
769 11 : torture_assert_ntstatus_ok(
770 : tctx,
771 : dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
772 : "ServerReqChallenge failed");
773 11 : torture_assert_ntstatus_ok(
774 : tctx,
775 : r.out.result,
776 : "ServerReqChallenge failed");
777 11 : a.in.server_name = NULL;
778 11 : a.in.account_name = account_name;
779 11 : a.in.secure_channel_type = sec_chan_type;
780 11 : a.in.computer_name = machine_name;
781 11 : a.in.negotiate_flags = &in_negotiate_flags;
782 11 : a.out.negotiate_flags = &out_negotiate_flags;
783 11 : a.in.credentials = &credentials3;
784 11 : a.out.return_credentials = &credentials3;
785 :
786 11 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
787 : a.in.computer_name,
788 10 : a.in.secure_channel_type,
789 : &credentials1, &credentials2,
790 : mach_password, &credentials3,
791 : in_negotiate_flags);
792 :
793 11 : torture_assert(tctx, creds != NULL, "memory allocation");
794 :
795 11 : torture_comment(tctx, "Testing ServerAuthenticate2\n");
796 :
797 11 : torture_assert_ntstatus_ok(
798 : tctx,
799 : dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
800 : "ServerAuthenticate2 failed");
801 11 : torture_assert_ntstatus_equal(
802 : tctx,
803 : a.out.result,
804 : NT_STATUS_OK,
805 : "ServerAuthenticate2 unexpected");
806 :
807 10 : return true;
808 : }
809 :
810 : /*
811 : * Establish a NetLogon session, using a session key that encrypts the
812 : * target character to zero
813 : */
814 33 : static bool test_ServerAuthenticate2_encrypts_to_zero(
815 : struct torture_context *tctx,
816 : struct dcerpc_pipe *p,
817 : struct cli_credentials *machine_credentials,
818 : const char target,
819 : struct netlogon_creds_CredentialState **creds_out)
820 : {
821 3 : const char *computer_name =
822 33 : cli_credentials_get_workstation(machine_credentials);
823 3 : struct netr_ServerReqChallenge r;
824 3 : struct netr_ServerAuthenticate2 a;
825 3 : struct netr_Credential credentials1, credentials2, credentials3;
826 33 : struct netlogon_creds_CredentialState *creds = NULL;
827 3 : const struct samr_Password *mach_password;
828 33 : struct dcerpc_binding_handle *b = p->binding_handle;
829 33 : const char *account_name = cli_credentials_get_username(
830 : machine_credentials);
831 33 : uint32_t flags =
832 : NETLOGON_NEG_AUTH2_ADS_FLAGS |
833 : NETLOGON_NEG_SUPPORTS_AES;
834 3 : enum netr_SchannelType sec_chan_type =
835 33 : cli_credentials_get_secure_channel_type(machine_credentials);
836 : /*
837 : * Limit the number of attempts to generate a suitable session key.
838 : */
839 33 : const unsigned MAX_ITER = 4096;
840 33 : unsigned i = 0;
841 :
842 33 : mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
843 :
844 33 : r.in.server_name = NULL;
845 33 : r.in.computer_name = computer_name;
846 33 : r.in.credentials = &credentials1;
847 33 : r.out.return_credentials = &credentials2;
848 :
849 33 : netlogon_creds_random_challenge(&credentials1);
850 33 : credentials1.data[0] = target;
851 33 : i = 0;
852 33 : torture_comment(tctx, "Generating candidate session keys\n");
853 528 : do {
854 9162 : TALLOC_FREE(creds);
855 9162 : i++;
856 :
857 9162 : torture_assert_ntstatus_ok(
858 : tctx,
859 : dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
860 : "ServerReqChallenge failed");
861 9162 : torture_assert_ntstatus_ok(
862 : tctx,
863 : r.out.result,
864 : "ServerReqChallenge failed");
865 :
866 9162 : a.in.server_name = NULL;
867 9162 : a.in.account_name = account_name;
868 9162 : a.in.secure_channel_type = sec_chan_type;
869 9162 : a.in.computer_name = computer_name;
870 9162 : a.in.negotiate_flags = &flags;
871 9162 : a.out.negotiate_flags = &flags;
872 9162 : a.in.credentials = &credentials3;
873 9162 : a.out.return_credentials = &credentials3;
874 :
875 9162 : creds = netlogon_creds_client_init(
876 : tctx,
877 : a.in.account_name,
878 : a.in.computer_name,
879 8634 : a.in.secure_channel_type,
880 : &credentials1,
881 : &credentials2,
882 : mach_password,
883 : &credentials3,
884 : flags);
885 :
886 9162 : torture_assert(tctx, creds != NULL, "memory allocation");
887 9162 : } while (credentials3.data[0] != 0 && i < MAX_ITER);
888 :
889 33 : if (i >= MAX_ITER) {
890 0 : torture_comment(
891 : tctx,
892 : "Unable to obtain a suitable session key, "
893 : "after [%u] attempts\n",
894 : i);
895 0 : torture_fail(tctx, "Unable to obtain suitable session key");
896 : }
897 :
898 33 : torture_assert_ntstatus_ok(
899 : tctx,
900 : dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
901 : "ServerAuthenticate2 failed");
902 33 : torture_assert_ntstatus_equal(
903 : tctx,
904 : a.out.result,
905 : NT_STATUS_OK,
906 : "ServerAuthenticate2 unexpected result code");
907 :
908 33 : *creds_out = creds;
909 33 : return true;
910 : }
911 :
912 : /*
913 : try a change password for our machine account
914 : */
915 21 : static bool test_SetPassword(struct torture_context *tctx,
916 : struct dcerpc_pipe *p,
917 : struct cli_credentials *machine_credentials)
918 : {
919 3 : struct netr_ServerPasswordSet r;
920 3 : const char *password;
921 3 : struct netlogon_creds_CredentialState *creds;
922 3 : struct netr_Authenticator credential, return_authenticator;
923 3 : struct samr_Password new_password;
924 21 : struct dcerpc_binding_handle *b = p->binding_handle;
925 :
926 21 : if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
927 0 : return false;
928 : }
929 :
930 21 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
931 21 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
932 21 : r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
933 21 : r.in.computer_name = TEST_MACHINE_NAME;
934 21 : r.in.credential = &credential;
935 21 : r.in.new_password = &new_password;
936 21 : r.out.return_authenticator = &return_authenticator;
937 :
938 21 : password = generate_random_password(tctx, 8, 255);
939 21 : E_md4hash(password, new_password.hash);
940 :
941 21 : netlogon_creds_des_encrypt(creds, &new_password);
942 :
943 21 : torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
944 21 : torture_comment(tctx, "Changing machine account password to '%s'\n",
945 : password);
946 :
947 21 : netlogon_creds_client_authenticator(creds, &credential);
948 :
949 21 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
950 : "ServerPasswordSet failed");
951 21 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
952 :
953 21 : if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
954 0 : torture_comment(tctx, "Credential chaining failed\n");
955 : }
956 :
957 : /* by changing the machine password twice we test the
958 : credentials chaining fully, and we verify that the server
959 : allows the password to be set to the same value twice in a
960 : row (match win2k3) */
961 21 : torture_comment(tctx,
962 : "Testing a second ServerPasswordSet on machine account\n");
963 21 : torture_comment(tctx,
964 : "Changing machine account password to '%s' (same as previous run)\n", password);
965 :
966 21 : netlogon_creds_client_authenticator(creds, &credential);
967 :
968 21 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
969 : "ServerPasswordSet (2) failed");
970 21 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
971 :
972 21 : if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
973 0 : torture_comment(tctx, "Credential chaining failed\n");
974 : }
975 :
976 21 : cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
977 :
978 21 : torture_assert(tctx,
979 : test_SetupCredentials(p, tctx, machine_credentials, &creds),
980 : "ServerPasswordSet failed to actually change the password");
981 :
982 18 : return true;
983 : }
984 :
985 : /*
986 : try a change password for our machine account
987 : */
988 0 : static bool test_SetPassword_flags(struct torture_context *tctx,
989 : struct dcerpc_pipe *p1,
990 : struct cli_credentials *machine_credentials,
991 : uint32_t negotiate_flags)
992 : {
993 0 : struct netr_ServerPasswordSet r;
994 0 : const char *password;
995 0 : struct netlogon_creds_CredentialState *creds;
996 0 : struct netr_Authenticator credential, return_authenticator;
997 0 : struct samr_Password new_password;
998 0 : struct dcerpc_pipe *p = NULL;
999 0 : struct dcerpc_binding_handle *b = NULL;
1000 :
1001 0 : if (!test_SetupCredentials2(p1, tctx, negotiate_flags,
1002 : machine_credentials,
1003 : cli_credentials_get_secure_channel_type(machine_credentials),
1004 : &creds)) {
1005 0 : return false;
1006 : }
1007 0 : if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
1008 : DCERPC_SIGN | DCERPC_SEAL, &p)) {
1009 0 : return false;
1010 : }
1011 0 : b = p->binding_handle;
1012 :
1013 0 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1014 0 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1015 0 : r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1016 0 : r.in.computer_name = TEST_MACHINE_NAME;
1017 0 : r.in.credential = &credential;
1018 0 : r.in.new_password = &new_password;
1019 0 : r.out.return_authenticator = &return_authenticator;
1020 :
1021 0 : password = generate_random_password(tctx, 8, 255);
1022 0 : E_md4hash(password, new_password.hash);
1023 :
1024 0 : netlogon_creds_des_encrypt(creds, &new_password);
1025 :
1026 0 : torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
1027 0 : torture_comment(tctx, "Changing machine account password to '%s'\n",
1028 : password);
1029 :
1030 0 : netlogon_creds_client_authenticator(creds, &credential);
1031 :
1032 0 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
1033 : "ServerPasswordSet failed");
1034 0 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
1035 :
1036 0 : if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1037 0 : torture_comment(tctx, "Credential chaining failed\n");
1038 : }
1039 :
1040 : /* by changing the machine password twice we test the
1041 : credentials chaining fully, and we verify that the server
1042 : allows the password to be set to the same value twice in a
1043 : row (match win2k3) */
1044 0 : torture_comment(tctx,
1045 : "Testing a second ServerPasswordSet on machine account\n");
1046 0 : torture_comment(tctx,
1047 : "Changing machine account password to '%s' (same as previous run)\n", password);
1048 :
1049 0 : netlogon_creds_client_authenticator(creds, &credential);
1050 :
1051 0 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
1052 : "ServerPasswordSet (2) failed");
1053 0 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
1054 :
1055 0 : if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1056 0 : torture_comment(tctx, "Credential chaining failed\n");
1057 : }
1058 :
1059 0 : cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
1060 :
1061 0 : torture_assert(tctx,
1062 : test_SetupCredentials(p, tctx, machine_credentials, &creds),
1063 : "ServerPasswordSet failed to actually change the password");
1064 :
1065 0 : return true;
1066 : }
1067 :
1068 :
1069 : /*
1070 : generate a random password for password change tests
1071 : */
1072 53 : static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
1073 : {
1074 7 : int i;
1075 53 : DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
1076 53 : generate_random_buffer(password.data, password.length);
1077 :
1078 8252 : for (i=0; i < len; i++) {
1079 8192 : if (((uint16_t *)password.data)[i] == 0) {
1080 0 : ((uint16_t *)password.data)[i] = 1;
1081 : }
1082 : }
1083 :
1084 53 : return password;
1085 : }
1086 :
1087 : /*
1088 : try a change password for our machine account
1089 : */
1090 42 : static bool test_SetPassword2_with_flags(struct torture_context *tctx,
1091 : struct dcerpc_pipe *p1,
1092 : struct cli_credentials *machine_credentials,
1093 : uint32_t flags)
1094 : {
1095 6 : struct netr_ServerPasswordSet2 r;
1096 6 : const char *password;
1097 6 : DATA_BLOB new_random_pass;
1098 6 : struct netlogon_creds_CredentialState *creds;
1099 6 : struct samr_CryptPassword password_buf;
1100 6 : struct samr_Password nt_hash;
1101 6 : struct netr_Authenticator credential, return_authenticator;
1102 6 : struct netr_CryptPassword new_password;
1103 42 : struct dcerpc_pipe *p = NULL;
1104 42 : struct dcerpc_binding_handle *b = NULL;
1105 :
1106 42 : if (!test_SetupCredentials2(p1, tctx, flags, machine_credentials,
1107 : cli_credentials_get_secure_channel_type(machine_credentials),
1108 : &creds)) {
1109 0 : return false;
1110 : }
1111 42 : if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
1112 : DCERPC_SIGN | DCERPC_SEAL, &p)) {
1113 0 : return false;
1114 : }
1115 42 : b = p->binding_handle;
1116 :
1117 42 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1118 42 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1119 42 : r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1120 42 : r.in.computer_name = TEST_MACHINE_NAME;
1121 42 : r.in.credential = &credential;
1122 42 : r.in.new_password = &new_password;
1123 42 : r.out.return_authenticator = &return_authenticator;
1124 :
1125 42 : password = generate_random_password(tctx, 8, 255);
1126 42 : encode_pw_buffer(password_buf.data, password, STR_UNICODE);
1127 42 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1128 21 : netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1129 : } else {
1130 21 : netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1131 : }
1132 :
1133 42 : memcpy(new_password.data, password_buf.data, 512);
1134 42 : new_password.length = IVAL(password_buf.data, 512);
1135 :
1136 42 : torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
1137 42 : torture_comment(tctx, "Changing machine account password to '%s'\n", password);
1138 :
1139 42 : netlogon_creds_client_authenticator(creds, &credential);
1140 :
1141 42 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1142 : "ServerPasswordSet2 failed");
1143 42 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
1144 :
1145 42 : if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1146 0 : torture_comment(tctx, "Credential chaining failed\n");
1147 : }
1148 :
1149 42 : cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
1150 :
1151 : /*
1152 : * As a consequence of CVE-2020-1472(ZeroLogon)
1153 : * Samba explicitly disallows the setting of an empty machine account
1154 : * password.
1155 : *
1156 : * Note that this may fail against Windows, and leave a machine account
1157 : * with an empty password.
1158 : */
1159 42 : password = "";
1160 42 : encode_pw_buffer(password_buf.data, password, STR_UNICODE);
1161 42 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1162 21 : netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1163 : } else {
1164 21 : netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1165 : }
1166 42 : memcpy(new_password.data, password_buf.data, 512);
1167 42 : new_password.length = IVAL(password_buf.data, 512);
1168 :
1169 42 : torture_comment(tctx,
1170 : "Testing ServerPasswordSet2 on machine account\n");
1171 42 : torture_comment(tctx,
1172 : "Changing machine account password to '%s'\n", password);
1173 :
1174 42 : netlogon_creds_client_authenticator(creds, &credential);
1175 :
1176 42 : torture_assert_ntstatus_ok(
1177 : tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1178 : "ServerPasswordSet2 failed");
1179 42 : torture_assert_ntstatus_equal(
1180 : tctx,
1181 : r.out.result,
1182 : NT_STATUS_WRONG_PASSWORD,
1183 : "ServerPasswordSet2 did not return NT_STATUS_WRONG_PASSWORD");
1184 :
1185 : /* now try a random password */
1186 42 : password = generate_random_password(tctx, 8, 255);
1187 42 : encode_pw_buffer(password_buf.data, password, STR_UNICODE);
1188 42 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1189 21 : netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1190 : } else {
1191 21 : netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1192 : }
1193 42 : memcpy(new_password.data, password_buf.data, 512);
1194 42 : new_password.length = IVAL(password_buf.data, 512);
1195 :
1196 42 : torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
1197 42 : torture_comment(tctx, "Changing machine account password to '%s'\n", password);
1198 :
1199 42 : netlogon_creds_client_authenticator(creds, &credential);
1200 :
1201 42 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1202 : "ServerPasswordSet2 (2) failed");
1203 42 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 (2) failed");
1204 :
1205 42 : if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1206 0 : torture_comment(tctx, "Credential chaining failed\n");
1207 : }
1208 :
1209 : /* by changing the machine password twice we test the
1210 : credentials chaining fully, and we verify that the server
1211 : allows the password to be set to the same value twice in a
1212 : row (match win2k3) */
1213 42 : torture_comment(tctx,
1214 : "Testing a second ServerPasswordSet2 on machine account\n");
1215 42 : torture_comment(tctx,
1216 : "Changing machine account password to '%s' (same as previous run)\n", password);
1217 :
1218 42 : netlogon_creds_client_authenticator(creds, &credential);
1219 :
1220 42 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1221 : "ServerPasswordSet (3) failed");
1222 42 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
1223 :
1224 42 : if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1225 0 : torture_comment(tctx, "Credential chaining failed\n");
1226 : }
1227 :
1228 42 : cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
1229 :
1230 42 : torture_assert (tctx,
1231 : test_SetupCredentials(p, tctx, machine_credentials, &creds),
1232 : "ServerPasswordSet failed to actually change the password");
1233 :
1234 42 : new_random_pass = netlogon_very_rand_pass(tctx, 128);
1235 :
1236 : /* now try a random stream of bytes for a password */
1237 42 : set_pw_in_buffer(password_buf.data, &new_random_pass);
1238 :
1239 42 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1240 24 : netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1241 : } else {
1242 18 : netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1243 : }
1244 :
1245 42 : memcpy(new_password.data, password_buf.data, 512);
1246 42 : new_password.length = IVAL(password_buf.data, 512);
1247 :
1248 42 : torture_comment(tctx,
1249 : "Testing a third ServerPasswordSet2 on machine account, with a completely random password\n");
1250 :
1251 42 : netlogon_creds_client_authenticator(creds, &credential);
1252 :
1253 42 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1254 : "ServerPasswordSet (3) failed");
1255 42 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
1256 :
1257 42 : if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1258 0 : torture_comment(tctx, "Credential chaining failed\n");
1259 : }
1260 :
1261 42 : mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
1262 :
1263 42 : cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
1264 42 : cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
1265 :
1266 42 : torture_assert (tctx,
1267 : test_SetupCredentials(p, tctx, machine_credentials, &creds),
1268 : "ServerPasswordSet failed to actually change the password");
1269 :
1270 36 : return true;
1271 : }
1272 :
1273 : /*
1274 : try to change the password of our machine account using a buffer of all zeros,
1275 : and a session key that encrypts that to all zeros.
1276 :
1277 : Note: The test does use sign and seal, it's purpose is to exercise
1278 : the detection code in dcesrv_netr_ServerPasswordSet2
1279 : */
1280 11 : static bool test_SetPassword2_encrypted_to_all_zeros(
1281 : struct torture_context *tctx,
1282 : struct dcerpc_pipe *p1,
1283 : struct cli_credentials *machine_credentials)
1284 : {
1285 1 : struct netr_ServerPasswordSet2 r;
1286 1 : struct netlogon_creds_CredentialState *creds;
1287 1 : struct samr_CryptPassword password_buf;
1288 1 : struct netr_Authenticator credential, return_authenticator;
1289 1 : struct netr_CryptPassword new_password;
1290 11 : struct dcerpc_pipe *p = NULL;
1291 11 : struct dcerpc_binding_handle *b = NULL;
1292 :
1293 11 : if (!test_ServerAuthenticate2_encrypts_to_zero(
1294 : tctx,
1295 : p1,
1296 : machine_credentials,
1297 : '\0',
1298 : &creds)) {
1299 :
1300 0 : return false;
1301 : }
1302 :
1303 11 : if (!test_SetupCredentialsPipe(
1304 : p1,
1305 : tctx,
1306 : machine_credentials,
1307 : creds,
1308 : DCERPC_SIGN | DCERPC_SEAL,
1309 : &p))
1310 : {
1311 0 : return false;
1312 : }
1313 11 : b = p->binding_handle;
1314 :
1315 11 : r.in.server_name = talloc_asprintf(
1316 : tctx,
1317 : "\\\\%s", dcerpc_server_name(p));
1318 11 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1319 12 : r.in.secure_channel_type =
1320 11 : cli_credentials_get_secure_channel_type(machine_credentials);
1321 11 : r.in.computer_name = TEST_MACHINE_NAME;
1322 11 : r.in.credential = &credential;
1323 11 : r.in.new_password = &new_password;
1324 11 : r.out.return_authenticator = &return_authenticator;
1325 :
1326 11 : ZERO_STRUCT(password_buf);
1327 :
1328 11 : if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
1329 0 : torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES not set");
1330 : }
1331 11 : netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1332 11 : if(!all_zero(password_buf.data, 516)) {
1333 0 : torture_fail(tctx, "Password did not encrypt to all zeros\n");
1334 : }
1335 :
1336 11 : memcpy(new_password.data, password_buf.data, 512);
1337 11 : new_password.length = IVAL(password_buf.data, 512);
1338 11 : torture_assert_int_equal(
1339 : tctx,
1340 : new_password.length,
1341 : 0,
1342 : "Length should have encrypted to 0");
1343 :
1344 11 : netlogon_creds_client_authenticator(creds, &credential);
1345 :
1346 11 : torture_assert_ntstatus_ok(
1347 : tctx,
1348 : dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1349 : "ServerPasswordSet2 zero length check failed");
1350 11 : torture_assert_ntstatus_equal(
1351 : tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
1352 :
1353 10 : return true;
1354 : }
1355 :
1356 : /*
1357 : * Choose a session key that encrypts a password of all zeros to all zeros.
1358 : * Then try to set the password, using a zeroed buffer, with a non zero
1359 : * length.
1360 : *
1361 : * This exercises the password self encryption check.
1362 : *
1363 : * Note: The test does use sign and seal, it's purpose is to exercise
1364 : * the detection code in dcesrv_netr_ServerPasswordSet2
1365 : */
1366 11 : static bool test_SetPassword2_password_encrypts_to_zero(
1367 : struct torture_context *tctx,
1368 : struct dcerpc_pipe *p1,
1369 : struct cli_credentials *machine_credentials)
1370 : {
1371 1 : struct netr_ServerPasswordSet2 r;
1372 1 : struct netlogon_creds_CredentialState *creds;
1373 1 : struct samr_CryptPassword password_buf;
1374 1 : struct netr_Authenticator credential, return_authenticator;
1375 1 : struct netr_CryptPassword new_password;
1376 11 : struct dcerpc_pipe *p = NULL;
1377 11 : struct dcerpc_binding_handle *b = NULL;
1378 :
1379 11 : if (!test_ServerAuthenticate2_encrypts_to_zero(
1380 : tctx,
1381 : p1,
1382 : machine_credentials,
1383 : 0x00,
1384 : &creds)) {
1385 :
1386 0 : return false;
1387 : }
1388 :
1389 11 : if (!test_SetupCredentialsPipe(
1390 : p1,
1391 : tctx,
1392 : machine_credentials,
1393 : creds,
1394 : DCERPC_SIGN | DCERPC_SEAL,
1395 : &p))
1396 : {
1397 0 : return false;
1398 : }
1399 11 : b = p->binding_handle;
1400 :
1401 11 : r.in.server_name = talloc_asprintf(
1402 : tctx,
1403 : "\\\\%s", dcerpc_server_name(p));
1404 11 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1405 12 : r.in.secure_channel_type =
1406 11 : cli_credentials_get_secure_channel_type(machine_credentials);
1407 11 : r.in.computer_name = TEST_MACHINE_NAME;
1408 11 : r.in.credential = &credential;
1409 11 : r.in.new_password = &new_password;
1410 11 : r.out.return_authenticator = &return_authenticator;
1411 :
1412 11 : ZERO_STRUCT(password_buf);
1413 11 : SIVAL(password_buf.data, 512, 512);
1414 :
1415 11 : if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
1416 0 : torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES not set");
1417 : }
1418 11 : netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1419 :
1420 11 : memcpy(new_password.data, password_buf.data, 512);
1421 11 : new_password.length = IVAL(password_buf.data, 512);
1422 :
1423 11 : netlogon_creds_client_authenticator(creds, &credential);
1424 :
1425 11 : torture_assert_ntstatus_ok(
1426 : tctx,
1427 : dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1428 : "ServerPasswordSet2 password encrypts to zero check failed");
1429 11 : torture_assert_ntstatus_equal(
1430 : tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
1431 :
1432 10 : return true;
1433 : }
1434 :
1435 : /*
1436 : * Check that an all zero confounder, that encrypts to all zeros is
1437 : * rejected.
1438 : *
1439 : * Note: The test does use sign and seal, it's purpose is to exercise
1440 : * the detection code in dcesrv_netr_ServerPasswordSet2
1441 : */
1442 11 : static bool test_SetPassword2_confounder(
1443 : struct torture_context *tctx,
1444 : struct dcerpc_pipe *p1,
1445 : struct cli_credentials *machine_credentials)
1446 : {
1447 1 : struct netr_ServerPasswordSet2 r;
1448 1 : struct netlogon_creds_CredentialState *creds;
1449 1 : struct samr_CryptPassword password_buf;
1450 1 : struct netr_Authenticator credential, return_authenticator;
1451 1 : struct netr_CryptPassword new_password;
1452 11 : struct dcerpc_pipe *p = NULL;
1453 11 : struct dcerpc_binding_handle *b = NULL;
1454 :
1455 11 : if (!test_ServerAuthenticate2_encrypts_to_zero(
1456 : tctx,
1457 : p1,
1458 : machine_credentials,
1459 : '\0',
1460 : &creds)) {
1461 :
1462 0 : return false;
1463 : }
1464 :
1465 11 : if (!test_SetupCredentialsPipe(
1466 : p1,
1467 : tctx,
1468 : machine_credentials,
1469 : creds,
1470 : DCERPC_SIGN | DCERPC_SEAL,
1471 : &p))
1472 : {
1473 0 : return false;
1474 : }
1475 11 : b = p->binding_handle;
1476 :
1477 11 : r.in.server_name = talloc_asprintf(
1478 : tctx,
1479 : "\\\\%s", dcerpc_server_name(p));
1480 11 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1481 12 : r.in.secure_channel_type =
1482 11 : cli_credentials_get_secure_channel_type(machine_credentials);
1483 11 : r.in.computer_name = TEST_MACHINE_NAME;
1484 11 : r.in.credential = &credential;
1485 11 : r.in.new_password = &new_password;
1486 11 : r.out.return_authenticator = &return_authenticator;
1487 :
1488 11 : ZERO_STRUCT(password_buf);
1489 11 : password_buf.data[511] = 'A';
1490 11 : SIVAL(password_buf.data, 512, 2);
1491 :
1492 11 : if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
1493 0 : torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES not set");
1494 : }
1495 11 : netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1496 :
1497 11 : memcpy(new_password.data, password_buf.data, 512);
1498 11 : new_password.length = IVAL(password_buf.data, 512);
1499 :
1500 11 : netlogon_creds_client_authenticator(creds, &credential);
1501 :
1502 11 : torture_assert_ntstatus_ok(
1503 : tctx,
1504 : dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1505 : "ServerPasswordSet2 confounder check failed");
1506 11 : torture_assert_ntstatus_equal(
1507 : tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
1508 :
1509 10 : return true;
1510 : }
1511 :
1512 : /*
1513 : * try a change password for our machine account, using an all zero
1514 : * request. This should fail on the zero length check.
1515 : *
1516 : * Note: This test uses ARC4 encryption to exercise the desired check.
1517 : */
1518 11 : static bool test_SetPassword2_all_zeros(
1519 : struct torture_context *tctx,
1520 : struct dcerpc_pipe *p1,
1521 : struct cli_credentials *machine_credentials)
1522 : {
1523 1 : struct netr_ServerPasswordSet2 r;
1524 1 : struct netlogon_creds_CredentialState *creds;
1525 1 : struct samr_CryptPassword password_buf;
1526 1 : struct netr_Authenticator credential, return_authenticator;
1527 1 : struct netr_CryptPassword new_password;
1528 11 : struct dcerpc_pipe *p = NULL;
1529 11 : struct dcerpc_binding_handle *b = NULL;
1530 11 : uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; /* no AES desired here */
1531 :
1532 11 : if (!test_SetupCredentials2(
1533 : p1,
1534 : tctx,
1535 : flags,
1536 : machine_credentials,
1537 : cli_credentials_get_secure_channel_type(machine_credentials),
1538 : &creds))
1539 : {
1540 0 : return false;
1541 : }
1542 11 : if (!test_SetupCredentialsPipe(
1543 : p1,
1544 : tctx,
1545 : machine_credentials,
1546 : creds,
1547 : DCERPC_SIGN | DCERPC_SEAL,
1548 : &p))
1549 : {
1550 0 : return false;
1551 : }
1552 11 : b = p->binding_handle;
1553 :
1554 11 : r.in.server_name = talloc_asprintf(
1555 : tctx,
1556 : "\\\\%s", dcerpc_server_name(p));
1557 11 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1558 12 : r.in.secure_channel_type =
1559 11 : cli_credentials_get_secure_channel_type(machine_credentials);
1560 11 : r.in.computer_name = TEST_MACHINE_NAME;
1561 11 : r.in.credential = &credential;
1562 11 : r.in.new_password = &new_password;
1563 11 : r.out.return_authenticator = &return_authenticator;
1564 :
1565 11 : ZERO_STRUCT(password_buf.data);
1566 11 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1567 0 : torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES enabled\n");
1568 : }
1569 11 : netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1570 :
1571 11 : memcpy(new_password.data, password_buf.data, 512);
1572 11 : new_password.length = IVAL(password_buf.data, 512);
1573 :
1574 11 : torture_comment(
1575 : tctx,
1576 : "Testing ServerPasswordSet2 on machine account\n");
1577 :
1578 11 : netlogon_creds_client_authenticator(creds, &credential);
1579 :
1580 11 : torture_assert_ntstatus_ok(
1581 : tctx,
1582 : dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1583 : "ServerPasswordSet2 zero length check failed");
1584 11 : torture_assert_ntstatus_equal(
1585 : tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
1586 :
1587 10 : return true;
1588 : }
1589 :
1590 : /*
1591 : try a change password for our machine account, using a maximum length
1592 : password
1593 : */
1594 11 : static bool test_SetPassword2_maximum_length_password(
1595 : struct torture_context *tctx,
1596 : struct dcerpc_pipe *p1,
1597 : struct cli_credentials *machine_credentials)
1598 : {
1599 1 : struct netr_ServerPasswordSet2 r;
1600 1 : struct netlogon_creds_CredentialState *creds;
1601 1 : struct samr_CryptPassword password_buf;
1602 1 : struct netr_Authenticator credential, return_authenticator;
1603 1 : struct netr_CryptPassword new_password;
1604 11 : struct dcerpc_pipe *p = NULL;
1605 11 : struct dcerpc_binding_handle *b = NULL;
1606 11 : uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
1607 11 : DATA_BLOB new_random_pass = data_blob_null;
1608 :
1609 11 : if (!test_SetupCredentials2(
1610 : p1,
1611 : tctx,
1612 : flags,
1613 : machine_credentials,
1614 : cli_credentials_get_secure_channel_type(machine_credentials),
1615 : &creds))
1616 : {
1617 0 : return false;
1618 : }
1619 11 : if (!test_SetupCredentialsPipe(
1620 : p1,
1621 : tctx,
1622 : machine_credentials,
1623 : creds,
1624 : DCERPC_SIGN | DCERPC_SEAL,
1625 : &p))
1626 : {
1627 0 : return false;
1628 : }
1629 11 : b = p->binding_handle;
1630 :
1631 11 : r.in.server_name = talloc_asprintf(
1632 : tctx,
1633 : "\\\\%s", dcerpc_server_name(p));
1634 11 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1635 12 : r.in.secure_channel_type =
1636 11 : cli_credentials_get_secure_channel_type(machine_credentials);
1637 11 : r.in.computer_name = TEST_MACHINE_NAME;
1638 11 : r.in.credential = &credential;
1639 11 : r.in.new_password = &new_password;
1640 11 : r.out.return_authenticator = &return_authenticator;
1641 :
1642 11 : new_random_pass = netlogon_very_rand_pass(tctx, 256);
1643 11 : set_pw_in_buffer(password_buf.data, &new_random_pass);
1644 11 : SIVAL(password_buf.data, 512, 512);
1645 11 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1646 11 : netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1647 : } else {
1648 0 : netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1649 : }
1650 :
1651 11 : memcpy(new_password.data, password_buf.data, 512);
1652 11 : new_password.length = IVAL(password_buf.data, 512);
1653 :
1654 11 : torture_comment(
1655 : tctx,
1656 : "Testing ServerPasswordSet2 on machine account\n");
1657 :
1658 11 : netlogon_creds_client_authenticator(creds, &credential);
1659 :
1660 11 : torture_assert_ntstatus_ok(
1661 : tctx,
1662 : dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1663 : "ServerPasswordSet2 zero length check failed");
1664 11 : torture_assert_ntstatus_equal(
1665 : tctx, r.out.result, NT_STATUS_OK, "");
1666 :
1667 8 : return true;
1668 : }
1669 :
1670 : /*
1671 : try a change password for our machine account, using a password of
1672 : all zeros, and a non zero password length.
1673 :
1674 : This test relies on the buffer being encrypted with ARC4, to
1675 : trigger the appropriate check in the rpc server code
1676 : */
1677 11 : static bool test_SetPassword2_all_zero_password(
1678 : struct torture_context *tctx,
1679 : struct dcerpc_pipe *p1,
1680 : struct cli_credentials *machine_credentials)
1681 : {
1682 1 : struct netr_ServerPasswordSet2 r;
1683 1 : struct netlogon_creds_CredentialState *creds;
1684 1 : struct samr_CryptPassword password_buf;
1685 1 : struct netr_Authenticator credential, return_authenticator;
1686 1 : struct netr_CryptPassword new_password;
1687 11 : struct dcerpc_pipe *p = NULL;
1688 11 : struct dcerpc_binding_handle *b = NULL;
1689 11 : uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; /* no AES desired here */
1690 :
1691 11 : if (!test_SetupCredentials2(
1692 : p1,
1693 : tctx,
1694 : flags,
1695 : machine_credentials,
1696 : cli_credentials_get_secure_channel_type(machine_credentials),
1697 : &creds))
1698 : {
1699 0 : return false;
1700 : }
1701 11 : if (!test_SetupCredentialsPipe(
1702 : p1,
1703 : tctx,
1704 : machine_credentials,
1705 : creds,
1706 : DCERPC_SIGN | DCERPC_SEAL,
1707 : &p))
1708 : {
1709 0 : return false;
1710 : }
1711 11 : b = p->binding_handle;
1712 :
1713 11 : r.in.server_name = talloc_asprintf(
1714 : tctx,
1715 : "\\\\%s", dcerpc_server_name(p));
1716 11 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1717 12 : r.in.secure_channel_type =
1718 11 : cli_credentials_get_secure_channel_type(machine_credentials);
1719 11 : r.in.computer_name = TEST_MACHINE_NAME;
1720 11 : r.in.credential = &credential;
1721 11 : r.in.new_password = &new_password;
1722 11 : r.out.return_authenticator = &return_authenticator;
1723 :
1724 11 : ZERO_STRUCT(password_buf.data);
1725 11 : SIVAL(password_buf.data, 512, 128);
1726 11 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1727 0 : torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES set");
1728 : }
1729 11 : netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1730 :
1731 11 : memcpy(new_password.data, password_buf.data, 512);
1732 11 : new_password.length = IVAL(password_buf.data, 512);
1733 :
1734 11 : torture_comment(
1735 : tctx,
1736 : "Testing ServerPasswordSet2 on machine account\n");
1737 :
1738 11 : netlogon_creds_client_authenticator(creds, &credential);
1739 :
1740 11 : torture_assert_ntstatus_ok(
1741 : tctx,
1742 : dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1743 : "ServerPasswordSet2 all zero password check failed");
1744 11 : torture_assert_ntstatus_equal(
1745 : tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
1746 :
1747 10 : return true;
1748 : }
1749 :
1750 :
1751 21 : static bool test_SetPassword2(struct torture_context *tctx,
1752 : struct dcerpc_pipe *p,
1753 : struct cli_credentials *machine_credentials)
1754 : {
1755 21 : return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS);
1756 : }
1757 :
1758 21 : static bool test_SetPassword2_AES(struct torture_context *tctx,
1759 : struct dcerpc_pipe *p,
1760 : struct cli_credentials *machine_credentials)
1761 : {
1762 21 : return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
1763 : }
1764 :
1765 18 : static bool test_GetPassword(struct torture_context *tctx,
1766 : struct dcerpc_pipe *p,
1767 : struct cli_credentials *machine_credentials)
1768 : {
1769 3 : struct netr_ServerPasswordGet r;
1770 3 : struct netlogon_creds_CredentialState *creds;
1771 3 : struct netr_Authenticator credential;
1772 3 : NTSTATUS status;
1773 3 : struct netr_Authenticator return_authenticator;
1774 3 : struct samr_Password password;
1775 18 : struct dcerpc_binding_handle *b = p->binding_handle;
1776 :
1777 18 : if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1778 0 : return false;
1779 : }
1780 :
1781 18 : netlogon_creds_client_authenticator(creds, &credential);
1782 :
1783 18 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1784 18 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1785 18 : r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1786 18 : r.in.computer_name = TEST_MACHINE_NAME;
1787 18 : r.in.credential = &credential;
1788 18 : r.out.return_authenticator = &return_authenticator;
1789 18 : r.out.password = &password;
1790 :
1791 18 : status = dcerpc_netr_ServerPasswordGet_r(b, tctx, &r);
1792 18 : torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
1793 0 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordGet");
1794 :
1795 0 : return true;
1796 : }
1797 :
1798 18 : static bool test_GetTrustPasswords(struct torture_context *tctx,
1799 : struct dcerpc_pipe *p,
1800 : struct cli_credentials *machine_credentials)
1801 : {
1802 3 : struct netr_ServerTrustPasswordsGet r;
1803 3 : struct netlogon_creds_CredentialState *creds;
1804 3 : struct netr_Authenticator credential;
1805 3 : struct netr_Authenticator return_authenticator;
1806 3 : struct samr_Password password, password2;
1807 18 : struct dcerpc_binding_handle *b = p->binding_handle;
1808 :
1809 18 : if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1810 0 : return false;
1811 : }
1812 :
1813 18 : netlogon_creds_client_authenticator(creds, &credential);
1814 :
1815 18 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1816 18 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1817 18 : r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1818 18 : r.in.computer_name = TEST_MACHINE_NAME;
1819 18 : r.in.credential = &credential;
1820 18 : r.out.return_authenticator = &return_authenticator;
1821 18 : r.out.new_owf_password = &password;
1822 18 : r.out.old_owf_password = &password2;
1823 :
1824 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerTrustPasswordsGet_r(b, tctx, &r),
1825 : "ServerTrustPasswordsGet failed");
1826 18 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerTrustPasswordsGet failed");
1827 :
1828 15 : return true;
1829 : }
1830 :
1831 : /*
1832 : try a netlogon SamLogon
1833 : */
1834 852 : static bool test_netlogon_ops_args(struct dcerpc_pipe *p, struct torture_context *tctx,
1835 : struct cli_credentials *credentials,
1836 : struct netlogon_creds_CredentialState *creds,
1837 : bool null_domain)
1838 : {
1839 147 : NTSTATUS status;
1840 147 : struct netr_LogonSamLogon r;
1841 147 : struct netr_Authenticator auth, auth2;
1842 147 : union netr_LogonLevel logon;
1843 147 : union netr_Validation validation;
1844 147 : uint8_t authoritative;
1845 147 : struct netr_NetworkInfo ninfo;
1846 147 : DATA_BLOB names_blob, chal, lm_resp, nt_resp;
1847 147 : int i;
1848 852 : struct dcerpc_binding_handle *b = p->binding_handle;
1849 852 : int flags = CLI_CRED_NTLM_AUTH;
1850 852 : if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
1851 741 : flags |= CLI_CRED_LANMAN_AUTH;
1852 : }
1853 :
1854 852 : if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx) && !null_domain) {
1855 849 : flags |= CLI_CRED_NTLMv2_AUTH;
1856 : }
1857 :
1858 852 : cli_credentials_get_ntlm_username_domain(samba_cmdline_get_creds(),
1859 : tctx,
1860 : &ninfo.identity_info.account_name.string,
1861 : &ninfo.identity_info.domain_name.string);
1862 :
1863 852 : if (null_domain) {
1864 3 : ninfo.identity_info.domain_name.string = NULL;
1865 : }
1866 :
1867 852 : generate_random_buffer(ninfo.challenge,
1868 : sizeof(ninfo.challenge));
1869 852 : chal = data_blob_const(ninfo.challenge,
1870 : sizeof(ninfo.challenge));
1871 :
1872 852 : names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials),
1873 : cli_credentials_get_domain(credentials));
1874 :
1875 852 : status = cli_credentials_get_ntlm_response(
1876 : samba_cmdline_get_creds(), tctx,
1877 : &flags,
1878 : chal,
1879 : NULL, /* server_timestamp */
1880 : names_blob,
1881 : &lm_resp, &nt_resp,
1882 : NULL, NULL);
1883 852 : torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
1884 :
1885 852 : ninfo.lm.data = lm_resp.data;
1886 852 : ninfo.lm.length = lm_resp.length;
1887 :
1888 852 : ninfo.nt.data = nt_resp.data;
1889 852 : ninfo.nt.length = nt_resp.length;
1890 :
1891 852 : ninfo.identity_info.parameter_control = 0;
1892 852 : ninfo.identity_info.logon_id = 0;
1893 852 : ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
1894 :
1895 852 : logon.network = &ninfo;
1896 :
1897 852 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1898 852 : r.in.computer_name = cli_credentials_get_workstation(credentials);
1899 852 : r.in.credential = &auth;
1900 852 : r.in.return_authenticator = &auth2;
1901 852 : r.in.logon_level = NetlogonNetworkInformation;
1902 852 : r.in.logon = &logon;
1903 852 : r.out.validation = &validation;
1904 852 : r.out.authoritative = &authoritative;
1905 :
1906 852 : d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
1907 :
1908 2703 : for (i=2;i<=3;i++) {
1909 1704 : ZERO_STRUCT(auth2);
1910 1704 : netlogon_creds_client_authenticator(creds, &auth);
1911 :
1912 1704 : r.in.validation_level = i;
1913 :
1914 1704 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1915 : "LogonSamLogon failed");
1916 1704 : torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
1917 :
1918 1704 : torture_assert(tctx, netlogon_creds_client_check(creds,
1919 : &r.out.return_authenticator->cred),
1920 : "Credential chaining failed");
1921 1704 : torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1922 : "LogonSamLogon invalid *r.out.authoritative");
1923 : }
1924 :
1925 : /* this makes sure we get the unmarshalling right for invalid levels */
1926 1704 : for (i=52;i<53;i++) {
1927 852 : ZERO_STRUCT(auth2);
1928 : /* the authenticator should be ignored by the server */
1929 852 : generate_random_buffer((uint8_t *) &auth, sizeof(auth));
1930 :
1931 852 : r.in.validation_level = i;
1932 :
1933 852 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1934 : "LogonSamLogon failed");
1935 852 : torture_assert_ntstatus_equal(tctx, r.out.result,
1936 : NT_STATUS_INVALID_INFO_CLASS,
1937 : "LogonSamLogon failed");
1938 :
1939 852 : torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1940 : "LogonSamLogon invalid *r.out.authoritative");
1941 852 : torture_assert(tctx,
1942 : all_zero((uint8_t *)&auth2, sizeof(auth2)),
1943 : "Return authenticator non zero");
1944 : }
1945 :
1946 2556 : for (i=2;i<=3;i++) {
1947 1704 : ZERO_STRUCT(auth2);
1948 1704 : netlogon_creds_client_authenticator(creds, &auth);
1949 :
1950 1704 : r.in.validation_level = i;
1951 :
1952 1704 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1953 : "LogonSamLogon failed");
1954 1704 : torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
1955 :
1956 1704 : torture_assert(tctx, netlogon_creds_client_check(creds,
1957 : &r.out.return_authenticator->cred),
1958 : "Credential chaining failed");
1959 1704 : torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1960 : "LogonSamLogon invalid *r.out.authoritative");
1961 : }
1962 :
1963 852 : r.in.logon_level = 52;
1964 :
1965 2556 : for (i=2;i<=3;i++) {
1966 1704 : ZERO_STRUCT(auth2);
1967 : /* the authenticator should be ignored by the server */
1968 1704 : generate_random_buffer((uint8_t *) &auth, sizeof(auth));
1969 :
1970 1704 : r.in.validation_level = i;
1971 :
1972 1704 : torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
1973 :
1974 1704 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1975 : "LogonSamLogon failed");
1976 1704 : torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
1977 : "LogonSamLogon expected INVALID_PARAMETER");
1978 :
1979 1704 : torture_assert(tctx,
1980 : all_zero((uint8_t *)&auth2, sizeof(auth2)),
1981 : "Return authenticator non zero");
1982 1704 : torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1983 : "LogonSamLogon invalid *r.out.authoritative");
1984 : }
1985 :
1986 852 : r.in.credential = NULL;
1987 :
1988 2556 : for (i=2;i<=3;i++) {
1989 1704 : ZERO_STRUCT(auth2);
1990 :
1991 1704 : r.in.validation_level = i;
1992 :
1993 1704 : torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
1994 :
1995 1704 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1996 : "LogonSamLogon failed");
1997 1704 : torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
1998 : "LogonSamLogon expected INVALID_PARAMETER");
1999 :
2000 1704 : torture_assert(tctx,
2001 : all_zero((uint8_t *)&auth2, sizeof(auth2)),
2002 : "Return authenticator non zero");
2003 1704 : torture_assert_int_equal(tctx, *r.out.authoritative, 1,
2004 : "LogonSamLogon invalid *r.out.authoritative");
2005 : }
2006 :
2007 852 : r.in.logon_level = NetlogonNetworkInformation;
2008 852 : r.in.credential = &auth;
2009 :
2010 2556 : for (i=2;i<=3;i++) {
2011 1704 : ZERO_STRUCT(auth2);
2012 1704 : netlogon_creds_client_authenticator(creds, &auth);
2013 :
2014 1704 : r.in.validation_level = i;
2015 :
2016 1704 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
2017 : "LogonSamLogon failed");
2018 1704 : torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
2019 :
2020 1704 : torture_assert(tctx, netlogon_creds_client_check(creds,
2021 : &r.out.return_authenticator->cred),
2022 : "Credential chaining failed");
2023 1704 : torture_assert_int_equal(tctx, *r.out.authoritative, 1,
2024 : "LogonSamLogon invalid *r.out.authoritative");
2025 : }
2026 :
2027 705 : return true;
2028 : }
2029 :
2030 849 : bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2031 : struct cli_credentials *credentials,
2032 : struct netlogon_creds_CredentialState *creds)
2033 : {
2034 849 : return test_netlogon_ops_args(p, tctx, credentials, creds, false);
2035 : }
2036 :
2037 : /*
2038 : try a netlogon GetCapabilities
2039 : */
2040 552 : bool test_netlogon_capabilities(struct dcerpc_pipe *p, struct torture_context *tctx,
2041 : struct cli_credentials *credentials,
2042 : struct netlogon_creds_CredentialState *creds)
2043 : {
2044 96 : NTSTATUS status;
2045 96 : struct netr_LogonGetCapabilities r;
2046 96 : union netr_Capabilities capabilities;
2047 96 : struct netr_Authenticator auth, return_auth;
2048 96 : struct netlogon_creds_CredentialState tmp_creds;
2049 552 : struct dcerpc_binding_handle *b = p->binding_handle;
2050 :
2051 552 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2052 552 : r.in.computer_name = cli_credentials_get_workstation(credentials);
2053 552 : r.in.credential = &auth;
2054 552 : r.in.return_authenticator = &return_auth;
2055 552 : r.in.query_level = 1;
2056 552 : r.out.capabilities = &capabilities;
2057 552 : r.out.return_authenticator = &return_auth;
2058 :
2059 552 : torture_comment(tctx, "Testing LogonGetCapabilities with query_level=0\n");
2060 :
2061 552 : r.in.query_level = 0;
2062 552 : ZERO_STRUCT(return_auth);
2063 :
2064 : /*
2065 : * we need to operate on a temporary copy of creds
2066 : * because dcerpc_netr_LogonGetCapabilities with
2067 : * an unknown query level returns DCERPC_NCA_S_FAULT_INVALID_TAG
2068 : * => NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
2069 : * without looking at the authenticator.
2070 : */
2071 552 : tmp_creds = *creds;
2072 552 : netlogon_creds_client_authenticator(&tmp_creds, &auth);
2073 :
2074 552 : status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
2075 552 : torture_assert_ntstatus_equal(tctx, status, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE,
2076 : "LogonGetCapabilities query_level=0 failed");
2077 :
2078 552 : torture_comment(tctx, "Testing LogonGetCapabilities with query_level=3\n");
2079 :
2080 552 : r.in.query_level = 3;
2081 552 : ZERO_STRUCT(return_auth);
2082 :
2083 : /*
2084 : * we need to operate on a temporary copy of creds
2085 : * because dcerpc_netr_LogonGetCapabilities with
2086 : * an unknown query level returns DCERPC_NCA_S_FAULT_INVALID_TAG
2087 : * => NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
2088 : * without looking at the authenticator.
2089 : */
2090 552 : tmp_creds = *creds;
2091 552 : netlogon_creds_client_authenticator(&tmp_creds, &auth);
2092 :
2093 552 : status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
2094 552 : torture_assert_ntstatus_equal(tctx, status, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE,
2095 : "LogonGetCapabilities query_level=0 failed");
2096 :
2097 552 : torture_comment(tctx, "Testing LogonGetCapabilities with query_level=1\n");
2098 :
2099 552 : r.in.query_level = 1;
2100 552 : ZERO_STRUCT(return_auth);
2101 :
2102 : /*
2103 : * we need to operate on a temporary copy of creds
2104 : * because dcerpc_netr_LogonGetCapabilities was
2105 : * dcerpc_netr_DummyFunction and returns NT_STATUS_NOT_IMPLEMENTED
2106 : * without looking at the authenticator.
2107 : */
2108 552 : tmp_creds = *creds;
2109 552 : netlogon_creds_client_authenticator(&tmp_creds, &auth);
2110 :
2111 552 : status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
2112 552 : torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities failed");
2113 552 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2114 0 : return true;
2115 : }
2116 :
2117 552 : *creds = tmp_creds;
2118 :
2119 552 : torture_assert(tctx, netlogon_creds_client_check(creds,
2120 : &r.out.return_authenticator->cred),
2121 : "Credential chaining failed");
2122 :
2123 552 : torture_assert_int_equal(tctx, creds->negotiate_flags,
2124 : capabilities.server_capabilities,
2125 : "negotiate flags");
2126 :
2127 552 : torture_comment(tctx, "Testing LogonGetCapabilities with query_level=2\n");
2128 :
2129 552 : r.in.query_level = 2;
2130 552 : ZERO_STRUCT(return_auth);
2131 :
2132 : /*
2133 : * we need to operate on a temporary copy of creds
2134 : * because dcerpc_netr_LogonGetCapabilities with
2135 : * an query level 2 may returns DCERPC_NCA_S_FAULT_INVALID_TAG
2136 : * => NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
2137 : * without looking at the authenticator.
2138 : */
2139 552 : tmp_creds = *creds;
2140 552 : netlogon_creds_client_authenticator(&tmp_creds, &auth);
2141 :
2142 552 : status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
2143 552 : if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE)) {
2144 : /*
2145 : * an server without KB5028166 returns
2146 : * DCERPC_NCA_S_FAULT_INVALID_TAG =>
2147 : * NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
2148 : */
2149 456 : return true;
2150 : }
2151 0 : torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities query_level=2 failed");
2152 :
2153 0 : *creds = tmp_creds;
2154 :
2155 0 : torture_assert(tctx, netlogon_creds_client_check(creds,
2156 : &r.out.return_authenticator->cred),
2157 : "Credential chaining failed");
2158 :
2159 0 : torture_assert_int_equal(tctx, creds->negotiate_flags,
2160 : capabilities.server_capabilities,
2161 : "negotiate flags");
2162 :
2163 0 : return true;
2164 : }
2165 :
2166 : /*
2167 : try a netlogon SamLogon
2168 : */
2169 21 : static bool test_SamLogon(struct torture_context *tctx,
2170 : struct dcerpc_pipe *p,
2171 : struct cli_credentials *credentials)
2172 : {
2173 3 : struct netlogon_creds_CredentialState *creds;
2174 :
2175 21 : if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
2176 0 : return false;
2177 : }
2178 :
2179 21 : return test_netlogon_ops(p, tctx, credentials, creds);
2180 : }
2181 :
2182 18 : static bool test_invalidAuthenticate2(struct torture_context *tctx,
2183 : struct dcerpc_pipe *p,
2184 : struct cli_credentials *credentials)
2185 : {
2186 3 : struct netlogon_creds_CredentialState *creds;
2187 18 : uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2188 :
2189 18 : torture_comment(tctx, "Testing invalidAuthenticate2\n");
2190 :
2191 18 : if (!test_SetupCredentials2(p, tctx, flags,
2192 : credentials,
2193 : cli_credentials_get_secure_channel_type(credentials),
2194 : &creds)) {
2195 0 : return false;
2196 : }
2197 :
2198 18 : if (!test_SetupCredentials2ex(p, tctx, flags,
2199 : credentials,
2200 : "1234567890123456",
2201 : cli_credentials_get_secure_channel_type(credentials),
2202 18 : STATUS_BUFFER_OVERFLOW,
2203 : &creds)) {
2204 0 : return false;
2205 : }
2206 :
2207 18 : if (!test_SetupCredentials2ex(p, tctx, flags,
2208 : credentials,
2209 : "123456789012345",
2210 : cli_credentials_get_secure_channel_type(credentials),
2211 18 : NT_STATUS_OK,
2212 : &creds)) {
2213 0 : return false;
2214 : }
2215 :
2216 18 : return true;
2217 : }
2218 :
2219 18 : static bool test_ServerReqChallengeGlobal(struct torture_context *tctx,
2220 : struct dcerpc_pipe *p1,
2221 : struct cli_credentials *machine_credentials)
2222 : {
2223 18 : uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2224 3 : struct netr_ServerReqChallenge r;
2225 3 : struct netr_ServerAuthenticate3 a;
2226 3 : struct netr_Credential credentials1, credentials2, credentials3;
2227 3 : struct netlogon_creds_CredentialState *creds;
2228 3 : struct samr_Password mach_password;
2229 3 : uint32_t rid;
2230 3 : const char *machine_name;
2231 3 : const char *plain_pass;
2232 18 : struct dcerpc_binding_handle *b1 = p1->binding_handle;
2233 18 : struct dcerpc_pipe *p2 = NULL;
2234 18 : struct dcerpc_binding_handle *b2 = NULL;
2235 :
2236 18 : machine_name = cli_credentials_get_workstation(machine_credentials);
2237 18 : torture_assert(tctx, machine_name != NULL, "machine_name");
2238 18 : plain_pass = cli_credentials_get_password(machine_credentials);
2239 18 : torture_assert(tctx, plain_pass != NULL, "plain_pass");
2240 :
2241 18 : torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2242 :
2243 18 : torture_assert_ntstatus_ok(tctx,
2244 : dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
2245 : &ndr_table_netlogon,
2246 : machine_credentials,
2247 : tctx->ev, tctx->lp_ctx),
2248 : "dcerpc_pipe_connect_b failed");
2249 18 : b2 = p2->binding_handle;
2250 :
2251 18 : r.in.server_name = NULL;
2252 18 : r.in.computer_name = machine_name;
2253 18 : r.in.credentials = &credentials1;
2254 18 : r.out.return_credentials = &credentials2;
2255 :
2256 18 : netlogon_creds_random_challenge(&credentials1);
2257 :
2258 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2259 : "ServerReqChallenge failed on b1");
2260 18 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2261 :
2262 18 : E_md4hash(plain_pass, mach_password.hash);
2263 :
2264 18 : a.in.server_name = NULL;
2265 18 : a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2266 18 : a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2267 18 : a.in.computer_name = machine_name;
2268 18 : a.in.negotiate_flags = &flags;
2269 18 : a.in.credentials = &credentials3;
2270 18 : a.out.return_credentials = &credentials3;
2271 18 : a.out.negotiate_flags = &flags;
2272 18 : a.out.rid = &rid;
2273 :
2274 18 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2275 : a.in.computer_name,
2276 15 : a.in.secure_channel_type,
2277 : &credentials1, &credentials2,
2278 : &mach_password, &credentials3,
2279 : flags);
2280 :
2281 18 : torture_assert(tctx, creds != NULL, "memory allocation");
2282 :
2283 18 : torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
2284 :
2285 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2286 : "ServerAuthenticate3 failed on b2");
2287 18 : torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
2288 18 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2289 :
2290 15 : return true;
2291 : }
2292 :
2293 : /*
2294 : * Test the re-use of the challenge is not possible on a third
2295 : * connection, after first using it second one.
2296 : */
2297 :
2298 18 : static bool test_ServerReqChallengeReuseGlobal(struct torture_context *tctx,
2299 : struct dcerpc_pipe *p1,
2300 : struct cli_credentials *machine_credentials)
2301 : {
2302 18 : uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2303 3 : struct netr_ServerReqChallenge r;
2304 3 : struct netr_ServerAuthenticate3 a;
2305 3 : struct netr_Credential credentials1, credentials2, credentials3;
2306 3 : struct netlogon_creds_CredentialState *creds;
2307 3 : struct samr_Password mach_password;
2308 3 : uint32_t rid;
2309 3 : const char *machine_name;
2310 3 : const char *plain_pass;
2311 18 : struct dcerpc_binding_handle *b1 = p1->binding_handle;
2312 18 : struct dcerpc_pipe *p2 = NULL;
2313 18 : struct dcerpc_binding_handle *b2 = NULL;
2314 18 : struct dcerpc_pipe *p3 = NULL;
2315 18 : struct dcerpc_binding_handle *b3 = NULL;
2316 :
2317 18 : machine_name = cli_credentials_get_workstation(machine_credentials);
2318 18 : torture_assert(tctx, machine_name != NULL, "machine_name");
2319 18 : plain_pass = cli_credentials_get_password(machine_credentials);
2320 18 : torture_assert(tctx, plain_pass != NULL, "plain_pass");
2321 :
2322 18 : torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2323 :
2324 18 : torture_assert_ntstatus_ok(tctx,
2325 : dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
2326 : &ndr_table_netlogon,
2327 : machine_credentials,
2328 : tctx->ev, tctx->lp_ctx),
2329 : "dcerpc_pipe_connect_b failed");
2330 18 : b2 = p2->binding_handle;
2331 :
2332 18 : torture_assert_ntstatus_ok(tctx,
2333 : dcerpc_pipe_connect_b(tctx, &p3, p1->binding,
2334 : &ndr_table_netlogon,
2335 : machine_credentials,
2336 : tctx->ev, tctx->lp_ctx),
2337 : "dcerpc_pipe_connect_b failed");
2338 18 : b3 = p3->binding_handle;
2339 :
2340 18 : r.in.server_name = NULL;
2341 18 : r.in.computer_name = machine_name;
2342 18 : r.in.credentials = &credentials1;
2343 18 : r.out.return_credentials = &credentials2;
2344 :
2345 18 : netlogon_creds_random_challenge(&credentials1);
2346 :
2347 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2348 : "ServerReqChallenge failed on b1");
2349 18 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2350 :
2351 18 : E_md4hash(plain_pass, mach_password.hash);
2352 :
2353 18 : a.in.server_name = NULL;
2354 18 : a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2355 18 : a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2356 18 : a.in.computer_name = machine_name;
2357 18 : a.in.negotiate_flags = &flags;
2358 18 : a.in.credentials = &credentials3;
2359 18 : a.out.return_credentials = &credentials3;
2360 18 : a.out.negotiate_flags = &flags;
2361 18 : a.out.rid = &rid;
2362 :
2363 18 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2364 : a.in.computer_name,
2365 15 : a.in.secure_channel_type,
2366 : &credentials1, &credentials2,
2367 : &mach_password, &credentials3,
2368 : flags);
2369 :
2370 18 : torture_assert(tctx, creds != NULL, "memory allocation");
2371 :
2372 18 : torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
2373 :
2374 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2375 : "ServerAuthenticate3 failed on b2");
2376 18 : torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
2377 18 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2378 :
2379 : /* We have to re-run this part */
2380 21 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2381 : a.in.computer_name,
2382 18 : a.in.secure_channel_type,
2383 : &credentials1, &credentials2,
2384 : &mach_password, &credentials3,
2385 : flags);
2386 :
2387 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b3, tctx, &a),
2388 : "ServerAuthenticate3 failed on b3");
2389 18 : torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2390 : "ServerAuthenticate3 should have failed on b3, due to credential reuse");
2391 15 : return true;
2392 : }
2393 :
2394 : /*
2395 : * Test if use of the per-pipe challenge will wipe out the globally cached challenge
2396 : */
2397 18 : static bool test_ServerReqChallengeReuseGlobal2(struct torture_context *tctx,
2398 : struct dcerpc_pipe *p1,
2399 : struct cli_credentials *machine_credentials)
2400 : {
2401 18 : uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2402 3 : struct netr_ServerReqChallenge r;
2403 3 : struct netr_ServerAuthenticate3 a;
2404 3 : struct netr_Credential credentials1, credentials2, credentials3;
2405 3 : struct netlogon_creds_CredentialState *creds;
2406 3 : struct samr_Password mach_password;
2407 3 : uint32_t rid;
2408 3 : const char *machine_name;
2409 3 : const char *plain_pass;
2410 18 : struct dcerpc_binding_handle *b1 = p1->binding_handle;
2411 18 : struct dcerpc_pipe *p2 = NULL;
2412 18 : struct dcerpc_binding_handle *b2 = NULL;
2413 :
2414 18 : machine_name = cli_credentials_get_workstation(machine_credentials);
2415 18 : torture_assert(tctx, machine_name != NULL, "machine_name");
2416 18 : plain_pass = cli_credentials_get_password(machine_credentials);
2417 18 : torture_assert(tctx, plain_pass != NULL, "plain_pass");
2418 :
2419 18 : torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2420 :
2421 18 : torture_assert_ntstatus_ok(tctx,
2422 : dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
2423 : &ndr_table_netlogon,
2424 : machine_credentials,
2425 : tctx->ev, tctx->lp_ctx),
2426 : "dcerpc_pipe_connect_b failed");
2427 18 : b2 = p2->binding_handle;
2428 :
2429 18 : r.in.server_name = NULL;
2430 18 : r.in.computer_name = machine_name;
2431 18 : r.in.credentials = &credentials1;
2432 18 : r.out.return_credentials = &credentials2;
2433 :
2434 18 : netlogon_creds_random_challenge(&credentials1);
2435 :
2436 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2437 : "ServerReqChallenge failed on b1");
2438 18 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2439 :
2440 18 : E_md4hash(plain_pass, mach_password.hash);
2441 :
2442 18 : a.in.server_name = NULL;
2443 18 : a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2444 18 : a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2445 18 : a.in.computer_name = machine_name;
2446 18 : a.in.negotiate_flags = &flags;
2447 18 : a.in.credentials = &credentials3;
2448 18 : a.out.return_credentials = &credentials3;
2449 18 : a.out.negotiate_flags = &flags;
2450 18 : a.out.rid = &rid;
2451 :
2452 18 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2453 : a.in.computer_name,
2454 15 : a.in.secure_channel_type,
2455 : &credentials1, &credentials2,
2456 : &mach_password, &credentials3,
2457 : flags);
2458 :
2459 18 : torture_assert(tctx, creds != NULL, "memory allocation");
2460 :
2461 18 : torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
2462 :
2463 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
2464 : "ServerAuthenticate3 failed on b");
2465 18 : torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b");
2466 18 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2467 :
2468 : /* We have to re-run this part */
2469 21 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2470 : a.in.computer_name,
2471 18 : a.in.secure_channel_type,
2472 : &credentials1, &credentials2,
2473 : &mach_password, &credentials3,
2474 : flags);
2475 :
2476 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2477 : "ServerAuthenticate3 failed on b2");
2478 18 : torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2479 : "ServerAuthenticate3 should have failed on b2, due to credential reuse");
2480 15 : return true;
2481 : }
2482 :
2483 : /*
2484 : * Test if use of the globally cached challenge will wipe out the
2485 : * per-pipe challenge
2486 : */
2487 18 : static bool test_ServerReqChallengeReuseGlobal3(struct torture_context *tctx,
2488 : struct dcerpc_pipe *p1,
2489 : struct cli_credentials *machine_credentials)
2490 : {
2491 18 : uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2492 3 : struct netr_ServerReqChallenge r;
2493 3 : struct netr_ServerAuthenticate3 a;
2494 3 : struct netr_Credential credentials1, credentials2, credentials3;
2495 3 : struct netlogon_creds_CredentialState *creds;
2496 3 : struct samr_Password mach_password;
2497 3 : uint32_t rid;
2498 3 : const char *machine_name;
2499 3 : const char *plain_pass;
2500 18 : struct dcerpc_binding_handle *b1 = p1->binding_handle;
2501 18 : struct dcerpc_pipe *p2 = NULL;
2502 18 : struct dcerpc_binding_handle *b2 = NULL;
2503 :
2504 18 : machine_name = cli_credentials_get_workstation(machine_credentials);
2505 18 : torture_assert(tctx, machine_name != NULL, "machine_name");
2506 18 : plain_pass = cli_credentials_get_password(machine_credentials);
2507 18 : torture_assert(tctx, plain_pass != NULL, "plain_pass");
2508 :
2509 18 : torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2510 :
2511 18 : torture_assert_ntstatus_ok(tctx,
2512 : dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
2513 : &ndr_table_netlogon,
2514 : machine_credentials,
2515 : tctx->ev, tctx->lp_ctx),
2516 : "dcerpc_pipe_connect_b failed");
2517 18 : b2 = p2->binding_handle;
2518 :
2519 18 : r.in.server_name = NULL;
2520 18 : r.in.computer_name = machine_name;
2521 18 : r.in.credentials = &credentials1;
2522 18 : r.out.return_credentials = &credentials2;
2523 :
2524 18 : netlogon_creds_random_challenge(&credentials1);
2525 :
2526 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2527 : "ServerReqChallenge failed on b1");
2528 18 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2529 :
2530 18 : E_md4hash(plain_pass, mach_password.hash);
2531 :
2532 18 : a.in.server_name = NULL;
2533 18 : a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2534 18 : a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2535 18 : a.in.computer_name = machine_name;
2536 18 : a.in.negotiate_flags = &flags;
2537 18 : a.in.credentials = &credentials3;
2538 18 : a.out.return_credentials = &credentials3;
2539 18 : a.out.negotiate_flags = &flags;
2540 18 : a.out.rid = &rid;
2541 :
2542 18 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2543 : a.in.computer_name,
2544 15 : a.in.secure_channel_type,
2545 : &credentials1, &credentials2,
2546 : &mach_password, &credentials3,
2547 : flags);
2548 :
2549 18 : torture_assert(tctx, creds != NULL, "memory allocation");
2550 :
2551 18 : torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
2552 :
2553 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2554 : "ServerAuthenticate3 failed on b2");
2555 18 : torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b");
2556 18 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2557 :
2558 : /* We have to re-run this part */
2559 21 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2560 : a.in.computer_name,
2561 18 : a.in.secure_channel_type,
2562 : &credentials1, &credentials2,
2563 : &mach_password, &credentials3,
2564 : flags);
2565 :
2566 18 : torture_assert(tctx, creds != NULL, "memory allocation");
2567 :
2568 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
2569 : "ServerAuthenticate3 failed on b1");
2570 18 : torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2571 : "ServerAuthenticate3 should have failed on b1, due to credential reuse");
2572 0 : return true;
2573 : }
2574 :
2575 : /*
2576 : * Test if more than one globally cached challenge works
2577 : */
2578 18 : static bool test_ServerReqChallengeReuseGlobal4(struct torture_context *tctx,
2579 : struct dcerpc_pipe *p1,
2580 : struct cli_credentials *machine_credentials)
2581 : {
2582 18 : uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2583 3 : struct netr_ServerReqChallenge r;
2584 3 : struct netr_ServerAuthenticate3 a;
2585 3 : struct netr_Credential credentials1, credentials1_random,
2586 : credentials2, credentials3, credentials_discard;
2587 3 : struct netlogon_creds_CredentialState *creds;
2588 3 : struct samr_Password mach_password;
2589 3 : uint32_t rid;
2590 3 : const char *machine_name;
2591 3 : const char *plain_pass;
2592 18 : struct dcerpc_binding_handle *b1 = p1->binding_handle;
2593 18 : struct dcerpc_pipe *p2 = NULL;
2594 18 : struct dcerpc_binding_handle *b2 = NULL;
2595 :
2596 18 : machine_name = cli_credentials_get_workstation(machine_credentials);
2597 18 : torture_assert(tctx, machine_name != NULL, "machine_name");
2598 18 : plain_pass = cli_credentials_get_password(machine_credentials);
2599 18 : torture_assert(tctx, plain_pass != NULL, "plain_pass");
2600 :
2601 18 : torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2602 :
2603 18 : torture_assert_ntstatus_ok(tctx,
2604 : dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
2605 : &ndr_table_netlogon,
2606 : machine_credentials,
2607 : tctx->ev, tctx->lp_ctx),
2608 : "dcerpc_pipe_connect_b failed");
2609 18 : b2 = p2->binding_handle;
2610 :
2611 18 : r.in.server_name = NULL;
2612 18 : r.in.computer_name = "CHALTEST1";
2613 18 : r.in.credentials = &credentials1_random;
2614 18 : r.out.return_credentials = &credentials_discard;
2615 :
2616 18 : netlogon_creds_random_challenge(&credentials1_random);
2617 :
2618 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2619 : "ServerReqChallenge failed on b1");
2620 18 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2621 :
2622 : /* Now ask for the actual client name */
2623 18 : r.in.server_name = NULL;
2624 18 : r.in.computer_name = machine_name;
2625 18 : r.in.credentials = &credentials1;
2626 18 : r.out.return_credentials = &credentials2;
2627 :
2628 18 : netlogon_creds_random_challenge(&credentials1);
2629 :
2630 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2631 : "ServerReqChallenge failed on b1");
2632 18 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2633 :
2634 18 : r.in.server_name = NULL;
2635 18 : r.in.computer_name = "CHALTEST2";
2636 18 : r.in.credentials = &credentials1_random;
2637 18 : r.out.return_credentials = &credentials_discard;
2638 :
2639 18 : netlogon_creds_random_challenge(&credentials1_random);
2640 :
2641 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2642 : "ServerReqChallenge failed on b1");
2643 18 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2644 :
2645 18 : E_md4hash(plain_pass, mach_password.hash);
2646 :
2647 18 : a.in.server_name = NULL;
2648 18 : a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2649 18 : a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2650 18 : a.in.computer_name = machine_name;
2651 18 : a.in.negotiate_flags = &flags;
2652 18 : a.in.credentials = &credentials3;
2653 18 : a.out.return_credentials = &credentials3;
2654 18 : a.out.negotiate_flags = &flags;
2655 18 : a.out.rid = &rid;
2656 :
2657 18 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2658 : a.in.computer_name,
2659 15 : a.in.secure_channel_type,
2660 : &credentials1, &credentials2,
2661 : &mach_password, &credentials3,
2662 : flags);
2663 :
2664 18 : torture_assert(tctx, creds != NULL, "memory allocation");
2665 :
2666 18 : torture_comment(tctx, "Testing ServerAuthenticate3 on b2 (must use global credentials)\n");
2667 :
2668 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2669 : "ServerAuthenticate3 failed on b2");
2670 18 : torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
2671 18 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2672 :
2673 : /* We have to re-run this part */
2674 21 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2675 : a.in.computer_name,
2676 18 : a.in.secure_channel_type,
2677 : &credentials1, &credentials2,
2678 : &mach_password, &credentials3,
2679 : flags);
2680 :
2681 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
2682 : "ServerAuthenticate3 failed on b1");
2683 18 : torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2684 : "ServerAuthenticate3 should have failed on b1, due to credential reuse");
2685 15 : return true;
2686 : }
2687 :
2688 18 : static bool test_ServerReqChallengeReuse(struct torture_context *tctx,
2689 : struct dcerpc_pipe *p,
2690 : struct cli_credentials *machine_credentials)
2691 : {
2692 18 : uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2693 3 : struct netr_ServerReqChallenge r;
2694 3 : struct netr_ServerAuthenticate3 a;
2695 3 : struct netr_Credential credentials1, credentials2, credentials3;
2696 3 : struct netlogon_creds_CredentialState *creds;
2697 3 : struct samr_Password mach_password;
2698 3 : uint32_t rid;
2699 3 : const char *machine_name;
2700 3 : const char *plain_pass;
2701 18 : struct dcerpc_binding_handle *b = p->binding_handle;
2702 :
2703 18 : machine_name = cli_credentials_get_workstation(machine_credentials);
2704 18 : torture_assert(tctx, machine_name != NULL, "machine_name");
2705 18 : plain_pass = cli_credentials_get_password(machine_credentials);
2706 18 : torture_assert(tctx, plain_pass != NULL, "plain_pass");
2707 :
2708 18 : torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2709 :
2710 18 : r.in.server_name = NULL;
2711 18 : r.in.computer_name = machine_name;
2712 18 : r.in.credentials = &credentials1;
2713 18 : r.out.return_credentials = &credentials2;
2714 :
2715 18 : netlogon_creds_random_challenge(&credentials1);
2716 :
2717 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2718 : "ServerReqChallenge");
2719 18 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2720 :
2721 18 : E_md4hash(plain_pass, mach_password.hash);
2722 :
2723 18 : a.in.server_name = NULL;
2724 18 : a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2725 18 : a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2726 18 : a.in.computer_name = machine_name;
2727 18 : a.in.negotiate_flags = &flags;
2728 18 : a.in.credentials = &credentials3;
2729 18 : a.out.return_credentials = &credentials3;
2730 18 : a.out.negotiate_flags = &flags;
2731 18 : a.out.rid = &rid;
2732 :
2733 18 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2734 : a.in.computer_name,
2735 15 : a.in.secure_channel_type,
2736 : &credentials1, &credentials2,
2737 : &mach_password, &credentials3,
2738 : flags);
2739 :
2740 18 : torture_assert(tctx, creds != NULL, "memory allocation");
2741 :
2742 18 : torture_comment(tctx, "Testing ServerAuthenticate3\n");
2743 :
2744 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2745 : "ServerAuthenticate3 failed");
2746 18 : torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed");
2747 18 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2748 :
2749 : /* We have to re-run this part */
2750 21 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2751 : a.in.computer_name,
2752 18 : a.in.secure_channel_type,
2753 : &credentials1, &credentials2,
2754 : &mach_password, &credentials3,
2755 : flags);
2756 :
2757 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2758 : "ServerAuthenticate3 failed");
2759 18 : torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2760 : "ServerAuthenticate3 should have failed on b3, due to credential reuse");
2761 :
2762 18 : ZERO_STRUCT(credentials1.data);
2763 18 : ZERO_STRUCT(credentials2.data);
2764 21 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2765 : a.in.computer_name,
2766 18 : a.in.secure_channel_type,
2767 : &credentials1, &credentials2,
2768 : &mach_password, &credentials3,
2769 : flags);
2770 :
2771 18 : torture_assert(tctx, creds != NULL, "memory allocation");
2772 :
2773 18 : torture_comment(tctx, "Testing ServerAuthenticate3 with zero'ed challenge\n");
2774 :
2775 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2776 : "ServerAuthenticate3 failed");
2777 18 : torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2778 : "ServerAuthenticate3 should have failed on b3, due to credential reuse");
2779 15 : return true;
2780 : }
2781 :
2782 3 : static bool test_SamLogon_NULL_domain(struct torture_context *tctx,
2783 : struct dcerpc_pipe *p,
2784 : struct cli_credentials *credentials)
2785 : {
2786 0 : struct netlogon_creds_CredentialState *creds;
2787 :
2788 3 : if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
2789 0 : return false;
2790 : }
2791 :
2792 3 : return test_netlogon_ops_args(p, tctx, credentials, creds, true);
2793 : }
2794 :
2795 : /* we remember the sequence numbers so we can easily do a DatabaseDelta */
2796 : static uint64_t sequence_nums[3];
2797 :
2798 : /*
2799 : try a netlogon DatabaseSync
2800 : */
2801 18 : static bool test_DatabaseSync(struct torture_context *tctx,
2802 : struct dcerpc_pipe *p,
2803 : struct cli_credentials *machine_credentials)
2804 : {
2805 3 : struct netr_DatabaseSync r;
2806 3 : struct netlogon_creds_CredentialState *creds;
2807 18 : const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
2808 3 : int i;
2809 18 : struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2810 3 : struct netr_Authenticator credential, return_authenticator;
2811 18 : struct dcerpc_binding_handle *b = p->binding_handle;
2812 :
2813 18 : if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2814 0 : return false;
2815 : }
2816 :
2817 18 : ZERO_STRUCT(return_authenticator);
2818 :
2819 18 : r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2820 18 : r.in.computername = TEST_MACHINE_NAME;
2821 18 : r.in.preferredmaximumlength = (uint32_t)-1;
2822 18 : r.in.return_authenticator = &return_authenticator;
2823 18 : r.out.delta_enum_array = &delta_enum_array;
2824 18 : r.out.return_authenticator = &return_authenticator;
2825 :
2826 18 : for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2827 :
2828 18 : uint32_t sync_context = 0;
2829 :
2830 18 : r.in.database_id = database_ids[i];
2831 18 : r.in.sync_context = &sync_context;
2832 18 : r.out.sync_context = &sync_context;
2833 :
2834 18 : torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
2835 :
2836 3 : do {
2837 18 : netlogon_creds_client_authenticator(creds, &credential);
2838 :
2839 18 : r.in.credential = &credential;
2840 :
2841 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync_r(b, tctx, &r),
2842 : "DatabaseSync failed");
2843 18 : if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2844 0 : break;
2845 :
2846 : /* Native mode servers don't do this */
2847 18 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
2848 0 : return true;
2849 : }
2850 18 : torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync");
2851 :
2852 0 : if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
2853 0 : torture_comment(tctx, "Credential chaining failed\n");
2854 : }
2855 :
2856 0 : if (delta_enum_array &&
2857 0 : delta_enum_array->num_deltas > 0 &&
2858 0 : delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
2859 0 : delta_enum_array->delta_enum[0].delta_union.domain) {
2860 0 : sequence_nums[r.in.database_id] =
2861 0 : delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
2862 0 : torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
2863 0 : r.in.database_id,
2864 0 : (unsigned long long)sequence_nums[r.in.database_id]);
2865 : }
2866 0 : } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2867 : }
2868 :
2869 0 : return true;
2870 : }
2871 :
2872 :
2873 : /*
2874 : try a netlogon DatabaseDeltas
2875 : */
2876 18 : static bool test_DatabaseDeltas(struct torture_context *tctx,
2877 : struct dcerpc_pipe *p,
2878 : struct cli_credentials *machine_credentials)
2879 : {
2880 3 : struct netr_DatabaseDeltas r;
2881 3 : struct netlogon_creds_CredentialState *creds;
2882 3 : struct netr_Authenticator credential;
2883 3 : struct netr_Authenticator return_authenticator;
2884 18 : struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2885 18 : const uint32_t database_ids[] = {0, 1, 2};
2886 3 : int i;
2887 18 : struct dcerpc_binding_handle *b = p->binding_handle;
2888 :
2889 18 : if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2890 0 : return false;
2891 : }
2892 :
2893 18 : r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2894 18 : r.in.computername = TEST_MACHINE_NAME;
2895 18 : r.in.preferredmaximumlength = (uint32_t)-1;
2896 18 : ZERO_STRUCT(r.in.return_authenticator);
2897 18 : r.out.return_authenticator = &return_authenticator;
2898 18 : r.out.delta_enum_array = &delta_enum_array;
2899 :
2900 72 : for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2901 54 : r.in.database_id = database_ids[i];
2902 54 : r.in.sequence_num = &sequence_nums[r.in.database_id];
2903 :
2904 54 : if (*r.in.sequence_num == 0) continue;
2905 :
2906 0 : *r.in.sequence_num -= 1;
2907 :
2908 0 : torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n",
2909 0 : r.in.database_id, (unsigned long long)*r.in.sequence_num);
2910 :
2911 0 : do {
2912 0 : netlogon_creds_client_authenticator(creds, &credential);
2913 :
2914 0 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseDeltas_r(b, tctx, &r),
2915 : "DatabaseDeltas failed");
2916 0 : if (NT_STATUS_EQUAL(r.out.result,
2917 : NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
2918 0 : torture_comment(tctx, "not considering %s to be an error\n",
2919 : nt_errstr(r.out.result));
2920 0 : return true;
2921 : }
2922 0 : if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2923 0 : break;
2924 :
2925 0 : torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseDeltas");
2926 :
2927 0 : if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
2928 0 : torture_comment(tctx, "Credential chaining failed\n");
2929 : }
2930 :
2931 0 : (*r.in.sequence_num)++;
2932 0 : } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2933 : }
2934 :
2935 15 : return true;
2936 : }
2937 :
2938 18 : static bool test_DatabaseRedo(struct torture_context *tctx,
2939 : struct dcerpc_pipe *p,
2940 : struct cli_credentials *machine_credentials)
2941 : {
2942 3 : struct netr_DatabaseRedo r;
2943 3 : struct netlogon_creds_CredentialState *creds;
2944 3 : struct netr_Authenticator credential;
2945 3 : struct netr_Authenticator return_authenticator;
2946 18 : struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2947 3 : struct netr_ChangeLogEntry e;
2948 3 : struct dom_sid null_sid, *sid;
2949 3 : int i,d;
2950 18 : struct dcerpc_binding_handle *b = p->binding_handle;
2951 :
2952 18 : ZERO_STRUCT(null_sid);
2953 :
2954 18 : sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
2955 :
2956 : {
2957 :
2958 3 : struct {
2959 : uint32_t rid;
2960 : uint16_t flags;
2961 : uint8_t db_index;
2962 : uint8_t delta_type;
2963 : struct dom_sid sid;
2964 : const char *name;
2965 : NTSTATUS expected_error;
2966 : uint32_t expected_num_results;
2967 : uint8_t expected_delta_type_1;
2968 : uint8_t expected_delta_type_2;
2969 : const char *comment;
2970 144 : } changes[] = {
2971 :
2972 : /* SAM_DATABASE_DOMAIN */
2973 :
2974 : {
2975 : .rid = 0,
2976 : .flags = 0,
2977 : .db_index = SAM_DATABASE_DOMAIN,
2978 : .delta_type = NETR_DELTA_MODIFY_COUNT,
2979 : .sid = null_sid,
2980 : .name = NULL,
2981 : .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
2982 : .expected_num_results = 0,
2983 : .comment = "NETR_DELTA_MODIFY_COUNT"
2984 : },
2985 : {
2986 : .rid = 0,
2987 : .flags = 0,
2988 : .db_index = SAM_DATABASE_DOMAIN,
2989 : .delta_type = 0,
2990 : .sid = null_sid,
2991 : .name = NULL,
2992 : .expected_error = NT_STATUS_OK,
2993 : .expected_num_results = 1,
2994 : .expected_delta_type_1 = NETR_DELTA_DOMAIN,
2995 : .comment = "NULL DELTA"
2996 : },
2997 : {
2998 : .rid = 0,
2999 : .flags = 0,
3000 : .db_index = SAM_DATABASE_DOMAIN,
3001 : .delta_type = NETR_DELTA_DOMAIN,
3002 : .sid = null_sid,
3003 : .name = NULL,
3004 : .expected_error = NT_STATUS_OK,
3005 : .expected_num_results = 1,
3006 : .expected_delta_type_1 = NETR_DELTA_DOMAIN,
3007 : .comment = "NETR_DELTA_DOMAIN"
3008 : },
3009 : {
3010 : .rid = DOMAIN_RID_ADMINISTRATOR,
3011 : .flags = 0,
3012 : .db_index = SAM_DATABASE_DOMAIN,
3013 : .delta_type = NETR_DELTA_USER,
3014 : .sid = null_sid,
3015 : .name = NULL,
3016 : .expected_error = NT_STATUS_OK,
3017 : .expected_num_results = 1,
3018 : .expected_delta_type_1 = NETR_DELTA_USER,
3019 : .comment = "NETR_DELTA_USER by rid 500"
3020 : },
3021 : {
3022 : .rid = DOMAIN_RID_GUEST,
3023 : .flags = 0,
3024 : .db_index = SAM_DATABASE_DOMAIN,
3025 : .delta_type = NETR_DELTA_USER,
3026 : .sid = null_sid,
3027 : .name = NULL,
3028 : .expected_error = NT_STATUS_OK,
3029 : .expected_num_results = 1,
3030 : .expected_delta_type_1 = NETR_DELTA_USER,
3031 : .comment = "NETR_DELTA_USER by rid 501"
3032 : },
3033 : {
3034 : .rid = 0,
3035 : .flags = NETR_CHANGELOG_SID_INCLUDED,
3036 : .db_index = SAM_DATABASE_DOMAIN,
3037 : .delta_type = NETR_DELTA_USER,
3038 : .sid = *sid,
3039 : .name = NULL,
3040 : .expected_error = NT_STATUS_OK,
3041 : .expected_num_results = 1,
3042 : .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
3043 : .comment = "NETR_DELTA_USER by sid and flags"
3044 : },
3045 : {
3046 : .rid = 0,
3047 : .flags = NETR_CHANGELOG_SID_INCLUDED,
3048 : .db_index = SAM_DATABASE_DOMAIN,
3049 : .delta_type = NETR_DELTA_USER,
3050 : .sid = null_sid,
3051 : .name = NULL,
3052 : .expected_error = NT_STATUS_OK,
3053 : .expected_num_results = 1,
3054 : .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
3055 : .comment = "NETR_DELTA_USER by null_sid and flags"
3056 : },
3057 : {
3058 : .rid = 0,
3059 : .flags = NETR_CHANGELOG_NAME_INCLUDED,
3060 : .db_index = SAM_DATABASE_DOMAIN,
3061 : .delta_type = NETR_DELTA_USER,
3062 : .sid = null_sid,
3063 : .name = "administrator",
3064 : .expected_error = NT_STATUS_OK,
3065 : .expected_num_results = 1,
3066 : .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
3067 : .comment = "NETR_DELTA_USER by name 'administrator'"
3068 : },
3069 : {
3070 : .rid = DOMAIN_RID_ADMINS,
3071 : .flags = 0,
3072 : .db_index = SAM_DATABASE_DOMAIN,
3073 : .delta_type = NETR_DELTA_GROUP,
3074 : .sid = null_sid,
3075 : .name = NULL,
3076 : .expected_error = NT_STATUS_OK,
3077 : .expected_num_results = 2,
3078 : .expected_delta_type_1 = NETR_DELTA_GROUP,
3079 : .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
3080 : .comment = "NETR_DELTA_GROUP by rid 512"
3081 : },
3082 : {
3083 : .rid = DOMAIN_RID_ADMINS,
3084 : .flags = 0,
3085 : .db_index = SAM_DATABASE_DOMAIN,
3086 : .delta_type = NETR_DELTA_GROUP_MEMBER,
3087 : .sid = null_sid,
3088 : .name = NULL,
3089 : .expected_error = NT_STATUS_OK,
3090 : .expected_num_results = 2,
3091 : .expected_delta_type_1 = NETR_DELTA_GROUP,
3092 : .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
3093 : .comment = "NETR_DELTA_GROUP_MEMBER by rid 512"
3094 : },
3095 :
3096 :
3097 : /* SAM_DATABASE_BUILTIN */
3098 :
3099 : {
3100 : .rid = 0,
3101 : .flags = 0,
3102 : .db_index = SAM_DATABASE_BUILTIN,
3103 : .delta_type = NETR_DELTA_MODIFY_COUNT,
3104 : .sid = null_sid,
3105 : .name = NULL,
3106 : .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
3107 : .expected_num_results = 0,
3108 : .comment = "NETR_DELTA_MODIFY_COUNT"
3109 : },
3110 : {
3111 : .rid = 0,
3112 : .flags = 0,
3113 : .db_index = SAM_DATABASE_BUILTIN,
3114 : .delta_type = NETR_DELTA_DOMAIN,
3115 : .sid = null_sid,
3116 : .name = NULL,
3117 : .expected_error = NT_STATUS_OK,
3118 : .expected_num_results = 1,
3119 : .expected_delta_type_1 = NETR_DELTA_DOMAIN,
3120 : .comment = "NETR_DELTA_DOMAIN"
3121 : },
3122 : {
3123 : .rid = DOMAIN_RID_ADMINISTRATOR,
3124 : .flags = 0,
3125 : .db_index = SAM_DATABASE_BUILTIN,
3126 : .delta_type = NETR_DELTA_USER,
3127 : .sid = null_sid,
3128 : .name = NULL,
3129 : .expected_error = NT_STATUS_OK,
3130 : .expected_num_results = 1,
3131 : .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
3132 : .comment = "NETR_DELTA_USER by rid 500"
3133 : },
3134 : {
3135 : .rid = 0,
3136 : .flags = 0,
3137 : .db_index = SAM_DATABASE_BUILTIN,
3138 : .delta_type = NETR_DELTA_USER,
3139 : .sid = null_sid,
3140 : .name = NULL,
3141 : .expected_error = NT_STATUS_OK,
3142 : .expected_num_results = 1,
3143 : .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
3144 : .comment = "NETR_DELTA_USER"
3145 : },
3146 : {
3147 : .rid = 544,
3148 : .flags = 0,
3149 : .db_index = SAM_DATABASE_BUILTIN,
3150 : .delta_type = NETR_DELTA_ALIAS,
3151 : .sid = null_sid,
3152 : .name = NULL,
3153 : .expected_error = NT_STATUS_OK,
3154 : .expected_num_results = 2,
3155 : .expected_delta_type_1 = NETR_DELTA_ALIAS,
3156 : .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
3157 : .comment = "NETR_DELTA_ALIAS by rid 544"
3158 : },
3159 : {
3160 : .rid = 544,
3161 : .flags = 0,
3162 : .db_index = SAM_DATABASE_BUILTIN,
3163 : .delta_type = NETR_DELTA_ALIAS_MEMBER,
3164 : .sid = null_sid,
3165 : .name = NULL,
3166 : .expected_error = NT_STATUS_OK,
3167 : .expected_num_results = 2,
3168 : .expected_delta_type_1 = NETR_DELTA_ALIAS,
3169 : .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
3170 : .comment = "NETR_DELTA_ALIAS_MEMBER by rid 544"
3171 : },
3172 : {
3173 : .rid = 544,
3174 : .flags = 0,
3175 : .db_index = SAM_DATABASE_BUILTIN,
3176 : .delta_type = 0,
3177 : .sid = null_sid,
3178 : .name = NULL,
3179 : .expected_error = NT_STATUS_OK,
3180 : .expected_num_results = 1,
3181 : .expected_delta_type_1 = NETR_DELTA_DOMAIN,
3182 : .comment = "NULL DELTA by rid 544"
3183 : },
3184 : {
3185 : .rid = 544,
3186 : .flags = NETR_CHANGELOG_SID_INCLUDED,
3187 : .db_index = SAM_DATABASE_BUILTIN,
3188 : .delta_type = 0,
3189 18 : .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
3190 : .name = NULL,
3191 : .expected_error = NT_STATUS_OK,
3192 : .expected_num_results = 1,
3193 : .expected_delta_type_1 = NETR_DELTA_DOMAIN,
3194 : .comment = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
3195 : },
3196 : {
3197 : .rid = 544,
3198 : .flags = NETR_CHANGELOG_SID_INCLUDED,
3199 : .db_index = SAM_DATABASE_BUILTIN,
3200 : .delta_type = NETR_DELTA_ALIAS,
3201 18 : .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
3202 : .name = NULL,
3203 : .expected_error = NT_STATUS_OK,
3204 : .expected_num_results = 2,
3205 : .expected_delta_type_1 = NETR_DELTA_ALIAS,
3206 : .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
3207 : .comment = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
3208 : },
3209 : {
3210 : .rid = 0,
3211 : .flags = NETR_CHANGELOG_SID_INCLUDED,
3212 : .db_index = SAM_DATABASE_BUILTIN,
3213 : .delta_type = NETR_DELTA_ALIAS,
3214 18 : .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
3215 : .name = NULL,
3216 : .expected_error = NT_STATUS_OK,
3217 : .expected_num_results = 1,
3218 : .expected_delta_type_1 = NETR_DELTA_DELETE_ALIAS,
3219 : .comment = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
3220 : },
3221 :
3222 : /* SAM_DATABASE_PRIVS */
3223 :
3224 : {
3225 : .rid = 0,
3226 : .flags = 0,
3227 : .db_index = SAM_DATABASE_PRIVS,
3228 : .delta_type = 0,
3229 : .sid = null_sid,
3230 : .name = NULL,
3231 : .expected_error = NT_STATUS_ACCESS_DENIED,
3232 : .expected_num_results = 0,
3233 : .comment = "NULL DELTA"
3234 : },
3235 : {
3236 : .rid = 0,
3237 : .flags = 0,
3238 : .db_index = SAM_DATABASE_PRIVS,
3239 : .delta_type = NETR_DELTA_MODIFY_COUNT,
3240 : .sid = null_sid,
3241 : .name = NULL,
3242 : .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
3243 : .expected_num_results = 0,
3244 : .comment = "NETR_DELTA_MODIFY_COUNT"
3245 : },
3246 : {
3247 : .rid = 0,
3248 : .flags = 0,
3249 : .db_index = SAM_DATABASE_PRIVS,
3250 : .delta_type = NETR_DELTA_POLICY,
3251 : .sid = null_sid,
3252 : .name = NULL,
3253 : .expected_error = NT_STATUS_OK,
3254 : .expected_num_results = 1,
3255 : .expected_delta_type_1 = NETR_DELTA_POLICY,
3256 : .comment = "NETR_DELTA_POLICY"
3257 : },
3258 : {
3259 : .rid = 0,
3260 : .flags = NETR_CHANGELOG_SID_INCLUDED,
3261 : .db_index = SAM_DATABASE_PRIVS,
3262 : .delta_type = NETR_DELTA_POLICY,
3263 : .sid = null_sid,
3264 : .name = NULL,
3265 : .expected_error = NT_STATUS_OK,
3266 : .expected_num_results = 1,
3267 : .expected_delta_type_1 = NETR_DELTA_POLICY,
3268 : .comment = "NETR_DELTA_POLICY by null sid and flags"
3269 : },
3270 : {
3271 : .rid = 0,
3272 : .flags = NETR_CHANGELOG_SID_INCLUDED,
3273 : .db_index = SAM_DATABASE_PRIVS,
3274 : .delta_type = NETR_DELTA_POLICY,
3275 18 : .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
3276 : .name = NULL,
3277 : .expected_error = NT_STATUS_OK,
3278 : .expected_num_results = 1,
3279 : .expected_delta_type_1 = NETR_DELTA_POLICY,
3280 : .comment = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
3281 : },
3282 : {
3283 : .rid = DOMAIN_RID_ADMINISTRATOR,
3284 : .flags = 0,
3285 : .db_index = SAM_DATABASE_PRIVS,
3286 : .delta_type = NETR_DELTA_ACCOUNT,
3287 : .sid = null_sid,
3288 : .name = NULL,
3289 : .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
3290 : .expected_num_results = 0,
3291 : .comment = "NETR_DELTA_ACCOUNT by rid 500"
3292 : },
3293 : {
3294 : .rid = 0,
3295 : .flags = NETR_CHANGELOG_SID_INCLUDED,
3296 : .db_index = SAM_DATABASE_PRIVS,
3297 : .delta_type = NETR_DELTA_ACCOUNT,
3298 18 : .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
3299 : .name = NULL,
3300 : .expected_error = NT_STATUS_OK,
3301 : .expected_num_results = 1,
3302 : .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
3303 : .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
3304 : },
3305 : {
3306 : .rid = 0,
3307 : .flags = NETR_CHANGELOG_SID_INCLUDED |
3308 : NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
3309 : .db_index = SAM_DATABASE_PRIVS,
3310 : .delta_type = NETR_DELTA_ACCOUNT,
3311 18 : .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
3312 : .name = NULL,
3313 : .expected_error = NT_STATUS_OK,
3314 : .expected_num_results = 1,
3315 : .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
3316 : .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
3317 : },
3318 : {
3319 : .rid = 0,
3320 : .flags = NETR_CHANGELOG_SID_INCLUDED |
3321 : NETR_CHANGELOG_NAME_INCLUDED,
3322 : .db_index = SAM_DATABASE_PRIVS,
3323 : .delta_type = NETR_DELTA_ACCOUNT,
3324 18 : .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
3325 : .name = NULL,
3326 : .expected_error = NT_STATUS_INVALID_PARAMETER,
3327 : .expected_num_results = 0,
3328 : .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
3329 : },
3330 : {
3331 : .rid = DOMAIN_RID_ADMINISTRATOR,
3332 : .flags = NETR_CHANGELOG_SID_INCLUDED,
3333 : .db_index = SAM_DATABASE_PRIVS,
3334 : .delta_type = NETR_DELTA_ACCOUNT,
3335 : .sid = *sid,
3336 : .name = NULL,
3337 : .expected_error = NT_STATUS_OK,
3338 : .expected_num_results = 1,
3339 : .expected_delta_type_1 = NETR_DELTA_DELETE_ACCOUNT,
3340 : .comment = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
3341 : },
3342 : {
3343 : .rid = 0,
3344 : .flags = NETR_CHANGELOG_NAME_INCLUDED,
3345 : .db_index = SAM_DATABASE_PRIVS,
3346 : .delta_type = NETR_DELTA_SECRET,
3347 : .sid = null_sid,
3348 : .name = "IsurelydontexistIhope",
3349 : .expected_error = NT_STATUS_OK,
3350 : .expected_num_results = 1,
3351 : .expected_delta_type_1 = NETR_DELTA_DELETE_SECRET,
3352 : .comment = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
3353 : },
3354 : {
3355 : .rid = 0,
3356 : .flags = NETR_CHANGELOG_NAME_INCLUDED,
3357 : .db_index = SAM_DATABASE_PRIVS,
3358 : .delta_type = NETR_DELTA_SECRET,
3359 : .sid = null_sid,
3360 : .name = "G$BCKUPKEY_P",
3361 : .expected_error = NT_STATUS_OK,
3362 : .expected_num_results = 1,
3363 : .expected_delta_type_1 = NETR_DELTA_SECRET,
3364 : .comment = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
3365 : }
3366 : };
3367 :
3368 18 : ZERO_STRUCT(return_authenticator);
3369 :
3370 18 : r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3371 18 : r.in.computername = TEST_MACHINE_NAME;
3372 18 : r.in.return_authenticator = &return_authenticator;
3373 18 : r.out.return_authenticator = &return_authenticator;
3374 18 : r.out.delta_enum_array = &delta_enum_array;
3375 :
3376 18 : for (d=0; d<3; d++) {
3377 18 : const char *database = NULL;
3378 :
3379 18 : switch (d) {
3380 15 : case 0:
3381 15 : database = "SAM";
3382 15 : break;
3383 0 : case 1:
3384 0 : database = "BUILTIN";
3385 0 : break;
3386 0 : case 2:
3387 0 : database = "LSA";
3388 0 : break;
3389 0 : default:
3390 0 : break;
3391 : }
3392 :
3393 18 : torture_comment(tctx, "Testing DatabaseRedo\n");
3394 :
3395 18 : if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
3396 18 : return false;
3397 : }
3398 :
3399 18 : for (i=0;i<ARRAY_SIZE(changes);i++) {
3400 :
3401 18 : if (d != changes[i].db_index) {
3402 0 : continue;
3403 : }
3404 :
3405 18 : netlogon_creds_client_authenticator(creds, &credential);
3406 :
3407 18 : r.in.credential = &credential;
3408 :
3409 18 : e.serial_number1 = 0;
3410 18 : e.serial_number2 = 0;
3411 18 : e.object_rid = changes[i].rid;
3412 18 : e.flags = changes[i].flags;
3413 18 : e.db_index = changes[i].db_index;
3414 18 : e.delta_type = changes[i].delta_type;
3415 :
3416 18 : switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
3417 0 : case NETR_CHANGELOG_SID_INCLUDED:
3418 0 : e.object.object_sid = changes[i].sid;
3419 0 : break;
3420 0 : case NETR_CHANGELOG_NAME_INCLUDED:
3421 0 : e.object.object_name = changes[i].name;
3422 0 : break;
3423 15 : default:
3424 15 : break;
3425 : }
3426 :
3427 18 : r.in.change_log_entry = e;
3428 :
3429 18 : torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
3430 : database, changes[i].comment);
3431 :
3432 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseRedo_r(b, tctx, &r),
3433 : "DatabaseRedo failed");
3434 0 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
3435 0 : return true;
3436 : }
3437 :
3438 0 : torture_assert_ntstatus_equal(tctx, r.out.result, changes[i].expected_error, changes[i].comment);
3439 0 : if (delta_enum_array) {
3440 0 : torture_assert_int_equal(tctx,
3441 : delta_enum_array->num_deltas,
3442 : changes[i].expected_num_results,
3443 : changes[i].comment);
3444 0 : if (delta_enum_array->num_deltas > 0) {
3445 0 : torture_assert_int_equal(tctx,
3446 : delta_enum_array->delta_enum[0].delta_type,
3447 : changes[i].expected_delta_type_1,
3448 : changes[i].comment);
3449 : }
3450 0 : if (delta_enum_array->num_deltas > 1) {
3451 0 : torture_assert_int_equal(tctx,
3452 : delta_enum_array->delta_enum[1].delta_type,
3453 : changes[i].expected_delta_type_2,
3454 : changes[i].comment);
3455 : }
3456 : }
3457 :
3458 0 : if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
3459 0 : torture_comment(tctx, "Credential chaining failed\n");
3460 0 : if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
3461 0 : return false;
3462 : }
3463 : }
3464 : }
3465 : }
3466 : }
3467 :
3468 0 : return true;
3469 : }
3470 :
3471 : /*
3472 : try a netlogon AccountDeltas
3473 : */
3474 18 : static bool test_AccountDeltas(struct torture_context *tctx,
3475 : struct dcerpc_pipe *p,
3476 : struct cli_credentials *machine_credentials)
3477 : {
3478 3 : struct netr_AccountDeltas r;
3479 3 : struct netlogon_creds_CredentialState *creds;
3480 :
3481 3 : struct netr_AccountBuffer buffer;
3482 18 : uint32_t count_returned = 0;
3483 18 : uint32_t total_entries = 0;
3484 3 : struct netr_UAS_INFO_0 recordid;
3485 3 : struct netr_Authenticator return_authenticator;
3486 18 : struct dcerpc_binding_handle *b = p->binding_handle;
3487 :
3488 18 : if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
3489 0 : return false;
3490 : }
3491 :
3492 18 : ZERO_STRUCT(return_authenticator);
3493 :
3494 18 : r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3495 18 : r.in.computername = TEST_MACHINE_NAME;
3496 18 : r.in.return_authenticator = &return_authenticator;
3497 18 : netlogon_creds_client_authenticator(creds, &r.in.credential);
3498 18 : ZERO_STRUCT(r.in.uas);
3499 18 : r.in.count=10;
3500 18 : r.in.level=0;
3501 18 : r.in.buffersize=100;
3502 18 : r.out.buffer = &buffer;
3503 18 : r.out.count_returned = &count_returned;
3504 18 : r.out.total_entries = &total_entries;
3505 18 : r.out.recordid = &recordid;
3506 18 : r.out.return_authenticator = &return_authenticator;
3507 :
3508 : /* w2k3 returns "NOT IMPLEMENTED" for this call */
3509 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountDeltas_r(b, tctx, &r),
3510 : "AccountDeltas failed");
3511 18 : torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
3512 :
3513 15 : return true;
3514 : }
3515 :
3516 : /*
3517 : try a netlogon AccountSync
3518 : */
3519 18 : static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
3520 : struct cli_credentials *machine_credentials)
3521 : {
3522 3 : struct netr_AccountSync r;
3523 3 : struct netlogon_creds_CredentialState *creds;
3524 :
3525 3 : struct netr_AccountBuffer buffer;
3526 18 : uint32_t count_returned = 0;
3527 18 : uint32_t total_entries = 0;
3528 18 : uint32_t next_reference = 0;
3529 3 : struct netr_UAS_INFO_0 recordid;
3530 3 : struct netr_Authenticator return_authenticator;
3531 18 : struct dcerpc_binding_handle *b = p->binding_handle;
3532 :
3533 18 : ZERO_STRUCT(recordid);
3534 18 : ZERO_STRUCT(return_authenticator);
3535 :
3536 18 : if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
3537 0 : return false;
3538 : }
3539 :
3540 18 : r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3541 18 : r.in.computername = TEST_MACHINE_NAME;
3542 18 : r.in.return_authenticator = &return_authenticator;
3543 18 : netlogon_creds_client_authenticator(creds, &r.in.credential);
3544 18 : r.in.recordid = &recordid;
3545 18 : r.in.reference=0;
3546 18 : r.in.level=0;
3547 18 : r.in.buffersize=100;
3548 18 : r.out.buffer = &buffer;
3549 18 : r.out.count_returned = &count_returned;
3550 18 : r.out.total_entries = &total_entries;
3551 18 : r.out.next_reference = &next_reference;
3552 18 : r.out.recordid = &recordid;
3553 18 : r.out.return_authenticator = &return_authenticator;
3554 :
3555 : /* w2k3 returns "NOT IMPLEMENTED" for this call */
3556 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountSync_r(b, tctx, &r),
3557 : "AccountSync failed");
3558 18 : torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
3559 :
3560 15 : return true;
3561 : }
3562 :
3563 : /*
3564 : try a netlogon GetDcName
3565 : */
3566 18 : static bool test_GetDcName(struct torture_context *tctx,
3567 : struct dcerpc_pipe *p)
3568 : {
3569 3 : struct netr_GetDcName r;
3570 18 : const char *dcname = NULL;
3571 18 : struct dcerpc_binding_handle *b = p->binding_handle;
3572 :
3573 18 : r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3574 18 : r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
3575 18 : r.out.dcname = &dcname;
3576 :
3577 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_GetDcName_r(b, tctx, &r),
3578 : "GetDcName failed");
3579 18 : torture_assert_werr_ok(tctx, r.out.result, "GetDcName failed");
3580 :
3581 18 : torture_comment(tctx, "\tDC is at '%s'\n", dcname);
3582 :
3583 18 : return true;
3584 : }
3585 :
3586 6417 : static const char *function_code_str(TALLOC_CTX *mem_ctx,
3587 : enum netr_LogonControlCode function_code)
3588 : {
3589 6417 : switch (function_code) {
3590 228 : case NETLOGON_CONTROL_QUERY:
3591 228 : return "NETLOGON_CONTROL_QUERY";
3592 276 : case NETLOGON_CONTROL_REPLICATE:
3593 276 : return "NETLOGON_CONTROL_REPLICATE";
3594 276 : case NETLOGON_CONTROL_SYNCHRONIZE:
3595 276 : return "NETLOGON_CONTROL_SYNCHRONIZE";
3596 276 : case NETLOGON_CONTROL_PDC_REPLICATE:
3597 276 : return "NETLOGON_CONTROL_PDC_REPLICATE";
3598 690 : case NETLOGON_CONTROL_REDISCOVER:
3599 690 : return "NETLOGON_CONTROL_REDISCOVER";
3600 690 : case NETLOGON_CONTROL_TC_QUERY:
3601 690 : return "NETLOGON_CONTROL_TC_QUERY";
3602 690 : case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
3603 690 : return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
3604 276 : case NETLOGON_CONTROL_FIND_USER:
3605 276 : return "NETLOGON_CONTROL_FIND_USER";
3606 276 : case NETLOGON_CONTROL_CHANGE_PASSWORD:
3607 276 : return "NETLOGON_CONTROL_CHANGE_PASSWORD";
3608 276 : case NETLOGON_CONTROL_TC_VERIFY:
3609 276 : return "NETLOGON_CONTROL_TC_VERIFY";
3610 276 : case NETLOGON_CONTROL_FORCE_DNS_REG:
3611 276 : return "NETLOGON_CONTROL_FORCE_DNS_REG";
3612 276 : case NETLOGON_CONTROL_QUERY_DNS_REG:
3613 276 : return "NETLOGON_CONTROL_QUERY_DNS_REG";
3614 276 : case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
3615 276 : return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
3616 276 : case NETLOGON_CONTROL_TRUNCATE_LOG:
3617 276 : return "NETLOGON_CONTROL_TRUNCATE_LOG";
3618 828 : case NETLOGON_CONTROL_SET_DBFLAG:
3619 828 : return "NETLOGON_CONTROL_SET_DBFLAG";
3620 345 : case NETLOGON_CONTROL_BREAKPOINT:
3621 345 : return "NETLOGON_CONTROL_BREAKPOINT";
3622 138 : default:
3623 138 : return talloc_asprintf(mem_ctx, "unknown function code: %d",
3624 : function_code);
3625 : }
3626 : }
3627 :
3628 :
3629 : /*
3630 : try a netlogon LogonControl
3631 : */
3632 69 : static bool test_LogonControl(struct torture_context *tctx,
3633 : struct dcerpc_pipe *p,
3634 : struct cli_credentials *machine_credentials)
3635 :
3636 : {
3637 12 : NTSTATUS status;
3638 12 : struct netr_LogonControl r;
3639 12 : union netr_CONTROL_QUERY_INFORMATION query;
3640 12 : int i,f;
3641 69 : enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
3642 69 : struct dcerpc_binding_handle *b = p->binding_handle;
3643 :
3644 69 : uint32_t function_codes[] = {
3645 : NETLOGON_CONTROL_QUERY,
3646 : NETLOGON_CONTROL_REPLICATE,
3647 : NETLOGON_CONTROL_SYNCHRONIZE,
3648 : NETLOGON_CONTROL_PDC_REPLICATE,
3649 : NETLOGON_CONTROL_REDISCOVER,
3650 : NETLOGON_CONTROL_TC_QUERY,
3651 : NETLOGON_CONTROL_TRANSPORT_NOTIFY,
3652 : NETLOGON_CONTROL_FIND_USER,
3653 : NETLOGON_CONTROL_CHANGE_PASSWORD,
3654 : NETLOGON_CONTROL_TC_VERIFY,
3655 : NETLOGON_CONTROL_FORCE_DNS_REG,
3656 : NETLOGON_CONTROL_QUERY_DNS_REG,
3657 : NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
3658 : NETLOGON_CONTROL_TRUNCATE_LOG,
3659 : NETLOGON_CONTROL_SET_DBFLAG,
3660 : NETLOGON_CONTROL_BREAKPOINT
3661 : };
3662 :
3663 69 : if (machine_credentials) {
3664 69 : secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
3665 : }
3666 :
3667 69 : torture_comment(tctx, "Testing LogonControl with secure channel type: %d\n",
3668 : secure_channel_type);
3669 :
3670 69 : r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3671 69 : r.in.function_code = 1;
3672 69 : r.out.query = &query;
3673 :
3674 1173 : for (f=0;f<ARRAY_SIZE(function_codes); f++) {
3675 5520 : for (i=1;i<5;i++) {
3676 :
3677 4416 : r.in.function_code = function_codes[f];
3678 4416 : r.in.level = i;
3679 :
3680 4416 : torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
3681 3648 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3682 :
3683 4416 : status = dcerpc_netr_LogonControl_r(b, tctx, &r);
3684 4416 : torture_assert_ntstatus_ok(tctx, status, "LogonControl");
3685 :
3686 4416 : switch (r.in.level) {
3687 1104 : case 1:
3688 1104 : switch (r.in.function_code) {
3689 345 : case NETLOGON_CONTROL_REPLICATE:
3690 : case NETLOGON_CONTROL_SYNCHRONIZE:
3691 : case NETLOGON_CONTROL_PDC_REPLICATE:
3692 : case NETLOGON_CONTROL_BREAKPOINT:
3693 : case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
3694 345 : if ((secure_channel_type == SEC_CHAN_BDC) ||
3695 60 : (secure_channel_type == SEC_CHAN_WKSTA)) {
3696 230 : torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
3697 : "LogonControl returned unexpected error code");
3698 : } else {
3699 115 : torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
3700 : "LogonControl returned unexpected error code");
3701 : }
3702 285 : break;
3703 :
3704 621 : case NETLOGON_CONTROL_REDISCOVER:
3705 : case NETLOGON_CONTROL_TC_QUERY:
3706 : case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
3707 : case NETLOGON_CONTROL_FIND_USER:
3708 : case NETLOGON_CONTROL_CHANGE_PASSWORD:
3709 : case NETLOGON_CONTROL_TC_VERIFY:
3710 : case NETLOGON_CONTROL_FORCE_DNS_REG:
3711 : case NETLOGON_CONTROL_QUERY_DNS_REG:
3712 : case NETLOGON_CONTROL_SET_DBFLAG:
3713 621 : torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
3714 : "LogonControl returned unexpected error code");
3715 513 : break;
3716 69 : case NETLOGON_CONTROL_TRUNCATE_LOG:
3717 69 : if ((secure_channel_type == SEC_CHAN_BDC) ||
3718 12 : (secure_channel_type == SEC_CHAN_WKSTA)) {
3719 46 : torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
3720 : "LogonControl returned unexpected error code");
3721 23 : } else if (!W_ERROR_EQUAL(r.out.result, WERR_NOT_SUPPORTED)) {
3722 0 : torture_assert_werr_ok(tctx, r.out.result,
3723 : "LogonControl returned unexpected result");
3724 : }
3725 57 : break;
3726 69 : default:
3727 69 : torture_assert_werr_ok(tctx, r.out.result,
3728 : "LogonControl returned unexpected result");
3729 57 : break;
3730 : }
3731 912 : break;
3732 1104 : case 2:
3733 1104 : torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
3734 : "LogonControl returned unexpected error code");
3735 912 : break;
3736 2208 : default:
3737 2208 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL,
3738 : "LogonControl returned unexpected error code");
3739 1824 : break;
3740 : }
3741 : }
3742 : }
3743 :
3744 69 : r.in.level = 52;
3745 69 : torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
3746 69 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3747 69 : status = dcerpc_netr_LogonControl_r(b, tctx, &r);
3748 69 : torture_assert_ntstatus_ok(tctx, status, "LogonControl");
3749 69 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl");
3750 :
3751 57 : return true;
3752 : }
3753 :
3754 :
3755 : /*
3756 : try a netlogon GetAnyDCName
3757 : */
3758 18 : static bool test_GetAnyDCName(struct torture_context *tctx,
3759 : struct dcerpc_pipe *p)
3760 : {
3761 3 : NTSTATUS status;
3762 3 : struct netr_GetAnyDCName r;
3763 18 : const char *dcname = NULL;
3764 18 : struct dcerpc_binding_handle *b = p->binding_handle;
3765 :
3766 18 : r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
3767 18 : r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3768 18 : r.out.dcname = &dcname;
3769 :
3770 18 : status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
3771 18 : torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3772 18 : if ((!W_ERROR_IS_OK(r.out.result)) &&
3773 15 : (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
3774 0 : return false;
3775 : }
3776 :
3777 18 : if (dcname) {
3778 0 : torture_comment(tctx, "\tDC is at '%s'\n", dcname);
3779 : }
3780 :
3781 18 : r.in.domainname = NULL;
3782 :
3783 18 : status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
3784 18 : torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3785 18 : if ((!W_ERROR_IS_OK(r.out.result)) &&
3786 15 : (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
3787 0 : return false;
3788 : }
3789 :
3790 18 : r.in.domainname = "";
3791 :
3792 18 : status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
3793 18 : torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3794 18 : if ((!W_ERROR_IS_OK(r.out.result)) &&
3795 15 : (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
3796 0 : return false;
3797 : }
3798 :
3799 15 : return true;
3800 : }
3801 :
3802 :
3803 : /*
3804 : try a netlogon LogonControl2
3805 : */
3806 69 : static bool test_LogonControl2(struct torture_context *tctx,
3807 : struct dcerpc_pipe *p,
3808 : struct cli_credentials *machine_credentials)
3809 :
3810 : {
3811 12 : NTSTATUS status;
3812 12 : struct netr_LogonControl2 r;
3813 12 : union netr_CONTROL_DATA_INFORMATION data;
3814 12 : union netr_CONTROL_QUERY_INFORMATION query;
3815 69 : enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
3816 12 : int i;
3817 69 : struct dcerpc_binding_handle *b = p->binding_handle;
3818 :
3819 69 : data.domain = lpcfg_workgroup(tctx->lp_ctx);
3820 :
3821 69 : if (machine_credentials) {
3822 69 : secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
3823 : }
3824 :
3825 69 : torture_comment(tctx, "Testing LogonControl2 with secure channel type: %d\n",
3826 : secure_channel_type);
3827 :
3828 69 : r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3829 :
3830 69 : r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
3831 69 : r.in.data = &data;
3832 69 : r.out.query = &query;
3833 :
3834 276 : for (i=1;i<4;i++) {
3835 207 : r.in.level = i;
3836 :
3837 207 : torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3838 207 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3839 :
3840 207 : status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3841 207 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3842 : }
3843 :
3844 69 : data.domain = lpcfg_workgroup(tctx->lp_ctx);
3845 :
3846 69 : r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
3847 69 : r.in.data = &data;
3848 :
3849 276 : for (i=1;i<4;i++) {
3850 207 : r.in.level = i;
3851 :
3852 207 : torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3853 207 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3854 :
3855 207 : status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3856 207 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3857 : }
3858 :
3859 69 : data.domain = lpcfg_workgroup(tctx->lp_ctx);
3860 :
3861 69 : r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
3862 69 : r.in.data = &data;
3863 :
3864 276 : for (i=1;i<4;i++) {
3865 207 : r.in.level = i;
3866 :
3867 207 : torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3868 207 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3869 :
3870 207 : status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3871 207 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3872 : }
3873 :
3874 69 : data.debug_level = ~0;
3875 :
3876 69 : r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
3877 69 : r.in.data = &data;
3878 :
3879 276 : for (i=1;i<4;i++) {
3880 207 : r.in.level = i;
3881 :
3882 207 : torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3883 207 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3884 :
3885 207 : status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3886 207 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3887 : }
3888 :
3889 69 : ZERO_STRUCT(data);
3890 69 : r.in.function_code = 52;
3891 69 : r.in.data = &data;
3892 :
3893 69 : torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3894 57 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3895 :
3896 69 : status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3897 69 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3898 69 : switch (secure_channel_type) {
3899 23 : case SEC_CHAN_NULL:
3900 23 : torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2");
3901 19 : break;
3902 46 : default:
3903 46 : torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2");
3904 38 : break;
3905 : }
3906 69 : data.debug_level = ~0;
3907 :
3908 69 : r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
3909 69 : r.in.data = &data;
3910 :
3911 69 : r.in.level = 52;
3912 69 : torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3913 57 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3914 :
3915 69 : status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3916 69 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3917 69 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl2");
3918 :
3919 57 : return true;
3920 : }
3921 :
3922 : /*
3923 : try a netlogon DatabaseSync2
3924 : */
3925 18 : static bool test_DatabaseSync2(struct torture_context *tctx,
3926 : struct dcerpc_pipe *p,
3927 : struct cli_credentials *machine_credentials)
3928 : {
3929 3 : struct netr_DatabaseSync2 r;
3930 18 : struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
3931 3 : struct netr_Authenticator return_authenticator, credential;
3932 :
3933 3 : struct netlogon_creds_CredentialState *creds;
3934 18 : const uint32_t database_ids[] = {0, 1, 2};
3935 3 : int i;
3936 18 : struct dcerpc_binding_handle *b = p->binding_handle;
3937 :
3938 18 : if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
3939 : machine_credentials,
3940 : cli_credentials_get_secure_channel_type(machine_credentials),
3941 : &creds)) {
3942 6 : return false;
3943 : }
3944 :
3945 9 : ZERO_STRUCT(return_authenticator);
3946 :
3947 9 : r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3948 9 : r.in.computername = TEST_MACHINE_NAME;
3949 9 : r.in.preferredmaximumlength = (uint32_t)-1;
3950 9 : r.in.return_authenticator = &return_authenticator;
3951 9 : r.out.return_authenticator = &return_authenticator;
3952 9 : r.out.delta_enum_array = &delta_enum_array;
3953 :
3954 9 : for (i=0;i<ARRAY_SIZE(database_ids);i++) {
3955 :
3956 9 : uint32_t sync_context = 0;
3957 :
3958 9 : r.in.database_id = database_ids[i];
3959 9 : r.in.sync_context = &sync_context;
3960 9 : r.out.sync_context = &sync_context;
3961 9 : r.in.restart_state = 0;
3962 :
3963 9 : torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
3964 :
3965 0 : do {
3966 9 : netlogon_creds_client_authenticator(creds, &credential);
3967 :
3968 9 : r.in.credential = &credential;
3969 :
3970 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync2_r(b, tctx, &r),
3971 : "DatabaseSync2 failed");
3972 9 : if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
3973 0 : break;
3974 :
3975 : /* Native mode servers don't do this */
3976 9 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
3977 0 : return true;
3978 : }
3979 :
3980 9 : torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync2");
3981 :
3982 0 : if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
3983 0 : torture_comment(tctx, "Credential chaining failed\n");
3984 : }
3985 :
3986 0 : } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
3987 : }
3988 :
3989 0 : return true;
3990 : }
3991 :
3992 :
3993 : /*
3994 : try a netlogon LogonControl2Ex
3995 : */
3996 69 : static bool test_LogonControl2Ex(struct torture_context *tctx,
3997 : struct dcerpc_pipe *p,
3998 : struct cli_credentials *machine_credentials)
3999 :
4000 : {
4001 12 : NTSTATUS status;
4002 12 : struct netr_LogonControl2Ex r;
4003 12 : union netr_CONTROL_DATA_INFORMATION data;
4004 12 : union netr_CONTROL_QUERY_INFORMATION query;
4005 69 : enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
4006 12 : int i;
4007 69 : struct dcerpc_binding_handle *b = p->binding_handle;
4008 :
4009 69 : data.domain = lpcfg_workgroup(tctx->lp_ctx);
4010 :
4011 69 : if (machine_credentials) {
4012 69 : secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
4013 : }
4014 :
4015 69 : torture_comment(tctx, "Testing LogonControl2Ex with secure channel type: %d\n",
4016 : secure_channel_type);
4017 :
4018 69 : r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4019 :
4020 69 : r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
4021 69 : r.in.data = &data;
4022 69 : r.out.query = &query;
4023 :
4024 276 : for (i=1;i<4;i++) {
4025 207 : r.in.level = i;
4026 :
4027 207 : torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4028 207 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
4029 :
4030 207 : status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4031 207 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4032 : }
4033 :
4034 69 : data.domain = lpcfg_workgroup(tctx->lp_ctx);
4035 :
4036 69 : r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
4037 69 : r.in.data = &data;
4038 :
4039 276 : for (i=1;i<4;i++) {
4040 207 : r.in.level = i;
4041 :
4042 207 : torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4043 207 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
4044 :
4045 207 : status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4046 207 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4047 : }
4048 :
4049 69 : data.domain = lpcfg_workgroup(tctx->lp_ctx);
4050 :
4051 69 : r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
4052 69 : r.in.data = &data;
4053 :
4054 276 : for (i=1;i<4;i++) {
4055 207 : r.in.level = i;
4056 :
4057 207 : torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4058 207 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
4059 :
4060 207 : status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4061 207 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4062 : }
4063 :
4064 69 : data.debug_level = ~0;
4065 :
4066 69 : r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
4067 69 : r.in.data = &data;
4068 :
4069 276 : for (i=1;i<4;i++) {
4070 207 : r.in.level = i;
4071 :
4072 207 : torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4073 207 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
4074 :
4075 207 : status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4076 207 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4077 : }
4078 :
4079 69 : ZERO_STRUCT(data);
4080 69 : r.in.function_code = 52;
4081 69 : r.in.data = &data;
4082 :
4083 69 : torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4084 57 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
4085 :
4086 69 : status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4087 69 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4088 69 : switch (secure_channel_type) {
4089 23 : case SEC_CHAN_NULL:
4090 23 : torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2Ex");
4091 19 : break;
4092 46 : default:
4093 46 : torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2Ex");
4094 38 : break;
4095 : }
4096 69 : data.debug_level = ~0;
4097 :
4098 69 : r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
4099 69 : r.in.data = &data;
4100 :
4101 69 : r.in.level = 52;
4102 69 : torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4103 57 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
4104 :
4105 69 : status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4106 69 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4107 69 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl2Ex");
4108 :
4109 57 : return true;
4110 : }
4111 :
4112 18 : static bool test_netr_GetForestTrustInformation(struct torture_context *tctx,
4113 : struct dcerpc_pipe *p1,
4114 : struct cli_credentials *machine_credentials)
4115 : {
4116 3 : struct netr_GetForestTrustInformation r;
4117 3 : struct netlogon_creds_CredentialState *creds;
4118 3 : struct netr_Authenticator a;
4119 3 : struct netr_Authenticator return_authenticator;
4120 3 : struct lsa_ForestTrustInformation *forest_trust_info;
4121 18 : struct dcerpc_pipe *p = NULL;
4122 18 : struct dcerpc_binding_handle *b = NULL;
4123 :
4124 18 : if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
4125 : machine_credentials, &creds)) {
4126 0 : return false;
4127 : }
4128 18 : if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
4129 : DCERPC_SIGN | DCERPC_SEAL, &p)) {
4130 0 : return false;
4131 : }
4132 18 : b = p->binding_handle;
4133 :
4134 18 : netlogon_creds_client_authenticator(creds, &a);
4135 :
4136 18 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4137 18 : r.in.computer_name = TEST_MACHINE_NAME;
4138 18 : r.in.credential = &a;
4139 18 : r.in.flags = 0;
4140 18 : r.out.return_authenticator = &return_authenticator;
4141 18 : r.out.forest_trust_info = &forest_trust_info;
4142 :
4143 18 : torture_assert_ntstatus_ok(tctx,
4144 : dcerpc_netr_GetForestTrustInformation_r(b, tctx, &r),
4145 : "netr_GetForestTrustInformation failed");
4146 18 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
4147 18 : torture_comment(tctx, "not considering NT_STATUS_NOT_IMPLEMENTED as an error\n");
4148 : } else {
4149 0 : torture_assert_ntstatus_ok(tctx, r.out.result,
4150 : "netr_GetForestTrustInformation failed");
4151 : }
4152 :
4153 18 : torture_assert(tctx,
4154 : netlogon_creds_client_check(creds, &return_authenticator.cred),
4155 : "Credential chaining failed");
4156 :
4157 15 : return true;
4158 : }
4159 :
4160 18 : static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
4161 : struct dcerpc_pipe *p, const char *trusted_domain_name)
4162 : {
4163 3 : NTSTATUS status;
4164 3 : struct netr_DsRGetForestTrustInformation r;
4165 3 : struct lsa_ForestTrustInformation info, *info_ptr;
4166 18 : struct dcerpc_binding_handle *b = p->binding_handle;
4167 :
4168 18 : info_ptr = &info;
4169 :
4170 18 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4171 18 : r.in.trusted_domain_name = trusted_domain_name;
4172 18 : r.in.flags = 0;
4173 18 : r.out.forest_trust_info = &info_ptr;
4174 :
4175 18 : torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
4176 :
4177 18 : status = dcerpc_netr_DsRGetForestTrustInformation_r(b, tctx, &r);
4178 18 : torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
4179 18 : torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
4180 :
4181 15 : return true;
4182 : }
4183 :
4184 : /*
4185 : try a netlogon netr_DsrEnumerateDomainTrusts
4186 : */
4187 18 : static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
4188 : struct dcerpc_pipe *p)
4189 : {
4190 3 : NTSTATUS status;
4191 3 : struct netr_DsrEnumerateDomainTrusts r;
4192 3 : struct netr_DomainTrustList trusts;
4193 3 : int i;
4194 18 : struct dcerpc_binding_handle *b = p->binding_handle;
4195 :
4196 18 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4197 18 : r.in.trust_flags = 0x3f;
4198 18 : r.out.trusts = &trusts;
4199 :
4200 18 : status = dcerpc_netr_DsrEnumerateDomainTrusts_r(b, tctx, &r);
4201 18 : torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
4202 18 : torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
4203 :
4204 : /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
4205 : * will show non-forest trusts and all UPN suffixes of the own forest
4206 : * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
4207 :
4208 18 : if (r.out.trusts->count) {
4209 18 : if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
4210 0 : return false;
4211 : }
4212 : }
4213 :
4214 36 : for (i=0; i<r.out.trusts->count; i++) {
4215 :
4216 : /* get info for transitive forest trusts */
4217 :
4218 18 : if (r.out.trusts->array[i].trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
4219 0 : if (!test_netr_DsRGetForestTrustInformation(tctx, p,
4220 0 : r.out.trusts->array[i].dns_name)) {
4221 0 : return false;
4222 : }
4223 : }
4224 : }
4225 :
4226 15 : return true;
4227 : }
4228 :
4229 21 : static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
4230 : struct dcerpc_pipe *p)
4231 : {
4232 3 : NTSTATUS status;
4233 3 : struct netr_NetrEnumerateTrustedDomains r;
4234 3 : struct netr_Blob trusted_domains_blob;
4235 21 : struct dcerpc_binding_handle *b = p->binding_handle;
4236 :
4237 21 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4238 21 : r.out.trusted_domains_blob = &trusted_domains_blob;
4239 :
4240 21 : status = dcerpc_netr_NetrEnumerateTrustedDomains_r(b, tctx, &r);
4241 21 : torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
4242 0 : torture_assert_ntstatus_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
4243 :
4244 0 : return true;
4245 : }
4246 :
4247 18 : static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
4248 : struct dcerpc_pipe *p)
4249 : {
4250 3 : NTSTATUS status;
4251 3 : struct netr_NetrEnumerateTrustedDomainsEx r;
4252 3 : struct netr_DomainTrustList dom_trust_list;
4253 18 : struct dcerpc_binding_handle *b = p->binding_handle;
4254 :
4255 18 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4256 18 : r.out.dom_trust_list = &dom_trust_list;
4257 :
4258 18 : status = dcerpc_netr_NetrEnumerateTrustedDomainsEx_r(b, tctx, &r);
4259 18 : torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
4260 0 : torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
4261 :
4262 0 : return true;
4263 : }
4264 :
4265 :
4266 54 : static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
4267 : const char *computer_name,
4268 : const char *expected_site)
4269 : {
4270 9 : NTSTATUS status;
4271 9 : struct netr_DsRGetSiteName r;
4272 54 : const char *site = NULL;
4273 54 : struct dcerpc_binding_handle *b = p->binding_handle;
4274 :
4275 54 : r.in.computer_name = computer_name;
4276 54 : r.out.site = &site;
4277 54 : torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
4278 :
4279 54 : status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
4280 54 : torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
4281 54 : torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
4282 54 : torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
4283 :
4284 45 : return true;
4285 : }
4286 :
4287 : /*
4288 : try a netlogon netr_DsRGetDCName
4289 : */
4290 18 : static bool test_netr_DsRGetDCName(struct torture_context *tctx,
4291 : struct dcerpc_pipe *p)
4292 : {
4293 3 : NTSTATUS status;
4294 3 : struct netr_DsRGetDCName r;
4295 18 : struct netr_DsRGetDCNameInfo *info = NULL;
4296 18 : struct dcerpc_binding_handle *b = p->binding_handle;
4297 :
4298 18 : r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4299 18 : r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
4300 18 : r.in.domain_guid = NULL;
4301 18 : r.in.site_guid = NULL;
4302 18 : r.in.flags = DS_RETURN_DNS_NAME;
4303 18 : r.out.info = &info;
4304 :
4305 18 : status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
4306 18 : torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
4307 18 : torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
4308 :
4309 18 : torture_assert_int_equal(tctx,
4310 : (info->dc_flags & (DS_DNS_CONTROLLER)),
4311 : DS_DNS_CONTROLLER,
4312 : "DsRGetDCName");
4313 18 : torture_assert_int_equal(tctx,
4314 : (info->dc_flags & (DS_DNS_DOMAIN)),
4315 : DS_DNS_DOMAIN,
4316 : "DsRGetDCName");
4317 18 : torture_assert_int_equal(tctx,
4318 : (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4319 : DS_DNS_FOREST_ROOT,
4320 : "DsRGetDCName");
4321 :
4322 18 : r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
4323 18 : r.in.flags = 0;
4324 :
4325 18 : status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
4326 18 : torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
4327 18 : torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
4328 :
4329 18 : torture_assert_int_equal(tctx,
4330 : (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
4331 : "DsRGetDCName");
4332 18 : torture_assert_int_equal(tctx,
4333 : (info->dc_flags & (DS_DNS_DOMAIN)), 0,
4334 : "DsRGetDCName");
4335 18 : torture_assert_int_equal(tctx,
4336 : (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4337 : DS_DNS_FOREST_ROOT,
4338 : "DsRGetDCName");
4339 :
4340 18 : if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
4341 18 : torture_assert_int_equal(tctx,
4342 : (info->dc_flags & (DS_SERVER_CLOSEST)),
4343 : DS_SERVER_CLOSEST,
4344 : "DsRGetDCName");
4345 : }
4346 :
4347 18 : return test_netr_DsRGetSiteName(p, tctx,
4348 15 : info->dc_unc,
4349 15 : info->dc_site_name);
4350 : }
4351 :
4352 : /*
4353 : try a netlogon netr_DsRGetDCNameEx
4354 : */
4355 18 : static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
4356 : struct dcerpc_pipe *p)
4357 : {
4358 3 : NTSTATUS status;
4359 3 : struct netr_DsRGetDCNameEx r;
4360 18 : struct netr_DsRGetDCNameInfo *info = NULL;
4361 18 : struct dcerpc_binding_handle *b = p->binding_handle;
4362 :
4363 18 : r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4364 18 : r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
4365 18 : r.in.domain_guid = NULL;
4366 18 : r.in.site_name = NULL;
4367 18 : r.in.flags = DS_RETURN_DNS_NAME;
4368 18 : r.out.info = &info;
4369 :
4370 18 : status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
4371 18 : torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
4372 18 : torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
4373 :
4374 18 : torture_assert_int_equal(tctx,
4375 : (info->dc_flags & (DS_DNS_CONTROLLER)),
4376 : DS_DNS_CONTROLLER,
4377 : "DsRGetDCNameEx");
4378 18 : torture_assert_int_equal(tctx,
4379 : (info->dc_flags & (DS_DNS_DOMAIN)),
4380 : DS_DNS_DOMAIN,
4381 : "DsRGetDCNameEx");
4382 18 : torture_assert_int_equal(tctx,
4383 : (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4384 : DS_DNS_FOREST_ROOT,
4385 : "DsRGetDCNameEx");
4386 :
4387 18 : r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
4388 18 : r.in.flags = 0;
4389 :
4390 18 : status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
4391 18 : torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
4392 18 : torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
4393 :
4394 18 : torture_assert_int_equal(tctx,
4395 : (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
4396 : "DsRGetDCNameEx");
4397 18 : torture_assert_int_equal(tctx,
4398 : (info->dc_flags & (DS_DNS_DOMAIN)), 0,
4399 : "DsRGetDCNameEx");
4400 18 : torture_assert_int_equal(tctx,
4401 : (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4402 : DS_DNS_FOREST_ROOT,
4403 : "DsRGetDCNameEx");
4404 :
4405 18 : if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
4406 18 : torture_assert_int_equal(tctx,
4407 : (info->dc_flags & (DS_SERVER_CLOSEST)),
4408 : DS_SERVER_CLOSEST,
4409 : "DsRGetDCNameEx");
4410 : }
4411 :
4412 18 : return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
4413 15 : info->dc_site_name);
4414 : }
4415 :
4416 : /*
4417 : try a netlogon netr_DsRGetDCNameEx2
4418 : */
4419 18 : static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
4420 : struct dcerpc_pipe *p)
4421 : {
4422 3 : NTSTATUS status;
4423 3 : struct netr_DsRGetDCNameEx2 r;
4424 18 : struct netr_DsRGetDCNameInfo *info = NULL;
4425 18 : struct dcerpc_binding_handle *b = p->binding_handle;
4426 :
4427 18 : torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with no inputs\n");
4428 18 : ZERO_STRUCT(r.in);
4429 18 : r.in.flags = DS_RETURN_DNS_NAME;
4430 18 : r.out.info = &info;
4431 :
4432 18 : status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
4433 18 : torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
4434 18 : torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
4435 :
4436 18 : torture_assert_int_equal(tctx,
4437 : (info->dc_flags & (DS_DNS_CONTROLLER)),
4438 : DS_DNS_CONTROLLER,
4439 : "DsRGetDCNameEx2");
4440 18 : torture_assert_int_equal(tctx,
4441 : (info->dc_flags & (DS_DNS_DOMAIN)),
4442 : DS_DNS_DOMAIN,
4443 : "DsRGetDCNameEx2");
4444 18 : torture_assert_int_equal(tctx,
4445 : (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4446 : DS_DNS_FOREST_ROOT,
4447 : "DsRGetDCNameEx2");
4448 :
4449 18 : r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4450 18 : r.in.client_account = NULL;
4451 18 : r.in.mask = 0x00000000;
4452 18 : r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
4453 18 : r.in.domain_guid = NULL;
4454 18 : r.in.site_name = NULL;
4455 18 : r.in.flags = DS_RETURN_DNS_NAME;
4456 18 : r.out.info = &info;
4457 :
4458 18 : torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
4459 :
4460 18 : status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
4461 18 : torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
4462 18 : torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
4463 :
4464 18 : r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
4465 18 : r.in.flags = 0;
4466 :
4467 18 : status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
4468 18 : torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
4469 18 : torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
4470 :
4471 18 : torture_assert_int_equal(tctx,
4472 : (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
4473 : "DsRGetDCNameEx2");
4474 18 : torture_assert_int_equal(tctx,
4475 : (info->dc_flags & (DS_DNS_DOMAIN)), 0,
4476 : "DsRGetDCNameEx2");
4477 18 : torture_assert_int_equal(tctx,
4478 : (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4479 : DS_DNS_FOREST_ROOT,
4480 : "DsRGetDCNameEx2");
4481 :
4482 18 : if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
4483 18 : torture_assert_int_equal(tctx,
4484 : (info->dc_flags & (DS_SERVER_CLOSEST)),
4485 : DS_SERVER_CLOSEST,
4486 : "DsRGetDCNameEx2");
4487 : }
4488 :
4489 18 : torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client account\n");
4490 18 : r.in.client_account = TEST_MACHINE_NAME"$";
4491 18 : r.in.mask = ACB_SVRTRUST;
4492 18 : r.in.flags = DS_RETURN_FLAT_NAME;
4493 18 : r.out.info = &info;
4494 :
4495 18 : status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
4496 18 : torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
4497 18 : torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
4498 :
4499 18 : return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
4500 18 : info->dc_site_name);
4501 : }
4502 :
4503 : /* This is a substitution for "samdb_server_site_name" which relies on the
4504 : * correct "lp_ctx" and therefore can't be used here. */
4505 195 : static const char *server_site_name(struct torture_context *tctx,
4506 : struct ldb_context *ldb)
4507 : {
4508 39 : TALLOC_CTX *tmp_ctx;
4509 39 : struct ldb_dn *dn, *server_dn;
4510 39 : const struct ldb_val *site_name_val;
4511 39 : const char *server_dn_str, *site_name;
4512 :
4513 195 : tmp_ctx = talloc_new(ldb);
4514 195 : if (tmp_ctx == NULL) {
4515 0 : goto failed;
4516 : }
4517 :
4518 195 : dn = ldb_dn_new(tmp_ctx, ldb, "");
4519 195 : if (dn == NULL) {
4520 0 : goto failed;
4521 : }
4522 :
4523 195 : server_dn_str = samdb_search_string(ldb, tmp_ctx, dn, "serverName",
4524 : NULL);
4525 195 : if (server_dn_str == NULL) {
4526 0 : goto failed;
4527 : }
4528 :
4529 195 : server_dn = ldb_dn_new(tmp_ctx, ldb, server_dn_str);
4530 195 : if (server_dn == NULL) {
4531 0 : goto failed;
4532 : }
4533 :
4534 : /* CN=<Server name>, CN=Servers, CN=<Site name>, CN=Sites, ... */
4535 195 : site_name_val = ldb_dn_get_component_val(server_dn, 2);
4536 195 : if (site_name_val == NULL) {
4537 0 : goto failed;
4538 : }
4539 :
4540 195 : site_name = (const char *) site_name_val->data;
4541 :
4542 195 : talloc_steal(tctx, site_name);
4543 195 : talloc_free(tmp_ctx);
4544 :
4545 195 : return site_name;
4546 :
4547 0 : failed:
4548 0 : talloc_free(tmp_ctx);
4549 0 : return NULL;
4550 : }
4551 :
4552 18 : static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
4553 : struct dcerpc_pipe *p)
4554 : {
4555 3 : char *url;
4556 18 : struct ldb_context *sam_ctx = NULL;
4557 3 : NTSTATUS status;
4558 3 : struct netr_DsrGetDcSiteCoverageW r;
4559 18 : struct DcSitesCtr *ctr = NULL;
4560 18 : struct dcerpc_binding_handle *b = p->binding_handle;
4561 :
4562 18 : torture_comment(tctx, "This does only pass with the default site\n");
4563 :
4564 : /* We won't double-check this when we are over 'local' transports */
4565 18 : if (dcerpc_server_name(p)) {
4566 : /* Set up connection to SAMDB on DC */
4567 15 : url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
4568 15 : sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
4569 : NULL,
4570 : samba_cmdline_get_creds(),
4571 : 0);
4572 :
4573 15 : torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
4574 : }
4575 :
4576 18 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4577 18 : r.out.ctr = &ctr;
4578 :
4579 18 : status = dcerpc_netr_DsrGetDcSiteCoverageW_r(b, tctx, &r);
4580 18 : torture_assert_ntstatus_ok(tctx, status, "failed");
4581 18 : torture_assert_werr_ok(tctx, r.out.result, "failed");
4582 :
4583 18 : torture_assert(tctx, ctr->num_sites == 1,
4584 : "we should per default only get the default site");
4585 18 : if (sam_ctx != NULL) {
4586 15 : torture_assert_casestr_equal(tctx, ctr->sites[0].string,
4587 : server_site_name(tctx, sam_ctx),
4588 : "didn't return default site");
4589 : }
4590 :
4591 15 : return true;
4592 : }
4593 :
4594 18 : static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
4595 : struct dcerpc_pipe *p)
4596 : {
4597 3 : char *url;
4598 18 : struct ldb_context *sam_ctx = NULL;
4599 3 : NTSTATUS status;
4600 3 : struct netr_DsRAddressToSitenamesW r;
4601 3 : struct netr_DsRAddress addrs[6];
4602 3 : struct sockaddr_in *addr;
4603 : #ifdef HAVE_IPV6
4604 3 : struct sockaddr_in6 *addr6;
4605 : #endif
4606 3 : struct netr_DsRAddressToSitenamesWCtr *ctr;
4607 18 : struct dcerpc_binding_handle *b = p->binding_handle;
4608 3 : uint32_t i;
4609 3 : int ret;
4610 :
4611 18 : torture_comment(tctx, "This does only pass with the default site\n");
4612 :
4613 : /* We won't double-check this when we are over 'local' transports */
4614 18 : if (dcerpc_server_name(p)) {
4615 : /* Set up connection to SAMDB on DC */
4616 15 : url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
4617 15 : sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
4618 : NULL,
4619 : samba_cmdline_get_creds(),
4620 : 0);
4621 :
4622 15 : torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
4623 : }
4624 :
4625 : /* First try valid IP addresses */
4626 :
4627 18 : addrs[0].size = sizeof(struct sockaddr_in);
4628 18 : addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
4629 18 : addr = (struct sockaddr_in *) addrs[0].buffer;
4630 18 : addrs[0].buffer[0] = AF_INET;
4631 18 : ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
4632 18 : torture_assert(tctx, ret > 0, "inet_pton failed");
4633 :
4634 18 : addrs[1].size = sizeof(struct sockaddr_in);
4635 18 : addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
4636 18 : addr = (struct sockaddr_in *) addrs[1].buffer;
4637 18 : addrs[1].buffer[0] = AF_INET;
4638 18 : ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
4639 18 : torture_assert(tctx, ret > 0, "inet_pton failed");
4640 :
4641 18 : addrs[2].size = sizeof(struct sockaddr_in);
4642 18 : addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
4643 18 : addr = (struct sockaddr_in *) addrs[2].buffer;
4644 18 : addrs[2].buffer[0] = AF_INET;
4645 18 : ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
4646 18 : torture_assert(tctx, ret > 0, "inet_pton failed");
4647 :
4648 : #ifdef HAVE_IPV6
4649 18 : addrs[3].size = sizeof(struct sockaddr_in6);
4650 18 : addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
4651 18 : addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
4652 18 : addrs[3].buffer[0] = AF_INET6;
4653 18 : ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
4654 18 : torture_assert(tctx, ret > 0, "inet_pton failed");
4655 :
4656 18 : addrs[4].size = sizeof(struct sockaddr_in6);
4657 18 : addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
4658 18 : addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
4659 18 : addrs[4].buffer[0] = AF_INET6;
4660 18 : ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
4661 18 : torture_assert(tctx, ret > 0, "inet_pton failed");
4662 :
4663 18 : addrs[5].size = sizeof(struct sockaddr_in6);
4664 18 : addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
4665 18 : addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
4666 18 : addrs[5].buffer[0] = AF_INET6;
4667 18 : ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
4668 18 : torture_assert(tctx, ret > 0, "inet_pton failed");
4669 : #else
4670 : /* the test cases are repeated to have exactly 6. This is for
4671 : * compatibility with IPv4-only machines */
4672 : addrs[3].size = sizeof(struct sockaddr_in);
4673 : addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
4674 : addr = (struct sockaddr_in *) addrs[3].buffer;
4675 : addrs[3].buffer[0] = AF_INET;
4676 : ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
4677 : torture_assert(tctx, ret > 0, "inet_pton failed");
4678 :
4679 : addrs[4].size = sizeof(struct sockaddr_in);
4680 : addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
4681 : addr = (struct sockaddr_in *) addrs[4].buffer;
4682 : addrs[4].buffer[0] = AF_INET;
4683 : ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
4684 : torture_assert(tctx, ret > 0, "inet_pton failed");
4685 :
4686 : addrs[5].size = sizeof(struct sockaddr_in);
4687 : addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
4688 : addr = (struct sockaddr_in *) addrs[5].buffer;
4689 : addrs[5].buffer[0] = AF_INET;
4690 : ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
4691 : torture_assert(tctx, ret > 0, "inet_pton failed");
4692 : #endif
4693 :
4694 18 : ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
4695 :
4696 18 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4697 18 : r.in.count = 6;
4698 18 : r.in.addresses = addrs;
4699 18 : r.out.ctr = &ctr;
4700 :
4701 18 : status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
4702 18 : torture_assert_ntstatus_ok(tctx, status, "failed");
4703 18 : torture_assert_werr_ok(tctx, r.out.result, "failed");
4704 :
4705 18 : if (sam_ctx != NULL) {
4706 60 : for (i = 0; i < 3; i++) {
4707 45 : torture_assert_casestr_equal(tctx,
4708 : ctr->sitename[i].string,
4709 : server_site_name(tctx, sam_ctx),
4710 : "didn't return default site");
4711 : }
4712 60 : for (i = 3; i < 6; i++) {
4713 : /* Windows returns "NULL" for the sitename if it isn't
4714 : * IPv6 configured */
4715 45 : if (torture_setting_bool(tctx, "samba4", false)) {
4716 45 : torture_assert_casestr_equal(tctx,
4717 : ctr->sitename[i].string,
4718 : server_site_name(tctx, sam_ctx),
4719 : "didn't return default site");
4720 : }
4721 : }
4722 : }
4723 :
4724 : /* Now try invalid ones (too short buffers) */
4725 :
4726 18 : addrs[0].size = 0;
4727 18 : addrs[1].size = 1;
4728 18 : addrs[2].size = 4;
4729 :
4730 18 : addrs[3].size = 0;
4731 18 : addrs[4].size = 1;
4732 18 : addrs[5].size = 4;
4733 :
4734 18 : status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
4735 18 : torture_assert_ntstatus_ok(tctx, status, "failed");
4736 18 : torture_assert_werr_ok(tctx, r.out.result, "failed");
4737 :
4738 126 : for (i = 0; i < 6; i++) {
4739 108 : torture_assert(tctx, ctr->sitename[i].string == NULL,
4740 : "sitename should be null");
4741 : }
4742 :
4743 : /* Now try invalid ones (wrong address types) */
4744 :
4745 18 : addrs[0].size = 10;
4746 18 : addrs[0].buffer[0] = AF_UNSPEC;
4747 18 : addrs[1].size = 10;
4748 18 : addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
4749 18 : addrs[2].size = 10;
4750 18 : addrs[2].buffer[0] = AF_UNIX;
4751 :
4752 18 : addrs[3].size = 10;
4753 18 : addrs[3].buffer[0] = 250;
4754 18 : addrs[4].size = 10;
4755 18 : addrs[4].buffer[0] = 251;
4756 18 : addrs[5].size = 10;
4757 18 : addrs[5].buffer[0] = 252;
4758 :
4759 18 : status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
4760 18 : torture_assert_ntstatus_ok(tctx, status, "failed");
4761 18 : torture_assert_werr_ok(tctx, r.out.result, "failed");
4762 :
4763 126 : for (i = 0; i < 6; i++) {
4764 108 : torture_assert(tctx, ctr->sitename[i].string == NULL,
4765 : "sitename should be null");
4766 : }
4767 :
4768 15 : return true;
4769 : }
4770 :
4771 18 : static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
4772 : struct dcerpc_pipe *p)
4773 : {
4774 3 : char *url;
4775 18 : struct ldb_context *sam_ctx = NULL;
4776 3 : NTSTATUS status;
4777 3 : struct netr_DsRAddressToSitenamesExW r;
4778 3 : struct netr_DsRAddress addrs[6];
4779 3 : struct sockaddr_in *addr;
4780 : #ifdef HAVE_IPV6
4781 3 : struct sockaddr_in6 *addr6;
4782 : #endif
4783 3 : struct netr_DsRAddressToSitenamesExWCtr *ctr;
4784 18 : struct dcerpc_binding_handle *b = p->binding_handle;
4785 3 : uint32_t i;
4786 3 : int ret;
4787 :
4788 18 : torture_comment(tctx, "This does pass with the default site\n");
4789 :
4790 : /* We won't double-check this when we are over 'local' transports */
4791 18 : if (dcerpc_server_name(p)) {
4792 : /* Set up connection to SAMDB on DC */
4793 15 : url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
4794 15 : sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
4795 : NULL,
4796 : samba_cmdline_get_creds(),
4797 : 0);
4798 :
4799 15 : torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
4800 : }
4801 :
4802 : /* First try valid IP addresses */
4803 :
4804 18 : addrs[0].size = sizeof(struct sockaddr_in);
4805 18 : addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
4806 18 : addr = (struct sockaddr_in *) addrs[0].buffer;
4807 18 : addrs[0].buffer[0] = AF_INET;
4808 18 : ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
4809 18 : torture_assert(tctx, ret > 0, "inet_pton failed");
4810 :
4811 18 : addrs[1].size = sizeof(struct sockaddr_in);
4812 18 : addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
4813 18 : addr = (struct sockaddr_in *) addrs[1].buffer;
4814 18 : addrs[1].buffer[0] = AF_INET;
4815 18 : ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
4816 18 : torture_assert(tctx, ret > 0, "inet_pton failed");
4817 :
4818 18 : addrs[2].size = sizeof(struct sockaddr_in);
4819 18 : addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
4820 18 : addr = (struct sockaddr_in *) addrs[2].buffer;
4821 18 : addrs[2].buffer[0] = AF_INET;
4822 18 : ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
4823 18 : torture_assert(tctx, ret > 0, "inet_pton failed");
4824 :
4825 : #ifdef HAVE_IPV6
4826 18 : addrs[3].size = sizeof(struct sockaddr_in6);
4827 18 : addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
4828 18 : addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
4829 18 : addrs[3].buffer[0] = AF_INET6;
4830 18 : ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
4831 18 : torture_assert(tctx, ret > 0, "inet_pton failed");
4832 :
4833 18 : addrs[4].size = sizeof(struct sockaddr_in6);
4834 18 : addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
4835 18 : addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
4836 18 : addrs[4].buffer[0] = AF_INET6;
4837 18 : ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
4838 18 : torture_assert(tctx, ret > 0, "inet_pton failed");
4839 :
4840 18 : addrs[5].size = sizeof(struct sockaddr_in6);
4841 18 : addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
4842 18 : addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
4843 18 : addrs[5].buffer[0] = AF_INET6;
4844 18 : ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
4845 18 : torture_assert(tctx, ret > 0, "inet_pton failed");
4846 : #else
4847 : /* the test cases are repeated to have exactly 6. This is for
4848 : * compatibility with IPv4-only machines */
4849 : addrs[3].size = sizeof(struct sockaddr_in);
4850 : addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
4851 : addr = (struct sockaddr_in *) addrs[3].buffer;
4852 : addrs[3].buffer[0] = AF_INET;
4853 : ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
4854 : torture_assert(tctx, ret > 0, "inet_pton failed");
4855 :
4856 : addrs[4].size = sizeof(struct sockaddr_in);
4857 : addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
4858 : addr = (struct sockaddr_in *) addrs[4].buffer;
4859 : addrs[4].buffer[0] = AF_INET;
4860 : ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
4861 : torture_assert(tctx, ret > 0, "inet_pton failed");
4862 :
4863 : addrs[5].size = sizeof(struct sockaddr_in);
4864 : addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
4865 : addr = (struct sockaddr_in *) addrs[5].buffer;
4866 : addrs[5].buffer[0] = AF_INET;
4867 : ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
4868 : torture_assert(tctx, ret > 0, "inet_pton failed");
4869 : #endif
4870 :
4871 18 : ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
4872 :
4873 18 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4874 18 : r.in.count = 6;
4875 18 : r.in.addresses = addrs;
4876 18 : r.out.ctr = &ctr;
4877 :
4878 18 : status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
4879 18 : torture_assert_ntstatus_ok(tctx, status, "failed");
4880 18 : torture_assert_werr_ok(tctx, r.out.result, "failed");
4881 :
4882 18 : if (sam_ctx != NULL) {
4883 60 : for (i = 0; i < 3; i++) {
4884 45 : torture_assert_casestr_equal(tctx,
4885 : ctr->sitename[i].string,
4886 : server_site_name(tctx, sam_ctx),
4887 : "didn't return default site");
4888 45 : torture_assert(tctx, ctr->subnetname[i].string == NULL,
4889 : "subnet should be null");
4890 : }
4891 60 : for (i = 3; i < 6; i++) {
4892 : /* Windows returns "NULL" for the sitename if it isn't
4893 : * IPv6 configured */
4894 45 : if (torture_setting_bool(tctx, "samba4", false)) {
4895 45 : torture_assert_casestr_equal(tctx,
4896 : ctr->sitename[i].string,
4897 : server_site_name(tctx, sam_ctx),
4898 : "didn't return default site");
4899 : }
4900 45 : torture_assert(tctx, ctr->subnetname[i].string == NULL,
4901 : "subnet should be null");
4902 : }
4903 : }
4904 :
4905 : /* Now try invalid ones (too short buffers) */
4906 :
4907 18 : addrs[0].size = 0;
4908 18 : addrs[1].size = 1;
4909 18 : addrs[2].size = 4;
4910 :
4911 18 : addrs[3].size = 0;
4912 18 : addrs[4].size = 1;
4913 18 : addrs[5].size = 4;
4914 :
4915 18 : status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
4916 18 : torture_assert_ntstatus_ok(tctx, status, "failed");
4917 18 : torture_assert_werr_ok(tctx, r.out.result, "failed");
4918 :
4919 126 : for (i = 0; i < 6; i++) {
4920 108 : torture_assert(tctx, ctr->sitename[i].string == NULL,
4921 : "sitename should be null");
4922 108 : torture_assert(tctx, ctr->subnetname[i].string == NULL,
4923 : "subnet should be null");
4924 : }
4925 :
4926 18 : addrs[0].size = 10;
4927 18 : addrs[0].buffer[0] = AF_UNSPEC;
4928 18 : addrs[1].size = 10;
4929 18 : addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
4930 18 : addrs[2].size = 10;
4931 18 : addrs[2].buffer[0] = AF_UNIX;
4932 :
4933 18 : addrs[3].size = 10;
4934 18 : addrs[3].buffer[0] = 250;
4935 18 : addrs[4].size = 10;
4936 18 : addrs[4].buffer[0] = 251;
4937 18 : addrs[5].size = 10;
4938 18 : addrs[5].buffer[0] = 252;
4939 :
4940 18 : status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
4941 18 : torture_assert_ntstatus_ok(tctx, status, "failed");
4942 18 : torture_assert_werr_ok(tctx, r.out.result, "failed");
4943 :
4944 126 : for (i = 0; i < 6; i++) {
4945 108 : torture_assert(tctx, ctr->sitename[i].string == NULL,
4946 : "sitename should be null");
4947 108 : torture_assert(tctx, ctr->subnetname[i].string == NULL,
4948 : "subnet should be null");
4949 : }
4950 :
4951 15 : return true;
4952 : }
4953 :
4954 36 : static bool test_netr_ServerGetTrustInfo_flags(struct torture_context *tctx,
4955 : struct dcerpc_pipe *p1,
4956 : struct cli_credentials *machine_credentials,
4957 : uint32_t negotiate_flags)
4958 : {
4959 6 : struct netr_ServerGetTrustInfo r;
4960 :
4961 6 : struct netr_Authenticator a;
4962 6 : struct netr_Authenticator return_authenticator;
4963 6 : struct samr_Password new_owf_password;
4964 6 : struct samr_Password old_owf_password;
4965 6 : struct netr_TrustInfo *trust_info;
4966 :
4967 6 : struct netlogon_creds_CredentialState *creds;
4968 36 : struct dcerpc_pipe *p = NULL;
4969 36 : struct dcerpc_binding_handle *b = NULL;
4970 :
4971 6 : struct samr_Password nt_hash;
4972 :
4973 36 : if (!test_SetupCredentials3(p1, tctx, negotiate_flags,
4974 : machine_credentials, &creds)) {
4975 0 : return false;
4976 : }
4977 36 : if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
4978 : DCERPC_SIGN | DCERPC_SEAL, &p)) {
4979 0 : return false;
4980 : }
4981 36 : b = p->binding_handle;
4982 :
4983 36 : netlogon_creds_client_authenticator(creds, &a);
4984 :
4985 36 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4986 36 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
4987 36 : r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
4988 36 : r.in.computer_name = TEST_MACHINE_NAME;
4989 36 : r.in.credential = &a;
4990 :
4991 36 : r.out.return_authenticator = &return_authenticator;
4992 36 : r.out.new_owf_password = &new_owf_password;
4993 36 : r.out.old_owf_password = &old_owf_password;
4994 36 : r.out.trust_info = &trust_info;
4995 :
4996 36 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerGetTrustInfo_r(b, tctx, &r),
4997 : "ServerGetTrustInfo failed");
4998 36 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerGetTrustInfo failed");
4999 36 : torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
5000 :
5001 36 : E_md4hash(cli_credentials_get_password(machine_credentials), nt_hash.hash);
5002 :
5003 36 : netlogon_creds_des_decrypt(creds, &new_owf_password);
5004 :
5005 36 : dump_data(1, new_owf_password.hash, 16);
5006 36 : dump_data(1, nt_hash.hash, 16);
5007 :
5008 36 : torture_assert_mem_equal(tctx, new_owf_password.hash, nt_hash.hash, 16,
5009 : "received unexpected owf password\n");
5010 :
5011 30 : return true;
5012 : }
5013 :
5014 18 : static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
5015 : struct dcerpc_pipe *p,
5016 : struct cli_credentials *machine_credentials)
5017 : {
5018 18 : return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
5019 : NETLOGON_NEG_AUTH2_ADS_FLAGS);
5020 : }
5021 :
5022 18 : static bool test_netr_ServerGetTrustInfo_AES(struct torture_context *tctx,
5023 : struct dcerpc_pipe *p,
5024 : struct cli_credentials *machine_credentials)
5025 : {
5026 18 : return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
5027 : NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
5028 : }
5029 :
5030 18 : static bool test_GetDomainInfo(struct torture_context *tctx,
5031 : struct dcerpc_pipe *p1,
5032 : struct cli_credentials *machine_credentials)
5033 : {
5034 3 : struct netr_LogonGetDomainInfo r;
5035 3 : struct netr_WorkstationInformation q1;
5036 3 : struct netr_Authenticator a;
5037 3 : struct netlogon_creds_CredentialState *creds;
5038 3 : struct netr_OsVersion os;
5039 3 : union netr_WorkstationInfo query;
5040 3 : union netr_DomainInfo info;
5041 18 : const char* const attrs[] = { "dNSHostName", "operatingSystem",
5042 : "operatingSystemServicePack", "operatingSystemVersion",
5043 : "servicePrincipalName", NULL };
5044 3 : char *url;
5045 18 : struct ldb_context *sam_ctx = NULL;
5046 3 : struct ldb_message **res;
5047 3 : struct ldb_message_element *spn_el;
5048 3 : int ret, i;
5049 3 : char *version_str;
5050 18 : const char *old_dnsname = NULL;
5051 18 : char **spns = NULL;
5052 18 : int num_spns = 0;
5053 18 : char *temp_str = NULL;
5054 18 : char *temp_str2 = NULL;
5055 18 : struct dcerpc_pipe *p = NULL;
5056 18 : struct dcerpc_binding_handle *b = NULL;
5057 18 : struct netr_OneDomainInfo *odi1 = NULL;
5058 18 : struct netr_OneDomainInfo *odi2 = NULL;
5059 18 : struct netr_trust_extension_info *tex2 = NULL;
5060 :
5061 18 : torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
5062 :
5063 18 : if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
5064 : machine_credentials, &creds)) {
5065 0 : return false;
5066 : }
5067 18 : if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
5068 : DCERPC_SIGN | DCERPC_SEAL, &p)) {
5069 0 : return false;
5070 : }
5071 18 : b = p->binding_handle;
5072 :
5073 : /* We won't double-check this when we are over 'local' transports */
5074 18 : if (dcerpc_server_name(p)) {
5075 : /* Set up connection to SAMDB on DC */
5076 15 : url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
5077 15 : sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
5078 : NULL,
5079 : samba_cmdline_get_creds(),
5080 : 0);
5081 :
5082 15 : torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
5083 : }
5084 :
5085 18 : torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
5086 18 : netlogon_creds_client_authenticator(creds, &a);
5087 :
5088 18 : ZERO_STRUCT(r);
5089 18 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
5090 18 : r.in.computer_name = TEST_MACHINE_NAME;
5091 18 : r.in.credential = &a;
5092 18 : r.in.level = 1;
5093 18 : r.in.return_authenticator = &a;
5094 18 : r.in.query = &query;
5095 18 : r.out.return_authenticator = &a;
5096 18 : r.out.info = &info;
5097 :
5098 18 : ZERO_STRUCT(os);
5099 18 : os.os.MajorVersion = 123;
5100 18 : os.os.MinorVersion = 456;
5101 18 : os.os.BuildNumber = 789;
5102 18 : os.os.CSDVersion = "Service Pack 10";
5103 18 : os.os.ServicePackMajor = 10;
5104 18 : os.os.ServicePackMinor = 1;
5105 18 : os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
5106 18 : os.os.ProductType = NETR_VER_NT_SERVER;
5107 18 : os.os.Reserved = 0;
5108 :
5109 18 : version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
5110 : os.os.MinorVersion, os.os.BuildNumber);
5111 :
5112 18 : ZERO_STRUCT(q1);
5113 18 : q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
5114 : lpcfg_dnsdomain(tctx->lp_ctx));
5115 18 : q1.sitename = "Default-First-Site-Name";
5116 18 : q1.os_version.os = &os;
5117 18 : q1.os_name.string = talloc_asprintf(tctx,
5118 : "Tortured by Samba4 RPC-NETLOGON: %s",
5119 : timestring(tctx, time(NULL)));
5120 :
5121 : /* The workstation handles the "servicePrincipalName" and DNS hostname
5122 : updates */
5123 18 : q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
5124 :
5125 18 : query.workstation_info = &q1;
5126 :
5127 18 : if (sam_ctx) {
5128 : /* Gets back the old DNS hostname in AD */
5129 15 : ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
5130 : "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
5131 3 : old_dnsname =
5132 15 : ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
5133 :
5134 : /* Gets back the "servicePrincipalName"s in AD */
5135 15 : spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5136 15 : if (spn_el != NULL) {
5137 45 : for (i=0; i < spn_el->num_values; i++) {
5138 30 : spns = talloc_realloc(tctx, spns, char *, i + 1);
5139 30 : spns[i] = (char *) spn_el->values[i].data;
5140 : }
5141 12 : num_spns = i;
5142 : }
5143 : }
5144 :
5145 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5146 : "LogonGetDomainInfo failed");
5147 18 : torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5148 18 : torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5149 :
5150 18 : smb_msleep(250);
5151 :
5152 18 : if (sam_ctx) {
5153 : /* AD workstation infos entry check */
5154 15 : ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
5155 : "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
5156 15 : torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
5157 15 : torture_assert_str_equal(tctx,
5158 : ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
5159 : q1.os_name.string, "'operatingSystem' wrong!");
5160 15 : torture_assert_str_equal(tctx,
5161 : ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
5162 : os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
5163 15 : torture_assert_str_equal(tctx,
5164 : ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
5165 : version_str, "'operatingSystemVersion' wrong!");
5166 :
5167 15 : if (old_dnsname != NULL) {
5168 : /* If before a DNS hostname was set then it should remain
5169 : the same in combination with the "servicePrincipalName"s.
5170 : The DNS hostname should also be returned by our
5171 : "LogonGetDomainInfo" call (in the domain info structure). */
5172 :
5173 15 : torture_assert_str_equal(tctx,
5174 : ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
5175 : old_dnsname, "'DNS hostname' was not set!");
5176 :
5177 15 : spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5178 15 : torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
5179 : "'servicePrincipalName's not set!");
5180 15 : torture_assert(tctx, spn_el->num_values == num_spns,
5181 : "'servicePrincipalName's incorrect!");
5182 45 : for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
5183 30 : torture_assert_str_equal(tctx,
5184 : (char *) spn_el->values[i].data,
5185 : spns[i], "'servicePrincipalName's incorrect!");
5186 :
5187 15 : torture_assert_str_equal(tctx,
5188 : info.domain_info->dns_hostname.string,
5189 : old_dnsname,
5190 : "Out 'DNS hostname' doesn't match the old one!");
5191 : } else {
5192 : /* If no DNS hostname was set then also now none should be set,
5193 : the "servicePrincipalName"s should remain empty and no DNS
5194 : hostname should be returned by our "LogonGetDomainInfo"
5195 : call (in the domain info structure). */
5196 :
5197 0 : torture_assert(tctx,
5198 : ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
5199 : "'DNS hostname' was set!");
5200 :
5201 0 : spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5202 0 : torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
5203 : "'servicePrincipalName's were set!");
5204 :
5205 0 : torture_assert(tctx,
5206 : info.domain_info->dns_hostname.string == NULL,
5207 : "Out 'DNS host name' was set!");
5208 : }
5209 : }
5210 :
5211 : /* Checks "workstation flags" */
5212 18 : torture_assert(tctx,
5213 : info.domain_info->workstation_flags
5214 : == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
5215 : "Out 'workstation flags' don't match!");
5216 :
5217 :
5218 18 : torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname doesn't work)\n");
5219 18 : netlogon_creds_client_authenticator(creds, &a);
5220 :
5221 : /* Wipe out the CSDVersion, and prove which values still 'stick' */
5222 18 : os.os.CSDVersion = "";
5223 :
5224 : /* Change also the DNS hostname to test differences in behaviour */
5225 18 : talloc_free(discard_const_p(char, q1.dns_hostname));
5226 18 : q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
5227 : lpcfg_dnsdomain(tctx->lp_ctx));
5228 :
5229 : /* The workstation handles the "servicePrincipalName" and DNS hostname
5230 : updates */
5231 18 : q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
5232 :
5233 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5234 : "LogonGetDomainInfo failed");
5235 18 : torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5236 :
5237 18 : torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5238 :
5239 18 : smb_msleep(250);
5240 :
5241 18 : if (sam_ctx) {
5242 : /* AD workstation infos entry check */
5243 15 : ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
5244 : "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
5245 15 : torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
5246 :
5247 15 : torture_assert_str_equal(tctx,
5248 : ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
5249 : q1.os_name.string, "'operatingSystem' should stick!");
5250 15 : torture_assert(tctx,
5251 : ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
5252 : "'operatingSystemServicePack' shouldn't stick!");
5253 15 : torture_assert_str_equal(tctx,
5254 : ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
5255 : version_str, "'operatingSystemVersion' wrong!");
5256 :
5257 : /* The DNS host name shouldn't have been updated by the server */
5258 :
5259 15 : torture_assert_str_equal(tctx,
5260 : ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
5261 : old_dnsname, "'DNS host name' did change!");
5262 :
5263 : /* Find the two "servicePrincipalName"s which the DC shouldn't have been
5264 : updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
5265 : 3.5.4.3.9 */
5266 15 : spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5267 15 : torture_assert(tctx, spn_el != NULL,
5268 : "There should exist 'servicePrincipalName's in AD!");
5269 15 : temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
5270 33 : for (i=0; i < spn_el->num_values; i++)
5271 30 : if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
5272 12 : break;
5273 15 : torture_assert(tctx, i != spn_el->num_values,
5274 : "'servicePrincipalName' HOST/<Netbios name> not found!");
5275 15 : temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
5276 18 : for (i=0; i < spn_el->num_values; i++)
5277 15 : if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
5278 12 : break;
5279 15 : torture_assert(tctx, i != spn_el->num_values,
5280 : "'servicePrincipalName' HOST/<FQDN name> not found!");
5281 :
5282 : /* Check that the out DNS hostname was set properly */
5283 15 : torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
5284 : old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
5285 : }
5286 :
5287 : /* Checks "workstation flags" */
5288 18 : torture_assert(tctx,
5289 : info.domain_info->workstation_flags == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
5290 : "Out 'workstation flags' don't match!");
5291 :
5292 :
5293 : /* Now try the same but the workstation flags set to 0 */
5294 :
5295 18 : torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (variation of DNS hostname doesn't work)\n");
5296 18 : netlogon_creds_client_authenticator(creds, &a);
5297 :
5298 : /* Change also the DNS hostname to test differences in behaviour */
5299 18 : talloc_free(discard_const_p(char, q1.dns_hostname));
5300 18 : q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
5301 : lpcfg_dnsdomain(tctx->lp_ctx));
5302 :
5303 : /* Wipe out the osVersion, and prove which values still 'stick' */
5304 18 : q1.os_version.os = NULL;
5305 :
5306 : /* Let the DC handle the "servicePrincipalName" and DNS hostname
5307 : updates */
5308 18 : q1.workstation_flags = 0;
5309 :
5310 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5311 : "LogonGetDomainInfo failed");
5312 18 : torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5313 18 : torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5314 :
5315 18 : smb_msleep(250);
5316 :
5317 18 : if (sam_ctx) {
5318 : /* AD workstation infos entry check */
5319 15 : ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
5320 : "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
5321 15 : torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
5322 :
5323 15 : torture_assert_str_equal(tctx,
5324 : ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
5325 : q1.os_name.string, "'operatingSystem' should stick!");
5326 15 : torture_assert(tctx,
5327 : ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
5328 : "'operatingSystemServicePack' shouldn't stick!");
5329 15 : torture_assert_str_equal(tctx,
5330 : ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
5331 : version_str, "'operatingSystemVersion' wrong!");
5332 :
5333 : /* The DNS host name shouldn't have been updated by the server */
5334 :
5335 15 : torture_assert_str_equal(tctx,
5336 : ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
5337 : old_dnsname, "'DNS host name' did change!");
5338 :
5339 : /* Find the two "servicePrincipalName"s which the DC shouldn't have been
5340 : updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
5341 : 3.5.4.3.9 */
5342 15 : spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5343 15 : torture_assert(tctx, spn_el != NULL,
5344 : "There should exist 'servicePrincipalName's in AD!");
5345 15 : temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
5346 33 : for (i=0; i < spn_el->num_values; i++)
5347 30 : if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
5348 12 : break;
5349 15 : torture_assert(tctx, i != spn_el->num_values,
5350 : "'servicePrincipalName' HOST/<Netbios name> not found!");
5351 15 : temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
5352 18 : for (i=0; i < spn_el->num_values; i++)
5353 15 : if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
5354 12 : break;
5355 15 : torture_assert(tctx, i != spn_el->num_values,
5356 : "'servicePrincipalName' HOST/<FQDN name> not found!");
5357 :
5358 : /* Here the server gives us NULL as the out DNS hostname */
5359 15 : torture_assert(tctx, info.domain_info->dns_hostname.string == NULL,
5360 : "Out 'DNS hostname' should be NULL!");
5361 : }
5362 :
5363 : /* Checks "workstation flags" */
5364 18 : torture_assert(tctx,
5365 : info.domain_info->workstation_flags == 0,
5366 : "Out 'workstation flags' don't match!");
5367 :
5368 :
5369 18 : torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (verification of DNS hostname and check for trusted domains)\n");
5370 18 : netlogon_creds_client_authenticator(creds, &a);
5371 :
5372 : /* Put the DNS hostname back */
5373 18 : talloc_free(discard_const_p(char, q1.dns_hostname));
5374 18 : q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
5375 : lpcfg_dnsdomain(tctx->lp_ctx));
5376 :
5377 : /* The workstation handles the "servicePrincipalName" and DNS hostname
5378 : updates */
5379 18 : q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
5380 :
5381 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5382 : "LogonGetDomainInfo failed");
5383 18 : torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5384 18 : torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5385 :
5386 18 : smb_msleep(250);
5387 :
5388 : /* Now the in/out DNS hostnames should be the same */
5389 18 : torture_assert_str_equal(tctx,
5390 : info.domain_info->dns_hostname.string,
5391 : query.workstation_info->dns_hostname,
5392 : "In/Out 'DNS hostnames' don't match!");
5393 18 : old_dnsname = info.domain_info->dns_hostname.string;
5394 :
5395 : /* Checks "workstation flags" */
5396 18 : torture_assert(tctx,
5397 : info.domain_info->workstation_flags
5398 : == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
5399 : "Out 'workstation flags' don't match!");
5400 :
5401 : /* Checks for trusted domains */
5402 18 : torture_assert(tctx,
5403 : (info.domain_info->trusted_domain_count != 0)
5404 : && (info.domain_info->trusted_domains != NULL),
5405 : "Trusted domains have been requested!");
5406 :
5407 :
5408 18 : torture_comment(tctx, "Testing netr_LogonGetDomainInfo 5th call (check for trusted domains)\n");
5409 18 : netlogon_creds_client_authenticator(creds, &a);
5410 :
5411 : /* The workstation handles the "servicePrincipalName" and DNS hostname
5412 : updates and requests inbound trusts */
5413 18 : q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
5414 : | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
5415 :
5416 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5417 : "LogonGetDomainInfo failed");
5418 18 : torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5419 18 : torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5420 :
5421 18 : smb_msleep(250);
5422 :
5423 : /* Checks "workstation flags" */
5424 18 : torture_assert(tctx,
5425 : info.domain_info->workstation_flags
5426 : == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
5427 : | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
5428 : "Out 'workstation flags' don't match!");
5429 :
5430 : /* Checks for trusted domains */
5431 18 : torture_assert(tctx,
5432 : (info.domain_info->trusted_domain_count != 0)
5433 : && (info.domain_info->trusted_domains != NULL),
5434 : "Trusted domains have been requested!");
5435 :
5436 18 : odi1 = &info.domain_info->primary_domain;
5437 :
5438 18 : torture_assert(tctx, !GUID_all_zero(&odi1->domain_guid),
5439 : "primary domain_guid needs to be valid");
5440 :
5441 36 : for (i=0; i < info.domain_info->trusted_domain_count; i++) {
5442 18 : struct netr_OneDomainInfo *odiT =
5443 18 : &info.domain_info->trusted_domains[i];
5444 18 : struct netr_trust_extension_info *texT = NULL;
5445 :
5446 18 : torture_assert_int_equal(tctx, odiT->trust_extension.length, 16,
5447 : "trust_list should have extension");
5448 18 : torture_assert(tctx, odiT->trust_extension.info != NULL,
5449 : "trust_list should have extension");
5450 18 : texT = &odiT->trust_extension.info->info;
5451 :
5452 18 : if (GUID_equal(&odiT->domain_guid, &odi1->domain_guid)) {
5453 18 : odi2 = odiT;
5454 18 : tex2 = texT;
5455 18 : continue;
5456 : }
5457 :
5458 0 : torture_assert_int_equal(tctx,
5459 : texT->flags & NETR_TRUST_FLAG_PRIMARY,
5460 : 0,
5461 : "trust_list flags should not have PRIMARY");
5462 :
5463 0 : torture_assert(tctx, odiT->domainname.string != NULL,
5464 : "trust_list domainname should be valid");
5465 0 : if (texT->trust_type == LSA_TRUST_TYPE_DOWNLEVEL ||
5466 0 : texT->trust_type == LSA_TRUST_TYPE_MIT)
5467 : {
5468 0 : torture_assert(tctx, odiT->dns_domainname.string == NULL,
5469 : "trust_list dns_domainname should be NULL for downlevel or MIT");
5470 : } else {
5471 0 : torture_assert(tctx, odiT->dns_domainname.string != NULL,
5472 : "trust_list dns_domainname should be valid for uplevel");
5473 : }
5474 0 : torture_assert(tctx, odiT->dns_forestname.string == NULL,
5475 : "trust_list dns_forestname needs to be NULL");
5476 :
5477 3 : torture_assert(tctx, odiT->domain_sid != NULL,
5478 : "trust_list domain_sid needs to be valid");
5479 : }
5480 :
5481 18 : torture_assert(tctx, odi2 != NULL,
5482 : "trust_list primary domain not found.");
5483 :
5484 18 : torture_assert_str_equal(tctx,
5485 : odi1->domainname.string,
5486 : odi2->domainname.string,
5487 : "netbios name should match");
5488 :
5489 18 : temp_str = talloc_strdup(tctx, odi1->dns_domainname.string);
5490 18 : torture_assert(tctx, temp_str != NULL,
5491 : "primary_domain dns_domainname copy");
5492 18 : temp_str2 = strrchr(temp_str, '.');
5493 18 : torture_assert(tctx, temp_str2 != NULL && temp_str2[1] == '\0',
5494 : "primary_domain dns_domainname needs trailing '.'");
5495 18 : temp_str2[0] = '\0';
5496 18 : torture_assert_str_equal(tctx,
5497 : temp_str,
5498 : odi2->dns_domainname.string,
5499 : "dns domainname should match "
5500 : "(without trailing '.')");
5501 :
5502 18 : temp_str = talloc_strdup(tctx, odi1->dns_forestname.string);
5503 18 : torture_assert(tctx, temp_str != NULL,
5504 : "primary_domain dns_forestname copy");
5505 18 : temp_str2 = strrchr(temp_str, '.');
5506 18 : torture_assert(tctx, temp_str2 != NULL && temp_str2[1] == '\0',
5507 : "primary_domain dns_forestname needs trailing '.'");
5508 18 : temp_str2[0] = '\0';
5509 18 : torture_assert(tctx, odi2->dns_forestname.string == NULL,
5510 : "trust_list dns_forestname needs to be NULL");
5511 :
5512 18 : torture_assert_guid_equal(tctx, odi1->domain_guid, odi2->domain_guid,
5513 : "domain_guid should match");
5514 18 : torture_assert(tctx, odi1->domain_sid != NULL,
5515 : "primary domain_sid needs to be valid");
5516 18 : torture_assert(tctx, odi2->domain_sid != NULL,
5517 : "trust_list domain_sid needs to be valid");
5518 18 : torture_assert_sid_equal(tctx, odi1->domain_sid, odi2->domain_sid,
5519 : "domain_sid should match");
5520 :
5521 18 : torture_assert_int_equal(tctx, odi1->trust_extension.length, 0,
5522 : "primary_domain should not have extension");
5523 18 : torture_assert_int_equal(tctx, odi2->trust_extension.length, 16,
5524 : "trust_list should have extension");
5525 18 : torture_assert(tctx, odi2->trust_extension.info != NULL,
5526 : "trust_list should have extension");
5527 18 : tex2 = &odi2->trust_extension.info->info;
5528 18 : torture_assert_int_equal(tctx,
5529 : tex2->flags & NETR_TRUST_FLAG_PRIMARY,
5530 : NETR_TRUST_FLAG_PRIMARY,
5531 : "trust_list flags should have PRIMARY");
5532 18 : torture_assert_int_equal(tctx,
5533 : tex2->flags & NETR_TRUST_FLAG_IN_FOREST,
5534 : NETR_TRUST_FLAG_IN_FOREST,
5535 : "trust_list flags should have IN_FOREST");
5536 18 : torture_assert_int_equal(tctx,
5537 : tex2->flags & NETR_TRUST_FLAG_NATIVE,
5538 : NETR_TRUST_FLAG_NATIVE,
5539 : "trust_list flags should have NATIVE");
5540 18 : torture_assert_int_equal(tctx,
5541 : tex2->flags & ~NETR_TRUST_FLAG_TREEROOT,
5542 : NETR_TRUST_FLAG_IN_FOREST |
5543 : NETR_TRUST_FLAG_PRIMARY |
5544 : NETR_TRUST_FLAG_NATIVE,
5545 : "trust_list flags IN_FOREST, PRIMARY, NATIVE "
5546 : "(TREEROOT optional)");
5547 18 : if (strcmp(odi1->dns_domainname.string, odi1->dns_forestname.string) == 0) {
5548 18 : torture_assert_int_equal(tctx,
5549 : tex2->flags & NETR_TRUST_FLAG_TREEROOT,
5550 : NETR_TRUST_FLAG_TREEROOT,
5551 : "trust_list flags TREEROOT on forest root");
5552 18 : torture_assert_int_equal(tctx,
5553 : tex2->parent_index, 0,
5554 : "trust_list no parent on forest root");
5555 : }
5556 18 : torture_assert_int_equal(tctx,
5557 : tex2->trust_type, LSA_TRUST_TYPE_UPLEVEL,
5558 : "trust_list uplevel");
5559 18 : torture_assert_int_equal(tctx,
5560 : tex2->trust_attributes, 0,
5561 : "trust_list no attributes");
5562 :
5563 18 : torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
5564 18 : netlogon_creds_client_authenticator(creds, &a);
5565 :
5566 18 : query.workstation_info->dns_hostname = NULL;
5567 :
5568 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5569 : "LogonGetDomainInfo failed");
5570 18 : torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5571 18 : torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5572 :
5573 : /* The old DNS hostname should stick */
5574 18 : torture_assert_str_equal(tctx,
5575 : info.domain_info->dns_hostname.string,
5576 : old_dnsname,
5577 : "'DNS hostname' changed!");
5578 :
5579 18 : torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (extra workstation flags)\n");
5580 18 : netlogon_creds_client_authenticator(creds, &a);
5581 :
5582 18 : q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
5583 : | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | 0x4;
5584 :
5585 : /* Put the DNS hostname back */
5586 18 : talloc_free(discard_const_p(char, q1.dns_hostname));
5587 18 : q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
5588 : lpcfg_dnsdomain(tctx->lp_ctx));
5589 :
5590 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5591 : "LogonGetDomainInfo failed");
5592 18 : torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5593 18 : torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5594 :
5595 : /* Checks "workstation flags" */
5596 18 : torture_assert(tctx,
5597 : info.domain_info->workstation_flags
5598 : == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
5599 : | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
5600 : "Out 'workstation flags' don't match!");
5601 :
5602 18 : if (!torture_setting_bool(tctx, "dangerous", false)) {
5603 18 : torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 8th call (no workstation info) - enable dangerous tests in order to do so\n");
5604 : } else {
5605 : /* Try a call without the workstation information structure */
5606 :
5607 0 : torture_comment(tctx, "Testing netr_LogonGetDomainInfo 8th call (no workstation info)\n");
5608 0 : netlogon_creds_client_authenticator(creds, &a);
5609 :
5610 0 : query.workstation_info = NULL;
5611 :
5612 0 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5613 : "LogonGetDomainInfo failed");
5614 0 : torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5615 0 : torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5616 : }
5617 :
5618 15 : return true;
5619 : }
5620 :
5621 0 : static bool test_GetDomainInfo_async(struct torture_context *tctx,
5622 : struct dcerpc_pipe *p1,
5623 : struct cli_credentials *machine_credentials)
5624 : {
5625 0 : NTSTATUS status;
5626 0 : struct netr_LogonGetDomainInfo r;
5627 0 : struct netr_WorkstationInformation q1;
5628 0 : struct netr_Authenticator a;
5629 : #define ASYNC_COUNT 100
5630 0 : struct netlogon_creds_CredentialState *creds;
5631 0 : struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
5632 0 : struct tevent_req *req[ASYNC_COUNT];
5633 0 : int i;
5634 0 : union netr_WorkstationInfo query;
5635 0 : union netr_DomainInfo info;
5636 0 : struct dcerpc_pipe *p = NULL;
5637 :
5638 0 : torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
5639 :
5640 0 : if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
5641 : machine_credentials, &creds)) {
5642 0 : return false;
5643 : }
5644 0 : if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
5645 : DCERPC_SIGN | DCERPC_SEAL, &p)) {
5646 0 : return false;
5647 : }
5648 :
5649 0 : ZERO_STRUCT(r);
5650 0 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
5651 0 : r.in.computer_name = TEST_MACHINE_NAME;
5652 0 : r.in.credential = &a;
5653 0 : r.in.level = 1;
5654 0 : r.in.return_authenticator = &a;
5655 0 : r.in.query = &query;
5656 0 : r.out.return_authenticator = &a;
5657 0 : r.out.info = &info;
5658 :
5659 0 : ZERO_STRUCT(q1);
5660 0 : q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
5661 : lpcfg_dnsdomain(tctx->lp_ctx));
5662 0 : q1.sitename = "Default-First-Site-Name";
5663 0 : q1.os_name.string = "UNIX/Linux or similar";
5664 :
5665 0 : query.workstation_info = &q1;
5666 :
5667 0 : for (i=0;i<ASYNC_COUNT;i++) {
5668 0 : netlogon_creds_client_authenticator(creds, &a);
5669 :
5670 0 : creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
5671 0 : req[i] = dcerpc_netr_LogonGetDomainInfo_r_send(tctx, tctx->ev, p->binding_handle, &r);
5672 :
5673 : /* even with this flush per request a w2k3 server seems to
5674 : clag with multiple outstanding requests. bleergh. */
5675 0 : torture_assert_int_equal(tctx, tevent_loop_once(tctx->ev), 0,
5676 : "tevent_loop_once failed");
5677 : }
5678 :
5679 0 : for (i=0;i<ASYNC_COUNT;i++) {
5680 0 : torture_assert_int_equal(tctx, tevent_req_poll(req[i], tctx->ev), true,
5681 : "tevent_req_poll() failed");
5682 :
5683 0 : status = dcerpc_netr_LogonGetDomainInfo_r_recv(req[i], tctx);
5684 :
5685 0 : torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
5686 0 : torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
5687 :
5688 0 : torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred),
5689 : "Credential chaining failed at async");
5690 : }
5691 :
5692 0 : torture_comment(tctx,
5693 : "Testing netr_LogonGetDomainInfo - async count %d OK\n", ASYNC_COUNT);
5694 :
5695 0 : return true;
5696 : }
5697 :
5698 18 : static bool test_ManyGetDCName(struct torture_context *tctx,
5699 : struct dcerpc_pipe *p)
5700 : {
5701 3 : NTSTATUS status;
5702 3 : struct cli_credentials *anon_creds;
5703 3 : struct dcerpc_binding *binding2;
5704 3 : struct dcerpc_pipe *p2;
5705 3 : struct lsa_ObjectAttribute attr;
5706 3 : struct lsa_QosInfo qos;
5707 3 : struct lsa_OpenPolicy2 o;
5708 3 : struct policy_handle lsa_handle;
5709 3 : struct lsa_DomainList domains;
5710 :
5711 3 : struct lsa_EnumTrustDom t;
5712 18 : uint32_t resume_handle = 0;
5713 3 : struct netr_GetAnyDCName d;
5714 18 : const char *dcname = NULL;
5715 18 : struct dcerpc_binding_handle *b = p->binding_handle;
5716 3 : struct dcerpc_binding_handle *b2;
5717 :
5718 3 : int i;
5719 :
5720 18 : if (p->conn->transport.transport != NCACN_NP) {
5721 6 : torture_skip(tctx, "test_ManyGetDCName works only with NCACN_NP");
5722 : }
5723 :
5724 12 : torture_comment(tctx, "Torturing GetDCName\n");
5725 :
5726 12 : anon_creds = cli_credentials_init_anon(tctx);
5727 12 : torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed");
5728 :
5729 12 : binding2 = dcerpc_binding_dup(tctx, p->binding);
5730 : /* Swap the binding details from NETLOGON to LSA */
5731 12 : status = dcerpc_epm_map_binding(tctx, binding2, &ndr_table_lsarpc, tctx->ev, tctx->lp_ctx);
5732 12 : dcerpc_binding_set_assoc_group_id(binding2, 0);
5733 12 : torture_assert_ntstatus_ok(tctx, status, "epm map");
5734 :
5735 12 : status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_lsarpc,
5736 : anon_creds, tctx->lp_ctx,
5737 : tctx, &p2);
5738 12 : torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
5739 12 : b2 = p2->binding_handle;
5740 :
5741 12 : qos.len = 0;
5742 12 : qos.impersonation_level = 2;
5743 12 : qos.context_mode = 1;
5744 12 : qos.effective_only = 0;
5745 :
5746 12 : attr.len = 0;
5747 12 : attr.root_dir = NULL;
5748 12 : attr.object_name = NULL;
5749 12 : attr.attributes = 0;
5750 12 : attr.sec_desc = NULL;
5751 12 : attr.sec_qos = &qos;
5752 :
5753 12 : o.in.system_name = "\\";
5754 12 : o.in.attr = &attr;
5755 12 : o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5756 12 : o.out.handle = &lsa_handle;
5757 :
5758 12 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
5759 : "OpenPolicy2 failed");
5760 12 : torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
5761 :
5762 12 : t.in.handle = &lsa_handle;
5763 12 : t.in.resume_handle = &resume_handle;
5764 12 : t.in.max_size = 1000;
5765 12 : t.out.domains = &domains;
5766 12 : t.out.resume_handle = &resume_handle;
5767 :
5768 12 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b2, tctx, &t),
5769 : "EnumTrustDom failed");
5770 :
5771 12 : if ((!NT_STATUS_IS_OK(t.out.result) &&
5772 9 : (!NT_STATUS_EQUAL(t.out.result, NT_STATUS_NO_MORE_ENTRIES))))
5773 0 : torture_fail(tctx, "Could not list domains");
5774 :
5775 12 : talloc_free(p2);
5776 :
5777 12 : d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
5778 : dcerpc_server_name(p));
5779 12 : d.out.dcname = &dcname;
5780 :
5781 12 : for (i=0; i<domains.count * 4; i++) {
5782 0 : struct lsa_DomainInfo *info =
5783 0 : &domains.domains[rand()%domains.count];
5784 :
5785 0 : d.in.domainname = info->name.string;
5786 :
5787 0 : status = dcerpc_netr_GetAnyDCName_r(b, tctx, &d);
5788 0 : torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
5789 :
5790 0 : torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
5791 0 : dcname ? dcname : "unknown");
5792 : }
5793 :
5794 9 : return true;
5795 : }
5796 :
5797 18 : static bool test_lsa_over_netlogon(struct torture_context *tctx,
5798 : struct dcerpc_pipe *p)
5799 : {
5800 3 : NTSTATUS status;
5801 3 : struct cli_credentials *anon_creds;
5802 3 : const struct dcerpc_binding *binding2;
5803 3 : struct dcerpc_pipe *p2;
5804 3 : struct lsa_ObjectAttribute attr;
5805 3 : struct lsa_QosInfo qos;
5806 3 : struct lsa_OpenPolicy2 o;
5807 3 : struct policy_handle lsa_handle;
5808 :
5809 3 : struct dcerpc_binding_handle *b2;
5810 :
5811 :
5812 18 : if (p->conn->transport.transport != NCACN_NP) {
5813 6 : torture_skip(tctx, "test_lsa_over_netlogon works only with NCACN_NP");
5814 : }
5815 :
5816 12 : torture_comment(tctx, "Testing if we can access the LSA server over\n"
5817 : " \\\\pipe\\netlogon rather than \\\\pipe\\lsarpc\n");
5818 :
5819 12 : anon_creds = cli_credentials_init_anon(tctx);
5820 12 : torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed");
5821 :
5822 12 : binding2 = p->binding;
5823 :
5824 12 : status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_lsarpc,
5825 : anon_creds, tctx->lp_ctx,
5826 : tctx, &p2);
5827 12 : torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
5828 3 : b2 = p2->binding_handle;
5829 :
5830 3 : qos.len = 0;
5831 3 : qos.impersonation_level = 2;
5832 3 : qos.context_mode = 1;
5833 3 : qos.effective_only = 0;
5834 :
5835 3 : attr.len = 0;
5836 3 : attr.root_dir = NULL;
5837 3 : attr.object_name = NULL;
5838 3 : attr.attributes = 0;
5839 3 : attr.sec_desc = NULL;
5840 3 : attr.sec_qos = &qos;
5841 :
5842 3 : o.in.system_name = "\\";
5843 3 : o.in.attr = &attr;
5844 3 : o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5845 3 : o.out.handle = &lsa_handle;
5846 :
5847 3 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
5848 : "OpenPolicy2 failed");
5849 3 : torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
5850 :
5851 3 : talloc_free(p2);
5852 :
5853 3 : return true;
5854 : }
5855 :
5856 3 : static bool test_SetPassword_with_flags(struct torture_context *tctx,
5857 : struct dcerpc_pipe *p,
5858 : struct cli_credentials *machine_credentials)
5859 : {
5860 3 : uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
5861 0 : struct netlogon_creds_CredentialState *creds;
5862 0 : int i;
5863 :
5864 3 : if (!test_SetupCredentials2(p, tctx, 0,
5865 : machine_credentials,
5866 : cli_credentials_get_secure_channel_type(machine_credentials),
5867 : &creds)) {
5868 3 : torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
5869 : }
5870 :
5871 0 : for (i=0; i < ARRAY_SIZE(flags); i++) {
5872 0 : torture_assert(tctx,
5873 : test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
5874 : talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
5875 : }
5876 :
5877 0 : return true;
5878 : }
5879 :
5880 2354 : struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
5881 : {
5882 2354 : struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon");
5883 125 : struct torture_rpc_tcase *tcase;
5884 125 : struct torture_test *test;
5885 :
5886 2354 : tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
5887 : &ndr_table_netlogon, TEST_MACHINE_NAME);
5888 :
5889 2354 : torture_rpc_tcase_add_test_creds(tcase, "SetupCredentialsDowngrade", test_SetupCredentialsDowngrade);
5890 2354 : torture_rpc_tcase_add_test(tcase, "lsa_over_netlogon", test_lsa_over_netlogon);
5891 :
5892 2354 : torture_rpc_tcase_add_test_creds(tcase, "GetForestTrustInformation", test_netr_GetForestTrustInformation);
5893 2354 : torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo_AES", test_netr_ServerGetTrustInfo_AES);
5894 2354 : torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
5895 2354 : torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
5896 2354 : torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
5897 2354 : torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
5898 2354 : torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
5899 2354 : torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
5900 2354 : torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
5901 2354 : test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
5902 2354 : test->dangerous = true;
5903 2354 : torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
5904 2354 : torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
5905 2354 : torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
5906 2354 : torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
5907 2354 : torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
5908 2354 : torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
5909 2354 : torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
5910 2354 : torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
5911 2354 : torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
5912 2354 : torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
5913 2354 : torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
5914 2354 : torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
5915 2354 : torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
5916 2354 : torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
5917 2354 : torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
5918 2354 : torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
5919 2354 : torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
5920 2354 : torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
5921 2354 : torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuse", test_ServerReqChallengeReuse);
5922 2354 : torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal4", test_ServerReqChallengeReuseGlobal4);
5923 2354 : torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal3", test_ServerReqChallengeReuseGlobal3);
5924 2354 : torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal2", test_ServerReqChallengeReuseGlobal2);
5925 2354 : torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal", test_ServerReqChallengeReuseGlobal);
5926 2354 : torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeGlobal", test_ServerReqChallengeGlobal);
5927 2354 : torture_rpc_tcase_add_test_creds(tcase, "invalidAuthenticate2", test_invalidAuthenticate2);
5928 2354 : torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
5929 2354 : torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
5930 2354 : torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
5931 :
5932 2354 : torture_rpc_tcase_add_test(tcase, "Broken RPC binding handle",
5933 : test_netr_broken_binding_handle);
5934 :
5935 2354 : return suite;
5936 : }
5937 :
5938 2354 : struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
5939 : {
5940 2354 : struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon-s3");
5941 125 : struct torture_rpc_tcase *tcase;
5942 :
5943 2354 : tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
5944 : &ndr_table_netlogon, TEST_MACHINE_NAME);
5945 :
5946 2354 : torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
5947 2354 : torture_rpc_tcase_add_test_creds(tcase, "SamLogon_NULL_domain", test_SamLogon_NULL_domain);
5948 2354 : torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
5949 2354 : torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
5950 2354 : torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
5951 2354 : torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
5952 2354 : torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
5953 :
5954 2354 : return suite;
5955 : }
5956 :
5957 2354 : struct torture_suite *torture_rpc_netlogon_zerologon(TALLOC_CTX *mem_ctx)
5958 : {
5959 2354 : struct torture_suite *suite = torture_suite_create(
5960 : mem_ctx,
5961 : "netlogon.zerologon");
5962 125 : struct torture_rpc_tcase *tcase;
5963 :
5964 2354 : tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(
5965 : suite,
5966 : "netlogon",
5967 : &ndr_table_netlogon,
5968 : TEST_MACHINE_NAME);
5969 :
5970 2354 : torture_rpc_tcase_add_test_creds(
5971 : tcase,
5972 : "ServerReqChallenge",
5973 : test_ServerReqChallenge);
5974 2354 : torture_rpc_tcase_add_test_creds(
5975 : tcase,
5976 : "ServerReqChallenge_zero_challenge",
5977 : test_ServerReqChallenge_zero_challenge);
5978 2354 : torture_rpc_tcase_add_test_creds(
5979 : tcase,
5980 : "ServerReqChallenge_5_repeats",
5981 : test_ServerReqChallenge_5_repeats);
5982 2354 : torture_rpc_tcase_add_test_creds(
5983 : tcase,
5984 : "ServerReqChallenge_4_repeats",
5985 : test_ServerReqChallenge_4_repeats);
5986 2354 : torture_rpc_tcase_add_test_creds(
5987 : tcase,
5988 : "test_SetPassword2_encrypted_to_all_zeros",
5989 : test_SetPassword2_encrypted_to_all_zeros);
5990 2354 : torture_rpc_tcase_add_test_creds(
5991 : tcase,
5992 : "test_SetPassword2_password_encrypts_to_zero",
5993 : test_SetPassword2_password_encrypts_to_zero);
5994 2354 : torture_rpc_tcase_add_test_creds(
5995 : tcase,
5996 : "test_SetPassword2_confounder",
5997 : test_SetPassword2_confounder);
5998 2354 : torture_rpc_tcase_add_test_creds(
5999 : tcase,
6000 : "test_SetPassword2_all_zeros",
6001 : test_SetPassword2_all_zeros);
6002 2354 : torture_rpc_tcase_add_test_creds(
6003 : tcase,
6004 : "test_SetPassword2_all_zero_password",
6005 : test_SetPassword2_all_zero_password);
6006 2354 : torture_rpc_tcase_add_test_creds(
6007 : tcase,
6008 : "test_SetPassword2_maximum_length_password",
6009 : test_SetPassword2_maximum_length_password);
6010 :
6011 2354 : return suite;
6012 : }
6013 :
6014 2354 : struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
6015 : {
6016 2354 : struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon.admin");
6017 125 : struct torture_rpc_tcase *tcase;
6018 :
6019 2354 : tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "bdc",
6020 : &ndr_table_netlogon, TEST_MACHINE_NAME);
6021 2354 : torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
6022 2354 : torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
6023 2354 : torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
6024 :
6025 2354 : tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "wkst",
6026 : &ndr_table_netlogon, TEST_MACHINE_NAME);
6027 2354 : torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
6028 2354 : torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
6029 2354 : torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
6030 :
6031 2354 : tcase = torture_suite_add_rpc_iface_tcase(suite, "admin",
6032 : &ndr_table_netlogon);
6033 2354 : torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
6034 2354 : torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
6035 2354 : torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
6036 :
6037 2354 : return suite;
6038 : }
|