s4:tortore/rpc/spoolss: some compilers don't like .foo.bar = 5
[Samba/gebeck_regimport.git] / source4 / torture / rpc / lsa_lookup.c
blobbaeb95c3ea74528b6369c46c60778eb20bc31553
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(struct torture_context *tctx,
27 struct dcerpc_binding_handle *b,
28 struct policy_handle **handle)
30 struct lsa_ObjectAttribute attr;
31 struct lsa_QosInfo qos;
32 struct lsa_OpenPolicy2 r;
34 *handle = talloc(tctx, 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 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b, tctx, &r),
57 "OpenPolicy2 failed");
59 return NT_STATUS_IS_OK(r.out.result);
62 static bool get_domainsid(struct torture_context *tctx,
63 struct dcerpc_binding_handle *b,
64 struct policy_handle *handle,
65 struct dom_sid **sid)
67 struct lsa_QueryInfoPolicy r;
68 union lsa_PolicyInformation *info = NULL;
70 r.in.level = LSA_POLICY_INFO_DOMAIN;
71 r.in.handle = handle;
72 r.out.info = &info;
74 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy_r(b, tctx, &r),
75 "QueryInfoPolicy failed");
76 torture_assert_ntstatus_ok(tctx, r.out.result, "QueryInfoPolicy failed");
78 *sid = info->domain.sid;
79 return true;
82 static NTSTATUS lookup_sids(struct torture_context *tctx,
83 uint16_t level,
84 struct dcerpc_binding_handle *b,
85 struct policy_handle *handle,
86 struct dom_sid **sids, uint32_t num_sids,
87 struct lsa_TransNameArray *names)
89 struct lsa_LookupSids r;
90 struct lsa_SidArray sidarray;
91 struct lsa_RefDomainList *domains;
92 uint32_t count = 0;
93 uint32_t i;
94 NTSTATUS status;
96 names->count = 0;
97 names->names = NULL;
99 sidarray.num_sids = num_sids;
100 sidarray.sids = talloc_array(tctx, struct lsa_SidPtr, num_sids);
102 for (i=0; i<num_sids; i++) {
103 sidarray.sids[i].sid = sids[i];
106 r.in.handle = handle;
107 r.in.sids = &sidarray;
108 r.in.names = names;
109 r.in.level = level;
110 r.in.count = &count;
111 r.out.names = names;
112 r.out.count = &count;
113 r.out.domains = &domains;
115 status = dcerpc_lsa_LookupSids_r(b, tctx, &r);
116 if (!NT_STATUS_IS_OK(status)) {
117 return status;
119 return r.out.result;
122 static const char *sid_type_lookup(enum lsa_SidType r)
124 switch (r) {
125 case SID_NAME_USE_NONE: return "SID_NAME_USE_NONE"; break;
126 case SID_NAME_USER: return "SID_NAME_USER"; break;
127 case SID_NAME_DOM_GRP: return "SID_NAME_DOM_GRP"; break;
128 case SID_NAME_DOMAIN: return "SID_NAME_DOMAIN"; break;
129 case SID_NAME_ALIAS: return "SID_NAME_ALIAS"; break;
130 case SID_NAME_WKN_GRP: return "SID_NAME_WKN_GRP"; break;
131 case SID_NAME_DELETED: return "SID_NAME_DELETED"; break;
132 case SID_NAME_INVALID: return "SID_NAME_INVALID"; break;
133 case SID_NAME_UNKNOWN: return "SID_NAME_UNKNOWN"; break;
134 case SID_NAME_COMPUTER: return "SID_NAME_COMPUTER"; break;
136 return "Invalid sid type\n";
139 static bool test_lookupsids(struct torture_context *tctx,
140 struct dcerpc_binding_handle *b,
141 struct policy_handle *handle,
142 struct dom_sid **sids, uint32_t num_sids,
143 int level, NTSTATUS expected_result,
144 enum lsa_SidType *types)
146 struct lsa_TransNameArray names;
147 NTSTATUS status;
148 uint32_t i;
149 bool ret = true;
151 status = lookup_sids(tctx, level, b, handle, sids, num_sids,
152 &names);
153 if (!NT_STATUS_EQUAL(status, expected_result)) {
154 printf("For level %d expected %s, got %s\n",
155 level, nt_errstr(expected_result),
156 nt_errstr(status));
157 return false;
160 if (!NT_STATUS_EQUAL(status, NT_STATUS_OK) &&
161 !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
162 return true;
165 for (i=0; i<num_sids; i++) {
166 if (names.names[i].sid_type != types[i]) {
167 printf("In level %d, for sid %s expected %s, "
168 "got %s\n", level,
169 dom_sid_string(tctx, sids[i]),
170 sid_type_lookup(types[i]),
171 sid_type_lookup(names.names[i].sid_type));
172 ret = false;
175 return ret;
178 static bool get_downleveltrust(struct torture_context *tctx, struct dcerpc_binding_handle *b,
179 struct policy_handle *handle,
180 struct dom_sid **sid)
182 struct lsa_EnumTrustDom r;
183 uint32_t resume_handle = 0;
184 struct lsa_DomainList domains;
185 int i;
187 r.in.handle = handle;
188 r.in.resume_handle = &resume_handle;
189 r.in.max_size = 1000;
190 r.out.domains = &domains;
191 r.out.resume_handle = &resume_handle;
193 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b, tctx, &r),
194 "EnumTrustDom failed");
196 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES))
197 torture_fail(tctx, "no trusts");
199 if (domains.count == 0) {
200 torture_fail(tctx, "no trusts");
203 for (i=0; i<domains.count; i++) {
204 struct lsa_QueryTrustedDomainInfoBySid q;
205 union lsa_TrustedDomainInfo *info = NULL;
207 if (domains.domains[i].sid == NULL)
208 continue;
210 q.in.handle = handle;
211 q.in.dom_sid = domains.domains[i].sid;
212 q.in.level = 6;
213 q.out.info = &info;
215 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfoBySid_r(b, tctx, &q),
216 "QueryTrustedDomainInfoBySid failed");
217 if (!NT_STATUS_IS_OK(q.out.result)) continue;
219 if ((info->info_ex.trust_direction & 2) &&
220 (info->info_ex.trust_type == 1)) {
221 *sid = domains.domains[i].sid;
222 return true;
226 torture_fail(tctx, "I need a AD DC with an outgoing trust to NT4");
229 #define NUM_SIDS 8
231 bool torture_rpc_lsa_lookup(struct torture_context *torture)
233 NTSTATUS status;
234 struct dcerpc_pipe *p;
235 bool ret = true;
236 struct policy_handle *handle;
237 struct dom_sid *dom_sid = NULL;
238 struct dom_sid *trusted_sid = NULL;
239 struct dom_sid *sids[NUM_SIDS];
240 struct dcerpc_binding_handle *b;
242 status = torture_rpc_connection(torture, &p, &ndr_table_lsarpc);
243 if (!NT_STATUS_IS_OK(status)) {
244 torture_fail(torture, "unable to connect to table");
246 b = p->binding_handle;
248 ret &= open_policy(torture, b, &handle);
249 if (!ret) return false;
251 ret &= get_domainsid(torture, b, handle, &dom_sid);
252 if (!ret) return false;
254 ret &= get_downleveltrust(torture, b, handle, &trusted_sid);
255 if (!ret) return false;
257 torture_comment(torture, "domain sid: %s\n",
258 dom_sid_string(torture, dom_sid));
260 sids[0] = dom_sid_parse_talloc(torture, "S-1-1-0");
261 sids[1] = dom_sid_parse_talloc(torture, "S-1-5-4");
262 sids[2] = dom_sid_parse_talloc(torture, "S-1-5-32");
263 sids[3] = dom_sid_parse_talloc(torture, "S-1-5-32-545");
264 sids[4] = dom_sid_dup(torture, dom_sid);
265 sids[5] = dom_sid_add_rid(torture, dom_sid, 512);
266 sids[6] = dom_sid_dup(torture, trusted_sid);
267 sids[7] = dom_sid_add_rid(torture, trusted_sid, 512);
269 ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 0,
270 NT_STATUS_INVALID_PARAMETER, NULL);
273 enum lsa_SidType types[NUM_SIDS] =
274 { SID_NAME_WKN_GRP, SID_NAME_WKN_GRP, SID_NAME_DOMAIN,
275 SID_NAME_ALIAS, SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
276 SID_NAME_DOMAIN, SID_NAME_DOM_GRP };
278 ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 1,
279 NT_STATUS_OK, types);
283 enum lsa_SidType types[NUM_SIDS] =
284 { SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
285 SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
286 SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
287 SID_NAME_DOMAIN, SID_NAME_DOM_GRP };
288 ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 2,
289 STATUS_SOME_UNMAPPED, types);
293 enum lsa_SidType types[NUM_SIDS] =
294 { SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
295 SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
296 SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
297 SID_NAME_UNKNOWN, SID_NAME_UNKNOWN };
298 ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 3,
299 STATUS_SOME_UNMAPPED, types);
303 enum lsa_SidType types[NUM_SIDS] =
304 { SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
305 SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
306 SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
307 SID_NAME_UNKNOWN, SID_NAME_UNKNOWN };
308 ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 4,
309 STATUS_SOME_UNMAPPED, types);
312 ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 5,
313 NT_STATUS_NONE_MAPPED, NULL);
316 enum lsa_SidType types[NUM_SIDS] =
317 { SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
318 SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
319 SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
320 SID_NAME_UNKNOWN, SID_NAME_UNKNOWN };
321 ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 6,
322 STATUS_SOME_UNMAPPED, types);
325 ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 7,
326 NT_STATUS_INVALID_PARAMETER, NULL);
327 ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 8,
328 NT_STATUS_INVALID_PARAMETER, NULL);
329 ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 9,
330 NT_STATUS_INVALID_PARAMETER, NULL);
331 ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 10,
332 NT_STATUS_INVALID_PARAMETER, NULL);
334 return ret;
337 static bool test_LookupSidsReply(struct torture_context *tctx,
338 struct dcerpc_pipe *p)
340 struct policy_handle *handle;
342 struct dom_sid **sids;
343 uint32_t num_sids = 1;
345 struct lsa_LookupSids r;
346 struct lsa_SidArray sidarray;
347 struct lsa_RefDomainList *domains = NULL;
348 struct lsa_TransNameArray names;
349 uint32_t count = 0;
351 uint32_t i;
352 const char *dom_sid = "S-1-5-21-1111111111-2222222222-3333333333";
353 const char *dom_admin_sid;
354 struct dcerpc_binding_handle *b = p->binding_handle;
356 if (!open_policy(tctx, b, &handle)) {
357 return false;
360 dom_admin_sid = talloc_asprintf(tctx, "%s-%d", dom_sid, 512);
362 sids = talloc_array(tctx, struct dom_sid *, num_sids);
364 sids[0] = dom_sid_parse_talloc(tctx, dom_admin_sid);
366 names.count = 0;
367 names.names = NULL;
369 sidarray.num_sids = num_sids;
370 sidarray.sids = talloc_array(tctx, struct lsa_SidPtr, num_sids);
372 for (i=0; i<num_sids; i++) {
373 sidarray.sids[i].sid = sids[i];
376 r.in.handle = handle;
377 r.in.sids = &sidarray;
378 r.in.names = &names;
379 r.in.level = LSA_LOOKUP_NAMES_ALL;
380 r.in.count = &count;
381 r.out.names = &names;
382 r.out.count = &count;
383 r.out.domains = &domains;
385 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids_r(b, tctx, &r),
386 "LookupSids failed");
388 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NONE_MAPPED,
389 "unexpected error code");
391 torture_assert_int_equal(tctx, names.count, num_sids,
392 "unexpected names count");
393 torture_assert(tctx, names.names,
394 "unexpected names pointer");
395 torture_assert_str_equal(tctx, names.names[0].name.string, dom_admin_sid,
396 "unexpected names[0].string");
398 #if 0
399 /* vista sp1 passes, w2k3 sp2 fails */
400 torture_assert_int_equal(tctx, domains->count, num_sids,
401 "unexpected domains count");
402 torture_assert(tctx, domains->domains,
403 "unexpected domains pointer");
404 torture_assert_str_equal(tctx, dom_sid_string(tctx, domains->domains[0].sid), dom_sid,
405 "unexpected domain sid");
406 #endif
408 return true;
411 /* check for lookup sids results */
412 struct torture_suite *torture_rpc_lsa_lookup_sids(TALLOC_CTX *mem_ctx)
414 struct torture_suite *suite;
415 struct torture_rpc_tcase *tcase;
417 suite = torture_suite_create(mem_ctx, "LSA-LOOKUPSIDS");
418 tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
419 &ndr_table_lsarpc);
421 torture_rpc_tcase_add_test(tcase, "LookupSidsReply", test_LookupSidsReply);
423 return suite;