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/>.
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
)
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");
59 qos
.impersonation_level
= 2;
61 qos
.effective_only
= 0;
65 attr
.object_name
= NULL
;
70 r
.in
.system_name
= &system_name
;
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
),
78 torture_assert_ntstatus_ok(tctx
,
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
= '\\';
95 torture_comment(tctx
, "\nTesting OpenPolicy_fail\n");
98 qos
.impersonation_level
= 2;
100 qos
.effective_only
= 0;
103 attr
.root_dir
= NULL
;
104 attr
.object_name
= NULL
;
106 attr
.sec_desc
= NULL
;
109 r
.in
.system_name
= &system_name
;
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 "
124 torture_assert_ntstatus_equal(tctx
,
126 NT_STATUS_ACCESS_DENIED
,
127 "OpenPolicy return value should "
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 "
138 nt_errstr(r
.out
.result
));
143 torture_assert_ntstatus_equal(tctx
,
146 "OpenPolicy return value should be "
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
;
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)");
169 qos
.impersonation_level
= 2;
170 qos
.context_mode
= 1;
171 qos
.effective_only
= 0;
174 attr
.root_dir
= NULL
;
175 attr
.object_name
= NULL
;
177 attr
.sec_desc
= NULL
;
180 r
.in
.system_name
= "\\";
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
)) {
192 torture_assert_ntstatus_ok(tctx
,
194 "OpenPolicy2 failed");
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
;
216 torture_comment(tctx
, "\nTesting OpenPolicy2_fail\n");
219 qos
.impersonation_level
= 2;
220 qos
.context_mode
= 1;
221 qos
.effective_only
= 0;
224 attr
.root_dir
= NULL
;
225 attr
.object_name
= NULL
;
227 attr
.sec_desc
= NULL
;
230 r
.in
.system_name
= "\\";
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 "
245 torture_assert_ntstatus_equal(tctx
,
247 NT_STATUS_ACCESS_DENIED
,
248 "OpenPolicy2 return value should "
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 "
258 nt_errstr(r
.out
.result
));
263 "OpenPolicy2 return value should be "
264 "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
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
;
282 torture_comment(tctx
, "\nTesting LookupNames with %d names\n", tnames
->count
);
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
;
301 r
.in
.handle
= handle
;
306 r
.out
.count
= &count
;
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
) {
346 torture_assert_int_equal(tctx
,
349 talloc_asprintf(tctx
,
350 "LookupName of %s got unexpected rid: %d\n",
351 tnames
->names
[input_idx
[i
]].name
.string
,
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];
368 torture_comment(tctx
, "\nTesting LookupNames with bogus name\n");
373 init_lsa_String(&names
[0], "NT AUTHORITY\\BOGUS");
375 r
.in
.handle
= handle
;
381 r
.out
.count
= &count
;
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
));
393 torture_comment(tctx
, "\n");
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];
408 torture_comment(tctx
, "\nTesting LookupNames with NULL name\n");
413 names
[0].string
= NULL
;
415 r
.in
.handle
= handle
;
421 r
.out
.count
= &count
;
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");
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
;
450 torture_comment(tctx
, "Testing LookupNames with well known names\n");
452 tnames
.names
= &name
;
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
);
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
);
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
);
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
,
498 struct lsa_LookupNames2 r
;
499 struct lsa_TransSidArray2 sids
;
500 struct lsa_RefDomainList
*domains
= NULL
;
501 struct lsa_String
*names
;
506 torture_comment(tctx
, "\nTesting LookupNames2 with %d names\n", tnames
->count
);
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
;
524 r
.in
.handle
= handle
;
529 r
.in
.lookup_options
= 0;
530 r
.in
.client_revision
= 0;
531 r
.out
.count
= &count
;
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");
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");
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
,
559 struct lsa_LookupNames3 r
;
560 struct lsa_TransSidArray3 sids
;
561 struct lsa_RefDomainList
*domains
= NULL
;
562 struct lsa_String
*names
;
567 torture_comment(tctx
, "\nTesting LookupNames3 with %d names\n", tnames
->count
);
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
;
584 r
.in
.handle
= handle
;
589 r
.in
.lookup_options
= 0;
590 r
.in
.client_revision
= 0;
591 r
.out
.count
= &count
;
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");
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");
613 static bool test_LookupNames4(struct dcerpc_binding_handle
*b
,
614 struct torture_context
*tctx
,
615 struct lsa_TransNameArray2
*tnames
,
618 struct lsa_LookupNames4 r
;
619 struct lsa_TransSidArray3 sids
;
620 struct lsa_RefDomainList
*domains
= NULL
;
621 struct lsa_String
*names
;
626 torture_comment(tctx
, "\nTesting LookupNames4 with %d names\n", tnames
->count
);
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
;
643 r
.in
.num_names
= tnames
->count
;
648 r
.in
.lookup_options
= 0;
649 r
.in
.client_revision
= 0;
650 r
.out
.count
= &count
;
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
));
666 torture_assert_ntstatus_ok(tctx
,
668 "LookupNames4 failed");
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");
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
;
693 torture_comment(tctx
, "\nTesting LookupNames4_fail");
700 r
.in
.num_names
= count
;
705 r
.in
.lookup_options
= 0;
706 r
.in
.client_revision
= 0;
707 r
.out
.count
= &count
;
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 "
721 torture_assert_ntstatus_equal(tctx
,
723 NT_STATUS_ACCESS_DENIED
,
724 "LookupNames4 return value should "
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 "
735 nt_errstr(r
.out
.result
));
741 "LookupNames4 return value should be "
742 "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
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");
763 r
.in
.handle
= handle
;
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
)) {
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");
804 r
.in
.handle
= handle
;
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
));
824 torture_comment(tctx
, "\n");
826 if (!test_LookupNames2(b
, tctx
, handle
, &names
, false)) {
830 if (!test_LookupNames3(b
, tctx
, handle
, &names
, false)) {
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");
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
));
873 torture_assert_ntstatus_ok(tctx
,
875 "LookupSids3 failed");
880 torture_comment(tctx
, "\n");
882 if (!test_LookupNames4(b
, tctx
, &names
, 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
;
899 torture_comment(tctx
, "\nTesting LookupSids3\n");
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 "
924 torture_assert_ntstatus_equal(tctx
,
926 NT_STATUS_ACCESS_DENIED
,
927 "LookupSids3 return value should "
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 "
937 nt_errstr(r
.out
.result
));
942 "LookupSids3 return value should be "
943 "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
948 bool test_many_LookupSids(struct dcerpc_pipe
*p
,
949 struct torture_context
*tctx
,
950 struct policy_handle
*handle
)
953 struct lsa_SidArray sids
;
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");
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
;
972 struct lsa_LookupSids r
;
973 struct lsa_TransNameArray names
;
974 struct lsa_RefDomainList
*domains
= NULL
;
978 r
.in
.handle
= handle
;
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
));
995 torture_comment(tctx
, "\n");
997 if (!test_LookupNames(b
, tctx
, handle
, &names
)) {
1002 if (transport
== NCACN_NP
) {
1003 if (!test_LookupSids3_fail(b
, tctx
, &sids
)) {
1006 if (!test_LookupNames4_fail(b
, tctx
)) {
1009 } else if (transport
== NCACN_IP_TCP
) {
1010 struct lsa_TransNameArray2 names
;
1011 enum dcerpc_AuthType auth_type
;
1012 enum dcerpc_AuthLevel auth_level
;
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
)) {
1025 if (!test_LookupNames4(b
, tctx
, &names
, true)) {
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
)) {
1036 if (!test_LookupNames4_fail(b
, tctx
)) {
1042 torture_comment(tctx
, "\n");
1049 static void lookupsids_cb(struct tevent_req
*subreq
)
1051 int *replies
= (int *)tevent_req_callback_data_void(subreq
);
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
));
1061 if (*replies
>= 0) {
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
;
1073 struct lsa_TransNameArray
*names
;
1074 struct lsa_LookupSids
*r
;
1075 struct lsa_RefDomainList
*domains
= NULL
;
1076 struct tevent_req
**req
;
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
);
1090 sids
.sids
= &sidptr
;
1091 sidptr
.sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-545");
1095 for (i
=0; i
<num_async_requests
; i
++) {
1098 names
[i
].names
= NULL
;
1100 r
[i
].in
.handle
= handle
;
1101 r
[i
].in
.sids
= &sids
;
1102 r
[i
].in
.names
= &names
[i
];
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
) {
1115 tevent_req_set_callback(req
[i
], lookupsids_cb
, &replies
);
1118 while (replies
>= 0 && replies
< num_async_requests
) {
1119 tevent_loop_once(tctx
->ev
);
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
;
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");
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
;
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");
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
;
1180 torture_comment(tctx
, "\nTesting RemovePrivilegesFromAccount\n");
1182 r
.in
.handle
= acct_handle
;
1183 r
.in
.remove_all
= 0;
1184 r
.in
.privs
= &privs
;
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
));
1210 /* Windows 2008 does not allow this to be removed */
1211 if (strcmp("SeAuditPrivilege", name
->string
) == 0) {
1215 torture_comment(tctx
, "RemovePrivilegesFromAccount failed to remove %s - %s\n",
1217 nt_errstr(r
.out
.result
));
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
;
1233 torture_comment(tctx
, "\nTesting AddPrivilegesToAccount\n");
1235 r
.in
.handle
= acct_handle
;
1236 r
.in
.privs
= &privs
;
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");
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
;
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) {
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
);
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");
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
),
1349 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_NOT_SUPPORTED
,
1350 "Delete should have failed NT_STATUS_NOT_SUPPORTED");
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");
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
;
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");
1405 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1406 "CreateAccount failed");
1409 if (!test_Delete(b
, tctx
, &acct_handle
)) {
1413 if (!test_DeleteObject(b
, tctx
, &acct_handle
)) {
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
)) {
1442 if (!test_DeleteObject(b
, tctx
, &trustdom_handle
)) {
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
;
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");
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
;
1487 DATA_BLOB session_key
;
1488 NTTIME old_mtime
, new_mtime
;
1490 const char *secret1
= "abcdef12345699qwerty";
1492 const char *secret3
= "ABCDEF12345699QWERTY";
1494 const char *secret5
= "NEW-SAMBA4-SECRET";
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 */
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
;
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
));
1597 if (r4
.out
.new_val
== NULL
|| r4
.out
.new_val
->buf
== NULL
) {
1598 torture_comment(tctx
, "No secret buffer returned\n");
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",
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
;
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
));
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
;
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
));
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");
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
);
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
);
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",
1690 nt_time_string(tctx
, *r6
.out
.old_mtime
),
1691 nt_time_string(tctx
, *r6
.out
.new_mtime
));
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
));
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
;
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
));
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");
1736 } else if (r8
.out
.new_val
->buf
!= NULL
) {
1737 torture_comment(tctx
, "NEW secret buffer must not be returned after OLD set\n");
1739 } else if (r8
.out
.old_val
->buf
== NULL
) {
1740 torture_comment(tctx
, "OLD secret buffer was not returned after OLD set\n");
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");
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
);
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",
1760 nt_time_string(tctx
, *r8
.out
.old_mtime
),
1761 nt_time_string(tctx
, *r8
.out
.new_mtime
));
1767 if (!test_Delete(b
, tctx
, &sec_handle
)) {
1771 if (!test_DeleteObject(b
, tctx
, &sec_handle
)) {
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");
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
;
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");
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");
1833 torture_comment(tctx
, "\nTesting QuerySecurity\n");
1835 r
.in
.handle
= acct_handle
;
1836 r
.in
.sec_info
= SECINFO_OWNER
|
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
));
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
;
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
)) {
1875 if (!test_GetSystemAccessAccount(b
, tctx
, handle
, &acct_handle
)) {
1879 if (!test_QuerySecurity(b
, tctx
, handle
, &acct_handle
)) {
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;
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
;
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
)) {
1911 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1912 "EnumAccounts failed");
1914 if (!test_LookupSids(b
, tctx
, handle
, &sids1
)) {
1918 if (!test_LookupSids2(b
, tctx
, handle
, &sids1
)) {
1922 /* Can't test lookupSids3 here, as clearly we must not
1923 * be on schannel, or we would not be able to do the
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) {
1938 torture_comment(tctx
, "Trying EnumAccounts partial listing (asking for 1 at 2)\n");
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
);
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
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
));
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
);
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
;
2000 torture_comment(tctx
, "\nTesting EnumAccountsWithUserRight(%s)\n", priv_name
->string
);
2002 r
.in
.handle
= handle
;
2003 r
.in
.name
= priv_name
;
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
)) {
2014 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2015 torture_comment(tctx
, "EnumAccountsWithUserRight failed - %s\n", nt_errstr(r
.out
.result
));
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;
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
;
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
)) {
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
)
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");
2075 ZERO_STRUCT(string
);
2077 if (trusted_domain_name
) {
2078 init_lsa_String(&string
, trusted_domain_name
);
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
));
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
)
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
);
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
)
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
;
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
));
2152 if (!NT_STATUS_IS_OK(trust
.out
.result
)) {
2153 torture_comment(tctx
, "OpenTrustedDomain failed - %s\n", nt_errstr(trust
.out
.result
));
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
];
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
));
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
));
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
));
2189 c
.in
.handle
= &trustdom_handle
;
2190 c
.out
.handle
= &handle2
;
2192 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_Close_r(b
, tctx
, &c
),
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
));
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
) {
2207 q
.in
.handle
= handle
;
2208 q
.in
.dom_sid
= domains
->domains
[i
].sid
;
2209 q
.in
.level
= levels
[j
];
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
));
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
));
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
));
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
));
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
];
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
));
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
));
2264 c
.in
.handle
= &trustdom_handle
;
2265 c
.out
.handle
= &handle2
;
2267 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_Close_r(b
, tctx
, &c
),
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
));
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
];
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
));
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
));
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
;
2311 torture_comment(tctx
, "\nTesting EnumTrustDom\n");
2313 r
.in
.handle
= handle
;
2314 r
.in
.resume_handle
= &in_resume_handle
;
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
);
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");
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
));
2350 /* Start from the bottom again */
2351 in_resume_handle
= 0;
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
);
2381 /* NO_MORE_ENTRIES is allowed */
2382 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_NO_MORE_ENTRIES
)) {
2383 if (domains
.count
== 0) {
2386 torture_comment(tctx
, "EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
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
);
2397 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2398 torture_comment(tctx
, "EnumTrustDom failed - %s\n", nt_errstr(r
.out
.result
));
2402 if (domains
.count
== 0) {
2403 torture_comment(tctx
, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
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
)));
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
;
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
);
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");
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
));
2467 in_resume_handle
= 0;
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) {
2485 torture_comment(tctx
, "EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
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
,
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
));
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");
2507 ret
&= test_query_each_TrustDomEx(b
, tctx
, handle
, &domains_ex
);
2509 } while ((NT_STATUS_EQUAL(r_ex
.out
.result
, STATUS_MORE_ENTRIES
)));
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
)
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
;
2529 torture_comment(tctx
, "\nTesting CreateTrustedDomain for %d domains\n", num_trusts
);
2531 if (!test_EnumTrustDom(b
, tctx
, handle
)) {
2535 if (!test_EnumTrustDomEx(b
, tctx
, handle
)) {
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
));
2568 q
.in
.trustdom_handle
= &trustdom_handle
[i
];
2569 q
.in
.level
= LSA_TRUSTED_DOMAIN_INFO_INFO_EX
;
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
));
2576 } else if (!q
.out
.info
) {
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
);
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
);
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
);
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);
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
);
2608 /* now that we have some domains to look over, we can test the enum calls */
2609 if (!test_EnumTrustDom(b
, tctx
, handle
)) {
2613 if (!test_EnumTrustDomEx(b
, tctx
, handle
)) {
2617 for (i
=0; i
<num_trusts
; i
++) {
2618 if (!test_DeleteTrustedDomainBySid(b
, tctx
, handle
, domsid
[i
])) {
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
;
2643 authinfo_internal
= talloc_zero(mem_ctx
, struct lsa_TrustDomainInfoAuthInfoInternal
);
2644 if (authinfo_internal
== NULL
) {
2648 in_info
.AuthType
= TRUST_AUTH_TYPE_CLEAR
;
2649 ok
= convert_string_talloc(mem_ctx
, CH_UNIX
, CH_UTF16
,
2651 strlen(incoming_new
),
2652 &in_info
.AuthInfo
.clear
.password
,
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
,
2662 strlen(incoming_old
),
2663 &io_info
.AuthInfo
.clear
.password
,
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
,
2673 strlen(outgoing_new
),
2674 &on_info
.AuthInfo
.clear
.password
,
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
,
2684 strlen(outgoing_old
),
2685 &oo_info
.AuthInfo
.clear
.password
,
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
)) {
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
;
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
;
2734 authinfo
= talloc_zero(mem_ctx
, struct lsa_TrustDomainInfoAuthInfo
);
2735 if (authinfo
== NULL
) {
2739 in_buffer
= talloc_zero(authinfo
, struct lsa_TrustDomainInfoBuffer
);
2740 if (in_buffer
== NULL
) {
2743 in_buffer
->AuthType
= TRUST_AUTH_TYPE_CLEAR
;
2744 ok
= convert_string_talloc(in_buffer
, CH_UNIX
, CH_UTF16
,
2746 strlen(incoming_new
),
2747 &in_buffer
->data
.data
,
2752 in_buffer
->data
.size
= converted_size
;
2754 io_buffer
= talloc_zero(authinfo
, struct lsa_TrustDomainInfoBuffer
);
2755 if (io_buffer
== NULL
) {
2758 io_buffer
->AuthType
= TRUST_AUTH_TYPE_CLEAR
;
2759 ok
= convert_string_talloc(io_buffer
, CH_UNIX
, CH_UTF16
,
2761 strlen(incoming_old
),
2762 &io_buffer
->data
.data
,
2767 io_buffer
->data
.size
= converted_size
;
2769 on_buffer
= talloc_zero(authinfo
, struct lsa_TrustDomainInfoBuffer
);
2770 if (on_buffer
== NULL
) {
2773 on_buffer
->AuthType
= TRUST_AUTH_TYPE_CLEAR
;
2774 ok
= convert_string_talloc(on_buffer
, CH_UNIX
, CH_UTF16
,
2776 strlen(outgoing_new
),
2777 &on_buffer
->data
.data
,
2782 on_buffer
->data
.size
= converted_size
;
2784 oo_buffer
= talloc_zero(authinfo
, struct lsa_TrustDomainInfoBuffer
);
2785 if (oo_buffer
== NULL
) {
2788 oo_buffer
->AuthType
= TRUST_AUTH_TYPE_CLEAR
;
2789 ok
= convert_string_talloc(oo_buffer
, CH_UNIX
, CH_UTF16
,
2791 strlen(outgoing_old
),
2792 &oo_buffer
->data
.data
,
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
;
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
;
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
;
2851 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
2853 a
.in
.secure_channel_type
,
2854 &credentials1
, &credentials2
,
2855 new_password
, &credentials3
,
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");
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
,
2878 a
.in
.secure_channel_type
,
2879 &credentials1
, &credentials2
,
2880 old_password
, &credentials3
,
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");
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");
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
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
2920 struct check_pw_with_krb5_ctx
{
2921 struct addrinfo
*server
;
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
,
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
;
2975 hi
.proto
= KRB5_KRBHST_TCP
;
2977 smb_krb5_free_error(ctx
->smb_krb5_context
->krb5_context
,
2981 k5ret
= smb_krb5_send_and_recv_func_forced(context
, ctx
->server
,
2982 &hi
, timeout
, send_buf
, recv_buf
);
2988 ret
= decode_KRB_ERROR(recv_buf
->data
, recv_buf
->length
,
2989 &ctx
->error
, &used
);
2991 ctx
->counts
.errors
++;
2992 ctx
->counts
.error_io
= ctx
->counts
.io
;
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
);
3007 if (ctx
->krb_options
!= NULL
) {
3008 krb5_get_init_creds_opt_free(ctx
->smb_krb5_context
->krb5_context
,
3010 ctx
->krb_options
= NULL
;
3013 krb5_free_cred_contents(ctx
->smb_krb5_context
->krb5_context
,
3016 if (ctx
->opt_canon
!= NULL
) {
3017 krb5_get_creds_opt_free(ctx
->smb_krb5_context
->krb5_context
,
3019 ctx
->opt_canon
= NULL
;
3022 if (ctx
->opt_nocanon
!= NULL
) {
3023 krb5_get_creds_opt_free(ctx
->smb_krb5_context
->krb5_context
,
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
,
3037 ctx
->upn_realm
= NULL
;
3040 if (ctx
->upn_dns
!= NULL
) {
3041 krb5_free_principal(ctx
->smb_krb5_context
->krb5_context
,
3043 ctx
->upn_dns
= NULL
;
3046 if (ctx
->upn_netbios
!= NULL
) {
3047 krb5_free_principal(ctx
->smb_krb5_context
->krb5_context
,
3049 ctx
->upn_netbios
= NULL
;
3052 if (ctx
->krbtgt_trust_realm
!= NULL
) {
3053 krb5_free_principal(ctx
->smb_krb5_context
->krb5_context
,
3054 ctx
->krbtgt_trust_realm
);
3055 ctx
->krbtgt_trust_realm
= NULL
;
3058 if (ctx
->krbtgt_trust_realm_creds
!= NULL
) {
3059 krb5_free_creds(ctx
->smb_krb5_context
->krb5_context
,
3060 ctx
->krbtgt_trust_realm_creds
);
3061 ctx
->krbtgt_trust_realm_creds
= NULL
;
3064 if (ctx
->krbtgt_trust_dns
!= NULL
) {
3065 krb5_free_principal(ctx
->smb_krb5_context
->krb5_context
,
3066 ctx
->krbtgt_trust_dns
);
3067 ctx
->krbtgt_trust_dns
= NULL
;
3070 if (ctx
->krbtgt_trust_dns_creds
!= NULL
) {
3071 krb5_free_creds(ctx
->smb_krb5_context
->krb5_context
,
3072 ctx
->krbtgt_trust_dns_creds
);
3073 ctx
->krbtgt_trust_dns_creds
= NULL
;
3076 if (ctx
->krbtgt_trust_netbios
!= NULL
) {
3077 krb5_free_principal(ctx
->smb_krb5_context
->krb5_context
,
3078 ctx
->krbtgt_trust_netbios
);
3079 ctx
->krbtgt_trust_netbios
= NULL
;
3082 if (ctx
->krbtgt_trust_netbios_creds
!= NULL
) {
3083 krb5_free_creds(ctx
->smb_krb5_context
->krb5_context
,
3084 ctx
->krbtgt_trust_netbios_creds
);
3085 ctx
->krbtgt_trust_netbios_creds
= NULL
;
3088 if (ctx
->cifs_trust_dns
!= NULL
) {
3089 krb5_free_principal(ctx
->smb_krb5_context
->krb5_context
,
3090 ctx
->cifs_trust_dns
);
3091 ctx
->cifs_trust_dns
= NULL
;
3094 if (ctx
->cifs_trust_dns_creds
!= NULL
) {
3095 krb5_free_creds(ctx
->smb_krb5_context
->krb5_context
,
3096 ctx
->cifs_trust_dns_creds
);
3097 ctx
->cifs_trust_dns_creds
= NULL
;
3100 if (ctx
->cifs_trust_netbios
!= NULL
) {
3101 krb5_free_principal(ctx
->smb_krb5_context
->krb5_context
,
3102 ctx
->cifs_trust_netbios
);
3103 ctx
->cifs_trust_netbios
= NULL
;
3106 if (ctx
->cifs_trust_netbios_creds
!= NULL
) {
3107 krb5_free_creds(ctx
->smb_krb5_context
->krb5_context
,
3108 ctx
->cifs_trust_netbios_creds
);
3109 ctx
->cifs_trust_netbios_creds
= NULL
;
3112 if (ctx
->drs_trust_dns
!= NULL
) {
3113 krb5_free_principal(ctx
->smb_krb5_context
->krb5_context
,
3114 ctx
->drs_trust_dns
);
3115 ctx
->drs_trust_dns
= NULL
;
3118 if (ctx
->drs_trust_dns_creds
!= NULL
) {
3119 krb5_free_creds(ctx
->smb_krb5_context
->krb5_context
,
3120 ctx
->drs_trust_dns_creds
);
3121 ctx
->drs_trust_dns_creds
= NULL
;
3124 if (ctx
->drs_trust_netbios
!= NULL
) {
3125 krb5_free_principal(ctx
->smb_krb5_context
->krb5_context
,
3126 ctx
->drs_trust_netbios
);
3127 ctx
->drs_trust_netbios
= NULL
;
3130 if (ctx
->drs_trust_netbios_creds
!= NULL
) {
3131 krb5_free_creds(ctx
->smb_krb5_context
->krb5_context
,
3132 ctx
->drs_trust_netbios_creds
);
3133 ctx
->drs_trust_netbios_creds
= NULL
;
3136 if (ctx
->four_trust_dns
!= NULL
) {
3137 krb5_free_principal(ctx
->smb_krb5_context
->krb5_context
,
3138 ctx
->four_trust_dns
);
3139 ctx
->four_trust_dns
= NULL
;
3142 if (ctx
->four_trust_dns_creds
!= NULL
) {
3143 krb5_free_creds(ctx
->smb_krb5_context
->krb5_context
,
3144 ctx
->four_trust_dns_creds
);
3145 ctx
->four_trust_dns_creds
= NULL
;
3148 krb5_free_cred_contents(ctx
->smb_krb5_context
->krb5_context
,
3149 &ctx
->krbtgt_referral_creds
);
3151 free_Ticket(&ctx
->krbtgt_referral_ticket
);
3153 krb5_free_keyblock_contents(ctx
->smb_krb5_context
->krb5_context
,
3154 &ctx
->krbtgt_referral_keyblock
);
3156 free_EncTicketPart(&ctx
->krbtgt_referral_enc_part
);
3158 smb_krb5_free_error(ctx
->smb_krb5_context
->krb5_context
,
3161 talloc_unlink(ctx
, ctx
->smb_krb5_context
);
3162 ctx
->smb_krb5_context
= NULL
;
3166 static bool check_pw_with_krb5(struct torture_context
*tctx
,
3167 struct cli_credentials
*credentials
,
3168 const struct lsa_TrustDomainInfoInfoEx
*trusted
)
3170 const char *trusted_dns_name
= trusted
->domain_name
.string
;
3171 const char *trusted_netbios_name
= trusted
->netbios_name
.string
;
3172 char *trusted_realm_name
= NULL
;
3173 krb5_principal principal
= NULL
;
3174 enum credentials_obtained obtained
;
3175 const char *error_string
= NULL
;
3176 const char *workstation
= cli_credentials_get_workstation(credentials
);
3177 const char *password
= cli_credentials_get_password(credentials
);
3178 const struct samr_Password
*nthash
= NULL
;
3179 const struct samr_Password
*old_nthash
= NULL
;
3180 const char *old_password
= cli_credentials_get_old_password(credentials
);
3181 int kvno
= cli_credentials_get_kvno(credentials
);
3182 int expected_kvno
= 0;
3183 krb5uint32 t_kvno
= 0;
3184 const char *host
= torture_setting_string(tctx
, "host", NULL
);
3185 krb5_error_code k5ret
;
3189 struct check_pw_with_krb5_ctx
*ctx
= NULL
;
3190 char *assertion_message
= NULL
;
3191 const char *realm
= NULL
;
3192 char *upn_realm_string
= NULL
;
3193 char *upn_dns_string
= NULL
;
3194 char *upn_netbios_string
= NULL
;
3195 char *krbtgt_cc_name
= NULL
;
3196 char *krbtgt_trust_realm_string
= NULL
;
3197 char *krbtgt_trust_dns_string
= NULL
;
3198 char *krbtgt_trust_netbios_string
= NULL
;
3199 char *cifs_trust_dns_string
= NULL
;
3200 char *cifs_trust_netbios_string
= NULL
;
3201 char *drs_trust_dns_string
= NULL
;
3202 char *drs_trust_netbios_string
= NULL
;
3203 char *four_trust_dns_string
= NULL
;
3205 ctx
= talloc_zero(tctx
, struct check_pw_with_krb5_ctx
);
3206 torture_assert(tctx
, ctx
!= NULL
, "Failed to allocate");
3208 realm
= cli_credentials_get_realm(credentials
);
3209 trusted_realm_name
= strupper_talloc(tctx
, trusted_dns_name
);
3211 nthash
= cli_credentials_get_nt_hash(credentials
, ctx
);
3212 old_nthash
= cli_credentials_get_old_nt_hash(credentials
, ctx
);
3214 k5ret
= smb_krb5_init_context(ctx
, tctx
->lp_ctx
, &ctx
->smb_krb5_context
);
3215 torture_assert_int_equal(tctx
, k5ret
, 0, "smb_krb5_init_context failed");
3217 ok
= interpret_string_addr_internal(&ctx
->server
, host
, AI_NUMERICHOST
);
3218 torture_assert(tctx
, ok
, "Failed to parse target server");
3219 talloc_set_destructor(ctx
, check_pw_with_krb5_ctx_destructor
);
3221 set_sockaddr_port(ctx
->server
->ai_addr
, 88);
3223 k5ret
= krb5_set_send_to_kdc_func(ctx
->smb_krb5_context
->krb5_context
,
3224 check_pw_with_krb5_send_and_recv_func
,
3226 torture_assert_int_equal(tctx
, k5ret
, 0, "krb5_set_send_to_kdc_func failed");
3228 torture_assert_int_equal(tctx
,
3229 krb5_get_init_creds_opt_alloc(ctx
->smb_krb5_context
->krb5_context
,
3231 0, "krb5_get_init_creds_opt_alloc failed");
3232 torture_assert_int_equal(tctx
,
3233 krb5_get_init_creds_opt_set_pac_request(
3234 ctx
->smb_krb5_context
->krb5_context
,
3235 ctx
->krb_options
, true),
3236 0, "krb5_get_init_creds_opt_set_pac_request failed");
3238 upn_realm_string
= talloc_asprintf(ctx
, "user@%s",
3239 trusted_realm_name
);
3240 torture_assert_int_equal(tctx
,
3241 smb_krb5_make_principal(ctx
->smb_krb5_context
->krb5_context
,
3243 realm
, upn_realm_string
, NULL
),
3244 0, "smb_krb5_make_principal failed");
3245 krb5_principal_set_type(ctx
->smb_krb5_context
->krb5_context
,
3246 ctx
->upn_realm
, KRB5_NT_ENTERPRISE_PRINCIPAL
);
3248 upn_dns_string
= talloc_asprintf(ctx
, "user@%s",
3250 torture_assert_int_equal(tctx
,
3251 smb_krb5_make_principal(ctx
->smb_krb5_context
->krb5_context
,
3253 realm
, upn_dns_string
, NULL
),
3254 0, "smb_krb5_make_principal failed");
3255 krb5_principal_set_type(ctx
->smb_krb5_context
->krb5_context
,
3256 ctx
->upn_dns
, KRB5_NT_ENTERPRISE_PRINCIPAL
);
3258 upn_netbios_string
= talloc_asprintf(ctx
, "user@%s",
3259 trusted_netbios_name
);
3260 torture_assert_int_equal(tctx
,
3261 smb_krb5_make_principal(ctx
->smb_krb5_context
->krb5_context
,
3263 realm
, upn_netbios_string
, NULL
),
3264 0, "smb_krb5_make_principal failed");
3265 krb5_principal_set_type(ctx
->smb_krb5_context
->krb5_context
,
3266 ctx
->upn_netbios
, KRB5_NT_ENTERPRISE_PRINCIPAL
);
3268 k5ret
= principal_from_credentials(ctx
, credentials
, ctx
->smb_krb5_context
,
3269 &principal
, &obtained
, &error_string
);
3270 torture_assert_int_equal(tctx
, k5ret
, 0, error_string
);
3272 ZERO_STRUCT(ctx
->counts
);
3273 k5ret
= krb5_get_init_creds_password(ctx
->smb_krb5_context
->krb5_context
,
3274 &ctx
->my_creds
, ctx
->upn_realm
,
3275 "_none_", NULL
, NULL
, 0,
3276 NULL
, ctx
->krb_options
);
3277 assertion_message
= talloc_asprintf(ctx
,
3278 "krb5_get_init_creds_password(%s, canon) for failed: "
3279 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3282 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3284 trusted
->trust_direction
,
3285 trusted
->trust_type
,
3286 trusted
->trust_attributes
,
3287 ctx
->counts
.io
, ctx
->counts
.error_io
, ctx
->counts
.errors
, ctx
->counts
.ok
);
3288 torture_assert_int_equal(tctx
, k5ret
, KRB5_KDC_UNREACH
, assertion_message
);
3289 torture_assert_int_equal(tctx
, ctx
->counts
.io
, 1, assertion_message
);
3290 torture_assert_int_equal(tctx
, ctx
->counts
.error_io
, 1, assertion_message
);
3291 torture_assert_int_equal(tctx
, ctx
->error
.error_code
, 68, assertion_message
);
3292 torture_assert(tctx
, ctx
->error
.crealm
!= NULL
, assertion_message
);
3293 torture_assert_str_equal(tctx
, *ctx
->error
.crealm
, trusted_realm_name
, assertion_message
);
3294 torture_assert(tctx
, ctx
->error
.cname
== NULL
, assertion_message
);
3295 torture_assert_str_equal(tctx
, ctx
->error
.realm
, realm
, assertion_message
);
3297 ZERO_STRUCT(ctx
->counts
);
3298 k5ret
= krb5_get_init_creds_password(ctx
->smb_krb5_context
->krb5_context
,
3299 &ctx
->my_creds
, ctx
->upn_dns
,
3300 "_none_", NULL
, NULL
, 0,
3301 NULL
, ctx
->krb_options
);
3302 assertion_message
= talloc_asprintf(ctx
,
3303 "krb5_get_init_creds_password(%s, canon) for failed: "
3304 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3307 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3309 trusted
->trust_direction
,
3310 trusted
->trust_type
,
3311 trusted
->trust_attributes
,
3312 ctx
->counts
.io
, ctx
->counts
.error_io
, ctx
->counts
.errors
, ctx
->counts
.ok
);
3313 torture_assert_int_equal(tctx
, k5ret
, KRB5_KDC_UNREACH
, assertion_message
);
3314 torture_assert_int_equal(tctx
, ctx
->counts
.io
, 1, assertion_message
);
3315 torture_assert_int_equal(tctx
, ctx
->counts
.error_io
, 1, assertion_message
);
3316 torture_assert_int_equal(tctx
, ctx
->error
.error_code
, 68, assertion_message
);
3317 torture_assert(tctx
, ctx
->error
.crealm
!= NULL
, assertion_message
);
3318 torture_assert_str_equal(tctx
, *ctx
->error
.crealm
, trusted_realm_name
, assertion_message
);
3319 torture_assert(tctx
, ctx
->error
.cname
== NULL
, assertion_message
);
3320 torture_assert_str_equal(tctx
, ctx
->error
.realm
, realm
, assertion_message
);
3322 ZERO_STRUCT(ctx
->counts
);
3323 k5ret
= krb5_get_init_creds_password(ctx
->smb_krb5_context
->krb5_context
,
3324 &ctx
->my_creds
, ctx
->upn_netbios
,
3325 "_none_", NULL
, NULL
, 0,
3326 NULL
, ctx
->krb_options
);
3327 assertion_message
= talloc_asprintf(ctx
,
3328 "krb5_get_init_creds_password(%s, canon) for failed: "
3329 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3332 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3334 trusted
->trust_direction
,
3335 trusted
->trust_type
,
3336 trusted
->trust_attributes
,
3337 ctx
->counts
.io
, ctx
->counts
.error_io
, ctx
->counts
.errors
, ctx
->counts
.ok
);
3338 torture_assert_int_equal(tctx
, k5ret
, KRB5_KDC_UNREACH
, assertion_message
);
3339 torture_assert_int_equal(tctx
, ctx
->counts
.io
, 1, assertion_message
);
3340 torture_assert_int_equal(tctx
, ctx
->counts
.error_io
, 1, assertion_message
);
3341 torture_assert_int_equal(tctx
, ctx
->error
.error_code
, 68, assertion_message
);
3342 torture_assert(tctx
, ctx
->error
.crealm
!= NULL
, assertion_message
);
3343 torture_assert_str_equal(tctx
, *ctx
->error
.crealm
, trusted_realm_name
, assertion_message
);
3344 torture_assert(tctx
, ctx
->error
.cname
== NULL
, assertion_message
);
3345 torture_assert_str_equal(tctx
, ctx
->error
.realm
, realm
, assertion_message
);
3347 torture_comment(tctx
, "password[%s] old_password[%s]\n",
3348 password
, old_password
);
3349 if (old_password
!= NULL
) {
3350 k5ret
= krb5_get_init_creds_password(ctx
->smb_krb5_context
->krb5_context
,
3351 &ctx
->my_creds
, principal
,
3352 old_password
, NULL
, NULL
, 0,
3353 NULL
, ctx
->krb_options
);
3354 torture_assert_int_equal(tctx
, k5ret
, KRB5KDC_ERR_PREAUTH_FAILED
,
3355 "preauth should fail with old password");
3358 k5ret
= krb5_get_init_creds_password(ctx
->smb_krb5_context
->krb5_context
,
3359 &ctx
->my_creds
, principal
,
3360 password
, NULL
, NULL
, 0,
3361 NULL
, ctx
->krb_options
);
3362 if (k5ret
== KRB5KDC_ERR_PREAUTH_FAILED
) {
3367 assertion_message
= talloc_asprintf(ctx
,
3368 "krb5_get_init_creds_password for failed: %s",
3369 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3371 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
3373 torture_assert_int_equal(tctx
,
3374 krb5_get_creds_opt_alloc(ctx
->smb_krb5_context
->krb5_context
,
3376 0, "krb5_get_creds_opt_alloc");
3378 krb5_get_creds_opt_add_options(ctx
->smb_krb5_context
->krb5_context
,
3380 KRB5_GC_CANONICALIZE
);
3382 krb5_get_creds_opt_add_options(ctx
->smb_krb5_context
->krb5_context
,
3386 torture_assert_int_equal(tctx
,
3387 krb5_get_creds_opt_alloc(ctx
->smb_krb5_context
->krb5_context
,
3389 0, "krb5_get_creds_opt_alloc");
3391 krb5_get_creds_opt_add_options(ctx
->smb_krb5_context
->krb5_context
,
3395 krbtgt_cc_name
= talloc_asprintf(ctx
, "MEMORY:%p.krbtgt", ctx
->smb_krb5_context
);
3396 torture_assert_int_equal(tctx
,
3397 krb5_cc_resolve(ctx
->smb_krb5_context
->krb5_context
,
3399 &ctx
->krbtgt_ccache
),
3400 0, "krb5_cc_resolve failed");
3402 torture_assert_int_equal(tctx
,
3403 krb5_cc_initialize(ctx
->smb_krb5_context
->krb5_context
,
3405 ctx
->my_creds
.client
),
3406 0, "krb5_cc_initialize failed");
3408 torture_assert_int_equal(tctx
,
3409 krb5_cc_store_cred(ctx
->smb_krb5_context
->krb5_context
,
3412 0, "krb5_cc_store_cred failed");
3414 krbtgt_trust_realm_string
= talloc_asprintf(ctx
, "krbtgt/%s@%s",
3415 trusted_realm_name
, realm
);
3416 torture_assert_int_equal(tctx
,
3417 smb_krb5_make_principal(ctx
->smb_krb5_context
->krb5_context
,
3418 &ctx
->krbtgt_trust_realm
,
3420 trusted_realm_name
, NULL
),
3421 0, "smb_krb5_make_principal failed");
3423 krbtgt_trust_dns_string
= talloc_asprintf(ctx
, "krbtgt/%s@%s",
3424 trusted_dns_name
, realm
);
3425 torture_assert_int_equal(tctx
,
3426 smb_krb5_make_principal(ctx
->smb_krb5_context
->krb5_context
,
3427 &ctx
->krbtgt_trust_dns
,
3429 trusted_dns_name
, NULL
),
3430 0, "smb_krb5_make_principal failed");
3432 krbtgt_trust_netbios_string
= talloc_asprintf(ctx
, "krbtgt/%s@%s",
3433 trusted_netbios_name
, realm
);
3434 torture_assert_int_equal(tctx
,
3435 smb_krb5_make_principal(ctx
->smb_krb5_context
->krb5_context
,
3436 &ctx
->krbtgt_trust_netbios
,
3438 trusted_netbios_name
, NULL
),
3439 0, "smb_krb5_make_principal failed");
3441 /* Confirm if we can do a TGS for krbtgt/trusted_realm */
3442 ZERO_STRUCT(ctx
->counts
);
3443 k5ret
= krb5_get_creds(ctx
->smb_krb5_context
->krb5_context
,
3446 ctx
->krbtgt_trust_realm
,
3447 &ctx
->krbtgt_trust_realm_creds
);
3448 assertion_message
= talloc_asprintf(ctx
,
3449 "krb5_get_creds(%s, canon) for failed: "
3450 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3451 krbtgt_trust_realm_string
,
3453 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3455 trusted
->trust_direction
,
3456 trusted
->trust_type
,
3457 trusted
->trust_attributes
,
3458 ctx
->counts
.io
, ctx
->counts
.errors
, ctx
->counts
.ok
);
3459 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
3460 torture_assert_int_equal(tctx
, ctx
->counts
.io
, 1, assertion_message
);
3461 torture_assert_int_equal(tctx
, ctx
->counts
.ok
, 1, assertion_message
);
3463 k5ok
= krb5_principal_compare(ctx
->smb_krb5_context
->krb5_context
,
3464 ctx
->krbtgt_trust_realm_creds
->server
,
3465 ctx
->krbtgt_trust_realm
);
3466 torture_assert(tctx
, k5ok
, assertion_message
);
3467 type
= smb_krb5_principal_get_type(ctx
->smb_krb5_context
->krb5_context
,
3468 ctx
->krbtgt_trust_realm_creds
->server
);
3469 torture_assert_int_equal(tctx
, type
, KRB5_NT_SRV_INST
, assertion_message
);
3471 /* Confirm if we have no referral ticket in the cache */
3472 krb5_free_cred_contents(ctx
->smb_krb5_context
->krb5_context
,
3473 &ctx
->krbtgt_referral_creds
);
3474 k5ret
= krb5_cc_retrieve_cred(ctx
->smb_krb5_context
->krb5_context
,
3477 ctx
->krbtgt_trust_realm_creds
,
3478 &ctx
->krbtgt_referral_creds
);
3479 assertion_message
= talloc_asprintf(ctx
,
3480 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3481 krbtgt_trust_realm_string
,
3483 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3485 torture_assert_int_equal(tctx
, k5ret
, KRB5_CC_END
, assertion_message
);
3487 /* Confirm if we can do a TGS for krbtgt/trusted_dns with CANON */
3488 ZERO_STRUCT(ctx
->counts
);
3489 k5ret
= krb5_get_creds(ctx
->smb_krb5_context
->krb5_context
,
3492 ctx
->krbtgt_trust_dns
,
3493 &ctx
->krbtgt_trust_dns_creds
);
3494 assertion_message
= talloc_asprintf(ctx
,
3495 "krb5_get_creds(%s, canon) for failed: "
3496 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3497 krbtgt_trust_dns_string
,
3499 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3501 trusted
->trust_direction
,
3502 trusted
->trust_type
,
3503 trusted
->trust_attributes
,
3504 ctx
->counts
.io
, ctx
->counts
.errors
, ctx
->counts
.ok
);
3505 torture_assert_int_equal(tctx
, k5ret
, KRB5_KDC_UNREACH
, assertion_message
);
3506 torture_assert_int_equal(tctx
, ctx
->counts
.io
, 1, assertion_message
);
3507 torture_assert_int_equal(tctx
, ctx
->counts
.ok
, 1, assertion_message
);
3509 /* Confirm if we have the referral ticket in the cache */
3510 krb5_free_cred_contents(ctx
->smb_krb5_context
->krb5_context
,
3511 &ctx
->krbtgt_referral_creds
);
3512 k5ret
= krb5_cc_retrieve_cred(ctx
->smb_krb5_context
->krb5_context
,
3515 ctx
->krbtgt_trust_realm_creds
,
3516 &ctx
->krbtgt_referral_creds
);
3517 assertion_message
= talloc_asprintf(ctx
,
3518 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3519 krbtgt_trust_realm_string
,
3521 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3523 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
3525 k5ok
= krb5_principal_compare(ctx
->smb_krb5_context
->krb5_context
,
3526 ctx
->krbtgt_referral_creds
.server
,
3527 ctx
->krbtgt_trust_realm
);
3528 torture_assert(tctx
, k5ok
, assertion_message
);
3529 type
= smb_krb5_principal_get_type(ctx
->smb_krb5_context
->krb5_context
,
3530 ctx
->krbtgt_referral_creds
.server
);
3531 torture_assert_int_equal(tctx
, type
, KRB5_NT_SRV_INST
, assertion_message
);
3532 k5ret
= decode_Ticket(ctx
->krbtgt_referral_creds
.ticket
.data
,
3533 ctx
->krbtgt_referral_creds
.ticket
.length
,
3534 &ctx
->krbtgt_referral_ticket
, NULL
);
3535 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
3537 expected_kvno
= kvno
- 1;
3539 if (ctx
->krbtgt_referral_ticket
.enc_part
.kvno
!= NULL
) {
3540 t_kvno
= *ctx
->krbtgt_referral_ticket
.enc_part
.kvno
;
3541 assertion_message
= talloc_asprintf(ctx
,
3542 "krbtgt_referral_ticket(%s) kvno(%u) expected(%u) current(%u)",
3543 krbtgt_trust_realm_string
,
3544 (unsigned)t_kvno
, (unsigned)expected_kvno
,(unsigned)kvno
);
3545 torture_comment(tctx
, "%s\n", assertion_message
);
3546 torture_assert_int_not_equal(tctx
, t_kvno
, 0, assertion_message
);
3548 assertion_message
= talloc_asprintf(ctx
,
3549 "krbtgt_referral_ticket(%s) kvno(NULL) exptected(%u) current(%u)",
3550 krbtgt_trust_realm_string
,
3551 (unsigned)expected_kvno
,(unsigned)kvno
);
3552 torture_comment(tctx
, "%s\n", assertion_message
);
3554 torture_assert_int_equal(tctx
, t_kvno
, expected_kvno
, assertion_message
);
3556 if (old_nthash
!= NULL
&& expected_kvno
!= kvno
) {
3557 torture_comment(tctx
, "old_nthash: %s\n", assertion_message
);
3558 k5ret
= smb_krb5_keyblock_init_contents(ctx
->smb_krb5_context
->krb5_context
,
3559 ENCTYPE_ARCFOUR_HMAC
,
3561 sizeof(old_nthash
->hash
),
3562 &ctx
->krbtgt_referral_keyblock
);
3563 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
3565 torture_comment(tctx
, "nthash: %s\n", assertion_message
);
3566 k5ret
= smb_krb5_keyblock_init_contents(ctx
->smb_krb5_context
->krb5_context
,
3567 ENCTYPE_ARCFOUR_HMAC
,
3569 sizeof(nthash
->hash
),
3570 &ctx
->krbtgt_referral_keyblock
);
3571 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
3573 k5ret
= krb5_decrypt_ticket(ctx
->smb_krb5_context
->krb5_context
,
3574 &ctx
->krbtgt_referral_ticket
,
3575 &ctx
->krbtgt_referral_keyblock
,
3576 &ctx
->krbtgt_referral_enc_part
,
3578 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
3580 /* Delete the referral ticket from the cache */
3581 k5ret
= krb5_cc_remove_cred(ctx
->smb_krb5_context
->krb5_context
,
3584 &ctx
->krbtgt_referral_creds
);
3585 assertion_message
= talloc_asprintf(ctx
,
3586 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3587 krbtgt_trust_realm_string
,
3589 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3591 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
3593 /* Confirm if we can do a TGS for krbtgt/trusted_dns no CANON */
3594 ZERO_STRUCT(ctx
->counts
);
3595 k5ret
= krb5_get_creds(ctx
->smb_krb5_context
->krb5_context
,
3598 ctx
->krbtgt_trust_dns
,
3599 &ctx
->krbtgt_trust_dns_creds
);
3600 assertion_message
= talloc_asprintf(ctx
,
3601 "krb5_get_creds(%s, nocanon) for failed: "
3602 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3603 krbtgt_trust_dns_string
,
3605 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3607 trusted
->trust_direction
,
3608 trusted
->trust_type
,
3609 trusted
->trust_attributes
,
3610 ctx
->counts
.io
, ctx
->counts
.errors
, ctx
->counts
.ok
);
3611 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
3612 torture_assert_int_equal(tctx
, ctx
->counts
.io
, 2, assertion_message
);
3613 torture_assert_int_equal(tctx
, ctx
->counts
.ok
, 2, assertion_message
);
3615 k5ok
= krb5_principal_compare(ctx
->smb_krb5_context
->krb5_context
,
3616 ctx
->krbtgt_trust_dns_creds
->server
,
3617 ctx
->krbtgt_trust_realm
);
3618 torture_assert(tctx
, k5ok
, assertion_message
);
3619 type
= smb_krb5_principal_get_type(ctx
->smb_krb5_context
->krb5_context
,
3620 ctx
->krbtgt_trust_dns_creds
->server
);
3621 torture_assert_int_equal(tctx
, type
, KRB5_NT_SRV_INST
, assertion_message
);
3623 /* Confirm if we have the referral ticket in the cache */
3624 krb5_free_cred_contents(ctx
->smb_krb5_context
->krb5_context
,
3625 &ctx
->krbtgt_referral_creds
);
3626 k5ret
= krb5_cc_retrieve_cred(ctx
->smb_krb5_context
->krb5_context
,
3629 ctx
->krbtgt_trust_realm_creds
,
3630 &ctx
->krbtgt_referral_creds
);
3631 assertion_message
= talloc_asprintf(ctx
,
3632 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3633 krbtgt_trust_realm_string
,
3635 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3637 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
3639 k5ok
= krb5_principal_compare(ctx
->smb_krb5_context
->krb5_context
,
3640 ctx
->krbtgt_referral_creds
.server
,
3641 ctx
->krbtgt_trust_realm
);
3642 torture_assert(tctx
, k5ok
, assertion_message
);
3643 type
= smb_krb5_principal_get_type(ctx
->smb_krb5_context
->krb5_context
,
3644 ctx
->krbtgt_referral_creds
.server
);
3645 torture_assert_int_equal(tctx
, type
, KRB5_NT_SRV_INST
, assertion_message
);
3647 /* Delete the referral ticket from the cache */
3648 k5ret
= krb5_cc_remove_cred(ctx
->smb_krb5_context
->krb5_context
,
3651 &ctx
->krbtgt_referral_creds
);
3652 assertion_message
= talloc_asprintf(ctx
,
3653 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3654 krbtgt_trust_realm_string
,
3656 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3658 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
3660 /* Confirm if we can do a TGS for krbtgt/NETBIOS with CANON */
3661 ZERO_STRUCT(ctx
->counts
);
3662 k5ret
= krb5_get_creds(ctx
->smb_krb5_context
->krb5_context
,
3665 ctx
->krbtgt_trust_netbios
,
3666 &ctx
->krbtgt_trust_netbios_creds
);
3667 assertion_message
= talloc_asprintf(ctx
,
3668 "krb5_get_creds(%s, canon) for failed: "
3669 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3670 krbtgt_trust_netbios_string
,
3672 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3674 trusted
->trust_direction
,
3675 trusted
->trust_type
,
3676 trusted
->trust_attributes
,
3677 ctx
->counts
.io
, ctx
->counts
.errors
, ctx
->counts
.ok
);
3678 torture_assert_int_equal(tctx
, k5ret
, KRB5_KDC_UNREACH
, assertion_message
);
3679 torture_assert_int_equal(tctx
, ctx
->counts
.io
, 1, assertion_message
);
3680 torture_assert_int_equal(tctx
, ctx
->counts
.ok
, 1, assertion_message
);
3682 /* Confirm if we have the referral ticket in the cache */
3683 krb5_free_cred_contents(ctx
->smb_krb5_context
->krb5_context
,
3684 &ctx
->krbtgt_referral_creds
);
3685 k5ret
= krb5_cc_retrieve_cred(ctx
->smb_krb5_context
->krb5_context
,
3688 ctx
->krbtgt_trust_realm_creds
,
3689 &ctx
->krbtgt_referral_creds
);
3690 assertion_message
= talloc_asprintf(ctx
,
3691 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3692 krbtgt_trust_netbios_string
,
3694 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3696 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
3698 k5ok
= krb5_principal_compare(ctx
->smb_krb5_context
->krb5_context
,
3699 ctx
->krbtgt_referral_creds
.server
,
3700 ctx
->krbtgt_trust_realm
);
3701 torture_assert(tctx
, k5ok
, assertion_message
);
3702 type
= smb_krb5_principal_get_type(ctx
->smb_krb5_context
->krb5_context
,
3703 ctx
->krbtgt_referral_creds
.server
);
3704 torture_assert_int_equal(tctx
, type
, KRB5_NT_SRV_INST
, assertion_message
);
3706 /* Delete the referral ticket from the cache */
3707 k5ret
= krb5_cc_remove_cred(ctx
->smb_krb5_context
->krb5_context
,
3710 &ctx
->krbtgt_referral_creds
);
3711 assertion_message
= talloc_asprintf(ctx
,
3712 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3713 krbtgt_trust_realm_string
,
3715 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3717 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
3719 /* Confirm if we can do a TGS for krbtgt/NETBIOS no CANON */
3720 ZERO_STRUCT(ctx
->counts
);
3721 k5ret
= krb5_get_creds(ctx
->smb_krb5_context
->krb5_context
,
3724 ctx
->krbtgt_trust_netbios
,
3725 &ctx
->krbtgt_trust_netbios_creds
);
3726 assertion_message
= talloc_asprintf(ctx
,
3727 "krb5_get_creds(%s, nocanon) for failed: "
3728 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3729 krbtgt_trust_netbios_string
,
3731 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3733 trusted
->trust_direction
,
3734 trusted
->trust_type
,
3735 trusted
->trust_attributes
,
3736 ctx
->counts
.io
, ctx
->counts
.errors
, ctx
->counts
.ok
);
3737 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
3738 torture_assert_int_equal(tctx
, ctx
->counts
.io
, 2, assertion_message
);
3739 torture_assert_int_equal(tctx
, ctx
->counts
.ok
, 2, assertion_message
);
3741 k5ok
= krb5_principal_compare(ctx
->smb_krb5_context
->krb5_context
,
3742 ctx
->krbtgt_trust_netbios_creds
->server
,
3743 ctx
->krbtgt_trust_realm
);
3744 torture_assert(tctx
, k5ok
, assertion_message
);
3745 type
= smb_krb5_principal_get_type(ctx
->smb_krb5_context
->krb5_context
,
3746 ctx
->krbtgt_trust_netbios_creds
->server
);
3747 torture_assert_int_equal(tctx
, type
, KRB5_NT_SRV_INST
, assertion_message
);
3749 /* Confirm if we have the referral ticket in the cache */
3750 krb5_free_cred_contents(ctx
->smb_krb5_context
->krb5_context
,
3751 &ctx
->krbtgt_referral_creds
);
3752 k5ret
= krb5_cc_retrieve_cred(ctx
->smb_krb5_context
->krb5_context
,
3755 ctx
->krbtgt_trust_realm_creds
,
3756 &ctx
->krbtgt_referral_creds
);
3757 assertion_message
= talloc_asprintf(ctx
,
3758 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3759 krbtgt_trust_realm_string
,
3761 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3763 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
3765 k5ok
= krb5_principal_compare(ctx
->smb_krb5_context
->krb5_context
,
3766 ctx
->krbtgt_referral_creds
.server
,
3767 ctx
->krbtgt_trust_realm
);
3768 torture_assert(tctx
, k5ok
, assertion_message
);
3769 type
= smb_krb5_principal_get_type(ctx
->smb_krb5_context
->krb5_context
,
3770 ctx
->krbtgt_referral_creds
.server
);
3771 torture_assert_int_equal(tctx
, type
, KRB5_NT_SRV_INST
, assertion_message
);
3773 /* Delete the referral ticket from the cache */
3774 k5ret
= krb5_cc_remove_cred(ctx
->smb_krb5_context
->krb5_context
,
3777 &ctx
->krbtgt_referral_creds
);
3778 assertion_message
= talloc_asprintf(ctx
,
3779 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3780 krbtgt_trust_realm_string
,
3782 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3784 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
3786 cifs_trust_dns_string
= talloc_asprintf(ctx
, "cifs/%s@%s",
3787 trusted_dns_name
, realm
);
3788 torture_assert_int_equal(tctx
,
3789 smb_krb5_make_principal(ctx
->smb_krb5_context
->krb5_context
,
3790 &ctx
->cifs_trust_dns
,
3792 trusted_dns_name
, NULL
),
3793 0, "smb_krb5_make_principal failed");
3795 /* Confirm if we get krbtgt/trusted_realm back when asking for cifs/trusted_realm */
3796 ZERO_STRUCT(ctx
->counts
);
3797 k5ret
= krb5_get_creds(ctx
->smb_krb5_context
->krb5_context
,
3800 ctx
->cifs_trust_dns
,
3801 &ctx
->cifs_trust_dns_creds
);
3802 assertion_message
= talloc_asprintf(ctx
,
3803 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3804 cifs_trust_dns_string
,
3806 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3808 trusted
->trust_direction
,
3809 trusted
->trust_type
,
3810 trusted
->trust_attributes
,
3811 ctx
->counts
.io
, ctx
->counts
.errors
, ctx
->counts
.ok
);
3812 torture_assert_int_equal(tctx
, k5ret
, KRB5_KDC_UNREACH
, assertion_message
);
3813 torture_assert_int_equal(tctx
, ctx
->counts
.io
, 1, assertion_message
);
3814 torture_assert_int_equal(tctx
, ctx
->counts
.ok
, 1, assertion_message
);
3816 /* Confirm if we have the referral ticket in the cache */
3817 krb5_free_cred_contents(ctx
->smb_krb5_context
->krb5_context
,
3818 &ctx
->krbtgt_referral_creds
);
3819 k5ret
= krb5_cc_retrieve_cred(ctx
->smb_krb5_context
->krb5_context
,
3822 ctx
->krbtgt_trust_realm_creds
,
3823 &ctx
->krbtgt_referral_creds
);
3824 assertion_message
= talloc_asprintf(ctx
,
3825 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3826 krbtgt_trust_realm_string
,
3828 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3830 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
3832 k5ok
= krb5_principal_compare(ctx
->smb_krb5_context
->krb5_context
,
3833 ctx
->krbtgt_referral_creds
.server
,
3834 ctx
->krbtgt_trust_realm
);
3835 torture_assert(tctx
, k5ok
, assertion_message
);
3836 type
= smb_krb5_principal_get_type(ctx
->smb_krb5_context
->krb5_context
,
3837 ctx
->krbtgt_referral_creds
.server
);
3838 torture_assert_int_equal(tctx
, type
, KRB5_NT_SRV_INST
, assertion_message
);
3840 /* Delete the referral ticket from the cache */
3841 k5ret
= krb5_cc_remove_cred(ctx
->smb_krb5_context
->krb5_context
,
3844 &ctx
->krbtgt_referral_creds
);
3845 assertion_message
= talloc_asprintf(ctx
,
3846 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3847 krbtgt_trust_realm_string
,
3849 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3851 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
3853 cifs_trust_netbios_string
= talloc_asprintf(ctx
, "cifs/%s@%s",
3854 trusted_netbios_name
, realm
);
3855 torture_assert_int_equal(tctx
,
3856 smb_krb5_make_principal(ctx
->smb_krb5_context
->krb5_context
,
3857 &ctx
->cifs_trust_netbios
,
3859 trusted_netbios_name
, NULL
),
3860 0, "smb_krb5_make_principal failed");
3862 /* Confirm if we get krbtgt/trusted_realm back when asking for cifs/trusted_realm */
3863 ZERO_STRUCT(ctx
->counts
);
3864 k5ret
= krb5_get_creds(ctx
->smb_krb5_context
->krb5_context
,
3867 ctx
->cifs_trust_netbios
,
3868 &ctx
->cifs_trust_netbios_creds
);
3869 assertion_message
= talloc_asprintf(ctx
,
3870 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3871 cifs_trust_netbios_string
,
3873 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3875 trusted
->trust_direction
,
3876 trusted
->trust_type
,
3877 trusted
->trust_attributes
,
3878 ctx
->counts
.io
, ctx
->counts
.errors
, ctx
->counts
.ok
);
3879 torture_assert_int_equal(tctx
, k5ret
, KRB5_KDC_UNREACH
, assertion_message
);
3880 torture_assert_int_equal(tctx
, ctx
->counts
.io
, 1, assertion_message
);
3881 torture_assert_int_equal(tctx
, ctx
->counts
.ok
, 1, assertion_message
);
3883 /* Confirm if we have the referral ticket in the cache */
3884 krb5_free_cred_contents(ctx
->smb_krb5_context
->krb5_context
,
3885 &ctx
->krbtgt_referral_creds
);
3886 k5ret
= krb5_cc_retrieve_cred(ctx
->smb_krb5_context
->krb5_context
,
3889 ctx
->krbtgt_trust_realm_creds
,
3890 &ctx
->krbtgt_referral_creds
);
3891 assertion_message
= talloc_asprintf(ctx
,
3892 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3893 krbtgt_trust_realm_string
,
3895 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3897 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
3899 k5ok
= krb5_principal_compare(ctx
->smb_krb5_context
->krb5_context
,
3900 ctx
->krbtgt_referral_creds
.server
,
3901 ctx
->krbtgt_trust_realm
);
3902 torture_assert(tctx
, k5ok
, assertion_message
);
3903 type
= smb_krb5_principal_get_type(ctx
->smb_krb5_context
->krb5_context
,
3904 ctx
->krbtgt_referral_creds
.server
);
3905 torture_assert_int_equal(tctx
, type
, KRB5_NT_SRV_INST
, assertion_message
);
3907 /* Delete the referral ticket from the cache */
3908 k5ret
= krb5_cc_remove_cred(ctx
->smb_krb5_context
->krb5_context
,
3911 &ctx
->krbtgt_referral_creds
);
3912 assertion_message
= talloc_asprintf(ctx
,
3913 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3914 krbtgt_trust_realm_string
,
3916 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3918 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
3920 drs_trust_dns_string
= talloc_asprintf(ctx
,
3921 "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s@%s",
3922 workstation
, trusted_dns_name
, realm
);
3923 torture_assert_int_equal(tctx
,
3924 smb_krb5_make_principal(ctx
->smb_krb5_context
->krb5_context
,
3925 &ctx
->drs_trust_dns
,
3926 realm
, "E3514235-4B06-11D1-AB04-00C04FC2DCD2",
3927 workstation
, trusted_dns_name
, NULL
),
3928 0, "smb_krb5_make_principal failed");
3930 /* Confirm if we get krbtgt/trusted_realm back when asking for a 3 part principal */
3931 ZERO_STRUCT(ctx
->counts
);
3932 k5ret
= krb5_get_creds(ctx
->smb_krb5_context
->krb5_context
,
3936 &ctx
->drs_trust_dns_creds
);
3937 assertion_message
= talloc_asprintf(ctx
,
3938 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3939 drs_trust_dns_string
,
3941 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3943 trusted
->trust_direction
,
3944 trusted
->trust_type
,
3945 trusted
->trust_attributes
,
3946 ctx
->counts
.io
, ctx
->counts
.errors
, ctx
->counts
.ok
);
3947 torture_assert_int_equal(tctx
, k5ret
, KRB5_KDC_UNREACH
, assertion_message
);
3948 torture_assert_int_equal(tctx
, ctx
->counts
.io
, 1, assertion_message
);
3949 torture_assert_int_equal(tctx
, ctx
->counts
.ok
, 1, assertion_message
);
3951 /* Confirm if we have the referral ticket in the cache */
3952 krb5_free_cred_contents(ctx
->smb_krb5_context
->krb5_context
,
3953 &ctx
->krbtgt_referral_creds
);
3954 k5ret
= krb5_cc_retrieve_cred(ctx
->smb_krb5_context
->krb5_context
,
3957 ctx
->krbtgt_trust_realm_creds
,
3958 &ctx
->krbtgt_referral_creds
);
3959 assertion_message
= talloc_asprintf(ctx
,
3960 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3961 krbtgt_trust_realm_string
,
3963 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3965 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
3967 k5ok
= krb5_principal_compare(ctx
->smb_krb5_context
->krb5_context
,
3968 ctx
->krbtgt_referral_creds
.server
,
3969 ctx
->krbtgt_trust_realm
);
3970 torture_assert(tctx
, k5ok
, assertion_message
);
3971 type
= smb_krb5_principal_get_type(ctx
->smb_krb5_context
->krb5_context
,
3972 ctx
->krbtgt_referral_creds
.server
);
3973 torture_assert_int_equal(tctx
, type
, KRB5_NT_SRV_INST
, assertion_message
);
3975 /* Delete the referral ticket from the cache */
3976 k5ret
= krb5_cc_remove_cred(ctx
->smb_krb5_context
->krb5_context
,
3979 &ctx
->krbtgt_referral_creds
);
3980 assertion_message
= talloc_asprintf(ctx
,
3981 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3982 krbtgt_trust_realm_string
,
3984 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
3986 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
3988 drs_trust_netbios_string
= talloc_asprintf(ctx
,
3989 "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s@%s",
3990 workstation
, trusted_netbios_name
, realm
);
3991 torture_assert_int_equal(tctx
,
3992 smb_krb5_make_principal(ctx
->smb_krb5_context
->krb5_context
,
3993 &ctx
->drs_trust_netbios
,
3994 realm
, "E3514235-4B06-11D1-AB04-00C04FC2DCD2",
3995 workstation
, trusted_netbios_name
, NULL
),
3996 0, "smb_krb5_make_principal failed");
3998 /* Confirm if we get krbtgt/trusted_realm back when asking for a 3 part principal */
3999 ZERO_STRUCT(ctx
->counts
);
4000 k5ret
= krb5_get_creds(ctx
->smb_krb5_context
->krb5_context
,
4003 ctx
->drs_trust_netbios
,
4004 &ctx
->drs_trust_netbios_creds
);
4005 assertion_message
= talloc_asprintf(ctx
,
4006 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4007 drs_trust_netbios_string
,
4009 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
4011 trusted
->trust_direction
,
4012 trusted
->trust_type
,
4013 trusted
->trust_attributes
,
4014 ctx
->counts
.io
, ctx
->counts
.errors
, ctx
->counts
.ok
);
4015 torture_assert_int_equal(tctx
, k5ret
, KRB5_KDC_UNREACH
, assertion_message
);
4016 torture_assert_int_equal(tctx
, ctx
->counts
.io
, 1, assertion_message
);
4017 torture_assert_int_equal(tctx
, ctx
->counts
.ok
, 1, assertion_message
);
4019 /* Confirm if we have the referral ticket in the cache */
4020 krb5_free_cred_contents(ctx
->smb_krb5_context
->krb5_context
,
4021 &ctx
->krbtgt_referral_creds
);
4022 k5ret
= krb5_cc_retrieve_cred(ctx
->smb_krb5_context
->krb5_context
,
4025 ctx
->krbtgt_trust_realm_creds
,
4026 &ctx
->krbtgt_referral_creds
);
4027 assertion_message
= talloc_asprintf(ctx
,
4028 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4029 krbtgt_trust_realm_string
,
4031 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
4033 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
4035 k5ok
= krb5_principal_compare(ctx
->smb_krb5_context
->krb5_context
,
4036 ctx
->krbtgt_referral_creds
.server
,
4037 ctx
->krbtgt_trust_realm
);
4038 torture_assert(tctx
, k5ok
, assertion_message
);
4039 type
= smb_krb5_principal_get_type(ctx
->smb_krb5_context
->krb5_context
,
4040 ctx
->krbtgt_referral_creds
.server
);
4041 torture_assert_int_equal(tctx
, type
, KRB5_NT_SRV_INST
, assertion_message
);
4043 /* Delete the referral ticket from the cache */
4044 k5ret
= krb5_cc_remove_cred(ctx
->smb_krb5_context
->krb5_context
,
4047 &ctx
->krbtgt_referral_creds
);
4048 assertion_message
= talloc_asprintf(ctx
,
4049 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
4050 krbtgt_trust_realm_string
,
4052 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
4054 torture_assert_int_equal(tctx
, k5ret
, 0, assertion_message
);
4056 four_trust_dns_string
= talloc_asprintf(ctx
, "four/tree/two/%s@%s",
4057 trusted_dns_name
, realm
);
4058 torture_assert_int_equal(tctx
,
4059 smb_krb5_make_principal(ctx
->smb_krb5_context
->krb5_context
,
4060 &ctx
->four_trust_dns
,
4061 realm
, "four", "tree", "two",
4062 trusted_dns_name
, NULL
),
4063 0, "smb_krb5_make_principal failed");
4065 /* Confirm if we get an error back for a 4 part principal */
4066 ZERO_STRUCT(ctx
->counts
);
4067 k5ret
= krb5_get_creds(ctx
->smb_krb5_context
->krb5_context
,
4070 ctx
->four_trust_dns
,
4071 &ctx
->four_trust_dns_creds
);
4072 assertion_message
= talloc_asprintf(ctx
,
4073 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4074 four_trust_dns_string
,
4076 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
4078 trusted
->trust_direction
,
4079 trusted
->trust_type
,
4080 trusted
->trust_attributes
,
4081 ctx
->counts
.io
, ctx
->counts
.errors
, ctx
->counts
.ok
);
4082 torture_assert_int_equal(tctx
, k5ret
, KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
, assertion_message
);
4083 torture_assert_int_equal(tctx
, ctx
->counts
.io
, 1, assertion_message
);
4084 torture_assert_int_equal(tctx
, ctx
->counts
.error_io
, 1, assertion_message
);
4085 torture_assert_int_equal(tctx
, ctx
->error
.error_code
, 7, assertion_message
);
4087 /* Confirm if we have no referral ticket in the cache */
4088 krb5_free_cred_contents(ctx
->smb_krb5_context
->krb5_context
,
4089 &ctx
->krbtgt_referral_creds
);
4090 k5ret
= krb5_cc_retrieve_cred(ctx
->smb_krb5_context
->krb5_context
,
4093 ctx
->krbtgt_trust_realm_creds
,
4094 &ctx
->krbtgt_referral_creds
);
4095 assertion_message
= talloc_asprintf(ctx
,
4096 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4097 krbtgt_trust_realm_string
,
4099 smb_get_krb5_error_message(ctx
->smb_krb5_context
->krb5_context
,
4101 torture_assert_int_equal(tctx
, k5ret
, KRB5_CC_END
, assertion_message
);
4107 static bool check_dom_trust_pw(struct dcerpc_pipe
*p
,
4108 struct torture_context
*tctx
,
4109 const char *our_netbios_name
,
4110 const char *our_dns_name
,
4111 enum netr_SchannelType secure_channel_type
,
4112 const struct lsa_TrustDomainInfoInfoEx
*trusted
,
4113 const char *previous_password
,
4114 const char *current_password
,
4115 uint32_t current_version
,
4116 const char *next_password
,
4117 uint32_t next_version
,
4118 bool expected_result
)
4120 struct cli_credentials
*incoming_creds
;
4121 char *server_name
= NULL
;
4122 char *account
= NULL
;
4123 char *principal
= NULL
;
4124 char *workstation
= NULL
;
4125 const char *binding
= torture_setting_string(tctx
, "binding", NULL
);
4126 const char *host
= torture_setting_string(tctx
, "host", NULL
);
4127 struct dcerpc_binding
*b2
;
4128 struct netlogon_creds_CredentialState
*creds
;
4129 struct samr_CryptPassword samr_crypt_password
;
4130 struct netr_CryptPassword netr_crypt_password
;
4131 struct netr_Authenticator req_auth
;
4132 struct netr_Authenticator rep_auth
;
4133 struct netr_ServerPasswordSet2 s
;
4134 struct dcerpc_pipe
*p2
;
4138 const char *trusted_netbios_name
= trusted
->netbios_name
.string
;
4139 const char *trusted_dns_name
= trusted
->domain_name
.string
;
4140 struct tsocket_address
*dest_addr
;
4141 struct cldap_socket
*cldap
;
4142 struct cldap_netlogon cldap1
;
4144 incoming_creds
= cli_credentials_init(tctx
);
4145 torture_assert(tctx
, incoming_creds
, "cli_credentials_init");
4147 cli_credentials_set_domain(incoming_creds
, our_netbios_name
, CRED_SPECIFIED
);
4148 cli_credentials_set_realm(incoming_creds
, our_dns_name
, CRED_SPECIFIED
);
4150 if (secure_channel_type
== SEC_CHAN_DNS_DOMAIN
) {
4151 account
= talloc_asprintf(tctx
, "%s.", trusted_dns_name
);
4152 torture_assert(tctx
, account
, __location__
);
4154 principal
= talloc_asprintf(tctx
, "%s$@%s",
4155 trusted_netbios_name
,
4156 cli_credentials_get_realm(incoming_creds
));
4157 torture_assert(tctx
, principal
, __location__
);
4159 workstation
= talloc_asprintf(tctx
, "%sUP",
4160 trusted_netbios_name
);
4161 torture_assert(tctx
, workstation
, __location__
);
4163 account
= talloc_asprintf(tctx
, "%s$", trusted_netbios_name
);
4164 torture_assert(tctx
, account
, __location__
);
4166 workstation
= talloc_asprintf(tctx
, "%sDOWN",
4167 trusted_netbios_name
);
4168 torture_assert(tctx
, workstation
, __location__
);
4171 cli_credentials_set_username(incoming_creds
, account
, CRED_SPECIFIED
);
4172 if (principal
!= NULL
) {
4173 cli_credentials_set_principal(incoming_creds
, principal
,
4176 cli_credentials_set_kvno(incoming_creds
, current_version
);
4177 cli_credentials_set_password(incoming_creds
, current_password
, CRED_SPECIFIED
);
4178 cli_credentials_set_old_password(incoming_creds
, previous_password
, CRED_SPECIFIED
);
4179 cli_credentials_set_workstation(incoming_creds
, workstation
, CRED_SPECIFIED
);
4180 cli_credentials_set_secure_channel_type(incoming_creds
, secure_channel_type
);
4182 rc
= tsocket_address_inet_from_strings(tctx
, "ip",
4184 lpcfg_cldap_port(tctx
->lp_ctx
),
4186 torture_assert_int_equal(tctx
, rc
, 0, "tsocket_address_inet_from_strings");
4188 /* cldap_socket_init should now know about the dest. address */
4189 status
= cldap_socket_init(tctx
, NULL
, dest_addr
, &cldap
);
4190 torture_assert_ntstatus_ok(tctx
, status
, "cldap_socket_init");
4192 ZERO_STRUCT(cldap1
);
4193 cldap1
.in
.dest_address
= NULL
;
4194 cldap1
.in
.dest_port
= 0;
4195 cldap1
.in
.version
= NETLOGON_NT_VERSION_5
| NETLOGON_NT_VERSION_5EX
;
4196 cldap1
.in
.user
= account
;
4197 if (secure_channel_type
== SEC_CHAN_DNS_DOMAIN
) {
4198 cldap1
.in
.acct_control
= ACB_AUTOLOCK
;
4200 cldap1
.in
.acct_control
= ACB_DOMTRUST
;
4202 status
= cldap_netlogon(cldap
, tctx
, &cldap1
);
4203 torture_assert_ntstatus_ok(tctx
, status
, "cldap_netlogon");
4204 torture_assert_int_equal(tctx
, cldap1
.out
.netlogon
.ntver
,
4205 NETLOGON_NT_VERSION_5EX
,
4207 torture_assert_int_equal(tctx
, cldap1
.out
.netlogon
.data
.nt5_ex
.nt_version
,
4208 NETLOGON_NT_VERSION_1
| NETLOGON_NT_VERSION_5EX
,
4210 torture_assert_int_equal(tctx
, cldap1
.out
.netlogon
.data
.nt5_ex
.command
,
4211 LOGON_SAM_LOGON_RESPONSE_EX
,
4213 torture_assert_str_equal(tctx
, cldap1
.out
.netlogon
.data
.nt5_ex
.user_name
,
4216 server_name
= talloc_asprintf(tctx
, "\\\\%s",
4217 cldap1
.out
.netlogon
.data
.nt5_ex
.pdc_dns_name
);
4218 torture_assert(tctx
, server_name
, __location__
);
4220 status
= dcerpc_parse_binding(tctx
, binding
, &b2
);
4221 torture_assert_ntstatus_ok(tctx
, status
, "Bad binding string");
4223 status
= dcerpc_pipe_connect_b(tctx
, &p2
, b2
,
4224 &ndr_table_netlogon
,
4225 cli_credentials_init_anon(tctx
),
4226 tctx
->ev
, tctx
->lp_ctx
);
4227 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_pipe_connect_b");
4229 ok
= check_pw_with_ServerAuthenticate3(p2
, tctx
,
4230 NETLOGON_NEG_AUTH2_ADS_FLAGS
,
4232 incoming_creds
, &creds
);
4233 torture_assert_int_equal(tctx
, ok
, expected_result
,
4234 "check_pw_with_ServerAuthenticate3");
4236 if (trusted
->trust_type
!= LSA_TRUST_TYPE_DOWNLEVEL
) {
4237 ok
= check_pw_with_krb5(tctx
, incoming_creds
, trusted
);
4238 torture_assert_int_equal(tctx
, ok
, expected_result
,
4239 "check_pw_with_krb5");
4242 if (expected_result
!= true || next_password
== NULL
) {
4248 * netr_ServerPasswordSet2
4250 ok
= encode_pw_buffer(samr_crypt_password
.data
,
4251 next_password
, STR_UNICODE
);
4252 torture_assert(tctx
, ok
, "encode_pw_buffer");
4254 if (next_version
!= 0) {
4255 struct NL_PASSWORD_VERSION version
;
4256 uint32_t len
= IVAL(samr_crypt_password
.data
, 512);
4257 uint32_t ofs
= 512 - len
;
4262 version
.ReservedField
= 0;
4263 version
.PasswordVersionNumber
= next_version
;
4264 version
.PasswordVersionPresent
=
4265 NETLOGON_PASSWORD_VERSION_NUMBER_PRESENT
;
4267 ptr
= samr_crypt_password
.data
+ ofs
;
4268 SIVAL(ptr
, 0, version
.ReservedField
);
4269 SIVAL(ptr
, 4, version
.PasswordVersionNumber
);
4270 SIVAL(ptr
, 8, version
.PasswordVersionPresent
);
4273 netlogon_creds_client_authenticator(creds
, &req_auth
);
4274 ZERO_STRUCT(rep_auth
);
4276 if (creds
->negotiate_flags
& NETLOGON_NEG_SUPPORTS_AES
) {
4277 netlogon_creds_aes_encrypt(creds
,
4278 samr_crypt_password
.data
,
4281 netlogon_creds_arcfour_crypt(creds
,
4282 samr_crypt_password
.data
,
4286 memcpy(netr_crypt_password
.data
,
4287 samr_crypt_password
.data
, 512);
4288 netr_crypt_password
.length
= IVAL(samr_crypt_password
.data
, 512);
4291 s
.in
.server_name
= server_name
;
4292 s
.in
.account_name
= cli_credentials_get_username(incoming_creds
);
4293 s
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(incoming_creds
);
4294 s
.in
.computer_name
= cli_credentials_get_workstation(incoming_creds
);
4295 s
.in
.credential
= &req_auth
;
4296 s
.in
.new_password
= &netr_crypt_password
;
4297 s
.out
.return_authenticator
= &rep_auth
;
4298 status
= dcerpc_netr_ServerPasswordSet2_r(p2
->binding_handle
, tctx
, &s
);
4299 torture_assert_ntstatus_ok(tctx
, status
, "failed to set password");
4301 ok
= netlogon_creds_client_check(creds
, &rep_auth
.cred
);
4302 torture_assert(tctx
, ok
, "netlogon_creds_client_check");
4304 cli_credentials_set_kvno(incoming_creds
, next_version
);
4305 cli_credentials_set_password(incoming_creds
, next_password
, CRED_SPECIFIED
);
4306 cli_credentials_set_old_password(incoming_creds
, current_password
, CRED_SPECIFIED
);
4309 status
= dcerpc_pipe_connect_b(tctx
, &p2
, b2
,
4310 &ndr_table_netlogon
,
4311 cli_credentials_init_anon(tctx
),
4312 tctx
->ev
, tctx
->lp_ctx
);
4313 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_pipe_connect_b");
4315 ok
= check_pw_with_ServerAuthenticate3(p2
, tctx
,
4316 NETLOGON_NEG_AUTH2_ADS_FLAGS
,
4318 incoming_creds
, &creds
);
4319 torture_assert(tctx
, ok
, "check_pw_with_ServerAuthenticate3 with changed password");
4321 if (trusted
->trust_type
!= LSA_TRUST_TYPE_DOWNLEVEL
) {
4322 ok
= check_pw_with_krb5(tctx
, incoming_creds
, trusted
);
4323 torture_assert(tctx
, ok
, "check_pw_with_krb5 with changed password");
4330 static bool test_CreateTrustedDomainEx_common(struct dcerpc_pipe
*p
,
4331 struct torture_context
*tctx
,
4332 struct policy_handle
*handle
,
4333 uint32_t num_trusts
,
4338 struct lsa_QueryInfoPolicy2 p2
;
4339 union lsa_PolicyInformation
*our_info
= NULL
;
4340 struct lsa_CreateTrustedDomainEx r
;
4341 struct lsa_CreateTrustedDomainEx2 r2
;
4342 struct lsa_TrustDomainInfoInfoEx trustinfo
;
4343 struct lsa_TrustDomainInfoAuthInfoInternal
*authinfo_internal
= NULL
;
4344 struct lsa_TrustDomainInfoAuthInfo
*authinfo
= NULL
;
4345 struct dom_sid
**domsid
;
4346 struct policy_handle
*trustdom_handle
;
4347 struct lsa_QueryTrustedDomainInfo q
;
4348 union lsa_TrustedDomainInfo
*info
= NULL
;
4349 DATA_BLOB session_key
;
4351 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4353 const char *incoming_v00
= TRUSTPW
"InV00";
4354 const char *incoming_v0
= TRUSTPW
"InV0";
4355 const char *incoming_v1
= TRUSTPW
"InV1";
4356 const char *incoming_v2
= TRUSTPW
"InV2";
4357 const char *incoming_v40
= TRUSTPW
"InV40";
4358 const char *outgoing_v00
= TRUSTPW
"OutV00";
4359 const char *outgoing_v0
= TRUSTPW
"OutV0";
4362 torture_comment(tctx
, "\nTesting CreateTrustedDomainEx2 for %d domains\n", num_trusts
);
4365 torture_comment(tctx
, "\nTesting CreateTrustedDomainEx for %d domains\n", num_trusts
);
4369 domsid
= talloc_array(tctx
, struct dom_sid
*, num_trusts
);
4370 trustdom_handle
= talloc_array(tctx
, struct policy_handle
, num_trusts
);
4372 status
= dcerpc_fetch_session_key(p
, &session_key
);
4373 if (!NT_STATUS_IS_OK(status
)) {
4374 torture_comment(tctx
, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status
));
4379 p2
.in
.handle
= handle
;
4380 p2
.in
.level
= LSA_POLICY_INFO_DNS
;
4381 p2
.out
.info
= &our_info
;
4383 torture_assert_ntstatus_ok(tctx
,
4384 dcerpc_lsa_QueryInfoPolicy2_r(b
, tctx
, &p2
),
4385 "lsa_QueryInfoPolicy2 failed");
4386 torture_assert_ntstatus_ok(tctx
, p2
.out
.result
,
4387 "lsa_QueryInfoPolicy2 failed");
4388 torture_assert(tctx
, our_info
!= NULL
, "lsa_QueryInfoPolicy2 our_info");
4390 for (i
=0; i
< num_trusts
; i
++) {
4391 char *trust_name
= talloc_asprintf(tctx
, "TORTURE%s%02d", id
, i
);
4392 char *trust_name_dns
= talloc_asprintf(tctx
, "torturedom%s%02d.samba._none_.example.com", id
, i
);
4393 char *trust_sid
= talloc_asprintf(tctx
, "S-1-5-21-97398-379795-%s%02d", id
, i
);
4396 domsid
[i
] = dom_sid_parse_talloc(tctx
, trust_sid
);
4398 trustinfo
.sid
= domsid
[i
];
4399 trustinfo
.netbios_name
.string
= trust_name
;
4400 trustinfo
.domain_name
.string
= trust_name_dns
;
4402 /* Create inbound, some outbound, and some
4403 * bi-directional trusts in a repeating pattern based
4406 /* 1 == inbound, 2 == outbound, 3 == both */
4407 trustinfo
.trust_direction
= (i
% 3) + 1;
4409 /* Try different trust types too */
4411 /* 1 == downlevel (NT4), 2 == uplevel (ADS), 3 == MIT (kerberos but not AD) */
4412 trustinfo
.trust_type
= (((i
/ 3) + 1) % 3) + 1;
4414 trustinfo
.trust_attributes
= LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION
;
4416 ok
= gen_authinfo_internal(tctx
, incoming_v00
, incoming_v0
,
4417 outgoing_v00
, outgoing_v0
,
4418 session_key
, &authinfo_internal
);
4420 torture_comment(tctx
, "gen_authinfo_internal failed");
4424 ok
= gen_authinfo(tctx
, incoming_v00
, incoming_v0
,
4425 outgoing_v00
, outgoing_v0
,
4428 torture_comment(tctx
, "gen_authinfonfo failed");
4434 r2
.in
.policy_handle
= handle
;
4435 r2
.in
.info
= &trustinfo
;
4436 r2
.in
.auth_info_internal
= authinfo_internal
;
4437 r2
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4438 r2
.out
.trustdom_handle
= &trustdom_handle
[i
];
4440 torture_assert_ntstatus_ok(tctx
,
4441 dcerpc_lsa_CreateTrustedDomainEx2_r(b
, tctx
, &r2
),
4442 "CreateTrustedDomainEx2 failed");
4444 status
= r2
.out
.result
;
4447 r
.in
.policy_handle
= handle
;
4448 r
.in
.info
= &trustinfo
;
4449 r
.in
.auth_info
= authinfo
;
4450 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4451 r
.out
.trustdom_handle
= &trustdom_handle
[i
];
4453 torture_assert_ntstatus_ok(tctx
,
4454 dcerpc_lsa_CreateTrustedDomainEx_r(b
, tctx
, &r
),
4455 "CreateTrustedDomainEx failed");
4457 status
= r
.out
.result
;
4460 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_COLLISION
)) {
4461 test_DeleteTrustedDomain(b
, tctx
, handle
, trustinfo
.netbios_name
);
4463 torture_assert_ntstatus_ok(tctx
,
4464 dcerpc_lsa_CreateTrustedDomainEx2_r(b
, tctx
, &r2
),
4465 "CreateTrustedDomainEx2 failed");
4466 status
= r2
.out
.result
;
4468 torture_assert_ntstatus_ok(tctx
,
4469 dcerpc_lsa_CreateTrustedDomainEx_r(b
, tctx
, &r
),
4470 "CreateTrustedDomainEx2 failed");
4471 status
= r
.out
.result
;
4474 if (!NT_STATUS_IS_OK(status
)) {
4475 torture_comment(tctx
, "CreateTrustedDomainEx failed2 - %s\n", nt_errstr(status
));
4478 /* For outbound and MIT trusts there is no trust account */
4479 if (trustinfo
.trust_direction
!= 2 &&
4480 trustinfo
.trust_type
!= 3) {
4482 if (torture_setting_bool(tctx
, "samba3", false)) {
4483 torture_comment(tctx
, "skipping trusted domain auth tests against samba3\n");
4484 } else if (ex2_call
== false &&
4485 torture_setting_bool(tctx
, "samba4", false)) {
4486 torture_comment(tctx
, "skipping CreateTrustedDomainEx trusted domain auth tests against samba4\n");
4489 ok
= check_dom_trust_pw(p
, tctx
,
4490 our_info
->dns
.name
.string
,
4491 our_info
->dns
.dns_domain
.string
,
4499 torture_comment(tctx
, "Password check passed unexpectedly\n");
4502 ok
= check_dom_trust_pw(p
, tctx
,
4503 our_info
->dns
.name
.string
,
4504 our_info
->dns
.dns_domain
.string
,
4512 torture_comment(tctx
, "Password check failed (SEC_CHAN_DOMAIN)\n");
4515 ok
= check_dom_trust_pw(p
, tctx
,
4516 our_info
->dns
.name
.string
,
4517 our_info
->dns
.dns_domain
.string
,
4518 SEC_CHAN_DNS_DOMAIN
,
4525 torture_comment(tctx
, "Password check failed v2 (SEC_CHAN_DNS_DOMAIN)\n");
4528 ok
= check_dom_trust_pw(p
, tctx
,
4529 our_info
->dns
.name
.string
,
4530 our_info
->dns
.dns_domain
.string
,
4531 SEC_CHAN_DNS_DOMAIN
,
4538 torture_comment(tctx
, "Password check failed v4 (SEC_CHAN_DNS_DOMAIN)\n");
4544 q
.in
.trustdom_handle
= &trustdom_handle
[i
];
4545 q
.in
.level
= LSA_TRUSTED_DOMAIN_INFO_INFO_EX
;
4547 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QueryTrustedDomainInfo_r(b
, tctx
, &q
),
4548 "QueryTrustedDomainInfo failed");
4549 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
4550 torture_comment(tctx
, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(q
.out
.result
));
4552 } else if (!q
.out
.info
) {
4553 torture_comment(tctx
, "QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
4556 if (strcmp(info
->info_ex
.domain_name
.string
, trustinfo
.domain_name
.string
) != 0) {
4557 torture_comment(tctx
, "QueryTrustedDomainInfo returned inconsistent long name: %s != %s\n",
4558 info
->info_ex
.domain_name
.string
, trustinfo
.domain_name
.string
);
4561 if (strcmp(info
->info_ex
.netbios_name
.string
, trustinfo
.netbios_name
.string
) != 0) {
4562 torture_comment(tctx
, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
4563 info
->info_ex
.netbios_name
.string
, trustinfo
.netbios_name
.string
);
4566 if (info
->info_ex
.trust_type
!= trustinfo
.trust_type
) {
4567 torture_comment(tctx
, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
4568 trust_name
, info
->info_ex
.trust_type
, trustinfo
.trust_type
);
4571 if (info
->info_ex
.trust_attributes
!= LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION
) {
4572 torture_comment(tctx
, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
4573 trust_name
, info
->info_ex
.trust_attributes
, LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION
);
4576 if (info
->info_ex
.trust_direction
!= trustinfo
.trust_direction
) {
4577 torture_comment(tctx
, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
4578 trust_name
, info
->info_ex
.trust_direction
, trustinfo
.trust_direction
);
4585 /* now that we have some domains to look over, we can test the enum calls */
4586 if (!test_EnumTrustDom(b
, tctx
, handle
)) {
4587 torture_comment(tctx
, "test_EnumTrustDom failed\n");
4591 if (!test_EnumTrustDomEx(b
, tctx
, handle
)) {
4592 torture_comment(tctx
, "test_EnumTrustDomEx failed\n");
4596 for (i
=0; i
<num_trusts
; i
++) {
4597 if (!test_DeleteTrustedDomainBySid(b
, tctx
, handle
, domsid
[i
])) {
4598 torture_comment(tctx
, "test_DeleteTrustedDomainBySid failed\n");
4606 static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe
*p
,
4607 struct torture_context
*tctx
,
4608 struct policy_handle
*handle
,
4609 uint32_t num_trusts
)
4611 return test_CreateTrustedDomainEx_common(p
, tctx
, handle
, num_trusts
, true);
4614 static bool test_CreateTrustedDomainEx(struct dcerpc_pipe
*p
,
4615 struct torture_context
*tctx
,
4616 struct policy_handle
*handle
,
4617 uint32_t num_trusts
)
4619 return test_CreateTrustedDomainEx_common(p
, tctx
, handle
, num_trusts
, false);
4622 static bool test_QueryDomainInfoPolicy(struct dcerpc_binding_handle
*b
,
4623 struct torture_context
*tctx
,
4624 struct policy_handle
*handle
)
4626 struct lsa_QueryDomainInformationPolicy r
;
4627 union lsa_DomainInformationPolicy
*info
= NULL
;
4631 if (torture_setting_bool(tctx
, "samba3", false)) {
4632 torture_skip(tctx
, "skipping QueryDomainInformationPolicy test\n");
4635 torture_comment(tctx
, "\nTesting QueryDomainInformationPolicy\n");
4638 r
.in
.handle
= handle
;
4642 torture_comment(tctx
, "\nTrying QueryDomainInformationPolicy level %d\n", i
);
4644 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QueryDomainInformationPolicy_r(b
, tctx
, &r
),
4645 "QueryDomainInformationPolicy failed");
4647 /* If the server does not support EFS, then this is the correct return */
4648 if (i
== LSA_DOMAIN_INFO_POLICY_EFS
&& NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
4650 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
4651 torture_comment(tctx
, "QueryDomainInformationPolicy failed - %s\n", nt_errstr(r
.out
.result
));
4661 static bool test_QueryInfoPolicyCalls( bool version2
,
4662 struct dcerpc_binding_handle
*b
,
4663 struct torture_context
*tctx
,
4664 struct policy_handle
*handle
)
4666 struct lsa_QueryInfoPolicy r
;
4667 union lsa_PolicyInformation
*info
= NULL
;
4670 const char *call
= talloc_asprintf(tctx
, "QueryInfoPolicy%s", version2
? "2":"");
4672 torture_comment(tctx
, "\nTesting %s\n", call
);
4674 if (version2
&& torture_setting_bool(tctx
, "samba3", false)) {
4675 torture_skip(tctx
, "skipping QueryInfoPolicy2 tests\n");
4678 for (i
=1;i
<=14;i
++) {
4679 r
.in
.handle
= handle
;
4683 torture_comment(tctx
, "\nTrying %s level %d\n", call
, i
);
4686 /* We can perform the cast, because both types are
4687 structurally equal */
4688 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QueryInfoPolicy2_r(b
, tctx
,
4689 (struct lsa_QueryInfoPolicy2
*) &r
),
4690 "QueryInfoPolicy2 failed");
4692 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QueryInfoPolicy_r(b
, tctx
, &r
),
4693 "QueryInfoPolicy2 failed");
4696 case LSA_POLICY_INFO_MOD
:
4697 case LSA_POLICY_INFO_AUDIT_FULL_SET
:
4698 case LSA_POLICY_INFO_AUDIT_FULL_QUERY
:
4699 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
4700 torture_comment(tctx
, "Server should have failed level %u: %s\n", i
, nt_errstr(r
.out
.result
));
4704 case LSA_POLICY_INFO_DOMAIN
:
4705 case LSA_POLICY_INFO_ACCOUNT_DOMAIN
:
4706 case LSA_POLICY_INFO_REPLICA
:
4707 case LSA_POLICY_INFO_QUOTA
:
4708 case LSA_POLICY_INFO_ROLE
:
4709 case LSA_POLICY_INFO_AUDIT_LOG
:
4710 case LSA_POLICY_INFO_AUDIT_EVENTS
:
4711 case LSA_POLICY_INFO_PD
:
4712 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
4713 torture_comment(tctx
, "%s failed - %s\n", call
, nt_errstr(r
.out
.result
));
4717 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN
:
4718 case LSA_POLICY_INFO_DNS_INT
:
4719 case LSA_POLICY_INFO_DNS
:
4720 if (torture_setting_bool(tctx
, "samba3", false)) {
4721 /* Other levels not implemented yet */
4722 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_INFO_CLASS
)) {
4723 torture_comment(tctx
, "%s failed - %s\n", call
, nt_errstr(r
.out
.result
));
4726 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
4727 torture_comment(tctx
, "%s failed - %s\n", call
, nt_errstr(r
.out
.result
));
4732 if (torture_setting_bool(tctx
, "samba4", false)) {
4733 /* Other levels not implemented yet */
4734 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_INFO_CLASS
)) {
4735 torture_comment(tctx
, "%s failed - %s\n", call
, nt_errstr(r
.out
.result
));
4738 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
4739 torture_comment(tctx
, "%s failed - %s\n", call
, nt_errstr(r
.out
.result
));
4745 if (NT_STATUS_IS_OK(r
.out
.result
) && (i
== LSA_POLICY_INFO_DNS
4746 || i
== LSA_POLICY_INFO_DNS_INT
)) {
4747 /* Let's look up some of these names */
4749 struct lsa_TransNameArray tnames
;
4751 tnames
.names
= talloc_zero_array(tctx
, struct lsa_TranslatedName
, tnames
.count
);
4752 tnames
.names
[0].name
.string
= info
->dns
.name
.string
;
4753 tnames
.names
[0].sid_type
= SID_NAME_DOMAIN
;
4754 tnames
.names
[1].name
.string
= info
->dns
.dns_domain
.string
;
4755 tnames
.names
[1].sid_type
= SID_NAME_DOMAIN
;
4756 tnames
.names
[2].name
.string
= talloc_asprintf(tctx
, "%s\\", info
->dns
.name
.string
);
4757 tnames
.names
[2].sid_type
= SID_NAME_DOMAIN
;
4758 tnames
.names
[3].name
.string
= talloc_asprintf(tctx
, "%s\\", info
->dns
.dns_domain
.string
);
4759 tnames
.names
[3].sid_type
= SID_NAME_DOMAIN
;
4760 tnames
.names
[4].name
.string
= talloc_asprintf(tctx
, "%s\\guest", info
->dns
.name
.string
);
4761 tnames
.names
[4].sid_type
= SID_NAME_USER
;
4762 tnames
.names
[5].name
.string
= talloc_asprintf(tctx
, "%s\\krbtgt", info
->dns
.name
.string
);
4763 tnames
.names
[5].sid_type
= SID_NAME_USER
;
4764 tnames
.names
[6].name
.string
= talloc_asprintf(tctx
, "%s\\guest", info
->dns
.dns_domain
.string
);
4765 tnames
.names
[6].sid_type
= SID_NAME_USER
;
4766 tnames
.names
[7].name
.string
= talloc_asprintf(tctx
, "%s\\krbtgt", info
->dns
.dns_domain
.string
);
4767 tnames
.names
[7].sid_type
= SID_NAME_USER
;
4768 tnames
.names
[8].name
.string
= talloc_asprintf(tctx
, "krbtgt@%s", info
->dns
.name
.string
);
4769 tnames
.names
[8].sid_type
= SID_NAME_USER
;
4770 tnames
.names
[9].name
.string
= talloc_asprintf(tctx
, "krbtgt@%s", info
->dns
.dns_domain
.string
);
4771 tnames
.names
[9].sid_type
= SID_NAME_USER
;
4772 tnames
.names
[10].name
.string
= talloc_asprintf(tctx
, "%s\\"TEST_MACHINENAME
"$", info
->dns
.name
.string
);
4773 tnames
.names
[10].sid_type
= SID_NAME_USER
;
4774 tnames
.names
[11].name
.string
= talloc_asprintf(tctx
, "%s\\"TEST_MACHINENAME
"$", info
->dns
.dns_domain
.string
);
4775 tnames
.names
[11].sid_type
= SID_NAME_USER
;
4776 tnames
.names
[12].name
.string
= talloc_asprintf(tctx
, TEST_MACHINENAME
"$@%s", info
->dns
.name
.string
);
4777 tnames
.names
[12].sid_type
= SID_NAME_USER
;
4778 tnames
.names
[13].name
.string
= talloc_asprintf(tctx
, TEST_MACHINENAME
"$@%s", info
->dns
.dns_domain
.string
);
4779 tnames
.names
[13].sid_type
= SID_NAME_USER
;
4780 ret
&= test_LookupNames(b
, tctx
, handle
, &tnames
);
4788 static bool test_QueryInfoPolicy(struct dcerpc_binding_handle
*b
,
4789 struct torture_context
*tctx
,
4790 struct policy_handle
*handle
)
4792 return test_QueryInfoPolicyCalls(false, b
, tctx
, handle
);
4795 static bool test_QueryInfoPolicy2(struct dcerpc_binding_handle
*b
,
4796 struct torture_context
*tctx
,
4797 struct policy_handle
*handle
)
4799 return test_QueryInfoPolicyCalls(true, b
, tctx
, handle
);
4802 static bool test_GetUserName(struct dcerpc_binding_handle
*b
,
4803 struct torture_context
*tctx
)
4805 struct lsa_GetUserName r
;
4807 struct lsa_String
*authority_name_p
= NULL
;
4808 struct lsa_String
*account_name_p
= NULL
;
4810 torture_comment(tctx
, "\nTesting GetUserName\n");
4812 r
.in
.system_name
= "\\";
4813 r
.in
.account_name
= &account_name_p
;
4814 r
.in
.authority_name
= NULL
;
4815 r
.out
.account_name
= &account_name_p
;
4817 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_GetUserName_r(b
, tctx
, &r
),
4818 "GetUserName failed");
4820 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
4821 torture_comment(tctx
, "GetUserName failed - %s\n", nt_errstr(r
.out
.result
));
4825 account_name_p
= NULL
;
4826 r
.in
.account_name
= &account_name_p
;
4827 r
.in
.authority_name
= &authority_name_p
;
4828 r
.out
.account_name
= &account_name_p
;
4830 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_GetUserName_r(b
, tctx
, &r
),
4831 "GetUserName failed");
4833 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
4834 torture_comment(tctx
, "GetUserName failed - %s\n", nt_errstr(r
.out
.result
));
4841 static bool test_GetUserName_fail(struct dcerpc_binding_handle
*b
,
4842 struct torture_context
*tctx
)
4844 struct lsa_GetUserName r
;
4845 struct lsa_String
*account_name_p
= NULL
;
4848 torture_comment(tctx
, "\nTesting GetUserName_fail\n");
4850 r
.in
.system_name
= "\\";
4851 r
.in
.account_name
= &account_name_p
;
4852 r
.in
.authority_name
= NULL
;
4853 r
.out
.account_name
= &account_name_p
;
4855 status
= dcerpc_lsa_GetUserName_r(b
, tctx
, &r
);
4856 if (!NT_STATUS_IS_OK(status
)) {
4857 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
4858 torture_comment(tctx
,
4859 "GetUserName correctly returned with "
4865 torture_assert_ntstatus_equal(tctx
,
4867 NT_STATUS_ACCESS_DENIED
,
4868 "GetUserName return value should "
4869 "be ACCESS_DENIED");
4873 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
4874 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
) ||
4875 NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED
)) {
4876 torture_comment(tctx
,
4877 "GetUserName correctly returned with "
4879 nt_errstr(r
.out
.result
));
4884 torture_assert_ntstatus_equal(tctx
,
4887 "GetUserName return value should be "
4893 bool test_lsa_Close(struct dcerpc_binding_handle
*b
,
4894 struct torture_context
*tctx
,
4895 struct policy_handle
*handle
)
4898 struct policy_handle handle2
;
4900 torture_comment(tctx
, "\nTesting Close\n");
4902 r
.in
.handle
= handle
;
4903 r
.out
.handle
= &handle2
;
4905 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_Close_r(b
, tctx
, &r
),
4907 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4910 torture_assert_ntstatus_equal(tctx
, dcerpc_lsa_Close_r(b
, tctx
, &r
),
4911 NT_STATUS_RPC_SS_CONTEXT_MISMATCH
, "Close should failed");
4913 torture_comment(tctx
, "\n");
4918 bool torture_rpc_lsa(struct torture_context
*tctx
)
4921 struct dcerpc_pipe
*p
;
4923 struct policy_handle
*handle
= NULL
;
4924 struct test_join
*join
= NULL
;
4925 struct cli_credentials
*machine_creds
;
4926 struct dcerpc_binding_handle
*b
;
4927 enum dcerpc_transport_t transport
;
4929 status
= torture_rpc_connection(tctx
, &p
, &ndr_table_lsarpc
);
4930 if (!NT_STATUS_IS_OK(status
)) {
4933 b
= p
->binding_handle
;
4934 transport
= dcerpc_binding_get_transport(p
->binding
);
4936 /* Test lsaLookupSids3 and lsaLookupNames4 over tcpip */
4937 if (transport
== NCACN_IP_TCP
) {
4938 if (!test_OpenPolicy_fail(b
, tctx
)) {
4942 if (!test_OpenPolicy2_fail(b
, tctx
)) {
4946 if (!test_many_LookupSids(p
, tctx
, handle
)) {
4953 if (!test_OpenPolicy(b
, tctx
)) {
4957 if (!test_lsa_OpenPolicy2(b
, tctx
, &handle
)) {
4962 join
= torture_join_domain(tctx
, TEST_MACHINENAME
, ACB_WSTRUST
, &machine_creds
);
4967 if (!test_LookupSids_async(b
, tctx
, handle
)) {
4971 if (!test_QueryDomainInfoPolicy(b
, tctx
, handle
)) {
4975 if (!test_CreateSecret(p
, tctx
, handle
)) {
4979 if (!test_QueryInfoPolicy(b
, tctx
, handle
)) {
4983 if (!test_QueryInfoPolicy2(b
, tctx
, handle
)) {
4987 if (!test_Delete(b
, tctx
, handle
)) {
4991 if (!test_many_LookupSids(p
, tctx
, handle
)) {
4995 if (!test_lsa_Close(b
, tctx
, handle
)) {
4999 torture_leave_domain(tctx
, join
);
5002 if (!test_many_LookupSids(p
, tctx
, handle
)) {
5007 if (!test_GetUserName(b
, tctx
)) {
5014 bool torture_rpc_lsa_get_user(struct torture_context
*tctx
)
5017 struct dcerpc_pipe
*p
;
5019 struct dcerpc_binding_handle
*b
;
5020 enum dcerpc_transport_t transport
;
5022 status
= torture_rpc_connection(tctx
, &p
, &ndr_table_lsarpc
);
5023 if (!NT_STATUS_IS_OK(status
)) {
5026 b
= p
->binding_handle
;
5027 transport
= dcerpc_binding_get_transport(p
->binding
);
5029 if (transport
== NCACN_IP_TCP
) {
5030 if (!test_GetUserName_fail(b
, tctx
)) {
5036 if (!test_GetUserName(b
, tctx
)) {
5043 static bool testcase_LookupNames(struct torture_context
*tctx
,
5044 struct dcerpc_pipe
*p
)
5047 struct policy_handle
*handle
;
5048 struct lsa_TransNameArray tnames
;
5049 struct lsa_TransNameArray2 tnames2
;
5050 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5051 enum dcerpc_transport_t transport
= dcerpc_binding_get_transport(p
->binding
);
5053 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
5054 torture_comment(tctx
, "testcase_LookupNames is only available "
5055 "over NCACN_NP or NCALRPC");
5059 if (!test_OpenPolicy(b
, tctx
)) {
5063 if (!test_lsa_OpenPolicy2(b
, tctx
, &handle
)) {
5072 tnames
.names
= talloc_array(tctx
, struct lsa_TranslatedName
, tnames
.count
);
5073 ZERO_STRUCT(tnames
.names
[0]);
5074 tnames
.names
[0].name
.string
= "BUILTIN";
5075 tnames
.names
[0].sid_type
= SID_NAME_DOMAIN
;
5077 if (!test_LookupNames(b
, tctx
, handle
, &tnames
)) {
5082 tnames2
.names
= talloc_array(tctx
, struct lsa_TranslatedName2
, tnames2
.count
);
5083 ZERO_STRUCT(tnames2
.names
[0]);
5084 tnames2
.names
[0].name
.string
= "BUILTIN";
5085 tnames2
.names
[0].sid_type
= SID_NAME_DOMAIN
;
5087 if (!test_LookupNames2(b
, tctx
, handle
, &tnames2
, true)) {
5091 if (!test_LookupNames3(b
, tctx
, handle
, &tnames2
, true)) {
5095 if (!test_LookupNames_wellknown(b
, tctx
, handle
)) {
5099 if (!test_LookupNames_NULL(b
, tctx
, handle
)) {
5103 if (!test_LookupNames_bogus(b
, tctx
, handle
)) {
5107 if (!test_lsa_Close(b
, tctx
, handle
)) {
5114 struct torture_suite
*torture_rpc_lsa_lookup_names(TALLOC_CTX
*mem_ctx
)
5116 struct torture_suite
*suite
;
5117 struct torture_rpc_tcase
*tcase
;
5119 suite
= torture_suite_create(mem_ctx
, "lsa.lookupnames");
5121 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "lsa",
5123 torture_rpc_tcase_add_test(tcase
, "LookupNames",
5124 testcase_LookupNames
);
5129 struct lsa_trustdom_state
{
5130 uint32_t num_trusts
;
5133 static bool testcase_TrustedDomains(struct torture_context
*tctx
,
5134 struct dcerpc_pipe
*p
,
5138 struct policy_handle
*handle
;
5139 struct lsa_trustdom_state
*state
=
5140 talloc_get_type_abort(data
, struct lsa_trustdom_state
);
5141 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5142 enum dcerpc_transport_t transport
= dcerpc_binding_get_transport(p
->binding
);
5144 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
5145 torture_comment(tctx
, "testcase_TrustedDomains is only available "
5146 "over NCACN_NP or NCALRPC");
5150 torture_comment(tctx
, "Testing %d domains\n", state
->num_trusts
);
5152 if (!test_OpenPolicy(b
, tctx
)) {
5156 if (!test_lsa_OpenPolicy2(b
, tctx
, &handle
)) {
5164 if (!test_CreateTrustedDomain(b
, tctx
, handle
, state
->num_trusts
)) {
5168 if (!test_CreateTrustedDomainEx(p
, tctx
, handle
, state
->num_trusts
)) {
5172 if (!test_CreateTrustedDomainEx2(p
, tctx
, handle
, state
->num_trusts
)) {
5176 if (!test_lsa_Close(b
, tctx
, handle
)) {
5183 struct torture_suite
*torture_rpc_lsa_trusted_domains(TALLOC_CTX
*mem_ctx
)
5185 struct torture_suite
*suite
;
5186 struct torture_rpc_tcase
*tcase
;
5187 struct lsa_trustdom_state
*state
;
5189 state
= talloc(mem_ctx
, struct lsa_trustdom_state
);
5191 state
->num_trusts
= 12;
5193 suite
= torture_suite_create(mem_ctx
, "lsa.trusted.domains");
5195 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "lsa",
5197 torture_rpc_tcase_add_test_ex(tcase
, "TrustedDomains",
5198 testcase_TrustedDomains
,
5204 static bool testcase_Privileges(struct torture_context
*tctx
,
5205 struct dcerpc_pipe
*p
)
5207 struct policy_handle
*handle
;
5208 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5209 enum dcerpc_transport_t transport
= dcerpc_binding_get_transport(p
->binding
);
5211 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
5212 torture_skip(tctx
, "testcase_Privileges is only available "
5213 "over NCACN_NP or NCALRPC");
5216 if (!test_OpenPolicy(b
, tctx
)) {
5220 if (!test_lsa_OpenPolicy2(b
, tctx
, &handle
)) {
5228 if (!test_CreateAccount(b
, tctx
, handle
)) {
5232 if (!test_EnumAccounts(b
, tctx
, handle
)) {
5236 if (!test_EnumPrivs(b
, tctx
, handle
)) {
5240 if (!test_lsa_Close(b
, tctx
, handle
)) {
5248 struct torture_suite
*torture_rpc_lsa_privileges(TALLOC_CTX
*mem_ctx
)
5250 struct torture_suite
*suite
;
5251 struct torture_rpc_tcase
*tcase
;
5253 suite
= torture_suite_create(mem_ctx
, "lsa.privileges");
5255 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "lsa",
5257 torture_rpc_tcase_add_test(tcase
, "Privileges",
5258 testcase_Privileges
);