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 9 : static bool test_netr_broken_binding_handle(struct torture_context *tctx,
46 : struct dcerpc_pipe *p)
47 : {
48 : NTSTATUS status;
49 : struct netr_DsRGetSiteName r;
50 9 : const char *site = NULL;
51 9 : struct dcerpc_binding_handle *b = p->binding_handle;
52 :
53 9 : r.in.computer_name = talloc_asprintf(tctx, "\\\\%s",
54 : dcerpc_server_name(p));
55 9 : r.out.site = &site;
56 :
57 9 : torture_comment(tctx,
58 : "Testing netlogon request with correct binding handle: %s\n",
59 : r.in.computer_name);
60 :
61 9 : status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
62 9 : torture_assert_ntstatus_ok(tctx, status,
63 : "Netlogon request with broken binding handle");
64 9 : torture_assert_werr_ok(tctx, r.out.result,
65 : "Netlogon request with broken binding handle");
66 :
67 18 : if (torture_setting_bool(tctx, "samba3", false) ||
68 9 : torture_setting_bool(tctx, "samba4", false)) {
69 9 : 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 9 : static bool test_LogonUasLogon(struct torture_context *tctx,
104 : struct dcerpc_pipe *p)
105 : {
106 : NTSTATUS status;
107 : struct netr_LogonUasLogon r;
108 9 : struct netr_UasInfo *info = NULL;
109 9 : struct dcerpc_binding_handle *b = p->binding_handle;
110 :
111 9 : r.in.server_name = NULL;
112 9 : r.in.account_name = cli_credentials_get_username(
113 : samba_cmdline_get_creds());
114 9 : r.in.workstation = TEST_MACHINE_NAME;
115 9 : r.out.info = &info;
116 :
117 9 : status = dcerpc_netr_LogonUasLogon_r(b, tctx, &r);
118 9 : torture_assert_ntstatus_ok(tctx, status, "LogonUasLogon");
119 :
120 0 : return true;
121 : }
122 :
123 9 : static bool test_LogonUasLogoff(struct torture_context *tctx,
124 : struct dcerpc_pipe *p)
125 : {
126 : NTSTATUS status;
127 : struct netr_LogonUasLogoff r;
128 : struct netr_UasLogoffInfo info;
129 9 : struct dcerpc_binding_handle *b = p->binding_handle;
130 :
131 9 : r.in.server_name = NULL;
132 9 : r.in.account_name = cli_credentials_get_username(
133 : samba_cmdline_get_creds());
134 9 : r.in.workstation = TEST_MACHINE_NAME;
135 9 : r.out.info = &info;
136 :
137 9 : status = dcerpc_netr_LogonUasLogoff_r(b, tctx, &r);
138 9 : torture_assert_ntstatus_ok(tctx, status, "LogonUasLogoff");
139 :
140 0 : return true;
141 : }
142 :
143 150 : 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 : struct netr_ServerReqChallenge r;
148 : struct netr_ServerAuthenticate a;
149 : struct netr_Credential credentials1, credentials2, credentials3;
150 : struct netlogon_creds_CredentialState *creds;
151 : const struct samr_Password *mach_password;
152 : const char *machine_name;
153 150 : struct dcerpc_binding_handle *b = p->binding_handle;
154 :
155 150 : mach_password = cli_credentials_get_nt_hash(credentials, tctx);
156 150 : machine_name = cli_credentials_get_workstation(credentials);
157 :
158 150 : torture_comment(tctx, "Testing ServerReqChallenge\n");
159 :
160 150 : r.in.server_name = NULL;
161 150 : r.in.computer_name = machine_name;
162 150 : r.in.credentials = &credentials1;
163 150 : r.out.return_credentials = &credentials2;
164 :
165 150 : netlogon_creds_random_challenge(&credentials1);
166 :
167 150 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
168 : "ServerReqChallenge failed");
169 150 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
170 :
171 150 : a.in.server_name = NULL;
172 150 : a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
173 150 : a.in.secure_channel_type = cli_credentials_get_secure_channel_type(credentials);
174 150 : a.in.computer_name = machine_name;
175 150 : a.in.credentials = &credentials3;
176 150 : a.out.return_credentials = &credentials3;
177 :
178 150 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
179 : a.in.computer_name,
180 150 : a.in.secure_channel_type,
181 : &credentials1, &credentials2,
182 : mach_password, &credentials3,
183 : 0);
184 150 : torture_assert(tctx, creds != NULL, "memory allocation");
185 :
186 :
187 150 : torture_comment(tctx, "Testing ServerAuthenticate\n");
188 :
189 150 : 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 150 : if (NT_STATUS_EQUAL(a.out.result, NT_STATUS_DOWNGRADE_DETECTED)) {
194 24 : 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 145 : 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 : struct netr_ServerReqChallenge r;
218 : struct netr_ServerAuthenticate2 a;
219 : struct netr_Credential credentials1, credentials2, credentials3;
220 : struct netlogon_creds_CredentialState *creds;
221 : const struct samr_Password *mach_password;
222 145 : struct dcerpc_binding_handle *b = p->binding_handle;
223 145 : const char *account_name = cli_credentials_get_username(machine_credentials);
224 :
225 145 : mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
226 :
227 145 : torture_comment(tctx, "Testing ServerReqChallenge\n");
228 :
229 145 : r.in.server_name = NULL;
230 145 : r.in.computer_name = computer_name;
231 145 : r.in.credentials = &credentials1;
232 145 : r.out.return_credentials = &credentials2;
233 :
234 145 : netlogon_creds_random_challenge(&credentials1);
235 :
236 145 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
237 : "ServerReqChallenge failed");
238 145 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
239 :
240 145 : a.in.server_name = NULL;
241 145 : a.in.account_name = account_name;
242 145 : a.in.secure_channel_type = sec_chan_type;
243 145 : a.in.computer_name = computer_name;
244 145 : a.in.negotiate_flags = &negotiate_flags;
245 145 : a.out.negotiate_flags = &negotiate_flags;
246 145 : a.in.credentials = &credentials3;
247 145 : a.out.return_credentials = &credentials3;
248 :
249 290 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
250 : a.in.computer_name,
251 145 : a.in.secure_channel_type,
252 : &credentials1, &credentials2,
253 : mach_password, &credentials3,
254 : negotiate_flags);
255 :
256 145 : torture_assert(tctx, creds != NULL, "memory allocation");
257 :
258 145 : torture_comment(tctx, "Testing ServerAuthenticate2\n");
259 :
260 145 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
261 : "ServerAuthenticate2 failed");
262 145 : torture_assert_ntstatus_equal(tctx, a.out.result, expected_result,
263 : "ServerAuthenticate2 unexpected");
264 :
265 142 : if (NT_STATUS_IS_OK(expected_result)) {
266 133 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
267 : "Credential chaining failed");
268 : } else {
269 9 : torture_assert(tctx, !netlogon_creds_client_check(creds, &credentials3),
270 : "Credential chaining passed unexptected");
271 : }
272 :
273 142 : torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
274 :
275 142 : *creds_out = creds;
276 142 : return true;
277 : }
278 :
279 127 : 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 127 : const char *computer_name =
286 0 : cli_credentials_get_workstation(machine_credentials);
287 :
288 127 : return test_SetupCredentials2ex(p, tctx, negotiate_flags,
289 : machine_credentials,
290 : computer_name,
291 : sec_chan_type,
292 127 : NT_STATUS_OK,
293 : creds_out);
294 : }
295 :
296 39 : 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 : struct netr_ServerReqChallenge r;
302 : struct netr_ServerAuthenticate3 a;
303 : struct netr_Credential credentials1, credentials2, credentials3;
304 : struct netlogon_creds_CredentialState *creds;
305 : struct samr_Password mach_password;
306 : uint32_t rid;
307 : const char *machine_name;
308 : const char *plain_pass;
309 39 : struct dcerpc_binding_handle *b = NULL;
310 :
311 39 : if (p == NULL) {
312 0 : return false;
313 : }
314 :
315 39 : b = p->binding_handle;
316 :
317 39 : machine_name = cli_credentials_get_workstation(machine_credentials);
318 39 : torture_assert(tctx, machine_name != NULL, "machine_name");
319 39 : plain_pass = cli_credentials_get_password(machine_credentials);
320 39 : torture_assert(tctx, plain_pass != NULL, "plain_pass");
321 :
322 39 : torture_comment(tctx, "Testing ServerReqChallenge\n");
323 :
324 39 : r.in.server_name = NULL;
325 39 : r.in.computer_name = machine_name;
326 39 : r.in.credentials = &credentials1;
327 39 : r.out.return_credentials = &credentials2;
328 :
329 39 : netlogon_creds_random_challenge(&credentials1);
330 :
331 39 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
332 : "ServerReqChallenge failed");
333 39 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
334 :
335 39 : E_md4hash(plain_pass, mach_password.hash);
336 :
337 39 : a.in.server_name = NULL;
338 39 : a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
339 39 : a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
340 39 : a.in.computer_name = machine_name;
341 39 : a.in.negotiate_flags = &negotiate_flags;
342 39 : a.in.credentials = &credentials3;
343 39 : a.out.return_credentials = &credentials3;
344 39 : a.out.negotiate_flags = &negotiate_flags;
345 39 : a.out.rid = &rid;
346 :
347 78 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
348 : a.in.computer_name,
349 39 : a.in.secure_channel_type,
350 : &credentials1, &credentials2,
351 : &mach_password, &credentials3,
352 : negotiate_flags);
353 :
354 39 : torture_assert(tctx, creds != NULL, "memory allocation");
355 :
356 39 : torture_comment(tctx, "Testing ServerAuthenticate3\n");
357 :
358 39 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
359 : "ServerAuthenticate3 failed");
360 39 : torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed");
361 39 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
362 :
363 39 : torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
364 :
365 : /* Prove that requesting a challenge again won't break it */
366 39 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
367 : "ServerReqChallenge failed");
368 39 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
369 :
370 39 : *creds_out = creds;
371 39 : return true;
372 : }
373 :
374 9 : bool test_SetupCredentialsDowngrade(struct torture_context *tctx,
375 : struct dcerpc_pipe *p,
376 : struct cli_credentials *machine_credentials)
377 : {
378 : struct netr_ServerReqChallenge r;
379 : struct netr_ServerAuthenticate3 a;
380 : struct netr_Credential credentials1, credentials2, credentials3;
381 : struct netlogon_creds_CredentialState *creds;
382 : struct samr_Password mach_password;
383 : uint32_t rid;
384 : const char *machine_name;
385 : const char *plain_pass;
386 9 : struct dcerpc_binding_handle *b = p->binding_handle;
387 9 : uint32_t negotiate_flags = 0;
388 :
389 9 : machine_name = cli_credentials_get_workstation(machine_credentials);
390 9 : torture_assert(tctx, machine_name != NULL, "machine_name");
391 9 : plain_pass = cli_credentials_get_password(machine_credentials);
392 9 : torture_assert(tctx, plain_pass != NULL, "plain_pass");
393 :
394 9 : torture_comment(tctx, "Testing ServerReqChallenge\n");
395 :
396 9 : r.in.server_name = NULL;
397 9 : r.in.computer_name = machine_name;
398 9 : r.in.credentials = &credentials1;
399 9 : r.out.return_credentials = &credentials2;
400 :
401 9 : netlogon_creds_random_challenge(&credentials1);
402 :
403 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
404 : "ServerReqChallenge failed");
405 9 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
406 :
407 9 : E_md4hash(plain_pass, mach_password.hash);
408 :
409 9 : a.in.server_name = NULL;
410 9 : a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
411 9 : a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
412 9 : a.in.computer_name = machine_name;
413 9 : a.in.negotiate_flags = &negotiate_flags;
414 9 : a.in.credentials = &credentials3;
415 9 : a.out.return_credentials = &credentials3;
416 9 : a.out.negotiate_flags = &negotiate_flags;
417 9 : a.out.rid = &rid;
418 :
419 18 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
420 : a.in.computer_name,
421 9 : a.in.secure_channel_type,
422 : &credentials1, &credentials2,
423 : &mach_password, &credentials3,
424 : negotiate_flags);
425 :
426 9 : torture_assert(tctx, creds != NULL, "memory allocation");
427 :
428 9 : torture_comment(tctx, "Testing ServerAuthenticate3\n");
429 :
430 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
431 : "ServerAuthenticate3 failed");
432 9 : torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_DOWNGRADE_DETECTED, "ServerAuthenticate3 should have failed");
433 :
434 0 : negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
435 0 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
436 : a.in.computer_name,
437 0 : a.in.secure_channel_type,
438 : &credentials1, &credentials2,
439 : &mach_password, &credentials3,
440 : negotiate_flags);
441 :
442 0 : torture_assert(tctx, creds != NULL, "memory allocation");
443 :
444 0 : torture_comment(tctx, "Testing ServerAuthenticate3\n");
445 :
446 0 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
447 : "ServerAuthenticate3 failed");
448 0 : torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 should succeed");
449 :
450 0 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
451 :
452 0 : torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
453 :
454 : /* Prove that requesting a challenge again won't break it */
455 0 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
456 : "ServerReqChallenge failed");
457 0 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
458 :
459 0 : return true;
460 : }
461 :
462 193 : 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 : NTSTATUS status;
470 193 : struct dcerpc_binding *b2 = NULL;
471 193 : struct dcerpc_pipe *p2 = NULL;
472 :
473 193 : b2 = dcerpc_binding_dup(tctx, p1->binding);
474 193 : torture_assert(tctx, b2 != NULL, "dcerpc_binding_dup");
475 193 : dcerpc_binding_set_flags(b2,
476 : DCERPC_SCHANNEL | additional_flags,
477 : DCERPC_AUTH_OPTIONS);
478 :
479 193 : cli_credentials_set_netlogon_creds(machine_credentials, creds);
480 193 : status = dcerpc_pipe_connect_b(tctx, &p2, b2,
481 : &ndr_table_netlogon,
482 : machine_credentials,
483 : tctx->ev, tctx->lp_ctx);
484 193 : cli_credentials_set_netlogon_creds(machine_credentials, NULL);
485 193 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b schannel");
486 :
487 193 : *_p2 = p2;
488 193 : return true;
489 : }
490 :
491 6 : static bool test_ServerReqChallenge(
492 : struct torture_context *tctx,
493 : struct dcerpc_pipe *p,
494 : struct cli_credentials *credentials)
495 : {
496 : struct netr_ServerReqChallenge r;
497 : struct netr_Credential credentials1, credentials2, credentials3;
498 : const char *machine_name;
499 6 : struct dcerpc_binding_handle *b = p->binding_handle;
500 : struct netr_ServerAuthenticate2 a;
501 6 : uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
502 6 : uint32_t out_negotiate_flags = 0;
503 6 : const struct samr_Password *mach_password = NULL;
504 6 : enum netr_SchannelType sec_chan_type = 0;
505 6 : struct netlogon_creds_CredentialState *creds = NULL;
506 6 : const char *account_name = NULL;
507 :
508 6 : machine_name = cli_credentials_get_workstation(credentials);
509 6 : mach_password = cli_credentials_get_nt_hash(credentials, tctx);
510 6 : account_name = cli_credentials_get_username(credentials);
511 6 : sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
512 :
513 6 : torture_comment(tctx, "Testing ServerReqChallenge\n");
514 :
515 6 : r.in.server_name = NULL;
516 6 : r.in.computer_name = machine_name;
517 6 : r.in.credentials = &credentials1;
518 6 : r.out.return_credentials = &credentials2;
519 :
520 6 : netlogon_creds_random_challenge(&credentials1);
521 :
522 6 : torture_assert_ntstatus_ok(
523 : tctx,
524 : dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
525 : "ServerReqChallenge failed");
526 6 : torture_assert_ntstatus_ok(
527 : tctx,
528 : r.out.result,
529 : "ServerReqChallenge failed");
530 6 : a.in.server_name = NULL;
531 6 : a.in.account_name = account_name;
532 6 : a.in.secure_channel_type = sec_chan_type;
533 6 : a.in.computer_name = machine_name;
534 6 : a.in.negotiate_flags = &in_negotiate_flags;
535 6 : a.out.negotiate_flags = &out_negotiate_flags;
536 6 : a.in.credentials = &credentials3;
537 6 : a.out.return_credentials = &credentials3;
538 :
539 12 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
540 : a.in.computer_name,
541 6 : a.in.secure_channel_type,
542 : &credentials1, &credentials2,
543 : mach_password, &credentials3,
544 : in_negotiate_flags);
545 :
546 6 : torture_assert(tctx, creds != NULL, "memory allocation");
547 :
548 6 : torture_comment(tctx, "Testing ServerAuthenticate2\n");
549 :
550 6 : torture_assert_ntstatus_ok(
551 : tctx,
552 : dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
553 : "ServerAuthenticate2 failed");
554 6 : torture_assert_ntstatus_equal(
555 : tctx,
556 : a.out.result,
557 : NT_STATUS_OK,
558 : "ServerAuthenticate2 unexpected");
559 :
560 6 : return true;
561 : }
562 :
563 6 : static bool test_ServerReqChallenge_zero_challenge(
564 : struct torture_context *tctx,
565 : struct dcerpc_pipe *p,
566 : struct cli_credentials *credentials)
567 : {
568 : struct netr_ServerReqChallenge r;
569 : struct netr_Credential credentials1, credentials2, credentials3;
570 : const char *machine_name;
571 6 : struct dcerpc_binding_handle *b = p->binding_handle;
572 : struct netr_ServerAuthenticate2 a;
573 6 : uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
574 6 : uint32_t out_negotiate_flags = 0;
575 6 : const struct samr_Password *mach_password = NULL;
576 6 : enum netr_SchannelType sec_chan_type = 0;
577 6 : struct netlogon_creds_CredentialState *creds = NULL;
578 6 : const char *account_name = NULL;
579 :
580 6 : machine_name = cli_credentials_get_workstation(credentials);
581 6 : mach_password = cli_credentials_get_nt_hash(credentials, tctx);
582 6 : account_name = cli_credentials_get_username(credentials);
583 6 : sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
584 :
585 6 : torture_comment(tctx, "Testing ServerReqChallenge\n");
586 :
587 6 : r.in.server_name = NULL;
588 6 : r.in.computer_name = machine_name;
589 6 : r.in.credentials = &credentials1;
590 6 : 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 6 : ZERO_STRUCT(credentials1);
598 :
599 6 : torture_assert_ntstatus_ok(
600 : tctx,
601 : dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
602 : "ServerReqChallenge failed");
603 6 : torture_assert_ntstatus_ok(
604 : tctx,
605 : r.out.result,
606 : "ServerReqChallenge failed");
607 6 : a.in.server_name = NULL;
608 6 : a.in.account_name = account_name;
609 6 : a.in.secure_channel_type = sec_chan_type;
610 6 : a.in.computer_name = machine_name;
611 6 : a.in.negotiate_flags = &in_negotiate_flags;
612 6 : a.out.negotiate_flags = &out_negotiate_flags;
613 6 : a.in.credentials = &credentials3;
614 6 : a.out.return_credentials = &credentials3;
615 :
616 12 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
617 : a.in.computer_name,
618 6 : a.in.secure_channel_type,
619 : &credentials1, &credentials2,
620 : mach_password, &credentials3,
621 : in_negotiate_flags);
622 :
623 6 : torture_assert(tctx, creds != NULL, "memory allocation");
624 :
625 6 : torture_comment(tctx, "Testing ServerAuthenticate2\n");
626 :
627 6 : torture_assert_ntstatus_ok(
628 : tctx,
629 : dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
630 : "ServerAuthenticate2 failed");
631 6 : torture_assert_ntstatus_equal(
632 : tctx,
633 : a.out.result,
634 : NT_STATUS_ACCESS_DENIED,
635 : "ServerAuthenticate2 unexpected");
636 :
637 6 : return true;
638 : }
639 :
640 6 : static bool test_ServerReqChallenge_5_repeats(
641 : struct torture_context *tctx,
642 : struct dcerpc_pipe *p,
643 : struct cli_credentials *credentials)
644 : {
645 : struct netr_ServerReqChallenge r;
646 : struct netr_Credential credentials1, credentials2, credentials3;
647 : const char *machine_name;
648 6 : struct dcerpc_binding_handle *b = p->binding_handle;
649 : struct netr_ServerAuthenticate2 a;
650 6 : uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
651 6 : uint32_t out_negotiate_flags = 0;
652 6 : const struct samr_Password *mach_password = NULL;
653 6 : enum netr_SchannelType sec_chan_type = 0;
654 6 : struct netlogon_creds_CredentialState *creds = NULL;
655 6 : const char *account_name = NULL;
656 :
657 6 : machine_name = cli_credentials_get_workstation(credentials);
658 6 : mach_password = cli_credentials_get_nt_hash(credentials, tctx);
659 6 : account_name = cli_credentials_get_username(credentials);
660 6 : sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
661 :
662 6 : torture_comment(tctx, "Testing ServerReqChallenge\n");
663 :
664 6 : r.in.server_name = NULL;
665 6 : r.in.computer_name = machine_name;
666 6 : r.in.credentials = &credentials1;
667 6 : 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 6 : credentials1.data[0] = 'A';
675 6 : credentials1.data[1] = 'A';
676 6 : credentials1.data[2] = 'A';
677 6 : credentials1.data[3] = 'A';
678 6 : credentials1.data[4] = 'A';
679 6 : credentials1.data[5] = 'B';
680 6 : credentials1.data[6] = 'C';
681 6 : credentials1.data[7] = 'D';
682 :
683 6 : torture_assert_ntstatus_ok(
684 : tctx,
685 : dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
686 : "ServerReqChallenge failed");
687 6 : torture_assert_ntstatus_ok(
688 : tctx,
689 : r.out.result,
690 : "ServerReqChallenge failed");
691 6 : a.in.server_name = NULL;
692 6 : a.in.account_name = account_name;
693 6 : a.in.secure_channel_type = sec_chan_type;
694 6 : a.in.computer_name = machine_name;
695 6 : a.in.negotiate_flags = &in_negotiate_flags;
696 6 : a.out.negotiate_flags = &out_negotiate_flags;
697 6 : a.in.credentials = &credentials3;
698 6 : a.out.return_credentials = &credentials3;
699 :
700 12 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
701 : a.in.computer_name,
702 6 : a.in.secure_channel_type,
703 : &credentials1, &credentials2,
704 : mach_password, &credentials3,
705 : in_negotiate_flags);
706 :
707 6 : torture_assert(tctx, creds != NULL, "memory allocation");
708 :
709 6 : torture_comment(tctx, "Testing ServerAuthenticate2\n");
710 :
711 6 : torture_assert_ntstatus_ok(
712 : tctx,
713 : dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
714 : "ServerAuthenticate2 failed");
715 6 : torture_assert_ntstatus_equal(
716 : tctx,
717 : a.out.result,
718 : NT_STATUS_ACCESS_DENIED,
719 : "ServerAuthenticate2 unexpected");
720 :
721 6 : return true;
722 : }
723 :
724 6 : static bool test_ServerReqChallenge_4_repeats(
725 : struct torture_context *tctx,
726 : struct dcerpc_pipe *p,
727 : struct cli_credentials *credentials)
728 : {
729 : struct netr_ServerReqChallenge r;
730 : struct netr_Credential credentials1, credentials2, credentials3;
731 : const char *machine_name;
732 6 : struct dcerpc_binding_handle *b = p->binding_handle;
733 : struct netr_ServerAuthenticate2 a;
734 6 : uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
735 6 : uint32_t out_negotiate_flags = 0;
736 6 : const struct samr_Password *mach_password = NULL;
737 6 : enum netr_SchannelType sec_chan_type = 0;
738 6 : struct netlogon_creds_CredentialState *creds = NULL;
739 6 : const char *account_name = NULL;
740 :
741 6 : machine_name = cli_credentials_get_workstation(credentials);
742 6 : mach_password = cli_credentials_get_nt_hash(credentials, tctx);
743 6 : account_name = cli_credentials_get_username(credentials);
744 6 : sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
745 :
746 6 : torture_comment(tctx, "Testing ServerReqChallenge\n");
747 :
748 6 : r.in.server_name = NULL;
749 6 : r.in.computer_name = machine_name;
750 6 : r.in.credentials = &credentials1;
751 6 : 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 6 : credentials1.data[0] = 'A';
761 6 : credentials1.data[1] = 'A';
762 6 : credentials1.data[2] = 'A';
763 6 : credentials1.data[3] = 'A';
764 6 : credentials1.data[4] = 'B';
765 6 : credentials1.data[5] = 'C';
766 6 : credentials1.data[6] = 'D';
767 6 : credentials1.data[7] = 'E';
768 :
769 6 : torture_assert_ntstatus_ok(
770 : tctx,
771 : dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
772 : "ServerReqChallenge failed");
773 6 : torture_assert_ntstatus_ok(
774 : tctx,
775 : r.out.result,
776 : "ServerReqChallenge failed");
777 6 : a.in.server_name = NULL;
778 6 : a.in.account_name = account_name;
779 6 : a.in.secure_channel_type = sec_chan_type;
780 6 : a.in.computer_name = machine_name;
781 6 : a.in.negotiate_flags = &in_negotiate_flags;
782 6 : a.out.negotiate_flags = &out_negotiate_flags;
783 6 : a.in.credentials = &credentials3;
784 6 : a.out.return_credentials = &credentials3;
785 :
786 12 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
787 : a.in.computer_name,
788 6 : a.in.secure_channel_type,
789 : &credentials1, &credentials2,
790 : mach_password, &credentials3,
791 : in_negotiate_flags);
792 :
793 6 : torture_assert(tctx, creds != NULL, "memory allocation");
794 :
795 6 : torture_comment(tctx, "Testing ServerAuthenticate2\n");
796 :
797 6 : torture_assert_ntstatus_ok(
798 : tctx,
799 : dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
800 : "ServerAuthenticate2 failed");
801 6 : torture_assert_ntstatus_equal(
802 : tctx,
803 : a.out.result,
804 : NT_STATUS_OK,
805 : "ServerAuthenticate2 unexpected");
806 :
807 6 : return true;
808 : }
809 :
810 : /*
811 : * Establish a NetLogon session, using a session key that encrypts the
812 : * target character to zero
813 : */
814 18 : 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 18 : const char *computer_name =
822 0 : cli_credentials_get_workstation(machine_credentials);
823 : struct netr_ServerReqChallenge r;
824 : struct netr_ServerAuthenticate2 a;
825 : struct netr_Credential credentials1, credentials2, credentials3;
826 18 : struct netlogon_creds_CredentialState *creds = NULL;
827 : const struct samr_Password *mach_password;
828 18 : struct dcerpc_binding_handle *b = p->binding_handle;
829 18 : const char *account_name = cli_credentials_get_username(
830 : machine_credentials);
831 18 : uint32_t flags =
832 : NETLOGON_NEG_AUTH2_ADS_FLAGS |
833 : NETLOGON_NEG_SUPPORTS_AES;
834 18 : enum netr_SchannelType sec_chan_type =
835 0 : cli_credentials_get_secure_channel_type(machine_credentials);
836 : /*
837 : * Limit the number of attempts to generate a suitable session key.
838 : */
839 18 : const unsigned MAX_ITER = 4096;
840 18 : unsigned i = 0;
841 :
842 18 : mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
843 :
844 18 : r.in.server_name = NULL;
845 18 : r.in.computer_name = computer_name;
846 18 : r.in.credentials = &credentials1;
847 18 : r.out.return_credentials = &credentials2;
848 :
849 18 : netlogon_creds_random_challenge(&credentials1);
850 18 : credentials1.data[0] = target;
851 18 : i = 0;
852 18 : torture_comment(tctx, "Generating candidate session keys\n");
853 : do {
854 3913 : TALLOC_FREE(creds);
855 3913 : i++;
856 :
857 3913 : torture_assert_ntstatus_ok(
858 : tctx,
859 : dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
860 : "ServerReqChallenge failed");
861 3913 : torture_assert_ntstatus_ok(
862 : tctx,
863 : r.out.result,
864 : "ServerReqChallenge failed");
865 :
866 3913 : a.in.server_name = NULL;
867 3913 : a.in.account_name = account_name;
868 3913 : a.in.secure_channel_type = sec_chan_type;
869 3913 : a.in.computer_name = computer_name;
870 3913 : a.in.negotiate_flags = &flags;
871 3913 : a.out.negotiate_flags = &flags;
872 3913 : a.in.credentials = &credentials3;
873 3913 : a.out.return_credentials = &credentials3;
874 :
875 7826 : creds = netlogon_creds_client_init(
876 : tctx,
877 : a.in.account_name,
878 : a.in.computer_name,
879 3913 : a.in.secure_channel_type,
880 : &credentials1,
881 : &credentials2,
882 : mach_password,
883 : &credentials3,
884 : flags);
885 :
886 3913 : torture_assert(tctx, creds != NULL, "memory allocation");
887 3913 : } while (credentials3.data[0] != 0 && i < MAX_ITER);
888 :
889 18 : 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 obtain suitable session key");
896 : }
897 :
898 18 : torture_assert_ntstatus_ok(
899 : tctx,
900 : dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
901 : "ServerAuthenticate2 failed");
902 18 : torture_assert_ntstatus_equal(
903 : tctx,
904 : a.out.result,
905 : NT_STATUS_OK,
906 : "ServerAuthenticate2 unexpected result code");
907 :
908 18 : *creds_out = creds;
909 18 : return true;
910 : }
911 :
912 : /*
913 : try a change password for our machine account
914 : */
915 12 : static bool test_SetPassword(struct torture_context *tctx,
916 : struct dcerpc_pipe *p,
917 : struct cli_credentials *machine_credentials)
918 : {
919 : struct netr_ServerPasswordSet r;
920 : const char *password;
921 : struct netlogon_creds_CredentialState *creds;
922 : struct netr_Authenticator credential, return_authenticator;
923 : struct samr_Password new_password;
924 12 : struct dcerpc_binding_handle *b = p->binding_handle;
925 :
926 12 : if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
927 0 : return false;
928 : }
929 :
930 12 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
931 12 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
932 12 : r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
933 12 : r.in.computer_name = TEST_MACHINE_NAME;
934 12 : r.in.credential = &credential;
935 12 : r.in.new_password = &new_password;
936 12 : r.out.return_authenticator = &return_authenticator;
937 :
938 12 : password = generate_random_password(tctx, 8, 255);
939 12 : E_md4hash(password, new_password.hash);
940 :
941 12 : netlogon_creds_des_encrypt(creds, &new_password);
942 :
943 12 : torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
944 12 : torture_comment(tctx, "Changing machine account password to '%s'\n",
945 : password);
946 :
947 12 : netlogon_creds_client_authenticator(creds, &credential);
948 :
949 12 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
950 : "ServerPasswordSet failed");
951 12 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
952 :
953 12 : 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 12 : torture_comment(tctx,
962 : "Testing a second ServerPasswordSet on machine account\n");
963 12 : torture_comment(tctx,
964 : "Changing machine account password to '%s' (same as previous run)\n", password);
965 :
966 12 : netlogon_creds_client_authenticator(creds, &credential);
967 :
968 12 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
969 : "ServerPasswordSet (2) failed");
970 12 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
971 :
972 12 : if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
973 0 : torture_comment(tctx, "Credential chaining failed\n");
974 : }
975 :
976 12 : cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
977 :
978 12 : torture_assert(tctx,
979 : test_SetupCredentials(p, tctx, machine_credentials, &creds),
980 : "ServerPasswordSet failed to actually change the password");
981 :
982 12 : 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 : struct netr_ServerPasswordSet r;
994 : const char *password;
995 : struct netlogon_creds_CredentialState *creds;
996 : struct netr_Authenticator credential, return_authenticator;
997 : 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 30 : static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
1073 : {
1074 : int i;
1075 30 : DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
1076 30 : generate_random_buffer(password.data, password.length);
1077 :
1078 4638 : for (i=0; i < len; i++) {
1079 4608 : if (((uint16_t *)password.data)[i] == 0) {
1080 0 : ((uint16_t *)password.data)[i] = 1;
1081 : }
1082 : }
1083 :
1084 30 : return password;
1085 : }
1086 :
1087 : /*
1088 : try a change password for our machine account
1089 : */
1090 24 : 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 : struct netr_ServerPasswordSet2 r;
1096 : const char *password;
1097 : DATA_BLOB new_random_pass;
1098 : struct netlogon_creds_CredentialState *creds;
1099 : struct samr_CryptPassword password_buf;
1100 : struct samr_Password nt_hash;
1101 : struct netr_Authenticator credential, return_authenticator;
1102 : struct netr_CryptPassword new_password;
1103 24 : struct dcerpc_pipe *p = NULL;
1104 24 : struct dcerpc_binding_handle *b = NULL;
1105 :
1106 24 : 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 24 : if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
1112 : DCERPC_SIGN | DCERPC_SEAL, &p)) {
1113 0 : return false;
1114 : }
1115 24 : b = p->binding_handle;
1116 :
1117 24 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1118 24 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1119 24 : r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1120 24 : r.in.computer_name = TEST_MACHINE_NAME;
1121 24 : r.in.credential = &credential;
1122 24 : r.in.new_password = &new_password;
1123 24 : r.out.return_authenticator = &return_authenticator;
1124 :
1125 24 : password = generate_random_password(tctx, 8, 255);
1126 24 : encode_pw_buffer(password_buf.data, password, STR_UNICODE);
1127 24 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1128 12 : netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1129 : } else {
1130 12 : netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1131 : }
1132 :
1133 24 : memcpy(new_password.data, password_buf.data, 512);
1134 24 : new_password.length = IVAL(password_buf.data, 512);
1135 :
1136 24 : torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
1137 24 : torture_comment(tctx, "Changing machine account password to '%s'\n", password);
1138 :
1139 24 : netlogon_creds_client_authenticator(creds, &credential);
1140 :
1141 24 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1142 : "ServerPasswordSet2 failed");
1143 24 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
1144 :
1145 24 : if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1146 0 : torture_comment(tctx, "Credential chaining failed\n");
1147 : }
1148 :
1149 24 : 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 24 : password = "";
1160 24 : encode_pw_buffer(password_buf.data, password, STR_UNICODE);
1161 24 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1162 12 : netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1163 : } else {
1164 12 : netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1165 : }
1166 24 : memcpy(new_password.data, password_buf.data, 512);
1167 24 : new_password.length = IVAL(password_buf.data, 512);
1168 :
1169 24 : torture_comment(tctx,
1170 : "Testing ServerPasswordSet2 on machine account\n");
1171 24 : torture_comment(tctx,
1172 : "Changing machine account password to '%s'\n", password);
1173 :
1174 24 : netlogon_creds_client_authenticator(creds, &credential);
1175 :
1176 24 : torture_assert_ntstatus_ok(
1177 : tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1178 : "ServerPasswordSet2 failed");
1179 24 : 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 24 : password = generate_random_password(tctx, 8, 255);
1187 24 : encode_pw_buffer(password_buf.data, password, STR_UNICODE);
1188 24 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1189 12 : netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1190 : } else {
1191 12 : netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1192 : }
1193 24 : memcpy(new_password.data, password_buf.data, 512);
1194 24 : new_password.length = IVAL(password_buf.data, 512);
1195 :
1196 24 : torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
1197 24 : torture_comment(tctx, "Changing machine account password to '%s'\n", password);
1198 :
1199 24 : netlogon_creds_client_authenticator(creds, &credential);
1200 :
1201 24 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1202 : "ServerPasswordSet2 (2) failed");
1203 24 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 (2) failed");
1204 :
1205 24 : 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 24 : torture_comment(tctx,
1214 : "Testing a second ServerPasswordSet2 on machine account\n");
1215 24 : torture_comment(tctx,
1216 : "Changing machine account password to '%s' (same as previous run)\n", password);
1217 :
1218 24 : netlogon_creds_client_authenticator(creds, &credential);
1219 :
1220 24 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1221 : "ServerPasswordSet (3) failed");
1222 24 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
1223 :
1224 24 : if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1225 0 : torture_comment(tctx, "Credential chaining failed\n");
1226 : }
1227 :
1228 24 : cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
1229 :
1230 24 : torture_assert (tctx,
1231 : test_SetupCredentials(p, tctx, machine_credentials, &creds),
1232 : "ServerPasswordSet failed to actually change the password");
1233 :
1234 24 : new_random_pass = netlogon_very_rand_pass(tctx, 128);
1235 :
1236 : /* now try a random stream of bytes for a password */
1237 24 : set_pw_in_buffer(password_buf.data, &new_random_pass);
1238 :
1239 24 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1240 6 : 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 24 : memcpy(new_password.data, password_buf.data, 512);
1246 24 : new_password.length = IVAL(password_buf.data, 512);
1247 :
1248 24 : torture_comment(tctx,
1249 : "Testing a third ServerPasswordSet2 on machine account, with a completely random password\n");
1250 :
1251 24 : netlogon_creds_client_authenticator(creds, &credential);
1252 :
1253 24 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1254 : "ServerPasswordSet (3) failed");
1255 24 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
1256 :
1257 24 : if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1258 0 : torture_comment(tctx, "Credential chaining failed\n");
1259 : }
1260 :
1261 24 : mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
1262 :
1263 24 : cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
1264 24 : cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
1265 :
1266 24 : torture_assert (tctx,
1267 : test_SetupCredentials(p, tctx, machine_credentials, &creds),
1268 : "ServerPasswordSet failed to actually change the password");
1269 :
1270 24 : 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 6 : 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 : struct netr_ServerPasswordSet2 r;
1286 : struct netlogon_creds_CredentialState *creds;
1287 : struct samr_CryptPassword password_buf;
1288 : struct netr_Authenticator credential, return_authenticator;
1289 : struct netr_CryptPassword new_password;
1290 6 : struct dcerpc_pipe *p = NULL;
1291 6 : struct dcerpc_binding_handle *b = NULL;
1292 :
1293 6 : 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 6 : 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 6 : b = p->binding_handle;
1314 :
1315 6 : r.in.server_name = talloc_asprintf(
1316 : tctx,
1317 : "\\\\%s", dcerpc_server_name(p));
1318 6 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1319 6 : r.in.secure_channel_type =
1320 6 : cli_credentials_get_secure_channel_type(machine_credentials);
1321 6 : r.in.computer_name = TEST_MACHINE_NAME;
1322 6 : r.in.credential = &credential;
1323 6 : r.in.new_password = &new_password;
1324 6 : r.out.return_authenticator = &return_authenticator;
1325 :
1326 6 : ZERO_STRUCT(password_buf);
1327 :
1328 6 : if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
1329 0 : torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES not set");
1330 : }
1331 6 : netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1332 6 : if(!all_zero(password_buf.data, 516)) {
1333 0 : torture_fail(tctx, "Password did not encrypt to all zeros\n");
1334 : }
1335 :
1336 6 : memcpy(new_password.data, password_buf.data, 512);
1337 6 : new_password.length = IVAL(password_buf.data, 512);
1338 6 : torture_assert_int_equal(
1339 : tctx,
1340 : new_password.length,
1341 : 0,
1342 : "Length should have encrypted to 0");
1343 :
1344 6 : netlogon_creds_client_authenticator(creds, &credential);
1345 :
1346 6 : torture_assert_ntstatus_ok(
1347 : tctx,
1348 : dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1349 : "ServerPasswordSet2 zero length check failed");
1350 6 : torture_assert_ntstatus_equal(
1351 : tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
1352 :
1353 6 : 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 6 : 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 : struct netr_ServerPasswordSet2 r;
1372 : struct netlogon_creds_CredentialState *creds;
1373 : struct samr_CryptPassword password_buf;
1374 : struct netr_Authenticator credential, return_authenticator;
1375 : struct netr_CryptPassword new_password;
1376 6 : struct dcerpc_pipe *p = NULL;
1377 6 : struct dcerpc_binding_handle *b = NULL;
1378 :
1379 6 : 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 6 : 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 6 : b = p->binding_handle;
1400 :
1401 6 : r.in.server_name = talloc_asprintf(
1402 : tctx,
1403 : "\\\\%s", dcerpc_server_name(p));
1404 6 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1405 6 : r.in.secure_channel_type =
1406 6 : cli_credentials_get_secure_channel_type(machine_credentials);
1407 6 : r.in.computer_name = TEST_MACHINE_NAME;
1408 6 : r.in.credential = &credential;
1409 6 : r.in.new_password = &new_password;
1410 6 : r.out.return_authenticator = &return_authenticator;
1411 :
1412 6 : ZERO_STRUCT(password_buf);
1413 6 : SIVAL(password_buf.data, 512, 512);
1414 :
1415 6 : if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
1416 0 : torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES not set");
1417 : }
1418 6 : netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1419 :
1420 6 : memcpy(new_password.data, password_buf.data, 512);
1421 6 : new_password.length = IVAL(password_buf.data, 512);
1422 :
1423 6 : netlogon_creds_client_authenticator(creds, &credential);
1424 :
1425 6 : torture_assert_ntstatus_ok(
1426 : tctx,
1427 : dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1428 : "ServerPasswordSet2 password encrypts to zero check failed");
1429 6 : torture_assert_ntstatus_equal(
1430 : tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
1431 :
1432 6 : 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 6 : static bool test_SetPassword2_confounder(
1443 : struct torture_context *tctx,
1444 : struct dcerpc_pipe *p1,
1445 : struct cli_credentials *machine_credentials)
1446 : {
1447 : struct netr_ServerPasswordSet2 r;
1448 : struct netlogon_creds_CredentialState *creds;
1449 : struct samr_CryptPassword password_buf;
1450 : struct netr_Authenticator credential, return_authenticator;
1451 : struct netr_CryptPassword new_password;
1452 6 : struct dcerpc_pipe *p = NULL;
1453 6 : struct dcerpc_binding_handle *b = NULL;
1454 :
1455 6 : 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 6 : 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 6 : b = p->binding_handle;
1476 :
1477 6 : r.in.server_name = talloc_asprintf(
1478 : tctx,
1479 : "\\\\%s", dcerpc_server_name(p));
1480 6 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1481 6 : r.in.secure_channel_type =
1482 6 : cli_credentials_get_secure_channel_type(machine_credentials);
1483 6 : r.in.computer_name = TEST_MACHINE_NAME;
1484 6 : r.in.credential = &credential;
1485 6 : r.in.new_password = &new_password;
1486 6 : r.out.return_authenticator = &return_authenticator;
1487 :
1488 6 : ZERO_STRUCT(password_buf);
1489 6 : password_buf.data[511] = 'A';
1490 6 : SIVAL(password_buf.data, 512, 2);
1491 :
1492 6 : if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
1493 0 : torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES not set");
1494 : }
1495 6 : netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
1496 :
1497 6 : memcpy(new_password.data, password_buf.data, 512);
1498 6 : new_password.length = IVAL(password_buf.data, 512);
1499 :
1500 6 : netlogon_creds_client_authenticator(creds, &credential);
1501 :
1502 6 : torture_assert_ntstatus_ok(
1503 : tctx,
1504 : dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1505 : "ServerPasswordSet2 confounder check failed");
1506 6 : torture_assert_ntstatus_equal(
1507 : tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
1508 :
1509 6 : 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 6 : static bool test_SetPassword2_all_zeros(
1519 : struct torture_context *tctx,
1520 : struct dcerpc_pipe *p1,
1521 : struct cli_credentials *machine_credentials)
1522 : {
1523 : struct netr_ServerPasswordSet2 r;
1524 : struct netlogon_creds_CredentialState *creds;
1525 : struct samr_CryptPassword password_buf;
1526 : struct netr_Authenticator credential, return_authenticator;
1527 : struct netr_CryptPassword new_password;
1528 6 : struct dcerpc_pipe *p = NULL;
1529 6 : struct dcerpc_binding_handle *b = NULL;
1530 6 : uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; /* no AES desired here */
1531 :
1532 6 : 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 6 : 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 6 : b = p->binding_handle;
1553 :
1554 6 : r.in.server_name = talloc_asprintf(
1555 : tctx,
1556 : "\\\\%s", dcerpc_server_name(p));
1557 6 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1558 6 : r.in.secure_channel_type =
1559 6 : cli_credentials_get_secure_channel_type(machine_credentials);
1560 6 : r.in.computer_name = TEST_MACHINE_NAME;
1561 6 : r.in.credential = &credential;
1562 6 : r.in.new_password = &new_password;
1563 6 : r.out.return_authenticator = &return_authenticator;
1564 :
1565 6 : ZERO_STRUCT(password_buf.data);
1566 6 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1567 0 : torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES enabled\n");
1568 : }
1569 6 : netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1570 :
1571 6 : memcpy(new_password.data, password_buf.data, 512);
1572 6 : new_password.length = IVAL(password_buf.data, 512);
1573 :
1574 6 : torture_comment(
1575 : tctx,
1576 : "Testing ServerPasswordSet2 on machine account\n");
1577 :
1578 6 : netlogon_creds_client_authenticator(creds, &credential);
1579 :
1580 6 : torture_assert_ntstatus_ok(
1581 : tctx,
1582 : dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1583 : "ServerPasswordSet2 zero length check failed");
1584 6 : torture_assert_ntstatus_equal(
1585 : tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
1586 :
1587 6 : return true;
1588 : }
1589 :
1590 : /*
1591 : try a change password for our machine account, using a maximum length
1592 : password
1593 : */
1594 6 : 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 : struct netr_ServerPasswordSet2 r;
1600 : struct netlogon_creds_CredentialState *creds;
1601 : struct samr_CryptPassword password_buf;
1602 : struct netr_Authenticator credential, return_authenticator;
1603 : struct netr_CryptPassword new_password;
1604 6 : struct dcerpc_pipe *p = NULL;
1605 6 : struct dcerpc_binding_handle *b = NULL;
1606 6 : uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
1607 6 : DATA_BLOB new_random_pass = data_blob_null;
1608 :
1609 6 : 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 6 : 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 6 : b = p->binding_handle;
1630 :
1631 6 : r.in.server_name = talloc_asprintf(
1632 : tctx,
1633 : "\\\\%s", dcerpc_server_name(p));
1634 6 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1635 6 : r.in.secure_channel_type =
1636 6 : cli_credentials_get_secure_channel_type(machine_credentials);
1637 6 : r.in.computer_name = TEST_MACHINE_NAME;
1638 6 : r.in.credential = &credential;
1639 6 : r.in.new_password = &new_password;
1640 6 : r.out.return_authenticator = &return_authenticator;
1641 :
1642 6 : new_random_pass = netlogon_very_rand_pass(tctx, 256);
1643 6 : set_pw_in_buffer(password_buf.data, &new_random_pass);
1644 6 : SIVAL(password_buf.data, 512, 512);
1645 6 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1646 6 : 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 6 : memcpy(new_password.data, password_buf.data, 512);
1652 6 : new_password.length = IVAL(password_buf.data, 512);
1653 :
1654 6 : torture_comment(
1655 : tctx,
1656 : "Testing ServerPasswordSet2 on machine account\n");
1657 :
1658 6 : netlogon_creds_client_authenticator(creds, &credential);
1659 :
1660 6 : torture_assert_ntstatus_ok(
1661 : tctx,
1662 : dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1663 : "ServerPasswordSet2 zero length check failed");
1664 6 : torture_assert_ntstatus_equal(
1665 : tctx, r.out.result, NT_STATUS_OK, "");
1666 :
1667 6 : 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 6 : 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 : struct netr_ServerPasswordSet2 r;
1683 : struct netlogon_creds_CredentialState *creds;
1684 : struct samr_CryptPassword password_buf;
1685 : struct netr_Authenticator credential, return_authenticator;
1686 : struct netr_CryptPassword new_password;
1687 6 : struct dcerpc_pipe *p = NULL;
1688 6 : struct dcerpc_binding_handle *b = NULL;
1689 6 : uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; /* no AES desired here */
1690 :
1691 6 : 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 6 : 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 6 : b = p->binding_handle;
1712 :
1713 6 : r.in.server_name = talloc_asprintf(
1714 : tctx,
1715 : "\\\\%s", dcerpc_server_name(p));
1716 6 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1717 6 : r.in.secure_channel_type =
1718 6 : cli_credentials_get_secure_channel_type(machine_credentials);
1719 6 : r.in.computer_name = TEST_MACHINE_NAME;
1720 6 : r.in.credential = &credential;
1721 6 : r.in.new_password = &new_password;
1722 6 : r.out.return_authenticator = &return_authenticator;
1723 :
1724 6 : ZERO_STRUCT(password_buf.data);
1725 6 : SIVAL(password_buf.data, 512, 128);
1726 6 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1727 0 : torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES set");
1728 : }
1729 6 : netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
1730 :
1731 6 : memcpy(new_password.data, password_buf.data, 512);
1732 6 : new_password.length = IVAL(password_buf.data, 512);
1733 :
1734 6 : torture_comment(
1735 : tctx,
1736 : "Testing ServerPasswordSet2 on machine account\n");
1737 :
1738 6 : netlogon_creds_client_authenticator(creds, &credential);
1739 :
1740 6 : torture_assert_ntstatus_ok(
1741 : tctx,
1742 : dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
1743 : "ServerPasswordSet2 all zero password check failed");
1744 6 : torture_assert_ntstatus_equal(
1745 : tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
1746 :
1747 6 : return true;
1748 : }
1749 :
1750 :
1751 12 : static bool test_SetPassword2(struct torture_context *tctx,
1752 : struct dcerpc_pipe *p,
1753 : struct cli_credentials *machine_credentials)
1754 : {
1755 12 : return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS);
1756 : }
1757 :
1758 12 : static bool test_SetPassword2_AES(struct torture_context *tctx,
1759 : struct dcerpc_pipe *p,
1760 : struct cli_credentials *machine_credentials)
1761 : {
1762 12 : return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
1763 : }
1764 :
1765 9 : static bool test_GetPassword(struct torture_context *tctx,
1766 : struct dcerpc_pipe *p,
1767 : struct cli_credentials *machine_credentials)
1768 : {
1769 : struct netr_ServerPasswordGet r;
1770 : struct netlogon_creds_CredentialState *creds;
1771 : struct netr_Authenticator credential;
1772 : NTSTATUS status;
1773 : struct netr_Authenticator return_authenticator;
1774 : struct samr_Password password;
1775 9 : struct dcerpc_binding_handle *b = p->binding_handle;
1776 :
1777 9 : if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1778 0 : return false;
1779 : }
1780 :
1781 9 : netlogon_creds_client_authenticator(creds, &credential);
1782 :
1783 9 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1784 9 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1785 9 : r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1786 9 : r.in.computer_name = TEST_MACHINE_NAME;
1787 9 : r.in.credential = &credential;
1788 9 : r.out.return_authenticator = &return_authenticator;
1789 9 : r.out.password = &password;
1790 :
1791 9 : status = dcerpc_netr_ServerPasswordGet_r(b, tctx, &r);
1792 9 : 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 9 : static bool test_GetTrustPasswords(struct torture_context *tctx,
1799 : struct dcerpc_pipe *p,
1800 : struct cli_credentials *machine_credentials)
1801 : {
1802 : struct netr_ServerTrustPasswordsGet r;
1803 : struct netlogon_creds_CredentialState *creds;
1804 : struct netr_Authenticator credential;
1805 : struct netr_Authenticator return_authenticator;
1806 : struct samr_Password password, password2;
1807 9 : struct dcerpc_binding_handle *b = p->binding_handle;
1808 :
1809 9 : if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1810 0 : return false;
1811 : }
1812 :
1813 9 : netlogon_creds_client_authenticator(creds, &credential);
1814 :
1815 9 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1816 9 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
1817 9 : r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1818 9 : r.in.computer_name = TEST_MACHINE_NAME;
1819 9 : r.in.credential = &credential;
1820 9 : r.out.return_authenticator = &return_authenticator;
1821 9 : r.out.new_owf_password = &password;
1822 9 : r.out.old_owf_password = &password2;
1823 :
1824 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerTrustPasswordsGet_r(b, tctx, &r),
1825 : "ServerTrustPasswordsGet failed");
1826 9 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerTrustPasswordsGet failed");
1827 :
1828 9 : return true;
1829 : }
1830 :
1831 : /*
1832 : try a netlogon SamLogon
1833 : */
1834 339 : 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 : NTSTATUS status;
1840 : struct netr_LogonSamLogon r;
1841 : struct netr_Authenticator auth, auth2;
1842 : union netr_LogonLevel logon;
1843 : union netr_Validation validation;
1844 : uint8_t authoritative;
1845 : struct netr_NetworkInfo ninfo;
1846 : DATA_BLOB names_blob, chal, lm_resp, nt_resp;
1847 : int i;
1848 339 : struct dcerpc_binding_handle *b = p->binding_handle;
1849 339 : int flags = CLI_CRED_NTLM_AUTH;
1850 339 : if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
1851 228 : flags |= CLI_CRED_LANMAN_AUTH;
1852 : }
1853 :
1854 339 : if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx) && !null_domain) {
1855 336 : flags |= CLI_CRED_NTLMv2_AUTH;
1856 : }
1857 :
1858 339 : 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 339 : if (null_domain) {
1864 3 : ninfo.identity_info.domain_name.string = NULL;
1865 : }
1866 :
1867 339 : generate_random_buffer(ninfo.challenge,
1868 : sizeof(ninfo.challenge));
1869 339 : chal = data_blob_const(ninfo.challenge,
1870 : sizeof(ninfo.challenge));
1871 :
1872 339 : names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials),
1873 : cli_credentials_get_domain(credentials));
1874 :
1875 339 : 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 339 : torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
1884 :
1885 339 : ninfo.lm.data = lm_resp.data;
1886 339 : ninfo.lm.length = lm_resp.length;
1887 :
1888 339 : ninfo.nt.data = nt_resp.data;
1889 339 : ninfo.nt.length = nt_resp.length;
1890 :
1891 339 : ninfo.identity_info.parameter_control = 0;
1892 339 : ninfo.identity_info.logon_id = 0;
1893 339 : ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
1894 :
1895 339 : logon.network = &ninfo;
1896 :
1897 339 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1898 339 : r.in.computer_name = cli_credentials_get_workstation(credentials);
1899 339 : r.in.credential = &auth;
1900 339 : r.in.return_authenticator = &auth2;
1901 339 : r.in.logon_level = NetlogonNetworkInformation;
1902 339 : r.in.logon = &logon;
1903 339 : r.out.validation = &validation;
1904 339 : r.out.authoritative = &authoritative;
1905 :
1906 339 : d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
1907 :
1908 1017 : for (i=2;i<=3;i++) {
1909 678 : ZERO_STRUCT(auth2);
1910 678 : netlogon_creds_client_authenticator(creds, &auth);
1911 :
1912 678 : r.in.validation_level = i;
1913 :
1914 678 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1915 : "LogonSamLogon failed");
1916 678 : torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
1917 :
1918 678 : torture_assert(tctx, netlogon_creds_client_check(creds,
1919 : &r.out.return_authenticator->cred),
1920 : "Credential chaining failed");
1921 678 : 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 678 : for (i=52;i<53;i++) {
1927 339 : ZERO_STRUCT(auth2);
1928 : /* the authenticator should be ignored by the server */
1929 339 : generate_random_buffer((uint8_t *) &auth, sizeof(auth));
1930 :
1931 339 : r.in.validation_level = i;
1932 :
1933 339 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1934 : "LogonSamLogon failed");
1935 339 : torture_assert_ntstatus_equal(tctx, r.out.result,
1936 : NT_STATUS_INVALID_INFO_CLASS,
1937 : "LogonSamLogon failed");
1938 :
1939 339 : torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1940 : "LogonSamLogon invalid *r.out.authoritative");
1941 339 : torture_assert(tctx,
1942 : all_zero((uint8_t *)&auth2, sizeof(auth2)),
1943 : "Return authenticator non zero");
1944 : }
1945 :
1946 1017 : for (i=2;i<=3;i++) {
1947 678 : ZERO_STRUCT(auth2);
1948 678 : netlogon_creds_client_authenticator(creds, &auth);
1949 :
1950 678 : r.in.validation_level = i;
1951 :
1952 678 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1953 : "LogonSamLogon failed");
1954 678 : torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
1955 :
1956 678 : torture_assert(tctx, netlogon_creds_client_check(creds,
1957 : &r.out.return_authenticator->cred),
1958 : "Credential chaining failed");
1959 678 : torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1960 : "LogonSamLogon invalid *r.out.authoritative");
1961 : }
1962 :
1963 339 : r.in.logon_level = 52;
1964 :
1965 1017 : for (i=2;i<=3;i++) {
1966 678 : ZERO_STRUCT(auth2);
1967 : /* the authenticator should be ignored by the server */
1968 678 : generate_random_buffer((uint8_t *) &auth, sizeof(auth));
1969 :
1970 678 : r.in.validation_level = i;
1971 :
1972 678 : torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
1973 :
1974 678 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1975 : "LogonSamLogon failed");
1976 678 : torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
1977 : "LogonSamLogon expected INVALID_PARAMETER");
1978 :
1979 678 : torture_assert(tctx,
1980 : all_zero((uint8_t *)&auth2, sizeof(auth2)),
1981 : "Return authenticator non zero");
1982 678 : torture_assert_int_equal(tctx, *r.out.authoritative, 1,
1983 : "LogonSamLogon invalid *r.out.authoritative");
1984 : }
1985 :
1986 339 : r.in.credential = NULL;
1987 :
1988 1017 : for (i=2;i<=3;i++) {
1989 678 : ZERO_STRUCT(auth2);
1990 :
1991 678 : r.in.validation_level = i;
1992 :
1993 678 : torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
1994 :
1995 678 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
1996 : "LogonSamLogon failed");
1997 678 : torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
1998 : "LogonSamLogon expected INVALID_PARAMETER");
1999 :
2000 678 : torture_assert(tctx,
2001 : all_zero((uint8_t *)&auth2, sizeof(auth2)),
2002 : "Return authenticator non zero");
2003 678 : torture_assert_int_equal(tctx, *r.out.authoritative, 1,
2004 : "LogonSamLogon invalid *r.out.authoritative");
2005 : }
2006 :
2007 339 : r.in.logon_level = NetlogonNetworkInformation;
2008 339 : r.in.credential = &auth;
2009 :
2010 1017 : for (i=2;i<=3;i++) {
2011 678 : ZERO_STRUCT(auth2);
2012 678 : netlogon_creds_client_authenticator(creds, &auth);
2013 :
2014 678 : r.in.validation_level = i;
2015 :
2016 678 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
2017 : "LogonSamLogon failed");
2018 678 : torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
2019 :
2020 678 : torture_assert(tctx, netlogon_creds_client_check(creds,
2021 : &r.out.return_authenticator->cred),
2022 : "Credential chaining failed");
2023 678 : torture_assert_int_equal(tctx, *r.out.authoritative, 1,
2024 : "LogonSamLogon invalid *r.out.authoritative");
2025 : }
2026 :
2027 339 : return true;
2028 : }
2029 :
2030 336 : 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 336 : return test_netlogon_ops_args(p, tctx, credentials, creds, false);
2035 : }
2036 :
2037 : /*
2038 : try a netlogon GetCapabilities
2039 : */
2040 216 : 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 : NTSTATUS status;
2045 : struct netr_LogonGetCapabilities r;
2046 : union netr_Capabilities capabilities;
2047 : struct netr_Authenticator auth, return_auth;
2048 : struct netlogon_creds_CredentialState tmp_creds;
2049 216 : struct dcerpc_binding_handle *b = p->binding_handle;
2050 :
2051 216 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2052 216 : r.in.computer_name = cli_credentials_get_workstation(credentials);
2053 216 : r.in.credential = &auth;
2054 216 : r.in.return_authenticator = &return_auth;
2055 216 : r.in.query_level = 1;
2056 216 : r.out.capabilities = &capabilities;
2057 216 : r.out.return_authenticator = &return_auth;
2058 :
2059 216 : torture_comment(tctx, "Testing LogonGetCapabilities with query_level=0\n");
2060 :
2061 216 : r.in.query_level = 0;
2062 216 : 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 a the authenticator.
2070 : */
2071 216 : tmp_creds = *creds;
2072 216 : netlogon_creds_client_authenticator(&tmp_creds, &auth);
2073 :
2074 216 : status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
2075 216 : torture_assert_ntstatus_equal(tctx, status, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE,
2076 : "LogonGetCapabilities query_level=0 failed");
2077 :
2078 216 : torture_comment(tctx, "Testing LogonGetCapabilities with query_level=3\n");
2079 :
2080 216 : r.in.query_level = 3;
2081 216 : 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 a the authenticator.
2089 : */
2090 216 : tmp_creds = *creds;
2091 216 : netlogon_creds_client_authenticator(&tmp_creds, &auth);
2092 :
2093 216 : status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
2094 216 : torture_assert_ntstatus_equal(tctx, status, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE,
2095 : "LogonGetCapabilities query_level=0 failed");
2096 :
2097 216 : torture_comment(tctx, "Testing LogonGetCapabilities with query_level=1\n");
2098 :
2099 216 : r.in.query_level = 1;
2100 216 : 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 a the authenticator.
2107 : */
2108 216 : tmp_creds = *creds;
2109 216 : netlogon_creds_client_authenticator(&tmp_creds, &auth);
2110 :
2111 216 : status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
2112 216 : torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities failed");
2113 216 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2114 0 : return true;
2115 : }
2116 :
2117 216 : *creds = tmp_creds;
2118 :
2119 216 : torture_assert(tctx, netlogon_creds_client_check(creds,
2120 : &r.out.return_authenticator->cred),
2121 : "Credential chaining failed");
2122 :
2123 216 : torture_assert_int_equal(tctx, creds->negotiate_flags,
2124 : capabilities.server_capabilities,
2125 : "negotiate flags");
2126 :
2127 216 : torture_comment(tctx, "Testing LogonGetCapabilities with query_level=2\n");
2128 :
2129 216 : r.in.query_level = 2;
2130 216 : 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 a the authenticator.
2138 : */
2139 216 : tmp_creds = *creds;
2140 216 : netlogon_creds_client_authenticator(&tmp_creds, &auth);
2141 :
2142 216 : status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
2143 216 : 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 216 : 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 12 : static bool test_SamLogon(struct torture_context *tctx,
2170 : struct dcerpc_pipe *p,
2171 : struct cli_credentials *credentials)
2172 : {
2173 : struct netlogon_creds_CredentialState *creds;
2174 :
2175 12 : if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
2176 0 : return false;
2177 : }
2178 :
2179 12 : return test_netlogon_ops(p, tctx, credentials, creds);
2180 : }
2181 :
2182 9 : static bool test_invalidAuthenticate2(struct torture_context *tctx,
2183 : struct dcerpc_pipe *p,
2184 : struct cli_credentials *credentials)
2185 : {
2186 : struct netlogon_creds_CredentialState *creds;
2187 9 : uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2188 :
2189 9 : torture_comment(tctx, "Testing invalidAuthenticate2\n");
2190 :
2191 9 : 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 9 : if (!test_SetupCredentials2ex(p, tctx, flags,
2199 : credentials,
2200 : "1234567890123456",
2201 : cli_credentials_get_secure_channel_type(credentials),
2202 9 : STATUS_BUFFER_OVERFLOW,
2203 : &creds)) {
2204 0 : return false;
2205 : }
2206 :
2207 9 : if (!test_SetupCredentials2ex(p, tctx, flags,
2208 : credentials,
2209 : "123456789012345",
2210 : cli_credentials_get_secure_channel_type(credentials),
2211 9 : NT_STATUS_OK,
2212 : &creds)) {
2213 0 : return false;
2214 : }
2215 :
2216 9 : return true;
2217 : }
2218 :
2219 9 : static bool test_ServerReqChallengeGlobal(struct torture_context *tctx,
2220 : struct dcerpc_pipe *p1,
2221 : struct cli_credentials *machine_credentials)
2222 : {
2223 9 : uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2224 : struct netr_ServerReqChallenge r;
2225 : struct netr_ServerAuthenticate3 a;
2226 : struct netr_Credential credentials1, credentials2, credentials3;
2227 : struct netlogon_creds_CredentialState *creds;
2228 : struct samr_Password mach_password;
2229 : uint32_t rid;
2230 : const char *machine_name;
2231 : const char *plain_pass;
2232 9 : struct dcerpc_binding_handle *b1 = p1->binding_handle;
2233 9 : struct dcerpc_pipe *p2 = NULL;
2234 9 : struct dcerpc_binding_handle *b2 = NULL;
2235 :
2236 9 : machine_name = cli_credentials_get_workstation(machine_credentials);
2237 9 : torture_assert(tctx, machine_name != NULL, "machine_name");
2238 9 : plain_pass = cli_credentials_get_password(machine_credentials);
2239 9 : torture_assert(tctx, plain_pass != NULL, "plain_pass");
2240 :
2241 9 : torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2242 :
2243 9 : 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 9 : b2 = p2->binding_handle;
2250 :
2251 9 : r.in.server_name = NULL;
2252 9 : r.in.computer_name = machine_name;
2253 9 : r.in.credentials = &credentials1;
2254 9 : r.out.return_credentials = &credentials2;
2255 :
2256 9 : netlogon_creds_random_challenge(&credentials1);
2257 :
2258 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2259 : "ServerReqChallenge failed on b1");
2260 9 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2261 :
2262 9 : E_md4hash(plain_pass, mach_password.hash);
2263 :
2264 9 : a.in.server_name = NULL;
2265 9 : a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2266 9 : a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2267 9 : a.in.computer_name = machine_name;
2268 9 : a.in.negotiate_flags = &flags;
2269 9 : a.in.credentials = &credentials3;
2270 9 : a.out.return_credentials = &credentials3;
2271 9 : a.out.negotiate_flags = &flags;
2272 9 : a.out.rid = &rid;
2273 :
2274 18 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2275 : a.in.computer_name,
2276 9 : a.in.secure_channel_type,
2277 : &credentials1, &credentials2,
2278 : &mach_password, &credentials3,
2279 : flags);
2280 :
2281 9 : torture_assert(tctx, creds != NULL, "memory allocation");
2282 :
2283 9 : torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
2284 :
2285 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2286 : "ServerAuthenticate3 failed on b2");
2287 9 : torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
2288 9 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2289 :
2290 9 : return true;
2291 : }
2292 :
2293 : /*
2294 : * Test the re-use of the challenge is not possible on a third
2295 : * connection, after first useing it second one.
2296 : */
2297 :
2298 9 : static bool test_ServerReqChallengeReuseGlobal(struct torture_context *tctx,
2299 : struct dcerpc_pipe *p1,
2300 : struct cli_credentials *machine_credentials)
2301 : {
2302 9 : uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2303 : struct netr_ServerReqChallenge r;
2304 : struct netr_ServerAuthenticate3 a;
2305 : struct netr_Credential credentials1, credentials2, credentials3;
2306 : struct netlogon_creds_CredentialState *creds;
2307 : struct samr_Password mach_password;
2308 : uint32_t rid;
2309 : const char *machine_name;
2310 : const char *plain_pass;
2311 9 : struct dcerpc_binding_handle *b1 = p1->binding_handle;
2312 9 : struct dcerpc_pipe *p2 = NULL;
2313 9 : struct dcerpc_binding_handle *b2 = NULL;
2314 9 : struct dcerpc_pipe *p3 = NULL;
2315 9 : struct dcerpc_binding_handle *b3 = NULL;
2316 :
2317 9 : machine_name = cli_credentials_get_workstation(machine_credentials);
2318 9 : torture_assert(tctx, machine_name != NULL, "machine_name");
2319 9 : plain_pass = cli_credentials_get_password(machine_credentials);
2320 9 : torture_assert(tctx, plain_pass != NULL, "plain_pass");
2321 :
2322 9 : torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2323 :
2324 9 : 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 9 : b2 = p2->binding_handle;
2331 :
2332 9 : 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 9 : b3 = p3->binding_handle;
2339 :
2340 9 : r.in.server_name = NULL;
2341 9 : r.in.computer_name = machine_name;
2342 9 : r.in.credentials = &credentials1;
2343 9 : r.out.return_credentials = &credentials2;
2344 :
2345 9 : netlogon_creds_random_challenge(&credentials1);
2346 :
2347 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2348 : "ServerReqChallenge failed on b1");
2349 9 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2350 :
2351 9 : E_md4hash(plain_pass, mach_password.hash);
2352 :
2353 9 : a.in.server_name = NULL;
2354 9 : a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2355 9 : a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2356 9 : a.in.computer_name = machine_name;
2357 9 : a.in.negotiate_flags = &flags;
2358 9 : a.in.credentials = &credentials3;
2359 9 : a.out.return_credentials = &credentials3;
2360 9 : a.out.negotiate_flags = &flags;
2361 9 : a.out.rid = &rid;
2362 :
2363 18 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2364 : a.in.computer_name,
2365 9 : a.in.secure_channel_type,
2366 : &credentials1, &credentials2,
2367 : &mach_password, &credentials3,
2368 : flags);
2369 :
2370 9 : torture_assert(tctx, creds != NULL, "memory allocation");
2371 :
2372 9 : torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
2373 :
2374 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2375 : "ServerAuthenticate3 failed on b2");
2376 9 : torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
2377 9 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2378 :
2379 : /* We have to re-run this part */
2380 18 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2381 : a.in.computer_name,
2382 9 : a.in.secure_channel_type,
2383 : &credentials1, &credentials2,
2384 : &mach_password, &credentials3,
2385 : flags);
2386 :
2387 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b3, tctx, &a),
2388 : "ServerAuthenticate3 failed on b3");
2389 9 : torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2390 : "ServerAuthenticate3 should have failed on b3, due to credential reuse");
2391 9 : return true;
2392 : }
2393 :
2394 : /*
2395 : * Test if use of the per-pipe challenge will wipe out the globally cached challenge
2396 : */
2397 9 : static bool test_ServerReqChallengeReuseGlobal2(struct torture_context *tctx,
2398 : struct dcerpc_pipe *p1,
2399 : struct cli_credentials *machine_credentials)
2400 : {
2401 9 : uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2402 : struct netr_ServerReqChallenge r;
2403 : struct netr_ServerAuthenticate3 a;
2404 : struct netr_Credential credentials1, credentials2, credentials3;
2405 : struct netlogon_creds_CredentialState *creds;
2406 : struct samr_Password mach_password;
2407 : uint32_t rid;
2408 : const char *machine_name;
2409 : const char *plain_pass;
2410 9 : struct dcerpc_binding_handle *b1 = p1->binding_handle;
2411 9 : struct dcerpc_pipe *p2 = NULL;
2412 9 : struct dcerpc_binding_handle *b2 = NULL;
2413 :
2414 9 : machine_name = cli_credentials_get_workstation(machine_credentials);
2415 9 : torture_assert(tctx, machine_name != NULL, "machine_name");
2416 9 : plain_pass = cli_credentials_get_password(machine_credentials);
2417 9 : torture_assert(tctx, plain_pass != NULL, "plain_pass");
2418 :
2419 9 : torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2420 :
2421 9 : 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 9 : b2 = p2->binding_handle;
2428 :
2429 9 : r.in.server_name = NULL;
2430 9 : r.in.computer_name = machine_name;
2431 9 : r.in.credentials = &credentials1;
2432 9 : r.out.return_credentials = &credentials2;
2433 :
2434 9 : netlogon_creds_random_challenge(&credentials1);
2435 :
2436 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2437 : "ServerReqChallenge failed on b1");
2438 9 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2439 :
2440 9 : E_md4hash(plain_pass, mach_password.hash);
2441 :
2442 9 : a.in.server_name = NULL;
2443 9 : a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2444 9 : a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2445 9 : a.in.computer_name = machine_name;
2446 9 : a.in.negotiate_flags = &flags;
2447 9 : a.in.credentials = &credentials3;
2448 9 : a.out.return_credentials = &credentials3;
2449 9 : a.out.negotiate_flags = &flags;
2450 9 : a.out.rid = &rid;
2451 :
2452 18 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2453 : a.in.computer_name,
2454 9 : a.in.secure_channel_type,
2455 : &credentials1, &credentials2,
2456 : &mach_password, &credentials3,
2457 : flags);
2458 :
2459 9 : torture_assert(tctx, creds != NULL, "memory allocation");
2460 :
2461 9 : torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
2462 :
2463 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
2464 : "ServerAuthenticate3 failed on b");
2465 9 : torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b");
2466 9 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2467 :
2468 : /* We have to re-run this part */
2469 18 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2470 : a.in.computer_name,
2471 9 : a.in.secure_channel_type,
2472 : &credentials1, &credentials2,
2473 : &mach_password, &credentials3,
2474 : flags);
2475 :
2476 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2477 : "ServerAuthenticate3 failed on b2");
2478 9 : torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2479 : "ServerAuthenticate3 should have failed on b2, due to credential reuse");
2480 9 : return true;
2481 : }
2482 :
2483 : /*
2484 : * Test if use of the globally cached challenge will wipe out the
2485 : * per-pipe challenge
2486 : */
2487 9 : static bool test_ServerReqChallengeReuseGlobal3(struct torture_context *tctx,
2488 : struct dcerpc_pipe *p1,
2489 : struct cli_credentials *machine_credentials)
2490 : {
2491 9 : uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2492 : struct netr_ServerReqChallenge r;
2493 : struct netr_ServerAuthenticate3 a;
2494 : struct netr_Credential credentials1, credentials2, credentials3;
2495 : struct netlogon_creds_CredentialState *creds;
2496 : struct samr_Password mach_password;
2497 : uint32_t rid;
2498 : const char *machine_name;
2499 : const char *plain_pass;
2500 9 : struct dcerpc_binding_handle *b1 = p1->binding_handle;
2501 9 : struct dcerpc_pipe *p2 = NULL;
2502 9 : struct dcerpc_binding_handle *b2 = NULL;
2503 :
2504 9 : machine_name = cli_credentials_get_workstation(machine_credentials);
2505 9 : torture_assert(tctx, machine_name != NULL, "machine_name");
2506 9 : plain_pass = cli_credentials_get_password(machine_credentials);
2507 9 : torture_assert(tctx, plain_pass != NULL, "plain_pass");
2508 :
2509 9 : torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2510 :
2511 9 : 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 9 : b2 = p2->binding_handle;
2518 :
2519 9 : r.in.server_name = NULL;
2520 9 : r.in.computer_name = machine_name;
2521 9 : r.in.credentials = &credentials1;
2522 9 : r.out.return_credentials = &credentials2;
2523 :
2524 9 : netlogon_creds_random_challenge(&credentials1);
2525 :
2526 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2527 : "ServerReqChallenge failed on b1");
2528 9 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2529 :
2530 9 : E_md4hash(plain_pass, mach_password.hash);
2531 :
2532 9 : a.in.server_name = NULL;
2533 9 : a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2534 9 : a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2535 9 : a.in.computer_name = machine_name;
2536 9 : a.in.negotiate_flags = &flags;
2537 9 : a.in.credentials = &credentials3;
2538 9 : a.out.return_credentials = &credentials3;
2539 9 : a.out.negotiate_flags = &flags;
2540 9 : a.out.rid = &rid;
2541 :
2542 18 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2543 : a.in.computer_name,
2544 9 : a.in.secure_channel_type,
2545 : &credentials1, &credentials2,
2546 : &mach_password, &credentials3,
2547 : flags);
2548 :
2549 9 : torture_assert(tctx, creds != NULL, "memory allocation");
2550 :
2551 9 : torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
2552 :
2553 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2554 : "ServerAuthenticate3 failed on b2");
2555 9 : torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b");
2556 9 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2557 :
2558 : /* We have to re-run this part */
2559 18 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2560 : a.in.computer_name,
2561 9 : a.in.secure_channel_type,
2562 : &credentials1, &credentials2,
2563 : &mach_password, &credentials3,
2564 : flags);
2565 :
2566 9 : torture_assert(tctx, creds != NULL, "memory allocation");
2567 :
2568 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
2569 : "ServerAuthenticate3 failed on b1");
2570 9 : 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 9 : static bool test_ServerReqChallengeReuseGlobal4(struct torture_context *tctx,
2579 : struct dcerpc_pipe *p1,
2580 : struct cli_credentials *machine_credentials)
2581 : {
2582 9 : uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2583 : struct netr_ServerReqChallenge r;
2584 : struct netr_ServerAuthenticate3 a;
2585 : struct netr_Credential credentials1, credentials1_random,
2586 : credentials2, credentials3, credentials_discard;
2587 : struct netlogon_creds_CredentialState *creds;
2588 : struct samr_Password mach_password;
2589 : uint32_t rid;
2590 : const char *machine_name;
2591 : const char *plain_pass;
2592 9 : struct dcerpc_binding_handle *b1 = p1->binding_handle;
2593 9 : struct dcerpc_pipe *p2 = NULL;
2594 9 : struct dcerpc_binding_handle *b2 = NULL;
2595 :
2596 9 : machine_name = cli_credentials_get_workstation(machine_credentials);
2597 9 : torture_assert(tctx, machine_name != NULL, "machine_name");
2598 9 : plain_pass = cli_credentials_get_password(machine_credentials);
2599 9 : torture_assert(tctx, plain_pass != NULL, "plain_pass");
2600 :
2601 9 : torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2602 :
2603 9 : 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 9 : b2 = p2->binding_handle;
2610 :
2611 9 : r.in.server_name = NULL;
2612 9 : r.in.computer_name = "CHALTEST1";
2613 9 : r.in.credentials = &credentials1_random;
2614 9 : r.out.return_credentials = &credentials_discard;
2615 :
2616 9 : netlogon_creds_random_challenge(&credentials1_random);
2617 :
2618 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2619 : "ServerReqChallenge failed on b1");
2620 9 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2621 :
2622 : /* Now ask for the actual client name */
2623 9 : r.in.server_name = NULL;
2624 9 : r.in.computer_name = machine_name;
2625 9 : r.in.credentials = &credentials1;
2626 9 : r.out.return_credentials = &credentials2;
2627 :
2628 9 : netlogon_creds_random_challenge(&credentials1);
2629 :
2630 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2631 : "ServerReqChallenge failed on b1");
2632 9 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2633 :
2634 9 : r.in.server_name = NULL;
2635 9 : r.in.computer_name = "CHALTEST2";
2636 9 : r.in.credentials = &credentials1_random;
2637 9 : r.out.return_credentials = &credentials_discard;
2638 :
2639 9 : netlogon_creds_random_challenge(&credentials1_random);
2640 :
2641 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
2642 : "ServerReqChallenge failed on b1");
2643 9 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2644 :
2645 9 : E_md4hash(plain_pass, mach_password.hash);
2646 :
2647 9 : a.in.server_name = NULL;
2648 9 : a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2649 9 : a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2650 9 : a.in.computer_name = machine_name;
2651 9 : a.in.negotiate_flags = &flags;
2652 9 : a.in.credentials = &credentials3;
2653 9 : a.out.return_credentials = &credentials3;
2654 9 : a.out.negotiate_flags = &flags;
2655 9 : a.out.rid = &rid;
2656 :
2657 18 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2658 : a.in.computer_name,
2659 9 : a.in.secure_channel_type,
2660 : &credentials1, &credentials2,
2661 : &mach_password, &credentials3,
2662 : flags);
2663 :
2664 9 : torture_assert(tctx, creds != NULL, "memory allocation");
2665 :
2666 9 : torture_comment(tctx, "Testing ServerAuthenticate3 on b2 (must use global credentials)\n");
2667 :
2668 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
2669 : "ServerAuthenticate3 failed on b2");
2670 9 : torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
2671 9 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2672 :
2673 : /* We have to re-run this part */
2674 18 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2675 : a.in.computer_name,
2676 9 : a.in.secure_channel_type,
2677 : &credentials1, &credentials2,
2678 : &mach_password, &credentials3,
2679 : flags);
2680 :
2681 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
2682 : "ServerAuthenticate3 failed on b1");
2683 9 : torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2684 : "ServerAuthenticate3 should have failed on b1, due to credential reuse");
2685 9 : return true;
2686 : }
2687 :
2688 9 : static bool test_ServerReqChallengeReuse(struct torture_context *tctx,
2689 : struct dcerpc_pipe *p,
2690 : struct cli_credentials *machine_credentials)
2691 : {
2692 9 : uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
2693 : struct netr_ServerReqChallenge r;
2694 : struct netr_ServerAuthenticate3 a;
2695 : struct netr_Credential credentials1, credentials2, credentials3;
2696 : struct netlogon_creds_CredentialState *creds;
2697 : struct samr_Password mach_password;
2698 : uint32_t rid;
2699 : const char *machine_name;
2700 : const char *plain_pass;
2701 9 : struct dcerpc_binding_handle *b = p->binding_handle;
2702 :
2703 9 : machine_name = cli_credentials_get_workstation(machine_credentials);
2704 9 : torture_assert(tctx, machine_name != NULL, "machine_name");
2705 9 : plain_pass = cli_credentials_get_password(machine_credentials);
2706 9 : torture_assert(tctx, plain_pass != NULL, "plain_pass");
2707 :
2708 9 : torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
2709 :
2710 9 : r.in.server_name = NULL;
2711 9 : r.in.computer_name = machine_name;
2712 9 : r.in.credentials = &credentials1;
2713 9 : r.out.return_credentials = &credentials2;
2714 :
2715 9 : netlogon_creds_random_challenge(&credentials1);
2716 :
2717 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2718 : "ServerReqChallenge");
2719 9 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
2720 :
2721 9 : E_md4hash(plain_pass, mach_password.hash);
2722 :
2723 9 : a.in.server_name = NULL;
2724 9 : a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2725 9 : a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2726 9 : a.in.computer_name = machine_name;
2727 9 : a.in.negotiate_flags = &flags;
2728 9 : a.in.credentials = &credentials3;
2729 9 : a.out.return_credentials = &credentials3;
2730 9 : a.out.negotiate_flags = &flags;
2731 9 : a.out.rid = &rid;
2732 :
2733 18 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2734 : a.in.computer_name,
2735 9 : a.in.secure_channel_type,
2736 : &credentials1, &credentials2,
2737 : &mach_password, &credentials3,
2738 : flags);
2739 :
2740 9 : torture_assert(tctx, creds != NULL, "memory allocation");
2741 :
2742 9 : torture_comment(tctx, "Testing ServerAuthenticate3\n");
2743 :
2744 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2745 : "ServerAuthenticate3 failed");
2746 9 : torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed");
2747 9 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2748 :
2749 : /* We have to re-run this part */
2750 18 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2751 : a.in.computer_name,
2752 9 : a.in.secure_channel_type,
2753 : &credentials1, &credentials2,
2754 : &mach_password, &credentials3,
2755 : flags);
2756 :
2757 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2758 : "ServerAuthenticate3 failed");
2759 9 : 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 9 : ZERO_STRUCT(credentials1.data);
2763 9 : ZERO_STRUCT(credentials2.data);
2764 18 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2765 : a.in.computer_name,
2766 9 : a.in.secure_channel_type,
2767 : &credentials1, &credentials2,
2768 : &mach_password, &credentials3,
2769 : flags);
2770 :
2771 9 : torture_assert(tctx, creds != NULL, "memory allocation");
2772 :
2773 9 : torture_comment(tctx, "Testing ServerAuthenticate3 with zero'ed challenge\n");
2774 :
2775 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2776 : "ServerAuthenticate3 failed");
2777 9 : torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
2778 : "ServerAuthenticate3 should have failed on b3, due to credential reuse");
2779 9 : 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 : 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 9 : static bool test_DatabaseSync(struct torture_context *tctx,
2802 : struct dcerpc_pipe *p,
2803 : struct cli_credentials *machine_credentials)
2804 : {
2805 : struct netr_DatabaseSync r;
2806 : struct netlogon_creds_CredentialState *creds;
2807 9 : const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
2808 : int i;
2809 9 : struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2810 : struct netr_Authenticator credential, return_authenticator;
2811 9 : struct dcerpc_binding_handle *b = p->binding_handle;
2812 :
2813 9 : if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2814 0 : return false;
2815 : }
2816 :
2817 9 : ZERO_STRUCT(return_authenticator);
2818 :
2819 9 : r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2820 9 : r.in.computername = TEST_MACHINE_NAME;
2821 9 : r.in.preferredmaximumlength = (uint32_t)-1;
2822 9 : r.in.return_authenticator = &return_authenticator;
2823 9 : r.out.delta_enum_array = &delta_enum_array;
2824 9 : r.out.return_authenticator = &return_authenticator;
2825 :
2826 9 : for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2827 :
2828 9 : uint32_t sync_context = 0;
2829 :
2830 9 : r.in.database_id = database_ids[i];
2831 9 : r.in.sync_context = &sync_context;
2832 9 : r.out.sync_context = &sync_context;
2833 :
2834 9 : torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
2835 :
2836 : do {
2837 9 : netlogon_creds_client_authenticator(creds, &credential);
2838 :
2839 9 : r.in.credential = &credential;
2840 :
2841 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync_r(b, tctx, &r),
2842 : "DatabaseSync failed");
2843 9 : if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2844 0 : break;
2845 :
2846 : /* Native mode servers don't do this */
2847 9 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
2848 0 : return true;
2849 : }
2850 9 : 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 9 : static bool test_DatabaseDeltas(struct torture_context *tctx,
2877 : struct dcerpc_pipe *p,
2878 : struct cli_credentials *machine_credentials)
2879 : {
2880 : struct netr_DatabaseDeltas r;
2881 : struct netlogon_creds_CredentialState *creds;
2882 : struct netr_Authenticator credential;
2883 : struct netr_Authenticator return_authenticator;
2884 9 : struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2885 9 : const uint32_t database_ids[] = {0, 1, 2};
2886 : int i;
2887 9 : struct dcerpc_binding_handle *b = p->binding_handle;
2888 :
2889 9 : if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2890 0 : return false;
2891 : }
2892 :
2893 9 : r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2894 9 : r.in.computername = TEST_MACHINE_NAME;
2895 9 : r.in.preferredmaximumlength = (uint32_t)-1;
2896 9 : ZERO_STRUCT(r.in.return_authenticator);
2897 9 : r.out.return_authenticator = &return_authenticator;
2898 9 : r.out.delta_enum_array = &delta_enum_array;
2899 :
2900 36 : for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2901 27 : r.in.database_id = database_ids[i];
2902 27 : r.in.sequence_num = &sequence_nums[r.in.database_id];
2903 :
2904 27 : 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 : 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 9 : return true;
2936 : }
2937 :
2938 9 : static bool test_DatabaseRedo(struct torture_context *tctx,
2939 : struct dcerpc_pipe *p,
2940 : struct cli_credentials *machine_credentials)
2941 : {
2942 : struct netr_DatabaseRedo r;
2943 : struct netlogon_creds_CredentialState *creds;
2944 : struct netr_Authenticator credential;
2945 : struct netr_Authenticator return_authenticator;
2946 9 : struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2947 : struct netr_ChangeLogEntry e;
2948 : struct dom_sid null_sid, *sid;
2949 : int i,d;
2950 9 : struct dcerpc_binding_handle *b = p->binding_handle;
2951 :
2952 9 : ZERO_STRUCT(null_sid);
2953 :
2954 9 : sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
2955 :
2956 : {
2957 :
2958 : 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 72 : } 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 9 : .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 9 : .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 9 : .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 9 : .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 9 : .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 9 : .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 9 : .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 9 : ZERO_STRUCT(return_authenticator);
3369 :
3370 9 : r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3371 9 : r.in.computername = TEST_MACHINE_NAME;
3372 9 : r.in.return_authenticator = &return_authenticator;
3373 9 : r.out.return_authenticator = &return_authenticator;
3374 9 : r.out.delta_enum_array = &delta_enum_array;
3375 :
3376 9 : for (d=0; d<3; d++) {
3377 9 : const char *database = NULL;
3378 :
3379 9 : switch (d) {
3380 9 : case 0:
3381 9 : database = "SAM";
3382 9 : 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 9 : torture_comment(tctx, "Testing DatabaseRedo\n");
3394 :
3395 9 : if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
3396 9 : return false;
3397 : }
3398 :
3399 9 : for (i=0;i<ARRAY_SIZE(changes);i++) {
3400 :
3401 9 : if (d != changes[i].db_index) {
3402 0 : continue;
3403 : }
3404 :
3405 9 : netlogon_creds_client_authenticator(creds, &credential);
3406 :
3407 9 : r.in.credential = &credential;
3408 :
3409 9 : e.serial_number1 = 0;
3410 9 : e.serial_number2 = 0;
3411 9 : e.object_rid = changes[i].rid;
3412 9 : e.flags = changes[i].flags;
3413 9 : e.db_index = changes[i].db_index;
3414 9 : e.delta_type = changes[i].delta_type;
3415 :
3416 9 : 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 9 : default:
3424 9 : break;
3425 : }
3426 :
3427 9 : r.in.change_log_entry = e;
3428 :
3429 9 : torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
3430 : database, changes[i].comment);
3431 :
3432 9 : 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 9 : static bool test_AccountDeltas(struct torture_context *tctx,
3475 : struct dcerpc_pipe *p,
3476 : struct cli_credentials *machine_credentials)
3477 : {
3478 : struct netr_AccountDeltas r;
3479 : struct netlogon_creds_CredentialState *creds;
3480 :
3481 : struct netr_AccountBuffer buffer;
3482 9 : uint32_t count_returned = 0;
3483 9 : uint32_t total_entries = 0;
3484 : struct netr_UAS_INFO_0 recordid;
3485 : struct netr_Authenticator return_authenticator;
3486 9 : struct dcerpc_binding_handle *b = p->binding_handle;
3487 :
3488 9 : if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
3489 0 : return false;
3490 : }
3491 :
3492 9 : ZERO_STRUCT(return_authenticator);
3493 :
3494 9 : r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3495 9 : r.in.computername = TEST_MACHINE_NAME;
3496 9 : r.in.return_authenticator = &return_authenticator;
3497 9 : netlogon_creds_client_authenticator(creds, &r.in.credential);
3498 9 : ZERO_STRUCT(r.in.uas);
3499 9 : r.in.count=10;
3500 9 : r.in.level=0;
3501 9 : r.in.buffersize=100;
3502 9 : r.out.buffer = &buffer;
3503 9 : r.out.count_returned = &count_returned;
3504 9 : r.out.total_entries = &total_entries;
3505 9 : r.out.recordid = &recordid;
3506 9 : r.out.return_authenticator = &return_authenticator;
3507 :
3508 : /* w2k3 returns "NOT IMPLEMENTED" for this call */
3509 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountDeltas_r(b, tctx, &r),
3510 : "AccountDeltas failed");
3511 9 : torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
3512 :
3513 9 : return true;
3514 : }
3515 :
3516 : /*
3517 : try a netlogon AccountSync
3518 : */
3519 9 : static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
3520 : struct cli_credentials *machine_credentials)
3521 : {
3522 : struct netr_AccountSync r;
3523 : struct netlogon_creds_CredentialState *creds;
3524 :
3525 : struct netr_AccountBuffer buffer;
3526 9 : uint32_t count_returned = 0;
3527 9 : uint32_t total_entries = 0;
3528 9 : uint32_t next_reference = 0;
3529 : struct netr_UAS_INFO_0 recordid;
3530 : struct netr_Authenticator return_authenticator;
3531 9 : struct dcerpc_binding_handle *b = p->binding_handle;
3532 :
3533 9 : ZERO_STRUCT(recordid);
3534 9 : ZERO_STRUCT(return_authenticator);
3535 :
3536 9 : if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
3537 0 : return false;
3538 : }
3539 :
3540 9 : r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3541 9 : r.in.computername = TEST_MACHINE_NAME;
3542 9 : r.in.return_authenticator = &return_authenticator;
3543 9 : netlogon_creds_client_authenticator(creds, &r.in.credential);
3544 9 : r.in.recordid = &recordid;
3545 9 : r.in.reference=0;
3546 9 : r.in.level=0;
3547 9 : r.in.buffersize=100;
3548 9 : r.out.buffer = &buffer;
3549 9 : r.out.count_returned = &count_returned;
3550 9 : r.out.total_entries = &total_entries;
3551 9 : r.out.next_reference = &next_reference;
3552 9 : r.out.recordid = &recordid;
3553 9 : r.out.return_authenticator = &return_authenticator;
3554 :
3555 : /* w2k3 returns "NOT IMPLEMENTED" for this call */
3556 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountSync_r(b, tctx, &r),
3557 : "AccountSync failed");
3558 9 : torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
3559 :
3560 9 : return true;
3561 : }
3562 :
3563 : /*
3564 : try a netlogon GetDcName
3565 : */
3566 9 : static bool test_GetDcName(struct torture_context *tctx,
3567 : struct dcerpc_pipe *p)
3568 : {
3569 : struct netr_GetDcName r;
3570 9 : const char *dcname = NULL;
3571 9 : struct dcerpc_binding_handle *b = p->binding_handle;
3572 :
3573 9 : r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3574 9 : r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
3575 9 : r.out.dcname = &dcname;
3576 :
3577 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_GetDcName_r(b, tctx, &r),
3578 : "GetDcName failed");
3579 9 : torture_assert_werr_ok(tctx, r.out.result, "GetDcName failed");
3580 :
3581 9 : torture_comment(tctx, "\tDC is at '%s'\n", dcname);
3582 :
3583 9 : return true;
3584 : }
3585 :
3586 2511 : static const char *function_code_str(TALLOC_CTX *mem_ctx,
3587 : enum netr_LogonControlCode function_code)
3588 : {
3589 2511 : switch (function_code) {
3590 108 : case NETLOGON_CONTROL_QUERY:
3591 108 : return "NETLOGON_CONTROL_QUERY";
3592 108 : case NETLOGON_CONTROL_REPLICATE:
3593 108 : return "NETLOGON_CONTROL_REPLICATE";
3594 108 : case NETLOGON_CONTROL_SYNCHRONIZE:
3595 108 : return "NETLOGON_CONTROL_SYNCHRONIZE";
3596 108 : case NETLOGON_CONTROL_PDC_REPLICATE:
3597 108 : return "NETLOGON_CONTROL_PDC_REPLICATE";
3598 270 : case NETLOGON_CONTROL_REDISCOVER:
3599 270 : return "NETLOGON_CONTROL_REDISCOVER";
3600 270 : case NETLOGON_CONTROL_TC_QUERY:
3601 270 : return "NETLOGON_CONTROL_TC_QUERY";
3602 270 : case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
3603 270 : return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
3604 108 : case NETLOGON_CONTROL_FIND_USER:
3605 108 : return "NETLOGON_CONTROL_FIND_USER";
3606 108 : case NETLOGON_CONTROL_CHANGE_PASSWORD:
3607 108 : return "NETLOGON_CONTROL_CHANGE_PASSWORD";
3608 108 : case NETLOGON_CONTROL_TC_VERIFY:
3609 108 : return "NETLOGON_CONTROL_TC_VERIFY";
3610 108 : case NETLOGON_CONTROL_FORCE_DNS_REG:
3611 108 : return "NETLOGON_CONTROL_FORCE_DNS_REG";
3612 108 : case NETLOGON_CONTROL_QUERY_DNS_REG:
3613 108 : return "NETLOGON_CONTROL_QUERY_DNS_REG";
3614 108 : case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
3615 108 : return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
3616 108 : case NETLOGON_CONTROL_TRUNCATE_LOG:
3617 108 : return "NETLOGON_CONTROL_TRUNCATE_LOG";
3618 324 : case NETLOGON_CONTROL_SET_DBFLAG:
3619 324 : return "NETLOGON_CONTROL_SET_DBFLAG";
3620 135 : case NETLOGON_CONTROL_BREAKPOINT:
3621 135 : return "NETLOGON_CONTROL_BREAKPOINT";
3622 54 : default:
3623 54 : return talloc_asprintf(mem_ctx, "unknown function code: %d",
3624 : function_code);
3625 : }
3626 : }
3627 :
3628 :
3629 : /*
3630 : try a netlogon LogonControl
3631 : */
3632 27 : static bool test_LogonControl(struct torture_context *tctx,
3633 : struct dcerpc_pipe *p,
3634 : struct cli_credentials *machine_credentials)
3635 :
3636 : {
3637 : NTSTATUS status;
3638 : struct netr_LogonControl r;
3639 : union netr_CONTROL_QUERY_INFORMATION query;
3640 : int i,f;
3641 27 : enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
3642 27 : struct dcerpc_binding_handle *b = p->binding_handle;
3643 :
3644 27 : 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 27 : if (machine_credentials) {
3664 27 : secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
3665 : }
3666 :
3667 27 : torture_comment(tctx, "Testing LogonControl with secure channel type: %d\n",
3668 : secure_channel_type);
3669 :
3670 27 : r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3671 27 : r.in.function_code = 1;
3672 27 : r.out.query = &query;
3673 :
3674 459 : for (f=0;f<ARRAY_SIZE(function_codes); f++) {
3675 2160 : for (i=1;i<5;i++) {
3676 :
3677 1728 : r.in.function_code = function_codes[f];
3678 1728 : r.in.level = i;
3679 :
3680 3456 : torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
3681 1728 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3682 :
3683 1728 : status = dcerpc_netr_LogonControl_r(b, tctx, &r);
3684 1728 : torture_assert_ntstatus_ok(tctx, status, "LogonControl");
3685 :
3686 1728 : switch (r.in.level) {
3687 432 : case 1:
3688 432 : switch (r.in.function_code) {
3689 135 : 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 135 : if ((secure_channel_type == SEC_CHAN_BDC) ||
3695 : (secure_channel_type == SEC_CHAN_WKSTA)) {
3696 90 : torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
3697 : "LogonControl returned unexpected error code");
3698 : } else {
3699 45 : torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
3700 : "LogonControl returned unexpected error code");
3701 : }
3702 135 : break;
3703 :
3704 243 : 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 243 : torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
3714 : "LogonControl returned unexpected error code");
3715 243 : break;
3716 27 : case NETLOGON_CONTROL_TRUNCATE_LOG:
3717 27 : if ((secure_channel_type == SEC_CHAN_BDC) ||
3718 : (secure_channel_type == SEC_CHAN_WKSTA)) {
3719 18 : torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
3720 : "LogonControl returned unexpected error code");
3721 9 : } 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 27 : break;
3726 27 : default:
3727 27 : torture_assert_werr_ok(tctx, r.out.result,
3728 : "LogonControl returned unexpected result");
3729 27 : break;
3730 : }
3731 432 : break;
3732 432 : case 2:
3733 432 : torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
3734 : "LogonControl returned unexpected error code");
3735 432 : break;
3736 864 : default:
3737 864 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL,
3738 : "LogonControl returned unexpected error code");
3739 864 : break;
3740 : }
3741 : }
3742 : }
3743 :
3744 27 : r.in.level = 52;
3745 54 : torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
3746 27 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3747 27 : status = dcerpc_netr_LogonControl_r(b, tctx, &r);
3748 27 : torture_assert_ntstatus_ok(tctx, status, "LogonControl");
3749 27 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl");
3750 :
3751 27 : return true;
3752 : }
3753 :
3754 :
3755 : /*
3756 : try a netlogon GetAnyDCName
3757 : */
3758 9 : static bool test_GetAnyDCName(struct torture_context *tctx,
3759 : struct dcerpc_pipe *p)
3760 : {
3761 : NTSTATUS status;
3762 : struct netr_GetAnyDCName r;
3763 9 : const char *dcname = NULL;
3764 9 : struct dcerpc_binding_handle *b = p->binding_handle;
3765 :
3766 9 : r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
3767 9 : r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3768 9 : r.out.dcname = &dcname;
3769 :
3770 9 : status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
3771 9 : torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3772 18 : if ((!W_ERROR_IS_OK(r.out.result)) &&
3773 9 : (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
3774 0 : return false;
3775 : }
3776 :
3777 9 : if (dcname) {
3778 0 : torture_comment(tctx, "\tDC is at '%s'\n", dcname);
3779 : }
3780 :
3781 9 : r.in.domainname = NULL;
3782 :
3783 9 : status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
3784 9 : torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3785 18 : if ((!W_ERROR_IS_OK(r.out.result)) &&
3786 9 : (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
3787 0 : return false;
3788 : }
3789 :
3790 9 : r.in.domainname = "";
3791 :
3792 9 : status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
3793 9 : torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3794 18 : if ((!W_ERROR_IS_OK(r.out.result)) &&
3795 9 : (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
3796 0 : return false;
3797 : }
3798 :
3799 9 : return true;
3800 : }
3801 :
3802 :
3803 : /*
3804 : try a netlogon LogonControl2
3805 : */
3806 27 : static bool test_LogonControl2(struct torture_context *tctx,
3807 : struct dcerpc_pipe *p,
3808 : struct cli_credentials *machine_credentials)
3809 :
3810 : {
3811 : NTSTATUS status;
3812 : struct netr_LogonControl2 r;
3813 : union netr_CONTROL_DATA_INFORMATION data;
3814 : union netr_CONTROL_QUERY_INFORMATION query;
3815 27 : enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
3816 : int i;
3817 27 : struct dcerpc_binding_handle *b = p->binding_handle;
3818 :
3819 27 : data.domain = lpcfg_workgroup(tctx->lp_ctx);
3820 :
3821 27 : if (machine_credentials) {
3822 27 : secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
3823 : }
3824 :
3825 27 : torture_comment(tctx, "Testing LogonControl2 with secure channel type: %d\n",
3826 : secure_channel_type);
3827 :
3828 27 : r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3829 :
3830 27 : r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
3831 27 : r.in.data = &data;
3832 27 : r.out.query = &query;
3833 :
3834 108 : for (i=1;i<4;i++) {
3835 81 : r.in.level = i;
3836 :
3837 162 : torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3838 81 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3839 :
3840 81 : status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3841 81 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3842 : }
3843 :
3844 27 : data.domain = lpcfg_workgroup(tctx->lp_ctx);
3845 :
3846 27 : r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
3847 27 : r.in.data = &data;
3848 :
3849 108 : for (i=1;i<4;i++) {
3850 81 : r.in.level = i;
3851 :
3852 162 : torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3853 81 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3854 :
3855 81 : status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3856 81 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3857 : }
3858 :
3859 27 : data.domain = lpcfg_workgroup(tctx->lp_ctx);
3860 :
3861 27 : r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
3862 27 : r.in.data = &data;
3863 :
3864 108 : for (i=1;i<4;i++) {
3865 81 : r.in.level = i;
3866 :
3867 162 : torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3868 81 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3869 :
3870 81 : status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3871 81 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3872 : }
3873 :
3874 27 : data.debug_level = ~0;
3875 :
3876 27 : r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
3877 27 : r.in.data = &data;
3878 :
3879 108 : for (i=1;i<4;i++) {
3880 81 : r.in.level = i;
3881 :
3882 162 : torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3883 81 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3884 :
3885 81 : status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3886 81 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3887 : }
3888 :
3889 27 : ZERO_STRUCT(data);
3890 27 : r.in.function_code = 52;
3891 27 : r.in.data = &data;
3892 :
3893 54 : torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3894 27 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3895 :
3896 27 : status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3897 27 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3898 27 : switch (secure_channel_type) {
3899 9 : case SEC_CHAN_NULL:
3900 9 : torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2");
3901 9 : break;
3902 18 : default:
3903 18 : torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2");
3904 18 : break;
3905 : }
3906 27 : data.debug_level = ~0;
3907 :
3908 27 : r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
3909 27 : r.in.data = &data;
3910 :
3911 27 : r.in.level = 52;
3912 54 : torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
3913 27 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
3914 :
3915 27 : status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
3916 27 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
3917 27 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl2");
3918 :
3919 27 : return true;
3920 : }
3921 :
3922 : /*
3923 : try a netlogon DatabaseSync2
3924 : */
3925 9 : static bool test_DatabaseSync2(struct torture_context *tctx,
3926 : struct dcerpc_pipe *p,
3927 : struct cli_credentials *machine_credentials)
3928 : {
3929 : struct netr_DatabaseSync2 r;
3930 9 : struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
3931 : struct netr_Authenticator return_authenticator, credential;
3932 :
3933 : struct netlogon_creds_CredentialState *creds;
3934 9 : const uint32_t database_ids[] = {0, 1, 2};
3935 : int i;
3936 9 : struct dcerpc_binding_handle *b = p->binding_handle;
3937 :
3938 9 : if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
3939 : machine_credentials,
3940 : cli_credentials_get_secure_channel_type(machine_credentials),
3941 : &creds)) {
3942 0 : 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 : 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 27 : static bool test_LogonControl2Ex(struct torture_context *tctx,
3997 : struct dcerpc_pipe *p,
3998 : struct cli_credentials *machine_credentials)
3999 :
4000 : {
4001 : NTSTATUS status;
4002 : struct netr_LogonControl2Ex r;
4003 : union netr_CONTROL_DATA_INFORMATION data;
4004 : union netr_CONTROL_QUERY_INFORMATION query;
4005 27 : enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
4006 : int i;
4007 27 : struct dcerpc_binding_handle *b = p->binding_handle;
4008 :
4009 27 : data.domain = lpcfg_workgroup(tctx->lp_ctx);
4010 :
4011 27 : if (machine_credentials) {
4012 27 : secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
4013 : }
4014 :
4015 27 : torture_comment(tctx, "Testing LogonControl2Ex with secure channel type: %d\n",
4016 : secure_channel_type);
4017 :
4018 27 : r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4019 :
4020 27 : r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
4021 27 : r.in.data = &data;
4022 27 : r.out.query = &query;
4023 :
4024 108 : for (i=1;i<4;i++) {
4025 81 : r.in.level = i;
4026 :
4027 162 : torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4028 81 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
4029 :
4030 81 : status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4031 81 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4032 : }
4033 :
4034 27 : data.domain = lpcfg_workgroup(tctx->lp_ctx);
4035 :
4036 27 : r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
4037 27 : r.in.data = &data;
4038 :
4039 108 : for (i=1;i<4;i++) {
4040 81 : r.in.level = i;
4041 :
4042 162 : torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4043 81 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
4044 :
4045 81 : status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4046 81 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4047 : }
4048 :
4049 27 : data.domain = lpcfg_workgroup(tctx->lp_ctx);
4050 :
4051 27 : r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
4052 27 : r.in.data = &data;
4053 :
4054 108 : for (i=1;i<4;i++) {
4055 81 : r.in.level = i;
4056 :
4057 162 : torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4058 81 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
4059 :
4060 81 : status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4061 81 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4062 : }
4063 :
4064 27 : data.debug_level = ~0;
4065 :
4066 27 : r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
4067 27 : r.in.data = &data;
4068 :
4069 108 : for (i=1;i<4;i++) {
4070 81 : r.in.level = i;
4071 :
4072 162 : torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4073 81 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
4074 :
4075 81 : status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4076 81 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4077 : }
4078 :
4079 27 : ZERO_STRUCT(data);
4080 27 : r.in.function_code = 52;
4081 27 : r.in.data = &data;
4082 :
4083 54 : torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4084 27 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
4085 :
4086 27 : status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4087 27 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4088 27 : switch (secure_channel_type) {
4089 9 : case SEC_CHAN_NULL:
4090 9 : torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2Ex");
4091 9 : break;
4092 18 : default:
4093 18 : torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2Ex");
4094 18 : break;
4095 : }
4096 27 : data.debug_level = ~0;
4097 :
4098 27 : r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
4099 27 : r.in.data = &data;
4100 :
4101 27 : r.in.level = 52;
4102 54 : torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
4103 27 : function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
4104 :
4105 27 : status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
4106 27 : torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
4107 27 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl2Ex");
4108 :
4109 27 : return true;
4110 : }
4111 :
4112 9 : static bool test_netr_GetForestTrustInformation(struct torture_context *tctx,
4113 : struct dcerpc_pipe *p1,
4114 : struct cli_credentials *machine_credentials)
4115 : {
4116 : struct netr_GetForestTrustInformation r;
4117 : struct netlogon_creds_CredentialState *creds;
4118 : struct netr_Authenticator a;
4119 : struct netr_Authenticator return_authenticator;
4120 : struct lsa_ForestTrustInformation *forest_trust_info;
4121 9 : struct dcerpc_pipe *p = NULL;
4122 9 : struct dcerpc_binding_handle *b = NULL;
4123 :
4124 9 : if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
4125 : machine_credentials, &creds)) {
4126 0 : return false;
4127 : }
4128 9 : if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
4129 : DCERPC_SIGN | DCERPC_SEAL, &p)) {
4130 0 : return false;
4131 : }
4132 9 : b = p->binding_handle;
4133 :
4134 9 : netlogon_creds_client_authenticator(creds, &a);
4135 :
4136 9 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4137 9 : r.in.computer_name = TEST_MACHINE_NAME;
4138 9 : r.in.credential = &a;
4139 9 : r.in.flags = 0;
4140 9 : r.out.return_authenticator = &return_authenticator;
4141 9 : r.out.forest_trust_info = &forest_trust_info;
4142 :
4143 9 : torture_assert_ntstatus_ok(tctx,
4144 : dcerpc_netr_GetForestTrustInformation_r(b, tctx, &r),
4145 : "netr_GetForestTrustInformation failed");
4146 9 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
4147 9 : 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 9 : torture_assert(tctx,
4154 : netlogon_creds_client_check(creds, &return_authenticator.cred),
4155 : "Credential chaining failed");
4156 :
4157 9 : return true;
4158 : }
4159 :
4160 9 : static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
4161 : struct dcerpc_pipe *p, const char *trusted_domain_name)
4162 : {
4163 : NTSTATUS status;
4164 : struct netr_DsRGetForestTrustInformation r;
4165 : struct lsa_ForestTrustInformation info, *info_ptr;
4166 9 : struct dcerpc_binding_handle *b = p->binding_handle;
4167 :
4168 9 : info_ptr = &info;
4169 :
4170 9 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4171 9 : r.in.trusted_domain_name = trusted_domain_name;
4172 9 : r.in.flags = 0;
4173 9 : r.out.forest_trust_info = &info_ptr;
4174 :
4175 9 : torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
4176 :
4177 9 : status = dcerpc_netr_DsRGetForestTrustInformation_r(b, tctx, &r);
4178 9 : torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
4179 9 : torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
4180 :
4181 9 : return true;
4182 : }
4183 :
4184 : /*
4185 : try a netlogon netr_DsrEnumerateDomainTrusts
4186 : */
4187 9 : static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
4188 : struct dcerpc_pipe *p)
4189 : {
4190 : NTSTATUS status;
4191 : struct netr_DsrEnumerateDomainTrusts r;
4192 : struct netr_DomainTrustList trusts;
4193 : int i;
4194 9 : struct dcerpc_binding_handle *b = p->binding_handle;
4195 :
4196 9 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4197 9 : r.in.trust_flags = 0x3f;
4198 9 : r.out.trusts = &trusts;
4199 :
4200 9 : status = dcerpc_netr_DsrEnumerateDomainTrusts_r(b, tctx, &r);
4201 9 : torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
4202 9 : 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 9 : if (r.out.trusts->count) {
4209 9 : if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
4210 0 : return false;
4211 : }
4212 : }
4213 :
4214 18 : for (i=0; i<r.out.trusts->count; i++) {
4215 :
4216 : /* get info for transitive forest trusts */
4217 :
4218 9 : 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 9 : return true;
4227 : }
4228 :
4229 12 : static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
4230 : struct dcerpc_pipe *p)
4231 : {
4232 : NTSTATUS status;
4233 : struct netr_NetrEnumerateTrustedDomains r;
4234 : struct netr_Blob trusted_domains_blob;
4235 12 : struct dcerpc_binding_handle *b = p->binding_handle;
4236 :
4237 12 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4238 12 : r.out.trusted_domains_blob = &trusted_domains_blob;
4239 :
4240 12 : status = dcerpc_netr_NetrEnumerateTrustedDomains_r(b, tctx, &r);
4241 12 : 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 9 : static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
4248 : struct dcerpc_pipe *p)
4249 : {
4250 : NTSTATUS status;
4251 : struct netr_NetrEnumerateTrustedDomainsEx r;
4252 : struct netr_DomainTrustList dom_trust_list;
4253 9 : struct dcerpc_binding_handle *b = p->binding_handle;
4254 :
4255 9 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4256 9 : r.out.dom_trust_list = &dom_trust_list;
4257 :
4258 9 : status = dcerpc_netr_NetrEnumerateTrustedDomainsEx_r(b, tctx, &r);
4259 9 : 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 27 : 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 : NTSTATUS status;
4271 : struct netr_DsRGetSiteName r;
4272 27 : const char *site = NULL;
4273 27 : struct dcerpc_binding_handle *b = p->binding_handle;
4274 :
4275 27 : r.in.computer_name = computer_name;
4276 27 : r.out.site = &site;
4277 27 : torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
4278 :
4279 27 : status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
4280 27 : torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
4281 27 : torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
4282 27 : torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
4283 :
4284 27 : return true;
4285 : }
4286 :
4287 : /*
4288 : try a netlogon netr_DsRGetDCName
4289 : */
4290 9 : static bool test_netr_DsRGetDCName(struct torture_context *tctx,
4291 : struct dcerpc_pipe *p)
4292 : {
4293 : NTSTATUS status;
4294 : struct netr_DsRGetDCName r;
4295 9 : struct netr_DsRGetDCNameInfo *info = NULL;
4296 9 : struct dcerpc_binding_handle *b = p->binding_handle;
4297 :
4298 9 : r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4299 9 : r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
4300 9 : r.in.domain_guid = NULL;
4301 9 : r.in.site_guid = NULL;
4302 9 : r.in.flags = DS_RETURN_DNS_NAME;
4303 9 : r.out.info = &info;
4304 :
4305 9 : status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
4306 9 : torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
4307 9 : torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
4308 :
4309 9 : torture_assert_int_equal(tctx,
4310 : (info->dc_flags & (DS_DNS_CONTROLLER)),
4311 : DS_DNS_CONTROLLER,
4312 : "DsRGetDCName");
4313 9 : torture_assert_int_equal(tctx,
4314 : (info->dc_flags & (DS_DNS_DOMAIN)),
4315 : DS_DNS_DOMAIN,
4316 : "DsRGetDCName");
4317 9 : torture_assert_int_equal(tctx,
4318 : (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4319 : DS_DNS_FOREST_ROOT,
4320 : "DsRGetDCName");
4321 :
4322 9 : r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
4323 9 : r.in.flags = 0;
4324 :
4325 9 : status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
4326 9 : torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
4327 9 : torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
4328 :
4329 9 : torture_assert_int_equal(tctx,
4330 : (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
4331 : "DsRGetDCName");
4332 9 : torture_assert_int_equal(tctx,
4333 : (info->dc_flags & (DS_DNS_DOMAIN)), 0,
4334 : "DsRGetDCName");
4335 9 : torture_assert_int_equal(tctx,
4336 : (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4337 : DS_DNS_FOREST_ROOT,
4338 : "DsRGetDCName");
4339 :
4340 9 : if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
4341 9 : 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 9 : info->dc_unc,
4349 9 : info->dc_site_name);
4350 : }
4351 :
4352 : /*
4353 : try a netlogon netr_DsRGetDCNameEx
4354 : */
4355 9 : static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
4356 : struct dcerpc_pipe *p)
4357 : {
4358 : NTSTATUS status;
4359 : struct netr_DsRGetDCNameEx r;
4360 9 : struct netr_DsRGetDCNameInfo *info = NULL;
4361 9 : struct dcerpc_binding_handle *b = p->binding_handle;
4362 :
4363 9 : r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4364 9 : r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
4365 9 : r.in.domain_guid = NULL;
4366 9 : r.in.site_name = NULL;
4367 9 : r.in.flags = DS_RETURN_DNS_NAME;
4368 9 : r.out.info = &info;
4369 :
4370 9 : status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
4371 9 : torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
4372 9 : torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
4373 :
4374 9 : torture_assert_int_equal(tctx,
4375 : (info->dc_flags & (DS_DNS_CONTROLLER)),
4376 : DS_DNS_CONTROLLER,
4377 : "DsRGetDCNameEx");
4378 9 : torture_assert_int_equal(tctx,
4379 : (info->dc_flags & (DS_DNS_DOMAIN)),
4380 : DS_DNS_DOMAIN,
4381 : "DsRGetDCNameEx");
4382 9 : torture_assert_int_equal(tctx,
4383 : (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4384 : DS_DNS_FOREST_ROOT,
4385 : "DsRGetDCNameEx");
4386 :
4387 9 : r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
4388 9 : r.in.flags = 0;
4389 :
4390 9 : status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
4391 9 : torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
4392 9 : torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
4393 :
4394 9 : torture_assert_int_equal(tctx,
4395 : (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
4396 : "DsRGetDCNameEx");
4397 9 : torture_assert_int_equal(tctx,
4398 : (info->dc_flags & (DS_DNS_DOMAIN)), 0,
4399 : "DsRGetDCNameEx");
4400 9 : torture_assert_int_equal(tctx,
4401 : (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4402 : DS_DNS_FOREST_ROOT,
4403 : "DsRGetDCNameEx");
4404 :
4405 9 : if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
4406 9 : torture_assert_int_equal(tctx,
4407 : (info->dc_flags & (DS_SERVER_CLOSEST)),
4408 : DS_SERVER_CLOSEST,
4409 : "DsRGetDCNameEx");
4410 : }
4411 :
4412 9 : return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
4413 9 : info->dc_site_name);
4414 : }
4415 :
4416 : /*
4417 : try a netlogon netr_DsRGetDCNameEx2
4418 : */
4419 9 : static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
4420 : struct dcerpc_pipe *p)
4421 : {
4422 : NTSTATUS status;
4423 : struct netr_DsRGetDCNameEx2 r;
4424 9 : struct netr_DsRGetDCNameInfo *info = NULL;
4425 9 : struct dcerpc_binding_handle *b = p->binding_handle;
4426 :
4427 9 : torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with no inputs\n");
4428 9 : ZERO_STRUCT(r.in);
4429 9 : r.in.flags = DS_RETURN_DNS_NAME;
4430 9 : r.out.info = &info;
4431 :
4432 9 : status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
4433 9 : torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
4434 9 : torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
4435 :
4436 9 : torture_assert_int_equal(tctx,
4437 : (info->dc_flags & (DS_DNS_CONTROLLER)),
4438 : DS_DNS_CONTROLLER,
4439 : "DsRGetDCNameEx2");
4440 9 : torture_assert_int_equal(tctx,
4441 : (info->dc_flags & (DS_DNS_DOMAIN)),
4442 : DS_DNS_DOMAIN,
4443 : "DsRGetDCNameEx2");
4444 9 : torture_assert_int_equal(tctx,
4445 : (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4446 : DS_DNS_FOREST_ROOT,
4447 : "DsRGetDCNameEx2");
4448 :
4449 9 : r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4450 9 : r.in.client_account = NULL;
4451 9 : r.in.mask = 0x00000000;
4452 9 : r.in.domain_name = lpcfg_dnsdomain(tctx->lp_ctx);
4453 9 : r.in.domain_guid = NULL;
4454 9 : r.in.site_name = NULL;
4455 9 : r.in.flags = DS_RETURN_DNS_NAME;
4456 9 : r.out.info = &info;
4457 :
4458 9 : torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
4459 :
4460 9 : status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
4461 9 : torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
4462 9 : torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
4463 :
4464 9 : r.in.domain_name = lpcfg_workgroup(tctx->lp_ctx);
4465 9 : r.in.flags = 0;
4466 :
4467 9 : status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
4468 9 : torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
4469 9 : torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
4470 :
4471 9 : torture_assert_int_equal(tctx,
4472 : (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
4473 : "DsRGetDCNameEx2");
4474 9 : torture_assert_int_equal(tctx,
4475 : (info->dc_flags & (DS_DNS_DOMAIN)), 0,
4476 : "DsRGetDCNameEx2");
4477 9 : torture_assert_int_equal(tctx,
4478 : (info->dc_flags & (DS_DNS_FOREST_ROOT)),
4479 : DS_DNS_FOREST_ROOT,
4480 : "DsRGetDCNameEx2");
4481 :
4482 9 : if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
4483 9 : torture_assert_int_equal(tctx,
4484 : (info->dc_flags & (DS_SERVER_CLOSEST)),
4485 : DS_SERVER_CLOSEST,
4486 : "DsRGetDCNameEx2");
4487 : }
4488 :
4489 9 : torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client account\n");
4490 9 : r.in.client_account = TEST_MACHINE_NAME"$";
4491 9 : r.in.mask = ACB_SVRTRUST;
4492 9 : r.in.flags = DS_RETURN_FLAT_NAME;
4493 9 : r.out.info = &info;
4494 :
4495 9 : status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
4496 9 : torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
4497 9 : torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
4498 :
4499 9 : return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
4500 9 : 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 78 : static const char *server_site_name(struct torture_context *tctx,
4506 : struct ldb_context *ldb)
4507 : {
4508 : TALLOC_CTX *tmp_ctx;
4509 : struct ldb_dn *dn, *server_dn;
4510 : const struct ldb_val *site_name_val;
4511 : const char *server_dn_str, *site_name;
4512 :
4513 78 : tmp_ctx = talloc_new(ldb);
4514 78 : if (tmp_ctx == NULL) {
4515 0 : goto failed;
4516 : }
4517 :
4518 78 : dn = ldb_dn_new(tmp_ctx, ldb, "");
4519 78 : if (dn == NULL) {
4520 0 : goto failed;
4521 : }
4522 :
4523 78 : server_dn_str = samdb_search_string(ldb, tmp_ctx, dn, "serverName",
4524 : NULL);
4525 78 : if (server_dn_str == NULL) {
4526 0 : goto failed;
4527 : }
4528 :
4529 78 : server_dn = ldb_dn_new(tmp_ctx, ldb, server_dn_str);
4530 78 : if (server_dn == NULL) {
4531 0 : goto failed;
4532 : }
4533 :
4534 : /* CN=<Server name>, CN=Servers, CN=<Site name>, CN=Sites, ... */
4535 78 : site_name_val = ldb_dn_get_component_val(server_dn, 2);
4536 78 : if (site_name_val == NULL) {
4537 0 : goto failed;
4538 : }
4539 :
4540 78 : site_name = (const char *) site_name_val->data;
4541 :
4542 78 : talloc_steal(tctx, site_name);
4543 78 : talloc_free(tmp_ctx);
4544 :
4545 78 : return site_name;
4546 :
4547 0 : failed:
4548 0 : talloc_free(tmp_ctx);
4549 0 : return NULL;
4550 : }
4551 :
4552 9 : static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
4553 : struct dcerpc_pipe *p)
4554 : {
4555 : char *url;
4556 9 : struct ldb_context *sam_ctx = NULL;
4557 : NTSTATUS status;
4558 : struct netr_DsrGetDcSiteCoverageW r;
4559 9 : struct DcSitesCtr *ctr = NULL;
4560 9 : struct dcerpc_binding_handle *b = p->binding_handle;
4561 :
4562 9 : 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 9 : if (dcerpc_server_name(p)) {
4566 : /* Set up connection to SAMDB on DC */
4567 6 : url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
4568 6 : sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
4569 : NULL,
4570 : samba_cmdline_get_creds(),
4571 : 0);
4572 :
4573 6 : torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
4574 : }
4575 :
4576 9 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4577 9 : r.out.ctr = &ctr;
4578 :
4579 9 : status = dcerpc_netr_DsrGetDcSiteCoverageW_r(b, tctx, &r);
4580 9 : torture_assert_ntstatus_ok(tctx, status, "failed");
4581 9 : torture_assert_werr_ok(tctx, r.out.result, "failed");
4582 :
4583 9 : torture_assert(tctx, ctr->num_sites == 1,
4584 : "we should per default only get the default site");
4585 9 : if (sam_ctx != NULL) {
4586 6 : 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 9 : return true;
4592 : }
4593 :
4594 9 : static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
4595 : struct dcerpc_pipe *p)
4596 : {
4597 : char *url;
4598 9 : struct ldb_context *sam_ctx = NULL;
4599 : NTSTATUS status;
4600 : struct netr_DsRAddressToSitenamesW r;
4601 : struct netr_DsRAddress addrs[6];
4602 : struct sockaddr_in *addr;
4603 : #ifdef HAVE_IPV6
4604 : struct sockaddr_in6 *addr6;
4605 : #endif
4606 : struct netr_DsRAddressToSitenamesWCtr *ctr;
4607 9 : struct dcerpc_binding_handle *b = p->binding_handle;
4608 : uint32_t i;
4609 : int ret;
4610 :
4611 9 : 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 9 : if (dcerpc_server_name(p)) {
4615 : /* Set up connection to SAMDB on DC */
4616 6 : url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
4617 6 : sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
4618 : NULL,
4619 : samba_cmdline_get_creds(),
4620 : 0);
4621 :
4622 6 : torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
4623 : }
4624 :
4625 : /* First try valid IP addresses */
4626 :
4627 9 : addrs[0].size = sizeof(struct sockaddr_in);
4628 9 : addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
4629 9 : addr = (struct sockaddr_in *) addrs[0].buffer;
4630 9 : addrs[0].buffer[0] = AF_INET;
4631 9 : ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
4632 9 : torture_assert(tctx, ret > 0, "inet_pton failed");
4633 :
4634 9 : addrs[1].size = sizeof(struct sockaddr_in);
4635 9 : addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
4636 9 : addr = (struct sockaddr_in *) addrs[1].buffer;
4637 9 : addrs[1].buffer[0] = AF_INET;
4638 9 : ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
4639 9 : torture_assert(tctx, ret > 0, "inet_pton failed");
4640 :
4641 9 : addrs[2].size = sizeof(struct sockaddr_in);
4642 9 : addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
4643 9 : addr = (struct sockaddr_in *) addrs[2].buffer;
4644 9 : addrs[2].buffer[0] = AF_INET;
4645 9 : ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
4646 9 : torture_assert(tctx, ret > 0, "inet_pton failed");
4647 :
4648 : #ifdef HAVE_IPV6
4649 9 : addrs[3].size = sizeof(struct sockaddr_in6);
4650 9 : addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
4651 9 : addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
4652 9 : addrs[3].buffer[0] = AF_INET6;
4653 9 : ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
4654 9 : torture_assert(tctx, ret > 0, "inet_pton failed");
4655 :
4656 9 : addrs[4].size = sizeof(struct sockaddr_in6);
4657 9 : addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
4658 9 : addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
4659 9 : addrs[4].buffer[0] = AF_INET6;
4660 9 : ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
4661 9 : torture_assert(tctx, ret > 0, "inet_pton failed");
4662 :
4663 9 : addrs[5].size = sizeof(struct sockaddr_in6);
4664 9 : addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
4665 9 : addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
4666 9 : addrs[5].buffer[0] = AF_INET6;
4667 9 : ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
4668 9 : 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 9 : ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
4695 :
4696 9 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4697 9 : r.in.count = 6;
4698 9 : r.in.addresses = addrs;
4699 9 : r.out.ctr = &ctr;
4700 :
4701 9 : status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
4702 9 : torture_assert_ntstatus_ok(tctx, status, "failed");
4703 9 : torture_assert_werr_ok(tctx, r.out.result, "failed");
4704 :
4705 9 : if (sam_ctx != NULL) {
4706 24 : for (i = 0; i < 3; i++) {
4707 18 : 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 24 : for (i = 3; i < 6; i++) {
4713 : /* Windows returns "NULL" for the sitename if it isn't
4714 : * IPv6 configured */
4715 18 : if (torture_setting_bool(tctx, "samba4", false)) {
4716 18 : 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 9 : addrs[0].size = 0;
4727 9 : addrs[1].size = 1;
4728 9 : addrs[2].size = 4;
4729 :
4730 9 : addrs[3].size = 0;
4731 9 : addrs[4].size = 1;
4732 9 : addrs[5].size = 4;
4733 :
4734 9 : status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
4735 9 : torture_assert_ntstatus_ok(tctx, status, "failed");
4736 9 : torture_assert_werr_ok(tctx, r.out.result, "failed");
4737 :
4738 63 : for (i = 0; i < 6; i++) {
4739 54 : 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 9 : addrs[0].size = 10;
4746 9 : addrs[0].buffer[0] = AF_UNSPEC;
4747 9 : addrs[1].size = 10;
4748 9 : addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
4749 9 : addrs[2].size = 10;
4750 9 : addrs[2].buffer[0] = AF_UNIX;
4751 :
4752 9 : addrs[3].size = 10;
4753 9 : addrs[3].buffer[0] = 250;
4754 9 : addrs[4].size = 10;
4755 9 : addrs[4].buffer[0] = 251;
4756 9 : addrs[5].size = 10;
4757 9 : addrs[5].buffer[0] = 252;
4758 :
4759 9 : status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
4760 9 : torture_assert_ntstatus_ok(tctx, status, "failed");
4761 9 : torture_assert_werr_ok(tctx, r.out.result, "failed");
4762 :
4763 63 : for (i = 0; i < 6; i++) {
4764 54 : torture_assert(tctx, ctr->sitename[i].string == NULL,
4765 : "sitename should be null");
4766 : }
4767 :
4768 9 : return true;
4769 : }
4770 :
4771 9 : static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
4772 : struct dcerpc_pipe *p)
4773 : {
4774 : char *url;
4775 9 : struct ldb_context *sam_ctx = NULL;
4776 : NTSTATUS status;
4777 : struct netr_DsRAddressToSitenamesExW r;
4778 : struct netr_DsRAddress addrs[6];
4779 : struct sockaddr_in *addr;
4780 : #ifdef HAVE_IPV6
4781 : struct sockaddr_in6 *addr6;
4782 : #endif
4783 : struct netr_DsRAddressToSitenamesExWCtr *ctr;
4784 9 : struct dcerpc_binding_handle *b = p->binding_handle;
4785 : uint32_t i;
4786 : int ret;
4787 :
4788 9 : 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 9 : if (dcerpc_server_name(p)) {
4792 : /* Set up connection to SAMDB on DC */
4793 6 : url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
4794 6 : sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
4795 : NULL,
4796 : samba_cmdline_get_creds(),
4797 : 0);
4798 :
4799 6 : torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
4800 : }
4801 :
4802 : /* First try valid IP addresses */
4803 :
4804 9 : addrs[0].size = sizeof(struct sockaddr_in);
4805 9 : addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
4806 9 : addr = (struct sockaddr_in *) addrs[0].buffer;
4807 9 : addrs[0].buffer[0] = AF_INET;
4808 9 : ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
4809 9 : torture_assert(tctx, ret > 0, "inet_pton failed");
4810 :
4811 9 : addrs[1].size = sizeof(struct sockaddr_in);
4812 9 : addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
4813 9 : addr = (struct sockaddr_in *) addrs[1].buffer;
4814 9 : addrs[1].buffer[0] = AF_INET;
4815 9 : ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
4816 9 : torture_assert(tctx, ret > 0, "inet_pton failed");
4817 :
4818 9 : addrs[2].size = sizeof(struct sockaddr_in);
4819 9 : addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
4820 9 : addr = (struct sockaddr_in *) addrs[2].buffer;
4821 9 : addrs[2].buffer[0] = AF_INET;
4822 9 : ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
4823 9 : torture_assert(tctx, ret > 0, "inet_pton failed");
4824 :
4825 : #ifdef HAVE_IPV6
4826 9 : addrs[3].size = sizeof(struct sockaddr_in6);
4827 9 : addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
4828 9 : addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
4829 9 : addrs[3].buffer[0] = AF_INET6;
4830 9 : ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
4831 9 : torture_assert(tctx, ret > 0, "inet_pton failed");
4832 :
4833 9 : addrs[4].size = sizeof(struct sockaddr_in6);
4834 9 : addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
4835 9 : addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
4836 9 : addrs[4].buffer[0] = AF_INET6;
4837 9 : ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
4838 9 : torture_assert(tctx, ret > 0, "inet_pton failed");
4839 :
4840 9 : addrs[5].size = sizeof(struct sockaddr_in6);
4841 9 : addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
4842 9 : addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
4843 9 : addrs[5].buffer[0] = AF_INET6;
4844 9 : ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
4845 9 : 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 9 : ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
4872 :
4873 9 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4874 9 : r.in.count = 6;
4875 9 : r.in.addresses = addrs;
4876 9 : r.out.ctr = &ctr;
4877 :
4878 9 : status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
4879 9 : torture_assert_ntstatus_ok(tctx, status, "failed");
4880 9 : torture_assert_werr_ok(tctx, r.out.result, "failed");
4881 :
4882 9 : if (sam_ctx != NULL) {
4883 24 : for (i = 0; i < 3; i++) {
4884 18 : torture_assert_casestr_equal(tctx,
4885 : ctr->sitename[i].string,
4886 : server_site_name(tctx, sam_ctx),
4887 : "didn't return default site");
4888 18 : torture_assert(tctx, ctr->subnetname[i].string == NULL,
4889 : "subnet should be null");
4890 : }
4891 24 : for (i = 3; i < 6; i++) {
4892 : /* Windows returns "NULL" for the sitename if it isn't
4893 : * IPv6 configured */
4894 18 : if (torture_setting_bool(tctx, "samba4", false)) {
4895 18 : 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 18 : 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 9 : addrs[0].size = 0;
4908 9 : addrs[1].size = 1;
4909 9 : addrs[2].size = 4;
4910 :
4911 9 : addrs[3].size = 0;
4912 9 : addrs[4].size = 1;
4913 9 : addrs[5].size = 4;
4914 :
4915 9 : status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
4916 9 : torture_assert_ntstatus_ok(tctx, status, "failed");
4917 9 : torture_assert_werr_ok(tctx, r.out.result, "failed");
4918 :
4919 63 : for (i = 0; i < 6; i++) {
4920 54 : torture_assert(tctx, ctr->sitename[i].string == NULL,
4921 : "sitename should be null");
4922 54 : torture_assert(tctx, ctr->subnetname[i].string == NULL,
4923 : "subnet should be null");
4924 : }
4925 :
4926 9 : addrs[0].size = 10;
4927 9 : addrs[0].buffer[0] = AF_UNSPEC;
4928 9 : addrs[1].size = 10;
4929 9 : addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
4930 9 : addrs[2].size = 10;
4931 9 : addrs[2].buffer[0] = AF_UNIX;
4932 :
4933 9 : addrs[3].size = 10;
4934 9 : addrs[3].buffer[0] = 250;
4935 9 : addrs[4].size = 10;
4936 9 : addrs[4].buffer[0] = 251;
4937 9 : addrs[5].size = 10;
4938 9 : addrs[5].buffer[0] = 252;
4939 :
4940 9 : status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
4941 9 : torture_assert_ntstatus_ok(tctx, status, "failed");
4942 9 : torture_assert_werr_ok(tctx, r.out.result, "failed");
4943 :
4944 63 : for (i = 0; i < 6; i++) {
4945 54 : torture_assert(tctx, ctr->sitename[i].string == NULL,
4946 : "sitename should be null");
4947 54 : torture_assert(tctx, ctr->subnetname[i].string == NULL,
4948 : "subnet should be null");
4949 : }
4950 :
4951 9 : return true;
4952 : }
4953 :
4954 18 : 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 : struct netr_ServerGetTrustInfo r;
4960 :
4961 : struct netr_Authenticator a;
4962 : struct netr_Authenticator return_authenticator;
4963 : struct samr_Password new_owf_password;
4964 : struct samr_Password old_owf_password;
4965 : struct netr_TrustInfo *trust_info;
4966 :
4967 : struct netlogon_creds_CredentialState *creds;
4968 18 : struct dcerpc_pipe *p = NULL;
4969 18 : struct dcerpc_binding_handle *b = NULL;
4970 :
4971 : struct samr_Password nt_hash;
4972 :
4973 18 : if (!test_SetupCredentials3(p1, tctx, negotiate_flags,
4974 : machine_credentials, &creds)) {
4975 0 : return false;
4976 : }
4977 18 : if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
4978 : DCERPC_SIGN | DCERPC_SEAL, &p)) {
4979 0 : return false;
4980 : }
4981 18 : b = p->binding_handle;
4982 :
4983 18 : netlogon_creds_client_authenticator(creds, &a);
4984 :
4985 18 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
4986 18 : r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
4987 18 : r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
4988 18 : r.in.computer_name = TEST_MACHINE_NAME;
4989 18 : r.in.credential = &a;
4990 :
4991 18 : r.out.return_authenticator = &return_authenticator;
4992 18 : r.out.new_owf_password = &new_owf_password;
4993 18 : r.out.old_owf_password = &old_owf_password;
4994 18 : r.out.trust_info = &trust_info;
4995 :
4996 18 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerGetTrustInfo_r(b, tctx, &r),
4997 : "ServerGetTrustInfo failed");
4998 18 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerGetTrustInfo failed");
4999 18 : torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
5000 :
5001 18 : E_md4hash(cli_credentials_get_password(machine_credentials), nt_hash.hash);
5002 :
5003 18 : netlogon_creds_des_decrypt(creds, &new_owf_password);
5004 :
5005 18 : dump_data(1, new_owf_password.hash, 16);
5006 18 : dump_data(1, nt_hash.hash, 16);
5007 :
5008 18 : torture_assert_mem_equal(tctx, new_owf_password.hash, nt_hash.hash, 16,
5009 : "received unexpected owf password\n");
5010 :
5011 18 : return true;
5012 : }
5013 :
5014 9 : static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
5015 : struct dcerpc_pipe *p,
5016 : struct cli_credentials *machine_credentials)
5017 : {
5018 9 : return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
5019 : NETLOGON_NEG_AUTH2_ADS_FLAGS);
5020 : }
5021 :
5022 9 : static bool test_netr_ServerGetTrustInfo_AES(struct torture_context *tctx,
5023 : struct dcerpc_pipe *p,
5024 : struct cli_credentials *machine_credentials)
5025 : {
5026 9 : return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
5027 : NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
5028 : }
5029 :
5030 9 : static bool test_GetDomainInfo(struct torture_context *tctx,
5031 : struct dcerpc_pipe *p1,
5032 : struct cli_credentials *machine_credentials)
5033 : {
5034 : struct netr_LogonGetDomainInfo r;
5035 : struct netr_WorkstationInformation q1;
5036 : struct netr_Authenticator a;
5037 : struct netlogon_creds_CredentialState *creds;
5038 : struct netr_OsVersion os;
5039 : union netr_WorkstationInfo query;
5040 : union netr_DomainInfo info;
5041 9 : const char* const attrs[] = { "dNSHostName", "operatingSystem",
5042 : "operatingSystemServicePack", "operatingSystemVersion",
5043 : "servicePrincipalName", NULL };
5044 : char *url;
5045 9 : struct ldb_context *sam_ctx = NULL;
5046 : struct ldb_message **res;
5047 : struct ldb_message_element *spn_el;
5048 : int ret, i;
5049 : char *version_str;
5050 9 : const char *old_dnsname = NULL;
5051 9 : char **spns = NULL;
5052 9 : int num_spns = 0;
5053 9 : char *temp_str = NULL;
5054 9 : char *temp_str2 = NULL;
5055 9 : struct dcerpc_pipe *p = NULL;
5056 9 : struct dcerpc_binding_handle *b = NULL;
5057 9 : struct netr_OneDomainInfo *odi1 = NULL;
5058 9 : struct netr_OneDomainInfo *odi2 = NULL;
5059 9 : struct netr_trust_extension_info *tex2 = NULL;
5060 :
5061 9 : torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
5062 :
5063 9 : if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
5064 : machine_credentials, &creds)) {
5065 0 : return false;
5066 : }
5067 9 : if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
5068 : DCERPC_SIGN | DCERPC_SEAL, &p)) {
5069 0 : return false;
5070 : }
5071 9 : b = p->binding_handle;
5072 :
5073 : /* We won't double-check this when we are over 'local' transports */
5074 9 : if (dcerpc_server_name(p)) {
5075 : /* Set up connection to SAMDB on DC */
5076 6 : url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
5077 6 : sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
5078 : NULL,
5079 : samba_cmdline_get_creds(),
5080 : 0);
5081 :
5082 6 : torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
5083 : }
5084 :
5085 9 : torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
5086 9 : netlogon_creds_client_authenticator(creds, &a);
5087 :
5088 9 : ZERO_STRUCT(r);
5089 9 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
5090 9 : r.in.computer_name = TEST_MACHINE_NAME;
5091 9 : r.in.credential = &a;
5092 9 : r.in.level = 1;
5093 9 : r.in.return_authenticator = &a;
5094 9 : r.in.query = &query;
5095 9 : r.out.return_authenticator = &a;
5096 9 : r.out.info = &info;
5097 :
5098 9 : ZERO_STRUCT(os);
5099 9 : os.os.MajorVersion = 123;
5100 9 : os.os.MinorVersion = 456;
5101 9 : os.os.BuildNumber = 789;
5102 9 : os.os.CSDVersion = "Service Pack 10";
5103 9 : os.os.ServicePackMajor = 10;
5104 9 : os.os.ServicePackMinor = 1;
5105 9 : os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
5106 9 : os.os.ProductType = NETR_VER_NT_SERVER;
5107 9 : os.os.Reserved = 0;
5108 :
5109 9 : version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
5110 : os.os.MinorVersion, os.os.BuildNumber);
5111 :
5112 9 : ZERO_STRUCT(q1);
5113 9 : q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
5114 : lpcfg_dnsdomain(tctx->lp_ctx));
5115 9 : q1.sitename = "Default-First-Site-Name";
5116 9 : q1.os_version.os = &os;
5117 9 : 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 9 : q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
5124 :
5125 9 : query.workstation_info = &q1;
5126 :
5127 9 : if (sam_ctx) {
5128 : /* Gets back the old DNS hostname in AD */
5129 6 : ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
5130 : "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
5131 6 : old_dnsname =
5132 6 : ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
5133 :
5134 : /* Gets back the "servicePrincipalName"s in AD */
5135 6 : spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5136 6 : if (spn_el != NULL) {
5137 18 : for (i=0; i < spn_el->num_values; i++) {
5138 12 : spns = talloc_realloc(tctx, spns, char *, i + 1);
5139 12 : spns[i] = (char *) spn_el->values[i].data;
5140 : }
5141 6 : num_spns = i;
5142 : }
5143 : }
5144 :
5145 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5146 : "LogonGetDomainInfo failed");
5147 9 : torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5148 9 : torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5149 :
5150 9 : smb_msleep(250);
5151 :
5152 9 : if (sam_ctx) {
5153 : /* AD workstation infos entry check */
5154 6 : ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
5155 : "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
5156 6 : torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
5157 6 : torture_assert_str_equal(tctx,
5158 : ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
5159 : q1.os_name.string, "'operatingSystem' wrong!");
5160 6 : torture_assert_str_equal(tctx,
5161 : ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
5162 : os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
5163 6 : torture_assert_str_equal(tctx,
5164 : ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
5165 : version_str, "'operatingSystemVersion' wrong!");
5166 :
5167 6 : 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 6 : 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 6 : spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5178 6 : torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
5179 : "'servicePrincipalName's not set!");
5180 6 : torture_assert(tctx, spn_el->num_values == num_spns,
5181 : "'servicePrincipalName's incorrect!");
5182 18 : for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
5183 12 : torture_assert_str_equal(tctx,
5184 : (char *) spn_el->values[i].data,
5185 : spns[i], "'servicePrincipalName's incorrect!");
5186 :
5187 6 : 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 9 : 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 9 : torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname doesn't work)\n");
5219 9 : netlogon_creds_client_authenticator(creds, &a);
5220 :
5221 : /* Wipe out the CSDVersion, and prove which values still 'stick' */
5222 9 : os.os.CSDVersion = "";
5223 :
5224 : /* Change also the DNS hostname to test differences in behaviour */
5225 9 : talloc_free(discard_const_p(char, q1.dns_hostname));
5226 9 : 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 9 : q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
5232 :
5233 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5234 : "LogonGetDomainInfo failed");
5235 9 : torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5236 :
5237 9 : torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5238 :
5239 9 : smb_msleep(250);
5240 :
5241 9 : if (sam_ctx) {
5242 : /* AD workstation infos entry check */
5243 6 : ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
5244 : "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
5245 6 : torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
5246 :
5247 6 : 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 6 : torture_assert(tctx,
5251 : ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
5252 : "'operatingSystemServicePack' shouldn't stick!");
5253 6 : 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 6 : 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 6 : spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5267 6 : torture_assert(tctx, spn_el != NULL,
5268 : "There should exist 'servicePrincipalName's in AD!");
5269 6 : temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
5270 12 : for (i=0; i < spn_el->num_values; i++)
5271 12 : if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
5272 6 : break;
5273 6 : torture_assert(tctx, i != spn_el->num_values,
5274 : "'servicePrincipalName' HOST/<Netbios name> not found!");
5275 6 : temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
5276 6 : for (i=0; i < spn_el->num_values; i++)
5277 6 : if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
5278 6 : break;
5279 6 : 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 6 : 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 9 : 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 9 : torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (variation of DNS hostname doesn't work)\n");
5296 9 : netlogon_creds_client_authenticator(creds, &a);
5297 :
5298 : /* Change also the DNS hostname to test differences in behaviour */
5299 9 : talloc_free(discard_const_p(char, q1.dns_hostname));
5300 9 : 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 9 : q1.os_version.os = NULL;
5305 :
5306 : /* Let the DC handle the "servicePrincipalName" and DNS hostname
5307 : updates */
5308 9 : q1.workstation_flags = 0;
5309 :
5310 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5311 : "LogonGetDomainInfo failed");
5312 9 : torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5313 9 : torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5314 :
5315 9 : smb_msleep(250);
5316 :
5317 9 : if (sam_ctx) {
5318 : /* AD workstation infos entry check */
5319 6 : ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
5320 : "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
5321 6 : torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
5322 :
5323 6 : 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 6 : torture_assert(tctx,
5327 : ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
5328 : "'operatingSystemServicePack' shouldn't stick!");
5329 6 : 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 6 : 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 6 : spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
5343 6 : torture_assert(tctx, spn_el != NULL,
5344 : "There should exist 'servicePrincipalName's in AD!");
5345 6 : temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
5346 12 : for (i=0; i < spn_el->num_values; i++)
5347 12 : if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
5348 6 : break;
5349 6 : torture_assert(tctx, i != spn_el->num_values,
5350 : "'servicePrincipalName' HOST/<Netbios name> not found!");
5351 6 : temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
5352 6 : for (i=0; i < spn_el->num_values; i++)
5353 6 : if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
5354 6 : break;
5355 6 : 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 6 : torture_assert(tctx, info.domain_info->dns_hostname.string == NULL,
5360 : "Out 'DNS hostname' should be NULL!");
5361 : }
5362 :
5363 : /* Checks "workstation flags" */
5364 9 : torture_assert(tctx,
5365 : info.domain_info->workstation_flags == 0,
5366 : "Out 'workstation flags' don't match!");
5367 :
5368 :
5369 9 : torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (verification of DNS hostname and check for trusted domains)\n");
5370 9 : netlogon_creds_client_authenticator(creds, &a);
5371 :
5372 : /* Put the DNS hostname back */
5373 9 : talloc_free(discard_const_p(char, q1.dns_hostname));
5374 9 : 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 9 : q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
5380 :
5381 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5382 : "LogonGetDomainInfo failed");
5383 9 : torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5384 9 : torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5385 :
5386 9 : smb_msleep(250);
5387 :
5388 : /* Now the in/out DNS hostnames should be the same */
5389 9 : 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 9 : old_dnsname = info.domain_info->dns_hostname.string;
5394 :
5395 : /* Checks "workstation flags" */
5396 9 : 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 9 : 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 9 : torture_comment(tctx, "Testing netr_LogonGetDomainInfo 5th call (check for trusted domains)\n");
5409 9 : netlogon_creds_client_authenticator(creds, &a);
5410 :
5411 : /* The workstation handles the "servicePrincipalName" and DNS hostname
5412 : updates and requests inbound trusts */
5413 9 : q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
5414 : | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
5415 :
5416 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5417 : "LogonGetDomainInfo failed");
5418 9 : torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5419 9 : torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5420 :
5421 9 : smb_msleep(250);
5422 :
5423 : /* Checks "workstation flags" */
5424 9 : 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 9 : 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 9 : odi1 = &info.domain_info->primary_domain;
5437 :
5438 9 : torture_assert(tctx, !GUID_all_zero(&odi1->domain_guid),
5439 : "primary domain_guid needs to be valid");
5440 :
5441 18 : for (i=0; i < info.domain_info->trusted_domain_count; i++) {
5442 9 : struct netr_OneDomainInfo *odiT =
5443 9 : &info.domain_info->trusted_domains[i];
5444 9 : struct netr_trust_extension_info *texT = NULL;
5445 :
5446 9 : torture_assert_int_equal(tctx, odiT->trust_extension.length, 16,
5447 : "trust_list should have extension");
5448 9 : torture_assert(tctx, odiT->trust_extension.info != NULL,
5449 : "trust_list should have extension");
5450 9 : texT = &odiT->trust_extension.info->info;
5451 :
5452 9 : if (GUID_equal(&odiT->domain_guid, &odi1->domain_guid)) {
5453 9 : odi2 = odiT;
5454 9 : tex2 = texT;
5455 9 : 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 0 : torture_assert(tctx, odiT->domain_sid != NULL,
5478 : "trust_list domain_sid needs to be valid");
5479 : }
5480 :
5481 9 : torture_assert(tctx, odi2 != NULL,
5482 : "trust_list primary domain not found.");
5483 :
5484 9 : torture_assert_str_equal(tctx,
5485 : odi1->domainname.string,
5486 : odi2->domainname.string,
5487 : "netbios name should match");
5488 :
5489 9 : temp_str = talloc_strdup(tctx, odi1->dns_domainname.string);
5490 9 : torture_assert(tctx, temp_str != NULL,
5491 : "primary_domain dns_domainname copy");
5492 9 : temp_str2 = strrchr(temp_str, '.');
5493 9 : torture_assert(tctx, temp_str2 != NULL && temp_str2[1] == '\0',
5494 : "primary_domain dns_domainname needs trailing '.'");
5495 9 : temp_str2[0] = '\0';
5496 9 : torture_assert_str_equal(tctx,
5497 : temp_str,
5498 : odi2->dns_domainname.string,
5499 : "dns domainname should match "
5500 : "(without trailing '.')");
5501 :
5502 9 : temp_str = talloc_strdup(tctx, odi1->dns_forestname.string);
5503 9 : torture_assert(tctx, temp_str != NULL,
5504 : "primary_domain dns_forestname copy");
5505 9 : temp_str2 = strrchr(temp_str, '.');
5506 9 : torture_assert(tctx, temp_str2 != NULL && temp_str2[1] == '\0',
5507 : "primary_domain dns_forestname needs trailing '.'");
5508 9 : temp_str2[0] = '\0';
5509 9 : torture_assert(tctx, odi2->dns_forestname.string == NULL,
5510 : "trust_list dns_forestname needs to be NULL");
5511 :
5512 9 : torture_assert_guid_equal(tctx, odi1->domain_guid, odi2->domain_guid,
5513 : "domain_guid should match");
5514 9 : torture_assert(tctx, odi1->domain_sid != NULL,
5515 : "primary domain_sid needs to be valid");
5516 9 : torture_assert(tctx, odi2->domain_sid != NULL,
5517 : "trust_list domain_sid needs to be valid");
5518 9 : torture_assert_sid_equal(tctx, odi1->domain_sid, odi2->domain_sid,
5519 : "domain_sid should match");
5520 :
5521 9 : torture_assert_int_equal(tctx, odi1->trust_extension.length, 0,
5522 : "primary_domain should not have extension");
5523 9 : torture_assert_int_equal(tctx, odi2->trust_extension.length, 16,
5524 : "trust_list should have extension");
5525 9 : torture_assert(tctx, odi2->trust_extension.info != NULL,
5526 : "trust_list should have extension");
5527 9 : tex2 = &odi2->trust_extension.info->info;
5528 9 : 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 9 : 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 9 : 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 9 : 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 9 : if (strcmp(odi1->dns_domainname.string, odi1->dns_forestname.string) == 0) {
5548 9 : 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 9 : torture_assert_int_equal(tctx,
5553 : tex2->parent_index, 0,
5554 : "trust_list no parent on foreset root");
5555 : }
5556 9 : torture_assert_int_equal(tctx,
5557 : tex2->trust_type, LSA_TRUST_TYPE_UPLEVEL,
5558 : "trust_list uplevel");
5559 9 : torture_assert_int_equal(tctx,
5560 : tex2->trust_attributes, 0,
5561 : "trust_list no attributes");
5562 :
5563 9 : torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
5564 9 : netlogon_creds_client_authenticator(creds, &a);
5565 :
5566 9 : query.workstation_info->dns_hostname = NULL;
5567 :
5568 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5569 : "LogonGetDomainInfo failed");
5570 9 : torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5571 9 : torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5572 :
5573 : /* The old DNS hostname should stick */
5574 9 : torture_assert_str_equal(tctx,
5575 : info.domain_info->dns_hostname.string,
5576 : old_dnsname,
5577 : "'DNS hostname' changed!");
5578 :
5579 9 : torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (extra workstation flags)\n");
5580 9 : netlogon_creds_client_authenticator(creds, &a);
5581 :
5582 9 : 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 9 : talloc_free(discard_const_p(char, q1.dns_hostname));
5587 9 : q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
5588 : lpcfg_dnsdomain(tctx->lp_ctx));
5589 :
5590 9 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
5591 : "LogonGetDomainInfo failed");
5592 9 : torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
5593 9 : torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
5594 :
5595 : /* Checks "workstation flags" */
5596 9 : 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 9 : if (!torture_setting_bool(tctx, "dangerous", false)) {
5603 9 : 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 9 : 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 : NTSTATUS status;
5626 : struct netr_LogonGetDomainInfo r;
5627 : struct netr_WorkstationInformation q1;
5628 : struct netr_Authenticator a;
5629 : #define ASYNC_COUNT 100
5630 : struct netlogon_creds_CredentialState *creds;
5631 : struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
5632 : struct tevent_req *req[ASYNC_COUNT];
5633 : int i;
5634 : union netr_WorkstationInfo query;
5635 : 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 9 : static bool test_ManyGetDCName(struct torture_context *tctx,
5699 : struct dcerpc_pipe *p)
5700 : {
5701 : NTSTATUS status;
5702 : struct cli_credentials *anon_creds;
5703 : struct dcerpc_binding *binding2;
5704 : struct dcerpc_pipe *p2;
5705 : struct lsa_ObjectAttribute attr;
5706 : struct lsa_QosInfo qos;
5707 : struct lsa_OpenPolicy2 o;
5708 : struct policy_handle lsa_handle;
5709 : struct lsa_DomainList domains;
5710 :
5711 : struct lsa_EnumTrustDom t;
5712 9 : uint32_t resume_handle = 0;
5713 : struct netr_GetAnyDCName d;
5714 9 : const char *dcname = NULL;
5715 9 : struct dcerpc_binding_handle *b = p->binding_handle;
5716 : struct dcerpc_binding_handle *b2;
5717 :
5718 : int i;
5719 :
5720 9 : if (p->conn->transport.transport != NCACN_NP) {
5721 6 : torture_skip(tctx, "test_ManyGetDCName works only with NCACN_NP");
5722 : }
5723 :
5724 3 : torture_comment(tctx, "Torturing GetDCName\n");
5725 :
5726 3 : anon_creds = cli_credentials_init_anon(tctx);
5727 3 : torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed");
5728 :
5729 3 : binding2 = dcerpc_binding_dup(tctx, p->binding);
5730 : /* Swap the binding details from NETLOGON to LSA */
5731 3 : status = dcerpc_epm_map_binding(tctx, binding2, &ndr_table_lsarpc, tctx->ev, tctx->lp_ctx);
5732 3 : dcerpc_binding_set_assoc_group_id(binding2, 0);
5733 3 : torture_assert_ntstatus_ok(tctx, status, "epm map");
5734 :
5735 3 : status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_lsarpc,
5736 : anon_creds, tctx->lp_ctx,
5737 : tctx, &p2);
5738 3 : torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
5739 3 : b2 = p2->binding_handle;
5740 :
5741 3 : qos.len = 0;
5742 3 : qos.impersonation_level = 2;
5743 3 : qos.context_mode = 1;
5744 3 : qos.effective_only = 0;
5745 :
5746 3 : attr.len = 0;
5747 3 : attr.root_dir = NULL;
5748 3 : attr.object_name = NULL;
5749 3 : attr.attributes = 0;
5750 3 : attr.sec_desc = NULL;
5751 3 : attr.sec_qos = &qos;
5752 :
5753 3 : o.in.system_name = "\\";
5754 3 : o.in.attr = &attr;
5755 3 : o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5756 3 : o.out.handle = &lsa_handle;
5757 :
5758 3 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
5759 : "OpenPolicy2 failed");
5760 3 : torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
5761 :
5762 3 : t.in.handle = &lsa_handle;
5763 3 : t.in.resume_handle = &resume_handle;
5764 3 : t.in.max_size = 1000;
5765 3 : t.out.domains = &domains;
5766 3 : t.out.resume_handle = &resume_handle;
5767 :
5768 3 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b2, tctx, &t),
5769 : "EnumTrustDom failed");
5770 :
5771 6 : if ((!NT_STATUS_IS_OK(t.out.result) &&
5772 3 : (!NT_STATUS_EQUAL(t.out.result, NT_STATUS_NO_MORE_ENTRIES))))
5773 0 : torture_fail(tctx, "Could not list domains");
5774 :
5775 3 : talloc_free(p2);
5776 :
5777 3 : d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
5778 : dcerpc_server_name(p));
5779 3 : d.out.dcname = &dcname;
5780 :
5781 3 : 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 3 : return true;
5795 : }
5796 :
5797 9 : static bool test_lsa_over_netlogon(struct torture_context *tctx,
5798 : struct dcerpc_pipe *p)
5799 : {
5800 : NTSTATUS status;
5801 : struct cli_credentials *anon_creds;
5802 : const struct dcerpc_binding *binding2;
5803 : struct dcerpc_pipe *p2;
5804 : struct lsa_ObjectAttribute attr;
5805 : struct lsa_QosInfo qos;
5806 : struct lsa_OpenPolicy2 o;
5807 : struct policy_handle lsa_handle;
5808 :
5809 : struct dcerpc_binding_handle *b2;
5810 :
5811 :
5812 9 : if (p->conn->transport.transport != NCACN_NP) {
5813 6 : torture_skip(tctx, "test_lsa_over_netlogon works only with NCACN_NP");
5814 : }
5815 :
5816 3 : torture_comment(tctx, "Testing if we can access the LSA server over\n"
5817 : " \\\\pipe\\netlogon rather than \\\\pipe\\lsarpc\n");
5818 :
5819 3 : anon_creds = cli_credentials_init_anon(tctx);
5820 3 : torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed");
5821 :
5822 3 : binding2 = p->binding;
5823 :
5824 3 : status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_lsarpc,
5825 : anon_creds, tctx->lp_ctx,
5826 : tctx, &p2);
5827 3 : 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 : struct netlogon_creds_CredentialState *creds;
5862 : 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 964 : struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
5881 : {
5882 964 : struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon");
5883 : struct torture_rpc_tcase *tcase;
5884 : struct torture_test *test;
5885 :
5886 964 : tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
5887 : &ndr_table_netlogon, TEST_MACHINE_NAME);
5888 :
5889 964 : torture_rpc_tcase_add_test_creds(tcase, "SetupCredentialsDowngrade", test_SetupCredentialsDowngrade);
5890 964 : torture_rpc_tcase_add_test(tcase, "lsa_over_netlogon", test_lsa_over_netlogon);
5891 :
5892 964 : torture_rpc_tcase_add_test_creds(tcase, "GetForestTrustInformation", test_netr_GetForestTrustInformation);
5893 964 : torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo_AES", test_netr_ServerGetTrustInfo_AES);
5894 964 : torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
5895 964 : torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
5896 964 : torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
5897 964 : torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
5898 964 : torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
5899 964 : torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
5900 964 : torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
5901 964 : test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
5902 964 : test->dangerous = true;
5903 964 : torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
5904 964 : torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
5905 964 : torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
5906 964 : torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
5907 964 : torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
5908 964 : torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
5909 964 : torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
5910 964 : torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
5911 964 : torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
5912 964 : torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
5913 964 : torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
5914 964 : torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
5915 964 : torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
5916 964 : torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
5917 964 : torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
5918 964 : torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
5919 964 : torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
5920 964 : torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
5921 964 : torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuse", test_ServerReqChallengeReuse);
5922 964 : torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal4", test_ServerReqChallengeReuseGlobal4);
5923 964 : torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal3", test_ServerReqChallengeReuseGlobal3);
5924 964 : torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal2", test_ServerReqChallengeReuseGlobal2);
5925 964 : torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal", test_ServerReqChallengeReuseGlobal);
5926 964 : torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeGlobal", test_ServerReqChallengeGlobal);
5927 964 : torture_rpc_tcase_add_test_creds(tcase, "invalidAuthenticate2", test_invalidAuthenticate2);
5928 964 : torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
5929 964 : torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
5930 964 : torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
5931 :
5932 964 : torture_rpc_tcase_add_test(tcase, "Broken RPC binding handle",
5933 : test_netr_broken_binding_handle);
5934 :
5935 964 : return suite;
5936 : }
5937 :
5938 964 : struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
5939 : {
5940 964 : struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon-s3");
5941 : struct torture_rpc_tcase *tcase;
5942 :
5943 964 : tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
5944 : &ndr_table_netlogon, TEST_MACHINE_NAME);
5945 :
5946 964 : torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
5947 964 : torture_rpc_tcase_add_test_creds(tcase, "SamLogon_NULL_domain", test_SamLogon_NULL_domain);
5948 964 : torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
5949 964 : torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
5950 964 : torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
5951 964 : torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
5952 964 : torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
5953 :
5954 964 : return suite;
5955 : }
5956 :
5957 964 : struct torture_suite *torture_rpc_netlogon_zerologon(TALLOC_CTX *mem_ctx)
5958 : {
5959 964 : struct torture_suite *suite = torture_suite_create(
5960 : mem_ctx,
5961 : "netlogon.zerologon");
5962 : struct torture_rpc_tcase *tcase;
5963 :
5964 964 : tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(
5965 : suite,
5966 : "netlogon",
5967 : &ndr_table_netlogon,
5968 : TEST_MACHINE_NAME);
5969 :
5970 964 : torture_rpc_tcase_add_test_creds(
5971 : tcase,
5972 : "ServerReqChallenge",
5973 : test_ServerReqChallenge);
5974 964 : torture_rpc_tcase_add_test_creds(
5975 : tcase,
5976 : "ServerReqChallenge_zero_challenge",
5977 : test_ServerReqChallenge_zero_challenge);
5978 964 : torture_rpc_tcase_add_test_creds(
5979 : tcase,
5980 : "ServerReqChallenge_5_repeats",
5981 : test_ServerReqChallenge_5_repeats);
5982 964 : torture_rpc_tcase_add_test_creds(
5983 : tcase,
5984 : "ServerReqChallenge_4_repeats",
5985 : test_ServerReqChallenge_4_repeats);
5986 964 : torture_rpc_tcase_add_test_creds(
5987 : tcase,
5988 : "test_SetPassword2_encrypted_to_all_zeros",
5989 : test_SetPassword2_encrypted_to_all_zeros);
5990 964 : torture_rpc_tcase_add_test_creds(
5991 : tcase,
5992 : "test_SetPassword2_password_encrypts_to_zero",
5993 : test_SetPassword2_password_encrypts_to_zero);
5994 964 : torture_rpc_tcase_add_test_creds(
5995 : tcase,
5996 : "test_SetPassword2_confounder",
5997 : test_SetPassword2_confounder);
5998 964 : torture_rpc_tcase_add_test_creds(
5999 : tcase,
6000 : "test_SetPassword2_all_zeros",
6001 : test_SetPassword2_all_zeros);
6002 964 : torture_rpc_tcase_add_test_creds(
6003 : tcase,
6004 : "test_SetPassword2_all_zero_password",
6005 : test_SetPassword2_all_zero_password);
6006 964 : torture_rpc_tcase_add_test_creds(
6007 : tcase,
6008 : "test_SetPassword2_maximum_length_password",
6009 : test_SetPassword2_maximum_length_password);
6010 :
6011 964 : return suite;
6012 : }
6013 :
6014 964 : struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
6015 : {
6016 964 : struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon.admin");
6017 : struct torture_rpc_tcase *tcase;
6018 :
6019 964 : tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "bdc",
6020 : &ndr_table_netlogon, TEST_MACHINE_NAME);
6021 964 : torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
6022 964 : torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
6023 964 : torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
6024 :
6025 964 : tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "wkst",
6026 : &ndr_table_netlogon, TEST_MACHINE_NAME);
6027 964 : torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
6028 964 : torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
6029 964 : torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
6030 :
6031 964 : tcase = torture_suite_add_rpc_iface_tcase(suite, "admin",
6032 : &ndr_table_netlogon);
6033 964 : torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
6034 964 : torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
6035 964 : torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
6036 :
6037 964 : return suite;
6038 : }
|