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