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
;
952 torture_comment(tctx
, "\nTesting LookupSids with lots of SIDs\n");
956 sids
.sids
= talloc_array(tctx
, struct lsa_SidPtr
, sids
.num_sids
);
958 for (i
=0; i
<sids
.num_sids
; i
++) {
959 const char *sidstr
= "S-1-5-32-545";
960 sids
.sids
[i
].sid
= dom_sid_parse_talloc(tctx
, sidstr
);
963 count
= sids
.num_sids
;
966 struct lsa_LookupSids r
;
967 struct lsa_TransNameArray names
;
968 struct lsa_RefDomainList
*domains
= NULL
;
972 r
.in
.handle
= handle
;
976 r
.in
.count
= &names
.count
;
977 r
.out
.count
= &count
;
978 r
.out
.names
= &names
;
979 r
.out
.domains
= &domains
;
981 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_LookupSids_r(b
, tctx
, &r
),
982 "LookupSids failed");
983 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
984 torture_comment(tctx
, "LookupSids failed - %s\n",
985 nt_errstr(r
.out
.result
));
989 torture_comment(tctx
, "\n");
991 if (!test_LookupNames(b
, tctx
, handle
, &names
)) {
996 if (p
->binding
->transport
== NCACN_NP
) {
997 if (!test_LookupSids3_fail(b
, tctx
, &sids
)) {
1000 if (!test_LookupNames4_fail(b
, tctx
)) {
1003 } else if (p
->binding
->transport
== NCACN_IP_TCP
) {
1004 struct lsa_TransNameArray2 names
;
1009 if (p
->conn
->security_state
.auth_info
->auth_type
== DCERPC_AUTH_TYPE_SCHANNEL
&&
1010 p
->conn
->security_state
.auth_info
->auth_level
>= DCERPC_AUTH_LEVEL_INTEGRITY
) {
1011 if (!test_LookupSids3(b
, tctx
, &sids
)) {
1014 if (!test_LookupNames4(b
, tctx
, &names
, true)) {
1019 * If we don't have a secure channel these tests must
1020 * fail with ACCESS_DENIED.
1022 if (!test_LookupSids3_fail(b
, tctx
, &sids
)) {
1025 if (!test_LookupNames4_fail(b
, tctx
)) {
1031 torture_comment(tctx
, "\n");
1038 static void lookupsids_cb(struct tevent_req
*subreq
)
1040 int *replies
= (int *)tevent_req_callback_data_void(subreq
);
1043 status
= dcerpc_lsa_LookupSids_r_recv(subreq
, subreq
);
1044 TALLOC_FREE(subreq
);
1045 if (!NT_STATUS_IS_OK(status
)) {
1046 printf("lookupsids returned %s\n", nt_errstr(status
));
1050 if (*replies
>= 0) {
1055 static bool test_LookupSids_async(struct dcerpc_binding_handle
*b
,
1056 struct torture_context
*tctx
,
1057 struct policy_handle
*handle
)
1059 struct lsa_SidArray sids
;
1060 struct lsa_SidPtr sidptr
;
1062 struct lsa_TransNameArray
*names
;
1063 struct lsa_LookupSids
*r
;
1064 struct lsa_RefDomainList
*domains
= NULL
;
1065 struct tevent_req
**req
;
1068 const int num_async_requests
= 50;
1070 count
= talloc_array(tctx
, uint32_t, num_async_requests
);
1071 names
= talloc_array(tctx
, struct lsa_TransNameArray
, num_async_requests
);
1072 r
= talloc_array(tctx
, struct lsa_LookupSids
, num_async_requests
);
1074 torture_comment(tctx
, "\nTesting %d async lookupsids request\n", num_async_requests
);
1076 req
= talloc_array(tctx
, struct tevent_req
*, num_async_requests
);
1079 sids
.sids
= &sidptr
;
1080 sidptr
.sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-545");
1084 for (i
=0; i
<num_async_requests
; i
++) {
1087 names
[i
].names
= NULL
;
1089 r
[i
].in
.handle
= handle
;
1090 r
[i
].in
.sids
= &sids
;
1091 r
[i
].in
.names
= &names
[i
];
1093 r
[i
].in
.count
= &names
[i
].count
;
1094 r
[i
].out
.count
= &count
[i
];
1095 r
[i
].out
.names
= &names
[i
];
1096 r
[i
].out
.domains
= &domains
;
1098 req
[i
] = dcerpc_lsa_LookupSids_r_send(tctx
, tctx
->ev
, b
, &r
[i
]);
1099 if (req
[i
] == NULL
) {
1104 tevent_req_set_callback(req
[i
], lookupsids_cb
, &replies
);
1107 while (replies
>= 0 && replies
< num_async_requests
) {
1108 tevent_loop_once(tctx
->ev
);
1120 static bool test_LookupPrivValue(struct dcerpc_binding_handle
*b
,
1121 struct torture_context
*tctx
,
1122 struct policy_handle
*handle
,
1123 struct lsa_String
*name
)
1125 struct lsa_LookupPrivValue r
;
1126 struct lsa_LUID luid
;
1128 r
.in
.handle
= handle
;
1132 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_LookupPrivValue_r(b
, tctx
, &r
),
1133 "LookupPrivValue failed");
1134 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1135 "LookupPrivValue failed");
1140 static bool test_LookupPrivName(struct dcerpc_binding_handle
*b
,
1141 struct torture_context
*tctx
,
1142 struct policy_handle
*handle
,
1143 struct lsa_LUID
*luid
)
1145 struct lsa_LookupPrivName r
;
1146 struct lsa_StringLarge
*name
= NULL
;
1148 r
.in
.handle
= handle
;
1152 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_LookupPrivName_r(b
, tctx
, &r
),
1153 "LookupPrivName failed");
1154 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LookupPrivName failed");
1159 static bool test_RemovePrivilegesFromAccount(struct dcerpc_binding_handle
*b
,
1160 struct torture_context
*tctx
,
1161 struct policy_handle
*handle
,
1162 struct policy_handle
*acct_handle
,
1163 struct lsa_LUID
*luid
)
1165 struct lsa_RemovePrivilegesFromAccount r
;
1166 struct lsa_PrivilegeSet privs
;
1169 torture_comment(tctx
, "\nTesting RemovePrivilegesFromAccount\n");
1171 r
.in
.handle
= acct_handle
;
1172 r
.in
.remove_all
= 0;
1173 r
.in
.privs
= &privs
;
1177 privs
.set
= talloc_array(tctx
, struct lsa_LUIDAttribute
, 1);
1178 privs
.set
[0].luid
= *luid
;
1179 privs
.set
[0].attribute
= 0;
1181 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_RemovePrivilegesFromAccount_r(b
, tctx
, &r
),
1182 "RemovePrivilegesFromAccount failed");
1183 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1185 struct lsa_LookupPrivName r_name
;
1186 struct lsa_StringLarge
*name
= NULL
;
1188 r_name
.in
.handle
= handle
;
1189 r_name
.in
.luid
= luid
;
1190 r_name
.out
.name
= &name
;
1192 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_LookupPrivName_r(b
, tctx
, &r_name
),
1193 "LookupPrivName failed");
1194 if (!NT_STATUS_IS_OK(r_name
.out
.result
)) {
1195 torture_comment(tctx
, "\nLookupPrivName failed - %s\n",
1196 nt_errstr(r_name
.out
.result
));
1199 /* Windows 2008 does not allow this to be removed */
1200 if (strcmp("SeAuditPrivilege", name
->string
) == 0) {
1204 torture_comment(tctx
, "RemovePrivilegesFromAccount failed to remove %s - %s\n",
1206 nt_errstr(r
.out
.result
));
1213 static bool test_AddPrivilegesToAccount(struct dcerpc_binding_handle
*b
,
1214 struct torture_context
*tctx
,
1215 struct policy_handle
*acct_handle
,
1216 struct lsa_LUID
*luid
)
1218 struct lsa_AddPrivilegesToAccount r
;
1219 struct lsa_PrivilegeSet privs
;
1222 torture_comment(tctx
, "\nTesting AddPrivilegesToAccount\n");
1224 r
.in
.handle
= acct_handle
;
1225 r
.in
.privs
= &privs
;
1229 privs
.set
= talloc_array(tctx
, struct lsa_LUIDAttribute
, 1);
1230 privs
.set
[0].luid
= *luid
;
1231 privs
.set
[0].attribute
= 0;
1233 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_AddPrivilegesToAccount_r(b
, tctx
, &r
),
1234 "AddPrivilegesToAccount failed");
1235 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1236 "AddPrivilegesToAccount failed");
1240 static bool test_EnumPrivsAccount(struct dcerpc_binding_handle
*b
,
1241 struct torture_context
*tctx
,
1242 struct policy_handle
*handle
,
1243 struct policy_handle
*acct_handle
)
1245 struct lsa_EnumPrivsAccount r
;
1246 struct lsa_PrivilegeSet
*privs
= NULL
;
1249 torture_comment(tctx
, "\nTesting EnumPrivsAccount\n");
1251 r
.in
.handle
= acct_handle
;
1252 r
.out
.privs
= &privs
;
1254 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumPrivsAccount_r(b
, tctx
, &r
),
1255 "EnumPrivsAccount failed");
1256 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1257 "EnumPrivsAccount failed");
1259 if (privs
&& privs
->count
> 0) {
1261 for (i
=0;i
<privs
->count
;i
++) {
1262 test_LookupPrivName(b
, tctx
, handle
,
1263 &privs
->set
[i
].luid
);
1266 ret
&= test_RemovePrivilegesFromAccount(b
, tctx
, handle
, acct_handle
,
1267 &privs
->set
[0].luid
);
1268 ret
&= test_AddPrivilegesToAccount(b
, tctx
, acct_handle
,
1269 &privs
->set
[0].luid
);
1275 static bool test_GetSystemAccessAccount(struct dcerpc_binding_handle
*b
,
1276 struct torture_context
*tctx
,
1277 struct policy_handle
*handle
,
1278 struct policy_handle
*acct_handle
)
1280 uint32_t access_mask
;
1281 struct lsa_GetSystemAccessAccount r
;
1283 torture_comment(tctx
, "\nTesting GetSystemAccessAccount\n");
1285 r
.in
.handle
= acct_handle
;
1286 r
.out
.access_mask
= &access_mask
;
1288 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_GetSystemAccessAccount_r(b
, tctx
, &r
),
1289 "GetSystemAccessAccount failed");
1290 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1291 "GetSystemAccessAccount failed");
1293 if (r
.out
.access_mask
!= NULL
) {
1294 torture_comment(tctx
, "Rights:");
1295 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_INTERACTIVE
)
1296 torture_comment(tctx
, " LSA_POLICY_MODE_INTERACTIVE");
1297 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_NETWORK
)
1298 torture_comment(tctx
, " LSA_POLICY_MODE_NETWORK");
1299 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_BATCH
)
1300 torture_comment(tctx
, " LSA_POLICY_MODE_BATCH");
1301 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_SERVICE
)
1302 torture_comment(tctx
, " LSA_POLICY_MODE_SERVICE");
1303 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_PROXY
)
1304 torture_comment(tctx
, " LSA_POLICY_MODE_PROXY");
1305 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_DENY_INTERACTIVE
)
1306 torture_comment(tctx
, " LSA_POLICY_MODE_DENY_INTERACTIVE");
1307 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_DENY_NETWORK
)
1308 torture_comment(tctx
, " LSA_POLICY_MODE_DENY_NETWORK");
1309 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_DENY_BATCH
)
1310 torture_comment(tctx
, " LSA_POLICY_MODE_DENY_BATCH");
1311 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_DENY_SERVICE
)
1312 torture_comment(tctx
, " LSA_POLICY_MODE_DENY_SERVICE");
1313 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_REMOTE_INTERACTIVE
)
1314 torture_comment(tctx
, " LSA_POLICY_MODE_REMOTE_INTERACTIVE");
1315 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE
)
1316 torture_comment(tctx
, " LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE");
1317 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_ALL
)
1318 torture_comment(tctx
, " LSA_POLICY_MODE_ALL");
1319 if (*(r
.out
.access_mask
) & LSA_POLICY_MODE_ALL_NT4
)
1320 torture_comment(tctx
, " LSA_POLICY_MODE_ALL_NT4");
1321 torture_comment(tctx
, "\n");
1327 static bool test_Delete(struct dcerpc_binding_handle
*b
,
1328 struct torture_context
*tctx
,
1329 struct policy_handle
*handle
)
1331 struct lsa_Delete r
;
1333 torture_comment(tctx
, "\nTesting Delete\n");
1335 r
.in
.handle
= handle
;
1336 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_Delete_r(b
, tctx
, &r
),
1338 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_NOT_SUPPORTED
,
1339 "Delete should have failed NT_STATUS_NOT_SUPPORTED");
1344 static bool test_DeleteObject(struct dcerpc_binding_handle
*b
,
1345 struct torture_context
*tctx
,
1346 struct policy_handle
*handle
)
1348 struct lsa_DeleteObject r
;
1350 torture_comment(tctx
, "\nTesting DeleteObject\n");
1352 r
.in
.handle
= handle
;
1353 r
.out
.handle
= handle
;
1354 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_DeleteObject_r(b
, tctx
, &r
),
1355 "DeleteObject failed");
1356 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1357 "DeleteObject failed");
1363 static bool test_CreateAccount(struct dcerpc_binding_handle
*b
,
1364 struct torture_context
*tctx
,
1365 struct policy_handle
*handle
)
1367 struct lsa_CreateAccount r
;
1368 struct dom_sid2
*newsid
;
1369 struct policy_handle acct_handle
;
1371 newsid
= dom_sid_parse_talloc(tctx
, "S-1-5-12349876-4321-2854");
1373 torture_comment(tctx
, "\nTesting CreateAccount\n");
1375 r
.in
.handle
= handle
;
1377 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1378 r
.out
.acct_handle
= &acct_handle
;
1380 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_CreateAccount_r(b
, tctx
, &r
),
1381 "CreateAccount failed");
1382 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_OBJECT_NAME_COLLISION
)) {
1383 struct lsa_OpenAccount r_o
;
1384 r_o
.in
.handle
= handle
;
1385 r_o
.in
.sid
= newsid
;
1386 r_o
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1387 r_o
.out
.acct_handle
= &acct_handle
;
1389 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenAccount_r(b
, tctx
, &r_o
),
1390 "OpenAccount failed");
1391 torture_assert_ntstatus_ok(tctx
, r_o
.out
.result
,
1392 "OpenAccount failed");
1394 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1395 "CreateAccount failed");
1398 if (!test_Delete(b
, tctx
, &acct_handle
)) {
1402 if (!test_DeleteObject(b
, tctx
, &acct_handle
)) {
1409 static bool test_DeleteTrustedDomain(struct dcerpc_binding_handle
*b
,
1410 struct torture_context
*tctx
,
1411 struct policy_handle
*handle
,
1412 struct lsa_StringLarge name
)
1414 struct lsa_OpenTrustedDomainByName r
;
1415 struct policy_handle trustdom_handle
;
1417 r
.in
.handle
= handle
;
1418 r
.in
.name
.string
= name
.string
;
1419 r
.in
.access_mask
= SEC_STD_DELETE
;
1420 r
.out
.trustdom_handle
= &trustdom_handle
;
1422 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenTrustedDomainByName_r(b
, tctx
, &r
),
1423 "OpenTrustedDomainByName failed");
1424 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1425 "OpenTrustedDomainByName failed");
1427 if (!test_Delete(b
, tctx
, &trustdom_handle
)) {
1431 if (!test_DeleteObject(b
, tctx
, &trustdom_handle
)) {
1438 static bool test_DeleteTrustedDomainBySid(struct dcerpc_binding_handle
*b
,
1439 struct torture_context
*tctx
,
1440 struct policy_handle
*handle
,
1441 struct dom_sid
*sid
)
1443 struct lsa_DeleteTrustedDomain r
;
1445 r
.in
.handle
= handle
;
1448 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_DeleteTrustedDomain_r(b
, tctx
, &r
),
1449 "DeleteTrustedDomain failed");
1450 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1451 "DeleteTrustedDomain failed");
1457 static bool test_CreateSecret(struct dcerpc_pipe
*p
,
1458 struct torture_context
*tctx
,
1459 struct policy_handle
*handle
)
1461 struct lsa_CreateSecret r
;
1462 struct lsa_OpenSecret r2
;
1463 struct lsa_SetSecret r3
;
1464 struct lsa_QuerySecret r4
;
1465 struct lsa_SetSecret r5
;
1466 struct lsa_QuerySecret r6
;
1467 struct lsa_SetSecret r7
;
1468 struct lsa_QuerySecret r8
;
1469 struct policy_handle sec_handle
, sec_handle2
, sec_handle3
;
1470 struct lsa_DeleteObject d_o
;
1471 struct lsa_DATA_BUF buf1
;
1472 struct lsa_DATA_BUF_PTR bufp1
;
1473 struct lsa_DATA_BUF_PTR bufp2
;
1476 DATA_BLOB session_key
;
1477 NTTIME old_mtime
, new_mtime
;
1479 const char *secret1
= "abcdef12345699qwerty";
1481 const char *secret3
= "ABCDEF12345699QWERTY";
1483 const char *secret5
= "NEW-SAMBA4-SECRET";
1487 const int LOCAL
= 0;
1488 const int GLOBAL
= 1;
1489 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1491 secname
[LOCAL
] = talloc_asprintf(tctx
, "torturesecret-%u", (unsigned int)random());
1492 secname
[GLOBAL
] = talloc_asprintf(tctx
, "G$torturesecret-%u", (unsigned int)random());
1494 for (i
=0; i
< 2; i
++) {
1495 torture_comment(tctx
, "\nTesting CreateSecret of %s\n", secname
[i
]);
1497 init_lsa_String(&r
.in
.name
, secname
[i
]);
1499 r
.in
.handle
= handle
;
1500 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1501 r
.out
.sec_handle
= &sec_handle
;
1503 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_CreateSecret_r(b
, tctx
, &r
),
1504 "CreateSecret failed");
1505 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1506 "CreateSecret failed");
1508 r
.in
.handle
= handle
;
1509 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1510 r
.out
.sec_handle
= &sec_handle3
;
1512 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_CreateSecret_r(b
, tctx
, &r
),
1513 "CreateSecret failed");
1514 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_OBJECT_NAME_COLLISION
,
1515 "CreateSecret should have failed OBJECT_NAME_COLLISION");
1517 r2
.in
.handle
= handle
;
1518 r2
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1519 r2
.in
.name
= r
.in
.name
;
1520 r2
.out
.sec_handle
= &sec_handle2
;
1522 torture_comment(tctx
, "Testing OpenSecret\n");
1524 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenSecret_r(b
, tctx
, &r2
),
1525 "OpenSecret failed");
1526 torture_assert_ntstatus_ok(tctx
, r2
.out
.result
,
1527 "OpenSecret failed");
1529 torture_assert_ntstatus_ok(tctx
, dcerpc_fetch_session_key(p
, &session_key
),
1530 "dcerpc_fetch_session_key failed");
1532 enc_key
= sess_encrypt_string(secret1
, &session_key
);
1534 r3
.in
.sec_handle
= &sec_handle
;
1535 r3
.in
.new_val
= &buf1
;
1536 r3
.in
.old_val
= NULL
;
1537 r3
.in
.new_val
->data
= enc_key
.data
;
1538 r3
.in
.new_val
->length
= enc_key
.length
;
1539 r3
.in
.new_val
->size
= enc_key
.length
;
1541 torture_comment(tctx
, "Testing SetSecret\n");
1543 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_SetSecret_r(b
, tctx
, &r3
),
1544 "SetSecret failed");
1545 torture_assert_ntstatus_ok(tctx
, r3
.out
.result
,
1546 "SetSecret failed");
1548 r3
.in
.sec_handle
= &sec_handle
;
1549 r3
.in
.new_val
= &buf1
;
1550 r3
.in
.old_val
= NULL
;
1551 r3
.in
.new_val
->data
= enc_key
.data
;
1552 r3
.in
.new_val
->length
= enc_key
.length
;
1553 r3
.in
.new_val
->size
= enc_key
.length
;
1555 /* break the encrypted data */
1558 torture_comment(tctx
, "Testing SetSecret with broken key\n");
1560 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_SetSecret_r(b
, tctx
, &r3
),
1561 "SetSecret failed");
1562 torture_assert_ntstatus_equal(tctx
, r3
.out
.result
, NT_STATUS_UNKNOWN_REVISION
,
1563 "SetSecret should have failed UNKNOWN_REVISION");
1565 data_blob_free(&enc_key
);
1567 ZERO_STRUCT(new_mtime
);
1568 ZERO_STRUCT(old_mtime
);
1570 /* fetch the secret back again */
1571 r4
.in
.sec_handle
= &sec_handle
;
1572 r4
.in
.new_val
= &bufp1
;
1573 r4
.in
.new_mtime
= &new_mtime
;
1574 r4
.in
.old_val
= NULL
;
1575 r4
.in
.old_mtime
= NULL
;
1579 torture_comment(tctx
, "Testing QuerySecret\n");
1580 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QuerySecret_r(b
, tctx
, &r4
),
1581 "QuerySecret failed");
1582 if (!NT_STATUS_IS_OK(r4
.out
.result
)) {
1583 torture_comment(tctx
, "QuerySecret failed - %s\n", nt_errstr(r4
.out
.result
));
1586 if (r4
.out
.new_val
== NULL
|| r4
.out
.new_val
->buf
== NULL
) {
1587 torture_comment(tctx
, "No secret buffer returned\n");
1590 blob1
.data
= r4
.out
.new_val
->buf
->data
;
1591 blob1
.length
= r4
.out
.new_val
->buf
->size
;
1593 secret2
= sess_decrypt_string(tctx
,
1594 &blob1
, &session_key
);
1596 if (strcmp(secret1
, secret2
) != 0) {
1597 torture_comment(tctx
, "Returned secret (r4) '%s' doesn't match '%s'\n",
1604 enc_key
= sess_encrypt_string(secret3
, &session_key
);
1606 r5
.in
.sec_handle
= &sec_handle
;
1607 r5
.in
.new_val
= &buf1
;
1608 r5
.in
.old_val
= NULL
;
1609 r5
.in
.new_val
->data
= enc_key
.data
;
1610 r5
.in
.new_val
->length
= enc_key
.length
;
1611 r5
.in
.new_val
->size
= enc_key
.length
;
1615 torture_comment(tctx
, "Testing SetSecret (existing value should move to old)\n");
1617 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_SetSecret_r(b
, tctx
, &r5
),
1618 "SetSecret failed");
1619 if (!NT_STATUS_IS_OK(r5
.out
.result
)) {
1620 torture_comment(tctx
, "SetSecret failed - %s\n", nt_errstr(r5
.out
.result
));
1624 data_blob_free(&enc_key
);
1626 ZERO_STRUCT(new_mtime
);
1627 ZERO_STRUCT(old_mtime
);
1629 /* fetch the secret back again */
1630 r6
.in
.sec_handle
= &sec_handle
;
1631 r6
.in
.new_val
= &bufp1
;
1632 r6
.in
.new_mtime
= &new_mtime
;
1633 r6
.in
.old_val
= &bufp2
;
1634 r6
.in
.old_mtime
= &old_mtime
;
1639 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QuerySecret_r(b
, tctx
, &r6
),
1640 "QuerySecret failed");
1641 if (!NT_STATUS_IS_OK(r6
.out
.result
)) {
1642 torture_comment(tctx
, "QuerySecret failed - %s\n", nt_errstr(r6
.out
.result
));
1647 if (r6
.out
.new_val
->buf
== NULL
|| r6
.out
.old_val
->buf
== NULL
1648 || r6
.out
.new_mtime
== NULL
|| r6
.out
.old_mtime
== NULL
) {
1649 torture_comment(tctx
, "Both secret buffers and both times not returned\n");
1653 blob1
.data
= r6
.out
.new_val
->buf
->data
;
1654 blob1
.length
= r6
.out
.new_val
->buf
->size
;
1656 secret4
= sess_decrypt_string(tctx
,
1657 &blob1
, &session_key
);
1659 if (strcmp(secret3
, secret4
) != 0) {
1660 torture_comment(tctx
, "Returned NEW secret %s doesn't match %s\n", secret4
, secret3
);
1664 blob1
.data
= r6
.out
.old_val
->buf
->data
;
1665 blob1
.length
= r6
.out
.old_val
->buf
->length
;
1667 secret2
= sess_decrypt_string(tctx
,
1668 &blob1
, &session_key
);
1670 if (strcmp(secret1
, secret2
) != 0) {
1671 torture_comment(tctx
, "Returned OLD secret %s doesn't match %s\n", secret2
, secret1
);
1675 if (*r6
.out
.new_mtime
== *r6
.out
.old_mtime
) {
1676 torture_comment(tctx
, "Returned secret (r6-%d) %s must not have same mtime for both secrets: %s != %s\n",
1679 nt_time_string(tctx
, *r6
.out
.old_mtime
),
1680 nt_time_string(tctx
, *r6
.out
.new_mtime
));
1686 enc_key
= sess_encrypt_string(secret5
, &session_key
);
1688 r7
.in
.sec_handle
= &sec_handle
;
1689 r7
.in
.old_val
= &buf1
;
1690 r7
.in
.old_val
->data
= enc_key
.data
;
1691 r7
.in
.old_val
->length
= enc_key
.length
;
1692 r7
.in
.old_val
->size
= enc_key
.length
;
1693 r7
.in
.new_val
= NULL
;
1695 torture_comment(tctx
, "Testing SetSecret of old Secret only\n");
1697 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_SetSecret_r(b
, tctx
, &r7
),
1698 "SetSecret failed");
1699 if (!NT_STATUS_IS_OK(r7
.out
.result
)) {
1700 torture_comment(tctx
, "SetSecret failed - %s\n", nt_errstr(r7
.out
.result
));
1704 data_blob_free(&enc_key
);
1706 /* fetch the secret back again */
1707 r8
.in
.sec_handle
= &sec_handle
;
1708 r8
.in
.new_val
= &bufp1
;
1709 r8
.in
.new_mtime
= &new_mtime
;
1710 r8
.in
.old_val
= &bufp2
;
1711 r8
.in
.old_mtime
= &old_mtime
;
1716 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QuerySecret_r(b
, tctx
, &r8
),
1717 "QuerySecret failed");
1718 if (!NT_STATUS_IS_OK(r8
.out
.result
)) {
1719 torture_comment(tctx
, "QuerySecret failed - %s\n", nt_errstr(r8
.out
.result
));
1722 if (!r8
.out
.new_val
|| !r8
.out
.old_val
) {
1723 torture_comment(tctx
, "in/out pointers not returned, despite being set on in for QuerySecret\n");
1725 } else if (r8
.out
.new_val
->buf
!= NULL
) {
1726 torture_comment(tctx
, "NEW secret buffer must not be returned after OLD set\n");
1728 } else if (r8
.out
.old_val
->buf
== NULL
) {
1729 torture_comment(tctx
, "OLD secret buffer was not returned after OLD set\n");
1731 } else if (r8
.out
.new_mtime
== NULL
|| r8
.out
.old_mtime
== NULL
) {
1732 torture_comment(tctx
, "Both times not returned after OLD set\n");
1735 blob1
.data
= r8
.out
.old_val
->buf
->data
;
1736 blob1
.length
= r8
.out
.old_val
->buf
->size
;
1738 secret6
= sess_decrypt_string(tctx
,
1739 &blob1
, &session_key
);
1741 if (strcmp(secret5
, secret6
) != 0) {
1742 torture_comment(tctx
, "Returned OLD secret %s doesn't match %s\n", secret5
, secret6
);
1746 if (*r8
.out
.new_mtime
!= *r8
.out
.old_mtime
) {
1747 torture_comment(tctx
, "Returned secret (r8) %s did not had same mtime for both secrets: %s != %s\n",
1749 nt_time_string(tctx
, *r8
.out
.old_mtime
),
1750 nt_time_string(tctx
, *r8
.out
.new_mtime
));
1756 if (!test_Delete(b
, tctx
, &sec_handle
)) {
1760 if (!test_DeleteObject(b
, tctx
, &sec_handle
)) {
1764 d_o
.in
.handle
= &sec_handle2
;
1765 d_o
.out
.handle
= &sec_handle2
;
1766 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_DeleteObject_r(b
, tctx
, &d_o
),
1767 "DeleteObject failed");
1768 torture_assert_ntstatus_equal(tctx
, d_o
.out
.result
, NT_STATUS_INVALID_HANDLE
,
1769 "OpenSecret expected INVALID_HANDLE");
1771 torture_comment(tctx
, "Testing OpenSecret of just-deleted secret\n");
1773 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenSecret_r(b
, tctx
, &r2
),
1774 "OpenSecret failed");
1775 torture_assert_ntstatus_equal(tctx
, r2
.out
.result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
1776 "OpenSecret expected OBJECT_NAME_NOT_FOUND");
1782 static bool test_EnumAccountRights(struct dcerpc_binding_handle
*b
,
1783 struct torture_context
*tctx
,
1784 struct policy_handle
*acct_handle
,
1785 struct dom_sid
*sid
)
1787 struct lsa_EnumAccountRights r
;
1788 struct lsa_RightSet rights
;
1790 torture_comment(tctx
, "\nTesting EnumAccountRights\n");
1792 r
.in
.handle
= acct_handle
;
1794 r
.out
.rights
= &rights
;
1796 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountRights_r(b
, tctx
, &r
),
1797 "EnumAccountRights failed");
1798 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1799 torture_comment(tctx
, "EnumAccountRights of %s failed - %s\n",
1800 dom_sid_string(tctx
, sid
), nt_errstr(r
.out
.result
));
1802 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1803 "EnumAccountRights failed");
1809 static bool test_QuerySecurity(struct dcerpc_binding_handle
*b
,
1810 struct torture_context
*tctx
,
1811 struct policy_handle
*handle
,
1812 struct policy_handle
*acct_handle
)
1814 struct lsa_QuerySecurity r
;
1815 struct sec_desc_buf
*sdbuf
= NULL
;
1817 if (torture_setting_bool(tctx
, "samba4", false)) {
1818 torture_comment(tctx
, "\nskipping QuerySecurity test against Samba4\n");
1822 torture_comment(tctx
, "\nTesting QuerySecurity\n");
1824 r
.in
.handle
= acct_handle
;
1825 r
.in
.sec_info
= SECINFO_OWNER
|
1828 r
.out
.sdbuf
= &sdbuf
;
1830 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QuerySecurity_r(b
, tctx
, &r
),
1831 "QuerySecurity failed");
1832 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1833 torture_comment(tctx
, "QuerySecurity failed - %s\n", nt_errstr(r
.out
.result
));
1840 static bool test_OpenAccount(struct dcerpc_binding_handle
*b
,
1841 struct torture_context
*tctx
,
1842 struct policy_handle
*handle
,
1843 struct dom_sid
*sid
)
1845 struct lsa_OpenAccount r
;
1846 struct policy_handle acct_handle
;
1848 torture_comment(tctx
, "\nTesting OpenAccount\n");
1850 r
.in
.handle
= handle
;
1852 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1853 r
.out
.acct_handle
= &acct_handle
;
1855 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenAccount_r(b
, tctx
, &r
),
1856 "OpenAccount failed");
1857 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1858 "OpenAccount failed");
1860 if (!test_EnumPrivsAccount(b
, tctx
, handle
, &acct_handle
)) {
1864 if (!test_GetSystemAccessAccount(b
, tctx
, handle
, &acct_handle
)) {
1868 if (!test_QuerySecurity(b
, tctx
, handle
, &acct_handle
)) {
1875 static bool test_EnumAccounts(struct dcerpc_binding_handle
*b
,
1876 struct torture_context
*tctx
,
1877 struct policy_handle
*handle
)
1879 struct lsa_EnumAccounts r
;
1880 struct lsa_SidArray sids1
, sids2
;
1881 uint32_t resume_handle
= 0;
1885 torture_comment(tctx
, "\nTesting EnumAccounts\n");
1887 r
.in
.handle
= handle
;
1888 r
.in
.resume_handle
= &resume_handle
;
1889 r
.in
.num_entries
= 100;
1890 r
.out
.resume_handle
= &resume_handle
;
1891 r
.out
.sids
= &sids1
;
1895 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccounts_r(b
, tctx
, &r
),
1896 "EnumAccounts failed");
1897 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_NO_MORE_ENTRIES
)) {
1900 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1901 "EnumAccounts failed");
1903 if (!test_LookupSids(b
, tctx
, handle
, &sids1
)) {
1907 if (!test_LookupSids2(b
, tctx
, handle
, &sids1
)) {
1911 /* Can't test lookupSids3 here, as clearly we must not
1912 * be on schannel, or we would not be able to do the
1915 torture_comment(tctx
, "Testing all accounts\n");
1916 for (i
=0;i
<sids1
.num_sids
;i
++) {
1917 ret
&= test_OpenAccount(b
, tctx
, handle
, sids1
.sids
[i
].sid
);
1918 ret
&= test_EnumAccountRights(b
, tctx
, handle
, sids1
.sids
[i
].sid
);
1920 torture_comment(tctx
, "\n");
1923 if (sids1
.num_sids
< 3) {
1927 torture_comment(tctx
, "Trying EnumAccounts partial listing (asking for 1 at 2)\n");
1929 r
.in
.num_entries
= 1;
1930 r
.out
.sids
= &sids2
;
1932 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccounts_r(b
, tctx
, &r
),
1933 "EnumAccounts failed");
1934 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
1935 "EnumAccounts failed");
1937 if (sids2
.num_sids
!= 1) {
1938 torture_comment(tctx
, "Returned wrong number of entries (%d)\n", sids2
.num_sids
);
1945 static bool test_LookupPrivDisplayName(struct dcerpc_binding_handle
*b
,
1946 struct torture_context
*tctx
,
1947 struct policy_handle
*handle
,
1948 struct lsa_String
*priv_name
)
1950 struct lsa_LookupPrivDisplayName r
;
1951 /* produce a reasonable range of language output without screwing up
1953 uint16_t language_id
= (random() % 4) + 0x409;
1954 uint16_t returned_language_id
= 0;
1955 struct lsa_StringLarge
*disp_name
= NULL
;
1957 torture_comment(tctx
, "\nTesting LookupPrivDisplayName(%s)\n", priv_name
->string
);
1959 r
.in
.handle
= handle
;
1960 r
.in
.name
= priv_name
;
1961 r
.in
.language_id
= language_id
;
1962 r
.in
.language_id_sys
= 0;
1963 r
.out
.returned_language_id
= &returned_language_id
;
1964 r
.out
.disp_name
= &disp_name
;
1966 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_LookupPrivDisplayName_r(b
, tctx
, &r
),
1967 "LookupPrivDisplayName failed");
1968 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1969 torture_comment(tctx
, "LookupPrivDisplayName failed - %s\n", nt_errstr(r
.out
.result
));
1972 torture_comment(tctx
, "%s -> \"%s\" (language 0x%x/0x%x)\n",
1973 priv_name
->string
, disp_name
->string
,
1974 r
.in
.language_id
, *r
.out
.returned_language_id
);
1979 static bool test_EnumAccountsWithUserRight(struct dcerpc_binding_handle
*b
,
1980 struct torture_context
*tctx
,
1981 struct policy_handle
*handle
,
1982 struct lsa_String
*priv_name
)
1984 struct lsa_EnumAccountsWithUserRight r
;
1985 struct lsa_SidArray sids
;
1989 torture_comment(tctx
, "\nTesting EnumAccountsWithUserRight(%s)\n", priv_name
->string
);
1991 r
.in
.handle
= handle
;
1992 r
.in
.name
= priv_name
;
1995 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountsWithUserRight_r(b
, tctx
, &r
),
1996 "EnumAccountsWithUserRight failed");
1998 /* NT_STATUS_NO_MORE_ENTRIES means noone has this privilege */
1999 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_NO_MORE_ENTRIES
)) {
2003 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2004 torture_comment(tctx
, "EnumAccountsWithUserRight failed - %s\n", nt_errstr(r
.out
.result
));
2012 static bool test_EnumPrivs(struct dcerpc_binding_handle
*b
,
2013 struct torture_context
*tctx
,
2014 struct policy_handle
*handle
)
2016 struct lsa_EnumPrivs r
;
2017 struct lsa_PrivArray privs1
;
2018 uint32_t resume_handle
= 0;
2022 torture_comment(tctx
, "\nTesting EnumPrivs\n");
2024 r
.in
.handle
= handle
;
2025 r
.in
.resume_handle
= &resume_handle
;
2026 r
.in
.max_count
= 100;
2027 r
.out
.resume_handle
= &resume_handle
;
2028 r
.out
.privs
= &privs1
;
2031 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumPrivs_r(b
, tctx
, &r
),
2032 "EnumPrivs failed");
2033 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
2034 "EnumPrivs failed");
2036 for (i
= 0; i
< privs1
.count
; i
++) {
2037 test_LookupPrivDisplayName(b
, tctx
, handle
, (struct lsa_String
*)&privs1
.privs
[i
].name
);
2038 test_LookupPrivValue(b
, tctx
, handle
, (struct lsa_String
*)&privs1
.privs
[i
].name
);
2039 if (!test_EnumAccountsWithUserRight(b
, tctx
, handle
, (struct lsa_String
*)&privs1
.privs
[i
].name
)) {
2047 static bool test_QueryForestTrustInformation(struct dcerpc_binding_handle
*b
,
2048 struct torture_context
*tctx
,
2049 struct policy_handle
*handle
,
2050 const char *trusted_domain_name
)
2053 struct lsa_lsaRQueryForestTrustInformation r
;
2054 struct lsa_String string
;
2055 struct lsa_ForestTrustInformation info
, *info_ptr
;
2057 torture_comment(tctx
, "\nTesting lsaRQueryForestTrustInformation\n");
2059 if (torture_setting_bool(tctx
, "samba4", false)) {
2060 torture_comment(tctx
, "skipping QueryForestTrustInformation against Samba4\n");
2064 ZERO_STRUCT(string
);
2066 if (trusted_domain_name
) {
2067 init_lsa_String(&string
, trusted_domain_name
);
2072 r
.in
.handle
= handle
;
2073 r
.in
.trusted_domain_name
= &string
;
2075 r
.out
.forest_trust_info
= &info_ptr
;
2077 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_lsaRQueryForestTrustInformation_r(b
, tctx
, &r
),
2078 "lsaRQueryForestTrustInformation failed");
2080 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2081 torture_comment(tctx
, "lsaRQueryForestTrustInformation of %s failed - %s\n", trusted_domain_name
, nt_errstr(r
.out
.result
));
2088 static bool test_query_each_TrustDomEx(struct dcerpc_binding_handle
*b
,
2089 struct torture_context
*tctx
,
2090 struct policy_handle
*handle
,
2091 struct lsa_DomainListEx
*domains
)
2096 for (i
=0; i
< domains
->count
; i
++) {
2098 if (domains
->domains
[i
].trust_attributes
& NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE
) {
2099 ret
&= test_QueryForestTrustInformation(b
, tctx
, handle
,
2100 domains
->domains
[i
].domain_name
.string
);
2107 static bool test_query_each_TrustDom(struct dcerpc_binding_handle
*b
,
2108 struct torture_context
*tctx
,
2109 struct policy_handle
*handle
,
2110 struct lsa_DomainList
*domains
)
2115 torture_comment(tctx
, "\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
2116 for (i
=0; i
< domains
->count
; i
++) {
2117 struct lsa_OpenTrustedDomain trust
;
2118 struct lsa_OpenTrustedDomainByName trust_by_name
;
2119 struct policy_handle trustdom_handle
;
2120 struct policy_handle handle2
;
2122 struct lsa_CloseTrustedDomainEx c_trust
;
2123 int levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
2124 int ok
[] = {1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1};
2126 if (domains
->domains
[i
].sid
) {
2127 trust
.in
.handle
= handle
;
2128 trust
.in
.sid
= domains
->domains
[i
].sid
;
2129 trust
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2130 trust
.out
.trustdom_handle
= &trustdom_handle
;
2132 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenTrustedDomain_r(b
, tctx
, &trust
),
2133 "OpenTrustedDomain failed");
2135 if (!NT_STATUS_IS_OK(trust
.out
.result
)) {
2136 torture_comment(tctx
, "OpenTrustedDomain failed - %s\n", nt_errstr(trust
.out
.result
));
2140 c
.in
.handle
= &trustdom_handle
;
2141 c
.out
.handle
= &handle2
;
2143 c_trust
.in
.handle
= &trustdom_handle
;
2144 c_trust
.out
.handle
= &handle2
;
2146 for (j
=0; j
< ARRAY_SIZE(levels
); j
++) {
2147 struct lsa_QueryTrustedDomainInfo q
;
2148 union lsa_TrustedDomainInfo
*info
= NULL
;
2149 q
.in
.trustdom_handle
= &trustdom_handle
;
2150 q
.in
.level
= levels
[j
];
2152 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QueryTrustedDomainInfo_r(b
, tctx
, &q
),
2153 "QueryTrustedDomainInfo failed");
2154 if (!NT_STATUS_IS_OK(q
.out
.result
) && ok
[j
]) {
2155 torture_comment(tctx
, "QueryTrustedDomainInfo level %d failed - %s\n",
2156 levels
[j
], nt_errstr(q
.out
.result
));
2158 } else if (NT_STATUS_IS_OK(q
.out
.result
) && !ok
[j
]) {
2159 torture_comment(tctx
, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
2160 levels
[j
], nt_errstr(q
.out
.result
));
2165 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_CloseTrustedDomainEx_r(b
, tctx
, &c_trust
),
2166 "CloseTrustedDomainEx failed");
2167 if (!NT_STATUS_EQUAL(c_trust
.out
.result
, NT_STATUS_NOT_IMPLEMENTED
)) {
2168 torture_comment(tctx
, "Expected CloseTrustedDomainEx to return NT_STATUS_NOT_IMPLEMENTED, instead - %s\n", nt_errstr(c_trust
.out
.result
));
2172 c
.in
.handle
= &trustdom_handle
;
2173 c
.out
.handle
= &handle2
;
2175 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_Close_r(b
, tctx
, &c
),
2177 if (!NT_STATUS_IS_OK(c
.out
.result
)) {
2178 torture_comment(tctx
, "Close of trusted domain failed - %s\n", nt_errstr(c
.out
.result
));
2182 for (j
=0; j
< ARRAY_SIZE(levels
); j
++) {
2183 struct lsa_QueryTrustedDomainInfoBySid q
;
2184 union lsa_TrustedDomainInfo
*info
= NULL
;
2186 if (!domains
->domains
[i
].sid
) {
2190 q
.in
.handle
= handle
;
2191 q
.in
.dom_sid
= domains
->domains
[i
].sid
;
2192 q
.in
.level
= levels
[j
];
2195 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QueryTrustedDomainInfoBySid_r(b
, tctx
, &q
),
2196 "lsa_QueryTrustedDomainInfoBySid failed");
2197 if (!NT_STATUS_IS_OK(q
.out
.result
) && ok
[j
]) {
2198 torture_comment(tctx
, "QueryTrustedDomainInfoBySid level %d failed - %s\n",
2199 levels
[j
], nt_errstr(q
.out
.result
));
2201 } else if (NT_STATUS_IS_OK(q
.out
.result
) && !ok
[j
]) {
2202 torture_comment(tctx
, "QueryTrustedDomainInfoBySid level %d unexpectedly succeeded - %s\n",
2203 levels
[j
], nt_errstr(q
.out
.result
));
2209 trust_by_name
.in
.handle
= handle
;
2210 trust_by_name
.in
.name
.string
= domains
->domains
[i
].name
.string
;
2211 trust_by_name
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2212 trust_by_name
.out
.trustdom_handle
= &trustdom_handle
;
2214 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenTrustedDomainByName_r(b
, tctx
, &trust_by_name
),
2215 "OpenTrustedDomainByName failed");
2217 if (!NT_STATUS_IS_OK(trust_by_name
.out
.result
)) {
2218 torture_comment(tctx
, "OpenTrustedDomainByName failed - %s\n", nt_errstr(trust_by_name
.out
.result
));
2222 for (j
=0; j
< ARRAY_SIZE(levels
); j
++) {
2223 struct lsa_QueryTrustedDomainInfo q
;
2224 union lsa_TrustedDomainInfo
*info
= NULL
;
2225 q
.in
.trustdom_handle
= &trustdom_handle
;
2226 q
.in
.level
= levels
[j
];
2228 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QueryTrustedDomainInfo_r(b
, tctx
, &q
),
2229 "QueryTrustedDomainInfo failed");
2230 if (!NT_STATUS_IS_OK(q
.out
.result
) && ok
[j
]) {
2231 torture_comment(tctx
, "QueryTrustedDomainInfo level %d failed - %s\n",
2232 levels
[j
], nt_errstr(q
.out
.result
));
2234 } else if (NT_STATUS_IS_OK(q
.out
.result
) && !ok
[j
]) {
2235 torture_comment(tctx
, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
2236 levels
[j
], nt_errstr(q
.out
.result
));
2241 c
.in
.handle
= &trustdom_handle
;
2242 c
.out
.handle
= &handle2
;
2244 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_Close_r(b
, tctx
, &c
),
2246 if (!NT_STATUS_IS_OK(c
.out
.result
)) {
2247 torture_comment(tctx
, "Close of trusted domain failed - %s\n", nt_errstr(c
.out
.result
));
2251 for (j
=0; j
< ARRAY_SIZE(levels
); j
++) {
2252 struct lsa_QueryTrustedDomainInfoByName q
;
2253 union lsa_TrustedDomainInfo
*info
= NULL
;
2254 struct lsa_String name
;
2256 name
.string
= domains
->domains
[i
].name
.string
;
2258 q
.in
.handle
= handle
;
2259 q
.in
.trusted_domain
= &name
;
2260 q
.in
.level
= levels
[j
];
2262 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QueryTrustedDomainInfoByName_r(b
, tctx
, &q
),
2263 "QueryTrustedDomainInfoByName failed");
2264 if (!NT_STATUS_IS_OK(q
.out
.result
) && ok
[j
]) {
2265 torture_comment(tctx
, "QueryTrustedDomainInfoByName level %d failed - %s\n",
2266 levels
[j
], nt_errstr(q
.out
.result
));
2268 } else if (NT_STATUS_IS_OK(q
.out
.result
) && !ok
[j
]) {
2269 torture_comment(tctx
, "QueryTrustedDomainInfoByName level %d unexpectedly succeeded - %s\n",
2270 levels
[j
], nt_errstr(q
.out
.result
));
2278 static bool test_EnumTrustDom(struct dcerpc_binding_handle
*b
,
2279 struct torture_context
*tctx
,
2280 struct policy_handle
*handle
)
2282 struct lsa_EnumTrustDom r
;
2283 uint32_t in_resume_handle
= 0;
2284 uint32_t out_resume_handle
;
2285 struct lsa_DomainList domains
;
2288 torture_comment(tctx
, "\nTesting EnumTrustDom\n");
2290 r
.in
.handle
= handle
;
2291 r
.in
.resume_handle
= &in_resume_handle
;
2293 r
.out
.domains
= &domains
;
2294 r
.out
.resume_handle
= &out_resume_handle
;
2296 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumTrustDom_r(b
, tctx
, &r
),
2297 "lsa_EnumTrustDom failed");
2299 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2300 * always be larger than the previous input resume handle, in
2301 * particular when hitting the last query it is vital to set the
2302 * resume handle correctly to avoid infinite client loops, as
2303 * seen e.g. with Windows XP SP3 when resume handle is 0 and
2304 * status is NT_STATUS_OK - gd */
2306 if (NT_STATUS_IS_OK(r
.out
.result
) ||
2307 NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_NO_MORE_ENTRIES
) ||
2308 NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
))
2310 if (out_resume_handle
<= in_resume_handle
) {
2311 torture_comment(tctx
, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2312 out_resume_handle
, in_resume_handle
);
2317 if (NT_STATUS_IS_OK(r
.out
.result
)) {
2318 if (domains
.count
== 0) {
2319 torture_comment(tctx
, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2322 } else if (!(NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
) || NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_NO_MORE_ENTRIES
))) {
2323 torture_comment(tctx
, "EnumTrustDom of zero size failed - %s\n", nt_errstr(r
.out
.result
));
2327 /* Start from the bottom again */
2328 in_resume_handle
= 0;
2331 r
.in
.handle
= handle
;
2332 r
.in
.resume_handle
= &in_resume_handle
;
2333 r
.in
.max_size
= LSA_ENUM_TRUST_DOMAIN_MULTIPLIER
* 3;
2334 r
.out
.domains
= &domains
;
2335 r
.out
.resume_handle
= &out_resume_handle
;
2337 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumTrustDom_r(b
, tctx
, &r
),
2338 "EnumTrustDom failed");
2340 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2341 * always be larger than the previous input resume handle, in
2342 * particular when hitting the last query it is vital to set the
2343 * resume handle correctly to avoid infinite client loops, as
2344 * seen e.g. with Windows XP SP3 when resume handle is 0 and
2345 * status is NT_STATUS_OK - gd */
2347 if (NT_STATUS_IS_OK(r
.out
.result
) ||
2348 NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_NO_MORE_ENTRIES
) ||
2349 NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
))
2351 if (out_resume_handle
<= in_resume_handle
) {
2352 torture_comment(tctx
, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2353 out_resume_handle
, in_resume_handle
);
2358 /* NO_MORE_ENTRIES is allowed */
2359 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_NO_MORE_ENTRIES
)) {
2360 if (domains
.count
== 0) {
2363 torture_comment(tctx
, "EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
2365 } else if (NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
)) {
2366 /* Windows 2003 gets this off by one on the first run */
2367 if (r
.out
.domains
->count
< 3 || r
.out
.domains
->count
> 4) {
2368 torture_comment(tctx
, "EnumTrustDom didn't fill the buffer we "
2369 "asked it to (got %d, expected %d / %d == %d entries)\n",
2370 r
.out
.domains
->count
, LSA_ENUM_TRUST_DOMAIN_MULTIPLIER
* 3,
2371 LSA_ENUM_TRUST_DOMAIN_MULTIPLIER
, r
.in
.max_size
);
2374 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2375 torture_comment(tctx
, "EnumTrustDom failed - %s\n", nt_errstr(r
.out
.result
));
2379 if (domains
.count
== 0) {
2380 torture_comment(tctx
, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2384 ret
&= test_query_each_TrustDom(b
, tctx
, handle
, &domains
);
2386 in_resume_handle
= out_resume_handle
;
2388 } while ((NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
)));
2393 static bool test_EnumTrustDomEx(struct dcerpc_binding_handle
*b
,
2394 struct torture_context
*tctx
,
2395 struct policy_handle
*handle
)
2397 struct lsa_EnumTrustedDomainsEx r_ex
;
2398 uint32_t resume_handle
= 0;
2399 struct lsa_DomainListEx domains_ex
;
2402 torture_comment(tctx
, "\nTesting EnumTrustedDomainsEx\n");
2404 r_ex
.in
.handle
= handle
;
2405 r_ex
.in
.resume_handle
= &resume_handle
;
2406 r_ex
.in
.max_size
= LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER
* 3;
2407 r_ex
.out
.domains
= &domains_ex
;
2408 r_ex
.out
.resume_handle
= &resume_handle
;
2410 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumTrustedDomainsEx_r(b
, tctx
, &r_ex
),
2411 "EnumTrustedDomainsEx failed");
2413 if (!(NT_STATUS_EQUAL(r_ex
.out
.result
, STATUS_MORE_ENTRIES
) || NT_STATUS_EQUAL(r_ex
.out
.result
, NT_STATUS_NO_MORE_ENTRIES
))) {
2414 torture_comment(tctx
, "EnumTrustedDomainEx of zero size failed - %s\n", nt_errstr(r_ex
.out
.result
));
2420 r_ex
.in
.handle
= handle
;
2421 r_ex
.in
.resume_handle
= &resume_handle
;
2422 r_ex
.in
.max_size
= LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER
* 3;
2423 r_ex
.out
.domains
= &domains_ex
;
2424 r_ex
.out
.resume_handle
= &resume_handle
;
2426 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumTrustedDomainsEx_r(b
, tctx
, &r_ex
),
2427 "EnumTrustedDomainsEx failed");
2429 /* NO_MORE_ENTRIES is allowed */
2430 if (NT_STATUS_EQUAL(r_ex
.out
.result
, NT_STATUS_NO_MORE_ENTRIES
)) {
2431 if (domains_ex
.count
== 0) {
2434 torture_comment(tctx
, "EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
2436 } else if (NT_STATUS_EQUAL(r_ex
.out
.result
, STATUS_MORE_ENTRIES
)) {
2437 /* Windows 2003 gets this off by one on the first run */
2438 if (r_ex
.out
.domains
->count
< 3 || r_ex
.out
.domains
->count
> 4) {
2439 torture_comment(tctx
, "EnumTrustDom didn't fill the buffer we "
2440 "asked it to (got %d, expected %d / %d == %d entries)\n",
2441 r_ex
.out
.domains
->count
,
2443 LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER
,
2444 r_ex
.in
.max_size
/ LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER
);
2446 } else if (!NT_STATUS_IS_OK(r_ex
.out
.result
)) {
2447 torture_comment(tctx
, "EnumTrustedDomainEx failed - %s\n", nt_errstr(r_ex
.out
.result
));
2451 if (domains_ex
.count
== 0) {
2452 torture_comment(tctx
, "EnumTrustDomainEx failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2456 ret
&= test_query_each_TrustDomEx(b
, tctx
, handle
, &domains_ex
);
2458 } while ((NT_STATUS_EQUAL(r_ex
.out
.result
, STATUS_MORE_ENTRIES
)));
2464 static bool test_CreateTrustedDomain(struct dcerpc_binding_handle
*b
,
2465 struct torture_context
*tctx
,
2466 struct policy_handle
*handle
,
2467 uint32_t num_trusts
)
2470 struct lsa_CreateTrustedDomain r
;
2471 struct lsa_DomainInfo trustinfo
;
2472 struct dom_sid
**domsid
;
2473 struct policy_handle
*trustdom_handle
;
2474 struct lsa_QueryTrustedDomainInfo q
;
2475 union lsa_TrustedDomainInfo
*info
= NULL
;
2478 torture_comment(tctx
, "\nTesting CreateTrustedDomain for %d domains\n", num_trusts
);
2480 if (!test_EnumTrustDom(b
, tctx
, handle
)) {
2484 if (!test_EnumTrustDomEx(b
, tctx
, handle
)) {
2488 domsid
= talloc_array(tctx
, struct dom_sid
*, num_trusts
);
2489 trustdom_handle
= talloc_array(tctx
, struct policy_handle
, num_trusts
);
2491 for (i
=0; i
< num_trusts
; i
++) {
2492 char *trust_name
= talloc_asprintf(tctx
, "torturedom%02d", i
);
2493 char *trust_sid
= talloc_asprintf(tctx
, "S-1-5-21-97398-379795-100%02d", i
);
2495 domsid
[i
] = dom_sid_parse_talloc(tctx
, trust_sid
);
2497 trustinfo
.sid
= domsid
[i
];
2498 init_lsa_String((struct lsa_String
*)&trustinfo
.name
, trust_name
);
2500 r
.in
.policy_handle
= handle
;
2501 r
.in
.info
= &trustinfo
;
2502 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2503 r
.out
.trustdom_handle
= &trustdom_handle
[i
];
2505 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_CreateTrustedDomain_r(b
, tctx
, &r
),
2506 "CreateTrustedDomain failed");
2507 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_OBJECT_NAME_COLLISION
)) {
2508 test_DeleteTrustedDomain(b
, tctx
, handle
, trustinfo
.name
);
2509 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_CreateTrustedDomain_r(b
, tctx
, &r
),
2510 "CreateTrustedDomain failed");
2512 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2513 torture_comment(tctx
, "CreateTrustedDomain failed - %s\n", nt_errstr(r
.out
.result
));
2517 q
.in
.trustdom_handle
= &trustdom_handle
[i
];
2518 q
.in
.level
= LSA_TRUSTED_DOMAIN_INFO_INFO_EX
;
2520 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QueryTrustedDomainInfo_r(b
, tctx
, &q
),
2521 "QueryTrustedDomainInfo failed");
2522 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
2523 torture_comment(tctx
, "QueryTrustedDomainInfo level %d failed - %s\n", q
.in
.level
, nt_errstr(q
.out
.result
));
2525 } else if (!q
.out
.info
) {
2528 if (strcmp(info
->info_ex
.netbios_name
.string
, trustinfo
.name
.string
) != 0) {
2529 torture_comment(tctx
, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
2530 info
->info_ex
.netbios_name
.string
, trustinfo
.name
.string
);
2533 if (info
->info_ex
.trust_type
!= LSA_TRUST_TYPE_DOWNLEVEL
) {
2534 torture_comment(tctx
, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
2535 trust_name
, info
->info_ex
.trust_type
, LSA_TRUST_TYPE_DOWNLEVEL
);
2538 if (info
->info_ex
.trust_attributes
!= 0) {
2539 torture_comment(tctx
, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
2540 trust_name
, info
->info_ex
.trust_attributes
, 0);
2543 if (info
->info_ex
.trust_direction
!= LSA_TRUST_DIRECTION_OUTBOUND
) {
2544 torture_comment(tctx
, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
2545 trust_name
, info
->info_ex
.trust_direction
, LSA_TRUST_DIRECTION_OUTBOUND
);
2552 /* now that we have some domains to look over, we can test the enum calls */
2553 if (!test_EnumTrustDom(b
, tctx
, handle
)) {
2557 if (!test_EnumTrustDomEx(b
, tctx
, handle
)) {
2561 for (i
=0; i
<num_trusts
; i
++) {
2562 if (!test_DeleteTrustedDomainBySid(b
, tctx
, handle
, domsid
[i
])) {
2570 static bool gen_authinfo_internal(TALLOC_CTX
*mem_ctx
, const char *password
,
2571 DATA_BLOB session_key
,
2572 struct lsa_TrustDomainInfoAuthInfoInternal
**_authinfo_internal
)
2574 struct lsa_TrustDomainInfoAuthInfoInternal
*authinfo_internal
;
2575 struct trustDomainPasswords auth_struct
;
2576 struct AuthenticationInformation
*auth_info_array
;
2577 size_t converted_size
;
2578 DATA_BLOB auth_blob
;
2579 enum ndr_err_code ndr_err
;
2581 authinfo_internal
= talloc_zero(mem_ctx
, struct lsa_TrustDomainInfoAuthInfoInternal
);
2582 if (authinfo_internal
== NULL
) {
2586 auth_info_array
= talloc_array(mem_ctx
,
2587 struct AuthenticationInformation
, 1);
2588 if (auth_info_array
== NULL
) {
2592 generate_random_buffer(auth_struct
.confounder
, sizeof(auth_struct
.confounder
));
2594 auth_info_array
[0].AuthType
= TRUST_AUTH_TYPE_CLEAR
;
2596 if (!convert_string_talloc(mem_ctx
, CH_UNIX
, CH_UTF16
, password
,
2598 &auth_info_array
[0].AuthInfo
.clear
.password
,
2603 auth_info_array
[0].AuthInfo
.clear
.size
= converted_size
;
2605 auth_struct
.outgoing
.count
= 1;
2606 auth_struct
.outgoing
.current
.count
= 1;
2607 auth_struct
.outgoing
.current
.array
= auth_info_array
;
2608 auth_struct
.outgoing
.previous
.count
= 0;
2609 auth_struct
.outgoing
.previous
.array
= NULL
;
2611 auth_struct
.incoming
.count
= 1;
2612 auth_struct
.incoming
.current
.count
= 1;
2613 auth_struct
.incoming
.current
.array
= auth_info_array
;
2614 auth_struct
.incoming
.previous
.count
= 0;
2615 auth_struct
.incoming
.previous
.array
= NULL
;
2618 ndr_err
= ndr_push_struct_blob(&auth_blob
, mem_ctx
, &auth_struct
,
2619 (ndr_push_flags_fn_t
)ndr_push_trustDomainPasswords
);
2620 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
2624 arcfour_crypt_blob(auth_blob
.data
, auth_blob
.length
, &session_key
);
2626 authinfo_internal
->auth_blob
.size
= auth_blob
.length
;
2627 authinfo_internal
->auth_blob
.data
= auth_blob
.data
;
2629 *_authinfo_internal
= authinfo_internal
;
2634 static bool gen_authinfo(TALLOC_CTX
*mem_ctx
, const char *password
,
2635 struct lsa_TrustDomainInfoAuthInfo
**_authinfo
)
2637 struct lsa_TrustDomainInfoAuthInfo
*authinfo
;
2638 struct lsa_TrustDomainInfoBuffer
*info_buffer
;
2639 size_t converted_size
;
2641 authinfo
= talloc_zero(mem_ctx
, struct lsa_TrustDomainInfoAuthInfo
);
2642 if (authinfo
== NULL
) {
2646 info_buffer
= talloc_zero(mem_ctx
, struct lsa_TrustDomainInfoBuffer
);
2647 if (info_buffer
== NULL
) {
2651 info_buffer
->AuthType
= TRUST_AUTH_TYPE_CLEAR
;
2653 if (!convert_string_talloc(mem_ctx
, CH_UNIX
, CH_UTF16
, password
,
2655 &info_buffer
->data
.data
,
2660 info_buffer
->data
.size
= converted_size
;
2662 authinfo
->incoming_count
= 1;
2663 authinfo
->incoming_current_auth_info
= info_buffer
;
2664 authinfo
->incoming_previous_auth_info
= NULL
;
2665 authinfo
->outgoing_count
= 1;
2666 authinfo
->outgoing_current_auth_info
= info_buffer
;
2667 authinfo
->outgoing_previous_auth_info
= NULL
;
2669 *_authinfo
= authinfo
;
2674 static bool check_pw_with_ServerAuthenticate3(struct dcerpc_pipe
*p
,
2675 struct torture_context
*tctx
,
2676 uint32_t negotiate_flags
,
2677 struct cli_credentials
*machine_credentials
,
2678 struct netlogon_creds_CredentialState
**creds_out
)
2680 struct netr_ServerReqChallenge r
;
2681 struct netr_ServerAuthenticate3 a
;
2682 struct netr_Credential credentials1
, credentials2
, credentials3
;
2683 struct netlogon_creds_CredentialState
*creds
;
2684 struct samr_Password mach_password
;
2686 const char *machine_name
;
2687 const char *plain_pass
;
2688 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2690 machine_name
= cli_credentials_get_workstation(machine_credentials
);
2691 plain_pass
= cli_credentials_get_password(machine_credentials
);
2693 r
.in
.server_name
= NULL
;
2694 r
.in
.computer_name
= machine_name
;
2695 r
.in
.credentials
= &credentials1
;
2696 r
.out
.return_credentials
= &credentials2
;
2698 generate_random_buffer(credentials1
.data
, sizeof(credentials1
.data
));
2700 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerReqChallenge_r(b
, tctx
, &r
),
2701 "ServerReqChallenge failed");
2702 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerReqChallenge failed");
2704 E_md4hash(plain_pass
, mach_password
.hash
);
2706 a
.in
.server_name
= NULL
;
2707 a
.in
.account_name
= talloc_asprintf(tctx
, "%s$", machine_name
);
2708 a
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(machine_credentials
);
2709 a
.in
.computer_name
= machine_name
;
2710 a
.in
.negotiate_flags
= &negotiate_flags
;
2711 a
.in
.credentials
= &credentials3
;
2712 a
.out
.return_credentials
= &credentials3
;
2713 a
.out
.negotiate_flags
= &negotiate_flags
;
2716 creds
= netlogon_creds_client_init(tctx
, a
.in
.account_name
,
2718 &credentials1
, &credentials2
,
2719 &mach_password
, &credentials3
,
2722 torture_assert(tctx
, creds
!= NULL
, "memory allocation");
2724 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerAuthenticate3_r(b
, tctx
, &a
),
2725 "ServerAuthenticate3 failed");
2726 if (!NT_STATUS_IS_OK(a
.out
.result
)) {
2727 if (!NT_STATUS_EQUAL(a
.out
.result
, NT_STATUS_ACCESS_DENIED
)) {
2728 torture_assert_ntstatus_ok(tctx
, a
.out
.result
,
2729 "ServerAuthenticate3 failed");
2733 torture_assert(tctx
, netlogon_creds_client_check(creds
, &credentials3
), "Credential chaining failed");
2735 /* Prove that requesting a challenge again won't break it */
2736 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerReqChallenge_r(b
, tctx
, &r
),
2737 "ServerReqChallenge failed");
2738 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerReqChallenge failed");
2744 static bool check_dom_trust_pw(struct dcerpc_pipe
*p
,
2745 struct torture_context
*tctx
,
2746 const char *trusted_dom_name
,
2747 const char *password
)
2749 struct cli_credentials
*credentials
;
2751 struct netlogon_creds_CredentialState
*creds
;
2752 struct dcerpc_pipe
*pipe
;
2756 credentials
= cli_credentials_init(tctx
);
2757 if (credentials
== NULL
) {
2761 dummy
= talloc_asprintf(tctx
, "%s$", trusted_dom_name
);
2762 if (dummy
== NULL
) {
2766 cli_credentials_set_username(credentials
, dummy
, CRED_SPECIFIED
);
2767 cli_credentials_set_password(credentials
, password
, CRED_SPECIFIED
);
2768 cli_credentials_set_workstation(credentials
,
2769 trusted_dom_name
, CRED_SPECIFIED
);
2770 cli_credentials_set_secure_channel_type(credentials
, SEC_CHAN_DOMAIN
);
2772 status
= dcerpc_pipe_connect_b(tctx
, &pipe
, p
->binding
,
2773 &ndr_table_netlogon
,
2774 cli_credentials_init_anon(tctx
),
2775 tctx
->ev
, tctx
->lp_ctx
);
2776 if (!NT_STATUS_IS_OK(status
)) {
2777 torture_comment(tctx
, "dcerpc_pipe_connect_b failed.\n");
2781 ok
= check_pw_with_ServerAuthenticate3(pipe
, tctx
,
2782 NETLOGON_NEG_AUTH2_ADS_FLAGS
,
2783 credentials
, &creds
);
2789 static bool test_CreateTrustedDomainEx_common(struct dcerpc_pipe
*p
,
2790 struct torture_context
*tctx
,
2791 struct policy_handle
*handle
,
2792 uint32_t num_trusts
,
2797 struct lsa_CreateTrustedDomainEx r
;
2798 struct lsa_CreateTrustedDomainEx2 r2
;
2799 struct lsa_TrustDomainInfoInfoEx trustinfo
;
2800 struct lsa_TrustDomainInfoAuthInfoInternal
*authinfo_internal
;
2801 struct lsa_TrustDomainInfoAuthInfo
*authinfo
;
2802 struct dom_sid
**domsid
;
2803 struct policy_handle
*trustdom_handle
;
2804 struct lsa_QueryTrustedDomainInfo q
;
2805 union lsa_TrustedDomainInfo
*info
= NULL
;
2806 DATA_BLOB session_key
;
2808 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2811 torture_comment(tctx
, "\nTesting CreateTrustedDomainEx2 for %d domains\n", num_trusts
);
2813 torture_comment(tctx
, "\nTesting CreateTrustedDomainEx for %d domains\n", num_trusts
);
2816 domsid
= talloc_array(tctx
, struct dom_sid
*, num_trusts
);
2817 trustdom_handle
= talloc_array(tctx
, struct policy_handle
, num_trusts
);
2819 status
= dcerpc_fetch_session_key(p
, &session_key
);
2820 if (!NT_STATUS_IS_OK(status
)) {
2821 torture_comment(tctx
, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status
));
2825 for (i
=0; i
< num_trusts
; i
++) {
2826 char *trust_name
= talloc_asprintf(tctx
, "torturedom%02d", i
);
2827 char *trust_name_dns
= talloc_asprintf(tctx
, "torturedom%02d.samba.example.com", i
);
2828 char *trust_sid
= talloc_asprintf(tctx
, "S-1-5-21-97398-379795-100%02d", i
);
2830 domsid
[i
] = dom_sid_parse_talloc(tctx
, trust_sid
);
2832 trustinfo
.sid
= domsid
[i
];
2833 trustinfo
.netbios_name
.string
= trust_name
;
2834 trustinfo
.domain_name
.string
= trust_name_dns
;
2836 /* Create inbound, some outbound, and some
2837 * bi-directional trusts in a repeating pattern based
2840 /* 1 == inbound, 2 == outbound, 3 == both */
2841 trustinfo
.trust_direction
= (i
% 3) + 1;
2843 /* Try different trust types too */
2845 /* 1 == downlevel (NT4), 2 == uplevel (ADS), 3 == MIT (kerberos but not AD) */
2846 trustinfo
.trust_type
= (((i
/ 3) + 1) % 3) + 1;
2848 trustinfo
.trust_attributes
= LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION
;
2850 if (!gen_authinfo_internal(tctx
, TRUSTPW
, session_key
, &authinfo_internal
)) {
2851 torture_comment(tctx
, "gen_authinfo_internal failed");
2855 if (!gen_authinfo(tctx
, TRUSTPW
, &authinfo
)) {
2856 torture_comment(tctx
, "gen_authinfonfo failed");
2862 r2
.in
.policy_handle
= handle
;
2863 r2
.in
.info
= &trustinfo
;
2864 r2
.in
.auth_info_internal
= authinfo_internal
;
2865 r2
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2866 r2
.out
.trustdom_handle
= &trustdom_handle
[i
];
2868 torture_assert_ntstatus_ok(tctx
,
2869 dcerpc_lsa_CreateTrustedDomainEx2_r(b
, tctx
, &r2
),
2870 "CreateTrustedDomainEx2 failed");
2872 status
= r2
.out
.result
;
2875 r
.in
.policy_handle
= handle
;
2876 r
.in
.info
= &trustinfo
;
2877 r
.in
.auth_info
= authinfo
;
2878 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2879 r
.out
.trustdom_handle
= &trustdom_handle
[i
];
2881 torture_assert_ntstatus_ok(tctx
,
2882 dcerpc_lsa_CreateTrustedDomainEx_r(b
, tctx
, &r
),
2883 "CreateTrustedDomainEx failed");
2885 status
= r
.out
.result
;
2888 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_COLLISION
)) {
2889 test_DeleteTrustedDomain(b
, tctx
, handle
, trustinfo
.netbios_name
);
2891 torture_assert_ntstatus_ok(tctx
,
2892 dcerpc_lsa_CreateTrustedDomainEx2_r(b
, tctx
, &r2
),
2893 "CreateTrustedDomainEx2 failed");
2894 status
= r2
.out
.result
;
2896 torture_assert_ntstatus_ok(tctx
,
2897 dcerpc_lsa_CreateTrustedDomainEx_r(b
, tctx
, &r
),
2898 "CreateTrustedDomainEx2 failed");
2899 status
= r
.out
.result
;
2902 if (!NT_STATUS_IS_OK(status
)) {
2903 torture_comment(tctx
, "CreateTrustedDomainEx failed2 - %s\n", nt_errstr(status
));
2906 /* For outbound and MIT trusts there is no trust account */
2907 if (trustinfo
.trust_direction
!= 2 &&
2908 trustinfo
.trust_type
!= 3) {
2910 if (torture_setting_bool(tctx
, "samba3", false) ||
2911 torture_setting_bool(tctx
, "samba4", false)) {
2912 torture_comment(tctx
, "skipping trusted domain auth tests against samba");
2914 if (check_dom_trust_pw(p
, tctx
, trust_name
,
2916 torture_comment(tctx
, "Password check passed unexpectedly\n");
2919 if (!check_dom_trust_pw(p
, tctx
, trust_name
,
2921 torture_comment(tctx
, "Password check failed\n");
2927 q
.in
.trustdom_handle
= &trustdom_handle
[i
];
2928 q
.in
.level
= LSA_TRUSTED_DOMAIN_INFO_INFO_EX
;
2930 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QueryTrustedDomainInfo_r(b
, tctx
, &q
),
2931 "QueryTrustedDomainInfo failed");
2932 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
2933 torture_comment(tctx
, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(q
.out
.result
));
2935 } else if (!q
.out
.info
) {
2936 torture_comment(tctx
, "QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
2939 if (strcmp(info
->info_ex
.netbios_name
.string
, trustinfo
.netbios_name
.string
) != 0) {
2940 torture_comment(tctx
, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
2941 info
->info_ex
.netbios_name
.string
, trustinfo
.netbios_name
.string
);
2944 if (info
->info_ex
.trust_type
!= trustinfo
.trust_type
) {
2945 torture_comment(tctx
, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
2946 trust_name
, info
->info_ex
.trust_type
, trustinfo
.trust_type
);
2949 if (info
->info_ex
.trust_attributes
!= LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION
) {
2950 torture_comment(tctx
, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
2951 trust_name
, info
->info_ex
.trust_attributes
, LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION
);
2954 if (info
->info_ex
.trust_direction
!= trustinfo
.trust_direction
) {
2955 torture_comment(tctx
, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
2956 trust_name
, info
->info_ex
.trust_direction
, trustinfo
.trust_direction
);
2963 /* now that we have some domains to look over, we can test the enum calls */
2964 if (!test_EnumTrustDom(b
, tctx
, handle
)) {
2965 torture_comment(tctx
, "test_EnumTrustDom failed\n");
2969 if (!test_EnumTrustDomEx(b
, tctx
, handle
)) {
2970 torture_comment(tctx
, "test_EnumTrustDomEx failed\n");
2974 for (i
=0; i
<num_trusts
; i
++) {
2975 if (!test_DeleteTrustedDomainBySid(b
, tctx
, handle
, domsid
[i
])) {
2976 torture_comment(tctx
, "test_DeleteTrustedDomainBySid failed\n");
2984 static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe
*p
,
2985 struct torture_context
*tctx
,
2986 struct policy_handle
*handle
,
2987 uint32_t num_trusts
)
2989 return test_CreateTrustedDomainEx_common(p
, tctx
, handle
, num_trusts
, true);
2992 static bool test_CreateTrustedDomainEx(struct dcerpc_pipe
*p
,
2993 struct torture_context
*tctx
,
2994 struct policy_handle
*handle
,
2995 uint32_t num_trusts
)
2997 return test_CreateTrustedDomainEx_common(p
, tctx
, handle
, num_trusts
, false);
3000 static bool test_QueryDomainInfoPolicy(struct dcerpc_binding_handle
*b
,
3001 struct torture_context
*tctx
,
3002 struct policy_handle
*handle
)
3004 struct lsa_QueryDomainInformationPolicy r
;
3005 union lsa_DomainInformationPolicy
*info
= NULL
;
3009 if (torture_setting_bool(tctx
, "samba3", false)) {
3010 torture_skip(tctx
, "skipping QueryDomainInformationPolicy test\n");
3013 torture_comment(tctx
, "\nTesting QueryDomainInformationPolicy\n");
3016 r
.in
.handle
= handle
;
3020 torture_comment(tctx
, "\nTrying QueryDomainInformationPolicy level %d\n", i
);
3022 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QueryDomainInformationPolicy_r(b
, tctx
, &r
),
3023 "QueryDomainInformationPolicy failed");
3025 /* If the server does not support EFS, then this is the correct return */
3026 if (i
== LSA_DOMAIN_INFO_POLICY_EFS
&& NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
3028 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
3029 torture_comment(tctx
, "QueryDomainInformationPolicy failed - %s\n", nt_errstr(r
.out
.result
));
3039 static bool test_QueryInfoPolicyCalls( bool version2
,
3040 struct dcerpc_binding_handle
*b
,
3041 struct torture_context
*tctx
,
3042 struct policy_handle
*handle
)
3044 struct lsa_QueryInfoPolicy r
;
3045 union lsa_PolicyInformation
*info
= NULL
;
3048 const char *call
= talloc_asprintf(tctx
, "QueryInfoPolicy%s", version2
? "2":"");
3050 torture_comment(tctx
, "\nTesting %s\n", call
);
3052 if (version2
&& torture_setting_bool(tctx
, "samba3", false)) {
3053 torture_skip(tctx
, "skipping QueryInfoPolicy2 tests\n");
3056 for (i
=1;i
<=14;i
++) {
3057 r
.in
.handle
= handle
;
3061 torture_comment(tctx
, "\nTrying %s level %d\n", call
, i
);
3064 /* We can perform the cast, because both types are
3065 structurally equal */
3066 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QueryInfoPolicy2_r(b
, tctx
,
3067 (struct lsa_QueryInfoPolicy2
*) &r
),
3068 "QueryInfoPolicy2 failed");
3070 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QueryInfoPolicy_r(b
, tctx
, &r
),
3071 "QueryInfoPolicy2 failed");
3074 case LSA_POLICY_INFO_MOD
:
3075 case LSA_POLICY_INFO_AUDIT_FULL_SET
:
3076 case LSA_POLICY_INFO_AUDIT_FULL_QUERY
:
3077 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
3078 torture_comment(tctx
, "Server should have failed level %u: %s\n", i
, nt_errstr(r
.out
.result
));
3082 case LSA_POLICY_INFO_DOMAIN
:
3083 case LSA_POLICY_INFO_ACCOUNT_DOMAIN
:
3084 case LSA_POLICY_INFO_REPLICA
:
3085 case LSA_POLICY_INFO_QUOTA
:
3086 case LSA_POLICY_INFO_ROLE
:
3087 case LSA_POLICY_INFO_AUDIT_LOG
:
3088 case LSA_POLICY_INFO_AUDIT_EVENTS
:
3089 case LSA_POLICY_INFO_PD
:
3090 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
3091 torture_comment(tctx
, "%s failed - %s\n", call
, nt_errstr(r
.out
.result
));
3095 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN
:
3096 case LSA_POLICY_INFO_DNS_INT
:
3097 case LSA_POLICY_INFO_DNS
:
3098 if (torture_setting_bool(tctx
, "samba3", false)) {
3099 /* Other levels not implemented yet */
3100 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_INFO_CLASS
)) {
3101 torture_comment(tctx
, "%s failed - %s\n", call
, nt_errstr(r
.out
.result
));
3104 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
3105 torture_comment(tctx
, "%s failed - %s\n", call
, nt_errstr(r
.out
.result
));
3110 if (torture_setting_bool(tctx
, "samba4", false)) {
3111 /* Other levels not implemented yet */
3112 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_INFO_CLASS
)) {
3113 torture_comment(tctx
, "%s failed - %s\n", call
, nt_errstr(r
.out
.result
));
3116 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
3117 torture_comment(tctx
, "%s failed - %s\n", call
, nt_errstr(r
.out
.result
));
3123 if (NT_STATUS_IS_OK(r
.out
.result
) && (i
== LSA_POLICY_INFO_DNS
3124 || i
== LSA_POLICY_INFO_DNS_INT
)) {
3125 /* Let's look up some of these names */
3127 struct lsa_TransNameArray tnames
;
3129 tnames
.names
= talloc_zero_array(tctx
, struct lsa_TranslatedName
, tnames
.count
);
3130 tnames
.names
[0].name
.string
= info
->dns
.name
.string
;
3131 tnames
.names
[0].sid_type
= SID_NAME_DOMAIN
;
3132 tnames
.names
[1].name
.string
= info
->dns
.dns_domain
.string
;
3133 tnames
.names
[1].sid_type
= SID_NAME_DOMAIN
;
3134 tnames
.names
[2].name
.string
= talloc_asprintf(tctx
, "%s\\", info
->dns
.name
.string
);
3135 tnames
.names
[2].sid_type
= SID_NAME_DOMAIN
;
3136 tnames
.names
[3].name
.string
= talloc_asprintf(tctx
, "%s\\", info
->dns
.dns_domain
.string
);
3137 tnames
.names
[3].sid_type
= SID_NAME_DOMAIN
;
3138 tnames
.names
[4].name
.string
= talloc_asprintf(tctx
, "%s\\guest", info
->dns
.name
.string
);
3139 tnames
.names
[4].sid_type
= SID_NAME_USER
;
3140 tnames
.names
[5].name
.string
= talloc_asprintf(tctx
, "%s\\krbtgt", info
->dns
.name
.string
);
3141 tnames
.names
[5].sid_type
= SID_NAME_USER
;
3142 tnames
.names
[6].name
.string
= talloc_asprintf(tctx
, "%s\\guest", info
->dns
.dns_domain
.string
);
3143 tnames
.names
[6].sid_type
= SID_NAME_USER
;
3144 tnames
.names
[7].name
.string
= talloc_asprintf(tctx
, "%s\\krbtgt", info
->dns
.dns_domain
.string
);
3145 tnames
.names
[7].sid_type
= SID_NAME_USER
;
3146 tnames
.names
[8].name
.string
= talloc_asprintf(tctx
, "krbtgt@%s", info
->dns
.name
.string
);
3147 tnames
.names
[8].sid_type
= SID_NAME_USER
;
3148 tnames
.names
[9].name
.string
= talloc_asprintf(tctx
, "krbtgt@%s", info
->dns
.dns_domain
.string
);
3149 tnames
.names
[9].sid_type
= SID_NAME_USER
;
3150 tnames
.names
[10].name
.string
= talloc_asprintf(tctx
, "%s\\"TEST_MACHINENAME
"$", info
->dns
.name
.string
);
3151 tnames
.names
[10].sid_type
= SID_NAME_USER
;
3152 tnames
.names
[11].name
.string
= talloc_asprintf(tctx
, "%s\\"TEST_MACHINENAME
"$", info
->dns
.dns_domain
.string
);
3153 tnames
.names
[11].sid_type
= SID_NAME_USER
;
3154 tnames
.names
[12].name
.string
= talloc_asprintf(tctx
, TEST_MACHINENAME
"$@%s", info
->dns
.name
.string
);
3155 tnames
.names
[12].sid_type
= SID_NAME_USER
;
3156 tnames
.names
[13].name
.string
= talloc_asprintf(tctx
, TEST_MACHINENAME
"$@%s", info
->dns
.dns_domain
.string
);
3157 tnames
.names
[13].sid_type
= SID_NAME_USER
;
3158 ret
&= test_LookupNames(b
, tctx
, handle
, &tnames
);
3166 static bool test_QueryInfoPolicy(struct dcerpc_binding_handle
*b
,
3167 struct torture_context
*tctx
,
3168 struct policy_handle
*handle
)
3170 return test_QueryInfoPolicyCalls(false, b
, tctx
, handle
);
3173 static bool test_QueryInfoPolicy2(struct dcerpc_binding_handle
*b
,
3174 struct torture_context
*tctx
,
3175 struct policy_handle
*handle
)
3177 return test_QueryInfoPolicyCalls(true, b
, tctx
, handle
);
3180 static bool test_GetUserName(struct dcerpc_binding_handle
*b
,
3181 struct torture_context
*tctx
)
3183 struct lsa_GetUserName r
;
3185 struct lsa_String
*authority_name_p
= NULL
;
3186 struct lsa_String
*account_name_p
= NULL
;
3188 torture_comment(tctx
, "\nTesting GetUserName\n");
3190 r
.in
.system_name
= "\\";
3191 r
.in
.account_name
= &account_name_p
;
3192 r
.in
.authority_name
= NULL
;
3193 r
.out
.account_name
= &account_name_p
;
3195 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_GetUserName_r(b
, tctx
, &r
),
3196 "GetUserName failed");
3198 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
3199 torture_comment(tctx
, "GetUserName failed - %s\n", nt_errstr(r
.out
.result
));
3203 account_name_p
= NULL
;
3204 r
.in
.account_name
= &account_name_p
;
3205 r
.in
.authority_name
= &authority_name_p
;
3206 r
.out
.account_name
= &account_name_p
;
3208 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_GetUserName_r(b
, tctx
, &r
),
3209 "GetUserName failed");
3211 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
3212 torture_comment(tctx
, "GetUserName failed - %s\n", nt_errstr(r
.out
.result
));
3219 static bool test_GetUserName_fail(struct dcerpc_binding_handle
*b
,
3220 struct torture_context
*tctx
)
3222 struct lsa_GetUserName r
;
3223 struct lsa_String
*account_name_p
= NULL
;
3226 torture_comment(tctx
, "\nTesting GetUserName_fail\n");
3228 r
.in
.system_name
= "\\";
3229 r
.in
.account_name
= &account_name_p
;
3230 r
.in
.authority_name
= NULL
;
3231 r
.out
.account_name
= &account_name_p
;
3233 status
= dcerpc_lsa_GetUserName_r(b
, tctx
, &r
);
3234 if (!NT_STATUS_IS_OK(status
)) {
3235 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
3236 torture_comment(tctx
,
3237 "GetUserName correctly returned with "
3243 torture_assert_ntstatus_equal(tctx
,
3245 NT_STATUS_ACCESS_DENIED
,
3246 "GetUserName return value should "
3247 "be ACCESS_DENIED");
3251 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
3252 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
) ||
3253 NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED
)) {
3254 torture_comment(tctx
,
3255 "GetUserName correctly returned with "
3257 nt_errstr(r
.out
.result
));
3262 torture_assert_ntstatus_equal(tctx
,
3265 "GetUserName return value should be "
3271 bool test_lsa_Close(struct dcerpc_binding_handle
*b
,
3272 struct torture_context
*tctx
,
3273 struct policy_handle
*handle
)
3276 struct policy_handle handle2
;
3278 torture_comment(tctx
, "\nTesting Close\n");
3280 r
.in
.handle
= handle
;
3281 r
.out
.handle
= &handle2
;
3283 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_Close_r(b
, tctx
, &r
),
3285 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
3288 torture_assert_ntstatus_equal(tctx
, dcerpc_lsa_Close_r(b
, tctx
, &r
),
3289 NT_STATUS_RPC_SS_CONTEXT_MISMATCH
, "Close should failed");
3291 torture_comment(tctx
, "\n");
3296 bool torture_rpc_lsa(struct torture_context
*tctx
)
3299 struct dcerpc_pipe
*p
;
3301 struct policy_handle
*handle
= NULL
;
3302 struct test_join
*join
= NULL
;
3303 struct cli_credentials
*machine_creds
;
3304 struct dcerpc_binding_handle
*b
;
3306 status
= torture_rpc_connection(tctx
, &p
, &ndr_table_lsarpc
);
3307 if (!NT_STATUS_IS_OK(status
)) {
3310 b
= p
->binding_handle
;
3312 /* Test lsaLookupSids3 and lsaLookupNames4 over tcpip */
3313 if (p
->binding
->transport
== NCACN_IP_TCP
) {
3314 if (!test_OpenPolicy_fail(b
, tctx
)) {
3318 if (!test_OpenPolicy2_fail(b
, tctx
)) {
3322 if (!test_many_LookupSids(p
, tctx
, handle
)) {
3329 if (!test_OpenPolicy(b
, tctx
)) {
3333 if (!test_lsa_OpenPolicy2(b
, tctx
, &handle
)) {
3338 join
= torture_join_domain(tctx
, TEST_MACHINENAME
, ACB_WSTRUST
, &machine_creds
);
3343 if (!test_LookupSids_async(b
, tctx
, handle
)) {
3347 if (!test_QueryDomainInfoPolicy(b
, tctx
, handle
)) {
3351 if (!test_CreateSecret(p
, tctx
, handle
)) {
3355 if (!test_QueryInfoPolicy(b
, tctx
, handle
)) {
3359 if (!test_QueryInfoPolicy2(b
, tctx
, handle
)) {
3363 if (!test_Delete(b
, tctx
, handle
)) {
3367 if (!test_many_LookupSids(p
, tctx
, handle
)) {
3371 if (!test_lsa_Close(b
, tctx
, handle
)) {
3375 torture_leave_domain(tctx
, join
);
3378 if (!test_many_LookupSids(p
, tctx
, handle
)) {
3383 if (!test_GetUserName(b
, tctx
)) {
3390 bool torture_rpc_lsa_get_user(struct torture_context
*tctx
)
3393 struct dcerpc_pipe
*p
;
3395 struct dcerpc_binding_handle
*b
;
3397 status
= torture_rpc_connection(tctx
, &p
, &ndr_table_lsarpc
);
3398 if (!NT_STATUS_IS_OK(status
)) {
3401 b
= p
->binding_handle
;
3403 if (p
->binding
->transport
== NCACN_IP_TCP
) {
3404 if (!test_GetUserName_fail(b
, tctx
)) {
3410 if (!test_GetUserName(b
, tctx
)) {
3417 static bool testcase_LookupNames(struct torture_context
*tctx
,
3418 struct dcerpc_pipe
*p
)
3421 struct policy_handle
*handle
;
3422 struct lsa_TransNameArray tnames
;
3423 struct lsa_TransNameArray2 tnames2
;
3424 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3426 if (p
->binding
->transport
!= NCACN_NP
&&
3427 p
->binding
->transport
!= NCALRPC
) {
3428 torture_comment(tctx
, "testcase_LookupNames is only available "
3429 "over NCACN_NP or NCALRPC");
3433 if (!test_OpenPolicy(b
, tctx
)) {
3437 if (!test_lsa_OpenPolicy2(b
, tctx
, &handle
)) {
3446 tnames
.names
= talloc_array(tctx
, struct lsa_TranslatedName
, tnames
.count
);
3447 ZERO_STRUCT(tnames
.names
[0]);
3448 tnames
.names
[0].name
.string
= "BUILTIN";
3449 tnames
.names
[0].sid_type
= SID_NAME_DOMAIN
;
3451 if (!test_LookupNames(b
, tctx
, handle
, &tnames
)) {
3456 tnames2
.names
= talloc_array(tctx
, struct lsa_TranslatedName2
, tnames2
.count
);
3457 ZERO_STRUCT(tnames2
.names
[0]);
3458 tnames2
.names
[0].name
.string
= "BUILTIN";
3459 tnames2
.names
[0].sid_type
= SID_NAME_DOMAIN
;
3461 if (!test_LookupNames2(b
, tctx
, handle
, &tnames2
, true)) {
3465 if (!test_LookupNames3(b
, tctx
, handle
, &tnames2
, true)) {
3469 if (!test_LookupNames_wellknown(b
, tctx
, handle
)) {
3473 if (!test_LookupNames_NULL(b
, tctx
, handle
)) {
3477 if (!test_LookupNames_bogus(b
, tctx
, handle
)) {
3481 if (!test_lsa_Close(b
, tctx
, handle
)) {
3488 struct torture_suite
*torture_rpc_lsa_lookup_names(TALLOC_CTX
*mem_ctx
)
3490 struct torture_suite
*suite
;
3491 struct torture_rpc_tcase
*tcase
;
3493 suite
= torture_suite_create(mem_ctx
, "lsa.lookupnames");
3495 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "lsa",
3497 torture_rpc_tcase_add_test(tcase
, "LookupNames",
3498 testcase_LookupNames
);
3503 struct lsa_trustdom_state
{
3504 uint32_t num_trusts
;
3507 static bool testcase_TrustedDomains(struct torture_context
*tctx
,
3508 struct dcerpc_pipe
*p
,
3512 struct policy_handle
*handle
;
3513 struct lsa_trustdom_state
*state
=
3514 talloc_get_type_abort(data
, struct lsa_trustdom_state
);
3515 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3517 if (p
->binding
->transport
!= NCACN_NP
&&
3518 p
->binding
->transport
!= NCALRPC
) {
3519 torture_comment(tctx
, "testcase_TrustedDomains is only available "
3520 "over NCACN_NP or NCALRPC");
3524 torture_comment(tctx
, "Testing %d domains\n", state
->num_trusts
);
3526 if (!test_OpenPolicy(b
, tctx
)) {
3530 if (!test_lsa_OpenPolicy2(b
, tctx
, &handle
)) {
3538 if (!test_CreateTrustedDomain(b
, tctx
, handle
, state
->num_trusts
)) {
3542 if (!test_CreateTrustedDomainEx(p
, tctx
, handle
, state
->num_trusts
)) {
3546 if (!test_CreateTrustedDomainEx2(p
, tctx
, handle
, state
->num_trusts
)) {
3550 if (!test_lsa_Close(b
, tctx
, handle
)) {
3557 struct torture_suite
*torture_rpc_lsa_trusted_domains(TALLOC_CTX
*mem_ctx
)
3559 struct torture_suite
*suite
;
3560 struct torture_rpc_tcase
*tcase
;
3561 struct lsa_trustdom_state
*state
;
3563 state
= talloc(mem_ctx
, struct lsa_trustdom_state
);
3565 state
->num_trusts
= 12;
3567 suite
= torture_suite_create(mem_ctx
, "lsa.trusted.domains");
3569 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "lsa",
3571 torture_rpc_tcase_add_test_ex(tcase
, "TrustedDomains",
3572 testcase_TrustedDomains
,
3578 static bool testcase_Privileges(struct torture_context
*tctx
,
3579 struct dcerpc_pipe
*p
)
3581 struct policy_handle
*handle
;
3582 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3584 if (p
->binding
->transport
!= NCACN_NP
&&
3585 p
->binding
->transport
!= NCALRPC
) {
3586 torture_skip(tctx
, "testcase_Privileges is only available "
3587 "over NCACN_NP or NCALRPC");
3590 if (!test_OpenPolicy(b
, tctx
)) {
3594 if (!test_lsa_OpenPolicy2(b
, tctx
, &handle
)) {
3602 if (!test_CreateAccount(b
, tctx
, handle
)) {
3606 if (!test_EnumAccounts(b
, tctx
, handle
)) {
3610 if (!test_EnumPrivs(b
, tctx
, handle
)) {
3614 if (!test_lsa_Close(b
, tctx
, handle
)) {
3622 struct torture_suite
*torture_rpc_lsa_privileges(TALLOC_CTX
*mem_ctx
)
3624 struct torture_suite
*suite
;
3625 struct torture_rpc_tcase
*tcase
;
3627 suite
= torture_suite_create(mem_ctx
, "lsa.privileges");
3629 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "lsa",
3631 torture_rpc_tcase_add_test(tcase
, "Privileges",
3632 testcase_Privileges
);