r743: Start on a NETLOGON server in Samba4.
[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_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_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
36                                 struct policy_handle *handle);
37
38 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
39                                struct policy_handle *handle);
40
41 static void init_samr_Name(struct samr_Name *name, const char *s)
42 {
43         name->name = s;
44 }
45
46 static BOOL test_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
47                        struct policy_handle *handle)
48 {
49         NTSTATUS status;
50         struct samr_Close r;
51
52         r.in.handle = handle;
53         r.out.handle = handle;
54
55         status = dcerpc_samr_Close(p, mem_ctx, &r);
56         if (!NT_STATUS_IS_OK(status)) {
57                 printf("Close handle failed - %s\n", nt_errstr(status));
58                 return False;
59         }
60
61         return True;
62 }
63
64 static BOOL test_Shutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
65                        struct policy_handle *handle)
66 {
67         NTSTATUS status;
68         struct samr_Shutdown r;
69
70         if (lp_parm_int(-1, "torture", "dangerous") != 1) {
71                 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
72                 return True;
73         }
74
75         r.in.handle = handle;
76
77         printf("testing samr_Shutdown\n");
78
79         status = dcerpc_samr_Shutdown(p, mem_ctx, &r);
80         if (!NT_STATUS_IS_OK(status)) {
81                 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
82                 return False;
83         }
84
85         return True;
86 }
87
88 static BOOL test_SetDsrmPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
89                                  struct policy_handle *handle)
90 {
91         NTSTATUS status;
92         struct samr_SetDsrmPassword r;
93         struct samr_Name name;
94         struct samr_Hash hash;
95
96         if (lp_parm_int(-1, "torture", "dangerous") != 1) {
97                 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
98                 return True;
99         }
100
101         E_md4hash("TeSTDSRM123", hash.hash);
102
103         init_samr_Name(&name, "Administrator");
104
105         r.in.name = &name;
106         r.in.unknown = 0;
107         r.in.hash = &hash;
108
109         printf("testing samr_SetDsrmPassword\n");
110
111         status = dcerpc_samr_SetDsrmPassword(p, mem_ctx, &r);
112         if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
113                 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
114                 return False;
115         }
116
117         return True;
118 }
119
120
121 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
122                                struct policy_handle *handle)
123 {
124         NTSTATUS status;
125         struct samr_QuerySecurity r;
126         struct samr_SetSecurity s;
127
128         r.in.handle = handle;
129         r.in.sec_info = 7;
130
131         status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
132         if (!NT_STATUS_IS_OK(status)) {
133                 printf("QuerySecurity failed - %s\n", nt_errstr(status));
134                 return False;
135         }
136
137         s.in.handle = handle;
138         s.in.sec_info = 7;
139         s.in.sdbuf = r.out.sdbuf;
140
141         status = dcerpc_samr_SetSecurity(p, mem_ctx, &s);
142         if (!NT_STATUS_IS_OK(status)) {
143                 printf("SetSecurity failed - %s\n", nt_errstr(status));
144                 return False;
145         }
146
147         status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
148         if (!NT_STATUS_IS_OK(status)) {
149                 printf("QuerySecurity failed - %s\n", nt_errstr(status));
150                 return False;
151         }
152
153         return True;
154 }
155
156
157 static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
158                              struct policy_handle *handle)
159 {
160         NTSTATUS status;
161         struct samr_SetUserInfo s;
162         struct samr_SetUserInfo2 s2;
163         struct samr_QueryUserInfo q;
164         struct samr_QueryUserInfo q0;
165         union samr_UserInfo u;
166         BOOL ret = True;
167
168         s.in.handle = handle;
169         s.in.info = &u;
170
171         s2.in.handle = handle;
172         s2.in.info = &u;
173
174         q.in.handle = handle;
175         q.out.info = &u;
176         q0 = q;
177
178 #define TESTCALL(call, r) \
179                 status = dcerpc_samr_ ##call(p, mem_ctx, &r); \
180                 if (!NT_STATUS_IS_OK(status)) { \
181                         printf(#call " level %u failed - %s (line %d)\n", \
182                                r.in.level, nt_errstr(status), __LINE__); \
183                         ret = False; \
184                         break; \
185                 }
186
187 #define STRING_EQUAL(s1, s2, field) \
188                 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
189                         printf("Failed to set %s to '%s' (line %d)\n", \
190                                #field, s2, __LINE__); \
191                         ret = False; \
192                         break; \
193                 }
194
195 #define INT_EQUAL(i1, i2, field) \
196                 if (i1 != i2) { \
197                         printf("Failed to set %s to %u (line %d)\n", \
198                                #field, i2, __LINE__); \
199                         ret = False; \
200                         break; \
201                 }
202
203 #define TEST_USERINFO_NAME(lvl1, field1, lvl2, field2, value, fpval) do { \
204                 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
205                 q.in.level = lvl1; \
206                 TESTCALL(QueryUserInfo, q) \
207                 s.in.level = lvl1; \
208                 s2.in.level = lvl1; \
209                 u = *q.out.info; \
210                 if (lvl1 == 21) { \
211                         ZERO_STRUCT(u.info21); \
212                         u.info21.fields_present = fpval; \
213                 } \
214                 init_samr_Name(&u.info ## lvl1.field1, value); \
215                 TESTCALL(SetUserInfo, s) \
216                 TESTCALL(SetUserInfo2, s2) \
217                 init_samr_Name(&u.info ## lvl1.field1, ""); \
218                 TESTCALL(QueryUserInfo, q); \
219                 u = *q.out.info; \
220                 STRING_EQUAL(u.info ## lvl1.field1.name, value, field1); \
221                 q.in.level = lvl2; \
222                 TESTCALL(QueryUserInfo, q) \
223                 u = *q.out.info; \
224                 STRING_EQUAL(u.info ## lvl2.field2.name, value, field2); \
225         } while (0)
226
227 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
228                 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
229                 q.in.level = lvl1; \
230                 TESTCALL(QueryUserInfo, q) \
231                 s.in.level = lvl1; \
232                 s2.in.level = lvl1; \
233                 u = *q.out.info; \
234                 if (lvl1 == 21) { \
235                         uint8 *bitmap = u.info21.logon_hours.bitmap; \
236                         ZERO_STRUCT(u.info21); \
237                         if (fpval == SAMR_FIELD_LOGON_HOURS) { \
238                                 u.info21.logon_hours.units_per_week = 168; \
239                                 u.info21.logon_hours.bitmap = bitmap; \
240                         } \
241                         u.info21.fields_present = fpval; \
242                 } \
243                 u.info ## lvl1.field1 = value; \
244                 TESTCALL(SetUserInfo, s) \
245                 TESTCALL(SetUserInfo2, s2) \
246                 u.info ## lvl1.field1 = 0; \
247                 TESTCALL(QueryUserInfo, q); \
248                 u = *q.out.info; \
249                 INT_EQUAL(u.info ## lvl1.field1, value, field1); \
250                 q.in.level = lvl2; \
251                 TESTCALL(QueryUserInfo, q) \
252                 u = *q.out.info; \
253                 INT_EQUAL(u.info ## lvl2.field2, value, field1); \
254         } while (0)
255
256         q0.in.level = 12;
257         do { TESTCALL(QueryUserInfo, q0) } while (0);
258
259         TEST_USERINFO_NAME(2, comment,  1, comment, "xx2-1 comment", 0);
260         TEST_USERINFO_NAME(2, comment, 21, comment, "xx2-21 comment", 0);
261         TEST_USERINFO_NAME(21, comment, 21, comment, "xx21-21 comment", 
262                            SAMR_FIELD_COMMENT);
263
264         TEST_USERINFO_NAME(6, full_name,  1, full_name, "xx6-1 full_name", 0);
265         TEST_USERINFO_NAME(6, full_name,  3, full_name, "xx6-3 full_name", 0);
266         TEST_USERINFO_NAME(6, full_name,  5, full_name, "xx6-5 full_name", 0);
267         TEST_USERINFO_NAME(6, full_name,  6, full_name, "xx6-6 full_name", 0);
268         TEST_USERINFO_NAME(6, full_name,  8, full_name, "xx6-8 full_name", 0);
269         TEST_USERINFO_NAME(6, full_name, 21, full_name, "xx6-21 full_name", 0);
270         TEST_USERINFO_NAME(8, full_name, 21, full_name, "xx8-21 full_name", 0);
271         TEST_USERINFO_NAME(21, full_name, 21, full_name, "xx21-21 full_name", 
272                            SAMR_FIELD_NAME);
273
274         TEST_USERINFO_NAME(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
275         TEST_USERINFO_NAME(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
276         TEST_USERINFO_NAME(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
277         TEST_USERINFO_NAME(21, logon_script, 21, logon_script, "xx21-21 logon_script", 
278                            SAMR_FIELD_LOGON_SCRIPT);
279
280         TEST_USERINFO_NAME(12, profile,  3, profile, "xx12-3 profile", 0);
281         TEST_USERINFO_NAME(12, profile,  5, profile, "xx12-5 profile", 0);
282         TEST_USERINFO_NAME(12, profile, 21, profile, "xx12-21 profile", 0);
283         TEST_USERINFO_NAME(21, profile, 21, profile, "xx21-21 profile", 
284                            SAMR_FIELD_PROFILE);
285
286         TEST_USERINFO_NAME(13, description,  1, description, "xx13-1 description", 0);
287         TEST_USERINFO_NAME(13, description,  5, description, "xx13-5 description", 0);
288         TEST_USERINFO_NAME(13, description, 21, description, "xx13-21 description", 0);
289         TEST_USERINFO_NAME(21, description, 21, description, "xx21-21 description", 
290                            SAMR_FIELD_DESCRIPTION);
291
292         TEST_USERINFO_NAME(14, workstations,  3, workstations, "14workstation3", 0);
293         TEST_USERINFO_NAME(14, workstations,  5, workstations, "14workstation4", 0);
294         TEST_USERINFO_NAME(14, workstations, 21, workstations, "14workstation21", 0);
295         TEST_USERINFO_NAME(21, workstations, 21, workstations, "21workstation21", 
296                            SAMR_FIELD_WORKSTATION);
297
298         TEST_USERINFO_NAME(20, callback, 21, callback, "xx20-21 callback", 0);
299         TEST_USERINFO_NAME(21, callback, 21, callback, "xx21-21 callback", 
300                            SAMR_FIELD_CALLBACK);
301
302         TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
303         TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__, 
304                           SAMR_FIELD_COUNTRY_CODE);
305
306         TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
307         TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__, 
308                           SAMR_FIELD_CODE_PAGE);
309
310         TEST_USERINFO_INT(4, logon_hours.bitmap[3],  3, logon_hours.bitmap[3], 1, 0);
311         TEST_USERINFO_INT(4, logon_hours.bitmap[3],  5, logon_hours.bitmap[3], 2, 0);
312         TEST_USERINFO_INT(4, logon_hours.bitmap[3], 21, logon_hours.bitmap[3], 3, 0);
313         TEST_USERINFO_INT(21, logon_hours.bitmap[3], 21, logon_hours.bitmap[3], 4, 
314                           SAMR_FIELD_LOGON_HOURS);
315
316 #if 0
317         /* these fail with win2003 - it appears you can't set the primary gid?
318            the set succeeds, but the gid isn't changed. Very weird! */
319         TEST_USERINFO_INT(9, primary_gid,  1, primary_gid, 513);
320         TEST_USERINFO_INT(9, primary_gid,  3, primary_gid, 513);
321         TEST_USERINFO_INT(9, primary_gid,  5, primary_gid, 513);
322         TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
323 #endif
324         return ret;
325 }
326
327 /*
328   generate a random password for password change tests
329 */
330 static char *samr_rand_pass(TALLOC_CTX *mem_ctx)
331 {
332         size_t len = 8 + (random() % 6);
333         char *s = generate_random_str(mem_ctx, len);
334         printf("Generated password '%s'\n", s);
335         return s;
336 }
337
338 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
339                              struct policy_handle *handle, char **password)
340 {
341         NTSTATUS status;
342         struct samr_SetUserInfo s;
343         union samr_UserInfo u;
344         BOOL ret = True;
345         DATA_BLOB session_key;
346         char *newpass = samr_rand_pass(mem_ctx);
347
348         s.in.handle = handle;
349         s.in.info = &u;
350         s.in.level = 24;
351
352         encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
353         /* w2k3 ignores this length */
354         u.info24.pw_len = str_charnum(newpass)*2;
355
356         status = dcerpc_fetch_session_key(p, &session_key);
357         if (!NT_STATUS_IS_OK(status)) {
358                 printf("SetUserInfo level %u - no session key - %s\n",
359                        s.in.level, nt_errstr(status));
360                 return False;
361         }
362
363         SamOEMhashBlob(u.info24.password.data, 516, &session_key);
364
365         printf("Testing SetUserInfo level 24 (set password)\n");
366
367         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
368         if (!NT_STATUS_IS_OK(status)) {
369                 printf("SetUserInfo level %u failed - %s\n",
370                        s.in.level, nt_errstr(status));
371                 ret = False;
372         } else {
373                 *password = newpass;
374         }
375
376         return ret;
377 }
378
379
380 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
381                                 struct policy_handle *handle, char **password)
382 {
383         NTSTATUS status;
384         struct samr_SetUserInfo s;
385         union samr_UserInfo u;
386         BOOL ret = True;
387         DATA_BLOB session_key;
388         char *newpass = samr_rand_pass(mem_ctx);
389
390         s.in.handle = handle;
391         s.in.info = &u;
392         s.in.level = 23;
393
394         ZERO_STRUCT(u);
395
396         u.info23.info.fields_present = SAMR_FIELD_PASSWORD;
397
398         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
399
400         status = dcerpc_fetch_session_key(p, &session_key);
401         if (!NT_STATUS_IS_OK(status)) {
402                 printf("SetUserInfo level %u - no session key - %s\n",
403                        s.in.level, nt_errstr(status));
404                 return False;
405         }
406
407         SamOEMhashBlob(u.info23.password.data, 516, &session_key);
408
409         printf("Testing SetUserInfo level 23 (set password)\n");
410
411         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
412         if (!NT_STATUS_IS_OK(status)) {
413                 printf("SetUserInfo level %u failed - %s\n",
414                        s.in.level, nt_errstr(status));
415                 ret = False;
416         } else {
417                 *password = newpass;
418         }
419
420         return ret;
421 }
422
423
424 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
425                                struct policy_handle *handle, char **password)
426 {
427         NTSTATUS status;
428         struct samr_SetUserInfo s;
429         union samr_UserInfo u;
430         BOOL ret = True;
431         DATA_BLOB session_key;
432         DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
433         uint8 confounder[16];
434         char *newpass = samr_rand_pass(mem_ctx);        
435         struct MD5Context ctx;
436
437         s.in.handle = handle;
438         s.in.info = &u;
439         s.in.level = 26;
440
441         encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
442         u.info26.pw_len = strlen(newpass);
443
444         status = dcerpc_fetch_session_key(p, &session_key);
445         if (!NT_STATUS_IS_OK(status)) {
446                 printf("SetUserInfo level %u - no session key - %s\n",
447                        s.in.level, nt_errstr(status));
448                 return False;
449         }
450
451         generate_random_buffer((unsigned char *)confounder, 16, False);
452
453         MD5Init(&ctx);
454         MD5Update(&ctx, confounder, 16);
455         MD5Update(&ctx, session_key.data, session_key.length);
456         MD5Final(confounded_session_key.data, &ctx);
457
458         SamOEMhashBlob(u.info26.password.data, 516, &confounded_session_key);
459         memcpy(&u.info26.password.data[516], confounder, 16);
460
461         printf("Testing SetUserInfo level 26 (set password ex)\n");
462
463         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
464         if (!NT_STATUS_IS_OK(status)) {
465                 printf("SetUserInfo level %u failed - %s\n",
466                        s.in.level, nt_errstr(status));
467                 ret = False;
468         } else {
469                 *password = newpass;
470         }
471
472         return ret;
473 }
474
475 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
476                                 struct policy_handle *handle, char **password)
477 {
478         NTSTATUS status;
479         struct samr_SetUserInfo s;
480         union samr_UserInfo u;
481         BOOL ret = True;
482         DATA_BLOB session_key;
483         DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
484         uint8 confounder[16];
485         char *newpass = samr_rand_pass(mem_ctx);        
486         struct MD5Context ctx;
487
488         s.in.handle = handle;
489         s.in.info = &u;
490         s.in.level = 25;
491
492         ZERO_STRUCT(u);
493
494         u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
495
496         encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
497
498         status = dcerpc_fetch_session_key(p, &session_key);
499         if (!NT_STATUS_IS_OK(status)) {
500                 printf("SetUserInfo level %u - no session key - %s\n",
501                        s.in.level, nt_errstr(status));
502                 return False;
503         }
504
505         generate_random_buffer((unsigned char *)confounder, 16, False);
506
507         MD5Init(&ctx);
508         MD5Update(&ctx, confounder, 16);
509         MD5Update(&ctx, session_key.data, session_key.length);
510         MD5Final(confounded_session_key.data, &ctx);
511
512         SamOEMhashBlob(u.info25.password.data, 516, &confounded_session_key);
513         memcpy(&u.info25.password.data[516], confounder, 16);
514
515         printf("Testing SetUserInfo level 25 (set password ex)\n");
516
517         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
518         if (!NT_STATUS_IS_OK(status)) {
519                 printf("SetUserInfo level %u failed - %s\n",
520                        s.in.level, nt_errstr(status));
521                 ret = False;
522         } else {
523                 *password = newpass;
524         }
525
526         return ret;
527 }
528
529 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
530                                struct policy_handle *handle)
531 {
532         NTSTATUS status;
533         struct samr_SetAliasInfo r;
534         struct samr_QueryAliasInfo q;
535         uint16 levels[] = {2, 3};
536         int i;
537         BOOL ret = True;
538
539         /* Ignoring switch level 1, as that includes the number of members for the alias
540          * and setting this to a wrong value might have negative consequences
541          */
542
543         for (i=0;i<ARRAY_SIZE(levels);i++) {
544                 printf("Testing SetAliasInfo level %u\n", levels[i]);
545
546                 r.in.handle = handle;
547                 r.in.level = levels[i];
548                 switch (r.in.level) {
549                     case 2 : init_samr_Name(&r.in.info.name,TEST_ALIASNAME); break;
550                     case 3 : init_samr_Name(&r.in.info.description,
551                                 "Test Description, should test I18N as well"); break;
552                 }
553
554                 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
555                 if (!NT_STATUS_IS_OK(status)) {
556                         printf("SetAliasInfo level %u failed - %s\n",
557                                levels[i], nt_errstr(status));
558                         ret = False;
559                 }
560
561                 q.in.handle = handle;
562                 q.in.level = levels[i];
563
564                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
565                 if (!NT_STATUS_IS_OK(status)) {
566                         printf("QueryAliasInfo level %u failed - %s\n",
567                                levels[i], nt_errstr(status));
568                         ret = False;
569                 }
570         }
571
572         return ret;
573 }
574
575 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
576                                   struct policy_handle *user_handle)
577 {
578         struct samr_GetGroupsForUser r;
579         NTSTATUS status;
580         BOOL ret = True;
581
582         printf("testing GetGroupsForUser\n");
583
584         r.in.handle = user_handle;
585
586         status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
587         if (!NT_STATUS_IS_OK(status)) {
588                 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
589                 ret = False;
590         }
591
592         return ret;
593
594 }
595
596 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
597                               struct samr_Name *domain_name)
598 {
599         NTSTATUS status;
600         struct samr_GetDomPwInfo r;
601         BOOL ret = True;
602
603         printf("Testing GetDomPwInfo\n");
604
605         r.in.name = domain_name;
606
607         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
608         if (!NT_STATUS_IS_OK(status)) {
609                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
610                 ret = False;
611         }
612
613         return ret;
614 }
615
616 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
617                                struct policy_handle *handle)
618 {
619         NTSTATUS status;
620         struct samr_GetUserPwInfo r;
621         BOOL ret = True;
622
623         printf("Testing GetUserPwInfo\n");
624
625         r.in.handle = handle;
626
627         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
628         if (!NT_STATUS_IS_OK(status)) {
629                 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
630                 ret = False;
631         }
632
633         return ret;
634 }
635
636 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
637                                 struct policy_handle *domain_handle, const char *name,
638                                 uint32 *rid)
639 {
640         NTSTATUS status;
641         struct samr_LookupNames n;
642         struct samr_Name sname[2];
643
644         init_samr_Name(&sname[0], name);
645
646         n.in.handle = domain_handle;
647         n.in.num_names = 1;
648         n.in.names = sname;
649         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
650         if (NT_STATUS_IS_OK(status)) {
651                 *rid = n.out.rids.ids[0];
652         } else {
653                 return status;
654         }
655
656         init_samr_Name(&sname[1], "xxNONAMExx");
657         n.in.num_names = 2;
658         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
659         if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
660                 printf("LookupNames[2] failed - %s\n", nt_errstr(status));              
661                 return status;
662         }
663
664         init_samr_Name(&sname[1], "xxNONAMExx");
665         n.in.num_names = 0;
666         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
667         if (!NT_STATUS_IS_OK(status)) {
668                 printf("LookupNames[0] failed - %s\n", nt_errstr(status));              
669         }
670
671         return status;
672 }
673
674 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
675                                      struct policy_handle *domain_handle,
676                                      const char *name, struct policy_handle *user_handle)
677 {
678         NTSTATUS status;
679         struct samr_OpenUser r;
680         uint32 rid;
681
682         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
683         if (!NT_STATUS_IS_OK(status)) {
684                 return status;
685         }
686
687         r.in.handle = domain_handle;
688         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
689         r.in.rid = rid;
690         r.out.acct_handle = user_handle;
691         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
692         if (!NT_STATUS_IS_OK(status)) {
693                 printf("OpenUser_byname(%s) failed - %s\n", name, nt_errstr(status));
694         }
695
696         return status;
697 }
698
699
700 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
701                                     struct policy_handle *handle, char **password)
702 {
703         NTSTATUS status;
704         struct samr_ChangePasswordUser r;
705         BOOL ret = True;
706         struct samr_Hash hash1, hash2, hash3, hash4, hash5, hash6;
707         struct policy_handle user_handle;
708         char *oldpass = *password;
709         char *newpass = samr_rand_pass(mem_ctx);        
710         uint8 old_nt_hash[16], new_nt_hash[16];
711         uint8 old_lm_hash[16], new_lm_hash[16];
712
713         status = test_OpenUser_byname(p, mem_ctx, handle, TEST_USERNAME, &user_handle);
714         if (!NT_STATUS_IS_OK(status)) {
715                 return False;
716         }
717
718         printf("Testing ChangePasswordUser\n");
719
720         E_md4hash(oldpass, old_nt_hash);
721         E_md4hash(newpass, new_nt_hash);
722         E_deshash(oldpass, old_lm_hash);
723         E_deshash(newpass, new_lm_hash);
724
725         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
726         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
727         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
728         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
729         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
730         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
731
732         r.in.handle = &user_handle;
733         r.in.lm_present = 1;
734         r.in.old_lm_crypted = &hash1;
735         r.in.new_lm_crypted = &hash2;
736         r.in.nt_present = 1;
737         r.in.old_nt_crypted = &hash3;
738         r.in.new_nt_crypted = &hash4;
739         r.in.cross1_present = 1;
740         r.in.nt_cross = &hash5;
741         r.in.cross2_present = 1;
742         r.in.lm_cross = &hash6;
743
744         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
745         if (!NT_STATUS_IS_OK(status)) {
746                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
747                 ret = False;
748         } else {
749                 *password = newpass;
750         }
751
752         if (!test_Close(p, mem_ctx, &user_handle)) {
753                 ret = False;
754         }
755
756         return ret;
757 }
758
759
760 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
761                                         struct policy_handle *handle, char **password)
762 {
763         NTSTATUS status;
764         struct samr_OemChangePasswordUser2 r;
765         BOOL ret = True;
766         struct samr_Hash lm_verifier;
767         struct samr_CryptPassword lm_pass;
768         struct samr_AsciiName server, account;
769         char *oldpass = *password;
770         char *newpass = samr_rand_pass(mem_ctx);        
771         uint8 old_lm_hash[16], new_lm_hash[16];
772
773         printf("Testing OemChangePasswordUser2\n");
774
775         server.name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
776         account.name = TEST_USERNAME;
777
778         E_deshash(oldpass, old_lm_hash);
779         E_deshash(newpass, new_lm_hash);
780
781         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
782         SamOEMhash(lm_pass.data, old_lm_hash, 516);
783         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
784
785         r.in.server = &server;
786         r.in.account = &account;
787         r.in.password = &lm_pass;
788         r.in.hash = &lm_verifier;
789
790         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
791         if (!NT_STATUS_IS_OK(status)) {
792                 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
793                 ret = False;
794         } else {
795                 *password = newpass;
796         }
797
798         return ret;
799 }
800
801
802 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
803                                      struct policy_handle *handle, char **password)
804 {
805         NTSTATUS status;
806         struct samr_ChangePasswordUser2 r;
807         BOOL ret = True;
808         struct samr_Name server, account;
809         struct samr_CryptPassword nt_pass, lm_pass;
810         struct samr_Hash nt_verifier, lm_verifier;
811         char *oldpass = *password;
812         char *newpass = samr_rand_pass(mem_ctx);        
813         uint8 old_nt_hash[16], new_nt_hash[16];
814         uint8 old_lm_hash[16], new_lm_hash[16];
815
816         printf("Testing ChangePasswordUser2\n");
817
818         server.name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
819         init_samr_Name(&account, TEST_USERNAME);
820
821         E_md4hash(oldpass, old_nt_hash);
822         E_md4hash(newpass, new_nt_hash);
823
824         E_deshash(oldpass, old_lm_hash);
825         E_deshash(newpass, new_lm_hash);
826
827         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
828         SamOEMhash(lm_pass.data, old_lm_hash, 516);
829         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
830
831         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
832         SamOEMhash(nt_pass.data, old_nt_hash, 516);
833         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
834
835         r.in.server = &server;
836         r.in.account = &account;
837         r.in.nt_password = &nt_pass;
838         r.in.nt_verifier = &nt_verifier;
839         r.in.lm_change = 1;
840         r.in.lm_password = &lm_pass;
841         r.in.lm_verifier = &lm_verifier;
842
843         status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
844         if (!NT_STATUS_IS_OK(status)) {
845                 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
846                 ret = False;
847         } else {
848                 *password = newpass;
849         }
850
851         return ret;
852 }
853
854
855 static BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
856                                      struct policy_handle *handle, char **password)
857 {
858         NTSTATUS status;
859         struct samr_ChangePasswordUser3 r;
860         BOOL ret = True;
861         struct samr_Name server, account;
862         struct samr_CryptPassword nt_pass, lm_pass;
863         struct samr_Hash nt_verifier, lm_verifier;
864         char *oldpass = *password;
865         char *newpass = samr_rand_pass(mem_ctx);
866         uint8 old_nt_hash[16], new_nt_hash[16];
867         uint8 old_lm_hash[16], new_lm_hash[16];
868
869         printf("Testing ChangePasswordUser3\n");
870
871         server.name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
872         init_samr_Name(&account, TEST_USERNAME);
873
874         E_md4hash(oldpass, old_nt_hash);
875         E_md4hash(newpass, new_nt_hash);
876
877         E_deshash(oldpass, old_lm_hash);
878         E_deshash(newpass, new_lm_hash);
879
880         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
881         SamOEMhash(lm_pass.data, old_lm_hash, 516);
882         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
883
884         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
885         SamOEMhash(nt_pass.data, old_nt_hash, 516);
886         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
887
888         r.in.server = &server;
889         r.in.account = &account;
890         r.in.nt_password = &nt_pass;
891         r.in.nt_verifier = &nt_verifier;
892         r.in.lm_change = 1;
893         r.in.lm_password = &lm_pass;
894         r.in.lm_verifier = &lm_verifier;
895         r.in.password3 = NULL;
896
897         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
898         if (!NT_STATUS_IS_OK(status)) {
899                 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
900                 ret = False;
901         } else {
902                 *password = newpass;
903         }
904
905         return ret;
906 }
907
908
909 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
910                                   struct policy_handle *alias_handle)
911 {
912         struct samr_GetMembersInAlias r;
913         struct lsa_SidArray sids;
914         NTSTATUS status;
915         BOOL     ret = True;
916
917         printf("Testing GetMembersInAlias\n");
918
919         r.in.handle = alias_handle;
920         r.out.sids = &sids;
921
922         status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
923         if (!NT_STATUS_IS_OK(status)) {
924                 printf("GetMembersInAlias failed - %s\n",
925                        nt_errstr(status));
926                 ret = False;
927         }
928
929         return ret;
930 }
931
932 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
933                                   struct policy_handle *alias_handle,
934                                   struct policy_handle *domain_handle,
935                                   const struct dom_sid *domain_sid)
936 {
937         struct samr_AddAliasMember r;
938         struct samr_DeleteAliasMember d;
939         NTSTATUS status;
940         BOOL ret = True;
941         struct dom_sid *sid;
942
943         sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
944
945         printf("testing AddAliasMember\n");
946         r.in.handle = alias_handle;
947         r.in.sid = sid;
948
949         status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
950         if (!NT_STATUS_IS_OK(status)) {
951                 printf("AddAliasMember failed - %s\n", nt_errstr(status));
952                 ret = False;
953         }
954
955         d.in.handle = alias_handle;
956         d.in.sid = sid;
957
958         status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
959         if (!NT_STATUS_IS_OK(status)) {
960                 printf("DelAliasMember failed - %s\n", nt_errstr(status));
961                 ret = False;
962         }
963
964         return ret;
965 }
966
967 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
968                                            struct policy_handle *alias_handle)
969 {
970         struct samr_AddMultipleMembersToAlias a;
971         struct samr_RemoveMultipleMembersFromAlias r;
972         NTSTATUS status;
973         BOOL ret = True;
974         struct lsa_SidArray sids;
975
976         printf("testing AddMultipleMembersToAlias\n");
977         a.in.handle = alias_handle;
978         a.in.sids = &sids;
979
980         sids.num_sids = 3;
981         sids.sids = talloc_array_p(mem_ctx, struct lsa_SidPtr, 3);
982
983         sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
984         sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
985         sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
986
987         status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
988         if (!NT_STATUS_IS_OK(status)) {
989                 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
990                 ret = False;
991         }
992
993
994         printf("testing RemoveMultipleMembersFromAlias\n");
995         r.in.handle = alias_handle;
996         r.in.sids = &sids;
997
998         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
999         if (!NT_STATUS_IS_OK(status)) {
1000                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1001                 ret = False;
1002         }
1003
1004         /* strange! removing twice doesn't give any error */
1005         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1006         if (!NT_STATUS_IS_OK(status)) {
1007                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1008                 ret = False;
1009         }
1010
1011         /* but removing an alias that isn't there does */
1012         sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1013
1014         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1015         if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1016                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1017                 ret = False;
1018         }
1019
1020         return ret;
1021 }
1022
1023 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1024                                             struct policy_handle *user_handle)
1025 {
1026         struct samr_TestPrivateFunctionsUser r;
1027         NTSTATUS status;
1028         BOOL ret = True;
1029
1030         printf("Testing TestPrivateFunctionsUser\n");
1031
1032         r.in.handle = user_handle;
1033
1034         status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1035         if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1036                 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1037                 ret = False;
1038         }
1039
1040         return ret;
1041 }
1042
1043
1044 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1045                           struct policy_handle *handle)
1046 {
1047         BOOL ret = True;
1048
1049         if (!test_QuerySecurity(p, mem_ctx, handle)) {
1050                 ret = False;
1051         }
1052
1053         if (!test_QueryUserInfo(p, mem_ctx, handle)) {
1054                 ret = False;
1055         }
1056
1057         if (!test_QueryUserInfo2(p, mem_ctx, handle)) {
1058                 ret = False;
1059         }
1060
1061         if (!test_SetUserInfo(p, mem_ctx, handle)) {
1062                 ret = False;
1063         }       
1064
1065         if (!test_GetUserPwInfo(p, mem_ctx, handle)) {
1066                 ret = False;
1067         }
1068
1069         if (!test_TestPrivateFunctionsUser(p, mem_ctx, handle)) {
1070                 ret = False;
1071         }
1072
1073         return ret;
1074 }
1075
1076 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1077                            struct policy_handle *alias_handle,
1078                            struct policy_handle *domain_handle,
1079                            const struct dom_sid *domain_sid)
1080 {
1081         BOOL ret = True;
1082
1083         if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
1084                 ret = False;
1085         }
1086
1087         if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
1088                 ret = False;
1089         }
1090
1091         if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
1092                 ret = False;
1093         }
1094
1095         if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, 
1096                                    domain_handle, domain_sid)) {
1097                 ret = False;
1098         }
1099
1100         if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
1101                 ret = False;
1102         }
1103
1104         return ret;
1105 }
1106
1107
1108 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1109                             struct policy_handle *handle, const char *name)
1110 {
1111         NTSTATUS status;
1112         struct samr_DeleteUser d;
1113         struct policy_handle acct_handle;
1114         uint32 rid;
1115
1116         status = test_LookupName(p, mem_ctx, handle, name, &rid);
1117         if (!NT_STATUS_IS_OK(status)) {
1118                 goto failed;
1119         }
1120
1121         status = test_OpenUser_byname(p, mem_ctx, handle, name, &acct_handle);
1122         if (!NT_STATUS_IS_OK(status)) {
1123                 goto failed;
1124         }
1125
1126         d.in.handle = &acct_handle;
1127         d.out.handle = &acct_handle;
1128         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1129         if (!NT_STATUS_IS_OK(status)) {
1130                 goto failed;
1131         }
1132
1133         return True;
1134
1135 failed:
1136         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1137         return False;
1138 }
1139
1140
1141 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1142                                     struct policy_handle *handle, const char *name)
1143 {
1144         NTSTATUS status;
1145         struct samr_OpenGroup r;
1146         struct samr_DeleteDomainGroup d;
1147         struct policy_handle group_handle;
1148         uint32 rid;
1149
1150         status = test_LookupName(p, mem_ctx, handle, name, &rid);
1151         if (!NT_STATUS_IS_OK(status)) {
1152                 goto failed;
1153         }
1154
1155         r.in.handle = handle;
1156         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1157         r.in.rid = rid;
1158         r.out.acct_handle = &group_handle;
1159         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1160         if (!NT_STATUS_IS_OK(status)) {
1161                 goto failed;
1162         }
1163
1164         d.in.handle = &group_handle;
1165         d.out.handle = &group_handle;
1166         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
1167         if (!NT_STATUS_IS_OK(status)) {
1168                 goto failed;
1169         }
1170
1171         return True;
1172
1173 failed:
1174         printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
1175         return False;
1176 }
1177
1178
1179 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1180                                    struct policy_handle *domain_handle, const char *name)
1181 {
1182         NTSTATUS status;
1183         struct samr_OpenAlias r;
1184         struct samr_DeleteDomAlias d;
1185         struct policy_handle alias_handle;
1186         uint32 rid;
1187
1188         printf("testing DeleteAlias_byname\n");
1189
1190         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1191         if (!NT_STATUS_IS_OK(status)) {
1192                 goto failed;
1193         }
1194
1195         r.in.handle = domain_handle;
1196         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1197         r.in.rid = rid;
1198         r.out.acct_handle = &alias_handle;
1199         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1200         if (!NT_STATUS_IS_OK(status)) {
1201                 goto failed;
1202         }
1203
1204         d.in.handle = &alias_handle;
1205         d.out.handle = &alias_handle;
1206         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1207         if (!NT_STATUS_IS_OK(status)) {
1208                 goto failed;
1209         }
1210
1211         return True;
1212
1213 failed:
1214         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1215         return False;
1216 }
1217
1218 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1219                                      struct policy_handle *alias_handle)
1220 {
1221         struct samr_DeleteDomAlias d;
1222         NTSTATUS status;
1223         BOOL ret = True;
1224         printf("Testing DeleteAlias\n");
1225
1226         d.in.handle = alias_handle;
1227         d.out.handle = alias_handle;
1228
1229         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1230         if (!NT_STATUS_IS_OK(status)) {
1231                 printf("DeleteAlias failed - %s\n", nt_errstr(status));
1232                 ret = False;
1233         }
1234
1235         return ret;
1236 }
1237
1238 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1239                             struct policy_handle *domain_handle, 
1240                              struct policy_handle *alias_handle, 
1241                              const struct dom_sid *domain_sid)
1242 {
1243         NTSTATUS status;
1244         struct samr_CreateDomAlias r;
1245         struct samr_Name name;
1246         uint32 rid;
1247         BOOL ret = True;
1248
1249         init_samr_Name(&name, TEST_ALIASNAME);
1250         r.in.handle = domain_handle;
1251         r.in.aliasname = &name;
1252         r.in.access_mask = SEC_RIGHT_MAXIMUM_ALLOWED;
1253         r.out.acct_handle = alias_handle;
1254         r.out.rid = &rid;
1255
1256         printf("Testing CreateAlias (%s)\n", r.in.aliasname->name);
1257
1258         status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1259
1260         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1261                 printf("Server refused create of '%s'\n", r.in.aliasname->name);
1262                 return True;
1263         }
1264
1265         if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
1266                 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.aliasname->name)) {
1267                         return False;
1268                 }
1269                 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1270         }
1271
1272         if (!NT_STATUS_IS_OK(status)) {
1273                 printf("CreateAlias failed - %s\n", nt_errstr(status));
1274                 return False;
1275         }
1276
1277         if (!test_alias_ops(p, mem_ctx, alias_handle, domain_handle, domain_sid)) {
1278                 ret = False;
1279         }
1280
1281         return ret;
1282 }
1283
1284 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1285                                 struct policy_handle *domain_handle, char **password)
1286 {
1287         BOOL ret = True;
1288
1289         if (!*password) {
1290                 return False;
1291         }
1292
1293         if (!test_ChangePasswordUser(p, mem_ctx, domain_handle, password)) {
1294                 ret = False;
1295         }
1296
1297         if (!test_ChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1298                 ret = False;
1299         }
1300
1301         if (!test_OemChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1302                 ret = False;
1303         }
1304
1305         if (!test_ChangePasswordUser3(p, mem_ctx, domain_handle, password)) {
1306                 ret = False;
1307         }
1308
1309         return ret;
1310 }
1311
1312 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1313                             struct policy_handle *domain_handle, struct policy_handle *user_handle)
1314 {
1315         NTSTATUS status;
1316         struct samr_CreateUser r;
1317         struct samr_QueryUserInfo q;
1318         uint32 rid;
1319         char *password = NULL;
1320
1321         /* This call creates a 'normal' account - check that it really does */
1322         const uint32 acct_flags = ACB_NORMAL;
1323         struct samr_Name name;
1324         BOOL ret = True;
1325
1326         init_samr_Name(&name, TEST_USERNAME);
1327
1328         r.in.handle = domain_handle;
1329         r.in.username = &name;
1330         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1331         r.out.acct_handle = user_handle;
1332         r.out.rid = &rid;
1333
1334         printf("Testing CreateUser(%s)\n", r.in.username->name);
1335
1336         status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
1337
1338         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1339                 printf("Server refused create of '%s'\n", r.in.username->name);
1340                 ZERO_STRUCTP(user_handle);
1341                 return True;
1342         }
1343
1344         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1345                 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.username->name)) {
1346                         return False;
1347                 }
1348                 status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
1349         }
1350         if (!NT_STATUS_IS_OK(status)) {
1351                 printf("CreateUser failed - %s\n", nt_errstr(status));
1352                 return False;
1353         }
1354
1355         q.in.handle = user_handle;
1356         q.in.level = 16;
1357
1358         status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
1359         if (!NT_STATUS_IS_OK(status)) {
1360                 printf("QueryUserInfo level %u failed - %s\n", 
1361                        q.in.level, nt_errstr(status));
1362                 ret = False;
1363         } else {
1364                 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1365                         printf("QuerUserInfo level 16 failed, it returned 0x%08x (%u) when we expected flags of 0x%08x (%u)\n",
1366                                q.out.info->info16.acct_flags, q.out.info->info16.acct_flags, 
1367                                acct_flags, acct_flags);
1368                         ret = False;
1369                 }
1370         }
1371
1372         if (!test_user_ops(p, mem_ctx, user_handle)) {
1373                 ret = False;
1374         }
1375
1376         if (!test_SetUserPass(p, mem_ctx, user_handle, &password)) {
1377                 ret = False;
1378         }       
1379
1380         if (!test_SetUserPass_23(p, mem_ctx, user_handle, &password)) {
1381                 ret = False;
1382         }       
1383
1384         if (!test_SetUserPassEx(p, mem_ctx, user_handle, &password)) {
1385                 ret = False;
1386         }       
1387
1388         if (!test_SetUserPass_25(p, mem_ctx, user_handle, &password)) {
1389                 ret = False;
1390         }       
1391
1392         /* we change passwords twice - this has the effect of verifying
1393            they were changed correctly */
1394         if (!test_ChangePassword(p, mem_ctx, domain_handle, &password)) {
1395                 ret = False;
1396         }       
1397
1398         if (!test_ChangePassword(p, mem_ctx, domain_handle, &password)) {
1399                 ret = False;
1400         }       
1401
1402
1403         return ret;
1404 }
1405
1406
1407 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1408                             struct policy_handle *user_handle)
1409 {
1410         struct samr_DeleteUser d;
1411         NTSTATUS status;
1412         BOOL ret = True;
1413
1414         printf("Testing DeleteUser\n");
1415
1416         d.in.handle = user_handle;
1417         d.out.handle = user_handle;
1418
1419         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1420         if (!NT_STATUS_IS_OK(status)) {
1421                 printf("DeleteUser failed - %s\n", nt_errstr(status));
1422                 ret = False;
1423         }
1424
1425         return ret;
1426 }
1427
1428 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1429                              struct policy_handle *handle)
1430 {
1431         NTSTATUS status;
1432         struct samr_CreateUser2 r;
1433         struct samr_QueryUserInfo q;
1434         struct samr_DeleteUser d;
1435         struct policy_handle acct_handle;
1436         uint32 rid;
1437         struct samr_Name name;
1438         BOOL ret = True;
1439         int i;
1440
1441         struct {
1442                 uint32 acct_flags;
1443                 const char *account_name;
1444                 NTSTATUS nt_status;
1445         } account_types[] = {
1446                 { ACB_NORMAL, TEST_USERNAME, NT_STATUS_OK },
1447                 { ACB_NORMAL | ACB_DISABLED, TEST_USERNAME, NT_STATUS_INVALID_PARAMETER },
1448                 { ACB_NORMAL | ACB_PWNOEXP, TEST_USERNAME, NT_STATUS_INVALID_PARAMETER },
1449                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1450                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1451                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1452                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1453                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1454                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1455                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
1456                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1457                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1458                 { 0, TEST_USERNAME, NT_STATUS_INVALID_PARAMETER },
1459                 { ACB_DISABLED, TEST_USERNAME, NT_STATUS_INVALID_PARAMETER },
1460                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
1461         };
1462
1463         for (i = 0; account_types[i].account_name; i++) {
1464                 uint32 acct_flags = account_types[i].acct_flags;
1465                 uint32 access_granted;
1466
1467                 init_samr_Name(&name, account_types[i].account_name);
1468
1469                 r.in.handle = handle;
1470                 r.in.username = &name;
1471                 r.in.acct_flags = acct_flags;
1472                 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1473                 r.out.acct_handle = &acct_handle;
1474                 r.out.access_granted = &access_granted;
1475                 r.out.rid = &rid;
1476                 
1477                 printf("Testing CreateUser2(%s)\n", r.in.username->name);
1478                 
1479                 status = dcerpc_samr_CreateUser2(p, mem_ctx, &r);
1480                 
1481                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1482                         printf("Server refused create of '%s'\n", r.in.username->name);
1483                         continue;
1484
1485                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1486                         if (!test_DeleteUser_byname(p, mem_ctx, handle, r.in.username->name)) {
1487                                 return False;
1488                         }
1489                         status = dcerpc_samr_CreateUser2(p, mem_ctx, &r);
1490
1491                 }
1492                 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
1493                         printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n", 
1494                                nt_errstr(status), nt_errstr(account_types[i].nt_status));
1495                         ret = False;
1496                 }
1497                 
1498                 if (NT_STATUS_IS_OK(status)) {
1499                         q.in.handle = &acct_handle;
1500                         q.in.level = 16;
1501                         
1502                         status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
1503                         if (!NT_STATUS_IS_OK(status)) {
1504                                 printf("QueryUserInfo level %u failed - %s\n", 
1505                                        q.in.level, nt_errstr(status));
1506                                 ret = False;
1507                         } else {
1508                                 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1509                                         printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
1510                                                q.out.info->info16.acct_flags, 
1511                                                acct_flags);
1512                                         ret = False;
1513                                 }
1514                         }
1515                 
1516                         if (!test_user_ops(p, mem_ctx, &acct_handle)) {
1517                                 ret = False;
1518                         }
1519
1520                         printf("Testing DeleteUser (createuser2 test)\n");
1521                 
1522                         d.in.handle = &acct_handle;
1523                         d.out.handle = &acct_handle;
1524                         
1525                         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1526                         if (!NT_STATUS_IS_OK(status)) {
1527                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
1528                                 ret = False;
1529                         }
1530                 }
1531         }
1532
1533         return ret;
1534 }
1535
1536 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1537                                 struct policy_handle *handle)
1538 {
1539         NTSTATUS status;
1540         struct samr_QueryAliasInfo r;
1541         uint16 levels[] = {1, 2, 3};
1542         int i;
1543         BOOL ret = True;
1544
1545         for (i=0;i<ARRAY_SIZE(levels);i++) {
1546                 printf("Testing QueryAliasInfo level %u\n", levels[i]);
1547
1548                 r.in.handle = handle;
1549                 r.in.level = levels[i];
1550
1551                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
1552                 if (!NT_STATUS_IS_OK(status)) {
1553                         printf("QueryAliasInfo level %u failed - %s\n", 
1554                                levels[i], nt_errstr(status));
1555                         ret = False;
1556                 }
1557         }
1558
1559         return ret;
1560 }
1561
1562 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1563                                 struct policy_handle *handle)
1564 {
1565         NTSTATUS status;
1566         struct samr_QueryGroupInfo r;
1567         uint16 levels[] = {1, 2, 3, 4};
1568         int i;
1569         BOOL ret = True;
1570
1571         for (i=0;i<ARRAY_SIZE(levels);i++) {
1572                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1573
1574                 r.in.handle = handle;
1575                 r.in.level = levels[i];
1576
1577                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1578                 if (!NT_STATUS_IS_OK(status)) {
1579                         printf("QueryGroupInfo level %u failed - %s\n", 
1580                                levels[i], nt_errstr(status));
1581                         ret = False;
1582                 }
1583         }
1584
1585         return ret;
1586 }
1587
1588
1589 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1590                               struct policy_handle *handle)
1591 {
1592         NTSTATUS status;
1593         struct samr_QueryGroupInfo r;
1594         struct samr_SetGroupInfo s;
1595         uint16 levels[] = {1, 2, 3, 4};
1596         uint16 set_ok[] = {0, 1, 1, 1};
1597         int i;
1598         BOOL ret = True;
1599
1600         for (i=0;i<ARRAY_SIZE(levels);i++) {
1601                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1602
1603                 r.in.handle = handle;
1604                 r.in.level = levels[i];
1605
1606                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1607                 if (!NT_STATUS_IS_OK(status)) {
1608                         printf("QueryGroupInfo level %u failed - %s\n", 
1609                                levels[i], nt_errstr(status));
1610                         ret = False;
1611                 }
1612
1613                 printf("Testing SetGroupInfo level %u\n", levels[i]);
1614
1615                 s.in.handle = handle;
1616                 s.in.level = levels[i];
1617                 s.in.info = r.out.info;
1618
1619                 if (s.in.level == 2) {
1620                         init_samr_Name(&s.in.info->name, "NewName");
1621                 }
1622
1623                 if (s.in.level == 4) {
1624                         init_samr_Name(&s.in.info->description, "test description");
1625                 }
1626
1627                 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
1628                 if (set_ok[i]) {
1629                         if (!NT_STATUS_IS_OK(status)) {
1630                                 printf("SetGroupInfo level %u failed - %s\n", 
1631                                        r.in.level, nt_errstr(status));
1632                                 ret = False;
1633                                 continue;
1634                         }
1635                 } else {
1636                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
1637                                 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
1638                                        r.in.level, nt_errstr(status));
1639                                 ret = False;
1640                                 continue;
1641                         }
1642                 }
1643         }
1644
1645         return ret;
1646 }
1647
1648 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1649                                struct policy_handle *handle)
1650 {
1651         NTSTATUS status;
1652         struct samr_QueryUserInfo r;
1653         uint16 levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1654                            11, 12, 13, 14, 16, 17, 20, 21};
1655         int i;
1656         BOOL ret = True;
1657
1658         for (i=0;i<ARRAY_SIZE(levels);i++) {
1659                 printf("Testing QueryUserInfo level %u\n", levels[i]);
1660
1661                 r.in.handle = handle;
1662                 r.in.level = levels[i];
1663
1664                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
1665                 if (!NT_STATUS_IS_OK(status)) {
1666                         printf("QueryUserInfo level %u failed - %s\n", 
1667                                levels[i], nt_errstr(status));
1668                         ret = False;
1669                 }
1670         }
1671
1672         return ret;
1673 }
1674
1675 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1676                                 struct policy_handle *handle)
1677 {
1678         NTSTATUS status;
1679         struct samr_QueryUserInfo2 r;
1680         uint16 levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1681                            11, 12, 13, 14, 16, 17, 20, 21};
1682         int i;
1683         BOOL ret = True;
1684
1685         for (i=0;i<ARRAY_SIZE(levels);i++) {
1686                 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
1687
1688                 r.in.handle = handle;
1689                 r.in.level = levels[i];
1690
1691                 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
1692                 if (!NT_STATUS_IS_OK(status)) {
1693                         printf("QueryUserInfo2 level %u failed - %s\n", 
1694                                levels[i], nt_errstr(status));
1695                         ret = False;
1696                 }
1697         }
1698
1699         return ret;
1700 }
1701
1702 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1703                           struct policy_handle *handle, uint32 rid)
1704 {
1705         NTSTATUS status;
1706         struct samr_OpenUser r;
1707         struct policy_handle acct_handle;
1708         BOOL ret = True;
1709
1710         printf("Testing OpenUser(%u)\n", rid);
1711
1712         r.in.handle = handle;
1713         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1714         r.in.rid = rid;
1715         r.out.acct_handle = &acct_handle;
1716
1717         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1718         if (!NT_STATUS_IS_OK(status)) {
1719                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
1720                 return False;
1721         }
1722
1723         if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
1724                 ret = False;
1725         }
1726
1727         if (!test_QueryUserInfo(p, mem_ctx, &acct_handle)) {
1728                 ret = False;
1729         }
1730
1731         if (!test_QueryUserInfo2(p, mem_ctx, &acct_handle)) {
1732                 ret = False;
1733         }
1734
1735         if (!test_GetUserPwInfo(p, mem_ctx, &acct_handle)) {
1736                 ret = False;
1737         }
1738
1739         if (!test_GetGroupsForUser(p,mem_ctx, &acct_handle)) {
1740                 ret = False;
1741         }
1742
1743         if (!test_Close(p, mem_ctx, &acct_handle)) {
1744                 ret = False;
1745         }
1746
1747         return ret;
1748 }
1749
1750 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1751                            struct policy_handle *handle, uint32 rid)
1752 {
1753         NTSTATUS status;
1754         struct samr_OpenGroup r;
1755         struct policy_handle acct_handle;
1756         BOOL ret = True;
1757
1758         printf("Testing OpenGroup(%u)\n", rid);
1759
1760         r.in.handle = handle;
1761         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1762         r.in.rid = rid;
1763         r.out.acct_handle = &acct_handle;
1764
1765         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1766         if (!NT_STATUS_IS_OK(status)) {
1767                 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
1768                 return False;
1769         }
1770
1771         if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
1772                 ret = False;
1773         }
1774
1775         if (!test_QueryGroupInfo(p, mem_ctx, &acct_handle)) {
1776                 ret = False;
1777         }
1778
1779         if (!test_Close(p, mem_ctx, &acct_handle)) {
1780                 ret = False;
1781         }
1782
1783         return ret;
1784 }
1785
1786 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1787                            struct policy_handle *handle, uint32 rid)
1788 {
1789         NTSTATUS status;
1790         struct samr_OpenAlias r;
1791         struct policy_handle acct_handle;
1792         BOOL ret = True;
1793
1794         printf("Testing OpenAlias(%u)\n", rid);
1795
1796         r.in.handle = handle;
1797         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1798         r.in.rid = rid;
1799         r.out.acct_handle = &acct_handle;
1800
1801         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1802         if (!NT_STATUS_IS_OK(status)) {
1803                 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
1804                 return False;
1805         }
1806
1807         if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
1808                 ret = False;
1809         }
1810
1811         if (!test_QueryAliasInfo(p, mem_ctx, &acct_handle)) {
1812                 ret = False;
1813         }
1814
1815         if (!test_GetMembersInAlias(p, mem_ctx, &acct_handle)) {
1816                 ret = False;
1817         }
1818
1819         if (!test_Close(p, mem_ctx, &acct_handle)) {
1820                 ret = False;
1821         }
1822
1823         return ret;
1824 }
1825
1826 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1827                                  struct policy_handle *handle)
1828 {
1829         NTSTATUS status;
1830         struct samr_EnumDomainUsers r;
1831         uint32 resume_handle=0;
1832         int i;
1833         BOOL ret = True;
1834         struct samr_LookupNames n;
1835         struct samr_LookupRids  lr ;
1836
1837         printf("Testing EnumDomainUsers\n");
1838
1839         r.in.handle = handle;
1840         r.in.resume_handle = &resume_handle;
1841         r.in.acct_flags = 0;
1842         r.in.max_size = (uint32)-1;
1843         r.out.resume_handle = &resume_handle;
1844
1845         status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
1846         if (!NT_STATUS_IS_OK(status)) {
1847                 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
1848                 return False;
1849         }
1850         
1851         if (!r.out.sam) {
1852                 return False;
1853         }
1854
1855         if (r.out.sam->count == 0) {
1856                 return True;
1857         }
1858
1859         for (i=0;i<r.out.sam->count;i++) {
1860                 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
1861                         ret = False;
1862                 }
1863         }
1864
1865         printf("Testing LookupNames\n");
1866         n.in.handle = handle;
1867         n.in.num_names = r.out.sam->count;
1868         n.in.names = talloc(mem_ctx, r.out.sam->count * sizeof(struct samr_Name));
1869         for (i=0;i<r.out.sam->count;i++) {
1870                 n.in.names[i] = r.out.sam->entries[i].name;
1871         }
1872         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
1873         if (!NT_STATUS_IS_OK(status)) {
1874                 printf("LookupNames failed - %s\n", nt_errstr(status));
1875                 ret = False;
1876         }
1877
1878
1879         printf("Testing LookupRids\n");
1880         lr.in.handle = handle;
1881         lr.in.num_rids = r.out.sam->count;
1882         lr.in.rids = talloc(mem_ctx, r.out.sam->count * sizeof(uint32));
1883         for (i=0;i<r.out.sam->count;i++) {
1884                 lr.in.rids[i] = r.out.sam->entries[i].idx;
1885         }
1886         status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
1887         if (!NT_STATUS_IS_OK(status)) {
1888                 printf("LookupRids failed - %s\n", nt_errstr(status));
1889                 ret = False;
1890         }
1891
1892         return ret;     
1893 }
1894
1895 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1896                                   struct policy_handle *handle)
1897 {
1898         NTSTATUS status;
1899         struct samr_EnumDomainGroups r;
1900         uint32 resume_handle=0;
1901         int i;
1902         BOOL ret = True;
1903
1904         printf("Testing EnumDomainGroups\n");
1905
1906         r.in.handle = handle;
1907         r.in.resume_handle = &resume_handle;
1908         r.in.max_size = (uint32)-1;
1909         r.out.resume_handle = &resume_handle;
1910
1911         status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
1912         if (!NT_STATUS_IS_OK(status)) {
1913                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
1914                 return False;
1915         }
1916         
1917         if (!r.out.sam) {
1918                 return False;
1919         }
1920
1921         for (i=0;i<r.out.sam->count;i++) {
1922                 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
1923                         ret = False;
1924                 }
1925         }
1926
1927         return ret;
1928 }
1929
1930 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1931                                    struct policy_handle *handle)
1932 {
1933         NTSTATUS status;
1934         struct samr_EnumDomainAliases r;
1935         uint32 resume_handle=0;
1936         int i;
1937         BOOL ret = True;
1938
1939         printf("Testing EnumDomainAliases\n");
1940
1941         r.in.handle = handle;
1942         r.in.resume_handle = &resume_handle;
1943         r.in.max_size = (uint32)-1;
1944         r.out.resume_handle = &resume_handle;
1945
1946         status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
1947         if (!NT_STATUS_IS_OK(status)) {
1948                 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
1949                 return False;
1950         }
1951         
1952         if (!r.out.sam) {
1953                 return False;
1954         }
1955
1956         for (i=0;i<r.out.sam->count;i++) {
1957                 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
1958                         ret = False;
1959                 }
1960         }
1961
1962         return ret;     
1963 }
1964
1965 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1966                                             struct policy_handle *handle)
1967 {
1968         NTSTATUS status;
1969         struct samr_GetDisplayEnumerationIndex r;
1970         BOOL ret = True;
1971         uint16 levels[] = {1, 2, 3, 4, 5};
1972         uint16 ok_lvl[] = {1, 1, 1, 0, 0};
1973         int i;
1974
1975         for (i=0;i<ARRAY_SIZE(levels);i++) {
1976                 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
1977
1978                 r.in.handle = handle;
1979                 r.in.level = levels[i];
1980                 init_samr_Name(&r.in.name, TEST_USERNAME);
1981
1982                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
1983
1984                 if (ok_lvl[i] && 
1985                     !NT_STATUS_IS_OK(status) &&
1986                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
1987                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
1988                                levels[i], nt_errstr(status));
1989                         ret = False;
1990                 }
1991
1992                 init_samr_Name(&r.in.name, "zzzzzzzz");
1993
1994                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
1995                 
1996                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
1997                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
1998                                levels[i], nt_errstr(status));
1999                         ret = False;
2000                 }
2001         }
2002         
2003         return ret;     
2004 }
2005
2006 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2007                                              struct policy_handle *handle)
2008 {
2009         NTSTATUS status;
2010         struct samr_GetDisplayEnumerationIndex2 r;
2011         BOOL ret = True;
2012         uint16 levels[] = {1, 2, 3, 4, 5};
2013         uint16 ok_lvl[] = {1, 1, 1, 0, 0};
2014         int i;
2015
2016         for (i=0;i<ARRAY_SIZE(levels);i++) {
2017                 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2018
2019                 r.in.handle = handle;
2020                 r.in.level = levels[i];
2021                 init_samr_Name(&r.in.name, TEST_USERNAME);
2022
2023                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2024                 if (ok_lvl[i] && 
2025                     !NT_STATUS_IS_OK(status) && 
2026                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2027                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
2028                                levels[i], nt_errstr(status));
2029                         ret = False;
2030                 }
2031
2032                 init_samr_Name(&r.in.name, "zzzzzzzz");
2033
2034                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2035                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2036                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
2037                                levels[i], nt_errstr(status));
2038                         ret = False;
2039                 }
2040         }
2041         
2042         return ret;     
2043 }
2044
2045 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2046                                   struct policy_handle *handle)
2047 {
2048         NTSTATUS status;
2049         struct samr_QueryDisplayInfo r;
2050         BOOL ret = True;
2051         uint16 levels[] = {1, 2, 3, 4, 5};
2052         int i;
2053
2054         for (i=0;i<ARRAY_SIZE(levels);i++) {
2055                 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2056
2057                 r.in.handle = handle;
2058                 r.in.level = levels[i];
2059                 r.in.start_idx = 0;
2060                 r.in.max_entries = 1000;
2061                 r.in.buf_size = (uint32)-1;
2062
2063                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2064                 if (!NT_STATUS_IS_OK(status)) {
2065                         printf("QueryDisplayInfo level %u failed - %s\n", 
2066                                levels[i], nt_errstr(status));
2067                         ret = False;
2068                 }
2069         }
2070         
2071         return ret;     
2072 }
2073
2074 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2075                                   struct policy_handle *handle)
2076 {
2077         NTSTATUS status;
2078         struct samr_QueryDisplayInfo2 r;
2079         BOOL ret = True;
2080         uint16 levels[] = {1, 2, 3, 4, 5};
2081         int i;
2082
2083         for (i=0;i<ARRAY_SIZE(levels);i++) {
2084                 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2085
2086                 r.in.handle = handle;
2087                 r.in.level = levels[i];
2088                 r.in.start_idx = 0;
2089                 r.in.max_entries = 1000;
2090                 r.in.buf_size = (uint32)-1;
2091
2092                 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2093                 if (!NT_STATUS_IS_OK(status)) {
2094                         printf("QueryDisplayInfo2 level %u failed - %s\n", 
2095                                levels[i], nt_errstr(status));
2096                         ret = False;
2097                 }
2098         }
2099         
2100         return ret;     
2101 }
2102
2103 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2104                                   struct policy_handle *handle)
2105 {
2106         NTSTATUS status;
2107         struct samr_QueryDisplayInfo3 r;
2108         BOOL ret = True;
2109         uint16 levels[] = {1, 2, 3, 4, 5};
2110         int i;
2111
2112         for (i=0;i<ARRAY_SIZE(levels);i++) {
2113                 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2114
2115                 r.in.handle = handle;
2116                 r.in.level = levels[i];
2117                 r.in.start_idx = 0;
2118                 r.in.max_entries = 1000;
2119                 r.in.buf_size = (uint32)-1;
2120
2121                 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2122                 if (!NT_STATUS_IS_OK(status)) {
2123                         printf("QueryDisplayInfo3 level %u failed - %s\n", 
2124                                levels[i], nt_errstr(status));
2125                         ret = False;
2126                 }
2127         }
2128         
2129         return ret;     
2130 }
2131
2132 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2133                                  struct policy_handle *handle)
2134 {
2135         NTSTATUS status;
2136         struct samr_QueryDomainInfo r;
2137         struct samr_SetDomainInfo s;
2138         uint16 levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2139         uint16 set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
2140         int i;
2141         BOOL ret = True;
2142
2143         for (i=0;i<ARRAY_SIZE(levels);i++) {
2144                 printf("Testing QueryDomainInfo level %u\n", levels[i]);
2145
2146                 r.in.handle = handle;
2147                 r.in.level = levels[i];
2148
2149                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2150                 if (!NT_STATUS_IS_OK(status)) {
2151                         printf("QueryDomainInfo level %u failed - %s\n", 
2152                                r.in.level, nt_errstr(status));
2153                         ret = False;
2154                         continue;
2155                 }
2156
2157                 printf("Testing SetDomainInfo level %u\n", levels[i]);
2158
2159                 s.in.handle = handle;
2160                 s.in.level = levels[i];
2161                 s.in.info = r.out.info;
2162
2163                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2164                 if (set_ok[i]) {
2165                         if (!NT_STATUS_IS_OK(status)) {
2166                                 printf("SetDomainInfo level %u failed - %s\n", 
2167                                        r.in.level, nt_errstr(status));
2168                                 ret = False;
2169                                 continue;
2170                         }
2171                 } else {
2172                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2173                                 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
2174                                        r.in.level, nt_errstr(status));
2175                                 ret = False;
2176                                 continue;
2177                         }
2178                 }
2179
2180                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2181                 if (!NT_STATUS_IS_OK(status)) {
2182                         printf("QueryDomainInfo level %u failed - %s\n", 
2183                                r.in.level, nt_errstr(status));
2184                         ret = False;
2185                         continue;
2186                 }
2187         }
2188
2189         return True;    
2190 }
2191
2192
2193 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2194                                   struct policy_handle *handle)
2195 {
2196         NTSTATUS status;
2197         struct samr_QueryDomainInfo2 r;
2198         uint16 levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2199         int i;
2200         BOOL ret = True;
2201
2202         for (i=0;i<ARRAY_SIZE(levels);i++) {
2203                 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
2204
2205                 r.in.handle = handle;
2206                 r.in.level = levels[i];
2207
2208                 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
2209                 if (!NT_STATUS_IS_OK(status)) {
2210                         printf("QueryDomainInfo2 level %u failed - %s\n", 
2211                                r.in.level, nt_errstr(status));
2212                         ret = False;
2213                         continue;
2214                 }
2215         }
2216
2217         return True;    
2218 }
2219
2220 void add_string_to_array(TALLOC_CTX *mem_ctx,
2221                          const char *str, const char ***strings, int *num)
2222 {
2223         *strings = talloc_realloc(mem_ctx, *strings,
2224                                   ((*num)+1) * sizeof(**strings));
2225
2226         if (*strings == NULL)
2227                 return;
2228
2229         (*strings)[*num] = str;
2230         *num += 1;
2231
2232         return;
2233 }
2234
2235 /* Test whether querydispinfo level 5 and enumdomgroups return the same
2236    set of group names. */
2237 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2238                            struct policy_handle *handle)
2239 {
2240         struct samr_EnumDomainGroups q1;
2241         struct samr_QueryDisplayInfo q2;
2242         NTSTATUS status;
2243         uint32 resume_handle=0;
2244         int i;
2245         BOOL ret = True;
2246
2247         int num_names = 0;
2248         const char **names = NULL;
2249
2250         printf("Testing coherency of querydispinfo vs enumdomgroups\n");
2251
2252         q1.in.handle = handle;
2253         q1.in.resume_handle = &resume_handle;
2254         q1.in.max_size = 5;
2255         q1.out.resume_handle = &resume_handle;
2256
2257         status = STATUS_MORE_ENTRIES;
2258         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2259                 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
2260
2261                 if (!NT_STATUS_IS_OK(status) &&
2262                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2263                         break;
2264
2265                 for (i=0; i<q1.out.sam->count; i++) {
2266                         add_string_to_array(mem_ctx,
2267                                             q1.out.sam->entries[i].name.name,
2268                                             &names, &num_names);
2269                 }
2270         }
2271
2272         if (!NT_STATUS_IS_OK(status)) {
2273                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2274                 return False;
2275         }
2276         
2277         if (!q1.out.sam) {
2278                 return False;
2279         }
2280
2281         q2.in.handle = handle;
2282         q2.in.level = 5;
2283         q2.in.start_idx = 0;
2284         q2.in.max_entries = 5;
2285         q2.in.buf_size = (uint32)-1;
2286
2287         status = STATUS_MORE_ENTRIES;
2288         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2289                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
2290
2291                 if (!NT_STATUS_IS_OK(status) &&
2292                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2293                         break;
2294
2295                 for (i=0; i<q2.out.info.info5.count; i++) {
2296                         char *name;
2297                         size_t namelen;
2298                         int j;
2299                         BOOL found = False;
2300
2301                         /* Querydisplayinfo returns ascii -- convert */
2302
2303                         namelen = convert_string_allocate(CH_DISPLAY, CH_UNIX,
2304                                                           q2.out.info.info5.entries[i].account_name.name,
2305                                                           q2.out.info.info5.entries[i].account_name.name_len,
2306                                                           (void **)&name);
2307                         name = realloc(name, namelen+1);
2308                         name[namelen] = 0;
2309
2310                         for (j=0; j<num_names; j++) {
2311                                 if (names[j] == NULL)
2312                                         continue;
2313                                 /* Hmm. No strequal in samba4 */
2314                                 if (strequal(names[j], name)) {
2315                                         names[j] = NULL;
2316                                         found = True;
2317                                         break;
2318                                 }
2319                         }
2320
2321                         if (!found) {
2322                                 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
2323                                        name);
2324                                 ret = False;
2325                         }
2326                 }
2327                 q2.in.start_idx += q2.out.info.info5.count;
2328         }
2329
2330         if (!NT_STATUS_IS_OK(status)) {
2331                 printf("QueryDisplayInfo level 5 failed - %s\n",
2332                        nt_errstr(status));
2333                 ret = False;
2334         }
2335
2336         for (i=0; i<num_names; i++) {
2337                 if (names[i] != NULL) {
2338                         printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
2339                                names[i]);
2340                         ret = False;
2341                 }
2342         }
2343
2344         return ret;
2345 }
2346
2347 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2348                                    struct policy_handle *group_handle)
2349 {
2350         struct samr_DeleteDomainGroup d;
2351         NTSTATUS status;
2352         BOOL ret = True;
2353
2354         printf("Testing DeleteDomainGroup\n");
2355
2356         d.in.handle = group_handle;
2357         d.out.handle = group_handle;
2358
2359         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2360         if (!NT_STATUS_IS_OK(status)) {
2361                 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
2362                 ret = False;
2363         }
2364
2365         return ret;
2366 }
2367
2368 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2369                                             struct policy_handle *domain_handle)
2370 {
2371         struct samr_TestPrivateFunctionsDomain r;
2372         NTSTATUS status;
2373         BOOL ret = True;
2374
2375         printf("Testing TestPrivateFunctionsDomain\n");
2376
2377         r.in.handle = domain_handle;
2378
2379         status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
2380         if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2381                 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
2382                 ret = False;
2383         }
2384
2385         return ret;
2386 }
2387
2388 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2389                           struct policy_handle *domain_handle)
2390 {
2391         struct samr_RidToSid r;
2392         NTSTATUS status;
2393         BOOL ret = True;
2394
2395         printf("Testing RidToSid\n");
2396
2397         r.in.handle = domain_handle;
2398         r.in.rid = 512;
2399
2400         status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
2401         if (!NT_STATUS_IS_OK(status)) {
2402                 printf("RidToSid failed - %s\n", nt_errstr(status));
2403                 ret = False;
2404         }
2405
2406         return ret;
2407 }
2408
2409 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2410                                        struct policy_handle *domain_handle)
2411 {
2412         struct samr_GetBootKeyInformation r;
2413         NTSTATUS status;
2414         BOOL ret = True;
2415
2416         printf("Testing GetBootKeyInformation\n");
2417
2418         r.in.handle = domain_handle;
2419
2420         status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
2421         if (!NT_STATUS_IS_OK(status)) {
2422                 /* w2k3 seems to fail this sometimes and pass it sometimes */
2423                 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
2424         }
2425
2426         return ret;
2427 }
2428
2429 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2430                                 struct policy_handle *domain_handle,
2431                                 struct policy_handle *group_handle)
2432 {
2433         NTSTATUS status;
2434         struct samr_AddGroupMember r;
2435         struct samr_DeleteGroupMember d;
2436         struct samr_QueryGroupMember q;
2437         struct samr_SetMemberAttributesOfGroup s;
2438         BOOL ret = True;
2439         uint32 rid;
2440
2441         status = test_LookupName(p, mem_ctx, domain_handle, TEST_USERNAME, &rid);
2442         if (!NT_STATUS_IS_OK(status)) {
2443                 return False;
2444         }
2445
2446         r.in.handle = group_handle;
2447         r.in.rid = rid;
2448         r.in.flags = 0; /* ??? */
2449
2450         printf("Testing AddGroupMember and DeleteGroupMember\n");
2451
2452         d.in.handle = group_handle;
2453         d.in.rid = rid;
2454
2455         status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2456         if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
2457                 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n", 
2458                        nt_errstr(status));
2459                 return False;
2460         }
2461
2462         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2463         if (!NT_STATUS_IS_OK(status)) {
2464                 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2465                 return False;
2466         }
2467
2468         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2469         if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
2470                 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n", 
2471                        nt_errstr(status));
2472                 return False;
2473         }
2474
2475         /* this one is quite strange. I am using random inputs in the
2476            hope of triggering an error that might give us a clue */
2477         s.in.handle = group_handle;
2478         s.in.unknown1 = random();
2479         s.in.unknown2 = random();
2480
2481         status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
2482         if (!NT_STATUS_IS_OK(status)) {
2483                 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
2484                 return False;
2485         }
2486
2487         q.in.handle = group_handle;
2488
2489         status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
2490         if (!NT_STATUS_IS_OK(status)) {
2491                 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
2492                 return False;
2493         }
2494
2495         status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2496         if (!NT_STATUS_IS_OK(status)) {
2497                 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
2498                 return False;
2499         }
2500
2501         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2502         if (!NT_STATUS_IS_OK(status)) {
2503                 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2504                 return False;
2505         }
2506
2507         return ret;
2508 }
2509
2510
2511 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2512                                    struct policy_handle *domain_handle, struct policy_handle *group_handle)
2513 {
2514         NTSTATUS status;
2515         struct samr_CreateDomainGroup r;
2516         uint32 rid;
2517         struct samr_Name name;
2518         BOOL ret = True;
2519
2520         init_samr_Name(&name, TEST_GROUPNAME);
2521
2522         r.in.handle = domain_handle;
2523         r.in.name = &name;
2524         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2525         r.out.group_handle = group_handle;
2526         r.out.rid = &rid;
2527
2528         printf("Testing CreateDomainGroup(%s)\n", r.in.name->name);
2529
2530         status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
2531
2532         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2533                 printf("Server refused create of '%s'\n", r.in.name->name);
2534                 ZERO_STRUCTP(group_handle);
2535                 return True;
2536         }
2537
2538         if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
2539                 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->name)) {
2540                         return False;
2541                 }
2542                 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
2543         }
2544         if (!NT_STATUS_IS_OK(status)) {
2545                 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
2546                 return False;
2547         }
2548
2549         if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
2550                 ret = False;
2551         }
2552
2553         if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
2554                 ret = False;
2555         }
2556
2557         return ret;
2558 }
2559
2560
2561 /*
2562   its not totally clear what this does. It seems to accept any sid you like.
2563 */
2564 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p, 
2565                                                TALLOC_CTX *mem_ctx, 
2566                                                struct policy_handle *domain_handle)
2567 {
2568         NTSTATUS status;
2569         struct samr_RemoveMemberFromForeignDomain r;
2570
2571         r.in.handle = domain_handle;
2572         r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78-9");
2573
2574         status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
2575         if (!NT_STATUS_IS_OK(status)) {
2576                 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
2577                 return False;
2578         }
2579
2580         return True;
2581 }
2582
2583
2584
2585
2586 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2587                             struct policy_handle *handle, struct dom_sid *sid)
2588 {
2589         NTSTATUS status;
2590         struct samr_OpenDomain r;
2591         struct policy_handle domain_handle;
2592         struct policy_handle user_handle;
2593         struct policy_handle alias_handle;
2594         struct policy_handle group_handle;
2595         BOOL ret = True;
2596
2597         ZERO_STRUCT(user_handle);
2598         ZERO_STRUCT(alias_handle);
2599         ZERO_STRUCT(group_handle);
2600         ZERO_STRUCT(domain_handle);
2601
2602         printf("Testing OpenDomain\n");
2603
2604         r.in.handle = handle;
2605         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2606         r.in.sid = sid;
2607         r.out.domain_handle = &domain_handle;
2608
2609         status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
2610         if (!NT_STATUS_IS_OK(status)) {
2611                 printf("OpenDomain failed - %s\n", nt_errstr(status));
2612                 return False;
2613         }
2614
2615         if (!test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle)) {
2616                 ret = False;
2617         }
2618
2619         if (!test_CreateUser2(p, mem_ctx, &domain_handle)) {
2620                 ret = False;
2621         }
2622
2623         if (!test_CreateUser(p, mem_ctx, &domain_handle, &user_handle)) {
2624                 ret = False;
2625         }
2626
2627         if (!test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid)) {
2628                 ret = False;
2629         }
2630
2631         if (!test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle)) {
2632                 ret = False;
2633         }
2634
2635         if (!test_QuerySecurity(p, mem_ctx, &domain_handle)) {
2636                 ret = False;
2637         }
2638
2639         if (!test_QueryDomainInfo(p, mem_ctx, &domain_handle)) {
2640                 ret = False;
2641         }
2642
2643         if (!test_QueryDomainInfo2(p, mem_ctx, &domain_handle)) {
2644                 ret = False;
2645         }
2646
2647         if (!test_EnumDomainUsers(p, mem_ctx, &domain_handle)) {
2648                 ret = False;
2649         }
2650
2651         if (!test_EnumDomainGroups(p, mem_ctx, &domain_handle)) {
2652                 ret = False;
2653         }
2654
2655         if (!test_EnumDomainAliases(p, mem_ctx, &domain_handle)) {
2656                 ret = False;
2657         }
2658
2659         if (!test_QueryDisplayInfo(p, mem_ctx, &domain_handle)) {
2660                 ret = False;
2661         }
2662
2663         if (!test_QueryDisplayInfo2(p, mem_ctx, &domain_handle)) {
2664                 ret = False;
2665         }
2666
2667         if (!test_QueryDisplayInfo3(p, mem_ctx, &domain_handle)) {
2668                 ret = False;
2669         }
2670
2671         if (!test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle)) {
2672                 ret = False;
2673         }
2674
2675         if (!test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle)) {
2676                 ret = False;
2677         }
2678
2679         if (!test_GroupList(p, mem_ctx, &domain_handle)) {
2680                 ret = False;
2681         }
2682
2683         if (!test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle)) {
2684                 ret = False;
2685         }
2686
2687         if (!test_RidToSid(p, mem_ctx, &domain_handle)) {
2688                 ret = False;
2689         }
2690
2691         if (!test_GetBootKeyInformation(p, mem_ctx, &domain_handle)) {
2692                 ret = False;
2693         }
2694
2695         if (!policy_handle_empty(&user_handle) &&
2696             !test_DeleteUser(p, mem_ctx, &user_handle)) {
2697                 ret = False;
2698         }
2699
2700         if (!policy_handle_empty(&alias_handle) &&
2701             !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
2702                 ret = False;
2703         }
2704
2705         if (!policy_handle_empty(&group_handle) &&
2706             !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
2707                 ret = False;
2708         }
2709
2710         if (!test_Close(p, mem_ctx, &domain_handle)) {
2711                 ret = False;
2712         }
2713
2714         return ret;
2715 }
2716
2717 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2718                               struct policy_handle *handle, struct samr_Name *domain)
2719 {
2720         NTSTATUS status;
2721         struct samr_LookupDomain r;
2722         struct samr_Name n2;
2723         BOOL ret = True;
2724
2725         printf("Testing LookupDomain(%s)\n", domain->name);
2726
2727         /* check for correct error codes */
2728         r.in.handle = handle;
2729         r.in.domain = &n2;
2730         n2.name = NULL;
2731
2732         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
2733         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
2734                 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
2735                 ret = False;
2736         }
2737
2738         n2.name = "xxNODOMAINxx";
2739
2740         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
2741         if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
2742                 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
2743                 ret = False;
2744         }
2745
2746         r.in.handle = handle;
2747         r.in.domain = domain;
2748
2749         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
2750         if (!NT_STATUS_IS_OK(status)) {
2751                 printf("LookupDomain failed - %s\n", nt_errstr(status));
2752                 ret = False;
2753         }
2754
2755         if (!test_GetDomPwInfo(p, mem_ctx, domain)) {
2756                 ret = False;
2757         }
2758
2759         if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
2760                 ret = False;
2761         }
2762
2763         return ret;
2764 }
2765
2766
2767 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2768                              struct policy_handle *handle)
2769 {
2770         NTSTATUS status;
2771         struct samr_EnumDomains r;
2772         uint32 resume_handle = 0;
2773         int i;
2774         BOOL ret = True;
2775
2776         r.in.handle = handle;
2777         r.in.resume_handle = &resume_handle;
2778         r.in.buf_size = (uint32)-1;
2779         r.out.resume_handle = &resume_handle;
2780
2781         status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
2782         if (!NT_STATUS_IS_OK(status)) {
2783                 printf("EnumDomains failed - %s\n", nt_errstr(status));
2784                 return False;
2785         }
2786
2787         if (!r.out.sam) {
2788                 return False;
2789         }
2790
2791         for (i=0;i<r.out.sam->count;i++) {
2792                 if (!test_LookupDomain(p, mem_ctx, handle, 
2793                                        &r.out.sam->entries[i].name)) {
2794                         ret = False;
2795                 }
2796         }
2797
2798         status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
2799         if (!NT_STATUS_IS_OK(status)) {
2800                 printf("EnumDomains failed - %s\n", nt_errstr(status));
2801                 return False;
2802         }
2803
2804         return ret;
2805 }
2806
2807
2808 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2809                          struct policy_handle *handle)
2810 {
2811         NTSTATUS status;
2812         struct samr_Connect r;
2813         struct samr_Connect2 r2;
2814         struct samr_Connect3 r3;
2815         struct samr_Connect4 r4;
2816         struct samr_Connect5 r5;
2817         union samr_ConnectInfo info;
2818         BOOL ret = True;
2819
2820         printf("testing samr_Connect\n");
2821
2822         r.in.system_name = 0;
2823         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2824         r.out.handle = handle;
2825
2826         status = dcerpc_samr_Connect(p, mem_ctx, &r);
2827         if (!NT_STATUS_IS_OK(status)) {
2828                 printf("Connect failed - %s\n", nt_errstr(status));
2829                 ret = False;
2830         }
2831
2832         printf("testing samr_Connect2\n");
2833
2834         r2.in.system_name = NULL;
2835         r2.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2836         r2.out.handle = handle;
2837
2838         status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
2839         if (!NT_STATUS_IS_OK(status)) {
2840                 printf("Connect2 failed - %s\n", nt_errstr(status));
2841                 ret = False;
2842         }
2843
2844         printf("testing samr_Connect3\n");
2845
2846         r3.in.system_name = NULL;
2847         r3.in.unknown = 0;
2848         r3.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2849         r3.out.handle = handle;
2850
2851         status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
2852         if (!NT_STATUS_IS_OK(status)) {
2853                 printf("Connect3 failed - %s\n", nt_errstr(status));
2854                 ret = False;
2855         }
2856
2857         printf("testing samr_Connect4\n");
2858
2859         r4.in.system_name = "";
2860         r4.in.unknown = 0;
2861         r4.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2862         r4.out.handle = handle;
2863
2864         status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
2865         if (!NT_STATUS_IS_OK(status)) {
2866                 printf("Connect4 failed - %s\n", nt_errstr(status));
2867                 ret = False;
2868         }
2869
2870         printf("testing samr_Connect5\n");
2871
2872         info.info1.unknown1 = 0;
2873         info.info1.unknown2 = 0;
2874
2875         r5.in.system_name = "";
2876         r5.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2877         r5.in.level = 1;
2878         r5.in.info = &info;
2879         r5.out.info = &info;
2880         r5.out.handle = handle;
2881
2882         status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
2883         if (!NT_STATUS_IS_OK(status)) {
2884                 printf("Connect5 failed - %s\n", nt_errstr(status));
2885                 ret = False;
2886         }
2887
2888         return ret;
2889 }
2890
2891
2892 BOOL torture_rpc_samr(int dummy)
2893 {
2894         NTSTATUS status;
2895         struct dcerpc_pipe *p;
2896         TALLOC_CTX *mem_ctx;
2897         BOOL ret = True;
2898         struct policy_handle handle;
2899
2900         mem_ctx = talloc_init("torture_rpc_samr");
2901
2902         status = torture_rpc_connection(&p, 
2903                                         DCERPC_SAMR_NAME,
2904                                         DCERPC_SAMR_UUID,
2905                                         DCERPC_SAMR_VERSION);
2906         if (!NT_STATUS_IS_OK(status)) {
2907                 return False;
2908         }
2909
2910         if (!test_Connect(p, mem_ctx, &handle)) {
2911                 ret = False;
2912         }
2913
2914         if (!test_QuerySecurity(p, mem_ctx, &handle)) {
2915                 ret = False;
2916         }
2917
2918         if (!test_EnumDomains(p, mem_ctx, &handle)) {
2919                 ret = False;
2920         }
2921
2922         if (!test_SetDsrmPassword(p, mem_ctx, &handle)) {
2923                 ret = False;
2924         }
2925
2926         if (!test_Shutdown(p, mem_ctx, &handle)) {
2927                 ret = False;
2928         }
2929
2930         if (!test_Close(p, mem_ctx, &handle)) {
2931                 ret = False;
2932         }
2933
2934         talloc_destroy(mem_ctx);
2935
2936         torture_rpc_close(p);
2937
2938         return ret;
2939 }
2940