added samr_LookupRids() and test code
[samba.git] / source4 / torture / rpc / samr.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for samr 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 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
26                                struct policy_handle *handle);
27
28 /*
29   this makes the debug code display the right thing
30 */
31 static void init_samr_Name(struct samr_Name *name, const char *s)
32 {
33         name->name = s;
34         name->name_len = strlen_m(s)*2;
35         name->name_size = name->name_len;
36 }
37
38 static BOOL test_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
39                        struct policy_handle *handle)
40 {
41         NTSTATUS status;
42         struct samr_Close r;
43
44         r.in.handle = handle;
45         r.out.handle = handle;
46
47         status = dcerpc_samr_Close(p, mem_ctx, &r);
48         if (!NT_STATUS_IS_OK(status)) {
49                 printf("Close handle failed - %s\n", nt_errstr(status));
50                 return False;
51         }
52
53         return True;
54 }
55
56
57 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
58                                struct policy_handle *handle)
59 {
60         NTSTATUS status;
61         struct samr_QuerySecurity r;
62
63         r.in.handle = handle;
64         r.in.sec_info = 7;
65
66         status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
67         if (!NT_STATUS_IS_OK(status)) {
68                 printf("QuerySecurity failed - %s\n", nt_errstr(status));
69                 return False;
70         }
71
72         return True;
73 }
74
75 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
76                           struct policy_handle *handle)
77 {
78         BOOL ret = True;
79
80         if (!test_QuerySecurity(p, mem_ctx, handle)) {
81                 ret = False;
82         }
83
84         if (!test_QueryUserInfo(p, mem_ctx, handle)) {
85                 ret = False;
86         }
87
88         return ret;
89 }
90
91
92 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
93                             struct policy_handle *handle)
94 {
95         NTSTATUS status;
96         struct samr_CreateUser r;
97         struct samr_DeleteUser d;
98         struct policy_handle acct_handle;
99         uint32 rid;
100         struct samr_Name name;
101         BOOL ret = True;
102
103         init_samr_Name(&name, "samrtorturetest");
104
105         r.in.handle = handle;
106         r.in.username = &name;
107         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
108         r.out.acct_handle = &acct_handle;
109         r.out.rid = &rid;
110
111         printf("Testing CreateUser(%s)\n", r.in.username->name);
112
113         status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
114
115         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
116                 printf("Server refused create of '%s'\n", r.in.username->name);
117                 return True;
118         }
119
120         if (!NT_STATUS_IS_OK(status) && 
121             !NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
122                 printf("CreateUser failed - %s\n", nt_errstr(status));
123                 return False;
124         }
125
126
127         if (!test_user_ops(p, mem_ctx, &acct_handle)) {
128                 ret = False;
129         }
130
131         printf("Testing DeleteUser\n");
132
133         d.in.handle = &acct_handle;
134         d.out.handle = &acct_handle;
135
136         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
137         if (!NT_STATUS_IS_OK(status)) {
138                 printf("DeleteUser failed - %s\n", nt_errstr(status));
139                 ret = False;
140         }
141
142         return ret;
143 }
144
145 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
146                                 struct policy_handle *handle)
147 {
148         NTSTATUS status;
149         struct samr_QueryAliasInfo r;
150         uint16 levels[] = {1, 2, 3};
151         int i;
152         BOOL ret = True;
153
154         for (i=0;i<ARRAY_SIZE(levels);i++) {
155                 printf("Testing QueryAliasInfo level %u\n", levels[i]);
156
157                 r.in.handle = handle;
158                 r.in.level = levels[i];
159
160                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
161                 if (!NT_STATUS_IS_OK(status)) {
162                         printf("QueryAliasInfo level %u failed - %s\n", 
163                                levels[i], nt_errstr(status));
164                         ret = False;
165                 }
166         }
167
168         return ret;
169 }
170
171 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
172                                 struct policy_handle *handle)
173 {
174         NTSTATUS status;
175         struct samr_QueryGroupInfo r;
176         uint16 levels[] = {1, 2, 3, 4};
177         int i;
178         BOOL ret = True;
179
180         for (i=0;i<ARRAY_SIZE(levels);i++) {
181                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
182
183                 r.in.handle = handle;
184                 r.in.level = levels[i];
185
186                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
187                 if (!NT_STATUS_IS_OK(status)) {
188                         printf("QueryGroupInfo level %u failed - %s\n", 
189                                levels[i], nt_errstr(status));
190                         ret = False;
191                 }
192         }
193
194         return ret;
195 }
196
197 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
198                                struct policy_handle *handle)
199 {
200         NTSTATUS status;
201         struct samr_QueryUserInfo r;
202         uint16 levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
203                            11, 12, 13, 14, 16, 17, 20, 21};
204         int i;
205         BOOL ret = True;
206
207         for (i=0;i<ARRAY_SIZE(levels);i++) {
208                 printf("Testing QueryUserInfo level %u\n", levels[i]);
209
210                 r.in.handle = handle;
211                 r.in.level = levels[i];
212
213                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
214                 if (!NT_STATUS_IS_OK(status)) {
215                         printf("QueryUserInfo level %u failed - %s\n", 
216                                levels[i], nt_errstr(status));
217                         ret = False;
218                 }
219         }
220
221         return ret;
222 }
223
224 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
225                           struct policy_handle *handle, uint32 rid)
226 {
227         NTSTATUS status;
228         struct samr_OpenUser r;
229         struct policy_handle acct_handle;
230         BOOL ret = True;
231
232         printf("Testing OpenUser(%u)\n", rid);
233
234         r.in.handle = handle;
235         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
236         r.in.rid = rid;
237         r.out.acct_handle = &acct_handle;
238
239         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
240         if (!NT_STATUS_IS_OK(status)) {
241                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
242                 return False;
243         }
244
245         if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
246                 ret = False;
247         }
248
249         if (!test_QueryUserInfo(p, mem_ctx, &acct_handle)) {
250                 ret = False;
251         }
252
253         if (!test_Close(p, mem_ctx, &acct_handle)) {
254                 ret = False;
255         }
256
257         return ret;
258 }
259
260 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
261                            struct policy_handle *handle, uint32 rid)
262 {
263         NTSTATUS status;
264         struct samr_OpenGroup r;
265         struct policy_handle acct_handle;
266         BOOL ret = True;
267
268         printf("Testing OpenGroup(%u)\n", rid);
269
270         r.in.handle = handle;
271         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
272         r.in.rid = rid;
273         r.out.acct_handle = &acct_handle;
274
275         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
276         if (!NT_STATUS_IS_OK(status)) {
277                 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
278                 return False;
279         }
280
281         if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
282                 ret = False;
283         }
284
285         if (!test_QueryGroupInfo(p, mem_ctx, &acct_handle)) {
286                 ret = False;
287         }
288
289         if (!test_Close(p, mem_ctx, &acct_handle)) {
290                 ret = False;
291         }
292
293         return ret;
294 }
295
296 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
297                            struct policy_handle *handle, uint32 rid)
298 {
299         NTSTATUS status;
300         struct samr_OpenAlias r;
301         struct policy_handle acct_handle;
302         BOOL ret = True;
303
304         printf("Testing OpenAlias(%u)\n", rid);
305
306         r.in.handle = handle;
307         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
308         r.in.rid = rid;
309         r.out.acct_handle = &acct_handle;
310
311         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
312         if (!NT_STATUS_IS_OK(status)) {
313                 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
314                 return False;
315         }
316
317         if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
318                 ret = False;
319         }
320
321         if (!test_QueryAliasInfo(p, mem_ctx, &acct_handle)) {
322                 ret = False;
323         }
324
325         if (!test_Close(p, mem_ctx, &acct_handle)) {
326                 ret = False;
327         }
328
329         return ret;
330 }
331
332 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
333                                  struct policy_handle *handle)
334 {
335         NTSTATUS status;
336         struct samr_EnumDomainUsers r;
337         uint32 resume_handle=0;
338         int i;
339         BOOL ret = True;
340         struct samr_LookupNames n;
341         struct samr_LookupRids  lr ;
342
343         printf("Testing EnumDomainUsers\n");
344
345         r.in.handle = handle;
346         r.in.resume_handle = &resume_handle;
347         r.in.acct_flags = 0;
348         r.in.max_size = (uint32)-1;
349         r.out.resume_handle = &resume_handle;
350
351         status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
352         if (!NT_STATUS_IS_OK(status)) {
353                 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
354                 return False;
355         }
356         
357         if (!r.out.sam) {
358                 return False;
359         }
360
361         if (r.out.sam->count == 0) {
362                 return True;
363         }
364
365         for (i=0;i<r.out.sam->count;i++) {
366                 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
367                         ret = False;
368                 }
369         }
370
371         printf("Testing LookupNames\n");
372         n.in.handle = handle;
373         n.in.num_names = r.out.sam->count;
374         n.in.names = talloc(mem_ctx, r.out.sam->count * sizeof(struct samr_Name));
375         for (i=0;i<r.out.sam->count;i++) {
376                 n.in.names[i] = r.out.sam->entries[i].name;
377         }
378         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
379         if (!NT_STATUS_IS_OK(status)) {
380                 printf("LookupNames failed - %s\n", nt_errstr(status));
381                 ret = False;
382         }
383
384
385         printf("Testing LookupRids\n");
386         lr.in.handle = handle;
387         lr.in.num_rids = r.out.sam->count;
388         lr.in.rids = talloc(mem_ctx, r.out.sam->count * sizeof(uint32));
389         for (i=0;i<r.out.sam->count;i++) {
390                 lr.in.rids[i] = r.out.sam->entries[i].idx;
391         }
392         status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
393         if (!NT_STATUS_IS_OK(status)) {
394                 printf("LookupRids failed - %s\n", nt_errstr(status));
395                 ret = False;
396         }
397
398         return ret;     
399 }
400
401 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
402                                   struct policy_handle *handle)
403 {
404         NTSTATUS status;
405         struct samr_EnumDomainGroups r;
406         uint32 resume_handle=0;
407         int i;
408         BOOL ret = True;
409
410         printf("Testing EnumDomainGroups\n");
411
412         r.in.handle = handle;
413         r.in.resume_handle = &resume_handle;
414         r.in.max_size = (uint32)-1;
415         r.out.resume_handle = &resume_handle;
416
417         status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
418         if (!NT_STATUS_IS_OK(status)) {
419                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
420                 return False;
421         }
422         
423         if (!r.out.sam) {
424                 return False;
425         }
426
427         for (i=0;i<r.out.sam->count;i++) {
428                 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
429                         ret = False;
430                 }
431         }
432
433         return ret;
434 }
435
436 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
437                                    struct policy_handle *handle)
438 {
439         NTSTATUS status;
440         struct samr_EnumDomainAliases r;
441         uint32 resume_handle=0;
442         int i;
443         BOOL ret = True;
444
445         printf("Testing EnumDomainAliases\n");
446
447         r.in.handle = handle;
448         r.in.resume_handle = &resume_handle;
449         r.in.max_size = (uint32)-1;
450         r.out.resume_handle = &resume_handle;
451
452         status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
453         if (!NT_STATUS_IS_OK(status)) {
454                 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
455                 return False;
456         }
457         
458         if (!r.out.sam) {
459                 return False;
460         }
461
462         for (i=0;i<r.out.sam->count;i++) {
463                 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
464                         ret = False;
465                 }
466         }
467
468         return ret;     
469 }
470
471 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
472                                  struct policy_handle *handle)
473 {
474         NTSTATUS status;
475         struct samr_QueryDomainInfo r;
476         uint16 levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
477         int i;
478         BOOL ret = True;
479
480         for (i=0;i<ARRAY_SIZE(levels);i++) {
481                 printf("Testing QueryDomainInfo level %u\n", levels[i]);
482
483                 r.in.handle = handle;
484                 r.in.level = levels[i];
485
486                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
487                 if (!NT_STATUS_IS_OK(status)) {
488                         printf("QueryDomainInfo level %u failed - %s\n", 
489                                r.in.level, nt_errstr(status));
490                         ret = False;
491                         continue;
492                 }
493         }
494
495         return True;    
496 }
497
498 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
499                             struct policy_handle *handle, struct dom_sid2 *sid)
500 {
501         NTSTATUS status;
502         struct samr_OpenDomain r;
503         struct policy_handle domain_handle;
504         BOOL ret = True;
505
506         printf("Testing OpenDomain\n");
507
508         r.in.handle = handle;
509         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
510         r.in.sid = sid;
511         r.out.domain_handle = &domain_handle;
512
513         status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
514         if (!NT_STATUS_IS_OK(status)) {
515                 printf("OpenDomain failed - %s\n", nt_errstr(status));
516                 return False;
517         }
518
519         if (!test_CreateUser(p, mem_ctx, &domain_handle)) {
520                 ret = False;
521         }
522
523         if (!test_QuerySecurity(p, mem_ctx, &domain_handle)) {
524                 ret = False;
525         }
526
527         if (!test_QueryDomainInfo(p, mem_ctx, &domain_handle)) {
528                 ret = False;
529         }
530
531         if (!test_EnumDomainUsers(p, mem_ctx, &domain_handle)) {
532                 ret = False;
533         }
534
535         if (!test_EnumDomainGroups(p, mem_ctx, &domain_handle)) {
536                 ret = False;
537         }
538
539         if (!test_EnumDomainAliases(p, mem_ctx, &domain_handle)) {
540                 ret = False;
541         }
542
543         if (!test_Close(p, mem_ctx, &domain_handle)) {
544                 ret = False;
545         }
546
547         return ret;
548 }
549
550 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
551                               struct policy_handle *handle, struct samr_Name *domain)
552 {
553         NTSTATUS status;
554         struct samr_LookupDomain r;
555
556         printf("Testing LookupDomain(%s)\n", domain->name);
557
558         r.in.handle = handle;
559         r.in.domain = domain;
560
561         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
562         if (!NT_STATUS_IS_OK(status)) {
563                 printf("LookupDomain failed - %s\n", nt_errstr(status));
564                 return False;
565         }
566
567         if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
568                 return False;
569         }
570
571         return True;    
572 }
573
574
575 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
576                              struct policy_handle *handle)
577 {
578         NTSTATUS status;
579         struct samr_EnumDomains r;
580         uint32 resume_handle = 0;
581         uint32 num_entries=0;
582         int i;
583         BOOL ret = True;
584
585         r.in.handle = handle;
586         r.in.resume_handle = &resume_handle;
587         r.in.buf_size = (uint32)-1;
588         r.out.resume_handle = &resume_handle;
589         r.out.num_entries = &num_entries;
590
591         status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
592         if (!NT_STATUS_IS_OK(status)) {
593                 printf("EnumDomains failed - %s\n", nt_errstr(status));
594                 return False;
595         }
596
597         if (!r.out.sam) {
598                 return False;
599         }
600
601         for (i=0;i<r.out.sam->count;i++) {
602                 if (!test_LookupDomain(p, mem_ctx, handle, 
603                                        &r.out.sam->entries[i].name)) {
604                         ret = False;
605                 }
606         }
607
608         return ret;
609 }
610
611
612 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
613                          struct policy_handle *handle)
614 {
615         NTSTATUS status;
616         struct samr_Connect r;
617         struct samr_Connect4 r4;
618
619         r.in.system_name = 0;
620         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
621         r.out.handle = handle;
622
623         status = dcerpc_samr_Connect(p, mem_ctx, &r);
624         if (!NT_STATUS_IS_OK(status)) {
625                 printf("Connect failed - %s\n", nt_errstr(status));
626                 return False;
627         }
628
629         r4.in.system_name = "";
630         r4.in.unknown = 0;
631         r4.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
632         r4.out.handle = handle;
633
634         status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
635         if (!NT_STATUS_IS_OK(status)) {
636                 printf("Connect4 failed - %s\n", nt_errstr(status));
637                 return False;
638         }
639
640         return True;
641 }
642
643
644 BOOL torture_rpc_samr(int dummy)
645 {
646         NTSTATUS status;
647         struct dcerpc_pipe *p;
648         TALLOC_CTX *mem_ctx;
649         BOOL ret = True;
650         struct policy_handle handle;
651
652         mem_ctx = talloc_init("torture_rpc_samr");
653
654         status = torture_rpc_connection(&p, 
655                                         DCERPC_SAMR_NAME,
656                                         DCERPC_SAMR_UUID,
657                                         DCERPC_SAMR_VERSION);
658         if (!NT_STATUS_IS_OK(status)) {
659                 return False;
660         }
661         
662         p->flags |= DCERPC_DEBUG_PRINT_BOTH;
663
664         if (!test_Connect(p, mem_ctx, &handle)) {
665                 ret = False;
666         }
667
668         if (!test_QuerySecurity(p, mem_ctx, &handle)) {
669                 ret = False;
670         }
671
672         if (!test_EnumDomains(p, mem_ctx, &handle)) {
673                 ret = False;
674         }
675
676         if (!test_Close(p, mem_ctx, &handle)) {
677                 ret = False;
678         }
679
680         torture_rpc_close(p);
681
682         return ret;
683 }