s4-torture: use smb_krb5_principal_get_type in lsa forest krb5 tests.
[Samba.git] / source4 / torture / rpc / lsa.c
blobe708e90a4de15bb7b9aff664940425ba7b5042dd
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 KRB_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 free_KRB_ERROR(&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 free_KRB_ERROR(&ctx->error);
3160 talloc_unlink(ctx, ctx->smb_krb5_context);
3161 ctx->smb_krb5_context = NULL;
3162 return 0;
3165 static bool check_pw_with_krb5(struct torture_context *tctx,
3166 struct cli_credentials *credentials,
3167 const struct lsa_TrustDomainInfoInfoEx *trusted)
3169 const char *trusted_dns_name = trusted->domain_name.string;
3170 const char *trusted_netbios_name = trusted->netbios_name.string;
3171 char *trusted_realm_name = NULL;
3172 krb5_principal principal = NULL;
3173 enum credentials_obtained obtained;
3174 const char *error_string = NULL;
3175 const char *workstation = cli_credentials_get_workstation(credentials);
3176 const char *password = cli_credentials_get_password(credentials);
3177 const struct samr_Password *nthash = NULL;
3178 const struct samr_Password *old_nthash = NULL;
3179 const char *old_password = cli_credentials_get_old_password(credentials);
3180 int kvno = cli_credentials_get_kvno(credentials);
3181 int expected_kvno = 0;
3182 krb5uint32 t_kvno = 0;
3183 const char *host = torture_setting_string(tctx, "host", NULL);
3184 krb5_error_code k5ret;
3185 krb5_boolean k5ok;
3186 int type;
3187 bool ok;
3188 struct check_pw_with_krb5_ctx *ctx = NULL;
3189 char *assertion_message = NULL;
3190 const char *realm = NULL;
3191 char *upn_realm_string = NULL;
3192 char *upn_dns_string = NULL;
3193 char *upn_netbios_string = NULL;
3194 char *krbtgt_cc_name = NULL;
3195 char *krbtgt_trust_realm_string = NULL;
3196 char *krbtgt_trust_dns_string = NULL;
3197 char *krbtgt_trust_netbios_string = NULL;
3198 char *cifs_trust_dns_string = NULL;
3199 char *cifs_trust_netbios_string = NULL;
3200 char *drs_trust_dns_string = NULL;
3201 char *drs_trust_netbios_string = NULL;
3202 char *four_trust_dns_string = NULL;
3204 ctx = talloc_zero(tctx, struct check_pw_with_krb5_ctx);
3205 torture_assert(tctx, ctx != NULL, "Failed to allocate");
3207 realm = cli_credentials_get_realm(credentials);
3208 trusted_realm_name = strupper_talloc(tctx, trusted_dns_name);
3210 nthash = cli_credentials_get_nt_hash(credentials, ctx);
3211 old_nthash = cli_credentials_get_old_nt_hash(credentials, ctx);
3213 k5ret = smb_krb5_init_context(ctx, tctx->lp_ctx, &ctx->smb_krb5_context);
3214 torture_assert_int_equal(tctx, k5ret, 0, "smb_krb5_init_context failed");
3216 ok = interpret_string_addr_internal(&ctx->server, host, AI_NUMERICHOST);
3217 torture_assert(tctx, ok, "Failed to parse target server");
3218 talloc_set_destructor(ctx, check_pw_with_krb5_ctx_destructor);
3220 set_sockaddr_port(ctx->server->ai_addr, 88);
3222 k5ret = krb5_set_send_to_kdc_func(ctx->smb_krb5_context->krb5_context,
3223 check_pw_with_krb5_send_and_recv_func,
3224 ctx);
3225 torture_assert_int_equal(tctx, k5ret, 0, "krb5_set_send_to_kdc_func failed");
3227 torture_assert_int_equal(tctx,
3228 krb5_get_init_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3229 &ctx->krb_options),
3230 0, "krb5_get_init_creds_opt_alloc failed");
3231 torture_assert_int_equal(tctx,
3232 krb5_get_init_creds_opt_set_pac_request(
3233 ctx->smb_krb5_context->krb5_context,
3234 ctx->krb_options, true),
3235 0, "krb5_get_init_creds_opt_set_pac_request failed");
3237 upn_realm_string = talloc_asprintf(ctx, "user@%s",
3238 trusted_realm_name);
3239 torture_assert_int_equal(tctx,
3240 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3241 &ctx->upn_realm,
3242 realm, upn_realm_string, NULL),
3243 0, "smb_krb5_make_principal failed");
3244 krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3245 ctx->upn_realm, KRB5_NT_ENTERPRISE_PRINCIPAL);
3247 upn_dns_string = talloc_asprintf(ctx, "user@%s",
3248 trusted_dns_name);
3249 torture_assert_int_equal(tctx,
3250 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3251 &ctx->upn_dns,
3252 realm, upn_dns_string, NULL),
3253 0, "smb_krb5_make_principal failed");
3254 krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3255 ctx->upn_dns, KRB5_NT_ENTERPRISE_PRINCIPAL);
3257 upn_netbios_string = talloc_asprintf(ctx, "user@%s",
3258 trusted_netbios_name);
3259 torture_assert_int_equal(tctx,
3260 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3261 &ctx->upn_netbios,
3262 realm, upn_netbios_string, NULL),
3263 0, "smb_krb5_make_principal failed");
3264 krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3265 ctx->upn_netbios, KRB5_NT_ENTERPRISE_PRINCIPAL);
3267 k5ret = principal_from_credentials(ctx, credentials, ctx->smb_krb5_context,
3268 &principal, &obtained, &error_string);
3269 torture_assert_int_equal(tctx, k5ret, 0, error_string);
3271 ZERO_STRUCT(ctx->counts);
3272 k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3273 &ctx->my_creds, ctx->upn_realm,
3274 "_none_", NULL, NULL, 0,
3275 NULL, ctx->krb_options);
3276 assertion_message = talloc_asprintf(ctx,
3277 "krb5_get_init_creds_password(%s, canon) for failed: "
3278 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3279 upn_realm_string,
3280 k5ret,
3281 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3282 k5ret, ctx),
3283 trusted->trust_direction,
3284 trusted->trust_type,
3285 trusted->trust_attributes,
3286 ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3287 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3288 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3289 torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3290 torture_assert_int_equal(tctx, ctx->error.error_code, 68, assertion_message);
3291 torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3292 torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3293 torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3294 torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3296 ZERO_STRUCT(ctx->counts);
3297 k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3298 &ctx->my_creds, ctx->upn_dns,
3299 "_none_", NULL, NULL, 0,
3300 NULL, ctx->krb_options);
3301 assertion_message = talloc_asprintf(ctx,
3302 "krb5_get_init_creds_password(%s, canon) for failed: "
3303 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3304 upn_dns_string,
3305 k5ret,
3306 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3307 k5ret, ctx),
3308 trusted->trust_direction,
3309 trusted->trust_type,
3310 trusted->trust_attributes,
3311 ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3312 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3313 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3314 torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3315 torture_assert_int_equal(tctx, ctx->error.error_code, 68, assertion_message);
3316 torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3317 torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3318 torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3319 torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3321 ZERO_STRUCT(ctx->counts);
3322 k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3323 &ctx->my_creds, ctx->upn_netbios,
3324 "_none_", NULL, NULL, 0,
3325 NULL, ctx->krb_options);
3326 assertion_message = talloc_asprintf(ctx,
3327 "krb5_get_init_creds_password(%s, canon) for failed: "
3328 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3329 upn_netbios_string,
3330 k5ret,
3331 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3332 k5ret, ctx),
3333 trusted->trust_direction,
3334 trusted->trust_type,
3335 trusted->trust_attributes,
3336 ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3337 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3338 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3339 torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3340 torture_assert_int_equal(tctx, ctx->error.error_code, 68, assertion_message);
3341 torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3342 torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3343 torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3344 torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3346 torture_comment(tctx, "password[%s] old_password[%s]\n",
3347 password, old_password);
3348 if (old_password != NULL) {
3349 k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3350 &ctx->my_creds, principal,
3351 old_password, NULL, NULL, 0,
3352 NULL, ctx->krb_options);
3353 torture_assert_int_equal(tctx, k5ret, KRB5KDC_ERR_PREAUTH_FAILED,
3354 "preauth should fail with old password");
3357 k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3358 &ctx->my_creds, principal,
3359 password, NULL, NULL, 0,
3360 NULL, ctx->krb_options);
3361 if (k5ret == KRB5KDC_ERR_PREAUTH_FAILED) {
3362 TALLOC_FREE(ctx);
3363 return false;
3366 assertion_message = talloc_asprintf(ctx,
3367 "krb5_get_init_creds_password for failed: %s",
3368 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3369 k5ret, ctx));
3370 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3372 torture_assert_int_equal(tctx,
3373 krb5_get_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3374 &ctx->opt_canon),
3375 0, "krb5_get_creds_opt_alloc");
3377 krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3378 ctx->opt_canon,
3379 KRB5_GC_CANONICALIZE);
3381 krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3382 ctx->opt_canon,
3383 KRB5_GC_NO_STORE);
3385 torture_assert_int_equal(tctx,
3386 krb5_get_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3387 &ctx->opt_nocanon),
3388 0, "krb5_get_creds_opt_alloc");
3390 krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3391 ctx->opt_nocanon,
3392 KRB5_GC_NO_STORE);
3394 krbtgt_cc_name = talloc_asprintf(ctx, "MEMORY:%p.krbtgt", ctx->smb_krb5_context);
3395 torture_assert_int_equal(tctx,
3396 krb5_cc_resolve(ctx->smb_krb5_context->krb5_context,
3397 krbtgt_cc_name,
3398 &ctx->krbtgt_ccache),
3399 0, "krb5_cc_resolve failed");
3401 torture_assert_int_equal(tctx,
3402 krb5_cc_initialize(ctx->smb_krb5_context->krb5_context,
3403 ctx->krbtgt_ccache,
3404 ctx->my_creds.client),
3405 0, "krb5_cc_initialize failed");
3407 torture_assert_int_equal(tctx,
3408 krb5_cc_store_cred(ctx->smb_krb5_context->krb5_context,
3409 ctx->krbtgt_ccache,
3410 &ctx->my_creds),
3411 0, "krb5_cc_store_cred failed");
3413 krbtgt_trust_realm_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3414 trusted_realm_name, realm);
3415 torture_assert_int_equal(tctx,
3416 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3417 &ctx->krbtgt_trust_realm,
3418 realm, "krbtgt",
3419 trusted_realm_name, NULL),
3420 0, "smb_krb5_make_principal failed");
3422 krbtgt_trust_dns_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3423 trusted_dns_name, realm);
3424 torture_assert_int_equal(tctx,
3425 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3426 &ctx->krbtgt_trust_dns,
3427 realm, "krbtgt",
3428 trusted_dns_name, NULL),
3429 0, "smb_krb5_make_principal failed");
3431 krbtgt_trust_netbios_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3432 trusted_netbios_name, realm);
3433 torture_assert_int_equal(tctx,
3434 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3435 &ctx->krbtgt_trust_netbios,
3436 realm, "krbtgt",
3437 trusted_netbios_name, NULL),
3438 0, "smb_krb5_make_principal failed");
3440 /* Confirm if we can do a TGS for krbtgt/trusted_realm */
3441 ZERO_STRUCT(ctx->counts);
3442 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3443 ctx->opt_nocanon,
3444 ctx->krbtgt_ccache,
3445 ctx->krbtgt_trust_realm,
3446 &ctx->krbtgt_trust_realm_creds);
3447 assertion_message = talloc_asprintf(ctx,
3448 "krb5_get_creds(%s, canon) for failed: "
3449 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3450 krbtgt_trust_realm_string,
3451 k5ret,
3452 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3453 k5ret, ctx),
3454 trusted->trust_direction,
3455 trusted->trust_type,
3456 trusted->trust_attributes,
3457 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3458 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3459 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3460 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3462 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3463 ctx->krbtgt_trust_realm_creds->server,
3464 ctx->krbtgt_trust_realm);
3465 torture_assert(tctx, k5ok, assertion_message);
3466 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3467 ctx->krbtgt_trust_realm_creds->server);
3468 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3470 /* Confirm if we have no referral ticket in the cache */
3471 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3472 &ctx->krbtgt_referral_creds);
3473 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3474 ctx->krbtgt_ccache,
3476 ctx->krbtgt_trust_realm_creds,
3477 &ctx->krbtgt_referral_creds);
3478 assertion_message = talloc_asprintf(ctx,
3479 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3480 krbtgt_trust_realm_string,
3481 k5ret,
3482 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3483 k5ret, ctx));
3484 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3486 /* Confirm if we can do a TGS for krbtgt/trusted_dns with CANON */
3487 ZERO_STRUCT(ctx->counts);
3488 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3489 ctx->opt_canon,
3490 ctx->krbtgt_ccache,
3491 ctx->krbtgt_trust_dns,
3492 &ctx->krbtgt_trust_dns_creds);
3493 assertion_message = talloc_asprintf(ctx,
3494 "krb5_get_creds(%s, canon) for failed: "
3495 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3496 krbtgt_trust_dns_string,
3497 k5ret,
3498 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3499 k5ret, ctx),
3500 trusted->trust_direction,
3501 trusted->trust_type,
3502 trusted->trust_attributes,
3503 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3504 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3505 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3506 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3508 /* Confirm if we have the referral ticket in the cache */
3509 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3510 &ctx->krbtgt_referral_creds);
3511 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3512 ctx->krbtgt_ccache,
3514 ctx->krbtgt_trust_realm_creds,
3515 &ctx->krbtgt_referral_creds);
3516 assertion_message = talloc_asprintf(ctx,
3517 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3518 krbtgt_trust_realm_string,
3519 k5ret,
3520 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3521 k5ret, ctx));
3522 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3524 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3525 ctx->krbtgt_referral_creds.server,
3526 ctx->krbtgt_trust_realm);
3527 torture_assert(tctx, k5ok, assertion_message);
3528 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3529 ctx->krbtgt_referral_creds.server);
3530 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3531 k5ret = decode_Ticket(ctx->krbtgt_referral_creds.ticket.data,
3532 ctx->krbtgt_referral_creds.ticket.length,
3533 &ctx->krbtgt_referral_ticket, NULL);
3534 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3535 if (kvno > 0) {
3536 expected_kvno = kvno - 1;
3538 if (ctx->krbtgt_referral_ticket.enc_part.kvno != NULL) {
3539 t_kvno = *ctx->krbtgt_referral_ticket.enc_part.kvno;
3540 assertion_message = talloc_asprintf(ctx,
3541 "krbtgt_referral_ticket(%s) kvno(%u) expected(%u) current(%u)",
3542 krbtgt_trust_realm_string,
3543 (unsigned)t_kvno, (unsigned)expected_kvno,(unsigned)kvno);
3544 torture_comment(tctx, "%s\n", assertion_message);
3545 torture_assert_int_not_equal(tctx, t_kvno, 0, assertion_message);
3546 } else {
3547 assertion_message = talloc_asprintf(ctx,
3548 "krbtgt_referral_ticket(%s) kvno(NULL) exptected(%u) current(%u)",
3549 krbtgt_trust_realm_string,
3550 (unsigned)expected_kvno,(unsigned)kvno);
3551 torture_comment(tctx, "%s\n", assertion_message);
3553 torture_assert_int_equal(tctx, t_kvno, expected_kvno, assertion_message);
3555 if (old_nthash != NULL && expected_kvno != kvno) {
3556 torture_comment(tctx, "old_nthash: %s\n", assertion_message);
3557 k5ret = smb_krb5_keyblock_init_contents(ctx->smb_krb5_context->krb5_context,
3558 ENCTYPE_ARCFOUR_HMAC,
3559 old_nthash->hash,
3560 sizeof(old_nthash->hash),
3561 &ctx->krbtgt_referral_keyblock);
3562 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3563 } else {
3564 torture_comment(tctx, "nthash: %s\n", assertion_message);
3565 k5ret = smb_krb5_keyblock_init_contents(ctx->smb_krb5_context->krb5_context,
3566 ENCTYPE_ARCFOUR_HMAC,
3567 nthash->hash,
3568 sizeof(nthash->hash),
3569 &ctx->krbtgt_referral_keyblock);
3570 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3572 k5ret = krb5_decrypt_ticket(ctx->smb_krb5_context->krb5_context,
3573 &ctx->krbtgt_referral_ticket,
3574 &ctx->krbtgt_referral_keyblock,
3575 &ctx->krbtgt_referral_enc_part,
3577 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3579 /* Delete the referral ticket from the cache */
3580 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3581 ctx->krbtgt_ccache,
3583 &ctx->krbtgt_referral_creds);
3584 assertion_message = talloc_asprintf(ctx,
3585 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3586 krbtgt_trust_realm_string,
3587 k5ret,
3588 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3589 k5ret, ctx));
3590 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3592 /* Confirm if we can do a TGS for krbtgt/trusted_dns no CANON */
3593 ZERO_STRUCT(ctx->counts);
3594 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3595 ctx->opt_nocanon,
3596 ctx->krbtgt_ccache,
3597 ctx->krbtgt_trust_dns,
3598 &ctx->krbtgt_trust_dns_creds);
3599 assertion_message = talloc_asprintf(ctx,
3600 "krb5_get_creds(%s, nocanon) for failed: "
3601 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3602 krbtgt_trust_dns_string,
3603 k5ret,
3604 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3605 k5ret, ctx),
3606 trusted->trust_direction,
3607 trusted->trust_type,
3608 trusted->trust_attributes,
3609 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3610 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3611 torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
3612 torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
3614 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3615 ctx->krbtgt_trust_dns_creds->server,
3616 ctx->krbtgt_trust_realm);
3617 torture_assert(tctx, k5ok, assertion_message);
3618 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3619 ctx->krbtgt_trust_dns_creds->server);
3620 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3622 /* Confirm if we have the referral ticket in the cache */
3623 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3624 &ctx->krbtgt_referral_creds);
3625 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3626 ctx->krbtgt_ccache,
3628 ctx->krbtgt_trust_realm_creds,
3629 &ctx->krbtgt_referral_creds);
3630 assertion_message = talloc_asprintf(ctx,
3631 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3632 krbtgt_trust_realm_string,
3633 k5ret,
3634 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3635 k5ret, ctx));
3636 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3638 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3639 ctx->krbtgt_referral_creds.server,
3640 ctx->krbtgt_trust_realm);
3641 torture_assert(tctx, k5ok, assertion_message);
3642 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3643 ctx->krbtgt_referral_creds.server);
3644 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3646 /* Delete the referral ticket from the cache */
3647 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3648 ctx->krbtgt_ccache,
3650 &ctx->krbtgt_referral_creds);
3651 assertion_message = talloc_asprintf(ctx,
3652 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3653 krbtgt_trust_realm_string,
3654 k5ret,
3655 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3656 k5ret, ctx));
3657 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3659 /* Confirm if we can do a TGS for krbtgt/NETBIOS with CANON */
3660 ZERO_STRUCT(ctx->counts);
3661 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3662 ctx->opt_canon,
3663 ctx->krbtgt_ccache,
3664 ctx->krbtgt_trust_netbios,
3665 &ctx->krbtgt_trust_netbios_creds);
3666 assertion_message = talloc_asprintf(ctx,
3667 "krb5_get_creds(%s, canon) for failed: "
3668 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3669 krbtgt_trust_netbios_string,
3670 k5ret,
3671 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3672 k5ret, ctx),
3673 trusted->trust_direction,
3674 trusted->trust_type,
3675 trusted->trust_attributes,
3676 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3677 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3678 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3679 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3681 /* Confirm if we have the referral ticket in the cache */
3682 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3683 &ctx->krbtgt_referral_creds);
3684 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3685 ctx->krbtgt_ccache,
3687 ctx->krbtgt_trust_realm_creds,
3688 &ctx->krbtgt_referral_creds);
3689 assertion_message = talloc_asprintf(ctx,
3690 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3691 krbtgt_trust_netbios_string,
3692 k5ret,
3693 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3694 k5ret, ctx));
3695 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3697 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3698 ctx->krbtgt_referral_creds.server,
3699 ctx->krbtgt_trust_realm);
3700 torture_assert(tctx, k5ok, assertion_message);
3701 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3702 ctx->krbtgt_referral_creds.server);
3703 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3705 /* Delete the referral ticket from the cache */
3706 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3707 ctx->krbtgt_ccache,
3709 &ctx->krbtgt_referral_creds);
3710 assertion_message = talloc_asprintf(ctx,
3711 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3712 krbtgt_trust_realm_string,
3713 k5ret,
3714 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3715 k5ret, ctx));
3716 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3718 /* Confirm if we can do a TGS for krbtgt/NETBIOS no CANON */
3719 ZERO_STRUCT(ctx->counts);
3720 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3721 ctx->opt_nocanon,
3722 ctx->krbtgt_ccache,
3723 ctx->krbtgt_trust_netbios,
3724 &ctx->krbtgt_trust_netbios_creds);
3725 assertion_message = talloc_asprintf(ctx,
3726 "krb5_get_creds(%s, nocanon) for failed: "
3727 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3728 krbtgt_trust_netbios_string,
3729 k5ret,
3730 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3731 k5ret, ctx),
3732 trusted->trust_direction,
3733 trusted->trust_type,
3734 trusted->trust_attributes,
3735 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3736 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3737 torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
3738 torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
3740 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3741 ctx->krbtgt_trust_netbios_creds->server,
3742 ctx->krbtgt_trust_realm);
3743 torture_assert(tctx, k5ok, assertion_message);
3744 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3745 ctx->krbtgt_trust_netbios_creds->server);
3746 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3748 /* Confirm if we have the referral ticket in the cache */
3749 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3750 &ctx->krbtgt_referral_creds);
3751 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3752 ctx->krbtgt_ccache,
3754 ctx->krbtgt_trust_realm_creds,
3755 &ctx->krbtgt_referral_creds);
3756 assertion_message = talloc_asprintf(ctx,
3757 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3758 krbtgt_trust_realm_string,
3759 k5ret,
3760 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3761 k5ret, ctx));
3762 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3764 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3765 ctx->krbtgt_referral_creds.server,
3766 ctx->krbtgt_trust_realm);
3767 torture_assert(tctx, k5ok, assertion_message);
3768 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3769 ctx->krbtgt_referral_creds.server);
3770 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3772 /* Delete the referral ticket from the cache */
3773 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3774 ctx->krbtgt_ccache,
3776 &ctx->krbtgt_referral_creds);
3777 assertion_message = talloc_asprintf(ctx,
3778 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3779 krbtgt_trust_realm_string,
3780 k5ret,
3781 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3782 k5ret, ctx));
3783 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3785 cifs_trust_dns_string = talloc_asprintf(ctx, "cifs/%s@%s",
3786 trusted_dns_name, realm);
3787 torture_assert_int_equal(tctx,
3788 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3789 &ctx->cifs_trust_dns,
3790 realm, "cifs",
3791 trusted_dns_name, NULL),
3792 0, "smb_krb5_make_principal failed");
3794 /* Confirm if we get krbtgt/trusted_realm back when asking for cifs/trusted_realm */
3795 ZERO_STRUCT(ctx->counts);
3796 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3797 ctx->opt_canon,
3798 ctx->krbtgt_ccache,
3799 ctx->cifs_trust_dns,
3800 &ctx->cifs_trust_dns_creds);
3801 assertion_message = talloc_asprintf(ctx,
3802 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3803 cifs_trust_dns_string,
3804 k5ret,
3805 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3806 k5ret, ctx),
3807 trusted->trust_direction,
3808 trusted->trust_type,
3809 trusted->trust_attributes,
3810 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3811 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3812 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3813 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3815 /* Confirm if we have the referral ticket in the cache */
3816 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3817 &ctx->krbtgt_referral_creds);
3818 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3819 ctx->krbtgt_ccache,
3821 ctx->krbtgt_trust_realm_creds,
3822 &ctx->krbtgt_referral_creds);
3823 assertion_message = talloc_asprintf(ctx,
3824 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3825 krbtgt_trust_realm_string,
3826 k5ret,
3827 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3828 k5ret, ctx));
3829 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3831 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3832 ctx->krbtgt_referral_creds.server,
3833 ctx->krbtgt_trust_realm);
3834 torture_assert(tctx, k5ok, assertion_message);
3835 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3836 ctx->krbtgt_referral_creds.server);
3837 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3839 /* Delete the referral ticket from the cache */
3840 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3841 ctx->krbtgt_ccache,
3843 &ctx->krbtgt_referral_creds);
3844 assertion_message = talloc_asprintf(ctx,
3845 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3846 krbtgt_trust_realm_string,
3847 k5ret,
3848 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3849 k5ret, ctx));
3850 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3852 cifs_trust_netbios_string = talloc_asprintf(ctx, "cifs/%s@%s",
3853 trusted_netbios_name, realm);
3854 torture_assert_int_equal(tctx,
3855 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3856 &ctx->cifs_trust_netbios,
3857 realm, "cifs",
3858 trusted_netbios_name, NULL),
3859 0, "smb_krb5_make_principal failed");
3861 /* Confirm if we get krbtgt/trusted_realm back when asking for cifs/trusted_realm */
3862 ZERO_STRUCT(ctx->counts);
3863 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3864 ctx->opt_canon,
3865 ctx->krbtgt_ccache,
3866 ctx->cifs_trust_netbios,
3867 &ctx->cifs_trust_netbios_creds);
3868 assertion_message = talloc_asprintf(ctx,
3869 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3870 cifs_trust_netbios_string,
3871 k5ret,
3872 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3873 k5ret, ctx),
3874 trusted->trust_direction,
3875 trusted->trust_type,
3876 trusted->trust_attributes,
3877 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3878 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3879 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3880 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3882 /* Confirm if we have the referral ticket in the cache */
3883 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3884 &ctx->krbtgt_referral_creds);
3885 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3886 ctx->krbtgt_ccache,
3888 ctx->krbtgt_trust_realm_creds,
3889 &ctx->krbtgt_referral_creds);
3890 assertion_message = talloc_asprintf(ctx,
3891 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3892 krbtgt_trust_realm_string,
3893 k5ret,
3894 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3895 k5ret, ctx));
3896 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3898 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3899 ctx->krbtgt_referral_creds.server,
3900 ctx->krbtgt_trust_realm);
3901 torture_assert(tctx, k5ok, assertion_message);
3902 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3903 ctx->krbtgt_referral_creds.server);
3904 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3906 /* Delete the referral ticket from the cache */
3907 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3908 ctx->krbtgt_ccache,
3910 &ctx->krbtgt_referral_creds);
3911 assertion_message = talloc_asprintf(ctx,
3912 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3913 krbtgt_trust_realm_string,
3914 k5ret,
3915 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3916 k5ret, ctx));
3917 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3919 drs_trust_dns_string = talloc_asprintf(ctx,
3920 "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s@%s",
3921 workstation, trusted_dns_name, realm);
3922 torture_assert_int_equal(tctx,
3923 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3924 &ctx->drs_trust_dns,
3925 realm, "E3514235-4B06-11D1-AB04-00C04FC2DCD2",
3926 workstation, trusted_dns_name, NULL),
3927 0, "smb_krb5_make_principal failed");
3929 /* Confirm if we get krbtgt/trusted_realm back when asking for a 3 part principal */
3930 ZERO_STRUCT(ctx->counts);
3931 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3932 ctx->opt_canon,
3933 ctx->krbtgt_ccache,
3934 ctx->drs_trust_dns,
3935 &ctx->drs_trust_dns_creds);
3936 assertion_message = talloc_asprintf(ctx,
3937 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3938 drs_trust_dns_string,
3939 k5ret,
3940 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3941 k5ret, ctx),
3942 trusted->trust_direction,
3943 trusted->trust_type,
3944 trusted->trust_attributes,
3945 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3946 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3947 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3948 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3950 /* Confirm if we have the referral ticket in the cache */
3951 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3952 &ctx->krbtgt_referral_creds);
3953 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3954 ctx->krbtgt_ccache,
3956 ctx->krbtgt_trust_realm_creds,
3957 &ctx->krbtgt_referral_creds);
3958 assertion_message = talloc_asprintf(ctx,
3959 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3960 krbtgt_trust_realm_string,
3961 k5ret,
3962 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3963 k5ret, ctx));
3964 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3966 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3967 ctx->krbtgt_referral_creds.server,
3968 ctx->krbtgt_trust_realm);
3969 torture_assert(tctx, k5ok, assertion_message);
3970 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3971 ctx->krbtgt_referral_creds.server);
3972 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3974 /* Delete the referral ticket from the cache */
3975 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3976 ctx->krbtgt_ccache,
3978 &ctx->krbtgt_referral_creds);
3979 assertion_message = talloc_asprintf(ctx,
3980 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3981 krbtgt_trust_realm_string,
3982 k5ret,
3983 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3984 k5ret, ctx));
3985 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3987 drs_trust_netbios_string = talloc_asprintf(ctx,
3988 "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s@%s",
3989 workstation, trusted_netbios_name, realm);
3990 torture_assert_int_equal(tctx,
3991 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3992 &ctx->drs_trust_netbios,
3993 realm, "E3514235-4B06-11D1-AB04-00C04FC2DCD2",
3994 workstation, trusted_netbios_name, NULL),
3995 0, "smb_krb5_make_principal failed");
3997 /* Confirm if we get krbtgt/trusted_realm back when asking for a 3 part principal */
3998 ZERO_STRUCT(ctx->counts);
3999 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4000 ctx->opt_canon,
4001 ctx->krbtgt_ccache,
4002 ctx->drs_trust_netbios,
4003 &ctx->drs_trust_netbios_creds);
4004 assertion_message = talloc_asprintf(ctx,
4005 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4006 drs_trust_netbios_string,
4007 k5ret,
4008 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4009 k5ret, ctx),
4010 trusted->trust_direction,
4011 trusted->trust_type,
4012 trusted->trust_attributes,
4013 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4014 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
4015 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4016 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
4018 /* Confirm if we have the referral ticket in the cache */
4019 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4020 &ctx->krbtgt_referral_creds);
4021 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4022 ctx->krbtgt_ccache,
4024 ctx->krbtgt_trust_realm_creds,
4025 &ctx->krbtgt_referral_creds);
4026 assertion_message = talloc_asprintf(ctx,
4027 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4028 krbtgt_trust_realm_string,
4029 k5ret,
4030 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4031 k5ret, ctx));
4032 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4034 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
4035 ctx->krbtgt_referral_creds.server,
4036 ctx->krbtgt_trust_realm);
4037 torture_assert(tctx, k5ok, assertion_message);
4038 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
4039 ctx->krbtgt_referral_creds.server);
4040 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
4042 /* Delete the referral ticket from the cache */
4043 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
4044 ctx->krbtgt_ccache,
4046 &ctx->krbtgt_referral_creds);
4047 assertion_message = talloc_asprintf(ctx,
4048 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
4049 krbtgt_trust_realm_string,
4050 k5ret,
4051 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4052 k5ret, ctx));
4053 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4055 four_trust_dns_string = talloc_asprintf(ctx, "four/tree/two/%s@%s",
4056 trusted_dns_name, realm);
4057 torture_assert_int_equal(tctx,
4058 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
4059 &ctx->four_trust_dns,
4060 realm, "four", "tree", "two",
4061 trusted_dns_name, NULL),
4062 0, "smb_krb5_make_principal failed");
4064 /* Confirm if we get an error back for a 4 part principal */
4065 ZERO_STRUCT(ctx->counts);
4066 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4067 ctx->opt_canon,
4068 ctx->krbtgt_ccache,
4069 ctx->four_trust_dns,
4070 &ctx->four_trust_dns_creds);
4071 assertion_message = talloc_asprintf(ctx,
4072 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4073 four_trust_dns_string,
4074 k5ret,
4075 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4076 k5ret, ctx),
4077 trusted->trust_direction,
4078 trusted->trust_type,
4079 trusted->trust_attributes,
4080 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4081 torture_assert_int_equal(tctx, k5ret, KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, assertion_message);
4082 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4083 torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
4084 torture_assert_int_equal(tctx, ctx->error.error_code, 7, assertion_message);
4086 /* Confirm if we have no referral ticket in the cache */
4087 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4088 &ctx->krbtgt_referral_creds);
4089 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4090 ctx->krbtgt_ccache,
4092 ctx->krbtgt_trust_realm_creds,
4093 &ctx->krbtgt_referral_creds);
4094 assertion_message = talloc_asprintf(ctx,
4095 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4096 krbtgt_trust_realm_string,
4097 k5ret,
4098 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4099 k5ret, ctx));
4100 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4102 TALLOC_FREE(ctx);
4103 return true;
4106 static bool check_dom_trust_pw(struct dcerpc_pipe *p,
4107 struct torture_context *tctx,
4108 const char *our_netbios_name,
4109 const char *our_dns_name,
4110 enum netr_SchannelType secure_channel_type,
4111 const struct lsa_TrustDomainInfoInfoEx *trusted,
4112 const char *previous_password,
4113 const char *current_password,
4114 uint32_t current_version,
4115 const char *next_password,
4116 uint32_t next_version,
4117 bool expected_result)
4119 struct cli_credentials *incoming_creds;
4120 char *server_name = NULL;
4121 char *account = NULL;
4122 char *principal = NULL;
4123 char *workstation = NULL;
4124 const char *binding = torture_setting_string(tctx, "binding", NULL);
4125 const char *host = torture_setting_string(tctx, "host", NULL);
4126 struct dcerpc_binding *b2;
4127 struct netlogon_creds_CredentialState *creds;
4128 struct samr_CryptPassword samr_crypt_password;
4129 struct netr_CryptPassword netr_crypt_password;
4130 struct netr_Authenticator req_auth;
4131 struct netr_Authenticator rep_auth;
4132 struct netr_ServerPasswordSet2 s;
4133 struct dcerpc_pipe *p2;
4134 NTSTATUS status;
4135 bool ok;
4136 int rc;
4137 const char *trusted_netbios_name = trusted->netbios_name.string;
4138 const char *trusted_dns_name = trusted->domain_name.string;
4139 struct tsocket_address *dest_addr;
4140 struct cldap_socket *cldap;
4141 struct cldap_netlogon cldap1;
4143 incoming_creds = cli_credentials_init(tctx);
4144 torture_assert(tctx, incoming_creds, "cli_credentials_init");
4146 cli_credentials_set_domain(incoming_creds, our_netbios_name, CRED_SPECIFIED);
4147 cli_credentials_set_realm(incoming_creds, our_dns_name, CRED_SPECIFIED);
4149 if (secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
4150 account = talloc_asprintf(tctx, "%s.", trusted_dns_name);
4151 torture_assert(tctx, account, __location__);
4153 principal = talloc_asprintf(tctx, "%s$@%s",
4154 trusted_netbios_name,
4155 cli_credentials_get_realm(incoming_creds));
4156 torture_assert(tctx, principal, __location__);
4158 workstation = talloc_asprintf(tctx, "%sUP",
4159 trusted_netbios_name);
4160 torture_assert(tctx, workstation, __location__);
4161 } else {
4162 account = talloc_asprintf(tctx, "%s$", trusted_netbios_name);
4163 torture_assert(tctx, account, __location__);
4165 workstation = talloc_asprintf(tctx, "%sDOWN",
4166 trusted_netbios_name);
4167 torture_assert(tctx, workstation, __location__);
4170 cli_credentials_set_username(incoming_creds, account, CRED_SPECIFIED);
4171 if (principal != NULL) {
4172 cli_credentials_set_principal(incoming_creds, principal,
4173 CRED_SPECIFIED);
4175 cli_credentials_set_kvno(incoming_creds, current_version);
4176 cli_credentials_set_password(incoming_creds, current_password, CRED_SPECIFIED);
4177 cli_credentials_set_old_password(incoming_creds, previous_password, CRED_SPECIFIED);
4178 cli_credentials_set_workstation(incoming_creds, workstation, CRED_SPECIFIED);
4179 cli_credentials_set_secure_channel_type(incoming_creds, secure_channel_type);
4181 rc = tsocket_address_inet_from_strings(tctx, "ip",
4182 host,
4183 lpcfg_cldap_port(tctx->lp_ctx),
4184 &dest_addr);
4185 torture_assert_int_equal(tctx, rc, 0, "tsocket_address_inet_from_strings");
4187 /* cldap_socket_init should now know about the dest. address */
4188 status = cldap_socket_init(tctx, NULL, dest_addr, &cldap);
4189 torture_assert_ntstatus_ok(tctx, status, "cldap_socket_init");
4191 ZERO_STRUCT(cldap1);
4192 cldap1.in.dest_address = NULL;
4193 cldap1.in.dest_port = 0;
4194 cldap1.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
4195 cldap1.in.user = account;
4196 if (secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
4197 cldap1.in.acct_control = ACB_AUTOLOCK;
4198 } else {
4199 cldap1.in.acct_control = ACB_DOMTRUST;
4201 status = cldap_netlogon(cldap, tctx, &cldap1);
4202 torture_assert_ntstatus_ok(tctx, status, "cldap_netlogon");
4203 torture_assert_int_equal(tctx, cldap1.out.netlogon.ntver,
4204 NETLOGON_NT_VERSION_5EX,
4205 "ntver");
4206 torture_assert_int_equal(tctx, cldap1.out.netlogon.data.nt5_ex.nt_version,
4207 NETLOGON_NT_VERSION_1 | NETLOGON_NT_VERSION_5EX,
4208 "nt_version");
4209 torture_assert_int_equal(tctx, cldap1.out.netlogon.data.nt5_ex.command,
4210 LOGON_SAM_LOGON_RESPONSE_EX,
4211 "command");
4212 torture_assert_str_equal(tctx, cldap1.out.netlogon.data.nt5_ex.user_name,
4213 cldap1.in.user,
4214 "user_name");
4215 server_name = talloc_asprintf(tctx, "\\\\%s",
4216 cldap1.out.netlogon.data.nt5_ex.pdc_dns_name);
4217 torture_assert(tctx, server_name, __location__);
4219 status = dcerpc_parse_binding(tctx, binding, &b2);
4220 torture_assert_ntstatus_ok(tctx, status, "Bad binding string");
4222 status = dcerpc_pipe_connect_b(tctx, &p2, b2,
4223 &ndr_table_netlogon,
4224 cli_credentials_init_anon(tctx),
4225 tctx->ev, tctx->lp_ctx);
4226 torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b");
4228 ok = check_pw_with_ServerAuthenticate3(p2, tctx,
4229 NETLOGON_NEG_AUTH2_ADS_FLAGS,
4230 server_name,
4231 incoming_creds, &creds);
4232 torture_assert_int_equal(tctx, ok, expected_result,
4233 "check_pw_with_ServerAuthenticate3");
4235 if (trusted->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
4236 ok = check_pw_with_krb5(tctx, incoming_creds, trusted);
4237 torture_assert_int_equal(tctx, ok, expected_result,
4238 "check_pw_with_krb5");
4241 if (expected_result != true || next_password == NULL) {
4242 TALLOC_FREE(p2);
4243 return true;
4247 * netr_ServerPasswordSet2
4249 ok = encode_pw_buffer(samr_crypt_password.data,
4250 next_password, STR_UNICODE);
4251 torture_assert(tctx, ok, "encode_pw_buffer");
4253 if (next_version != 0) {
4254 struct NL_PASSWORD_VERSION version;
4255 uint32_t len = IVAL(samr_crypt_password.data, 512);
4256 uint32_t ofs = 512 - len;
4257 uint8_t *ptr;
4259 ofs -= 12;
4261 version.ReservedField = 0;
4262 version.PasswordVersionNumber = next_version;
4263 version.PasswordVersionPresent =
4264 NETLOGON_PASSWORD_VERSION_NUMBER_PRESENT;
4266 ptr = samr_crypt_password.data + ofs;
4267 SIVAL(ptr, 0, version.ReservedField);
4268 SIVAL(ptr, 4, version.PasswordVersionNumber);
4269 SIVAL(ptr, 8, version.PasswordVersionPresent);
4272 netlogon_creds_client_authenticator(creds, &req_auth);
4273 ZERO_STRUCT(rep_auth);
4275 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
4276 netlogon_creds_aes_encrypt(creds,
4277 samr_crypt_password.data,
4278 516);
4279 } else {
4280 netlogon_creds_arcfour_crypt(creds,
4281 samr_crypt_password.data,
4282 516);
4285 memcpy(netr_crypt_password.data,
4286 samr_crypt_password.data, 512);
4287 netr_crypt_password.length = IVAL(samr_crypt_password.data, 512);
4290 s.in.server_name = server_name;
4291 s.in.account_name = cli_credentials_get_username(incoming_creds);
4292 s.in.secure_channel_type = cli_credentials_get_secure_channel_type(incoming_creds);
4293 s.in.computer_name = cli_credentials_get_workstation(incoming_creds);
4294 s.in.credential = &req_auth;
4295 s.in.new_password = &netr_crypt_password;
4296 s.out.return_authenticator = &rep_auth;
4297 status = dcerpc_netr_ServerPasswordSet2_r(p2->binding_handle, tctx, &s);
4298 torture_assert_ntstatus_ok(tctx, status, "failed to set password");
4300 ok = netlogon_creds_client_check(creds, &rep_auth.cred);
4301 torture_assert(tctx, ok, "netlogon_creds_client_check");
4303 cli_credentials_set_kvno(incoming_creds, next_version);
4304 cli_credentials_set_password(incoming_creds, next_password, CRED_SPECIFIED);
4305 cli_credentials_set_old_password(incoming_creds, current_password, CRED_SPECIFIED);
4307 TALLOC_FREE(p2);
4308 status = dcerpc_pipe_connect_b(tctx, &p2, b2,
4309 &ndr_table_netlogon,
4310 cli_credentials_init_anon(tctx),
4311 tctx->ev, tctx->lp_ctx);
4312 torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b");
4314 ok = check_pw_with_ServerAuthenticate3(p2, tctx,
4315 NETLOGON_NEG_AUTH2_ADS_FLAGS,
4316 server_name,
4317 incoming_creds, &creds);
4318 torture_assert(tctx, ok, "check_pw_with_ServerAuthenticate3 with changed password");
4320 if (trusted->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
4321 ok = check_pw_with_krb5(tctx, incoming_creds, trusted);
4322 torture_assert(tctx, ok, "check_pw_with_krb5 with changed password");
4325 TALLOC_FREE(p2);
4326 return true;
4329 static bool test_CreateTrustedDomainEx_common(struct dcerpc_pipe *p,
4330 struct torture_context *tctx,
4331 struct policy_handle *handle,
4332 uint32_t num_trusts,
4333 bool ex2_call)
4335 NTSTATUS status;
4336 bool ret = true;
4337 struct lsa_QueryInfoPolicy2 p2;
4338 union lsa_PolicyInformation *our_info = NULL;
4339 struct lsa_CreateTrustedDomainEx r;
4340 struct lsa_CreateTrustedDomainEx2 r2;
4341 struct lsa_TrustDomainInfoInfoEx trustinfo;
4342 struct lsa_TrustDomainInfoAuthInfoInternal *authinfo_internal = NULL;
4343 struct lsa_TrustDomainInfoAuthInfo *authinfo = NULL;
4344 struct dom_sid **domsid;
4345 struct policy_handle *trustdom_handle;
4346 struct lsa_QueryTrustedDomainInfo q;
4347 union lsa_TrustedDomainInfo *info = NULL;
4348 DATA_BLOB session_key;
4349 int i;
4350 struct dcerpc_binding_handle *b = p->binding_handle;
4351 const char *id;
4352 const char *incoming_v00 = TRUSTPW "InV00";
4353 const char *incoming_v0 = TRUSTPW "InV0";
4354 const char *incoming_v1 = TRUSTPW "InV1";
4355 const char *incoming_v2 = TRUSTPW "InV2";
4356 const char *incoming_v40 = TRUSTPW "InV40";
4357 const char *outgoing_v00 = TRUSTPW "OutV00";
4358 const char *outgoing_v0 = TRUSTPW "OutV0";
4360 if (ex2_call) {
4361 torture_comment(tctx, "\nTesting CreateTrustedDomainEx2 for %d domains\n", num_trusts);
4362 id = "3";
4363 } else {
4364 torture_comment(tctx, "\nTesting CreateTrustedDomainEx for %d domains\n", num_trusts);
4365 id = "2";
4368 domsid = talloc_array(tctx, struct dom_sid *, num_trusts);
4369 trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts);
4371 status = dcerpc_fetch_session_key(p, &session_key);
4372 if (!NT_STATUS_IS_OK(status)) {
4373 torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
4374 return false;
4377 ZERO_STRUCT(p2);
4378 p2.in.handle = handle;
4379 p2.in.level = LSA_POLICY_INFO_DNS;
4380 p2.out.info = &our_info;
4382 torture_assert_ntstatus_ok(tctx,
4383 dcerpc_lsa_QueryInfoPolicy2_r(b, tctx, &p2),
4384 "lsa_QueryInfoPolicy2 failed");
4385 torture_assert_ntstatus_ok(tctx, p2.out.result,
4386 "lsa_QueryInfoPolicy2 failed");
4387 torture_assert(tctx, our_info != NULL, "lsa_QueryInfoPolicy2 our_info");
4389 for (i=0; i< num_trusts; i++) {
4390 char *trust_name = talloc_asprintf(tctx, "TORTURE%s%02d", id, i);
4391 char *trust_name_dns = talloc_asprintf(tctx, "torturedom%s%02d.samba._none_.example.com", id, i);
4392 char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-%s%02d", id, i);
4393 bool ok;
4395 domsid[i] = dom_sid_parse_talloc(tctx, trust_sid);
4397 trustinfo.sid = domsid[i];
4398 trustinfo.netbios_name.string = trust_name;
4399 trustinfo.domain_name.string = trust_name_dns;
4401 /* Create inbound, some outbound, and some
4402 * bi-directional trusts in a repeating pattern based
4403 * on i */
4405 /* 1 == inbound, 2 == outbound, 3 == both */
4406 trustinfo.trust_direction = (i % 3) + 1;
4408 /* Try different trust types too */
4410 /* 1 == downlevel (NT4), 2 == uplevel (ADS), 3 == MIT (kerberos but not AD) */
4411 trustinfo.trust_type = (((i / 3) + 1) % 3) + 1;
4413 trustinfo.trust_attributes = LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION;
4415 ok = gen_authinfo_internal(tctx, incoming_v00, incoming_v0,
4416 outgoing_v00, outgoing_v0,
4417 session_key, &authinfo_internal);
4418 if (!ok) {
4419 torture_comment(tctx, "gen_authinfo_internal failed");
4420 ret = false;
4423 ok = gen_authinfo(tctx, incoming_v00, incoming_v0,
4424 outgoing_v00, outgoing_v0,
4425 &authinfo);
4426 if (!ok) {
4427 torture_comment(tctx, "gen_authinfonfo failed");
4428 ret = false;
4431 if (ex2_call) {
4433 r2.in.policy_handle = handle;
4434 r2.in.info = &trustinfo;
4435 r2.in.auth_info_internal = authinfo_internal;
4436 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4437 r2.out.trustdom_handle = &trustdom_handle[i];
4439 torture_assert_ntstatus_ok(tctx,
4440 dcerpc_lsa_CreateTrustedDomainEx2_r(b, tctx, &r2),
4441 "CreateTrustedDomainEx2 failed");
4443 status = r2.out.result;
4444 } else {
4446 r.in.policy_handle = handle;
4447 r.in.info = &trustinfo;
4448 r.in.auth_info = authinfo;
4449 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4450 r.out.trustdom_handle = &trustdom_handle[i];
4452 torture_assert_ntstatus_ok(tctx,
4453 dcerpc_lsa_CreateTrustedDomainEx_r(b, tctx, &r),
4454 "CreateTrustedDomainEx failed");
4456 status = r.out.result;
4459 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
4460 test_DeleteTrustedDomain(b, tctx, handle, trustinfo.netbios_name);
4461 if (ex2_call) {
4462 torture_assert_ntstatus_ok(tctx,
4463 dcerpc_lsa_CreateTrustedDomainEx2_r(b, tctx, &r2),
4464 "CreateTrustedDomainEx2 failed");
4465 status = r2.out.result;
4466 } else {
4467 torture_assert_ntstatus_ok(tctx,
4468 dcerpc_lsa_CreateTrustedDomainEx_r(b, tctx, &r),
4469 "CreateTrustedDomainEx2 failed");
4470 status = r.out.result;
4473 if (!NT_STATUS_IS_OK(status)) {
4474 torture_comment(tctx, "CreateTrustedDomainEx failed2 - %s\n", nt_errstr(status));
4475 ret = false;
4476 } else {
4477 /* For outbound and MIT trusts there is no trust account */
4478 if (trustinfo.trust_direction != 2 &&
4479 trustinfo.trust_type != 3) {
4481 if (torture_setting_bool(tctx, "samba3", false)) {
4482 torture_comment(tctx, "skipping trusted domain auth tests against samba3\n");
4483 } else if (ex2_call == false &&
4484 torture_setting_bool(tctx, "samba4", false)) {
4485 torture_comment(tctx, "skipping CreateTrustedDomainEx trusted domain auth tests against samba4\n");
4487 } else {
4488 ok = check_dom_trust_pw(p, tctx,
4489 our_info->dns.name.string,
4490 our_info->dns.dns_domain.string,
4491 SEC_CHAN_DOMAIN,
4492 &trustinfo,
4493 NULL,
4494 "x" TRUSTPW "x", 0,
4495 NULL, 0,
4496 false);
4497 if (!ok) {
4498 torture_comment(tctx, "Password check passed unexpectedly\n");
4499 ret = false;
4501 ok = check_dom_trust_pw(p, tctx,
4502 our_info->dns.name.string,
4503 our_info->dns.dns_domain.string,
4504 SEC_CHAN_DOMAIN,
4505 &trustinfo,
4506 incoming_v00,
4507 incoming_v0, 0,
4508 incoming_v1, 1,
4509 true);
4510 if (!ok) {
4511 torture_comment(tctx, "Password check failed (SEC_CHAN_DOMAIN)\n");
4512 ret = false;
4514 ok = check_dom_trust_pw(p, tctx,
4515 our_info->dns.name.string,
4516 our_info->dns.dns_domain.string,
4517 SEC_CHAN_DNS_DOMAIN,
4518 &trustinfo,
4519 incoming_v0,
4520 incoming_v1, 1,
4521 incoming_v2, 2,
4522 true);
4523 if (!ok) {
4524 torture_comment(tctx, "Password check failed v2 (SEC_CHAN_DNS_DOMAIN)\n");
4525 ret = false;
4527 ok = check_dom_trust_pw(p, tctx,
4528 our_info->dns.name.string,
4529 our_info->dns.dns_domain.string,
4530 SEC_CHAN_DNS_DOMAIN,
4531 &trustinfo,
4532 incoming_v1,
4533 incoming_v2, 2,
4534 incoming_v40, 40,
4535 true);
4536 if (!ok) {
4537 torture_comment(tctx, "Password check failed v4 (SEC_CHAN_DNS_DOMAIN)\n");
4538 ret = false;
4543 q.in.trustdom_handle = &trustdom_handle[i];
4544 q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
4545 q.out.info = &info;
4546 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
4547 "QueryTrustedDomainInfo failed");
4548 if (!NT_STATUS_IS_OK(q.out.result)) {
4549 torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(q.out.result));
4550 ret = false;
4551 } else if (!q.out.info) {
4552 torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
4553 ret = false;
4554 } else {
4555 if (strcmp(info->info_ex.domain_name.string, trustinfo.domain_name.string) != 0) {
4556 torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent long name: %s != %s\n",
4557 info->info_ex.domain_name.string, trustinfo.domain_name.string);
4558 ret = false;
4560 if (strcmp(info->info_ex.netbios_name.string, trustinfo.netbios_name.string) != 0) {
4561 torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
4562 info->info_ex.netbios_name.string, trustinfo.netbios_name.string);
4563 ret = false;
4565 if (info->info_ex.trust_type != trustinfo.trust_type) {
4566 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
4567 trust_name, info->info_ex.trust_type, trustinfo.trust_type);
4568 ret = false;
4570 if (info->info_ex.trust_attributes != LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION) {
4571 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
4572 trust_name, info->info_ex.trust_attributes, LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION);
4573 ret = false;
4575 if (info->info_ex.trust_direction != trustinfo.trust_direction) {
4576 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
4577 trust_name, info->info_ex.trust_direction, trustinfo.trust_direction);
4578 ret = false;
4584 /* now that we have some domains to look over, we can test the enum calls */
4585 if (!test_EnumTrustDom(b, tctx, handle)) {
4586 torture_comment(tctx, "test_EnumTrustDom failed\n");
4587 ret = false;
4590 if (!test_EnumTrustDomEx(b, tctx, handle)) {
4591 torture_comment(tctx, "test_EnumTrustDomEx failed\n");
4592 ret = false;
4595 for (i=0; i<num_trusts; i++) {
4596 if (!test_DeleteTrustedDomainBySid(b, tctx, handle, domsid[i])) {
4597 torture_comment(tctx, "test_DeleteTrustedDomainBySid failed\n");
4598 ret = false;
4602 return ret;
4605 static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
4606 struct torture_context *tctx,
4607 struct policy_handle *handle,
4608 uint32_t num_trusts)
4610 return test_CreateTrustedDomainEx_common(p, tctx, handle, num_trusts, true);
4613 static bool test_CreateTrustedDomainEx(struct dcerpc_pipe *p,
4614 struct torture_context *tctx,
4615 struct policy_handle *handle,
4616 uint32_t num_trusts)
4618 return test_CreateTrustedDomainEx_common(p, tctx, handle, num_trusts, false);
4621 static bool test_QueryDomainInfoPolicy(struct dcerpc_binding_handle *b,
4622 struct torture_context *tctx,
4623 struct policy_handle *handle)
4625 struct lsa_QueryDomainInformationPolicy r;
4626 union lsa_DomainInformationPolicy *info = NULL;
4627 int i;
4628 bool ret = true;
4630 if (torture_setting_bool(tctx, "samba3", false)) {
4631 torture_skip(tctx, "skipping QueryDomainInformationPolicy test\n");
4634 torture_comment(tctx, "\nTesting QueryDomainInformationPolicy\n");
4636 for (i=2;i<4;i++) {
4637 r.in.handle = handle;
4638 r.in.level = i;
4639 r.out.info = &info;
4641 torture_comment(tctx, "\nTrying QueryDomainInformationPolicy level %d\n", i);
4643 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryDomainInformationPolicy_r(b, tctx, &r),
4644 "QueryDomainInformationPolicy failed");
4646 /* If the server does not support EFS, then this is the correct return */
4647 if (i == LSA_DOMAIN_INFO_POLICY_EFS && NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4648 continue;
4649 } else if (!NT_STATUS_IS_OK(r.out.result)) {
4650 torture_comment(tctx, "QueryDomainInformationPolicy failed - %s\n", nt_errstr(r.out.result));
4651 ret = false;
4652 continue;
4656 return ret;
4660 static bool test_QueryInfoPolicyCalls( bool version2,
4661 struct dcerpc_binding_handle *b,
4662 struct torture_context *tctx,
4663 struct policy_handle *handle)
4665 struct lsa_QueryInfoPolicy r;
4666 union lsa_PolicyInformation *info = NULL;
4667 int i;
4668 bool ret = true;
4669 const char *call = talloc_asprintf(tctx, "QueryInfoPolicy%s", version2 ? "2":"");
4671 torture_comment(tctx, "\nTesting %s\n", call);
4673 if (version2 && torture_setting_bool(tctx, "samba3", false)) {
4674 torture_skip(tctx, "skipping QueryInfoPolicy2 tests\n");
4677 for (i=1;i<=14;i++) {
4678 r.in.handle = handle;
4679 r.in.level = i;
4680 r.out.info = &info;
4682 torture_comment(tctx, "\nTrying %s level %d\n", call, i);
4684 if (version2)
4685 /* We can perform the cast, because both types are
4686 structurally equal */
4687 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy2_r(b, tctx,
4688 (struct lsa_QueryInfoPolicy2*) &r),
4689 "QueryInfoPolicy2 failed");
4690 else
4691 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy_r(b, tctx, &r),
4692 "QueryInfoPolicy2 failed");
4694 switch (i) {
4695 case LSA_POLICY_INFO_MOD:
4696 case LSA_POLICY_INFO_AUDIT_FULL_SET:
4697 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
4698 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
4699 torture_comment(tctx, "Server should have failed level %u: %s\n", i, nt_errstr(r.out.result));
4700 ret = false;
4702 break;
4703 case LSA_POLICY_INFO_DOMAIN:
4704 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
4705 case LSA_POLICY_INFO_REPLICA:
4706 case LSA_POLICY_INFO_QUOTA:
4707 case LSA_POLICY_INFO_ROLE:
4708 case LSA_POLICY_INFO_AUDIT_LOG:
4709 case LSA_POLICY_INFO_AUDIT_EVENTS:
4710 case LSA_POLICY_INFO_PD:
4711 if (!NT_STATUS_IS_OK(r.out.result)) {
4712 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4713 ret = false;
4715 break;
4716 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
4717 case LSA_POLICY_INFO_DNS_INT:
4718 case LSA_POLICY_INFO_DNS:
4719 if (torture_setting_bool(tctx, "samba3", false)) {
4720 /* Other levels not implemented yet */
4721 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
4722 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4723 ret = false;
4725 } else if (!NT_STATUS_IS_OK(r.out.result)) {
4726 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4727 ret = false;
4729 break;
4730 default:
4731 if (torture_setting_bool(tctx, "samba4", false)) {
4732 /* Other levels not implemented yet */
4733 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
4734 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4735 ret = false;
4737 } else if (!NT_STATUS_IS_OK(r.out.result)) {
4738 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4739 ret = false;
4741 break;
4744 if (NT_STATUS_IS_OK(r.out.result) && (i == LSA_POLICY_INFO_DNS
4745 || i == LSA_POLICY_INFO_DNS_INT)) {
4746 /* Let's look up some of these names */
4748 struct lsa_TransNameArray tnames;
4749 tnames.count = 14;
4750 tnames.names = talloc_zero_array(tctx, struct lsa_TranslatedName, tnames.count);
4751 tnames.names[0].name.string = info->dns.name.string;
4752 tnames.names[0].sid_type = SID_NAME_DOMAIN;
4753 tnames.names[1].name.string = info->dns.dns_domain.string;
4754 tnames.names[1].sid_type = SID_NAME_DOMAIN;
4755 tnames.names[2].name.string = talloc_asprintf(tctx, "%s\\", info->dns.name.string);
4756 tnames.names[2].sid_type = SID_NAME_DOMAIN;
4757 tnames.names[3].name.string = talloc_asprintf(tctx, "%s\\", info->dns.dns_domain.string);
4758 tnames.names[3].sid_type = SID_NAME_DOMAIN;
4759 tnames.names[4].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.name.string);
4760 tnames.names[4].sid_type = SID_NAME_USER;
4761 tnames.names[5].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.name.string);
4762 tnames.names[5].sid_type = SID_NAME_USER;
4763 tnames.names[6].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.dns_domain.string);
4764 tnames.names[6].sid_type = SID_NAME_USER;
4765 tnames.names[7].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.dns_domain.string);
4766 tnames.names[7].sid_type = SID_NAME_USER;
4767 tnames.names[8].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.name.string);
4768 tnames.names[8].sid_type = SID_NAME_USER;
4769 tnames.names[9].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.dns_domain.string);
4770 tnames.names[9].sid_type = SID_NAME_USER;
4771 tnames.names[10].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.name.string);
4772 tnames.names[10].sid_type = SID_NAME_USER;
4773 tnames.names[11].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.dns_domain.string);
4774 tnames.names[11].sid_type = SID_NAME_USER;
4775 tnames.names[12].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.name.string);
4776 tnames.names[12].sid_type = SID_NAME_USER;
4777 tnames.names[13].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.dns_domain.string);
4778 tnames.names[13].sid_type = SID_NAME_USER;
4779 ret &= test_LookupNames(b, tctx, handle, &tnames);
4784 return ret;
4787 static bool test_QueryInfoPolicy(struct dcerpc_binding_handle *b,
4788 struct torture_context *tctx,
4789 struct policy_handle *handle)
4791 return test_QueryInfoPolicyCalls(false, b, tctx, handle);
4794 static bool test_QueryInfoPolicy2(struct dcerpc_binding_handle *b,
4795 struct torture_context *tctx,
4796 struct policy_handle *handle)
4798 return test_QueryInfoPolicyCalls(true, b, tctx, handle);
4801 static bool test_GetUserName(struct dcerpc_binding_handle *b,
4802 struct torture_context *tctx)
4804 struct lsa_GetUserName r;
4805 bool ret = true;
4806 struct lsa_String *authority_name_p = NULL;
4807 struct lsa_String *account_name_p = NULL;
4809 torture_comment(tctx, "\nTesting GetUserName\n");
4811 r.in.system_name = "\\";
4812 r.in.account_name = &account_name_p;
4813 r.in.authority_name = NULL;
4814 r.out.account_name = &account_name_p;
4816 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
4817 "GetUserName failed");
4819 if (!NT_STATUS_IS_OK(r.out.result)) {
4820 torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(r.out.result));
4821 ret = false;
4824 account_name_p = NULL;
4825 r.in.account_name = &account_name_p;
4826 r.in.authority_name = &authority_name_p;
4827 r.out.account_name = &account_name_p;
4829 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
4830 "GetUserName failed");
4832 if (!NT_STATUS_IS_OK(r.out.result)) {
4833 torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(r.out.result));
4834 ret = false;
4837 return ret;
4840 static bool test_GetUserName_fail(struct dcerpc_binding_handle *b,
4841 struct torture_context *tctx)
4843 struct lsa_GetUserName r;
4844 struct lsa_String *account_name_p = NULL;
4845 NTSTATUS status;
4847 torture_comment(tctx, "\nTesting GetUserName_fail\n");
4849 r.in.system_name = "\\";
4850 r.in.account_name = &account_name_p;
4851 r.in.authority_name = NULL;
4852 r.out.account_name = &account_name_p;
4854 status = dcerpc_lsa_GetUserName_r(b, tctx, &r);
4855 if (!NT_STATUS_IS_OK(status)) {
4856 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4857 torture_comment(tctx,
4858 "GetUserName correctly returned with "
4859 "status: %s\n",
4860 nt_errstr(status));
4861 return true;
4864 torture_assert_ntstatus_equal(tctx,
4865 status,
4866 NT_STATUS_ACCESS_DENIED,
4867 "GetUserName return value should "
4868 "be ACCESS_DENIED");
4869 return true;
4872 if (!NT_STATUS_IS_OK(r.out.result)) {
4873 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
4874 NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
4875 torture_comment(tctx,
4876 "GetUserName correctly returned with "
4877 "result: %s\n",
4878 nt_errstr(r.out.result));
4879 return true;
4883 torture_assert_ntstatus_equal(tctx,
4884 r.out.result,
4885 NT_STATUS_OK,
4886 "GetUserName return value should be "
4887 "ACCESS_DENIED");
4889 return false;
4892 bool test_lsa_Close(struct dcerpc_binding_handle *b,
4893 struct torture_context *tctx,
4894 struct policy_handle *handle)
4896 struct lsa_Close r;
4897 struct policy_handle handle2;
4899 torture_comment(tctx, "\nTesting Close\n");
4901 r.in.handle = handle;
4902 r.out.handle = &handle2;
4904 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &r),
4905 "Close failed");
4906 torture_assert_ntstatus_ok(tctx, r.out.result,
4907 "Close failed");
4909 torture_assert_ntstatus_equal(tctx, dcerpc_lsa_Close_r(b, tctx, &r),
4910 NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "Close should failed");
4912 torture_comment(tctx, "\n");
4914 return true;
4917 bool torture_rpc_lsa(struct torture_context *tctx)
4919 NTSTATUS status;
4920 struct dcerpc_pipe *p;
4921 bool ret = true;
4922 struct policy_handle *handle = NULL;
4923 struct test_join *join = NULL;
4924 struct cli_credentials *machine_creds;
4925 struct dcerpc_binding_handle *b;
4926 enum dcerpc_transport_t transport;
4928 status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
4929 if (!NT_STATUS_IS_OK(status)) {
4930 return false;
4932 b = p->binding_handle;
4933 transport = dcerpc_binding_get_transport(p->binding);
4935 /* Test lsaLookupSids3 and lsaLookupNames4 over tcpip */
4936 if (transport == NCACN_IP_TCP) {
4937 if (!test_OpenPolicy_fail(b, tctx)) {
4938 ret = false;
4941 if (!test_OpenPolicy2_fail(b, tctx)) {
4942 ret = false;
4945 if (!test_many_LookupSids(p, tctx, handle)) {
4946 ret = false;
4949 return ret;
4952 if (!test_OpenPolicy(b, tctx)) {
4953 ret = false;
4956 if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
4957 ret = false;
4960 if (handle) {
4961 join = torture_join_domain(tctx, TEST_MACHINENAME, ACB_WSTRUST, &machine_creds);
4962 if (!join) {
4963 ret = false;
4966 if (!test_LookupSids_async(b, tctx, handle)) {
4967 ret = false;
4970 if (!test_QueryDomainInfoPolicy(b, tctx, handle)) {
4971 ret = false;
4974 if (!test_CreateSecret(p, tctx, handle)) {
4975 ret = false;
4978 if (!test_QueryInfoPolicy(b, tctx, handle)) {
4979 ret = false;
4982 if (!test_QueryInfoPolicy2(b, tctx, handle)) {
4983 ret = false;
4986 if (!test_Delete(b, tctx, handle)) {
4987 ret = false;
4990 if (!test_many_LookupSids(p, tctx, handle)) {
4991 ret = false;
4994 if (!test_lsa_Close(b, tctx, handle)) {
4995 ret = false;
4998 torture_leave_domain(tctx, join);
5000 } else {
5001 if (!test_many_LookupSids(p, tctx, handle)) {
5002 ret = false;
5006 if (!test_GetUserName(b, tctx)) {
5007 ret = false;
5010 return ret;
5013 bool torture_rpc_lsa_get_user(struct torture_context *tctx)
5015 NTSTATUS status;
5016 struct dcerpc_pipe *p;
5017 bool ret = true;
5018 struct dcerpc_binding_handle *b;
5019 enum dcerpc_transport_t transport;
5021 status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
5022 if (!NT_STATUS_IS_OK(status)) {
5023 return false;
5025 b = p->binding_handle;
5026 transport = dcerpc_binding_get_transport(p->binding);
5028 if (transport == NCACN_IP_TCP) {
5029 if (!test_GetUserName_fail(b, tctx)) {
5030 ret = false;
5032 return ret;
5035 if (!test_GetUserName(b, tctx)) {
5036 ret = false;
5039 return ret;
5042 static bool testcase_LookupNames(struct torture_context *tctx,
5043 struct dcerpc_pipe *p)
5045 bool ret = true;
5046 struct policy_handle *handle;
5047 struct lsa_TransNameArray tnames;
5048 struct lsa_TransNameArray2 tnames2;
5049 struct dcerpc_binding_handle *b = p->binding_handle;
5050 enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
5052 if (transport != NCACN_NP && transport != NCALRPC) {
5053 torture_comment(tctx, "testcase_LookupNames is only available "
5054 "over NCACN_NP or NCALRPC");
5055 return true;
5058 if (!test_OpenPolicy(b, tctx)) {
5059 ret = false;
5062 if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5063 ret = false;
5066 if (!handle) {
5067 ret = false;
5070 tnames.count = 1;
5071 tnames.names = talloc_array(tctx, struct lsa_TranslatedName, tnames.count);
5072 ZERO_STRUCT(tnames.names[0]);
5073 tnames.names[0].name.string = "BUILTIN";
5074 tnames.names[0].sid_type = SID_NAME_DOMAIN;
5076 if (!test_LookupNames(b, tctx, handle, &tnames)) {
5077 ret = false;
5080 tnames2.count = 1;
5081 tnames2.names = talloc_array(tctx, struct lsa_TranslatedName2, tnames2.count);
5082 ZERO_STRUCT(tnames2.names[0]);
5083 tnames2.names[0].name.string = "BUILTIN";
5084 tnames2.names[0].sid_type = SID_NAME_DOMAIN;
5086 if (!test_LookupNames2(b, tctx, handle, &tnames2, true)) {
5087 ret = false;
5090 if (!test_LookupNames3(b, tctx, handle, &tnames2, true)) {
5091 ret = false;
5094 if (!test_LookupNames_wellknown(b, tctx, handle)) {
5095 ret = false;
5098 if (!test_LookupNames_NULL(b, tctx, handle)) {
5099 ret = false;
5102 if (!test_LookupNames_bogus(b, tctx, handle)) {
5103 ret = false;
5106 if (!test_lsa_Close(b, tctx, handle)) {
5107 ret = false;
5110 return ret;
5113 struct torture_suite *torture_rpc_lsa_lookup_names(TALLOC_CTX *mem_ctx)
5115 struct torture_suite *suite;
5116 struct torture_rpc_tcase *tcase;
5118 suite = torture_suite_create(mem_ctx, "lsa.lookupnames");
5120 tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5121 &ndr_table_lsarpc);
5122 torture_rpc_tcase_add_test(tcase, "LookupNames",
5123 testcase_LookupNames);
5125 return suite;
5128 struct lsa_trustdom_state {
5129 uint32_t num_trusts;
5132 static bool testcase_TrustedDomains(struct torture_context *tctx,
5133 struct dcerpc_pipe *p,
5134 void *data)
5136 bool ret = true;
5137 struct policy_handle *handle;
5138 struct lsa_trustdom_state *state =
5139 talloc_get_type_abort(data, struct lsa_trustdom_state);
5140 struct dcerpc_binding_handle *b = p->binding_handle;
5141 enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
5143 if (transport != NCACN_NP && transport != NCALRPC) {
5144 torture_comment(tctx, "testcase_TrustedDomains is only available "
5145 "over NCACN_NP or NCALRPC");
5146 return true;
5149 torture_comment(tctx, "Testing %d domains\n", state->num_trusts);
5151 if (!test_OpenPolicy(b, tctx)) {
5152 ret = false;
5155 if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5156 ret = false;
5159 if (!handle) {
5160 ret = false;
5163 if (!test_CreateTrustedDomain(b, tctx, handle, state->num_trusts)) {
5164 ret = false;
5167 if (!test_CreateTrustedDomainEx(p, tctx, handle, state->num_trusts)) {
5168 ret = false;
5171 if (!test_CreateTrustedDomainEx2(p, tctx, handle, state->num_trusts)) {
5172 ret = false;
5175 if (!test_lsa_Close(b, tctx, handle)) {
5176 ret = false;
5179 return ret;
5182 struct torture_suite *torture_rpc_lsa_trusted_domains(TALLOC_CTX *mem_ctx)
5184 struct torture_suite *suite;
5185 struct torture_rpc_tcase *tcase;
5186 struct lsa_trustdom_state *state;
5188 state = talloc(mem_ctx, struct lsa_trustdom_state);
5190 state->num_trusts = 12;
5192 suite = torture_suite_create(mem_ctx, "lsa.trusted.domains");
5194 tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5195 &ndr_table_lsarpc);
5196 torture_rpc_tcase_add_test_ex(tcase, "TrustedDomains",
5197 testcase_TrustedDomains,
5198 state);
5200 return suite;
5203 static bool testcase_Privileges(struct torture_context *tctx,
5204 struct dcerpc_pipe *p)
5206 struct policy_handle *handle;
5207 struct dcerpc_binding_handle *b = p->binding_handle;
5208 enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
5210 if (transport != NCACN_NP && transport != NCALRPC) {
5211 torture_skip(tctx, "testcase_Privileges is only available "
5212 "over NCACN_NP or NCALRPC");
5215 if (!test_OpenPolicy(b, tctx)) {
5216 return false;
5219 if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5220 return false;
5223 if (!handle) {
5224 return false;
5227 if (!test_CreateAccount(b, tctx, handle)) {
5228 return false;
5231 if (!test_EnumAccounts(b, tctx, handle)) {
5232 return false;
5235 if (!test_EnumPrivs(b, tctx, handle)) {
5236 return false;
5239 if (!test_lsa_Close(b, tctx, handle)) {
5240 return false;
5243 return true;
5247 struct torture_suite *torture_rpc_lsa_privileges(TALLOC_CTX *mem_ctx)
5249 struct torture_suite *suite;
5250 struct torture_rpc_tcase *tcase;
5252 suite = torture_suite_create(mem_ctx, "lsa.privileges");
5254 tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5255 &ndr_table_lsarpc);
5256 torture_rpc_tcase_add_test(tcase, "Privileges",
5257 testcase_Privileges);
5259 return suite;