Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : test suite for lsa rpc operations
4 :
5 : Copyright (C) Andrew Tridgell 2003
6 : Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
7 :
8 : This program is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include "includes.h"
23 : #include "torture/torture.h"
24 : #include "libcli/cldap/cldap.h"
25 : #include "../lib/tsocket/tsocket.h"
26 : #include "librpc/gen_ndr/ndr_lsa_c.h"
27 : #include "librpc/gen_ndr/netlogon.h"
28 : #include "librpc/gen_ndr/ndr_drsblobs.h"
29 : #include "librpc/gen_ndr/ndr_netlogon_c.h"
30 : #include "lib/events/events.h"
31 : #include "libcli/security/security.h"
32 : #include "libcli/auth/libcli_auth.h"
33 : #include "torture/rpc/torture_rpc.h"
34 : #include "param/param.h"
35 : #include "source4/auth/kerberos/kerberos.h"
36 : #include "source4/auth/kerberos/kerberos_util.h"
37 : #include "lib/util/util_net.h"
38 : #include "libcli/resolve/resolve.h"
39 :
40 : #include <gnutls/gnutls.h>
41 : #include <gnutls/crypto.h>
42 :
43 : #define TEST_MACHINENAME "lsatestmach"
44 : #define TRUSTPW "12345678"
45 :
46 25448 : static void init_lsa_String(struct lsa_String *name, const char *s)
47 : {
48 30248 : name->string = s;
49 25448 : }
50 :
51 33 : static bool test_OpenPolicy(struct dcerpc_binding_handle *b,
52 : struct torture_context *tctx)
53 : {
54 : struct lsa_ObjectAttribute attr;
55 : struct policy_handle handle;
56 : struct lsa_QosInfo qos;
57 : struct lsa_OpenPolicy r;
58 33 : uint16_t system_name = '\\';
59 :
60 33 : torture_comment(tctx, "\nTesting OpenPolicy\n");
61 :
62 33 : qos.len = 0;
63 33 : qos.impersonation_level = 2;
64 33 : qos.context_mode = 1;
65 33 : qos.effective_only = 0;
66 :
67 33 : attr.len = 0;
68 33 : attr.root_dir = NULL;
69 33 : attr.object_name = NULL;
70 33 : attr.attributes = 0;
71 33 : attr.sec_desc = NULL;
72 33 : attr.sec_qos = &qos;
73 :
74 33 : r.in.system_name = &system_name;
75 33 : r.in.attr = &attr;
76 33 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
77 33 : r.out.handle = &handle;
78 :
79 33 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy_r(b, tctx, &r),
80 : "OpenPolicy failed");
81 :
82 33 : torture_assert_ntstatus_ok(tctx,
83 : r.out.result,
84 : "OpenPolicy failed");
85 :
86 33 : return true;
87 : }
88 :
89 7 : static bool test_OpenPolicy_fail(struct dcerpc_binding_handle *b,
90 : struct torture_context *tctx)
91 : {
92 : struct lsa_ObjectAttribute attr;
93 : struct policy_handle handle;
94 : struct lsa_QosInfo qos;
95 : struct lsa_OpenPolicy r;
96 7 : uint16_t system_name = '\\';
97 : NTSTATUS status;
98 :
99 7 : torture_comment(tctx, "\nTesting OpenPolicy_fail\n");
100 :
101 7 : qos.len = 0;
102 7 : qos.impersonation_level = 2;
103 7 : qos.context_mode = 1;
104 7 : qos.effective_only = 0;
105 :
106 7 : attr.len = 0;
107 7 : attr.root_dir = NULL;
108 7 : attr.object_name = NULL;
109 7 : attr.attributes = 0;
110 7 : attr.sec_desc = NULL;
111 7 : attr.sec_qos = &qos;
112 :
113 7 : r.in.system_name = &system_name;
114 7 : r.in.attr = &attr;
115 7 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
116 7 : r.out.handle = &handle;
117 :
118 7 : status = dcerpc_lsa_OpenPolicy_r(b, tctx, &r);
119 7 : if (!NT_STATUS_IS_OK(status)) {
120 7 : if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
121 7 : torture_comment(tctx,
122 : "OpenPolicy correctly returned with "
123 : "status: %s\n",
124 : nt_errstr(status));
125 7 : return true;
126 : }
127 :
128 0 : torture_assert_ntstatus_equal(tctx,
129 : status,
130 : NT_STATUS_ACCESS_DENIED,
131 : "OpenPolicy return value should "
132 : "be ACCESS_DENIED");
133 0 : return true;
134 : }
135 :
136 0 : if (!NT_STATUS_IS_OK(r.out.result)) {
137 0 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
138 0 : NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
139 0 : torture_comment(tctx,
140 : "OpenPolicy correctly returned with "
141 : "result: %s\n",
142 : nt_errstr(r.out.result));
143 0 : return true;
144 : }
145 : }
146 :
147 0 : torture_assert_ntstatus_equal(tctx,
148 : r.out.result,
149 : NT_STATUS_OK,
150 : "OpenPolicy return value should be "
151 : "ACCESS_DENIED");
152 :
153 0 : return false;
154 : }
155 :
156 :
157 2453 : bool test_lsa_OpenPolicy2_ex(struct dcerpc_binding_handle *b,
158 : struct torture_context *tctx,
159 : struct policy_handle **handle,
160 : NTSTATUS expected_status,
161 : NTSTATUS expected_status2)
162 : {
163 : struct lsa_ObjectAttribute attr;
164 : struct lsa_QosInfo qos;
165 : struct lsa_OpenPolicy2 r;
166 : NTSTATUS status;
167 :
168 2453 : torture_comment(tctx, "\nTesting OpenPolicy2\n");
169 :
170 2453 : *handle = talloc(tctx, struct policy_handle);
171 2453 : torture_assert(tctx, *handle != NULL, "talloc(tctx, struct policy_handle)");
172 :
173 2453 : qos.len = 0;
174 2453 : qos.impersonation_level = 2;
175 2453 : qos.context_mode = 1;
176 2453 : qos.effective_only = 0;
177 :
178 2453 : attr.len = 0;
179 2453 : attr.root_dir = NULL;
180 2453 : attr.object_name = NULL;
181 2453 : attr.attributes = 0;
182 2453 : attr.sec_desc = NULL;
183 2453 : attr.sec_qos = &qos;
184 :
185 2453 : r.in.system_name = "\\";
186 2453 : r.in.attr = &attr;
187 2453 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
188 2453 : r.out.handle = *handle;
189 :
190 2453 : status = dcerpc_lsa_OpenPolicy2_r(b, tctx, &r);
191 :
192 : /* Allow two possible failure status codes */
193 2453 : if (!NT_STATUS_EQUAL(status, expected_status2)) {
194 15 : torture_assert_ntstatus_equal(tctx, status,
195 : expected_status,
196 : "OpenPolicy2 failed");
197 : }
198 4173 : if (!NT_STATUS_IS_OK(expected_status) ||
199 2438 : !NT_STATUS_IS_OK(expected_status2)) {
200 12 : return true;
201 : }
202 :
203 2438 : torture_assert_ntstatus_ok(tctx,
204 : r.out.result,
205 : "OpenPolicy2 failed");
206 :
207 2432 : return true;
208 : }
209 :
210 :
211 2438 : bool test_lsa_OpenPolicy2(struct dcerpc_binding_handle *b,
212 : struct torture_context *tctx,
213 : struct policy_handle **handle)
214 : {
215 3156 : return test_lsa_OpenPolicy2_ex(b, tctx, handle,
216 2438 : NT_STATUS_OK, NT_STATUS_OK);
217 : }
218 :
219 7 : static bool test_OpenPolicy2_fail(struct dcerpc_binding_handle *b,
220 : struct torture_context *tctx)
221 : {
222 : struct lsa_ObjectAttribute attr;
223 : struct policy_handle handle;
224 : struct lsa_QosInfo qos;
225 : struct lsa_OpenPolicy2 r;
226 : NTSTATUS status;
227 :
228 7 : torture_comment(tctx, "\nTesting OpenPolicy2_fail\n");
229 :
230 7 : qos.len = 0;
231 7 : qos.impersonation_level = 2;
232 7 : qos.context_mode = 1;
233 7 : qos.effective_only = 0;
234 :
235 7 : attr.len = 0;
236 7 : attr.root_dir = NULL;
237 7 : attr.object_name = NULL;
238 7 : attr.attributes = 0;
239 7 : attr.sec_desc = NULL;
240 7 : attr.sec_qos = &qos;
241 :
242 7 : r.in.system_name = "\\";
243 7 : r.in.attr = &attr;
244 7 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
245 7 : r.out.handle = &handle;
246 :
247 7 : status = dcerpc_lsa_OpenPolicy2_r(b, tctx, &r);
248 7 : if (!NT_STATUS_IS_OK(status)) {
249 7 : if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
250 7 : torture_comment(tctx,
251 : "OpenPolicy2 correctly returned with "
252 : "status: %s\n",
253 : nt_errstr(status));
254 7 : return true;
255 : }
256 :
257 0 : torture_assert_ntstatus_equal(tctx,
258 : status,
259 : NT_STATUS_ACCESS_DENIED,
260 : "OpenPolicy2 return value should "
261 : "be ACCESS_DENIED");
262 0 : return true;
263 : }
264 :
265 0 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
266 0 : NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
267 0 : torture_comment(tctx,
268 : "OpenPolicy2 correctly returned with "
269 : "result: %s\n",
270 : nt_errstr(r.out.result));
271 0 : return true;
272 : }
273 :
274 0 : torture_fail(tctx,
275 : "OpenPolicy2 return value should be "
276 : "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
277 :
278 : return false;
279 : }
280 :
281 183 : static bool test_LookupNames(struct dcerpc_binding_handle *b,
282 : struct torture_context *tctx,
283 : struct policy_handle *handle,
284 : enum lsa_LookupNamesLevel level,
285 : struct lsa_TransNameArray *tnames)
286 : {
287 : struct lsa_LookupNames r;
288 : struct lsa_TransSidArray sids;
289 183 : struct lsa_RefDomainList *domains = NULL;
290 : struct lsa_String *names;
291 183 : uint32_t count = 0;
292 : int i;
293 : uint32_t *input_idx;
294 :
295 183 : torture_comment(tctx, "\nTesting LookupNames with %d names\n", tnames->count);
296 :
297 183 : sids.count = 0;
298 183 : sids.sids = NULL;
299 :
300 :
301 183 : r.in.num_names = 0;
302 :
303 183 : input_idx = talloc_array(tctx, uint32_t, tnames->count);
304 183 : names = talloc_array(tctx, struct lsa_String, tnames->count);
305 :
306 2661 : for (i=0;i<tnames->count;i++) {
307 2478 : if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
308 2478 : init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
309 2478 : input_idx[r.in.num_names] = i;
310 2478 : r.in.num_names++;
311 : }
312 : }
313 :
314 183 : r.in.handle = handle;
315 183 : r.in.names = names;
316 183 : r.in.sids = &sids;
317 183 : r.in.level = level;
318 183 : r.in.count = &count;
319 183 : r.out.count = &count;
320 183 : r.out.sids = &sids;
321 183 : r.out.domains = &domains;
322 :
323 183 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
324 : "LookupNames failed");
325 325 : if (NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED) ||
326 183 : NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
327 0 : for (i=0;i< r.in.num_names;i++) {
328 0 : if (i < count && sids.sids[i].sid_type == SID_NAME_UNKNOWN) {
329 0 : torture_comment(tctx, "LookupName of %s was unmapped\n",
330 0 : tnames->names[i].name.string);
331 0 : } else if (i >=count) {
332 0 : torture_comment(tctx, "LookupName of %s failed to return a result\n",
333 0 : tnames->names[i].name.string);
334 : }
335 : }
336 0 : torture_assert_ntstatus_ok(tctx, r.out.result,
337 : "LookupNames failed");
338 183 : } else if (!NT_STATUS_IS_OK(r.out.result)) {
339 0 : torture_assert_ntstatus_ok(tctx, r.out.result,
340 : "LookupNames failed");
341 : }
342 :
343 2661 : for (i=0;i< r.in.num_names;i++) {
344 2478 : torture_assert(tctx, (i < count),
345 : talloc_asprintf(tctx,
346 : "LookupName of %s failed to return a result\n",
347 : tnames->names[input_idx[i]].name.string));
348 :
349 2478 : torture_assert_int_equal(tctx,
350 : sids.sids[i].sid_type,
351 : tnames->names[input_idx[i]].sid_type,
352 : talloc_asprintf(tctx,
353 : "LookupName of %s got unexpected name type: %s\n",
354 : tnames->names[input_idx[i]].name.string,
355 : sid_type_lookup(sids.sids[i].sid_type)));
356 2478 : if (sids.sids[i].sid_type != SID_NAME_DOMAIN) {
357 2256 : continue;
358 : }
359 222 : torture_assert_int_equal(tctx,
360 : sids.sids[i].rid,
361 : UINT32_MAX,
362 : talloc_asprintf(tctx,
363 : "LookupName of %s got unexpected rid: %d\n",
364 : tnames->names[input_idx[i]].name.string,
365 : sids.sids[i].rid));
366 : }
367 :
368 183 : return true;
369 : }
370 :
371 7 : static bool test_LookupNames_bogus(struct dcerpc_binding_handle *b,
372 : struct torture_context *tctx,
373 : struct policy_handle *handle,
374 : enum lsa_LookupNamesLevel level)
375 : {
376 : struct lsa_LookupNames r;
377 : struct lsa_TransSidArray sids;
378 7 : struct lsa_RefDomainList *domains = NULL;
379 : struct lsa_String names[1];
380 7 : uint32_t count = 0;
381 :
382 7 : torture_comment(tctx, "\nTesting LookupNames with bogus name\n");
383 :
384 7 : sids.count = 0;
385 7 : sids.sids = NULL;
386 :
387 7 : init_lsa_String(&names[0], "NT AUTHORITY\\BOGUS");
388 :
389 7 : r.in.handle = handle;
390 7 : r.in.num_names = 1;
391 7 : r.in.names = names;
392 7 : r.in.sids = &sids;
393 7 : r.in.level = level;
394 7 : r.in.count = &count;
395 7 : r.out.count = &count;
396 7 : r.out.sids = &sids;
397 7 : r.out.domains = &domains;
398 :
399 7 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
400 : "LookupNames bogus failed");
401 7 : if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
402 0 : torture_comment(tctx, "LookupNames failed - %s\n",
403 : nt_errstr(r.out.result));
404 0 : return false;
405 : }
406 :
407 7 : torture_comment(tctx, "\n");
408 :
409 7 : return true;
410 : }
411 :
412 7 : static bool test_LookupNames_NULL(struct dcerpc_binding_handle *b,
413 : struct torture_context *tctx,
414 : struct policy_handle *handle,
415 : enum lsa_LookupNamesLevel level)
416 : {
417 : struct lsa_LookupNames r;
418 : struct lsa_TransSidArray sids;
419 7 : struct lsa_RefDomainList *domains = NULL;
420 : struct lsa_String names[1];
421 7 : uint32_t count = 0;
422 :
423 7 : torture_comment(tctx, "\nTesting LookupNames with NULL name\n");
424 :
425 7 : sids.count = 0;
426 7 : sids.sids = NULL;
427 :
428 7 : names[0].string = NULL;
429 :
430 7 : r.in.handle = handle;
431 7 : r.in.num_names = 1;
432 7 : r.in.names = names;
433 7 : r.in.sids = &sids;
434 7 : r.in.level = level;
435 7 : r.in.count = &count;
436 7 : r.out.count = &count;
437 7 : r.out.sids = &sids;
438 7 : r.out.domains = &domains;
439 :
440 : /* nt4 returns NT_STATUS_NONE_MAPPED with sid_type
441 : * SID_NAME_UNKNOWN, rid 0, and sid_index -1;
442 : *
443 : * w2k3/w2k8 return NT_STATUS_OK with sid_type
444 : * SID_NAME_DOMAIN, rid -1 and sid_index 0 and BUILTIN domain
445 : */
446 :
447 7 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
448 : "LookupNames with NULL name failed");
449 7 : torture_assert_ntstatus_ok(tctx, r.out.result,
450 : "LookupNames with NULL name failed");
451 :
452 7 : torture_comment(tctx, "\n");
453 :
454 7 : return true;
455 : }
456 :
457 7 : static bool test_LookupNames_wellknown(struct dcerpc_binding_handle *b,
458 : struct torture_context *tctx,
459 : struct policy_handle *handle,
460 : enum lsa_LookupNamesLevel level)
461 : {
462 : struct lsa_TranslatedName name;
463 : struct lsa_TransNameArray tnames;
464 7 : bool ret = true;
465 :
466 7 : torture_comment(tctx, "Testing LookupNames with well known names\n");
467 :
468 7 : tnames.names = &name;
469 7 : tnames.count = 1;
470 7 : name.name.string = "NT AUTHORITY\\SYSTEM";
471 7 : name.sid_type = SID_NAME_WKN_GRP;
472 7 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
473 :
474 7 : name.name.string = "NT AUTHORITY\\ANONYMOUS LOGON";
475 7 : name.sid_type = SID_NAME_WKN_GRP;
476 7 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
477 :
478 7 : name.name.string = "NT AUTHORITY\\Authenticated Users";
479 7 : name.sid_type = SID_NAME_WKN_GRP;
480 7 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
481 :
482 : #if 0
483 : name.name.string = "NT AUTHORITY";
484 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
485 :
486 : name.name.string = "NT AUTHORITY\\";
487 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
488 : #endif
489 :
490 7 : name.name.string = "BUILTIN\\";
491 7 : name.sid_type = SID_NAME_DOMAIN;
492 7 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
493 :
494 7 : name.name.string = "BUILTIN\\Administrators";
495 7 : name.sid_type = SID_NAME_ALIAS;
496 7 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
497 :
498 7 : name.name.string = "SYSTEM";
499 7 : name.sid_type = SID_NAME_WKN_GRP;
500 7 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
501 :
502 7 : name.name.string = "Everyone";
503 7 : name.sid_type = SID_NAME_WKN_GRP;
504 7 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
505 7 : return ret;
506 : }
507 :
508 14 : static bool test_LookupNames2(struct dcerpc_binding_handle *b,
509 : struct torture_context *tctx,
510 : struct policy_handle *handle,
511 : enum lsa_LookupNamesLevel level,
512 : struct lsa_TransNameArray2 *tnames,
513 : bool check_result)
514 : {
515 : struct lsa_LookupNames2 r;
516 : struct lsa_TransSidArray2 sids;
517 14 : struct lsa_RefDomainList *domains = NULL;
518 : struct lsa_String *names;
519 : uint32_t *input_idx;
520 14 : uint32_t count = 0;
521 : int i;
522 :
523 14 : torture_comment(tctx, "\nTesting LookupNames2 with %d names\n", tnames->count);
524 :
525 14 : sids.count = 0;
526 14 : sids.sids = NULL;
527 :
528 14 : r.in.num_names = 0;
529 :
530 14 : input_idx = talloc_array(tctx, uint32_t, tnames->count);
531 14 : names = talloc_array(tctx, struct lsa_String, tnames->count);
532 :
533 63 : for (i=0;i<tnames->count;i++) {
534 49 : if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
535 49 : init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
536 49 : input_idx[r.in.num_names] = i;
537 49 : r.in.num_names++;
538 : }
539 : }
540 :
541 14 : r.in.handle = handle;
542 14 : r.in.names = names;
543 14 : r.in.sids = &sids;
544 14 : r.in.level = level;
545 14 : r.in.count = &count;
546 14 : r.in.lookup_options = 0;
547 14 : r.in.client_revision = 0;
548 14 : r.out.count = &count;
549 14 : r.out.sids = &sids;
550 14 : r.out.domains = &domains;
551 :
552 14 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames2_r(b, tctx, &r),
553 : "LookupNames2 failed");
554 14 : torture_assert_ntstatus_ok(tctx, r.out.result, "LookupNames2 failed");
555 :
556 14 : if (check_result) {
557 7 : torture_assert_int_equal(tctx, count, sids.count,
558 : "unexpected number of results returned");
559 7 : if (sids.count > 0) {
560 7 : torture_assert(tctx, sids.sids, "invalid sid buffer");
561 : }
562 : }
563 :
564 14 : torture_comment(tctx, "\n");
565 :
566 14 : return true;
567 : }
568 :
569 :
570 14 : static bool test_LookupNames3(struct dcerpc_binding_handle *b,
571 : struct torture_context *tctx,
572 : struct policy_handle *handle,
573 : enum lsa_LookupNamesLevel level,
574 : struct lsa_TransNameArray2 *tnames,
575 : bool check_result)
576 : {
577 : struct lsa_LookupNames3 r;
578 : struct lsa_TransSidArray3 sids;
579 14 : struct lsa_RefDomainList *domains = NULL;
580 : struct lsa_String *names;
581 14 : uint32_t count = 0;
582 : int i;
583 : uint32_t *input_idx;
584 :
585 14 : torture_comment(tctx, "\nTesting LookupNames3 with %d names\n", tnames->count);
586 :
587 14 : sids.count = 0;
588 14 : sids.sids = NULL;
589 :
590 14 : r.in.num_names = 0;
591 :
592 14 : input_idx = talloc_array(tctx, uint32_t, tnames->count);
593 14 : names = talloc_array(tctx, struct lsa_String, tnames->count);
594 63 : for (i=0;i<tnames->count;i++) {
595 49 : if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
596 49 : init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
597 49 : input_idx[r.in.num_names] = i;
598 49 : r.in.num_names++;
599 : }
600 : }
601 :
602 14 : r.in.handle = handle;
603 14 : r.in.names = names;
604 14 : r.in.sids = &sids;
605 14 : r.in.level = level;
606 14 : r.in.count = &count;
607 14 : r.in.lookup_options = 0;
608 14 : r.in.client_revision = 0;
609 14 : r.out.count = &count;
610 14 : r.out.sids = &sids;
611 14 : r.out.domains = &domains;
612 :
613 14 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames3_r(b, tctx, &r),
614 : "LookupNames3 failed");
615 14 : torture_assert_ntstatus_ok(tctx, r.out.result,
616 : "LookupNames3 failed");
617 :
618 14 : if (check_result) {
619 7 : torture_assert_int_equal(tctx, count, sids.count,
620 : "unexpected number of results returned");
621 7 : if (sids.count > 0) {
622 7 : torture_assert(tctx, sids.sids, "invalid sid buffer");
623 : }
624 : }
625 :
626 14 : torture_comment(tctx, "\n");
627 :
628 14 : return true;
629 : }
630 :
631 552 : static bool test_LookupNames4(struct dcerpc_binding_handle *b,
632 : struct torture_context *tctx,
633 : enum lsa_LookupNamesLevel level,
634 : struct lsa_TransNameArray2 *tnames,
635 : bool check_result)
636 : {
637 : struct lsa_LookupNames4 r;
638 : struct lsa_TransSidArray3 sids;
639 552 : struct lsa_RefDomainList *domains = NULL;
640 : struct lsa_String *names;
641 552 : uint32_t count = 0;
642 : int i;
643 : uint32_t *input_idx;
644 :
645 552 : torture_comment(tctx, "\nTesting LookupNames4 with %d names\n", tnames->count);
646 :
647 552 : sids.count = 0;
648 552 : sids.sids = NULL;
649 :
650 552 : r.in.num_names = 0;
651 :
652 552 : input_idx = talloc_array(tctx, uint32_t, tnames->count);
653 552 : names = talloc_array(tctx, struct lsa_String, tnames->count);
654 28152 : for (i=0;i<tnames->count;i++) {
655 27600 : if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
656 32400 : init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
657 27600 : input_idx[r.in.num_names] = i;
658 27600 : r.in.num_names++;
659 : }
660 : }
661 :
662 552 : r.in.num_names = tnames->count;
663 552 : r.in.names = names;
664 552 : r.in.sids = &sids;
665 552 : r.in.level = level;
666 552 : r.in.count = &count;
667 552 : r.in.lookup_options = 0;
668 552 : r.in.client_revision = 0;
669 552 : r.out.count = &count;
670 552 : r.out.sids = &sids;
671 552 : r.out.domains = &domains;
672 :
673 552 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames4_r(b, tctx, &r),
674 : "LookupNames4 failed");
675 :
676 552 : if (!NT_STATUS_IS_OK(r.out.result)) {
677 276 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
678 276 : torture_comment(tctx,
679 : "LookupNames4 failed: %s - not considered as an error",
680 : nt_errstr(r.out.result));
681 :
682 276 : return true;
683 : }
684 : }
685 276 : torture_assert_ntstatus_ok(tctx,
686 : r.out.result,
687 : "LookupNames4 failed");
688 :
689 276 : if (check_result) {
690 276 : torture_assert_int_equal(tctx, count, sids.count,
691 : "unexpected number of results returned");
692 276 : if (sids.count > 0) {
693 276 : torture_assert(tctx, sids.sids, "invalid sid buffer");
694 : }
695 : }
696 :
697 276 : torture_comment(tctx, "\n");
698 :
699 276 : return true;
700 : }
701 :
702 20 : static bool test_LookupNames4_fail(struct dcerpc_binding_handle *b,
703 : struct torture_context *tctx,
704 : enum lsa_LookupNamesLevel level)
705 : {
706 : struct lsa_LookupNames4 r;
707 : struct lsa_TransSidArray3 sids;
708 20 : struct lsa_RefDomainList *domains = NULL;
709 20 : struct lsa_String *names = NULL;
710 20 : uint32_t count = 0;
711 : NTSTATUS status;
712 :
713 20 : torture_comment(tctx, "\nTesting LookupNames4_fail");
714 :
715 20 : sids.count = 0;
716 20 : sids.sids = NULL;
717 :
718 20 : r.in.num_names = 0;
719 :
720 20 : r.in.num_names = count;
721 20 : r.in.names = names;
722 20 : r.in.sids = &sids;
723 20 : r.in.level = level;
724 20 : r.in.count = &count;
725 20 : r.in.lookup_options = 0;
726 20 : r.in.client_revision = 0;
727 20 : r.out.count = &count;
728 20 : r.out.sids = &sids;
729 20 : r.out.domains = &domains;
730 :
731 20 : status = dcerpc_lsa_LookupNames4_r(b, tctx, &r);
732 20 : if (!NT_STATUS_IS_OK(status)) {
733 20 : if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
734 20 : torture_comment(tctx,
735 : "LookupNames4 correctly returned with "
736 : "status: %s\n",
737 : nt_errstr(status));
738 20 : return true;
739 : }
740 :
741 0 : torture_assert_ntstatus_equal(tctx,
742 : status,
743 : NT_STATUS_ACCESS_DENIED,
744 : "LookupNames4 return value should "
745 : "be ACCESS_DENIED");
746 0 : return true;
747 : }
748 :
749 0 : if (!NT_STATUS_IS_OK(r.out.result)) {
750 0 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
751 0 : NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
752 0 : torture_comment(tctx,
753 : "LookupSids3 correctly returned with "
754 : "result: %s\n",
755 : nt_errstr(r.out.result));
756 0 : return true;
757 : }
758 : }
759 :
760 0 : torture_fail(tctx,
761 : "LookupNames4 return value should be "
762 : "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
763 :
764 : return false;
765 : }
766 :
767 :
768 7 : static bool test_LookupSids(struct dcerpc_binding_handle *b,
769 : struct torture_context *tctx,
770 : struct policy_handle *handle,
771 : enum lsa_LookupNamesLevel level,
772 : struct lsa_SidArray *sids)
773 : {
774 : struct lsa_LookupSids r;
775 : struct lsa_TransNameArray names;
776 7 : struct lsa_RefDomainList *domains = NULL;
777 7 : uint32_t count = sids->num_sids;
778 :
779 7 : torture_comment(tctx, "\nTesting LookupSids\n");
780 :
781 7 : names.count = 0;
782 7 : names.names = NULL;
783 :
784 7 : r.in.handle = handle;
785 7 : r.in.sids = sids;
786 7 : r.in.names = &names;
787 7 : r.in.level = level;
788 7 : r.in.count = &count;
789 7 : r.out.count = &count;
790 7 : r.out.names = &names;
791 7 : r.out.domains = &domains;
792 :
793 7 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids_r(b, tctx, &r),
794 : "LookupSids failed");
795 7 : if (!NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED)) {
796 7 : torture_assert_ntstatus_ok(tctx, r.out.result,
797 : "LookupSids failed");
798 : }
799 :
800 7 : torture_comment(tctx, "\n");
801 :
802 7 : if (!test_LookupNames(b, tctx, handle, level, &names)) {
803 0 : return false;
804 : }
805 :
806 7 : return true;
807 : }
808 :
809 :
810 7 : static bool test_LookupSids2(struct dcerpc_binding_handle *b,
811 : struct torture_context *tctx,
812 : struct policy_handle *handle,
813 : enum lsa_LookupNamesLevel level,
814 : struct lsa_SidArray *sids)
815 : {
816 : struct lsa_LookupSids2 r;
817 : struct lsa_TransNameArray2 names;
818 7 : struct lsa_RefDomainList *domains = NULL;
819 7 : uint32_t count = sids->num_sids;
820 :
821 7 : torture_comment(tctx, "\nTesting LookupSids2\n");
822 :
823 7 : names.count = 0;
824 7 : names.names = NULL;
825 :
826 7 : r.in.handle = handle;
827 7 : r.in.sids = sids;
828 7 : r.in.names = &names;
829 7 : r.in.level = level;
830 7 : r.in.count = &count;
831 7 : r.in.lookup_options = 0;
832 7 : r.in.client_revision = 0;
833 7 : r.out.count = &count;
834 7 : r.out.names = &names;
835 7 : r.out.domains = &domains;
836 :
837 7 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids2_r(b, tctx, &r),
838 : "LookupSids2 failed");
839 7 : if (!NT_STATUS_IS_OK(r.out.result) &&
840 0 : !NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED)) {
841 0 : torture_comment(tctx, "LookupSids2 failed - %s\n",
842 : nt_errstr(r.out.result));
843 0 : return false;
844 : }
845 :
846 7 : torture_comment(tctx, "\n");
847 :
848 7 : if (!test_LookupNames2(b, tctx, handle, level, &names, false)) {
849 0 : return false;
850 : }
851 :
852 7 : if (!test_LookupNames3(b, tctx, handle, level, &names, false)) {
853 0 : return false;
854 : }
855 :
856 7 : return true;
857 : }
858 :
859 276 : static bool test_LookupSids3(struct dcerpc_binding_handle *b,
860 : struct torture_context *tctx,
861 : enum lsa_LookupNamesLevel level,
862 : struct lsa_SidArray *sids)
863 : {
864 : struct lsa_LookupSids3 r;
865 : struct lsa_TransNameArray2 names;
866 276 : struct lsa_RefDomainList *domains = NULL;
867 276 : uint32_t count = sids->num_sids;
868 :
869 276 : torture_comment(tctx, "\nTesting LookupSids3\n");
870 :
871 276 : names.count = 0;
872 276 : names.names = NULL;
873 :
874 276 : r.in.sids = sids;
875 276 : r.in.names = &names;
876 276 : r.in.level = level;
877 276 : r.in.count = &count;
878 276 : r.in.lookup_options = 0;
879 276 : r.in.client_revision = 0;
880 276 : r.out.domains = &domains;
881 276 : r.out.count = &count;
882 276 : r.out.names = &names;
883 :
884 276 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids3_r(b, tctx, &r),
885 : "LookupSids3 failed");
886 :
887 276 : if (!NT_STATUS_IS_OK(r.out.result)) {
888 0 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
889 0 : torture_comment(tctx,
890 : "LookupSids3 failed: %s - not considered as an error",
891 : nt_errstr(r.out.result));
892 :
893 0 : return true;
894 : }
895 :
896 0 : torture_assert_ntstatus_ok(tctx,
897 : r.out.result,
898 : "LookupSids3 failed");
899 :
900 0 : return false;
901 : }
902 :
903 276 : torture_comment(tctx, "\n");
904 :
905 276 : if (!test_LookupNames4(b, tctx, level, &names, true)) {
906 0 : return false;
907 : }
908 :
909 276 : return true;
910 : }
911 :
912 20 : static bool test_LookupSids3_fail(struct dcerpc_binding_handle *b,
913 : struct torture_context *tctx,
914 : enum lsa_LookupNamesLevel level,
915 : struct lsa_SidArray *sids)
916 : {
917 : struct lsa_LookupSids3 r;
918 : struct lsa_TransNameArray2 names;
919 20 : struct lsa_RefDomainList *domains = NULL;
920 20 : uint32_t count = sids->num_sids;
921 : NTSTATUS status;
922 :
923 20 : torture_comment(tctx, "\nTesting LookupSids3\n");
924 :
925 20 : names.count = 0;
926 20 : names.names = NULL;
927 :
928 20 : r.in.sids = sids;
929 20 : r.in.names = &names;
930 20 : r.in.level = level;
931 20 : r.in.count = &count;
932 20 : r.in.lookup_options = 0;
933 20 : r.in.client_revision = 0;
934 20 : r.out.domains = &domains;
935 20 : r.out.count = &count;
936 20 : r.out.names = &names;
937 :
938 20 : status = dcerpc_lsa_LookupSids3_r(b, tctx, &r);
939 20 : if (!NT_STATUS_IS_OK(status)) {
940 20 : if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
941 20 : torture_comment(tctx,
942 : "LookupSids3 correctly returned with "
943 : "status: %s\n",
944 : nt_errstr(status));
945 20 : return true;
946 : }
947 :
948 0 : torture_assert_ntstatus_equal(tctx,
949 : status,
950 : NT_STATUS_ACCESS_DENIED,
951 : "LookupSids3 return value should "
952 : "be ACCESS_DENIED");
953 0 : return true;
954 : }
955 :
956 0 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
957 0 : NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
958 0 : torture_comment(tctx,
959 : "LookupNames4 correctly returned with "
960 : "result: %s\n",
961 : nt_errstr(r.out.result));
962 0 : return true;
963 : }
964 :
965 0 : torture_fail(tctx,
966 : "LookupSids3 return value should be "
967 : "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
968 :
969 : return false;
970 : }
971 :
972 299 : bool test_many_LookupSids(struct dcerpc_pipe *p,
973 : struct torture_context *tctx,
974 : struct policy_handle *handle,
975 : enum lsa_LookupNamesLevel level)
976 : {
977 : uint32_t count;
978 : struct lsa_SidArray sids;
979 : int i;
980 299 : struct dcerpc_binding_handle *b = p->binding_handle;
981 299 : enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
982 :
983 299 : torture_comment(tctx, "\nTesting LookupSids with lots of SIDs\n");
984 :
985 299 : sids.num_sids = 100;
986 :
987 299 : sids.sids = talloc_array(tctx, struct lsa_SidPtr, sids.num_sids);
988 :
989 30199 : for (i=0; i<sids.num_sids; i++) {
990 29900 : const char *sidstr = "S-1-5-32-545";
991 29900 : sids.sids[i].sid = dom_sid_parse_talloc(tctx, sidstr);
992 : }
993 :
994 299 : count = sids.num_sids;
995 :
996 299 : if (handle) {
997 : struct lsa_LookupSids r;
998 : struct lsa_TransNameArray names;
999 16 : struct lsa_RefDomainList *domains = NULL;
1000 16 : names.count = 0;
1001 16 : names.names = NULL;
1002 :
1003 16 : r.in.handle = handle;
1004 16 : r.in.sids = &sids;
1005 16 : r.in.names = &names;
1006 16 : r.in.level = level;
1007 16 : r.in.count = &names.count;
1008 16 : r.out.count = &count;
1009 16 : r.out.names = &names;
1010 16 : r.out.domains = &domains;
1011 :
1012 16 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids_r(b, tctx, &r),
1013 : "LookupSids failed");
1014 16 : if (!NT_STATUS_IS_OK(r.out.result)) {
1015 0 : torture_comment(tctx, "LookupSids failed - %s\n",
1016 : nt_errstr(r.out.result));
1017 0 : return false;
1018 : }
1019 :
1020 16 : torture_comment(tctx, "\n");
1021 :
1022 16 : if (!test_LookupNames(b, tctx, handle, level, &names)) {
1023 0 : return false;
1024 : }
1025 : }
1026 :
1027 299 : if (transport == NCACN_NP) {
1028 13 : if (!test_LookupSids3_fail(b, tctx, level, &sids)) {
1029 0 : return false;
1030 : }
1031 13 : if (!test_LookupNames4_fail(b, tctx, level)) {
1032 0 : return false;
1033 : }
1034 286 : } else if (transport == NCACN_IP_TCP) {
1035 : struct lsa_TransNameArray2 names;
1036 : enum dcerpc_AuthType auth_type;
1037 : enum dcerpc_AuthLevel auth_level;
1038 :
1039 283 : names.count = 0;
1040 283 : names.names = NULL;
1041 :
1042 283 : dcerpc_binding_handle_auth_info(p->binding_handle,
1043 : &auth_type, &auth_level);
1044 :
1045 511 : if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL &&
1046 276 : auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) {
1047 276 : if (!test_LookupSids3(b, tctx, level, &sids)) {
1048 0 : return false;
1049 : }
1050 456 : if (!test_LookupNames4(b, tctx, level, &names, true)) {
1051 0 : return false;
1052 : }
1053 : } else {
1054 : /*
1055 : * If we don't have a secure channel these tests must
1056 : * fail with ACCESS_DENIED.
1057 : */
1058 7 : if (!test_LookupSids3_fail(b, tctx, level, &sids)) {
1059 0 : return false;
1060 : }
1061 7 : if (!test_LookupNames4_fail(b, tctx, level)) {
1062 0 : return false;
1063 : }
1064 : }
1065 : }
1066 :
1067 299 : torture_comment(tctx, "\n");
1068 :
1069 :
1070 :
1071 299 : return true;
1072 : }
1073 :
1074 800 : static void lookupsids_cb(struct tevent_req *subreq)
1075 : {
1076 800 : int *replies = (int *)tevent_req_callback_data_void(subreq);
1077 : NTSTATUS status;
1078 :
1079 800 : status = dcerpc_lsa_LookupSids_r_recv(subreq, subreq);
1080 800 : TALLOC_FREE(subreq);
1081 800 : if (!NT_STATUS_IS_OK(status)) {
1082 0 : printf("lookupsids returned %s\n", nt_errstr(status));
1083 0 : *replies = -1;
1084 : }
1085 :
1086 800 : if (*replies >= 0) {
1087 800 : *replies += 1;
1088 : }
1089 800 : }
1090 :
1091 16 : static bool test_LookupSids_async(struct dcerpc_binding_handle *b,
1092 : struct torture_context *tctx,
1093 : struct policy_handle *handle,
1094 : enum lsa_LookupNamesLevel level)
1095 : {
1096 : struct lsa_SidArray sids;
1097 : struct lsa_SidPtr sidptr;
1098 : uint32_t *count;
1099 : struct lsa_TransNameArray *names;
1100 : struct lsa_LookupSids *r;
1101 16 : struct lsa_RefDomainList *domains = NULL;
1102 : struct tevent_req **req;
1103 : int i, replies;
1104 16 : bool ret = true;
1105 16 : const int num_async_requests = 50;
1106 :
1107 16 : count = talloc_array(tctx, uint32_t, num_async_requests);
1108 16 : names = talloc_array(tctx, struct lsa_TransNameArray, num_async_requests);
1109 16 : r = talloc_array(tctx, struct lsa_LookupSids, num_async_requests);
1110 :
1111 16 : torture_comment(tctx, "\nTesting %d async lookupsids request\n", num_async_requests);
1112 :
1113 16 : req = talloc_array(tctx, struct tevent_req *, num_async_requests);
1114 :
1115 16 : sids.num_sids = 1;
1116 16 : sids.sids = &sidptr;
1117 16 : sidptr.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-545");
1118 :
1119 16 : replies = 0;
1120 :
1121 816 : for (i=0; i<num_async_requests; i++) {
1122 800 : count[i] = 0;
1123 800 : names[i].count = 0;
1124 800 : names[i].names = NULL;
1125 :
1126 800 : r[i].in.handle = handle;
1127 800 : r[i].in.sids = &sids;
1128 800 : r[i].in.names = &names[i];
1129 800 : r[i].in.level = level;
1130 800 : r[i].in.count = &names[i].count;
1131 800 : r[i].out.count = &count[i];
1132 800 : r[i].out.names = &names[i];
1133 800 : r[i].out.domains = &domains;
1134 :
1135 800 : req[i] = dcerpc_lsa_LookupSids_r_send(tctx, tctx->ev, b, &r[i]);
1136 800 : if (req[i] == NULL) {
1137 0 : ret = false;
1138 0 : break;
1139 : }
1140 :
1141 800 : tevent_req_set_callback(req[i], lookupsids_cb, &replies);
1142 : }
1143 :
1144 8797 : while (replies >= 0 && replies < num_async_requests) {
1145 8769 : tevent_loop_once(tctx->ev);
1146 : }
1147 :
1148 16 : talloc_free(req);
1149 :
1150 16 : if (replies < 0) {
1151 0 : ret = false;
1152 : }
1153 :
1154 16 : return ret;
1155 : }
1156 :
1157 143 : static bool test_LookupPrivValue(struct dcerpc_binding_handle *b,
1158 : struct torture_context *tctx,
1159 : struct policy_handle *handle,
1160 : struct lsa_String *name)
1161 : {
1162 : struct lsa_LookupPrivValue r;
1163 : struct lsa_LUID luid;
1164 :
1165 143 : r.in.handle = handle;
1166 143 : r.in.name = name;
1167 143 : r.out.luid = &luid;
1168 :
1169 143 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivValue_r(b, tctx, &r),
1170 : "LookupPrivValue failed");
1171 143 : torture_assert_ntstatus_ok(tctx, r.out.result,
1172 : "LookupPrivValue failed");
1173 :
1174 143 : return true;
1175 : }
1176 :
1177 210 : static bool test_LookupPrivName(struct dcerpc_binding_handle *b,
1178 : struct torture_context *tctx,
1179 : struct policy_handle *handle,
1180 : struct lsa_LUID *luid)
1181 : {
1182 : struct lsa_LookupPrivName r;
1183 210 : struct lsa_StringLarge *name = NULL;
1184 :
1185 210 : r.in.handle = handle;
1186 210 : r.in.luid = luid;
1187 210 : r.out.name = &name;
1188 :
1189 210 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivName_r(b, tctx, &r),
1190 : "LookupPrivName failed");
1191 210 : torture_assert_ntstatus_ok(tctx, r.out.result, "LookupPrivName failed");
1192 :
1193 210 : return true;
1194 : }
1195 :
1196 27 : static bool test_RemovePrivilegesFromAccount(struct dcerpc_binding_handle *b,
1197 : struct torture_context *tctx,
1198 : struct policy_handle *handle,
1199 : struct policy_handle *acct_handle,
1200 : struct lsa_LUID *luid)
1201 : {
1202 : struct lsa_RemovePrivilegesFromAccount r;
1203 : struct lsa_PrivilegeSet privs;
1204 27 : bool ret = true;
1205 :
1206 27 : torture_comment(tctx, "\nTesting RemovePrivilegesFromAccount\n");
1207 :
1208 27 : r.in.handle = acct_handle;
1209 27 : r.in.remove_all = 0;
1210 27 : r.in.privs = &privs;
1211 :
1212 27 : privs.count = 1;
1213 27 : privs.unknown = 0;
1214 27 : privs.set = talloc_array(tctx, struct lsa_LUIDAttribute, 1);
1215 27 : privs.set[0].luid = *luid;
1216 27 : privs.set[0].attribute = 0;
1217 :
1218 27 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_RemovePrivilegesFromAccount_r(b, tctx, &r),
1219 : "RemovePrivilegesFromAccount failed");
1220 27 : if (!NT_STATUS_IS_OK(r.out.result)) {
1221 :
1222 : struct lsa_LookupPrivName r_name;
1223 0 : struct lsa_StringLarge *name = NULL;
1224 :
1225 0 : r_name.in.handle = handle;
1226 0 : r_name.in.luid = luid;
1227 0 : r_name.out.name = &name;
1228 :
1229 0 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivName_r(b, tctx, &r_name),
1230 : "LookupPrivName failed");
1231 0 : if (!NT_STATUS_IS_OK(r_name.out.result)) {
1232 0 : torture_comment(tctx, "\nLookupPrivName failed - %s\n",
1233 : nt_errstr(r_name.out.result));
1234 0 : return false;
1235 : }
1236 : /* Windows 2008 does not allow this to be removed */
1237 0 : if (strcmp("SeAuditPrivilege", name->string) == 0) {
1238 0 : return ret;
1239 : }
1240 :
1241 0 : torture_comment(tctx, "RemovePrivilegesFromAccount failed to remove %s - %s\n",
1242 0 : name->string,
1243 : nt_errstr(r.out.result));
1244 0 : return false;
1245 : }
1246 :
1247 27 : return ret;
1248 : }
1249 :
1250 27 : static bool test_AddPrivilegesToAccount(struct dcerpc_binding_handle *b,
1251 : struct torture_context *tctx,
1252 : struct policy_handle *acct_handle,
1253 : struct lsa_LUID *luid)
1254 : {
1255 : struct lsa_AddPrivilegesToAccount r;
1256 : struct lsa_PrivilegeSet privs;
1257 27 : bool ret = true;
1258 :
1259 27 : torture_comment(tctx, "\nTesting AddPrivilegesToAccount\n");
1260 :
1261 27 : r.in.handle = acct_handle;
1262 27 : r.in.privs = &privs;
1263 :
1264 27 : privs.count = 1;
1265 27 : privs.unknown = 0;
1266 27 : privs.set = talloc_array(tctx, struct lsa_LUIDAttribute, 1);
1267 27 : privs.set[0].luid = *luid;
1268 27 : privs.set[0].attribute = 0;
1269 :
1270 27 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddPrivilegesToAccount_r(b, tctx, &r),
1271 : "AddPrivilegesToAccount failed");
1272 27 : torture_assert_ntstatus_ok(tctx, r.out.result,
1273 : "AddPrivilegesToAccount failed");
1274 27 : return ret;
1275 : }
1276 :
1277 42 : static bool test_EnumPrivsAccount(struct dcerpc_binding_handle *b,
1278 : struct torture_context *tctx,
1279 : struct policy_handle *handle,
1280 : struct policy_handle *acct_handle)
1281 : {
1282 : struct lsa_EnumPrivsAccount r;
1283 42 : struct lsa_PrivilegeSet *privs = NULL;
1284 42 : bool ret = true;
1285 :
1286 42 : torture_comment(tctx, "\nTesting EnumPrivsAccount\n");
1287 :
1288 42 : r.in.handle = acct_handle;
1289 42 : r.out.privs = &privs;
1290 :
1291 42 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumPrivsAccount_r(b, tctx, &r),
1292 : "EnumPrivsAccount failed");
1293 42 : torture_assert_ntstatus_ok(tctx, r.out.result,
1294 : "EnumPrivsAccount failed");
1295 :
1296 42 : if (privs && privs->count > 0) {
1297 : int i;
1298 237 : for (i=0;i<privs->count;i++) {
1299 210 : test_LookupPrivName(b, tctx, handle,
1300 210 : &privs->set[i].luid);
1301 : }
1302 :
1303 32 : ret &= test_RemovePrivilegesFromAccount(b, tctx, handle, acct_handle,
1304 27 : &privs->set[0].luid);
1305 27 : ret &= test_AddPrivilegesToAccount(b, tctx, acct_handle,
1306 27 : &privs->set[0].luid);
1307 : }
1308 :
1309 42 : return ret;
1310 : }
1311 :
1312 42 : static bool test_GetSystemAccessAccount(struct dcerpc_binding_handle *b,
1313 : struct torture_context *tctx,
1314 : struct policy_handle *handle,
1315 : struct policy_handle *acct_handle)
1316 : {
1317 : uint32_t access_mask;
1318 : struct lsa_GetSystemAccessAccount r;
1319 :
1320 42 : torture_comment(tctx, "\nTesting GetSystemAccessAccount\n");
1321 :
1322 42 : r.in.handle = acct_handle;
1323 42 : r.out.access_mask = &access_mask;
1324 :
1325 42 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(b, tctx, &r),
1326 : "GetSystemAccessAccount failed");
1327 42 : torture_assert_ntstatus_ok(tctx, r.out.result,
1328 : "GetSystemAccessAccount failed");
1329 :
1330 42 : if (r.out.access_mask != NULL) {
1331 42 : torture_comment(tctx, "Rights:");
1332 42 : if (*(r.out.access_mask) & LSA_POLICY_MODE_INTERACTIVE)
1333 37 : torture_comment(tctx, " LSA_POLICY_MODE_INTERACTIVE");
1334 42 : if (*(r.out.access_mask) & LSA_POLICY_MODE_NETWORK)
1335 17 : torture_comment(tctx, " LSA_POLICY_MODE_NETWORK");
1336 42 : if (*(r.out.access_mask) & LSA_POLICY_MODE_BATCH)
1337 0 : torture_comment(tctx, " LSA_POLICY_MODE_BATCH");
1338 42 : if (*(r.out.access_mask) & LSA_POLICY_MODE_SERVICE)
1339 0 : torture_comment(tctx, " LSA_POLICY_MODE_SERVICE");
1340 42 : if (*(r.out.access_mask) & LSA_POLICY_MODE_PROXY)
1341 0 : torture_comment(tctx, " LSA_POLICY_MODE_PROXY");
1342 42 : if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_INTERACTIVE)
1343 0 : torture_comment(tctx, " LSA_POLICY_MODE_DENY_INTERACTIVE");
1344 42 : if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_NETWORK)
1345 0 : torture_comment(tctx, " LSA_POLICY_MODE_DENY_NETWORK");
1346 42 : if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_BATCH)
1347 0 : torture_comment(tctx, " LSA_POLICY_MODE_DENY_BATCH");
1348 42 : if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_SERVICE)
1349 0 : torture_comment(tctx, " LSA_POLICY_MODE_DENY_SERVICE");
1350 42 : if (*(r.out.access_mask) & LSA_POLICY_MODE_REMOTE_INTERACTIVE)
1351 10 : torture_comment(tctx, " LSA_POLICY_MODE_REMOTE_INTERACTIVE");
1352 42 : if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE)
1353 0 : torture_comment(tctx, " LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE");
1354 42 : if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL)
1355 42 : torture_comment(tctx, " LSA_POLICY_MODE_ALL");
1356 42 : if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL_NT4)
1357 37 : torture_comment(tctx, " LSA_POLICY_MODE_ALL_NT4");
1358 42 : torture_comment(tctx, "\n");
1359 : }
1360 :
1361 42 : return true;
1362 : }
1363 :
1364 49 : static bool test_Delete(struct dcerpc_binding_handle *b,
1365 : struct torture_context *tctx,
1366 : struct policy_handle *handle)
1367 : {
1368 : struct lsa_Delete r;
1369 :
1370 49 : torture_comment(tctx, "\nTesting Delete\n");
1371 :
1372 49 : r.in.handle = handle;
1373 49 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Delete_r(b, tctx, &r),
1374 : "Delete failed");
1375 49 : torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_SUPPORTED,
1376 : "Delete should have failed NT_STATUS_NOT_SUPPORTED");
1377 :
1378 49 : return true;
1379 : }
1380 :
1381 33 : static bool test_DeleteObject(struct dcerpc_binding_handle *b,
1382 : struct torture_context *tctx,
1383 : struct policy_handle *handle)
1384 : {
1385 : struct lsa_DeleteObject r;
1386 :
1387 33 : torture_comment(tctx, "\nTesting DeleteObject\n");
1388 :
1389 33 : r.in.handle = handle;
1390 33 : r.out.handle = handle;
1391 33 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(b, tctx, &r),
1392 : "DeleteObject failed");
1393 33 : torture_assert_ntstatus_ok(tctx, r.out.result,
1394 : "DeleteObject failed");
1395 :
1396 33 : return true;
1397 : }
1398 :
1399 :
1400 7 : static bool test_CreateAccount(struct dcerpc_binding_handle *b,
1401 : struct torture_context *tctx,
1402 : struct policy_handle *handle)
1403 : {
1404 : struct lsa_CreateAccount r;
1405 : struct dom_sid2 *newsid;
1406 : struct policy_handle acct_handle;
1407 :
1408 7 : newsid = dom_sid_parse_talloc(tctx, "S-1-5-12349876-4321-2854");
1409 :
1410 7 : torture_comment(tctx, "\nTesting CreateAccount\n");
1411 :
1412 7 : r.in.handle = handle;
1413 7 : r.in.sid = newsid;
1414 7 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1415 7 : r.out.acct_handle = &acct_handle;
1416 :
1417 7 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateAccount_r(b, tctx, &r),
1418 : "CreateAccount failed");
1419 7 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_COLLISION)) {
1420 : struct lsa_OpenAccount r_o;
1421 0 : r_o.in.handle = handle;
1422 0 : r_o.in.sid = newsid;
1423 0 : r_o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1424 0 : r_o.out.acct_handle = &acct_handle;
1425 :
1426 0 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(b, tctx, &r_o),
1427 : "OpenAccount failed");
1428 0 : torture_assert_ntstatus_ok(tctx, r_o.out.result,
1429 : "OpenAccount failed");
1430 : } else {
1431 7 : torture_assert_ntstatus_ok(tctx, r.out.result,
1432 : "CreateAccount failed");
1433 : }
1434 :
1435 7 : if (!test_Delete(b, tctx, &acct_handle)) {
1436 0 : return false;
1437 : }
1438 :
1439 7 : if (!test_DeleteObject(b, tctx, &acct_handle)) {
1440 0 : return false;
1441 : }
1442 :
1443 7 : return true;
1444 : }
1445 :
1446 0 : static bool test_DeleteTrustedDomain(struct dcerpc_binding_handle *b,
1447 : struct torture_context *tctx,
1448 : struct policy_handle *handle,
1449 : struct lsa_StringLarge name)
1450 : {
1451 : struct lsa_OpenTrustedDomainByName r;
1452 : struct policy_handle trustdom_handle;
1453 :
1454 0 : r.in.handle = handle;
1455 0 : r.in.name.string = name.string;
1456 0 : r.in.access_mask = SEC_STD_DELETE;
1457 0 : r.out.trustdom_handle = &trustdom_handle;
1458 :
1459 0 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomainByName_r(b, tctx, &r),
1460 : "OpenTrustedDomainByName failed");
1461 0 : torture_assert_ntstatus_ok(tctx, r.out.result,
1462 : "OpenTrustedDomainByName failed");
1463 :
1464 0 : if (!test_Delete(b, tctx, &trustdom_handle)) {
1465 0 : return false;
1466 : }
1467 :
1468 0 : if (!test_DeleteObject(b, tctx, &trustdom_handle)) {
1469 0 : return false;
1470 : }
1471 :
1472 0 : return true;
1473 : }
1474 :
1475 108 : static bool test_DeleteTrustedDomainBySid(struct dcerpc_binding_handle *b,
1476 : struct torture_context *tctx,
1477 : struct policy_handle *handle,
1478 : struct dom_sid *sid)
1479 : {
1480 : struct lsa_DeleteTrustedDomain r;
1481 :
1482 108 : r.in.handle = handle;
1483 108 : r.in.dom_sid = sid;
1484 :
1485 108 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteTrustedDomain_r(b, tctx, &r),
1486 : "DeleteTrustedDomain failed");
1487 108 : torture_assert_ntstatus_ok(tctx, r.out.result,
1488 : "DeleteTrustedDomain failed");
1489 :
1490 108 : return true;
1491 : }
1492 :
1493 :
1494 16 : static bool test_CreateSecret(struct dcerpc_pipe *p,
1495 : struct torture_context *tctx,
1496 : struct policy_handle *handle)
1497 : {
1498 : struct lsa_CreateSecret r;
1499 : struct lsa_OpenSecret r2;
1500 : struct lsa_SetSecret r3;
1501 : struct lsa_QuerySecret r4;
1502 : struct lsa_SetSecret r5;
1503 : struct lsa_QuerySecret r6;
1504 : struct lsa_SetSecret r7;
1505 : struct lsa_QuerySecret r8;
1506 : struct policy_handle sec_handle, sec_handle2, sec_handle3;
1507 : struct lsa_DeleteObject d_o;
1508 : struct lsa_DATA_BUF buf1;
1509 : struct lsa_DATA_BUF_PTR bufp1;
1510 : struct lsa_DATA_BUF_PTR bufp2;
1511 : DATA_BLOB enc_key;
1512 16 : bool ret = true;
1513 : DATA_BLOB session_key;
1514 : NTTIME old_mtime, new_mtime;
1515 : DATA_BLOB blob1;
1516 16 : const char *secret1 = "abcdef12345699qwerty";
1517 : char *secret2;
1518 16 : const char *secret3 = "ABCDEF12345699QWERTY";
1519 : char *secret4;
1520 16 : const char *secret5 = "NEW-SAMBA4-SECRET";
1521 : char *secret6;
1522 : char *secname[2];
1523 : int i;
1524 16 : const int LOCAL = 0;
1525 16 : const int GLOBAL = 1;
1526 16 : struct dcerpc_binding_handle *b = p->binding_handle;
1527 :
1528 16 : secname[LOCAL] = talloc_asprintf(tctx, "torturesecret-%u", (unsigned int)random());
1529 16 : secname[GLOBAL] = talloc_asprintf(tctx, "G$torturesecret-%u", (unsigned int)random());
1530 :
1531 42 : for (i=0; i< 2; i++) {
1532 29 : torture_comment(tctx, "\nTesting CreateSecret of %s\n", secname[i]);
1533 :
1534 29 : init_lsa_String(&r.in.name, secname[i]);
1535 :
1536 29 : r.in.handle = handle;
1537 29 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1538 29 : r.out.sec_handle = &sec_handle;
1539 :
1540 29 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateSecret_r(b, tctx, &r),
1541 : "CreateSecret failed");
1542 29 : torture_assert_ntstatus_ok(tctx, r.out.result,
1543 : "CreateSecret failed");
1544 :
1545 29 : r.in.handle = handle;
1546 29 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1547 29 : r.out.sec_handle = &sec_handle3;
1548 :
1549 29 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateSecret_r(b, tctx, &r),
1550 : "CreateSecret failed");
1551 29 : torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_COLLISION,
1552 : "CreateSecret should have failed OBJECT_NAME_COLLISION");
1553 :
1554 29 : r2.in.handle = handle;
1555 29 : r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1556 29 : r2.in.name = r.in.name;
1557 29 : r2.out.sec_handle = &sec_handle2;
1558 :
1559 29 : torture_comment(tctx, "Testing OpenSecret\n");
1560 :
1561 29 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(b, tctx, &r2),
1562 : "OpenSecret failed");
1563 29 : torture_assert_ntstatus_ok(tctx, r2.out.result,
1564 : "OpenSecret failed");
1565 :
1566 29 : torture_assert_ntstatus_ok(tctx, dcerpc_fetch_session_key(p, &session_key),
1567 : "dcerpc_fetch_session_key failed");
1568 :
1569 26 : enc_key = sess_encrypt_string(secret1, &session_key);
1570 :
1571 26 : r3.in.sec_handle = &sec_handle;
1572 26 : r3.in.new_val = &buf1;
1573 26 : r3.in.old_val = NULL;
1574 26 : r3.in.new_val->data = enc_key.data;
1575 26 : r3.in.new_val->length = enc_key.length;
1576 26 : r3.in.new_val->size = enc_key.length;
1577 :
1578 26 : torture_comment(tctx, "Testing SetSecret\n");
1579 :
1580 26 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r3),
1581 : "SetSecret failed");
1582 26 : torture_assert_ntstatus_ok(tctx, r3.out.result,
1583 : "SetSecret failed");
1584 :
1585 26 : r3.in.sec_handle = &sec_handle;
1586 26 : r3.in.new_val = &buf1;
1587 26 : r3.in.old_val = NULL;
1588 26 : r3.in.new_val->data = enc_key.data;
1589 26 : r3.in.new_val->length = enc_key.length;
1590 26 : r3.in.new_val->size = enc_key.length;
1591 :
1592 : /* break the encrypted data */
1593 26 : enc_key.data[0]++;
1594 :
1595 26 : torture_comment(tctx, "Testing SetSecret with broken key\n");
1596 :
1597 26 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r3),
1598 : "SetSecret failed");
1599 26 : torture_assert_ntstatus_equal(tctx, r3.out.result, NT_STATUS_UNKNOWN_REVISION,
1600 : "SetSecret should have failed UNKNOWN_REVISION");
1601 :
1602 26 : data_blob_free(&enc_key);
1603 :
1604 26 : ZERO_STRUCT(new_mtime);
1605 26 : ZERO_STRUCT(old_mtime);
1606 :
1607 : /* fetch the secret back again */
1608 26 : r4.in.sec_handle = &sec_handle;
1609 26 : r4.in.new_val = &bufp1;
1610 26 : r4.in.new_mtime = &new_mtime;
1611 26 : r4.in.old_val = NULL;
1612 26 : r4.in.old_mtime = NULL;
1613 :
1614 26 : bufp1.buf = NULL;
1615 :
1616 26 : torture_comment(tctx, "Testing QuerySecret\n");
1617 26 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r4),
1618 : "QuerySecret failed");
1619 26 : if (!NT_STATUS_IS_OK(r4.out.result)) {
1620 0 : torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r4.out.result));
1621 0 : ret = false;
1622 : } else {
1623 26 : if (r4.out.new_val == NULL || r4.out.new_val->buf == NULL) {
1624 0 : torture_comment(tctx, "No secret buffer returned\n");
1625 0 : ret = false;
1626 : } else {
1627 26 : blob1.data = r4.out.new_val->buf->data;
1628 26 : blob1.length = r4.out.new_val->buf->size;
1629 :
1630 26 : secret2 = sess_decrypt_string(tctx,
1631 : &blob1, &session_key);
1632 :
1633 26 : if (strcmp(secret1, secret2) != 0) {
1634 0 : torture_comment(tctx, "Returned secret (r4) '%s' doesn't match '%s'\n",
1635 : secret2, secret1);
1636 0 : ret = false;
1637 : }
1638 : }
1639 : }
1640 :
1641 26 : enc_key = sess_encrypt_string(secret3, &session_key);
1642 :
1643 26 : r5.in.sec_handle = &sec_handle;
1644 26 : r5.in.new_val = &buf1;
1645 26 : r5.in.old_val = NULL;
1646 26 : r5.in.new_val->data = enc_key.data;
1647 26 : r5.in.new_val->length = enc_key.length;
1648 26 : r5.in.new_val->size = enc_key.length;
1649 :
1650 :
1651 26 : smb_msleep(200);
1652 26 : torture_comment(tctx, "Testing SetSecret (existing value should move to old)\n");
1653 :
1654 26 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r5),
1655 : "SetSecret failed");
1656 26 : if (!NT_STATUS_IS_OK(r5.out.result)) {
1657 0 : torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(r5.out.result));
1658 0 : ret = false;
1659 : }
1660 :
1661 26 : data_blob_free(&enc_key);
1662 :
1663 26 : ZERO_STRUCT(new_mtime);
1664 26 : ZERO_STRUCT(old_mtime);
1665 :
1666 : /* fetch the secret back again */
1667 26 : r6.in.sec_handle = &sec_handle;
1668 26 : r6.in.new_val = &bufp1;
1669 26 : r6.in.new_mtime = &new_mtime;
1670 26 : r6.in.old_val = &bufp2;
1671 26 : r6.in.old_mtime = &old_mtime;
1672 :
1673 26 : bufp1.buf = NULL;
1674 26 : bufp2.buf = NULL;
1675 :
1676 26 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r6),
1677 : "QuerySecret failed");
1678 26 : if (!NT_STATUS_IS_OK(r6.out.result)) {
1679 0 : torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r6.out.result));
1680 0 : ret = false;
1681 0 : secret4 = NULL;
1682 : } else {
1683 :
1684 26 : if (r6.out.new_val->buf == NULL || r6.out.old_val->buf == NULL
1685 26 : || r6.out.new_mtime == NULL || r6.out.old_mtime == NULL) {
1686 0 : torture_comment(tctx, "Both secret buffers and both times not returned\n");
1687 0 : ret = false;
1688 0 : secret4 = NULL;
1689 : } else {
1690 26 : blob1.data = r6.out.new_val->buf->data;
1691 26 : blob1.length = r6.out.new_val->buf->size;
1692 :
1693 26 : secret4 = sess_decrypt_string(tctx,
1694 : &blob1, &session_key);
1695 :
1696 26 : if (strcmp(secret3, secret4) != 0) {
1697 0 : torture_comment(tctx, "Returned NEW secret %s doesn't match %s\n", secret4, secret3);
1698 0 : ret = false;
1699 : }
1700 :
1701 26 : blob1.data = r6.out.old_val->buf->data;
1702 26 : blob1.length = r6.out.old_val->buf->length;
1703 :
1704 26 : secret2 = sess_decrypt_string(tctx,
1705 : &blob1, &session_key);
1706 :
1707 26 : if (strcmp(secret1, secret2) != 0) {
1708 0 : torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret2, secret1);
1709 0 : ret = false;
1710 : }
1711 :
1712 26 : if (*r6.out.new_mtime == *r6.out.old_mtime) {
1713 0 : torture_comment(tctx, "Returned secret (r6-%d) %s must not have same mtime for both secrets: %s != %s\n",
1714 : i,
1715 : secname[i],
1716 0 : nt_time_string(tctx, *r6.out.old_mtime),
1717 0 : nt_time_string(tctx, *r6.out.new_mtime));
1718 0 : ret = false;
1719 : }
1720 : }
1721 : }
1722 :
1723 26 : enc_key = sess_encrypt_string(secret5, &session_key);
1724 :
1725 26 : r7.in.sec_handle = &sec_handle;
1726 26 : r7.in.old_val = &buf1;
1727 26 : r7.in.old_val->data = enc_key.data;
1728 26 : r7.in.old_val->length = enc_key.length;
1729 26 : r7.in.old_val->size = enc_key.length;
1730 26 : r7.in.new_val = NULL;
1731 :
1732 26 : torture_comment(tctx, "Testing SetSecret of old Secret only\n");
1733 :
1734 26 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r7),
1735 : "SetSecret failed");
1736 26 : if (!NT_STATUS_IS_OK(r7.out.result)) {
1737 0 : torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(r7.out.result));
1738 0 : ret = false;
1739 : }
1740 :
1741 26 : data_blob_free(&enc_key);
1742 :
1743 : /* fetch the secret back again */
1744 26 : r8.in.sec_handle = &sec_handle;
1745 26 : r8.in.new_val = &bufp1;
1746 26 : r8.in.new_mtime = &new_mtime;
1747 26 : r8.in.old_val = &bufp2;
1748 26 : r8.in.old_mtime = &old_mtime;
1749 :
1750 26 : bufp1.buf = NULL;
1751 26 : bufp2.buf = NULL;
1752 :
1753 26 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r8),
1754 : "QuerySecret failed");
1755 26 : if (!NT_STATUS_IS_OK(r8.out.result)) {
1756 0 : torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r8.out.result));
1757 0 : ret = false;
1758 : } else {
1759 26 : if (!r8.out.new_val || !r8.out.old_val) {
1760 0 : torture_comment(tctx, "in/out pointers not returned, despite being set on in for QuerySecret\n");
1761 0 : ret = false;
1762 26 : } else if (r8.out.new_val->buf != NULL) {
1763 0 : torture_comment(tctx, "NEW secret buffer must not be returned after OLD set\n");
1764 0 : ret = false;
1765 26 : } else if (r8.out.old_val->buf == NULL) {
1766 0 : torture_comment(tctx, "OLD secret buffer was not returned after OLD set\n");
1767 0 : ret = false;
1768 26 : } else if (r8.out.new_mtime == NULL || r8.out.old_mtime == NULL) {
1769 0 : torture_comment(tctx, "Both times not returned after OLD set\n");
1770 0 : ret = false;
1771 : } else {
1772 26 : blob1.data = r8.out.old_val->buf->data;
1773 26 : blob1.length = r8.out.old_val->buf->size;
1774 :
1775 26 : secret6 = sess_decrypt_string(tctx,
1776 : &blob1, &session_key);
1777 :
1778 26 : if (strcmp(secret5, secret6) != 0) {
1779 0 : torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret5, secret6);
1780 0 : ret = false;
1781 : }
1782 :
1783 26 : if (*r8.out.new_mtime != *r8.out.old_mtime) {
1784 0 : torture_comment(tctx, "Returned secret (r8) %s did not had same mtime for both secrets: %s != %s\n",
1785 : secname[i],
1786 0 : nt_time_string(tctx, *r8.out.old_mtime),
1787 0 : nt_time_string(tctx, *r8.out.new_mtime));
1788 0 : ret = false;
1789 : }
1790 : }
1791 : }
1792 :
1793 26 : if (!test_Delete(b, tctx, &sec_handle)) {
1794 0 : ret = false;
1795 : }
1796 :
1797 26 : if (!test_DeleteObject(b, tctx, &sec_handle)) {
1798 0 : return false;
1799 : }
1800 :
1801 26 : d_o.in.handle = &sec_handle2;
1802 26 : d_o.out.handle = &sec_handle2;
1803 26 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(b, tctx, &d_o),
1804 : "DeleteObject failed");
1805 26 : torture_assert_ntstatus_equal(tctx, d_o.out.result, NT_STATUS_INVALID_HANDLE,
1806 : "OpenSecret expected INVALID_HANDLE");
1807 :
1808 26 : torture_comment(tctx, "Testing OpenSecret of just-deleted secret\n");
1809 :
1810 26 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(b, tctx, &r2),
1811 : "OpenSecret failed");
1812 26 : torture_assert_ntstatus_equal(tctx, r2.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
1813 : "OpenSecret expected OBJECT_NAME_NOT_FOUND");
1814 : }
1815 13 : return ret;
1816 : }
1817 :
1818 :
1819 42 : static bool test_EnumAccountRights(struct dcerpc_binding_handle *b,
1820 : struct torture_context *tctx,
1821 : struct policy_handle *acct_handle,
1822 : struct dom_sid *sid)
1823 : {
1824 : struct lsa_EnumAccountRights r;
1825 : struct lsa_RightSet rights;
1826 :
1827 42 : torture_comment(tctx, "\nTesting EnumAccountRights\n");
1828 :
1829 42 : r.in.handle = acct_handle;
1830 42 : r.in.sid = sid;
1831 42 : r.out.rights = &rights;
1832 :
1833 42 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(b, tctx, &r),
1834 : "EnumAccountRights failed");
1835 42 : if (!NT_STATUS_IS_OK(r.out.result)) {
1836 0 : torture_comment(tctx, "EnumAccountRights of %s failed - %s\n",
1837 : dom_sid_string(tctx, sid), nt_errstr(r.out.result));
1838 : }
1839 42 : torture_assert_ntstatus_ok(tctx, r.out.result,
1840 : "EnumAccountRights failed");
1841 :
1842 42 : return true;
1843 : }
1844 :
1845 :
1846 42 : static bool test_QuerySecurity(struct dcerpc_binding_handle *b,
1847 : struct torture_context *tctx,
1848 : struct policy_handle *handle,
1849 : struct policy_handle *acct_handle)
1850 : {
1851 : struct lsa_QuerySecurity r;
1852 42 : struct sec_desc_buf *sdbuf = NULL;
1853 :
1854 42 : if (torture_setting_bool(tctx, "samba4", false)) {
1855 18 : torture_comment(tctx, "\nskipping QuerySecurity test against Samba4\n");
1856 18 : return true;
1857 : }
1858 :
1859 24 : torture_comment(tctx, "\nTesting QuerySecurity\n");
1860 :
1861 24 : r.in.handle = acct_handle;
1862 24 : r.in.sec_info = SECINFO_OWNER |
1863 : SECINFO_GROUP |
1864 : SECINFO_DACL;
1865 24 : r.out.sdbuf = &sdbuf;
1866 :
1867 24 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecurity_r(b, tctx, &r),
1868 : "QuerySecurity failed");
1869 24 : if (!NT_STATUS_IS_OK(r.out.result)) {
1870 0 : torture_comment(tctx, "QuerySecurity failed - %s\n", nt_errstr(r.out.result));
1871 0 : return false;
1872 : }
1873 :
1874 24 : return true;
1875 : }
1876 :
1877 42 : static bool test_OpenAccount(struct dcerpc_binding_handle *b,
1878 : struct torture_context *tctx,
1879 : struct policy_handle *handle,
1880 : struct dom_sid *sid)
1881 : {
1882 : struct lsa_OpenAccount r;
1883 : struct policy_handle acct_handle;
1884 :
1885 42 : torture_comment(tctx, "\nTesting OpenAccount\n");
1886 :
1887 42 : r.in.handle = handle;
1888 42 : r.in.sid = sid;
1889 42 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1890 42 : r.out.acct_handle = &acct_handle;
1891 :
1892 42 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(b, tctx, &r),
1893 : "OpenAccount failed");
1894 42 : torture_assert_ntstatus_ok(tctx, r.out.result,
1895 : "OpenAccount failed");
1896 :
1897 42 : if (!test_EnumPrivsAccount(b, tctx, handle, &acct_handle)) {
1898 0 : return false;
1899 : }
1900 :
1901 42 : if (!test_GetSystemAccessAccount(b, tctx, handle, &acct_handle)) {
1902 0 : return false;
1903 : }
1904 :
1905 42 : if (!test_QuerySecurity(b, tctx, handle, &acct_handle)) {
1906 0 : return false;
1907 : }
1908 :
1909 42 : return true;
1910 : }
1911 :
1912 7 : static bool test_EnumAccounts(struct dcerpc_binding_handle *b,
1913 : struct torture_context *tctx,
1914 : struct policy_handle *handle)
1915 : {
1916 : struct lsa_EnumAccounts r;
1917 : struct lsa_SidArray sids1, sids2;
1918 7 : uint32_t resume_handle = 0;
1919 : int i;
1920 7 : bool ret = true;
1921 :
1922 7 : torture_comment(tctx, "\nTesting EnumAccounts\n");
1923 :
1924 7 : r.in.handle = handle;
1925 7 : r.in.resume_handle = &resume_handle;
1926 7 : r.in.num_entries = 100;
1927 7 : r.out.resume_handle = &resume_handle;
1928 7 : r.out.sids = &sids1;
1929 :
1930 7 : resume_handle = 0;
1931 : while (true) {
1932 20 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(b, tctx, &r),
1933 : "EnumAccounts failed");
1934 14 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
1935 7 : break;
1936 : }
1937 7 : torture_assert_ntstatus_ok(tctx, r.out.result,
1938 : "EnumAccounts failed");
1939 :
1940 7 : if (!test_LookupSids(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &sids1)) {
1941 0 : return false;
1942 : }
1943 :
1944 7 : if (!test_LookupSids2(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &sids1)) {
1945 0 : return false;
1946 : }
1947 :
1948 : /* Can't test lookupSids3 here, as clearly we must not
1949 : * be on schannel, or we would not be able to do the
1950 : * rest */
1951 :
1952 7 : torture_comment(tctx, "Testing all accounts\n");
1953 49 : for (i=0;i<sids1.num_sids;i++) {
1954 42 : ret &= test_OpenAccount(b, tctx, handle, sids1.sids[i].sid);
1955 42 : ret &= test_EnumAccountRights(b, tctx, handle, sids1.sids[i].sid);
1956 : }
1957 7 : torture_comment(tctx, "\n");
1958 : }
1959 :
1960 7 : if (sids1.num_sids < 3) {
1961 7 : return ret;
1962 : }
1963 :
1964 0 : torture_comment(tctx, "Trying EnumAccounts partial listing (asking for 1 at 2)\n");
1965 0 : resume_handle = 2;
1966 0 : r.in.num_entries = 1;
1967 0 : r.out.sids = &sids2;
1968 :
1969 0 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(b, tctx, &r),
1970 : "EnumAccounts failed");
1971 0 : torture_assert_ntstatus_ok(tctx, r.out.result,
1972 : "EnumAccounts failed");
1973 :
1974 0 : if (sids2.num_sids != 1) {
1975 0 : torture_comment(tctx, "Returned wrong number of entries (%d)\n", sids2.num_sids);
1976 0 : return false;
1977 : }
1978 :
1979 0 : return true;
1980 : }
1981 :
1982 143 : static bool test_LookupPrivDisplayName(struct dcerpc_binding_handle *b,
1983 : struct torture_context *tctx,
1984 : struct policy_handle *handle,
1985 : struct lsa_String *priv_name)
1986 : {
1987 : struct lsa_LookupPrivDisplayName r;
1988 : /* produce a reasonable range of language output without screwing up
1989 : terminals */
1990 143 : uint16_t language_id = (random() % 4) + 0x409;
1991 143 : uint16_t returned_language_id = 0;
1992 143 : struct lsa_StringLarge *disp_name = NULL;
1993 :
1994 143 : torture_comment(tctx, "\nTesting LookupPrivDisplayName(%s)\n", priv_name->string);
1995 :
1996 143 : r.in.handle = handle;
1997 143 : r.in.name = priv_name;
1998 143 : r.in.language_id = language_id;
1999 143 : r.in.language_id_sys = 0;
2000 143 : r.out.returned_language_id = &returned_language_id;
2001 143 : r.out.disp_name = &disp_name;
2002 :
2003 143 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivDisplayName_r(b, tctx, &r),
2004 : "LookupPrivDisplayName failed");
2005 143 : if (!NT_STATUS_IS_OK(r.out.result)) {
2006 0 : torture_comment(tctx, "LookupPrivDisplayName failed - %s\n", nt_errstr(r.out.result));
2007 0 : return false;
2008 : }
2009 379 : torture_comment(tctx, "%s -> \"%s\" (language 0x%x/0x%x)\n",
2010 143 : priv_name->string, disp_name->string,
2011 261 : r.in.language_id, *r.out.returned_language_id);
2012 :
2013 143 : return true;
2014 : }
2015 :
2016 143 : static bool test_EnumAccountsWithUserRight(struct dcerpc_binding_handle *b,
2017 : struct torture_context *tctx,
2018 : struct policy_handle *handle,
2019 : struct lsa_String *priv_name)
2020 : {
2021 : struct lsa_EnumAccountsWithUserRight r;
2022 : struct lsa_SidArray sids;
2023 :
2024 143 : ZERO_STRUCT(sids);
2025 :
2026 143 : torture_comment(tctx, "\nTesting EnumAccountsWithUserRight(%s)\n", priv_name->string);
2027 :
2028 143 : r.in.handle = handle;
2029 143 : r.in.name = priv_name;
2030 143 : r.out.sids = &sids;
2031 :
2032 143 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountsWithUserRight_r(b, tctx, &r),
2033 : "EnumAccountsWithUserRight failed");
2034 :
2035 : /* NT_STATUS_NO_MORE_ENTRIES means no one has this privilege */
2036 143 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2037 20 : return true;
2038 : }
2039 :
2040 123 : if (!NT_STATUS_IS_OK(r.out.result)) {
2041 0 : torture_comment(tctx, "EnumAccountsWithUserRight failed - %s\n", nt_errstr(r.out.result));
2042 0 : return false;
2043 : }
2044 :
2045 123 : return true;
2046 : }
2047 :
2048 :
2049 7 : static bool test_EnumPrivs(struct dcerpc_binding_handle *b,
2050 : struct torture_context *tctx,
2051 : struct policy_handle *handle)
2052 : {
2053 : struct lsa_EnumPrivs r;
2054 : struct lsa_PrivArray privs1;
2055 7 : uint32_t resume_handle = 0;
2056 : int i;
2057 7 : bool ret = true;
2058 :
2059 7 : torture_comment(tctx, "\nTesting EnumPrivs\n");
2060 :
2061 7 : r.in.handle = handle;
2062 7 : r.in.resume_handle = &resume_handle;
2063 7 : r.in.max_count = 100;
2064 7 : r.out.resume_handle = &resume_handle;
2065 7 : r.out.privs = &privs1;
2066 :
2067 7 : resume_handle = 0;
2068 7 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumPrivs_r(b, tctx, &r),
2069 : "EnumPrivs failed");
2070 7 : torture_assert_ntstatus_ok(tctx, r.out.result,
2071 : "EnumPrivs failed");
2072 :
2073 150 : for (i = 0; i< privs1.count; i++) {
2074 143 : test_LookupPrivDisplayName(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name);
2075 143 : test_LookupPrivValue(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name);
2076 143 : if (!test_EnumAccountsWithUserRight(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name)) {
2077 0 : ret = false;
2078 : }
2079 : }
2080 :
2081 7 : return ret;
2082 : }
2083 :
2084 0 : static bool test_QueryForestTrustInformation(struct dcerpc_binding_handle *b,
2085 : struct torture_context *tctx,
2086 : struct policy_handle *handle,
2087 : const char *trusted_domain_name)
2088 : {
2089 0 : bool ret = true;
2090 : struct lsa_lsaRQueryForestTrustInformation r;
2091 : struct lsa_String string;
2092 : struct lsa_ForestTrustInformation info, *info_ptr;
2093 :
2094 0 : torture_comment(tctx, "\nTesting lsaRQueryForestTrustInformation\n");
2095 :
2096 0 : if (torture_setting_bool(tctx, "samba4", false)) {
2097 0 : torture_comment(tctx, "skipping QueryForestTrustInformation against Samba4\n");
2098 0 : return true;
2099 : }
2100 :
2101 0 : ZERO_STRUCT(string);
2102 :
2103 0 : if (trusted_domain_name) {
2104 0 : init_lsa_String(&string, trusted_domain_name);
2105 : }
2106 :
2107 0 : info_ptr = &info;
2108 :
2109 0 : r.in.handle = handle;
2110 0 : r.in.trusted_domain_name = &string;
2111 0 : r.in.highest_record_type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
2112 0 : r.out.forest_trust_info = &info_ptr;
2113 :
2114 0 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_lsaRQueryForestTrustInformation_r(b, tctx, &r),
2115 : "lsaRQueryForestTrustInformation failed");
2116 :
2117 0 : if (!NT_STATUS_IS_OK(r.out.result)) {
2118 0 : torture_comment(tctx, "lsaRQueryForestTrustInformation of %s failed - %s\n", trusted_domain_name, nt_errstr(r.out.result));
2119 0 : ret = false;
2120 : }
2121 :
2122 0 : return ret;
2123 : }
2124 :
2125 27 : static bool test_query_each_TrustDomEx(struct dcerpc_binding_handle *b,
2126 : struct torture_context *tctx,
2127 : struct policy_handle *handle,
2128 : struct lsa_DomainListEx *domains)
2129 : {
2130 : int i;
2131 27 : bool ret = true;
2132 :
2133 135 : for (i=0; i< domains->count; i++) {
2134 :
2135 108 : if (domains->domains[i].trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2136 0 : ret &= test_QueryForestTrustInformation(b, tctx, handle,
2137 0 : domains->domains[i].domain_name.string);
2138 : }
2139 : }
2140 :
2141 27 : return ret;
2142 : }
2143 :
2144 27 : static bool test_query_each_TrustDom(struct dcerpc_binding_handle *b,
2145 : struct torture_context *tctx,
2146 : struct policy_handle *handle,
2147 : struct lsa_DomainList *domains)
2148 : {
2149 : int i,j;
2150 27 : bool ret = true;
2151 :
2152 27 : torture_comment(tctx, "\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
2153 135 : for (i=0; i< domains->count; i++) {
2154 : struct lsa_OpenTrustedDomain trust;
2155 : struct lsa_OpenTrustedDomainByName trust_by_name;
2156 : struct policy_handle trustdom_handle;
2157 : struct policy_handle handle2;
2158 : struct lsa_Close c;
2159 : struct lsa_CloseTrustedDomainEx c_trust;
2160 108 : int levels [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
2161 108 : int ok[] = {1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1};
2162 :
2163 108 : if (domains->domains[i].sid) {
2164 108 : trust.in.handle = handle;
2165 108 : trust.in.sid = domains->domains[i].sid;
2166 108 : trust.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2167 108 : trust.out.trustdom_handle = &trustdom_handle;
2168 :
2169 108 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomain_r(b, tctx, &trust),
2170 : "OpenTrustedDomain failed");
2171 :
2172 108 : if (NT_STATUS_EQUAL(trust.out.result, NT_STATUS_NO_SUCH_DOMAIN)) {
2173 0 : torture_comment(tctx, "DOMAIN(%s, %s) not a direct trust?\n",
2174 0 : domains->domains[i].name.string,
2175 0 : dom_sid_string(tctx, domains->domains[i].sid));
2176 0 : continue;
2177 : }
2178 108 : if (!NT_STATUS_IS_OK(trust.out.result)) {
2179 0 : torture_comment(tctx, "OpenTrustedDomain failed - %s\n", nt_errstr(trust.out.result));
2180 0 : return false;
2181 : }
2182 :
2183 108 : c.in.handle = &trustdom_handle;
2184 108 : c.out.handle = &handle2;
2185 :
2186 108 : c_trust.in.handle = &trustdom_handle;
2187 108 : c_trust.out.handle = &handle2;
2188 :
2189 1512 : for (j=0; j < ARRAY_SIZE(levels); j++) {
2190 : struct lsa_QueryTrustedDomainInfo q;
2191 1404 : union lsa_TrustedDomainInfo *info = NULL;
2192 1404 : q.in.trustdom_handle = &trustdom_handle;
2193 1404 : q.in.level = levels[j];
2194 1404 : q.out.info = &info;
2195 1404 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2196 : "QueryTrustedDomainInfo failed");
2197 1404 : if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2198 0 : torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
2199 : levels[j], nt_errstr(q.out.result));
2200 0 : ret = false;
2201 1404 : } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2202 0 : torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
2203 : levels[j], nt_errstr(q.out.result));
2204 0 : ret = false;
2205 : }
2206 : }
2207 :
2208 108 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CloseTrustedDomainEx_r(b, tctx, &c_trust),
2209 : "CloseTrustedDomainEx failed");
2210 108 : if (!NT_STATUS_EQUAL(c_trust.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2211 0 : torture_comment(tctx, "Expected CloseTrustedDomainEx to return NT_STATUS_NOT_IMPLEMENTED, instead - %s\n", nt_errstr(c_trust.out.result));
2212 0 : return false;
2213 : }
2214 :
2215 108 : c.in.handle = &trustdom_handle;
2216 108 : c.out.handle = &handle2;
2217 :
2218 108 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &c),
2219 : "Close failed");
2220 108 : if (!NT_STATUS_IS_OK(c.out.result)) {
2221 0 : torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(c.out.result));
2222 0 : return false;
2223 : }
2224 :
2225 1512 : for (j=0; j < ARRAY_SIZE(levels); j++) {
2226 : struct lsa_QueryTrustedDomainInfoBySid q;
2227 1404 : union lsa_TrustedDomainInfo *info = NULL;
2228 :
2229 1404 : if (!domains->domains[i].sid) {
2230 0 : continue;
2231 : }
2232 :
2233 1404 : q.in.handle = handle;
2234 1404 : q.in.dom_sid = domains->domains[i].sid;
2235 1404 : q.in.level = levels[j];
2236 1404 : q.out.info = &info;
2237 :
2238 1404 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfoBySid_r(b, tctx, &q),
2239 : "lsa_QueryTrustedDomainInfoBySid failed");
2240 1404 : if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2241 0 : torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d failed - %s\n",
2242 : levels[j], nt_errstr(q.out.result));
2243 0 : ret = false;
2244 1404 : } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2245 0 : torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d unexpectedly succeeded - %s\n",
2246 : levels[j], nt_errstr(q.out.result));
2247 0 : ret = false;
2248 : }
2249 : }
2250 : }
2251 :
2252 108 : trust_by_name.in.handle = handle;
2253 108 : trust_by_name.in.name.string = domains->domains[i].name.string;
2254 108 : trust_by_name.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2255 108 : trust_by_name.out.trustdom_handle = &trustdom_handle;
2256 :
2257 108 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomainByName_r(b, tctx, &trust_by_name),
2258 : "OpenTrustedDomainByName failed");
2259 :
2260 108 : if (NT_STATUS_EQUAL(trust_by_name.out.result, NT_STATUS_NO_SUCH_DOMAIN)) {
2261 0 : torture_comment(tctx, "DOMAIN(%s, %s) not a direct trust?\n",
2262 0 : domains->domains[i].name.string,
2263 0 : dom_sid_string(tctx, domains->domains[i].sid));
2264 0 : continue;
2265 : }
2266 108 : if (!NT_STATUS_IS_OK(trust_by_name.out.result)) {
2267 0 : torture_comment(tctx, "OpenTrustedDomainByName failed - %s\n", nt_errstr(trust_by_name.out.result));
2268 0 : return false;
2269 : }
2270 :
2271 1512 : for (j=0; j < ARRAY_SIZE(levels); j++) {
2272 : struct lsa_QueryTrustedDomainInfo q;
2273 1404 : union lsa_TrustedDomainInfo *info = NULL;
2274 1404 : q.in.trustdom_handle = &trustdom_handle;
2275 1404 : q.in.level = levels[j];
2276 1404 : q.out.info = &info;
2277 1404 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2278 : "QueryTrustedDomainInfo failed");
2279 1404 : if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2280 0 : torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
2281 : levels[j], nt_errstr(q.out.result));
2282 0 : ret = false;
2283 1404 : } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2284 0 : torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
2285 : levels[j], nt_errstr(q.out.result));
2286 0 : ret = false;
2287 : }
2288 : }
2289 :
2290 108 : c.in.handle = &trustdom_handle;
2291 108 : c.out.handle = &handle2;
2292 :
2293 108 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &c),
2294 : "Close failed");
2295 108 : if (!NT_STATUS_IS_OK(c.out.result)) {
2296 0 : torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(c.out.result));
2297 0 : return false;
2298 : }
2299 :
2300 1512 : for (j=0; j < ARRAY_SIZE(levels); j++) {
2301 : struct lsa_QueryTrustedDomainInfoByName q;
2302 1404 : union lsa_TrustedDomainInfo *info = NULL;
2303 : struct lsa_String name;
2304 :
2305 1404 : name.string = domains->domains[i].name.string;
2306 :
2307 1404 : q.in.handle = handle;
2308 1404 : q.in.trusted_domain = &name;
2309 1404 : q.in.level = levels[j];
2310 1404 : q.out.info = &info;
2311 1404 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfoByName_r(b, tctx, &q),
2312 : "QueryTrustedDomainInfoByName failed");
2313 1404 : if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2314 0 : torture_comment(tctx, "QueryTrustedDomainInfoByName level %d failed - %s\n",
2315 : levels[j], nt_errstr(q.out.result));
2316 0 : ret = false;
2317 1404 : } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2318 0 : torture_comment(tctx, "QueryTrustedDomainInfoByName level %d unexpectedly succeeded - %s\n",
2319 : levels[j], nt_errstr(q.out.result));
2320 0 : ret = false;
2321 : }
2322 : }
2323 : }
2324 27 : return ret;
2325 : }
2326 :
2327 12 : static bool test_EnumTrustDom(struct dcerpc_binding_handle *b,
2328 : struct torture_context *tctx,
2329 : struct policy_handle *handle)
2330 : {
2331 : struct lsa_EnumTrustDom r;
2332 12 : uint32_t in_resume_handle = 0;
2333 : uint32_t out_resume_handle;
2334 : struct lsa_DomainList domains;
2335 12 : bool ret = true;
2336 :
2337 12 : torture_comment(tctx, "\nTesting EnumTrustDom\n");
2338 :
2339 12 : r.in.handle = handle;
2340 12 : r.in.resume_handle = &in_resume_handle;
2341 12 : r.in.max_size = 0;
2342 12 : r.out.domains = &domains;
2343 12 : r.out.resume_handle = &out_resume_handle;
2344 :
2345 12 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b, tctx, &r),
2346 : "lsa_EnumTrustDom failed");
2347 :
2348 : /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2349 : * always be larger than the previous input resume handle, in
2350 : * particular when hitting the last query it is vital to set the
2351 : * resume handle correctly to avoid infinite client loops, as
2352 : * seen e.g. with Windows XP SP3 when resume handle is 0 and
2353 : * status is NT_STATUS_OK - gd */
2354 :
2355 24 : if (NT_STATUS_IS_OK(r.out.result) ||
2356 21 : NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
2357 9 : NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2358 : {
2359 12 : if (out_resume_handle <= in_resume_handle) {
2360 0 : torture_comment(tctx, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2361 : out_resume_handle, in_resume_handle);
2362 0 : return false;
2363 : }
2364 : }
2365 :
2366 12 : if (NT_STATUS_IS_OK(r.out.result)) {
2367 0 : if (domains.count == 0) {
2368 0 : torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2369 0 : return false;
2370 : }
2371 12 : } else if (!(NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES))) {
2372 0 : torture_comment(tctx, "EnumTrustDom of zero size failed - %s\n", nt_errstr(r.out.result));
2373 0 : return false;
2374 : }
2375 :
2376 : /* Start from the bottom again */
2377 12 : in_resume_handle = 0;
2378 :
2379 : do {
2380 30 : r.in.handle = handle;
2381 30 : r.in.resume_handle = &in_resume_handle;
2382 30 : r.in.max_size = LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3;
2383 30 : r.out.domains = &domains;
2384 30 : r.out.resume_handle = &out_resume_handle;
2385 :
2386 30 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b, tctx, &r),
2387 : "EnumTrustDom failed");
2388 :
2389 : /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2390 : * always be larger than the previous input resume handle, in
2391 : * particular when hitting the last query it is vital to set the
2392 : * resume handle correctly to avoid infinite client loops, as
2393 : * seen e.g. with Windows XP SP3 when resume handle is 0 and
2394 : * status is NT_STATUS_OK - gd */
2395 :
2396 51 : if (NT_STATUS_IS_OK(r.out.result) ||
2397 39 : NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
2398 18 : NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2399 : {
2400 30 : if (out_resume_handle <= in_resume_handle) {
2401 0 : torture_comment(tctx, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2402 : out_resume_handle, in_resume_handle);
2403 0 : return false;
2404 : }
2405 : }
2406 :
2407 : /* NO_MORE_ENTRIES is allowed */
2408 30 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2409 3 : if (domains.count == 0) {
2410 3 : return true;
2411 : }
2412 0 : torture_comment(tctx, "EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
2413 0 : return false;
2414 27 : } else if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
2415 : /* Windows 2003 gets this off by one on the first run */
2416 18 : if (r.out.domains->count < 3 || r.out.domains->count > 4) {
2417 0 : torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
2418 : "asked it to (got %d, expected %d / %d == %d entries)\n",
2419 0 : r.out.domains->count, LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3,
2420 : LSA_ENUM_TRUST_DOMAIN_MULTIPLIER, r.in.max_size);
2421 0 : ret = false;
2422 : }
2423 9 : } else if (!NT_STATUS_IS_OK(r.out.result)) {
2424 0 : torture_comment(tctx, "EnumTrustDom failed - %s\n", nt_errstr(r.out.result));
2425 0 : return false;
2426 : }
2427 :
2428 27 : if (domains.count == 0) {
2429 0 : torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2430 0 : return false;
2431 : }
2432 :
2433 27 : ret &= test_query_each_TrustDom(b, tctx, handle, &domains);
2434 :
2435 27 : in_resume_handle = out_resume_handle;
2436 :
2437 27 : } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2438 :
2439 9 : return ret;
2440 : }
2441 :
2442 12 : static bool test_EnumTrustDomEx(struct dcerpc_binding_handle *b,
2443 : struct torture_context *tctx,
2444 : struct policy_handle *handle)
2445 : {
2446 : struct lsa_EnumTrustedDomainsEx r_ex;
2447 12 : uint32_t in_resume_handle = 0;
2448 : uint32_t out_resume_handle;
2449 : struct lsa_DomainListEx domains_ex;
2450 12 : bool ret = true;
2451 :
2452 12 : torture_comment(tctx, "\nTesting EnumTrustedDomainsEx\n");
2453 :
2454 12 : r_ex.in.handle = handle;
2455 12 : r_ex.in.resume_handle = &in_resume_handle;
2456 12 : r_ex.in.max_size = 0;
2457 12 : r_ex.out.domains = &domains_ex;
2458 12 : r_ex.out.resume_handle = &out_resume_handle;
2459 :
2460 12 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustedDomainsEx_r(b, tctx, &r_ex),
2461 : "EnumTrustedDomainsEx failed");
2462 :
2463 : /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2464 : * always be larger than the previous input resume handle, in
2465 : * particular when hitting the last query it is vital to set the
2466 : * resume handle correctly to avoid infinite client loops, as
2467 : * seen e.g. with Windows XP SP3 when resume handle is 0 and
2468 : * status is NT_STATUS_OK - gd */
2469 :
2470 24 : if (NT_STATUS_IS_OK(r_ex.out.result) ||
2471 21 : NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
2472 9 : NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES))
2473 : {
2474 12 : if (out_resume_handle <= in_resume_handle) {
2475 0 : torture_comment(tctx, "EnumTrustDomEx failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2476 : out_resume_handle, in_resume_handle);
2477 0 : return false;
2478 : }
2479 : }
2480 :
2481 12 : if (NT_STATUS_IS_OK(r_ex.out.result)) {
2482 0 : if (domains_ex.count == 0) {
2483 0 : torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2484 0 : return false;
2485 : }
2486 15 : } else if (!(NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES) ||
2487 3 : NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES))) {
2488 0 : torture_comment(tctx, "EnumTrustDom of zero size failed - %s\n",
2489 : nt_errstr(r_ex.out.result));
2490 0 : return false;
2491 : }
2492 :
2493 12 : in_resume_handle = 0;
2494 : do {
2495 30 : r_ex.in.handle = handle;
2496 30 : r_ex.in.resume_handle = &in_resume_handle;
2497 30 : r_ex.in.max_size = LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER * 3;
2498 30 : r_ex.out.domains = &domains_ex;
2499 30 : r_ex.out.resume_handle = &out_resume_handle;
2500 :
2501 30 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustedDomainsEx_r(b, tctx, &r_ex),
2502 : "EnumTrustedDomainsEx failed");
2503 :
2504 30 : in_resume_handle = out_resume_handle;
2505 :
2506 : /* NO_MORE_ENTRIES is allowed */
2507 30 : if (NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2508 3 : if (domains_ex.count == 0) {
2509 3 : return true;
2510 : }
2511 0 : torture_comment(tctx, "EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
2512 0 : return false;
2513 27 : } else if (NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES)) {
2514 : /* Windows 2003 gets this off by one on the first run */
2515 18 : if (r_ex.out.domains->count < 3 || r_ex.out.domains->count > 4) {
2516 0 : torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
2517 : "asked it to (got %d, expected %d / %d == %d entries)\n",
2518 0 : r_ex.out.domains->count,
2519 : r_ex.in.max_size,
2520 : LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER,
2521 0 : r_ex.in.max_size / LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER);
2522 : }
2523 9 : } else if (!NT_STATUS_IS_OK(r_ex.out.result)) {
2524 0 : torture_comment(tctx, "EnumTrustedDomainEx failed - %s\n", nt_errstr(r_ex.out.result));
2525 0 : return false;
2526 : }
2527 :
2528 27 : if (domains_ex.count == 0) {
2529 0 : torture_comment(tctx, "EnumTrustDomainEx failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2530 0 : return false;
2531 : }
2532 :
2533 27 : ret &= test_query_each_TrustDomEx(b, tctx, handle, &domains_ex);
2534 :
2535 27 : } while (NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES));
2536 :
2537 9 : return ret;
2538 : }
2539 :
2540 :
2541 3 : static bool test_CreateTrustedDomain(struct dcerpc_binding_handle *b,
2542 : struct torture_context *tctx,
2543 : struct policy_handle *handle,
2544 : uint32_t num_trusts)
2545 : {
2546 3 : bool ret = true;
2547 : struct lsa_CreateTrustedDomain r;
2548 : struct lsa_DomainInfo trustinfo;
2549 : struct dom_sid **domsid;
2550 : struct policy_handle *trustdom_handle;
2551 : struct lsa_QueryTrustedDomainInfo q;
2552 3 : union lsa_TrustedDomainInfo *info = NULL;
2553 : int i;
2554 :
2555 3 : torture_comment(tctx, "\nTesting CreateTrustedDomain for %d domains\n", num_trusts);
2556 :
2557 3 : if (!test_EnumTrustDom(b, tctx, handle)) {
2558 0 : ret = false;
2559 : }
2560 :
2561 3 : if (!test_EnumTrustDomEx(b, tctx, handle)) {
2562 0 : ret = false;
2563 : }
2564 :
2565 3 : domsid = talloc_array(tctx, struct dom_sid *, num_trusts);
2566 3 : trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts);
2567 :
2568 39 : for (i=0; i< num_trusts; i++) {
2569 36 : char *trust_name = talloc_asprintf(tctx, "TORTURE1%02d", i);
2570 36 : char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-1%02d", i);
2571 :
2572 36 : domsid[i] = dom_sid_parse_talloc(tctx, trust_sid);
2573 :
2574 36 : trustinfo.sid = domsid[i];
2575 36 : init_lsa_String((struct lsa_String *)&trustinfo.name, trust_name);
2576 :
2577 36 : r.in.policy_handle = handle;
2578 36 : r.in.info = &trustinfo;
2579 36 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2580 36 : r.out.trustdom_handle = &trustdom_handle[i];
2581 :
2582 36 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateTrustedDomain_r(b, tctx, &r),
2583 : "CreateTrustedDomain failed");
2584 36 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_COLLISION)) {
2585 0 : test_DeleteTrustedDomain(b, tctx, handle, trustinfo.name);
2586 0 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateTrustedDomain_r(b, tctx, &r),
2587 : "CreateTrustedDomain failed");
2588 : }
2589 36 : if (!NT_STATUS_IS_OK(r.out.result)) {
2590 0 : torture_comment(tctx, "CreateTrustedDomain failed - %s\n", nt_errstr(r.out.result));
2591 0 : ret = false;
2592 : } else {
2593 :
2594 36 : q.in.trustdom_handle = &trustdom_handle[i];
2595 36 : q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
2596 36 : q.out.info = &info;
2597 36 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2598 : "QueryTrustedDomainInfo failed");
2599 36 : if (!NT_STATUS_IS_OK(q.out.result)) {
2600 0 : torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n", q.in.level, nt_errstr(q.out.result));
2601 0 : ret = false;
2602 36 : } else if (!q.out.info) {
2603 0 : ret = false;
2604 : } else {
2605 36 : if (strcmp(info->info_ex.domain_name.string, trustinfo.name.string) != 0) {
2606 0 : torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent long name: %s != %s\n",
2607 0 : info->info_ex.domain_name.string, trustinfo.name.string);
2608 0 : ret = false;
2609 : }
2610 36 : if (strcmp(info->info_ex.netbios_name.string, trustinfo.name.string) != 0) {
2611 0 : torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
2612 0 : info->info_ex.netbios_name.string, trustinfo.name.string);
2613 0 : ret = false;
2614 : }
2615 36 : if (info->info_ex.trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
2616 0 : torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
2617 0 : trust_name, info->info_ex.trust_type, LSA_TRUST_TYPE_DOWNLEVEL);
2618 0 : ret = false;
2619 : }
2620 36 : if (info->info_ex.trust_attributes != 0) {
2621 0 : torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
2622 0 : trust_name, info->info_ex.trust_attributes, 0);
2623 0 : ret = false;
2624 : }
2625 36 : if (info->info_ex.trust_direction != LSA_TRUST_DIRECTION_OUTBOUND) {
2626 0 : torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
2627 0 : trust_name, info->info_ex.trust_direction, LSA_TRUST_DIRECTION_OUTBOUND);
2628 0 : ret = false;
2629 : }
2630 : }
2631 : }
2632 : }
2633 :
2634 : /* now that we have some domains to look over, we can test the enum calls */
2635 3 : if (!test_EnumTrustDom(b, tctx, handle)) {
2636 0 : ret = false;
2637 : }
2638 :
2639 3 : if (!test_EnumTrustDomEx(b, tctx, handle)) {
2640 0 : ret = false;
2641 : }
2642 :
2643 39 : for (i=0; i<num_trusts; i++) {
2644 36 : if (!test_DeleteTrustedDomainBySid(b, tctx, handle, domsid[i])) {
2645 0 : ret = false;
2646 : }
2647 : }
2648 :
2649 3 : return ret;
2650 : }
2651 :
2652 72 : static bool gen_authinfo_internal(TALLOC_CTX *mem_ctx,
2653 : const char *incoming_old, const char *incoming_new,
2654 : const char *outgoing_old, const char *outgoing_new,
2655 : DATA_BLOB session_key,
2656 : struct lsa_TrustDomainInfoAuthInfoInternal **_authinfo_internal)
2657 : {
2658 : struct lsa_TrustDomainInfoAuthInfoInternal *authinfo_internal;
2659 : struct trustDomainPasswords auth_struct;
2660 : struct AuthenticationInformation in_info;
2661 : struct AuthenticationInformation io_info;
2662 : struct AuthenticationInformation on_info;
2663 : struct AuthenticationInformation oo_info;
2664 : size_t converted_size;
2665 : DATA_BLOB auth_blob;
2666 : enum ndr_err_code ndr_err;
2667 : bool ok;
2668 72 : gnutls_cipher_hd_t cipher_hnd = NULL;
2669 : gnutls_datum_t _session_key;
2670 :
2671 72 : authinfo_internal = talloc_zero(mem_ctx, struct lsa_TrustDomainInfoAuthInfoInternal);
2672 72 : if (authinfo_internal == NULL) {
2673 0 : return false;
2674 : }
2675 :
2676 72 : in_info.AuthType = TRUST_AUTH_TYPE_CLEAR;
2677 72 : ok = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16,
2678 : incoming_new,
2679 : strlen(incoming_new),
2680 : &in_info.AuthInfo.clear.password,
2681 : &converted_size);
2682 72 : if (!ok) {
2683 0 : return false;
2684 : }
2685 72 : in_info.AuthInfo.clear.size = converted_size;
2686 :
2687 72 : io_info.AuthType = TRUST_AUTH_TYPE_CLEAR;
2688 72 : ok = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16,
2689 : incoming_old,
2690 : strlen(incoming_old),
2691 : &io_info.AuthInfo.clear.password,
2692 : &converted_size);
2693 72 : if (!ok) {
2694 0 : return false;
2695 : }
2696 72 : io_info.AuthInfo.clear.size = converted_size;
2697 :
2698 72 : on_info.AuthType = TRUST_AUTH_TYPE_CLEAR;
2699 72 : ok = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16,
2700 : outgoing_new,
2701 : strlen(outgoing_new),
2702 : &on_info.AuthInfo.clear.password,
2703 : &converted_size);
2704 72 : if (!ok) {
2705 0 : return false;
2706 : }
2707 72 : on_info.AuthInfo.clear.size = converted_size;
2708 :
2709 72 : oo_info.AuthType = TRUST_AUTH_TYPE_CLEAR;
2710 72 : ok = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16,
2711 : outgoing_old,
2712 : strlen(outgoing_old),
2713 : &oo_info.AuthInfo.clear.password,
2714 : &converted_size);
2715 72 : if (!ok) {
2716 0 : return false;
2717 : }
2718 72 : oo_info.AuthInfo.clear.size = converted_size;
2719 :
2720 72 : generate_random_buffer(auth_struct.confounder, sizeof(auth_struct.confounder));
2721 72 : auth_struct.outgoing.count = 1;
2722 72 : auth_struct.outgoing.current.count = 1;
2723 72 : auth_struct.outgoing.current.array = &on_info;
2724 72 : auth_struct.outgoing.previous.count = 1;
2725 72 : auth_struct.outgoing.previous.array = &oo_info;
2726 :
2727 72 : auth_struct.incoming.count = 1;
2728 72 : auth_struct.incoming.current.count = 1;
2729 72 : auth_struct.incoming.current.array = &in_info;
2730 72 : auth_struct.incoming.previous.count = 1;
2731 72 : auth_struct.incoming.previous.array = &io_info;
2732 :
2733 72 : ndr_err = ndr_push_struct_blob(&auth_blob, mem_ctx, &auth_struct,
2734 : (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords);
2735 72 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2736 0 : return false;
2737 : }
2738 :
2739 72 : _session_key = (gnutls_datum_t) {
2740 72 : .data = session_key.data,
2741 72 : .size = session_key.length,
2742 : };
2743 :
2744 72 : gnutls_cipher_init(&cipher_hnd,
2745 : GNUTLS_CIPHER_ARCFOUR_128,
2746 : &_session_key,
2747 : NULL);
2748 144 : gnutls_cipher_encrypt(cipher_hnd,
2749 72 : auth_blob.data,
2750 : auth_blob.length);
2751 72 : gnutls_cipher_deinit(cipher_hnd);
2752 :
2753 72 : authinfo_internal->auth_blob.size = auth_blob.length;
2754 72 : authinfo_internal->auth_blob.data = auth_blob.data;
2755 :
2756 72 : *_authinfo_internal = authinfo_internal;
2757 :
2758 72 : return true;
2759 : }
2760 :
2761 72 : static bool gen_authinfo(TALLOC_CTX *mem_ctx,
2762 : const char *incoming_old, const char *incoming_new,
2763 : const char *outgoing_old, const char *outgoing_new,
2764 : struct lsa_TrustDomainInfoAuthInfo **_authinfo)
2765 : {
2766 : struct lsa_TrustDomainInfoAuthInfo *authinfo;
2767 : struct lsa_TrustDomainInfoBuffer *in_buffer;
2768 : struct lsa_TrustDomainInfoBuffer *io_buffer;
2769 : struct lsa_TrustDomainInfoBuffer *on_buffer;
2770 : struct lsa_TrustDomainInfoBuffer *oo_buffer;
2771 : size_t converted_size;
2772 : bool ok;
2773 :
2774 72 : authinfo = talloc_zero(mem_ctx, struct lsa_TrustDomainInfoAuthInfo);
2775 72 : if (authinfo == NULL) {
2776 0 : return false;
2777 : }
2778 :
2779 72 : in_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2780 72 : if (in_buffer == NULL) {
2781 0 : return false;
2782 : }
2783 72 : in_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2784 72 : ok = convert_string_talloc(in_buffer, CH_UNIX, CH_UTF16,
2785 : incoming_new,
2786 : strlen(incoming_new),
2787 72 : &in_buffer->data.data,
2788 : &converted_size);
2789 72 : if (!ok) {
2790 0 : return false;
2791 : }
2792 72 : in_buffer->data.size = converted_size;
2793 :
2794 72 : io_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2795 72 : if (io_buffer == NULL) {
2796 0 : return false;
2797 : }
2798 72 : io_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2799 72 : ok = convert_string_talloc(io_buffer, CH_UNIX, CH_UTF16,
2800 : incoming_old,
2801 : strlen(incoming_old),
2802 72 : &io_buffer->data.data,
2803 : &converted_size);
2804 72 : if (!ok) {
2805 0 : return false;
2806 : }
2807 72 : io_buffer->data.size = converted_size;
2808 :
2809 72 : on_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2810 72 : if (on_buffer == NULL) {
2811 0 : return false;
2812 : }
2813 72 : on_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2814 72 : ok = convert_string_talloc(on_buffer, CH_UNIX, CH_UTF16,
2815 : outgoing_new,
2816 : strlen(outgoing_new),
2817 72 : &on_buffer->data.data,
2818 : &converted_size);
2819 72 : if (!ok) {
2820 0 : return false;
2821 : }
2822 72 : on_buffer->data.size = converted_size;
2823 :
2824 72 : oo_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2825 72 : if (oo_buffer == NULL) {
2826 0 : return false;
2827 : }
2828 72 : oo_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2829 72 : ok = convert_string_talloc(oo_buffer, CH_UNIX, CH_UTF16,
2830 : outgoing_old,
2831 : strlen(outgoing_old),
2832 72 : &oo_buffer->data.data,
2833 : &converted_size);
2834 72 : if (!ok) {
2835 0 : return false;
2836 : }
2837 72 : oo_buffer->data.size = converted_size;
2838 :
2839 72 : authinfo->incoming_count = 1;
2840 72 : authinfo->incoming_current_auth_info = in_buffer;
2841 72 : authinfo->incoming_previous_auth_info = io_buffer;
2842 72 : authinfo->outgoing_count = 1;
2843 72 : authinfo->outgoing_current_auth_info = on_buffer;
2844 72 : authinfo->outgoing_previous_auth_info = oo_buffer;
2845 :
2846 72 : *_authinfo = authinfo;
2847 :
2848 72 : return true;
2849 : }
2850 :
2851 126 : static bool check_pw_with_ServerAuthenticate3(struct dcerpc_pipe *p,
2852 : struct torture_context *tctx,
2853 : uint32_t negotiate_flags,
2854 : const char *server_name,
2855 : struct cli_credentials *machine_credentials,
2856 : struct netlogon_creds_CredentialState **creds_out)
2857 : {
2858 : struct netr_ServerReqChallenge r;
2859 : struct netr_ServerAuthenticate3 a;
2860 : struct netr_Credential credentials1, credentials2, credentials3;
2861 : struct netlogon_creds_CredentialState *creds;
2862 126 : const struct samr_Password *new_password = NULL;
2863 126 : const struct samr_Password *old_password = NULL;
2864 : uint32_t rid;
2865 126 : struct dcerpc_binding_handle *b = p->binding_handle;
2866 :
2867 126 : new_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
2868 126 : old_password = cli_credentials_get_old_nt_hash(machine_credentials, tctx);
2869 :
2870 126 : r.in.server_name = server_name;
2871 126 : r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2872 126 : r.in.credentials = &credentials1;
2873 126 : r.out.return_credentials = &credentials2;
2874 :
2875 126 : netlogon_creds_random_challenge(&credentials1);
2876 :
2877 126 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2878 : "ServerReqChallenge failed");
2879 126 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
2880 :
2881 126 : a.in.server_name = server_name;
2882 126 : a.in.account_name = cli_credentials_get_username(machine_credentials);
2883 126 : a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2884 126 : a.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2885 126 : a.in.negotiate_flags = &negotiate_flags;
2886 126 : a.in.credentials = &credentials3;
2887 126 : a.out.return_credentials = &credentials3;
2888 126 : a.out.negotiate_flags = &negotiate_flags;
2889 126 : a.out.rid = &rid;
2890 :
2891 252 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2892 : a.in.computer_name,
2893 126 : a.in.secure_channel_type,
2894 : &credentials1, &credentials2,
2895 : new_password, &credentials3,
2896 : negotiate_flags);
2897 :
2898 126 : torture_assert(tctx, creds != NULL, "memory allocation");
2899 :
2900 126 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2901 : "ServerAuthenticate3 failed");
2902 126 : if (!NT_STATUS_IS_OK(a.out.result)) {
2903 18 : if (!NT_STATUS_EQUAL(a.out.result, NT_STATUS_ACCESS_DENIED)) {
2904 0 : torture_assert_ntstatus_ok(tctx, a.out.result,
2905 : "ServerAuthenticate3 failed");
2906 : }
2907 18 : return false;
2908 : }
2909 108 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2910 :
2911 108 : if (old_password != NULL) {
2912 108 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2913 : "ServerReqChallenge failed");
2914 108 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
2915 :
2916 216 : creds = netlogon_creds_client_init(tctx, a.in.account_name,
2917 : a.in.computer_name,
2918 108 : a.in.secure_channel_type,
2919 : &credentials1, &credentials2,
2920 : old_password, &credentials3,
2921 : negotiate_flags);
2922 :
2923 108 : torture_assert(tctx, creds != NULL, "memory allocation");
2924 :
2925 108 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2926 : "ServerAuthenticate3 failed");
2927 108 : if (!NT_STATUS_IS_OK(a.out.result)) {
2928 0 : if (!NT_STATUS_EQUAL(a.out.result, NT_STATUS_ACCESS_DENIED)) {
2929 0 : torture_assert_ntstatus_ok(tctx, a.out.result,
2930 : "ServerAuthenticate3 (old) failed");
2931 : }
2932 0 : return false;
2933 : }
2934 108 : torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential (old) chaining failed");
2935 : }
2936 :
2937 : /* Prove that requesting a challenge again won't break it */
2938 108 : torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2939 : "ServerReqChallenge failed");
2940 108 : torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
2941 :
2942 108 : *creds_out = creds;
2943 108 : return true;
2944 : }
2945 :
2946 : #ifdef SAMBA4_USES_HEIMDAL
2947 :
2948 : /*
2949 : * This function is set in torture_krb5_init_context as krb5
2950 : * send_and_recv function. This allows us to override what server the
2951 : * test is aimed at, and to inspect the packets just before they are
2952 : * sent to the network, and before they are processed on the recv
2953 : * side.
2954 : *
2955 : * The torture_krb5_pre_send_test() and torture_krb5_post_recv_test()
2956 : * functions are implement the actual tests.
2957 : *
2958 : * When this asserts, the caller will get a spurious 'cannot contact
2959 : * any KDC' message.
2960 : *
2961 : */
2962 : struct check_pw_with_krb5_ctx {
2963 : struct addrinfo *server;
2964 : struct {
2965 : unsigned io;
2966 : unsigned fail;
2967 : unsigned errors;
2968 : unsigned error_io;
2969 : unsigned ok;
2970 : } counts;
2971 : krb5_error error;
2972 : struct smb_krb5_context *smb_krb5_context;
2973 : krb5_get_init_creds_opt *krb_options;
2974 : krb5_creds my_creds;
2975 : krb5_get_creds_opt opt_canon;
2976 : krb5_get_creds_opt opt_nocanon;
2977 : krb5_principal upn_realm;
2978 : krb5_principal upn_dns;
2979 : krb5_principal upn_netbios;
2980 : krb5_ccache krbtgt_ccache;
2981 : krb5_principal krbtgt_trust_realm;
2982 : krb5_creds *krbtgt_trust_realm_creds;
2983 : krb5_principal krbtgt_trust_dns;
2984 : krb5_creds *krbtgt_trust_dns_creds;
2985 : krb5_principal krbtgt_trust_netbios;
2986 : krb5_creds *krbtgt_trust_netbios_creds;
2987 : krb5_principal cifs_trust_dns;
2988 : krb5_creds *cifs_trust_dns_creds;
2989 : krb5_principal cifs_trust_netbios;
2990 : krb5_creds *cifs_trust_netbios_creds;
2991 : krb5_principal drs_trust_dns;
2992 : krb5_creds *drs_trust_dns_creds;
2993 : krb5_principal drs_trust_netbios;
2994 : krb5_creds *drs_trust_netbios_creds;
2995 : krb5_principal four_trust_dns;
2996 : krb5_creds *four_trust_dns_creds;
2997 : krb5_creds krbtgt_referral_creds;
2998 : Ticket krbtgt_referral_ticket;
2999 : krb5_keyblock krbtgt_referral_keyblock;
3000 : EncTicketPart krbtgt_referral_enc_part;
3001 : };
3002 :
3003 1428 : static krb5_error_code check_pw_with_krb5_send_and_recv_func(krb5_context context,
3004 : void *data, /* struct check_pw_with_krb5_ctx */
3005 : krb5_krbhst_info *_hi,
3006 : time_t timeout,
3007 : const krb5_data *send_buf,
3008 : krb5_data *recv_buf)
3009 : {
3010 1428 : struct check_pw_with_krb5_ctx *ctx =
3011 : talloc_get_type_abort(data, struct check_pw_with_krb5_ctx);
3012 : krb5_error_code k5ret;
3013 1428 : krb5_krbhst_info hi = *_hi;
3014 : size_t used;
3015 : int ret;
3016 :
3017 1428 : hi.proto = KRB5_KRBHST_TCP;
3018 :
3019 1428 : krb5_free_error_contents(ctx->smb_krb5_context->krb5_context,
3020 : &ctx->error);
3021 1428 : ctx->counts.io++;
3022 :
3023 1428 : k5ret = smb_krb5_send_and_recv_func_forced(context, ctx->server,
3024 : &hi, timeout, send_buf, recv_buf);
3025 1428 : if (k5ret != 0) {
3026 0 : ctx->counts.fail++;
3027 0 : return k5ret;
3028 : }
3029 :
3030 1428 : ret = decode_KRB_ERROR(recv_buf->data, recv_buf->length,
3031 1428 : &ctx->error, &used);
3032 1428 : if (ret == 0) {
3033 564 : ctx->counts.errors++;
3034 564 : ctx->counts.error_io = ctx->counts.io;
3035 : } else {
3036 864 : ctx->counts.ok++;
3037 : }
3038 :
3039 1428 : return k5ret;
3040 : }
3041 :
3042 84 : static int check_pw_with_krb5_ctx_destructor(struct check_pw_with_krb5_ctx *ctx)
3043 : {
3044 84 : if (ctx->server != NULL) {
3045 84 : freeaddrinfo(ctx->server);
3046 84 : ctx->server = NULL;
3047 : }
3048 :
3049 84 : if (ctx->krb_options != NULL) {
3050 84 : krb5_get_init_creds_opt_free(ctx->smb_krb5_context->krb5_context,
3051 : ctx->krb_options);
3052 84 : ctx->krb_options = NULL;
3053 : }
3054 :
3055 84 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3056 : &ctx->my_creds);
3057 :
3058 84 : if (ctx->opt_canon != NULL) {
3059 72 : krb5_get_creds_opt_free(ctx->smb_krb5_context->krb5_context,
3060 : ctx->opt_canon);
3061 72 : ctx->opt_canon = NULL;
3062 : }
3063 :
3064 84 : if (ctx->opt_nocanon != NULL) {
3065 72 : krb5_get_creds_opt_free(ctx->smb_krb5_context->krb5_context,
3066 : ctx->opt_nocanon);
3067 72 : ctx->opt_nocanon = NULL;
3068 : }
3069 :
3070 84 : if (ctx->krbtgt_ccache != NULL) {
3071 72 : krb5_cc_close(ctx->smb_krb5_context->krb5_context,
3072 : ctx->krbtgt_ccache);
3073 72 : ctx->krbtgt_ccache = NULL;
3074 : }
3075 :
3076 84 : if (ctx->upn_realm != NULL) {
3077 84 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3078 : ctx->upn_realm);
3079 84 : ctx->upn_realm = NULL;
3080 : }
3081 :
3082 84 : if (ctx->upn_dns != NULL) {
3083 84 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3084 : ctx->upn_dns);
3085 84 : ctx->upn_dns = NULL;
3086 : }
3087 :
3088 84 : if (ctx->upn_netbios != NULL) {
3089 84 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3090 : ctx->upn_netbios);
3091 84 : ctx->upn_netbios = NULL;
3092 : }
3093 :
3094 84 : if (ctx->krbtgt_trust_realm != NULL) {
3095 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3096 : ctx->krbtgt_trust_realm);
3097 72 : ctx->krbtgt_trust_realm = NULL;
3098 : }
3099 :
3100 84 : if (ctx->krbtgt_trust_realm_creds != NULL) {
3101 72 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3102 : ctx->krbtgt_trust_realm_creds);
3103 72 : ctx->krbtgt_trust_realm_creds = NULL;
3104 : }
3105 :
3106 84 : if (ctx->krbtgt_trust_dns != NULL) {
3107 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3108 : ctx->krbtgt_trust_dns);
3109 72 : ctx->krbtgt_trust_dns = NULL;
3110 : }
3111 :
3112 84 : if (ctx->krbtgt_trust_dns_creds != NULL) {
3113 72 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3114 : ctx->krbtgt_trust_dns_creds);
3115 72 : ctx->krbtgt_trust_dns_creds = NULL;
3116 : }
3117 :
3118 84 : if (ctx->krbtgt_trust_netbios != NULL) {
3119 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3120 : ctx->krbtgt_trust_netbios);
3121 72 : ctx->krbtgt_trust_netbios = NULL;
3122 : }
3123 :
3124 84 : if (ctx->krbtgt_trust_netbios_creds != NULL) {
3125 72 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3126 : ctx->krbtgt_trust_netbios_creds);
3127 72 : ctx->krbtgt_trust_netbios_creds = NULL;
3128 : }
3129 :
3130 84 : if (ctx->cifs_trust_dns != NULL) {
3131 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3132 : ctx->cifs_trust_dns);
3133 72 : ctx->cifs_trust_dns = NULL;
3134 : }
3135 :
3136 84 : if (ctx->cifs_trust_dns_creds != NULL) {
3137 0 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3138 : ctx->cifs_trust_dns_creds);
3139 0 : ctx->cifs_trust_dns_creds = NULL;
3140 : }
3141 :
3142 84 : if (ctx->cifs_trust_netbios != NULL) {
3143 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3144 : ctx->cifs_trust_netbios);
3145 72 : ctx->cifs_trust_netbios = NULL;
3146 : }
3147 :
3148 84 : if (ctx->cifs_trust_netbios_creds != NULL) {
3149 0 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3150 : ctx->cifs_trust_netbios_creds);
3151 0 : ctx->cifs_trust_netbios_creds = NULL;
3152 : }
3153 :
3154 84 : if (ctx->drs_trust_dns != NULL) {
3155 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3156 : ctx->drs_trust_dns);
3157 72 : ctx->drs_trust_dns = NULL;
3158 : }
3159 :
3160 84 : if (ctx->drs_trust_dns_creds != NULL) {
3161 0 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3162 : ctx->drs_trust_dns_creds);
3163 0 : ctx->drs_trust_dns_creds = NULL;
3164 : }
3165 :
3166 84 : if (ctx->drs_trust_netbios != NULL) {
3167 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3168 : ctx->drs_trust_netbios);
3169 72 : ctx->drs_trust_netbios = NULL;
3170 : }
3171 :
3172 84 : if (ctx->drs_trust_netbios_creds != NULL) {
3173 0 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3174 : ctx->drs_trust_netbios_creds);
3175 0 : ctx->drs_trust_netbios_creds = NULL;
3176 : }
3177 :
3178 84 : if (ctx->four_trust_dns != NULL) {
3179 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3180 : ctx->four_trust_dns);
3181 72 : ctx->four_trust_dns = NULL;
3182 : }
3183 :
3184 84 : if (ctx->four_trust_dns_creds != NULL) {
3185 0 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3186 : ctx->four_trust_dns_creds);
3187 0 : ctx->four_trust_dns_creds = NULL;
3188 : }
3189 :
3190 84 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3191 : &ctx->krbtgt_referral_creds);
3192 :
3193 84 : free_Ticket(&ctx->krbtgt_referral_ticket);
3194 :
3195 84 : krb5_free_keyblock_contents(ctx->smb_krb5_context->krb5_context,
3196 : &ctx->krbtgt_referral_keyblock);
3197 :
3198 84 : free_EncTicketPart(&ctx->krbtgt_referral_enc_part);
3199 :
3200 84 : krb5_free_error_contents(ctx->smb_krb5_context->krb5_context,
3201 : &ctx->error);
3202 :
3203 84 : talloc_unlink(ctx, ctx->smb_krb5_context);
3204 84 : ctx->smb_krb5_context = NULL;
3205 84 : return 0;
3206 : }
3207 :
3208 84 : static bool check_pw_with_krb5(struct torture_context *tctx,
3209 : struct cli_credentials *credentials,
3210 : const struct lsa_TrustDomainInfoInfoEx *trusted)
3211 : {
3212 84 : const char *trusted_dns_name = trusted->domain_name.string;
3213 84 : const char *trusted_netbios_name = trusted->netbios_name.string;
3214 84 : char *trusted_realm_name = NULL;
3215 84 : krb5_principal principal = NULL;
3216 : enum credentials_obtained obtained;
3217 84 : const char *error_string = NULL;
3218 84 : const char *workstation = cli_credentials_get_workstation(credentials);
3219 84 : const char *password = cli_credentials_get_password(credentials);
3220 84 : const struct samr_Password *nthash = NULL;
3221 84 : const struct samr_Password *old_nthash = NULL;
3222 84 : const char *old_password = cli_credentials_get_old_password(credentials);
3223 84 : int kvno = cli_credentials_get_kvno(credentials);
3224 84 : int expected_kvno = 0;
3225 84 : krb5uint32 t_kvno = 0;
3226 84 : const char *host = torture_setting_string(tctx, "host", NULL);
3227 : krb5_error_code k5ret;
3228 : krb5_boolean k5ok;
3229 : int type;
3230 : bool ok;
3231 84 : struct check_pw_with_krb5_ctx *ctx = NULL;
3232 84 : char *assertion_message = NULL;
3233 84 : const char *realm = NULL;
3234 84 : char *upn_realm_string = NULL;
3235 84 : char *upn_dns_string = NULL;
3236 84 : char *upn_netbios_string = NULL;
3237 84 : char *krbtgt_cc_name = NULL;
3238 84 : char *krbtgt_trust_realm_string = NULL;
3239 84 : char *krbtgt_trust_dns_string = NULL;
3240 84 : char *krbtgt_trust_netbios_string = NULL;
3241 84 : char *cifs_trust_dns_string = NULL;
3242 84 : char *cifs_trust_netbios_string = NULL;
3243 84 : char *drs_trust_dns_string = NULL;
3244 84 : char *drs_trust_netbios_string = NULL;
3245 84 : char *four_trust_dns_string = NULL;
3246 :
3247 84 : ctx = talloc_zero(tctx, struct check_pw_with_krb5_ctx);
3248 84 : torture_assert(tctx, ctx != NULL, "Failed to allocate");
3249 :
3250 84 : realm = cli_credentials_get_realm(credentials);
3251 84 : trusted_realm_name = strupper_talloc(tctx, trusted_dns_name);
3252 :
3253 84 : nthash = cli_credentials_get_nt_hash(credentials, ctx);
3254 84 : old_nthash = cli_credentials_get_old_nt_hash(credentials, ctx);
3255 :
3256 84 : k5ret = smb_krb5_init_context(ctx, tctx->lp_ctx, &ctx->smb_krb5_context);
3257 84 : torture_assert_int_equal(tctx, k5ret, 0, "smb_krb5_init_context failed");
3258 :
3259 84 : ok = interpret_string_addr_internal(&ctx->server, host, 0);
3260 84 : torture_assert(tctx, ok, "Failed to parse target server");
3261 84 : talloc_set_destructor(ctx, check_pw_with_krb5_ctx_destructor);
3262 :
3263 84 : set_sockaddr_port(ctx->server->ai_addr, 88);
3264 :
3265 84 : k5ret = krb5_set_send_to_kdc_func(ctx->smb_krb5_context->krb5_context,
3266 : check_pw_with_krb5_send_and_recv_func,
3267 : ctx);
3268 84 : torture_assert_int_equal(tctx, k5ret, 0, "krb5_set_send_to_kdc_func failed");
3269 :
3270 84 : torture_assert_int_equal(tctx,
3271 : krb5_get_init_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3272 : &ctx->krb_options),
3273 : 0, "krb5_get_init_creds_opt_alloc failed");
3274 84 : torture_assert_int_equal(tctx,
3275 : krb5_get_init_creds_opt_set_pac_request(
3276 : ctx->smb_krb5_context->krb5_context,
3277 : ctx->krb_options, true),
3278 : 0, "krb5_get_init_creds_opt_set_pac_request failed");
3279 :
3280 84 : upn_realm_string = talloc_asprintf(ctx, "user@%s",
3281 : trusted_realm_name);
3282 84 : torture_assert_int_equal(tctx,
3283 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3284 : &ctx->upn_realm,
3285 : realm, upn_realm_string, NULL),
3286 : 0, "smb_krb5_make_principal failed");
3287 84 : smb_krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3288 : ctx->upn_realm, KRB5_NT_ENTERPRISE_PRINCIPAL);
3289 :
3290 84 : upn_dns_string = talloc_asprintf(ctx, "user@%s",
3291 : trusted_dns_name);
3292 84 : torture_assert_int_equal(tctx,
3293 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3294 : &ctx->upn_dns,
3295 : realm, upn_dns_string, NULL),
3296 : 0, "smb_krb5_make_principal failed");
3297 84 : smb_krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3298 : ctx->upn_dns, KRB5_NT_ENTERPRISE_PRINCIPAL);
3299 :
3300 84 : upn_netbios_string = talloc_asprintf(ctx, "user@%s",
3301 : trusted_netbios_name);
3302 84 : torture_assert_int_equal(tctx,
3303 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3304 : &ctx->upn_netbios,
3305 : realm, upn_netbios_string, NULL),
3306 : 0, "smb_krb5_make_principal failed");
3307 84 : smb_krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3308 : ctx->upn_netbios, KRB5_NT_ENTERPRISE_PRINCIPAL);
3309 :
3310 84 : k5ret = principal_from_credentials(ctx, credentials, ctx->smb_krb5_context,
3311 : &principal, &obtained, &error_string);
3312 84 : torture_assert_int_equal(tctx, k5ret, 0, error_string);
3313 :
3314 84 : ZERO_STRUCT(ctx->counts);
3315 84 : k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3316 : &ctx->my_creds, ctx->upn_realm,
3317 : "_none_", NULL, NULL, 0,
3318 : NULL, ctx->krb_options);
3319 252 : assertion_message = talloc_asprintf(ctx,
3320 : "krb5_get_init_creds_password(%s, canon) for failed: "
3321 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3322 : upn_realm_string,
3323 : k5ret,
3324 84 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3325 : k5ret, ctx),
3326 : trusted->trust_direction,
3327 84 : trusted->trust_type,
3328 : trusted->trust_attributes,
3329 : ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3330 84 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3331 84 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3332 84 : torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3333 84 : torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
3334 84 : torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3335 84 : torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3336 84 : torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3337 84 : torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3338 :
3339 84 : ZERO_STRUCT(ctx->counts);
3340 84 : k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3341 : &ctx->my_creds, ctx->upn_dns,
3342 : "_none_", NULL, NULL, 0,
3343 : NULL, ctx->krb_options);
3344 252 : assertion_message = talloc_asprintf(ctx,
3345 : "krb5_get_init_creds_password(%s, canon) for failed: "
3346 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3347 : upn_dns_string,
3348 : k5ret,
3349 84 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3350 : k5ret, ctx),
3351 : trusted->trust_direction,
3352 84 : trusted->trust_type,
3353 : trusted->trust_attributes,
3354 : ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3355 84 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3356 84 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3357 84 : torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3358 84 : torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
3359 84 : torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3360 84 : torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3361 84 : torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3362 84 : torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3363 :
3364 84 : ZERO_STRUCT(ctx->counts);
3365 84 : k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3366 : &ctx->my_creds, ctx->upn_netbios,
3367 : "_none_", NULL, NULL, 0,
3368 : NULL, ctx->krb_options);
3369 252 : assertion_message = talloc_asprintf(ctx,
3370 : "krb5_get_init_creds_password(%s, canon) for failed: "
3371 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3372 : upn_netbios_string,
3373 : k5ret,
3374 84 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3375 : k5ret, ctx),
3376 : trusted->trust_direction,
3377 84 : trusted->trust_type,
3378 : trusted->trust_attributes,
3379 : ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3380 84 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3381 84 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3382 84 : torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3383 84 : torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
3384 84 : torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3385 84 : torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3386 84 : torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3387 84 : torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3388 :
3389 84 : torture_comment(tctx, "(%s:%s) password[%s] old_password[%s]\n",
3390 : __location__, __FUNCTION__,
3391 : password, old_password);
3392 84 : if (old_password != NULL) {
3393 72 : k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3394 : &ctx->my_creds, principal,
3395 : old_password, NULL, NULL, 0,
3396 : NULL, ctx->krb_options);
3397 72 : torture_assert_int_equal(tctx, k5ret, KRB5KDC_ERR_PREAUTH_FAILED,
3398 : "preauth should fail with old password");
3399 : }
3400 :
3401 84 : k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3402 : &ctx->my_creds, principal,
3403 : password, NULL, NULL, 0,
3404 : NULL, ctx->krb_options);
3405 84 : if (k5ret == KRB5KDC_ERR_PREAUTH_FAILED) {
3406 12 : TALLOC_FREE(ctx);
3407 12 : return false;
3408 : }
3409 :
3410 72 : assertion_message = talloc_asprintf(ctx,
3411 : "krb5_get_init_creds_password for failed: %s",
3412 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3413 : k5ret, ctx));
3414 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3415 :
3416 72 : torture_assert_int_equal(tctx,
3417 : krb5_get_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3418 : &ctx->opt_canon),
3419 : 0, "krb5_get_creds_opt_alloc");
3420 :
3421 72 : krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3422 : ctx->opt_canon,
3423 : KRB5_GC_CANONICALIZE);
3424 :
3425 72 : krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3426 : ctx->opt_canon,
3427 : KRB5_GC_NO_STORE);
3428 :
3429 72 : torture_assert_int_equal(tctx,
3430 : krb5_get_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3431 : &ctx->opt_nocanon),
3432 : 0, "krb5_get_creds_opt_alloc");
3433 :
3434 72 : krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3435 : ctx->opt_nocanon,
3436 : KRB5_GC_NO_STORE);
3437 :
3438 72 : krbtgt_cc_name = talloc_asprintf(ctx, "MEMORY:%p.krbtgt", ctx->smb_krb5_context);
3439 72 : torture_assert_int_equal(tctx,
3440 : krb5_cc_resolve(ctx->smb_krb5_context->krb5_context,
3441 : krbtgt_cc_name,
3442 : &ctx->krbtgt_ccache),
3443 : 0, "krb5_cc_resolve failed");
3444 :
3445 72 : torture_assert_int_equal(tctx,
3446 : krb5_cc_initialize(ctx->smb_krb5_context->krb5_context,
3447 : ctx->krbtgt_ccache,
3448 : ctx->my_creds.client),
3449 : 0, "krb5_cc_initialize failed");
3450 :
3451 72 : torture_assert_int_equal(tctx,
3452 : krb5_cc_store_cred(ctx->smb_krb5_context->krb5_context,
3453 : ctx->krbtgt_ccache,
3454 : &ctx->my_creds),
3455 : 0, "krb5_cc_store_cred failed");
3456 :
3457 72 : krbtgt_trust_realm_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3458 : trusted_realm_name, realm);
3459 72 : torture_assert_int_equal(tctx,
3460 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3461 : &ctx->krbtgt_trust_realm,
3462 : realm, "krbtgt",
3463 : trusted_realm_name, NULL),
3464 : 0, "smb_krb5_make_principal failed");
3465 :
3466 72 : krbtgt_trust_dns_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3467 : trusted_dns_name, realm);
3468 72 : torture_assert_int_equal(tctx,
3469 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3470 : &ctx->krbtgt_trust_dns,
3471 : realm, "krbtgt",
3472 : trusted_dns_name, NULL),
3473 : 0, "smb_krb5_make_principal failed");
3474 :
3475 72 : krbtgt_trust_netbios_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3476 : trusted_netbios_name, realm);
3477 72 : torture_assert_int_equal(tctx,
3478 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3479 : &ctx->krbtgt_trust_netbios,
3480 : realm, "krbtgt",
3481 : trusted_netbios_name, NULL),
3482 : 0, "smb_krb5_make_principal failed");
3483 :
3484 : /* Confirm if we can do a TGS for krbtgt/trusted_realm */
3485 72 : ZERO_STRUCT(ctx->counts);
3486 144 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3487 : ctx->opt_nocanon,
3488 : ctx->krbtgt_ccache,
3489 72 : ctx->krbtgt_trust_realm,
3490 : &ctx->krbtgt_trust_realm_creds);
3491 216 : assertion_message = talloc_asprintf(ctx,
3492 : "krb5_get_creds(%s, canon) for failed: "
3493 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3494 : krbtgt_trust_realm_string,
3495 : k5ret,
3496 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3497 : k5ret, ctx),
3498 : trusted->trust_direction,
3499 72 : trusted->trust_type,
3500 : trusted->trust_attributes,
3501 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3502 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3503 72 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3504 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3505 :
3506 72 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3507 72 : ctx->krbtgt_trust_realm_creds->server,
3508 72 : ctx->krbtgt_trust_realm);
3509 72 : torture_assert(tctx, k5ok, assertion_message);
3510 72 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3511 72 : ctx->krbtgt_trust_realm_creds->server);
3512 72 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3513 :
3514 : /* Confirm if we have no referral ticket in the cache */
3515 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3516 : &ctx->krbtgt_referral_creds);
3517 144 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3518 : ctx->krbtgt_ccache,
3519 : 0,
3520 72 : ctx->krbtgt_trust_realm_creds,
3521 : &ctx->krbtgt_referral_creds);
3522 72 : assertion_message = talloc_asprintf(ctx,
3523 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3524 : krbtgt_trust_realm_string,
3525 : k5ret,
3526 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3527 : k5ret, ctx));
3528 72 : torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3529 :
3530 : /* Confirm if we can do a TGS for krbtgt/trusted_dns with CANON */
3531 72 : ZERO_STRUCT(ctx->counts);
3532 144 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3533 : ctx->opt_canon,
3534 : ctx->krbtgt_ccache,
3535 72 : ctx->krbtgt_trust_dns,
3536 : &ctx->krbtgt_trust_dns_creds);
3537 216 : assertion_message = talloc_asprintf(ctx,
3538 : "krb5_get_creds(%s, canon) for failed: "
3539 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3540 : krbtgt_trust_dns_string,
3541 : k5ret,
3542 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3543 : k5ret, ctx),
3544 : trusted->trust_direction,
3545 72 : trusted->trust_type,
3546 : trusted->trust_attributes,
3547 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3548 72 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3549 72 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3550 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3551 :
3552 : /* Confirm if we have the referral ticket in the cache */
3553 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3554 : &ctx->krbtgt_referral_creds);
3555 144 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3556 : ctx->krbtgt_ccache,
3557 : 0,
3558 72 : ctx->krbtgt_trust_realm_creds,
3559 : &ctx->krbtgt_referral_creds);
3560 72 : assertion_message = talloc_asprintf(ctx,
3561 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3562 : krbtgt_trust_realm_string,
3563 : k5ret,
3564 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3565 : k5ret, ctx));
3566 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3567 :
3568 72 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3569 72 : ctx->krbtgt_referral_creds.server,
3570 72 : ctx->krbtgt_trust_realm);
3571 72 : torture_assert(tctx, k5ok, assertion_message);
3572 72 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3573 72 : ctx->krbtgt_referral_creds.server);
3574 72 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3575 72 : k5ret = decode_Ticket(ctx->krbtgt_referral_creds.ticket.data,
3576 : ctx->krbtgt_referral_creds.ticket.length,
3577 : &ctx->krbtgt_referral_ticket, NULL);
3578 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3579 72 : if (kvno > 0) {
3580 60 : expected_kvno = kvno - 1;
3581 : }
3582 72 : if (ctx->krbtgt_referral_ticket.enc_part.kvno != NULL) {
3583 36 : t_kvno = *ctx->krbtgt_referral_ticket.enc_part.kvno;
3584 36 : assertion_message = talloc_asprintf(ctx,
3585 : "krbtgt_referral_ticket(%s) kvno(%u) expected(%u) current(%u)",
3586 : krbtgt_trust_realm_string,
3587 : (unsigned)t_kvno, (unsigned)expected_kvno,(unsigned)kvno);
3588 36 : torture_comment(tctx, "%s\n", assertion_message);
3589 36 : torture_assert_int_not_equal(tctx, t_kvno, 0, assertion_message);
3590 : } else {
3591 36 : assertion_message = talloc_asprintf(ctx,
3592 : "krbtgt_referral_ticket(%s) kvno(NULL) exptected(%u) current(%u)",
3593 : krbtgt_trust_realm_string,
3594 : (unsigned)expected_kvno,(unsigned)kvno);
3595 36 : torture_comment(tctx, "%s\n", assertion_message);
3596 : }
3597 72 : torture_assert_int_equal(tctx, t_kvno, expected_kvno, assertion_message);
3598 :
3599 72 : if (old_nthash != NULL && expected_kvno != kvno) {
3600 60 : torture_comment(tctx, "old_nthash: %s\n", assertion_message);
3601 120 : k5ret = smb_krb5_keyblock_init_contents(ctx->smb_krb5_context->krb5_context,
3602 : ENCTYPE_ARCFOUR_HMAC,
3603 60 : old_nthash->hash,
3604 : sizeof(old_nthash->hash),
3605 : &ctx->krbtgt_referral_keyblock);
3606 60 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3607 : } else {
3608 12 : torture_comment(tctx, "nthash: %s\n", assertion_message);
3609 24 : k5ret = smb_krb5_keyblock_init_contents(ctx->smb_krb5_context->krb5_context,
3610 : ENCTYPE_ARCFOUR_HMAC,
3611 12 : nthash->hash,
3612 : sizeof(nthash->hash),
3613 : &ctx->krbtgt_referral_keyblock);
3614 12 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3615 : }
3616 72 : k5ret = krb5_decrypt_ticket(ctx->smb_krb5_context->krb5_context,
3617 : &ctx->krbtgt_referral_ticket,
3618 : &ctx->krbtgt_referral_keyblock,
3619 : &ctx->krbtgt_referral_enc_part,
3620 : 0);
3621 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3622 :
3623 : /* Delete the referral ticket from the cache */
3624 72 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3625 : ctx->krbtgt_ccache,
3626 : 0,
3627 : &ctx->krbtgt_referral_creds);
3628 72 : assertion_message = talloc_asprintf(ctx,
3629 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3630 : krbtgt_trust_realm_string,
3631 : k5ret,
3632 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3633 : k5ret, ctx));
3634 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3635 :
3636 : /* Confirm if we can do a TGS for krbtgt/trusted_dns no CANON */
3637 72 : ZERO_STRUCT(ctx->counts);
3638 144 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3639 : ctx->opt_nocanon,
3640 : ctx->krbtgt_ccache,
3641 72 : ctx->krbtgt_trust_dns,
3642 : &ctx->krbtgt_trust_dns_creds);
3643 216 : assertion_message = talloc_asprintf(ctx,
3644 : "krb5_get_creds(%s, nocanon) for failed: "
3645 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3646 : krbtgt_trust_dns_string,
3647 : k5ret,
3648 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3649 : k5ret, ctx),
3650 : trusted->trust_direction,
3651 72 : trusted->trust_type,
3652 : trusted->trust_attributes,
3653 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3654 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3655 72 : torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
3656 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
3657 :
3658 72 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3659 72 : ctx->krbtgt_trust_dns_creds->server,
3660 72 : ctx->krbtgt_trust_realm);
3661 72 : torture_assert(tctx, k5ok, assertion_message);
3662 72 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3663 72 : ctx->krbtgt_trust_dns_creds->server);
3664 72 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3665 :
3666 : /* Confirm if we have the referral ticket in the cache */
3667 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3668 : &ctx->krbtgt_referral_creds);
3669 144 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3670 : ctx->krbtgt_ccache,
3671 : 0,
3672 72 : ctx->krbtgt_trust_realm_creds,
3673 : &ctx->krbtgt_referral_creds);
3674 72 : assertion_message = talloc_asprintf(ctx,
3675 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3676 : krbtgt_trust_realm_string,
3677 : k5ret,
3678 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3679 : k5ret, ctx));
3680 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3681 :
3682 72 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3683 72 : ctx->krbtgt_referral_creds.server,
3684 72 : ctx->krbtgt_trust_realm);
3685 72 : torture_assert(tctx, k5ok, assertion_message);
3686 72 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3687 72 : ctx->krbtgt_referral_creds.server);
3688 72 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3689 :
3690 : /* Delete the referral ticket from the cache */
3691 72 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3692 : ctx->krbtgt_ccache,
3693 : 0,
3694 : &ctx->krbtgt_referral_creds);
3695 72 : assertion_message = talloc_asprintf(ctx,
3696 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3697 : krbtgt_trust_realm_string,
3698 : k5ret,
3699 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3700 : k5ret, ctx));
3701 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3702 :
3703 : /* Confirm if we can do a TGS for krbtgt/NETBIOS with CANON */
3704 72 : ZERO_STRUCT(ctx->counts);
3705 144 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3706 : ctx->opt_canon,
3707 : ctx->krbtgt_ccache,
3708 72 : ctx->krbtgt_trust_netbios,
3709 : &ctx->krbtgt_trust_netbios_creds);
3710 216 : assertion_message = talloc_asprintf(ctx,
3711 : "krb5_get_creds(%s, canon) for failed: "
3712 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3713 : krbtgt_trust_netbios_string,
3714 : k5ret,
3715 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3716 : k5ret, ctx),
3717 : trusted->trust_direction,
3718 72 : trusted->trust_type,
3719 : trusted->trust_attributes,
3720 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3721 72 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3722 72 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3723 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3724 :
3725 : /* Confirm if we have the referral ticket in the cache */
3726 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3727 : &ctx->krbtgt_referral_creds);
3728 144 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3729 : ctx->krbtgt_ccache,
3730 : 0,
3731 72 : ctx->krbtgt_trust_realm_creds,
3732 : &ctx->krbtgt_referral_creds);
3733 72 : assertion_message = talloc_asprintf(ctx,
3734 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3735 : krbtgt_trust_netbios_string,
3736 : k5ret,
3737 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3738 : k5ret, ctx));
3739 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3740 :
3741 72 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3742 72 : ctx->krbtgt_referral_creds.server,
3743 72 : ctx->krbtgt_trust_realm);
3744 72 : torture_assert(tctx, k5ok, assertion_message);
3745 72 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3746 72 : ctx->krbtgt_referral_creds.server);
3747 72 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3748 :
3749 : /* Delete the referral ticket from the cache */
3750 72 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3751 : ctx->krbtgt_ccache,
3752 : 0,
3753 : &ctx->krbtgt_referral_creds);
3754 72 : assertion_message = talloc_asprintf(ctx,
3755 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3756 : krbtgt_trust_realm_string,
3757 : k5ret,
3758 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3759 : k5ret, ctx));
3760 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3761 :
3762 : /* Confirm if we can do a TGS for krbtgt/NETBIOS no CANON */
3763 72 : ZERO_STRUCT(ctx->counts);
3764 144 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3765 : ctx->opt_nocanon,
3766 : ctx->krbtgt_ccache,
3767 72 : ctx->krbtgt_trust_netbios,
3768 : &ctx->krbtgt_trust_netbios_creds);
3769 216 : assertion_message = talloc_asprintf(ctx,
3770 : "krb5_get_creds(%s, nocanon) for failed: "
3771 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3772 : krbtgt_trust_netbios_string,
3773 : k5ret,
3774 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3775 : k5ret, ctx),
3776 : trusted->trust_direction,
3777 72 : trusted->trust_type,
3778 : trusted->trust_attributes,
3779 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3780 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3781 72 : torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
3782 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
3783 :
3784 72 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3785 72 : ctx->krbtgt_trust_netbios_creds->server,
3786 72 : ctx->krbtgt_trust_realm);
3787 72 : torture_assert(tctx, k5ok, assertion_message);
3788 72 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3789 72 : ctx->krbtgt_trust_netbios_creds->server);
3790 72 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3791 :
3792 : /* Confirm if we have the referral ticket in the cache */
3793 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3794 : &ctx->krbtgt_referral_creds);
3795 144 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3796 : ctx->krbtgt_ccache,
3797 : 0,
3798 72 : ctx->krbtgt_trust_realm_creds,
3799 : &ctx->krbtgt_referral_creds);
3800 72 : assertion_message = talloc_asprintf(ctx,
3801 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3802 : krbtgt_trust_realm_string,
3803 : k5ret,
3804 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3805 : k5ret, ctx));
3806 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3807 :
3808 72 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3809 72 : ctx->krbtgt_referral_creds.server,
3810 72 : ctx->krbtgt_trust_realm);
3811 72 : torture_assert(tctx, k5ok, assertion_message);
3812 72 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3813 72 : ctx->krbtgt_referral_creds.server);
3814 72 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3815 :
3816 : /* Delete the referral ticket from the cache */
3817 72 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3818 : ctx->krbtgt_ccache,
3819 : 0,
3820 : &ctx->krbtgt_referral_creds);
3821 72 : assertion_message = talloc_asprintf(ctx,
3822 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3823 : krbtgt_trust_realm_string,
3824 : k5ret,
3825 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3826 : k5ret, ctx));
3827 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3828 :
3829 72 : cifs_trust_dns_string = talloc_asprintf(ctx, "cifs/%s@%s",
3830 : trusted_dns_name, realm);
3831 72 : torture_assert_int_equal(tctx,
3832 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3833 : &ctx->cifs_trust_dns,
3834 : realm, "cifs",
3835 : trusted_dns_name, NULL),
3836 : 0, "smb_krb5_make_principal failed");
3837 :
3838 : /* Confirm if we get krbtgt/trusted_realm back when asking for cifs/trusted_realm */
3839 72 : ZERO_STRUCT(ctx->counts);
3840 144 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3841 : ctx->opt_canon,
3842 : ctx->krbtgt_ccache,
3843 72 : ctx->cifs_trust_dns,
3844 : &ctx->cifs_trust_dns_creds);
3845 216 : assertion_message = talloc_asprintf(ctx,
3846 : "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3847 : cifs_trust_dns_string,
3848 : k5ret,
3849 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3850 : k5ret, ctx),
3851 : trusted->trust_direction,
3852 72 : trusted->trust_type,
3853 : trusted->trust_attributes,
3854 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3855 72 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3856 72 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3857 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3858 :
3859 : /* Confirm if we have the referral ticket in the cache */
3860 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3861 : &ctx->krbtgt_referral_creds);
3862 144 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3863 : ctx->krbtgt_ccache,
3864 : 0,
3865 72 : ctx->krbtgt_trust_realm_creds,
3866 : &ctx->krbtgt_referral_creds);
3867 72 : assertion_message = talloc_asprintf(ctx,
3868 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3869 : krbtgt_trust_realm_string,
3870 : k5ret,
3871 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3872 : k5ret, ctx));
3873 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3874 :
3875 72 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3876 72 : ctx->krbtgt_referral_creds.server,
3877 72 : ctx->krbtgt_trust_realm);
3878 72 : torture_assert(tctx, k5ok, assertion_message);
3879 72 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3880 72 : ctx->krbtgt_referral_creds.server);
3881 72 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3882 :
3883 : /* Delete the referral ticket from the cache */
3884 72 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3885 : ctx->krbtgt_ccache,
3886 : 0,
3887 : &ctx->krbtgt_referral_creds);
3888 72 : assertion_message = talloc_asprintf(ctx,
3889 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3890 : krbtgt_trust_realm_string,
3891 : k5ret,
3892 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3893 : k5ret, ctx));
3894 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3895 :
3896 72 : cifs_trust_netbios_string = talloc_asprintf(ctx, "cifs/%s@%s",
3897 : trusted_netbios_name, realm);
3898 72 : torture_assert_int_equal(tctx,
3899 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3900 : &ctx->cifs_trust_netbios,
3901 : realm, "cifs",
3902 : trusted_netbios_name, NULL),
3903 : 0, "smb_krb5_make_principal failed");
3904 :
3905 : /* Confirm if we get krbtgt/trusted_realm back when asking for cifs/trusted_realm */
3906 72 : ZERO_STRUCT(ctx->counts);
3907 144 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3908 : ctx->opt_canon,
3909 : ctx->krbtgt_ccache,
3910 72 : ctx->cifs_trust_netbios,
3911 : &ctx->cifs_trust_netbios_creds);
3912 216 : assertion_message = talloc_asprintf(ctx,
3913 : "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3914 : cifs_trust_netbios_string,
3915 : k5ret,
3916 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3917 : k5ret, ctx),
3918 : trusted->trust_direction,
3919 72 : trusted->trust_type,
3920 : trusted->trust_attributes,
3921 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3922 72 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3923 72 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3924 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3925 :
3926 : /* Confirm if we have the referral ticket in the cache */
3927 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3928 : &ctx->krbtgt_referral_creds);
3929 144 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3930 : ctx->krbtgt_ccache,
3931 : 0,
3932 72 : ctx->krbtgt_trust_realm_creds,
3933 : &ctx->krbtgt_referral_creds);
3934 72 : assertion_message = talloc_asprintf(ctx,
3935 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3936 : krbtgt_trust_realm_string,
3937 : k5ret,
3938 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3939 : k5ret, ctx));
3940 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3941 :
3942 72 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3943 72 : ctx->krbtgt_referral_creds.server,
3944 72 : ctx->krbtgt_trust_realm);
3945 72 : torture_assert(tctx, k5ok, assertion_message);
3946 72 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3947 72 : ctx->krbtgt_referral_creds.server);
3948 72 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3949 :
3950 : /* Delete the referral ticket from the cache */
3951 72 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3952 : ctx->krbtgt_ccache,
3953 : 0,
3954 : &ctx->krbtgt_referral_creds);
3955 72 : assertion_message = talloc_asprintf(ctx,
3956 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3957 : krbtgt_trust_realm_string,
3958 : k5ret,
3959 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3960 : k5ret, ctx));
3961 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3962 :
3963 72 : drs_trust_dns_string = talloc_asprintf(ctx,
3964 : "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s@%s",
3965 : workstation, trusted_dns_name, realm);
3966 72 : torture_assert_int_equal(tctx,
3967 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3968 : &ctx->drs_trust_dns,
3969 : realm, "E3514235-4B06-11D1-AB04-00C04FC2DCD2",
3970 : workstation, trusted_dns_name, NULL),
3971 : 0, "smb_krb5_make_principal failed");
3972 :
3973 : /* Confirm if we get krbtgt/trusted_realm back when asking for a 3 part principal */
3974 72 : ZERO_STRUCT(ctx->counts);
3975 144 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3976 : ctx->opt_canon,
3977 : ctx->krbtgt_ccache,
3978 72 : ctx->drs_trust_dns,
3979 : &ctx->drs_trust_dns_creds);
3980 216 : assertion_message = talloc_asprintf(ctx,
3981 : "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3982 : drs_trust_dns_string,
3983 : k5ret,
3984 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3985 : k5ret, ctx),
3986 : trusted->trust_direction,
3987 72 : trusted->trust_type,
3988 : trusted->trust_attributes,
3989 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3990 72 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3991 72 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3992 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3993 :
3994 : /* Confirm if we have the referral ticket in the cache */
3995 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3996 : &ctx->krbtgt_referral_creds);
3997 144 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3998 : ctx->krbtgt_ccache,
3999 : 0,
4000 72 : ctx->krbtgt_trust_realm_creds,
4001 : &ctx->krbtgt_referral_creds);
4002 72 : assertion_message = talloc_asprintf(ctx,
4003 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4004 : krbtgt_trust_realm_string,
4005 : k5ret,
4006 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4007 : k5ret, ctx));
4008 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4009 :
4010 72 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
4011 72 : ctx->krbtgt_referral_creds.server,
4012 72 : ctx->krbtgt_trust_realm);
4013 72 : torture_assert(tctx, k5ok, assertion_message);
4014 72 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
4015 72 : ctx->krbtgt_referral_creds.server);
4016 72 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
4017 :
4018 : /* Delete the referral ticket from the cache */
4019 72 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
4020 : ctx->krbtgt_ccache,
4021 : 0,
4022 : &ctx->krbtgt_referral_creds);
4023 72 : assertion_message = talloc_asprintf(ctx,
4024 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
4025 : krbtgt_trust_realm_string,
4026 : k5ret,
4027 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4028 : k5ret, ctx));
4029 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4030 :
4031 72 : drs_trust_netbios_string = talloc_asprintf(ctx,
4032 : "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s@%s",
4033 : workstation, trusted_netbios_name, realm);
4034 72 : torture_assert_int_equal(tctx,
4035 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
4036 : &ctx->drs_trust_netbios,
4037 : realm, "E3514235-4B06-11D1-AB04-00C04FC2DCD2",
4038 : workstation, trusted_netbios_name, NULL),
4039 : 0, "smb_krb5_make_principal failed");
4040 :
4041 : /* Confirm if we get krbtgt/trusted_realm back when asking for a 3 part principal */
4042 72 : ZERO_STRUCT(ctx->counts);
4043 144 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4044 : ctx->opt_canon,
4045 : ctx->krbtgt_ccache,
4046 72 : ctx->drs_trust_netbios,
4047 : &ctx->drs_trust_netbios_creds);
4048 216 : assertion_message = talloc_asprintf(ctx,
4049 : "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4050 : drs_trust_netbios_string,
4051 : k5ret,
4052 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4053 : k5ret, ctx),
4054 : trusted->trust_direction,
4055 72 : trusted->trust_type,
4056 : trusted->trust_attributes,
4057 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4058 72 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
4059 72 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4060 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
4061 :
4062 : /* Confirm if we have the referral ticket in the cache */
4063 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4064 : &ctx->krbtgt_referral_creds);
4065 144 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4066 : ctx->krbtgt_ccache,
4067 : 0,
4068 72 : ctx->krbtgt_trust_realm_creds,
4069 : &ctx->krbtgt_referral_creds);
4070 72 : assertion_message = talloc_asprintf(ctx,
4071 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4072 : krbtgt_trust_realm_string,
4073 : k5ret,
4074 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4075 : k5ret, ctx));
4076 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4077 :
4078 72 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
4079 72 : ctx->krbtgt_referral_creds.server,
4080 72 : ctx->krbtgt_trust_realm);
4081 72 : torture_assert(tctx, k5ok, assertion_message);
4082 72 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
4083 72 : ctx->krbtgt_referral_creds.server);
4084 72 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
4085 :
4086 : /* Delete the referral ticket from the cache */
4087 72 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
4088 : ctx->krbtgt_ccache,
4089 : 0,
4090 : &ctx->krbtgt_referral_creds);
4091 72 : assertion_message = talloc_asprintf(ctx,
4092 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
4093 : krbtgt_trust_realm_string,
4094 : k5ret,
4095 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4096 : k5ret, ctx));
4097 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4098 :
4099 72 : four_trust_dns_string = talloc_asprintf(ctx, "four/tree/two/%s@%s",
4100 : trusted_dns_name, realm);
4101 72 : torture_assert_int_equal(tctx,
4102 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
4103 : &ctx->four_trust_dns,
4104 : realm, "four", "tree", "two",
4105 : trusted_dns_name, NULL),
4106 : 0, "smb_krb5_make_principal failed");
4107 :
4108 : /* Confirm if we get an error back for a 4 part principal */
4109 72 : ZERO_STRUCT(ctx->counts);
4110 144 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4111 : ctx->opt_canon,
4112 : ctx->krbtgt_ccache,
4113 72 : ctx->four_trust_dns,
4114 : &ctx->four_trust_dns_creds);
4115 216 : assertion_message = talloc_asprintf(ctx,
4116 : "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4117 : four_trust_dns_string,
4118 : k5ret,
4119 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4120 : k5ret, ctx),
4121 : trusted->trust_direction,
4122 72 : trusted->trust_type,
4123 : trusted->trust_attributes,
4124 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4125 72 : torture_assert_int_equal(tctx, k5ret, KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, assertion_message);
4126 72 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4127 72 : torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
4128 72 : torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 7, assertion_message);
4129 :
4130 : /* Confirm if we have no referral ticket in the cache */
4131 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4132 : &ctx->krbtgt_referral_creds);
4133 144 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4134 : ctx->krbtgt_ccache,
4135 : 0,
4136 72 : ctx->krbtgt_trust_realm_creds,
4137 : &ctx->krbtgt_referral_creds);
4138 72 : assertion_message = talloc_asprintf(ctx,
4139 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4140 : krbtgt_trust_realm_string,
4141 : k5ret,
4142 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4143 : k5ret, ctx));
4144 72 : torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4145 :
4146 72 : TALLOC_FREE(ctx);
4147 72 : return true;
4148 : }
4149 : #endif
4150 :
4151 72 : static bool check_dom_trust_pw(struct dcerpc_pipe *p,
4152 : struct torture_context *tctx,
4153 : const char *our_netbios_name,
4154 : const char *our_dns_name,
4155 : enum netr_SchannelType secure_channel_type,
4156 : const struct lsa_TrustDomainInfoInfoEx *trusted,
4157 : const char *previous_password,
4158 : const char *current_password,
4159 : uint32_t current_version,
4160 : const char *next_password,
4161 : uint32_t next_version,
4162 : bool expected_result)
4163 : {
4164 : struct cli_credentials *incoming_creds;
4165 72 : char *server_name = NULL;
4166 72 : char *account = NULL;
4167 72 : char *principal = NULL;
4168 72 : char *workstation = NULL;
4169 72 : const char *binding = torture_setting_string(tctx, "binding", NULL);
4170 72 : const char *host = torture_setting_string(tctx, "host", NULL);
4171 : const char *ip;
4172 : struct nbt_name nbt_name;
4173 : struct dcerpc_binding *b2;
4174 : struct netlogon_creds_CredentialState *creds;
4175 : struct samr_CryptPassword samr_crypt_password;
4176 : struct netr_CryptPassword netr_crypt_password;
4177 : struct netr_Authenticator req_auth;
4178 : struct netr_Authenticator rep_auth;
4179 : struct netr_ServerPasswordSet2 s;
4180 72 : struct dcerpc_pipe *p1 = NULL;
4181 72 : struct dcerpc_pipe *p2 = NULL;
4182 : NTSTATUS status;
4183 : bool ok;
4184 : int rc;
4185 72 : const char *trusted_netbios_name = trusted->netbios_name.string;
4186 72 : const char *trusted_dns_name = trusted->domain_name.string;
4187 : struct tsocket_address *dest_addr;
4188 : struct cldap_socket *cldap;
4189 : struct cldap_netlogon cldap1;
4190 :
4191 72 : incoming_creds = cli_credentials_init(tctx);
4192 72 : torture_assert(tctx, incoming_creds, "cli_credentials_init");
4193 :
4194 72 : cli_credentials_set_domain(incoming_creds, our_netbios_name, CRED_SPECIFIED);
4195 72 : cli_credentials_set_realm(incoming_creds, our_dns_name, CRED_SPECIFIED);
4196 :
4197 72 : if (secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
4198 36 : account = talloc_asprintf(tctx, "%s.", trusted_dns_name);
4199 36 : torture_assert(tctx, account, __location__);
4200 :
4201 36 : principal = talloc_asprintf(tctx, "%s$@%s",
4202 : trusted_netbios_name,
4203 : cli_credentials_get_realm(incoming_creds));
4204 36 : torture_assert(tctx, principal, __location__);
4205 :
4206 36 : workstation = talloc_asprintf(tctx, "%sUP",
4207 : trusted_netbios_name);
4208 36 : torture_assert(tctx, workstation, __location__);
4209 : } else {
4210 36 : account = talloc_asprintf(tctx, "%s$", trusted_netbios_name);
4211 36 : torture_assert(tctx, account, __location__);
4212 :
4213 36 : workstation = talloc_asprintf(tctx, "%sDOWN",
4214 : trusted_netbios_name);
4215 36 : torture_assert(tctx, workstation, __location__);
4216 : }
4217 :
4218 72 : cli_credentials_set_username(incoming_creds, account, CRED_SPECIFIED);
4219 72 : if (principal != NULL) {
4220 36 : cli_credentials_set_principal(incoming_creds, principal,
4221 : CRED_SPECIFIED);
4222 : }
4223 72 : cli_credentials_set_kvno(incoming_creds, current_version);
4224 72 : cli_credentials_set_password(incoming_creds, current_password, CRED_SPECIFIED);
4225 72 : cli_credentials_set_old_password(incoming_creds, previous_password, CRED_SPECIFIED);
4226 72 : cli_credentials_set_workstation(incoming_creds, workstation, CRED_SPECIFIED);
4227 72 : cli_credentials_set_secure_channel_type(incoming_creds, secure_channel_type);
4228 :
4229 72 : make_nbt_name_server(&nbt_name, host);
4230 :
4231 72 : status = resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx),
4232 : 0, 0, &nbt_name, tctx, &ip, tctx->ev);
4233 72 : torture_assert_ntstatus_ok(tctx, status,
4234 : talloc_asprintf(tctx,"Failed to resolve %s: %s",
4235 : nbt_name.name, nt_errstr(status)));
4236 :
4237 72 : rc = tsocket_address_inet_from_strings(tctx, "ip",
4238 : ip,
4239 : lpcfg_cldap_port(tctx->lp_ctx),
4240 : &dest_addr);
4241 72 : torture_assert_int_equal(tctx, rc, 0,
4242 : talloc_asprintf(tctx,
4243 : "tsocket_address_inet_from_strings failed parsing %s:%d",
4244 : host, lpcfg_cldap_port(tctx->lp_ctx)));
4245 :
4246 : /* cldap_socket_init should now know about the dest. address */
4247 72 : status = cldap_socket_init(tctx, NULL, dest_addr, &cldap);
4248 72 : torture_assert_ntstatus_ok(tctx, status, "cldap_socket_init");
4249 :
4250 72 : ZERO_STRUCT(cldap1);
4251 72 : cldap1.in.dest_address = NULL;
4252 72 : cldap1.in.dest_port = 0;
4253 72 : cldap1.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
4254 72 : cldap1.in.user = account;
4255 72 : if (secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
4256 36 : cldap1.in.acct_control = ACB_AUTOLOCK;
4257 : } else {
4258 36 : cldap1.in.acct_control = ACB_DOMTRUST;
4259 : }
4260 72 : status = cldap_netlogon(cldap, tctx, &cldap1);
4261 72 : torture_assert_ntstatus_ok(tctx, status, "cldap_netlogon");
4262 72 : torture_assert_int_equal(tctx, cldap1.out.netlogon.ntver,
4263 : NETLOGON_NT_VERSION_5EX,
4264 : "ntver");
4265 72 : torture_assert_int_equal(tctx, cldap1.out.netlogon.data.nt5_ex.nt_version,
4266 : NETLOGON_NT_VERSION_1 | NETLOGON_NT_VERSION_5EX,
4267 : "nt_version");
4268 72 : torture_assert_int_equal(tctx, cldap1.out.netlogon.data.nt5_ex.command,
4269 : LOGON_SAM_LOGON_RESPONSE_EX,
4270 : "command");
4271 72 : torture_assert_str_equal(tctx, cldap1.out.netlogon.data.nt5_ex.user_name,
4272 : cldap1.in.user,
4273 : "user_name");
4274 72 : server_name = talloc_asprintf(tctx, "\\\\%s",
4275 : cldap1.out.netlogon.data.nt5_ex.pdc_dns_name);
4276 72 : torture_assert(tctx, server_name, __location__);
4277 :
4278 72 : status = dcerpc_parse_binding(tctx, binding, &b2);
4279 72 : torture_assert_ntstatus_ok(tctx, status, "Bad binding string");
4280 :
4281 72 : status = dcerpc_pipe_connect_b(tctx, &p1, b2,
4282 : &ndr_table_netlogon,
4283 : cli_credentials_init_anon(tctx),
4284 : tctx->ev, tctx->lp_ctx);
4285 72 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b");
4286 :
4287 72 : ok = check_pw_with_ServerAuthenticate3(p1, tctx,
4288 : NETLOGON_NEG_AUTH2_ADS_FLAGS,
4289 : server_name,
4290 : incoming_creds, &creds);
4291 72 : torture_assert_int_equal(tctx, ok, expected_result,
4292 : "check_pw_with_ServerAuthenticate3");
4293 72 : if (expected_result == true) {
4294 54 : ok = test_SetupCredentialsPipe(p1, tctx, incoming_creds, creds,
4295 : DCERPC_SIGN | DCERPC_SEAL, &p2);
4296 54 : torture_assert_int_equal(tctx, ok, true,
4297 : "test_SetupCredentialsPipe");
4298 : }
4299 72 : TALLOC_FREE(p1);
4300 :
4301 72 : if (trusted->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
4302 : #ifdef SAMBA4_USES_HEIMDAL
4303 48 : ok = check_pw_with_krb5(tctx, incoming_creds, trusted);
4304 48 : torture_assert_int_equal(tctx, ok, expected_result,
4305 : "check_pw_with_krb5");
4306 : #else
4307 0 : torture_comment(tctx, "skipping check_pw_with_krb5 for MIT Kerberos build");
4308 : #endif
4309 : }
4310 :
4311 72 : if (expected_result != true || next_password == NULL) {
4312 18 : TALLOC_FREE(p2);
4313 18 : return true;
4314 : }
4315 :
4316 : /*
4317 : * netr_ServerPasswordSet2
4318 : */
4319 54 : ok = encode_pw_buffer(samr_crypt_password.data,
4320 : next_password, STR_UNICODE);
4321 54 : torture_assert(tctx, ok, "encode_pw_buffer");
4322 :
4323 54 : if (next_version != 0) {
4324 : struct NL_PASSWORD_VERSION version;
4325 54 : uint32_t len = IVAL(samr_crypt_password.data, 512);
4326 54 : uint32_t ofs = 512 - len;
4327 : uint8_t *ptr;
4328 :
4329 54 : ofs -= 12;
4330 :
4331 54 : version.ReservedField = 0;
4332 54 : version.PasswordVersionNumber = next_version;
4333 54 : version.PasswordVersionPresent =
4334 : NETLOGON_PASSWORD_VERSION_NUMBER_PRESENT;
4335 :
4336 54 : ptr = samr_crypt_password.data + ofs;
4337 54 : SIVAL(ptr, 0, version.ReservedField);
4338 54 : SIVAL(ptr, 4, version.PasswordVersionNumber);
4339 54 : SIVAL(ptr, 8, version.PasswordVersionPresent);
4340 : }
4341 :
4342 54 : netlogon_creds_client_authenticator(creds, &req_auth);
4343 54 : ZERO_STRUCT(rep_auth);
4344 :
4345 54 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
4346 0 : netlogon_creds_aes_encrypt(creds,
4347 : samr_crypt_password.data,
4348 : 516);
4349 : } else {
4350 54 : netlogon_creds_arcfour_crypt(creds,
4351 : samr_crypt_password.data,
4352 : 516);
4353 : }
4354 :
4355 54 : memcpy(netr_crypt_password.data,
4356 : samr_crypt_password.data, 512);
4357 54 : netr_crypt_password.length = IVAL(samr_crypt_password.data, 512);
4358 :
4359 :
4360 54 : s.in.server_name = server_name;
4361 54 : s.in.account_name = cli_credentials_get_username(incoming_creds);
4362 54 : s.in.secure_channel_type = cli_credentials_get_secure_channel_type(incoming_creds);
4363 54 : s.in.computer_name = cli_credentials_get_workstation(incoming_creds);
4364 54 : s.in.credential = &req_auth;
4365 54 : s.in.new_password = &netr_crypt_password;
4366 54 : s.out.return_authenticator = &rep_auth;
4367 54 : status = dcerpc_netr_ServerPasswordSet2_r(p2->binding_handle, tctx, &s);
4368 54 : torture_assert_ntstatus_ok(tctx, status, "failed to set password");
4369 :
4370 54 : ok = netlogon_creds_client_check(creds, &rep_auth.cred);
4371 54 : torture_assert(tctx, ok, "netlogon_creds_client_check");
4372 :
4373 54 : cli_credentials_set_kvno(incoming_creds, next_version);
4374 54 : cli_credentials_set_password(incoming_creds, next_password, CRED_SPECIFIED);
4375 54 : cli_credentials_set_old_password(incoming_creds, current_password, CRED_SPECIFIED);
4376 :
4377 54 : TALLOC_FREE(p2);
4378 54 : status = dcerpc_pipe_connect_b(tctx, &p2, b2,
4379 : &ndr_table_netlogon,
4380 : cli_credentials_init_anon(tctx),
4381 : tctx->ev, tctx->lp_ctx);
4382 54 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b");
4383 :
4384 54 : ok = check_pw_with_ServerAuthenticate3(p2, tctx,
4385 : NETLOGON_NEG_AUTH2_ADS_FLAGS,
4386 : server_name,
4387 : incoming_creds, &creds);
4388 54 : torture_assert(tctx, ok, "check_pw_with_ServerAuthenticate3 with changed password");
4389 :
4390 54 : if (trusted->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
4391 : #if SAMBA4_USES_HEIMDAL
4392 36 : ok = check_pw_with_krb5(tctx, incoming_creds, trusted);
4393 36 : torture_assert(tctx, ok, "check_pw_with_krb5 with changed password");
4394 : #else
4395 0 : torture_comment(tctx, "skipping check_pw_with_krb5 for MIT Kerberos build");
4396 : #endif
4397 : }
4398 :
4399 54 : TALLOC_FREE(p2);
4400 54 : return true;
4401 : }
4402 :
4403 6 : static bool test_CreateTrustedDomainEx_common(struct dcerpc_pipe *p,
4404 : struct torture_context *tctx,
4405 : struct policy_handle *handle,
4406 : uint32_t num_trusts,
4407 : bool ex2_call)
4408 : {
4409 : NTSTATUS status;
4410 6 : bool ret = true;
4411 : struct lsa_QueryInfoPolicy2 p2;
4412 6 : union lsa_PolicyInformation *our_info = NULL;
4413 : struct lsa_CreateTrustedDomainEx r;
4414 : struct lsa_CreateTrustedDomainEx2 r2;
4415 : struct lsa_TrustDomainInfoInfoEx trustinfo;
4416 6 : struct lsa_TrustDomainInfoAuthInfoInternal *authinfo_internal = NULL;
4417 6 : struct lsa_TrustDomainInfoAuthInfo *authinfo = NULL;
4418 : struct dom_sid **domsid;
4419 : struct policy_handle *trustdom_handle;
4420 : struct lsa_QueryTrustedDomainInfo q;
4421 6 : union lsa_TrustedDomainInfo *info = NULL;
4422 : DATA_BLOB session_key;
4423 : int i;
4424 6 : struct dcerpc_binding_handle *b = p->binding_handle;
4425 : const char *id;
4426 6 : const char *incoming_v00 = TRUSTPW "InV00";
4427 6 : const char *incoming_v0 = TRUSTPW "InV0";
4428 6 : const char *incoming_v1 = TRUSTPW "InV1";
4429 6 : const char *incoming_v2 = TRUSTPW "InV2";
4430 6 : const char *incoming_v40 = TRUSTPW "InV40";
4431 6 : const char *outgoing_v00 = TRUSTPW "OutV00";
4432 6 : const char *outgoing_v0 = TRUSTPW "OutV0";
4433 :
4434 6 : if (ex2_call) {
4435 3 : torture_comment(tctx, "\nTesting CreateTrustedDomainEx2 for %d domains\n", num_trusts);
4436 3 : id = "3";
4437 : } else {
4438 3 : torture_comment(tctx, "\nTesting CreateTrustedDomainEx for %d domains\n", num_trusts);
4439 3 : id = "2";
4440 : }
4441 :
4442 6 : domsid = talloc_array(tctx, struct dom_sid *, num_trusts);
4443 6 : trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts);
4444 :
4445 6 : status = dcerpc_fetch_session_key(p, &session_key);
4446 6 : if (!NT_STATUS_IS_OK(status)) {
4447 0 : torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
4448 0 : return false;
4449 : }
4450 :
4451 6 : ZERO_STRUCT(p2);
4452 6 : p2.in.handle = handle;
4453 6 : p2.in.level = LSA_POLICY_INFO_DNS;
4454 6 : p2.out.info = &our_info;
4455 :
4456 6 : torture_assert_ntstatus_ok(tctx,
4457 : dcerpc_lsa_QueryInfoPolicy2_r(b, tctx, &p2),
4458 : "lsa_QueryInfoPolicy2 failed");
4459 6 : torture_assert_ntstatus_ok(tctx, p2.out.result,
4460 : "lsa_QueryInfoPolicy2 failed");
4461 6 : torture_assert(tctx, our_info != NULL, "lsa_QueryInfoPolicy2 our_info");
4462 :
4463 78 : for (i=0; i< num_trusts; i++) {
4464 72 : char *trust_name = talloc_asprintf(tctx, "TORTURE%s%02d", id, i);
4465 72 : char *trust_name_dns = talloc_asprintf(tctx, "torturedom%s%02d.samba._none_.example.com", id, i);
4466 72 : char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-%s%02d", id, i);
4467 : bool ok;
4468 :
4469 72 : domsid[i] = dom_sid_parse_talloc(tctx, trust_sid);
4470 :
4471 72 : trustinfo.sid = domsid[i];
4472 72 : trustinfo.netbios_name.string = trust_name;
4473 72 : trustinfo.domain_name.string = trust_name_dns;
4474 :
4475 : /* Create inbound, some outbound, and some
4476 : * bi-directional trusts in a repeating pattern based
4477 : * on i */
4478 :
4479 : /* 1 == inbound, 2 == outbound, 3 == both */
4480 72 : trustinfo.trust_direction = (i % 3) + 1;
4481 :
4482 : /* Try different trust types too */
4483 :
4484 : /* 1 == downlevel (NT4), 2 == uplevel (ADS), 3 == MIT (kerberos but not AD) */
4485 72 : trustinfo.trust_type = (((i / 3) + 1) % 3) + 1;
4486 :
4487 72 : trustinfo.trust_attributes = LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION;
4488 :
4489 72 : ok = gen_authinfo_internal(tctx, incoming_v00, incoming_v0,
4490 : outgoing_v00, outgoing_v0,
4491 : session_key, &authinfo_internal);
4492 72 : if (!ok) {
4493 0 : torture_comment(tctx, "gen_authinfo_internal failed");
4494 0 : ret = false;
4495 : }
4496 :
4497 72 : ok = gen_authinfo(tctx, incoming_v00, incoming_v0,
4498 : outgoing_v00, outgoing_v0,
4499 : &authinfo);
4500 72 : if (!ok) {
4501 0 : torture_comment(tctx, "gen_authinfonfo failed");
4502 0 : ret = false;
4503 : }
4504 :
4505 72 : if (ex2_call) {
4506 :
4507 36 : r2.in.policy_handle = handle;
4508 36 : r2.in.info = &trustinfo;
4509 36 : r2.in.auth_info_internal = authinfo_internal;
4510 36 : r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4511 36 : r2.out.trustdom_handle = &trustdom_handle[i];
4512 :
4513 36 : torture_assert_ntstatus_ok(tctx,
4514 : dcerpc_lsa_CreateTrustedDomainEx2_r(b, tctx, &r2),
4515 : "CreateTrustedDomainEx2 failed");
4516 :
4517 36 : status = r2.out.result;
4518 : } else {
4519 :
4520 36 : r.in.policy_handle = handle;
4521 36 : r.in.info = &trustinfo;
4522 36 : r.in.auth_info = authinfo;
4523 36 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4524 36 : r.out.trustdom_handle = &trustdom_handle[i];
4525 :
4526 36 : torture_assert_ntstatus_ok(tctx,
4527 : dcerpc_lsa_CreateTrustedDomainEx_r(b, tctx, &r),
4528 : "CreateTrustedDomainEx failed");
4529 :
4530 36 : status = r.out.result;
4531 : }
4532 :
4533 72 : if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
4534 0 : test_DeleteTrustedDomain(b, tctx, handle, trustinfo.netbios_name);
4535 0 : if (ex2_call) {
4536 0 : torture_assert_ntstatus_ok(tctx,
4537 : dcerpc_lsa_CreateTrustedDomainEx2_r(b, tctx, &r2),
4538 : "CreateTrustedDomainEx2 failed");
4539 0 : status = r2.out.result;
4540 : } else {
4541 0 : torture_assert_ntstatus_ok(tctx,
4542 : dcerpc_lsa_CreateTrustedDomainEx_r(b, tctx, &r),
4543 : "CreateTrustedDomainEx2 failed");
4544 0 : status = r.out.result;
4545 : }
4546 : }
4547 72 : if (!NT_STATUS_IS_OK(status)) {
4548 0 : torture_comment(tctx, "CreateTrustedDomainEx failed2 - %s\n", nt_errstr(status));
4549 0 : ret = false;
4550 : } else {
4551 : /* For outbound and MIT trusts there is no trust account */
4552 120 : if (trustinfo.trust_direction != 2 &&
4553 48 : trustinfo.trust_type != 3) {
4554 :
4555 36 : if (torture_setting_bool(tctx, "samba3", false)) {
4556 0 : torture_comment(tctx, "skipping trusted domain auth tests against samba3\n");
4557 54 : } else if (ex2_call == false &&
4558 18 : torture_setting_bool(tctx, "samba4", false)) {
4559 18 : torture_comment(tctx, "skipping CreateTrustedDomainEx trusted domain auth tests against samba4\n");
4560 :
4561 : } else {
4562 36 : ok = check_dom_trust_pw(p, tctx,
4563 18 : our_info->dns.name.string,
4564 18 : our_info->dns.dns_domain.string,
4565 : SEC_CHAN_DOMAIN,
4566 : &trustinfo,
4567 : NULL,
4568 : "x" TRUSTPW "x", 0,
4569 : NULL, 0,
4570 : false);
4571 18 : if (!ok) {
4572 0 : torture_comment(tctx, "Password check passed unexpectedly\n");
4573 0 : ret = false;
4574 : }
4575 36 : ok = check_dom_trust_pw(p, tctx,
4576 18 : our_info->dns.name.string,
4577 18 : our_info->dns.dns_domain.string,
4578 : SEC_CHAN_DOMAIN,
4579 : &trustinfo,
4580 : incoming_v00,
4581 : incoming_v0, 0,
4582 : incoming_v1, 1,
4583 : true);
4584 18 : if (!ok) {
4585 0 : torture_comment(tctx, "Password check failed (SEC_CHAN_DOMAIN)\n");
4586 0 : ret = false;
4587 : }
4588 36 : ok = check_dom_trust_pw(p, tctx,
4589 18 : our_info->dns.name.string,
4590 18 : our_info->dns.dns_domain.string,
4591 : SEC_CHAN_DNS_DOMAIN,
4592 : &trustinfo,
4593 : incoming_v0,
4594 : incoming_v1, 1,
4595 : incoming_v2, 2,
4596 : true);
4597 18 : if (!ok) {
4598 0 : torture_comment(tctx, "Password check failed v2 (SEC_CHAN_DNS_DOMAIN)\n");
4599 0 : ret = false;
4600 : }
4601 36 : ok = check_dom_trust_pw(p, tctx,
4602 18 : our_info->dns.name.string,
4603 18 : our_info->dns.dns_domain.string,
4604 : SEC_CHAN_DNS_DOMAIN,
4605 : &trustinfo,
4606 : incoming_v1,
4607 : incoming_v2, 2,
4608 : incoming_v40, 40,
4609 : true);
4610 18 : if (!ok) {
4611 0 : torture_comment(tctx, "Password check failed v4 (SEC_CHAN_DNS_DOMAIN)\n");
4612 0 : ret = false;
4613 : }
4614 : }
4615 : }
4616 :
4617 72 : q.in.trustdom_handle = &trustdom_handle[i];
4618 72 : q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
4619 72 : q.out.info = &info;
4620 72 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
4621 : "QueryTrustedDomainInfo failed");
4622 72 : if (!NT_STATUS_IS_OK(q.out.result)) {
4623 0 : torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(q.out.result));
4624 0 : ret = false;
4625 72 : } else if (!q.out.info) {
4626 0 : torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
4627 0 : ret = false;
4628 : } else {
4629 72 : if (strcmp(info->info_ex.domain_name.string, trustinfo.domain_name.string) != 0) {
4630 0 : torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent long name: %s != %s\n",
4631 0 : info->info_ex.domain_name.string, trustinfo.domain_name.string);
4632 0 : ret = false;
4633 : }
4634 72 : if (strcmp(info->info_ex.netbios_name.string, trustinfo.netbios_name.string) != 0) {
4635 0 : torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
4636 0 : info->info_ex.netbios_name.string, trustinfo.netbios_name.string);
4637 0 : ret = false;
4638 : }
4639 72 : if (info->info_ex.trust_type != trustinfo.trust_type) {
4640 0 : torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
4641 0 : trust_name, info->info_ex.trust_type, trustinfo.trust_type);
4642 0 : ret = false;
4643 : }
4644 72 : if (info->info_ex.trust_attributes != LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION) {
4645 0 : torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
4646 0 : trust_name, info->info_ex.trust_attributes, LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION);
4647 0 : ret = false;
4648 : }
4649 72 : if (info->info_ex.trust_direction != trustinfo.trust_direction) {
4650 0 : torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
4651 0 : trust_name, info->info_ex.trust_direction, trustinfo.trust_direction);
4652 0 : ret = false;
4653 : }
4654 : }
4655 : }
4656 : }
4657 :
4658 : /* now that we have some domains to look over, we can test the enum calls */
4659 6 : if (!test_EnumTrustDom(b, tctx, handle)) {
4660 0 : torture_comment(tctx, "test_EnumTrustDom failed\n");
4661 0 : ret = false;
4662 : }
4663 :
4664 6 : if (!test_EnumTrustDomEx(b, tctx, handle)) {
4665 0 : torture_comment(tctx, "test_EnumTrustDomEx failed\n");
4666 0 : ret = false;
4667 : }
4668 :
4669 78 : for (i=0; i<num_trusts; i++) {
4670 72 : if (!test_DeleteTrustedDomainBySid(b, tctx, handle, domsid[i])) {
4671 0 : torture_comment(tctx, "test_DeleteTrustedDomainBySid failed\n");
4672 0 : ret = false;
4673 : }
4674 : }
4675 :
4676 6 : return ret;
4677 : }
4678 :
4679 3 : static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
4680 : struct torture_context *tctx,
4681 : struct policy_handle *handle,
4682 : uint32_t num_trusts)
4683 : {
4684 3 : return test_CreateTrustedDomainEx_common(p, tctx, handle, num_trusts, true);
4685 : }
4686 :
4687 3 : static bool test_CreateTrustedDomainEx(struct dcerpc_pipe *p,
4688 : struct torture_context *tctx,
4689 : struct policy_handle *handle,
4690 : uint32_t num_trusts)
4691 : {
4692 3 : return test_CreateTrustedDomainEx_common(p, tctx, handle, num_trusts, false);
4693 : }
4694 :
4695 16 : static bool test_QueryDomainInfoPolicy(struct dcerpc_binding_handle *b,
4696 : struct torture_context *tctx,
4697 : struct policy_handle *handle)
4698 : {
4699 : struct lsa_QueryDomainInformationPolicy r;
4700 16 : union lsa_DomainInformationPolicy *info = NULL;
4701 : int i;
4702 16 : bool ret = true;
4703 :
4704 16 : if (torture_setting_bool(tctx, "samba3", false)) {
4705 4 : torture_skip(tctx, "skipping QueryDomainInformationPolicy test\n");
4706 : }
4707 :
4708 12 : torture_comment(tctx, "\nTesting QueryDomainInformationPolicy\n");
4709 :
4710 36 : for (i=2;i<4;i++) {
4711 24 : r.in.handle = handle;
4712 24 : r.in.level = i;
4713 24 : r.out.info = &info;
4714 :
4715 24 : torture_comment(tctx, "\nTrying QueryDomainInformationPolicy level %d\n", i);
4716 :
4717 24 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryDomainInformationPolicy_r(b, tctx, &r),
4718 : "QueryDomainInformationPolicy failed");
4719 :
4720 : /* If the server does not support EFS, then this is the correct return */
4721 24 : if (i == LSA_DOMAIN_INFO_POLICY_EFS && NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4722 12 : continue;
4723 12 : } else if (!NT_STATUS_IS_OK(r.out.result)) {
4724 0 : torture_comment(tctx, "QueryDomainInformationPolicy failed - %s\n", nt_errstr(r.out.result));
4725 0 : ret = false;
4726 0 : continue;
4727 : }
4728 : }
4729 :
4730 12 : return ret;
4731 : }
4732 :
4733 :
4734 32 : static bool test_QueryInfoPolicyCalls( bool version2,
4735 : struct dcerpc_binding_handle *b,
4736 : struct torture_context *tctx,
4737 : struct policy_handle *handle)
4738 : {
4739 : struct lsa_QueryInfoPolicy r;
4740 32 : union lsa_PolicyInformation *info = NULL;
4741 : int i;
4742 32 : bool ret = true;
4743 32 : const char *call = talloc_asprintf(tctx, "QueryInfoPolicy%s", version2 ? "2":"");
4744 :
4745 32 : torture_comment(tctx, "\nTesting %s\n", call);
4746 :
4747 32 : if (version2 && torture_setting_bool(tctx, "samba3", false)) {
4748 4 : torture_skip(tctx, "skipping QueryInfoPolicy2 tests\n");
4749 : }
4750 :
4751 420 : for (i=1;i<=14;i++) {
4752 392 : r.in.handle = handle;
4753 392 : r.in.level = i;
4754 392 : r.out.info = &info;
4755 :
4756 392 : torture_comment(tctx, "\nTrying %s level %d\n", call, i);
4757 :
4758 392 : if (version2)
4759 : /* We can perform the cast, because both types are
4760 : structurally equal */
4761 168 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy2_r(b, tctx,
4762 : (struct lsa_QueryInfoPolicy2*) &r),
4763 : "QueryInfoPolicy2 failed");
4764 : else
4765 224 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy_r(b, tctx, &r),
4766 : "QueryInfoPolicy2 failed");
4767 :
4768 392 : switch (i) {
4769 84 : case LSA_POLICY_INFO_MOD:
4770 : case LSA_POLICY_INFO_AUDIT_FULL_SET:
4771 : case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
4772 84 : if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
4773 0 : torture_comment(tctx, "Server should have failed level %u: %s\n", i, nt_errstr(r.out.result));
4774 0 : ret = false;
4775 : }
4776 84 : break;
4777 224 : case LSA_POLICY_INFO_DOMAIN:
4778 : case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
4779 : case LSA_POLICY_INFO_REPLICA:
4780 : case LSA_POLICY_INFO_QUOTA:
4781 : case LSA_POLICY_INFO_ROLE:
4782 : case LSA_POLICY_INFO_AUDIT_LOG:
4783 : case LSA_POLICY_INFO_AUDIT_EVENTS:
4784 : case LSA_POLICY_INFO_PD:
4785 224 : if (!NT_STATUS_IS_OK(r.out.result)) {
4786 0 : torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4787 0 : ret = false;
4788 : }
4789 224 : break;
4790 84 : case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
4791 : case LSA_POLICY_INFO_DNS_INT:
4792 : case LSA_POLICY_INFO_DNS:
4793 84 : if (torture_setting_bool(tctx, "samba3", false)) {
4794 : /* Other levels not implemented yet */
4795 12 : if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
4796 6 : torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4797 6 : ret = false;
4798 : }
4799 72 : } else if (!NT_STATUS_IS_OK(r.out.result)) {
4800 0 : torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4801 0 : ret = false;
4802 : }
4803 84 : break;
4804 0 : default:
4805 0 : if (torture_setting_bool(tctx, "samba4", false)) {
4806 : /* Other levels not implemented yet */
4807 0 : if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
4808 0 : torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4809 0 : ret = false;
4810 : }
4811 0 : } else if (!NT_STATUS_IS_OK(r.out.result)) {
4812 0 : torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4813 0 : ret = false;
4814 : }
4815 0 : break;
4816 : }
4817 :
4818 392 : if (NT_STATUS_IS_OK(r.out.result) && (i == LSA_POLICY_INFO_DNS
4819 276 : || i == LSA_POLICY_INFO_DNS_INT)) {
4820 : /* Let's look up some of these names */
4821 :
4822 : struct lsa_TransNameArray tnames, dnames;
4823 52 : tnames.count = 14;
4824 52 : tnames.names = talloc_zero_array(tctx, struct lsa_TranslatedName, tnames.count);
4825 52 : tnames.names[0].name.string = info->dns.name.string;
4826 52 : tnames.names[0].sid_type = SID_NAME_DOMAIN;
4827 52 : tnames.names[1].name.string = info->dns.dns_domain.string;
4828 52 : tnames.names[1].sid_type = SID_NAME_DOMAIN;
4829 52 : tnames.names[2].name.string = talloc_asprintf(tctx, "%s\\", info->dns.name.string);
4830 52 : tnames.names[2].sid_type = SID_NAME_DOMAIN;
4831 52 : tnames.names[3].name.string = talloc_asprintf(tctx, "%s\\", info->dns.dns_domain.string);
4832 52 : tnames.names[3].sid_type = SID_NAME_DOMAIN;
4833 52 : tnames.names[4].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.name.string);
4834 52 : tnames.names[4].sid_type = SID_NAME_USER;
4835 52 : tnames.names[5].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.name.string);
4836 52 : tnames.names[5].sid_type = SID_NAME_USER;
4837 52 : tnames.names[6].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.dns_domain.string);
4838 52 : tnames.names[6].sid_type = SID_NAME_USER;
4839 52 : tnames.names[7].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.dns_domain.string);
4840 52 : tnames.names[7].sid_type = SID_NAME_USER;
4841 52 : tnames.names[8].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.name.string);
4842 52 : tnames.names[8].sid_type = SID_NAME_USER;
4843 52 : tnames.names[9].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.dns_domain.string);
4844 52 : tnames.names[9].sid_type = SID_NAME_USER;
4845 52 : tnames.names[10].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.name.string);
4846 52 : tnames.names[10].sid_type = SID_NAME_USER;
4847 52 : tnames.names[11].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.dns_domain.string);
4848 52 : tnames.names[11].sid_type = SID_NAME_USER;
4849 52 : tnames.names[12].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.name.string);
4850 52 : tnames.names[12].sid_type = SID_NAME_USER;
4851 52 : tnames.names[13].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.dns_domain.string);
4852 52 : tnames.names[13].sid_type = SID_NAME_USER;
4853 52 : ret &= test_LookupNames(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames);
4854 :
4855 : /* Try to use in-forest search for the test machine */
4856 52 : dnames.count = 1;
4857 52 : dnames.names = talloc_zero_array(tctx, struct lsa_TranslatedName, dnames.count);
4858 52 : dnames.names[0].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.name.string);
4859 52 : dnames.names[0].sid_type = SID_NAME_USER;
4860 52 : ret &= test_LookupNames(b, tctx, handle, LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2, &dnames);
4861 : }
4862 : }
4863 :
4864 28 : return ret;
4865 : }
4866 :
4867 16 : static bool test_QueryInfoPolicy(struct dcerpc_binding_handle *b,
4868 : struct torture_context *tctx,
4869 : struct policy_handle *handle)
4870 : {
4871 16 : return test_QueryInfoPolicyCalls(false, b, tctx, handle);
4872 : }
4873 :
4874 16 : static bool test_QueryInfoPolicy2(struct dcerpc_binding_handle *b,
4875 : struct torture_context *tctx,
4876 : struct policy_handle *handle)
4877 : {
4878 16 : return test_QueryInfoPolicyCalls(true, b, tctx, handle);
4879 : }
4880 :
4881 48 : static bool test_GetUserName(struct dcerpc_binding_handle *b,
4882 : struct torture_context *tctx)
4883 : {
4884 : struct lsa_GetUserName r;
4885 48 : struct lsa_String *authority_name_p = NULL;
4886 48 : struct lsa_String *account_name_p = NULL;
4887 :
4888 48 : torture_comment(tctx, "\nTesting GetUserName\n");
4889 :
4890 48 : r.in.system_name = "\\";
4891 48 : r.in.account_name = &account_name_p;
4892 48 : r.in.authority_name = NULL;
4893 48 : r.out.account_name = &account_name_p;
4894 :
4895 48 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
4896 : "GetUserName failed");
4897 48 : torture_assert_ntstatus_ok(tctx, r.out.result,
4898 : "GetUserName result failed");
4899 48 : torture_assert_not_null(tctx, r.out.account_name, "r.out.account_name");
4900 48 : torture_assert_not_null(tctx, *r.out.account_name, "*r.out.account_name");
4901 48 : torture_assert(tctx, r.out.authority_name == NULL, "r.out.authority_name");
4902 :
4903 48 : account_name_p = NULL;
4904 48 : r.in.account_name = &account_name_p;
4905 48 : r.in.authority_name = &authority_name_p;
4906 48 : r.out.account_name = &account_name_p;
4907 :
4908 48 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
4909 : "GetUserName failed");
4910 48 : torture_assert_ntstatus_ok(tctx, r.out.result,
4911 : "GetUserName result failed");
4912 48 : torture_assert_not_null(tctx, r.out.account_name, "r.out.account_name");
4913 48 : torture_assert_not_null(tctx, *r.out.account_name, "*r.out.account_name");
4914 48 : torture_assert_not_null(tctx, r.out.authority_name, "r.out.authority_name");
4915 48 : torture_assert_not_null(tctx, *r.out.authority_name, "*r.out.authority_name");
4916 :
4917 80 : torture_comment(tctx,
4918 : "Account Name: %s, Authority Name: %s\n",
4919 48 : (*r.out.account_name)->string,
4920 48 : (*r.out.authority_name)->string);
4921 :
4922 48 : return true;
4923 : }
4924 :
4925 3 : static bool test_GetUserName_fail(struct dcerpc_binding_handle *b,
4926 : struct torture_context *tctx)
4927 : {
4928 : struct lsa_GetUserName r;
4929 3 : struct lsa_String *account_name_p = NULL;
4930 : NTSTATUS status;
4931 :
4932 3 : torture_comment(tctx, "\nTesting GetUserName_fail\n");
4933 :
4934 3 : r.in.system_name = "\\";
4935 3 : r.in.account_name = &account_name_p;
4936 3 : r.in.authority_name = NULL;
4937 3 : r.out.account_name = &account_name_p;
4938 :
4939 3 : status = dcerpc_lsa_GetUserName_r(b, tctx, &r);
4940 3 : if (!NT_STATUS_IS_OK(status)) {
4941 3 : if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4942 3 : torture_comment(tctx,
4943 : "GetUserName correctly returned with "
4944 : "status: %s\n",
4945 : nt_errstr(status));
4946 3 : return true;
4947 : }
4948 :
4949 0 : torture_assert_ntstatus_equal(tctx,
4950 : status,
4951 : NT_STATUS_ACCESS_DENIED,
4952 : "GetUserName return value should "
4953 : "be ACCESS_DENIED");
4954 0 : return true;
4955 : }
4956 :
4957 0 : if (!NT_STATUS_IS_OK(r.out.result)) {
4958 0 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
4959 0 : NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
4960 0 : torture_comment(tctx,
4961 : "GetUserName correctly returned with "
4962 : "result: %s\n",
4963 : nt_errstr(r.out.result));
4964 0 : return true;
4965 : }
4966 : }
4967 :
4968 0 : torture_assert_ntstatus_equal(tctx,
4969 : r.out.result,
4970 : NT_STATUS_OK,
4971 : "GetUserName return value should be "
4972 : "ACCESS_DENIED");
4973 :
4974 0 : return false;
4975 : }
4976 :
4977 131 : bool test_lsa_Close(struct dcerpc_binding_handle *b,
4978 : struct torture_context *tctx,
4979 : struct policy_handle *handle)
4980 : {
4981 : struct lsa_Close r;
4982 : struct policy_handle handle2;
4983 :
4984 131 : torture_comment(tctx, "\nTesting Close\n");
4985 :
4986 131 : r.in.handle = handle;
4987 131 : r.out.handle = &handle2;
4988 :
4989 131 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &r),
4990 : "Close failed");
4991 131 : torture_assert_ntstatus_ok(tctx, r.out.result,
4992 : "Close failed");
4993 :
4994 131 : torture_assert_ntstatus_equal(tctx, dcerpc_lsa_Close_r(b, tctx, &r),
4995 : NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "Close should failed");
4996 :
4997 131 : torture_comment(tctx, "\n");
4998 :
4999 131 : return true;
5000 : }
5001 :
5002 23 : bool torture_rpc_lsa(struct torture_context *tctx)
5003 : {
5004 : NTSTATUS status;
5005 : struct dcerpc_pipe *p;
5006 23 : bool ret = true;
5007 23 : struct policy_handle *handle = NULL;
5008 23 : struct test_join *join = NULL;
5009 : struct cli_credentials *machine_creds;
5010 : struct dcerpc_binding_handle *b;
5011 : enum dcerpc_transport_t transport;
5012 :
5013 23 : status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
5014 23 : torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
5015 :
5016 23 : b = p->binding_handle;
5017 23 : transport = dcerpc_binding_get_transport(p->binding);
5018 :
5019 : /* Test lsaLookupSids3 and lsaLookupNames4 over tcpip */
5020 23 : if (transport == NCACN_IP_TCP) {
5021 7 : if (!test_OpenPolicy_fail(b, tctx)) {
5022 0 : ret = false;
5023 : }
5024 :
5025 7 : if (!test_OpenPolicy2_fail(b, tctx)) {
5026 0 : ret = false;
5027 : }
5028 :
5029 7 : if (!test_many_LookupSids(p, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5030 0 : ret = false;
5031 : }
5032 :
5033 7 : return ret;
5034 : }
5035 :
5036 16 : if (!test_OpenPolicy(b, tctx)) {
5037 0 : ret = false;
5038 : }
5039 :
5040 16 : if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5041 0 : ret = false;
5042 : }
5043 :
5044 16 : if (handle) {
5045 16 : join = torture_join_domain(tctx, TEST_MACHINENAME, ACB_WSTRUST, &machine_creds);
5046 16 : if (!join) {
5047 0 : ret = false;
5048 : }
5049 :
5050 16 : if (!test_LookupSids_async(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5051 0 : ret = false;
5052 : }
5053 :
5054 16 : if (!test_QueryDomainInfoPolicy(b, tctx, handle)) {
5055 0 : ret = false;
5056 : }
5057 :
5058 16 : if (!test_CreateSecret(p, tctx, handle)) {
5059 3 : ret = false;
5060 : }
5061 :
5062 16 : if (!test_QueryInfoPolicy(b, tctx, handle)) {
5063 2 : ret = false;
5064 : }
5065 :
5066 16 : if (!test_QueryInfoPolicy2(b, tctx, handle)) {
5067 0 : ret = false;
5068 : }
5069 :
5070 16 : if (!test_Delete(b, tctx, handle)) {
5071 0 : ret = false;
5072 : }
5073 :
5074 16 : if (!test_many_LookupSids(p, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5075 0 : ret = false;
5076 : }
5077 :
5078 16 : if (!test_lsa_Close(b, tctx, handle)) {
5079 0 : ret = false;
5080 : }
5081 :
5082 16 : torture_leave_domain(tctx, join);
5083 :
5084 : } else {
5085 0 : if (!test_many_LookupSids(p, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5086 0 : ret = false;
5087 : }
5088 : }
5089 :
5090 16 : if (!test_GetUserName(b, tctx)) {
5091 0 : ret = false;
5092 : }
5093 :
5094 16 : return ret;
5095 : }
5096 :
5097 37 : bool torture_rpc_lsa_get_user(struct torture_context *tctx)
5098 : {
5099 : NTSTATUS status;
5100 : struct dcerpc_pipe *p;
5101 37 : bool ret = true;
5102 : struct dcerpc_binding_handle *b;
5103 : enum dcerpc_transport_t transport;
5104 :
5105 37 : status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
5106 37 : torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
5107 :
5108 35 : b = p->binding_handle;
5109 35 : transport = dcerpc_binding_get_transport(p->binding);
5110 :
5111 35 : if (transport == NCACN_IP_TCP) {
5112 3 : if (!test_GetUserName_fail(b, tctx)) {
5113 0 : ret = false;
5114 : }
5115 3 : return ret;
5116 : }
5117 :
5118 32 : if (!test_GetUserName(b, tctx)) {
5119 0 : ret = false;
5120 : }
5121 :
5122 32 : return ret;
5123 : }
5124 :
5125 7 : static bool testcase_LookupNames(struct torture_context *tctx,
5126 : struct dcerpc_pipe *p)
5127 : {
5128 7 : bool ret = true;
5129 : struct policy_handle *handle;
5130 : struct lsa_TransNameArray tnames;
5131 : struct lsa_TransNameArray2 tnames2;
5132 7 : struct dcerpc_binding_handle *b = p->binding_handle;
5133 7 : enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
5134 :
5135 7 : if (transport != NCACN_NP && transport != NCALRPC) {
5136 0 : torture_comment(tctx, "testcase_LookupNames is only available "
5137 : "over NCACN_NP or NCALRPC");
5138 0 : return true;
5139 : }
5140 :
5141 7 : if (!test_OpenPolicy(b, tctx)) {
5142 0 : ret = false;
5143 : }
5144 :
5145 7 : if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5146 0 : ret = false;
5147 : }
5148 :
5149 7 : if (!handle) {
5150 0 : ret = false;
5151 : }
5152 :
5153 7 : tnames.count = 1;
5154 7 : tnames.names = talloc_array(tctx, struct lsa_TranslatedName, tnames.count);
5155 7 : ZERO_STRUCT(tnames.names[0]);
5156 7 : tnames.names[0].name.string = "BUILTIN";
5157 7 : tnames.names[0].sid_type = SID_NAME_DOMAIN;
5158 :
5159 7 : if (!test_LookupNames(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames)) {
5160 0 : ret = false;
5161 : }
5162 :
5163 7 : tnames2.count = 1;
5164 7 : tnames2.names = talloc_array(tctx, struct lsa_TranslatedName2, tnames2.count);
5165 7 : ZERO_STRUCT(tnames2.names[0]);
5166 7 : tnames2.names[0].name.string = "BUILTIN";
5167 7 : tnames2.names[0].sid_type = SID_NAME_DOMAIN;
5168 :
5169 7 : if (!test_LookupNames2(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames2, true)) {
5170 0 : ret = false;
5171 : }
5172 :
5173 7 : if (!test_LookupNames3(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames2, true)) {
5174 0 : ret = false;
5175 : }
5176 :
5177 7 : if (!test_LookupNames_wellknown(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5178 0 : ret = false;
5179 : }
5180 :
5181 7 : if (!test_LookupNames_NULL(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5182 0 : ret = false;
5183 : }
5184 :
5185 7 : if (!test_LookupNames_bogus(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5186 0 : ret = false;
5187 : }
5188 :
5189 7 : if (!test_lsa_Close(b, tctx, handle)) {
5190 0 : ret = false;
5191 : }
5192 :
5193 7 : return ret;
5194 : }
5195 :
5196 2355 : struct torture_suite *torture_rpc_lsa_lookup_names(TALLOC_CTX *mem_ctx)
5197 : {
5198 : struct torture_suite *suite;
5199 : struct torture_rpc_tcase *tcase;
5200 :
5201 2355 : suite = torture_suite_create(mem_ctx, "lsa.lookupnames");
5202 :
5203 2355 : tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5204 : &ndr_table_lsarpc);
5205 2355 : torture_rpc_tcase_add_test(tcase, "LookupNames",
5206 : testcase_LookupNames);
5207 :
5208 2355 : return suite;
5209 : }
5210 :
5211 : struct lsa_trustdom_state {
5212 : uint32_t num_trusts;
5213 : };
5214 :
5215 3 : static bool testcase_TrustedDomains(struct torture_context *tctx,
5216 : struct dcerpc_pipe *p,
5217 : void *data)
5218 : {
5219 3 : bool ret = true;
5220 : struct policy_handle *handle;
5221 3 : struct lsa_trustdom_state *state =
5222 0 : talloc_get_type_abort(data, struct lsa_trustdom_state);
5223 3 : struct dcerpc_binding_handle *b = p->binding_handle;
5224 3 : enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
5225 :
5226 3 : if (transport != NCACN_NP && transport != NCALRPC) {
5227 0 : torture_comment(tctx, "testcase_TrustedDomains is only available "
5228 : "over NCACN_NP or NCALRPC");
5229 0 : return true;
5230 : }
5231 :
5232 3 : torture_comment(tctx, "Testing %d domains\n", state->num_trusts);
5233 :
5234 3 : if (!test_OpenPolicy(b, tctx)) {
5235 0 : ret = false;
5236 : }
5237 :
5238 3 : if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5239 0 : ret = false;
5240 : }
5241 :
5242 3 : if (!handle) {
5243 0 : ret = false;
5244 : }
5245 :
5246 3 : if (!test_CreateTrustedDomain(b, tctx, handle, state->num_trusts)) {
5247 0 : ret = false;
5248 : }
5249 :
5250 3 : if (!test_CreateTrustedDomainEx(p, tctx, handle, state->num_trusts)) {
5251 0 : ret = false;
5252 : }
5253 :
5254 3 : if (!test_CreateTrustedDomainEx2(p, tctx, handle, state->num_trusts)) {
5255 0 : ret = false;
5256 : }
5257 :
5258 3 : if (!test_lsa_Close(b, tctx, handle)) {
5259 0 : ret = false;
5260 : }
5261 :
5262 3 : return ret;
5263 : }
5264 :
5265 2355 : struct torture_suite *torture_rpc_lsa_trusted_domains(TALLOC_CTX *mem_ctx)
5266 : {
5267 : struct torture_suite *suite;
5268 : struct torture_rpc_tcase *tcase;
5269 : struct lsa_trustdom_state *state;
5270 :
5271 2355 : state = talloc(mem_ctx, struct lsa_trustdom_state);
5272 :
5273 2355 : state->num_trusts = 12;
5274 :
5275 2355 : suite = torture_suite_create(mem_ctx, "lsa.trusted.domains");
5276 :
5277 2355 : tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5278 : &ndr_table_lsarpc);
5279 2355 : torture_rpc_tcase_add_test_ex(tcase, "TrustedDomains",
5280 : testcase_TrustedDomains,
5281 : state);
5282 :
5283 2355 : return suite;
5284 : }
5285 :
5286 7 : static bool testcase_Privileges(struct torture_context *tctx,
5287 : struct dcerpc_pipe *p)
5288 : {
5289 : struct policy_handle *handle;
5290 7 : struct dcerpc_binding_handle *b = p->binding_handle;
5291 7 : enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
5292 :
5293 7 : if (transport != NCACN_NP && transport != NCALRPC) {
5294 0 : torture_skip(tctx, "testcase_Privileges is only available "
5295 : "over NCACN_NP or NCALRPC");
5296 : }
5297 :
5298 7 : if (!test_OpenPolicy(b, tctx)) {
5299 0 : return false;
5300 : }
5301 :
5302 7 : if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5303 0 : return false;
5304 : }
5305 :
5306 7 : if (!handle) {
5307 0 : return false;
5308 : }
5309 :
5310 7 : if (!test_CreateAccount(b, tctx, handle)) {
5311 0 : return false;
5312 : }
5313 :
5314 7 : if (!test_EnumAccounts(b, tctx, handle)) {
5315 0 : return false;
5316 : }
5317 :
5318 7 : if (!test_EnumPrivs(b, tctx, handle)) {
5319 0 : return false;
5320 : }
5321 :
5322 7 : if (!test_lsa_Close(b, tctx, handle)) {
5323 0 : return false;
5324 : }
5325 :
5326 7 : return true;
5327 : }
5328 :
5329 :
5330 2355 : struct torture_suite *torture_rpc_lsa_privileges(TALLOC_CTX *mem_ctx)
5331 : {
5332 : struct torture_suite *suite;
5333 : struct torture_rpc_tcase *tcase;
5334 :
5335 2355 : suite = torture_suite_create(mem_ctx, "lsa.privileges");
5336 :
5337 2355 : tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5338 : &ndr_table_lsarpc);
5339 2355 : torture_rpc_tcase_add_test(tcase, "Privileges",
5340 : testcase_Privileges);
5341 :
5342 2355 : return suite;
5343 : }
|