- add 'print' to the DCERPC binding strings
[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    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_MACHINENAME "samrtorturetestmach$"
28 #define TEST_DOMAINNAME "samrtorturetestdom$"
29
30
31 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
32                                struct policy_handle *handle);
33
34 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
35                                struct policy_handle *handle);
36
37 static void init_samr_Name(struct samr_Name *name, const char *s)
38 {
39         name->name = s;
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         struct samr_SetSecurity s;
67
68         r.in.handle = handle;
69         r.in.sec_info = 7;
70
71         status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
72         if (!NT_STATUS_IS_OK(status)) {
73                 printf("QuerySecurity failed - %s\n", nt_errstr(status));
74                 return False;
75         }
76
77         s.in.handle = handle;
78         s.in.sec_info = 7;
79         s.in.sdbuf = r.out.sdbuf;
80
81         status = dcerpc_samr_SetSecurity(p, mem_ctx, &s);
82         if (!NT_STATUS_IS_OK(status)) {
83                 printf("SetSecurity failed - %s\n", nt_errstr(status));
84                 return False;
85         }
86
87         status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
88         if (!NT_STATUS_IS_OK(status)) {
89                 printf("QuerySecurity failed - %s\n", nt_errstr(status));
90                 return False;
91         }
92
93         return True;
94 }
95
96
97 static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
98                              struct policy_handle *handle)
99 {
100         NTSTATUS status;
101         struct samr_SetUserInfo s;
102         struct samr_QueryUserInfo q;
103         struct samr_QueryUserInfo q0;
104         union samr_UserInfo u;
105         BOOL ret = True;
106
107         s.in.handle = handle;
108         s.in.info = &u;
109         q.in.handle = handle;
110         q.out.info = &u;
111         q0 = q;
112
113 #define TESTCALL(call, r) \
114                 status = dcerpc_samr_ ##call(p, mem_ctx, &r); \
115                 if (!NT_STATUS_IS_OK(status)) { \
116                         printf(#call " level %u failed - %s (line %d)\n", \
117                                r.in.level, nt_errstr(status), __LINE__); \
118                         ret = False; \
119                         break; \
120                 }
121
122 #define STRING_EQUAL(s1, s2, field) \
123                 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
124                         printf("Failed to set %s to '%s' (line %d)\n", \
125                                #field, s2, __LINE__); \
126                         ret = False; \
127                         break; \
128                 }
129
130 #define INT_EQUAL(i1, i2, field) \
131                 if (i1 != i2) { \
132                         printf("Failed to set %s to %u (line %d)\n", \
133                                #field, i2, __LINE__); \
134                         ret = False; \
135                         break; \
136                 }
137
138 #define TEST_USERINFO_NAME(lvl1, field1, lvl2, field2, value, fpval) do { \
139                 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
140                 q.in.level = lvl1; \
141                 TESTCALL(QueryUserInfo, q) \
142                 s.in.level = lvl1; \
143                 u = *q.out.info; \
144                 init_samr_Name(&u.info ## lvl1.field1, value); \
145                 if (lvl1 == 21) { \
146                         u.info21.fields_present = fpval; \
147                 } \
148                 TESTCALL(SetUserInfo, s) \
149                 init_samr_Name(&u.info ## lvl1.field1, ""); \
150                 TESTCALL(QueryUserInfo, q); \
151                 u = *q.out.info; \
152                 STRING_EQUAL(u.info ## lvl1.field1.name, value, field1); \
153                 q.in.level = lvl2; \
154                 TESTCALL(QueryUserInfo, q) \
155                 u = *q.out.info; \
156                 STRING_EQUAL(u.info ## lvl2.field2.name, value, field2); \
157         } while (0)
158
159 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
160                 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
161                 q.in.level = lvl1; \
162                 TESTCALL(QueryUserInfo, q) \
163                 s.in.level = lvl1; \
164                 u = *q.out.info; \
165                 u.info ## lvl1.field1 = value; \
166                 if (lvl1 == 21) { \
167                         u.info21.fields_present = fpval; \
168                 } \
169                 TESTCALL(SetUserInfo, s) \
170                 u.info ## lvl1.field1 = 0; \
171                 TESTCALL(QueryUserInfo, q); \
172                 u = *q.out.info; \
173                 INT_EQUAL(u.info ## lvl1.field1, value, field1); \
174                 q.in.level = lvl2; \
175                 TESTCALL(QueryUserInfo, q) \
176                 u = *q.out.info; \
177                 INT_EQUAL(u.info ## lvl2.field2, value, field1); \
178         } while (0)
179
180         q0.in.level = 12;
181         do { TESTCALL(QueryUserInfo, q0) } while (0);
182
183         TEST_USERINFO_NAME(2, comment,  1, comment, "xx2-1 comment", 0);
184         TEST_USERINFO_NAME(2, comment, 21, comment, "xx2-21 comment", 0);
185         TEST_USERINFO_NAME(21, comment, 21, comment, "xx21-21 comment", 0x00000020);
186
187         TEST_USERINFO_NAME(6, full_name,  1, full_name, "xx6-1 full_name", 0);
188         TEST_USERINFO_NAME(6, full_name,  3, full_name, "xx6-3 full_name", 0);
189         TEST_USERINFO_NAME(6, full_name,  5, full_name, "xx6-5 full_name", 0);
190         TEST_USERINFO_NAME(6, full_name,  6, full_name, "xx6-6 full_name", 0);
191         TEST_USERINFO_NAME(6, full_name,  8, full_name, "xx6-8 full_name", 0);
192         TEST_USERINFO_NAME(6, full_name, 21, full_name, "xx6-21 full_name", 0);
193         TEST_USERINFO_NAME(8, full_name, 21, full_name, "xx8-21 full_name", 0);
194         TEST_USERINFO_NAME(21, full_name, 21, full_name, "xx21-21 full_name", 0x00000002);
195
196         TEST_USERINFO_NAME(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
197         TEST_USERINFO_NAME(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
198         TEST_USERINFO_NAME(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
199         TEST_USERINFO_NAME(21, logon_script, 21, logon_script, "xx21-21 logon_script", 0x00000100);
200
201         TEST_USERINFO_NAME(12, profile,  3, profile, "xx12-3 profile", 0);
202         TEST_USERINFO_NAME(12, profile,  5, profile, "xx12-5 profile", 0);
203         TEST_USERINFO_NAME(12, profile, 21, profile, "xx12-21 profile", 0);
204         TEST_USERINFO_NAME(21, profile, 21, profile, "xx21-21 profile", 0x00000200);
205
206         TEST_USERINFO_NAME(13, description,  1, description, "xx13-1 description", 0);
207         TEST_USERINFO_NAME(13, description,  5, description, "xx13-5 description", 0);
208         TEST_USERINFO_NAME(13, description, 21, description, "xx13-21 description", 0);
209         TEST_USERINFO_NAME(21, description, 21, description, "xx21-21 description", 0x00000010);
210
211         TEST_USERINFO_NAME(14, workstations,  3, workstations, "14workstation3", 0);
212         TEST_USERINFO_NAME(14, workstations,  5, workstations, "14workstation4", 0);
213         TEST_USERINFO_NAME(14, workstations, 21, workstations, "14workstation21", 0);
214         TEST_USERINFO_NAME(21, workstations, 21, workstations, "21workstation21", 0x00000400);
215
216         TEST_USERINFO_NAME(20, callback, 21, callback, "xx20-21 callback", 0);
217         TEST_USERINFO_NAME(21, callback, 21, callback, "xx21-21 callback", 0x00200000);
218
219         TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
220         TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__, 0x00400000);
221         TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
222         TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__, 0x00800000);
223
224         TEST_USERINFO_INT(4, logon_hours.bitmap[3],  3, logon_hours.bitmap[3], __LINE__, 0);
225         TEST_USERINFO_INT(4, logon_hours.bitmap[3],  5, logon_hours.bitmap[3], __LINE__, 0);
226         TEST_USERINFO_INT(4, logon_hours.bitmap[3], 21, logon_hours.bitmap[3], __LINE__, 0);
227         TEST_USERINFO_INT(21, logon_hours.bitmap[3], 21, logon_hours.bitmap[3], __LINE__, 0x00002000);
228
229 #if 0
230         /* these fail with win2003 - it appears you can't set the primary gid?
231            the set succeeds, but the gid isn't changed. Very weird! */
232         TEST_USERINFO_INT(9, primary_gid,  1, primary_gid, 513);
233         TEST_USERINFO_INT(9, primary_gid,  3, primary_gid, 513);
234         TEST_USERINFO_INT(9, primary_gid,  5, primary_gid, 513);
235         TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
236 #endif
237         return ret;
238 }
239
240 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
241                                struct policy_handle *handle)
242 {
243         NTSTATUS status;
244         struct samr_SetAliasInfo r;
245         struct samr_QueryAliasInfo q;
246         uint16 levels[] = {2, 3};
247         int i;
248         BOOL ret = True;
249
250         /* Ignoring switch level 1, as that includes the number of members for the alias
251          * and setting this to a wrong value might have negative consequences
252          */
253
254         for (i=0;i<ARRAY_SIZE(levels);i++) {
255                 printf("Testing SetAliasInfo level %u\n", levels[i]);
256
257                 r.in.handle = handle;
258                 r.in.level = levels[i];
259                 switch (r.in.level) {
260                     case 2 : init_samr_Name(&r.in.info.name,TEST_ALIASNAME); break;
261                     case 3 : init_samr_Name(&r.in.info.description,
262                                 "Test Description, should test I18N as well"); break;
263                 }
264
265                 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
266                 if (!NT_STATUS_IS_OK(status)) {
267                         printf("SetAliasInfo level %u failed - %s\n",
268                                levels[i], nt_errstr(status));
269                         ret = False;
270                 }
271
272                 q.in.handle = handle;
273                 q.in.level = levels[i];
274
275                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
276                 if (!NT_STATUS_IS_OK(status)) {
277                         printf("QueryAliasInfo level %u failed - %s\n",
278                                levels[i], nt_errstr(status));
279                         ret = False;
280                 }
281         }
282
283         return ret;
284 }
285
286 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
287                                   struct policy_handle *user_handle)
288 {
289         struct samr_GetGroupsForUser r;
290         NTSTATUS status;
291         BOOL ret = True;
292
293         printf("testing GetGroupsForUser\n");
294
295         r.in.handle = user_handle;
296
297         status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
298         if (!NT_STATUS_IS_OK(status)) {
299                 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
300                 ret = False;
301         }
302
303         return ret;
304
305 }
306 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
307                                struct policy_handle *handle)
308 {
309         NTSTATUS status;
310         struct samr_GetUserPwInfo r;
311         BOOL ret = True;
312
313         printf("Testing GetUserPwInfo\n");
314
315         r.in.handle = handle;
316
317         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
318         if (!NT_STATUS_IS_OK(status)) {
319                 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
320                 ret = False;
321         }
322
323         return ret;
324 }
325
326 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
327                                   struct policy_handle *alias_handle)
328 {
329         struct samr_GetMembersInAlias r;
330         struct lsa_SidArray sids;
331         NTSTATUS status;
332         BOOL     ret = True;
333
334         printf("Testing GetMembersInAlias\n");
335
336         r.in.handle = alias_handle;
337         r.out.sids = &sids;
338
339         status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
340         if (!NT_STATUS_IS_OK(status)) {
341                 printf("GetMembersInAlias failed - %s\n",
342                        nt_errstr(status));
343                 ret = False;
344         }
345
346         return ret;
347 }
348
349 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
350                                   struct policy_handle *alias_handle,
351                                   struct policy_handle *domain_handle,
352                                   const struct dom_sid *domain_sid)
353 {
354         struct samr_AddAliasMem r;
355         struct samr_DelAliasMem d;
356         NTSTATUS status;
357         BOOL ret = True;
358         struct dom_sid *sid;
359
360         sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
361
362         printf("testing AddAliasMem\n");
363         r.in.handle = alias_handle;
364         r.in.sid = sid;
365
366         status = dcerpc_samr_AddAliasMem(p, mem_ctx, &r);
367         if (!NT_STATUS_IS_OK(status)) {
368                 printf("AddAliasMem failed - %s\n", nt_errstr(status));
369                 ret = False;
370         }
371
372         d.in.handle = alias_handle;
373         d.in.sid = sid;
374
375         status = dcerpc_samr_DelAliasMem(p, mem_ctx, &d);
376         if (!NT_STATUS_IS_OK(status)) {
377                 printf("DelAliasMem failed - %s\n", nt_errstr(status));
378                 ret = False;
379         }
380
381         return ret;
382 }
383
384 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
385                           struct policy_handle *handle)
386 {
387         BOOL ret = True;
388
389         if (!test_QuerySecurity(p, mem_ctx, handle)) {
390                 ret = False;
391         }
392
393         if (!test_QueryUserInfo(p, mem_ctx, handle)) {
394                 ret = False;
395         }
396
397         if (!test_SetUserInfo(p, mem_ctx, handle)) {
398                 ret = False;
399         }       
400
401         if (!test_GetUserPwInfo(p, mem_ctx, handle)) {
402                 ret = False;
403         }
404
405         return ret;
406 }
407
408 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
409                            struct policy_handle *alias_handle,
410                            struct policy_handle *domain_handle,
411                            const struct dom_sid *domain_sid)
412 {
413         BOOL ret = True;
414
415         if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
416                 ret = False;
417         }
418
419         if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
420                 ret = False;
421         }
422
423         if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
424                 ret = False;
425         }
426
427         if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, 
428                                    domain_handle, domain_sid)) {
429                 ret = False;
430         }
431
432         return ret;
433 }
434
435 static BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
436                                    struct policy_handle *handle, const char *name)
437 {
438         NTSTATUS status;
439         struct samr_LookupNames n;
440         struct samr_OpenUser r;
441         struct samr_DeleteUser d;
442         struct policy_handle acct_handle;
443         struct samr_Name sname;
444
445         init_samr_Name(&sname, name);
446
447         n.in.handle = handle;
448         n.in.num_names = 1;
449         n.in.names = &sname;
450         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
451         if (!NT_STATUS_IS_OK(status)) {
452                 goto failed;
453         }
454
455         r.in.handle = handle;
456         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
457         r.in.rid = n.out.rids.ids[0];
458         r.out.acct_handle = &acct_handle;
459         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
460         if (!NT_STATUS_IS_OK(status)) {
461                 goto failed;
462         }
463
464         d.in.handle = &acct_handle;
465         d.out.handle = &acct_handle;
466         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
467         if (!NT_STATUS_IS_OK(status)) {
468                 goto failed;
469         }
470
471         return True;
472
473 failed:
474         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
475         return False;
476 }
477
478 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
479                                    struct policy_handle *domain_handle, const char *name)
480 {
481         NTSTATUS status;
482         struct samr_LookupNames n;
483         struct samr_OpenAlias r;
484         struct samr_DeleteDomAlias d;
485         struct policy_handle alias_handle;
486         struct samr_Name sname;
487
488         printf("testing DeleteAlias_byname\n");
489         init_samr_Name(&sname, name);
490
491         n.in.handle = domain_handle;
492         n.in.num_names = 1;
493         n.in.names = &sname;
494         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
495         if (!NT_STATUS_IS_OK(status)) {
496                 goto failed;
497         }
498
499         r.in.handle = domain_handle;
500         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
501         r.in.rid = n.out.rids.ids[0];
502         r.out.acct_handle = &alias_handle;
503         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
504         if (!NT_STATUS_IS_OK(status)) {
505                 goto failed;
506         }
507
508         d.in.handle = &alias_handle;
509         d.out.handle = &alias_handle;
510         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
511         if (!NT_STATUS_IS_OK(status)) {
512                 goto failed;
513         }
514
515         return True;
516
517 failed:
518         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
519         return False;
520 }
521
522 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
523                                      struct policy_handle *alias_handle)
524 {
525         struct samr_DeleteDomAlias d;
526         NTSTATUS status;
527         BOOL ret;
528         printf("Testing DeleteAlias\n");
529
530         d.in.handle = alias_handle;
531         d.out.handle = alias_handle;
532
533         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
534         if (!NT_STATUS_IS_OK(status)) {
535                 printf("DeleteAlias failed - %s\n", nt_errstr(status));
536                 ret = False;
537         }
538
539         return ret;
540 }
541
542 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
543                             struct policy_handle *domain_handle, 
544                              struct policy_handle *alias_handle, 
545                              const struct dom_sid *domain_sid)
546 {
547         NTSTATUS status;
548         struct samr_CreateDomAlias r;
549         struct samr_Name name;
550         uint32 rid;
551         BOOL ret = True;
552
553         init_samr_Name(&name, TEST_ALIASNAME);
554         r.in.handle = domain_handle;
555         r.in.aliasname = &name;
556         r.in.access_mask = SEC_RIGHT_MAXIMUM_ALLOWED;
557         r.out.acct_handle = alias_handle;
558         r.out.rid = &rid;
559
560         printf("Testing CreateAlias (%s)\n", r.in.aliasname->name);
561
562         status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
563
564         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
565                 printf("Server refused create of '%s'\n", r.in.aliasname->name);
566                 return True;
567         }
568
569         if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
570                 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.aliasname->name)) {
571                         return False;
572                 }
573                 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
574         }
575
576         if (!NT_STATUS_IS_OK(status)) {
577                 printf("CreateAlias failed - %s\n", nt_errstr(status));
578                 return False;
579         }
580
581         if (!test_alias_ops(p, mem_ctx, alias_handle, domain_handle, domain_sid)) {
582                 ret = False;
583         }
584
585         return ret;
586 }
587
588 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
589                             struct policy_handle *domain_handle, struct policy_handle *user_handle)
590 {
591         NTSTATUS status;
592         struct samr_CreateUser r;
593         struct samr_QueryUserInfo q;
594         uint32 rid;
595
596         /* This call creates a 'normal' account - check that it really does */
597         const uint32 acct_flags = ACB_NORMAL;
598         struct samr_Name name;
599         BOOL ret = True;
600
601         init_samr_Name(&name, TEST_USERNAME);
602
603         r.in.handle = domain_handle;
604         r.in.username = &name;
605         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
606         r.out.acct_handle = user_handle;
607         r.out.rid = &rid;
608
609         printf("Testing CreateUser(%s)\n", r.in.username->name);
610
611         status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
612
613         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
614                 printf("Server refused create of '%s'\n", r.in.username->name);
615                 ZERO_STRUCTP(user_handle);
616                 return True;
617         }
618
619         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
620                 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.username->name)) {
621                         return False;
622                 }
623                 status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
624         }
625         if (!NT_STATUS_IS_OK(status)) {
626                 printf("CreateUser failed - %s\n", nt_errstr(status));
627                 return False;
628         }
629
630
631         q.in.handle = user_handle;
632         q.in.level = 16;
633
634         status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
635         if (!NT_STATUS_IS_OK(status)) {
636                 printf("QueryUserInfo level %u failed - %s\n", 
637                        q.in.level, nt_errstr(status));
638                 ret = False;
639         } else {
640                 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
641                         printf("QuerUserInfo level 16 failed, it returned 0x%08x (%u) when we expected flags of 0x%08x (%u)\n",
642                                q.out.info->info16.acct_flags, q.out.info->info16.acct_flags, 
643                                acct_flags, acct_flags);
644                         ret = False;
645                 }
646         }
647
648         if (!test_user_ops(p, mem_ctx, user_handle)) {
649                 ret = False;
650         }
651
652         return ret;
653 }
654
655
656 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
657                             struct policy_handle *user_handle)
658 {
659         struct samr_DeleteUser d;
660         NTSTATUS status;
661         BOOL ret;
662
663         printf("Testing DeleteUser\n");
664
665         d.in.handle = user_handle;
666         d.out.handle = user_handle;
667
668         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
669         if (!NT_STATUS_IS_OK(status)) {
670                 printf("DeleteUser failed - %s\n", nt_errstr(status));
671                 ret = False;
672         }
673
674         return ret;
675 }
676
677 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
678                              struct policy_handle *handle)
679 {
680         NTSTATUS status;
681         struct samr_CreateUser2 r;
682         struct samr_QueryUserInfo q;
683         struct samr_DeleteUser d;
684         struct policy_handle acct_handle;
685         uint32 rid;
686         struct samr_Name name;
687         BOOL ret = True;
688         int i;
689
690         struct {
691                 uint32 acct_flags;
692                 const char *account_name;
693                 NTSTATUS nt_status;
694         } account_types[] = {
695                 { ACB_NORMAL, TEST_USERNAME, NT_STATUS_OK },
696                 { ACB_NORMAL | ACB_DISABLED, TEST_USERNAME, NT_STATUS_INVALID_PARAMETER },
697                 { ACB_NORMAL | ACB_PWNOEXP, TEST_USERNAME, NT_STATUS_INVALID_PARAMETER },
698                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
699                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
700                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
701                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
702                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
703                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
704                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
705                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
706                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
707                 { 0, TEST_USERNAME, NT_STATUS_INVALID_PARAMETER },
708                 { ACB_DISABLED, TEST_USERNAME, NT_STATUS_INVALID_PARAMETER },
709                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
710         };
711
712         for (i = 0; account_types[i].account_name; i++) {
713                 uint32 acct_flags = account_types[i].acct_flags;
714                 uint32 access_granted;
715
716                 init_samr_Name(&name, account_types[i].account_name);
717
718                 r.in.handle = handle;
719                 r.in.username = &name;
720                 r.in.acct_flags = acct_flags;
721                 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
722                 r.out.acct_handle = &acct_handle;
723                 r.out.access_granted = &access_granted;
724                 r.out.rid = &rid;
725                 
726                 printf("Testing CreateUser2(%s)\n", r.in.username->name);
727                 
728                 status = dcerpc_samr_CreateUser2(p, mem_ctx, &r);
729                 
730                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
731                         printf("Server refused create of '%s'\n", r.in.username->name);
732                         continue;
733
734                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
735                         if (!test_DeleteUser_byname(p, mem_ctx, handle, r.in.username->name)) {
736                                 return False;
737                         }
738                         status = dcerpc_samr_CreateUser2(p, mem_ctx, &r);
739
740                 }
741                 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
742                         printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n", 
743                                nt_errstr(status), nt_errstr(account_types[i].nt_status));
744                         ret = False;
745                 }
746                 
747                 if (NT_STATUS_IS_OK(status)) {
748                         q.in.handle = &acct_handle;
749                         q.in.level = 16;
750                         
751                         status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
752                         if (!NT_STATUS_IS_OK(status)) {
753                                 printf("QueryUserInfo level %u failed - %s\n", 
754                                        q.in.level, nt_errstr(status));
755                                 ret = False;
756                         } else {
757                                 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
758                                         printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
759                                                q.out.info->info16.acct_flags, 
760                                                acct_flags);
761                                         ret = False;
762                                 }
763                         }
764                 
765                         if (!test_user_ops(p, mem_ctx, &acct_handle)) {
766                                 ret = False;
767                         }
768
769                         printf("Testing DeleteUser (createuser2 test)\n");
770                 
771                         d.in.handle = &acct_handle;
772                         d.out.handle = &acct_handle;
773                         
774                         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
775                         if (!NT_STATUS_IS_OK(status)) {
776                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
777                                 ret = False;
778                         }
779                 }
780         }
781
782         return ret;
783 }
784
785 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
786                                 struct policy_handle *handle)
787 {
788         NTSTATUS status;
789         struct samr_QueryAliasInfo r;
790         uint16 levels[] = {1, 2, 3};
791         int i;
792         BOOL ret = True;
793
794         for (i=0;i<ARRAY_SIZE(levels);i++) {
795                 printf("Testing QueryAliasInfo level %u\n", levels[i]);
796
797                 r.in.handle = handle;
798                 r.in.level = levels[i];
799
800                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
801                 if (!NT_STATUS_IS_OK(status)) {
802                         printf("QueryAliasInfo level %u failed - %s\n", 
803                                levels[i], nt_errstr(status));
804                         ret = False;
805                 }
806         }
807
808         return ret;
809 }
810
811 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
812                                 struct policy_handle *handle)
813 {
814         NTSTATUS status;
815         struct samr_QueryGroupInfo r;
816         uint16 levels[] = {1, 2, 3, 4};
817         int i;
818         BOOL ret = True;
819
820         for (i=0;i<ARRAY_SIZE(levels);i++) {
821                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
822
823                 r.in.handle = handle;
824                 r.in.level = levels[i];
825
826                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
827                 if (!NT_STATUS_IS_OK(status)) {
828                         printf("QueryGroupInfo level %u failed - %s\n", 
829                                levels[i], nt_errstr(status));
830                         ret = False;
831                 }
832         }
833
834         return ret;
835 }
836
837 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
838                                struct policy_handle *handle)
839 {
840         NTSTATUS status;
841         struct samr_QueryUserInfo r;
842         uint16 levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
843                            11, 12, 13, 14, 16, 17, 20, 21};
844         int i;
845         BOOL ret = True;
846
847         for (i=0;i<ARRAY_SIZE(levels);i++) {
848                 printf("Testing QueryUserInfo level %u\n", levels[i]);
849
850                 r.in.handle = handle;
851                 r.in.level = levels[i];
852
853                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
854                 if (!NT_STATUS_IS_OK(status)) {
855                         printf("QueryUserInfo level %u failed - %s\n", 
856                                levels[i], nt_errstr(status));
857                         ret = False;
858                 }
859         }
860
861         return ret;
862 }
863
864 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
865                           struct policy_handle *handle, uint32 rid)
866 {
867         NTSTATUS status;
868         struct samr_OpenUser r;
869         struct policy_handle acct_handle;
870         BOOL ret = True;
871
872         printf("Testing OpenUser(%u)\n", rid);
873
874         r.in.handle = handle;
875         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
876         r.in.rid = rid;
877         r.out.acct_handle = &acct_handle;
878
879         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
880         if (!NT_STATUS_IS_OK(status)) {
881                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
882                 return False;
883         }
884
885         if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
886                 ret = False;
887         }
888
889         if (!test_QueryUserInfo(p, mem_ctx, &acct_handle)) {
890                 ret = False;
891         }
892
893         if (!test_GetUserPwInfo(p, mem_ctx, &acct_handle)) {
894                 ret = False;
895         }
896
897         if (!test_GetGroupsForUser(p,mem_ctx, &acct_handle)) {
898                 ret = False;
899         }
900
901         if (!test_Close(p, mem_ctx, &acct_handle)) {
902                 ret = False;
903         }
904
905         return ret;
906 }
907
908 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
909                            struct policy_handle *handle, uint32 rid)
910 {
911         NTSTATUS status;
912         struct samr_OpenGroup r;
913         struct policy_handle acct_handle;
914         BOOL ret = True;
915
916         printf("Testing OpenGroup(%u)\n", rid);
917
918         r.in.handle = handle;
919         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
920         r.in.rid = rid;
921         r.out.acct_handle = &acct_handle;
922
923         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
924         if (!NT_STATUS_IS_OK(status)) {
925                 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
926                 return False;
927         }
928
929         if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
930                 ret = False;
931         }
932
933         if (!test_QueryGroupInfo(p, mem_ctx, &acct_handle)) {
934                 ret = False;
935         }
936
937         if (!test_Close(p, mem_ctx, &acct_handle)) {
938                 ret = False;
939         }
940
941         return ret;
942 }
943
944 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
945                            struct policy_handle *handle, uint32 rid)
946 {
947         NTSTATUS status;
948         struct samr_OpenAlias r;
949         struct policy_handle acct_handle;
950         BOOL ret = True;
951
952         printf("Testing OpenAlias(%u)\n", rid);
953
954         r.in.handle = handle;
955         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
956         r.in.rid = rid;
957         r.out.acct_handle = &acct_handle;
958
959         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
960         if (!NT_STATUS_IS_OK(status)) {
961                 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
962                 return False;
963         }
964
965         if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
966                 ret = False;
967         }
968
969         if (!test_QueryAliasInfo(p, mem_ctx, &acct_handle)) {
970                 ret = False;
971         }
972
973         if (!test_GetMembersInAlias(p, mem_ctx, &acct_handle)) {
974                 ret = False;
975         }
976
977         if (!test_Close(p, mem_ctx, &acct_handle)) {
978                 ret = False;
979         }
980
981         return ret;
982 }
983
984 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
985                                  struct policy_handle *handle)
986 {
987         NTSTATUS status;
988         struct samr_EnumDomainUsers r;
989         uint32 resume_handle=0;
990         int i;
991         BOOL ret = True;
992         struct samr_LookupNames n;
993         struct samr_LookupRids  lr ;
994
995         printf("Testing EnumDomainUsers\n");
996
997         r.in.handle = handle;
998         r.in.resume_handle = &resume_handle;
999         r.in.acct_flags = 0;
1000         r.in.max_size = (uint32)-1;
1001         r.out.resume_handle = &resume_handle;
1002
1003         status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
1004         if (!NT_STATUS_IS_OK(status)) {
1005                 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
1006                 return False;
1007         }
1008         
1009         if (!r.out.sam) {
1010                 return False;
1011         }
1012
1013         if (r.out.sam->count == 0) {
1014                 return True;
1015         }
1016
1017         for (i=0;i<r.out.sam->count;i++) {
1018                 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
1019                         ret = False;
1020                 }
1021         }
1022
1023         printf("Testing LookupNames\n");
1024         n.in.handle = handle;
1025         n.in.num_names = r.out.sam->count;
1026         n.in.names = talloc(mem_ctx, r.out.sam->count * sizeof(struct samr_Name));
1027         for (i=0;i<r.out.sam->count;i++) {
1028                 n.in.names[i] = r.out.sam->entries[i].name;
1029         }
1030         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
1031         if (!NT_STATUS_IS_OK(status)) {
1032                 printf("LookupNames failed - %s\n", nt_errstr(status));
1033                 ret = False;
1034         }
1035
1036
1037         printf("Testing LookupRids\n");
1038         lr.in.handle = handle;
1039         lr.in.num_rids = r.out.sam->count;
1040         lr.in.rids = talloc(mem_ctx, r.out.sam->count * sizeof(uint32));
1041         for (i=0;i<r.out.sam->count;i++) {
1042                 lr.in.rids[i] = r.out.sam->entries[i].idx;
1043         }
1044         status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
1045         if (!NT_STATUS_IS_OK(status)) {
1046                 printf("LookupRids failed - %s\n", nt_errstr(status));
1047                 ret = False;
1048         }
1049
1050         return ret;     
1051 }
1052
1053 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1054                                   struct policy_handle *handle)
1055 {
1056         NTSTATUS status;
1057         struct samr_EnumDomainGroups r;
1058         uint32 resume_handle=0;
1059         int i;
1060         BOOL ret = True;
1061
1062         printf("Testing EnumDomainGroups\n");
1063
1064         r.in.handle = handle;
1065         r.in.resume_handle = &resume_handle;
1066         r.in.max_size = (uint32)-1;
1067         r.out.resume_handle = &resume_handle;
1068
1069         status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
1070         if (!NT_STATUS_IS_OK(status)) {
1071                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
1072                 return False;
1073         }
1074         
1075         if (!r.out.sam) {
1076                 return False;
1077         }
1078
1079         for (i=0;i<r.out.sam->count;i++) {
1080                 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
1081                         ret = False;
1082                 }
1083         }
1084
1085         return ret;
1086 }
1087
1088 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1089                                    struct policy_handle *handle)
1090 {
1091         NTSTATUS status;
1092         struct samr_EnumDomainAliases r;
1093         uint32 resume_handle=0;
1094         int i;
1095         BOOL ret = True;
1096
1097         printf("Testing EnumDomainAliases\n");
1098
1099         r.in.handle = handle;
1100         r.in.resume_handle = &resume_handle;
1101         r.in.max_size = (uint32)-1;
1102         r.out.resume_handle = &resume_handle;
1103
1104         status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
1105         if (!NT_STATUS_IS_OK(status)) {
1106                 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
1107                 return False;
1108         }
1109         
1110         if (!r.out.sam) {
1111                 return False;
1112         }
1113
1114         for (i=0;i<r.out.sam->count;i++) {
1115                 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
1116                         ret = False;
1117                 }
1118         }
1119
1120         return ret;     
1121 }
1122
1123 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1124                                   struct policy_handle *handle)
1125 {
1126         NTSTATUS status;
1127         struct samr_QueryDisplayInfo r;
1128         BOOL ret = True;
1129         uint16 levels[] = {1, 2, 3, 4, 5};
1130         int i;
1131
1132         for (i=0;i<ARRAY_SIZE(levels);i++) {
1133                 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
1134
1135                 r.in.handle = handle;
1136                 r.in.level = levels[i];
1137                 r.in.start_idx = 0;
1138                 r.in.max_entries = 1000;
1139                 r.in.buf_size = (uint32)-1;
1140
1141                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
1142                 if (!NT_STATUS_IS_OK(status)) {
1143                         printf("QueryDisplayInfo level %u failed - %s\n", 
1144                                levels[i], nt_errstr(status));
1145                         ret = False;
1146                 }
1147         }
1148         
1149         return ret;     
1150 }
1151
1152 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1153                                  struct policy_handle *handle)
1154 {
1155         NTSTATUS status;
1156         struct samr_QueryDomainInfo r;
1157         uint16 levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
1158         int i;
1159         BOOL ret = True;
1160
1161         for (i=0;i<ARRAY_SIZE(levels);i++) {
1162                 printf("Testing QueryDomainInfo level %u\n", levels[i]);
1163
1164                 r.in.handle = handle;
1165                 r.in.level = levels[i];
1166
1167                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
1168                 if (!NT_STATUS_IS_OK(status)) {
1169                         printf("QueryDomainInfo level %u failed - %s\n", 
1170                                r.in.level, nt_errstr(status));
1171                         ret = False;
1172                         continue;
1173                 }
1174         }
1175
1176         return True;    
1177 }
1178
1179 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1180                             struct policy_handle *handle, struct dom_sid *sid)
1181 {
1182         NTSTATUS status;
1183         struct samr_OpenDomain r;
1184         struct policy_handle domain_handle;
1185         struct policy_handle user_handle;
1186         struct policy_handle alias_handle;
1187         BOOL ret = True;
1188
1189         ZERO_STRUCT(user_handle);
1190         ZERO_STRUCT(alias_handle);
1191
1192         printf("Testing OpenDomain\n");
1193
1194         r.in.handle = handle;
1195         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1196         r.in.sid = sid;
1197         r.out.domain_handle = &domain_handle;
1198
1199         status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
1200         if (!NT_STATUS_IS_OK(status)) {
1201                 printf("OpenDomain failed - %s\n", nt_errstr(status));
1202                 return False;
1203         }
1204
1205         if (!test_CreateUser2(p, mem_ctx, &domain_handle)) {
1206                 ret = False;
1207         }
1208
1209         if (!test_CreateUser(p, mem_ctx, &domain_handle, &user_handle)) {
1210                 ret = False;
1211         }
1212
1213         if (!test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid)) {
1214                 ret = False;
1215         }
1216
1217         if (!test_QuerySecurity(p, mem_ctx, &domain_handle)) {
1218                 ret = False;
1219         }
1220
1221         if (!test_QueryDomainInfo(p, mem_ctx, &domain_handle)) {
1222                 ret = False;
1223         }
1224
1225         if (!test_EnumDomainUsers(p, mem_ctx, &domain_handle)) {
1226                 ret = False;
1227         }
1228
1229         if (!test_EnumDomainGroups(p, mem_ctx, &domain_handle)) {
1230                 ret = False;
1231         }
1232
1233         if (!test_EnumDomainAliases(p, mem_ctx, &domain_handle)) {
1234                 ret = False;
1235         }
1236
1237         if (!test_QueryDisplayInfo(p, mem_ctx, &domain_handle)) {
1238                 ret = False;
1239         }
1240
1241         if (!policy_handle_empty(&user_handle) &&
1242             !test_DeleteUser(p, mem_ctx, &user_handle)) {
1243                 ret = False;
1244         }
1245
1246         if (!policy_handle_empty(&alias_handle) &&
1247             !test_DeleteAlias(p,mem_ctx, &alias_handle)) {
1248                 ret = False;
1249         }
1250
1251         if (!test_Close(p, mem_ctx, &domain_handle)) {
1252                 ret = False;
1253         }
1254
1255         return ret;
1256 }
1257
1258 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1259                               struct policy_handle *handle, struct samr_Name *domain)
1260 {
1261         NTSTATUS status;
1262         struct samr_LookupDomain r;
1263
1264         printf("Testing LookupDomain(%s)\n", domain->name);
1265
1266         r.in.handle = handle;
1267         r.in.domain = domain;
1268
1269         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
1270         if (!NT_STATUS_IS_OK(status)) {
1271                 printf("LookupDomain failed - %s\n", nt_errstr(status));
1272                 return False;
1273         }
1274
1275         if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
1276                 return False;
1277         }
1278
1279         return True;    
1280 }
1281
1282
1283 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1284                              struct policy_handle *handle)
1285 {
1286         NTSTATUS status;
1287         struct samr_EnumDomains r;
1288         uint32 resume_handle = 0;
1289         int i;
1290         BOOL ret = True;
1291
1292         r.in.handle = handle;
1293         r.in.resume_handle = &resume_handle;
1294         r.in.buf_size = (uint32)-1;
1295         r.out.resume_handle = &resume_handle;
1296
1297         status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
1298         if (!NT_STATUS_IS_OK(status)) {
1299                 printf("EnumDomains failed - %s\n", nt_errstr(status));
1300                 return False;
1301         }
1302
1303         if (!r.out.sam) {
1304                 return False;
1305         }
1306
1307         for (i=0;i<r.out.sam->count;i++) {
1308                 if (!test_LookupDomain(p, mem_ctx, handle, 
1309                                        &r.out.sam->entries[i].name)) {
1310                         ret = False;
1311                 }
1312         }
1313
1314         return ret;
1315 }
1316
1317
1318 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1319                          struct policy_handle *handle)
1320 {
1321         NTSTATUS status;
1322         struct samr_Connect r;
1323         struct samr_Connect2 r2;
1324         struct samr_Connect4 r4;
1325         struct samr_Connect5 r5;
1326         BOOL ret = True;
1327
1328         r.in.system_name = 0;
1329         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1330         r.out.handle = handle;
1331
1332         status = dcerpc_samr_Connect(p, mem_ctx, &r);
1333         if (!NT_STATUS_IS_OK(status)) {
1334                 printf("Connect failed - %s\n", nt_errstr(status));
1335                 ret = False;
1336         }
1337
1338         r2.in.system_name = "";
1339         r2.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1340         r2.out.handle = handle;
1341
1342         status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
1343         if (!NT_STATUS_IS_OK(status)) {
1344                 printf("Connect2 failed - %s\n", nt_errstr(status));
1345                 ret = False;
1346         }
1347
1348         r4.in.system_name = "";
1349         r4.in.unknown = 0;
1350         r4.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1351         r4.out.handle = handle;
1352
1353         status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
1354         if (!NT_STATUS_IS_OK(status)) {
1355                 printf("Connect4 failed - %s\n", nt_errstr(status));
1356                 ret = False;
1357         }
1358
1359         r5.in.system_name = "";
1360         r5.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1361         r5.in.unknown0 = 1; /*Magic values I took from a WinXP pro workstation       */
1362         r5.in.unknown1 = 1; /*tests failed with NT_STATUS_NET_WRITE_FAULT if         */
1363         r5.in.unknown2 = 3; /*unknown0 and unknown1 where something other than 1     */
1364         r5.in.unknown3 = 0; /*unkown2 and unknown3 could be varied and had no effect */
1365         r5.out.handle = handle;
1366
1367         status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
1368         if (!NT_STATUS_IS_OK(status)) {
1369                 /*This fails for a Win2000pro machine, but succeeds for
1370                   WinXPpro  --  Kai
1371                  */
1372                 printf("Connect5 failed - %s\n", nt_errstr(status));
1373                 /*ret = False; Should this test fail? */
1374         }
1375
1376         return ret;
1377 }
1378
1379
1380 BOOL torture_rpc_samr(int dummy)
1381 {
1382         NTSTATUS status;
1383         struct dcerpc_pipe *p;
1384         TALLOC_CTX *mem_ctx;
1385         BOOL ret = True;
1386         struct policy_handle handle;
1387
1388         mem_ctx = talloc_init("torture_rpc_samr");
1389
1390         status = torture_rpc_connection(&p, 
1391                                         DCERPC_SAMR_NAME,
1392                                         DCERPC_SAMR_UUID,
1393                                         DCERPC_SAMR_VERSION);
1394         if (!NT_STATUS_IS_OK(status)) {
1395                 return False;
1396         }
1397
1398         if (!test_Connect(p, mem_ctx, &handle)) {
1399                 ret = False;
1400         }
1401
1402         if (!test_QuerySecurity(p, mem_ctx, &handle)) {
1403                 ret = False;
1404         }
1405
1406         if (!test_EnumDomains(p, mem_ctx, &handle)) {
1407                 ret = False;
1408         }
1409
1410         if (!test_Close(p, mem_ctx, &handle)) {
1411                 ret = False;
1412         }
1413
1414         talloc_destroy(mem_ctx);
1415
1416         torture_rpc_close(p);
1417
1418         return ret;
1419 }