r257: added samr_SetGroupInfo() IDL and test code
[samba.git] / source / 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    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24
25 #define TEST_USERNAME "samrtorturetest"
26 #define TEST_ALIASNAME "samrtorturetestalias"
27 #define TEST_GROUPNAME "samrtorturetestgroup"
28 #define TEST_MACHINENAME "samrtorturetestmach$"
29 #define TEST_DOMAINNAME "samrtorturetestdom$"
30
31
32 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
33                                struct policy_handle *handle);
34
35 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
36                                struct policy_handle *handle);
37
38 static void init_samr_Name(struct samr_Name *name, const char *s)
39 {
40         name->name = s;
41 }
42
43 static BOOL test_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
44                        struct policy_handle *handle)
45 {
46         NTSTATUS status;
47         struct samr_Close r;
48
49         r.in.handle = handle;
50         r.out.handle = handle;
51
52         status = dcerpc_samr_Close(p, mem_ctx, &r);
53         if (!NT_STATUS_IS_OK(status)) {
54                 printf("Close handle failed - %s\n", nt_errstr(status));
55                 return False;
56         }
57
58         return True;
59 }
60
61
62 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
63                                struct policy_handle *handle)
64 {
65         NTSTATUS status;
66         struct samr_QuerySecurity r;
67         struct samr_SetSecurity s;
68
69         r.in.handle = handle;
70         r.in.sec_info = 7;
71
72         status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
73         if (!NT_STATUS_IS_OK(status)) {
74                 printf("QuerySecurity failed - %s\n", nt_errstr(status));
75                 return False;
76         }
77
78         s.in.handle = handle;
79         s.in.sec_info = 7;
80         s.in.sdbuf = r.out.sdbuf;
81
82         status = dcerpc_samr_SetSecurity(p, mem_ctx, &s);
83         if (!NT_STATUS_IS_OK(status)) {
84                 printf("SetSecurity failed - %s\n", nt_errstr(status));
85                 return False;
86         }
87
88         status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
89         if (!NT_STATUS_IS_OK(status)) {
90                 printf("QuerySecurity failed - %s\n", nt_errstr(status));
91                 return False;
92         }
93
94         return True;
95 }
96
97
98 static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
99                              struct policy_handle *handle)
100 {
101         NTSTATUS status;
102         struct samr_SetUserInfo s;
103         struct samr_QueryUserInfo q;
104         struct samr_QueryUserInfo q0;
105         union samr_UserInfo u;
106         BOOL ret = True;
107
108         s.in.handle = handle;
109         s.in.info = &u;
110         q.in.handle = handle;
111         q.out.info = &u;
112         q0 = q;
113
114 #define TESTCALL(call, r) \
115                 status = dcerpc_samr_ ##call(p, mem_ctx, &r); \
116                 if (!NT_STATUS_IS_OK(status)) { \
117                         printf(#call " level %u failed - %s (line %d)\n", \
118                                r.in.level, nt_errstr(status), __LINE__); \
119                         ret = False; \
120                         break; \
121                 }
122
123 #define STRING_EQUAL(s1, s2, field) \
124                 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
125                         printf("Failed to set %s to '%s' (line %d)\n", \
126                                #field, s2, __LINE__); \
127                         ret = False; \
128                         break; \
129                 }
130
131 #define INT_EQUAL(i1, i2, field) \
132                 if (i1 != i2) { \
133                         printf("Failed to set %s to %u (line %d)\n", \
134                                #field, i2, __LINE__); \
135                         ret = False; \
136                         break; \
137                 }
138
139 #define TEST_USERINFO_NAME(lvl1, field1, lvl2, field2, value, fpval) 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                 init_samr_Name(&u.info ## lvl1.field1, value); \
146                 if (lvl1 == 21) { \
147                         u.info21.fields_present = fpval; \
148                 } \
149                 TESTCALL(SetUserInfo, s) \
150                 init_samr_Name(&u.info ## lvl1.field1, ""); \
151                 TESTCALL(QueryUserInfo, q); \
152                 u = *q.out.info; \
153                 STRING_EQUAL(u.info ## lvl1.field1.name, value, field1); \
154                 q.in.level = lvl2; \
155                 TESTCALL(QueryUserInfo, q) \
156                 u = *q.out.info; \
157                 STRING_EQUAL(u.info ## lvl2.field2.name, value, field2); \
158         } while (0)
159
160 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
161                 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
162                 q.in.level = lvl1; \
163                 TESTCALL(QueryUserInfo, q) \
164                 s.in.level = lvl1; \
165                 u = *q.out.info; \
166                 u.info ## lvl1.field1 = value; \
167                 if (lvl1 == 21) { \
168                         u.info21.fields_present = fpval; \
169                 } \
170                 TESTCALL(SetUserInfo, s) \
171                 u.info ## lvl1.field1 = 0; \
172                 TESTCALL(QueryUserInfo, q); \
173                 u = *q.out.info; \
174                 INT_EQUAL(u.info ## lvl1.field1, value, field1); \
175                 q.in.level = lvl2; \
176                 TESTCALL(QueryUserInfo, q) \
177                 u = *q.out.info; \
178                 INT_EQUAL(u.info ## lvl2.field2, value, field1); \
179         } while (0)
180
181         q0.in.level = 12;
182         do { TESTCALL(QueryUserInfo, q0) } while (0);
183
184         TEST_USERINFO_NAME(2, comment,  1, comment, "xx2-1 comment", 0);
185         TEST_USERINFO_NAME(2, comment, 21, comment, "xx2-21 comment", 0);
186         TEST_USERINFO_NAME(21, comment, 21, comment, "xx21-21 comment", 0x00000020);
187
188         TEST_USERINFO_NAME(6, full_name,  1, full_name, "xx6-1 full_name", 0);
189         TEST_USERINFO_NAME(6, full_name,  3, full_name, "xx6-3 full_name", 0);
190         TEST_USERINFO_NAME(6, full_name,  5, full_name, "xx6-5 full_name", 0);
191         TEST_USERINFO_NAME(6, full_name,  6, full_name, "xx6-6 full_name", 0);
192         TEST_USERINFO_NAME(6, full_name,  8, full_name, "xx6-8 full_name", 0);
193         TEST_USERINFO_NAME(6, full_name, 21, full_name, "xx6-21 full_name", 0);
194         TEST_USERINFO_NAME(8, full_name, 21, full_name, "xx8-21 full_name", 0);
195         TEST_USERINFO_NAME(21, full_name, 21, full_name, "xx21-21 full_name", 0x00000002);
196
197         TEST_USERINFO_NAME(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
198         TEST_USERINFO_NAME(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
199         TEST_USERINFO_NAME(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
200         TEST_USERINFO_NAME(21, logon_script, 21, logon_script, "xx21-21 logon_script", 0x00000100);
201
202         TEST_USERINFO_NAME(12, profile,  3, profile, "xx12-3 profile", 0);
203         TEST_USERINFO_NAME(12, profile,  5, profile, "xx12-5 profile", 0);
204         TEST_USERINFO_NAME(12, profile, 21, profile, "xx12-21 profile", 0);
205         TEST_USERINFO_NAME(21, profile, 21, profile, "xx21-21 profile", 0x00000200);
206
207         TEST_USERINFO_NAME(13, description,  1, description, "xx13-1 description", 0);
208         TEST_USERINFO_NAME(13, description,  5, description, "xx13-5 description", 0);
209         TEST_USERINFO_NAME(13, description, 21, description, "xx13-21 description", 0);
210         TEST_USERINFO_NAME(21, description, 21, description, "xx21-21 description", 0x00000010);
211
212         TEST_USERINFO_NAME(14, workstations,  3, workstations, "14workstation3", 0);
213         TEST_USERINFO_NAME(14, workstations,  5, workstations, "14workstation4", 0);
214         TEST_USERINFO_NAME(14, workstations, 21, workstations, "14workstation21", 0);
215         TEST_USERINFO_NAME(21, workstations, 21, workstations, "21workstation21", 0x00000400);
216
217         TEST_USERINFO_NAME(20, callback, 21, callback, "xx20-21 callback", 0);
218         TEST_USERINFO_NAME(21, callback, 21, callback, "xx21-21 callback", 0x00200000);
219
220         TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
221         TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__, 0x00400000);
222         TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
223         TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__, 0x00800000);
224
225         TEST_USERINFO_INT(4, logon_hours.bitmap[3],  3, logon_hours.bitmap[3], __LINE__, 0);
226         TEST_USERINFO_INT(4, logon_hours.bitmap[3],  5, logon_hours.bitmap[3], __LINE__, 0);
227         TEST_USERINFO_INT(4, logon_hours.bitmap[3], 21, logon_hours.bitmap[3], __LINE__, 0);
228         TEST_USERINFO_INT(21, logon_hours.bitmap[3], 21, logon_hours.bitmap[3], __LINE__, 0x00002000);
229
230 #if 0
231         /* these fail with win2003 - it appears you can't set the primary gid?
232            the set succeeds, but the gid isn't changed. Very weird! */
233         TEST_USERINFO_INT(9, primary_gid,  1, primary_gid, 513);
234         TEST_USERINFO_INT(9, primary_gid,  3, primary_gid, 513);
235         TEST_USERINFO_INT(9, primary_gid,  5, primary_gid, 513);
236         TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
237 #endif
238         return ret;
239 }
240
241 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
242                                struct policy_handle *handle)
243 {
244         NTSTATUS status;
245         struct samr_SetAliasInfo r;
246         struct samr_QueryAliasInfo q;
247         uint16 levels[] = {2, 3};
248         int i;
249         BOOL ret = True;
250
251         /* Ignoring switch level 1, as that includes the number of members for the alias
252          * and setting this to a wrong value might have negative consequences
253          */
254
255         for (i=0;i<ARRAY_SIZE(levels);i++) {
256                 printf("Testing SetAliasInfo level %u\n", levels[i]);
257
258                 r.in.handle = handle;
259                 r.in.level = levels[i];
260                 switch (r.in.level) {
261                     case 2 : init_samr_Name(&r.in.info.name,TEST_ALIASNAME); break;
262                     case 3 : init_samr_Name(&r.in.info.description,
263                                 "Test Description, should test I18N as well"); break;
264                 }
265
266                 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
267                 if (!NT_STATUS_IS_OK(status)) {
268                         printf("SetAliasInfo level %u failed - %s\n",
269                                levels[i], nt_errstr(status));
270                         ret = False;
271                 }
272
273                 q.in.handle = handle;
274                 q.in.level = levels[i];
275
276                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
277                 if (!NT_STATUS_IS_OK(status)) {
278                         printf("QueryAliasInfo level %u failed - %s\n",
279                                levels[i], nt_errstr(status));
280                         ret = False;
281                 }
282         }
283
284         return ret;
285 }
286
287 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
288                                   struct policy_handle *user_handle)
289 {
290         struct samr_GetGroupsForUser r;
291         NTSTATUS status;
292         BOOL ret = True;
293
294         printf("testing GetGroupsForUser\n");
295
296         r.in.handle = user_handle;
297
298         status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
299         if (!NT_STATUS_IS_OK(status)) {
300                 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
301                 ret = False;
302         }
303
304         return ret;
305
306 }
307 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
308                                struct policy_handle *handle)
309 {
310         NTSTATUS status;
311         struct samr_GetUserPwInfo r;
312         BOOL ret = True;
313
314         printf("Testing GetUserPwInfo\n");
315
316         r.in.handle = handle;
317
318         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
319         if (!NT_STATUS_IS_OK(status)) {
320                 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
321                 ret = False;
322         }
323
324         return ret;
325 }
326
327 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
328                                   struct policy_handle *alias_handle)
329 {
330         struct samr_GetMembersInAlias r;
331         struct lsa_SidArray sids;
332         NTSTATUS status;
333         BOOL     ret = True;
334
335         printf("Testing GetMembersInAlias\n");
336
337         r.in.handle = alias_handle;
338         r.out.sids = &sids;
339
340         status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
341         if (!NT_STATUS_IS_OK(status)) {
342                 printf("GetMembersInAlias failed - %s\n",
343                        nt_errstr(status));
344                 ret = False;
345         }
346
347         return ret;
348 }
349
350 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
351                                   struct policy_handle *alias_handle,
352                                   struct policy_handle *domain_handle,
353                                   const struct dom_sid *domain_sid)
354 {
355         struct samr_AddAliasMem r;
356         struct samr_DelAliasMem d;
357         NTSTATUS status;
358         BOOL ret = True;
359         struct dom_sid *sid;
360
361         sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
362
363         printf("testing AddAliasMem\n");
364         r.in.handle = alias_handle;
365         r.in.sid = sid;
366
367         status = dcerpc_samr_AddAliasMem(p, mem_ctx, &r);
368         if (!NT_STATUS_IS_OK(status)) {
369                 printf("AddAliasMem failed - %s\n", nt_errstr(status));
370                 ret = False;
371         }
372
373         d.in.handle = alias_handle;
374         d.in.sid = sid;
375
376         status = dcerpc_samr_DelAliasMem(p, mem_ctx, &d);
377         if (!NT_STATUS_IS_OK(status)) {
378                 printf("DelAliasMem failed - %s\n", nt_errstr(status));
379                 ret = False;
380         }
381
382         return ret;
383 }
384
385 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
386                           struct policy_handle *handle)
387 {
388         BOOL ret = True;
389
390         if (!test_QuerySecurity(p, mem_ctx, handle)) {
391                 ret = False;
392         }
393
394         if (!test_QueryUserInfo(p, mem_ctx, handle)) {
395                 ret = False;
396         }
397
398         if (!test_SetUserInfo(p, mem_ctx, handle)) {
399                 ret = False;
400         }       
401
402         if (!test_GetUserPwInfo(p, mem_ctx, handle)) {
403                 ret = False;
404         }
405
406         return ret;
407 }
408
409 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
410                            struct policy_handle *alias_handle,
411                            struct policy_handle *domain_handle,
412                            const struct dom_sid *domain_sid)
413 {
414         BOOL ret = True;
415
416         if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
417                 ret = False;
418         }
419
420         if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
421                 ret = False;
422         }
423
424         if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
425                 ret = False;
426         }
427
428         if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, 
429                                    domain_handle, domain_sid)) {
430                 ret = False;
431         }
432
433         return ret;
434 }
435
436 static BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
437                                    struct policy_handle *handle, const char *name)
438 {
439         NTSTATUS status;
440         struct samr_LookupNames n;
441         struct samr_OpenUser r;
442         struct samr_DeleteUser d;
443         struct policy_handle acct_handle;
444         struct samr_Name sname;
445
446         init_samr_Name(&sname, name);
447
448         n.in.handle = handle;
449         n.in.num_names = 1;
450         n.in.names = &sname;
451         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
452         if (!NT_STATUS_IS_OK(status)) {
453                 goto failed;
454         }
455
456         r.in.handle = handle;
457         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
458         r.in.rid = n.out.rids.ids[0];
459         r.out.acct_handle = &acct_handle;
460         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
461         if (!NT_STATUS_IS_OK(status)) {
462                 goto failed;
463         }
464
465         d.in.handle = &acct_handle;
466         d.out.handle = &acct_handle;
467         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
468         if (!NT_STATUS_IS_OK(status)) {
469                 goto failed;
470         }
471
472         return True;
473
474 failed:
475         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
476         return False;
477 }
478
479
480 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
481                                     struct policy_handle *handle, const char *name)
482 {
483         NTSTATUS status;
484         struct samr_LookupNames n;
485         struct samr_OpenGroup r;
486         struct samr_DeleteDomainGroup d;
487         struct policy_handle group_handle;
488         struct samr_Name sname;
489
490         init_samr_Name(&sname, name);
491
492         n.in.handle = handle;
493         n.in.num_names = 1;
494         n.in.names = &sname;
495         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
496         if (!NT_STATUS_IS_OK(status)) {
497                 goto failed;
498         }
499
500         r.in.handle = handle;
501         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
502         r.in.rid = n.out.rids.ids[0];
503         r.out.acct_handle = &group_handle;
504         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
505         if (!NT_STATUS_IS_OK(status)) {
506                 goto failed;
507         }
508
509         d.in.handle = &group_handle;
510         d.out.handle = &group_handle;
511         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
512         if (!NT_STATUS_IS_OK(status)) {
513                 goto failed;
514         }
515
516         return True;
517
518 failed:
519         printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
520         return False;
521 }
522
523
524 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
525                                    struct policy_handle *domain_handle, const char *name)
526 {
527         NTSTATUS status;
528         struct samr_LookupNames n;
529         struct samr_OpenAlias r;
530         struct samr_DeleteDomAlias d;
531         struct policy_handle alias_handle;
532         struct samr_Name sname;
533
534         printf("testing DeleteAlias_byname\n");
535         init_samr_Name(&sname, name);
536
537         n.in.handle = domain_handle;
538         n.in.num_names = 1;
539         n.in.names = &sname;
540         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
541         if (!NT_STATUS_IS_OK(status)) {
542                 goto failed;
543         }
544
545         r.in.handle = domain_handle;
546         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
547         r.in.rid = n.out.rids.ids[0];
548         r.out.acct_handle = &alias_handle;
549         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
550         if (!NT_STATUS_IS_OK(status)) {
551                 goto failed;
552         }
553
554         d.in.handle = &alias_handle;
555         d.out.handle = &alias_handle;
556         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
557         if (!NT_STATUS_IS_OK(status)) {
558                 goto failed;
559         }
560
561         return True;
562
563 failed:
564         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
565         return False;
566 }
567
568 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
569                                      struct policy_handle *alias_handle)
570 {
571         struct samr_DeleteDomAlias d;
572         NTSTATUS status;
573         BOOL ret = True;
574         printf("Testing DeleteAlias\n");
575
576         d.in.handle = alias_handle;
577         d.out.handle = alias_handle;
578
579         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
580         if (!NT_STATUS_IS_OK(status)) {
581                 printf("DeleteAlias failed - %s\n", nt_errstr(status));
582                 ret = False;
583         }
584
585         return ret;
586 }
587
588 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
589                             struct policy_handle *domain_handle, 
590                              struct policy_handle *alias_handle, 
591                              const struct dom_sid *domain_sid)
592 {
593         NTSTATUS status;
594         struct samr_CreateDomAlias r;
595         struct samr_Name name;
596         uint32 rid;
597         BOOL ret = True;
598
599         init_samr_Name(&name, TEST_ALIASNAME);
600         r.in.handle = domain_handle;
601         r.in.aliasname = &name;
602         r.in.access_mask = SEC_RIGHT_MAXIMUM_ALLOWED;
603         r.out.acct_handle = alias_handle;
604         r.out.rid = &rid;
605
606         printf("Testing CreateAlias (%s)\n", r.in.aliasname->name);
607
608         status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
609
610         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
611                 printf("Server refused create of '%s'\n", r.in.aliasname->name);
612                 return True;
613         }
614
615         if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
616                 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.aliasname->name)) {
617                         return False;
618                 }
619                 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
620         }
621
622         if (!NT_STATUS_IS_OK(status)) {
623                 printf("CreateAlias failed - %s\n", nt_errstr(status));
624                 return False;
625         }
626
627         if (!test_alias_ops(p, mem_ctx, alias_handle, domain_handle, domain_sid)) {
628                 ret = False;
629         }
630
631         return ret;
632 }
633
634 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
635                             struct policy_handle *domain_handle, struct policy_handle *user_handle)
636 {
637         NTSTATUS status;
638         struct samr_CreateUser r;
639         struct samr_QueryUserInfo q;
640         uint32 rid;
641
642         /* This call creates a 'normal' account - check that it really does */
643         const uint32 acct_flags = ACB_NORMAL;
644         struct samr_Name name;
645         BOOL ret = True;
646
647         init_samr_Name(&name, TEST_USERNAME);
648
649         r.in.handle = domain_handle;
650         r.in.username = &name;
651         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
652         r.out.acct_handle = user_handle;
653         r.out.rid = &rid;
654
655         printf("Testing CreateUser(%s)\n", r.in.username->name);
656
657         status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
658
659         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
660                 printf("Server refused create of '%s'\n", r.in.username->name);
661                 ZERO_STRUCTP(user_handle);
662                 return True;
663         }
664
665         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
666                 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.username->name)) {
667                         return False;
668                 }
669                 status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
670         }
671         if (!NT_STATUS_IS_OK(status)) {
672                 printf("CreateUser failed - %s\n", nt_errstr(status));
673                 return False;
674         }
675
676
677         q.in.handle = user_handle;
678         q.in.level = 16;
679
680         status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
681         if (!NT_STATUS_IS_OK(status)) {
682                 printf("QueryUserInfo level %u failed - %s\n", 
683                        q.in.level, nt_errstr(status));
684                 ret = False;
685         } else {
686                 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
687                         printf("QuerUserInfo level 16 failed, it returned 0x%08x (%u) when we expected flags of 0x%08x (%u)\n",
688                                q.out.info->info16.acct_flags, q.out.info->info16.acct_flags, 
689                                acct_flags, acct_flags);
690                         ret = False;
691                 }
692         }
693
694         if (!test_user_ops(p, mem_ctx, user_handle)) {
695                 ret = False;
696         }
697
698         return ret;
699 }
700
701
702 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
703                             struct policy_handle *user_handle)
704 {
705         struct samr_DeleteUser d;
706         NTSTATUS status;
707         BOOL ret = True;
708
709         printf("Testing DeleteUser\n");
710
711         d.in.handle = user_handle;
712         d.out.handle = user_handle;
713
714         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
715         if (!NT_STATUS_IS_OK(status)) {
716                 printf("DeleteUser failed - %s\n", nt_errstr(status));
717                 ret = False;
718         }
719
720         return ret;
721 }
722
723 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
724                              struct policy_handle *handle)
725 {
726         NTSTATUS status;
727         struct samr_CreateUser2 r;
728         struct samr_QueryUserInfo q;
729         struct samr_DeleteUser d;
730         struct policy_handle acct_handle;
731         uint32 rid;
732         struct samr_Name name;
733         BOOL ret = True;
734         int i;
735
736         struct {
737                 uint32 acct_flags;
738                 const char *account_name;
739                 NTSTATUS nt_status;
740         } account_types[] = {
741                 { ACB_NORMAL, TEST_USERNAME, NT_STATUS_OK },
742                 { ACB_NORMAL | ACB_DISABLED, TEST_USERNAME, NT_STATUS_INVALID_PARAMETER },
743                 { ACB_NORMAL | ACB_PWNOEXP, TEST_USERNAME, NT_STATUS_INVALID_PARAMETER },
744                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
745                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
746                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
747                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
748                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
749                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
750                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
751                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
752                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
753                 { 0, TEST_USERNAME, NT_STATUS_INVALID_PARAMETER },
754                 { ACB_DISABLED, TEST_USERNAME, NT_STATUS_INVALID_PARAMETER },
755                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
756         };
757
758         for (i = 0; account_types[i].account_name; i++) {
759                 uint32 acct_flags = account_types[i].acct_flags;
760                 uint32 access_granted;
761
762                 init_samr_Name(&name, account_types[i].account_name);
763
764                 r.in.handle = handle;
765                 r.in.username = &name;
766                 r.in.acct_flags = acct_flags;
767                 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
768                 r.out.acct_handle = &acct_handle;
769                 r.out.access_granted = &access_granted;
770                 r.out.rid = &rid;
771                 
772                 printf("Testing CreateUser2(%s)\n", r.in.username->name);
773                 
774                 status = dcerpc_samr_CreateUser2(p, mem_ctx, &r);
775                 
776                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
777                         printf("Server refused create of '%s'\n", r.in.username->name);
778                         continue;
779
780                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
781                         if (!test_DeleteUser_byname(p, mem_ctx, handle, r.in.username->name)) {
782                                 return False;
783                         }
784                         status = dcerpc_samr_CreateUser2(p, mem_ctx, &r);
785
786                 }
787                 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
788                         printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n", 
789                                nt_errstr(status), nt_errstr(account_types[i].nt_status));
790                         ret = False;
791                 }
792                 
793                 if (NT_STATUS_IS_OK(status)) {
794                         q.in.handle = &acct_handle;
795                         q.in.level = 16;
796                         
797                         status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
798                         if (!NT_STATUS_IS_OK(status)) {
799                                 printf("QueryUserInfo level %u failed - %s\n", 
800                                        q.in.level, nt_errstr(status));
801                                 ret = False;
802                         } else {
803                                 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
804                                         printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
805                                                q.out.info->info16.acct_flags, 
806                                                acct_flags);
807                                         ret = False;
808                                 }
809                         }
810                 
811                         if (!test_user_ops(p, mem_ctx, &acct_handle)) {
812                                 ret = False;
813                         }
814
815                         printf("Testing DeleteUser (createuser2 test)\n");
816                 
817                         d.in.handle = &acct_handle;
818                         d.out.handle = &acct_handle;
819                         
820                         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
821                         if (!NT_STATUS_IS_OK(status)) {
822                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
823                                 ret = False;
824                         }
825                 }
826         }
827
828         return ret;
829 }
830
831 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
832                                 struct policy_handle *handle)
833 {
834         NTSTATUS status;
835         struct samr_QueryAliasInfo r;
836         uint16 levels[] = {1, 2, 3};
837         int i;
838         BOOL ret = True;
839
840         for (i=0;i<ARRAY_SIZE(levels);i++) {
841                 printf("Testing QueryAliasInfo level %u\n", levels[i]);
842
843                 r.in.handle = handle;
844                 r.in.level = levels[i];
845
846                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
847                 if (!NT_STATUS_IS_OK(status)) {
848                         printf("QueryAliasInfo level %u failed - %s\n", 
849                                levels[i], nt_errstr(status));
850                         ret = False;
851                 }
852         }
853
854         return ret;
855 }
856
857 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
858                                 struct policy_handle *handle)
859 {
860         NTSTATUS status;
861         struct samr_QueryGroupInfo r;
862         struct samr_SetGroupInfo s;
863         uint16 levels[] = {1, 2, 3, 4};
864         uint16 set_ok[] = {0, 1, 1, 1};
865         int i;
866         BOOL ret = True;
867
868         for (i=0;i<ARRAY_SIZE(levels);i++) {
869                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
870
871                 r.in.handle = handle;
872                 r.in.level = levels[i];
873
874                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
875                 if (!NT_STATUS_IS_OK(status)) {
876                         printf("QueryGroupInfo level %u failed - %s\n", 
877                                levels[i], nt_errstr(status));
878                         ret = False;
879                 }
880
881                 printf("Testing SetGroupInfo level %u\n", levels[i]);
882
883                 s.in.handle = handle;
884                 s.in.level = levels[i];
885                 s.in.info = r.out.info;
886
887                 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
888                 if (set_ok[i]) {
889                         if (!NT_STATUS_IS_OK(status)) {
890                                 printf("SetGroupInfo level %u failed - %s\n", 
891                                        r.in.level, nt_errstr(status));
892                                 ret = False;
893                                 continue;
894                         }
895                 } else {
896                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
897                                 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
898                                        r.in.level, nt_errstr(status));
899                                 ret = False;
900                                 continue;
901                         }
902                 }
903         }
904
905         return ret;
906 }
907
908 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
909                                struct policy_handle *handle)
910 {
911         NTSTATUS status;
912         struct samr_QueryUserInfo r;
913         uint16 levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
914                            11, 12, 13, 14, 16, 17, 20, 21};
915         int i;
916         BOOL ret = True;
917
918         for (i=0;i<ARRAY_SIZE(levels);i++) {
919                 printf("Testing QueryUserInfo level %u\n", levels[i]);
920
921                 r.in.handle = handle;
922                 r.in.level = levels[i];
923
924                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
925                 if (!NT_STATUS_IS_OK(status)) {
926                         printf("QueryUserInfo level %u failed - %s\n", 
927                                levels[i], nt_errstr(status));
928                         ret = False;
929                 }
930         }
931
932         return ret;
933 }
934
935 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
936                           struct policy_handle *handle, uint32 rid)
937 {
938         NTSTATUS status;
939         struct samr_OpenUser r;
940         struct policy_handle acct_handle;
941         BOOL ret = True;
942
943         printf("Testing OpenUser(%u)\n", rid);
944
945         r.in.handle = handle;
946         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
947         r.in.rid = rid;
948         r.out.acct_handle = &acct_handle;
949
950         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
951         if (!NT_STATUS_IS_OK(status)) {
952                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
953                 return False;
954         }
955
956         if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
957                 ret = False;
958         }
959
960         if (!test_QueryUserInfo(p, mem_ctx, &acct_handle)) {
961                 ret = False;
962         }
963
964         if (!test_GetUserPwInfo(p, mem_ctx, &acct_handle)) {
965                 ret = False;
966         }
967
968         if (!test_GetGroupsForUser(p,mem_ctx, &acct_handle)) {
969                 ret = False;
970         }
971
972         if (!test_Close(p, mem_ctx, &acct_handle)) {
973                 ret = False;
974         }
975
976         return ret;
977 }
978
979 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
980                            struct policy_handle *handle, uint32 rid)
981 {
982         NTSTATUS status;
983         struct samr_OpenGroup r;
984         struct policy_handle acct_handle;
985         BOOL ret = True;
986
987         printf("Testing OpenGroup(%u)\n", rid);
988
989         r.in.handle = handle;
990         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
991         r.in.rid = rid;
992         r.out.acct_handle = &acct_handle;
993
994         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
995         if (!NT_STATUS_IS_OK(status)) {
996                 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
997                 return False;
998         }
999
1000         if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
1001                 ret = False;
1002         }
1003
1004         if (!test_QueryGroupInfo(p, mem_ctx, &acct_handle)) {
1005                 ret = False;
1006         }
1007
1008         if (!test_Close(p, mem_ctx, &acct_handle)) {
1009                 ret = False;
1010         }
1011
1012         return ret;
1013 }
1014
1015 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1016                            struct policy_handle *handle, uint32 rid)
1017 {
1018         NTSTATUS status;
1019         struct samr_OpenAlias r;
1020         struct policy_handle acct_handle;
1021         BOOL ret = True;
1022
1023         printf("Testing OpenAlias(%u)\n", rid);
1024
1025         r.in.handle = handle;
1026         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1027         r.in.rid = rid;
1028         r.out.acct_handle = &acct_handle;
1029
1030         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1031         if (!NT_STATUS_IS_OK(status)) {
1032                 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
1033                 return False;
1034         }
1035
1036         if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
1037                 ret = False;
1038         }
1039
1040         if (!test_QueryAliasInfo(p, mem_ctx, &acct_handle)) {
1041                 ret = False;
1042         }
1043
1044         if (!test_GetMembersInAlias(p, mem_ctx, &acct_handle)) {
1045                 ret = False;
1046         }
1047
1048         if (!test_Close(p, mem_ctx, &acct_handle)) {
1049                 ret = False;
1050         }
1051
1052         return ret;
1053 }
1054
1055 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1056                                  struct policy_handle *handle)
1057 {
1058         NTSTATUS status;
1059         struct samr_EnumDomainUsers r;
1060         uint32 resume_handle=0;
1061         int i;
1062         BOOL ret = True;
1063         struct samr_LookupNames n;
1064         struct samr_LookupRids  lr ;
1065
1066         printf("Testing EnumDomainUsers\n");
1067
1068         r.in.handle = handle;
1069         r.in.resume_handle = &resume_handle;
1070         r.in.acct_flags = 0;
1071         r.in.max_size = (uint32)-1;
1072         r.out.resume_handle = &resume_handle;
1073
1074         status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
1075         if (!NT_STATUS_IS_OK(status)) {
1076                 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
1077                 return False;
1078         }
1079         
1080         if (!r.out.sam) {
1081                 return False;
1082         }
1083
1084         if (r.out.sam->count == 0) {
1085                 return True;
1086         }
1087
1088         for (i=0;i<r.out.sam->count;i++) {
1089                 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
1090                         ret = False;
1091                 }
1092         }
1093
1094         printf("Testing LookupNames\n");
1095         n.in.handle = handle;
1096         n.in.num_names = r.out.sam->count;
1097         n.in.names = talloc(mem_ctx, r.out.sam->count * sizeof(struct samr_Name));
1098         for (i=0;i<r.out.sam->count;i++) {
1099                 n.in.names[i] = r.out.sam->entries[i].name;
1100         }
1101         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
1102         if (!NT_STATUS_IS_OK(status)) {
1103                 printf("LookupNames failed - %s\n", nt_errstr(status));
1104                 ret = False;
1105         }
1106
1107
1108         printf("Testing LookupRids\n");
1109         lr.in.handle = handle;
1110         lr.in.num_rids = r.out.sam->count;
1111         lr.in.rids = talloc(mem_ctx, r.out.sam->count * sizeof(uint32));
1112         for (i=0;i<r.out.sam->count;i++) {
1113                 lr.in.rids[i] = r.out.sam->entries[i].idx;
1114         }
1115         status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
1116         if (!NT_STATUS_IS_OK(status)) {
1117                 printf("LookupRids failed - %s\n", nt_errstr(status));
1118                 ret = False;
1119         }
1120
1121         return ret;     
1122 }
1123
1124 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1125                                   struct policy_handle *handle)
1126 {
1127         NTSTATUS status;
1128         struct samr_EnumDomainGroups r;
1129         uint32 resume_handle=0;
1130         int i;
1131         BOOL ret = True;
1132
1133         printf("Testing EnumDomainGroups\n");
1134
1135         r.in.handle = handle;
1136         r.in.resume_handle = &resume_handle;
1137         r.in.max_size = (uint32)-1;
1138         r.out.resume_handle = &resume_handle;
1139
1140         status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
1141         if (!NT_STATUS_IS_OK(status)) {
1142                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
1143                 return False;
1144         }
1145         
1146         if (!r.out.sam) {
1147                 return False;
1148         }
1149
1150         for (i=0;i<r.out.sam->count;i++) {
1151                 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
1152                         ret = False;
1153                 }
1154         }
1155
1156         return ret;
1157 }
1158
1159 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1160                                    struct policy_handle *handle)
1161 {
1162         NTSTATUS status;
1163         struct samr_EnumDomainAliases r;
1164         uint32 resume_handle=0;
1165         int i;
1166         BOOL ret = True;
1167
1168         printf("Testing EnumDomainAliases\n");
1169
1170         r.in.handle = handle;
1171         r.in.resume_handle = &resume_handle;
1172         r.in.max_size = (uint32)-1;
1173         r.out.resume_handle = &resume_handle;
1174
1175         status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
1176         if (!NT_STATUS_IS_OK(status)) {
1177                 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
1178                 return False;
1179         }
1180         
1181         if (!r.out.sam) {
1182                 return False;
1183         }
1184
1185         for (i=0;i<r.out.sam->count;i++) {
1186                 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
1187                         ret = False;
1188                 }
1189         }
1190
1191         return ret;     
1192 }
1193
1194 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1195                                   struct policy_handle *handle)
1196 {
1197         NTSTATUS status;
1198         struct samr_QueryDisplayInfo r;
1199         BOOL ret = True;
1200         uint16 levels[] = {1, 2, 3, 4, 5};
1201         int i;
1202
1203         for (i=0;i<ARRAY_SIZE(levels);i++) {
1204                 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
1205
1206                 r.in.handle = handle;
1207                 r.in.level = levels[i];
1208                 r.in.start_idx = 0;
1209                 r.in.max_entries = 1000;
1210                 r.in.buf_size = (uint32)-1;
1211
1212                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
1213                 if (!NT_STATUS_IS_OK(status)) {
1214                         printf("QueryDisplayInfo level %u failed - %s\n", 
1215                                levels[i], nt_errstr(status));
1216                         ret = False;
1217                 }
1218         }
1219         
1220         return ret;     
1221 }
1222
1223 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1224                                  struct policy_handle *handle)
1225 {
1226         NTSTATUS status;
1227         struct samr_QueryDomainInfo r;
1228         struct samr_SetDomainInfo s;
1229         uint16 levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
1230         uint16 set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
1231         int i;
1232         BOOL ret = True;
1233
1234         for (i=0;i<ARRAY_SIZE(levels);i++) {
1235                 printf("Testing QueryDomainInfo level %u\n", levels[i]);
1236
1237                 r.in.handle = handle;
1238                 r.in.level = levels[i];
1239
1240                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
1241                 if (!NT_STATUS_IS_OK(status)) {
1242                         printf("QueryDomainInfo level %u failed - %s\n", 
1243                                r.in.level, nt_errstr(status));
1244                         ret = False;
1245                         continue;
1246                 }
1247
1248                 printf("Testing SetDomainInfo level %u\n", levels[i]);
1249
1250                 s.in.handle = handle;
1251                 s.in.level = levels[i];
1252                 s.in.info = r.out.info;
1253
1254                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
1255                 if (set_ok[i]) {
1256                         if (!NT_STATUS_IS_OK(status)) {
1257                                 printf("SetDomainInfo level %u failed - %s\n", 
1258                                        r.in.level, nt_errstr(status));
1259                                 ret = False;
1260                                 continue;
1261                         }
1262                 } else {
1263                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
1264                                 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
1265                                        r.in.level, nt_errstr(status));
1266                                 ret = False;
1267                                 continue;
1268                         }
1269                 }
1270         }
1271
1272         return True;    
1273 }
1274
1275 void add_string_to_array(TALLOC_CTX *mem_ctx,
1276                          const char *str, const char ***strings, int *num)
1277 {
1278         *strings = talloc_realloc(mem_ctx, *strings,
1279                                   ((*num)+1) * sizeof(**strings));
1280
1281         if (*strings == NULL)
1282                 return;
1283
1284         (*strings)[*num] = str;
1285         *num += 1;
1286
1287         return;
1288 }
1289
1290 /* Test whether querydispinfo level 5 and enumdomgroups return the same
1291    set of group names. */
1292
1293 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1294                            struct policy_handle *handle)
1295 {
1296         struct samr_EnumDomainGroups q1;
1297         struct samr_QueryDisplayInfo q2;
1298         NTSTATUS status;
1299         uint32 resume_handle=0;
1300         int i;
1301         BOOL ret = True;
1302
1303         int num_names = 0;
1304         const char **names = NULL;
1305
1306         printf("Testing coherency of querydispinfo vs enumdomgroups\n");
1307
1308         q1.in.handle = handle;
1309         q1.in.resume_handle = &resume_handle;
1310         q1.in.max_size = 5;
1311         q1.out.resume_handle = &resume_handle;
1312
1313         status = STATUS_MORE_ENTRIES;
1314         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
1315                 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
1316
1317                 if (!NT_STATUS_IS_OK(status) &&
1318                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
1319                         break;
1320
1321                 for (i=0; i<q1.out.sam->count; i++) {
1322                         add_string_to_array(mem_ctx,
1323                                             q1.out.sam->entries[i].name.name,
1324                                             &names, &num_names);
1325                 }
1326         }
1327
1328         if (!NT_STATUS_IS_OK(status)) {
1329                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
1330                 return False;
1331         }
1332         
1333         if (!q1.out.sam) {
1334                 return False;
1335         }
1336
1337         q2.in.handle = handle;
1338         q2.in.level = 5;
1339         q2.in.start_idx = 0;
1340         q2.in.max_entries = 5;
1341         q2.in.buf_size = (uint32)-1;
1342
1343         status = STATUS_MORE_ENTRIES;
1344         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
1345                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
1346
1347                 if (!NT_STATUS_IS_OK(status) &&
1348                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
1349                         break;
1350
1351                 for (i=0; i<q2.out.info.info5.count; i++) {
1352                         char *name;
1353                         size_t namelen;
1354                         int j;
1355                         BOOL found = False;
1356
1357                         /* Querydisplayinfo returns ascii -- convert */
1358
1359                         namelen = convert_string_allocate(CH_DISPLAY, CH_UNIX,
1360                                                           q2.out.info.info5.entries[i].account_name.name,
1361                                                           q2.out.info.info5.entries[i].account_name.name_len,
1362                                                           (void **)&name);
1363                         name = realloc(name, namelen+1);
1364                         name[namelen] = 0;
1365
1366                         for (j=0; j<num_names; j++) {
1367                                 if (names[j] == NULL)
1368                                         continue;
1369                                 /* Hmm. No strequal in samba4 */
1370                                 if (strequal(names[j], name)) {
1371                                         names[j] = NULL;
1372                                         found = True;
1373                                         break;
1374                                 }
1375                         }
1376
1377                         if (!found) {
1378                                 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
1379                                        name);
1380                                 ret = False;
1381                         }
1382                 }
1383                 q2.in.start_idx += q2.out.info.info5.count;
1384         }
1385
1386         if (!NT_STATUS_IS_OK(status)) {
1387                 printf("QueryDisplayInfo level 5 failed - %s\n",
1388                        nt_errstr(status));
1389                 ret = False;
1390         }
1391
1392         for (i=0; i<num_names; i++) {
1393                 if (names[i] != NULL) {
1394                         printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
1395                                names[i]);
1396                         ret = False;
1397                 }
1398         }
1399
1400         return ret;
1401 }
1402
1403 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1404                                    struct policy_handle *group_handle)
1405 {
1406         struct samr_DeleteDomainGroup d;
1407         NTSTATUS status;
1408         BOOL ret = True;
1409
1410         printf("Testing DeleteDomainGroup\n");
1411
1412         d.in.handle = group_handle;
1413         d.out.handle = group_handle;
1414
1415         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
1416         if (!NT_STATUS_IS_OK(status)) {
1417                 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
1418                 ret = False;
1419         }
1420
1421         return ret;
1422 }
1423
1424
1425 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1426                                    struct policy_handle *domain_handle, struct policy_handle *group_handle)
1427 {
1428         NTSTATUS status;
1429         struct samr_CreateDomainGroup r;
1430         uint32 rid;
1431         struct samr_Name name;
1432         BOOL ret = True;
1433
1434         init_samr_Name(&name, TEST_GROUPNAME);
1435
1436         r.in.handle = domain_handle;
1437         r.in.name = &name;
1438         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1439         r.out.group_handle = group_handle;
1440         r.out.rid = &rid;
1441
1442         printf("Testing CreateDomainGroup(%s)\n", r.in.name->name);
1443
1444         status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
1445
1446         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1447                 printf("Server refused create of '%s'\n", r.in.name->name);
1448                 ZERO_STRUCTP(group_handle);
1449                 return True;
1450         }
1451
1452         if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
1453                 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->name)) {
1454                         return False;
1455                 }
1456                 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
1457         }
1458         if (!NT_STATUS_IS_OK(status)) {
1459                 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
1460                 return False;
1461         }
1462
1463         return ret;
1464 }
1465
1466
1467 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1468                             struct policy_handle *handle, struct dom_sid *sid)
1469 {
1470         NTSTATUS status;
1471         struct samr_OpenDomain r;
1472         struct policy_handle domain_handle;
1473         struct policy_handle user_handle;
1474         struct policy_handle alias_handle;
1475         struct policy_handle group_handle;
1476         BOOL ret = True;
1477
1478         ZERO_STRUCT(user_handle);
1479         ZERO_STRUCT(alias_handle);
1480
1481         printf("Testing OpenDomain\n");
1482
1483         r.in.handle = handle;
1484         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1485         r.in.sid = sid;
1486         r.out.domain_handle = &domain_handle;
1487
1488         status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
1489         if (!NT_STATUS_IS_OK(status)) {
1490                 printf("OpenDomain failed - %s\n", nt_errstr(status));
1491                 return False;
1492         }
1493
1494         if (!test_CreateUser2(p, mem_ctx, &domain_handle)) {
1495                 ret = False;
1496         }
1497
1498         if (!test_CreateUser(p, mem_ctx, &domain_handle, &user_handle)) {
1499                 ret = False;
1500         }
1501
1502         if (!test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid)) {
1503                 ret = False;
1504         }
1505
1506         if (!test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle)) {
1507                 ret = False;
1508         }
1509
1510         if (!test_QuerySecurity(p, mem_ctx, &domain_handle)) {
1511                 ret = False;
1512         }
1513
1514         if (!test_QueryDomainInfo(p, mem_ctx, &domain_handle)) {
1515                 ret = False;
1516         }
1517
1518         if (!test_EnumDomainUsers(p, mem_ctx, &domain_handle)) {
1519                 ret = False;
1520         }
1521
1522         if (!test_EnumDomainGroups(p, mem_ctx, &domain_handle)) {
1523                 ret = False;
1524         }
1525
1526         if (!test_EnumDomainAliases(p, mem_ctx, &domain_handle)) {
1527                 ret = False;
1528         }
1529
1530         if (!test_QueryDisplayInfo(p, mem_ctx, &domain_handle)) {
1531                 ret = False;
1532         }
1533
1534         if (!test_GroupList(p, mem_ctx, &domain_handle)) {
1535                 ret = False;
1536         }
1537
1538         if (!policy_handle_empty(&user_handle) &&
1539             !test_DeleteUser(p, mem_ctx, &user_handle)) {
1540                 ret = False;
1541         }
1542
1543         if (!policy_handle_empty(&alias_handle) &&
1544             !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
1545                 ret = False;
1546         }
1547
1548         if (!policy_handle_empty(&group_handle) &&
1549             !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
1550                 ret = False;
1551         }
1552
1553         if (!test_Close(p, mem_ctx, &domain_handle)) {
1554                 ret = False;
1555         }
1556
1557         return ret;
1558 }
1559
1560 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1561                               struct policy_handle *handle, struct samr_Name *domain)
1562 {
1563         NTSTATUS status;
1564         struct samr_LookupDomain r;
1565
1566         printf("Testing LookupDomain(%s)\n", domain->name);
1567
1568         r.in.handle = handle;
1569         r.in.domain = domain;
1570
1571         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
1572         if (!NT_STATUS_IS_OK(status)) {
1573                 printf("LookupDomain failed - %s\n", nt_errstr(status));
1574                 return False;
1575         }
1576
1577         if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
1578                 return False;
1579         }
1580
1581         return True;    
1582 }
1583
1584
1585 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1586                              struct policy_handle *handle)
1587 {
1588         NTSTATUS status;
1589         struct samr_EnumDomains r;
1590         uint32 resume_handle = 0;
1591         int i;
1592         BOOL ret = True;
1593
1594         r.in.handle = handle;
1595         r.in.resume_handle = &resume_handle;
1596         r.in.buf_size = (uint32)-1;
1597         r.out.resume_handle = &resume_handle;
1598
1599         status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
1600         if (!NT_STATUS_IS_OK(status)) {
1601                 printf("EnumDomains failed - %s\n", nt_errstr(status));
1602                 return False;
1603         }
1604
1605         if (!r.out.sam) {
1606                 return False;
1607         }
1608
1609         for (i=0;i<r.out.sam->count;i++) {
1610                 if (!test_LookupDomain(p, mem_ctx, handle, 
1611                                        &r.out.sam->entries[i].name)) {
1612                         ret = False;
1613                 }
1614         }
1615
1616         return ret;
1617 }
1618
1619
1620 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1621                          struct policy_handle *handle)
1622 {
1623         NTSTATUS status;
1624         struct samr_Connect r;
1625         struct samr_Connect2 r2;
1626         struct samr_Connect4 r4;
1627         struct samr_Connect5 r5;
1628         BOOL ret = True;
1629
1630         r.in.system_name = 0;
1631         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1632         r.out.handle = handle;
1633
1634         status = dcerpc_samr_Connect(p, mem_ctx, &r);
1635         if (!NT_STATUS_IS_OK(status)) {
1636                 printf("Connect failed - %s\n", nt_errstr(status));
1637                 ret = False;
1638         }
1639
1640         r2.in.system_name = "";
1641         r2.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1642         r2.out.handle = handle;
1643
1644         status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
1645         if (!NT_STATUS_IS_OK(status)) {
1646                 printf("Connect2 failed - %s\n", nt_errstr(status));
1647                 ret = False;
1648         }
1649
1650         r4.in.system_name = "";
1651         r4.in.unknown = 0;
1652         r4.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1653         r4.out.handle = handle;
1654
1655         status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
1656         if (!NT_STATUS_IS_OK(status)) {
1657                 printf("Connect4 failed - %s\n", nt_errstr(status));
1658                 ret = False;
1659         }
1660
1661         r5.in.system_name = "";
1662         r5.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1663         r5.in.unknown0 = 1; /*Magic values I took from a WinXP pro workstation       */
1664         r5.in.unknown1 = 1; /*tests failed with NT_STATUS_NET_WRITE_FAULT if         */
1665         r5.in.unknown2 = 3; /*unknown0 and unknown1 where something other than 1     */
1666         r5.in.unknown3 = 0; /*unkown2 and unknown3 could be varied and had no effect */
1667         r5.out.handle = handle;
1668
1669         status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
1670         if (!NT_STATUS_IS_OK(status)) {
1671                 /*This fails for a Win2000pro machine, but succeeds for
1672                   WinXPpro  --  Kai
1673                  */
1674                 printf("Connect5 failed - %s\n", nt_errstr(status));
1675                 /*ret = False; Should this test fail? */
1676         }
1677
1678         return ret;
1679 }
1680
1681
1682 BOOL torture_rpc_samr(int dummy)
1683 {
1684         NTSTATUS status;
1685         struct dcerpc_pipe *p;
1686         TALLOC_CTX *mem_ctx;
1687         BOOL ret = True;
1688         struct policy_handle handle;
1689
1690         mem_ctx = talloc_init("torture_rpc_samr");
1691
1692         status = torture_rpc_connection(&p, 
1693                                         DCERPC_SAMR_NAME,
1694                                         DCERPC_SAMR_UUID,
1695                                         DCERPC_SAMR_VERSION);
1696         if (!NT_STATUS_IS_OK(status)) {
1697                 return False;
1698         }
1699
1700         if (!test_Connect(p, mem_ctx, &handle)) {
1701                 ret = False;
1702         }
1703
1704         if (!test_QuerySecurity(p, mem_ctx, &handle)) {
1705                 ret = False;
1706         }
1707
1708         if (!test_EnumDomains(p, mem_ctx, &handle)) {
1709                 ret = False;
1710         }
1711
1712         if (!test_Close(p, mem_ctx, &handle)) {
1713                 ret = False;
1714         }
1715
1716         talloc_destroy(mem_ctx);
1717
1718         torture_rpc_close(p);
1719
1720         return ret;
1721 }