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