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 "librpc/gen_ndr/ndr_lsa_c.h"
25 #include "librpc/gen_ndr/netlogon.h"
26 #include "librpc/gen_ndr/ndr_drsblobs.h"
27 #include "librpc/gen_ndr/ndr_netlogon_c.h"
28 #include "lib/events/events.h"
29 #include "libcli/security/security.h"
30 #include "libcli/auth/libcli_auth.h"
31 #include "torture/rpc/torture_rpc.h"
32 #include "param/param.h"
33 #include "../lib/crypto/crypto.h"
34 #define TEST_MACHINENAME "lsatestmach"
35 #define TRUSTPW "12345678"
37 static void init_lsa_String(struct lsa_String
*name
, const char *s
)
42 static bool test_OpenPolicy(struct dcerpc_binding_handle
*b
,
43 struct torture_context
*tctx
)
45 struct lsa_ObjectAttribute attr
;
46 struct policy_handle handle
;
47 struct lsa_QosInfo qos
;
48 struct lsa_OpenPolicy r
;
49 uint16_t system_name
= '\\';
51 torture_comment(tctx
, "\nTesting OpenPolicy\n");
54 qos
.impersonation_level
= 2;
56 qos
.effective_only
= 0;
60 attr
.object_name
= NULL
;
65 r
.in
.system_name
= &system_name
;
67 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
68 r
.out
.handle
= &handle
;
70 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenPolicy_r(b
, tctx
, &r
),
73 torture_assert_ntstatus_ok(tctx
,
80 static bool test_OpenPolicy_fail(struct dcerpc_binding_handle
*b
,
81 struct torture_context
*tctx
)
83 struct lsa_ObjectAttribute attr
;
84 struct policy_handle handle
;
85 struct lsa_QosInfo qos
;
86 struct lsa_OpenPolicy r
;
87 uint16_t system_name
= '\\';
90 torture_comment(tctx
, "\nTesting OpenPolicy_fail\n");
93 qos
.impersonation_level
= 2;
95 qos
.effective_only
= 0;
99 attr
.object_name
= NULL
;
101 attr
.sec_desc
= NULL
;
104 r
.in
.system_name
= &system_name
;
106 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
107 r
.out
.handle
= &handle
;
109 status
= dcerpc_lsa_OpenPolicy_r(b
, tctx
, &r
);
110 if (!NT_STATUS_IS_OK(status
)) {
111 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
112 torture_comment(tctx
,
113 "OpenPolicy correctly returned with "
119 torture_assert_ntstatus_equal(tctx
,
121 NT_STATUS_ACCESS_DENIED
,
122 "OpenPolicy return value should "
127 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
128 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
) ||
129 NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED
)) {
130 torture_comment(tctx
,
131 "OpenPolicy correctly returned with "
133 nt_errstr(r
.out
.result
));
138 torture_assert_ntstatus_equal(tctx
,
141 "OpenPolicy return value should be "
148 bool test_lsa_OpenPolicy2_ex(struct dcerpc_binding_handle
*b
,
149 struct torture_context
*tctx
,
150 struct policy_handle
**handle
,
151 NTSTATUS expected_status
)
153 struct lsa_ObjectAttribute attr
;
154 struct lsa_QosInfo qos
;
155 struct lsa_OpenPolicy2 r
;
158 torture_comment(tctx
, "\nTesting OpenPolicy2\n");
160 *handle
= talloc(tctx
, struct policy_handle
);
161 torture_assert(tctx
, *handle
!= NULL
, "talloc(tctx, struct policy_handle)");
164 qos
.impersonation_level
= 2;
165 qos
.context_mode
= 1;
166 qos
.effective_only
= 0;
169 attr
.root_dir
= NULL
;
170 attr
.object_name
= NULL
;
172 attr
.sec_desc
= NULL
;
175 r
.in
.system_name
= "\\";
177 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
178 r
.out
.handle
= *handle
;
180 status
= dcerpc_lsa_OpenPolicy2_r(b
, tctx
, &r
);
181 torture_assert_ntstatus_equal(tctx
, status
, expected_status
,
182 "OpenPolicy2 failed");
183 if (!NT_STATUS_IS_OK(expected_status
)) {
187 torture_assert_ntstatus_ok(tctx
,
189 "OpenPolicy2 failed");
195 bool test_lsa_OpenPolicy2(struct dcerpc_binding_handle
*b
,
196 struct torture_context
*tctx
,
197 struct policy_handle
**handle
)
199 return test_lsa_OpenPolicy2_ex(b
, tctx
, handle
, NT_STATUS_OK
);
202 static bool test_OpenPolicy2_fail(struct dcerpc_binding_handle
*b
,
203 struct torture_context
*tctx
)
205 struct lsa_ObjectAttribute attr
;
206 struct policy_handle handle
;
207 struct lsa_QosInfo qos
;
208 struct lsa_OpenPolicy2 r
;
211 torture_comment(tctx
, "\nTesting OpenPolicy2_fail\n");
214 qos
.impersonation_level
= 2;
215 qos
.context_mode
= 1;
216 qos
.effective_only
= 0;
219 attr
.root_dir
= NULL
;
220 attr
.object_name
= NULL
;
222 attr
.sec_desc
= NULL
;
225 r
.in
.system_name
= "\\";
227 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
228 r
.out
.handle
= &handle
;
230 status
= dcerpc_lsa_OpenPolicy2_r(b
, tctx
, &r
);
231 if (!NT_STATUS_IS_OK(status
)) {
232 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
233 torture_comment(tctx
,
234 "OpenPolicy2 correctly returned with "
240 torture_assert_ntstatus_equal(tctx
,
242 NT_STATUS_ACCESS_DENIED
,
243 "OpenPolicy2 return value should "
248 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
) ||
249 NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED
)) {
250 torture_comment(tctx
,
251 "OpenPolicy2 correctly returned with "
253 nt_errstr(r
.out
.result
));
258 "OpenPolicy2 return value should be "
259 "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
264 static bool test_LookupNames(struct dcerpc_binding_handle
*b
,
265 struct torture_context
*tctx
,
266 struct policy_handle
*handle
,
267 struct lsa_TransNameArray
*tnames
)
269 struct lsa_LookupNames r
;
270 struct lsa_TransSidArray sids
;
271 struct lsa_RefDomainList
*domains
= NULL
;
272 struct lsa_String
*names
;
277 torture_comment(tctx
, "\nTesting LookupNames with %d names\n", tnames
->count
);
285 input_idx
= talloc_array(tctx
, uint32_t, tnames
->count
);
286 names
= talloc_array(tctx
, struct lsa_String
, tnames
->count
);
288 for (i
=0;i
<tnames
->count
;i
++) {
289 if (tnames
->names
[i
].sid_type
!= SID_NAME_UNKNOWN
) {
290 init_lsa_String(&names
[r
.in
.num_names
], tnames
->names
[i
].name
.string
);
291 input_idx
[r
.in
.num_names
] = i
;
296 r
.in
.handle
= handle
;
301 r
.out
.count
= &count
;
303 r
.out
.domains
= &domains
;
305 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_LookupNames_r(b
, tctx
, &r
),
306 "LookupNames failed");
307 if (NT_STATUS_EQUAL(r
.out
.result
, STATUS_SOME_UNMAPPED
) ||
308 NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_NONE_MAPPED
)) {
309 for (i
=0;i
< r
.in
.num_names
;i
++) {
310 if (i
< count
&& sids
.sids
[i
].sid_type
== SID_NAME_UNKNOWN
) {
311 torture_comment(tctx
, "LookupName of %s was unmapped\n",
312 tnames
->names
[i
].name
.string
);
313 } else if (i
>=count
) {
314 torture_comment(tctx
, "LookupName of %s failed to return a result\n",
315 tnames
->names
[i
].name
.string
);
318 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
319 "LookupNames failed");
320 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
321 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
322 "LookupNames failed");
325 for (i
=0;i
< r
.in
.num_names
;i
++) {
326 torture_assert(tctx
, (i
< count
),
327 talloc_asprintf(tctx
,
328 "LookupName of %s failed to return a result\n",
329 tnames
->names
[input_idx
[i
]].name
.string
));
331 torture_assert_int_equal(tctx
,
332 sids
.sids
[i
].sid_type
,
333 tnames
->names
[input_idx
[i
]].sid_type
,
334 talloc_asprintf(tctx
,
335 "LookupName of %s got unexpected name type: %s\n",
336 tnames
->names
[input_idx
[i
]].name
.string
,
337 sid_type_lookup(sids
.sids
[i
].sid_type
)));
338 if (sids
.sids
[i
].sid_type
!= SID_NAME_DOMAIN
) {
341 torture_assert_int_equal(tctx
,
344 talloc_asprintf(tctx
,
345 "LookupName of %s got unexpected rid: %d\n",
346 tnames
->names
[input_idx
[i
]].name
.string
,
353 static bool test_LookupNames_bogus(struct dcerpc_binding_handle
*b
,
354 struct torture_context
*tctx
,
355 struct policy_handle
*handle
)
357 struct lsa_LookupNames r
;
358 struct lsa_TransSidArray sids
;
359 struct lsa_RefDomainList
*domains
= NULL
;
360 struct lsa_String names
[1];
363 torture_comment(tctx
, "\nTesting LookupNames with bogus name\n");
368 init_lsa_String(&names
[0], "NT AUTHORITY\\BOGUS");
370 r
.in
.handle
= handle
;
376 r
.out
.count
= &count
;
378 r
.out
.domains
= &domains
;
380 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_LookupNames_r(b
, tctx
, &r
),
381 "LookupNames bogus failed");
382 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_NONE_MAPPED
)) {
383 torture_comment(tctx
, "LookupNames failed - %s\n",
384 nt_errstr(r
.out
.result
));
388 torture_comment(tctx
, "\n");
393 static bool test_LookupNames_NULL(struct dcerpc_binding_handle
*b
,
394 struct torture_context
*tctx
,
395 struct policy_handle
*handle
)
397 struct lsa_LookupNames r
;
398 struct lsa_TransSidArray sids
;
399 struct lsa_RefDomainList
*domains
= NULL
;
400 struct lsa_String names
[1];
403 torture_comment(tctx
, "\nTesting LookupNames with NULL name\n");
408 names
[0].string
= NULL
;
410 r
.in
.handle
= handle
;
416 r
.out
.count
= &count
;
418 r
.out
.domains
= &domains
;
420 /* nt4 returns NT_STATUS_NONE_MAPPED with sid_type
421 * SID_NAME_UNKNOWN, rid 0, and sid_index -1;
423 * w2k3/w2k8 return NT_STATUS_OK with sid_type
424 * SID_NAME_DOMAIN, rid -1 and sid_index 0 and BUILTIN domain
427 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_LookupNames_r(b
, tctx
, &r
),
428 "LookupNames with NULL name failed");
429 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
430 "LookupNames with NULL name failed");
432 torture_comment(tctx
, "\n");
437 static bool test_LookupNames_wellknown(struct dcerpc_binding_handle
*b
,
438 struct torture_context
*tctx
,
439 struct policy_handle
*handle
)
441 struct lsa_TranslatedName name
;
442 struct lsa_TransNameArray tnames
;
445 torture_comment(tctx
, "Testing LookupNames with well known names\n");
447 tnames
.names
= &name
;
449 name
.name
.string
= "NT AUTHORITY\\SYSTEM";
450 name
.sid_type
= SID_NAME_WKN_GRP
;
451 ret
&= test_LookupNames(b
, tctx
, handle
, &tnames
);
453 name
.name
.string
= "NT AUTHORITY\\ANONYMOUS LOGON";
454 name
.sid_type
= SID_NAME_WKN_GRP
;
455 ret
&= test_LookupNames(b
, tctx
, handle
, &tnames
);
457 name
.name
.string
= "NT AUTHORITY\\Authenticated Users";
458 name
.sid_type
= SID_NAME_WKN_GRP
;
459 ret
&= test_LookupNames(b
, tctx
, handle
, &tnames
);
462 name
.name
.string
= "NT AUTHORITY";
463 ret
&= test_LookupNames(b
, tctx
, handle
, &tnames
);
465 name
.name
.string
= "NT AUTHORITY\\";
466 ret
&= test_LookupNames(b
, tctx
, handle
, &tnames
);
469 name
.name
.string
= "BUILTIN\\";
470 name
.sid_type
= SID_NAME_DOMAIN
;
471 ret
&= test_LookupNames(b
, tctx
, handle
, &tnames
);
473 name
.name
.string
= "BUILTIN\\Administrators";
474 name
.sid_type
= SID_NAME_ALIAS
;
475 ret
&= test_LookupNames(b
, tctx
, handle
, &tnames
);
477 name
.name
.string
= "SYSTEM";
478 name
.sid_type
= SID_NAME_WKN_GRP
;
479 ret
&= test_LookupNames(b
, tctx
, handle
, &tnames
);
481 name
.name
.string
= "Everyone";
482 name
.sid_type
= SID_NAME_WKN_GRP
;
483 ret
&= test_LookupNames(b
, tctx
, handle
, &tnames
);
487 static bool test_LookupNames2(struct dcerpc_binding_handle
*b
,
488 struct torture_context
*tctx
,
489 struct policy_handle
*handle
,
490 struct lsa_TransNameArray2
*tnames
,
493 struct lsa_LookupNames2 r
;
494 struct lsa_TransSidArray2 sids
;
495 struct lsa_RefDomainList
*domains
= NULL
;
496 struct lsa_String
*names
;
501 torture_comment(tctx
, "\nTesting LookupNames2 with %d names\n", tnames
->count
);
508 input_idx
= talloc_array(tctx
, uint32_t, tnames
->count
);
509 names
= talloc_array(tctx
, struct lsa_String
, tnames
->count
);
511 for (i
=0;i
<tnames
->count
;i
++) {
512 if (tnames
->names
[i
].sid_type
!= SID_NAME_UNKNOWN
) {
513 init_lsa_String(&names
[r
.in
.num_names
], tnames
->names
[i
].name
.string
);
514 input_idx
[r
.in
.num_names
] = i
;
519 r
.in
.handle
= handle
;
524 r
.in
.lookup_options
= 0;
525 r
.in
.client_revision
= 0;
526 r
.out
.count
= &count
;
528 r
.out
.domains
= &domains
;
530 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_LookupNames2_r(b
, tctx
, &r
),
531 "LookupNames2 failed");
532 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LookupNames2 failed");
535 torture_assert_int_equal(tctx
, count
, sids
.count
,
536 "unexpected number of results returned");
537 if (sids
.count
> 0) {
538 torture_assert(tctx
, sids
.sids
, "invalid sid buffer");
542 torture_comment(tctx
, "\n");
548 static bool test_LookupNames3(struct dcerpc_binding_handle
*b
,
549 struct torture_context
*tctx
,
550 struct policy_handle
*handle
,
551 struct lsa_TransNameArray2
*tnames
,
554 struct lsa_LookupNames3 r
;
555 struct lsa_TransSidArray3 sids
;
556 struct lsa_RefDomainList
*domains
= NULL
;
557 struct lsa_String
*names
;
562 torture_comment(tctx
, "\nTesting LookupNames3 with %d names\n", tnames
->count
);
569 input_idx
= talloc_array(tctx
, uint32_t, tnames
->count
);
570 names
= talloc_array(tctx
, struct lsa_String
, tnames
->count
);
571 for (i
=0;i
<tnames
->count
;i
++) {
572 if (tnames
->names
[i
].sid_type
!= SID_NAME_UNKNOWN
) {
573 init_lsa_String(&names
[r
.in
.num_names
], tnames
->names
[i
].name
.string
);
574 input_idx
[r
.in
.num_names
] = i
;
579 r
.in
.handle
= handle
;
584 r
.in
.lookup_options
= 0;
585 r
.in
.client_revision
= 0;
586 r
.out
.count
= &count
;
588 r
.out
.domains
= &domains
;
590 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_LookupNames3_r(b
, tctx
, &r
),
591 "LookupNames3 failed");
592 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
593 "LookupNames3 failed");
596 torture_assert_int_equal(tctx
, count
, sids
.count
,
597 "unexpected number of results returned");
598 if (sids
.count
> 0) {
599 torture_assert(tctx
, sids
.sids
, "invalid sid buffer");
603 torture_comment(tctx
, "\n");
608 static bool test_LookupNames4(struct dcerpc_binding_handle
*b
,
609 struct torture_context
*tctx
,
610 struct lsa_TransNameArray2
*tnames
,
613 struct lsa_LookupNames4 r
;
614 struct lsa_TransSidArray3 sids
;
615 struct lsa_RefDomainList
*domains
= NULL
;
616 struct lsa_String
*names
;
621 torture_comment(tctx
, "\nTesting LookupNames4 with %d names\n", tnames
->count
);
628 input_idx
= talloc_array(tctx
, uint32_t, tnames
->count
);
629 names
= talloc_array(tctx
, struct lsa_String
, tnames
->count
);
630 for (i
=0;i
<tnames
->count
;i
++) {
631 if (tnames
->names
[i
].sid_type
!= SID_NAME_UNKNOWN
) {
632 init_lsa_String(&names
[r
.in
.num_names
], tnames
->names
[i
].name
.string
);
633 input_idx
[r
.in
.num_names
] = i
;
638 r
.in
.num_names
= tnames
->count
;
643 r
.in
.lookup_options
= 0;
644 r
.in
.client_revision
= 0;
645 r
.out
.count
= &count
;
647 r
.out
.domains
= &domains
;
649 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_LookupNames4_r(b
, tctx
, &r
),
650 "LookupNames4 failed");
652 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
653 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_NONE_MAPPED
)) {
654 torture_comment(tctx
,
655 "LookupNames4 failed: %s - not considered as an error",
656 nt_errstr(r
.out
.result
));
661 torture_assert_ntstatus_ok(tctx
,
663 "LookupNames4 failed");
666 torture_assert_int_equal(tctx
, count
, sids
.count
,
667 "unexpected number of results returned");
668 if (sids
.count
> 0) {
669 torture_assert(tctx
, sids
.sids
, "invalid sid buffer");
673 torture_comment(tctx
, "\n");
678 static bool test_LookupNames4_fail(struct dcerpc_binding_handle
*b
,
679 struct torture_context
*tctx
)
681 struct lsa_LookupNames4 r
;
682 struct lsa_TransSidArray3 sids
;
683 struct lsa_RefDomainList
*domains
= NULL
;
684 struct lsa_String
*names
= NULL
;
688 torture_comment(tctx
, "\nTesting LookupNames4_fail");
695 r
.in
.num_names
= count
;
700 r
.in
.lookup_options
= 0;
701 r
.in
.client_revision
= 0;
702 r
.out
.count
= &count
;
704 r
.out
.domains
= &domains
;
706 status
= dcerpc_lsa_LookupNames4_r(b
, tctx
, &r
);
707 if (!NT_STATUS_IS_OK(status
)) {
708 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
709 torture_comment(tctx
,
710 "LookupNames4 correctly returned with "
716 torture_assert_ntstatus_equal(tctx
,
718 NT_STATUS_ACCESS_DENIED
,
719 "LookupNames4 return value should "
724 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
725 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
) ||
726 NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED
)) {
727 torture_comment(tctx
,
728 "LookupSids3 correctly returned with "
730 nt_errstr(r
.out
.result
));
736 "LookupNames4 return value should be "
737 "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
743 static bool test_LookupSids(struct dcerpc_binding_handle
*b
,
744 struct torture_context
*tctx
,
745 struct policy_handle
*handle
,
746 struct lsa_SidArray
*sids
)
748 struct lsa_LookupSids r
;
749 struct lsa_TransNameArray names
;
750 struct lsa_RefDomainList
*domains
= NULL
;
751 uint32_t count
= sids
->num_sids
;
753 torture_comment(tctx
, "\nTesting LookupSids\n");
758 r
.in
.handle
= handle
;
763 r
.out
.count
= &count
;
764 r
.out
.names
= &names
;
765 r
.out
.domains
= &domains
;
767 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_LookupSids_r(b
, tctx
, &r
),
768 "LookupSids failed");
769 if (!NT_STATUS_EQUAL(r
.out
.result
, STATUS_SOME_UNMAPPED
)) {
770 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
771 "LookupSids failed");
774 torture_comment(tctx
, "\n");
776 if (!test_LookupNames(b
, tctx
, handle
, &names
)) {
784 static bool test_LookupSids2(struct dcerpc_binding_handle
*b
,
785 struct torture_context
*tctx
,
786 struct policy_handle
*handle
,
787 struct lsa_SidArray
*sids
)
789 struct lsa_LookupSids2 r
;
790 struct lsa_TransNameArray2 names
;
791 struct lsa_RefDomainList
*domains
= NULL
;
792 uint32_t count
= sids
->num_sids
;
794 torture_comment(tctx
, "\nTesting LookupSids2\n");
799 r
.in
.handle
= handle
;
804 r
.in
.lookup_options
= 0;
805 r
.in
.client_revision
= 0;
806 r
.out
.count
= &count
;
807 r
.out
.names
= &names
;
808 r
.out
.domains
= &domains
;
810 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_LookupSids2_r(b
, tctx
, &r
),
811 "LookupSids2 failed");
812 if (!NT_STATUS_IS_OK(r
.out
.result
) &&
813 !NT_STATUS_EQUAL(r
.out
.result
, STATUS_SOME_UNMAPPED
)) {
814 torture_comment(tctx
, "LookupSids2 failed - %s\n",
815 nt_errstr(r
.out
.result
));
819 torture_comment(tctx
, "\n");
821 if (!test_LookupNames2(b
, tctx
, handle
, &names
, false)) {
825 if (!test_LookupNames3(b
, tctx
, handle
, &names
, false)) {
832 static bool test_LookupSids3(struct dcerpc_binding_handle
*b
,
833 struct torture_context
*tctx
,
834 struct lsa_SidArray
*sids
)
836 struct lsa_LookupSids3 r
;
837 struct lsa_TransNameArray2 names
;
838 struct lsa_RefDomainList
*domains
= NULL
;
839 uint32_t count
= sids
->num_sids
;
841 torture_comment(tctx
, "\nTesting LookupSids3\n");
850 r
.in
.lookup_options
= 0;
851 r
.in
.client_revision
= 0;
852 r
.out
.domains
= &domains
;
853 r
.out
.count
= &count
;
854 r
.out
.names
= &names
;
856 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_LookupSids3_r(b
, tctx
, &r
),
857 "LookupSids3 failed");
859 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
860 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_NONE_MAPPED
)) {
861 torture_comment(tctx
,
862 "LookupSids3 failed: %s - not considered as an error",
863 nt_errstr(r
.out
.result
));
868 torture_assert_ntstatus_ok(tctx
,
870 "LookupSids3 failed");
875 torture_comment(tctx
, "\n");
877 if (!test_LookupNames4(b
, tctx
, &names
, true)) {
884 static bool test_LookupSids3_fail(struct dcerpc_binding_handle
*b
,
885 struct torture_context
*tctx
,
886 struct lsa_SidArray
*sids
)
888 struct lsa_LookupSids3 r
;
889 struct lsa_TransNameArray2 names
;
890 struct lsa_RefDomainList
*domains
= NULL
;
891 uint32_t count
= sids
->num_sids
;
894 torture_comment(tctx
, "\nTesting LookupSids3\n");
903 r
.in
.lookup_options
= 0;
904 r
.in
.client_revision
= 0;
905 r
.out
.domains
= &domains
;
906 r
.out
.count
= &count
;
907 r
.out
.names
= &names
;
909 status
= dcerpc_lsa_LookupSids3_r(b
, tctx
, &r
);
910 if (!NT_STATUS_IS_OK(status
)) {
911 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
912 torture_comment(tctx
,
913 "LookupSids3 correctly returned with "
919 torture_assert_ntstatus_equal(tctx
,
921 NT_STATUS_ACCESS_DENIED
,
922 "LookupSids3 return value should "
927 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
) ||
928 NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED
)) {
929 torture_comment(tctx
,
930 "LookupNames4 correctly returned with "
932 nt_errstr(r
.out
.result
));
937 "LookupSids3 return value should be "
938 "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
943 bool test_many_LookupSids(struct dcerpc_pipe
*p
,
944 struct torture_context
*tctx
,
945 struct policy_handle
*handle
)
948 struct lsa_SidArray sids
;
950 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
951 enum dcerpc_transport_t transport
= dcerpc_binding_get_transport(p
->binding
);
953 torture_comment(tctx
, "\nTesting LookupSids with lots of SIDs\n");
957 sids
.sids
= talloc_array(tctx
, struct lsa_SidPtr
, sids
.num_sids
);
959 for (i
=0; i
<sids
.num_sids
; i
++) {
960 const char *sidstr
= "S-1-5-32-545";
961 sids
.sids
[i
].sid
= dom_sid_parse_talloc(tctx
, sidstr
);
964 count
= sids
.num_sids
;
967 struct lsa_LookupSids r
;
968 struct lsa_TransNameArray names
;
969 struct lsa_RefDomainList
*domains
= NULL
;
973 r
.in
.handle
= handle
;
977 r
.in
.count
= &names
.count
;
978 r
.out
.count
= &count
;
979 r
.out
.names
= &names
;
980 r
.out
.domains
= &domains
;
982 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_LookupSids_r(b
, tctx
, &r
),
983 "LookupSids failed");
984 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
985 torture_comment(tctx
, "LookupSids failed - %s\n",
986 nt_errstr(r
.out
.result
));
990 torture_comment(tctx
, "\n");
992 if (!test_LookupNames(b
, tctx
, handle
, &names
)) {
997 if (transport
== NCACN_NP
) {
998 if (!test_LookupSids3_fail(b
, tctx
, &sids
)) {
1001 if (!test_LookupNames4_fail(b
, tctx
)) {
1004 } else if (transport
== NCACN_IP_TCP
) {
1005 struct lsa_TransNameArray2 names
;
1006 enum dcerpc_AuthType auth_type
;
1007 enum dcerpc_AuthLevel auth_level
;
1012 dcerpc_binding_handle_auth_info(p
->binding_handle
,
1013 &auth_type
, &auth_level
);
1015 if (auth_type
== DCERPC_AUTH_TYPE_SCHANNEL
&&
1016 auth_level
>= DCERPC_AUTH_LEVEL_INTEGRITY
) {
1017 if (!test_LookupSids3(b
, tctx
, &sids
)) {
1020 if (!test_LookupNames4(b
, tctx
, &names
, true)) {
1025 * If we don't have a secure channel these tests must
1026 * fail with ACCESS_DENIED.
1028 if (!test_LookupSids3_fail(b
, tctx
, &sids
)) {
1031 if (!test_LookupNames4_fail(b
, tctx
)) {
1037 torture_comment(tctx
, "\n");
1044 static void lookupsids_cb(struct tevent_req
*subreq
)
1046 int *replies
= (int *)tevent_req_callback_data_void(subreq
);
1049 status
= dcerpc_lsa_LookupSids_r_recv(subreq
, subreq
);
1050 TALLOC_FREE(subreq
);
1051 if (!NT_STATUS_IS_OK(status
)) {
1052 printf("lookupsids returned %s\n", nt_errstr(status
));
1056 if (*replies
>= 0) {
1061 static bool test_LookupSids_async(struct dcerpc_binding_handle
*b
,
1062 struct torture_context
*tctx
,
1063 struct policy_handle
*handle
)
1065 struct lsa_SidArray sids
;
1066 struct lsa_SidPtr sidptr
;
1068 struct lsa_TransNameArray
*names
;
1069 struct lsa_LookupSids
*r
;
1070 struct lsa_RefDomainList
*domains
= NULL
;
1071 struct tevent_req
**req
;
1074 const int num_async_requests
= 50;
1076 count
= talloc_array(tctx
, uint32_t, num_async_requests
);
1077 names
= talloc_array(tctx
, struct lsa_TransNameArray
, num_async_requests
);
1078 r
= talloc_array(tctx
, struct lsa_LookupSids
, num_async_requests
);
1080 torture_comment(tctx
, "\nTesting %d async lookupsids request\n", num_async_requests
);
1082 req
= talloc_array(tctx
, struct tevent_req
*, num_async_requests
);
1085 sids
.sids
= &sidptr
;
1086 sidptr
.sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-545");
1090 for (i
=0; i
<num_async_requests
; i
++) {
1093 names
[i
].names
= NULL
;
1095 r
[i
].in
.handle
= handle
;
1096 r
[i
].in
.sids
= &sids
;
1097 r
[i
].in
.names
= &names
[i
];
1099 r
[i
].in
.count
= &names
[i
].count
;
1100 r
[i
].out
.count
= &count
[i
];
1101 r
[i
].out
.names
= &names
[i
];
1102 r
[i
].out
.domains
= &domains
;
1104 req
[i
] = dcerpc_lsa_LookupSids_r_send(tctx
, tctx
->ev
, b
, &r
[i
]);
1105 if (req
[i
] == NULL
) {
1110 tevent_req_set_callback(req
[i
], lookupsids_cb
, &replies
);
1113 while (replies
>= 0 && replies
< num_async_requests
) {
1114 tevent_loop_once(tctx
->ev
);
1126 static bool test_LookupPrivValue(struct dcerpc_binding_handle
*b
,
1127 struct torture_context
*tctx
,
1128 struct policy_handle
*handle
,
1129 struct lsa_String
*name
)
1131 struct lsa_LookupPrivValue r
;
1132 struct lsa_LUID luid
;
1134 r
.in
.handle
= handle
;
1138 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_LookupPrivValue_r(b
, tctx
, &r
),
1139 "LookupPrivValue failed");
1140 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1141 "LookupPrivValue failed");
1146 static bool test_LookupPrivName(struct dcerpc_binding_handle
*b
,
1147 struct torture_context
*tctx
,
1148 struct policy_handle
*handle
,
1149 struct lsa_LUID
*luid
)
1151 struct lsa_LookupPrivName r
;
1152 struct lsa_StringLarge
*name
= NULL
;
1154 r
.in
.handle
= handle
;
1158 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_LookupPrivName_r(b
, tctx
, &r
),
1159 "LookupPrivName failed");
1160 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LookupPrivName failed");
1165 static bool test_RemovePrivilegesFromAccount(struct dcerpc_binding_handle
*b
,
1166 struct torture_context
*tctx
,
1167 struct policy_handle
*handle
,
1168 struct policy_handle
*acct_handle
,
1169 struct lsa_LUID
*luid
)
1171 struct lsa_RemovePrivilegesFromAccount r
;
1172 struct lsa_PrivilegeSet privs
;
1175 torture_comment(tctx
, "\nTesting RemovePrivilegesFromAccount\n");
1177 r
.in
.handle
= acct_handle
;
1178 r
.in
.remove_all
= 0;
1179 r
.in
.privs
= &privs
;
1183 privs
.set
= talloc_array(tctx
, struct lsa_LUIDAttribute
, 1);
1184 privs
.set
[0].luid
= *luid
;
1185 privs
.set
[0].attribute
= 0;
1187 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_RemovePrivilegesFromAccount_r(b
, tctx
, &r
),
1188 "RemovePrivilegesFromAccount failed");
1189 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1191 struct lsa_LookupPrivName r_name
;
1192 struct lsa_StringLarge
*name
= NULL
;
1194 r_name
.in
.handle
= handle
;
1195 r_name
.in
.luid
= luid
;
1196 r_name
.out
.name
= &name
;
1198 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_LookupPrivName_r(b
, tctx
, &r_name
),
1199 "LookupPrivName failed");
1200 if (!NT_STATUS_IS_OK(r_name
.out
.result
)) {
1201 torture_comment(tctx
, "\nLookupPrivName failed - %s\n",
1202 nt_errstr(r_name
.out
.result
));
1205 /* Windows 2008 does not allow this to be removed */
1206 if (strcmp("SeAuditPrivilege", name
->string
) == 0) {
1210 torture_comment(tctx
, "RemovePrivilegesFromAccount failed to remove %s - %s\n",
1212 nt_errstr(r
.out
.result
));
1219 static bool test_AddPrivilegesToAccount(struct dcerpc_binding_handle
*b
,
1220 struct torture_context
*tctx
,
1221 struct policy_handle
*acct_handle
,
1222 struct lsa_LUID
*luid
)
1224 struct lsa_AddPrivilegesToAccount r
;
1225 struct lsa_PrivilegeSet privs
;
1228 torture_comment(tctx
, "\nTesting AddPrivilegesToAccount\n");
1230 r
.in
.handle
= acct_handle
;
1231 r
.in
.privs
= &privs
;
1235 privs
.set
= talloc_array(tctx
, struct lsa_LUIDAttribute
, 1);
1236 privs
.set
[0].luid
= *luid
;
1237 privs
.set
[0].attribute
= 0;
1239 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_AddPrivilegesToAccount_r(b
, tctx
, &r
),
1240 "AddPrivilegesToAccount failed");
1241 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1242 "AddPrivilegesToAccount failed");
1246 static bool test_EnumPrivsAccount(struct dcerpc_binding_handle
*b
,
1247 struct torture_context
*tctx
,
1248 struct policy_handle
*handle
,
1249 struct policy_handle
*acct_handle
)
1251 struct lsa_EnumPrivsAccount r
;
1252 struct lsa_PrivilegeSet
*privs
= NULL
;
1255 torture_comment(tctx
, "\nTesting EnumPrivsAccount\n");
1257 r
.in
.handle
= acct_handle
;
1258 r
.out
.privs
= &privs
;
1260 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumPrivsAccount_r(b
, tctx
, &r
),
1261 "EnumPrivsAccount failed");
1262 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1263 "EnumPrivsAccount failed");
1265 if (privs
&& privs
->count
> 0) {
1267 for (i
=0;i
<privs
->count
;i
++) {
1268 test_LookupPrivName(b
, tctx
, handle
,
1269 &privs
->set
[i
].luid
);
1272 ret
&= test_RemovePrivilegesFromAccount(b
, tctx
, handle
, acct_handle
,
1273 &privs
->set
[0].luid
);
1274 ret
&= test_AddPrivilegesToAccount(b
, tctx
, acct_handle
,
1275 &privs
->set
[0].luid
);
1281 static bool test_GetSystemAccessAccount(struct dcerpc_binding_handle
*b
,
1282 struct torture_context
*tctx
,
1283 struct policy_handle
*handle
,
1284 struct policy_handle
*acct_handle
)
1286 uint32_t access_mask
;
1287 struct lsa_GetSystemAccessAccount r
;
1289 torture_comment(tctx
, "\nTesting GetSystemAccessAccount\n");
1291 r
.in
.handle
= acct_handle
;
1292 r
.out
.access_mask
= &access_mask
;
1294 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_GetSystemAccessAccount_r(b
, tctx
, &r
),
1295 "GetSystemAccessAccount failed");
1296 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1297 "GetSystemAccessAccount failed");
1299 if (r
.out
.access_mask
!= NULL
) {
1300 torture_comment(tctx
, "Rights:");
1301 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_INTERACTIVE
)
1302 torture_comment(tctx
, " LSA_POLICY_MODE_INTERACTIVE");
1303 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_NETWORK
)
1304 torture_comment(tctx
, " LSA_POLICY_MODE_NETWORK");
1305 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_BATCH
)
1306 torture_comment(tctx
, " LSA_POLICY_MODE_BATCH");
1307 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_SERVICE
)
1308 torture_comment(tctx
, " LSA_POLICY_MODE_SERVICE");
1309 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_PROXY
)
1310 torture_comment(tctx
, " LSA_POLICY_MODE_PROXY");
1311 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_DENY_INTERACTIVE
)
1312 torture_comment(tctx
, " LSA_POLICY_MODE_DENY_INTERACTIVE");
1313 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_DENY_NETWORK
)
1314 torture_comment(tctx
, " LSA_POLICY_MODE_DENY_NETWORK");
1315 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_DENY_BATCH
)
1316 torture_comment(tctx
, " LSA_POLICY_MODE_DENY_BATCH");
1317 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_DENY_SERVICE
)
1318 torture_comment(tctx
, " LSA_POLICY_MODE_DENY_SERVICE");
1319 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_REMOTE_INTERACTIVE
)
1320 torture_comment(tctx
, " LSA_POLICY_MODE_REMOTE_INTERACTIVE");
1321 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE
)
1322 torture_comment(tctx
, " LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE");
1323 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_ALL
)
1324 torture_comment(tctx
, " LSA_POLICY_MODE_ALL");
1325 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_ALL_NT4
)
1326 torture_comment(tctx
, " LSA_POLICY_MODE_ALL_NT4");
1327 torture_comment(tctx
, "\n");
1333 static bool test_Delete(struct dcerpc_binding_handle
*b
,
1334 struct torture_context
*tctx
,
1335 struct policy_handle
*handle
)
1337 struct lsa_Delete r
;
1339 torture_comment(tctx
, "\nTesting Delete\n");
1341 r
.in
.handle
= handle
;
1342 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_Delete_r(b
, tctx
, &r
),
1344 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_NOT_SUPPORTED
,
1345 "Delete should have failed NT_STATUS_NOT_SUPPORTED");
1350 static bool test_DeleteObject(struct dcerpc_binding_handle
*b
,
1351 struct torture_context
*tctx
,
1352 struct policy_handle
*handle
)
1354 struct lsa_DeleteObject r
;
1356 torture_comment(tctx
, "\nTesting DeleteObject\n");
1358 r
.in
.handle
= handle
;
1359 r
.out
.handle
= handle
;
1360 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_DeleteObject_r(b
, tctx
, &r
),
1361 "DeleteObject failed");
1362 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1363 "DeleteObject failed");
1369 static bool test_CreateAccount(struct dcerpc_binding_handle
*b
,
1370 struct torture_context
*tctx
,
1371 struct policy_handle
*handle
)
1373 struct lsa_CreateAccount r
;
1374 struct dom_sid2
*newsid
;
1375 struct policy_handle acct_handle
;
1377 newsid
= dom_sid_parse_talloc(tctx
, "S-1-5-12349876-4321-2854");
1379 torture_comment(tctx
, "\nTesting CreateAccount\n");
1381 r
.in
.handle
= handle
;
1383 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1384 r
.out
.acct_handle
= &acct_handle
;
1386 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_CreateAccount_r(b
, tctx
, &r
),
1387 "CreateAccount failed");
1388 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_OBJECT_NAME_COLLISION
)) {
1389 struct lsa_OpenAccount r_o
;
1390 r_o
.in
.handle
= handle
;
1391 r_o
.in
.sid
= newsid
;
1392 r_o
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1393 r_o
.out
.acct_handle
= &acct_handle
;
1395 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenAccount_r(b
, tctx
, &r_o
),
1396 "OpenAccount failed");
1397 torture_assert_ntstatus_ok(tctx
, r_o
.out
.result
,
1398 "OpenAccount failed");
1400 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1401 "CreateAccount failed");
1404 if (!test_Delete(b
, tctx
, &acct_handle
)) {
1408 if (!test_DeleteObject(b
, tctx
, &acct_handle
)) {
1415 static bool test_DeleteTrustedDomain(struct dcerpc_binding_handle
*b
,
1416 struct torture_context
*tctx
,
1417 struct policy_handle
*handle
,
1418 struct lsa_StringLarge name
)
1420 struct lsa_OpenTrustedDomainByName r
;
1421 struct policy_handle trustdom_handle
;
1423 r
.in
.handle
= handle
;
1424 r
.in
.name
.string
= name
.string
;
1425 r
.in
.access_mask
= SEC_STD_DELETE
;
1426 r
.out
.trustdom_handle
= &trustdom_handle
;
1428 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenTrustedDomainByName_r(b
, tctx
, &r
),
1429 "OpenTrustedDomainByName failed");
1430 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1431 "OpenTrustedDomainByName failed");
1433 if (!test_Delete(b
, tctx
, &trustdom_handle
)) {
1437 if (!test_DeleteObject(b
, tctx
, &trustdom_handle
)) {
1444 static bool test_DeleteTrustedDomainBySid(struct dcerpc_binding_handle
*b
,
1445 struct torture_context
*tctx
,
1446 struct policy_handle
*handle
,
1447 struct dom_sid
*sid
)
1449 struct lsa_DeleteTrustedDomain r
;
1451 r
.in
.handle
= handle
;
1454 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_DeleteTrustedDomain_r(b
, tctx
, &r
),
1455 "DeleteTrustedDomain failed");
1456 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1457 "DeleteTrustedDomain failed");
1463 static bool test_CreateSecret(struct dcerpc_pipe
*p
,
1464 struct torture_context
*tctx
,
1465 struct policy_handle
*handle
)
1467 struct lsa_CreateSecret r
;
1468 struct lsa_OpenSecret r2
;
1469 struct lsa_SetSecret r3
;
1470 struct lsa_QuerySecret r4
;
1471 struct lsa_SetSecret r5
;
1472 struct lsa_QuerySecret r6
;
1473 struct lsa_SetSecret r7
;
1474 struct lsa_QuerySecret r8
;
1475 struct policy_handle sec_handle
, sec_handle2
, sec_handle3
;
1476 struct lsa_DeleteObject d_o
;
1477 struct lsa_DATA_BUF buf1
;
1478 struct lsa_DATA_BUF_PTR bufp1
;
1479 struct lsa_DATA_BUF_PTR bufp2
;
1482 DATA_BLOB session_key
;
1483 NTTIME old_mtime
, new_mtime
;
1485 const char *secret1
= "abcdef12345699qwerty";
1487 const char *secret3
= "ABCDEF12345699QWERTY";
1489 const char *secret5
= "NEW-SAMBA4-SECRET";
1493 const int LOCAL
= 0;
1494 const int GLOBAL
= 1;
1495 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1497 secname
[LOCAL
] = talloc_asprintf(tctx
, "torturesecret-%u", (unsigned int)random());
1498 secname
[GLOBAL
] = talloc_asprintf(tctx
, "G$torturesecret-%u", (unsigned int)random());
1500 for (i
=0; i
< 2; i
++) {
1501 torture_comment(tctx
, "\nTesting CreateSecret of %s\n", secname
[i
]);
1503 init_lsa_String(&r
.in
.name
, secname
[i
]);
1505 r
.in
.handle
= handle
;
1506 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1507 r
.out
.sec_handle
= &sec_handle
;
1509 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_CreateSecret_r(b
, tctx
, &r
),
1510 "CreateSecret failed");
1511 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1512 "CreateSecret failed");
1514 r
.in
.handle
= handle
;
1515 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1516 r
.out
.sec_handle
= &sec_handle3
;
1518 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_CreateSecret_r(b
, tctx
, &r
),
1519 "CreateSecret failed");
1520 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_OBJECT_NAME_COLLISION
,
1521 "CreateSecret should have failed OBJECT_NAME_COLLISION");
1523 r2
.in
.handle
= handle
;
1524 r2
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1525 r2
.in
.name
= r
.in
.name
;
1526 r2
.out
.sec_handle
= &sec_handle2
;
1528 torture_comment(tctx
, "Testing OpenSecret\n");
1530 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenSecret_r(b
, tctx
, &r2
),
1531 "OpenSecret failed");
1532 torture_assert_ntstatus_ok(tctx
, r2
.out
.result
,
1533 "OpenSecret failed");
1535 torture_assert_ntstatus_ok(tctx
, dcerpc_fetch_session_key(p
, &session_key
),
1536 "dcerpc_fetch_session_key failed");
1538 enc_key
= sess_encrypt_string(secret1
, &session_key
);
1540 r3
.in
.sec_handle
= &sec_handle
;
1541 r3
.in
.new_val
= &buf1
;
1542 r3
.in
.old_val
= NULL
;
1543 r3
.in
.new_val
->data
= enc_key
.data
;
1544 r3
.in
.new_val
->length
= enc_key
.length
;
1545 r3
.in
.new_val
->size
= enc_key
.length
;
1547 torture_comment(tctx
, "Testing SetSecret\n");
1549 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_SetSecret_r(b
, tctx
, &r3
),
1550 "SetSecret failed");
1551 torture_assert_ntstatus_ok(tctx
, r3
.out
.result
,
1552 "SetSecret failed");
1554 r3
.in
.sec_handle
= &sec_handle
;
1555 r3
.in
.new_val
= &buf1
;
1556 r3
.in
.old_val
= NULL
;
1557 r3
.in
.new_val
->data
= enc_key
.data
;
1558 r3
.in
.new_val
->length
= enc_key
.length
;
1559 r3
.in
.new_val
->size
= enc_key
.length
;
1561 /* break the encrypted data */
1564 torture_comment(tctx
, "Testing SetSecret with broken key\n");
1566 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_SetSecret_r(b
, tctx
, &r3
),
1567 "SetSecret failed");
1568 torture_assert_ntstatus_equal(tctx
, r3
.out
.result
, NT_STATUS_UNKNOWN_REVISION
,
1569 "SetSecret should have failed UNKNOWN_REVISION");
1571 data_blob_free(&enc_key
);
1573 ZERO_STRUCT(new_mtime
);
1574 ZERO_STRUCT(old_mtime
);
1576 /* fetch the secret back again */
1577 r4
.in
.sec_handle
= &sec_handle
;
1578 r4
.in
.new_val
= &bufp1
;
1579 r4
.in
.new_mtime
= &new_mtime
;
1580 r4
.in
.old_val
= NULL
;
1581 r4
.in
.old_mtime
= NULL
;
1585 torture_comment(tctx
, "Testing QuerySecret\n");
1586 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QuerySecret_r(b
, tctx
, &r4
),
1587 "QuerySecret failed");
1588 if (!NT_STATUS_IS_OK(r4
.out
.result
)) {
1589 torture_comment(tctx
, "QuerySecret failed - %s\n", nt_errstr(r4
.out
.result
));
1592 if (r4
.out
.new_val
== NULL
|| r4
.out
.new_val
->buf
== NULL
) {
1593 torture_comment(tctx
, "No secret buffer returned\n");
1596 blob1
.data
= r4
.out
.new_val
->buf
->data
;
1597 blob1
.length
= r4
.out
.new_val
->buf
->size
;
1599 secret2
= sess_decrypt_string(tctx
,
1600 &blob1
, &session_key
);
1602 if (strcmp(secret1
, secret2
) != 0) {
1603 torture_comment(tctx
, "Returned secret (r4) '%s' doesn't match '%s'\n",
1610 enc_key
= sess_encrypt_string(secret3
, &session_key
);
1612 r5
.in
.sec_handle
= &sec_handle
;
1613 r5
.in
.new_val
= &buf1
;
1614 r5
.in
.old_val
= NULL
;
1615 r5
.in
.new_val
->data
= enc_key
.data
;
1616 r5
.in
.new_val
->length
= enc_key
.length
;
1617 r5
.in
.new_val
->size
= enc_key
.length
;
1621 torture_comment(tctx
, "Testing SetSecret (existing value should move to old)\n");
1623 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_SetSecret_r(b
, tctx
, &r5
),
1624 "SetSecret failed");
1625 if (!NT_STATUS_IS_OK(r5
.out
.result
)) {
1626 torture_comment(tctx
, "SetSecret failed - %s\n", nt_errstr(r5
.out
.result
));
1630 data_blob_free(&enc_key
);
1632 ZERO_STRUCT(new_mtime
);
1633 ZERO_STRUCT(old_mtime
);
1635 /* fetch the secret back again */
1636 r6
.in
.sec_handle
= &sec_handle
;
1637 r6
.in
.new_val
= &bufp1
;
1638 r6
.in
.new_mtime
= &new_mtime
;
1639 r6
.in
.old_val
= &bufp2
;
1640 r6
.in
.old_mtime
= &old_mtime
;
1645 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QuerySecret_r(b
, tctx
, &r6
),
1646 "QuerySecret failed");
1647 if (!NT_STATUS_IS_OK(r6
.out
.result
)) {
1648 torture_comment(tctx
, "QuerySecret failed - %s\n", nt_errstr(r6
.out
.result
));
1653 if (r6
.out
.new_val
->buf
== NULL
|| r6
.out
.old_val
->buf
== NULL
1654 || r6
.out
.new_mtime
== NULL
|| r6
.out
.old_mtime
== NULL
) {
1655 torture_comment(tctx
, "Both secret buffers and both times not returned\n");
1659 blob1
.data
= r6
.out
.new_val
->buf
->data
;
1660 blob1
.length
= r6
.out
.new_val
->buf
->size
;
1662 secret4
= sess_decrypt_string(tctx
,
1663 &blob1
, &session_key
);
1665 if (strcmp(secret3
, secret4
) != 0) {
1666 torture_comment(tctx
, "Returned NEW secret %s doesn't match %s\n", secret4
, secret3
);
1670 blob1
.data
= r6
.out
.old_val
->buf
->data
;
1671 blob1
.length
= r6
.out
.old_val
->buf
->length
;
1673 secret2
= sess_decrypt_string(tctx
,
1674 &blob1
, &session_key
);
1676 if (strcmp(secret1
, secret2
) != 0) {
1677 torture_comment(tctx
, "Returned OLD secret %s doesn't match %s\n", secret2
, secret1
);
1681 if (*r6
.out
.new_mtime
== *r6
.out
.old_mtime
) {
1682 torture_comment(tctx
, "Returned secret (r6-%d) %s must not have same mtime for both secrets: %s != %s\n",
1685 nt_time_string(tctx
, *r6
.out
.old_mtime
),
1686 nt_time_string(tctx
, *r6
.out
.new_mtime
));
1692 enc_key
= sess_encrypt_string(secret5
, &session_key
);
1694 r7
.in
.sec_handle
= &sec_handle
;
1695 r7
.in
.old_val
= &buf1
;
1696 r7
.in
.old_val
->data
= enc_key
.data
;
1697 r7
.in
.old_val
->length
= enc_key
.length
;
1698 r7
.in
.old_val
->size
= enc_key
.length
;
1699 r7
.in
.new_val
= NULL
;
1701 torture_comment(tctx
, "Testing SetSecret of old Secret only\n");
1703 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_SetSecret_r(b
, tctx
, &r7
),
1704 "SetSecret failed");
1705 if (!NT_STATUS_IS_OK(r7
.out
.result
)) {
1706 torture_comment(tctx
, "SetSecret failed - %s\n", nt_errstr(r7
.out
.result
));
1710 data_blob_free(&enc_key
);
1712 /* fetch the secret back again */
1713 r8
.in
.sec_handle
= &sec_handle
;
1714 r8
.in
.new_val
= &bufp1
;
1715 r8
.in
.new_mtime
= &new_mtime
;
1716 r8
.in
.old_val
= &bufp2
;
1717 r8
.in
.old_mtime
= &old_mtime
;
1722 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QuerySecret_r(b
, tctx
, &r8
),
1723 "QuerySecret failed");
1724 if (!NT_STATUS_IS_OK(r8
.out
.result
)) {
1725 torture_comment(tctx
, "QuerySecret failed - %s\n", nt_errstr(r8
.out
.result
));
1728 if (!r8
.out
.new_val
|| !r8
.out
.old_val
) {
1729 torture_comment(tctx
, "in/out pointers not returned, despite being set on in for QuerySecret\n");
1731 } else if (r8
.out
.new_val
->buf
!= NULL
) {
1732 torture_comment(tctx
, "NEW secret buffer must not be returned after OLD set\n");
1734 } else if (r8
.out
.old_val
->buf
== NULL
) {
1735 torture_comment(tctx
, "OLD secret buffer was not returned after OLD set\n");
1737 } else if (r8
.out
.new_mtime
== NULL
|| r8
.out
.old_mtime
== NULL
) {
1738 torture_comment(tctx
, "Both times not returned after OLD set\n");
1741 blob1
.data
= r8
.out
.old_val
->buf
->data
;
1742 blob1
.length
= r8
.out
.old_val
->buf
->size
;
1744 secret6
= sess_decrypt_string(tctx
,
1745 &blob1
, &session_key
);
1747 if (strcmp(secret5
, secret6
) != 0) {
1748 torture_comment(tctx
, "Returned OLD secret %s doesn't match %s\n", secret5
, secret6
);
1752 if (*r8
.out
.new_mtime
!= *r8
.out
.old_mtime
) {
1753 torture_comment(tctx
, "Returned secret (r8) %s did not had same mtime for both secrets: %s != %s\n",
1755 nt_time_string(tctx
, *r8
.out
.old_mtime
),
1756 nt_time_string(tctx
, *r8
.out
.new_mtime
));
1762 if (!test_Delete(b
, tctx
, &sec_handle
)) {
1766 if (!test_DeleteObject(b
, tctx
, &sec_handle
)) {
1770 d_o
.in
.handle
= &sec_handle2
;
1771 d_o
.out
.handle
= &sec_handle2
;
1772 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_DeleteObject_r(b
, tctx
, &d_o
),
1773 "DeleteObject failed");
1774 torture_assert_ntstatus_equal(tctx
, d_o
.out
.result
, NT_STATUS_INVALID_HANDLE
,
1775 "OpenSecret expected INVALID_HANDLE");
1777 torture_comment(tctx
, "Testing OpenSecret of just-deleted secret\n");
1779 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenSecret_r(b
, tctx
, &r2
),
1780 "OpenSecret failed");
1781 torture_assert_ntstatus_equal(tctx
, r2
.out
.result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
1782 "OpenSecret expected OBJECT_NAME_NOT_FOUND");
1788 static bool test_EnumAccountRights(struct dcerpc_binding_handle
*b
,
1789 struct torture_context
*tctx
,
1790 struct policy_handle
*acct_handle
,
1791 struct dom_sid
*sid
)
1793 struct lsa_EnumAccountRights r
;
1794 struct lsa_RightSet rights
;
1796 torture_comment(tctx
, "\nTesting EnumAccountRights\n");
1798 r
.in
.handle
= acct_handle
;
1800 r
.out
.rights
= &rights
;
1802 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountRights_r(b
, tctx
, &r
),
1803 "EnumAccountRights failed");
1804 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1805 torture_comment(tctx
, "EnumAccountRights of %s failed - %s\n",
1806 dom_sid_string(tctx
, sid
), nt_errstr(r
.out
.result
));
1808 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1809 "EnumAccountRights failed");
1815 static bool test_QuerySecurity(struct dcerpc_binding_handle
*b
,
1816 struct torture_context
*tctx
,
1817 struct policy_handle
*handle
,
1818 struct policy_handle
*acct_handle
)
1820 struct lsa_QuerySecurity r
;
1821 struct sec_desc_buf
*sdbuf
= NULL
;
1823 if (torture_setting_bool(tctx
, "samba4", false)) {
1824 torture_comment(tctx
, "\nskipping QuerySecurity test against Samba4\n");
1828 torture_comment(tctx
, "\nTesting QuerySecurity\n");
1830 r
.in
.handle
= acct_handle
;
1831 r
.in
.sec_info
= SECINFO_OWNER
|
1834 r
.out
.sdbuf
= &sdbuf
;
1836 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QuerySecurity_r(b
, tctx
, &r
),
1837 "QuerySecurity failed");
1838 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1839 torture_comment(tctx
, "QuerySecurity failed - %s\n", nt_errstr(r
.out
.result
));
1846 static bool test_OpenAccount(struct dcerpc_binding_handle
*b
,
1847 struct torture_context
*tctx
,
1848 struct policy_handle
*handle
,
1849 struct dom_sid
*sid
)
1851 struct lsa_OpenAccount r
;
1852 struct policy_handle acct_handle
;
1854 torture_comment(tctx
, "\nTesting OpenAccount\n");
1856 r
.in
.handle
= handle
;
1858 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1859 r
.out
.acct_handle
= &acct_handle
;
1861 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenAccount_r(b
, tctx
, &r
),
1862 "OpenAccount failed");
1863 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1864 "OpenAccount failed");
1866 if (!test_EnumPrivsAccount(b
, tctx
, handle
, &acct_handle
)) {
1870 if (!test_GetSystemAccessAccount(b
, tctx
, handle
, &acct_handle
)) {
1874 if (!test_QuerySecurity(b
, tctx
, handle
, &acct_handle
)) {
1881 static bool test_EnumAccounts(struct dcerpc_binding_handle
*b
,
1882 struct torture_context
*tctx
,
1883 struct policy_handle
*handle
)
1885 struct lsa_EnumAccounts r
;
1886 struct lsa_SidArray sids1
, sids2
;
1887 uint32_t resume_handle
= 0;
1891 torture_comment(tctx
, "\nTesting EnumAccounts\n");
1893 r
.in
.handle
= handle
;
1894 r
.in
.resume_handle
= &resume_handle
;
1895 r
.in
.num_entries
= 100;
1896 r
.out
.resume_handle
= &resume_handle
;
1897 r
.out
.sids
= &sids1
;
1901 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccounts_r(b
, tctx
, &r
),
1902 "EnumAccounts failed");
1903 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_NO_MORE_ENTRIES
)) {
1906 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1907 "EnumAccounts failed");
1909 if (!test_LookupSids(b
, tctx
, handle
, &sids1
)) {
1913 if (!test_LookupSids2(b
, tctx
, handle
, &sids1
)) {
1917 /* Can't test lookupSids3 here, as clearly we must not
1918 * be on schannel, or we would not be able to do the
1921 torture_comment(tctx
, "Testing all accounts\n");
1922 for (i
=0;i
<sids1
.num_sids
;i
++) {
1923 ret
&= test_OpenAccount(b
, tctx
, handle
, sids1
.sids
[i
].sid
);
1924 ret
&= test_EnumAccountRights(b
, tctx
, handle
, sids1
.sids
[i
].sid
);
1926 torture_comment(tctx
, "\n");
1929 if (sids1
.num_sids
< 3) {
1933 torture_comment(tctx
, "Trying EnumAccounts partial listing (asking for 1 at 2)\n");
1935 r
.in
.num_entries
= 1;
1936 r
.out
.sids
= &sids2
;
1938 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccounts_r(b
, tctx
, &r
),
1939 "EnumAccounts failed");
1940 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1941 "EnumAccounts failed");
1943 if (sids2
.num_sids
!= 1) {
1944 torture_comment(tctx
, "Returned wrong number of entries (%d)\n", sids2
.num_sids
);
1951 static bool test_LookupPrivDisplayName(struct dcerpc_binding_handle
*b
,
1952 struct torture_context
*tctx
,
1953 struct policy_handle
*handle
,
1954 struct lsa_String
*priv_name
)
1956 struct lsa_LookupPrivDisplayName r
;
1957 /* produce a reasonable range of language output without screwing up
1959 uint16_t language_id
= (random() % 4) + 0x409;
1960 uint16_t returned_language_id
= 0;
1961 struct lsa_StringLarge
*disp_name
= NULL
;
1963 torture_comment(tctx
, "\nTesting LookupPrivDisplayName(%s)\n", priv_name
->string
);
1965 r
.in
.handle
= handle
;
1966 r
.in
.name
= priv_name
;
1967 r
.in
.language_id
= language_id
;
1968 r
.in
.language_id_sys
= 0;
1969 r
.out
.returned_language_id
= &returned_language_id
;
1970 r
.out
.disp_name
= &disp_name
;
1972 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_LookupPrivDisplayName_r(b
, tctx
, &r
),
1973 "LookupPrivDisplayName failed");
1974 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1975 torture_comment(tctx
, "LookupPrivDisplayName failed - %s\n", nt_errstr(r
.out
.result
));
1978 torture_comment(tctx
, "%s -> \"%s\" (language 0x%x/0x%x)\n",
1979 priv_name
->string
, disp_name
->string
,
1980 r
.in
.language_id
, *r
.out
.returned_language_id
);
1985 static bool test_EnumAccountsWithUserRight(struct dcerpc_binding_handle
*b
,
1986 struct torture_context
*tctx
,
1987 struct policy_handle
*handle
,
1988 struct lsa_String
*priv_name
)
1990 struct lsa_EnumAccountsWithUserRight r
;
1991 struct lsa_SidArray sids
;
1995 torture_comment(tctx
, "\nTesting EnumAccountsWithUserRight(%s)\n", priv_name
->string
);
1997 r
.in
.handle
= handle
;
1998 r
.in
.name
= priv_name
;
2001 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountsWithUserRight_r(b
, tctx
, &r
),
2002 "EnumAccountsWithUserRight failed");
2004 /* NT_STATUS_NO_MORE_ENTRIES means noone has this privilege */
2005 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_NO_MORE_ENTRIES
)) {
2009 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2010 torture_comment(tctx
, "EnumAccountsWithUserRight failed - %s\n", nt_errstr(r
.out
.result
));
2018 static bool test_EnumPrivs(struct dcerpc_binding_handle
*b
,
2019 struct torture_context
*tctx
,
2020 struct policy_handle
*handle
)
2022 struct lsa_EnumPrivs r
;
2023 struct lsa_PrivArray privs1
;
2024 uint32_t resume_handle
= 0;
2028 torture_comment(tctx
, "\nTesting EnumPrivs\n");
2030 r
.in
.handle
= handle
;
2031 r
.in
.resume_handle
= &resume_handle
;
2032 r
.in
.max_count
= 100;
2033 r
.out
.resume_handle
= &resume_handle
;
2034 r
.out
.privs
= &privs1
;
2037 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumPrivs_r(b
, tctx
, &r
),
2038 "EnumPrivs failed");
2039 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
2040 "EnumPrivs failed");
2042 for (i
= 0; i
< privs1
.count
; i
++) {
2043 test_LookupPrivDisplayName(b
, tctx
, handle
, (struct lsa_String
*)&privs1
.privs
[i
].name
);
2044 test_LookupPrivValue(b
, tctx
, handle
, (struct lsa_String
*)&privs1
.privs
[i
].name
);
2045 if (!test_EnumAccountsWithUserRight(b
, tctx
, handle
, (struct lsa_String
*)&privs1
.privs
[i
].name
)) {
2053 static bool test_QueryForestTrustInformation(struct dcerpc_binding_handle
*b
,
2054 struct torture_context
*tctx
,
2055 struct policy_handle
*handle
,
2056 const char *trusted_domain_name
)
2059 struct lsa_lsaRQueryForestTrustInformation r
;
2060 struct lsa_String string
;
2061 struct lsa_ForestTrustInformation info
, *info_ptr
;
2063 torture_comment(tctx
, "\nTesting lsaRQueryForestTrustInformation\n");
2065 if (torture_setting_bool(tctx
, "samba4", false)) {
2066 torture_comment(tctx
, "skipping QueryForestTrustInformation against Samba4\n");
2070 ZERO_STRUCT(string
);
2072 if (trusted_domain_name
) {
2073 init_lsa_String(&string
, trusted_domain_name
);
2078 r
.in
.handle
= handle
;
2079 r
.in
.trusted_domain_name
= &string
;
2080 r
.in
.highest_record_type
= LSA_FOREST_TRUST_TOP_LEVEL_NAME
;
2081 r
.out
.forest_trust_info
= &info_ptr
;
2083 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_lsaRQueryForestTrustInformation_r(b
, tctx
, &r
),
2084 "lsaRQueryForestTrustInformation failed");
2086 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2087 torture_comment(tctx
, "lsaRQueryForestTrustInformation of %s failed - %s\n", trusted_domain_name
, nt_errstr(r
.out
.result
));
2094 static bool test_query_each_TrustDomEx(struct dcerpc_binding_handle
*b
,
2095 struct torture_context
*tctx
,
2096 struct policy_handle
*handle
,
2097 struct lsa_DomainListEx
*domains
)
2102 for (i
=0; i
< domains
->count
; i
++) {
2104 if (domains
->domains
[i
].trust_attributes
& LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE
) {
2105 ret
&= test_QueryForestTrustInformation(b
, tctx
, handle
,
2106 domains
->domains
[i
].domain_name
.string
);
2113 static bool test_query_each_TrustDom(struct dcerpc_binding_handle
*b
,
2114 struct torture_context
*tctx
,
2115 struct policy_handle
*handle
,
2116 struct lsa_DomainList
*domains
)
2121 torture_comment(tctx
, "\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
2122 for (i
=0; i
< domains
->count
; i
++) {
2123 struct lsa_OpenTrustedDomain trust
;
2124 struct lsa_OpenTrustedDomainByName trust_by_name
;
2125 struct policy_handle trustdom_handle
;
2126 struct policy_handle handle2
;
2128 struct lsa_CloseTrustedDomainEx c_trust
;
2129 int levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
2130 int ok
[] = {1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1};
2132 if (domains
->domains
[i
].sid
) {
2133 trust
.in
.handle
= handle
;
2134 trust
.in
.sid
= domains
->domains
[i
].sid
;
2135 trust
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2136 trust
.out
.trustdom_handle
= &trustdom_handle
;
2138 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenTrustedDomain_r(b
, tctx
, &trust
),
2139 "OpenTrustedDomain failed");
2141 if (NT_STATUS_EQUAL(trust
.out
.result
, NT_STATUS_NO_SUCH_DOMAIN
)) {
2142 torture_comment(tctx
, "DOMAIN(%s, %s) not a direct trust?\n",
2143 domains
->domains
[i
].name
.string
,
2144 dom_sid_string(tctx
, domains
->domains
[i
].sid
));
2147 if (!NT_STATUS_IS_OK(trust
.out
.result
)) {
2148 torture_comment(tctx
, "OpenTrustedDomain failed - %s\n", nt_errstr(trust
.out
.result
));
2152 c
.in
.handle
= &trustdom_handle
;
2153 c
.out
.handle
= &handle2
;
2155 c_trust
.in
.handle
= &trustdom_handle
;
2156 c_trust
.out
.handle
= &handle2
;
2158 for (j
=0; j
< ARRAY_SIZE(levels
); j
++) {
2159 struct lsa_QueryTrustedDomainInfo q
;
2160 union lsa_TrustedDomainInfo
*info
= NULL
;
2161 q
.in
.trustdom_handle
= &trustdom_handle
;
2162 q
.in
.level
= levels
[j
];
2164 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QueryTrustedDomainInfo_r(b
, tctx
, &q
),
2165 "QueryTrustedDomainInfo failed");
2166 if (!NT_STATUS_IS_OK(q
.out
.result
) && ok
[j
]) {
2167 torture_comment(tctx
, "QueryTrustedDomainInfo level %d failed - %s\n",
2168 levels
[j
], nt_errstr(q
.out
.result
));
2170 } else if (NT_STATUS_IS_OK(q
.out
.result
) && !ok
[j
]) {
2171 torture_comment(tctx
, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
2172 levels
[j
], nt_errstr(q
.out
.result
));
2177 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_CloseTrustedDomainEx_r(b
, tctx
, &c_trust
),
2178 "CloseTrustedDomainEx failed");
2179 if (!NT_STATUS_EQUAL(c_trust
.out
.result
, NT_STATUS_NOT_IMPLEMENTED
)) {
2180 torture_comment(tctx
, "Expected CloseTrustedDomainEx to return NT_STATUS_NOT_IMPLEMENTED, instead - %s\n", nt_errstr(c_trust
.out
.result
));
2184 c
.in
.handle
= &trustdom_handle
;
2185 c
.out
.handle
= &handle2
;
2187 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_Close_r(b
, tctx
, &c
),
2189 if (!NT_STATUS_IS_OK(c
.out
.result
)) {
2190 torture_comment(tctx
, "Close of trusted domain failed - %s\n", nt_errstr(c
.out
.result
));
2194 for (j
=0; j
< ARRAY_SIZE(levels
); j
++) {
2195 struct lsa_QueryTrustedDomainInfoBySid q
;
2196 union lsa_TrustedDomainInfo
*info
= NULL
;
2198 if (!domains
->domains
[i
].sid
) {
2202 q
.in
.handle
= handle
;
2203 q
.in
.dom_sid
= domains
->domains
[i
].sid
;
2204 q
.in
.level
= levels
[j
];
2207 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QueryTrustedDomainInfoBySid_r(b
, tctx
, &q
),
2208 "lsa_QueryTrustedDomainInfoBySid failed");
2209 if (!NT_STATUS_IS_OK(q
.out
.result
) && ok
[j
]) {
2210 torture_comment(tctx
, "QueryTrustedDomainInfoBySid level %d failed - %s\n",
2211 levels
[j
], nt_errstr(q
.out
.result
));
2213 } else if (NT_STATUS_IS_OK(q
.out
.result
) && !ok
[j
]) {
2214 torture_comment(tctx
, "QueryTrustedDomainInfoBySid level %d unexpectedly succeeded - %s\n",
2215 levels
[j
], nt_errstr(q
.out
.result
));
2221 trust_by_name
.in
.handle
= handle
;
2222 trust_by_name
.in
.name
.string
= domains
->domains
[i
].name
.string
;
2223 trust_by_name
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2224 trust_by_name
.out
.trustdom_handle
= &trustdom_handle
;
2226 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenTrustedDomainByName_r(b
, tctx
, &trust_by_name
),
2227 "OpenTrustedDomainByName failed");
2229 if (NT_STATUS_EQUAL(trust_by_name
.out
.result
, NT_STATUS_NO_SUCH_DOMAIN
)) {
2230 torture_comment(tctx
, "DOMAIN(%s, %s) not a direct trust?\n",
2231 domains
->domains
[i
].name
.string
,
2232 dom_sid_string(tctx
, domains
->domains
[i
].sid
));
2235 if (!NT_STATUS_IS_OK(trust_by_name
.out
.result
)) {
2236 torture_comment(tctx
, "OpenTrustedDomainByName failed - %s\n", nt_errstr(trust_by_name
.out
.result
));
2240 for (j
=0; j
< ARRAY_SIZE(levels
); j
++) {
2241 struct lsa_QueryTrustedDomainInfo q
;
2242 union lsa_TrustedDomainInfo
*info
= NULL
;
2243 q
.in
.trustdom_handle
= &trustdom_handle
;
2244 q
.in
.level
= levels
[j
];
2246 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QueryTrustedDomainInfo_r(b
, tctx
, &q
),
2247 "QueryTrustedDomainInfo failed");
2248 if (!NT_STATUS_IS_OK(q
.out
.result
) && ok
[j
]) {
2249 torture_comment(tctx
, "QueryTrustedDomainInfo level %d failed - %s\n",
2250 levels
[j
], nt_errstr(q
.out
.result
));
2252 } else if (NT_STATUS_IS_OK(q
.out
.result
) && !ok
[j
]) {
2253 torture_comment(tctx
, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
2254 levels
[j
], nt_errstr(q
.out
.result
));
2259 c
.in
.handle
= &trustdom_handle
;
2260 c
.out
.handle
= &handle2
;
2262 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_Close_r(b
, tctx
, &c
),
2264 if (!NT_STATUS_IS_OK(c
.out
.result
)) {
2265 torture_comment(tctx
, "Close of trusted domain failed - %s\n", nt_errstr(c
.out
.result
));
2269 for (j
=0; j
< ARRAY_SIZE(levels
); j
++) {
2270 struct lsa_QueryTrustedDomainInfoByName q
;
2271 union lsa_TrustedDomainInfo
*info
= NULL
;
2272 struct lsa_String name
;
2274 name
.string
= domains
->domains
[i
].name
.string
;
2276 q
.in
.handle
= handle
;
2277 q
.in
.trusted_domain
= &name
;
2278 q
.in
.level
= levels
[j
];
2280 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QueryTrustedDomainInfoByName_r(b
, tctx
, &q
),
2281 "QueryTrustedDomainInfoByName failed");
2282 if (!NT_STATUS_IS_OK(q
.out
.result
) && ok
[j
]) {
2283 torture_comment(tctx
, "QueryTrustedDomainInfoByName level %d failed - %s\n",
2284 levels
[j
], nt_errstr(q
.out
.result
));
2286 } else if (NT_STATUS_IS_OK(q
.out
.result
) && !ok
[j
]) {
2287 torture_comment(tctx
, "QueryTrustedDomainInfoByName level %d unexpectedly succeeded - %s\n",
2288 levels
[j
], nt_errstr(q
.out
.result
));
2296 static bool test_EnumTrustDom(struct dcerpc_binding_handle
*b
,
2297 struct torture_context
*tctx
,
2298 struct policy_handle
*handle
)
2300 struct lsa_EnumTrustDom r
;
2301 uint32_t in_resume_handle
= 0;
2302 uint32_t out_resume_handle
;
2303 struct lsa_DomainList domains
;
2306 torture_comment(tctx
, "\nTesting EnumTrustDom\n");
2308 r
.in
.handle
= handle
;
2309 r
.in
.resume_handle
= &in_resume_handle
;
2311 r
.out
.domains
= &domains
;
2312 r
.out
.resume_handle
= &out_resume_handle
;
2314 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumTrustDom_r(b
, tctx
, &r
),
2315 "lsa_EnumTrustDom failed");
2317 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2318 * always be larger than the previous input resume handle, in
2319 * particular when hitting the last query it is vital to set the
2320 * resume handle correctly to avoid infinite client loops, as
2321 * seen e.g. with Windows XP SP3 when resume handle is 0 and
2322 * status is NT_STATUS_OK - gd */
2324 if (NT_STATUS_IS_OK(r
.out
.result
) ||
2325 NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_NO_MORE_ENTRIES
) ||
2326 NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
))
2328 if (out_resume_handle
<= in_resume_handle
) {
2329 torture_comment(tctx
, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2330 out_resume_handle
, in_resume_handle
);
2335 if (NT_STATUS_IS_OK(r
.out
.result
)) {
2336 if (domains
.count
== 0) {
2337 torture_comment(tctx
, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2340 } else if (!(NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
) || NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_NO_MORE_ENTRIES
))) {
2341 torture_comment(tctx
, "EnumTrustDom of zero size failed - %s\n", nt_errstr(r
.out
.result
));
2345 /* Start from the bottom again */
2346 in_resume_handle
= 0;
2349 r
.in
.handle
= handle
;
2350 r
.in
.resume_handle
= &in_resume_handle
;
2351 r
.in
.max_size
= LSA_ENUM_TRUST_DOMAIN_MULTIPLIER
* 3;
2352 r
.out
.domains
= &domains
;
2353 r
.out
.resume_handle
= &out_resume_handle
;
2355 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumTrustDom_r(b
, tctx
, &r
),
2356 "EnumTrustDom failed");
2358 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2359 * always be larger than the previous input resume handle, in
2360 * particular when hitting the last query it is vital to set the
2361 * resume handle correctly to avoid infinite client loops, as
2362 * seen e.g. with Windows XP SP3 when resume handle is 0 and
2363 * status is NT_STATUS_OK - gd */
2365 if (NT_STATUS_IS_OK(r
.out
.result
) ||
2366 NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_NO_MORE_ENTRIES
) ||
2367 NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
))
2369 if (out_resume_handle
<= in_resume_handle
) {
2370 torture_comment(tctx
, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2371 out_resume_handle
, in_resume_handle
);
2376 /* NO_MORE_ENTRIES is allowed */
2377 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_NO_MORE_ENTRIES
)) {
2378 if (domains
.count
== 0) {
2381 torture_comment(tctx
, "EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
2383 } else if (NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
)) {
2384 /* Windows 2003 gets this off by one on the first run */
2385 if (r
.out
.domains
->count
< 3 || r
.out
.domains
->count
> 4) {
2386 torture_comment(tctx
, "EnumTrustDom didn't fill the buffer we "
2387 "asked it to (got %d, expected %d / %d == %d entries)\n",
2388 r
.out
.domains
->count
, LSA_ENUM_TRUST_DOMAIN_MULTIPLIER
* 3,
2389 LSA_ENUM_TRUST_DOMAIN_MULTIPLIER
, r
.in
.max_size
);
2392 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2393 torture_comment(tctx
, "EnumTrustDom failed - %s\n", nt_errstr(r
.out
.result
));
2397 if (domains
.count
== 0) {
2398 torture_comment(tctx
, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2402 ret
&= test_query_each_TrustDom(b
, tctx
, handle
, &domains
);
2404 in_resume_handle
= out_resume_handle
;
2406 } while ((NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
)));
2411 static bool test_EnumTrustDomEx(struct dcerpc_binding_handle
*b
,
2412 struct torture_context
*tctx
,
2413 struct policy_handle
*handle
)
2415 struct lsa_EnumTrustedDomainsEx r_ex
;
2416 uint32_t in_resume_handle
= 0;
2417 uint32_t out_resume_handle
;
2418 struct lsa_DomainListEx domains_ex
;
2421 torture_comment(tctx
, "\nTesting EnumTrustedDomainsEx\n");
2423 r_ex
.in
.handle
= handle
;
2424 r_ex
.in
.resume_handle
= &in_resume_handle
;
2425 r_ex
.in
.max_size
= 0;
2426 r_ex
.out
.domains
= &domains_ex
;
2427 r_ex
.out
.resume_handle
= &out_resume_handle
;
2429 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumTrustedDomainsEx_r(b
, tctx
, &r_ex
),
2430 "EnumTrustedDomainsEx failed");
2432 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2433 * always be larger than the previous input resume handle, in
2434 * particular when hitting the last query it is vital to set the
2435 * resume handle correctly to avoid infinite client loops, as
2436 * seen e.g. with Windows XP SP3 when resume handle is 0 and
2437 * status is NT_STATUS_OK - gd */
2439 if (NT_STATUS_IS_OK(r_ex
.out
.result
) ||
2440 NT_STATUS_EQUAL(r_ex
.out
.result
, NT_STATUS_NO_MORE_ENTRIES
) ||
2441 NT_STATUS_EQUAL(r_ex
.out
.result
, STATUS_MORE_ENTRIES
))
2443 if (out_resume_handle
<= in_resume_handle
) {
2444 torture_comment(tctx
, "EnumTrustDomEx failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2445 out_resume_handle
, in_resume_handle
);
2450 if (NT_STATUS_IS_OK(r_ex
.out
.result
)) {
2451 if (domains_ex
.count
== 0) {
2452 torture_comment(tctx
, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2455 } else if (!(NT_STATUS_EQUAL(r_ex
.out
.result
, STATUS_MORE_ENTRIES
) ||
2456 NT_STATUS_EQUAL(r_ex
.out
.result
, NT_STATUS_NO_MORE_ENTRIES
))) {
2457 torture_comment(tctx
, "EnumTrustDom of zero size failed - %s\n",
2458 nt_errstr(r_ex
.out
.result
));
2462 in_resume_handle
= 0;
2464 r_ex
.in
.handle
= handle
;
2465 r_ex
.in
.resume_handle
= &in_resume_handle
;
2466 r_ex
.in
.max_size
= LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER
* 3;
2467 r_ex
.out
.domains
= &domains_ex
;
2468 r_ex
.out
.resume_handle
= &out_resume_handle
;
2470 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumTrustedDomainsEx_r(b
, tctx
, &r_ex
),
2471 "EnumTrustedDomainsEx failed");
2473 in_resume_handle
= out_resume_handle
;
2475 /* NO_MORE_ENTRIES is allowed */
2476 if (NT_STATUS_EQUAL(r_ex
.out
.result
, NT_STATUS_NO_MORE_ENTRIES
)) {
2477 if (domains_ex
.count
== 0) {
2480 torture_comment(tctx
, "EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
2482 } else if (NT_STATUS_EQUAL(r_ex
.out
.result
, STATUS_MORE_ENTRIES
)) {
2483 /* Windows 2003 gets this off by one on the first run */
2484 if (r_ex
.out
.domains
->count
< 3 || r_ex
.out
.domains
->count
> 4) {
2485 torture_comment(tctx
, "EnumTrustDom didn't fill the buffer we "
2486 "asked it to (got %d, expected %d / %d == %d entries)\n",
2487 r_ex
.out
.domains
->count
,
2489 LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER
,
2490 r_ex
.in
.max_size
/ LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER
);
2492 } else if (!NT_STATUS_IS_OK(r_ex
.out
.result
)) {
2493 torture_comment(tctx
, "EnumTrustedDomainEx failed - %s\n", nt_errstr(r_ex
.out
.result
));
2497 if (domains_ex
.count
== 0) {
2498 torture_comment(tctx
, "EnumTrustDomainEx failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2502 ret
&= test_query_each_TrustDomEx(b
, tctx
, handle
, &domains_ex
);
2504 } while ((NT_STATUS_EQUAL(r_ex
.out
.result
, STATUS_MORE_ENTRIES
)));
2510 static bool test_CreateTrustedDomain(struct dcerpc_binding_handle
*b
,
2511 struct torture_context
*tctx
,
2512 struct policy_handle
*handle
,
2513 uint32_t num_trusts
)
2516 struct lsa_CreateTrustedDomain r
;
2517 struct lsa_DomainInfo trustinfo
;
2518 struct dom_sid
**domsid
;
2519 struct policy_handle
*trustdom_handle
;
2520 struct lsa_QueryTrustedDomainInfo q
;
2521 union lsa_TrustedDomainInfo
*info
= NULL
;
2524 torture_comment(tctx
, "\nTesting CreateTrustedDomain for %d domains\n", num_trusts
);
2526 if (!test_EnumTrustDom(b
, tctx
, handle
)) {
2530 if (!test_EnumTrustDomEx(b
, tctx
, handle
)) {
2534 domsid
= talloc_array(tctx
, struct dom_sid
*, num_trusts
);
2535 trustdom_handle
= talloc_array(tctx
, struct policy_handle
, num_trusts
);
2537 for (i
=0; i
< num_trusts
; i
++) {
2538 char *trust_name
= talloc_asprintf(tctx
, "torturedom1%02d", i
);
2539 char *trust_sid
= talloc_asprintf(tctx
, "S-1-5-21-97398-379795-1%02d", i
);
2541 domsid
[i
] = dom_sid_parse_talloc(tctx
, trust_sid
);
2543 trustinfo
.sid
= domsid
[i
];
2544 init_lsa_String((struct lsa_String
*)&trustinfo
.name
, trust_name
);
2546 r
.in
.policy_handle
= handle
;
2547 r
.in
.info
= &trustinfo
;
2548 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2549 r
.out
.trustdom_handle
= &trustdom_handle
[i
];
2551 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_CreateTrustedDomain_r(b
, tctx
, &r
),
2552 "CreateTrustedDomain failed");
2553 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_OBJECT_NAME_COLLISION
)) {
2554 test_DeleteTrustedDomain(b
, tctx
, handle
, trustinfo
.name
);
2555 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_CreateTrustedDomain_r(b
, tctx
, &r
),
2556 "CreateTrustedDomain failed");
2558 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2559 torture_comment(tctx
, "CreateTrustedDomain failed - %s\n", nt_errstr(r
.out
.result
));
2563 q
.in
.trustdom_handle
= &trustdom_handle
[i
];
2564 q
.in
.level
= LSA_TRUSTED_DOMAIN_INFO_INFO_EX
;
2566 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QueryTrustedDomainInfo_r(b
, tctx
, &q
),
2567 "QueryTrustedDomainInfo failed");
2568 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
2569 torture_comment(tctx
, "QueryTrustedDomainInfo level %d failed - %s\n", q
.in
.level
, nt_errstr(q
.out
.result
));
2571 } else if (!q
.out
.info
) {
2574 if (strcmp(info
->info_ex
.netbios_name
.string
, trustinfo
.name
.string
) != 0) {
2575 torture_comment(tctx
, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
2576 info
->info_ex
.netbios_name
.string
, trustinfo
.name
.string
);
2579 if (info
->info_ex
.trust_type
!= LSA_TRUST_TYPE_DOWNLEVEL
) {
2580 torture_comment(tctx
, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
2581 trust_name
, info
->info_ex
.trust_type
, LSA_TRUST_TYPE_DOWNLEVEL
);
2584 if (info
->info_ex
.trust_attributes
!= 0) {
2585 torture_comment(tctx
, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
2586 trust_name
, info
->info_ex
.trust_attributes
, 0);
2589 if (info
->info_ex
.trust_direction
!= LSA_TRUST_DIRECTION_OUTBOUND
) {
2590 torture_comment(tctx
, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
2591 trust_name
, info
->info_ex
.trust_direction
, LSA_TRUST_DIRECTION_OUTBOUND
);
2598 /* now that we have some domains to look over, we can test the enum calls */
2599 if (!test_EnumTrustDom(b
, tctx
, handle
)) {
2603 if (!test_EnumTrustDomEx(b
, tctx
, handle
)) {
2607 for (i
=0; i
<num_trusts
; i
++) {
2608 if (!test_DeleteTrustedDomainBySid(b
, tctx
, handle
, domsid
[i
])) {
2616 static bool gen_authinfo_internal(TALLOC_CTX
*mem_ctx
, const char *password
,
2617 DATA_BLOB session_key
,
2618 struct lsa_TrustDomainInfoAuthInfoInternal
**_authinfo_internal
)
2620 struct lsa_TrustDomainInfoAuthInfoInternal
*authinfo_internal
;
2621 struct trustDomainPasswords auth_struct
;
2622 struct AuthenticationInformation
*auth_info_array
;
2623 size_t converted_size
;
2624 DATA_BLOB auth_blob
;
2625 enum ndr_err_code ndr_err
;
2627 authinfo_internal
= talloc_zero(mem_ctx
, struct lsa_TrustDomainInfoAuthInfoInternal
);
2628 if (authinfo_internal
== NULL
) {
2632 auth_info_array
= talloc_array(mem_ctx
,
2633 struct AuthenticationInformation
, 1);
2634 if (auth_info_array
== NULL
) {
2638 generate_random_buffer(auth_struct
.confounder
, sizeof(auth_struct
.confounder
));
2640 auth_info_array
[0].AuthType
= TRUST_AUTH_TYPE_CLEAR
;
2642 if (!convert_string_talloc(mem_ctx
, CH_UNIX
, CH_UTF16
, password
,
2644 &auth_info_array
[0].AuthInfo
.clear
.password
,
2649 auth_info_array
[0].AuthInfo
.clear
.size
= converted_size
;
2651 auth_struct
.outgoing
.count
= 1;
2652 auth_struct
.outgoing
.current
.count
= 1;
2653 auth_struct
.outgoing
.current
.array
= auth_info_array
;
2654 auth_struct
.outgoing
.previous
.count
= 0;
2655 auth_struct
.outgoing
.previous
.array
= NULL
;
2657 auth_struct
.incoming
.count
= 1;
2658 auth_struct
.incoming
.current
.count
= 1;
2659 auth_struct
.incoming
.current
.array
= auth_info_array
;
2660 auth_struct
.incoming
.previous
.count
= 0;
2661 auth_struct
.incoming
.previous
.array
= NULL
;
2664 ndr_err
= ndr_push_struct_blob(&auth_blob
, mem_ctx
, &auth_struct
,
2665 (ndr_push_flags_fn_t
)ndr_push_trustDomainPasswords
);
2666 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
2670 arcfour_crypt_blob(auth_blob
.data
, auth_blob
.length
, &session_key
);
2672 authinfo_internal
->auth_blob
.size
= auth_blob
.length
;
2673 authinfo_internal
->auth_blob
.data
= auth_blob
.data
;
2675 *_authinfo_internal
= authinfo_internal
;
2680 static bool gen_authinfo(TALLOC_CTX
*mem_ctx
, const char *password
,
2681 struct lsa_TrustDomainInfoAuthInfo
**_authinfo
)
2683 struct lsa_TrustDomainInfoAuthInfo
*authinfo
;
2684 struct lsa_TrustDomainInfoBuffer
*info_buffer
;
2685 size_t converted_size
;
2687 authinfo
= talloc_zero(mem_ctx
, struct lsa_TrustDomainInfoAuthInfo
);
2688 if (authinfo
== NULL
) {
2692 info_buffer
= talloc_zero(mem_ctx
, struct lsa_TrustDomainInfoBuffer
);
2693 if (info_buffer
== NULL
) {
2697 info_buffer
->AuthType
= TRUST_AUTH_TYPE_CLEAR
;
2699 if (!convert_string_talloc(mem_ctx
, CH_UNIX
, CH_UTF16
, password
,
2701 &info_buffer
->data
.data
,
2706 info_buffer
->data
.size
= converted_size
;
2708 authinfo
->incoming_count
= 1;
2709 authinfo
->incoming_current_auth_info
= info_buffer
;
2710 authinfo
->incoming_previous_auth_info
= NULL
;
2711 authinfo
->outgoing_count
= 1;
2712 authinfo
->outgoing_current_auth_info
= info_buffer
;
2713 authinfo
->outgoing_previous_auth_info
= NULL
;
2715 *_authinfo
= authinfo
;
2720 static bool check_pw_with_ServerAuthenticate3(struct dcerpc_pipe
*p
,
2721 struct torture_context
*tctx
,
2722 uint32_t negotiate_flags
,
2723 struct cli_credentials
*machine_credentials
,
2724 struct netlogon_creds_CredentialState
**creds_out
)
2726 struct netr_ServerReqChallenge r
;
2727 struct netr_ServerAuthenticate3 a
;
2728 struct netr_Credential credentials1
, credentials2
, credentials3
;
2729 struct netlogon_creds_CredentialState
*creds
;
2730 struct samr_Password mach_password
;
2732 const char *machine_name
;
2733 const char *plain_pass
;
2734 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2736 machine_name
= cli_credentials_get_workstation(machine_credentials
);
2737 plain_pass
= cli_credentials_get_password(machine_credentials
);
2739 r
.in
.server_name
= NULL
;
2740 r
.in
.computer_name
= machine_name
;
2741 r
.in
.credentials
= &credentials1
;
2742 r
.out
.return_credentials
= &credentials2
;
2744 generate_random_buffer(credentials1
.data
, sizeof(credentials1
.data
));
2746 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerReqChallenge_r(b
, tctx
, &r
),
2747 "ServerReqChallenge failed");
2748 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerReqChallenge failed");
2750 E_md4hash(plain_pass
, mach_password
.hash
);
2752 a
.in
.server_name
= NULL
;
2753 a
.in
.account_name
= talloc_asprintf(tctx
, "%s$", machine_name
);
2754 a
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
2755 a
.in
.computer_name
= machine_name
;
2756 a
.in
.negotiate_flags
= &negotiate_flags
;
2757 a
.in
.credentials
= &credentials3
;
2758 a
.out
.return_credentials
= &credentials3
;
2759 a
.out
.negotiate_flags
= &negotiate_flags
;
2762 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
2764 a
.in
.secure_channel_type
,
2765 &credentials1
, &credentials2
,
2766 &mach_password
, &credentials3
,
2769 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
2771 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerAuthenticate3_r(b
, tctx
, &a
),
2772 "ServerAuthenticate3 failed");
2773 if (!NT_STATUS_IS_OK(a
.out
.result
)) {
2774 if (!NT_STATUS_EQUAL(a
.out
.result
, NT_STATUS_ACCESS_DENIED
)) {
2775 torture_assert_ntstatus_ok(tctx
, a
.out
.result
,
2776 "ServerAuthenticate3 failed");
2780 torture_assert(tctx
, netlogon_creds_client_check(creds
, &credentials3
), "Credential chaining failed");
2782 /* Prove that requesting a challenge again won't break it */
2783 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerReqChallenge_r(b
, tctx
, &r
),
2784 "ServerReqChallenge failed");
2785 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerReqChallenge failed");
2791 static bool check_dom_trust_pw(struct dcerpc_pipe
*p
,
2792 struct torture_context
*tctx
,
2793 const char *trusted_dom_name
,
2794 const char *password
)
2796 struct cli_credentials
*credentials
;
2798 const char *binding
= torture_setting_string(tctx
, "binding", NULL
);
2799 struct dcerpc_binding
*b2
;
2800 struct netlogon_creds_CredentialState
*creds
;
2801 struct dcerpc_pipe
*p2
;
2805 credentials
= cli_credentials_init(tctx
);
2806 if (credentials
== NULL
) {
2810 dummy
= talloc_asprintf(tctx
, "%s$", trusted_dom_name
);
2811 if (dummy
== NULL
) {
2815 cli_credentials_set_username(credentials
, dummy
, CRED_SPECIFIED
);
2816 cli_credentials_set_password(credentials
, password
, CRED_SPECIFIED
);
2817 cli_credentials_set_workstation(credentials
,
2818 trusted_dom_name
, CRED_SPECIFIED
);
2819 cli_credentials_set_secure_channel_type(credentials
, SEC_CHAN_DOMAIN
);
2821 status
= dcerpc_parse_binding(tctx
, binding
, &b2
);
2822 torture_assert_ntstatus_ok(tctx
, status
, "Bad binding string");
2824 status
= dcerpc_pipe_connect_b(tctx
, &p2
, b2
,
2825 &ndr_table_netlogon
,
2826 cli_credentials_init_anon(tctx
),
2827 tctx
->ev
, tctx
->lp_ctx
);
2828 if (!NT_STATUS_IS_OK(status
)) {
2829 torture_comment(tctx
, "dcerpc_pipe_connect_b failed.\n");
2833 ok
= check_pw_with_ServerAuthenticate3(p2
, tctx
,
2834 NETLOGON_NEG_AUTH2_ADS_FLAGS
,
2835 credentials
, &creds
);
2841 static bool test_CreateTrustedDomainEx_common(struct dcerpc_pipe
*p
,
2842 struct torture_context
*tctx
,
2843 struct policy_handle
*handle
,
2844 uint32_t num_trusts
,
2849 struct lsa_CreateTrustedDomainEx r
;
2850 struct lsa_CreateTrustedDomainEx2 r2
;
2851 struct lsa_TrustDomainInfoInfoEx trustinfo
;
2852 struct lsa_TrustDomainInfoAuthInfoInternal
*authinfo_internal
= NULL
;
2853 struct lsa_TrustDomainInfoAuthInfo
*authinfo
= NULL
;
2854 struct dom_sid
**domsid
;
2855 struct policy_handle
*trustdom_handle
;
2856 struct lsa_QueryTrustedDomainInfo q
;
2857 union lsa_TrustedDomainInfo
*info
= NULL
;
2858 DATA_BLOB session_key
;
2860 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2864 torture_comment(tctx
, "\nTesting CreateTrustedDomainEx2 for %d domains\n", num_trusts
);
2867 torture_comment(tctx
, "\nTesting CreateTrustedDomainEx for %d domains\n", num_trusts
);
2871 domsid
= talloc_array(tctx
, struct dom_sid
*, num_trusts
);
2872 trustdom_handle
= talloc_array(tctx
, struct policy_handle
, num_trusts
);
2874 status
= dcerpc_fetch_session_key(p
, &session_key
);
2875 if (!NT_STATUS_IS_OK(status
)) {
2876 torture_comment(tctx
, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status
));
2880 for (i
=0; i
< num_trusts
; i
++) {
2881 char *trust_name
= talloc_asprintf(tctx
, "torturedom%s%02d", id
, i
);
2882 char *trust_name_dns
= talloc_asprintf(tctx
, "torturedom%s%02d.samba.example.com", id
, i
);
2883 char *trust_sid
= talloc_asprintf(tctx
, "S-1-5-21-97398-379795-%s%02d", id
, i
);
2885 domsid
[i
] = dom_sid_parse_talloc(tctx
, trust_sid
);
2887 trustinfo
.sid
= domsid
[i
];
2888 trustinfo
.netbios_name
.string
= trust_name
;
2889 trustinfo
.domain_name
.string
= trust_name_dns
;
2891 /* Create inbound, some outbound, and some
2892 * bi-directional trusts in a repeating pattern based
2895 /* 1 == inbound, 2 == outbound, 3 == both */
2896 trustinfo
.trust_direction
= (i
% 3) + 1;
2898 /* Try different trust types too */
2900 /* 1 == downlevel (NT4), 2 == uplevel (ADS), 3 == MIT (kerberos but not AD) */
2901 trustinfo
.trust_type
= (((i
/ 3) + 1) % 3) + 1;
2903 trustinfo
.trust_attributes
= LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION
;
2905 if (!gen_authinfo_internal(tctx
, TRUSTPW
, session_key
, &authinfo_internal
)) {
2906 torture_comment(tctx
, "gen_authinfo_internal failed");
2910 if (!gen_authinfo(tctx
, TRUSTPW
, &authinfo
)) {
2911 torture_comment(tctx
, "gen_authinfonfo failed");
2917 r2
.in
.policy_handle
= handle
;
2918 r2
.in
.info
= &trustinfo
;
2919 r2
.in
.auth_info_internal
= authinfo_internal
;
2920 r2
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2921 r2
.out
.trustdom_handle
= &trustdom_handle
[i
];
2923 torture_assert_ntstatus_ok(tctx
,
2924 dcerpc_lsa_CreateTrustedDomainEx2_r(b
, tctx
, &r2
),
2925 "CreateTrustedDomainEx2 failed");
2927 status
= r2
.out
.result
;
2930 r
.in
.policy_handle
= handle
;
2931 r
.in
.info
= &trustinfo
;
2932 r
.in
.auth_info
= authinfo
;
2933 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2934 r
.out
.trustdom_handle
= &trustdom_handle
[i
];
2936 torture_assert_ntstatus_ok(tctx
,
2937 dcerpc_lsa_CreateTrustedDomainEx_r(b
, tctx
, &r
),
2938 "CreateTrustedDomainEx failed");
2940 status
= r
.out
.result
;
2943 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_COLLISION
)) {
2944 test_DeleteTrustedDomain(b
, tctx
, handle
, trustinfo
.netbios_name
);
2946 torture_assert_ntstatus_ok(tctx
,
2947 dcerpc_lsa_CreateTrustedDomainEx2_r(b
, tctx
, &r2
),
2948 "CreateTrustedDomainEx2 failed");
2949 status
= r2
.out
.result
;
2951 torture_assert_ntstatus_ok(tctx
,
2952 dcerpc_lsa_CreateTrustedDomainEx_r(b
, tctx
, &r
),
2953 "CreateTrustedDomainEx2 failed");
2954 status
= r
.out
.result
;
2957 if (!NT_STATUS_IS_OK(status
)) {
2958 torture_comment(tctx
, "CreateTrustedDomainEx failed2 - %s\n", nt_errstr(status
));
2961 /* For outbound and MIT trusts there is no trust account */
2962 if (trustinfo
.trust_direction
!= 2 &&
2963 trustinfo
.trust_type
!= 3) {
2965 if (torture_setting_bool(tctx
, "samba3", false)) {
2966 torture_comment(tctx
, "skipping trusted domain auth tests against samba3");
2967 } else if (ex2_call
== false &&
2968 torture_setting_bool(tctx
, "samba4", false)) {
2969 torture_comment(tctx
, "skipping CreateTrustedDomainEx trusted domain auth tests against samba4");
2972 if (check_dom_trust_pw(p
, tctx
, trust_name
,
2974 torture_comment(tctx
, "Password check passed unexpectedly\n");
2977 if (!check_dom_trust_pw(p
, tctx
, trust_name
,
2979 torture_comment(tctx
, "Password check failed\n");
2985 q
.in
.trustdom_handle
= &trustdom_handle
[i
];
2986 q
.in
.level
= LSA_TRUSTED_DOMAIN_INFO_INFO_EX
;
2988 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QueryTrustedDomainInfo_r(b
, tctx
, &q
),
2989 "QueryTrustedDomainInfo failed");
2990 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
2991 torture_comment(tctx
, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(q
.out
.result
));
2993 } else if (!q
.out
.info
) {
2994 torture_comment(tctx
, "QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
2997 if (strcmp(info
->info_ex
.netbios_name
.string
, trustinfo
.netbios_name
.string
) != 0) {
2998 torture_comment(tctx
, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
2999 info
->info_ex
.netbios_name
.string
, trustinfo
.netbios_name
.string
);
3002 if (info
->info_ex
.trust_type
!= trustinfo
.trust_type
) {
3003 torture_comment(tctx
, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
3004 trust_name
, info
->info_ex
.trust_type
, trustinfo
.trust_type
);
3007 if (info
->info_ex
.trust_attributes
!= LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION
) {
3008 torture_comment(tctx
, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
3009 trust_name
, info
->info_ex
.trust_attributes
, LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION
);
3012 if (info
->info_ex
.trust_direction
!= trustinfo
.trust_direction
) {
3013 torture_comment(tctx
, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
3014 trust_name
, info
->info_ex
.trust_direction
, trustinfo
.trust_direction
);
3021 /* now that we have some domains to look over, we can test the enum calls */
3022 if (!test_EnumTrustDom(b
, tctx
, handle
)) {
3023 torture_comment(tctx
, "test_EnumTrustDom failed\n");
3027 if (!test_EnumTrustDomEx(b
, tctx
, handle
)) {
3028 torture_comment(tctx
, "test_EnumTrustDomEx failed\n");
3032 for (i
=0; i
<num_trusts
; i
++) {
3033 if (!test_DeleteTrustedDomainBySid(b
, tctx
, handle
, domsid
[i
])) {
3034 torture_comment(tctx
, "test_DeleteTrustedDomainBySid failed\n");
3042 static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe
*p
,
3043 struct torture_context
*tctx
,
3044 struct policy_handle
*handle
,
3045 uint32_t num_trusts
)
3047 return test_CreateTrustedDomainEx_common(p
, tctx
, handle
, num_trusts
, true);
3050 static bool test_CreateTrustedDomainEx(struct dcerpc_pipe
*p
,
3051 struct torture_context
*tctx
,
3052 struct policy_handle
*handle
,
3053 uint32_t num_trusts
)
3055 return test_CreateTrustedDomainEx_common(p
, tctx
, handle
, num_trusts
, false);
3058 static bool test_QueryDomainInfoPolicy(struct dcerpc_binding_handle
*b
,
3059 struct torture_context
*tctx
,
3060 struct policy_handle
*handle
)
3062 struct lsa_QueryDomainInformationPolicy r
;
3063 union lsa_DomainInformationPolicy
*info
= NULL
;
3067 if (torture_setting_bool(tctx
, "samba3", false)) {
3068 torture_skip(tctx
, "skipping QueryDomainInformationPolicy test\n");
3071 torture_comment(tctx
, "\nTesting QueryDomainInformationPolicy\n");
3074 r
.in
.handle
= handle
;
3078 torture_comment(tctx
, "\nTrying QueryDomainInformationPolicy level %d\n", i
);
3080 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QueryDomainInformationPolicy_r(b
, tctx
, &r
),
3081 "QueryDomainInformationPolicy failed");
3083 /* If the server does not support EFS, then this is the correct return */
3084 if (i
== LSA_DOMAIN_INFO_POLICY_EFS
&& NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
3086 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
3087 torture_comment(tctx
, "QueryDomainInformationPolicy failed - %s\n", nt_errstr(r
.out
.result
));
3097 static bool test_QueryInfoPolicyCalls( bool version2
,
3098 struct dcerpc_binding_handle
*b
,
3099 struct torture_context
*tctx
,
3100 struct policy_handle
*handle
)
3102 struct lsa_QueryInfoPolicy r
;
3103 union lsa_PolicyInformation
*info
= NULL
;
3106 const char *call
= talloc_asprintf(tctx
, "QueryInfoPolicy%s", version2
? "2":"");
3108 torture_comment(tctx
, "\nTesting %s\n", call
);
3110 if (version2
&& torture_setting_bool(tctx
, "samba3", false)) {
3111 torture_skip(tctx
, "skipping QueryInfoPolicy2 tests\n");
3114 for (i
=1;i
<=14;i
++) {
3115 r
.in
.handle
= handle
;
3119 torture_comment(tctx
, "\nTrying %s level %d\n", call
, i
);
3122 /* We can perform the cast, because both types are
3123 structurally equal */
3124 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QueryInfoPolicy2_r(b
, tctx
,
3125 (struct lsa_QueryInfoPolicy2
*) &r
),
3126 "QueryInfoPolicy2 failed");
3128 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QueryInfoPolicy_r(b
, tctx
, &r
),
3129 "QueryInfoPolicy2 failed");
3132 case LSA_POLICY_INFO_MOD
:
3133 case LSA_POLICY_INFO_AUDIT_FULL_SET
:
3134 case LSA_POLICY_INFO_AUDIT_FULL_QUERY
:
3135 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
3136 torture_comment(tctx
, "Server should have failed level %u: %s\n", i
, nt_errstr(r
.out
.result
));
3140 case LSA_POLICY_INFO_DOMAIN
:
3141 case LSA_POLICY_INFO_ACCOUNT_DOMAIN
:
3142 case LSA_POLICY_INFO_REPLICA
:
3143 case LSA_POLICY_INFO_QUOTA
:
3144 case LSA_POLICY_INFO_ROLE
:
3145 case LSA_POLICY_INFO_AUDIT_LOG
:
3146 case LSA_POLICY_INFO_AUDIT_EVENTS
:
3147 case LSA_POLICY_INFO_PD
:
3148 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
3149 torture_comment(tctx
, "%s failed - %s\n", call
, nt_errstr(r
.out
.result
));
3153 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN
:
3154 case LSA_POLICY_INFO_DNS_INT
:
3155 case LSA_POLICY_INFO_DNS
:
3156 if (torture_setting_bool(tctx
, "samba3", false)) {
3157 /* Other levels not implemented yet */
3158 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_INFO_CLASS
)) {
3159 torture_comment(tctx
, "%s failed - %s\n", call
, nt_errstr(r
.out
.result
));
3162 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
3163 torture_comment(tctx
, "%s failed - %s\n", call
, nt_errstr(r
.out
.result
));
3168 if (torture_setting_bool(tctx
, "samba4", false)) {
3169 /* Other levels not implemented yet */
3170 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_INFO_CLASS
)) {
3171 torture_comment(tctx
, "%s failed - %s\n", call
, nt_errstr(r
.out
.result
));
3174 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
3175 torture_comment(tctx
, "%s failed - %s\n", call
, nt_errstr(r
.out
.result
));
3181 if (NT_STATUS_IS_OK(r
.out
.result
) && (i
== LSA_POLICY_INFO_DNS
3182 || i
== LSA_POLICY_INFO_DNS_INT
)) {
3183 /* Let's look up some of these names */
3185 struct lsa_TransNameArray tnames
;
3187 tnames
.names
= talloc_zero_array(tctx
, struct lsa_TranslatedName
, tnames
.count
);
3188 tnames
.names
[0].name
.string
= info
->dns
.name
.string
;
3189 tnames
.names
[0].sid_type
= SID_NAME_DOMAIN
;
3190 tnames
.names
[1].name
.string
= info
->dns
.dns_domain
.string
;
3191 tnames
.names
[1].sid_type
= SID_NAME_DOMAIN
;
3192 tnames
.names
[2].name
.string
= talloc_asprintf(tctx
, "%s\\", info
->dns
.name
.string
);
3193 tnames
.names
[2].sid_type
= SID_NAME_DOMAIN
;
3194 tnames
.names
[3].name
.string
= talloc_asprintf(tctx
, "%s\\", info
->dns
.dns_domain
.string
);
3195 tnames
.names
[3].sid_type
= SID_NAME_DOMAIN
;
3196 tnames
.names
[4].name
.string
= talloc_asprintf(tctx
, "%s\\guest", info
->dns
.name
.string
);
3197 tnames
.names
[4].sid_type
= SID_NAME_USER
;
3198 tnames
.names
[5].name
.string
= talloc_asprintf(tctx
, "%s\\krbtgt", info
->dns
.name
.string
);
3199 tnames
.names
[5].sid_type
= SID_NAME_USER
;
3200 tnames
.names
[6].name
.string
= talloc_asprintf(tctx
, "%s\\guest", info
->dns
.dns_domain
.string
);
3201 tnames
.names
[6].sid_type
= SID_NAME_USER
;
3202 tnames
.names
[7].name
.string
= talloc_asprintf(tctx
, "%s\\krbtgt", info
->dns
.dns_domain
.string
);
3203 tnames
.names
[7].sid_type
= SID_NAME_USER
;
3204 tnames
.names
[8].name
.string
= talloc_asprintf(tctx
, "krbtgt@%s", info
->dns
.name
.string
);
3205 tnames
.names
[8].sid_type
= SID_NAME_USER
;
3206 tnames
.names
[9].name
.string
= talloc_asprintf(tctx
, "krbtgt@%s", info
->dns
.dns_domain
.string
);
3207 tnames
.names
[9].sid_type
= SID_NAME_USER
;
3208 tnames
.names
[10].name
.string
= talloc_asprintf(tctx
, "%s\\"TEST_MACHINENAME
"$", info
->dns
.name
.string
);
3209 tnames
.names
[10].sid_type
= SID_NAME_USER
;
3210 tnames
.names
[11].name
.string
= talloc_asprintf(tctx
, "%s\\"TEST_MACHINENAME
"$", info
->dns
.dns_domain
.string
);
3211 tnames
.names
[11].sid_type
= SID_NAME_USER
;
3212 tnames
.names
[12].name
.string
= talloc_asprintf(tctx
, TEST_MACHINENAME
"$@%s", info
->dns
.name
.string
);
3213 tnames
.names
[12].sid_type
= SID_NAME_USER
;
3214 tnames
.names
[13].name
.string
= talloc_asprintf(tctx
, TEST_MACHINENAME
"$@%s", info
->dns
.dns_domain
.string
);
3215 tnames
.names
[13].sid_type
= SID_NAME_USER
;
3216 ret
&= test_LookupNames(b
, tctx
, handle
, &tnames
);
3224 static bool test_QueryInfoPolicy(struct dcerpc_binding_handle
*b
,
3225 struct torture_context
*tctx
,
3226 struct policy_handle
*handle
)
3228 return test_QueryInfoPolicyCalls(false, b
, tctx
, handle
);
3231 static bool test_QueryInfoPolicy2(struct dcerpc_binding_handle
*b
,
3232 struct torture_context
*tctx
,
3233 struct policy_handle
*handle
)
3235 return test_QueryInfoPolicyCalls(true, b
, tctx
, handle
);
3238 static bool test_GetUserName(struct dcerpc_binding_handle
*b
,
3239 struct torture_context
*tctx
)
3241 struct lsa_GetUserName r
;
3243 struct lsa_String
*authority_name_p
= NULL
;
3244 struct lsa_String
*account_name_p
= NULL
;
3246 torture_comment(tctx
, "\nTesting GetUserName\n");
3248 r
.in
.system_name
= "\\";
3249 r
.in
.account_name
= &account_name_p
;
3250 r
.in
.authority_name
= NULL
;
3251 r
.out
.account_name
= &account_name_p
;
3253 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_GetUserName_r(b
, tctx
, &r
),
3254 "GetUserName failed");
3256 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
3257 torture_comment(tctx
, "GetUserName failed - %s\n", nt_errstr(r
.out
.result
));
3261 account_name_p
= NULL
;
3262 r
.in
.account_name
= &account_name_p
;
3263 r
.in
.authority_name
= &authority_name_p
;
3264 r
.out
.account_name
= &account_name_p
;
3266 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_GetUserName_r(b
, tctx
, &r
),
3267 "GetUserName failed");
3269 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
3270 torture_comment(tctx
, "GetUserName failed - %s\n", nt_errstr(r
.out
.result
));
3277 static bool test_GetUserName_fail(struct dcerpc_binding_handle
*b
,
3278 struct torture_context
*tctx
)
3280 struct lsa_GetUserName r
;
3281 struct lsa_String
*account_name_p
= NULL
;
3284 torture_comment(tctx
, "\nTesting GetUserName_fail\n");
3286 r
.in
.system_name
= "\\";
3287 r
.in
.account_name
= &account_name_p
;
3288 r
.in
.authority_name
= NULL
;
3289 r
.out
.account_name
= &account_name_p
;
3291 status
= dcerpc_lsa_GetUserName_r(b
, tctx
, &r
);
3292 if (!NT_STATUS_IS_OK(status
)) {
3293 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
3294 torture_comment(tctx
,
3295 "GetUserName correctly returned with "
3301 torture_assert_ntstatus_equal(tctx
,
3303 NT_STATUS_ACCESS_DENIED
,
3304 "GetUserName return value should "
3305 "be ACCESS_DENIED");
3309 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
3310 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
) ||
3311 NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED
)) {
3312 torture_comment(tctx
,
3313 "GetUserName correctly returned with "
3315 nt_errstr(r
.out
.result
));
3320 torture_assert_ntstatus_equal(tctx
,
3323 "GetUserName return value should be "
3329 bool test_lsa_Close(struct dcerpc_binding_handle
*b
,
3330 struct torture_context
*tctx
,
3331 struct policy_handle
*handle
)
3334 struct policy_handle handle2
;
3336 torture_comment(tctx
, "\nTesting Close\n");
3338 r
.in
.handle
= handle
;
3339 r
.out
.handle
= &handle2
;
3341 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_Close_r(b
, tctx
, &r
),
3343 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
3346 torture_assert_ntstatus_equal(tctx
, dcerpc_lsa_Close_r(b
, tctx
, &r
),
3347 NT_STATUS_RPC_SS_CONTEXT_MISMATCH
, "Close should failed");
3349 torture_comment(tctx
, "\n");
3354 bool torture_rpc_lsa(struct torture_context
*tctx
)
3357 struct dcerpc_pipe
*p
;
3359 struct policy_handle
*handle
= NULL
;
3360 struct test_join
*join
= NULL
;
3361 struct cli_credentials
*machine_creds
;
3362 struct dcerpc_binding_handle
*b
;
3363 enum dcerpc_transport_t transport
;
3365 status
= torture_rpc_connection(tctx
, &p
, &ndr_table_lsarpc
);
3366 if (!NT_STATUS_IS_OK(status
)) {
3369 b
= p
->binding_handle
;
3370 transport
= dcerpc_binding_get_transport(p
->binding
);
3372 /* Test lsaLookupSids3 and lsaLookupNames4 over tcpip */
3373 if (transport
== NCACN_IP_TCP
) {
3374 if (!test_OpenPolicy_fail(b
, tctx
)) {
3378 if (!test_OpenPolicy2_fail(b
, tctx
)) {
3382 if (!test_many_LookupSids(p
, tctx
, handle
)) {
3389 if (!test_OpenPolicy(b
, tctx
)) {
3393 if (!test_lsa_OpenPolicy2(b
, tctx
, &handle
)) {
3398 join
= torture_join_domain(tctx
, TEST_MACHINENAME
, ACB_WSTRUST
, &machine_creds
);
3403 if (!test_LookupSids_async(b
, tctx
, handle
)) {
3407 if (!test_QueryDomainInfoPolicy(b
, tctx
, handle
)) {
3411 if (!test_CreateSecret(p
, tctx
, handle
)) {
3415 if (!test_QueryInfoPolicy(b
, tctx
, handle
)) {
3419 if (!test_QueryInfoPolicy2(b
, tctx
, handle
)) {
3423 if (!test_Delete(b
, tctx
, handle
)) {
3427 if (!test_many_LookupSids(p
, tctx
, handle
)) {
3431 if (!test_lsa_Close(b
, tctx
, handle
)) {
3435 torture_leave_domain(tctx
, join
);
3438 if (!test_many_LookupSids(p
, tctx
, handle
)) {
3443 if (!test_GetUserName(b
, tctx
)) {
3450 bool torture_rpc_lsa_get_user(struct torture_context
*tctx
)
3453 struct dcerpc_pipe
*p
;
3455 struct dcerpc_binding_handle
*b
;
3456 enum dcerpc_transport_t transport
;
3458 status
= torture_rpc_connection(tctx
, &p
, &ndr_table_lsarpc
);
3459 if (!NT_STATUS_IS_OK(status
)) {
3462 b
= p
->binding_handle
;
3463 transport
= dcerpc_binding_get_transport(p
->binding
);
3465 if (transport
== NCACN_IP_TCP
) {
3466 if (!test_GetUserName_fail(b
, tctx
)) {
3472 if (!test_GetUserName(b
, tctx
)) {
3479 static bool testcase_LookupNames(struct torture_context
*tctx
,
3480 struct dcerpc_pipe
*p
)
3483 struct policy_handle
*handle
;
3484 struct lsa_TransNameArray tnames
;
3485 struct lsa_TransNameArray2 tnames2
;
3486 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3487 enum dcerpc_transport_t transport
= dcerpc_binding_get_transport(p
->binding
);
3489 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
3490 torture_comment(tctx
, "testcase_LookupNames is only available "
3491 "over NCACN_NP or NCALRPC");
3495 if (!test_OpenPolicy(b
, tctx
)) {
3499 if (!test_lsa_OpenPolicy2(b
, tctx
, &handle
)) {
3508 tnames
.names
= talloc_array(tctx
, struct lsa_TranslatedName
, tnames
.count
);
3509 ZERO_STRUCT(tnames
.names
[0]);
3510 tnames
.names
[0].name
.string
= "BUILTIN";
3511 tnames
.names
[0].sid_type
= SID_NAME_DOMAIN
;
3513 if (!test_LookupNames(b
, tctx
, handle
, &tnames
)) {
3518 tnames2
.names
= talloc_array(tctx
, struct lsa_TranslatedName2
, tnames2
.count
);
3519 ZERO_STRUCT(tnames2
.names
[0]);
3520 tnames2
.names
[0].name
.string
= "BUILTIN";
3521 tnames2
.names
[0].sid_type
= SID_NAME_DOMAIN
;
3523 if (!test_LookupNames2(b
, tctx
, handle
, &tnames2
, true)) {
3527 if (!test_LookupNames3(b
, tctx
, handle
, &tnames2
, true)) {
3531 if (!test_LookupNames_wellknown(b
, tctx
, handle
)) {
3535 if (!test_LookupNames_NULL(b
, tctx
, handle
)) {
3539 if (!test_LookupNames_bogus(b
, tctx
, handle
)) {
3543 if (!test_lsa_Close(b
, tctx
, handle
)) {
3550 struct torture_suite
*torture_rpc_lsa_lookup_names(TALLOC_CTX
*mem_ctx
)
3552 struct torture_suite
*suite
;
3553 struct torture_rpc_tcase
*tcase
;
3555 suite
= torture_suite_create(mem_ctx
, "lsa.lookupnames");
3557 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "lsa",
3559 torture_rpc_tcase_add_test(tcase
, "LookupNames",
3560 testcase_LookupNames
);
3565 struct lsa_trustdom_state
{
3566 uint32_t num_trusts
;
3569 static bool testcase_TrustedDomains(struct torture_context
*tctx
,
3570 struct dcerpc_pipe
*p
,
3574 struct policy_handle
*handle
;
3575 struct lsa_trustdom_state
*state
=
3576 talloc_get_type_abort(data
, struct lsa_trustdom_state
);
3577 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3578 enum dcerpc_transport_t transport
= dcerpc_binding_get_transport(p
->binding
);
3580 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
3581 torture_comment(tctx
, "testcase_TrustedDomains is only available "
3582 "over NCACN_NP or NCALRPC");
3586 torture_comment(tctx
, "Testing %d domains\n", state
->num_trusts
);
3588 if (!test_OpenPolicy(b
, tctx
)) {
3592 if (!test_lsa_OpenPolicy2(b
, tctx
, &handle
)) {
3600 if (!test_CreateTrustedDomain(b
, tctx
, handle
, state
->num_trusts
)) {
3604 if (!test_CreateTrustedDomainEx(p
, tctx
, handle
, state
->num_trusts
)) {
3608 if (!test_CreateTrustedDomainEx2(p
, tctx
, handle
, state
->num_trusts
)) {
3612 if (!test_lsa_Close(b
, tctx
, handle
)) {
3619 struct torture_suite
*torture_rpc_lsa_trusted_domains(TALLOC_CTX
*mem_ctx
)
3621 struct torture_suite
*suite
;
3622 struct torture_rpc_tcase
*tcase
;
3623 struct lsa_trustdom_state
*state
;
3625 state
= talloc(mem_ctx
, struct lsa_trustdom_state
);
3627 state
->num_trusts
= 12;
3629 suite
= torture_suite_create(mem_ctx
, "lsa.trusted.domains");
3631 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "lsa",
3633 torture_rpc_tcase_add_test_ex(tcase
, "TrustedDomains",
3634 testcase_TrustedDomains
,
3640 static bool testcase_Privileges(struct torture_context
*tctx
,
3641 struct dcerpc_pipe
*p
)
3643 struct policy_handle
*handle
;
3644 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3645 enum dcerpc_transport_t transport
= dcerpc_binding_get_transport(p
->binding
);
3647 if (transport
!= NCACN_NP
&& transport
!= NCALRPC
) {
3648 torture_skip(tctx
, "testcase_Privileges is only available "
3649 "over NCACN_NP or NCALRPC");
3652 if (!test_OpenPolicy(b
, tctx
)) {
3656 if (!test_lsa_OpenPolicy2(b
, tctx
, &handle
)) {
3664 if (!test_CreateAccount(b
, tctx
, handle
)) {
3668 if (!test_EnumAccounts(b
, tctx
, handle
)) {
3672 if (!test_EnumPrivs(b
, tctx
, handle
)) {
3676 if (!test_lsa_Close(b
, tctx
, handle
)) {
3684 struct torture_suite
*torture_rpc_lsa_privileges(TALLOC_CTX
*mem_ctx
)
3686 struct torture_suite
*suite
;
3687 struct torture_rpc_tcase
*tcase
;
3689 suite
= torture_suite_create(mem_ctx
, "lsa.privileges");
3691 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "lsa",
3693 torture_rpc_tcase_add_test(tcase
, "Privileges",
3694 testcase_Privileges
);