s4: allow python code to dump NTACL object as well
[Samba/ekacnet.git] / source4 / torture / rpc / lsa_lookup.c
blob5f80117a682cf1041f211ca95ed6b0dae1158c50
1 /*
2 Unix SMB/CIFS implementation.
3 test suite for lsa rpc lookup operations
5 Copyright (C) Volker Lendecke 2006
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "torture/rpc/rpc.h"
23 #include "librpc/gen_ndr/ndr_lsa_c.h"
24 #include "libcli/security/security.h"
26 static bool open_policy(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *p,
27 struct policy_handle **handle)
29 struct lsa_ObjectAttribute attr;
30 struct lsa_QosInfo qos;
31 struct lsa_OpenPolicy2 r;
32 NTSTATUS status;
34 *handle = talloc(mem_ctx, struct policy_handle);
35 if (!*handle) {
36 return false;
39 qos.len = 0;
40 qos.impersonation_level = 2;
41 qos.context_mode = 1;
42 qos.effective_only = 0;
44 attr.len = 0;
45 attr.root_dir = NULL;
46 attr.object_name = NULL;
47 attr.attributes = 0;
48 attr.sec_desc = NULL;
49 attr.sec_qos = &qos;
51 r.in.system_name = "\\";
52 r.in.attr = &attr;
53 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
54 r.out.handle = *handle;
56 status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &r);
58 return NT_STATUS_IS_OK(status);
61 static bool get_domainsid(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *p,
62 struct policy_handle *handle,
63 struct dom_sid **sid)
65 struct lsa_QueryInfoPolicy r;
66 union lsa_PolicyInformation *info = NULL;
67 NTSTATUS status;
69 r.in.level = LSA_POLICY_INFO_DOMAIN;
70 r.in.handle = handle;
71 r.out.info = &info;
73 status = dcerpc_lsa_QueryInfoPolicy(p, mem_ctx, &r);
74 if (!NT_STATUS_IS_OK(status)) return false;
76 *sid = info->domain.sid;
77 return true;
80 static NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, uint16_t level,
81 struct dcerpc_pipe *p,
82 struct policy_handle *handle,
83 struct dom_sid **sids, uint32_t num_sids,
84 struct lsa_TransNameArray *names)
86 struct lsa_LookupSids r;
87 struct lsa_SidArray sidarray;
88 struct lsa_RefDomainList *domains;
89 uint32_t count = 0;
90 uint32_t i;
92 names->count = 0;
93 names->names = NULL;
95 sidarray.num_sids = num_sids;
96 sidarray.sids = talloc_array(mem_ctx, struct lsa_SidPtr, num_sids);
98 for (i=0; i<num_sids; i++) {
99 sidarray.sids[i].sid = sids[i];
102 r.in.handle = handle;
103 r.in.sids = &sidarray;
104 r.in.names = names;
105 r.in.level = level;
106 r.in.count = &count;
107 r.out.names = names;
108 r.out.count = &count;
109 r.out.domains = &domains;
111 return dcerpc_lsa_LookupSids(p, mem_ctx, &r);
114 static const char *sid_type_lookup(enum lsa_SidType r)
116 switch (r) {
117 case SID_NAME_USE_NONE: return "SID_NAME_USE_NONE"; break;
118 case SID_NAME_USER: return "SID_NAME_USER"; break;
119 case SID_NAME_DOM_GRP: return "SID_NAME_DOM_GRP"; break;
120 case SID_NAME_DOMAIN: return "SID_NAME_DOMAIN"; break;
121 case SID_NAME_ALIAS: return "SID_NAME_ALIAS"; break;
122 case SID_NAME_WKN_GRP: return "SID_NAME_WKN_GRP"; break;
123 case SID_NAME_DELETED: return "SID_NAME_DELETED"; break;
124 case SID_NAME_INVALID: return "SID_NAME_INVALID"; break;
125 case SID_NAME_UNKNOWN: return "SID_NAME_UNKNOWN"; break;
126 case SID_NAME_COMPUTER: return "SID_NAME_COMPUTER"; break;
128 return "Invalid sid type\n";
131 static bool test_lookupsids(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *p,
132 struct policy_handle *handle,
133 struct dom_sid **sids, uint32_t num_sids,
134 int level, NTSTATUS expected_result,
135 enum lsa_SidType *types)
137 struct lsa_TransNameArray names;
138 NTSTATUS status;
139 uint32_t i;
140 bool ret = true;
142 status = lookup_sids(mem_ctx, level, p, handle, sids, num_sids,
143 &names);
144 if (!NT_STATUS_EQUAL(status, expected_result)) {
145 printf("For level %d expected %s, got %s\n",
146 level, nt_errstr(expected_result),
147 nt_errstr(status));
148 return false;
151 if (!NT_STATUS_EQUAL(status, NT_STATUS_OK) &&
152 !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
153 return true;
156 for (i=0; i<num_sids; i++) {
157 if (names.names[i].sid_type != types[i]) {
158 printf("In level %d, for sid %s expected %s, "
159 "got %s\n", level,
160 dom_sid_string(mem_ctx, sids[i]),
161 sid_type_lookup(types[i]),
162 sid_type_lookup(names.names[i].sid_type));
163 ret = false;
166 return ret;
169 static bool get_downleveltrust(struct torture_context *tctx, struct dcerpc_pipe *p,
170 struct policy_handle *handle,
171 struct dom_sid **sid)
173 struct lsa_EnumTrustDom r;
174 uint32_t resume_handle = 0;
175 struct lsa_DomainList domains;
176 NTSTATUS status;
177 int i;
179 r.in.handle = handle;
180 r.in.resume_handle = &resume_handle;
181 r.in.max_size = 1000;
182 r.out.domains = &domains;
183 r.out.resume_handle = &resume_handle;
185 status = dcerpc_lsa_EnumTrustDom(p, tctx, &r);
187 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES))
188 torture_fail(tctx, "no trusts");
190 if (domains.count == 0) {
191 torture_fail(tctx, "no trusts");
194 for (i=0; i<domains.count; i++) {
195 struct lsa_QueryTrustedDomainInfoBySid q;
196 union lsa_TrustedDomainInfo *info = NULL;
198 if (domains.domains[i].sid == NULL)
199 continue;
201 q.in.handle = handle;
202 q.in.dom_sid = domains.domains[i].sid;
203 q.in.level = 6;
204 q.out.info = &info;
206 status = dcerpc_lsa_QueryTrustedDomainInfoBySid(p, tctx, &q);
207 if (!NT_STATUS_IS_OK(status)) continue;
209 if ((info->info_ex.trust_direction & 2) &&
210 (info->info_ex.trust_type == 1)) {
211 *sid = domains.domains[i].sid;
212 return true;
216 torture_fail(tctx, "I need a AD DC with an outgoing trust to NT4");
219 #define NUM_SIDS 8
221 bool torture_rpc_lsa_lookup(struct torture_context *torture)
223 NTSTATUS status;
224 struct dcerpc_pipe *p;
225 bool ret = true;
226 struct policy_handle *handle;
227 struct dom_sid *dom_sid = NULL;
228 struct dom_sid *trusted_sid = NULL;
229 struct dom_sid *sids[NUM_SIDS];
231 status = torture_rpc_connection(torture, &p, &ndr_table_lsarpc);
232 if (!NT_STATUS_IS_OK(status)) {
233 torture_fail(torture, "unable to connect to table");
236 ret &= open_policy(torture, p, &handle);
237 if (!ret) return false;
239 ret &= get_domainsid(torture, p, handle, &dom_sid);
240 if (!ret) return false;
242 ret &= get_downleveltrust(torture, p, handle, &trusted_sid);
243 if (!ret) return false;
245 torture_comment(torture, "domain sid: %s\n",
246 dom_sid_string(torture, dom_sid));
248 sids[0] = dom_sid_parse_talloc(torture, "S-1-1-0");
249 sids[1] = dom_sid_parse_talloc(torture, "S-1-5-4");
250 sids[2] = dom_sid_parse_talloc(torture, "S-1-5-32");
251 sids[3] = dom_sid_parse_talloc(torture, "S-1-5-32-545");
252 sids[4] = dom_sid_dup(torture, dom_sid);
253 sids[5] = dom_sid_add_rid(torture, dom_sid, 512);
254 sids[6] = dom_sid_dup(torture, trusted_sid);
255 sids[7] = dom_sid_add_rid(torture, trusted_sid, 512);
257 ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 0,
258 NT_STATUS_INVALID_PARAMETER, NULL);
261 enum lsa_SidType types[NUM_SIDS] =
262 { SID_NAME_WKN_GRP, SID_NAME_WKN_GRP, SID_NAME_DOMAIN,
263 SID_NAME_ALIAS, SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
264 SID_NAME_DOMAIN, SID_NAME_DOM_GRP };
266 ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 1,
267 NT_STATUS_OK, types);
271 enum lsa_SidType types[NUM_SIDS] =
272 { SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
273 SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
274 SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
275 SID_NAME_DOMAIN, SID_NAME_DOM_GRP };
276 ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 2,
277 STATUS_SOME_UNMAPPED, types);
281 enum lsa_SidType types[NUM_SIDS] =
282 { SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
283 SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
284 SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
285 SID_NAME_UNKNOWN, SID_NAME_UNKNOWN };
286 ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 3,
287 STATUS_SOME_UNMAPPED, types);
291 enum lsa_SidType types[NUM_SIDS] =
292 { SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
293 SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
294 SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
295 SID_NAME_UNKNOWN, SID_NAME_UNKNOWN };
296 ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 4,
297 STATUS_SOME_UNMAPPED, types);
300 ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 5,
301 NT_STATUS_NONE_MAPPED, NULL);
304 enum lsa_SidType types[NUM_SIDS] =
305 { SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
306 SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
307 SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
308 SID_NAME_UNKNOWN, SID_NAME_UNKNOWN };
309 ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 6,
310 STATUS_SOME_UNMAPPED, types);
313 ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 7,
314 NT_STATUS_INVALID_PARAMETER, NULL);
315 ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 8,
316 NT_STATUS_INVALID_PARAMETER, NULL);
317 ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 9,
318 NT_STATUS_INVALID_PARAMETER, NULL);
319 ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 10,
320 NT_STATUS_INVALID_PARAMETER, NULL);
322 return ret;
325 static bool test_LookupSidsReply(struct torture_context *tctx,
326 struct dcerpc_pipe *p)
328 struct policy_handle *handle;
330 struct dom_sid **sids;
331 uint32_t num_sids = 1;
333 struct lsa_LookupSids r;
334 struct lsa_SidArray sidarray;
335 struct lsa_RefDomainList *domains = NULL;
336 struct lsa_TransNameArray names;
337 uint32_t count = 0;
339 uint32_t i;
340 NTSTATUS status;
341 const char *dom_sid = "S-1-5-21-1111111111-2222222222-3333333333";
342 const char *dom_admin_sid;
344 if (!open_policy(tctx, p, &handle)) {
345 return false;
348 dom_admin_sid = talloc_asprintf(tctx, "%s-%d", dom_sid, 512);
350 sids = talloc_array(tctx, struct dom_sid *, num_sids);
352 sids[0] = dom_sid_parse_talloc(tctx, dom_admin_sid);
354 names.count = 0;
355 names.names = NULL;
357 sidarray.num_sids = num_sids;
358 sidarray.sids = talloc_array(tctx, struct lsa_SidPtr, num_sids);
360 for (i=0; i<num_sids; i++) {
361 sidarray.sids[i].sid = sids[i];
364 r.in.handle = handle;
365 r.in.sids = &sidarray;
366 r.in.names = &names;
367 r.in.level = LSA_LOOKUP_NAMES_ALL;
368 r.in.count = &count;
369 r.out.names = &names;
370 r.out.count = &count;
371 r.out.domains = &domains;
373 status = dcerpc_lsa_LookupSids(p, tctx, &r);
375 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NONE_MAPPED,
376 "unexpected error code");
378 torture_assert_int_equal(tctx, names.count, num_sids,
379 "unexpected names count");
380 torture_assert(tctx, names.names,
381 "unexpected names pointer");
382 torture_assert_str_equal(tctx, names.names[0].name.string, dom_admin_sid,
383 "unexpected names[0].string");
385 #if 0
386 /* vista sp1 passes, w2k3 sp2 fails */
387 torture_assert_int_equal(tctx, domains->count, num_sids,
388 "unexpected domains count");
389 torture_assert(tctx, domains->domains,
390 "unexpected domains pointer");
391 torture_assert_str_equal(tctx, dom_sid_string(tctx, domains->domains[0].sid), dom_sid,
392 "unexpected domain sid");
393 #endif
395 return true;
398 /* check for lookup sids results */
399 struct torture_suite *torture_rpc_lsa_lookup_sids(TALLOC_CTX *mem_ctx)
401 struct torture_suite *suite;
402 struct torture_rpc_tcase *tcase;
404 suite = torture_suite_create(mem_ctx, "LSA-LOOKUPSIDS");
405 tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
406 &ndr_table_lsarpc);
408 torture_rpc_tcase_add_test(tcase, "LookupSidsReply", test_LookupSidsReply);
410 return suite;