- fixed lsa_EnumTrustDom
[ira/wip.git] / source / torture / rpc / lsa.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for lsa rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    
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 2 of the License, or
10    (at your option) any later version.
11    
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.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 /*
25   these really shouldn't be here ....
26 */
27 static char *lsa_sid_string_talloc(TALLOC_CTX *mem_ctx, struct dom_sid *sid)
28 {
29         int i, ofs, maxlen;
30         uint32 ia;
31         char *ret;
32         
33         if (!sid) {
34                 return talloc_asprintf(mem_ctx, "(NULL SID)");
35         }
36
37         maxlen = sid->num_auths * 11 + 25;
38         ret = talloc(mem_ctx, maxlen);
39         if (!ret) return NULL;
40
41         ia = (sid->id_auth[5]) +
42                 (sid->id_auth[4] << 8 ) +
43                 (sid->id_auth[3] << 16) +
44                 (sid->id_auth[2] << 24);
45
46         ofs = snprintf(ret, maxlen, "S-%u-%lu", 
47                        (unsigned int)sid->sid_rev_num, (unsigned long)ia);
48
49         for (i = 0; i < sid->num_auths; i++) {
50                 ofs += snprintf(ret + ofs, maxlen - ofs, "-%lu", (unsigned long)sid->sub_auths[i]);
51         }
52
53         return ret;
54 }
55
56 static int dom_sid_compare(struct dom_sid *sid1, struct dom_sid *sid2)
57 {
58         int i;
59
60         if (sid1 == sid2) return 0;
61         if (!sid1) return -1;
62         if (!sid2) return 1;
63
64         /* Compare most likely different rids, first: i.e start at end */
65         if (sid1->num_auths != sid2->num_auths)
66                 return sid1->num_auths - sid2->num_auths;
67
68         for (i = sid1->num_auths-1; i >= 0; --i)
69                 if (sid1->sub_auths[i] != sid2->sub_auths[i])
70                         return sid1->sub_auths[i] - sid2->sub_auths[i];
71
72         if (sid1->sid_rev_num != sid2->sid_rev_num)
73                 return sid1->sid_rev_num - sid2->sid_rev_num;
74
75         for (i = 0; i < 6; i++)
76                 if (sid1->id_auth[i] != sid2->id_auth[i])
77                         return sid1->id_auth[i] - sid2->id_auth[i];
78
79         return 0;
80 }
81
82 static BOOL test_OpenPolicy(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
83 {
84         struct lsa_ObjectAttribute attr;
85         struct policy_handle handle;
86         struct lsa_QosInfo qos;
87         struct lsa_OpenPolicy r;
88         NTSTATUS status;
89         uint16 system_name = '\\';
90
91         printf("\ntesting OpenPolicy\n");
92
93         qos.impersonation_level = 2;
94         qos.context_mode = 1;
95         qos.effective_only = 0;
96
97         attr.root_dir = NULL;
98         attr.object_name = NULL;
99         attr.attributes = 0;
100         attr.sec_desc = NULL;
101         attr.sec_qos = &qos;
102
103         r.in.system_name = &system_name;
104         r.in.attr = &attr;
105         r.in.desired_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
106         r.out.handle = &handle;
107
108         status = dcerpc_lsa_OpenPolicy(p, mem_ctx, &r);
109         if (!NT_STATUS_IS_OK(status)) {
110                 printf("OpenPolicy failed - %s\n", nt_errstr(status));
111                 return False;
112         }
113
114         return True;
115 }
116
117
118 static BOOL test_OpenPolicy2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
119                              struct policy_handle *handle)
120 {
121         struct lsa_ObjectAttribute attr;
122         struct lsa_QosInfo qos;
123         struct lsa_OpenPolicy2 r;
124         NTSTATUS status;
125
126         printf("\ntesting OpenPolicy2\n");
127
128         qos.impersonation_level = 2;
129         qos.context_mode = 1;
130         qos.effective_only = 0;
131
132         attr.root_dir = NULL;
133         attr.object_name = NULL;
134         attr.attributes = 0;
135         attr.sec_desc = NULL;
136         attr.sec_qos = &qos;
137
138         r.in.system_name = "\\";
139         r.in.attr = &attr;
140         r.in.desired_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
141         r.out.handle = handle;
142
143         status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &r);
144         if (!NT_STATUS_IS_OK(status)) {
145                 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
146                 return False;
147         }
148
149         return True;
150 }
151
152 static BOOL test_LookupNames(struct dcerpc_pipe *p, 
153                             TALLOC_CTX *mem_ctx, 
154                             struct policy_handle *handle,
155                             struct lsa_TransNameArray *tnames)
156 {
157         struct lsa_LookupNames r;
158         struct lsa_TransSidArray sids;
159         struct lsa_Name *names;
160         uint32 count = 0;
161         NTSTATUS status;
162         int i;
163
164         printf("\nTesting LookupNames\n");
165
166         sids.count = 0;
167         sids.sids = NULL;
168
169         names = talloc(mem_ctx, tnames->count * sizeof(names[0]));
170         for (i=0;i<tnames->count;i++) {
171                 names[i].name_len = 2*strlen(tnames->names[i].name.name);
172                 names[i].name_size = 2*strlen(tnames->names[i].name.name);
173                 names[i].name = tnames->names[i].name.name;
174         }
175
176         r.in.handle = handle;
177         r.in.num_names = tnames->count;
178         r.in.names = names;
179         r.in.sids = &sids;
180         r.in.level = 1;
181         r.in.count = &count;
182         r.out.count = &count;
183         r.out.sids = &sids;
184
185         status = dcerpc_lsa_LookupNames(p, mem_ctx, &r);
186         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
187                 printf("LookupNames failed - %s\n", nt_errstr(status));
188                 return False;
189         }
190
191         if (r.out.domains) {
192                 printf("lookup gave %d domains (max_count=%d)\n", 
193                        r.out.domains->count,
194                        r.out.domains->max_count);
195                 for (i=0;i<r.out.domains->count;i++) {
196                         printf("name='%s' sid=%s\n", 
197                                r.out.domains->domains[i].name.name,
198                                lsa_sid_string_talloc(mem_ctx, r.out.domains->domains[i].sid));
199                 }
200         }
201
202         printf("lookup gave %d sids (sids.count=%d)\n", count, sids.count);
203         for (i=0;i<sids.count;i++) {
204                 printf("sid_type=%d rid=%d sid_index=%d\n", 
205                        sids.sids[i].sid_type,
206                        sids.sids[i].rid,
207                        sids.sids[i].sid_index);
208         }
209
210         printf("\n");
211
212         return True;
213 }
214
215
216 static BOOL test_LookupSids(struct dcerpc_pipe *p, 
217                             TALLOC_CTX *mem_ctx, 
218                             struct policy_handle *handle,
219                             struct lsa_SidArray *sids)
220 {
221         struct lsa_LookupSids r;
222         struct lsa_TransNameArray names;
223         uint32 count = sids->num_sids;
224         NTSTATUS status;
225         int i;
226
227         printf("\nTesting LookupSids\n");
228
229         names.count = 0;
230         names.names = NULL;
231
232         r.in.handle = handle;
233         r.in.sids = sids;
234         r.in.names = &names;
235         r.in.level = 1;
236         r.in.count = &count;
237         r.out.count = &count;
238         r.out.names = &names;
239
240         status = dcerpc_lsa_LookupSids(p, mem_ctx, &r);
241         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
242                 printf("LookupSids failed - %s\n", nt_errstr(status));
243                 return False;
244         }
245
246         if (r.out.domains) {
247                 printf("lookup gave %d domains (max_count=%d)\n", 
248                        r.out.domains->count,
249                        r.out.domains->max_count);
250                 for (i=0;i<r.out.domains->count;i++) {
251                         printf("name='%s' sid=%s\n", 
252                                r.out.domains->domains[i].name.name,
253                                lsa_sid_string_talloc(mem_ctx, r.out.domains->domains[i].sid));
254                 }
255         }
256
257         printf("lookup gave %d names (names.count=%d)\n", count, names.count);
258         for (i=0;i<names.count;i++) {
259                 printf("type=%d sid_index=%d name='%s'\n", 
260                        names.names[i].sid_type,
261                        names.names[i].sid_index,
262                        names.names[i].name.name);
263         }
264
265         printf("\n");
266
267         if (!test_LookupNames(p, mem_ctx, handle, &names)) {
268                 return False;
269         }
270
271         return True;
272 }
273
274 static BOOL test_OpenAccount(struct dcerpc_pipe *p, 
275                              TALLOC_CTX *mem_ctx, 
276                              struct policy_handle *handle,
277                              struct dom_sid *sid)
278 {
279         NTSTATUS status;
280         struct lsa_OpenAccount r;
281         struct policy_handle acct_handle;
282
283         printf("Testing account %s\n", lsa_sid_string_talloc(mem_ctx, sid));
284
285         r.in.handle = handle;
286         r.in.sid = sid;
287         r.in.desired_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
288         r.out.acct_handle = &acct_handle;
289
290         status = dcerpc_lsa_OpenAccount(p, mem_ctx, &r);
291         if (!NT_STATUS_IS_OK(status)) {
292                 printf("OpenAccount failed - %s\n", nt_errstr(status));
293                 return False;
294         }
295
296         return True;
297 }
298
299 static BOOL test_EnumAccounts(struct dcerpc_pipe *p, 
300                           TALLOC_CTX *mem_ctx, 
301                           struct policy_handle *handle)
302 {
303         NTSTATUS status;
304         struct lsa_EnumAccounts r;
305         struct lsa_SidArray sids1, sids2;
306         uint32 resume_handle = 0;
307         int i;
308
309         printf("\ntesting EnumAccounts\n");
310
311         r.in.handle = handle;
312         r.in.resume_handle = &resume_handle;
313         r.in.num_entries = 100;
314         r.out.resume_handle = &resume_handle;
315         r.out.sids = &sids1;
316
317         resume_handle = 0;
318         status = dcerpc_lsa_EnumAccounts(p, mem_ctx, &r);
319         if (!NT_STATUS_IS_OK(status)) {
320                 printf("EnumAccounts failed - %s\n", nt_errstr(status));
321                 return False;
322         }
323
324         printf("Got %d sids resume_handle=%u\n", sids1.num_sids, resume_handle);
325
326         for (i=0;i<sids1.num_sids;i++) {
327                 printf("%s\n", lsa_sid_string_talloc(mem_ctx, sids1.sids[i].sid));
328         }
329
330         if (!test_LookupSids(p, mem_ctx, handle, &sids1)) {
331                 return False;
332         }
333
334         printf("testing all accounts\n");
335         for (i=0;i<sids1.num_sids;i++) {
336                 test_OpenAccount(p, mem_ctx, handle, sids1.sids[i].sid);
337         }
338         printf("\n");
339         
340         if (sids1.num_sids < 3) {
341                 return True;
342         }
343         
344         printf("trying EnumAccounts partial listing (asking for 1 at 2)\n");
345         resume_handle = 2;
346         r.in.num_entries = 1;
347         r.out.sids = &sids2;
348
349         status = dcerpc_lsa_EnumAccounts(p, mem_ctx, &r);
350         if (!NT_STATUS_IS_OK(status)) {
351                 printf("EnumAccounts failed - %s\n", nt_errstr(status));
352                 return False;
353         }
354
355         if (sids2.num_sids != 1) {
356                 printf("Returned wrong number of entries (%d)\n", sids2.num_sids);
357                 return False;
358         }
359
360         return True;
361 }
362
363
364 static BOOL test_EnumPrivs(struct dcerpc_pipe *p, 
365                            TALLOC_CTX *mem_ctx, 
366                            struct policy_handle *handle)
367 {
368         NTSTATUS status;
369         struct lsa_EnumPrivs r;
370         struct lsa_PrivArray privs1;
371         uint32 resume_handle = 0;
372         int i;
373
374         printf("\ntesting EnumPrivs\n");
375
376         r.in.handle = handle;
377         r.in.resume_handle = &resume_handle;
378         r.in.max_count = 1000;
379         r.out.resume_handle = &resume_handle;
380         r.out.privs = &privs1;
381
382         resume_handle = 0;
383         status = dcerpc_lsa_EnumPrivs(p, mem_ctx, &r);
384         if (!NT_STATUS_IS_OK(status)) {
385                 printf("EnumPrivs failed - %s\n", nt_errstr(status));
386                 return False;
387         }
388
389         printf("Got %d privs resume_handle=%u\n", privs1.count, resume_handle);
390
391         for (i=0;i<privs1.count;i++) {
392                 printf("luid=%08x-%08x '%s'\n", 
393                        privs1.privs[i].luid_low,
394                        privs1.privs[i].luid_high,
395                        privs1.privs[i].name.name);
396         }
397
398         return True;
399 }
400
401
402 static BOOL test_EnumTrustDom(struct dcerpc_pipe *p, 
403                               TALLOC_CTX *mem_ctx, 
404                               struct policy_handle *handle)
405 {
406         struct lsa_EnumTrustDom r;
407         NTSTATUS status;
408         int i;
409         uint32 resume_handle = 0;
410         struct lsa_RefDomainList domains;
411
412         printf("\nTesting EnumTrustDom\n");
413
414         r.in.handle = handle;
415         r.in.resume_handle = &resume_handle;
416         r.in.num_entries = 1000;
417         r.out.domains = &domains;
418         r.out.resume_handle = &resume_handle;
419
420         status = dcerpc_lsa_EnumTrustDom(p, mem_ctx, &r);
421         if (!NT_STATUS_IS_OK(status)) {
422                 printf("EnumTrustDom failed - %s\n", nt_errstr(status));
423                 return False;
424         }
425
426         printf("lookup gave %d domains (max_count=%d)\n", 
427                domains.count,
428                domains.max_count);
429         for (i=0;i<r.out.domains->count;i++) {
430                 printf("name='%s' sid=%s\n", 
431                        domains.domains[i].name.name,
432                        lsa_sid_string_talloc(mem_ctx, domains.domains[i].sid));
433         }
434
435         return True;
436 }
437
438 static BOOL test_Delete(struct dcerpc_pipe *p, 
439                        TALLOC_CTX *mem_ctx, 
440                        struct policy_handle *handle)
441 {
442         NTSTATUS status;
443         struct lsa_Delete r;
444
445         printf("\ntesting Delete - but what does it do?\n");
446
447         r.in.handle = handle;
448         status = dcerpc_lsa_Delete(p, mem_ctx, &r);
449         if (!NT_STATUS_IS_OK(status)) {
450                 printf("Delete failed - %s\n", nt_errstr(status));
451                 return False;
452         }
453
454         printf("\n");
455
456         return True;
457 }
458
459 static BOOL test_Close(struct dcerpc_pipe *p, 
460                        TALLOC_CTX *mem_ctx, 
461                        struct policy_handle *handle)
462 {
463         NTSTATUS status;
464         struct lsa_Close r;
465         struct policy_handle handle2;
466
467         printf("\ntesting Close\n");
468
469         r.in.handle = handle;
470         r.out.handle = &handle2;
471
472         status = dcerpc_lsa_Close(p, mem_ctx, &r);
473         if (!NT_STATUS_IS_OK(status)) {
474                 printf("Close failed - %s\n", nt_errstr(status));
475                 return False;
476         }
477
478         status = dcerpc_lsa_Close(p, mem_ctx, &r);
479         /* its really a fault - we need a status code for rpc fault */
480         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) {
481                 printf("Close failed - %s\n", nt_errstr(status));
482                 return False;
483         }
484
485         printf("\n");
486
487         return True;
488 }
489
490 BOOL torture_rpc_lsa(int dummy)
491 {
492         NTSTATUS status;
493         struct dcerpc_pipe *p;
494         TALLOC_CTX *mem_ctx;
495         BOOL ret = True;
496         struct policy_handle handle;
497
498         mem_ctx = talloc_init("torture_rpc_lsa");
499
500         status = torture_rpc_connection(&p, "lsarpc");
501         if (!NT_STATUS_IS_OK(status)) {
502                 return False;
503         }
504         
505         if (!test_OpenPolicy(p, mem_ctx)) {
506                 ret = False;
507         }
508
509         if (!test_OpenPolicy2(p, mem_ctx, &handle)) {
510                 ret = False;
511         }
512
513         if (!test_EnumAccounts(p, mem_ctx, &handle)) {
514                 ret = False;
515         }
516
517         if (!test_EnumPrivs(p, mem_ctx, &handle)) {
518                 ret = False;
519         }
520
521         if (!test_EnumTrustDom(p, mem_ctx, &handle)) {
522                 ret = False;
523         }
524         
525 #if 0
526         if (!test_Delete(p, mem_ctx, &handle)) {
527                 ret = False;
528         }
529 #endif
530         
531         if (!test_Close(p, mem_ctx, &handle)) {
532                 ret = False;
533         }
534
535         torture_rpc_close(p);
536
537         return ret;
538 }