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 11894 : static void init_lsa_String(struct lsa_String *name, const char *s)
47 : {
48 11894 : name->string = s;
49 11894 : }
50 :
51 15 : 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 15 : uint16_t system_name = '\\';
59 :
60 15 : torture_comment(tctx, "\nTesting OpenPolicy\n");
61 :
62 15 : qos.len = 0;
63 15 : qos.impersonation_level = 2;
64 15 : qos.context_mode = 1;
65 15 : qos.effective_only = 0;
66 :
67 15 : attr.len = 0;
68 15 : attr.root_dir = NULL;
69 15 : attr.object_name = NULL;
70 15 : attr.attributes = 0;
71 15 : attr.sec_desc = NULL;
72 15 : attr.sec_qos = &qos;
73 :
74 15 : r.in.system_name = &system_name;
75 15 : r.in.attr = &attr;
76 15 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
77 15 : r.out.handle = &handle;
78 :
79 15 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy_r(b, tctx, &r),
80 : "OpenPolicy failed");
81 :
82 15 : torture_assert_ntstatus_ok(tctx,
83 : r.out.result,
84 : "OpenPolicy failed");
85 :
86 15 : return true;
87 : }
88 :
89 3 : 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 3 : uint16_t system_name = '\\';
97 : NTSTATUS status;
98 :
99 3 : torture_comment(tctx, "\nTesting OpenPolicy_fail\n");
100 :
101 3 : qos.len = 0;
102 3 : qos.impersonation_level = 2;
103 3 : qos.context_mode = 1;
104 3 : qos.effective_only = 0;
105 :
106 3 : attr.len = 0;
107 3 : attr.root_dir = NULL;
108 3 : attr.object_name = NULL;
109 3 : attr.attributes = 0;
110 3 : attr.sec_desc = NULL;
111 3 : attr.sec_qos = &qos;
112 :
113 3 : r.in.system_name = &system_name;
114 3 : r.in.attr = &attr;
115 3 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
116 3 : r.out.handle = &handle;
117 :
118 3 : status = dcerpc_lsa_OpenPolicy_r(b, tctx, &r);
119 3 : if (!NT_STATUS_IS_OK(status)) {
120 3 : if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
121 3 : torture_comment(tctx,
122 : "OpenPolicy correctly returned with "
123 : "status: %s\n",
124 : nt_errstr(status));
125 3 : 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 1696 : 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 1696 : torture_comment(tctx, "\nTesting OpenPolicy2\n");
169 :
170 1696 : *handle = talloc(tctx, struct policy_handle);
171 1696 : torture_assert(tctx, *handle != NULL, "talloc(tctx, struct policy_handle)");
172 :
173 1696 : qos.len = 0;
174 1696 : qos.impersonation_level = 2;
175 1696 : qos.context_mode = 1;
176 1696 : qos.effective_only = 0;
177 :
178 1696 : attr.len = 0;
179 1696 : attr.root_dir = NULL;
180 1696 : attr.object_name = NULL;
181 1696 : attr.attributes = 0;
182 1696 : attr.sec_desc = NULL;
183 1696 : attr.sec_qos = &qos;
184 :
185 1696 : r.in.system_name = "\\";
186 1696 : r.in.attr = &attr;
187 1696 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
188 1696 : r.out.handle = *handle;
189 :
190 1696 : status = dcerpc_lsa_OpenPolicy2_r(b, tctx, &r);
191 :
192 : /* Allow two possible failure status codes */
193 1696 : if (!NT_STATUS_EQUAL(status, expected_status2)) {
194 6 : torture_assert_ntstatus_equal(tctx, status,
195 : expected_status,
196 : "OpenPolicy2 failed");
197 : }
198 2714 : if (!NT_STATUS_IS_OK(expected_status) ||
199 1690 : !NT_STATUS_IS_OK(expected_status2)) {
200 6 : return true;
201 : }
202 :
203 1690 : torture_assert_ntstatus_ok(tctx,
204 : r.out.result,
205 : "OpenPolicy2 failed");
206 :
207 1690 : return true;
208 : }
209 :
210 :
211 1690 : bool test_lsa_OpenPolicy2(struct dcerpc_binding_handle *b,
212 : struct torture_context *tctx,
213 : struct policy_handle **handle)
214 : {
215 2362 : return test_lsa_OpenPolicy2_ex(b, tctx, handle,
216 1690 : NT_STATUS_OK, NT_STATUS_OK);
217 : }
218 :
219 3 : 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 3 : torture_comment(tctx, "\nTesting OpenPolicy2_fail\n");
229 :
230 3 : qos.len = 0;
231 3 : qos.impersonation_level = 2;
232 3 : qos.context_mode = 1;
233 3 : qos.effective_only = 0;
234 :
235 3 : attr.len = 0;
236 3 : attr.root_dir = NULL;
237 3 : attr.object_name = NULL;
238 3 : attr.attributes = 0;
239 3 : attr.sec_desc = NULL;
240 3 : attr.sec_qos = &qos;
241 :
242 3 : r.in.system_name = "\\";
243 3 : r.in.attr = &attr;
244 3 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
245 3 : r.out.handle = &handle;
246 :
247 3 : status = dcerpc_lsa_OpenPolicy2_r(b, tctx, &r);
248 3 : if (!NT_STATUS_IS_OK(status)) {
249 3 : if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
250 3 : torture_comment(tctx,
251 : "OpenPolicy2 correctly returned with "
252 : "status: %s\n",
253 : nt_errstr(status));
254 3 : 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 81 : 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 81 : struct lsa_RefDomainList *domains = NULL;
290 : struct lsa_String *names;
291 81 : uint32_t count = 0;
292 : int i;
293 : uint32_t *input_idx;
294 :
295 81 : torture_comment(tctx, "\nTesting LookupNames with %d names\n", tnames->count);
296 :
297 81 : sids.count = 0;
298 81 : sids.sids = NULL;
299 :
300 :
301 81 : r.in.num_names = 0;
302 :
303 81 : input_idx = talloc_array(tctx, uint32_t, tnames->count);
304 81 : names = talloc_array(tctx, struct lsa_String, tnames->count);
305 :
306 1083 : for (i=0;i<tnames->count;i++) {
307 1002 : if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
308 1002 : init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
309 1002 : input_idx[r.in.num_names] = i;
310 1002 : r.in.num_names++;
311 : }
312 : }
313 :
314 81 : r.in.handle = handle;
315 81 : r.in.names = names;
316 81 : r.in.sids = &sids;
317 81 : r.in.level = level;
318 81 : r.in.count = &count;
319 81 : r.out.count = &count;
320 81 : r.out.sids = &sids;
321 81 : r.out.domains = &domains;
322 :
323 81 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
324 : "LookupNames failed");
325 162 : if (NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED) ||
326 81 : 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 81 : } 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 1083 : for (i=0;i< r.in.num_names;i++) {
344 1002 : 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 1002 : 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 1002 : if (sids.sids[i].sid_type != SID_NAME_DOMAIN) {
357 900 : continue;
358 : }
359 102 : 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 81 : return true;
369 : }
370 :
371 3 : 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 3 : struct lsa_RefDomainList *domains = NULL;
379 : struct lsa_String names[1];
380 3 : uint32_t count = 0;
381 :
382 3 : torture_comment(tctx, "\nTesting LookupNames with bogus name\n");
383 :
384 3 : sids.count = 0;
385 3 : sids.sids = NULL;
386 :
387 3 : init_lsa_String(&names[0], "NT AUTHORITY\\BOGUS");
388 :
389 3 : r.in.handle = handle;
390 3 : r.in.num_names = 1;
391 3 : r.in.names = names;
392 3 : r.in.sids = &sids;
393 3 : r.in.level = level;
394 3 : r.in.count = &count;
395 3 : r.out.count = &count;
396 3 : r.out.sids = &sids;
397 3 : r.out.domains = &domains;
398 :
399 3 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
400 : "LookupNames bogus failed");
401 3 : 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 3 : torture_comment(tctx, "\n");
408 :
409 3 : return true;
410 : }
411 :
412 3 : 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 3 : struct lsa_RefDomainList *domains = NULL;
420 : struct lsa_String names[1];
421 3 : uint32_t count = 0;
422 :
423 3 : torture_comment(tctx, "\nTesting LookupNames with NULL name\n");
424 :
425 3 : sids.count = 0;
426 3 : sids.sids = NULL;
427 :
428 3 : names[0].string = NULL;
429 :
430 3 : r.in.handle = handle;
431 3 : r.in.num_names = 1;
432 3 : r.in.names = names;
433 3 : r.in.sids = &sids;
434 3 : r.in.level = level;
435 3 : r.in.count = &count;
436 3 : r.out.count = &count;
437 3 : r.out.sids = &sids;
438 3 : 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 3 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
448 : "LookupNames with NULL name failed");
449 3 : torture_assert_ntstatus_ok(tctx, r.out.result,
450 : "LookupNames with NULL name failed");
451 :
452 3 : torture_comment(tctx, "\n");
453 :
454 3 : return true;
455 : }
456 :
457 3 : 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 3 : bool ret = true;
465 :
466 3 : torture_comment(tctx, "Testing LookupNames with well known names\n");
467 :
468 3 : tnames.names = &name;
469 3 : tnames.count = 1;
470 3 : name.name.string = "NT AUTHORITY\\SYSTEM";
471 3 : name.sid_type = SID_NAME_WKN_GRP;
472 3 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
473 :
474 3 : name.name.string = "NT AUTHORITY\\ANONYMOUS LOGON";
475 3 : name.sid_type = SID_NAME_WKN_GRP;
476 3 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
477 :
478 3 : name.name.string = "NT AUTHORITY\\Authenticated Users";
479 3 : name.sid_type = SID_NAME_WKN_GRP;
480 3 : 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 3 : name.name.string = "BUILTIN\\";
491 3 : name.sid_type = SID_NAME_DOMAIN;
492 3 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
493 :
494 3 : name.name.string = "BUILTIN\\Administrators";
495 3 : name.sid_type = SID_NAME_ALIAS;
496 3 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
497 :
498 3 : name.name.string = "SYSTEM";
499 3 : name.sid_type = SID_NAME_WKN_GRP;
500 3 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
501 :
502 3 : name.name.string = "Everyone";
503 3 : name.sid_type = SID_NAME_WKN_GRP;
504 3 : ret &= test_LookupNames(b, tctx, handle, level, &tnames);
505 3 : return ret;
506 : }
507 :
508 6 : 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 6 : struct lsa_RefDomainList *domains = NULL;
518 : struct lsa_String *names;
519 : uint32_t *input_idx;
520 6 : uint32_t count = 0;
521 : int i;
522 :
523 6 : torture_comment(tctx, "\nTesting LookupNames2 with %d names\n", tnames->count);
524 :
525 6 : sids.count = 0;
526 6 : sids.sids = NULL;
527 :
528 6 : r.in.num_names = 0;
529 :
530 6 : input_idx = talloc_array(tctx, uint32_t, tnames->count);
531 6 : names = talloc_array(tctx, struct lsa_String, tnames->count);
532 :
533 27 : for (i=0;i<tnames->count;i++) {
534 21 : if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
535 21 : init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
536 21 : input_idx[r.in.num_names] = i;
537 21 : r.in.num_names++;
538 : }
539 : }
540 :
541 6 : r.in.handle = handle;
542 6 : r.in.names = names;
543 6 : r.in.sids = &sids;
544 6 : r.in.level = level;
545 6 : r.in.count = &count;
546 6 : r.in.lookup_options = 0;
547 6 : r.in.client_revision = 0;
548 6 : r.out.count = &count;
549 6 : r.out.sids = &sids;
550 6 : r.out.domains = &domains;
551 :
552 6 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames2_r(b, tctx, &r),
553 : "LookupNames2 failed");
554 6 : torture_assert_ntstatus_ok(tctx, r.out.result, "LookupNames2 failed");
555 :
556 6 : if (check_result) {
557 3 : torture_assert_int_equal(tctx, count, sids.count,
558 : "unexpected number of results returned");
559 3 : if (sids.count > 0) {
560 3 : torture_assert(tctx, sids.sids, "invalid sid buffer");
561 : }
562 : }
563 :
564 6 : torture_comment(tctx, "\n");
565 :
566 6 : return true;
567 : }
568 :
569 :
570 6 : 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 6 : struct lsa_RefDomainList *domains = NULL;
580 : struct lsa_String *names;
581 6 : uint32_t count = 0;
582 : int i;
583 : uint32_t *input_idx;
584 :
585 6 : torture_comment(tctx, "\nTesting LookupNames3 with %d names\n", tnames->count);
586 :
587 6 : sids.count = 0;
588 6 : sids.sids = NULL;
589 :
590 6 : r.in.num_names = 0;
591 :
592 6 : input_idx = talloc_array(tctx, uint32_t, tnames->count);
593 6 : names = talloc_array(tctx, struct lsa_String, tnames->count);
594 27 : for (i=0;i<tnames->count;i++) {
595 21 : if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
596 21 : init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
597 21 : input_idx[r.in.num_names] = i;
598 21 : r.in.num_names++;
599 : }
600 : }
601 :
602 6 : r.in.handle = handle;
603 6 : r.in.names = names;
604 6 : r.in.sids = &sids;
605 6 : r.in.level = level;
606 6 : r.in.count = &count;
607 6 : r.in.lookup_options = 0;
608 6 : r.in.client_revision = 0;
609 6 : r.out.count = &count;
610 6 : r.out.sids = &sids;
611 6 : r.out.domains = &domains;
612 :
613 6 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames3_r(b, tctx, &r),
614 : "LookupNames3 failed");
615 6 : torture_assert_ntstatus_ok(tctx, r.out.result,
616 : "LookupNames3 failed");
617 :
618 6 : if (check_result) {
619 3 : torture_assert_int_equal(tctx, count, sids.count,
620 : "unexpected number of results returned");
621 3 : if (sids.count > 0) {
622 3 : torture_assert(tctx, sids.sids, "invalid sid buffer");
623 : }
624 : }
625 :
626 6 : torture_comment(tctx, "\n");
627 :
628 6 : return true;
629 : }
630 :
631 216 : 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 216 : struct lsa_RefDomainList *domains = NULL;
640 : struct lsa_String *names;
641 216 : uint32_t count = 0;
642 : int i;
643 : uint32_t *input_idx;
644 :
645 216 : torture_comment(tctx, "\nTesting LookupNames4 with %d names\n", tnames->count);
646 :
647 216 : sids.count = 0;
648 216 : sids.sids = NULL;
649 :
650 216 : r.in.num_names = 0;
651 :
652 216 : input_idx = talloc_array(tctx, uint32_t, tnames->count);
653 216 : names = talloc_array(tctx, struct lsa_String, tnames->count);
654 11016 : for (i=0;i<tnames->count;i++) {
655 10800 : if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
656 10800 : init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
657 10800 : input_idx[r.in.num_names] = i;
658 10800 : r.in.num_names++;
659 : }
660 : }
661 :
662 216 : r.in.num_names = tnames->count;
663 216 : r.in.names = names;
664 216 : r.in.sids = &sids;
665 216 : r.in.level = level;
666 216 : r.in.count = &count;
667 216 : r.in.lookup_options = 0;
668 216 : r.in.client_revision = 0;
669 216 : r.out.count = &count;
670 216 : r.out.sids = &sids;
671 216 : r.out.domains = &domains;
672 :
673 216 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames4_r(b, tctx, &r),
674 : "LookupNames4 failed");
675 :
676 216 : if (!NT_STATUS_IS_OK(r.out.result)) {
677 108 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
678 108 : torture_comment(tctx,
679 : "LookupNames4 failed: %s - not considered as an error",
680 : nt_errstr(r.out.result));
681 :
682 108 : return true;
683 : }
684 : }
685 108 : torture_assert_ntstatus_ok(tctx,
686 : r.out.result,
687 : "LookupNames4 failed");
688 :
689 108 : if (check_result) {
690 108 : torture_assert_int_equal(tctx, count, sids.count,
691 : "unexpected number of results returned");
692 108 : if (sids.count > 0) {
693 108 : torture_assert(tctx, sids.sids, "invalid sid buffer");
694 : }
695 : }
696 :
697 108 : torture_comment(tctx, "\n");
698 :
699 108 : return true;
700 : }
701 :
702 6 : 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 6 : struct lsa_RefDomainList *domains = NULL;
709 6 : struct lsa_String *names = NULL;
710 6 : uint32_t count = 0;
711 : NTSTATUS status;
712 :
713 6 : torture_comment(tctx, "\nTesting LookupNames4_fail");
714 :
715 6 : sids.count = 0;
716 6 : sids.sids = NULL;
717 :
718 6 : r.in.num_names = 0;
719 :
720 6 : r.in.num_names = count;
721 6 : r.in.names = names;
722 6 : r.in.sids = &sids;
723 6 : r.in.level = level;
724 6 : r.in.count = &count;
725 6 : r.in.lookup_options = 0;
726 6 : r.in.client_revision = 0;
727 6 : r.out.count = &count;
728 6 : r.out.sids = &sids;
729 6 : r.out.domains = &domains;
730 :
731 6 : status = dcerpc_lsa_LookupNames4_r(b, tctx, &r);
732 6 : if (!NT_STATUS_IS_OK(status)) {
733 6 : if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
734 6 : torture_comment(tctx,
735 : "LookupNames4 correctly returned with "
736 : "status: %s\n",
737 : nt_errstr(status));
738 6 : 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 3 : 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 3 : struct lsa_RefDomainList *domains = NULL;
777 3 : uint32_t count = sids->num_sids;
778 :
779 3 : torture_comment(tctx, "\nTesting LookupSids\n");
780 :
781 3 : names.count = 0;
782 3 : names.names = NULL;
783 :
784 3 : r.in.handle = handle;
785 3 : r.in.sids = sids;
786 3 : r.in.names = &names;
787 3 : r.in.level = level;
788 3 : r.in.count = &count;
789 3 : r.out.count = &count;
790 3 : r.out.names = &names;
791 3 : r.out.domains = &domains;
792 :
793 3 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids_r(b, tctx, &r),
794 : "LookupSids failed");
795 3 : if (!NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED)) {
796 3 : torture_assert_ntstatus_ok(tctx, r.out.result,
797 : "LookupSids failed");
798 : }
799 :
800 3 : torture_comment(tctx, "\n");
801 :
802 3 : if (!test_LookupNames(b, tctx, handle, level, &names)) {
803 0 : return false;
804 : }
805 :
806 3 : return true;
807 : }
808 :
809 :
810 3 : 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 3 : struct lsa_RefDomainList *domains = NULL;
819 3 : uint32_t count = sids->num_sids;
820 :
821 3 : torture_comment(tctx, "\nTesting LookupSids2\n");
822 :
823 3 : names.count = 0;
824 3 : names.names = NULL;
825 :
826 3 : r.in.handle = handle;
827 3 : r.in.sids = sids;
828 3 : r.in.names = &names;
829 3 : r.in.level = level;
830 3 : r.in.count = &count;
831 3 : r.in.lookup_options = 0;
832 3 : r.in.client_revision = 0;
833 3 : r.out.count = &count;
834 3 : r.out.names = &names;
835 3 : r.out.domains = &domains;
836 :
837 3 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids2_r(b, tctx, &r),
838 : "LookupSids2 failed");
839 3 : 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 3 : torture_comment(tctx, "\n");
847 :
848 3 : if (!test_LookupNames2(b, tctx, handle, level, &names, false)) {
849 0 : return false;
850 : }
851 :
852 3 : if (!test_LookupNames3(b, tctx, handle, level, &names, false)) {
853 0 : return false;
854 : }
855 :
856 3 : return true;
857 : }
858 :
859 108 : 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 108 : struct lsa_RefDomainList *domains = NULL;
867 108 : uint32_t count = sids->num_sids;
868 :
869 108 : torture_comment(tctx, "\nTesting LookupSids3\n");
870 :
871 108 : names.count = 0;
872 108 : names.names = NULL;
873 :
874 108 : r.in.sids = sids;
875 108 : r.in.names = &names;
876 108 : r.in.level = level;
877 108 : r.in.count = &count;
878 108 : r.in.lookup_options = 0;
879 108 : r.in.client_revision = 0;
880 108 : r.out.domains = &domains;
881 108 : r.out.count = &count;
882 108 : r.out.names = &names;
883 :
884 108 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids3_r(b, tctx, &r),
885 : "LookupSids3 failed");
886 :
887 108 : 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 108 : torture_comment(tctx, "\n");
904 :
905 108 : if (!test_LookupNames4(b, tctx, level, &names, true)) {
906 0 : return false;
907 : }
908 :
909 108 : return true;
910 : }
911 :
912 6 : 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 6 : struct lsa_RefDomainList *domains = NULL;
920 6 : uint32_t count = sids->num_sids;
921 : NTSTATUS status;
922 :
923 6 : torture_comment(tctx, "\nTesting LookupSids3\n");
924 :
925 6 : names.count = 0;
926 6 : names.names = NULL;
927 :
928 6 : r.in.sids = sids;
929 6 : r.in.names = &names;
930 6 : r.in.level = level;
931 6 : r.in.count = &count;
932 6 : r.in.lookup_options = 0;
933 6 : r.in.client_revision = 0;
934 6 : r.out.domains = &domains;
935 6 : r.out.count = &count;
936 6 : r.out.names = &names;
937 :
938 6 : status = dcerpc_lsa_LookupSids3_r(b, tctx, &r);
939 6 : if (!NT_STATUS_IS_OK(status)) {
940 6 : if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
941 6 : torture_comment(tctx,
942 : "LookupSids3 correctly returned with "
943 : "status: %s\n",
944 : nt_errstr(status));
945 6 : 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 117 : 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 117 : struct dcerpc_binding_handle *b = p->binding_handle;
981 117 : enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
982 :
983 117 : torture_comment(tctx, "\nTesting LookupSids with lots of SIDs\n");
984 :
985 117 : sids.num_sids = 100;
986 :
987 117 : sids.sids = talloc_array(tctx, struct lsa_SidPtr, sids.num_sids);
988 :
989 11817 : for (i=0; i<sids.num_sids; i++) {
990 11700 : const char *sidstr = "S-1-5-32-545";
991 11700 : sids.sids[i].sid = dom_sid_parse_talloc(tctx, sidstr);
992 : }
993 :
994 117 : count = sids.num_sids;
995 :
996 117 : if (handle) {
997 : struct lsa_LookupSids r;
998 : struct lsa_TransNameArray names;
999 6 : struct lsa_RefDomainList *domains = NULL;
1000 6 : names.count = 0;
1001 6 : names.names = NULL;
1002 :
1003 6 : r.in.handle = handle;
1004 6 : r.in.sids = &sids;
1005 6 : r.in.names = &names;
1006 6 : r.in.level = level;
1007 6 : r.in.count = &names.count;
1008 6 : r.out.count = &count;
1009 6 : r.out.names = &names;
1010 6 : r.out.domains = &domains;
1011 :
1012 6 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids_r(b, tctx, &r),
1013 : "LookupSids failed");
1014 6 : 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 6 : torture_comment(tctx, "\n");
1021 :
1022 6 : if (!test_LookupNames(b, tctx, handle, level, &names)) {
1023 0 : return false;
1024 : }
1025 : }
1026 :
1027 117 : if (transport == NCACN_NP) {
1028 3 : if (!test_LookupSids3_fail(b, tctx, level, &sids)) {
1029 0 : return false;
1030 : }
1031 3 : if (!test_LookupNames4_fail(b, tctx, level)) {
1032 0 : return false;
1033 : }
1034 114 : } 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 111 : names.count = 0;
1040 111 : names.names = NULL;
1041 :
1042 111 : dcerpc_binding_handle_auth_info(p->binding_handle,
1043 : &auth_type, &auth_level);
1044 :
1045 219 : if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL &&
1046 108 : auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) {
1047 108 : if (!test_LookupSids3(b, tctx, level, &sids)) {
1048 0 : return false;
1049 : }
1050 216 : 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 3 : if (!test_LookupSids3_fail(b, tctx, level, &sids)) {
1059 0 : return false;
1060 : }
1061 3 : if (!test_LookupNames4_fail(b, tctx, level)) {
1062 0 : return false;
1063 : }
1064 : }
1065 : }
1066 :
1067 117 : torture_comment(tctx, "\n");
1068 :
1069 :
1070 :
1071 117 : return true;
1072 : }
1073 :
1074 300 : static void lookupsids_cb(struct tevent_req *subreq)
1075 : {
1076 300 : int *replies = (int *)tevent_req_callback_data_void(subreq);
1077 : NTSTATUS status;
1078 :
1079 300 : status = dcerpc_lsa_LookupSids_r_recv(subreq, subreq);
1080 300 : TALLOC_FREE(subreq);
1081 300 : if (!NT_STATUS_IS_OK(status)) {
1082 0 : printf("lookupsids returned %s\n", nt_errstr(status));
1083 0 : *replies = -1;
1084 : }
1085 :
1086 300 : if (*replies >= 0) {
1087 300 : *replies += 1;
1088 : }
1089 300 : }
1090 :
1091 6 : 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 6 : struct lsa_RefDomainList *domains = NULL;
1102 : struct tevent_req **req;
1103 : int i, replies;
1104 6 : bool ret = true;
1105 6 : const int num_async_requests = 50;
1106 :
1107 6 : count = talloc_array(tctx, uint32_t, num_async_requests);
1108 6 : names = talloc_array(tctx, struct lsa_TransNameArray, num_async_requests);
1109 6 : r = talloc_array(tctx, struct lsa_LookupSids, num_async_requests);
1110 :
1111 6 : torture_comment(tctx, "\nTesting %d async lookupsids request\n", num_async_requests);
1112 :
1113 6 : req = talloc_array(tctx, struct tevent_req *, num_async_requests);
1114 :
1115 6 : sids.num_sids = 1;
1116 6 : sids.sids = &sidptr;
1117 6 : sidptr.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-545");
1118 :
1119 6 : replies = 0;
1120 :
1121 306 : for (i=0; i<num_async_requests; i++) {
1122 300 : count[i] = 0;
1123 300 : names[i].count = 0;
1124 300 : names[i].names = NULL;
1125 :
1126 300 : r[i].in.handle = handle;
1127 300 : r[i].in.sids = &sids;
1128 300 : r[i].in.names = &names[i];
1129 300 : r[i].in.level = level;
1130 300 : r[i].in.count = &names[i].count;
1131 300 : r[i].out.count = &count[i];
1132 300 : r[i].out.names = &names[i];
1133 300 : r[i].out.domains = &domains;
1134 :
1135 300 : req[i] = dcerpc_lsa_LookupSids_r_send(tctx, tctx->ev, b, &r[i]);
1136 300 : if (req[i] == NULL) {
1137 0 : ret = false;
1138 0 : break;
1139 : }
1140 :
1141 300 : tevent_req_set_callback(req[i], lookupsids_cb, &replies);
1142 : }
1143 :
1144 2729 : while (replies >= 0 && replies < num_async_requests) {
1145 2717 : tevent_loop_once(tctx->ev);
1146 : }
1147 :
1148 6 : talloc_free(req);
1149 :
1150 6 : if (replies < 0) {
1151 0 : ret = false;
1152 : }
1153 :
1154 6 : return ret;
1155 : }
1156 :
1157 75 : 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 75 : r.in.handle = handle;
1166 75 : r.in.name = name;
1167 75 : r.out.luid = &luid;
1168 :
1169 75 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivValue_r(b, tctx, &r),
1170 : "LookupPrivValue failed");
1171 75 : torture_assert_ntstatus_ok(tctx, r.out.result,
1172 : "LookupPrivValue failed");
1173 :
1174 75 : return true;
1175 : }
1176 :
1177 96 : 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 96 : struct lsa_StringLarge *name = NULL;
1184 :
1185 96 : r.in.handle = handle;
1186 96 : r.in.luid = luid;
1187 96 : r.out.name = &name;
1188 :
1189 96 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivName_r(b, tctx, &r),
1190 : "LookupPrivName failed");
1191 96 : torture_assert_ntstatus_ok(tctx, r.out.result, "LookupPrivName failed");
1192 :
1193 96 : return true;
1194 : }
1195 :
1196 15 : 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 15 : bool ret = true;
1205 :
1206 15 : torture_comment(tctx, "\nTesting RemovePrivilegesFromAccount\n");
1207 :
1208 15 : r.in.handle = acct_handle;
1209 15 : r.in.remove_all = 0;
1210 15 : r.in.privs = &privs;
1211 :
1212 15 : privs.count = 1;
1213 15 : privs.unknown = 0;
1214 15 : privs.set = talloc_array(tctx, struct lsa_LUIDAttribute, 1);
1215 15 : privs.set[0].luid = *luid;
1216 15 : privs.set[0].attribute = 0;
1217 :
1218 15 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_RemovePrivilegesFromAccount_r(b, tctx, &r),
1219 : "RemovePrivilegesFromAccount failed");
1220 15 : 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 15 : return ret;
1248 : }
1249 :
1250 15 : 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 15 : bool ret = true;
1258 :
1259 15 : torture_comment(tctx, "\nTesting AddPrivilegesToAccount\n");
1260 :
1261 15 : r.in.handle = acct_handle;
1262 15 : r.in.privs = &privs;
1263 :
1264 15 : privs.count = 1;
1265 15 : privs.unknown = 0;
1266 15 : privs.set = talloc_array(tctx, struct lsa_LUIDAttribute, 1);
1267 15 : privs.set[0].luid = *luid;
1268 15 : privs.set[0].attribute = 0;
1269 :
1270 15 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddPrivilegesToAccount_r(b, tctx, &r),
1271 : "AddPrivilegesToAccount failed");
1272 15 : torture_assert_ntstatus_ok(tctx, r.out.result,
1273 : "AddPrivilegesToAccount failed");
1274 15 : return ret;
1275 : }
1276 :
1277 18 : 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 18 : struct lsa_PrivilegeSet *privs = NULL;
1284 18 : bool ret = true;
1285 :
1286 18 : torture_comment(tctx, "\nTesting EnumPrivsAccount\n");
1287 :
1288 18 : r.in.handle = acct_handle;
1289 18 : r.out.privs = &privs;
1290 :
1291 18 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumPrivsAccount_r(b, tctx, &r),
1292 : "EnumPrivsAccount failed");
1293 18 : torture_assert_ntstatus_ok(tctx, r.out.result,
1294 : "EnumPrivsAccount failed");
1295 :
1296 18 : if (privs && privs->count > 0) {
1297 : int i;
1298 111 : for (i=0;i<privs->count;i++) {
1299 96 : test_LookupPrivName(b, tctx, handle,
1300 96 : &privs->set[i].luid);
1301 : }
1302 :
1303 15 : ret &= test_RemovePrivilegesFromAccount(b, tctx, handle, acct_handle,
1304 15 : &privs->set[0].luid);
1305 15 : ret &= test_AddPrivilegesToAccount(b, tctx, acct_handle,
1306 15 : &privs->set[0].luid);
1307 : }
1308 :
1309 18 : return ret;
1310 : }
1311 :
1312 18 : 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 18 : torture_comment(tctx, "\nTesting GetSystemAccessAccount\n");
1321 :
1322 18 : r.in.handle = acct_handle;
1323 18 : r.out.access_mask = &access_mask;
1324 :
1325 18 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(b, tctx, &r),
1326 : "GetSystemAccessAccount failed");
1327 18 : torture_assert_ntstatus_ok(tctx, r.out.result,
1328 : "GetSystemAccessAccount failed");
1329 :
1330 18 : if (r.out.access_mask != NULL) {
1331 18 : torture_comment(tctx, "Rights:");
1332 18 : if (*(r.out.access_mask) & LSA_POLICY_MODE_INTERACTIVE)
1333 15 : torture_comment(tctx, " LSA_POLICY_MODE_INTERACTIVE");
1334 18 : if (*(r.out.access_mask) & LSA_POLICY_MODE_NETWORK)
1335 3 : torture_comment(tctx, " LSA_POLICY_MODE_NETWORK");
1336 18 : if (*(r.out.access_mask) & LSA_POLICY_MODE_BATCH)
1337 0 : torture_comment(tctx, " LSA_POLICY_MODE_BATCH");
1338 18 : if (*(r.out.access_mask) & LSA_POLICY_MODE_SERVICE)
1339 0 : torture_comment(tctx, " LSA_POLICY_MODE_SERVICE");
1340 18 : if (*(r.out.access_mask) & LSA_POLICY_MODE_PROXY)
1341 0 : torture_comment(tctx, " LSA_POLICY_MODE_PROXY");
1342 18 : if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_INTERACTIVE)
1343 0 : torture_comment(tctx, " LSA_POLICY_MODE_DENY_INTERACTIVE");
1344 18 : if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_NETWORK)
1345 0 : torture_comment(tctx, " LSA_POLICY_MODE_DENY_NETWORK");
1346 18 : if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_BATCH)
1347 0 : torture_comment(tctx, " LSA_POLICY_MODE_DENY_BATCH");
1348 18 : if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_SERVICE)
1349 0 : torture_comment(tctx, " LSA_POLICY_MODE_DENY_SERVICE");
1350 18 : if (*(r.out.access_mask) & LSA_POLICY_MODE_REMOTE_INTERACTIVE)
1351 6 : torture_comment(tctx, " LSA_POLICY_MODE_REMOTE_INTERACTIVE");
1352 18 : if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE)
1353 0 : torture_comment(tctx, " LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE");
1354 18 : if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL)
1355 18 : torture_comment(tctx, " LSA_POLICY_MODE_ALL");
1356 18 : if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL_NT4)
1357 15 : torture_comment(tctx, " LSA_POLICY_MODE_ALL_NT4");
1358 18 : torture_comment(tctx, "\n");
1359 : }
1360 :
1361 18 : return true;
1362 : }
1363 :
1364 19 : 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 19 : torture_comment(tctx, "\nTesting Delete\n");
1371 :
1372 19 : r.in.handle = handle;
1373 19 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Delete_r(b, tctx, &r),
1374 : "Delete failed");
1375 19 : torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_SUPPORTED,
1376 : "Delete should have failed NT_STATUS_NOT_SUPPORTED");
1377 :
1378 19 : return true;
1379 : }
1380 :
1381 13 : 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 13 : torture_comment(tctx, "\nTesting DeleteObject\n");
1388 :
1389 13 : r.in.handle = handle;
1390 13 : r.out.handle = handle;
1391 13 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(b, tctx, &r),
1392 : "DeleteObject failed");
1393 13 : torture_assert_ntstatus_ok(tctx, r.out.result,
1394 : "DeleteObject failed");
1395 :
1396 13 : return true;
1397 : }
1398 :
1399 :
1400 3 : 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 3 : newsid = dom_sid_parse_talloc(tctx, "S-1-5-12349876-4321-2854");
1409 :
1410 3 : torture_comment(tctx, "\nTesting CreateAccount\n");
1411 :
1412 3 : r.in.handle = handle;
1413 3 : r.in.sid = newsid;
1414 3 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1415 3 : r.out.acct_handle = &acct_handle;
1416 :
1417 3 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateAccount_r(b, tctx, &r),
1418 : "CreateAccount failed");
1419 3 : 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 3 : torture_assert_ntstatus_ok(tctx, r.out.result,
1432 : "CreateAccount failed");
1433 : }
1434 :
1435 3 : if (!test_Delete(b, tctx, &acct_handle)) {
1436 0 : return false;
1437 : }
1438 :
1439 3 : if (!test_DeleteObject(b, tctx, &acct_handle)) {
1440 0 : return false;
1441 : }
1442 :
1443 3 : 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 6 : 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 6 : bool ret = true;
1513 : DATA_BLOB session_key;
1514 : NTTIME old_mtime, new_mtime;
1515 : DATA_BLOB blob1;
1516 6 : const char *secret1 = "abcdef12345699qwerty";
1517 : char *secret2;
1518 6 : const char *secret3 = "ABCDEF12345699QWERTY";
1519 : char *secret4;
1520 6 : const char *secret5 = "NEW-SAMBA4-SECRET";
1521 : char *secret6;
1522 : char *secname[2];
1523 : int i;
1524 6 : const int LOCAL = 0;
1525 6 : const int GLOBAL = 1;
1526 6 : struct dcerpc_binding_handle *b = p->binding_handle;
1527 :
1528 6 : secname[LOCAL] = talloc_asprintf(tctx, "torturesecret-%u", (unsigned int)random());
1529 6 : secname[GLOBAL] = talloc_asprintf(tctx, "G$torturesecret-%u", (unsigned int)random());
1530 :
1531 16 : for (i=0; i< 2; i++) {
1532 11 : torture_comment(tctx, "\nTesting CreateSecret of %s\n", secname[i]);
1533 :
1534 11 : init_lsa_String(&r.in.name, secname[i]);
1535 :
1536 11 : r.in.handle = handle;
1537 11 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1538 11 : r.out.sec_handle = &sec_handle;
1539 :
1540 11 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateSecret_r(b, tctx, &r),
1541 : "CreateSecret failed");
1542 11 : torture_assert_ntstatus_ok(tctx, r.out.result,
1543 : "CreateSecret failed");
1544 :
1545 11 : r.in.handle = handle;
1546 11 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1547 11 : r.out.sec_handle = &sec_handle3;
1548 :
1549 11 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateSecret_r(b, tctx, &r),
1550 : "CreateSecret failed");
1551 11 : torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_COLLISION,
1552 : "CreateSecret should have failed OBJECT_NAME_COLLISION");
1553 :
1554 11 : r2.in.handle = handle;
1555 11 : r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1556 11 : r2.in.name = r.in.name;
1557 11 : r2.out.sec_handle = &sec_handle2;
1558 :
1559 11 : torture_comment(tctx, "Testing OpenSecret\n");
1560 :
1561 11 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(b, tctx, &r2),
1562 : "OpenSecret failed");
1563 11 : torture_assert_ntstatus_ok(tctx, r2.out.result,
1564 : "OpenSecret failed");
1565 :
1566 11 : torture_assert_ntstatus_ok(tctx, dcerpc_fetch_session_key(p, &session_key),
1567 : "dcerpc_fetch_session_key failed");
1568 :
1569 10 : enc_key = sess_encrypt_string(secret1, &session_key);
1570 :
1571 10 : r3.in.sec_handle = &sec_handle;
1572 10 : r3.in.new_val = &buf1;
1573 10 : r3.in.old_val = NULL;
1574 10 : r3.in.new_val->data = enc_key.data;
1575 10 : r3.in.new_val->length = enc_key.length;
1576 10 : r3.in.new_val->size = enc_key.length;
1577 :
1578 10 : torture_comment(tctx, "Testing SetSecret\n");
1579 :
1580 10 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r3),
1581 : "SetSecret failed");
1582 10 : torture_assert_ntstatus_ok(tctx, r3.out.result,
1583 : "SetSecret failed");
1584 :
1585 10 : r3.in.sec_handle = &sec_handle;
1586 10 : r3.in.new_val = &buf1;
1587 10 : r3.in.old_val = NULL;
1588 10 : r3.in.new_val->data = enc_key.data;
1589 10 : r3.in.new_val->length = enc_key.length;
1590 10 : r3.in.new_val->size = enc_key.length;
1591 :
1592 : /* break the encrypted data */
1593 10 : enc_key.data[0]++;
1594 :
1595 10 : torture_comment(tctx, "Testing SetSecret with broken key\n");
1596 :
1597 10 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r3),
1598 : "SetSecret failed");
1599 10 : torture_assert_ntstatus_equal(tctx, r3.out.result, NT_STATUS_UNKNOWN_REVISION,
1600 : "SetSecret should have failed UNKNOWN_REVISION");
1601 :
1602 10 : data_blob_free(&enc_key);
1603 :
1604 10 : ZERO_STRUCT(new_mtime);
1605 10 : ZERO_STRUCT(old_mtime);
1606 :
1607 : /* fetch the secret back again */
1608 10 : r4.in.sec_handle = &sec_handle;
1609 10 : r4.in.new_val = &bufp1;
1610 10 : r4.in.new_mtime = &new_mtime;
1611 10 : r4.in.old_val = NULL;
1612 10 : r4.in.old_mtime = NULL;
1613 :
1614 10 : bufp1.buf = NULL;
1615 :
1616 10 : torture_comment(tctx, "Testing QuerySecret\n");
1617 10 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r4),
1618 : "QuerySecret failed");
1619 10 : 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 10 : 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 10 : blob1.data = r4.out.new_val->buf->data;
1628 10 : blob1.length = r4.out.new_val->buf->size;
1629 :
1630 10 : secret2 = sess_decrypt_string(tctx,
1631 : &blob1, &session_key);
1632 :
1633 10 : 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 10 : enc_key = sess_encrypt_string(secret3, &session_key);
1642 :
1643 10 : r5.in.sec_handle = &sec_handle;
1644 10 : r5.in.new_val = &buf1;
1645 10 : r5.in.old_val = NULL;
1646 10 : r5.in.new_val->data = enc_key.data;
1647 10 : r5.in.new_val->length = enc_key.length;
1648 10 : r5.in.new_val->size = enc_key.length;
1649 :
1650 :
1651 10 : smb_msleep(200);
1652 10 : torture_comment(tctx, "Testing SetSecret (existing value should move to old)\n");
1653 :
1654 10 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r5),
1655 : "SetSecret failed");
1656 10 : 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 10 : data_blob_free(&enc_key);
1662 :
1663 10 : ZERO_STRUCT(new_mtime);
1664 10 : ZERO_STRUCT(old_mtime);
1665 :
1666 : /* fetch the secret back again */
1667 10 : r6.in.sec_handle = &sec_handle;
1668 10 : r6.in.new_val = &bufp1;
1669 10 : r6.in.new_mtime = &new_mtime;
1670 10 : r6.in.old_val = &bufp2;
1671 10 : r6.in.old_mtime = &old_mtime;
1672 :
1673 10 : bufp1.buf = NULL;
1674 10 : bufp2.buf = NULL;
1675 :
1676 10 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r6),
1677 : "QuerySecret failed");
1678 10 : 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 10 : if (r6.out.new_val->buf == NULL || r6.out.old_val->buf == NULL
1685 10 : || 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 10 : blob1.data = r6.out.new_val->buf->data;
1691 10 : blob1.length = r6.out.new_val->buf->size;
1692 :
1693 10 : secret4 = sess_decrypt_string(tctx,
1694 : &blob1, &session_key);
1695 :
1696 10 : 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 10 : blob1.data = r6.out.old_val->buf->data;
1702 10 : blob1.length = r6.out.old_val->buf->length;
1703 :
1704 10 : secret2 = sess_decrypt_string(tctx,
1705 : &blob1, &session_key);
1706 :
1707 10 : 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 10 : 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 10 : enc_key = sess_encrypt_string(secret5, &session_key);
1724 :
1725 10 : r7.in.sec_handle = &sec_handle;
1726 10 : r7.in.old_val = &buf1;
1727 10 : r7.in.old_val->data = enc_key.data;
1728 10 : r7.in.old_val->length = enc_key.length;
1729 10 : r7.in.old_val->size = enc_key.length;
1730 10 : r7.in.new_val = NULL;
1731 :
1732 10 : torture_comment(tctx, "Testing SetSecret of old Secret only\n");
1733 :
1734 10 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r7),
1735 : "SetSecret failed");
1736 10 : 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 10 : data_blob_free(&enc_key);
1742 :
1743 : /* fetch the secret back again */
1744 10 : r8.in.sec_handle = &sec_handle;
1745 10 : r8.in.new_val = &bufp1;
1746 10 : r8.in.new_mtime = &new_mtime;
1747 10 : r8.in.old_val = &bufp2;
1748 10 : r8.in.old_mtime = &old_mtime;
1749 :
1750 10 : bufp1.buf = NULL;
1751 10 : bufp2.buf = NULL;
1752 :
1753 10 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r8),
1754 : "QuerySecret failed");
1755 10 : 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 10 : 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 10 : } 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 10 : } 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 10 : } 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 10 : blob1.data = r8.out.old_val->buf->data;
1773 10 : blob1.length = r8.out.old_val->buf->size;
1774 :
1775 10 : secret6 = sess_decrypt_string(tctx,
1776 : &blob1, &session_key);
1777 :
1778 10 : 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 10 : 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 10 : if (!test_Delete(b, tctx, &sec_handle)) {
1794 0 : ret = false;
1795 : }
1796 :
1797 10 : if (!test_DeleteObject(b, tctx, &sec_handle)) {
1798 0 : return false;
1799 : }
1800 :
1801 10 : d_o.in.handle = &sec_handle2;
1802 10 : d_o.out.handle = &sec_handle2;
1803 10 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(b, tctx, &d_o),
1804 : "DeleteObject failed");
1805 10 : torture_assert_ntstatus_equal(tctx, d_o.out.result, NT_STATUS_INVALID_HANDLE,
1806 : "OpenSecret expected INVALID_HANDLE");
1807 :
1808 10 : torture_comment(tctx, "Testing OpenSecret of just-deleted secret\n");
1809 :
1810 10 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(b, tctx, &r2),
1811 : "OpenSecret failed");
1812 10 : torture_assert_ntstatus_equal(tctx, r2.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
1813 : "OpenSecret expected OBJECT_NAME_NOT_FOUND");
1814 : }
1815 5 : return ret;
1816 : }
1817 :
1818 :
1819 18 : 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 18 : torture_comment(tctx, "\nTesting EnumAccountRights\n");
1828 :
1829 18 : r.in.handle = acct_handle;
1830 18 : r.in.sid = sid;
1831 18 : r.out.rights = &rights;
1832 :
1833 18 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(b, tctx, &r),
1834 : "EnumAccountRights failed");
1835 18 : 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 18 : torture_assert_ntstatus_ok(tctx, r.out.result,
1840 : "EnumAccountRights failed");
1841 :
1842 18 : return true;
1843 : }
1844 :
1845 :
1846 18 : 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 18 : struct sec_desc_buf *sdbuf = NULL;
1853 :
1854 18 : 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 0 : torture_comment(tctx, "\nTesting QuerySecurity\n");
1860 :
1861 0 : r.in.handle = acct_handle;
1862 0 : r.in.sec_info = SECINFO_OWNER |
1863 : SECINFO_GROUP |
1864 : SECINFO_DACL;
1865 0 : r.out.sdbuf = &sdbuf;
1866 :
1867 0 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecurity_r(b, tctx, &r),
1868 : "QuerySecurity failed");
1869 0 : 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 0 : return true;
1875 : }
1876 :
1877 18 : 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 18 : torture_comment(tctx, "\nTesting OpenAccount\n");
1886 :
1887 18 : r.in.handle = handle;
1888 18 : r.in.sid = sid;
1889 18 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1890 18 : r.out.acct_handle = &acct_handle;
1891 :
1892 18 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(b, tctx, &r),
1893 : "OpenAccount failed");
1894 18 : torture_assert_ntstatus_ok(tctx, r.out.result,
1895 : "OpenAccount failed");
1896 :
1897 18 : if (!test_EnumPrivsAccount(b, tctx, handle, &acct_handle)) {
1898 0 : return false;
1899 : }
1900 :
1901 18 : if (!test_GetSystemAccessAccount(b, tctx, handle, &acct_handle)) {
1902 0 : return false;
1903 : }
1904 :
1905 18 : if (!test_QuerySecurity(b, tctx, handle, &acct_handle)) {
1906 0 : return false;
1907 : }
1908 :
1909 18 : return true;
1910 : }
1911 :
1912 3 : 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 3 : uint32_t resume_handle = 0;
1919 : int i;
1920 3 : bool ret = true;
1921 :
1922 3 : torture_comment(tctx, "\nTesting EnumAccounts\n");
1923 :
1924 3 : r.in.handle = handle;
1925 3 : r.in.resume_handle = &resume_handle;
1926 3 : r.in.num_entries = 100;
1927 3 : r.out.resume_handle = &resume_handle;
1928 3 : r.out.sids = &sids1;
1929 :
1930 3 : resume_handle = 0;
1931 : while (true) {
1932 9 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(b, tctx, &r),
1933 : "EnumAccounts failed");
1934 6 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
1935 3 : break;
1936 : }
1937 3 : torture_assert_ntstatus_ok(tctx, r.out.result,
1938 : "EnumAccounts failed");
1939 :
1940 3 : if (!test_LookupSids(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &sids1)) {
1941 0 : return false;
1942 : }
1943 :
1944 3 : 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 3 : torture_comment(tctx, "Testing all accounts\n");
1953 21 : for (i=0;i<sids1.num_sids;i++) {
1954 18 : ret &= test_OpenAccount(b, tctx, handle, sids1.sids[i].sid);
1955 18 : ret &= test_EnumAccountRights(b, tctx, handle, sids1.sids[i].sid);
1956 : }
1957 3 : torture_comment(tctx, "\n");
1958 : }
1959 :
1960 3 : if (sids1.num_sids < 3) {
1961 3 : 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 75 : 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 75 : uint16_t language_id = (random() % 4) + 0x409;
1991 75 : uint16_t returned_language_id = 0;
1992 75 : struct lsa_StringLarge *disp_name = NULL;
1993 :
1994 75 : torture_comment(tctx, "\nTesting LookupPrivDisplayName(%s)\n", priv_name->string);
1995 :
1996 75 : r.in.handle = handle;
1997 75 : r.in.name = priv_name;
1998 75 : r.in.language_id = language_id;
1999 75 : r.in.language_id_sys = 0;
2000 75 : r.out.returned_language_id = &returned_language_id;
2001 75 : r.out.disp_name = &disp_name;
2002 :
2003 75 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivDisplayName_r(b, tctx, &r),
2004 : "LookupPrivDisplayName failed");
2005 75 : 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 225 : torture_comment(tctx, "%s -> \"%s\" (language 0x%x/0x%x)\n",
2010 75 : priv_name->string, disp_name->string,
2011 150 : r.in.language_id, *r.out.returned_language_id);
2012 :
2013 75 : return true;
2014 : }
2015 :
2016 75 : 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 75 : ZERO_STRUCT(sids);
2025 :
2026 75 : torture_comment(tctx, "\nTesting EnumAccountsWithUserRight(%s)\n", priv_name->string);
2027 :
2028 75 : r.in.handle = handle;
2029 75 : r.in.name = priv_name;
2030 75 : r.out.sids = &sids;
2031 :
2032 75 : 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 75 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2037 12 : return true;
2038 : }
2039 :
2040 63 : 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 63 : return true;
2046 : }
2047 :
2048 :
2049 3 : 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 3 : uint32_t resume_handle = 0;
2056 : int i;
2057 3 : bool ret = true;
2058 :
2059 3 : torture_comment(tctx, "\nTesting EnumPrivs\n");
2060 :
2061 3 : r.in.handle = handle;
2062 3 : r.in.resume_handle = &resume_handle;
2063 3 : r.in.max_count = 100;
2064 3 : r.out.resume_handle = &resume_handle;
2065 3 : r.out.privs = &privs1;
2066 :
2067 3 : resume_handle = 0;
2068 3 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumPrivs_r(b, tctx, &r),
2069 : "EnumPrivs failed");
2070 3 : torture_assert_ntstatus_ok(tctx, r.out.result,
2071 : "EnumPrivs failed");
2072 :
2073 78 : for (i = 0; i< privs1.count; i++) {
2074 75 : test_LookupPrivDisplayName(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name);
2075 75 : test_LookupPrivValue(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name);
2076 75 : if (!test_EnumAccountsWithUserRight(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name)) {
2077 0 : ret = false;
2078 : }
2079 : }
2080 :
2081 3 : 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 : const char *server_nb_domain;
2965 : const char *server_dns_domain;
2966 : struct {
2967 : unsigned io;
2968 : unsigned fail;
2969 : unsigned errors;
2970 : unsigned error_io;
2971 : unsigned ok;
2972 : } counts;
2973 : krb5_error error;
2974 : struct smb_krb5_context *smb_krb5_context;
2975 : krb5_get_init_creds_opt *krb_options;
2976 : krb5_creds my_creds;
2977 : krb5_get_creds_opt opt_canon;
2978 : krb5_get_creds_opt opt_nocanon;
2979 : krb5_principal upn_realm;
2980 : krb5_principal upn_dns;
2981 : krb5_principal upn_netbios;
2982 : krb5_ccache krbtgt_ccache;
2983 : krb5_principal krbtgt_trust_realm;
2984 : krb5_creds *krbtgt_trust_realm_creds;
2985 : krb5_principal krbtgt_trust_dns;
2986 : krb5_creds *krbtgt_trust_dns_creds;
2987 : krb5_principal krbtgt_trust_netbios;
2988 : krb5_creds *krbtgt_trust_netbios_creds;
2989 : krb5_principal cifs_trust_dns;
2990 : krb5_creds *cifs_trust_dns_creds;
2991 : krb5_principal cifs_trust_netbios;
2992 : krb5_creds *cifs_trust_netbios_creds;
2993 : krb5_principal drs_trust_dns;
2994 : krb5_creds *drs_trust_dns_creds;
2995 : krb5_principal drs_trust_netbios;
2996 : krb5_creds *drs_trust_netbios_creds;
2997 : krb5_principal four_trust_dns;
2998 : krb5_creds *four_trust_dns_creds;
2999 : krb5_creds krbtgt_referral_creds;
3000 : Ticket krbtgt_referral_ticket;
3001 : krb5_keyblock krbtgt_referral_keyblock;
3002 : EncTicketPart krbtgt_referral_enc_part;
3003 : };
3004 :
3005 2184 : static krb5_error_code check_pw_with_krb5_send_to_realm(
3006 : struct smb_krb5_context *smb_krb5_context,
3007 : void *data, /* struct check_pw_with_krb5_ctx */
3008 : krb5_const_realm realm,
3009 : time_t timeout,
3010 : const krb5_data *send_buf,
3011 : krb5_data *recv_buf)
3012 : {
3013 2184 : struct check_pw_with_krb5_ctx *ctx =
3014 : talloc_get_type_abort(data, struct check_pw_with_krb5_ctx);
3015 : krb5_error_code k5ret;
3016 : size_t used;
3017 : int ret;
3018 :
3019 2184 : SMB_ASSERT(smb_krb5_context == ctx->smb_krb5_context);
3020 :
3021 4368 : if (!strequal_m(realm, ctx->server_nb_domain) &&
3022 2184 : !strequal_m(realm, ctx->server_dns_domain))
3023 : {
3024 540 : return KRB5_KDC_UNREACH;
3025 : }
3026 :
3027 1644 : krb5_free_error_contents(ctx->smb_krb5_context->krb5_context,
3028 : &ctx->error);
3029 1644 : ctx->counts.io++;
3030 :
3031 1644 : k5ret = smb_krb5_send_and_recv_func_forced_tcp(ctx->smb_krb5_context,
3032 : ctx->server,
3033 : timeout, send_buf, recv_buf);
3034 1644 : if (k5ret != 0) {
3035 0 : ctx->counts.fail++;
3036 0 : return k5ret;
3037 : }
3038 :
3039 1644 : ret = decode_KRB_ERROR(recv_buf->data, recv_buf->length,
3040 1644 : &ctx->error, &used);
3041 1644 : if (ret == 0) {
3042 636 : ctx->counts.errors++;
3043 636 : ctx->counts.error_io = ctx->counts.io;
3044 : } else {
3045 1008 : ctx->counts.ok++;
3046 : }
3047 :
3048 1644 : return k5ret;
3049 : }
3050 :
3051 84 : static int check_pw_with_krb5_ctx_destructor(struct check_pw_with_krb5_ctx *ctx)
3052 : {
3053 84 : if (ctx->server != NULL) {
3054 84 : freeaddrinfo(ctx->server);
3055 84 : ctx->server = NULL;
3056 : }
3057 :
3058 84 : if (ctx->krb_options != NULL) {
3059 84 : krb5_get_init_creds_opt_free(ctx->smb_krb5_context->krb5_context,
3060 : ctx->krb_options);
3061 84 : ctx->krb_options = NULL;
3062 : }
3063 :
3064 84 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3065 : &ctx->my_creds);
3066 :
3067 84 : if (ctx->opt_canon != NULL) {
3068 72 : krb5_get_creds_opt_free(ctx->smb_krb5_context->krb5_context,
3069 : ctx->opt_canon);
3070 72 : ctx->opt_canon = NULL;
3071 : }
3072 :
3073 84 : if (ctx->opt_nocanon != NULL) {
3074 72 : krb5_get_creds_opt_free(ctx->smb_krb5_context->krb5_context,
3075 : ctx->opt_nocanon);
3076 72 : ctx->opt_nocanon = NULL;
3077 : }
3078 :
3079 84 : if (ctx->krbtgt_ccache != NULL) {
3080 72 : krb5_cc_close(ctx->smb_krb5_context->krb5_context,
3081 : ctx->krbtgt_ccache);
3082 72 : ctx->krbtgt_ccache = NULL;
3083 : }
3084 :
3085 84 : if (ctx->upn_realm != NULL) {
3086 84 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3087 : ctx->upn_realm);
3088 84 : ctx->upn_realm = NULL;
3089 : }
3090 :
3091 84 : if (ctx->upn_dns != NULL) {
3092 84 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3093 : ctx->upn_dns);
3094 84 : ctx->upn_dns = NULL;
3095 : }
3096 :
3097 84 : if (ctx->upn_netbios != NULL) {
3098 84 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3099 : ctx->upn_netbios);
3100 84 : ctx->upn_netbios = NULL;
3101 : }
3102 :
3103 84 : if (ctx->krbtgt_trust_realm != NULL) {
3104 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3105 : ctx->krbtgt_trust_realm);
3106 72 : ctx->krbtgt_trust_realm = NULL;
3107 : }
3108 :
3109 84 : if (ctx->krbtgt_trust_realm_creds != NULL) {
3110 72 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3111 : ctx->krbtgt_trust_realm_creds);
3112 72 : ctx->krbtgt_trust_realm_creds = NULL;
3113 : }
3114 :
3115 84 : if (ctx->krbtgt_trust_dns != NULL) {
3116 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3117 : ctx->krbtgt_trust_dns);
3118 72 : ctx->krbtgt_trust_dns = NULL;
3119 : }
3120 :
3121 84 : if (ctx->krbtgt_trust_dns_creds != NULL) {
3122 72 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3123 : ctx->krbtgt_trust_dns_creds);
3124 72 : ctx->krbtgt_trust_dns_creds = NULL;
3125 : }
3126 :
3127 84 : if (ctx->krbtgt_trust_netbios != NULL) {
3128 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3129 : ctx->krbtgt_trust_netbios);
3130 72 : ctx->krbtgt_trust_netbios = NULL;
3131 : }
3132 :
3133 84 : if (ctx->krbtgt_trust_netbios_creds != NULL) {
3134 72 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3135 : ctx->krbtgt_trust_netbios_creds);
3136 72 : ctx->krbtgt_trust_netbios_creds = NULL;
3137 : }
3138 :
3139 84 : if (ctx->cifs_trust_dns != NULL) {
3140 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3141 : ctx->cifs_trust_dns);
3142 72 : ctx->cifs_trust_dns = NULL;
3143 : }
3144 :
3145 84 : if (ctx->cifs_trust_dns_creds != NULL) {
3146 0 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3147 : ctx->cifs_trust_dns_creds);
3148 0 : ctx->cifs_trust_dns_creds = NULL;
3149 : }
3150 :
3151 84 : if (ctx->cifs_trust_netbios != NULL) {
3152 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3153 : ctx->cifs_trust_netbios);
3154 72 : ctx->cifs_trust_netbios = NULL;
3155 : }
3156 :
3157 84 : if (ctx->cifs_trust_netbios_creds != NULL) {
3158 0 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3159 : ctx->cifs_trust_netbios_creds);
3160 0 : ctx->cifs_trust_netbios_creds = NULL;
3161 : }
3162 :
3163 84 : if (ctx->drs_trust_dns != NULL) {
3164 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3165 : ctx->drs_trust_dns);
3166 72 : ctx->drs_trust_dns = NULL;
3167 : }
3168 :
3169 84 : if (ctx->drs_trust_dns_creds != NULL) {
3170 0 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3171 : ctx->drs_trust_dns_creds);
3172 0 : ctx->drs_trust_dns_creds = NULL;
3173 : }
3174 :
3175 84 : if (ctx->drs_trust_netbios != NULL) {
3176 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3177 : ctx->drs_trust_netbios);
3178 72 : ctx->drs_trust_netbios = NULL;
3179 : }
3180 :
3181 84 : if (ctx->drs_trust_netbios_creds != NULL) {
3182 0 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3183 : ctx->drs_trust_netbios_creds);
3184 0 : ctx->drs_trust_netbios_creds = NULL;
3185 : }
3186 :
3187 84 : if (ctx->four_trust_dns != NULL) {
3188 72 : krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3189 : ctx->four_trust_dns);
3190 72 : ctx->four_trust_dns = NULL;
3191 : }
3192 :
3193 84 : if (ctx->four_trust_dns_creds != NULL) {
3194 0 : krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3195 : ctx->four_trust_dns_creds);
3196 0 : ctx->four_trust_dns_creds = NULL;
3197 : }
3198 :
3199 84 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3200 : &ctx->krbtgt_referral_creds);
3201 :
3202 84 : free_Ticket(&ctx->krbtgt_referral_ticket);
3203 :
3204 84 : krb5_free_keyblock_contents(ctx->smb_krb5_context->krb5_context,
3205 : &ctx->krbtgt_referral_keyblock);
3206 :
3207 84 : free_EncTicketPart(&ctx->krbtgt_referral_enc_part);
3208 :
3209 84 : krb5_free_error_contents(ctx->smb_krb5_context->krb5_context,
3210 : &ctx->error);
3211 :
3212 84 : talloc_unlink(ctx, ctx->smb_krb5_context);
3213 84 : ctx->smb_krb5_context = NULL;
3214 84 : return 0;
3215 : }
3216 :
3217 84 : static bool check_pw_with_krb5(struct torture_context *tctx,
3218 : struct cli_credentials *credentials,
3219 : const struct lsa_TrustDomainInfoInfoEx *trusted)
3220 : {
3221 84 : const char *trusted_dns_name = trusted->domain_name.string;
3222 84 : const char *trusted_netbios_name = trusted->netbios_name.string;
3223 84 : char *trusted_realm_name = NULL;
3224 84 : krb5_principal principal = NULL;
3225 : enum credentials_obtained obtained;
3226 84 : const char *error_string = NULL;
3227 84 : const char *workstation = cli_credentials_get_workstation(credentials);
3228 84 : const char *password = cli_credentials_get_password(credentials);
3229 : #ifndef USING_EMBEDDED_HEIMDAL
3230 : const struct samr_Password *nthash = NULL;
3231 : const struct samr_Password *old_nthash = NULL;
3232 : #endif
3233 84 : const char *old_password = cli_credentials_get_old_password(credentials);
3234 : #ifndef USING_EMBEDDED_HEIMDAL
3235 : int kvno = cli_credentials_get_kvno(credentials);
3236 : int expected_kvno = 0;
3237 : krb5uint32 t_kvno = 0;
3238 : #endif
3239 84 : const char *host = torture_setting_string(tctx, "host", NULL);
3240 : krb5_error_code k5ret;
3241 : krb5_boolean k5ok;
3242 : int type;
3243 : bool ok;
3244 84 : struct check_pw_with_krb5_ctx *ctx = NULL;
3245 84 : char *assertion_message = NULL;
3246 84 : const char *realm = NULL;
3247 84 : char *upn_realm_string = NULL;
3248 84 : char *upn_dns_string = NULL;
3249 84 : char *upn_netbios_string = NULL;
3250 84 : char *krbtgt_cc_name = NULL;
3251 84 : char *krbtgt_trust_realm_string = NULL;
3252 84 : char *krbtgt_trust_dns_string = NULL;
3253 84 : char *krbtgt_trust_netbios_string = NULL;
3254 84 : char *cifs_trust_dns_string = NULL;
3255 84 : char *cifs_trust_netbios_string = NULL;
3256 84 : char *drs_trust_dns_string = NULL;
3257 84 : char *drs_trust_netbios_string = NULL;
3258 84 : char *four_trust_dns_string = NULL;
3259 :
3260 84 : ctx = talloc_zero(tctx, struct check_pw_with_krb5_ctx);
3261 84 : torture_assert(tctx, ctx != NULL, "Failed to allocate");
3262 :
3263 84 : realm = cli_credentials_get_realm(credentials);
3264 84 : trusted_realm_name = strupper_talloc(tctx, trusted_dns_name);
3265 :
3266 : #ifndef USING_EMBEDDED_HEIMDAL
3267 : nthash = cli_credentials_get_nt_hash(credentials, ctx);
3268 : old_nthash = cli_credentials_get_old_nt_hash(credentials, ctx);
3269 : #endif
3270 :
3271 84 : k5ret = smb_krb5_init_context(ctx, tctx->lp_ctx, &ctx->smb_krb5_context);
3272 84 : torture_assert_int_equal(tctx, k5ret, 0, "smb_krb5_init_context failed");
3273 :
3274 84 : ctx->server_nb_domain = cli_credentials_get_domain(credentials);
3275 84 : ctx->server_dns_domain = cli_credentials_get_realm(credentials);
3276 :
3277 84 : ok = interpret_string_addr_internal(&ctx->server, host, 0);
3278 84 : torture_assert(tctx, ok, "Failed to parse target server");
3279 84 : talloc_set_destructor(ctx, check_pw_with_krb5_ctx_destructor);
3280 :
3281 84 : set_sockaddr_port(ctx->server->ai_addr, 88);
3282 :
3283 84 : k5ret = smb_krb5_set_send_to_kdc_func(ctx->smb_krb5_context,
3284 : check_pw_with_krb5_send_to_realm,
3285 : NULL, /* send_to_kdc */
3286 : ctx);
3287 84 : torture_assert_int_equal(tctx, k5ret, 0, "krb5_set_send_to_kdc_func failed");
3288 :
3289 84 : torture_assert_int_equal(tctx,
3290 : krb5_get_init_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3291 : &ctx->krb_options),
3292 : 0, "krb5_get_init_creds_opt_alloc failed");
3293 84 : torture_assert_int_equal(tctx,
3294 : krb5_get_init_creds_opt_set_pac_request(
3295 : ctx->smb_krb5_context->krb5_context,
3296 : ctx->krb_options, true),
3297 : 0, "krb5_get_init_creds_opt_set_pac_request failed");
3298 :
3299 84 : upn_realm_string = talloc_asprintf(ctx, "user@%s",
3300 : trusted_realm_name);
3301 84 : torture_assert_int_equal(tctx,
3302 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3303 : &ctx->upn_realm,
3304 : realm, upn_realm_string, NULL),
3305 : 0, "smb_krb5_make_principal failed");
3306 84 : smb_krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3307 : ctx->upn_realm, KRB5_NT_ENTERPRISE_PRINCIPAL);
3308 :
3309 84 : upn_dns_string = talloc_asprintf(ctx, "user@%s",
3310 : trusted_dns_name);
3311 84 : torture_assert_int_equal(tctx,
3312 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3313 : &ctx->upn_dns,
3314 : realm, upn_dns_string, NULL),
3315 : 0, "smb_krb5_make_principal failed");
3316 84 : smb_krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3317 : ctx->upn_dns, KRB5_NT_ENTERPRISE_PRINCIPAL);
3318 :
3319 84 : upn_netbios_string = talloc_asprintf(ctx, "user@%s",
3320 : trusted_netbios_name);
3321 84 : torture_assert_int_equal(tctx,
3322 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3323 : &ctx->upn_netbios,
3324 : realm, upn_netbios_string, NULL),
3325 : 0, "smb_krb5_make_principal failed");
3326 84 : smb_krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3327 : ctx->upn_netbios, KRB5_NT_ENTERPRISE_PRINCIPAL);
3328 :
3329 84 : k5ret = principal_from_credentials(ctx, credentials, ctx->smb_krb5_context,
3330 : &principal, &obtained, &error_string);
3331 84 : torture_assert_int_equal(tctx, k5ret, 0, error_string);
3332 :
3333 84 : ZERO_STRUCT(ctx->counts);
3334 84 : k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3335 : &ctx->my_creds, ctx->upn_realm,
3336 : "_none_", NULL, NULL, 0,
3337 : NULL, ctx->krb_options);
3338 252 : assertion_message = talloc_asprintf(ctx,
3339 : "krb5_get_init_creds_password(%s, canon) for failed: "
3340 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3341 : upn_realm_string,
3342 : k5ret,
3343 84 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3344 : k5ret, ctx),
3345 : trusted->trust_direction,
3346 84 : trusted->trust_type,
3347 : trusted->trust_attributes,
3348 : ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3349 84 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3350 84 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3351 84 : torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3352 84 : torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
3353 84 : torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3354 84 : torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3355 : #ifdef USING_EMBEDDED_HEIMDAL
3356 84 : torture_assert(tctx, ctx->error.cname != NULL, assertion_message);
3357 84 : torture_assert_int_equal(tctx, ctx->error.cname->name_type, KRB5_NT_ENTERPRISE_PRINCIPAL, assertion_message);
3358 84 : torture_assert_int_equal(tctx, ctx->error.cname->name_string.len, 1, assertion_message);
3359 84 : torture_assert_str_equal(tctx, ctx->error.cname->name_string.val[0], upn_realm_string, assertion_message);
3360 : #else
3361 : torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3362 : #endif
3363 84 : torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3364 :
3365 84 : ZERO_STRUCT(ctx->counts);
3366 84 : k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3367 : &ctx->my_creds, ctx->upn_dns,
3368 : "_none_", NULL, NULL, 0,
3369 : NULL, ctx->krb_options);
3370 252 : assertion_message = talloc_asprintf(ctx,
3371 : "krb5_get_init_creds_password(%s, canon) for failed: "
3372 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3373 : upn_dns_string,
3374 : k5ret,
3375 84 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3376 : k5ret, ctx),
3377 : trusted->trust_direction,
3378 84 : trusted->trust_type,
3379 : trusted->trust_attributes,
3380 : ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3381 84 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3382 84 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3383 84 : torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3384 84 : torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
3385 84 : torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3386 84 : torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3387 : #ifdef USING_EMBEDDED_HEIMDAL
3388 84 : torture_assert(tctx, ctx->error.cname != NULL, assertion_message);
3389 84 : torture_assert_int_equal(tctx, ctx->error.cname->name_type, KRB5_NT_ENTERPRISE_PRINCIPAL, assertion_message);
3390 84 : torture_assert_int_equal(tctx, ctx->error.cname->name_string.len, 1, assertion_message);
3391 84 : torture_assert_str_equal(tctx, ctx->error.cname->name_string.val[0], upn_dns_string, assertion_message);
3392 : #else
3393 : torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3394 : #endif
3395 84 : torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3396 :
3397 84 : ZERO_STRUCT(ctx->counts);
3398 84 : k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3399 : &ctx->my_creds, ctx->upn_netbios,
3400 : "_none_", NULL, NULL, 0,
3401 : NULL, ctx->krb_options);
3402 252 : assertion_message = talloc_asprintf(ctx,
3403 : "krb5_get_init_creds_password(%s, canon) for failed: "
3404 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3405 : upn_netbios_string,
3406 : k5ret,
3407 84 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3408 : k5ret, ctx),
3409 : trusted->trust_direction,
3410 84 : trusted->trust_type,
3411 : trusted->trust_attributes,
3412 : ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3413 84 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3414 84 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3415 84 : torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3416 84 : torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
3417 84 : torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3418 84 : torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3419 : #ifdef USING_EMBEDDED_HEIMDAL
3420 84 : torture_assert(tctx, ctx->error.cname != NULL, assertion_message);
3421 84 : torture_assert_int_equal(tctx, ctx->error.cname->name_type, KRB5_NT_ENTERPRISE_PRINCIPAL, assertion_message);
3422 84 : torture_assert_int_equal(tctx, ctx->error.cname->name_string.len, 1, assertion_message);
3423 84 : torture_assert_str_equal(tctx, ctx->error.cname->name_string.val[0], upn_netbios_string, assertion_message);
3424 : #else
3425 : torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3426 : #endif
3427 84 : torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3428 :
3429 84 : torture_comment(tctx, "(%s:%s) password[%s] old_password[%s]\n",
3430 : __location__, __FUNCTION__,
3431 : password, old_password);
3432 84 : if (old_password != NULL) {
3433 72 : k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3434 : &ctx->my_creds, principal,
3435 : old_password, NULL, NULL, 0,
3436 : NULL, ctx->krb_options);
3437 72 : torture_assert_int_equal(tctx, k5ret, KRB5KDC_ERR_PREAUTH_FAILED,
3438 : "preauth should fail with old password");
3439 : }
3440 :
3441 84 : k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3442 : &ctx->my_creds, principal,
3443 : password, NULL, NULL, 0,
3444 : NULL, ctx->krb_options);
3445 84 : if (k5ret == KRB5KDC_ERR_PREAUTH_FAILED) {
3446 12 : TALLOC_FREE(ctx);
3447 12 : return false;
3448 : }
3449 :
3450 72 : assertion_message = talloc_asprintf(ctx,
3451 : "krb5_get_init_creds_password for failed: %s",
3452 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3453 : k5ret, ctx));
3454 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3455 :
3456 72 : torture_assert_int_equal(tctx,
3457 : krb5_get_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3458 : &ctx->opt_canon),
3459 : 0, "krb5_get_creds_opt_alloc");
3460 :
3461 72 : krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3462 : ctx->opt_canon,
3463 : KRB5_GC_CANONICALIZE);
3464 :
3465 72 : krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3466 : ctx->opt_canon,
3467 : KRB5_GC_NO_STORE);
3468 :
3469 72 : torture_assert_int_equal(tctx,
3470 : krb5_get_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3471 : &ctx->opt_nocanon),
3472 : 0, "krb5_get_creds_opt_alloc");
3473 :
3474 72 : krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3475 : ctx->opt_nocanon,
3476 : KRB5_GC_NO_STORE);
3477 :
3478 72 : krbtgt_cc_name = talloc_asprintf(ctx, "MEMORY:%p.krbtgt", ctx->smb_krb5_context);
3479 72 : torture_assert_int_equal(tctx,
3480 : krb5_cc_resolve(ctx->smb_krb5_context->krb5_context,
3481 : krbtgt_cc_name,
3482 : &ctx->krbtgt_ccache),
3483 : 0, "krb5_cc_resolve failed");
3484 :
3485 72 : torture_assert_int_equal(tctx,
3486 : krb5_cc_initialize(ctx->smb_krb5_context->krb5_context,
3487 : ctx->krbtgt_ccache,
3488 : ctx->my_creds.client),
3489 : 0, "krb5_cc_initialize failed");
3490 :
3491 72 : torture_assert_int_equal(tctx,
3492 : krb5_cc_store_cred(ctx->smb_krb5_context->krb5_context,
3493 : ctx->krbtgt_ccache,
3494 : &ctx->my_creds),
3495 : 0, "krb5_cc_store_cred failed");
3496 :
3497 72 : krbtgt_trust_realm_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3498 : trusted_realm_name, realm);
3499 72 : torture_assert_int_equal(tctx,
3500 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3501 : &ctx->krbtgt_trust_realm,
3502 : realm, "krbtgt",
3503 : trusted_realm_name, NULL),
3504 : 0, "smb_krb5_make_principal failed");
3505 :
3506 72 : krbtgt_trust_dns_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3507 : trusted_dns_name, realm);
3508 72 : torture_assert_int_equal(tctx,
3509 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3510 : &ctx->krbtgt_trust_dns,
3511 : realm, "krbtgt",
3512 : trusted_dns_name, NULL),
3513 : 0, "smb_krb5_make_principal failed");
3514 :
3515 72 : krbtgt_trust_netbios_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3516 : trusted_netbios_name, realm);
3517 72 : torture_assert_int_equal(tctx,
3518 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3519 : &ctx->krbtgt_trust_netbios,
3520 : realm, "krbtgt",
3521 : trusted_netbios_name, NULL),
3522 : 0, "smb_krb5_make_principal failed");
3523 :
3524 : /* Confirm if we can do a TGS for krbtgt/trusted_realm */
3525 72 : ZERO_STRUCT(ctx->counts);
3526 144 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3527 : ctx->opt_nocanon,
3528 : ctx->krbtgt_ccache,
3529 72 : ctx->krbtgt_trust_realm,
3530 : &ctx->krbtgt_trust_realm_creds);
3531 216 : assertion_message = talloc_asprintf(ctx,
3532 : "krb5_get_creds(%s, canon) for failed: "
3533 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3534 : krbtgt_trust_realm_string,
3535 : k5ret,
3536 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3537 : k5ret, ctx),
3538 : trusted->trust_direction,
3539 72 : trusted->trust_type,
3540 : trusted->trust_attributes,
3541 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3542 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3543 72 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3544 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3545 :
3546 72 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3547 72 : ctx->krbtgt_trust_realm_creds->server,
3548 72 : ctx->krbtgt_trust_realm);
3549 72 : torture_assert(tctx, k5ok, assertion_message);
3550 72 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3551 72 : ctx->krbtgt_trust_realm_creds->server);
3552 72 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3553 :
3554 : /* Confirm if we have no referral ticket in the cache */
3555 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3556 : &ctx->krbtgt_referral_creds);
3557 144 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3558 : ctx->krbtgt_ccache,
3559 : 0,
3560 72 : ctx->krbtgt_trust_realm_creds,
3561 : &ctx->krbtgt_referral_creds);
3562 72 : assertion_message = talloc_asprintf(ctx,
3563 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3564 : krbtgt_trust_realm_string,
3565 : k5ret,
3566 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3567 : k5ret, ctx));
3568 72 : torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3569 :
3570 : /* Confirm if we can do a TGS for krbtgt/trusted_dns with CANON */
3571 72 : ZERO_STRUCT(ctx->counts);
3572 144 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3573 : ctx->opt_canon,
3574 : ctx->krbtgt_ccache,
3575 72 : ctx->krbtgt_trust_dns,
3576 : &ctx->krbtgt_trust_dns_creds);
3577 216 : assertion_message = talloc_asprintf(ctx,
3578 : "krb5_get_creds(%s, canon) for failed: "
3579 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3580 : krbtgt_trust_dns_string,
3581 : k5ret,
3582 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3583 : k5ret, ctx),
3584 : trusted->trust_direction,
3585 72 : trusted->trust_type,
3586 : trusted->trust_attributes,
3587 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3588 : #ifdef USING_EMBEDDED_HEIMDAL
3589 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3590 : #else
3591 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3592 : #endif
3593 72 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3594 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3595 :
3596 : /* Confirm if we have the referral ticket in the cache */
3597 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3598 : &ctx->krbtgt_referral_creds);
3599 144 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3600 : ctx->krbtgt_ccache,
3601 : 0,
3602 72 : ctx->krbtgt_trust_realm_creds,
3603 : &ctx->krbtgt_referral_creds);
3604 72 : assertion_message = talloc_asprintf(ctx,
3605 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3606 : krbtgt_trust_realm_string,
3607 : k5ret,
3608 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3609 : k5ret, ctx));
3610 : #ifdef USING_EMBEDDED_HEIMDAL
3611 72 : torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3612 : #else
3613 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3614 :
3615 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3616 : ctx->krbtgt_referral_creds.server,
3617 : ctx->krbtgt_trust_realm);
3618 : torture_assert(tctx, k5ok, assertion_message);
3619 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3620 : ctx->krbtgt_referral_creds.server);
3621 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3622 : k5ret = decode_Ticket(ctx->krbtgt_referral_creds.ticket.data,
3623 : ctx->krbtgt_referral_creds.ticket.length,
3624 : &ctx->krbtgt_referral_ticket, NULL);
3625 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3626 : if (kvno > 0) {
3627 : expected_kvno = kvno - 1;
3628 : }
3629 : if (ctx->krbtgt_referral_ticket.enc_part.kvno != NULL) {
3630 : t_kvno = *ctx->krbtgt_referral_ticket.enc_part.kvno;
3631 : assertion_message = talloc_asprintf(ctx,
3632 : "krbtgt_referral_ticket(%s) kvno(%u) expected(%u) current(%u)",
3633 : krbtgt_trust_realm_string,
3634 : (unsigned)t_kvno, (unsigned)expected_kvno,(unsigned)kvno);
3635 : torture_comment(tctx, "%s\n", assertion_message);
3636 : torture_assert_int_not_equal(tctx, t_kvno, 0, assertion_message);
3637 : } else {
3638 : assertion_message = talloc_asprintf(ctx,
3639 : "krbtgt_referral_ticket(%s) kvno(NULL) exptected(%u) current(%u)",
3640 : krbtgt_trust_realm_string,
3641 : (unsigned)expected_kvno,(unsigned)kvno);
3642 : torture_comment(tctx, "%s\n", assertion_message);
3643 : }
3644 : torture_assert_int_equal(tctx, t_kvno, expected_kvno, assertion_message);
3645 :
3646 : if (old_nthash != NULL && expected_kvno != kvno) {
3647 : torture_comment(tctx, "old_nthash: %s\n", assertion_message);
3648 : k5ret = smb_krb5_keyblock_init_contents(ctx->smb_krb5_context->krb5_context,
3649 : ENCTYPE_ARCFOUR_HMAC,
3650 : old_nthash->hash,
3651 : sizeof(old_nthash->hash),
3652 : &ctx->krbtgt_referral_keyblock);
3653 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3654 : } else {
3655 : torture_comment(tctx, "nthash: %s\n", assertion_message);
3656 : k5ret = smb_krb5_keyblock_init_contents(ctx->smb_krb5_context->krb5_context,
3657 : ENCTYPE_ARCFOUR_HMAC,
3658 : nthash->hash,
3659 : sizeof(nthash->hash),
3660 : &ctx->krbtgt_referral_keyblock);
3661 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3662 : }
3663 : k5ret = krb5_decrypt_ticket(ctx->smb_krb5_context->krb5_context,
3664 : &ctx->krbtgt_referral_ticket,
3665 : &ctx->krbtgt_referral_keyblock,
3666 : &ctx->krbtgt_referral_enc_part,
3667 : 0);
3668 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3669 :
3670 : /* Delete the referral ticket from the cache */
3671 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3672 : ctx->krbtgt_ccache,
3673 : 0,
3674 : &ctx->krbtgt_referral_creds);
3675 : assertion_message = talloc_asprintf(ctx,
3676 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3677 : krbtgt_trust_realm_string,
3678 : k5ret,
3679 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3680 : k5ret, ctx));
3681 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3682 : #endif
3683 :
3684 : /* Confirm if we can do a TGS for krbtgt/trusted_dns no CANON */
3685 72 : ZERO_STRUCT(ctx->counts);
3686 144 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3687 : ctx->opt_nocanon,
3688 : ctx->krbtgt_ccache,
3689 72 : ctx->krbtgt_trust_dns,
3690 : &ctx->krbtgt_trust_dns_creds);
3691 216 : assertion_message = talloc_asprintf(ctx,
3692 : "krb5_get_creds(%s, nocanon) for failed: "
3693 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3694 : krbtgt_trust_dns_string,
3695 : k5ret,
3696 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3697 : k5ret, ctx),
3698 : trusted->trust_direction,
3699 72 : trusted->trust_type,
3700 : trusted->trust_attributes,
3701 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3702 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3703 : #ifdef USING_EMBEDDED_HEIMDAL
3704 72 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3705 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3706 : #else
3707 : torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
3708 : torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
3709 : #endif
3710 :
3711 72 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3712 72 : ctx->krbtgt_trust_dns_creds->server,
3713 : #ifdef USING_EMBEDDED_HEIMDAL
3714 72 : ctx->krbtgt_trust_dns);
3715 : #else
3716 : ctx->krbtgt_trust_realm);
3717 : #endif
3718 72 : torture_assert(tctx, k5ok, assertion_message);
3719 72 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3720 72 : ctx->krbtgt_trust_dns_creds->server);
3721 72 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3722 :
3723 : /* Confirm if we have the referral ticket in the cache */
3724 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3725 : &ctx->krbtgt_referral_creds);
3726 144 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3727 : ctx->krbtgt_ccache,
3728 : 0,
3729 72 : ctx->krbtgt_trust_realm_creds,
3730 : &ctx->krbtgt_referral_creds);
3731 72 : assertion_message = talloc_asprintf(ctx,
3732 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3733 : krbtgt_trust_realm_string,
3734 : k5ret,
3735 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3736 : k5ret, ctx));
3737 : #ifdef USING_EMBEDDED_HEIMDAL
3738 72 : torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3739 : #else
3740 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3741 :
3742 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3743 : ctx->krbtgt_referral_creds.server,
3744 : ctx->krbtgt_trust_realm);
3745 : torture_assert(tctx, k5ok, assertion_message);
3746 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3747 : ctx->krbtgt_referral_creds.server);
3748 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3749 :
3750 : /* Delete the referral ticket from the cache */
3751 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3752 : ctx->krbtgt_ccache,
3753 : 0,
3754 : &ctx->krbtgt_referral_creds);
3755 : assertion_message = talloc_asprintf(ctx,
3756 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3757 : krbtgt_trust_realm_string,
3758 : k5ret,
3759 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3760 : k5ret, ctx));
3761 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3762 : #endif
3763 :
3764 : /* Confirm if we can do a TGS for krbtgt/NETBIOS with CANON */
3765 72 : ZERO_STRUCT(ctx->counts);
3766 144 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3767 : ctx->opt_canon,
3768 : ctx->krbtgt_ccache,
3769 72 : ctx->krbtgt_trust_netbios,
3770 : &ctx->krbtgt_trust_netbios_creds);
3771 216 : assertion_message = talloc_asprintf(ctx,
3772 : "krb5_get_creds(%s, canon) for failed: "
3773 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3774 : krbtgt_trust_netbios_string,
3775 : k5ret,
3776 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3777 : k5ret, ctx),
3778 : trusted->trust_direction,
3779 72 : trusted->trust_type,
3780 : trusted->trust_attributes,
3781 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3782 : #ifdef USING_EMBEDDED_HEIMDAL
3783 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3784 : #else
3785 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3786 : #endif
3787 72 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3788 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3789 :
3790 : /* Confirm if we have the referral ticket in the cache */
3791 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3792 : &ctx->krbtgt_referral_creds);
3793 144 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3794 : ctx->krbtgt_ccache,
3795 : 0,
3796 72 : ctx->krbtgt_trust_realm_creds,
3797 : &ctx->krbtgt_referral_creds);
3798 72 : assertion_message = talloc_asprintf(ctx,
3799 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3800 : krbtgt_trust_netbios_string,
3801 : k5ret,
3802 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3803 : k5ret, ctx));
3804 : #ifdef USING_EMBEDDED_HEIMDAL
3805 72 : torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3806 : #else
3807 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3808 :
3809 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3810 : ctx->krbtgt_referral_creds.server,
3811 : ctx->krbtgt_trust_realm);
3812 : torture_assert(tctx, k5ok, assertion_message);
3813 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3814 : ctx->krbtgt_referral_creds.server);
3815 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3816 :
3817 : /* Delete the referral ticket from the cache */
3818 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3819 : ctx->krbtgt_ccache,
3820 : 0,
3821 : &ctx->krbtgt_referral_creds);
3822 : assertion_message = talloc_asprintf(ctx,
3823 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3824 : krbtgt_trust_realm_string,
3825 : k5ret,
3826 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3827 : k5ret, ctx));
3828 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3829 : #endif
3830 :
3831 : /* Confirm if we can do a TGS for krbtgt/NETBIOS no CANON */
3832 72 : ZERO_STRUCT(ctx->counts);
3833 144 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3834 : ctx->opt_nocanon,
3835 : ctx->krbtgt_ccache,
3836 72 : ctx->krbtgt_trust_netbios,
3837 : &ctx->krbtgt_trust_netbios_creds);
3838 216 : assertion_message = talloc_asprintf(ctx,
3839 : "krb5_get_creds(%s, nocanon) for failed: "
3840 : "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3841 : krbtgt_trust_netbios_string,
3842 : k5ret,
3843 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3844 : k5ret, ctx),
3845 : trusted->trust_direction,
3846 72 : trusted->trust_type,
3847 : trusted->trust_attributes,
3848 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3849 72 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3850 : #ifdef USING_EMBEDDED_HEIMDAL
3851 72 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3852 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3853 : #else
3854 : torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
3855 : torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
3856 : #endif
3857 :
3858 72 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3859 72 : ctx->krbtgt_trust_netbios_creds->server,
3860 : #ifdef USING_EMBEDDED_HEIMDAL
3861 72 : ctx->krbtgt_trust_netbios);
3862 : #else
3863 : ctx->krbtgt_trust_realm);
3864 : #endif
3865 72 : torture_assert(tctx, k5ok, assertion_message);
3866 72 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3867 72 : ctx->krbtgt_trust_netbios_creds->server);
3868 72 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3869 :
3870 : /* Confirm if we have the referral ticket in the cache */
3871 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3872 : &ctx->krbtgt_referral_creds);
3873 144 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3874 : ctx->krbtgt_ccache,
3875 : 0,
3876 72 : ctx->krbtgt_trust_realm_creds,
3877 : &ctx->krbtgt_referral_creds);
3878 72 : assertion_message = talloc_asprintf(ctx,
3879 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3880 : krbtgt_trust_realm_string,
3881 : k5ret,
3882 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3883 : k5ret, ctx));
3884 : #ifdef USING_EMBEDDED_HEIMDAL
3885 72 : torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3886 : #else
3887 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3888 :
3889 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3890 : ctx->krbtgt_referral_creds.server,
3891 : ctx->krbtgt_trust_realm);
3892 : torture_assert(tctx, k5ok, assertion_message);
3893 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3894 : ctx->krbtgt_referral_creds.server);
3895 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3896 :
3897 : /* Delete the referral ticket from the cache */
3898 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3899 : ctx->krbtgt_ccache,
3900 : 0,
3901 : &ctx->krbtgt_referral_creds);
3902 : assertion_message = talloc_asprintf(ctx,
3903 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3904 : krbtgt_trust_realm_string,
3905 : k5ret,
3906 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3907 : k5ret, ctx));
3908 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3909 : #endif
3910 :
3911 72 : cifs_trust_dns_string = talloc_asprintf(ctx, "cifs/%s@%s",
3912 : trusted_dns_name, realm);
3913 72 : torture_assert_int_equal(tctx,
3914 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3915 : &ctx->cifs_trust_dns,
3916 : realm, "cifs",
3917 : trusted_dns_name, NULL),
3918 : 0, "smb_krb5_make_principal failed");
3919 :
3920 : /* Confirm if we get krbtgt/trusted_realm back when asking for cifs/trusted_realm */
3921 72 : ZERO_STRUCT(ctx->counts);
3922 144 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3923 : ctx->opt_canon,
3924 : ctx->krbtgt_ccache,
3925 72 : ctx->cifs_trust_dns,
3926 : &ctx->cifs_trust_dns_creds);
3927 216 : assertion_message = talloc_asprintf(ctx,
3928 : "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3929 : cifs_trust_dns_string,
3930 : k5ret,
3931 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3932 : k5ret, ctx),
3933 : trusted->trust_direction,
3934 72 : trusted->trust_type,
3935 : trusted->trust_attributes,
3936 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3937 72 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3938 : #ifdef USING_EMBEDDED_HEIMDAL
3939 72 : torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
3940 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
3941 : #else
3942 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3943 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3944 : #endif
3945 :
3946 : /* Confirm if we have the referral ticket in the cache */
3947 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3948 : &ctx->krbtgt_referral_creds);
3949 144 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3950 : ctx->krbtgt_ccache,
3951 : 0,
3952 72 : ctx->krbtgt_trust_realm_creds,
3953 : &ctx->krbtgt_referral_creds);
3954 72 : assertion_message = talloc_asprintf(ctx,
3955 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3956 : krbtgt_trust_realm_string,
3957 : k5ret,
3958 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3959 : k5ret, ctx));
3960 : #ifdef USING_EMBEDDED_HEIMDAL
3961 72 : torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3962 : #else
3963 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3964 :
3965 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3966 : ctx->krbtgt_referral_creds.server,
3967 : ctx->krbtgt_trust_realm);
3968 : torture_assert(tctx, k5ok, assertion_message);
3969 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3970 : ctx->krbtgt_referral_creds.server);
3971 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3972 :
3973 : /* Delete the referral ticket from the cache */
3974 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3975 : ctx->krbtgt_ccache,
3976 : 0,
3977 : &ctx->krbtgt_referral_creds);
3978 : assertion_message = talloc_asprintf(ctx,
3979 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3980 : krbtgt_trust_realm_string,
3981 : k5ret,
3982 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3983 : k5ret, ctx));
3984 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3985 : #endif
3986 :
3987 72 : cifs_trust_netbios_string = talloc_asprintf(ctx, "cifs/%s@%s",
3988 : trusted_netbios_name, realm);
3989 72 : torture_assert_int_equal(tctx,
3990 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3991 : &ctx->cifs_trust_netbios,
3992 : realm, "cifs",
3993 : trusted_netbios_name, NULL),
3994 : 0, "smb_krb5_make_principal failed");
3995 :
3996 : /* Confirm if we get krbtgt/trusted_realm back when asking for cifs/trusted_realm */
3997 72 : ZERO_STRUCT(ctx->counts);
3998 144 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3999 : ctx->opt_canon,
4000 : ctx->krbtgt_ccache,
4001 72 : ctx->cifs_trust_netbios,
4002 : &ctx->cifs_trust_netbios_creds);
4003 216 : assertion_message = talloc_asprintf(ctx,
4004 : "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4005 : cifs_trust_netbios_string,
4006 : k5ret,
4007 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4008 : k5ret, ctx),
4009 : trusted->trust_direction,
4010 72 : trusted->trust_type,
4011 : trusted->trust_attributes,
4012 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4013 72 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
4014 : #ifdef USING_EMBEDDED_HEIMDAL
4015 72 : torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
4016 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
4017 : #else
4018 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4019 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
4020 : #endif
4021 :
4022 : /* Confirm if we have the referral ticket in the cache */
4023 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4024 : &ctx->krbtgt_referral_creds);
4025 144 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4026 : ctx->krbtgt_ccache,
4027 : 0,
4028 72 : ctx->krbtgt_trust_realm_creds,
4029 : &ctx->krbtgt_referral_creds);
4030 72 : assertion_message = talloc_asprintf(ctx,
4031 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4032 : krbtgt_trust_realm_string,
4033 : k5ret,
4034 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4035 : k5ret, ctx));
4036 : #ifdef USING_EMBEDDED_HEIMDAL
4037 72 : torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4038 : #else
4039 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4040 :
4041 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
4042 : ctx->krbtgt_referral_creds.server,
4043 : ctx->krbtgt_trust_realm);
4044 : torture_assert(tctx, k5ok, assertion_message);
4045 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
4046 : ctx->krbtgt_referral_creds.server);
4047 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
4048 :
4049 : /* Delete the referral ticket from the cache */
4050 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
4051 : ctx->krbtgt_ccache,
4052 : 0,
4053 : &ctx->krbtgt_referral_creds);
4054 : assertion_message = talloc_asprintf(ctx,
4055 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
4056 : krbtgt_trust_realm_string,
4057 : k5ret,
4058 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4059 : k5ret, ctx));
4060 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4061 : #endif
4062 :
4063 72 : drs_trust_dns_string = talloc_asprintf(ctx,
4064 : "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s@%s",
4065 : workstation, trusted_dns_name, realm);
4066 72 : torture_assert_int_equal(tctx,
4067 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
4068 : &ctx->drs_trust_dns,
4069 : realm, "E3514235-4B06-11D1-AB04-00C04FC2DCD2",
4070 : workstation, trusted_dns_name, NULL),
4071 : 0, "smb_krb5_make_principal failed");
4072 :
4073 : /* Confirm if we get krbtgt/trusted_realm back when asking for a 3 part principal */
4074 72 : ZERO_STRUCT(ctx->counts);
4075 144 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4076 : ctx->opt_canon,
4077 : ctx->krbtgt_ccache,
4078 72 : ctx->drs_trust_dns,
4079 : &ctx->drs_trust_dns_creds);
4080 216 : assertion_message = talloc_asprintf(ctx,
4081 : "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4082 : drs_trust_dns_string,
4083 : k5ret,
4084 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4085 : k5ret, ctx),
4086 : trusted->trust_direction,
4087 72 : trusted->trust_type,
4088 : trusted->trust_attributes,
4089 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4090 72 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
4091 : #ifdef USING_EMBEDDED_HEIMDAL
4092 72 : torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
4093 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
4094 : #else
4095 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4096 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
4097 : #endif
4098 :
4099 : /* Confirm if we have the referral ticket in the cache */
4100 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4101 : &ctx->krbtgt_referral_creds);
4102 144 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4103 : ctx->krbtgt_ccache,
4104 : 0,
4105 72 : ctx->krbtgt_trust_realm_creds,
4106 : &ctx->krbtgt_referral_creds);
4107 72 : assertion_message = talloc_asprintf(ctx,
4108 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4109 : krbtgt_trust_realm_string,
4110 : k5ret,
4111 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4112 : k5ret, ctx));
4113 : #ifdef USING_EMBEDDED_HEIMDAL
4114 72 : torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4115 : #else
4116 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4117 :
4118 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
4119 : ctx->krbtgt_referral_creds.server,
4120 : ctx->krbtgt_trust_realm);
4121 : torture_assert(tctx, k5ok, assertion_message);
4122 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
4123 : ctx->krbtgt_referral_creds.server);
4124 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
4125 :
4126 : /* Delete the referral ticket from the cache */
4127 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
4128 : ctx->krbtgt_ccache,
4129 : 0,
4130 : &ctx->krbtgt_referral_creds);
4131 : assertion_message = talloc_asprintf(ctx,
4132 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
4133 : krbtgt_trust_realm_string,
4134 : k5ret,
4135 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4136 : k5ret, ctx));
4137 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4138 : #endif
4139 :
4140 72 : drs_trust_netbios_string = talloc_asprintf(ctx,
4141 : "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s@%s",
4142 : workstation, trusted_netbios_name, realm);
4143 72 : torture_assert_int_equal(tctx,
4144 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
4145 : &ctx->drs_trust_netbios,
4146 : realm, "E3514235-4B06-11D1-AB04-00C04FC2DCD2",
4147 : workstation, trusted_netbios_name, NULL),
4148 : 0, "smb_krb5_make_principal failed");
4149 :
4150 : /* Confirm if we get krbtgt/trusted_realm back when asking for a 3 part principal */
4151 72 : ZERO_STRUCT(ctx->counts);
4152 144 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4153 : ctx->opt_canon,
4154 : ctx->krbtgt_ccache,
4155 72 : ctx->drs_trust_netbios,
4156 : &ctx->drs_trust_netbios_creds);
4157 216 : assertion_message = talloc_asprintf(ctx,
4158 : "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4159 : drs_trust_netbios_string,
4160 : k5ret,
4161 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4162 : k5ret, ctx),
4163 : trusted->trust_direction,
4164 72 : trusted->trust_type,
4165 : trusted->trust_attributes,
4166 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4167 72 : torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
4168 : #ifdef USING_EMBEDDED_HEIMDAL
4169 72 : torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
4170 72 : torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
4171 : #else
4172 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4173 : torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
4174 : #endif
4175 :
4176 : /* Confirm if we have the referral ticket in the cache */
4177 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4178 : &ctx->krbtgt_referral_creds);
4179 144 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4180 : ctx->krbtgt_ccache,
4181 : 0,
4182 72 : ctx->krbtgt_trust_realm_creds,
4183 : &ctx->krbtgt_referral_creds);
4184 72 : assertion_message = talloc_asprintf(ctx,
4185 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4186 : krbtgt_trust_realm_string,
4187 : k5ret,
4188 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4189 : k5ret, ctx));
4190 : #ifdef USING_EMBEDDED_HEIMDAL
4191 72 : torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4192 : #else
4193 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4194 :
4195 : k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
4196 : ctx->krbtgt_referral_creds.server,
4197 : ctx->krbtgt_trust_realm);
4198 : torture_assert(tctx, k5ok, assertion_message);
4199 : type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
4200 : ctx->krbtgt_referral_creds.server);
4201 : torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
4202 :
4203 : /* Delete the referral ticket from the cache */
4204 : k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
4205 : ctx->krbtgt_ccache,
4206 : 0,
4207 : &ctx->krbtgt_referral_creds);
4208 : assertion_message = talloc_asprintf(ctx,
4209 : "krb5_cc_remove_cred(%s) for failed: (%d) %s",
4210 : krbtgt_trust_realm_string,
4211 : k5ret,
4212 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4213 : k5ret, ctx));
4214 : torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4215 : #endif
4216 :
4217 72 : four_trust_dns_string = talloc_asprintf(ctx, "four/tree/two/%s@%s",
4218 : trusted_dns_name, realm);
4219 72 : torture_assert_int_equal(tctx,
4220 : smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
4221 : &ctx->four_trust_dns,
4222 : realm, "four", "tree", "two",
4223 : trusted_dns_name, NULL),
4224 : 0, "smb_krb5_make_principal failed");
4225 :
4226 : /* Confirm if we get an error back for a 4 part principal */
4227 72 : ZERO_STRUCT(ctx->counts);
4228 144 : k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4229 : ctx->opt_canon,
4230 : ctx->krbtgt_ccache,
4231 72 : ctx->four_trust_dns,
4232 : &ctx->four_trust_dns_creds);
4233 216 : assertion_message = talloc_asprintf(ctx,
4234 : "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4235 : four_trust_dns_string,
4236 : k5ret,
4237 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4238 : k5ret, ctx),
4239 : trusted->trust_direction,
4240 72 : trusted->trust_type,
4241 : trusted->trust_attributes,
4242 : ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4243 72 : torture_assert_int_equal(tctx, k5ret, KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, assertion_message);
4244 : #ifdef USING_EMBEDDED_HEIMDAL
4245 72 : torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
4246 72 : torture_assert_int_equal(tctx, ctx->counts.error_io, 2, assertion_message);
4247 : #else
4248 : torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4249 : torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
4250 : #endif
4251 72 : torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 7, assertion_message);
4252 :
4253 : /* Confirm if we have no referral ticket in the cache */
4254 72 : krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4255 : &ctx->krbtgt_referral_creds);
4256 144 : k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4257 : ctx->krbtgt_ccache,
4258 : 0,
4259 72 : ctx->krbtgt_trust_realm_creds,
4260 : &ctx->krbtgt_referral_creds);
4261 72 : assertion_message = talloc_asprintf(ctx,
4262 : "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4263 : krbtgt_trust_realm_string,
4264 : k5ret,
4265 72 : smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4266 : k5ret, ctx));
4267 72 : torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4268 :
4269 72 : TALLOC_FREE(ctx);
4270 72 : return true;
4271 : }
4272 : #endif
4273 :
4274 72 : static bool check_dom_trust_pw(struct dcerpc_pipe *p,
4275 : struct torture_context *tctx,
4276 : const char *our_netbios_name,
4277 : const char *our_dns_name,
4278 : enum netr_SchannelType secure_channel_type,
4279 : const struct lsa_TrustDomainInfoInfoEx *trusted,
4280 : const char *previous_password,
4281 : const char *current_password,
4282 : uint32_t current_version,
4283 : const char *next_password,
4284 : uint32_t next_version,
4285 : bool expected_result)
4286 : {
4287 : struct cli_credentials *incoming_creds;
4288 72 : char *server_name = NULL;
4289 72 : char *account = NULL;
4290 72 : char *principal = NULL;
4291 72 : char *workstation = NULL;
4292 72 : const char *binding = torture_setting_string(tctx, "binding", NULL);
4293 72 : const char *host = torture_setting_string(tctx, "host", NULL);
4294 : const char *ip;
4295 : struct nbt_name nbt_name;
4296 : struct dcerpc_binding *b2;
4297 : struct netlogon_creds_CredentialState *creds;
4298 : struct samr_CryptPassword samr_crypt_password;
4299 : struct netr_CryptPassword netr_crypt_password;
4300 : struct netr_Authenticator req_auth;
4301 : struct netr_Authenticator rep_auth;
4302 : struct netr_ServerPasswordSet2 s;
4303 72 : struct dcerpc_pipe *p1 = NULL;
4304 72 : struct dcerpc_pipe *p2 = NULL;
4305 : NTSTATUS status;
4306 : bool ok;
4307 : int rc;
4308 72 : const char *trusted_netbios_name = trusted->netbios_name.string;
4309 72 : const char *trusted_dns_name = trusted->domain_name.string;
4310 : struct tsocket_address *dest_addr;
4311 : struct cldap_socket *cldap;
4312 : struct cldap_netlogon cldap1;
4313 :
4314 72 : incoming_creds = cli_credentials_init(tctx);
4315 72 : torture_assert(tctx, incoming_creds, "cli_credentials_init");
4316 :
4317 72 : cli_credentials_set_domain(incoming_creds, our_netbios_name, CRED_SPECIFIED);
4318 72 : cli_credentials_set_realm(incoming_creds, our_dns_name, CRED_SPECIFIED);
4319 :
4320 72 : if (secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
4321 36 : account = talloc_asprintf(tctx, "%s.", trusted_dns_name);
4322 36 : torture_assert(tctx, account, __location__);
4323 :
4324 36 : principal = talloc_asprintf(tctx, "%s$@%s",
4325 : trusted_netbios_name,
4326 : cli_credentials_get_realm(incoming_creds));
4327 36 : torture_assert(tctx, principal, __location__);
4328 :
4329 36 : workstation = talloc_asprintf(tctx, "%sUP",
4330 : trusted_netbios_name);
4331 36 : torture_assert(tctx, workstation, __location__);
4332 : } else {
4333 36 : account = talloc_asprintf(tctx, "%s$", trusted_netbios_name);
4334 36 : torture_assert(tctx, account, __location__);
4335 :
4336 36 : workstation = talloc_asprintf(tctx, "%sDOWN",
4337 : trusted_netbios_name);
4338 36 : torture_assert(tctx, workstation, __location__);
4339 : }
4340 :
4341 72 : cli_credentials_set_username(incoming_creds, account, CRED_SPECIFIED);
4342 72 : if (principal != NULL) {
4343 36 : cli_credentials_set_principal(incoming_creds, principal,
4344 : CRED_SPECIFIED);
4345 : }
4346 72 : cli_credentials_set_kvno(incoming_creds, current_version);
4347 72 : cli_credentials_set_password(incoming_creds, current_password, CRED_SPECIFIED);
4348 72 : cli_credentials_set_old_password(incoming_creds, previous_password, CRED_SPECIFIED);
4349 72 : cli_credentials_set_workstation(incoming_creds, workstation, CRED_SPECIFIED);
4350 72 : cli_credentials_set_secure_channel_type(incoming_creds, secure_channel_type);
4351 :
4352 72 : make_nbt_name_server(&nbt_name, host);
4353 :
4354 72 : status = resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx),
4355 : 0, 0, &nbt_name, tctx, &ip, tctx->ev);
4356 72 : torture_assert_ntstatus_ok(tctx, status,
4357 : talloc_asprintf(tctx,"Failed to resolve %s: %s",
4358 : nbt_name.name, nt_errstr(status)));
4359 :
4360 72 : rc = tsocket_address_inet_from_strings(tctx, "ip",
4361 : ip,
4362 : lpcfg_cldap_port(tctx->lp_ctx),
4363 : &dest_addr);
4364 72 : torture_assert_int_equal(tctx, rc, 0,
4365 : talloc_asprintf(tctx,
4366 : "tsocket_address_inet_from_strings failed parsing %s:%d",
4367 : host, lpcfg_cldap_port(tctx->lp_ctx)));
4368 :
4369 : /* cldap_socket_init should now know about the dest. address */
4370 72 : status = cldap_socket_init(tctx, NULL, dest_addr, &cldap);
4371 72 : torture_assert_ntstatus_ok(tctx, status, "cldap_socket_init");
4372 :
4373 72 : ZERO_STRUCT(cldap1);
4374 72 : cldap1.in.dest_address = NULL;
4375 72 : cldap1.in.dest_port = 0;
4376 72 : cldap1.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
4377 72 : cldap1.in.user = account;
4378 72 : if (secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
4379 36 : cldap1.in.acct_control = ACB_AUTOLOCK;
4380 : } else {
4381 36 : cldap1.in.acct_control = ACB_DOMTRUST;
4382 : }
4383 72 : status = cldap_netlogon(cldap, tctx, &cldap1);
4384 72 : torture_assert_ntstatus_ok(tctx, status, "cldap_netlogon");
4385 72 : torture_assert_int_equal(tctx, cldap1.out.netlogon.ntver,
4386 : NETLOGON_NT_VERSION_5EX,
4387 : "ntver");
4388 72 : torture_assert_int_equal(tctx, cldap1.out.netlogon.data.nt5_ex.nt_version,
4389 : NETLOGON_NT_VERSION_1 | NETLOGON_NT_VERSION_5EX,
4390 : "nt_version");
4391 72 : torture_assert_int_equal(tctx, cldap1.out.netlogon.data.nt5_ex.command,
4392 : LOGON_SAM_LOGON_RESPONSE_EX,
4393 : "command");
4394 72 : torture_assert_str_equal(tctx, cldap1.out.netlogon.data.nt5_ex.user_name,
4395 : cldap1.in.user,
4396 : "user_name");
4397 72 : server_name = talloc_asprintf(tctx, "\\\\%s",
4398 : cldap1.out.netlogon.data.nt5_ex.pdc_dns_name);
4399 72 : torture_assert(tctx, server_name, __location__);
4400 :
4401 72 : status = dcerpc_parse_binding(tctx, binding, &b2);
4402 72 : torture_assert_ntstatus_ok(tctx, status, "Bad binding string");
4403 :
4404 72 : status = dcerpc_pipe_connect_b(tctx, &p1, b2,
4405 : &ndr_table_netlogon,
4406 : cli_credentials_init_anon(tctx),
4407 : tctx->ev, tctx->lp_ctx);
4408 72 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b");
4409 :
4410 72 : ok = check_pw_with_ServerAuthenticate3(p1, tctx,
4411 : NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
4412 : server_name,
4413 : incoming_creds, &creds);
4414 72 : torture_assert_int_equal(tctx, ok, expected_result,
4415 : "check_pw_with_ServerAuthenticate3");
4416 72 : if (expected_result == true) {
4417 54 : ok = test_SetupCredentialsPipe(p1, tctx, incoming_creds, creds,
4418 : DCERPC_SIGN | DCERPC_SEAL, &p2);
4419 54 : torture_assert_int_equal(tctx, ok, true,
4420 : "test_SetupCredentialsPipe");
4421 : }
4422 72 : TALLOC_FREE(p1);
4423 :
4424 72 : if (trusted->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
4425 : #ifdef SAMBA4_USES_HEIMDAL
4426 48 : ok = check_pw_with_krb5(tctx, incoming_creds, trusted);
4427 48 : torture_assert_int_equal(tctx, ok, expected_result,
4428 : "check_pw_with_krb5");
4429 : #else
4430 0 : torture_comment(tctx, "skipping check_pw_with_krb5 for MIT Kerberos build");
4431 : #endif
4432 : }
4433 :
4434 72 : if (expected_result != true || next_password == NULL) {
4435 18 : TALLOC_FREE(p2);
4436 18 : return true;
4437 : }
4438 :
4439 : /*
4440 : * netr_ServerPasswordSet2
4441 : */
4442 54 : ok = encode_pw_buffer(samr_crypt_password.data,
4443 : next_password, STR_UNICODE);
4444 54 : torture_assert(tctx, ok, "encode_pw_buffer");
4445 :
4446 54 : if (next_version != 0) {
4447 : struct NL_PASSWORD_VERSION version;
4448 54 : uint32_t len = IVAL(samr_crypt_password.data, 512);
4449 54 : uint32_t ofs = 512 - len;
4450 : uint8_t *ptr;
4451 :
4452 54 : ofs -= 12;
4453 :
4454 54 : version.ReservedField = 0;
4455 54 : version.PasswordVersionNumber = next_version;
4456 54 : version.PasswordVersionPresent =
4457 : NETLOGON_PASSWORD_VERSION_NUMBER_PRESENT;
4458 :
4459 54 : ptr = samr_crypt_password.data + ofs;
4460 54 : SIVAL(ptr, 0, version.ReservedField);
4461 54 : SIVAL(ptr, 4, version.PasswordVersionNumber);
4462 54 : SIVAL(ptr, 8, version.PasswordVersionPresent);
4463 : }
4464 :
4465 54 : netlogon_creds_client_authenticator(creds, &req_auth);
4466 54 : ZERO_STRUCT(rep_auth);
4467 :
4468 54 : if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
4469 54 : netlogon_creds_aes_encrypt(creds,
4470 : samr_crypt_password.data,
4471 : 516);
4472 : } else {
4473 0 : netlogon_creds_arcfour_crypt(creds,
4474 : samr_crypt_password.data,
4475 : 516);
4476 : }
4477 :
4478 54 : memcpy(netr_crypt_password.data,
4479 : samr_crypt_password.data, 512);
4480 54 : netr_crypt_password.length = IVAL(samr_crypt_password.data, 512);
4481 :
4482 :
4483 54 : s.in.server_name = server_name;
4484 54 : s.in.account_name = cli_credentials_get_username(incoming_creds);
4485 54 : s.in.secure_channel_type = cli_credentials_get_secure_channel_type(incoming_creds);
4486 54 : s.in.computer_name = cli_credentials_get_workstation(incoming_creds);
4487 54 : s.in.credential = &req_auth;
4488 54 : s.in.new_password = &netr_crypt_password;
4489 54 : s.out.return_authenticator = &rep_auth;
4490 54 : status = dcerpc_netr_ServerPasswordSet2_r(p2->binding_handle, tctx, &s);
4491 54 : torture_assert_ntstatus_ok(tctx, status, "failed to set password");
4492 :
4493 54 : ok = netlogon_creds_client_check(creds, &rep_auth.cred);
4494 54 : torture_assert(tctx, ok, "netlogon_creds_client_check");
4495 :
4496 54 : cli_credentials_set_kvno(incoming_creds, next_version);
4497 54 : cli_credentials_set_password(incoming_creds, next_password, CRED_SPECIFIED);
4498 54 : cli_credentials_set_old_password(incoming_creds, current_password, CRED_SPECIFIED);
4499 :
4500 54 : TALLOC_FREE(p2);
4501 54 : status = dcerpc_pipe_connect_b(tctx, &p2, b2,
4502 : &ndr_table_netlogon,
4503 : cli_credentials_init_anon(tctx),
4504 : tctx->ev, tctx->lp_ctx);
4505 54 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b");
4506 :
4507 54 : ok = check_pw_with_ServerAuthenticate3(p2, tctx,
4508 : NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
4509 : server_name,
4510 : incoming_creds, &creds);
4511 54 : torture_assert(tctx, ok, "check_pw_with_ServerAuthenticate3 with changed password");
4512 :
4513 54 : if (trusted->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
4514 : #if SAMBA4_USES_HEIMDAL
4515 36 : ok = check_pw_with_krb5(tctx, incoming_creds, trusted);
4516 36 : torture_assert(tctx, ok, "check_pw_with_krb5 with changed password");
4517 : #else
4518 0 : torture_comment(tctx, "skipping check_pw_with_krb5 for MIT Kerberos build");
4519 : #endif
4520 : }
4521 :
4522 54 : TALLOC_FREE(p2);
4523 54 : return true;
4524 : }
4525 :
4526 6 : static bool test_CreateTrustedDomainEx_common(struct dcerpc_pipe *p,
4527 : struct torture_context *tctx,
4528 : struct policy_handle *handle,
4529 : uint32_t num_trusts,
4530 : bool ex2_call)
4531 : {
4532 : NTSTATUS status;
4533 6 : bool ret = true;
4534 : struct lsa_QueryInfoPolicy2 p2;
4535 6 : union lsa_PolicyInformation *our_info = NULL;
4536 : struct lsa_CreateTrustedDomainEx r;
4537 : struct lsa_CreateTrustedDomainEx2 r2;
4538 : struct lsa_TrustDomainInfoInfoEx trustinfo;
4539 6 : struct lsa_TrustDomainInfoAuthInfoInternal *authinfo_internal = NULL;
4540 6 : struct lsa_TrustDomainInfoAuthInfo *authinfo = NULL;
4541 : struct dom_sid **domsid;
4542 : struct policy_handle *trustdom_handle;
4543 : struct lsa_QueryTrustedDomainInfo q;
4544 6 : union lsa_TrustedDomainInfo *info = NULL;
4545 : DATA_BLOB session_key;
4546 : int i;
4547 6 : struct dcerpc_binding_handle *b = p->binding_handle;
4548 : const char *id;
4549 6 : const char *incoming_v00 = TRUSTPW "InV00";
4550 6 : const char *incoming_v0 = TRUSTPW "InV0";
4551 6 : const char *incoming_v1 = TRUSTPW "InV1";
4552 6 : const char *incoming_v2 = TRUSTPW "InV2";
4553 6 : const char *incoming_v40 = TRUSTPW "InV40";
4554 6 : const char *outgoing_v00 = TRUSTPW "OutV00";
4555 6 : const char *outgoing_v0 = TRUSTPW "OutV0";
4556 :
4557 6 : if (ex2_call) {
4558 3 : torture_comment(tctx, "\nTesting CreateTrustedDomainEx2 for %d domains\n", num_trusts);
4559 3 : id = "3";
4560 : } else {
4561 3 : torture_comment(tctx, "\nTesting CreateTrustedDomainEx for %d domains\n", num_trusts);
4562 3 : id = "2";
4563 : }
4564 :
4565 6 : domsid = talloc_array(tctx, struct dom_sid *, num_trusts);
4566 6 : trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts);
4567 :
4568 6 : status = dcerpc_fetch_session_key(p, &session_key);
4569 6 : if (!NT_STATUS_IS_OK(status)) {
4570 0 : torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
4571 0 : return false;
4572 : }
4573 :
4574 6 : ZERO_STRUCT(p2);
4575 6 : p2.in.handle = handle;
4576 6 : p2.in.level = LSA_POLICY_INFO_DNS;
4577 6 : p2.out.info = &our_info;
4578 :
4579 6 : torture_assert_ntstatus_ok(tctx,
4580 : dcerpc_lsa_QueryInfoPolicy2_r(b, tctx, &p2),
4581 : "lsa_QueryInfoPolicy2 failed");
4582 6 : torture_assert_ntstatus_ok(tctx, p2.out.result,
4583 : "lsa_QueryInfoPolicy2 failed");
4584 6 : torture_assert(tctx, our_info != NULL, "lsa_QueryInfoPolicy2 our_info");
4585 :
4586 78 : for (i=0; i< num_trusts; i++) {
4587 72 : char *trust_name = talloc_asprintf(tctx, "TORTURE%s%02d", id, i);
4588 72 : char *trust_name_dns = talloc_asprintf(tctx, "torturedom%s%02d.samba._none_.example.com", id, i);
4589 72 : char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-%s%02d", id, i);
4590 : bool ok;
4591 :
4592 72 : domsid[i] = dom_sid_parse_talloc(tctx, trust_sid);
4593 :
4594 72 : trustinfo.sid = domsid[i];
4595 72 : trustinfo.netbios_name.string = trust_name;
4596 72 : trustinfo.domain_name.string = trust_name_dns;
4597 :
4598 : /* Create inbound, some outbound, and some
4599 : * bi-directional trusts in a repeating pattern based
4600 : * on i */
4601 :
4602 : /* 1 == inbound, 2 == outbound, 3 == both */
4603 72 : trustinfo.trust_direction = (i % 3) + 1;
4604 :
4605 : /* Try different trust types too */
4606 :
4607 : /* 1 == downlevel (NT4), 2 == uplevel (ADS), 3 == MIT (kerberos but not AD) */
4608 72 : trustinfo.trust_type = (((i / 3) + 1) % 3) + 1;
4609 :
4610 72 : trustinfo.trust_attributes = LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION;
4611 :
4612 72 : ok = gen_authinfo_internal(tctx, incoming_v00, incoming_v0,
4613 : outgoing_v00, outgoing_v0,
4614 : session_key, &authinfo_internal);
4615 72 : if (!ok) {
4616 0 : torture_comment(tctx, "gen_authinfo_internal failed");
4617 0 : ret = false;
4618 : }
4619 :
4620 72 : ok = gen_authinfo(tctx, incoming_v00, incoming_v0,
4621 : outgoing_v00, outgoing_v0,
4622 : &authinfo);
4623 72 : if (!ok) {
4624 0 : torture_comment(tctx, "gen_authinfonfo failed");
4625 0 : ret = false;
4626 : }
4627 :
4628 72 : if (ex2_call) {
4629 :
4630 36 : r2.in.policy_handle = handle;
4631 36 : r2.in.info = &trustinfo;
4632 36 : r2.in.auth_info_internal = authinfo_internal;
4633 36 : r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4634 36 : r2.out.trustdom_handle = &trustdom_handle[i];
4635 :
4636 36 : torture_assert_ntstatus_ok(tctx,
4637 : dcerpc_lsa_CreateTrustedDomainEx2_r(b, tctx, &r2),
4638 : "CreateTrustedDomainEx2 failed");
4639 :
4640 36 : status = r2.out.result;
4641 : } else {
4642 :
4643 36 : r.in.policy_handle = handle;
4644 36 : r.in.info = &trustinfo;
4645 36 : r.in.auth_info = authinfo;
4646 36 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4647 36 : r.out.trustdom_handle = &trustdom_handle[i];
4648 :
4649 36 : torture_assert_ntstatus_ok(tctx,
4650 : dcerpc_lsa_CreateTrustedDomainEx_r(b, tctx, &r),
4651 : "CreateTrustedDomainEx failed");
4652 :
4653 36 : status = r.out.result;
4654 : }
4655 :
4656 72 : if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
4657 0 : test_DeleteTrustedDomain(b, tctx, handle, trustinfo.netbios_name);
4658 0 : if (ex2_call) {
4659 0 : torture_assert_ntstatus_ok(tctx,
4660 : dcerpc_lsa_CreateTrustedDomainEx2_r(b, tctx, &r2),
4661 : "CreateTrustedDomainEx2 failed");
4662 0 : status = r2.out.result;
4663 : } else {
4664 0 : torture_assert_ntstatus_ok(tctx,
4665 : dcerpc_lsa_CreateTrustedDomainEx_r(b, tctx, &r),
4666 : "CreateTrustedDomainEx2 failed");
4667 0 : status = r.out.result;
4668 : }
4669 : }
4670 72 : if (!NT_STATUS_IS_OK(status)) {
4671 0 : torture_comment(tctx, "CreateTrustedDomainEx failed2 - %s\n", nt_errstr(status));
4672 0 : ret = false;
4673 : } else {
4674 : /* For outbound and MIT trusts there is no trust account */
4675 120 : if (trustinfo.trust_direction != 2 &&
4676 48 : trustinfo.trust_type != 3) {
4677 :
4678 36 : if (torture_setting_bool(tctx, "samba3", false)) {
4679 0 : torture_comment(tctx, "skipping trusted domain auth tests against samba3\n");
4680 54 : } else if (ex2_call == false &&
4681 18 : torture_setting_bool(tctx, "samba4", false)) {
4682 18 : torture_comment(tctx, "skipping CreateTrustedDomainEx trusted domain auth tests against samba4\n");
4683 :
4684 : } else {
4685 36 : ok = check_dom_trust_pw(p, tctx,
4686 18 : our_info->dns.name.string,
4687 18 : our_info->dns.dns_domain.string,
4688 : SEC_CHAN_DOMAIN,
4689 : &trustinfo,
4690 : NULL,
4691 : "x" TRUSTPW "x", 0,
4692 : NULL, 0,
4693 : false);
4694 18 : if (!ok) {
4695 0 : torture_comment(tctx, "Password check passed unexpectedly\n");
4696 0 : ret = false;
4697 : }
4698 36 : ok = check_dom_trust_pw(p, tctx,
4699 18 : our_info->dns.name.string,
4700 18 : our_info->dns.dns_domain.string,
4701 : SEC_CHAN_DOMAIN,
4702 : &trustinfo,
4703 : incoming_v00,
4704 : incoming_v0, 0,
4705 : incoming_v1, 1,
4706 : true);
4707 18 : if (!ok) {
4708 0 : torture_comment(tctx, "Password check failed (SEC_CHAN_DOMAIN)\n");
4709 0 : ret = false;
4710 : }
4711 36 : ok = check_dom_trust_pw(p, tctx,
4712 18 : our_info->dns.name.string,
4713 18 : our_info->dns.dns_domain.string,
4714 : SEC_CHAN_DNS_DOMAIN,
4715 : &trustinfo,
4716 : incoming_v0,
4717 : incoming_v1, 1,
4718 : incoming_v2, 2,
4719 : true);
4720 18 : if (!ok) {
4721 0 : torture_comment(tctx, "Password check failed v2 (SEC_CHAN_DNS_DOMAIN)\n");
4722 0 : ret = false;
4723 : }
4724 36 : ok = check_dom_trust_pw(p, tctx,
4725 18 : our_info->dns.name.string,
4726 18 : our_info->dns.dns_domain.string,
4727 : SEC_CHAN_DNS_DOMAIN,
4728 : &trustinfo,
4729 : incoming_v1,
4730 : incoming_v2, 2,
4731 : incoming_v40, 40,
4732 : true);
4733 18 : if (!ok) {
4734 0 : torture_comment(tctx, "Password check failed v4 (SEC_CHAN_DNS_DOMAIN)\n");
4735 0 : ret = false;
4736 : }
4737 : }
4738 : }
4739 :
4740 72 : q.in.trustdom_handle = &trustdom_handle[i];
4741 72 : q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
4742 72 : q.out.info = &info;
4743 72 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
4744 : "QueryTrustedDomainInfo failed");
4745 72 : if (!NT_STATUS_IS_OK(q.out.result)) {
4746 0 : torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(q.out.result));
4747 0 : ret = false;
4748 72 : } else if (!q.out.info) {
4749 0 : torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
4750 0 : ret = false;
4751 : } else {
4752 72 : if (strcmp(info->info_ex.domain_name.string, trustinfo.domain_name.string) != 0) {
4753 0 : torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent long name: %s != %s\n",
4754 0 : info->info_ex.domain_name.string, trustinfo.domain_name.string);
4755 0 : ret = false;
4756 : }
4757 72 : if (strcmp(info->info_ex.netbios_name.string, trustinfo.netbios_name.string) != 0) {
4758 0 : torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
4759 0 : info->info_ex.netbios_name.string, trustinfo.netbios_name.string);
4760 0 : ret = false;
4761 : }
4762 72 : if (info->info_ex.trust_type != trustinfo.trust_type) {
4763 0 : torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
4764 0 : trust_name, info->info_ex.trust_type, trustinfo.trust_type);
4765 0 : ret = false;
4766 : }
4767 72 : if (info->info_ex.trust_attributes != LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION) {
4768 0 : torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
4769 0 : trust_name, info->info_ex.trust_attributes, LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION);
4770 0 : ret = false;
4771 : }
4772 72 : if (info->info_ex.trust_direction != trustinfo.trust_direction) {
4773 0 : torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
4774 0 : trust_name, info->info_ex.trust_direction, trustinfo.trust_direction);
4775 0 : ret = false;
4776 : }
4777 : }
4778 : }
4779 : }
4780 :
4781 : /* now that we have some domains to look over, we can test the enum calls */
4782 6 : if (!test_EnumTrustDom(b, tctx, handle)) {
4783 0 : torture_comment(tctx, "test_EnumTrustDom failed\n");
4784 0 : ret = false;
4785 : }
4786 :
4787 6 : if (!test_EnumTrustDomEx(b, tctx, handle)) {
4788 0 : torture_comment(tctx, "test_EnumTrustDomEx failed\n");
4789 0 : ret = false;
4790 : }
4791 :
4792 78 : for (i=0; i<num_trusts; i++) {
4793 72 : if (!test_DeleteTrustedDomainBySid(b, tctx, handle, domsid[i])) {
4794 0 : torture_comment(tctx, "test_DeleteTrustedDomainBySid failed\n");
4795 0 : ret = false;
4796 : }
4797 : }
4798 :
4799 6 : return ret;
4800 : }
4801 :
4802 3 : static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
4803 : struct torture_context *tctx,
4804 : struct policy_handle *handle,
4805 : uint32_t num_trusts)
4806 : {
4807 3 : return test_CreateTrustedDomainEx_common(p, tctx, handle, num_trusts, true);
4808 : }
4809 :
4810 3 : static bool test_CreateTrustedDomainEx(struct dcerpc_pipe *p,
4811 : struct torture_context *tctx,
4812 : struct policy_handle *handle,
4813 : uint32_t num_trusts)
4814 : {
4815 3 : return test_CreateTrustedDomainEx_common(p, tctx, handle, num_trusts, false);
4816 : }
4817 :
4818 6 : static bool test_QueryDomainInfoPolicy(struct dcerpc_binding_handle *b,
4819 : struct torture_context *tctx,
4820 : struct policy_handle *handle)
4821 : {
4822 : struct lsa_QueryDomainInformationPolicy r;
4823 6 : union lsa_DomainInformationPolicy *info = NULL;
4824 : int i;
4825 6 : bool ret = true;
4826 :
4827 6 : if (torture_setting_bool(tctx, "samba3", false)) {
4828 0 : torture_skip(tctx, "skipping QueryDomainInformationPolicy test\n");
4829 : }
4830 :
4831 6 : torture_comment(tctx, "\nTesting QueryDomainInformationPolicy\n");
4832 :
4833 18 : for (i=2;i<4;i++) {
4834 12 : r.in.handle = handle;
4835 12 : r.in.level = i;
4836 12 : r.out.info = &info;
4837 :
4838 12 : torture_comment(tctx, "\nTrying QueryDomainInformationPolicy level %d\n", i);
4839 :
4840 12 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryDomainInformationPolicy_r(b, tctx, &r),
4841 : "QueryDomainInformationPolicy failed");
4842 :
4843 : /* If the server does not support EFS, then this is the correct return */
4844 12 : if (i == LSA_DOMAIN_INFO_POLICY_EFS && NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4845 6 : continue;
4846 6 : } else if (!NT_STATUS_IS_OK(r.out.result)) {
4847 0 : torture_comment(tctx, "QueryDomainInformationPolicy failed - %s\n", nt_errstr(r.out.result));
4848 0 : ret = false;
4849 0 : continue;
4850 : }
4851 : }
4852 :
4853 6 : return ret;
4854 : }
4855 :
4856 :
4857 12 : static bool test_QueryInfoPolicyCalls( bool version2,
4858 : struct dcerpc_binding_handle *b,
4859 : struct torture_context *tctx,
4860 : struct policy_handle *handle)
4861 : {
4862 : struct lsa_QueryInfoPolicy r;
4863 12 : union lsa_PolicyInformation *info = NULL;
4864 : int i;
4865 12 : bool ret = true;
4866 12 : const char *call = talloc_asprintf(tctx, "QueryInfoPolicy%s", version2 ? "2":"");
4867 :
4868 12 : torture_comment(tctx, "\nTesting %s\n", call);
4869 :
4870 12 : if (version2 && torture_setting_bool(tctx, "samba3", false)) {
4871 0 : torture_skip(tctx, "skipping QueryInfoPolicy2 tests\n");
4872 : }
4873 :
4874 180 : for (i=1;i<=14;i++) {
4875 168 : r.in.handle = handle;
4876 168 : r.in.level = i;
4877 168 : r.out.info = &info;
4878 :
4879 168 : torture_comment(tctx, "\nTrying %s level %d\n", call, i);
4880 :
4881 168 : if (version2)
4882 : /* We can perform the cast, because both types are
4883 : structurally equal */
4884 84 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy2_r(b, tctx,
4885 : (struct lsa_QueryInfoPolicy2*) &r),
4886 : "QueryInfoPolicy2 failed");
4887 : else
4888 84 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy_r(b, tctx, &r),
4889 : "QueryInfoPolicy2 failed");
4890 :
4891 168 : switch (i) {
4892 36 : case LSA_POLICY_INFO_MOD:
4893 : case LSA_POLICY_INFO_AUDIT_FULL_SET:
4894 : case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
4895 36 : if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
4896 0 : torture_comment(tctx, "Server should have failed level %u: %s\n", i, nt_errstr(r.out.result));
4897 0 : ret = false;
4898 : }
4899 36 : break;
4900 96 : case LSA_POLICY_INFO_DOMAIN:
4901 : case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
4902 : case LSA_POLICY_INFO_REPLICA:
4903 : case LSA_POLICY_INFO_QUOTA:
4904 : case LSA_POLICY_INFO_ROLE:
4905 : case LSA_POLICY_INFO_AUDIT_LOG:
4906 : case LSA_POLICY_INFO_AUDIT_EVENTS:
4907 : case LSA_POLICY_INFO_PD:
4908 96 : if (!NT_STATUS_IS_OK(r.out.result)) {
4909 0 : torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4910 0 : ret = false;
4911 : }
4912 96 : break;
4913 36 : case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
4914 : case LSA_POLICY_INFO_DNS_INT:
4915 : case LSA_POLICY_INFO_DNS:
4916 36 : if (torture_setting_bool(tctx, "samba3", false)) {
4917 : /* Other levels not implemented yet */
4918 0 : if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
4919 0 : torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4920 0 : ret = false;
4921 : }
4922 36 : } else if (!NT_STATUS_IS_OK(r.out.result)) {
4923 0 : torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4924 0 : ret = false;
4925 : }
4926 36 : break;
4927 0 : default:
4928 0 : if (torture_setting_bool(tctx, "samba4", false)) {
4929 : /* Other levels not implemented yet */
4930 0 : if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
4931 0 : torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4932 0 : ret = false;
4933 : }
4934 0 : } else if (!NT_STATUS_IS_OK(r.out.result)) {
4935 0 : torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4936 0 : ret = false;
4937 : }
4938 0 : break;
4939 : }
4940 :
4941 168 : if (NT_STATUS_IS_OK(r.out.result) && (i == LSA_POLICY_INFO_DNS
4942 120 : || i == LSA_POLICY_INFO_DNS_INT)) {
4943 : /* Let's look up some of these names */
4944 :
4945 : struct lsa_TransNameArray tnames, dnames;
4946 24 : tnames.count = 14;
4947 24 : tnames.names = talloc_zero_array(tctx, struct lsa_TranslatedName, tnames.count);
4948 24 : tnames.names[0].name.string = info->dns.name.string;
4949 24 : tnames.names[0].sid_type = SID_NAME_DOMAIN;
4950 24 : tnames.names[1].name.string = info->dns.dns_domain.string;
4951 24 : tnames.names[1].sid_type = SID_NAME_DOMAIN;
4952 24 : tnames.names[2].name.string = talloc_asprintf(tctx, "%s\\", info->dns.name.string);
4953 24 : tnames.names[2].sid_type = SID_NAME_DOMAIN;
4954 24 : tnames.names[3].name.string = talloc_asprintf(tctx, "%s\\", info->dns.dns_domain.string);
4955 24 : tnames.names[3].sid_type = SID_NAME_DOMAIN;
4956 24 : tnames.names[4].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.name.string);
4957 24 : tnames.names[4].sid_type = SID_NAME_USER;
4958 24 : tnames.names[5].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.name.string);
4959 24 : tnames.names[5].sid_type = SID_NAME_USER;
4960 24 : tnames.names[6].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.dns_domain.string);
4961 24 : tnames.names[6].sid_type = SID_NAME_USER;
4962 24 : tnames.names[7].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.dns_domain.string);
4963 24 : tnames.names[7].sid_type = SID_NAME_USER;
4964 24 : tnames.names[8].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.name.string);
4965 24 : tnames.names[8].sid_type = SID_NAME_USER;
4966 24 : tnames.names[9].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.dns_domain.string);
4967 24 : tnames.names[9].sid_type = SID_NAME_USER;
4968 24 : tnames.names[10].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.name.string);
4969 24 : tnames.names[10].sid_type = SID_NAME_USER;
4970 24 : tnames.names[11].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.dns_domain.string);
4971 24 : tnames.names[11].sid_type = SID_NAME_USER;
4972 24 : tnames.names[12].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.name.string);
4973 24 : tnames.names[12].sid_type = SID_NAME_USER;
4974 24 : tnames.names[13].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.dns_domain.string);
4975 24 : tnames.names[13].sid_type = SID_NAME_USER;
4976 24 : ret &= test_LookupNames(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames);
4977 :
4978 : /* Try to use in-forest search for the test machine */
4979 24 : dnames.count = 1;
4980 24 : dnames.names = talloc_zero_array(tctx, struct lsa_TranslatedName, dnames.count);
4981 24 : dnames.names[0].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.name.string);
4982 24 : dnames.names[0].sid_type = SID_NAME_USER;
4983 24 : ret &= test_LookupNames(b, tctx, handle, LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2, &dnames);
4984 : }
4985 : }
4986 :
4987 12 : return ret;
4988 : }
4989 :
4990 6 : static bool test_QueryInfoPolicy(struct dcerpc_binding_handle *b,
4991 : struct torture_context *tctx,
4992 : struct policy_handle *handle)
4993 : {
4994 6 : return test_QueryInfoPolicyCalls(false, b, tctx, handle);
4995 : }
4996 :
4997 6 : static bool test_QueryInfoPolicy2(struct dcerpc_binding_handle *b,
4998 : struct torture_context *tctx,
4999 : struct policy_handle *handle)
5000 : {
5001 6 : return test_QueryInfoPolicyCalls(true, b, tctx, handle);
5002 : }
5003 :
5004 12 : static bool test_GetUserName(struct dcerpc_binding_handle *b,
5005 : struct torture_context *tctx)
5006 : {
5007 : struct lsa_GetUserName r;
5008 12 : struct lsa_String *authority_name_p = NULL;
5009 12 : struct lsa_String *account_name_p = NULL;
5010 :
5011 12 : torture_comment(tctx, "\nTesting GetUserName\n");
5012 :
5013 12 : r.in.system_name = "\\";
5014 12 : r.in.account_name = &account_name_p;
5015 12 : r.in.authority_name = NULL;
5016 12 : r.out.account_name = &account_name_p;
5017 :
5018 12 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
5019 : "GetUserName failed");
5020 12 : torture_assert_ntstatus_ok(tctx, r.out.result,
5021 : "GetUserName result failed");
5022 12 : torture_assert_not_null(tctx, r.out.account_name, "r.out.account_name");
5023 12 : torture_assert_not_null(tctx, *r.out.account_name, "*r.out.account_name");
5024 12 : torture_assert(tctx, r.out.authority_name == NULL, "r.out.authority_name");
5025 :
5026 12 : account_name_p = NULL;
5027 12 : r.in.account_name = &account_name_p;
5028 12 : r.in.authority_name = &authority_name_p;
5029 12 : r.out.account_name = &account_name_p;
5030 :
5031 12 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
5032 : "GetUserName failed");
5033 12 : torture_assert_ntstatus_ok(tctx, r.out.result,
5034 : "GetUserName result failed");
5035 12 : torture_assert_not_null(tctx, r.out.account_name, "r.out.account_name");
5036 12 : torture_assert_not_null(tctx, *r.out.account_name, "*r.out.account_name");
5037 12 : torture_assert_not_null(tctx, r.out.authority_name, "r.out.authority_name");
5038 12 : torture_assert_not_null(tctx, *r.out.authority_name, "*r.out.authority_name");
5039 :
5040 24 : torture_comment(tctx,
5041 : "Account Name: %s, Authority Name: %s\n",
5042 12 : (*r.out.account_name)->string,
5043 12 : (*r.out.authority_name)->string);
5044 :
5045 12 : return true;
5046 : }
5047 :
5048 3 : static bool test_GetUserName_fail(struct dcerpc_binding_handle *b,
5049 : struct torture_context *tctx)
5050 : {
5051 : struct lsa_GetUserName r;
5052 3 : struct lsa_String *account_name_p = NULL;
5053 : NTSTATUS status;
5054 :
5055 3 : torture_comment(tctx, "\nTesting GetUserName_fail\n");
5056 :
5057 3 : r.in.system_name = "\\";
5058 3 : r.in.account_name = &account_name_p;
5059 3 : r.in.authority_name = NULL;
5060 3 : r.out.account_name = &account_name_p;
5061 :
5062 3 : status = dcerpc_lsa_GetUserName_r(b, tctx, &r);
5063 3 : if (!NT_STATUS_IS_OK(status)) {
5064 3 : if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5065 3 : torture_comment(tctx,
5066 : "GetUserName correctly returned with "
5067 : "status: %s\n",
5068 : nt_errstr(status));
5069 3 : return true;
5070 : }
5071 :
5072 0 : torture_assert_ntstatus_equal(tctx,
5073 : status,
5074 : NT_STATUS_ACCESS_DENIED,
5075 : "GetUserName return value should "
5076 : "be ACCESS_DENIED");
5077 0 : return true;
5078 : }
5079 :
5080 0 : if (!NT_STATUS_IS_OK(r.out.result)) {
5081 0 : if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
5082 0 : NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
5083 0 : torture_comment(tctx,
5084 : "GetUserName correctly returned with "
5085 : "result: %s\n",
5086 : nt_errstr(r.out.result));
5087 0 : return true;
5088 : }
5089 : }
5090 :
5091 0 : torture_assert_ntstatus_equal(tctx,
5092 : r.out.result,
5093 : NT_STATUS_OK,
5094 : "GetUserName return value should be "
5095 : "ACCESS_DENIED");
5096 :
5097 0 : return false;
5098 : }
5099 :
5100 55 : bool test_lsa_Close(struct dcerpc_binding_handle *b,
5101 : struct torture_context *tctx,
5102 : struct policy_handle *handle)
5103 : {
5104 : struct lsa_Close r;
5105 : struct policy_handle handle2;
5106 :
5107 55 : torture_comment(tctx, "\nTesting Close\n");
5108 :
5109 55 : r.in.handle = handle;
5110 55 : r.out.handle = &handle2;
5111 :
5112 55 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &r),
5113 : "Close failed");
5114 55 : torture_assert_ntstatus_ok(tctx, r.out.result,
5115 : "Close failed");
5116 :
5117 55 : torture_assert_ntstatus_equal(tctx, dcerpc_lsa_Close_r(b, tctx, &r),
5118 : NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "Close should failed");
5119 :
5120 55 : torture_comment(tctx, "\n");
5121 :
5122 55 : return true;
5123 : }
5124 :
5125 9 : bool torture_rpc_lsa(struct torture_context *tctx)
5126 : {
5127 : NTSTATUS status;
5128 : struct dcerpc_pipe *p;
5129 9 : bool ret = true;
5130 9 : struct policy_handle *handle = NULL;
5131 9 : struct test_join *join = NULL;
5132 : struct cli_credentials *machine_creds;
5133 : struct dcerpc_binding_handle *b;
5134 : enum dcerpc_transport_t transport;
5135 :
5136 9 : status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
5137 9 : torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
5138 :
5139 9 : b = p->binding_handle;
5140 9 : transport = dcerpc_binding_get_transport(p->binding);
5141 :
5142 : /* Test lsaLookupSids3 and lsaLookupNames4 over tcpip */
5143 9 : if (transport == NCACN_IP_TCP) {
5144 3 : if (!test_OpenPolicy_fail(b, tctx)) {
5145 0 : ret = false;
5146 : }
5147 :
5148 3 : if (!test_OpenPolicy2_fail(b, tctx)) {
5149 0 : ret = false;
5150 : }
5151 :
5152 3 : if (!test_many_LookupSids(p, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5153 0 : ret = false;
5154 : }
5155 :
5156 3 : return ret;
5157 : }
5158 :
5159 6 : if (!test_OpenPolicy(b, tctx)) {
5160 0 : ret = false;
5161 : }
5162 :
5163 6 : if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5164 0 : ret = false;
5165 : }
5166 :
5167 6 : if (handle) {
5168 6 : join = torture_join_domain(tctx, TEST_MACHINENAME, ACB_WSTRUST, &machine_creds);
5169 6 : if (!join) {
5170 0 : ret = false;
5171 : }
5172 :
5173 6 : if (!test_LookupSids_async(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5174 0 : ret = false;
5175 : }
5176 :
5177 6 : if (!test_QueryDomainInfoPolicy(b, tctx, handle)) {
5178 0 : ret = false;
5179 : }
5180 :
5181 6 : if (!test_CreateSecret(p, tctx, handle)) {
5182 1 : ret = false;
5183 : }
5184 :
5185 6 : if (!test_QueryInfoPolicy(b, tctx, handle)) {
5186 0 : ret = false;
5187 : }
5188 :
5189 6 : if (!test_QueryInfoPolicy2(b, tctx, handle)) {
5190 0 : ret = false;
5191 : }
5192 :
5193 6 : if (!test_Delete(b, tctx, handle)) {
5194 0 : ret = false;
5195 : }
5196 :
5197 6 : if (!test_many_LookupSids(p, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5198 0 : ret = false;
5199 : }
5200 :
5201 6 : if (!test_lsa_Close(b, tctx, handle)) {
5202 0 : ret = false;
5203 : }
5204 :
5205 6 : torture_leave_domain(tctx, join);
5206 :
5207 : } else {
5208 0 : if (!test_many_LookupSids(p, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5209 0 : ret = false;
5210 : }
5211 : }
5212 :
5213 6 : if (!test_GetUserName(b, tctx)) {
5214 0 : ret = false;
5215 : }
5216 :
5217 6 : return ret;
5218 : }
5219 :
5220 9 : bool torture_rpc_lsa_get_user(struct torture_context *tctx)
5221 : {
5222 : NTSTATUS status;
5223 : struct dcerpc_pipe *p;
5224 9 : bool ret = true;
5225 : struct dcerpc_binding_handle *b;
5226 : enum dcerpc_transport_t transport;
5227 :
5228 9 : status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
5229 9 : torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
5230 :
5231 9 : b = p->binding_handle;
5232 9 : transport = dcerpc_binding_get_transport(p->binding);
5233 :
5234 9 : if (transport == NCACN_IP_TCP) {
5235 3 : if (!test_GetUserName_fail(b, tctx)) {
5236 0 : ret = false;
5237 : }
5238 3 : return ret;
5239 : }
5240 :
5241 6 : if (!test_GetUserName(b, tctx)) {
5242 0 : ret = false;
5243 : }
5244 :
5245 6 : return ret;
5246 : }
5247 :
5248 3 : static bool testcase_LookupNames(struct torture_context *tctx,
5249 : struct dcerpc_pipe *p)
5250 : {
5251 3 : bool ret = true;
5252 : struct policy_handle *handle;
5253 : struct lsa_TransNameArray tnames;
5254 : struct lsa_TransNameArray2 tnames2;
5255 3 : struct dcerpc_binding_handle *b = p->binding_handle;
5256 3 : enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
5257 :
5258 3 : if (transport != NCACN_NP && transport != NCALRPC) {
5259 0 : torture_comment(tctx, "testcase_LookupNames is only available "
5260 : "over NCACN_NP or NCALRPC");
5261 0 : return true;
5262 : }
5263 :
5264 3 : if (!test_OpenPolicy(b, tctx)) {
5265 0 : ret = false;
5266 : }
5267 :
5268 3 : if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5269 0 : ret = false;
5270 : }
5271 :
5272 3 : if (!handle) {
5273 0 : ret = false;
5274 : }
5275 :
5276 3 : tnames.count = 1;
5277 3 : tnames.names = talloc_array(tctx, struct lsa_TranslatedName, tnames.count);
5278 3 : ZERO_STRUCT(tnames.names[0]);
5279 3 : tnames.names[0].name.string = "BUILTIN";
5280 3 : tnames.names[0].sid_type = SID_NAME_DOMAIN;
5281 :
5282 3 : if (!test_LookupNames(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames)) {
5283 0 : ret = false;
5284 : }
5285 :
5286 3 : tnames2.count = 1;
5287 3 : tnames2.names = talloc_array(tctx, struct lsa_TranslatedName2, tnames2.count);
5288 3 : ZERO_STRUCT(tnames2.names[0]);
5289 3 : tnames2.names[0].name.string = "BUILTIN";
5290 3 : tnames2.names[0].sid_type = SID_NAME_DOMAIN;
5291 :
5292 3 : if (!test_LookupNames2(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames2, true)) {
5293 0 : ret = false;
5294 : }
5295 :
5296 3 : if (!test_LookupNames3(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames2, true)) {
5297 0 : ret = false;
5298 : }
5299 :
5300 3 : if (!test_LookupNames_wellknown(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5301 0 : ret = false;
5302 : }
5303 :
5304 3 : if (!test_LookupNames_NULL(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5305 0 : ret = false;
5306 : }
5307 :
5308 3 : if (!test_LookupNames_bogus(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5309 0 : ret = false;
5310 : }
5311 :
5312 3 : if (!test_lsa_Close(b, tctx, handle)) {
5313 0 : ret = false;
5314 : }
5315 :
5316 3 : return ret;
5317 : }
5318 :
5319 964 : struct torture_suite *torture_rpc_lsa_lookup_names(TALLOC_CTX *mem_ctx)
5320 : {
5321 : struct torture_suite *suite;
5322 : struct torture_rpc_tcase *tcase;
5323 :
5324 964 : suite = torture_suite_create(mem_ctx, "lsa.lookupnames");
5325 :
5326 964 : tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5327 : &ndr_table_lsarpc);
5328 964 : torture_rpc_tcase_add_test(tcase, "LookupNames",
5329 : testcase_LookupNames);
5330 :
5331 964 : return suite;
5332 : }
5333 :
5334 : struct lsa_trustdom_state {
5335 : uint32_t num_trusts;
5336 : };
5337 :
5338 3 : static bool testcase_TrustedDomains(struct torture_context *tctx,
5339 : struct dcerpc_pipe *p,
5340 : void *data)
5341 : {
5342 3 : bool ret = true;
5343 : struct policy_handle *handle;
5344 3 : struct lsa_trustdom_state *state =
5345 0 : talloc_get_type_abort(data, struct lsa_trustdom_state);
5346 3 : struct dcerpc_binding_handle *b = p->binding_handle;
5347 3 : enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
5348 :
5349 3 : if (transport != NCACN_NP && transport != NCALRPC) {
5350 0 : torture_comment(tctx, "testcase_TrustedDomains is only available "
5351 : "over NCACN_NP or NCALRPC");
5352 0 : return true;
5353 : }
5354 :
5355 3 : torture_comment(tctx, "Testing %d domains\n", state->num_trusts);
5356 :
5357 3 : if (!test_OpenPolicy(b, tctx)) {
5358 0 : ret = false;
5359 : }
5360 :
5361 3 : if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5362 0 : ret = false;
5363 : }
5364 :
5365 3 : if (!handle) {
5366 0 : ret = false;
5367 : }
5368 :
5369 3 : if (!test_CreateTrustedDomain(b, tctx, handle, state->num_trusts)) {
5370 0 : ret = false;
5371 : }
5372 :
5373 3 : if (!test_CreateTrustedDomainEx(p, tctx, handle, state->num_trusts)) {
5374 0 : ret = false;
5375 : }
5376 :
5377 3 : if (!test_CreateTrustedDomainEx2(p, tctx, handle, state->num_trusts)) {
5378 0 : ret = false;
5379 : }
5380 :
5381 3 : if (!test_lsa_Close(b, tctx, handle)) {
5382 0 : ret = false;
5383 : }
5384 :
5385 3 : return ret;
5386 : }
5387 :
5388 964 : struct torture_suite *torture_rpc_lsa_trusted_domains(TALLOC_CTX *mem_ctx)
5389 : {
5390 : struct torture_suite *suite;
5391 : struct torture_rpc_tcase *tcase;
5392 : struct lsa_trustdom_state *state;
5393 :
5394 964 : state = talloc(mem_ctx, struct lsa_trustdom_state);
5395 :
5396 964 : state->num_trusts = 12;
5397 :
5398 964 : suite = torture_suite_create(mem_ctx, "lsa.trusted.domains");
5399 :
5400 964 : tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5401 : &ndr_table_lsarpc);
5402 964 : torture_rpc_tcase_add_test_ex(tcase, "TrustedDomains",
5403 : testcase_TrustedDomains,
5404 : state);
5405 :
5406 964 : return suite;
5407 : }
5408 :
5409 3 : static bool testcase_Privileges(struct torture_context *tctx,
5410 : struct dcerpc_pipe *p)
5411 : {
5412 : struct policy_handle *handle;
5413 3 : struct dcerpc_binding_handle *b = p->binding_handle;
5414 3 : enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
5415 :
5416 3 : if (transport != NCACN_NP && transport != NCALRPC) {
5417 0 : torture_skip(tctx, "testcase_Privileges is only available "
5418 : "over NCACN_NP or NCALRPC");
5419 : }
5420 :
5421 3 : if (!test_OpenPolicy(b, tctx)) {
5422 0 : return false;
5423 : }
5424 :
5425 3 : if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5426 0 : return false;
5427 : }
5428 :
5429 3 : if (!handle) {
5430 0 : return false;
5431 : }
5432 :
5433 3 : if (!test_CreateAccount(b, tctx, handle)) {
5434 0 : return false;
5435 : }
5436 :
5437 3 : if (!test_EnumAccounts(b, tctx, handle)) {
5438 0 : return false;
5439 : }
5440 :
5441 3 : if (!test_EnumPrivs(b, tctx, handle)) {
5442 0 : return false;
5443 : }
5444 :
5445 3 : if (!test_lsa_Close(b, tctx, handle)) {
5446 0 : return false;
5447 : }
5448 :
5449 3 : return true;
5450 : }
5451 :
5452 :
5453 964 : struct torture_suite *torture_rpc_lsa_privileges(TALLOC_CTX *mem_ctx)
5454 : {
5455 : struct torture_suite *suite;
5456 : struct torture_rpc_tcase *tcase;
5457 :
5458 964 : suite = torture_suite_create(mem_ctx, "lsa.privileges");
5459 :
5460 964 : tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5461 : &ndr_table_lsarpc);
5462 964 : torture_rpc_tcase_add_test(tcase, "Privileges",
5463 : testcase_Privileges);
5464 :
5465 964 : return suite;
5466 : }
|