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/>.
22
#include "torture/torture.h"
23
#include "lib/events/events.h"
24
#include "libnet/libnet_join.h"
25
#include "torture/rpc/rpc.h"
26
#include "librpc/gen_ndr/ndr_lsa_c.h"
27
#include "libcli/security/security.h"
29
static bool open_policy(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *p,
30
struct policy_handle **handle)
32
struct lsa_ObjectAttribute attr;
33
struct lsa_QosInfo qos;
34
struct lsa_OpenPolicy2 r;
37
*handle = talloc(mem_ctx, struct policy_handle);
43
qos.impersonation_level = 2;
45
qos.effective_only = 0;
49
attr.object_name = NULL;
54
r.in.system_name = "\\";
56
r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
57
r.out.handle = *handle;
59
status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &r);
61
return NT_STATUS_IS_OK(status);
64
static bool get_domainsid(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *p,
65
struct policy_handle *handle,
68
struct lsa_QueryInfoPolicy r;
69
union lsa_PolicyInformation *info = NULL;
72
r.in.level = LSA_POLICY_INFO_DOMAIN;
76
status = dcerpc_lsa_QueryInfoPolicy(p, mem_ctx, &r);
77
if (!NT_STATUS_IS_OK(status)) return false;
79
*sid = info->domain.sid;
83
static NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, uint16_t level,
84
struct dcerpc_pipe *p,
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;
98
sidarray.num_sids = num_sids;
99
sidarray.sids = talloc_array(mem_ctx, struct lsa_SidPtr, num_sids);
101
for (i=0; i<num_sids; i++) {
102
sidarray.sids[i].sid = sids[i];
105
r.in.handle = handle;
106
r.in.sids = &sidarray;
111
r.out.count = &count;
112
r.out.domains = &domains;
114
return dcerpc_lsa_LookupSids(p, mem_ctx, &r);
117
static const char *sid_type_lookup(enum lsa_SidType r)
120
case SID_NAME_USE_NONE: return "SID_NAME_USE_NONE"; break;
121
case SID_NAME_USER: return "SID_NAME_USER"; break;
122
case SID_NAME_DOM_GRP: return "SID_NAME_DOM_GRP"; break;
123
case SID_NAME_DOMAIN: return "SID_NAME_DOMAIN"; break;
124
case SID_NAME_ALIAS: return "SID_NAME_ALIAS"; break;
125
case SID_NAME_WKN_GRP: return "SID_NAME_WKN_GRP"; break;
126
case SID_NAME_DELETED: return "SID_NAME_DELETED"; break;
127
case SID_NAME_INVALID: return "SID_NAME_INVALID"; break;
128
case SID_NAME_UNKNOWN: return "SID_NAME_UNKNOWN"; break;
129
case SID_NAME_COMPUTER: return "SID_NAME_COMPUTER"; break;
131
return "Invalid sid type\n";
134
static bool test_lookupsids(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *p,
135
struct policy_handle *handle,
136
struct dom_sid **sids, uint32_t num_sids,
137
int level, NTSTATUS expected_result,
138
enum lsa_SidType *types)
140
struct lsa_TransNameArray names;
145
status = lookup_sids(mem_ctx, level, p, handle, sids, num_sids,
147
if (!NT_STATUS_EQUAL(status, expected_result)) {
148
printf("For level %d expected %s, got %s\n",
149
level, nt_errstr(expected_result),
154
if (!NT_STATUS_EQUAL(status, NT_STATUS_OK) &&
155
!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
159
for (i=0; i<num_sids; i++) {
160
if (names.names[i].sid_type != types[i]) {
161
printf("In level %d, for sid %s expected %s, "
163
dom_sid_string(mem_ctx, sids[i]),
164
sid_type_lookup(types[i]),
165
sid_type_lookup(names.names[i].sid_type));
172
static bool get_downleveltrust(struct torture_context *tctx, struct dcerpc_pipe *p,
173
struct policy_handle *handle,
174
struct dom_sid **sid)
176
struct lsa_EnumTrustDom r;
177
uint32_t resume_handle = 0;
178
struct lsa_DomainList domains;
182
r.in.handle = handle;
183
r.in.resume_handle = &resume_handle;
184
r.in.max_size = 1000;
185
r.out.domains = &domains;
186
r.out.resume_handle = &resume_handle;
188
status = dcerpc_lsa_EnumTrustDom(p, tctx, &r);
190
if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES))
191
torture_fail(tctx, "no trusts");
193
if (domains.count == 0) {
194
torture_fail(tctx, "no trusts");
197
for (i=0; i<domains.count; i++) {
198
struct lsa_QueryTrustedDomainInfoBySid q;
199
union lsa_TrustedDomainInfo *info = NULL;
201
if (domains.domains[i].sid == NULL)
204
q.in.handle = handle;
205
q.in.dom_sid = domains.domains[i].sid;
209
status = dcerpc_lsa_QueryTrustedDomainInfoBySid(p, tctx, &q);
210
if (!NT_STATUS_IS_OK(status)) continue;
212
if ((info->info_ex.trust_direction & 2) &&
213
(info->info_ex.trust_type == 1)) {
214
*sid = domains.domains[i].sid;
219
torture_fail(tctx, "I need a AD DC with an outgoing trust to NT4");
224
bool torture_rpc_lsa_lookup(struct torture_context *torture)
227
struct dcerpc_pipe *p;
229
struct policy_handle *handle;
230
struct dom_sid *dom_sid;
231
struct dom_sid *trusted_sid;
232
struct dom_sid *sids[NUM_SIDS];
234
status = torture_rpc_connection(torture, &p, &ndr_table_lsarpc);
235
if (!NT_STATUS_IS_OK(status)) {
236
torture_fail(torture, "unable to connect to table");
239
ret &= open_policy(torture, p, &handle);
240
if (!ret) return false;
242
ret &= get_domainsid(torture, p, handle, &dom_sid);
243
if (!ret) return false;
245
ret &= get_downleveltrust(torture, p, handle, &trusted_sid);
246
if (!ret) return false;
248
torture_comment(torture, "domain sid: %s\n",
249
dom_sid_string(torture, dom_sid));
251
sids[0] = dom_sid_parse_talloc(torture, "S-1-1-0");
252
sids[1] = dom_sid_parse_talloc(torture, "S-1-5-4");
253
sids[2] = dom_sid_parse_talloc(torture, "S-1-5-32");
254
sids[3] = dom_sid_parse_talloc(torture, "S-1-5-32-545");
255
sids[4] = dom_sid_dup(torture, dom_sid);
256
sids[5] = dom_sid_add_rid(torture, dom_sid, 512);
257
sids[6] = dom_sid_dup(torture, trusted_sid);
258
sids[7] = dom_sid_add_rid(torture, trusted_sid, 512);
260
ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 0,
261
NT_STATUS_INVALID_PARAMETER, NULL);
264
enum lsa_SidType types[NUM_SIDS] =
265
{ SID_NAME_WKN_GRP, SID_NAME_WKN_GRP, SID_NAME_DOMAIN,
266
SID_NAME_ALIAS, SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
267
SID_NAME_DOMAIN, SID_NAME_DOM_GRP };
269
ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 1,
270
NT_STATUS_OK, types);
274
enum lsa_SidType types[NUM_SIDS] =
275
{ SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
276
SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
277
SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
278
SID_NAME_DOMAIN, SID_NAME_DOM_GRP };
279
ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 2,
280
STATUS_SOME_UNMAPPED, types);
284
enum lsa_SidType types[NUM_SIDS] =
285
{ SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
286
SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
287
SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
288
SID_NAME_UNKNOWN, SID_NAME_UNKNOWN };
289
ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 3,
290
STATUS_SOME_UNMAPPED, types);
294
enum lsa_SidType types[NUM_SIDS] =
295
{ SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
296
SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
297
SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
298
SID_NAME_UNKNOWN, SID_NAME_UNKNOWN };
299
ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 4,
300
STATUS_SOME_UNMAPPED, types);
303
ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 5,
304
NT_STATUS_NONE_MAPPED, NULL);
307
enum lsa_SidType types[NUM_SIDS] =
308
{ SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
309
SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
310
SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
311
SID_NAME_UNKNOWN, SID_NAME_UNKNOWN };
312
ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 6,
313
STATUS_SOME_UNMAPPED, types);
316
ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 7,
317
NT_STATUS_INVALID_PARAMETER, NULL);
318
ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 8,
319
NT_STATUS_INVALID_PARAMETER, NULL);
320
ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 9,
321
NT_STATUS_INVALID_PARAMETER, NULL);
322
ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 10,
323
NT_STATUS_INVALID_PARAMETER, NULL);
328
static bool test_LookupSidsReply(struct torture_context *tctx,
329
struct dcerpc_pipe *p)
331
struct policy_handle *handle;
333
struct dom_sid **sids;
334
uint32_t num_sids = 1;
336
struct lsa_LookupSids r;
337
struct lsa_SidArray sidarray;
338
struct lsa_RefDomainList *domains = NULL;
339
struct lsa_TransNameArray names;
344
const char *dom_sid = "S-1-5-21-1111111111-2222222222-3333333333";
345
const char *dom_admin_sid;
347
if (!open_policy(tctx, p, &handle)) {
351
dom_admin_sid = talloc_asprintf(tctx, "%s-%d", dom_sid, 512);
353
sids = talloc_array(tctx, struct dom_sid *, num_sids);
355
sids[0] = dom_sid_parse_talloc(tctx, dom_admin_sid);
360
sidarray.num_sids = num_sids;
361
sidarray.sids = talloc_array(tctx, struct lsa_SidPtr, num_sids);
363
for (i=0; i<num_sids; i++) {
364
sidarray.sids[i].sid = sids[i];
367
r.in.handle = handle;
368
r.in.sids = &sidarray;
370
r.in.level = LSA_LOOKUP_NAMES_ALL;
372
r.out.names = &names;
373
r.out.count = &count;
374
r.out.domains = &domains;
376
status = dcerpc_lsa_LookupSids(p, tctx, &r);
378
torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NONE_MAPPED,
379
"unexpected error code");
381
torture_assert_int_equal(tctx, names.count, num_sids,
382
"unexpected names count");
383
torture_assert(tctx, names.names,
384
"unexpected names pointer");
385
torture_assert_str_equal(tctx, names.names[0].name.string, dom_admin_sid,
386
"unexpected names[0].string");
389
/* vista sp1 passes, w2k3 sp2 fails */
390
torture_assert_int_equal(tctx, domains->count, num_sids,
391
"unexpected domains count");
392
torture_assert(tctx, domains->domains,
393
"unexpected domains pointer");
394
torture_assert_str_equal(tctx, dom_sid_string(tctx, domains->domains[0].sid), dom_sid,
395
"unexpected domain sid");
401
/* check for lookup sids results */
402
struct torture_suite *torture_rpc_lsa_lookup_sids(TALLOC_CTX *mem_ctx)
404
struct torture_suite *suite;
405
struct torture_rpc_tcase *tcase;
407
suite = torture_suite_create(mem_ctx, "LSA-LOOKUPSIDS");
408
tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
411
torture_rpc_tcase_add_test(tcase, "LookupSidsReply", test_LookupSidsReply);