* fixed NDR flag inheritance across push subcontexts
[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   this makes the debug code display the right thing
26 */
27 static void init_lsa_Name(struct lsa_Name *name, const char *s)
28 {
29         name->name = s;
30         name->name_len = strlen_m(s)*2;
31         name->name_size = name->name_len;
32 }
33
34 static BOOL test_OpenPolicy(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
35 {
36         struct lsa_ObjectAttribute attr;
37         struct policy_handle handle;
38         struct lsa_QosInfo qos;
39         struct lsa_OpenPolicy r;
40         NTSTATUS status;
41         uint16 system_name = '\\';
42
43         printf("\ntesting OpenPolicy\n");
44
45         qos.len = 0;
46         qos.impersonation_level = 2;
47         qos.context_mode = 1;
48         qos.effective_only = 0;
49
50         attr.len = 0;
51         attr.root_dir = NULL;
52         attr.object_name = NULL;
53         attr.attributes = 0;
54         attr.sec_desc = NULL;
55         attr.sec_qos = &qos;
56
57         r.in.system_name = &system_name;
58         r.in.attr = &attr;
59         r.in.desired_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
60         r.out.handle = &handle;
61
62         status = dcerpc_lsa_OpenPolicy(p, mem_ctx, &r);
63         if (!NT_STATUS_IS_OK(status)) {
64                 printf("OpenPolicy failed - %s\n", nt_errstr(status));
65                 return False;
66         }
67
68         return True;
69 }
70
71
72 static BOOL test_OpenPolicy2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
73                              struct policy_handle *handle)
74 {
75         struct lsa_ObjectAttribute attr;
76         struct lsa_QosInfo qos;
77         struct lsa_OpenPolicy2 r;
78         NTSTATUS status;
79
80         printf("\ntesting OpenPolicy2\n");
81
82         qos.len = 0;
83         qos.impersonation_level = 2;
84         qos.context_mode = 1;
85         qos.effective_only = 0;
86
87         attr.len = 0;
88         attr.root_dir = NULL;
89         attr.object_name = NULL;
90         attr.attributes = 0;
91         attr.sec_desc = NULL;
92         attr.sec_qos = &qos;
93
94         r.in.system_name = "\\";
95         r.in.attr = &attr;
96         r.in.desired_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
97         r.out.handle = handle;
98
99         status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &r);
100         if (!NT_STATUS_IS_OK(status)) {
101                 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
102                 return False;
103         }
104
105         return True;
106 }
107
108 static BOOL test_LookupNames(struct dcerpc_pipe *p, 
109                             TALLOC_CTX *mem_ctx, 
110                             struct policy_handle *handle,
111                             struct lsa_TransNameArray *tnames)
112 {
113         struct lsa_LookupNames r;
114         struct lsa_TransSidArray sids;
115         struct lsa_Name *names;
116         uint32 count = 0;
117         NTSTATUS status;
118         int i;
119
120         printf("\nTesting LookupNames\n");
121
122         sids.count = 0;
123         sids.sids = NULL;
124
125         names = talloc(mem_ctx, tnames->count * sizeof(names[0]));
126         for (i=0;i<tnames->count;i++) {
127                 init_lsa_Name(&names[i], tnames->names[i].name.name);
128         }
129
130         r.in.handle = handle;
131         r.in.num_names = tnames->count;
132         r.in.names = names;
133         r.in.sids = &sids;
134         r.in.level = 1;
135         r.in.count = &count;
136         r.out.count = &count;
137         r.out.sids = &sids;
138
139         status = dcerpc_lsa_LookupNames(p, mem_ctx, &r);
140         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
141                 printf("LookupNames failed - %s\n", nt_errstr(status));
142                 return False;
143         }
144
145         printf("\n");
146
147         return True;
148 }
149
150
151 static BOOL test_LookupSids(struct dcerpc_pipe *p, 
152                             TALLOC_CTX *mem_ctx, 
153                             struct policy_handle *handle,
154                             struct lsa_SidArray *sids)
155 {
156         struct lsa_LookupSids r;
157         struct lsa_TransNameArray names;
158         uint32 count = sids->num_sids;
159         NTSTATUS status;
160
161         printf("\nTesting LookupSids\n");
162
163         names.count = 0;
164         names.names = NULL;
165
166         r.in.handle = handle;
167         r.in.sids = sids;
168         r.in.names = &names;
169         r.in.level = 1;
170         r.in.count = &count;
171         r.out.count = &count;
172         r.out.names = &names;
173
174         status = dcerpc_lsa_LookupSids(p, mem_ctx, &r);
175         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
176                 printf("LookupSids failed - %s\n", nt_errstr(status));
177                 return False;
178         }
179
180         printf("\n");
181
182         if (!test_LookupNames(p, mem_ctx, handle, &names)) {
183                 return False;
184         }
185
186         return True;
187 }
188
189 static BOOL test_LookupPrivName(struct dcerpc_pipe *p, 
190                                 TALLOC_CTX *mem_ctx, 
191                                 struct policy_handle *handle,
192                                 struct lsa_LUID *luid)
193 {
194         NTSTATUS status;
195         struct lsa_LookupPrivName r;
196
197         r.in.handle = handle;
198         r.in.luid = luid;
199
200         status = dcerpc_lsa_LookupPrivName(p, mem_ctx, &r);
201         if (!NT_STATUS_IS_OK(status)) {
202                 printf("\nLookupPrivName failed - %s\n", nt_errstr(status));
203                 return False;
204         }
205
206         return True;
207 }
208
209 static BOOL test_EnumPrivsAccount(struct dcerpc_pipe *p, 
210                                   TALLOC_CTX *mem_ctx,                            
211                                   struct policy_handle *handle,
212                                   struct policy_handle *acct_handle)
213 {
214         NTSTATUS status;
215         struct lsa_EnumPrivsAccount r;
216
217         printf("Testing EnumPrivsAccount\n");
218
219         r.in.handle = acct_handle;
220
221         status = dcerpc_lsa_EnumPrivsAccount(p, mem_ctx, &r);
222         if (!NT_STATUS_IS_OK(status)) {
223                 printf("EnumPrivsAccount failed - %s\n", nt_errstr(status));
224                 return False;
225         }
226
227         if (r.out.privs) {
228                 int i;
229                 for (i=0;i<r.out.privs->count;i++) {
230                         test_LookupPrivName(p, mem_ctx, handle, 
231                                             &r.out.privs->set[i].luid);
232                 }
233         }
234
235         return True;
236 }
237
238 static BOOL test_EnumAccountRights(struct dcerpc_pipe *p, 
239                                    TALLOC_CTX *mem_ctx, 
240                                    struct policy_handle *acct_handle,
241                                    struct dom_sid *sid)
242 {
243         NTSTATUS status;
244         struct lsa_EnumAccountRights r;
245         struct lsa_RightSet rights;
246
247         printf("Testing EnumAccountRights\n");
248
249         r.in.handle = acct_handle;
250         r.in.sid = sid;
251         r.out.rights = &rights;
252
253         status = dcerpc_lsa_EnumAccountRights(p, mem_ctx, &r);
254         if (!NT_STATUS_IS_OK(status)) {
255                 printf("EnumAccountRights failed - %s\n", nt_errstr(status));
256                 return False;
257         }
258
259         return True;
260 }
261
262
263 static BOOL test_QuerySecObj(struct dcerpc_pipe *p, 
264                              TALLOC_CTX *mem_ctx, 
265                              struct policy_handle *handle,
266                              struct policy_handle *acct_handle)
267 {
268         NTSTATUS status;
269         struct lsa_QuerySecObj r;
270
271         printf("Testing QuerySecObj\n");
272
273         r.in.handle = acct_handle;
274         r.in.sec_info = 7;
275
276         status = dcerpc_lsa_QuerySecObj(p, mem_ctx, &r);
277         if (!NT_STATUS_IS_OK(status)) {
278                 printf("QuerySecObj failed - %s\n", nt_errstr(status));
279                 return False;
280         }
281
282         return True;
283 }
284
285 static BOOL test_OpenAccount(struct dcerpc_pipe *p, 
286                              TALLOC_CTX *mem_ctx, 
287                              struct policy_handle *handle,
288                              struct dom_sid *sid)
289 {
290         NTSTATUS status;
291         struct lsa_OpenAccount r;
292         struct policy_handle acct_handle;
293
294         printf("Testing OpenAccount\n");
295
296         r.in.handle = handle;
297         r.in.sid = sid;
298         r.in.desired_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
299         r.out.acct_handle = &acct_handle;
300
301         status = dcerpc_lsa_OpenAccount(p, mem_ctx, &r);
302         if (!NT_STATUS_IS_OK(status)) {
303                 printf("OpenAccount failed - %s\n", nt_errstr(status));
304                 return False;
305         }
306
307         if (!test_EnumPrivsAccount(p, mem_ctx, handle, &acct_handle)) {
308                 return False;
309         }
310
311         if (!test_QuerySecObj(p, mem_ctx, handle, &acct_handle)) {
312                 return False;
313         }
314
315         return True;
316 }
317
318 static BOOL test_EnumAccounts(struct dcerpc_pipe *p, 
319                           TALLOC_CTX *mem_ctx, 
320                           struct policy_handle *handle)
321 {
322         NTSTATUS status;
323         struct lsa_EnumAccounts r;
324         struct lsa_SidArray sids1, sids2;
325         uint32 resume_handle = 0;
326         int i;
327
328         printf("\ntesting EnumAccounts\n");
329
330         r.in.handle = handle;
331         r.in.resume_handle = &resume_handle;
332         r.in.num_entries = 100;
333         r.out.resume_handle = &resume_handle;
334         r.out.sids = &sids1;
335
336         resume_handle = 0;
337         status = dcerpc_lsa_EnumAccounts(p, mem_ctx, &r);
338         if (!NT_STATUS_IS_OK(status)) {
339                 printf("EnumAccounts failed - %s\n", nt_errstr(status));
340                 return False;
341         }
342
343         if (!test_LookupSids(p, mem_ctx, handle, &sids1)) {
344                 return False;
345         }
346
347         printf("testing all accounts\n");
348         for (i=0;i<sids1.num_sids;i++) {
349                 test_OpenAccount(p, mem_ctx, handle, sids1.sids[i].sid);
350                 test_EnumAccountRights(p, mem_ctx, handle, sids1.sids[i].sid);
351         }
352         printf("\n");
353
354         if (sids1.num_sids < 3) {
355                 return True;
356         }
357         
358         printf("trying EnumAccounts partial listing (asking for 1 at 2)\n");
359         resume_handle = 2;
360         r.in.num_entries = 1;
361         r.out.sids = &sids2;
362
363         status = dcerpc_lsa_EnumAccounts(p, mem_ctx, &r);
364         if (!NT_STATUS_IS_OK(status)) {
365                 printf("EnumAccounts failed - %s\n", nt_errstr(status));
366                 return False;
367         }
368
369         if (sids2.num_sids != 1) {
370                 printf("Returned wrong number of entries (%d)\n", sids2.num_sids);
371                 return False;
372         }
373
374         return True;
375 }
376
377
378 static BOOL test_EnumPrivs(struct dcerpc_pipe *p, 
379                            TALLOC_CTX *mem_ctx, 
380                            struct policy_handle *handle)
381 {
382         NTSTATUS status;
383         struct lsa_EnumPrivs r;
384         struct lsa_PrivArray privs1;
385         uint32 resume_handle = 0;
386
387         printf("\ntesting EnumPrivs\n");
388
389         r.in.handle = handle;
390         r.in.resume_handle = &resume_handle;
391         r.in.max_count = 1000;
392         r.out.resume_handle = &resume_handle;
393         r.out.privs = &privs1;
394
395         resume_handle = 0;
396         status = dcerpc_lsa_EnumPrivs(p, mem_ctx, &r);
397         if (!NT_STATUS_IS_OK(status)) {
398                 printf("EnumPrivs failed - %s\n", nt_errstr(status));
399                 return False;
400         }
401
402         return True;
403 }
404
405
406 static BOOL test_EnumTrustDom(struct dcerpc_pipe *p, 
407                               TALLOC_CTX *mem_ctx, 
408                               struct policy_handle *handle)
409 {
410         struct lsa_EnumTrustDom r;
411         NTSTATUS status;
412         uint32 resume_handle = 0;
413         struct lsa_DomainList domains;
414
415         printf("\nTesting EnumTrustDom\n");
416
417         r.in.handle = handle;
418         r.in.resume_handle = &resume_handle;
419         r.in.num_entries = 1000;
420         r.out.domains = &domains;
421         r.out.resume_handle = &resume_handle;
422
423         status = dcerpc_lsa_EnumTrustDom(p, mem_ctx, &r);
424
425         /* NO_MORE_ENTRIES is allowed */
426         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
427                 return True;
428         }
429
430         if (!NT_STATUS_IS_OK(status)) {
431                 printf("EnumTrustDom failed - %s\n", nt_errstr(status));
432                 return False;
433         }
434
435         return True;
436 }
437
438 static BOOL test_QueryInfoPolicy(struct dcerpc_pipe *p, 
439                                  TALLOC_CTX *mem_ctx, 
440                                  struct policy_handle *handle)
441 {
442         struct lsa_QueryInfoPolicy r;
443         NTSTATUS status;
444         int i;
445         BOOL ret = True;
446         printf("\nTesting QueryInfoPolicy\n");
447
448         for (i=1;i<13;i++) {
449                 r.in.handle = handle;
450                 r.in.level = i;
451
452                 printf("\ntrying QueryInfoPolicy level %d\n", i);
453
454                 status = dcerpc_lsa_QueryInfoPolicy(p, mem_ctx, &r);
455
456                 if ((i == 9 || i == 10 || i == 11) &&
457                     NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
458                         printf("server failed level %u (OK)\n", i);
459                         continue;
460                 }
461
462                 if (!NT_STATUS_IS_OK(status)) {
463                         printf("QueryInfoPolicy failed - %s\n", nt_errstr(status));
464                         ret = False;
465                         continue;
466                 }
467         }
468
469         return ret;
470 }
471
472 static BOOL test_Delete(struct dcerpc_pipe *p, 
473                        TALLOC_CTX *mem_ctx, 
474                        struct policy_handle *handle)
475 {
476         NTSTATUS status;
477         struct lsa_Delete r;
478
479         printf("\ntesting Delete - but what does it do?\n");
480
481         r.in.handle = handle;
482         status = dcerpc_lsa_Delete(p, mem_ctx, &r);
483         if (!NT_STATUS_IS_OK(status)) {
484                 printf("Delete failed - %s\n", nt_errstr(status));
485                 return False;
486         }
487
488         printf("\n");
489
490         return True;
491 }
492
493 static BOOL test_Close(struct dcerpc_pipe *p, 
494                        TALLOC_CTX *mem_ctx, 
495                        struct policy_handle *handle)
496 {
497         NTSTATUS status;
498         struct lsa_Close r;
499         struct policy_handle handle2;
500
501         printf("\ntesting Close\n");
502
503         r.in.handle = handle;
504         r.out.handle = &handle2;
505
506         status = dcerpc_lsa_Close(p, mem_ctx, &r);
507         if (!NT_STATUS_IS_OK(status)) {
508                 printf("Close failed - %s\n", nt_errstr(status));
509                 return False;
510         }
511
512         status = dcerpc_lsa_Close(p, mem_ctx, &r);
513         /* its really a fault - we need a status code for rpc fault */
514         if (!NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
515                 printf("Close failed - %s\n", nt_errstr(status));
516                 return False;
517         }
518
519         printf("\n");
520
521         return True;
522 }
523
524 BOOL torture_rpc_lsa(int dummy)
525 {
526         NTSTATUS status;
527         struct dcerpc_pipe *p;
528         TALLOC_CTX *mem_ctx;
529         BOOL ret = True;
530         struct policy_handle handle;
531
532         mem_ctx = talloc_init("torture_rpc_lsa");
533
534         status = torture_rpc_connection(&p, 
535                                         DCERPC_LSARPC_NAME, 
536                                         DCERPC_LSARPC_UUID, 
537                                         DCERPC_LSARPC_VERSION);
538         if (!NT_STATUS_IS_OK(status)) {
539                 return False;
540         }
541         
542         p->flags |= DCERPC_DEBUG_PRINT_BOTH;
543
544         if (!test_OpenPolicy(p, mem_ctx)) {
545                 ret = False;
546         }
547
548         if (!test_OpenPolicy2(p, mem_ctx, &handle)) {
549                 ret = False;
550         }
551
552         if (!test_EnumAccounts(p, mem_ctx, &handle)) {
553                 ret = False;
554         }
555
556         if (!test_EnumPrivs(p, mem_ctx, &handle)) {
557                 ret = False;
558         }
559
560         if (!test_EnumTrustDom(p, mem_ctx, &handle)) {
561                 ret = False;
562         }
563
564         if (!test_QueryInfoPolicy(p, mem_ctx, &handle)) {
565                 ret = False;
566         }
567         
568 #if 0
569         if (!test_Delete(p, mem_ctx, &handle)) {
570                 ret = False;
571         }
572 #endif
573         
574         if (!test_Close(p, mem_ctx, &handle)) {
575                 ret = False;
576         }
577
578         talloc_destroy(mem_ctx);
579
580         torture_rpc_close(p);
581
582         return ret;
583 }