extensive samr_SetUserInfo/samr_QueryUserInfo testing, with
[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_len = strlen_m(s)*2;
34         name->name_size = name->name_len;
35         if (name->name_len == 0) {
36                 name->name = NULL;
37         } else {
38                 name->name = s;
39         }
40 }
41
42 static BOOL test_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
43                        struct policy_handle *handle)
44 {
45         NTSTATUS status;
46         struct samr_Close r;
47
48         r.in.handle = handle;
49         r.out.handle = handle;
50
51         status = dcerpc_samr_Close(p, mem_ctx, &r);
52         if (!NT_STATUS_IS_OK(status)) {
53                 printf("Close handle failed - %s\n", nt_errstr(status));
54                 return False;
55         }
56
57         return True;
58 }
59
60
61 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
62                                struct policy_handle *handle)
63 {
64         NTSTATUS status;
65         struct samr_QuerySecurity r;
66
67         r.in.handle = handle;
68         r.in.sec_info = 7;
69
70         status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
71         if (!NT_STATUS_IS_OK(status)) {
72                 printf("QuerySecurity failed - %s\n", nt_errstr(status));
73                 return False;
74         }
75
76         return True;
77 }
78
79
80 static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
81                              struct policy_handle *handle)
82 {
83         NTSTATUS status;
84         struct samr_SetUserInfo s;
85         struct samr_QueryUserInfo q;
86         struct samr_QueryUserInfo q0;
87         union samr_UserInfo u;
88         BOOL ret = True;
89
90         s.in.handle = handle;
91         s.in.info = &u;
92         q.in.handle = handle;
93         q.out.info = &u;
94         q0 = q;
95
96 #define TESTCALL(call, r) \
97                 status = dcerpc_samr_ ##call(p, mem_ctx, &r); \
98                 if (!NT_STATUS_IS_OK(status)) { \
99                         printf(#call " level %u failed - %s (line %d)\n", \
100                                r.in.level, nt_errstr(status), __LINE__); \
101                         ret = False; \
102                         break; \
103                 }
104
105 #define STRING_EQUAL(s1, s2, field) \
106                 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
107                         printf("Failed to set %s to '%s' (line %d)\n", \
108                                #field, s2, __LINE__); \
109                         ret = False; \
110                         break; \
111                 }
112
113 #define INT_EQUAL(i1, i2, field) \
114                 if (i1 != i2) { \
115                         printf("Failed to set %s to %u (line %d)\n", \
116                                #field, i2, __LINE__); \
117                         ret = False; \
118                         break; \
119                 }
120
121 #define TEST_USERINFO_NAME(lvl1, field1, lvl2, field2, value) do { \
122                 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
123                 q.in.level = lvl1; \
124                 TESTCALL(QueryUserInfo, q) \
125                 s.in.level = lvl1; \
126                 u = *q.out.info; \
127                 init_samr_Name(&u.info ## lvl1.field1, value); \
128                 TESTCALL(SetUserInfo, s) \
129                 init_samr_Name(&u.info ## lvl1.field1, ""); \
130                 TESTCALL(QueryUserInfo, q); \
131                 u = *q.out.info; \
132                 STRING_EQUAL(u.info ## lvl1.field1.name, value, field1); \
133                 q.in.level = lvl2; \
134                 TESTCALL(QueryUserInfo, q) \
135                 u = *q.out.info; \
136                 STRING_EQUAL(u.info ## lvl2.field2.name, value, field2); \
137         } while (0)
138
139 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value) do { \
140                 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
141                 q.in.level = lvl1; \
142                 TESTCALL(QueryUserInfo, q) \
143                 s.in.level = lvl1; \
144                 u = *q.out.info; \
145                 u.info ## lvl1.field1 = value; \
146                 TESTCALL(SetUserInfo, s) \
147                 u.info ## lvl1.field1 = 0; \
148                 TESTCALL(QueryUserInfo, q); \
149                 u = *q.out.info; \
150                 INT_EQUAL(u.info ## lvl1.field1, value, field1); \
151                 q.in.level = lvl2; \
152                 TESTCALL(QueryUserInfo, q) \
153                 u = *q.out.info; \
154                 INT_EQUAL(u.info ## lvl2.field2, value, field1); \
155         } while (0)
156
157         q0.in.level = 12;
158         do { TESTCALL(QueryUserInfo, q0) } while (0);
159
160         TEST_USERINFO_NAME(2, comment,  1, comment, "xx2-1 comment");
161         TEST_USERINFO_NAME(2, comment, 21, comment, "xx2-21 comment");
162
163         TEST_USERINFO_NAME(6, full_name,  1, full_name, "xx6-1 full_name");
164         TEST_USERINFO_NAME(6, full_name,  3, full_name, "xx6-3 full_name");
165         TEST_USERINFO_NAME(6, full_name,  5, full_name, "xx6-5 full_name");
166         TEST_USERINFO_NAME(6, full_name,  6, full_name, "xx6-6 full_name");
167         TEST_USERINFO_NAME(6, full_name,  8, full_name, "xx6-8 full_name");
168         TEST_USERINFO_NAME(6, full_name, 21, full_name, "xx6-21 full_name");
169         TEST_USERINFO_NAME(8, full_name, 21, full_name, "xx7-21 full_name");
170
171         TEST_USERINFO_NAME(11, logon_script, 3, logon_script, "xx11-3 logon_script");
172         TEST_USERINFO_NAME(11, logon_script, 5, logon_script, "xx11-5 logon_script");
173         TEST_USERINFO_NAME(11, logon_script, 21, logon_script, "xx11-21 logon_script");
174
175         TEST_USERINFO_NAME(12, profile,  3, profile, "xx12-3 profile");
176         TEST_USERINFO_NAME(12, profile,  5, profile, "xx12-5 profile");
177         TEST_USERINFO_NAME(12, profile, 21, profile, "xx12-21 profile");
178
179         TEST_USERINFO_NAME(13, description,  1, description, "xx13-1 description");
180         TEST_USERINFO_NAME(13, description,  5, description, "xx13-5 description");
181         TEST_USERINFO_NAME(13, description, 21, description, "xx13-21 description");
182
183         TEST_USERINFO_NAME(14, workstations,  3, workstations, "testworkstation3");
184         TEST_USERINFO_NAME(14, workstations,  5, workstations, "testworkstation5");
185         TEST_USERINFO_NAME(14, workstations, 21, workstations, "testworkstation21");
186
187         TEST_USERINFO_NAME(20, callback, 21, callback, "xx20-21 callback");
188
189         TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__);
190         TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__);
191
192         TEST_USERINFO_INT(4, logon_hours[3],  3, logon_hours[3], __LINE__);
193         TEST_USERINFO_INT(4, logon_hours[3],  5, logon_hours[3], __LINE__);
194         TEST_USERINFO_INT(4, logon_hours[3], 21, logon_hours[3], __LINE__);
195
196         TEST_USERINFO_INT(9, primary_gid,  1, primary_gid, 513);
197         TEST_USERINFO_INT(9, primary_gid,  3, primary_gid, 513);
198         TEST_USERINFO_INT(9, primary_gid,  5, primary_gid, 513);
199         TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
200
201         return ret;
202 }
203
204
205 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
206                           struct policy_handle *handle)
207 {
208         BOOL ret = True;
209
210         if (!test_QuerySecurity(p, mem_ctx, handle)) {
211                 ret = False;
212         }
213
214         if (!test_QueryUserInfo(p, mem_ctx, handle)) {
215                 ret = False;
216         }
217
218         if (!test_SetUserInfo(p, mem_ctx, handle)) {
219                 ret = False;
220         }       
221
222         return ret;
223 }
224
225
226 static BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
227                                    struct policy_handle *handle, const char *name)
228 {
229         NTSTATUS status;
230         struct samr_LookupNames n;
231         struct samr_OpenUser r;
232         struct samr_DeleteUser d;
233         struct policy_handle acct_handle;
234         struct samr_Name sname;
235
236         init_samr_Name(&sname, name);
237
238         n.in.handle = handle;
239         n.in.num_names = 1;
240         n.in.names = &sname;
241         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
242         if (!NT_STATUS_IS_OK(status)) {
243                 goto failed;
244         }
245
246         r.in.handle = handle;
247         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
248         r.in.rid = n.out.rids.ids[0];
249         r.out.acct_handle = &acct_handle;
250         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
251         if (!NT_STATUS_IS_OK(status)) {
252                 goto failed;
253         }
254
255         d.in.handle = &acct_handle;
256         d.out.handle = &acct_handle;
257         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
258         if (!NT_STATUS_IS_OK(status)) {
259                 goto failed;
260         }
261
262         return True;
263
264 failed:
265         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
266         return False;
267 }
268
269
270 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
271                             struct policy_handle *handle)
272 {
273         NTSTATUS status;
274         struct samr_CreateUser r;
275         struct samr_DeleteUser d;
276         struct policy_handle acct_handle;
277         uint32 rid;
278         struct samr_Name name;
279         BOOL ret = True;
280
281         init_samr_Name(&name, "samrtorturetest");
282
283         r.in.handle = handle;
284         r.in.username = &name;
285         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
286         r.out.acct_handle = &acct_handle;
287         r.out.rid = &rid;
288
289         printf("Testing CreateUser(%s)\n", r.in.username->name);
290
291         status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
292
293         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
294                 printf("Server refused create of '%s'\n", r.in.username->name);
295                 return True;
296         }
297
298         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
299                 if (!test_DeleteUser_byname(p, mem_ctx, handle, r.in.username->name)) {
300                         return False;
301                 }
302                 status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
303         }
304         if (!NT_STATUS_IS_OK(status)) {
305                 printf("CreateUser failed - %s\n", nt_errstr(status));
306                 return False;
307         }
308
309
310         if (!test_user_ops(p, mem_ctx, &acct_handle)) {
311                 ret = False;
312         }
313
314         printf("Testing DeleteUser\n");
315
316         d.in.handle = &acct_handle;
317         d.out.handle = &acct_handle;
318
319         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
320         if (!NT_STATUS_IS_OK(status)) {
321                 printf("DeleteUser failed - %s\n", nt_errstr(status));
322                 ret = False;
323         }
324
325         return ret;
326 }
327
328 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
329                                 struct policy_handle *handle)
330 {
331         NTSTATUS status;
332         struct samr_QueryAliasInfo r;
333         uint16 levels[] = {1, 2, 3};
334         int i;
335         BOOL ret = True;
336
337         for (i=0;i<ARRAY_SIZE(levels);i++) {
338                 printf("Testing QueryAliasInfo level %u\n", levels[i]);
339
340                 r.in.handle = handle;
341                 r.in.level = levels[i];
342
343                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
344                 if (!NT_STATUS_IS_OK(status)) {
345                         printf("QueryAliasInfo level %u failed - %s\n", 
346                                levels[i], nt_errstr(status));
347                         ret = False;
348                 }
349         }
350
351         return ret;
352 }
353
354 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
355                                 struct policy_handle *handle)
356 {
357         NTSTATUS status;
358         struct samr_QueryGroupInfo r;
359         uint16 levels[] = {1, 2, 3, 4};
360         int i;
361         BOOL ret = True;
362
363         for (i=0;i<ARRAY_SIZE(levels);i++) {
364                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
365
366                 r.in.handle = handle;
367                 r.in.level = levels[i];
368
369                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
370                 if (!NT_STATUS_IS_OK(status)) {
371                         printf("QueryGroupInfo level %u failed - %s\n", 
372                                levels[i], nt_errstr(status));
373                         ret = False;
374                 }
375         }
376
377         return ret;
378 }
379
380 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
381                                struct policy_handle *handle)
382 {
383         NTSTATUS status;
384         struct samr_QueryUserInfo r;
385         uint16 levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
386                            11, 12, 13, 14, 16, 17, 20, 21};
387         int i;
388         BOOL ret = True;
389
390         for (i=0;i<ARRAY_SIZE(levels);i++) {
391                 printf("Testing QueryUserInfo level %u\n", levels[i]);
392
393                 r.in.handle = handle;
394                 r.in.level = levels[i];
395
396                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
397                 if (!NT_STATUS_IS_OK(status)) {
398                         printf("QueryUserInfo level %u failed - %s\n", 
399                                levels[i], nt_errstr(status));
400                         ret = False;
401                 }
402         }
403
404         return ret;
405 }
406
407 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
408                           struct policy_handle *handle, uint32 rid)
409 {
410         NTSTATUS status;
411         struct samr_OpenUser r;
412         struct policy_handle acct_handle;
413         BOOL ret = True;
414
415         printf("Testing OpenUser(%u)\n", rid);
416
417         r.in.handle = handle;
418         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
419         r.in.rid = rid;
420         r.out.acct_handle = &acct_handle;
421
422         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
423         if (!NT_STATUS_IS_OK(status)) {
424                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
425                 return False;
426         }
427
428         if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
429                 ret = False;
430         }
431
432         if (!test_QueryUserInfo(p, mem_ctx, &acct_handle)) {
433                 ret = False;
434         }
435
436         if (!test_Close(p, mem_ctx, &acct_handle)) {
437                 ret = False;
438         }
439
440         return ret;
441 }
442
443 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
444                            struct policy_handle *handle, uint32 rid)
445 {
446         NTSTATUS status;
447         struct samr_OpenGroup r;
448         struct policy_handle acct_handle;
449         BOOL ret = True;
450
451         printf("Testing OpenGroup(%u)\n", rid);
452
453         r.in.handle = handle;
454         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
455         r.in.rid = rid;
456         r.out.acct_handle = &acct_handle;
457
458         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
459         if (!NT_STATUS_IS_OK(status)) {
460                 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
461                 return False;
462         }
463
464         if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
465                 ret = False;
466         }
467
468         if (!test_QueryGroupInfo(p, mem_ctx, &acct_handle)) {
469                 ret = False;
470         }
471
472         if (!test_Close(p, mem_ctx, &acct_handle)) {
473                 ret = False;
474         }
475
476         return ret;
477 }
478
479 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
480                            struct policy_handle *handle, uint32 rid)
481 {
482         NTSTATUS status;
483         struct samr_OpenAlias r;
484         struct policy_handle acct_handle;
485         BOOL ret = True;
486
487         printf("Testing OpenAlias(%u)\n", rid);
488
489         r.in.handle = handle;
490         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
491         r.in.rid = rid;
492         r.out.acct_handle = &acct_handle;
493
494         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
495         if (!NT_STATUS_IS_OK(status)) {
496                 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
497                 return False;
498         }
499
500         if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
501                 ret = False;
502         }
503
504         if (!test_QueryAliasInfo(p, mem_ctx, &acct_handle)) {
505                 ret = False;
506         }
507
508         if (!test_Close(p, mem_ctx, &acct_handle)) {
509                 ret = False;
510         }
511
512         return ret;
513 }
514
515 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
516                                  struct policy_handle *handle)
517 {
518         NTSTATUS status;
519         struct samr_EnumDomainUsers r;
520         uint32 resume_handle=0;
521         int i;
522         BOOL ret = True;
523         struct samr_LookupNames n;
524         struct samr_LookupRids  lr ;
525
526         printf("Testing EnumDomainUsers\n");
527
528         r.in.handle = handle;
529         r.in.resume_handle = &resume_handle;
530         r.in.acct_flags = 0;
531         r.in.max_size = (uint32)-1;
532         r.out.resume_handle = &resume_handle;
533
534         status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
535         if (!NT_STATUS_IS_OK(status)) {
536                 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
537                 return False;
538         }
539         
540         if (!r.out.sam) {
541                 return False;
542         }
543
544         if (r.out.sam->count == 0) {
545                 return True;
546         }
547
548         for (i=0;i<r.out.sam->count;i++) {
549                 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
550                         ret = False;
551                 }
552         }
553
554         printf("Testing LookupNames\n");
555         n.in.handle = handle;
556         n.in.num_names = r.out.sam->count;
557         n.in.names = talloc(mem_ctx, r.out.sam->count * sizeof(struct samr_Name));
558         for (i=0;i<r.out.sam->count;i++) {
559                 n.in.names[i] = r.out.sam->entries[i].name;
560         }
561         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
562         if (!NT_STATUS_IS_OK(status)) {
563                 printf("LookupNames failed - %s\n", nt_errstr(status));
564                 ret = False;
565         }
566
567
568         printf("Testing LookupRids\n");
569         lr.in.handle = handle;
570         lr.in.num_rids = r.out.sam->count;
571         lr.in.rids = talloc(mem_ctx, r.out.sam->count * sizeof(uint32));
572         for (i=0;i<r.out.sam->count;i++) {
573                 lr.in.rids[i] = r.out.sam->entries[i].idx;
574         }
575         status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
576         if (!NT_STATUS_IS_OK(status)) {
577                 printf("LookupRids failed - %s\n", nt_errstr(status));
578                 ret = False;
579         }
580
581         return ret;     
582 }
583
584 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
585                                   struct policy_handle *handle)
586 {
587         NTSTATUS status;
588         struct samr_EnumDomainGroups r;
589         uint32 resume_handle=0;
590         int i;
591         BOOL ret = True;
592
593         printf("Testing EnumDomainGroups\n");
594
595         r.in.handle = handle;
596         r.in.resume_handle = &resume_handle;
597         r.in.max_size = (uint32)-1;
598         r.out.resume_handle = &resume_handle;
599
600         status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
601         if (!NT_STATUS_IS_OK(status)) {
602                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
603                 return False;
604         }
605         
606         if (!r.out.sam) {
607                 return False;
608         }
609
610         for (i=0;i<r.out.sam->count;i++) {
611                 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
612                         ret = False;
613                 }
614         }
615
616         return ret;
617 }
618
619 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
620                                    struct policy_handle *handle)
621 {
622         NTSTATUS status;
623         struct samr_EnumDomainAliases r;
624         uint32 resume_handle=0;
625         int i;
626         BOOL ret = True;
627
628         printf("Testing EnumDomainAliases\n");
629
630         r.in.handle = handle;
631         r.in.resume_handle = &resume_handle;
632         r.in.max_size = (uint32)-1;
633         r.out.resume_handle = &resume_handle;
634
635         status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
636         if (!NT_STATUS_IS_OK(status)) {
637                 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
638                 return False;
639         }
640         
641         if (!r.out.sam) {
642                 return False;
643         }
644
645         for (i=0;i<r.out.sam->count;i++) {
646                 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
647                         ret = False;
648                 }
649         }
650
651         return ret;     
652 }
653
654 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
655                                  struct policy_handle *handle)
656 {
657         NTSTATUS status;
658         struct samr_QueryDomainInfo r;
659         uint16 levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
660         int i;
661         BOOL ret = True;
662
663         for (i=0;i<ARRAY_SIZE(levels);i++) {
664                 printf("Testing QueryDomainInfo level %u\n", levels[i]);
665
666                 r.in.handle = handle;
667                 r.in.level = levels[i];
668
669                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
670                 if (!NT_STATUS_IS_OK(status)) {
671                         printf("QueryDomainInfo level %u failed - %s\n", 
672                                r.in.level, nt_errstr(status));
673                         ret = False;
674                         continue;
675                 }
676         }
677
678         return True;    
679 }
680
681 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
682                             struct policy_handle *handle, struct dom_sid2 *sid)
683 {
684         NTSTATUS status;
685         struct samr_OpenDomain r;
686         struct policy_handle domain_handle;
687         BOOL ret = True;
688
689         printf("Testing OpenDomain\n");
690
691         r.in.handle = handle;
692         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
693         r.in.sid = sid;
694         r.out.domain_handle = &domain_handle;
695
696         status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
697         if (!NT_STATUS_IS_OK(status)) {
698                 printf("OpenDomain failed - %s\n", nt_errstr(status));
699                 return False;
700         }
701
702         if (!test_CreateUser(p, mem_ctx, &domain_handle)) {
703                 ret = False;
704         }
705
706         if (!test_QuerySecurity(p, mem_ctx, &domain_handle)) {
707                 ret = False;
708         }
709
710         if (!test_QueryDomainInfo(p, mem_ctx, &domain_handle)) {
711                 ret = False;
712         }
713
714         if (!test_EnumDomainUsers(p, mem_ctx, &domain_handle)) {
715                 ret = False;
716         }
717
718         if (!test_EnumDomainGroups(p, mem_ctx, &domain_handle)) {
719                 ret = False;
720         }
721
722         if (!test_EnumDomainAliases(p, mem_ctx, &domain_handle)) {
723                 ret = False;
724         }
725
726         if (!test_Close(p, mem_ctx, &domain_handle)) {
727                 ret = False;
728         }
729
730         return ret;
731 }
732
733 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
734                               struct policy_handle *handle, struct samr_Name *domain)
735 {
736         NTSTATUS status;
737         struct samr_LookupDomain r;
738
739         printf("Testing LookupDomain(%s)\n", domain->name);
740
741         r.in.handle = handle;
742         r.in.domain = domain;
743
744         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
745         if (!NT_STATUS_IS_OK(status)) {
746                 printf("LookupDomain failed - %s\n", nt_errstr(status));
747                 return False;
748         }
749
750         if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
751                 return False;
752         }
753
754         return True;    
755 }
756
757
758 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
759                              struct policy_handle *handle)
760 {
761         NTSTATUS status;
762         struct samr_EnumDomains r;
763         uint32 resume_handle = 0;
764         uint32 num_entries=0;
765         int i;
766         BOOL ret = True;
767
768         r.in.handle = handle;
769         r.in.resume_handle = &resume_handle;
770         r.in.buf_size = (uint32)-1;
771         r.out.resume_handle = &resume_handle;
772         r.out.num_entries = &num_entries;
773
774         status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
775         if (!NT_STATUS_IS_OK(status)) {
776                 printf("EnumDomains failed - %s\n", nt_errstr(status));
777                 return False;
778         }
779
780         if (!r.out.sam) {
781                 return False;
782         }
783
784         for (i=0;i<r.out.sam->count;i++) {
785                 if (!test_LookupDomain(p, mem_ctx, handle, 
786                                        &r.out.sam->entries[i].name)) {
787                         ret = False;
788                 }
789         }
790
791         return ret;
792 }
793
794
795 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
796                          struct policy_handle *handle)
797 {
798         NTSTATUS status;
799         struct samr_Connect r;
800         struct samr_Connect4 r4;
801
802         r.in.system_name = 0;
803         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
804         r.out.handle = handle;
805
806         status = dcerpc_samr_Connect(p, mem_ctx, &r);
807         if (!NT_STATUS_IS_OK(status)) {
808                 printf("Connect failed - %s\n", nt_errstr(status));
809                 return False;
810         }
811
812         r4.in.system_name = "";
813         r4.in.unknown = 0;
814         r4.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
815         r4.out.handle = handle;
816
817         status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
818         if (!NT_STATUS_IS_OK(status)) {
819                 printf("Connect4 failed - %s\n", nt_errstr(status));
820                 return False;
821         }
822
823         return True;
824 }
825
826
827 BOOL torture_rpc_samr(int dummy)
828 {
829         NTSTATUS status;
830         struct dcerpc_pipe *p;
831         TALLOC_CTX *mem_ctx;
832         BOOL ret = True;
833         struct policy_handle handle;
834
835         mem_ctx = talloc_init("torture_rpc_samr");
836
837         status = torture_rpc_connection(&p, 
838                                         DCERPC_SAMR_NAME,
839                                         DCERPC_SAMR_UUID,
840                                         DCERPC_SAMR_VERSION);
841         if (!NT_STATUS_IS_OK(status)) {
842                 return False;
843         }
844         
845         p->flags |= DCERPC_DEBUG_PRINT_BOTH;
846
847         if (!test_Connect(p, mem_ctx, &handle)) {
848                 ret = False;
849         }
850
851         if (!test_QuerySecurity(p, mem_ctx, &handle)) {
852                 ret = False;
853         }
854
855         if (!test_EnumDomains(p, mem_ctx, &handle)) {
856                 ret = False;
857         }
858
859         if (!test_Close(p, mem_ctx, &handle)) {
860                 ret = False;
861         }
862
863         torture_rpc_close(p);
864
865         return ret;
866 }