s4-torture: use smb_krb5_principal_set_type() in lsa forest krb5 tests.
[Samba.git] / source4 / torture / rpc / lsa.c
blob95caebbd004554d75ab3de9eeb9b4ffab6d73573
1 /*
2 Unix SMB/CIFS implementation.
3 test suite for lsa rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
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.
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.
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/>.
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 "../lib/crypto/crypto.h"
39 #define TEST_MACHINENAME "lsatestmach"
40 #define TRUSTPW "12345678"
42 static void init_lsa_String(struct lsa_String *name, const char *s)
44 name->string = s;
47 static bool test_OpenPolicy(struct dcerpc_binding_handle *b,
48 struct torture_context *tctx)
50 struct lsa_ObjectAttribute attr;
51 struct policy_handle handle;
52 struct lsa_QosInfo qos;
53 struct lsa_OpenPolicy r;
54 uint16_t system_name = '\\';
56 torture_comment(tctx, "\nTesting OpenPolicy\n");
58 qos.len = 0;
59 qos.impersonation_level = 2;
60 qos.context_mode = 1;
61 qos.effective_only = 0;
63 attr.len = 0;
64 attr.root_dir = NULL;
65 attr.object_name = NULL;
66 attr.attributes = 0;
67 attr.sec_desc = NULL;
68 attr.sec_qos = &qos;
70 r.in.system_name = &system_name;
71 r.in.attr = &attr;
72 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
73 r.out.handle = &handle;
75 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy_r(b, tctx, &r),
76 "OpenPolicy failed");
78 torture_assert_ntstatus_ok(tctx,
79 r.out.result,
80 "OpenPolicy failed");
82 return true;
85 static bool test_OpenPolicy_fail(struct dcerpc_binding_handle *b,
86 struct torture_context *tctx)
88 struct lsa_ObjectAttribute attr;
89 struct policy_handle handle;
90 struct lsa_QosInfo qos;
91 struct lsa_OpenPolicy r;
92 uint16_t system_name = '\\';
93 NTSTATUS status;
95 torture_comment(tctx, "\nTesting OpenPolicy_fail\n");
97 qos.len = 0;
98 qos.impersonation_level = 2;
99 qos.context_mode = 1;
100 qos.effective_only = 0;
102 attr.len = 0;
103 attr.root_dir = NULL;
104 attr.object_name = NULL;
105 attr.attributes = 0;
106 attr.sec_desc = NULL;
107 attr.sec_qos = &qos;
109 r.in.system_name = &system_name;
110 r.in.attr = &attr;
111 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
112 r.out.handle = &handle;
114 status = dcerpc_lsa_OpenPolicy_r(b, tctx, &r);
115 if (!NT_STATUS_IS_OK(status)) {
116 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
117 torture_comment(tctx,
118 "OpenPolicy correctly returned with "
119 "status: %s\n",
120 nt_errstr(status));
121 return true;
124 torture_assert_ntstatus_equal(tctx,
125 status,
126 NT_STATUS_ACCESS_DENIED,
127 "OpenPolicy return value should "
128 "be ACCESS_DENIED");
129 return true;
132 if (!NT_STATUS_IS_OK(r.out.result)) {
133 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
134 NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
135 torture_comment(tctx,
136 "OpenPolicy correctly returned with "
137 "result: %s\n",
138 nt_errstr(r.out.result));
139 return true;
143 torture_assert_ntstatus_equal(tctx,
144 r.out.result,
145 NT_STATUS_OK,
146 "OpenPolicy return value should be "
147 "ACCESS_DENIED");
149 return false;
153 bool test_lsa_OpenPolicy2_ex(struct dcerpc_binding_handle *b,
154 struct torture_context *tctx,
155 struct policy_handle **handle,
156 NTSTATUS expected_status)
158 struct lsa_ObjectAttribute attr;
159 struct lsa_QosInfo qos;
160 struct lsa_OpenPolicy2 r;
161 NTSTATUS status;
163 torture_comment(tctx, "\nTesting OpenPolicy2\n");
165 *handle = talloc(tctx, struct policy_handle);
166 torture_assert(tctx, *handle != NULL, "talloc(tctx, struct policy_handle)");
168 qos.len = 0;
169 qos.impersonation_level = 2;
170 qos.context_mode = 1;
171 qos.effective_only = 0;
173 attr.len = 0;
174 attr.root_dir = NULL;
175 attr.object_name = NULL;
176 attr.attributes = 0;
177 attr.sec_desc = NULL;
178 attr.sec_qos = &qos;
180 r.in.system_name = "\\";
181 r.in.attr = &attr;
182 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
183 r.out.handle = *handle;
185 status = dcerpc_lsa_OpenPolicy2_r(b, tctx, &r);
186 torture_assert_ntstatus_equal(tctx, status, expected_status,
187 "OpenPolicy2 failed");
188 if (!NT_STATUS_IS_OK(expected_status)) {
189 return true;
192 torture_assert_ntstatus_ok(tctx,
193 r.out.result,
194 "OpenPolicy2 failed");
196 return true;
200 bool test_lsa_OpenPolicy2(struct dcerpc_binding_handle *b,
201 struct torture_context *tctx,
202 struct policy_handle **handle)
204 return test_lsa_OpenPolicy2_ex(b, tctx, handle, NT_STATUS_OK);
207 static bool test_OpenPolicy2_fail(struct dcerpc_binding_handle *b,
208 struct torture_context *tctx)
210 struct lsa_ObjectAttribute attr;
211 struct policy_handle handle;
212 struct lsa_QosInfo qos;
213 struct lsa_OpenPolicy2 r;
214 NTSTATUS status;
216 torture_comment(tctx, "\nTesting OpenPolicy2_fail\n");
218 qos.len = 0;
219 qos.impersonation_level = 2;
220 qos.context_mode = 1;
221 qos.effective_only = 0;
223 attr.len = 0;
224 attr.root_dir = NULL;
225 attr.object_name = NULL;
226 attr.attributes = 0;
227 attr.sec_desc = NULL;
228 attr.sec_qos = &qos;
230 r.in.system_name = "\\";
231 r.in.attr = &attr;
232 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
233 r.out.handle = &handle;
235 status = dcerpc_lsa_OpenPolicy2_r(b, tctx, &r);
236 if (!NT_STATUS_IS_OK(status)) {
237 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
238 torture_comment(tctx,
239 "OpenPolicy2 correctly returned with "
240 "status: %s\n",
241 nt_errstr(status));
242 return true;
245 torture_assert_ntstatus_equal(tctx,
246 status,
247 NT_STATUS_ACCESS_DENIED,
248 "OpenPolicy2 return value should "
249 "be ACCESS_DENIED");
250 return true;
253 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
254 NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
255 torture_comment(tctx,
256 "OpenPolicy2 correctly returned with "
257 "result: %s\n",
258 nt_errstr(r.out.result));
259 return true;
262 torture_fail(tctx,
263 "OpenPolicy2 return value should be "
264 "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
266 return false;
269 static bool test_LookupNames(struct dcerpc_binding_handle *b,
270 struct torture_context *tctx,
271 struct policy_handle *handle,
272 struct lsa_TransNameArray *tnames)
274 struct lsa_LookupNames r;
275 struct lsa_TransSidArray sids;
276 struct lsa_RefDomainList *domains = NULL;
277 struct lsa_String *names;
278 uint32_t count = 0;
279 int i;
280 uint32_t *input_idx;
282 torture_comment(tctx, "\nTesting LookupNames with %d names\n", tnames->count);
284 sids.count = 0;
285 sids.sids = NULL;
288 r.in.num_names = 0;
290 input_idx = talloc_array(tctx, uint32_t, tnames->count);
291 names = talloc_array(tctx, struct lsa_String, tnames->count);
293 for (i=0;i<tnames->count;i++) {
294 if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
295 init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
296 input_idx[r.in.num_names] = i;
297 r.in.num_names++;
301 r.in.handle = handle;
302 r.in.names = names;
303 r.in.sids = &sids;
304 r.in.level = 1;
305 r.in.count = &count;
306 r.out.count = &count;
307 r.out.sids = &sids;
308 r.out.domains = &domains;
310 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
311 "LookupNames failed");
312 if (NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED) ||
313 NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
314 for (i=0;i< r.in.num_names;i++) {
315 if (i < count && sids.sids[i].sid_type == SID_NAME_UNKNOWN) {
316 torture_comment(tctx, "LookupName of %s was unmapped\n",
317 tnames->names[i].name.string);
318 } else if (i >=count) {
319 torture_comment(tctx, "LookupName of %s failed to return a result\n",
320 tnames->names[i].name.string);
323 torture_assert_ntstatus_ok(tctx, r.out.result,
324 "LookupNames failed");
325 } else if (!NT_STATUS_IS_OK(r.out.result)) {
326 torture_assert_ntstatus_ok(tctx, r.out.result,
327 "LookupNames failed");
330 for (i=0;i< r.in.num_names;i++) {
331 torture_assert(tctx, (i < count),
332 talloc_asprintf(tctx,
333 "LookupName of %s failed to return a result\n",
334 tnames->names[input_idx[i]].name.string));
336 torture_assert_int_equal(tctx,
337 sids.sids[i].sid_type,
338 tnames->names[input_idx[i]].sid_type,
339 talloc_asprintf(tctx,
340 "LookupName of %s got unexpected name type: %s\n",
341 tnames->names[input_idx[i]].name.string,
342 sid_type_lookup(sids.sids[i].sid_type)));
343 if (sids.sids[i].sid_type != SID_NAME_DOMAIN) {
344 continue;
346 torture_assert_int_equal(tctx,
347 sids.sids[i].rid,
348 UINT32_MAX,
349 talloc_asprintf(tctx,
350 "LookupName of %s got unexpected rid: %d\n",
351 tnames->names[input_idx[i]].name.string,
352 sids.sids[i].rid));
355 return true;
358 static bool test_LookupNames_bogus(struct dcerpc_binding_handle *b,
359 struct torture_context *tctx,
360 struct policy_handle *handle)
362 struct lsa_LookupNames r;
363 struct lsa_TransSidArray sids;
364 struct lsa_RefDomainList *domains = NULL;
365 struct lsa_String names[1];
366 uint32_t count = 0;
368 torture_comment(tctx, "\nTesting LookupNames with bogus name\n");
370 sids.count = 0;
371 sids.sids = NULL;
373 init_lsa_String(&names[0], "NT AUTHORITY\\BOGUS");
375 r.in.handle = handle;
376 r.in.num_names = 1;
377 r.in.names = names;
378 r.in.sids = &sids;
379 r.in.level = 1;
380 r.in.count = &count;
381 r.out.count = &count;
382 r.out.sids = &sids;
383 r.out.domains = &domains;
385 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
386 "LookupNames bogus failed");
387 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
388 torture_comment(tctx, "LookupNames failed - %s\n",
389 nt_errstr(r.out.result));
390 return false;
393 torture_comment(tctx, "\n");
395 return true;
398 static bool test_LookupNames_NULL(struct dcerpc_binding_handle *b,
399 struct torture_context *tctx,
400 struct policy_handle *handle)
402 struct lsa_LookupNames r;
403 struct lsa_TransSidArray sids;
404 struct lsa_RefDomainList *domains = NULL;
405 struct lsa_String names[1];
406 uint32_t count = 0;
408 torture_comment(tctx, "\nTesting LookupNames with NULL name\n");
410 sids.count = 0;
411 sids.sids = NULL;
413 names[0].string = NULL;
415 r.in.handle = handle;
416 r.in.num_names = 1;
417 r.in.names = names;
418 r.in.sids = &sids;
419 r.in.level = 1;
420 r.in.count = &count;
421 r.out.count = &count;
422 r.out.sids = &sids;
423 r.out.domains = &domains;
425 /* nt4 returns NT_STATUS_NONE_MAPPED with sid_type
426 * SID_NAME_UNKNOWN, rid 0, and sid_index -1;
428 * w2k3/w2k8 return NT_STATUS_OK with sid_type
429 * SID_NAME_DOMAIN, rid -1 and sid_index 0 and BUILTIN domain
432 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
433 "LookupNames with NULL name failed");
434 torture_assert_ntstatus_ok(tctx, r.out.result,
435 "LookupNames with NULL name failed");
437 torture_comment(tctx, "\n");
439 return true;
442 static bool test_LookupNames_wellknown(struct dcerpc_binding_handle *b,
443 struct torture_context *tctx,
444 struct policy_handle *handle)
446 struct lsa_TranslatedName name;
447 struct lsa_TransNameArray tnames;
448 bool ret = true;
450 torture_comment(tctx, "Testing LookupNames with well known names\n");
452 tnames.names = &name;
453 tnames.count = 1;
454 name.name.string = "NT AUTHORITY\\SYSTEM";
455 name.sid_type = SID_NAME_WKN_GRP;
456 ret &= test_LookupNames(b, tctx, handle, &tnames);
458 name.name.string = "NT AUTHORITY\\ANONYMOUS LOGON";
459 name.sid_type = SID_NAME_WKN_GRP;
460 ret &= test_LookupNames(b, tctx, handle, &tnames);
462 name.name.string = "NT AUTHORITY\\Authenticated Users";
463 name.sid_type = SID_NAME_WKN_GRP;
464 ret &= test_LookupNames(b, tctx, handle, &tnames);
466 #if 0
467 name.name.string = "NT AUTHORITY";
468 ret &= test_LookupNames(b, tctx, handle, &tnames);
470 name.name.string = "NT AUTHORITY\\";
471 ret &= test_LookupNames(b, tctx, handle, &tnames);
472 #endif
474 name.name.string = "BUILTIN\\";
475 name.sid_type = SID_NAME_DOMAIN;
476 ret &= test_LookupNames(b, tctx, handle, &tnames);
478 name.name.string = "BUILTIN\\Administrators";
479 name.sid_type = SID_NAME_ALIAS;
480 ret &= test_LookupNames(b, tctx, handle, &tnames);
482 name.name.string = "SYSTEM";
483 name.sid_type = SID_NAME_WKN_GRP;
484 ret &= test_LookupNames(b, tctx, handle, &tnames);
486 name.name.string = "Everyone";
487 name.sid_type = SID_NAME_WKN_GRP;
488 ret &= test_LookupNames(b, tctx, handle, &tnames);
489 return ret;
492 static bool test_LookupNames2(struct dcerpc_binding_handle *b,
493 struct torture_context *tctx,
494 struct policy_handle *handle,
495 struct lsa_TransNameArray2 *tnames,
496 bool check_result)
498 struct lsa_LookupNames2 r;
499 struct lsa_TransSidArray2 sids;
500 struct lsa_RefDomainList *domains = NULL;
501 struct lsa_String *names;
502 uint32_t *input_idx;
503 uint32_t count = 0;
504 int i;
506 torture_comment(tctx, "\nTesting LookupNames2 with %d names\n", tnames->count);
508 sids.count = 0;
509 sids.sids = NULL;
511 r.in.num_names = 0;
513 input_idx = talloc_array(tctx, uint32_t, tnames->count);
514 names = talloc_array(tctx, struct lsa_String, tnames->count);
516 for (i=0;i<tnames->count;i++) {
517 if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
518 init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
519 input_idx[r.in.num_names] = i;
520 r.in.num_names++;
524 r.in.handle = handle;
525 r.in.names = names;
526 r.in.sids = &sids;
527 r.in.level = 1;
528 r.in.count = &count;
529 r.in.lookup_options = 0;
530 r.in.client_revision = 0;
531 r.out.count = &count;
532 r.out.sids = &sids;
533 r.out.domains = &domains;
535 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames2_r(b, tctx, &r),
536 "LookupNames2 failed");
537 torture_assert_ntstatus_ok(tctx, r.out.result, "LookupNames2 failed");
539 if (check_result) {
540 torture_assert_int_equal(tctx, count, sids.count,
541 "unexpected number of results returned");
542 if (sids.count > 0) {
543 torture_assert(tctx, sids.sids, "invalid sid buffer");
547 torture_comment(tctx, "\n");
549 return true;
553 static bool test_LookupNames3(struct dcerpc_binding_handle *b,
554 struct torture_context *tctx,
555 struct policy_handle *handle,
556 struct lsa_TransNameArray2 *tnames,
557 bool check_result)
559 struct lsa_LookupNames3 r;
560 struct lsa_TransSidArray3 sids;
561 struct lsa_RefDomainList *domains = NULL;
562 struct lsa_String *names;
563 uint32_t count = 0;
564 int i;
565 uint32_t *input_idx;
567 torture_comment(tctx, "\nTesting LookupNames3 with %d names\n", tnames->count);
569 sids.count = 0;
570 sids.sids = NULL;
572 r.in.num_names = 0;
574 input_idx = talloc_array(tctx, uint32_t, tnames->count);
575 names = talloc_array(tctx, struct lsa_String, tnames->count);
576 for (i=0;i<tnames->count;i++) {
577 if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
578 init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
579 input_idx[r.in.num_names] = i;
580 r.in.num_names++;
584 r.in.handle = handle;
585 r.in.names = names;
586 r.in.sids = &sids;
587 r.in.level = 1;
588 r.in.count = &count;
589 r.in.lookup_options = 0;
590 r.in.client_revision = 0;
591 r.out.count = &count;
592 r.out.sids = &sids;
593 r.out.domains = &domains;
595 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames3_r(b, tctx, &r),
596 "LookupNames3 failed");
597 torture_assert_ntstatus_ok(tctx, r.out.result,
598 "LookupNames3 failed");
600 if (check_result) {
601 torture_assert_int_equal(tctx, count, sids.count,
602 "unexpected number of results returned");
603 if (sids.count > 0) {
604 torture_assert(tctx, sids.sids, "invalid sid buffer");
608 torture_comment(tctx, "\n");
610 return true;
613 static bool test_LookupNames4(struct dcerpc_binding_handle *b,
614 struct torture_context *tctx,
615 struct lsa_TransNameArray2 *tnames,
616 bool check_result)
618 struct lsa_LookupNames4 r;
619 struct lsa_TransSidArray3 sids;
620 struct lsa_RefDomainList *domains = NULL;
621 struct lsa_String *names;
622 uint32_t count = 0;
623 int i;
624 uint32_t *input_idx;
626 torture_comment(tctx, "\nTesting LookupNames4 with %d names\n", tnames->count);
628 sids.count = 0;
629 sids.sids = NULL;
631 r.in.num_names = 0;
633 input_idx = talloc_array(tctx, uint32_t, tnames->count);
634 names = talloc_array(tctx, struct lsa_String, tnames->count);
635 for (i=0;i<tnames->count;i++) {
636 if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
637 init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
638 input_idx[r.in.num_names] = i;
639 r.in.num_names++;
643 r.in.num_names = tnames->count;
644 r.in.names = names;
645 r.in.sids = &sids;
646 r.in.level = 1;
647 r.in.count = &count;
648 r.in.lookup_options = 0;
649 r.in.client_revision = 0;
650 r.out.count = &count;
651 r.out.sids = &sids;
652 r.out.domains = &domains;
654 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames4_r(b, tctx, &r),
655 "LookupNames4 failed");
657 if (!NT_STATUS_IS_OK(r.out.result)) {
658 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
659 torture_comment(tctx,
660 "LookupNames4 failed: %s - not considered as an error",
661 nt_errstr(r.out.result));
663 return true;
666 torture_assert_ntstatus_ok(tctx,
667 r.out.result,
668 "LookupNames4 failed");
670 if (check_result) {
671 torture_assert_int_equal(tctx, count, sids.count,
672 "unexpected number of results returned");
673 if (sids.count > 0) {
674 torture_assert(tctx, sids.sids, "invalid sid buffer");
678 torture_comment(tctx, "\n");
680 return true;
683 static bool test_LookupNames4_fail(struct dcerpc_binding_handle *b,
684 struct torture_context *tctx)
686 struct lsa_LookupNames4 r;
687 struct lsa_TransSidArray3 sids;
688 struct lsa_RefDomainList *domains = NULL;
689 struct lsa_String *names = NULL;
690 uint32_t count = 0;
691 NTSTATUS status;
693 torture_comment(tctx, "\nTesting LookupNames4_fail");
695 sids.count = 0;
696 sids.sids = NULL;
698 r.in.num_names = 0;
700 r.in.num_names = count;
701 r.in.names = names;
702 r.in.sids = &sids;
703 r.in.level = 1;
704 r.in.count = &count;
705 r.in.lookup_options = 0;
706 r.in.client_revision = 0;
707 r.out.count = &count;
708 r.out.sids = &sids;
709 r.out.domains = &domains;
711 status = dcerpc_lsa_LookupNames4_r(b, tctx, &r);
712 if (!NT_STATUS_IS_OK(status)) {
713 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
714 torture_comment(tctx,
715 "LookupNames4 correctly returned with "
716 "status: %s\n",
717 nt_errstr(status));
718 return true;
721 torture_assert_ntstatus_equal(tctx,
722 status,
723 NT_STATUS_ACCESS_DENIED,
724 "LookupNames4 return value should "
725 "be ACCESS_DENIED");
726 return true;
729 if (!NT_STATUS_IS_OK(r.out.result)) {
730 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
731 NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
732 torture_comment(tctx,
733 "LookupSids3 correctly returned with "
734 "result: %s\n",
735 nt_errstr(r.out.result));
736 return true;
740 torture_fail(tctx,
741 "LookupNames4 return value should be "
742 "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
744 return false;
748 static bool test_LookupSids(struct dcerpc_binding_handle *b,
749 struct torture_context *tctx,
750 struct policy_handle *handle,
751 struct lsa_SidArray *sids)
753 struct lsa_LookupSids r;
754 struct lsa_TransNameArray names;
755 struct lsa_RefDomainList *domains = NULL;
756 uint32_t count = sids->num_sids;
758 torture_comment(tctx, "\nTesting LookupSids\n");
760 names.count = 0;
761 names.names = NULL;
763 r.in.handle = handle;
764 r.in.sids = sids;
765 r.in.names = &names;
766 r.in.level = 1;
767 r.in.count = &count;
768 r.out.count = &count;
769 r.out.names = &names;
770 r.out.domains = &domains;
772 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids_r(b, tctx, &r),
773 "LookupSids failed");
774 if (!NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED)) {
775 torture_assert_ntstatus_ok(tctx, r.out.result,
776 "LookupSids failed");
779 torture_comment(tctx, "\n");
781 if (!test_LookupNames(b, tctx, handle, &names)) {
782 return false;
785 return true;
789 static bool test_LookupSids2(struct dcerpc_binding_handle *b,
790 struct torture_context *tctx,
791 struct policy_handle *handle,
792 struct lsa_SidArray *sids)
794 struct lsa_LookupSids2 r;
795 struct lsa_TransNameArray2 names;
796 struct lsa_RefDomainList *domains = NULL;
797 uint32_t count = sids->num_sids;
799 torture_comment(tctx, "\nTesting LookupSids2\n");
801 names.count = 0;
802 names.names = NULL;
804 r.in.handle = handle;
805 r.in.sids = sids;
806 r.in.names = &names;
807 r.in.level = 1;
808 r.in.count = &count;
809 r.in.lookup_options = 0;
810 r.in.client_revision = 0;
811 r.out.count = &count;
812 r.out.names = &names;
813 r.out.domains = &domains;
815 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids2_r(b, tctx, &r),
816 "LookupSids2 failed");
817 if (!NT_STATUS_IS_OK(r.out.result) &&
818 !NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED)) {
819 torture_comment(tctx, "LookupSids2 failed - %s\n",
820 nt_errstr(r.out.result));
821 return false;
824 torture_comment(tctx, "\n");
826 if (!test_LookupNames2(b, tctx, handle, &names, false)) {
827 return false;
830 if (!test_LookupNames3(b, tctx, handle, &names, false)) {
831 return false;
834 return true;
837 static bool test_LookupSids3(struct dcerpc_binding_handle *b,
838 struct torture_context *tctx,
839 struct lsa_SidArray *sids)
841 struct lsa_LookupSids3 r;
842 struct lsa_TransNameArray2 names;
843 struct lsa_RefDomainList *domains = NULL;
844 uint32_t count = sids->num_sids;
846 torture_comment(tctx, "\nTesting LookupSids3\n");
848 names.count = 0;
849 names.names = NULL;
851 r.in.sids = sids;
852 r.in.names = &names;
853 r.in.level = 1;
854 r.in.count = &count;
855 r.in.lookup_options = 0;
856 r.in.client_revision = 0;
857 r.out.domains = &domains;
858 r.out.count = &count;
859 r.out.names = &names;
861 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids3_r(b, tctx, &r),
862 "LookupSids3 failed");
864 if (!NT_STATUS_IS_OK(r.out.result)) {
865 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
866 torture_comment(tctx,
867 "LookupSids3 failed: %s - not considered as an error",
868 nt_errstr(r.out.result));
870 return true;
873 torture_assert_ntstatus_ok(tctx,
874 r.out.result,
875 "LookupSids3 failed");
877 return false;
880 torture_comment(tctx, "\n");
882 if (!test_LookupNames4(b, tctx, &names, true)) {
883 return false;
886 return true;
889 static bool test_LookupSids3_fail(struct dcerpc_binding_handle *b,
890 struct torture_context *tctx,
891 struct lsa_SidArray *sids)
893 struct lsa_LookupSids3 r;
894 struct lsa_TransNameArray2 names;
895 struct lsa_RefDomainList *domains = NULL;
896 uint32_t count = sids->num_sids;
897 NTSTATUS status;
899 torture_comment(tctx, "\nTesting LookupSids3\n");
901 names.count = 0;
902 names.names = NULL;
904 r.in.sids = sids;
905 r.in.names = &names;
906 r.in.level = 1;
907 r.in.count = &count;
908 r.in.lookup_options = 0;
909 r.in.client_revision = 0;
910 r.out.domains = &domains;
911 r.out.count = &count;
912 r.out.names = &names;
914 status = dcerpc_lsa_LookupSids3_r(b, tctx, &r);
915 if (!NT_STATUS_IS_OK(status)) {
916 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
917 torture_comment(tctx,
918 "LookupSids3 correctly returned with "
919 "status: %s\n",
920 nt_errstr(status));
921 return true;
924 torture_assert_ntstatus_equal(tctx,
925 status,
926 NT_STATUS_ACCESS_DENIED,
927 "LookupSids3 return value should "
928 "be ACCESS_DENIED");
929 return true;
932 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
933 NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
934 torture_comment(tctx,
935 "LookupNames4 correctly returned with "
936 "result: %s\n",
937 nt_errstr(r.out.result));
938 return true;
941 torture_fail(tctx,
942 "LookupSids3 return value should be "
943 "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
945 return false;
948 bool test_many_LookupSids(struct dcerpc_pipe *p,
949 struct torture_context *tctx,
950 struct policy_handle *handle)
952 uint32_t count;
953 struct lsa_SidArray sids;
954 int i;
955 struct dcerpc_binding_handle *b = p->binding_handle;
956 enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
958 torture_comment(tctx, "\nTesting LookupSids with lots of SIDs\n");
960 sids.num_sids = 100;
962 sids.sids = talloc_array(tctx, struct lsa_SidPtr, sids.num_sids);
964 for (i=0; i<sids.num_sids; i++) {
965 const char *sidstr = "S-1-5-32-545";
966 sids.sids[i].sid = dom_sid_parse_talloc(tctx, sidstr);
969 count = sids.num_sids;
971 if (handle) {
972 struct lsa_LookupSids r;
973 struct lsa_TransNameArray names;
974 struct lsa_RefDomainList *domains = NULL;
975 names.count = 0;
976 names.names = NULL;
978 r.in.handle = handle;
979 r.in.sids = &sids;
980 r.in.names = &names;
981 r.in.level = 1;
982 r.in.count = &names.count;
983 r.out.count = &count;
984 r.out.names = &names;
985 r.out.domains = &domains;
987 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids_r(b, tctx, &r),
988 "LookupSids failed");
989 if (!NT_STATUS_IS_OK(r.out.result)) {
990 torture_comment(tctx, "LookupSids failed - %s\n",
991 nt_errstr(r.out.result));
992 return false;
995 torture_comment(tctx, "\n");
997 if (!test_LookupNames(b, tctx, handle, &names)) {
998 return false;
1002 if (transport == NCACN_NP) {
1003 if (!test_LookupSids3_fail(b, tctx, &sids)) {
1004 return false;
1006 if (!test_LookupNames4_fail(b, tctx)) {
1007 return false;
1009 } else if (transport == NCACN_IP_TCP) {
1010 struct lsa_TransNameArray2 names;
1011 enum dcerpc_AuthType auth_type;
1012 enum dcerpc_AuthLevel auth_level;
1014 names.count = 0;
1015 names.names = NULL;
1017 dcerpc_binding_handle_auth_info(p->binding_handle,
1018 &auth_type, &auth_level);
1020 if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL &&
1021 auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) {
1022 if (!test_LookupSids3(b, tctx, &sids)) {
1023 return false;
1025 if (!test_LookupNames4(b, tctx, &names, true)) {
1026 return false;
1028 } else {
1030 * If we don't have a secure channel these tests must
1031 * fail with ACCESS_DENIED.
1033 if (!test_LookupSids3_fail(b, tctx, &sids)) {
1034 return false;
1036 if (!test_LookupNames4_fail(b, tctx)) {
1037 return false;
1042 torture_comment(tctx, "\n");
1046 return true;
1049 static void lookupsids_cb(struct tevent_req *subreq)
1051 int *replies = (int *)tevent_req_callback_data_void(subreq);
1052 NTSTATUS status;
1054 status = dcerpc_lsa_LookupSids_r_recv(subreq, subreq);
1055 TALLOC_FREE(subreq);
1056 if (!NT_STATUS_IS_OK(status)) {
1057 printf("lookupsids returned %s\n", nt_errstr(status));
1058 *replies = -1;
1061 if (*replies >= 0) {
1062 *replies += 1;
1066 static bool test_LookupSids_async(struct dcerpc_binding_handle *b,
1067 struct torture_context *tctx,
1068 struct policy_handle *handle)
1070 struct lsa_SidArray sids;
1071 struct lsa_SidPtr sidptr;
1072 uint32_t *count;
1073 struct lsa_TransNameArray *names;
1074 struct lsa_LookupSids *r;
1075 struct lsa_RefDomainList *domains = NULL;
1076 struct tevent_req **req;
1077 int i, replies;
1078 bool ret = true;
1079 const int num_async_requests = 50;
1081 count = talloc_array(tctx, uint32_t, num_async_requests);
1082 names = talloc_array(tctx, struct lsa_TransNameArray, num_async_requests);
1083 r = talloc_array(tctx, struct lsa_LookupSids, num_async_requests);
1085 torture_comment(tctx, "\nTesting %d async lookupsids request\n", num_async_requests);
1087 req = talloc_array(tctx, struct tevent_req *, num_async_requests);
1089 sids.num_sids = 1;
1090 sids.sids = &sidptr;
1091 sidptr.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-545");
1093 replies = 0;
1095 for (i=0; i<num_async_requests; i++) {
1096 count[i] = 0;
1097 names[i].count = 0;
1098 names[i].names = NULL;
1100 r[i].in.handle = handle;
1101 r[i].in.sids = &sids;
1102 r[i].in.names = &names[i];
1103 r[i].in.level = 1;
1104 r[i].in.count = &names[i].count;
1105 r[i].out.count = &count[i];
1106 r[i].out.names = &names[i];
1107 r[i].out.domains = &domains;
1109 req[i] = dcerpc_lsa_LookupSids_r_send(tctx, tctx->ev, b, &r[i]);
1110 if (req[i] == NULL) {
1111 ret = false;
1112 break;
1115 tevent_req_set_callback(req[i], lookupsids_cb, &replies);
1118 while (replies >= 0 && replies < num_async_requests) {
1119 tevent_loop_once(tctx->ev);
1122 talloc_free(req);
1124 if (replies < 0) {
1125 ret = false;
1128 return ret;
1131 static bool test_LookupPrivValue(struct dcerpc_binding_handle *b,
1132 struct torture_context *tctx,
1133 struct policy_handle *handle,
1134 struct lsa_String *name)
1136 struct lsa_LookupPrivValue r;
1137 struct lsa_LUID luid;
1139 r.in.handle = handle;
1140 r.in.name = name;
1141 r.out.luid = &luid;
1143 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivValue_r(b, tctx, &r),
1144 "LookupPrivValue failed");
1145 torture_assert_ntstatus_ok(tctx, r.out.result,
1146 "LookupPrivValue failed");
1148 return true;
1151 static bool test_LookupPrivName(struct dcerpc_binding_handle *b,
1152 struct torture_context *tctx,
1153 struct policy_handle *handle,
1154 struct lsa_LUID *luid)
1156 struct lsa_LookupPrivName r;
1157 struct lsa_StringLarge *name = NULL;
1159 r.in.handle = handle;
1160 r.in.luid = luid;
1161 r.out.name = &name;
1163 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivName_r(b, tctx, &r),
1164 "LookupPrivName failed");
1165 torture_assert_ntstatus_ok(tctx, r.out.result, "LookupPrivName failed");
1167 return true;
1170 static bool test_RemovePrivilegesFromAccount(struct dcerpc_binding_handle *b,
1171 struct torture_context *tctx,
1172 struct policy_handle *handle,
1173 struct policy_handle *acct_handle,
1174 struct lsa_LUID *luid)
1176 struct lsa_RemovePrivilegesFromAccount r;
1177 struct lsa_PrivilegeSet privs;
1178 bool ret = true;
1180 torture_comment(tctx, "\nTesting RemovePrivilegesFromAccount\n");
1182 r.in.handle = acct_handle;
1183 r.in.remove_all = 0;
1184 r.in.privs = &privs;
1186 privs.count = 1;
1187 privs.unknown = 0;
1188 privs.set = talloc_array(tctx, struct lsa_LUIDAttribute, 1);
1189 privs.set[0].luid = *luid;
1190 privs.set[0].attribute = 0;
1192 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_RemovePrivilegesFromAccount_r(b, tctx, &r),
1193 "RemovePrivilegesFromAccount failed");
1194 if (!NT_STATUS_IS_OK(r.out.result)) {
1196 struct lsa_LookupPrivName r_name;
1197 struct lsa_StringLarge *name = NULL;
1199 r_name.in.handle = handle;
1200 r_name.in.luid = luid;
1201 r_name.out.name = &name;
1203 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivName_r(b, tctx, &r_name),
1204 "LookupPrivName failed");
1205 if (!NT_STATUS_IS_OK(r_name.out.result)) {
1206 torture_comment(tctx, "\nLookupPrivName failed - %s\n",
1207 nt_errstr(r_name.out.result));
1208 return false;
1210 /* Windows 2008 does not allow this to be removed */
1211 if (strcmp("SeAuditPrivilege", name->string) == 0) {
1212 return ret;
1215 torture_comment(tctx, "RemovePrivilegesFromAccount failed to remove %s - %s\n",
1216 name->string,
1217 nt_errstr(r.out.result));
1218 return false;
1221 return ret;
1224 static bool test_AddPrivilegesToAccount(struct dcerpc_binding_handle *b,
1225 struct torture_context *tctx,
1226 struct policy_handle *acct_handle,
1227 struct lsa_LUID *luid)
1229 struct lsa_AddPrivilegesToAccount r;
1230 struct lsa_PrivilegeSet privs;
1231 bool ret = true;
1233 torture_comment(tctx, "\nTesting AddPrivilegesToAccount\n");
1235 r.in.handle = acct_handle;
1236 r.in.privs = &privs;
1238 privs.count = 1;
1239 privs.unknown = 0;
1240 privs.set = talloc_array(tctx, struct lsa_LUIDAttribute, 1);
1241 privs.set[0].luid = *luid;
1242 privs.set[0].attribute = 0;
1244 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddPrivilegesToAccount_r(b, tctx, &r),
1245 "AddPrivilegesToAccount failed");
1246 torture_assert_ntstatus_ok(tctx, r.out.result,
1247 "AddPrivilegesToAccount failed");
1248 return ret;
1251 static bool test_EnumPrivsAccount(struct dcerpc_binding_handle *b,
1252 struct torture_context *tctx,
1253 struct policy_handle *handle,
1254 struct policy_handle *acct_handle)
1256 struct lsa_EnumPrivsAccount r;
1257 struct lsa_PrivilegeSet *privs = NULL;
1258 bool ret = true;
1260 torture_comment(tctx, "\nTesting EnumPrivsAccount\n");
1262 r.in.handle = acct_handle;
1263 r.out.privs = &privs;
1265 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumPrivsAccount_r(b, tctx, &r),
1266 "EnumPrivsAccount failed");
1267 torture_assert_ntstatus_ok(tctx, r.out.result,
1268 "EnumPrivsAccount failed");
1270 if (privs && privs->count > 0) {
1271 int i;
1272 for (i=0;i<privs->count;i++) {
1273 test_LookupPrivName(b, tctx, handle,
1274 &privs->set[i].luid);
1277 ret &= test_RemovePrivilegesFromAccount(b, tctx, handle, acct_handle,
1278 &privs->set[0].luid);
1279 ret &= test_AddPrivilegesToAccount(b, tctx, acct_handle,
1280 &privs->set[0].luid);
1283 return ret;
1286 static bool test_GetSystemAccessAccount(struct dcerpc_binding_handle *b,
1287 struct torture_context *tctx,
1288 struct policy_handle *handle,
1289 struct policy_handle *acct_handle)
1291 uint32_t access_mask;
1292 struct lsa_GetSystemAccessAccount r;
1294 torture_comment(tctx, "\nTesting GetSystemAccessAccount\n");
1296 r.in.handle = acct_handle;
1297 r.out.access_mask = &access_mask;
1299 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(b, tctx, &r),
1300 "GetSystemAccessAccount failed");
1301 torture_assert_ntstatus_ok(tctx, r.out.result,
1302 "GetSystemAccessAccount failed");
1304 if (r.out.access_mask != NULL) {
1305 torture_comment(tctx, "Rights:");
1306 if (*(r.out.access_mask) & LSA_POLICY_MODE_INTERACTIVE)
1307 torture_comment(tctx, " LSA_POLICY_MODE_INTERACTIVE");
1308 if (*(r.out.access_mask) & LSA_POLICY_MODE_NETWORK)
1309 torture_comment(tctx, " LSA_POLICY_MODE_NETWORK");
1310 if (*(r.out.access_mask) & LSA_POLICY_MODE_BATCH)
1311 torture_comment(tctx, " LSA_POLICY_MODE_BATCH");
1312 if (*(r.out.access_mask) & LSA_POLICY_MODE_SERVICE)
1313 torture_comment(tctx, " LSA_POLICY_MODE_SERVICE");
1314 if (*(r.out.access_mask) & LSA_POLICY_MODE_PROXY)
1315 torture_comment(tctx, " LSA_POLICY_MODE_PROXY");
1316 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_INTERACTIVE)
1317 torture_comment(tctx, " LSA_POLICY_MODE_DENY_INTERACTIVE");
1318 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_NETWORK)
1319 torture_comment(tctx, " LSA_POLICY_MODE_DENY_NETWORK");
1320 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_BATCH)
1321 torture_comment(tctx, " LSA_POLICY_MODE_DENY_BATCH");
1322 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_SERVICE)
1323 torture_comment(tctx, " LSA_POLICY_MODE_DENY_SERVICE");
1324 if (*(r.out.access_mask) & LSA_POLICY_MODE_REMOTE_INTERACTIVE)
1325 torture_comment(tctx, " LSA_POLICY_MODE_REMOTE_INTERACTIVE");
1326 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE)
1327 torture_comment(tctx, " LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE");
1328 if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL)
1329 torture_comment(tctx, " LSA_POLICY_MODE_ALL");
1330 if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL_NT4)
1331 torture_comment(tctx, " LSA_POLICY_MODE_ALL_NT4");
1332 torture_comment(tctx, "\n");
1335 return true;
1338 static bool test_Delete(struct dcerpc_binding_handle *b,
1339 struct torture_context *tctx,
1340 struct policy_handle *handle)
1342 struct lsa_Delete r;
1344 torture_comment(tctx, "\nTesting Delete\n");
1346 r.in.handle = handle;
1347 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Delete_r(b, tctx, &r),
1348 "Delete failed");
1349 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_SUPPORTED,
1350 "Delete should have failed NT_STATUS_NOT_SUPPORTED");
1352 return true;
1355 static bool test_DeleteObject(struct dcerpc_binding_handle *b,
1356 struct torture_context *tctx,
1357 struct policy_handle *handle)
1359 struct lsa_DeleteObject r;
1361 torture_comment(tctx, "\nTesting DeleteObject\n");
1363 r.in.handle = handle;
1364 r.out.handle = handle;
1365 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(b, tctx, &r),
1366 "DeleteObject failed");
1367 torture_assert_ntstatus_ok(tctx, r.out.result,
1368 "DeleteObject failed");
1370 return true;
1374 static bool test_CreateAccount(struct dcerpc_binding_handle *b,
1375 struct torture_context *tctx,
1376 struct policy_handle *handle)
1378 struct lsa_CreateAccount r;
1379 struct dom_sid2 *newsid;
1380 struct policy_handle acct_handle;
1382 newsid = dom_sid_parse_talloc(tctx, "S-1-5-12349876-4321-2854");
1384 torture_comment(tctx, "\nTesting CreateAccount\n");
1386 r.in.handle = handle;
1387 r.in.sid = newsid;
1388 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1389 r.out.acct_handle = &acct_handle;
1391 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateAccount_r(b, tctx, &r),
1392 "CreateAccount failed");
1393 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_COLLISION)) {
1394 struct lsa_OpenAccount r_o;
1395 r_o.in.handle = handle;
1396 r_o.in.sid = newsid;
1397 r_o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1398 r_o.out.acct_handle = &acct_handle;
1400 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(b, tctx, &r_o),
1401 "OpenAccount failed");
1402 torture_assert_ntstatus_ok(tctx, r_o.out.result,
1403 "OpenAccount failed");
1404 } else {
1405 torture_assert_ntstatus_ok(tctx, r.out.result,
1406 "CreateAccount failed");
1409 if (!test_Delete(b, tctx, &acct_handle)) {
1410 return false;
1413 if (!test_DeleteObject(b, tctx, &acct_handle)) {
1414 return false;
1417 return true;
1420 static bool test_DeleteTrustedDomain(struct dcerpc_binding_handle *b,
1421 struct torture_context *tctx,
1422 struct policy_handle *handle,
1423 struct lsa_StringLarge name)
1425 struct lsa_OpenTrustedDomainByName r;
1426 struct policy_handle trustdom_handle;
1428 r.in.handle = handle;
1429 r.in.name.string = name.string;
1430 r.in.access_mask = SEC_STD_DELETE;
1431 r.out.trustdom_handle = &trustdom_handle;
1433 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomainByName_r(b, tctx, &r),
1434 "OpenTrustedDomainByName failed");
1435 torture_assert_ntstatus_ok(tctx, r.out.result,
1436 "OpenTrustedDomainByName failed");
1438 if (!test_Delete(b, tctx, &trustdom_handle)) {
1439 return false;
1442 if (!test_DeleteObject(b, tctx, &trustdom_handle)) {
1443 return false;
1446 return true;
1449 static bool test_DeleteTrustedDomainBySid(struct dcerpc_binding_handle *b,
1450 struct torture_context *tctx,
1451 struct policy_handle *handle,
1452 struct dom_sid *sid)
1454 struct lsa_DeleteTrustedDomain r;
1456 r.in.handle = handle;
1457 r.in.dom_sid = sid;
1459 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteTrustedDomain_r(b, tctx, &r),
1460 "DeleteTrustedDomain failed");
1461 torture_assert_ntstatus_ok(tctx, r.out.result,
1462 "DeleteTrustedDomain failed");
1464 return true;
1468 static bool test_CreateSecret(struct dcerpc_pipe *p,
1469 struct torture_context *tctx,
1470 struct policy_handle *handle)
1472 struct lsa_CreateSecret r;
1473 struct lsa_OpenSecret r2;
1474 struct lsa_SetSecret r3;
1475 struct lsa_QuerySecret r4;
1476 struct lsa_SetSecret r5;
1477 struct lsa_QuerySecret r6;
1478 struct lsa_SetSecret r7;
1479 struct lsa_QuerySecret r8;
1480 struct policy_handle sec_handle, sec_handle2, sec_handle3;
1481 struct lsa_DeleteObject d_o;
1482 struct lsa_DATA_BUF buf1;
1483 struct lsa_DATA_BUF_PTR bufp1;
1484 struct lsa_DATA_BUF_PTR bufp2;
1485 DATA_BLOB enc_key;
1486 bool ret = true;
1487 DATA_BLOB session_key;
1488 NTTIME old_mtime, new_mtime;
1489 DATA_BLOB blob1;
1490 const char *secret1 = "abcdef12345699qwerty";
1491 char *secret2;
1492 const char *secret3 = "ABCDEF12345699QWERTY";
1493 char *secret4;
1494 const char *secret5 = "NEW-SAMBA4-SECRET";
1495 char *secret6;
1496 char *secname[2];
1497 int i;
1498 const int LOCAL = 0;
1499 const int GLOBAL = 1;
1500 struct dcerpc_binding_handle *b = p->binding_handle;
1502 secname[LOCAL] = talloc_asprintf(tctx, "torturesecret-%u", (unsigned int)random());
1503 secname[GLOBAL] = talloc_asprintf(tctx, "G$torturesecret-%u", (unsigned int)random());
1505 for (i=0; i< 2; i++) {
1506 torture_comment(tctx, "\nTesting CreateSecret of %s\n", secname[i]);
1508 init_lsa_String(&r.in.name, secname[i]);
1510 r.in.handle = handle;
1511 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1512 r.out.sec_handle = &sec_handle;
1514 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateSecret_r(b, tctx, &r),
1515 "CreateSecret failed");
1516 torture_assert_ntstatus_ok(tctx, r.out.result,
1517 "CreateSecret failed");
1519 r.in.handle = handle;
1520 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1521 r.out.sec_handle = &sec_handle3;
1523 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateSecret_r(b, tctx, &r),
1524 "CreateSecret failed");
1525 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_COLLISION,
1526 "CreateSecret should have failed OBJECT_NAME_COLLISION");
1528 r2.in.handle = handle;
1529 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1530 r2.in.name = r.in.name;
1531 r2.out.sec_handle = &sec_handle2;
1533 torture_comment(tctx, "Testing OpenSecret\n");
1535 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(b, tctx, &r2),
1536 "OpenSecret failed");
1537 torture_assert_ntstatus_ok(tctx, r2.out.result,
1538 "OpenSecret failed");
1540 torture_assert_ntstatus_ok(tctx, dcerpc_fetch_session_key(p, &session_key),
1541 "dcerpc_fetch_session_key failed");
1543 enc_key = sess_encrypt_string(secret1, &session_key);
1545 r3.in.sec_handle = &sec_handle;
1546 r3.in.new_val = &buf1;
1547 r3.in.old_val = NULL;
1548 r3.in.new_val->data = enc_key.data;
1549 r3.in.new_val->length = enc_key.length;
1550 r3.in.new_val->size = enc_key.length;
1552 torture_comment(tctx, "Testing SetSecret\n");
1554 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r3),
1555 "SetSecret failed");
1556 torture_assert_ntstatus_ok(tctx, r3.out.result,
1557 "SetSecret failed");
1559 r3.in.sec_handle = &sec_handle;
1560 r3.in.new_val = &buf1;
1561 r3.in.old_val = NULL;
1562 r3.in.new_val->data = enc_key.data;
1563 r3.in.new_val->length = enc_key.length;
1564 r3.in.new_val->size = enc_key.length;
1566 /* break the encrypted data */
1567 enc_key.data[0]++;
1569 torture_comment(tctx, "Testing SetSecret with broken key\n");
1571 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r3),
1572 "SetSecret failed");
1573 torture_assert_ntstatus_equal(tctx, r3.out.result, NT_STATUS_UNKNOWN_REVISION,
1574 "SetSecret should have failed UNKNOWN_REVISION");
1576 data_blob_free(&enc_key);
1578 ZERO_STRUCT(new_mtime);
1579 ZERO_STRUCT(old_mtime);
1581 /* fetch the secret back again */
1582 r4.in.sec_handle = &sec_handle;
1583 r4.in.new_val = &bufp1;
1584 r4.in.new_mtime = &new_mtime;
1585 r4.in.old_val = NULL;
1586 r4.in.old_mtime = NULL;
1588 bufp1.buf = NULL;
1590 torture_comment(tctx, "Testing QuerySecret\n");
1591 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r4),
1592 "QuerySecret failed");
1593 if (!NT_STATUS_IS_OK(r4.out.result)) {
1594 torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r4.out.result));
1595 ret = false;
1596 } else {
1597 if (r4.out.new_val == NULL || r4.out.new_val->buf == NULL) {
1598 torture_comment(tctx, "No secret buffer returned\n");
1599 ret = false;
1600 } else {
1601 blob1.data = r4.out.new_val->buf->data;
1602 blob1.length = r4.out.new_val->buf->size;
1604 secret2 = sess_decrypt_string(tctx,
1605 &blob1, &session_key);
1607 if (strcmp(secret1, secret2) != 0) {
1608 torture_comment(tctx, "Returned secret (r4) '%s' doesn't match '%s'\n",
1609 secret2, secret1);
1610 ret = false;
1615 enc_key = sess_encrypt_string(secret3, &session_key);
1617 r5.in.sec_handle = &sec_handle;
1618 r5.in.new_val = &buf1;
1619 r5.in.old_val = NULL;
1620 r5.in.new_val->data = enc_key.data;
1621 r5.in.new_val->length = enc_key.length;
1622 r5.in.new_val->size = enc_key.length;
1625 smb_msleep(200);
1626 torture_comment(tctx, "Testing SetSecret (existing value should move to old)\n");
1628 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r5),
1629 "SetSecret failed");
1630 if (!NT_STATUS_IS_OK(r5.out.result)) {
1631 torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(r5.out.result));
1632 ret = false;
1635 data_blob_free(&enc_key);
1637 ZERO_STRUCT(new_mtime);
1638 ZERO_STRUCT(old_mtime);
1640 /* fetch the secret back again */
1641 r6.in.sec_handle = &sec_handle;
1642 r6.in.new_val = &bufp1;
1643 r6.in.new_mtime = &new_mtime;
1644 r6.in.old_val = &bufp2;
1645 r6.in.old_mtime = &old_mtime;
1647 bufp1.buf = NULL;
1648 bufp2.buf = NULL;
1650 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r6),
1651 "QuerySecret failed");
1652 if (!NT_STATUS_IS_OK(r6.out.result)) {
1653 torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r6.out.result));
1654 ret = false;
1655 secret4 = NULL;
1656 } else {
1658 if (r6.out.new_val->buf == NULL || r6.out.old_val->buf == NULL
1659 || r6.out.new_mtime == NULL || r6.out.old_mtime == NULL) {
1660 torture_comment(tctx, "Both secret buffers and both times not returned\n");
1661 ret = false;
1662 secret4 = NULL;
1663 } else {
1664 blob1.data = r6.out.new_val->buf->data;
1665 blob1.length = r6.out.new_val->buf->size;
1667 secret4 = sess_decrypt_string(tctx,
1668 &blob1, &session_key);
1670 if (strcmp(secret3, secret4) != 0) {
1671 torture_comment(tctx, "Returned NEW secret %s doesn't match %s\n", secret4, secret3);
1672 ret = false;
1675 blob1.data = r6.out.old_val->buf->data;
1676 blob1.length = r6.out.old_val->buf->length;
1678 secret2 = sess_decrypt_string(tctx,
1679 &blob1, &session_key);
1681 if (strcmp(secret1, secret2) != 0) {
1682 torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret2, secret1);
1683 ret = false;
1686 if (*r6.out.new_mtime == *r6.out.old_mtime) {
1687 torture_comment(tctx, "Returned secret (r6-%d) %s must not have same mtime for both secrets: %s != %s\n",
1689 secname[i],
1690 nt_time_string(tctx, *r6.out.old_mtime),
1691 nt_time_string(tctx, *r6.out.new_mtime));
1692 ret = false;
1697 enc_key = sess_encrypt_string(secret5, &session_key);
1699 r7.in.sec_handle = &sec_handle;
1700 r7.in.old_val = &buf1;
1701 r7.in.old_val->data = enc_key.data;
1702 r7.in.old_val->length = enc_key.length;
1703 r7.in.old_val->size = enc_key.length;
1704 r7.in.new_val = NULL;
1706 torture_comment(tctx, "Testing SetSecret of old Secret only\n");
1708 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r7),
1709 "SetSecret failed");
1710 if (!NT_STATUS_IS_OK(r7.out.result)) {
1711 torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(r7.out.result));
1712 ret = false;
1715 data_blob_free(&enc_key);
1717 /* fetch the secret back again */
1718 r8.in.sec_handle = &sec_handle;
1719 r8.in.new_val = &bufp1;
1720 r8.in.new_mtime = &new_mtime;
1721 r8.in.old_val = &bufp2;
1722 r8.in.old_mtime = &old_mtime;
1724 bufp1.buf = NULL;
1725 bufp2.buf = NULL;
1727 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r8),
1728 "QuerySecret failed");
1729 if (!NT_STATUS_IS_OK(r8.out.result)) {
1730 torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r8.out.result));
1731 ret = false;
1732 } else {
1733 if (!r8.out.new_val || !r8.out.old_val) {
1734 torture_comment(tctx, "in/out pointers not returned, despite being set on in for QuerySecret\n");
1735 ret = false;
1736 } else if (r8.out.new_val->buf != NULL) {
1737 torture_comment(tctx, "NEW secret buffer must not be returned after OLD set\n");
1738 ret = false;
1739 } else if (r8.out.old_val->buf == NULL) {
1740 torture_comment(tctx, "OLD secret buffer was not returned after OLD set\n");
1741 ret = false;
1742 } else if (r8.out.new_mtime == NULL || r8.out.old_mtime == NULL) {
1743 torture_comment(tctx, "Both times not returned after OLD set\n");
1744 ret = false;
1745 } else {
1746 blob1.data = r8.out.old_val->buf->data;
1747 blob1.length = r8.out.old_val->buf->size;
1749 secret6 = sess_decrypt_string(tctx,
1750 &blob1, &session_key);
1752 if (strcmp(secret5, secret6) != 0) {
1753 torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret5, secret6);
1754 ret = false;
1757 if (*r8.out.new_mtime != *r8.out.old_mtime) {
1758 torture_comment(tctx, "Returned secret (r8) %s did not had same mtime for both secrets: %s != %s\n",
1759 secname[i],
1760 nt_time_string(tctx, *r8.out.old_mtime),
1761 nt_time_string(tctx, *r8.out.new_mtime));
1762 ret = false;
1767 if (!test_Delete(b, tctx, &sec_handle)) {
1768 ret = false;
1771 if (!test_DeleteObject(b, tctx, &sec_handle)) {
1772 return false;
1775 d_o.in.handle = &sec_handle2;
1776 d_o.out.handle = &sec_handle2;
1777 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(b, tctx, &d_o),
1778 "DeleteObject failed");
1779 torture_assert_ntstatus_equal(tctx, d_o.out.result, NT_STATUS_INVALID_HANDLE,
1780 "OpenSecret expected INVALID_HANDLE");
1782 torture_comment(tctx, "Testing OpenSecret of just-deleted secret\n");
1784 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(b, tctx, &r2),
1785 "OpenSecret failed");
1786 torture_assert_ntstatus_equal(tctx, r2.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
1787 "OpenSecret expected OBJECT_NAME_NOT_FOUND");
1789 return ret;
1793 static bool test_EnumAccountRights(struct dcerpc_binding_handle *b,
1794 struct torture_context *tctx,
1795 struct policy_handle *acct_handle,
1796 struct dom_sid *sid)
1798 struct lsa_EnumAccountRights r;
1799 struct lsa_RightSet rights;
1801 torture_comment(tctx, "\nTesting EnumAccountRights\n");
1803 r.in.handle = acct_handle;
1804 r.in.sid = sid;
1805 r.out.rights = &rights;
1807 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(b, tctx, &r),
1808 "EnumAccountRights failed");
1809 if (!NT_STATUS_IS_OK(r.out.result)) {
1810 torture_comment(tctx, "EnumAccountRights of %s failed - %s\n",
1811 dom_sid_string(tctx, sid), nt_errstr(r.out.result));
1813 torture_assert_ntstatus_ok(tctx, r.out.result,
1814 "EnumAccountRights failed");
1816 return true;
1820 static bool test_QuerySecurity(struct dcerpc_binding_handle *b,
1821 struct torture_context *tctx,
1822 struct policy_handle *handle,
1823 struct policy_handle *acct_handle)
1825 struct lsa_QuerySecurity r;
1826 struct sec_desc_buf *sdbuf = NULL;
1828 if (torture_setting_bool(tctx, "samba4", false)) {
1829 torture_comment(tctx, "\nskipping QuerySecurity test against Samba4\n");
1830 return true;
1833 torture_comment(tctx, "\nTesting QuerySecurity\n");
1835 r.in.handle = acct_handle;
1836 r.in.sec_info = SECINFO_OWNER |
1837 SECINFO_GROUP |
1838 SECINFO_DACL;
1839 r.out.sdbuf = &sdbuf;
1841 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecurity_r(b, tctx, &r),
1842 "QuerySecurity failed");
1843 if (!NT_STATUS_IS_OK(r.out.result)) {
1844 torture_comment(tctx, "QuerySecurity failed - %s\n", nt_errstr(r.out.result));
1845 return false;
1848 return true;
1851 static bool test_OpenAccount(struct dcerpc_binding_handle *b,
1852 struct torture_context *tctx,
1853 struct policy_handle *handle,
1854 struct dom_sid *sid)
1856 struct lsa_OpenAccount r;
1857 struct policy_handle acct_handle;
1859 torture_comment(tctx, "\nTesting OpenAccount\n");
1861 r.in.handle = handle;
1862 r.in.sid = sid;
1863 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1864 r.out.acct_handle = &acct_handle;
1866 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(b, tctx, &r),
1867 "OpenAccount failed");
1868 torture_assert_ntstatus_ok(tctx, r.out.result,
1869 "OpenAccount failed");
1871 if (!test_EnumPrivsAccount(b, tctx, handle, &acct_handle)) {
1872 return false;
1875 if (!test_GetSystemAccessAccount(b, tctx, handle, &acct_handle)) {
1876 return false;
1879 if (!test_QuerySecurity(b, tctx, handle, &acct_handle)) {
1880 return false;
1883 return true;
1886 static bool test_EnumAccounts(struct dcerpc_binding_handle *b,
1887 struct torture_context *tctx,
1888 struct policy_handle *handle)
1890 struct lsa_EnumAccounts r;
1891 struct lsa_SidArray sids1, sids2;
1892 uint32_t resume_handle = 0;
1893 int i;
1894 bool ret = true;
1896 torture_comment(tctx, "\nTesting EnumAccounts\n");
1898 r.in.handle = handle;
1899 r.in.resume_handle = &resume_handle;
1900 r.in.num_entries = 100;
1901 r.out.resume_handle = &resume_handle;
1902 r.out.sids = &sids1;
1904 resume_handle = 0;
1905 while (true) {
1906 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(b, tctx, &r),
1907 "EnumAccounts failed");
1908 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
1909 break;
1911 torture_assert_ntstatus_ok(tctx, r.out.result,
1912 "EnumAccounts failed");
1914 if (!test_LookupSids(b, tctx, handle, &sids1)) {
1915 return false;
1918 if (!test_LookupSids2(b, tctx, handle, &sids1)) {
1919 return false;
1922 /* Can't test lookupSids3 here, as clearly we must not
1923 * be on schannel, or we would not be able to do the
1924 * rest */
1926 torture_comment(tctx, "Testing all accounts\n");
1927 for (i=0;i<sids1.num_sids;i++) {
1928 ret &= test_OpenAccount(b, tctx, handle, sids1.sids[i].sid);
1929 ret &= test_EnumAccountRights(b, tctx, handle, sids1.sids[i].sid);
1931 torture_comment(tctx, "\n");
1934 if (sids1.num_sids < 3) {
1935 return ret;
1938 torture_comment(tctx, "Trying EnumAccounts partial listing (asking for 1 at 2)\n");
1939 resume_handle = 2;
1940 r.in.num_entries = 1;
1941 r.out.sids = &sids2;
1943 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(b, tctx, &r),
1944 "EnumAccounts failed");
1945 torture_assert_ntstatus_ok(tctx, r.out.result,
1946 "EnumAccounts failed");
1948 if (sids2.num_sids != 1) {
1949 torture_comment(tctx, "Returned wrong number of entries (%d)\n", sids2.num_sids);
1950 return false;
1953 return true;
1956 static bool test_LookupPrivDisplayName(struct dcerpc_binding_handle *b,
1957 struct torture_context *tctx,
1958 struct policy_handle *handle,
1959 struct lsa_String *priv_name)
1961 struct lsa_LookupPrivDisplayName r;
1962 /* produce a reasonable range of language output without screwing up
1963 terminals */
1964 uint16_t language_id = (random() % 4) + 0x409;
1965 uint16_t returned_language_id = 0;
1966 struct lsa_StringLarge *disp_name = NULL;
1968 torture_comment(tctx, "\nTesting LookupPrivDisplayName(%s)\n", priv_name->string);
1970 r.in.handle = handle;
1971 r.in.name = priv_name;
1972 r.in.language_id = language_id;
1973 r.in.language_id_sys = 0;
1974 r.out.returned_language_id = &returned_language_id;
1975 r.out.disp_name = &disp_name;
1977 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivDisplayName_r(b, tctx, &r),
1978 "LookupPrivDisplayName failed");
1979 if (!NT_STATUS_IS_OK(r.out.result)) {
1980 torture_comment(tctx, "LookupPrivDisplayName failed - %s\n", nt_errstr(r.out.result));
1981 return false;
1983 torture_comment(tctx, "%s -> \"%s\" (language 0x%x/0x%x)\n",
1984 priv_name->string, disp_name->string,
1985 r.in.language_id, *r.out.returned_language_id);
1987 return true;
1990 static bool test_EnumAccountsWithUserRight(struct dcerpc_binding_handle *b,
1991 struct torture_context *tctx,
1992 struct policy_handle *handle,
1993 struct lsa_String *priv_name)
1995 struct lsa_EnumAccountsWithUserRight r;
1996 struct lsa_SidArray sids;
1998 ZERO_STRUCT(sids);
2000 torture_comment(tctx, "\nTesting EnumAccountsWithUserRight(%s)\n", priv_name->string);
2002 r.in.handle = handle;
2003 r.in.name = priv_name;
2004 r.out.sids = &sids;
2006 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountsWithUserRight_r(b, tctx, &r),
2007 "EnumAccountsWithUserRight failed");
2009 /* NT_STATUS_NO_MORE_ENTRIES means noone has this privilege */
2010 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2011 return true;
2014 if (!NT_STATUS_IS_OK(r.out.result)) {
2015 torture_comment(tctx, "EnumAccountsWithUserRight failed - %s\n", nt_errstr(r.out.result));
2016 return false;
2019 return true;
2023 static bool test_EnumPrivs(struct dcerpc_binding_handle *b,
2024 struct torture_context *tctx,
2025 struct policy_handle *handle)
2027 struct lsa_EnumPrivs r;
2028 struct lsa_PrivArray privs1;
2029 uint32_t resume_handle = 0;
2030 int i;
2031 bool ret = true;
2033 torture_comment(tctx, "\nTesting EnumPrivs\n");
2035 r.in.handle = handle;
2036 r.in.resume_handle = &resume_handle;
2037 r.in.max_count = 100;
2038 r.out.resume_handle = &resume_handle;
2039 r.out.privs = &privs1;
2041 resume_handle = 0;
2042 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumPrivs_r(b, tctx, &r),
2043 "EnumPrivs failed");
2044 torture_assert_ntstatus_ok(tctx, r.out.result,
2045 "EnumPrivs failed");
2047 for (i = 0; i< privs1.count; i++) {
2048 test_LookupPrivDisplayName(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name);
2049 test_LookupPrivValue(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name);
2050 if (!test_EnumAccountsWithUserRight(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name)) {
2051 ret = false;
2055 return ret;
2058 static bool test_QueryForestTrustInformation(struct dcerpc_binding_handle *b,
2059 struct torture_context *tctx,
2060 struct policy_handle *handle,
2061 const char *trusted_domain_name)
2063 bool ret = true;
2064 struct lsa_lsaRQueryForestTrustInformation r;
2065 struct lsa_String string;
2066 struct lsa_ForestTrustInformation info, *info_ptr;
2068 torture_comment(tctx, "\nTesting lsaRQueryForestTrustInformation\n");
2070 if (torture_setting_bool(tctx, "samba4", false)) {
2071 torture_comment(tctx, "skipping QueryForestTrustInformation against Samba4\n");
2072 return true;
2075 ZERO_STRUCT(string);
2077 if (trusted_domain_name) {
2078 init_lsa_String(&string, trusted_domain_name);
2081 info_ptr = &info;
2083 r.in.handle = handle;
2084 r.in.trusted_domain_name = &string;
2085 r.in.highest_record_type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
2086 r.out.forest_trust_info = &info_ptr;
2088 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_lsaRQueryForestTrustInformation_r(b, tctx, &r),
2089 "lsaRQueryForestTrustInformation failed");
2091 if (!NT_STATUS_IS_OK(r.out.result)) {
2092 torture_comment(tctx, "lsaRQueryForestTrustInformation of %s failed - %s\n", trusted_domain_name, nt_errstr(r.out.result));
2093 ret = false;
2096 return ret;
2099 static bool test_query_each_TrustDomEx(struct dcerpc_binding_handle *b,
2100 struct torture_context *tctx,
2101 struct policy_handle *handle,
2102 struct lsa_DomainListEx *domains)
2104 int i;
2105 bool ret = true;
2107 for (i=0; i< domains->count; i++) {
2109 if (domains->domains[i].trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2110 ret &= test_QueryForestTrustInformation(b, tctx, handle,
2111 domains->domains[i].domain_name.string);
2115 return ret;
2118 static bool test_query_each_TrustDom(struct dcerpc_binding_handle *b,
2119 struct torture_context *tctx,
2120 struct policy_handle *handle,
2121 struct lsa_DomainList *domains)
2123 int i,j;
2124 bool ret = true;
2126 torture_comment(tctx, "\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
2127 for (i=0; i< domains->count; i++) {
2128 struct lsa_OpenTrustedDomain trust;
2129 struct lsa_OpenTrustedDomainByName trust_by_name;
2130 struct policy_handle trustdom_handle;
2131 struct policy_handle handle2;
2132 struct lsa_Close c;
2133 struct lsa_CloseTrustedDomainEx c_trust;
2134 int levels [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
2135 int ok[] = {1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1};
2137 if (domains->domains[i].sid) {
2138 trust.in.handle = handle;
2139 trust.in.sid = domains->domains[i].sid;
2140 trust.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2141 trust.out.trustdom_handle = &trustdom_handle;
2143 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomain_r(b, tctx, &trust),
2144 "OpenTrustedDomain failed");
2146 if (NT_STATUS_EQUAL(trust.out.result, NT_STATUS_NO_SUCH_DOMAIN)) {
2147 torture_comment(tctx, "DOMAIN(%s, %s) not a direct trust?\n",
2148 domains->domains[i].name.string,
2149 dom_sid_string(tctx, domains->domains[i].sid));
2150 continue;
2152 if (!NT_STATUS_IS_OK(trust.out.result)) {
2153 torture_comment(tctx, "OpenTrustedDomain failed - %s\n", nt_errstr(trust.out.result));
2154 return false;
2157 c.in.handle = &trustdom_handle;
2158 c.out.handle = &handle2;
2160 c_trust.in.handle = &trustdom_handle;
2161 c_trust.out.handle = &handle2;
2163 for (j=0; j < ARRAY_SIZE(levels); j++) {
2164 struct lsa_QueryTrustedDomainInfo q;
2165 union lsa_TrustedDomainInfo *info = NULL;
2166 q.in.trustdom_handle = &trustdom_handle;
2167 q.in.level = levels[j];
2168 q.out.info = &info;
2169 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2170 "QueryTrustedDomainInfo failed");
2171 if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2172 torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
2173 levels[j], nt_errstr(q.out.result));
2174 ret = false;
2175 } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2176 torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
2177 levels[j], nt_errstr(q.out.result));
2178 ret = false;
2182 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CloseTrustedDomainEx_r(b, tctx, &c_trust),
2183 "CloseTrustedDomainEx failed");
2184 if (!NT_STATUS_EQUAL(c_trust.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2185 torture_comment(tctx, "Expected CloseTrustedDomainEx to return NT_STATUS_NOT_IMPLEMENTED, instead - %s\n", nt_errstr(c_trust.out.result));
2186 return false;
2189 c.in.handle = &trustdom_handle;
2190 c.out.handle = &handle2;
2192 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &c),
2193 "Close failed");
2194 if (!NT_STATUS_IS_OK(c.out.result)) {
2195 torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(c.out.result));
2196 return false;
2199 for (j=0; j < ARRAY_SIZE(levels); j++) {
2200 struct lsa_QueryTrustedDomainInfoBySid q;
2201 union lsa_TrustedDomainInfo *info = NULL;
2203 if (!domains->domains[i].sid) {
2204 continue;
2207 q.in.handle = handle;
2208 q.in.dom_sid = domains->domains[i].sid;
2209 q.in.level = levels[j];
2210 q.out.info = &info;
2212 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfoBySid_r(b, tctx, &q),
2213 "lsa_QueryTrustedDomainInfoBySid failed");
2214 if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2215 torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d failed - %s\n",
2216 levels[j], nt_errstr(q.out.result));
2217 ret = false;
2218 } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2219 torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d unexpectedly succeeded - %s\n",
2220 levels[j], nt_errstr(q.out.result));
2221 ret = false;
2226 trust_by_name.in.handle = handle;
2227 trust_by_name.in.name.string = domains->domains[i].name.string;
2228 trust_by_name.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2229 trust_by_name.out.trustdom_handle = &trustdom_handle;
2231 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomainByName_r(b, tctx, &trust_by_name),
2232 "OpenTrustedDomainByName failed");
2234 if (NT_STATUS_EQUAL(trust_by_name.out.result, NT_STATUS_NO_SUCH_DOMAIN)) {
2235 torture_comment(tctx, "DOMAIN(%s, %s) not a direct trust?\n",
2236 domains->domains[i].name.string,
2237 dom_sid_string(tctx, domains->domains[i].sid));
2238 continue;
2240 if (!NT_STATUS_IS_OK(trust_by_name.out.result)) {
2241 torture_comment(tctx, "OpenTrustedDomainByName failed - %s\n", nt_errstr(trust_by_name.out.result));
2242 return false;
2245 for (j=0; j < ARRAY_SIZE(levels); j++) {
2246 struct lsa_QueryTrustedDomainInfo q;
2247 union lsa_TrustedDomainInfo *info = NULL;
2248 q.in.trustdom_handle = &trustdom_handle;
2249 q.in.level = levels[j];
2250 q.out.info = &info;
2251 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2252 "QueryTrustedDomainInfo failed");
2253 if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2254 torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
2255 levels[j], nt_errstr(q.out.result));
2256 ret = false;
2257 } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2258 torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
2259 levels[j], nt_errstr(q.out.result));
2260 ret = false;
2264 c.in.handle = &trustdom_handle;
2265 c.out.handle = &handle2;
2267 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &c),
2268 "Close failed");
2269 if (!NT_STATUS_IS_OK(c.out.result)) {
2270 torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(c.out.result));
2271 return false;
2274 for (j=0; j < ARRAY_SIZE(levels); j++) {
2275 struct lsa_QueryTrustedDomainInfoByName q;
2276 union lsa_TrustedDomainInfo *info = NULL;
2277 struct lsa_String name;
2279 name.string = domains->domains[i].name.string;
2281 q.in.handle = handle;
2282 q.in.trusted_domain = &name;
2283 q.in.level = levels[j];
2284 q.out.info = &info;
2285 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfoByName_r(b, tctx, &q),
2286 "QueryTrustedDomainInfoByName failed");
2287 if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2288 torture_comment(tctx, "QueryTrustedDomainInfoByName level %d failed - %s\n",
2289 levels[j], nt_errstr(q.out.result));
2290 ret = false;
2291 } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2292 torture_comment(tctx, "QueryTrustedDomainInfoByName level %d unexpectedly succeeded - %s\n",
2293 levels[j], nt_errstr(q.out.result));
2294 ret = false;
2298 return ret;
2301 static bool test_EnumTrustDom(struct dcerpc_binding_handle *b,
2302 struct torture_context *tctx,
2303 struct policy_handle *handle)
2305 struct lsa_EnumTrustDom r;
2306 uint32_t in_resume_handle = 0;
2307 uint32_t out_resume_handle;
2308 struct lsa_DomainList domains;
2309 bool ret = true;
2311 torture_comment(tctx, "\nTesting EnumTrustDom\n");
2313 r.in.handle = handle;
2314 r.in.resume_handle = &in_resume_handle;
2315 r.in.max_size = 0;
2316 r.out.domains = &domains;
2317 r.out.resume_handle = &out_resume_handle;
2319 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b, tctx, &r),
2320 "lsa_EnumTrustDom failed");
2322 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2323 * always be larger than the previous input resume handle, in
2324 * particular when hitting the last query it is vital to set the
2325 * resume handle correctly to avoid infinite client loops, as
2326 * seen e.g. with Windows XP SP3 when resume handle is 0 and
2327 * status is NT_STATUS_OK - gd */
2329 if (NT_STATUS_IS_OK(r.out.result) ||
2330 NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
2331 NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2333 if (out_resume_handle <= in_resume_handle) {
2334 torture_comment(tctx, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2335 out_resume_handle, in_resume_handle);
2336 return false;
2340 if (NT_STATUS_IS_OK(r.out.result)) {
2341 if (domains.count == 0) {
2342 torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2343 return false;
2345 } else if (!(NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES))) {
2346 torture_comment(tctx, "EnumTrustDom of zero size failed - %s\n", nt_errstr(r.out.result));
2347 return false;
2350 /* Start from the bottom again */
2351 in_resume_handle = 0;
2353 do {
2354 r.in.handle = handle;
2355 r.in.resume_handle = &in_resume_handle;
2356 r.in.max_size = LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3;
2357 r.out.domains = &domains;
2358 r.out.resume_handle = &out_resume_handle;
2360 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b, tctx, &r),
2361 "EnumTrustDom failed");
2363 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2364 * always be larger than the previous input resume handle, in
2365 * particular when hitting the last query it is vital to set the
2366 * resume handle correctly to avoid infinite client loops, as
2367 * seen e.g. with Windows XP SP3 when resume handle is 0 and
2368 * status is NT_STATUS_OK - gd */
2370 if (NT_STATUS_IS_OK(r.out.result) ||
2371 NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
2372 NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2374 if (out_resume_handle <= in_resume_handle) {
2375 torture_comment(tctx, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2376 out_resume_handle, in_resume_handle);
2377 return false;
2381 /* NO_MORE_ENTRIES is allowed */
2382 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2383 if (domains.count == 0) {
2384 return true;
2386 torture_comment(tctx, "EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
2387 return false;
2388 } else if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
2389 /* Windows 2003 gets this off by one on the first run */
2390 if (r.out.domains->count < 3 || r.out.domains->count > 4) {
2391 torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
2392 "asked it to (got %d, expected %d / %d == %d entries)\n",
2393 r.out.domains->count, LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3,
2394 LSA_ENUM_TRUST_DOMAIN_MULTIPLIER, r.in.max_size);
2395 ret = false;
2397 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2398 torture_comment(tctx, "EnumTrustDom failed - %s\n", nt_errstr(r.out.result));
2399 return false;
2402 if (domains.count == 0) {
2403 torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2404 return false;
2407 ret &= test_query_each_TrustDom(b, tctx, handle, &domains);
2409 in_resume_handle = out_resume_handle;
2411 } while ((NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)));
2413 return ret;
2416 static bool test_EnumTrustDomEx(struct dcerpc_binding_handle *b,
2417 struct torture_context *tctx,
2418 struct policy_handle *handle)
2420 struct lsa_EnumTrustedDomainsEx r_ex;
2421 uint32_t in_resume_handle = 0;
2422 uint32_t out_resume_handle;
2423 struct lsa_DomainListEx domains_ex;
2424 bool ret = true;
2426 torture_comment(tctx, "\nTesting EnumTrustedDomainsEx\n");
2428 r_ex.in.handle = handle;
2429 r_ex.in.resume_handle = &in_resume_handle;
2430 r_ex.in.max_size = 0;
2431 r_ex.out.domains = &domains_ex;
2432 r_ex.out.resume_handle = &out_resume_handle;
2434 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustedDomainsEx_r(b, tctx, &r_ex),
2435 "EnumTrustedDomainsEx failed");
2437 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2438 * always be larger than the previous input resume handle, in
2439 * particular when hitting the last query it is vital to set the
2440 * resume handle correctly to avoid infinite client loops, as
2441 * seen e.g. with Windows XP SP3 when resume handle is 0 and
2442 * status is NT_STATUS_OK - gd */
2444 if (NT_STATUS_IS_OK(r_ex.out.result) ||
2445 NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
2446 NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES))
2448 if (out_resume_handle <= in_resume_handle) {
2449 torture_comment(tctx, "EnumTrustDomEx failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2450 out_resume_handle, in_resume_handle);
2451 return false;
2455 if (NT_STATUS_IS_OK(r_ex.out.result)) {
2456 if (domains_ex.count == 0) {
2457 torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2458 return false;
2460 } else if (!(NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES) ||
2461 NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES))) {
2462 torture_comment(tctx, "EnumTrustDom of zero size failed - %s\n",
2463 nt_errstr(r_ex.out.result));
2464 return false;
2467 in_resume_handle = 0;
2468 do {
2469 r_ex.in.handle = handle;
2470 r_ex.in.resume_handle = &in_resume_handle;
2471 r_ex.in.max_size = LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER * 3;
2472 r_ex.out.domains = &domains_ex;
2473 r_ex.out.resume_handle = &out_resume_handle;
2475 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustedDomainsEx_r(b, tctx, &r_ex),
2476 "EnumTrustedDomainsEx failed");
2478 in_resume_handle = out_resume_handle;
2480 /* NO_MORE_ENTRIES is allowed */
2481 if (NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2482 if (domains_ex.count == 0) {
2483 return true;
2485 torture_comment(tctx, "EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
2486 return false;
2487 } else if (NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES)) {
2488 /* Windows 2003 gets this off by one on the first run */
2489 if (r_ex.out.domains->count < 3 || r_ex.out.domains->count > 4) {
2490 torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
2491 "asked it to (got %d, expected %d / %d == %d entries)\n",
2492 r_ex.out.domains->count,
2493 r_ex.in.max_size,
2494 LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER,
2495 r_ex.in.max_size / LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER);
2497 } else if (!NT_STATUS_IS_OK(r_ex.out.result)) {
2498 torture_comment(tctx, "EnumTrustedDomainEx failed - %s\n", nt_errstr(r_ex.out.result));
2499 return false;
2502 if (domains_ex.count == 0) {
2503 torture_comment(tctx, "EnumTrustDomainEx failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2504 return false;
2507 ret &= test_query_each_TrustDomEx(b, tctx, handle, &domains_ex);
2509 } while ((NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES)));
2511 return ret;
2515 static bool test_CreateTrustedDomain(struct dcerpc_binding_handle *b,
2516 struct torture_context *tctx,
2517 struct policy_handle *handle,
2518 uint32_t num_trusts)
2520 bool ret = true;
2521 struct lsa_CreateTrustedDomain r;
2522 struct lsa_DomainInfo trustinfo;
2523 struct dom_sid **domsid;
2524 struct policy_handle *trustdom_handle;
2525 struct lsa_QueryTrustedDomainInfo q;
2526 union lsa_TrustedDomainInfo *info = NULL;
2527 int i;
2529 torture_comment(tctx, "\nTesting CreateTrustedDomain for %d domains\n", num_trusts);
2531 if (!test_EnumTrustDom(b, tctx, handle)) {
2532 ret = false;
2535 if (!test_EnumTrustDomEx(b, tctx, handle)) {
2536 ret = false;
2539 domsid = talloc_array(tctx, struct dom_sid *, num_trusts);
2540 trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts);
2542 for (i=0; i< num_trusts; i++) {
2543 char *trust_name = talloc_asprintf(tctx, "TORTURE1%02d", i);
2544 char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-1%02d", i);
2546 domsid[i] = dom_sid_parse_talloc(tctx, trust_sid);
2548 trustinfo.sid = domsid[i];
2549 init_lsa_String((struct lsa_String *)&trustinfo.name, trust_name);
2551 r.in.policy_handle = handle;
2552 r.in.info = &trustinfo;
2553 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2554 r.out.trustdom_handle = &trustdom_handle[i];
2556 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateTrustedDomain_r(b, tctx, &r),
2557 "CreateTrustedDomain failed");
2558 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_COLLISION)) {
2559 test_DeleteTrustedDomain(b, tctx, handle, trustinfo.name);
2560 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateTrustedDomain_r(b, tctx, &r),
2561 "CreateTrustedDomain failed");
2563 if (!NT_STATUS_IS_OK(r.out.result)) {
2564 torture_comment(tctx, "CreateTrustedDomain failed - %s\n", nt_errstr(r.out.result));
2565 ret = false;
2566 } else {
2568 q.in.trustdom_handle = &trustdom_handle[i];
2569 q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
2570 q.out.info = &info;
2571 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2572 "QueryTrustedDomainInfo failed");
2573 if (!NT_STATUS_IS_OK(q.out.result)) {
2574 torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n", q.in.level, nt_errstr(q.out.result));
2575 ret = false;
2576 } else if (!q.out.info) {
2577 ret = false;
2578 } else {
2579 if (strcmp(info->info_ex.domain_name.string, trustinfo.name.string) != 0) {
2580 torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent long name: %s != %s\n",
2581 info->info_ex.domain_name.string, trustinfo.name.string);
2582 ret = false;
2584 if (strcmp(info->info_ex.netbios_name.string, trustinfo.name.string) != 0) {
2585 torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
2586 info->info_ex.netbios_name.string, trustinfo.name.string);
2587 ret = false;
2589 if (info->info_ex.trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
2590 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
2591 trust_name, info->info_ex.trust_type, LSA_TRUST_TYPE_DOWNLEVEL);
2592 ret = false;
2594 if (info->info_ex.trust_attributes != 0) {
2595 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
2596 trust_name, info->info_ex.trust_attributes, 0);
2597 ret = false;
2599 if (info->info_ex.trust_direction != LSA_TRUST_DIRECTION_OUTBOUND) {
2600 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
2601 trust_name, info->info_ex.trust_direction, LSA_TRUST_DIRECTION_OUTBOUND);
2602 ret = false;
2608 /* now that we have some domains to look over, we can test the enum calls */
2609 if (!test_EnumTrustDom(b, tctx, handle)) {
2610 ret = false;
2613 if (!test_EnumTrustDomEx(b, tctx, handle)) {
2614 ret = false;
2617 for (i=0; i<num_trusts; i++) {
2618 if (!test_DeleteTrustedDomainBySid(b, tctx, handle, domsid[i])) {
2619 ret = false;
2623 return ret;
2626 static bool gen_authinfo_internal(TALLOC_CTX *mem_ctx,
2627 const char *incoming_old, const char *incoming_new,
2628 const char *outgoing_old, const char *outgoing_new,
2629 DATA_BLOB session_key,
2630 struct lsa_TrustDomainInfoAuthInfoInternal **_authinfo_internal)
2632 struct lsa_TrustDomainInfoAuthInfoInternal *authinfo_internal;
2633 struct trustDomainPasswords auth_struct;
2634 struct AuthenticationInformation in_info;
2635 struct AuthenticationInformation io_info;
2636 struct AuthenticationInformation on_info;
2637 struct AuthenticationInformation oo_info;
2638 size_t converted_size;
2639 DATA_BLOB auth_blob;
2640 enum ndr_err_code ndr_err;
2641 bool ok;
2643 authinfo_internal = talloc_zero(mem_ctx, struct lsa_TrustDomainInfoAuthInfoInternal);
2644 if (authinfo_internal == NULL) {
2645 return false;
2648 in_info.AuthType = TRUST_AUTH_TYPE_CLEAR;
2649 ok = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16,
2650 incoming_new,
2651 strlen(incoming_new),
2652 &in_info.AuthInfo.clear.password,
2653 &converted_size);
2654 if (!ok) {
2655 return false;
2657 in_info.AuthInfo.clear.size = converted_size;
2659 io_info.AuthType = TRUST_AUTH_TYPE_CLEAR;
2660 ok = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16,
2661 incoming_old,
2662 strlen(incoming_old),
2663 &io_info.AuthInfo.clear.password,
2664 &converted_size);
2665 if (!ok) {
2666 return false;
2668 io_info.AuthInfo.clear.size = converted_size;
2670 on_info.AuthType = TRUST_AUTH_TYPE_CLEAR;
2671 ok = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16,
2672 outgoing_new,
2673 strlen(outgoing_new),
2674 &on_info.AuthInfo.clear.password,
2675 &converted_size);
2676 if (!ok) {
2677 return false;
2679 on_info.AuthInfo.clear.size = converted_size;
2681 oo_info.AuthType = TRUST_AUTH_TYPE_CLEAR;
2682 ok = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16,
2683 outgoing_old,
2684 strlen(outgoing_old),
2685 &oo_info.AuthInfo.clear.password,
2686 &converted_size);
2687 if (!ok) {
2688 return false;
2690 oo_info.AuthInfo.clear.size = converted_size;
2692 generate_random_buffer(auth_struct.confounder, sizeof(auth_struct.confounder));
2693 auth_struct.outgoing.count = 1;
2694 auth_struct.outgoing.current.count = 1;
2695 auth_struct.outgoing.current.array = &on_info;
2696 auth_struct.outgoing.previous.count = 1;
2697 auth_struct.outgoing.previous.array = &oo_info;
2699 auth_struct.incoming.count = 1;
2700 auth_struct.incoming.current.count = 1;
2701 auth_struct.incoming.current.array = &in_info;
2702 auth_struct.incoming.previous.count = 1;
2703 auth_struct.incoming.previous.array = &io_info;
2705 ndr_err = ndr_push_struct_blob(&auth_blob, mem_ctx, &auth_struct,
2706 (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords);
2707 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2708 return false;
2711 arcfour_crypt_blob(auth_blob.data, auth_blob.length, &session_key);
2713 authinfo_internal->auth_blob.size = auth_blob.length;
2714 authinfo_internal->auth_blob.data = auth_blob.data;
2716 *_authinfo_internal = authinfo_internal;
2718 return true;
2721 static bool gen_authinfo(TALLOC_CTX *mem_ctx,
2722 const char *incoming_old, const char *incoming_new,
2723 const char *outgoing_old, const char *outgoing_new,
2724 struct lsa_TrustDomainInfoAuthInfo **_authinfo)
2726 struct lsa_TrustDomainInfoAuthInfo *authinfo;
2727 struct lsa_TrustDomainInfoBuffer *in_buffer;
2728 struct lsa_TrustDomainInfoBuffer *io_buffer;
2729 struct lsa_TrustDomainInfoBuffer *on_buffer;
2730 struct lsa_TrustDomainInfoBuffer *oo_buffer;
2731 size_t converted_size;
2732 bool ok;
2734 authinfo = talloc_zero(mem_ctx, struct lsa_TrustDomainInfoAuthInfo);
2735 if (authinfo == NULL) {
2736 return false;
2739 in_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2740 if (in_buffer == NULL) {
2741 return false;
2743 in_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2744 ok = convert_string_talloc(in_buffer, CH_UNIX, CH_UTF16,
2745 incoming_new,
2746 strlen(incoming_new),
2747 &in_buffer->data.data,
2748 &converted_size);
2749 if (!ok) {
2750 return false;
2752 in_buffer->data.size = converted_size;
2754 io_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2755 if (io_buffer == NULL) {
2756 return false;
2758 io_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2759 ok = convert_string_talloc(io_buffer, CH_UNIX, CH_UTF16,
2760 incoming_old,
2761 strlen(incoming_old),
2762 &io_buffer->data.data,
2763 &converted_size);
2764 if (!ok) {
2765 return false;
2767 io_buffer->data.size = converted_size;
2769 on_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2770 if (on_buffer == NULL) {
2771 return false;
2773 on_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2774 ok = convert_string_talloc(on_buffer, CH_UNIX, CH_UTF16,
2775 outgoing_new,
2776 strlen(outgoing_new),
2777 &on_buffer->data.data,
2778 &converted_size);
2779 if (!ok) {
2780 return false;
2782 on_buffer->data.size = converted_size;
2784 oo_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2785 if (oo_buffer == NULL) {
2786 return false;
2788 oo_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2789 ok = convert_string_talloc(oo_buffer, CH_UNIX, CH_UTF16,
2790 outgoing_old,
2791 strlen(outgoing_old),
2792 &oo_buffer->data.data,
2793 &converted_size);
2794 if (!ok) {
2795 return false;
2797 oo_buffer->data.size = converted_size;
2799 authinfo->incoming_count = 1;
2800 authinfo->incoming_current_auth_info = in_buffer;
2801 authinfo->incoming_previous_auth_info = io_buffer;
2802 authinfo->outgoing_count = 1;
2803 authinfo->outgoing_current_auth_info = on_buffer;
2804 authinfo->outgoing_previous_auth_info = oo_buffer;
2806 *_authinfo = authinfo;
2808 return true;
2811 static bool check_pw_with_ServerAuthenticate3(struct dcerpc_pipe *p,
2812 struct torture_context *tctx,
2813 uint32_t negotiate_flags,
2814 const char *server_name,
2815 struct cli_credentials *machine_credentials,
2816 struct netlogon_creds_CredentialState **creds_out)
2818 struct netr_ServerReqChallenge r;
2819 struct netr_ServerAuthenticate3 a;
2820 struct netr_Credential credentials1, credentials2, credentials3;
2821 struct netlogon_creds_CredentialState *creds;
2822 const struct samr_Password *new_password = NULL;
2823 const struct samr_Password *old_password = NULL;
2824 uint32_t rid;
2825 struct dcerpc_binding_handle *b = p->binding_handle;
2827 new_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
2828 old_password = cli_credentials_get_old_nt_hash(machine_credentials, tctx);
2830 r.in.server_name = server_name;
2831 r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2832 r.in.credentials = &credentials1;
2833 r.out.return_credentials = &credentials2;
2835 generate_random_buffer(credentials1.data, sizeof(credentials1.data));
2837 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2838 "ServerReqChallenge failed");
2839 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
2841 a.in.server_name = server_name;
2842 a.in.account_name = cli_credentials_get_username(machine_credentials);
2843 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2844 a.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2845 a.in.negotiate_flags = &negotiate_flags;
2846 a.in.credentials = &credentials3;
2847 a.out.return_credentials = &credentials3;
2848 a.out.negotiate_flags = &negotiate_flags;
2849 a.out.rid = &rid;
2851 creds = netlogon_creds_client_init(tctx, a.in.account_name,
2852 a.in.computer_name,
2853 a.in.secure_channel_type,
2854 &credentials1, &credentials2,
2855 new_password, &credentials3,
2856 negotiate_flags);
2858 torture_assert(tctx, creds != NULL, "memory allocation");
2860 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2861 "ServerAuthenticate3 failed");
2862 if (!NT_STATUS_IS_OK(a.out.result)) {
2863 if (!NT_STATUS_EQUAL(a.out.result, NT_STATUS_ACCESS_DENIED)) {
2864 torture_assert_ntstatus_ok(tctx, a.out.result,
2865 "ServerAuthenticate3 failed");
2867 return false;
2869 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2871 if (old_password != NULL) {
2872 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2873 "ServerReqChallenge failed");
2874 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
2876 creds = netlogon_creds_client_init(tctx, a.in.account_name,
2877 a.in.computer_name,
2878 a.in.secure_channel_type,
2879 &credentials1, &credentials2,
2880 old_password, &credentials3,
2881 negotiate_flags);
2883 torture_assert(tctx, creds != NULL, "memory allocation");
2885 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2886 "ServerAuthenticate3 failed");
2887 if (!NT_STATUS_IS_OK(a.out.result)) {
2888 if (!NT_STATUS_EQUAL(a.out.result, NT_STATUS_ACCESS_DENIED)) {
2889 torture_assert_ntstatus_ok(tctx, a.out.result,
2890 "ServerAuthenticate3 (old) failed");
2892 return false;
2894 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential (old) chaining failed");
2897 /* Prove that requesting a challenge again won't break it */
2898 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2899 "ServerReqChallenge failed");
2900 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
2902 *creds_out = creds;
2903 return true;
2907 * This function is set in torture_krb5_init_context as krb5
2908 * send_and_recv function. This allows us to override what server the
2909 * test is aimed at, and to inspect the packets just before they are
2910 * sent to the network, and before they are processed on the recv
2911 * side.
2913 * The torture_krb5_pre_send_test() and torture_krb5_post_recv_test()
2914 * functions are implement the actual tests.
2916 * When this asserts, the caller will get a spurious 'cannot contact
2917 * any KDC' message.
2920 struct check_pw_with_krb5_ctx {
2921 struct addrinfo *server;
2922 struct {
2923 unsigned io;
2924 unsigned fail;
2925 unsigned errors;
2926 unsigned error_io;
2927 unsigned ok;
2928 } counts;
2929 krb5_error error;
2930 struct smb_krb5_context *smb_krb5_context;
2931 krb5_get_init_creds_opt *krb_options;
2932 krb5_creds my_creds;
2933 krb5_get_creds_opt opt_canon;
2934 krb5_get_creds_opt opt_nocanon;
2935 krb5_principal upn_realm;
2936 krb5_principal upn_dns;
2937 krb5_principal upn_netbios;
2938 krb5_ccache krbtgt_ccache;
2939 krb5_principal krbtgt_trust_realm;
2940 krb5_creds *krbtgt_trust_realm_creds;
2941 krb5_principal krbtgt_trust_dns;
2942 krb5_creds *krbtgt_trust_dns_creds;
2943 krb5_principal krbtgt_trust_netbios;
2944 krb5_creds *krbtgt_trust_netbios_creds;
2945 krb5_principal cifs_trust_dns;
2946 krb5_creds *cifs_trust_dns_creds;
2947 krb5_principal cifs_trust_netbios;
2948 krb5_creds *cifs_trust_netbios_creds;
2949 krb5_principal drs_trust_dns;
2950 krb5_creds *drs_trust_dns_creds;
2951 krb5_principal drs_trust_netbios;
2952 krb5_creds *drs_trust_netbios_creds;
2953 krb5_principal four_trust_dns;
2954 krb5_creds *four_trust_dns_creds;
2955 krb5_creds krbtgt_referral_creds;
2956 Ticket krbtgt_referral_ticket;
2957 krb5_keyblock krbtgt_referral_keyblock;
2958 EncTicketPart krbtgt_referral_enc_part;
2961 static krb5_error_code check_pw_with_krb5_send_and_recv_func(krb5_context context,
2962 void *data, /* struct check_pw_with_krb5_ctx */
2963 krb5_krbhst_info *_hi,
2964 time_t timeout,
2965 const krb5_data *send_buf,
2966 krb5_data *recv_buf)
2968 struct check_pw_with_krb5_ctx *ctx =
2969 talloc_get_type_abort(data, struct check_pw_with_krb5_ctx);
2970 krb5_error_code k5ret;
2971 krb5_krbhst_info hi = *_hi;
2972 size_t used;
2973 int ret;
2975 hi.proto = KRB5_KRBHST_TCP;
2977 smb_krb5_free_error(ctx->smb_krb5_context->krb5_context,
2978 &ctx->error);
2979 ctx->counts.io++;
2981 k5ret = smb_krb5_send_and_recv_func_forced(context, ctx->server,
2982 &hi, timeout, send_buf, recv_buf);
2983 if (k5ret != 0) {
2984 ctx->counts.fail++;
2985 return k5ret;
2988 ret = decode_KRB_ERROR(recv_buf->data, recv_buf->length,
2989 &ctx->error, &used);
2990 if (ret == 0) {
2991 ctx->counts.errors++;
2992 ctx->counts.error_io = ctx->counts.io;
2993 } else {
2994 ctx->counts.ok++;
2997 return k5ret;
3000 static int check_pw_with_krb5_ctx_destructor(struct check_pw_with_krb5_ctx *ctx)
3002 if (ctx->server != NULL) {
3003 freeaddrinfo(ctx->server);
3004 ctx->server = NULL;
3007 if (ctx->krb_options != NULL) {
3008 krb5_get_init_creds_opt_free(ctx->smb_krb5_context->krb5_context,
3009 ctx->krb_options);
3010 ctx->krb_options = NULL;
3013 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3014 &ctx->my_creds);
3016 if (ctx->opt_canon != NULL) {
3017 krb5_get_creds_opt_free(ctx->smb_krb5_context->krb5_context,
3018 ctx->opt_canon);
3019 ctx->opt_canon = NULL;
3022 if (ctx->opt_nocanon != NULL) {
3023 krb5_get_creds_opt_free(ctx->smb_krb5_context->krb5_context,
3024 ctx->opt_nocanon);
3025 ctx->opt_nocanon = NULL;
3028 if (ctx->krbtgt_ccache != NULL) {
3029 krb5_cc_close(ctx->smb_krb5_context->krb5_context,
3030 ctx->krbtgt_ccache);
3031 ctx->krbtgt_ccache = NULL;
3034 if (ctx->upn_realm != NULL) {
3035 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3036 ctx->upn_realm);
3037 ctx->upn_realm = NULL;
3040 if (ctx->upn_dns != NULL) {
3041 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3042 ctx->upn_dns);
3043 ctx->upn_dns = NULL;
3046 if (ctx->upn_netbios != NULL) {
3047 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3048 ctx->upn_netbios);
3049 ctx->upn_netbios = NULL;
3052 if (ctx->krbtgt_trust_realm != NULL) {
3053 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3054 ctx->krbtgt_trust_realm);
3055 ctx->krbtgt_trust_realm = NULL;
3058 if (ctx->krbtgt_trust_realm_creds != NULL) {
3059 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3060 ctx->krbtgt_trust_realm_creds);
3061 ctx->krbtgt_trust_realm_creds = NULL;
3064 if (ctx->krbtgt_trust_dns != NULL) {
3065 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3066 ctx->krbtgt_trust_dns);
3067 ctx->krbtgt_trust_dns = NULL;
3070 if (ctx->krbtgt_trust_dns_creds != NULL) {
3071 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3072 ctx->krbtgt_trust_dns_creds);
3073 ctx->krbtgt_trust_dns_creds = NULL;
3076 if (ctx->krbtgt_trust_netbios != NULL) {
3077 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3078 ctx->krbtgt_trust_netbios);
3079 ctx->krbtgt_trust_netbios = NULL;
3082 if (ctx->krbtgt_trust_netbios_creds != NULL) {
3083 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3084 ctx->krbtgt_trust_netbios_creds);
3085 ctx->krbtgt_trust_netbios_creds = NULL;
3088 if (ctx->cifs_trust_dns != NULL) {
3089 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3090 ctx->cifs_trust_dns);
3091 ctx->cifs_trust_dns = NULL;
3094 if (ctx->cifs_trust_dns_creds != NULL) {
3095 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3096 ctx->cifs_trust_dns_creds);
3097 ctx->cifs_trust_dns_creds = NULL;
3100 if (ctx->cifs_trust_netbios != NULL) {
3101 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3102 ctx->cifs_trust_netbios);
3103 ctx->cifs_trust_netbios = NULL;
3106 if (ctx->cifs_trust_netbios_creds != NULL) {
3107 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3108 ctx->cifs_trust_netbios_creds);
3109 ctx->cifs_trust_netbios_creds = NULL;
3112 if (ctx->drs_trust_dns != NULL) {
3113 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3114 ctx->drs_trust_dns);
3115 ctx->drs_trust_dns = NULL;
3118 if (ctx->drs_trust_dns_creds != NULL) {
3119 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3120 ctx->drs_trust_dns_creds);
3121 ctx->drs_trust_dns_creds = NULL;
3124 if (ctx->drs_trust_netbios != NULL) {
3125 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3126 ctx->drs_trust_netbios);
3127 ctx->drs_trust_netbios = NULL;
3130 if (ctx->drs_trust_netbios_creds != NULL) {
3131 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3132 ctx->drs_trust_netbios_creds);
3133 ctx->drs_trust_netbios_creds = NULL;
3136 if (ctx->four_trust_dns != NULL) {
3137 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3138 ctx->four_trust_dns);
3139 ctx->four_trust_dns = NULL;
3142 if (ctx->four_trust_dns_creds != NULL) {
3143 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3144 ctx->four_trust_dns_creds);
3145 ctx->four_trust_dns_creds = NULL;
3148 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3149 &ctx->krbtgt_referral_creds);
3151 free_Ticket(&ctx->krbtgt_referral_ticket);
3153 krb5_free_keyblock_contents(ctx->smb_krb5_context->krb5_context,
3154 &ctx->krbtgt_referral_keyblock);
3156 free_EncTicketPart(&ctx->krbtgt_referral_enc_part);
3158 smb_krb5_free_error(ctx->smb_krb5_context->krb5_context,
3159 &ctx->error);
3161 talloc_unlink(ctx, ctx->smb_krb5_context);
3162 ctx->smb_krb5_context = NULL;
3163 return 0;
3166 static bool check_pw_with_krb5(struct torture_context *tctx,
3167 struct cli_credentials *credentials,
3168 const struct lsa_TrustDomainInfoInfoEx *trusted)
3170 const char *trusted_dns_name = trusted->domain_name.string;
3171 const char *trusted_netbios_name = trusted->netbios_name.string;
3172 char *trusted_realm_name = NULL;
3173 krb5_principal principal = NULL;
3174 enum credentials_obtained obtained;
3175 const char *error_string = NULL;
3176 const char *workstation = cli_credentials_get_workstation(credentials);
3177 const char *password = cli_credentials_get_password(credentials);
3178 const struct samr_Password *nthash = NULL;
3179 const struct samr_Password *old_nthash = NULL;
3180 const char *old_password = cli_credentials_get_old_password(credentials);
3181 int kvno = cli_credentials_get_kvno(credentials);
3182 int expected_kvno = 0;
3183 krb5uint32 t_kvno = 0;
3184 const char *host = torture_setting_string(tctx, "host", NULL);
3185 krb5_error_code k5ret;
3186 krb5_boolean k5ok;
3187 int type;
3188 bool ok;
3189 struct check_pw_with_krb5_ctx *ctx = NULL;
3190 char *assertion_message = NULL;
3191 const char *realm = NULL;
3192 char *upn_realm_string = NULL;
3193 char *upn_dns_string = NULL;
3194 char *upn_netbios_string = NULL;
3195 char *krbtgt_cc_name = NULL;
3196 char *krbtgt_trust_realm_string = NULL;
3197 char *krbtgt_trust_dns_string = NULL;
3198 char *krbtgt_trust_netbios_string = NULL;
3199 char *cifs_trust_dns_string = NULL;
3200 char *cifs_trust_netbios_string = NULL;
3201 char *drs_trust_dns_string = NULL;
3202 char *drs_trust_netbios_string = NULL;
3203 char *four_trust_dns_string = NULL;
3205 ctx = talloc_zero(tctx, struct check_pw_with_krb5_ctx);
3206 torture_assert(tctx, ctx != NULL, "Failed to allocate");
3208 realm = cli_credentials_get_realm(credentials);
3209 trusted_realm_name = strupper_talloc(tctx, trusted_dns_name);
3211 nthash = cli_credentials_get_nt_hash(credentials, ctx);
3212 old_nthash = cli_credentials_get_old_nt_hash(credentials, ctx);
3214 k5ret = smb_krb5_init_context(ctx, tctx->lp_ctx, &ctx->smb_krb5_context);
3215 torture_assert_int_equal(tctx, k5ret, 0, "smb_krb5_init_context failed");
3217 ok = interpret_string_addr_internal(&ctx->server, host, AI_NUMERICHOST);
3218 torture_assert(tctx, ok, "Failed to parse target server");
3219 talloc_set_destructor(ctx, check_pw_with_krb5_ctx_destructor);
3221 set_sockaddr_port(ctx->server->ai_addr, 88);
3223 k5ret = krb5_set_send_to_kdc_func(ctx->smb_krb5_context->krb5_context,
3224 check_pw_with_krb5_send_and_recv_func,
3225 ctx);
3226 torture_assert_int_equal(tctx, k5ret, 0, "krb5_set_send_to_kdc_func failed");
3228 torture_assert_int_equal(tctx,
3229 krb5_get_init_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3230 &ctx->krb_options),
3231 0, "krb5_get_init_creds_opt_alloc failed");
3232 torture_assert_int_equal(tctx,
3233 krb5_get_init_creds_opt_set_pac_request(
3234 ctx->smb_krb5_context->krb5_context,
3235 ctx->krb_options, true),
3236 0, "krb5_get_init_creds_opt_set_pac_request failed");
3238 upn_realm_string = talloc_asprintf(ctx, "user@%s",
3239 trusted_realm_name);
3240 torture_assert_int_equal(tctx,
3241 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3242 &ctx->upn_realm,
3243 realm, upn_realm_string, NULL),
3244 0, "smb_krb5_make_principal failed");
3245 smb_krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3246 ctx->upn_realm, KRB5_NT_ENTERPRISE_PRINCIPAL);
3248 upn_dns_string = talloc_asprintf(ctx, "user@%s",
3249 trusted_dns_name);
3250 torture_assert_int_equal(tctx,
3251 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3252 &ctx->upn_dns,
3253 realm, upn_dns_string, NULL),
3254 0, "smb_krb5_make_principal failed");
3255 smb_krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3256 ctx->upn_dns, KRB5_NT_ENTERPRISE_PRINCIPAL);
3258 upn_netbios_string = talloc_asprintf(ctx, "user@%s",
3259 trusted_netbios_name);
3260 torture_assert_int_equal(tctx,
3261 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3262 &ctx->upn_netbios,
3263 realm, upn_netbios_string, NULL),
3264 0, "smb_krb5_make_principal failed");
3265 smb_krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3266 ctx->upn_netbios, KRB5_NT_ENTERPRISE_PRINCIPAL);
3268 k5ret = principal_from_credentials(ctx, credentials, ctx->smb_krb5_context,
3269 &principal, &obtained, &error_string);
3270 torture_assert_int_equal(tctx, k5ret, 0, error_string);
3272 ZERO_STRUCT(ctx->counts);
3273 k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3274 &ctx->my_creds, ctx->upn_realm,
3275 "_none_", NULL, NULL, 0,
3276 NULL, ctx->krb_options);
3277 assertion_message = talloc_asprintf(ctx,
3278 "krb5_get_init_creds_password(%s, canon) for failed: "
3279 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3280 upn_realm_string,
3281 k5ret,
3282 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3283 k5ret, ctx),
3284 trusted->trust_direction,
3285 trusted->trust_type,
3286 trusted->trust_attributes,
3287 ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3288 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3289 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3290 torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3291 torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
3292 torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3293 torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3294 torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3295 torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3297 ZERO_STRUCT(ctx->counts);
3298 k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3299 &ctx->my_creds, ctx->upn_dns,
3300 "_none_", NULL, NULL, 0,
3301 NULL, ctx->krb_options);
3302 assertion_message = talloc_asprintf(ctx,
3303 "krb5_get_init_creds_password(%s, canon) for failed: "
3304 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3305 upn_dns_string,
3306 k5ret,
3307 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3308 k5ret, ctx),
3309 trusted->trust_direction,
3310 trusted->trust_type,
3311 trusted->trust_attributes,
3312 ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3313 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3314 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3315 torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3316 torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
3317 torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3318 torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3319 torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3320 torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3322 ZERO_STRUCT(ctx->counts);
3323 k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3324 &ctx->my_creds, ctx->upn_netbios,
3325 "_none_", NULL, NULL, 0,
3326 NULL, ctx->krb_options);
3327 assertion_message = talloc_asprintf(ctx,
3328 "krb5_get_init_creds_password(%s, canon) for failed: "
3329 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3330 upn_netbios_string,
3331 k5ret,
3332 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3333 k5ret, ctx),
3334 trusted->trust_direction,
3335 trusted->trust_type,
3336 trusted->trust_attributes,
3337 ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3338 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3339 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3340 torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3341 torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
3342 torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3343 torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3344 torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3345 torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3347 torture_comment(tctx, "password[%s] old_password[%s]\n",
3348 password, old_password);
3349 if (old_password != NULL) {
3350 k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3351 &ctx->my_creds, principal,
3352 old_password, NULL, NULL, 0,
3353 NULL, ctx->krb_options);
3354 torture_assert_int_equal(tctx, k5ret, KRB5KDC_ERR_PREAUTH_FAILED,
3355 "preauth should fail with old password");
3358 k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3359 &ctx->my_creds, principal,
3360 password, NULL, NULL, 0,
3361 NULL, ctx->krb_options);
3362 if (k5ret == KRB5KDC_ERR_PREAUTH_FAILED) {
3363 TALLOC_FREE(ctx);
3364 return false;
3367 assertion_message = talloc_asprintf(ctx,
3368 "krb5_get_init_creds_password for failed: %s",
3369 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3370 k5ret, ctx));
3371 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3373 torture_assert_int_equal(tctx,
3374 krb5_get_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3375 &ctx->opt_canon),
3376 0, "krb5_get_creds_opt_alloc");
3378 krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3379 ctx->opt_canon,
3380 KRB5_GC_CANONICALIZE);
3382 krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3383 ctx->opt_canon,
3384 KRB5_GC_NO_STORE);
3386 torture_assert_int_equal(tctx,
3387 krb5_get_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3388 &ctx->opt_nocanon),
3389 0, "krb5_get_creds_opt_alloc");
3391 krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3392 ctx->opt_nocanon,
3393 KRB5_GC_NO_STORE);
3395 krbtgt_cc_name = talloc_asprintf(ctx, "MEMORY:%p.krbtgt", ctx->smb_krb5_context);
3396 torture_assert_int_equal(tctx,
3397 krb5_cc_resolve(ctx->smb_krb5_context->krb5_context,
3398 krbtgt_cc_name,
3399 &ctx->krbtgt_ccache),
3400 0, "krb5_cc_resolve failed");
3402 torture_assert_int_equal(tctx,
3403 krb5_cc_initialize(ctx->smb_krb5_context->krb5_context,
3404 ctx->krbtgt_ccache,
3405 ctx->my_creds.client),
3406 0, "krb5_cc_initialize failed");
3408 torture_assert_int_equal(tctx,
3409 krb5_cc_store_cred(ctx->smb_krb5_context->krb5_context,
3410 ctx->krbtgt_ccache,
3411 &ctx->my_creds),
3412 0, "krb5_cc_store_cred failed");
3414 krbtgt_trust_realm_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3415 trusted_realm_name, realm);
3416 torture_assert_int_equal(tctx,
3417 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3418 &ctx->krbtgt_trust_realm,
3419 realm, "krbtgt",
3420 trusted_realm_name, NULL),
3421 0, "smb_krb5_make_principal failed");
3423 krbtgt_trust_dns_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3424 trusted_dns_name, realm);
3425 torture_assert_int_equal(tctx,
3426 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3427 &ctx->krbtgt_trust_dns,
3428 realm, "krbtgt",
3429 trusted_dns_name, NULL),
3430 0, "smb_krb5_make_principal failed");
3432 krbtgt_trust_netbios_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3433 trusted_netbios_name, realm);
3434 torture_assert_int_equal(tctx,
3435 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3436 &ctx->krbtgt_trust_netbios,
3437 realm, "krbtgt",
3438 trusted_netbios_name, NULL),
3439 0, "smb_krb5_make_principal failed");
3441 /* Confirm if we can do a TGS for krbtgt/trusted_realm */
3442 ZERO_STRUCT(ctx->counts);
3443 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3444 ctx->opt_nocanon,
3445 ctx->krbtgt_ccache,
3446 ctx->krbtgt_trust_realm,
3447 &ctx->krbtgt_trust_realm_creds);
3448 assertion_message = talloc_asprintf(ctx,
3449 "krb5_get_creds(%s, canon) for failed: "
3450 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3451 krbtgt_trust_realm_string,
3452 k5ret,
3453 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3454 k5ret, ctx),
3455 trusted->trust_direction,
3456 trusted->trust_type,
3457 trusted->trust_attributes,
3458 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3459 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3460 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3461 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3463 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3464 ctx->krbtgt_trust_realm_creds->server,
3465 ctx->krbtgt_trust_realm);
3466 torture_assert(tctx, k5ok, assertion_message);
3467 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3468 ctx->krbtgt_trust_realm_creds->server);
3469 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3471 /* Confirm if we have no referral ticket in the cache */
3472 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3473 &ctx->krbtgt_referral_creds);
3474 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3475 ctx->krbtgt_ccache,
3477 ctx->krbtgt_trust_realm_creds,
3478 &ctx->krbtgt_referral_creds);
3479 assertion_message = talloc_asprintf(ctx,
3480 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3481 krbtgt_trust_realm_string,
3482 k5ret,
3483 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3484 k5ret, ctx));
3485 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3487 /* Confirm if we can do a TGS for krbtgt/trusted_dns with CANON */
3488 ZERO_STRUCT(ctx->counts);
3489 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3490 ctx->opt_canon,
3491 ctx->krbtgt_ccache,
3492 ctx->krbtgt_trust_dns,
3493 &ctx->krbtgt_trust_dns_creds);
3494 assertion_message = talloc_asprintf(ctx,
3495 "krb5_get_creds(%s, canon) for failed: "
3496 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3497 krbtgt_trust_dns_string,
3498 k5ret,
3499 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3500 k5ret, ctx),
3501 trusted->trust_direction,
3502 trusted->trust_type,
3503 trusted->trust_attributes,
3504 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3505 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3506 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3507 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3509 /* Confirm if we have the referral ticket in the cache */
3510 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3511 &ctx->krbtgt_referral_creds);
3512 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3513 ctx->krbtgt_ccache,
3515 ctx->krbtgt_trust_realm_creds,
3516 &ctx->krbtgt_referral_creds);
3517 assertion_message = talloc_asprintf(ctx,
3518 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3519 krbtgt_trust_realm_string,
3520 k5ret,
3521 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3522 k5ret, ctx));
3523 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3525 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3526 ctx->krbtgt_referral_creds.server,
3527 ctx->krbtgt_trust_realm);
3528 torture_assert(tctx, k5ok, assertion_message);
3529 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3530 ctx->krbtgt_referral_creds.server);
3531 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3532 k5ret = decode_Ticket(ctx->krbtgt_referral_creds.ticket.data,
3533 ctx->krbtgt_referral_creds.ticket.length,
3534 &ctx->krbtgt_referral_ticket, NULL);
3535 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3536 if (kvno > 0) {
3537 expected_kvno = kvno - 1;
3539 if (ctx->krbtgt_referral_ticket.enc_part.kvno != NULL) {
3540 t_kvno = *ctx->krbtgt_referral_ticket.enc_part.kvno;
3541 assertion_message = talloc_asprintf(ctx,
3542 "krbtgt_referral_ticket(%s) kvno(%u) expected(%u) current(%u)",
3543 krbtgt_trust_realm_string,
3544 (unsigned)t_kvno, (unsigned)expected_kvno,(unsigned)kvno);
3545 torture_comment(tctx, "%s\n", assertion_message);
3546 torture_assert_int_not_equal(tctx, t_kvno, 0, assertion_message);
3547 } else {
3548 assertion_message = talloc_asprintf(ctx,
3549 "krbtgt_referral_ticket(%s) kvno(NULL) exptected(%u) current(%u)",
3550 krbtgt_trust_realm_string,
3551 (unsigned)expected_kvno,(unsigned)kvno);
3552 torture_comment(tctx, "%s\n", assertion_message);
3554 torture_assert_int_equal(tctx, t_kvno, expected_kvno, assertion_message);
3556 if (old_nthash != NULL && expected_kvno != kvno) {
3557 torture_comment(tctx, "old_nthash: %s\n", assertion_message);
3558 k5ret = smb_krb5_keyblock_init_contents(ctx->smb_krb5_context->krb5_context,
3559 ENCTYPE_ARCFOUR_HMAC,
3560 old_nthash->hash,
3561 sizeof(old_nthash->hash),
3562 &ctx->krbtgt_referral_keyblock);
3563 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3564 } else {
3565 torture_comment(tctx, "nthash: %s\n", assertion_message);
3566 k5ret = smb_krb5_keyblock_init_contents(ctx->smb_krb5_context->krb5_context,
3567 ENCTYPE_ARCFOUR_HMAC,
3568 nthash->hash,
3569 sizeof(nthash->hash),
3570 &ctx->krbtgt_referral_keyblock);
3571 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3573 k5ret = krb5_decrypt_ticket(ctx->smb_krb5_context->krb5_context,
3574 &ctx->krbtgt_referral_ticket,
3575 &ctx->krbtgt_referral_keyblock,
3576 &ctx->krbtgt_referral_enc_part,
3578 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3580 /* Delete the referral ticket from the cache */
3581 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3582 ctx->krbtgt_ccache,
3584 &ctx->krbtgt_referral_creds);
3585 assertion_message = talloc_asprintf(ctx,
3586 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3587 krbtgt_trust_realm_string,
3588 k5ret,
3589 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3590 k5ret, ctx));
3591 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3593 /* Confirm if we can do a TGS for krbtgt/trusted_dns no CANON */
3594 ZERO_STRUCT(ctx->counts);
3595 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3596 ctx->opt_nocanon,
3597 ctx->krbtgt_ccache,
3598 ctx->krbtgt_trust_dns,
3599 &ctx->krbtgt_trust_dns_creds);
3600 assertion_message = talloc_asprintf(ctx,
3601 "krb5_get_creds(%s, nocanon) for failed: "
3602 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3603 krbtgt_trust_dns_string,
3604 k5ret,
3605 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3606 k5ret, ctx),
3607 trusted->trust_direction,
3608 trusted->trust_type,
3609 trusted->trust_attributes,
3610 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3611 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3612 torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
3613 torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
3615 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3616 ctx->krbtgt_trust_dns_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_trust_dns_creds->server);
3621 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3623 /* Confirm if we have the referral ticket in the cache */
3624 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3625 &ctx->krbtgt_referral_creds);
3626 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3627 ctx->krbtgt_ccache,
3629 ctx->krbtgt_trust_realm_creds,
3630 &ctx->krbtgt_referral_creds);
3631 assertion_message = talloc_asprintf(ctx,
3632 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3633 krbtgt_trust_realm_string,
3634 k5ret,
3635 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3636 k5ret, ctx));
3637 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3639 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3640 ctx->krbtgt_referral_creds.server,
3641 ctx->krbtgt_trust_realm);
3642 torture_assert(tctx, k5ok, assertion_message);
3643 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3644 ctx->krbtgt_referral_creds.server);
3645 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3647 /* Delete the referral ticket from the cache */
3648 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3649 ctx->krbtgt_ccache,
3651 &ctx->krbtgt_referral_creds);
3652 assertion_message = talloc_asprintf(ctx,
3653 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3654 krbtgt_trust_realm_string,
3655 k5ret,
3656 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3657 k5ret, ctx));
3658 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3660 /* Confirm if we can do a TGS for krbtgt/NETBIOS with CANON */
3661 ZERO_STRUCT(ctx->counts);
3662 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3663 ctx->opt_canon,
3664 ctx->krbtgt_ccache,
3665 ctx->krbtgt_trust_netbios,
3666 &ctx->krbtgt_trust_netbios_creds);
3667 assertion_message = talloc_asprintf(ctx,
3668 "krb5_get_creds(%s, canon) for failed: "
3669 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3670 krbtgt_trust_netbios_string,
3671 k5ret,
3672 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3673 k5ret, ctx),
3674 trusted->trust_direction,
3675 trusted->trust_type,
3676 trusted->trust_attributes,
3677 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3678 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3679 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3680 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3682 /* Confirm if we have the referral ticket in the cache */
3683 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3684 &ctx->krbtgt_referral_creds);
3685 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3686 ctx->krbtgt_ccache,
3688 ctx->krbtgt_trust_realm_creds,
3689 &ctx->krbtgt_referral_creds);
3690 assertion_message = talloc_asprintf(ctx,
3691 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3692 krbtgt_trust_netbios_string,
3693 k5ret,
3694 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3695 k5ret, ctx));
3696 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3698 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3699 ctx->krbtgt_referral_creds.server,
3700 ctx->krbtgt_trust_realm);
3701 torture_assert(tctx, k5ok, assertion_message);
3702 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3703 ctx->krbtgt_referral_creds.server);
3704 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3706 /* Delete the referral ticket from the cache */
3707 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3708 ctx->krbtgt_ccache,
3710 &ctx->krbtgt_referral_creds);
3711 assertion_message = talloc_asprintf(ctx,
3712 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3713 krbtgt_trust_realm_string,
3714 k5ret,
3715 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3716 k5ret, ctx));
3717 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3719 /* Confirm if we can do a TGS for krbtgt/NETBIOS no CANON */
3720 ZERO_STRUCT(ctx->counts);
3721 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3722 ctx->opt_nocanon,
3723 ctx->krbtgt_ccache,
3724 ctx->krbtgt_trust_netbios,
3725 &ctx->krbtgt_trust_netbios_creds);
3726 assertion_message = talloc_asprintf(ctx,
3727 "krb5_get_creds(%s, nocanon) for failed: "
3728 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3729 krbtgt_trust_netbios_string,
3730 k5ret,
3731 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3732 k5ret, ctx),
3733 trusted->trust_direction,
3734 trusted->trust_type,
3735 trusted->trust_attributes,
3736 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3737 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3738 torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
3739 torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
3741 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3742 ctx->krbtgt_trust_netbios_creds->server,
3743 ctx->krbtgt_trust_realm);
3744 torture_assert(tctx, k5ok, assertion_message);
3745 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3746 ctx->krbtgt_trust_netbios_creds->server);
3747 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3749 /* Confirm if we have the referral ticket in the cache */
3750 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3751 &ctx->krbtgt_referral_creds);
3752 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3753 ctx->krbtgt_ccache,
3755 ctx->krbtgt_trust_realm_creds,
3756 &ctx->krbtgt_referral_creds);
3757 assertion_message = talloc_asprintf(ctx,
3758 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3759 krbtgt_trust_realm_string,
3760 k5ret,
3761 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3762 k5ret, ctx));
3763 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3765 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3766 ctx->krbtgt_referral_creds.server,
3767 ctx->krbtgt_trust_realm);
3768 torture_assert(tctx, k5ok, assertion_message);
3769 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3770 ctx->krbtgt_referral_creds.server);
3771 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3773 /* Delete the referral ticket from the cache */
3774 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3775 ctx->krbtgt_ccache,
3777 &ctx->krbtgt_referral_creds);
3778 assertion_message = talloc_asprintf(ctx,
3779 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3780 krbtgt_trust_realm_string,
3781 k5ret,
3782 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3783 k5ret, ctx));
3784 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3786 cifs_trust_dns_string = talloc_asprintf(ctx, "cifs/%s@%s",
3787 trusted_dns_name, realm);
3788 torture_assert_int_equal(tctx,
3789 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3790 &ctx->cifs_trust_dns,
3791 realm, "cifs",
3792 trusted_dns_name, NULL),
3793 0, "smb_krb5_make_principal failed");
3795 /* Confirm if we get krbtgt/trusted_realm back when asking for cifs/trusted_realm */
3796 ZERO_STRUCT(ctx->counts);
3797 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3798 ctx->opt_canon,
3799 ctx->krbtgt_ccache,
3800 ctx->cifs_trust_dns,
3801 &ctx->cifs_trust_dns_creds);
3802 assertion_message = talloc_asprintf(ctx,
3803 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3804 cifs_trust_dns_string,
3805 k5ret,
3806 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3807 k5ret, ctx),
3808 trusted->trust_direction,
3809 trusted->trust_type,
3810 trusted->trust_attributes,
3811 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3812 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3813 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3814 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3816 /* Confirm if we have the referral ticket in the cache */
3817 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3818 &ctx->krbtgt_referral_creds);
3819 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3820 ctx->krbtgt_ccache,
3822 ctx->krbtgt_trust_realm_creds,
3823 &ctx->krbtgt_referral_creds);
3824 assertion_message = talloc_asprintf(ctx,
3825 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3826 krbtgt_trust_realm_string,
3827 k5ret,
3828 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3829 k5ret, ctx));
3830 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3832 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3833 ctx->krbtgt_referral_creds.server,
3834 ctx->krbtgt_trust_realm);
3835 torture_assert(tctx, k5ok, assertion_message);
3836 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3837 ctx->krbtgt_referral_creds.server);
3838 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3840 /* Delete the referral ticket from the cache */
3841 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3842 ctx->krbtgt_ccache,
3844 &ctx->krbtgt_referral_creds);
3845 assertion_message = talloc_asprintf(ctx,
3846 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3847 krbtgt_trust_realm_string,
3848 k5ret,
3849 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3850 k5ret, ctx));
3851 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3853 cifs_trust_netbios_string = talloc_asprintf(ctx, "cifs/%s@%s",
3854 trusted_netbios_name, realm);
3855 torture_assert_int_equal(tctx,
3856 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3857 &ctx->cifs_trust_netbios,
3858 realm, "cifs",
3859 trusted_netbios_name, NULL),
3860 0, "smb_krb5_make_principal failed");
3862 /* Confirm if we get krbtgt/trusted_realm back when asking for cifs/trusted_realm */
3863 ZERO_STRUCT(ctx->counts);
3864 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3865 ctx->opt_canon,
3866 ctx->krbtgt_ccache,
3867 ctx->cifs_trust_netbios,
3868 &ctx->cifs_trust_netbios_creds);
3869 assertion_message = talloc_asprintf(ctx,
3870 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3871 cifs_trust_netbios_string,
3872 k5ret,
3873 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3874 k5ret, ctx),
3875 trusted->trust_direction,
3876 trusted->trust_type,
3877 trusted->trust_attributes,
3878 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3879 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3880 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3881 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3883 /* Confirm if we have the referral ticket in the cache */
3884 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3885 &ctx->krbtgt_referral_creds);
3886 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3887 ctx->krbtgt_ccache,
3889 ctx->krbtgt_trust_realm_creds,
3890 &ctx->krbtgt_referral_creds);
3891 assertion_message = talloc_asprintf(ctx,
3892 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3893 krbtgt_trust_realm_string,
3894 k5ret,
3895 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3896 k5ret, ctx));
3897 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3899 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3900 ctx->krbtgt_referral_creds.server,
3901 ctx->krbtgt_trust_realm);
3902 torture_assert(tctx, k5ok, assertion_message);
3903 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3904 ctx->krbtgt_referral_creds.server);
3905 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3907 /* Delete the referral ticket from the cache */
3908 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3909 ctx->krbtgt_ccache,
3911 &ctx->krbtgt_referral_creds);
3912 assertion_message = talloc_asprintf(ctx,
3913 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3914 krbtgt_trust_realm_string,
3915 k5ret,
3916 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3917 k5ret, ctx));
3918 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3920 drs_trust_dns_string = talloc_asprintf(ctx,
3921 "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s@%s",
3922 workstation, trusted_dns_name, realm);
3923 torture_assert_int_equal(tctx,
3924 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3925 &ctx->drs_trust_dns,
3926 realm, "E3514235-4B06-11D1-AB04-00C04FC2DCD2",
3927 workstation, trusted_dns_name, NULL),
3928 0, "smb_krb5_make_principal failed");
3930 /* Confirm if we get krbtgt/trusted_realm back when asking for a 3 part principal */
3931 ZERO_STRUCT(ctx->counts);
3932 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3933 ctx->opt_canon,
3934 ctx->krbtgt_ccache,
3935 ctx->drs_trust_dns,
3936 &ctx->drs_trust_dns_creds);
3937 assertion_message = talloc_asprintf(ctx,
3938 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3939 drs_trust_dns_string,
3940 k5ret,
3941 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3942 k5ret, ctx),
3943 trusted->trust_direction,
3944 trusted->trust_type,
3945 trusted->trust_attributes,
3946 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3947 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3948 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3949 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3951 /* Confirm if we have the referral ticket in the cache */
3952 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3953 &ctx->krbtgt_referral_creds);
3954 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3955 ctx->krbtgt_ccache,
3957 ctx->krbtgt_trust_realm_creds,
3958 &ctx->krbtgt_referral_creds);
3959 assertion_message = talloc_asprintf(ctx,
3960 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3961 krbtgt_trust_realm_string,
3962 k5ret,
3963 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3964 k5ret, ctx));
3965 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3967 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3968 ctx->krbtgt_referral_creds.server,
3969 ctx->krbtgt_trust_realm);
3970 torture_assert(tctx, k5ok, assertion_message);
3971 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3972 ctx->krbtgt_referral_creds.server);
3973 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3975 /* Delete the referral ticket from the cache */
3976 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3977 ctx->krbtgt_ccache,
3979 &ctx->krbtgt_referral_creds);
3980 assertion_message = talloc_asprintf(ctx,
3981 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3982 krbtgt_trust_realm_string,
3983 k5ret,
3984 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3985 k5ret, ctx));
3986 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3988 drs_trust_netbios_string = talloc_asprintf(ctx,
3989 "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s@%s",
3990 workstation, trusted_netbios_name, realm);
3991 torture_assert_int_equal(tctx,
3992 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3993 &ctx->drs_trust_netbios,
3994 realm, "E3514235-4B06-11D1-AB04-00C04FC2DCD2",
3995 workstation, trusted_netbios_name, NULL),
3996 0, "smb_krb5_make_principal failed");
3998 /* Confirm if we get krbtgt/trusted_realm back when asking for a 3 part principal */
3999 ZERO_STRUCT(ctx->counts);
4000 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4001 ctx->opt_canon,
4002 ctx->krbtgt_ccache,
4003 ctx->drs_trust_netbios,
4004 &ctx->drs_trust_netbios_creds);
4005 assertion_message = talloc_asprintf(ctx,
4006 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4007 drs_trust_netbios_string,
4008 k5ret,
4009 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4010 k5ret, ctx),
4011 trusted->trust_direction,
4012 trusted->trust_type,
4013 trusted->trust_attributes,
4014 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4015 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
4016 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4017 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
4019 /* Confirm if we have the referral ticket in the cache */
4020 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4021 &ctx->krbtgt_referral_creds);
4022 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4023 ctx->krbtgt_ccache,
4025 ctx->krbtgt_trust_realm_creds,
4026 &ctx->krbtgt_referral_creds);
4027 assertion_message = talloc_asprintf(ctx,
4028 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4029 krbtgt_trust_realm_string,
4030 k5ret,
4031 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4032 k5ret, ctx));
4033 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4035 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
4036 ctx->krbtgt_referral_creds.server,
4037 ctx->krbtgt_trust_realm);
4038 torture_assert(tctx, k5ok, assertion_message);
4039 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
4040 ctx->krbtgt_referral_creds.server);
4041 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
4043 /* Delete the referral ticket from the cache */
4044 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
4045 ctx->krbtgt_ccache,
4047 &ctx->krbtgt_referral_creds);
4048 assertion_message = talloc_asprintf(ctx,
4049 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
4050 krbtgt_trust_realm_string,
4051 k5ret,
4052 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4053 k5ret, ctx));
4054 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4056 four_trust_dns_string = talloc_asprintf(ctx, "four/tree/two/%s@%s",
4057 trusted_dns_name, realm);
4058 torture_assert_int_equal(tctx,
4059 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
4060 &ctx->four_trust_dns,
4061 realm, "four", "tree", "two",
4062 trusted_dns_name, NULL),
4063 0, "smb_krb5_make_principal failed");
4065 /* Confirm if we get an error back for a 4 part principal */
4066 ZERO_STRUCT(ctx->counts);
4067 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4068 ctx->opt_canon,
4069 ctx->krbtgt_ccache,
4070 ctx->four_trust_dns,
4071 &ctx->four_trust_dns_creds);
4072 assertion_message = talloc_asprintf(ctx,
4073 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4074 four_trust_dns_string,
4075 k5ret,
4076 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4077 k5ret, ctx),
4078 trusted->trust_direction,
4079 trusted->trust_type,
4080 trusted->trust_attributes,
4081 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4082 torture_assert_int_equal(tctx, k5ret, KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, assertion_message);
4083 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4084 torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
4085 torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 7, assertion_message);
4087 /* Confirm if we have no referral ticket in the cache */
4088 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4089 &ctx->krbtgt_referral_creds);
4090 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4091 ctx->krbtgt_ccache,
4093 ctx->krbtgt_trust_realm_creds,
4094 &ctx->krbtgt_referral_creds);
4095 assertion_message = talloc_asprintf(ctx,
4096 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4097 krbtgt_trust_realm_string,
4098 k5ret,
4099 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4100 k5ret, ctx));
4101 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4103 TALLOC_FREE(ctx);
4104 return true;
4107 static bool check_dom_trust_pw(struct dcerpc_pipe *p,
4108 struct torture_context *tctx,
4109 const char *our_netbios_name,
4110 const char *our_dns_name,
4111 enum netr_SchannelType secure_channel_type,
4112 const struct lsa_TrustDomainInfoInfoEx *trusted,
4113 const char *previous_password,
4114 const char *current_password,
4115 uint32_t current_version,
4116 const char *next_password,
4117 uint32_t next_version,
4118 bool expected_result)
4120 struct cli_credentials *incoming_creds;
4121 char *server_name = NULL;
4122 char *account = NULL;
4123 char *principal = NULL;
4124 char *workstation = NULL;
4125 const char *binding = torture_setting_string(tctx, "binding", NULL);
4126 const char *host = torture_setting_string(tctx, "host", NULL);
4127 struct dcerpc_binding *b2;
4128 struct netlogon_creds_CredentialState *creds;
4129 struct samr_CryptPassword samr_crypt_password;
4130 struct netr_CryptPassword netr_crypt_password;
4131 struct netr_Authenticator req_auth;
4132 struct netr_Authenticator rep_auth;
4133 struct netr_ServerPasswordSet2 s;
4134 struct dcerpc_pipe *p2;
4135 NTSTATUS status;
4136 bool ok;
4137 int rc;
4138 const char *trusted_netbios_name = trusted->netbios_name.string;
4139 const char *trusted_dns_name = trusted->domain_name.string;
4140 struct tsocket_address *dest_addr;
4141 struct cldap_socket *cldap;
4142 struct cldap_netlogon cldap1;
4144 incoming_creds = cli_credentials_init(tctx);
4145 torture_assert(tctx, incoming_creds, "cli_credentials_init");
4147 cli_credentials_set_domain(incoming_creds, our_netbios_name, CRED_SPECIFIED);
4148 cli_credentials_set_realm(incoming_creds, our_dns_name, CRED_SPECIFIED);
4150 if (secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
4151 account = talloc_asprintf(tctx, "%s.", trusted_dns_name);
4152 torture_assert(tctx, account, __location__);
4154 principal = talloc_asprintf(tctx, "%s$@%s",
4155 trusted_netbios_name,
4156 cli_credentials_get_realm(incoming_creds));
4157 torture_assert(tctx, principal, __location__);
4159 workstation = talloc_asprintf(tctx, "%sUP",
4160 trusted_netbios_name);
4161 torture_assert(tctx, workstation, __location__);
4162 } else {
4163 account = talloc_asprintf(tctx, "%s$", trusted_netbios_name);
4164 torture_assert(tctx, account, __location__);
4166 workstation = talloc_asprintf(tctx, "%sDOWN",
4167 trusted_netbios_name);
4168 torture_assert(tctx, workstation, __location__);
4171 cli_credentials_set_username(incoming_creds, account, CRED_SPECIFIED);
4172 if (principal != NULL) {
4173 cli_credentials_set_principal(incoming_creds, principal,
4174 CRED_SPECIFIED);
4176 cli_credentials_set_kvno(incoming_creds, current_version);
4177 cli_credentials_set_password(incoming_creds, current_password, CRED_SPECIFIED);
4178 cli_credentials_set_old_password(incoming_creds, previous_password, CRED_SPECIFIED);
4179 cli_credentials_set_workstation(incoming_creds, workstation, CRED_SPECIFIED);
4180 cli_credentials_set_secure_channel_type(incoming_creds, secure_channel_type);
4182 rc = tsocket_address_inet_from_strings(tctx, "ip",
4183 host,
4184 lpcfg_cldap_port(tctx->lp_ctx),
4185 &dest_addr);
4186 torture_assert_int_equal(tctx, rc, 0, "tsocket_address_inet_from_strings");
4188 /* cldap_socket_init should now know about the dest. address */
4189 status = cldap_socket_init(tctx, NULL, dest_addr, &cldap);
4190 torture_assert_ntstatus_ok(tctx, status, "cldap_socket_init");
4192 ZERO_STRUCT(cldap1);
4193 cldap1.in.dest_address = NULL;
4194 cldap1.in.dest_port = 0;
4195 cldap1.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
4196 cldap1.in.user = account;
4197 if (secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
4198 cldap1.in.acct_control = ACB_AUTOLOCK;
4199 } else {
4200 cldap1.in.acct_control = ACB_DOMTRUST;
4202 status = cldap_netlogon(cldap, tctx, &cldap1);
4203 torture_assert_ntstatus_ok(tctx, status, "cldap_netlogon");
4204 torture_assert_int_equal(tctx, cldap1.out.netlogon.ntver,
4205 NETLOGON_NT_VERSION_5EX,
4206 "ntver");
4207 torture_assert_int_equal(tctx, cldap1.out.netlogon.data.nt5_ex.nt_version,
4208 NETLOGON_NT_VERSION_1 | NETLOGON_NT_VERSION_5EX,
4209 "nt_version");
4210 torture_assert_int_equal(tctx, cldap1.out.netlogon.data.nt5_ex.command,
4211 LOGON_SAM_LOGON_RESPONSE_EX,
4212 "command");
4213 torture_assert_str_equal(tctx, cldap1.out.netlogon.data.nt5_ex.user_name,
4214 cldap1.in.user,
4215 "user_name");
4216 server_name = talloc_asprintf(tctx, "\\\\%s",
4217 cldap1.out.netlogon.data.nt5_ex.pdc_dns_name);
4218 torture_assert(tctx, server_name, __location__);
4220 status = dcerpc_parse_binding(tctx, binding, &b2);
4221 torture_assert_ntstatus_ok(tctx, status, "Bad binding string");
4223 status = dcerpc_pipe_connect_b(tctx, &p2, b2,
4224 &ndr_table_netlogon,
4225 cli_credentials_init_anon(tctx),
4226 tctx->ev, tctx->lp_ctx);
4227 torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b");
4229 ok = check_pw_with_ServerAuthenticate3(p2, tctx,
4230 NETLOGON_NEG_AUTH2_ADS_FLAGS,
4231 server_name,
4232 incoming_creds, &creds);
4233 torture_assert_int_equal(tctx, ok, expected_result,
4234 "check_pw_with_ServerAuthenticate3");
4236 if (trusted->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
4237 ok = check_pw_with_krb5(tctx, incoming_creds, trusted);
4238 torture_assert_int_equal(tctx, ok, expected_result,
4239 "check_pw_with_krb5");
4242 if (expected_result != true || next_password == NULL) {
4243 TALLOC_FREE(p2);
4244 return true;
4248 * netr_ServerPasswordSet2
4250 ok = encode_pw_buffer(samr_crypt_password.data,
4251 next_password, STR_UNICODE);
4252 torture_assert(tctx, ok, "encode_pw_buffer");
4254 if (next_version != 0) {
4255 struct NL_PASSWORD_VERSION version;
4256 uint32_t len = IVAL(samr_crypt_password.data, 512);
4257 uint32_t ofs = 512 - len;
4258 uint8_t *ptr;
4260 ofs -= 12;
4262 version.ReservedField = 0;
4263 version.PasswordVersionNumber = next_version;
4264 version.PasswordVersionPresent =
4265 NETLOGON_PASSWORD_VERSION_NUMBER_PRESENT;
4267 ptr = samr_crypt_password.data + ofs;
4268 SIVAL(ptr, 0, version.ReservedField);
4269 SIVAL(ptr, 4, version.PasswordVersionNumber);
4270 SIVAL(ptr, 8, version.PasswordVersionPresent);
4273 netlogon_creds_client_authenticator(creds, &req_auth);
4274 ZERO_STRUCT(rep_auth);
4276 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
4277 netlogon_creds_aes_encrypt(creds,
4278 samr_crypt_password.data,
4279 516);
4280 } else {
4281 netlogon_creds_arcfour_crypt(creds,
4282 samr_crypt_password.data,
4283 516);
4286 memcpy(netr_crypt_password.data,
4287 samr_crypt_password.data, 512);
4288 netr_crypt_password.length = IVAL(samr_crypt_password.data, 512);
4291 s.in.server_name = server_name;
4292 s.in.account_name = cli_credentials_get_username(incoming_creds);
4293 s.in.secure_channel_type = cli_credentials_get_secure_channel_type(incoming_creds);
4294 s.in.computer_name = cli_credentials_get_workstation(incoming_creds);
4295 s.in.credential = &req_auth;
4296 s.in.new_password = &netr_crypt_password;
4297 s.out.return_authenticator = &rep_auth;
4298 status = dcerpc_netr_ServerPasswordSet2_r(p2->binding_handle, tctx, &s);
4299 torture_assert_ntstatus_ok(tctx, status, "failed to set password");
4301 ok = netlogon_creds_client_check(creds, &rep_auth.cred);
4302 torture_assert(tctx, ok, "netlogon_creds_client_check");
4304 cli_credentials_set_kvno(incoming_creds, next_version);
4305 cli_credentials_set_password(incoming_creds, next_password, CRED_SPECIFIED);
4306 cli_credentials_set_old_password(incoming_creds, current_password, CRED_SPECIFIED);
4308 TALLOC_FREE(p2);
4309 status = dcerpc_pipe_connect_b(tctx, &p2, b2,
4310 &ndr_table_netlogon,
4311 cli_credentials_init_anon(tctx),
4312 tctx->ev, tctx->lp_ctx);
4313 torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b");
4315 ok = check_pw_with_ServerAuthenticate3(p2, tctx,
4316 NETLOGON_NEG_AUTH2_ADS_FLAGS,
4317 server_name,
4318 incoming_creds, &creds);
4319 torture_assert(tctx, ok, "check_pw_with_ServerAuthenticate3 with changed password");
4321 if (trusted->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
4322 ok = check_pw_with_krb5(tctx, incoming_creds, trusted);
4323 torture_assert(tctx, ok, "check_pw_with_krb5 with changed password");
4326 TALLOC_FREE(p2);
4327 return true;
4330 static bool test_CreateTrustedDomainEx_common(struct dcerpc_pipe *p,
4331 struct torture_context *tctx,
4332 struct policy_handle *handle,
4333 uint32_t num_trusts,
4334 bool ex2_call)
4336 NTSTATUS status;
4337 bool ret = true;
4338 struct lsa_QueryInfoPolicy2 p2;
4339 union lsa_PolicyInformation *our_info = NULL;
4340 struct lsa_CreateTrustedDomainEx r;
4341 struct lsa_CreateTrustedDomainEx2 r2;
4342 struct lsa_TrustDomainInfoInfoEx trustinfo;
4343 struct lsa_TrustDomainInfoAuthInfoInternal *authinfo_internal = NULL;
4344 struct lsa_TrustDomainInfoAuthInfo *authinfo = NULL;
4345 struct dom_sid **domsid;
4346 struct policy_handle *trustdom_handle;
4347 struct lsa_QueryTrustedDomainInfo q;
4348 union lsa_TrustedDomainInfo *info = NULL;
4349 DATA_BLOB session_key;
4350 int i;
4351 struct dcerpc_binding_handle *b = p->binding_handle;
4352 const char *id;
4353 const char *incoming_v00 = TRUSTPW "InV00";
4354 const char *incoming_v0 = TRUSTPW "InV0";
4355 const char *incoming_v1 = TRUSTPW "InV1";
4356 const char *incoming_v2 = TRUSTPW "InV2";
4357 const char *incoming_v40 = TRUSTPW "InV40";
4358 const char *outgoing_v00 = TRUSTPW "OutV00";
4359 const char *outgoing_v0 = TRUSTPW "OutV0";
4361 if (ex2_call) {
4362 torture_comment(tctx, "\nTesting CreateTrustedDomainEx2 for %d domains\n", num_trusts);
4363 id = "3";
4364 } else {
4365 torture_comment(tctx, "\nTesting CreateTrustedDomainEx for %d domains\n", num_trusts);
4366 id = "2";
4369 domsid = talloc_array(tctx, struct dom_sid *, num_trusts);
4370 trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts);
4372 status = dcerpc_fetch_session_key(p, &session_key);
4373 if (!NT_STATUS_IS_OK(status)) {
4374 torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
4375 return false;
4378 ZERO_STRUCT(p2);
4379 p2.in.handle = handle;
4380 p2.in.level = LSA_POLICY_INFO_DNS;
4381 p2.out.info = &our_info;
4383 torture_assert_ntstatus_ok(tctx,
4384 dcerpc_lsa_QueryInfoPolicy2_r(b, tctx, &p2),
4385 "lsa_QueryInfoPolicy2 failed");
4386 torture_assert_ntstatus_ok(tctx, p2.out.result,
4387 "lsa_QueryInfoPolicy2 failed");
4388 torture_assert(tctx, our_info != NULL, "lsa_QueryInfoPolicy2 our_info");
4390 for (i=0; i< num_trusts; i++) {
4391 char *trust_name = talloc_asprintf(tctx, "TORTURE%s%02d", id, i);
4392 char *trust_name_dns = talloc_asprintf(tctx, "torturedom%s%02d.samba._none_.example.com", id, i);
4393 char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-%s%02d", id, i);
4394 bool ok;
4396 domsid[i] = dom_sid_parse_talloc(tctx, trust_sid);
4398 trustinfo.sid = domsid[i];
4399 trustinfo.netbios_name.string = trust_name;
4400 trustinfo.domain_name.string = trust_name_dns;
4402 /* Create inbound, some outbound, and some
4403 * bi-directional trusts in a repeating pattern based
4404 * on i */
4406 /* 1 == inbound, 2 == outbound, 3 == both */
4407 trustinfo.trust_direction = (i % 3) + 1;
4409 /* Try different trust types too */
4411 /* 1 == downlevel (NT4), 2 == uplevel (ADS), 3 == MIT (kerberos but not AD) */
4412 trustinfo.trust_type = (((i / 3) + 1) % 3) + 1;
4414 trustinfo.trust_attributes = LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION;
4416 ok = gen_authinfo_internal(tctx, incoming_v00, incoming_v0,
4417 outgoing_v00, outgoing_v0,
4418 session_key, &authinfo_internal);
4419 if (!ok) {
4420 torture_comment(tctx, "gen_authinfo_internal failed");
4421 ret = false;
4424 ok = gen_authinfo(tctx, incoming_v00, incoming_v0,
4425 outgoing_v00, outgoing_v0,
4426 &authinfo);
4427 if (!ok) {
4428 torture_comment(tctx, "gen_authinfonfo failed");
4429 ret = false;
4432 if (ex2_call) {
4434 r2.in.policy_handle = handle;
4435 r2.in.info = &trustinfo;
4436 r2.in.auth_info_internal = authinfo_internal;
4437 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4438 r2.out.trustdom_handle = &trustdom_handle[i];
4440 torture_assert_ntstatus_ok(tctx,
4441 dcerpc_lsa_CreateTrustedDomainEx2_r(b, tctx, &r2),
4442 "CreateTrustedDomainEx2 failed");
4444 status = r2.out.result;
4445 } else {
4447 r.in.policy_handle = handle;
4448 r.in.info = &trustinfo;
4449 r.in.auth_info = authinfo;
4450 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4451 r.out.trustdom_handle = &trustdom_handle[i];
4453 torture_assert_ntstatus_ok(tctx,
4454 dcerpc_lsa_CreateTrustedDomainEx_r(b, tctx, &r),
4455 "CreateTrustedDomainEx failed");
4457 status = r.out.result;
4460 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
4461 test_DeleteTrustedDomain(b, tctx, handle, trustinfo.netbios_name);
4462 if (ex2_call) {
4463 torture_assert_ntstatus_ok(tctx,
4464 dcerpc_lsa_CreateTrustedDomainEx2_r(b, tctx, &r2),
4465 "CreateTrustedDomainEx2 failed");
4466 status = r2.out.result;
4467 } else {
4468 torture_assert_ntstatus_ok(tctx,
4469 dcerpc_lsa_CreateTrustedDomainEx_r(b, tctx, &r),
4470 "CreateTrustedDomainEx2 failed");
4471 status = r.out.result;
4474 if (!NT_STATUS_IS_OK(status)) {
4475 torture_comment(tctx, "CreateTrustedDomainEx failed2 - %s\n", nt_errstr(status));
4476 ret = false;
4477 } else {
4478 /* For outbound and MIT trusts there is no trust account */
4479 if (trustinfo.trust_direction != 2 &&
4480 trustinfo.trust_type != 3) {
4482 if (torture_setting_bool(tctx, "samba3", false)) {
4483 torture_comment(tctx, "skipping trusted domain auth tests against samba3\n");
4484 } else if (ex2_call == false &&
4485 torture_setting_bool(tctx, "samba4", false)) {
4486 torture_comment(tctx, "skipping CreateTrustedDomainEx trusted domain auth tests against samba4\n");
4488 } else {
4489 ok = check_dom_trust_pw(p, tctx,
4490 our_info->dns.name.string,
4491 our_info->dns.dns_domain.string,
4492 SEC_CHAN_DOMAIN,
4493 &trustinfo,
4494 NULL,
4495 "x" TRUSTPW "x", 0,
4496 NULL, 0,
4497 false);
4498 if (!ok) {
4499 torture_comment(tctx, "Password check passed unexpectedly\n");
4500 ret = false;
4502 ok = check_dom_trust_pw(p, tctx,
4503 our_info->dns.name.string,
4504 our_info->dns.dns_domain.string,
4505 SEC_CHAN_DOMAIN,
4506 &trustinfo,
4507 incoming_v00,
4508 incoming_v0, 0,
4509 incoming_v1, 1,
4510 true);
4511 if (!ok) {
4512 torture_comment(tctx, "Password check failed (SEC_CHAN_DOMAIN)\n");
4513 ret = false;
4515 ok = check_dom_trust_pw(p, tctx,
4516 our_info->dns.name.string,
4517 our_info->dns.dns_domain.string,
4518 SEC_CHAN_DNS_DOMAIN,
4519 &trustinfo,
4520 incoming_v0,
4521 incoming_v1, 1,
4522 incoming_v2, 2,
4523 true);
4524 if (!ok) {
4525 torture_comment(tctx, "Password check failed v2 (SEC_CHAN_DNS_DOMAIN)\n");
4526 ret = false;
4528 ok = check_dom_trust_pw(p, tctx,
4529 our_info->dns.name.string,
4530 our_info->dns.dns_domain.string,
4531 SEC_CHAN_DNS_DOMAIN,
4532 &trustinfo,
4533 incoming_v1,
4534 incoming_v2, 2,
4535 incoming_v40, 40,
4536 true);
4537 if (!ok) {
4538 torture_comment(tctx, "Password check failed v4 (SEC_CHAN_DNS_DOMAIN)\n");
4539 ret = false;
4544 q.in.trustdom_handle = &trustdom_handle[i];
4545 q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
4546 q.out.info = &info;
4547 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
4548 "QueryTrustedDomainInfo failed");
4549 if (!NT_STATUS_IS_OK(q.out.result)) {
4550 torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(q.out.result));
4551 ret = false;
4552 } else if (!q.out.info) {
4553 torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
4554 ret = false;
4555 } else {
4556 if (strcmp(info->info_ex.domain_name.string, trustinfo.domain_name.string) != 0) {
4557 torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent long name: %s != %s\n",
4558 info->info_ex.domain_name.string, trustinfo.domain_name.string);
4559 ret = false;
4561 if (strcmp(info->info_ex.netbios_name.string, trustinfo.netbios_name.string) != 0) {
4562 torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
4563 info->info_ex.netbios_name.string, trustinfo.netbios_name.string);
4564 ret = false;
4566 if (info->info_ex.trust_type != trustinfo.trust_type) {
4567 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
4568 trust_name, info->info_ex.trust_type, trustinfo.trust_type);
4569 ret = false;
4571 if (info->info_ex.trust_attributes != LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION) {
4572 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
4573 trust_name, info->info_ex.trust_attributes, LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION);
4574 ret = false;
4576 if (info->info_ex.trust_direction != trustinfo.trust_direction) {
4577 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
4578 trust_name, info->info_ex.trust_direction, trustinfo.trust_direction);
4579 ret = false;
4585 /* now that we have some domains to look over, we can test the enum calls */
4586 if (!test_EnumTrustDom(b, tctx, handle)) {
4587 torture_comment(tctx, "test_EnumTrustDom failed\n");
4588 ret = false;
4591 if (!test_EnumTrustDomEx(b, tctx, handle)) {
4592 torture_comment(tctx, "test_EnumTrustDomEx failed\n");
4593 ret = false;
4596 for (i=0; i<num_trusts; i++) {
4597 if (!test_DeleteTrustedDomainBySid(b, tctx, handle, domsid[i])) {
4598 torture_comment(tctx, "test_DeleteTrustedDomainBySid failed\n");
4599 ret = false;
4603 return ret;
4606 static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
4607 struct torture_context *tctx,
4608 struct policy_handle *handle,
4609 uint32_t num_trusts)
4611 return test_CreateTrustedDomainEx_common(p, tctx, handle, num_trusts, true);
4614 static bool test_CreateTrustedDomainEx(struct dcerpc_pipe *p,
4615 struct torture_context *tctx,
4616 struct policy_handle *handle,
4617 uint32_t num_trusts)
4619 return test_CreateTrustedDomainEx_common(p, tctx, handle, num_trusts, false);
4622 static bool test_QueryDomainInfoPolicy(struct dcerpc_binding_handle *b,
4623 struct torture_context *tctx,
4624 struct policy_handle *handle)
4626 struct lsa_QueryDomainInformationPolicy r;
4627 union lsa_DomainInformationPolicy *info = NULL;
4628 int i;
4629 bool ret = true;
4631 if (torture_setting_bool(tctx, "samba3", false)) {
4632 torture_skip(tctx, "skipping QueryDomainInformationPolicy test\n");
4635 torture_comment(tctx, "\nTesting QueryDomainInformationPolicy\n");
4637 for (i=2;i<4;i++) {
4638 r.in.handle = handle;
4639 r.in.level = i;
4640 r.out.info = &info;
4642 torture_comment(tctx, "\nTrying QueryDomainInformationPolicy level %d\n", i);
4644 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryDomainInformationPolicy_r(b, tctx, &r),
4645 "QueryDomainInformationPolicy failed");
4647 /* If the server does not support EFS, then this is the correct return */
4648 if (i == LSA_DOMAIN_INFO_POLICY_EFS && NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4649 continue;
4650 } else if (!NT_STATUS_IS_OK(r.out.result)) {
4651 torture_comment(tctx, "QueryDomainInformationPolicy failed - %s\n", nt_errstr(r.out.result));
4652 ret = false;
4653 continue;
4657 return ret;
4661 static bool test_QueryInfoPolicyCalls( bool version2,
4662 struct dcerpc_binding_handle *b,
4663 struct torture_context *tctx,
4664 struct policy_handle *handle)
4666 struct lsa_QueryInfoPolicy r;
4667 union lsa_PolicyInformation *info = NULL;
4668 int i;
4669 bool ret = true;
4670 const char *call = talloc_asprintf(tctx, "QueryInfoPolicy%s", version2 ? "2":"");
4672 torture_comment(tctx, "\nTesting %s\n", call);
4674 if (version2 && torture_setting_bool(tctx, "samba3", false)) {
4675 torture_skip(tctx, "skipping QueryInfoPolicy2 tests\n");
4678 for (i=1;i<=14;i++) {
4679 r.in.handle = handle;
4680 r.in.level = i;
4681 r.out.info = &info;
4683 torture_comment(tctx, "\nTrying %s level %d\n", call, i);
4685 if (version2)
4686 /* We can perform the cast, because both types are
4687 structurally equal */
4688 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy2_r(b, tctx,
4689 (struct lsa_QueryInfoPolicy2*) &r),
4690 "QueryInfoPolicy2 failed");
4691 else
4692 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy_r(b, tctx, &r),
4693 "QueryInfoPolicy2 failed");
4695 switch (i) {
4696 case LSA_POLICY_INFO_MOD:
4697 case LSA_POLICY_INFO_AUDIT_FULL_SET:
4698 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
4699 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
4700 torture_comment(tctx, "Server should have failed level %u: %s\n", i, nt_errstr(r.out.result));
4701 ret = false;
4703 break;
4704 case LSA_POLICY_INFO_DOMAIN:
4705 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
4706 case LSA_POLICY_INFO_REPLICA:
4707 case LSA_POLICY_INFO_QUOTA:
4708 case LSA_POLICY_INFO_ROLE:
4709 case LSA_POLICY_INFO_AUDIT_LOG:
4710 case LSA_POLICY_INFO_AUDIT_EVENTS:
4711 case LSA_POLICY_INFO_PD:
4712 if (!NT_STATUS_IS_OK(r.out.result)) {
4713 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4714 ret = false;
4716 break;
4717 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
4718 case LSA_POLICY_INFO_DNS_INT:
4719 case LSA_POLICY_INFO_DNS:
4720 if (torture_setting_bool(tctx, "samba3", false)) {
4721 /* Other levels not implemented yet */
4722 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
4723 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4724 ret = false;
4726 } else if (!NT_STATUS_IS_OK(r.out.result)) {
4727 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4728 ret = false;
4730 break;
4731 default:
4732 if (torture_setting_bool(tctx, "samba4", false)) {
4733 /* Other levels not implemented yet */
4734 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
4735 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4736 ret = false;
4738 } else if (!NT_STATUS_IS_OK(r.out.result)) {
4739 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4740 ret = false;
4742 break;
4745 if (NT_STATUS_IS_OK(r.out.result) && (i == LSA_POLICY_INFO_DNS
4746 || i == LSA_POLICY_INFO_DNS_INT)) {
4747 /* Let's look up some of these names */
4749 struct lsa_TransNameArray tnames;
4750 tnames.count = 14;
4751 tnames.names = talloc_zero_array(tctx, struct lsa_TranslatedName, tnames.count);
4752 tnames.names[0].name.string = info->dns.name.string;
4753 tnames.names[0].sid_type = SID_NAME_DOMAIN;
4754 tnames.names[1].name.string = info->dns.dns_domain.string;
4755 tnames.names[1].sid_type = SID_NAME_DOMAIN;
4756 tnames.names[2].name.string = talloc_asprintf(tctx, "%s\\", info->dns.name.string);
4757 tnames.names[2].sid_type = SID_NAME_DOMAIN;
4758 tnames.names[3].name.string = talloc_asprintf(tctx, "%s\\", info->dns.dns_domain.string);
4759 tnames.names[3].sid_type = SID_NAME_DOMAIN;
4760 tnames.names[4].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.name.string);
4761 tnames.names[4].sid_type = SID_NAME_USER;
4762 tnames.names[5].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.name.string);
4763 tnames.names[5].sid_type = SID_NAME_USER;
4764 tnames.names[6].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.dns_domain.string);
4765 tnames.names[6].sid_type = SID_NAME_USER;
4766 tnames.names[7].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.dns_domain.string);
4767 tnames.names[7].sid_type = SID_NAME_USER;
4768 tnames.names[8].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.name.string);
4769 tnames.names[8].sid_type = SID_NAME_USER;
4770 tnames.names[9].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.dns_domain.string);
4771 tnames.names[9].sid_type = SID_NAME_USER;
4772 tnames.names[10].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.name.string);
4773 tnames.names[10].sid_type = SID_NAME_USER;
4774 tnames.names[11].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.dns_domain.string);
4775 tnames.names[11].sid_type = SID_NAME_USER;
4776 tnames.names[12].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.name.string);
4777 tnames.names[12].sid_type = SID_NAME_USER;
4778 tnames.names[13].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.dns_domain.string);
4779 tnames.names[13].sid_type = SID_NAME_USER;
4780 ret &= test_LookupNames(b, tctx, handle, &tnames);
4785 return ret;
4788 static bool test_QueryInfoPolicy(struct dcerpc_binding_handle *b,
4789 struct torture_context *tctx,
4790 struct policy_handle *handle)
4792 return test_QueryInfoPolicyCalls(false, b, tctx, handle);
4795 static bool test_QueryInfoPolicy2(struct dcerpc_binding_handle *b,
4796 struct torture_context *tctx,
4797 struct policy_handle *handle)
4799 return test_QueryInfoPolicyCalls(true, b, tctx, handle);
4802 static bool test_GetUserName(struct dcerpc_binding_handle *b,
4803 struct torture_context *tctx)
4805 struct lsa_GetUserName r;
4806 bool ret = true;
4807 struct lsa_String *authority_name_p = NULL;
4808 struct lsa_String *account_name_p = NULL;
4810 torture_comment(tctx, "\nTesting GetUserName\n");
4812 r.in.system_name = "\\";
4813 r.in.account_name = &account_name_p;
4814 r.in.authority_name = NULL;
4815 r.out.account_name = &account_name_p;
4817 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
4818 "GetUserName failed");
4820 if (!NT_STATUS_IS_OK(r.out.result)) {
4821 torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(r.out.result));
4822 ret = false;
4825 account_name_p = NULL;
4826 r.in.account_name = &account_name_p;
4827 r.in.authority_name = &authority_name_p;
4828 r.out.account_name = &account_name_p;
4830 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
4831 "GetUserName failed");
4833 if (!NT_STATUS_IS_OK(r.out.result)) {
4834 torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(r.out.result));
4835 ret = false;
4838 return ret;
4841 static bool test_GetUserName_fail(struct dcerpc_binding_handle *b,
4842 struct torture_context *tctx)
4844 struct lsa_GetUserName r;
4845 struct lsa_String *account_name_p = NULL;
4846 NTSTATUS status;
4848 torture_comment(tctx, "\nTesting GetUserName_fail\n");
4850 r.in.system_name = "\\";
4851 r.in.account_name = &account_name_p;
4852 r.in.authority_name = NULL;
4853 r.out.account_name = &account_name_p;
4855 status = dcerpc_lsa_GetUserName_r(b, tctx, &r);
4856 if (!NT_STATUS_IS_OK(status)) {
4857 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4858 torture_comment(tctx,
4859 "GetUserName correctly returned with "
4860 "status: %s\n",
4861 nt_errstr(status));
4862 return true;
4865 torture_assert_ntstatus_equal(tctx,
4866 status,
4867 NT_STATUS_ACCESS_DENIED,
4868 "GetUserName return value should "
4869 "be ACCESS_DENIED");
4870 return true;
4873 if (!NT_STATUS_IS_OK(r.out.result)) {
4874 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
4875 NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
4876 torture_comment(tctx,
4877 "GetUserName correctly returned with "
4878 "result: %s\n",
4879 nt_errstr(r.out.result));
4880 return true;
4884 torture_assert_ntstatus_equal(tctx,
4885 r.out.result,
4886 NT_STATUS_OK,
4887 "GetUserName return value should be "
4888 "ACCESS_DENIED");
4890 return false;
4893 bool test_lsa_Close(struct dcerpc_binding_handle *b,
4894 struct torture_context *tctx,
4895 struct policy_handle *handle)
4897 struct lsa_Close r;
4898 struct policy_handle handle2;
4900 torture_comment(tctx, "\nTesting Close\n");
4902 r.in.handle = handle;
4903 r.out.handle = &handle2;
4905 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &r),
4906 "Close failed");
4907 torture_assert_ntstatus_ok(tctx, r.out.result,
4908 "Close failed");
4910 torture_assert_ntstatus_equal(tctx, dcerpc_lsa_Close_r(b, tctx, &r),
4911 NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "Close should failed");
4913 torture_comment(tctx, "\n");
4915 return true;
4918 bool torture_rpc_lsa(struct torture_context *tctx)
4920 NTSTATUS status;
4921 struct dcerpc_pipe *p;
4922 bool ret = true;
4923 struct policy_handle *handle = NULL;
4924 struct test_join *join = NULL;
4925 struct cli_credentials *machine_creds;
4926 struct dcerpc_binding_handle *b;
4927 enum dcerpc_transport_t transport;
4929 status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
4930 if (!NT_STATUS_IS_OK(status)) {
4931 return false;
4933 b = p->binding_handle;
4934 transport = dcerpc_binding_get_transport(p->binding);
4936 /* Test lsaLookupSids3 and lsaLookupNames4 over tcpip */
4937 if (transport == NCACN_IP_TCP) {
4938 if (!test_OpenPolicy_fail(b, tctx)) {
4939 ret = false;
4942 if (!test_OpenPolicy2_fail(b, tctx)) {
4943 ret = false;
4946 if (!test_many_LookupSids(p, tctx, handle)) {
4947 ret = false;
4950 return ret;
4953 if (!test_OpenPolicy(b, tctx)) {
4954 ret = false;
4957 if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
4958 ret = false;
4961 if (handle) {
4962 join = torture_join_domain(tctx, TEST_MACHINENAME, ACB_WSTRUST, &machine_creds);
4963 if (!join) {
4964 ret = false;
4967 if (!test_LookupSids_async(b, tctx, handle)) {
4968 ret = false;
4971 if (!test_QueryDomainInfoPolicy(b, tctx, handle)) {
4972 ret = false;
4975 if (!test_CreateSecret(p, tctx, handle)) {
4976 ret = false;
4979 if (!test_QueryInfoPolicy(b, tctx, handle)) {
4980 ret = false;
4983 if (!test_QueryInfoPolicy2(b, tctx, handle)) {
4984 ret = false;
4987 if (!test_Delete(b, tctx, handle)) {
4988 ret = false;
4991 if (!test_many_LookupSids(p, tctx, handle)) {
4992 ret = false;
4995 if (!test_lsa_Close(b, tctx, handle)) {
4996 ret = false;
4999 torture_leave_domain(tctx, join);
5001 } else {
5002 if (!test_many_LookupSids(p, tctx, handle)) {
5003 ret = false;
5007 if (!test_GetUserName(b, tctx)) {
5008 ret = false;
5011 return ret;
5014 bool torture_rpc_lsa_get_user(struct torture_context *tctx)
5016 NTSTATUS status;
5017 struct dcerpc_pipe *p;
5018 bool ret = true;
5019 struct dcerpc_binding_handle *b;
5020 enum dcerpc_transport_t transport;
5022 status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
5023 if (!NT_STATUS_IS_OK(status)) {
5024 return false;
5026 b = p->binding_handle;
5027 transport = dcerpc_binding_get_transport(p->binding);
5029 if (transport == NCACN_IP_TCP) {
5030 if (!test_GetUserName_fail(b, tctx)) {
5031 ret = false;
5033 return ret;
5036 if (!test_GetUserName(b, tctx)) {
5037 ret = false;
5040 return ret;
5043 static bool testcase_LookupNames(struct torture_context *tctx,
5044 struct dcerpc_pipe *p)
5046 bool ret = true;
5047 struct policy_handle *handle;
5048 struct lsa_TransNameArray tnames;
5049 struct lsa_TransNameArray2 tnames2;
5050 struct dcerpc_binding_handle *b = p->binding_handle;
5051 enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
5053 if (transport != NCACN_NP && transport != NCALRPC) {
5054 torture_comment(tctx, "testcase_LookupNames is only available "
5055 "over NCACN_NP or NCALRPC");
5056 return true;
5059 if (!test_OpenPolicy(b, tctx)) {
5060 ret = false;
5063 if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5064 ret = false;
5067 if (!handle) {
5068 ret = false;
5071 tnames.count = 1;
5072 tnames.names = talloc_array(tctx, struct lsa_TranslatedName, tnames.count);
5073 ZERO_STRUCT(tnames.names[0]);
5074 tnames.names[0].name.string = "BUILTIN";
5075 tnames.names[0].sid_type = SID_NAME_DOMAIN;
5077 if (!test_LookupNames(b, tctx, handle, &tnames)) {
5078 ret = false;
5081 tnames2.count = 1;
5082 tnames2.names = talloc_array(tctx, struct lsa_TranslatedName2, tnames2.count);
5083 ZERO_STRUCT(tnames2.names[0]);
5084 tnames2.names[0].name.string = "BUILTIN";
5085 tnames2.names[0].sid_type = SID_NAME_DOMAIN;
5087 if (!test_LookupNames2(b, tctx, handle, &tnames2, true)) {
5088 ret = false;
5091 if (!test_LookupNames3(b, tctx, handle, &tnames2, true)) {
5092 ret = false;
5095 if (!test_LookupNames_wellknown(b, tctx, handle)) {
5096 ret = false;
5099 if (!test_LookupNames_NULL(b, tctx, handle)) {
5100 ret = false;
5103 if (!test_LookupNames_bogus(b, tctx, handle)) {
5104 ret = false;
5107 if (!test_lsa_Close(b, tctx, handle)) {
5108 ret = false;
5111 return ret;
5114 struct torture_suite *torture_rpc_lsa_lookup_names(TALLOC_CTX *mem_ctx)
5116 struct torture_suite *suite;
5117 struct torture_rpc_tcase *tcase;
5119 suite = torture_suite_create(mem_ctx, "lsa.lookupnames");
5121 tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5122 &ndr_table_lsarpc);
5123 torture_rpc_tcase_add_test(tcase, "LookupNames",
5124 testcase_LookupNames);
5126 return suite;
5129 struct lsa_trustdom_state {
5130 uint32_t num_trusts;
5133 static bool testcase_TrustedDomains(struct torture_context *tctx,
5134 struct dcerpc_pipe *p,
5135 void *data)
5137 bool ret = true;
5138 struct policy_handle *handle;
5139 struct lsa_trustdom_state *state =
5140 talloc_get_type_abort(data, struct lsa_trustdom_state);
5141 struct dcerpc_binding_handle *b = p->binding_handle;
5142 enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
5144 if (transport != NCACN_NP && transport != NCALRPC) {
5145 torture_comment(tctx, "testcase_TrustedDomains is only available "
5146 "over NCACN_NP or NCALRPC");
5147 return true;
5150 torture_comment(tctx, "Testing %d domains\n", state->num_trusts);
5152 if (!test_OpenPolicy(b, tctx)) {
5153 ret = false;
5156 if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5157 ret = false;
5160 if (!handle) {
5161 ret = false;
5164 if (!test_CreateTrustedDomain(b, tctx, handle, state->num_trusts)) {
5165 ret = false;
5168 if (!test_CreateTrustedDomainEx(p, tctx, handle, state->num_trusts)) {
5169 ret = false;
5172 if (!test_CreateTrustedDomainEx2(p, tctx, handle, state->num_trusts)) {
5173 ret = false;
5176 if (!test_lsa_Close(b, tctx, handle)) {
5177 ret = false;
5180 return ret;
5183 struct torture_suite *torture_rpc_lsa_trusted_domains(TALLOC_CTX *mem_ctx)
5185 struct torture_suite *suite;
5186 struct torture_rpc_tcase *tcase;
5187 struct lsa_trustdom_state *state;
5189 state = talloc(mem_ctx, struct lsa_trustdom_state);
5191 state->num_trusts = 12;
5193 suite = torture_suite_create(mem_ctx, "lsa.trusted.domains");
5195 tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5196 &ndr_table_lsarpc);
5197 torture_rpc_tcase_add_test_ex(tcase, "TrustedDomains",
5198 testcase_TrustedDomains,
5199 state);
5201 return suite;
5204 static bool testcase_Privileges(struct torture_context *tctx,
5205 struct dcerpc_pipe *p)
5207 struct policy_handle *handle;
5208 struct dcerpc_binding_handle *b = p->binding_handle;
5209 enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
5211 if (transport != NCACN_NP && transport != NCALRPC) {
5212 torture_skip(tctx, "testcase_Privileges is only available "
5213 "over NCACN_NP or NCALRPC");
5216 if (!test_OpenPolicy(b, tctx)) {
5217 return false;
5220 if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5221 return false;
5224 if (!handle) {
5225 return false;
5228 if (!test_CreateAccount(b, tctx, handle)) {
5229 return false;
5232 if (!test_EnumAccounts(b, tctx, handle)) {
5233 return false;
5236 if (!test_EnumPrivs(b, tctx, handle)) {
5237 return false;
5240 if (!test_lsa_Close(b, tctx, handle)) {
5241 return false;
5244 return true;
5248 struct torture_suite *torture_rpc_lsa_privileges(TALLOC_CTX *mem_ctx)
5250 struct torture_suite *suite;
5251 struct torture_rpc_tcase *tcase;
5253 suite = torture_suite_create(mem_ctx, "lsa.privileges");
5255 tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5256 &ndr_table_lsarpc);
5257 torture_rpc_tcase_add_test(tcase, "Privileges",
5258 testcase_Privileges);
5260 return suite;