90db819a33928f647373920dc8310c22b9da3412
[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)) {
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)) {
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_EnumAccounts(struct dcerpc_pipe *p, 
275                           TALLOC_CTX *mem_ctx, 
276                           struct policy_handle *handle)
277 {
278         NTSTATUS status;
279         struct lsa_EnumAccounts r;
280         struct lsa_SidArray sids1, sids2;
281         uint32 resume_handle = 0;
282         int i;
283
284         printf("\ntesting EnumAccounts\n");
285
286         r.in.handle = handle;
287         r.in.resume_handle = &resume_handle;
288         r.in.num_entries = 100;
289         r.out.resume_handle = &resume_handle;
290         r.out.sids = &sids1;
291
292         resume_handle = 0;
293         status = dcerpc_lsa_EnumAccounts(p, mem_ctx, &r);
294         if (!NT_STATUS_IS_OK(status)) {
295                 printf("EnumAccounts failed - %s\n", nt_errstr(status));
296                 return False;
297         }
298
299         printf("Got %d sids resume_handle=%u\n", sids1.num_sids, resume_handle);
300
301         for (i=0;i<sids1.num_sids;i++) {
302                 printf("%s\n", lsa_sid_string_talloc(mem_ctx, sids1.sids[i].sid));
303         }
304
305         if (!test_LookupSids(p, mem_ctx, handle, &sids1)) {
306                 return False;
307         }
308         
309         if (sids1.num_sids < 3) {
310                 return True;
311         }
312         
313         printf("trying EnumAccounts partial listing (asking for 1 at 2)\n");
314         resume_handle = 2;
315         r.in.num_entries = 1;
316         r.out.sids = &sids2;
317
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         if (sids2.num_sids != 1) {
325                 printf("Returned wrong number of entries (%d)\n", sids2.num_sids);
326                 return False;
327         }
328
329         return True;
330 }
331
332
333 static BOOL test_EnumPrivs(struct dcerpc_pipe *p, 
334                            TALLOC_CTX *mem_ctx, 
335                            struct policy_handle *handle)
336 {
337         NTSTATUS status;
338         struct lsa_EnumPrivs r;
339         struct lsa_PrivArray privs1;
340         uint32 resume_handle = 0;
341         int i;
342
343         printf("\ntesting EnumPrivs\n");
344
345         r.in.handle = handle;
346         r.in.resume_handle = &resume_handle;
347         r.in.max_count = 1000;
348         r.out.resume_handle = &resume_handle;
349         r.out.privs = &privs1;
350
351         resume_handle = 0;
352         status = dcerpc_lsa_EnumPrivs(p, mem_ctx, &r);
353         if (!NT_STATUS_IS_OK(status)) {
354                 printf("EnumPrivs failed - %s\n", nt_errstr(status));
355                 return False;
356         }
357
358         printf("Got %d privs resume_handle=%u\n", privs1.count, resume_handle);
359
360         for (i=0;i<privs1.count;i++) {
361                 printf("luid=%08x-%08x '%s'\n", 
362                        privs1.privs[i].luid_low,
363                        privs1.privs[i].luid_high,
364                        privs1.privs[i].name.name);
365         }
366
367         return True;
368 }
369
370
371 static BOOL test_EnumTrustDom(struct dcerpc_pipe *p, 
372                               TALLOC_CTX *mem_ctx, 
373                               struct policy_handle *handle)
374 {
375         struct lsa_EnumTrustDom r;
376         NTSTATUS status;
377         int i;
378         uint32 resume_handle = 0;
379
380         printf("\nTesting EnumTrustDom\n");
381
382         r.in.handle = handle;
383         r.in.resume_handle = &resume_handle;
384         r.in.num_entries = 1000;
385         r.out.resume_handle = &resume_handle;
386
387         status = dcerpc_lsa_EnumTrustDom(p, mem_ctx, &r);
388         if (!NT_STATUS_IS_OK(status)) {
389                 printf("EnumTrustDom failed - %s\n", nt_errstr(status));
390                 return False;
391         }
392
393         if (r.out.domains) {
394                 printf("lookup gave %d domains (max_count=%d)\n", 
395                        r.out.domains->count,
396                        r.out.domains->max_count);
397                 for (i=0;i<r.out.domains->count;i++) {
398                         printf("name='%s' sid=%s\n", 
399                                r.out.domains->domains[i].name.name,
400                                lsa_sid_string_talloc(mem_ctx, r.out.domains->domains[i].sid));
401                 }
402         }
403
404         return True;
405 }
406
407 static BOOL test_Delete(struct dcerpc_pipe *p, 
408                        TALLOC_CTX *mem_ctx, 
409                        struct policy_handle *handle)
410 {
411         NTSTATUS status;
412         struct lsa_Delete r;
413
414         printf("\ntesting Delete - but what does it do?\n");
415
416         r.in.handle = handle;
417         status = dcerpc_lsa_Delete(p, mem_ctx, &r);
418         if (!NT_STATUS_IS_OK(status)) {
419                 printf("Delete failed - %s\n", nt_errstr(status));
420                 return False;
421         }
422
423         printf("\n");
424
425         return True;
426 }
427
428 static BOOL test_Close(struct dcerpc_pipe *p, 
429                        TALLOC_CTX *mem_ctx, 
430                        struct policy_handle *handle)
431 {
432         NTSTATUS status;
433         struct lsa_Close r;
434
435         printf("\ntesting Close\n");
436
437         r.in.handle = handle;
438         status = dcerpc_lsa_Close(p, mem_ctx, &r);
439         if (!NT_STATUS_IS_OK(status)) {
440                 printf("Close failed - %s\n", nt_errstr(status));
441                 return False;
442         }
443
444         status = dcerpc_lsa_Close(p, mem_ctx, &r);
445         /* its really a fault - we need a status code for rpc fault */
446         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) {
447                 printf("Close failed - %s\n", nt_errstr(status));
448                 return False;
449         }
450
451         printf("\n");
452
453         return True;
454 }
455
456 BOOL torture_rpc_lsa(int dummy)
457 {
458         NTSTATUS status;
459         struct dcerpc_pipe *p;
460         TALLOC_CTX *mem_ctx;
461         BOOL ret = True;
462         struct policy_handle handle;
463
464         mem_ctx = talloc_init("torture_rpc_lsa");
465
466         status = torture_rpc_connection(&p, "lsarpc");
467         if (!NT_STATUS_IS_OK(status)) {
468                 return False;
469         }
470         
471         if (!test_OpenPolicy(p, mem_ctx)) {
472                 ret = False;
473         }
474
475         if (!test_OpenPolicy2(p, mem_ctx, &handle)) {
476                 ret = False;
477         }
478
479         if (!test_EnumAccounts(p, mem_ctx, &handle)) {
480                 ret = False;
481         }
482
483         if (!test_EnumPrivs(p, mem_ctx, &handle)) {
484                 ret = False;
485         }
486
487         if (!test_EnumTrustDom(p, mem_ctx, &handle)) {
488                 ret = False;
489         }
490         
491 #if 0
492         if (!test_Delete(p, mem_ctx, &handle)) {
493                 ret = False;
494         }
495 #endif
496         
497         if (!test_Close(p, mem_ctx, &handle)) {
498                 ret = False;
499         }
500
501         torture_rpc_close(p);
502
503         return ret;
504 }