r2107: added a SAMR async test - this one seems to work
[gd/samba-autobuild/.git] / source4 / torture / rpc / samr.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for samr rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24
25 #define TEST_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.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.handle = handle;
173         s.in.info = &u;
174
175         s2.in.handle = handle;
176         s2.in.info = &u;
177
178         q.in.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.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 = str_charnum(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.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.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.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.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.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.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.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.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.handle = domain_handle;
719         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
720         r.in.rid = rid;
721         r.out.acct_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.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.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                                   struct policy_handle *domain_handle,
1027                                   const struct dom_sid *domain_sid)
1028 {
1029         struct samr_AddAliasMember r;
1030         struct samr_DeleteAliasMember d;
1031         NTSTATUS status;
1032         BOOL ret = True;
1033         struct dom_sid *sid;
1034
1035         sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1036
1037         printf("testing AddAliasMember\n");
1038         r.in.handle = alias_handle;
1039         r.in.sid = sid;
1040
1041         status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1042         if (!NT_STATUS_IS_OK(status)) {
1043                 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1044                 ret = False;
1045         }
1046
1047         d.in.handle = alias_handle;
1048         d.in.sid = sid;
1049
1050         status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1051         if (!NT_STATUS_IS_OK(status)) {
1052                 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1053                 ret = False;
1054         }
1055
1056         return ret;
1057 }
1058
1059 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1060                                            struct policy_handle *alias_handle)
1061 {
1062         struct samr_AddMultipleMembersToAlias a;
1063         struct samr_RemoveMultipleMembersFromAlias r;
1064         NTSTATUS status;
1065         BOOL ret = True;
1066         struct lsa_SidArray sids;
1067
1068         printf("testing AddMultipleMembersToAlias\n");
1069         a.in.handle = alias_handle;
1070         a.in.sids = &sids;
1071
1072         sids.num_sids = 3;
1073         sids.sids = talloc_array_p(mem_ctx, struct lsa_SidPtr, 3);
1074
1075         sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1076         sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1077         sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1078
1079         status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1080         if (!NT_STATUS_IS_OK(status)) {
1081                 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1082                 ret = False;
1083         }
1084
1085
1086         printf("testing RemoveMultipleMembersFromAlias\n");
1087         r.in.handle = alias_handle;
1088         r.in.sids = &sids;
1089
1090         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1091         if (!NT_STATUS_IS_OK(status)) {
1092                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1093                 ret = False;
1094         }
1095
1096         /* strange! removing twice doesn't give any error */
1097         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1098         if (!NT_STATUS_IS_OK(status)) {
1099                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1100                 ret = False;
1101         }
1102
1103         /* but removing an alias that isn't there does */
1104         sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1105
1106         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1107         if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1108                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1109                 ret = False;
1110         }
1111
1112         return ret;
1113 }
1114
1115 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1116                                             struct policy_handle *user_handle)
1117 {
1118         struct samr_TestPrivateFunctionsUser r;
1119         NTSTATUS status;
1120         BOOL ret = True;
1121
1122         printf("Testing TestPrivateFunctionsUser\n");
1123
1124         r.in.handle = user_handle;
1125
1126         status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1127         if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1128                 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1129                 ret = False;
1130         }
1131
1132         return ret;
1133 }
1134
1135
1136 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1137                           struct policy_handle *handle)
1138 {
1139         BOOL ret = True;
1140
1141         if (!test_QuerySecurity(p, mem_ctx, handle)) {
1142                 ret = False;
1143         }
1144
1145         if (!test_QueryUserInfo(p, mem_ctx, handle)) {
1146                 ret = False;
1147         }
1148
1149         if (!test_QueryUserInfo2(p, mem_ctx, handle)) {
1150                 ret = False;
1151         }
1152
1153         if (!test_SetUserInfo(p, mem_ctx, handle)) {
1154                 ret = False;
1155         }       
1156
1157         if (!test_GetUserPwInfo(p, mem_ctx, handle)) {
1158                 ret = False;
1159         }
1160
1161         if (!test_TestPrivateFunctionsUser(p, mem_ctx, handle)) {
1162                 ret = False;
1163         }
1164
1165         return ret;
1166 }
1167
1168 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1169                            struct policy_handle *alias_handle,
1170                            struct policy_handle *domain_handle,
1171                            const struct dom_sid *domain_sid)
1172 {
1173         BOOL ret = True;
1174
1175         if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
1176                 ret = False;
1177         }
1178
1179         if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
1180                 ret = False;
1181         }
1182
1183         if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
1184                 ret = False;
1185         }
1186
1187         if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, 
1188                                    domain_handle, domain_sid)) {
1189                 ret = False;
1190         }
1191
1192         if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
1193                 ret = False;
1194         }
1195
1196         return ret;
1197 }
1198
1199
1200 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1201                             struct policy_handle *handle, const char *name)
1202 {
1203         NTSTATUS status;
1204         struct samr_DeleteUser d;
1205         struct policy_handle acct_handle;
1206         uint32_t rid;
1207
1208         status = test_LookupName(p, mem_ctx, handle, name, &rid);
1209         if (!NT_STATUS_IS_OK(status)) {
1210                 goto failed;
1211         }
1212
1213         status = test_OpenUser_byname(p, mem_ctx, handle, name, &acct_handle);
1214         if (!NT_STATUS_IS_OK(status)) {
1215                 goto failed;
1216         }
1217
1218         d.in.handle = &acct_handle;
1219         d.out.handle = &acct_handle;
1220         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1221         if (!NT_STATUS_IS_OK(status)) {
1222                 goto failed;
1223         }
1224
1225         return True;
1226
1227 failed:
1228         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1229         return False;
1230 }
1231
1232
1233 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1234                                     struct policy_handle *handle, const char *name)
1235 {
1236         NTSTATUS status;
1237         struct samr_OpenGroup r;
1238         struct samr_DeleteDomainGroup d;
1239         struct policy_handle group_handle;
1240         uint32_t rid;
1241
1242         status = test_LookupName(p, mem_ctx, handle, name, &rid);
1243         if (!NT_STATUS_IS_OK(status)) {
1244                 goto failed;
1245         }
1246
1247         r.in.handle = handle;
1248         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1249         r.in.rid = rid;
1250         r.out.acct_handle = &group_handle;
1251         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1252         if (!NT_STATUS_IS_OK(status)) {
1253                 goto failed;
1254         }
1255
1256         d.in.handle = &group_handle;
1257         d.out.handle = &group_handle;
1258         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
1259         if (!NT_STATUS_IS_OK(status)) {
1260                 goto failed;
1261         }
1262
1263         return True;
1264
1265 failed:
1266         printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
1267         return False;
1268 }
1269
1270
1271 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1272                                    struct policy_handle *domain_handle, const char *name)
1273 {
1274         NTSTATUS status;
1275         struct samr_OpenAlias r;
1276         struct samr_DeleteDomAlias d;
1277         struct policy_handle alias_handle;
1278         uint32_t rid;
1279
1280         printf("testing DeleteAlias_byname\n");
1281
1282         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1283         if (!NT_STATUS_IS_OK(status)) {
1284                 goto failed;
1285         }
1286
1287         r.in.handle = domain_handle;
1288         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1289         r.in.rid = rid;
1290         r.out.acct_handle = &alias_handle;
1291         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1292         if (!NT_STATUS_IS_OK(status)) {
1293                 goto failed;
1294         }
1295
1296         d.in.handle = &alias_handle;
1297         d.out.handle = &alias_handle;
1298         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1299         if (!NT_STATUS_IS_OK(status)) {
1300                 goto failed;
1301         }
1302
1303         return True;
1304
1305 failed:
1306         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1307         return False;
1308 }
1309
1310 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1311                                      struct policy_handle *alias_handle)
1312 {
1313         struct samr_DeleteDomAlias d;
1314         NTSTATUS status;
1315         BOOL ret = True;
1316         printf("Testing DeleteAlias\n");
1317
1318         d.in.handle = alias_handle;
1319         d.out.handle = alias_handle;
1320
1321         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1322         if (!NT_STATUS_IS_OK(status)) {
1323                 printf("DeleteAlias failed - %s\n", nt_errstr(status));
1324                 ret = False;
1325         }
1326
1327         return ret;
1328 }
1329
1330 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1331                             struct policy_handle *domain_handle, 
1332                              struct policy_handle *alias_handle, 
1333                              const struct dom_sid *domain_sid)
1334 {
1335         NTSTATUS status;
1336         struct samr_CreateDomAlias r;
1337         struct samr_Name name;
1338         uint32_t rid;
1339         BOOL ret = True;
1340
1341         init_samr_Name(&name, TEST_ALIASNAME);
1342         r.in.handle = domain_handle;
1343         r.in.aliasname = &name;
1344         r.in.access_mask = SEC_RIGHT_MAXIMUM_ALLOWED;
1345         r.out.acct_handle = alias_handle;
1346         r.out.rid = &rid;
1347
1348         printf("Testing CreateAlias (%s)\n", r.in.aliasname->name);
1349
1350         status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1351
1352         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1353                 printf("Server refused create of '%s'\n", r.in.aliasname->name);
1354                 return True;
1355         }
1356
1357         if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
1358                 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.aliasname->name)) {
1359                         return False;
1360                 }
1361                 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1362         }
1363
1364         if (!NT_STATUS_IS_OK(status)) {
1365                 printf("CreateAlias failed - %s\n", nt_errstr(status));
1366                 return False;
1367         }
1368
1369         if (!test_alias_ops(p, mem_ctx, alias_handle, domain_handle, domain_sid)) {
1370                 ret = False;
1371         }
1372
1373         return ret;
1374 }
1375
1376 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1377                                 struct policy_handle *domain_handle, char **password)
1378 {
1379         BOOL ret = True;
1380
1381         if (!*password) {
1382                 return False;
1383         }
1384
1385         if (!test_ChangePasswordUser(p, mem_ctx, domain_handle, password)) {
1386                 ret = False;
1387         }
1388
1389         if (!test_ChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1390                 ret = False;
1391         }
1392
1393         if (!test_OemChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1394                 ret = False;
1395         }
1396
1397         if (!test_ChangePasswordUser3(p, mem_ctx, domain_handle, password)) {
1398                 ret = False;
1399         }
1400
1401         return ret;
1402 }
1403
1404 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1405                             struct policy_handle *domain_handle, struct policy_handle *user_handle)
1406 {
1407         NTSTATUS status;
1408         struct samr_CreateUser r;
1409         struct samr_QueryUserInfo q;
1410         uint32_t rid;
1411         char *password = NULL;
1412
1413         /* This call creates a 'normal' account - check that it really does */
1414         const uint32_t acct_flags = ACB_NORMAL;
1415         struct samr_Name name;
1416         BOOL ret = True;
1417
1418         init_samr_Name(&name, TEST_ACCOUNT_NAME);
1419
1420         r.in.handle = domain_handle;
1421         r.in.account_name = &name;
1422         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1423         r.out.acct_handle = user_handle;
1424         r.out.rid = &rid;
1425
1426         printf("Testing CreateUser(%s)\n", r.in.account_name->name);
1427
1428         status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
1429
1430         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1431                 printf("Server refused create of '%s'\n", r.in.account_name->name);
1432                 ZERO_STRUCTP(user_handle);
1433                 return True;
1434         }
1435
1436         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1437                 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.account_name->name)) {
1438                         return False;
1439                 }
1440                 status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
1441         }
1442         if (!NT_STATUS_IS_OK(status)) {
1443                 printf("CreateUser failed - %s\n", nt_errstr(status));
1444                 return False;
1445         }
1446
1447         q.in.handle = user_handle;
1448         q.in.level = 16;
1449
1450         status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
1451         if (!NT_STATUS_IS_OK(status)) {
1452                 printf("QueryUserInfo level %u failed - %s\n", 
1453                        q.in.level, nt_errstr(status));
1454                 ret = False;
1455         } else {
1456                 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1457                         printf("QuerUserInfo level 16 failed, it returned 0x%08x (%u) when we expected flags of 0x%08x (%u)\n",
1458                                q.out.info->info16.acct_flags, q.out.info->info16.acct_flags, 
1459                                acct_flags, acct_flags);
1460                         ret = False;
1461                 }
1462         }
1463
1464         if (!test_user_ops(p, mem_ctx, user_handle)) {
1465                 ret = False;
1466         }
1467
1468         if (!test_SetUserPass(p, mem_ctx, user_handle, &password)) {
1469                 ret = False;
1470         }       
1471
1472         if (!test_SetUserPass_23(p, mem_ctx, user_handle, &password)) {
1473                 ret = False;
1474         }       
1475
1476         if (!test_SetUserPassEx(p, mem_ctx, user_handle, &password)) {
1477                 ret = False;
1478         }       
1479
1480         if (!test_SetUserPass_25(p, mem_ctx, user_handle, &password)) {
1481                 ret = False;
1482         }       
1483
1484         /* we change passwords twice - this has the effect of verifying
1485            they were changed correctly */
1486         if (!test_ChangePassword(p, mem_ctx, domain_handle, &password)) {
1487                 ret = False;
1488         }       
1489
1490         if (!test_ChangePassword(p, mem_ctx, domain_handle, &password)) {
1491                 ret = False;
1492         }       
1493
1494
1495         return ret;
1496 }
1497
1498
1499 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1500                             struct policy_handle *user_handle)
1501 {
1502         struct samr_DeleteUser d;
1503         NTSTATUS status;
1504         BOOL ret = True;
1505
1506         printf("Testing DeleteUser\n");
1507
1508         d.in.handle = user_handle;
1509         d.out.handle = user_handle;
1510
1511         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1512         if (!NT_STATUS_IS_OK(status)) {
1513                 printf("DeleteUser failed - %s\n", nt_errstr(status));
1514                 ret = False;
1515         }
1516
1517         return ret;
1518 }
1519
1520 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1521                              struct policy_handle *handle)
1522 {
1523         NTSTATUS status;
1524         struct samr_CreateUser2 r;
1525         struct samr_QueryUserInfo q;
1526         struct samr_DeleteUser d;
1527         struct policy_handle acct_handle;
1528         uint32_t rid;
1529         struct samr_Name name;
1530         BOOL ret = True;
1531         int i;
1532
1533         struct {
1534                 uint32_t acct_flags;
1535                 const char *account_name;
1536                 NTSTATUS nt_status;
1537         } account_types[] = {
1538                 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
1539                 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1540                 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1541                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1542                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1543                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1544                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1545                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1546                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1547                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
1548                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1549                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1550                 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1551                 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1552                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
1553         };
1554
1555         for (i = 0; account_types[i].account_name; i++) {
1556                 uint32_t acct_flags = account_types[i].acct_flags;
1557                 uint32_t access_granted;
1558
1559                 init_samr_Name(&name, account_types[i].account_name);
1560
1561                 r.in.handle = handle;
1562                 r.in.account_name = &name;
1563                 r.in.acct_flags = acct_flags;
1564                 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1565                 r.out.acct_handle = &acct_handle;
1566                 r.out.access_granted = &access_granted;
1567                 r.out.rid = &rid;
1568                 
1569                 printf("Testing CreateUser2(%s)\n", r.in.account_name->name);
1570                 
1571                 status = dcerpc_samr_CreateUser2(p, mem_ctx, &r);
1572                 
1573                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1574                         printf("Server refused create of '%s'\n", r.in.account_name->name);
1575                         continue;
1576
1577                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1578                         if (!test_DeleteUser_byname(p, mem_ctx, handle, r.in.account_name->name)) {
1579                                 return False;
1580                         }
1581                         status = dcerpc_samr_CreateUser2(p, mem_ctx, &r);
1582
1583                 }
1584                 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
1585                         printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n", 
1586                                nt_errstr(status), nt_errstr(account_types[i].nt_status));
1587                         ret = False;
1588                 }
1589                 
1590                 if (NT_STATUS_IS_OK(status)) {
1591                         q.in.handle = &acct_handle;
1592                         q.in.level = 16;
1593                         
1594                         status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
1595                         if (!NT_STATUS_IS_OK(status)) {
1596                                 printf("QueryUserInfo level %u failed - %s\n", 
1597                                        q.in.level, nt_errstr(status));
1598                                 ret = False;
1599                         } else {
1600                                 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1601                                         printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
1602                                                q.out.info->info16.acct_flags, 
1603                                                acct_flags);
1604                                         ret = False;
1605                                 }
1606                         }
1607                 
1608                         if (!test_user_ops(p, mem_ctx, &acct_handle)) {
1609                                 ret = False;
1610                         }
1611
1612                         printf("Testing DeleteUser (createuser2 test)\n");
1613                 
1614                         d.in.handle = &acct_handle;
1615                         d.out.handle = &acct_handle;
1616                         
1617                         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1618                         if (!NT_STATUS_IS_OK(status)) {
1619                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
1620                                 ret = False;
1621                         }
1622                 }
1623         }
1624
1625         return ret;
1626 }
1627
1628 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1629                                 struct policy_handle *handle)
1630 {
1631         NTSTATUS status;
1632         struct samr_QueryAliasInfo r;
1633         uint16_t levels[] = {1, 2, 3};
1634         int i;
1635         BOOL ret = True;
1636
1637         for (i=0;i<ARRAY_SIZE(levels);i++) {
1638                 printf("Testing QueryAliasInfo level %u\n", levels[i]);
1639
1640                 r.in.handle = handle;
1641                 r.in.level = levels[i];
1642
1643                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
1644                 if (!NT_STATUS_IS_OK(status)) {
1645                         printf("QueryAliasInfo level %u failed - %s\n", 
1646                                levels[i], nt_errstr(status));
1647                         ret = False;
1648                 }
1649         }
1650
1651         return ret;
1652 }
1653
1654 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1655                                 struct policy_handle *handle)
1656 {
1657         NTSTATUS status;
1658         struct samr_QueryGroupInfo r;
1659         uint16_t levels[] = {1, 2, 3, 4};
1660         int i;
1661         BOOL ret = True;
1662
1663         for (i=0;i<ARRAY_SIZE(levels);i++) {
1664                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1665
1666                 r.in.handle = handle;
1667                 r.in.level = levels[i];
1668
1669                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1670                 if (!NT_STATUS_IS_OK(status)) {
1671                         printf("QueryGroupInfo level %u failed - %s\n", 
1672                                levels[i], nt_errstr(status));
1673                         ret = False;
1674                 }
1675         }
1676
1677         return ret;
1678 }
1679
1680
1681 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1682                               struct policy_handle *handle)
1683 {
1684         NTSTATUS status;
1685         struct samr_QueryGroupInfo r;
1686         struct samr_SetGroupInfo s;
1687         uint16_t levels[] = {1, 2, 3, 4};
1688         uint16_t set_ok[] = {0, 1, 1, 1};
1689         int i;
1690         BOOL ret = True;
1691
1692         for (i=0;i<ARRAY_SIZE(levels);i++) {
1693                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1694
1695                 r.in.handle = handle;
1696                 r.in.level = levels[i];
1697
1698                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1699                 if (!NT_STATUS_IS_OK(status)) {
1700                         printf("QueryGroupInfo level %u failed - %s\n", 
1701                                levels[i], nt_errstr(status));
1702                         ret = False;
1703                 }
1704
1705                 printf("Testing SetGroupInfo level %u\n", levels[i]);
1706
1707                 s.in.handle = handle;
1708                 s.in.level = levels[i];
1709                 s.in.info = r.out.info;
1710
1711 #if 0
1712                 /* disabled this, as it changes the name only from the point of view of samr, 
1713                    but leaves the name from the point of view of w2k3 internals (and ldap). This means
1714                    the name is still reserved, so creating the old name fails, but deleting by the old name
1715                    also fails */
1716                 if (s.in.level == 2) {
1717                         init_samr_Name(&s.in.info->name, "NewName");
1718                 }
1719 #endif
1720
1721                 if (s.in.level == 4) {
1722                         init_samr_Name(&s.in.info->description, "test description");
1723                 }
1724
1725                 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
1726                 if (set_ok[i]) {
1727                         if (!NT_STATUS_IS_OK(status)) {
1728                                 printf("SetGroupInfo level %u failed - %s\n", 
1729                                        r.in.level, nt_errstr(status));
1730                                 ret = False;
1731                                 continue;
1732                         }
1733                 } else {
1734                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
1735                                 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
1736                                        r.in.level, nt_errstr(status));
1737                                 ret = False;
1738                                 continue;
1739                         }
1740                 }
1741         }
1742
1743         return ret;
1744 }
1745
1746 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1747                                struct policy_handle *handle)
1748 {
1749         NTSTATUS status;
1750         struct samr_QueryUserInfo r;
1751         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1752                            11, 12, 13, 14, 16, 17, 20, 21};
1753         int i;
1754         BOOL ret = True;
1755
1756         for (i=0;i<ARRAY_SIZE(levels);i++) {
1757                 printf("Testing QueryUserInfo level %u\n", levels[i]);
1758
1759                 r.in.handle = handle;
1760                 r.in.level = levels[i];
1761
1762                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
1763                 if (!NT_STATUS_IS_OK(status)) {
1764                         printf("QueryUserInfo level %u failed - %s\n", 
1765                                levels[i], nt_errstr(status));
1766                         ret = False;
1767                 }
1768         }
1769
1770         return ret;
1771 }
1772
1773 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1774                                 struct policy_handle *handle)
1775 {
1776         NTSTATUS status;
1777         struct samr_QueryUserInfo2 r;
1778         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1779                            11, 12, 13, 14, 16, 17, 20, 21};
1780         int i;
1781         BOOL ret = True;
1782
1783         for (i=0;i<ARRAY_SIZE(levels);i++) {
1784                 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
1785
1786                 r.in.handle = handle;
1787                 r.in.level = levels[i];
1788
1789                 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
1790                 if (!NT_STATUS_IS_OK(status)) {
1791                         printf("QueryUserInfo2 level %u failed - %s\n", 
1792                                levels[i], nt_errstr(status));
1793                         ret = False;
1794                 }
1795         }
1796
1797         return ret;
1798 }
1799
1800 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1801                           struct policy_handle *handle, uint32_t rid)
1802 {
1803         NTSTATUS status;
1804         struct samr_OpenUser r;
1805         struct policy_handle acct_handle;
1806         BOOL ret = True;
1807
1808         printf("Testing OpenUser(%u)\n", rid);
1809
1810         r.in.handle = handle;
1811         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1812         r.in.rid = rid;
1813         r.out.acct_handle = &acct_handle;
1814
1815         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1816         if (!NT_STATUS_IS_OK(status)) {
1817                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
1818                 return False;
1819         }
1820
1821         if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
1822                 ret = False;
1823         }
1824
1825         if (!test_QueryUserInfo(p, mem_ctx, &acct_handle)) {
1826                 ret = False;
1827         }
1828
1829         if (!test_QueryUserInfo2(p, mem_ctx, &acct_handle)) {
1830                 ret = False;
1831         }
1832
1833         if (!test_GetUserPwInfo(p, mem_ctx, &acct_handle)) {
1834                 ret = False;
1835         }
1836
1837         if (!test_GetGroupsForUser(p,mem_ctx, &acct_handle)) {
1838                 ret = False;
1839         }
1840
1841         if (!test_Close(p, mem_ctx, &acct_handle)) {
1842                 ret = False;
1843         }
1844
1845         return ret;
1846 }
1847
1848 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1849                            struct policy_handle *handle, uint32_t rid)
1850 {
1851         NTSTATUS status;
1852         struct samr_OpenGroup r;
1853         struct policy_handle acct_handle;
1854         BOOL ret = True;
1855
1856         printf("Testing OpenGroup(%u)\n", rid);
1857
1858         r.in.handle = handle;
1859         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1860         r.in.rid = rid;
1861         r.out.acct_handle = &acct_handle;
1862
1863         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1864         if (!NT_STATUS_IS_OK(status)) {
1865                 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
1866                 return False;
1867         }
1868
1869         if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
1870                 ret = False;
1871         }
1872
1873         if (!test_QueryGroupInfo(p, mem_ctx, &acct_handle)) {
1874                 ret = False;
1875         }
1876
1877         if (!test_Close(p, mem_ctx, &acct_handle)) {
1878                 ret = False;
1879         }
1880
1881         return ret;
1882 }
1883
1884 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1885                            struct policy_handle *handle, uint32_t rid)
1886 {
1887         NTSTATUS status;
1888         struct samr_OpenAlias r;
1889         struct policy_handle acct_handle;
1890         BOOL ret = True;
1891
1892         printf("Testing OpenAlias(%u)\n", rid);
1893
1894         r.in.handle = handle;
1895         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1896         r.in.rid = rid;
1897         r.out.acct_handle = &acct_handle;
1898
1899         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1900         if (!NT_STATUS_IS_OK(status)) {
1901                 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
1902                 return False;
1903         }
1904
1905         if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
1906                 ret = False;
1907         }
1908
1909         if (!test_QueryAliasInfo(p, mem_ctx, &acct_handle)) {
1910                 ret = False;
1911         }
1912
1913         if (!test_GetMembersInAlias(p, mem_ctx, &acct_handle)) {
1914                 ret = False;
1915         }
1916
1917         if (!test_Close(p, mem_ctx, &acct_handle)) {
1918                 ret = False;
1919         }
1920
1921         return ret;
1922 }
1923
1924 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1925                                  struct policy_handle *handle)
1926 {
1927         NTSTATUS status;
1928         struct samr_EnumDomainUsers r;
1929         uint32_t resume_handle=0;
1930         int i;
1931         BOOL ret = True;
1932         struct samr_LookupNames n;
1933         struct samr_LookupRids  lr ;
1934
1935         printf("Testing EnumDomainUsers\n");
1936
1937         r.in.handle = handle;
1938         r.in.resume_handle = &resume_handle;
1939         r.in.acct_flags = 0;
1940         r.in.max_size = (uint32_t)-1;
1941         r.out.resume_handle = &resume_handle;
1942
1943         status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
1944         if (!NT_STATUS_IS_OK(status)) {
1945                 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
1946                 return False;
1947         }
1948         
1949         if (!r.out.sam) {
1950                 return False;
1951         }
1952
1953         if (r.out.sam->count == 0) {
1954                 return True;
1955         }
1956
1957         for (i=0;i<r.out.sam->count;i++) {
1958                 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
1959                         ret = False;
1960                 }
1961         }
1962
1963         printf("Testing LookupNames\n");
1964         n.in.handle = handle;
1965         n.in.num_names = r.out.sam->count;
1966         n.in.names = talloc(mem_ctx, r.out.sam->count * sizeof(struct samr_Name));
1967         for (i=0;i<r.out.sam->count;i++) {
1968                 n.in.names[i] = r.out.sam->entries[i].name;
1969         }
1970         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
1971         if (!NT_STATUS_IS_OK(status)) {
1972                 printf("LookupNames failed - %s\n", nt_errstr(status));
1973                 ret = False;
1974         }
1975
1976
1977         printf("Testing LookupRids\n");
1978         lr.in.handle = handle;
1979         lr.in.num_rids = r.out.sam->count;
1980         lr.in.rids = talloc(mem_ctx, r.out.sam->count * sizeof(uint32_t));
1981         for (i=0;i<r.out.sam->count;i++) {
1982                 lr.in.rids[i] = r.out.sam->entries[i].idx;
1983         }
1984         status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
1985         if (!NT_STATUS_IS_OK(status)) {
1986                 printf("LookupRids failed - %s\n", nt_errstr(status));
1987                 ret = False;
1988         }
1989
1990         return ret;     
1991 }
1992
1993 /*
1994   try blasting the server with a bunch of sync requests
1995 */
1996 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1997                                        struct policy_handle *handle)
1998 {
1999         NTSTATUS status;
2000         struct samr_EnumDomainUsers r;
2001         uint32_t resume_handle=0;
2002         int i;
2003 #define ASYNC_COUNT 100
2004         struct rpc_request *req[ASYNC_COUNT];
2005
2006         printf("Testing EnumDomainUsers_async\n");
2007
2008         r.in.handle = handle;
2009         r.in.resume_handle = &resume_handle;
2010         r.in.acct_flags = 0;
2011         r.in.max_size = (uint32_t)-1;
2012         r.out.resume_handle = &resume_handle;
2013
2014         for (i=0;i<ASYNC_COUNT;i++) {
2015                 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
2016         }
2017
2018         for (i=0;i<ASYNC_COUNT;i++) {
2019                 status = dcerpc_ndr_request_recv(req[i]);
2020                 if (!NT_STATUS_IS_OK(status)) {
2021                         printf("EnumDomainUsers[%d] failed - %s\n", 
2022                                i, nt_errstr(status));
2023                         return False;
2024                 }
2025         }
2026         
2027         printf("%d async requests OK\n", i);
2028
2029         return True;
2030 }
2031
2032 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2033                                   struct policy_handle *handle)
2034 {
2035         NTSTATUS status;
2036         struct samr_EnumDomainGroups r;
2037         uint32_t resume_handle=0;
2038         int i;
2039         BOOL ret = True;
2040
2041         printf("Testing EnumDomainGroups\n");
2042
2043         r.in.handle = handle;
2044         r.in.resume_handle = &resume_handle;
2045         r.in.max_size = (uint32_t)-1;
2046         r.out.resume_handle = &resume_handle;
2047
2048         status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2049         if (!NT_STATUS_IS_OK(status)) {
2050                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2051                 return False;
2052         }
2053         
2054         if (!r.out.sam) {
2055                 return False;
2056         }
2057
2058         for (i=0;i<r.out.sam->count;i++) {
2059                 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2060                         ret = False;
2061                 }
2062         }
2063
2064         return ret;
2065 }
2066
2067 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2068                                    struct policy_handle *handle)
2069 {
2070         NTSTATUS status;
2071         struct samr_EnumDomainAliases r;
2072         uint32_t resume_handle=0;
2073         int i;
2074         BOOL ret = True;
2075
2076         printf("Testing EnumDomainAliases\n");
2077
2078         r.in.handle = handle;
2079         r.in.resume_handle = &resume_handle;
2080         r.in.account_flags = (uint32_t)-1;
2081         r.out.resume_handle = &resume_handle;
2082
2083         status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
2084         if (!NT_STATUS_IS_OK(status)) {
2085                 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
2086                 return False;
2087         }
2088         
2089         if (!r.out.sam) {
2090                 return False;
2091         }
2092
2093         for (i=0;i<r.out.sam->count;i++) {
2094                 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2095                         ret = False;
2096                 }
2097         }
2098
2099         return ret;     
2100 }
2101
2102 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2103                                             struct policy_handle *handle)
2104 {
2105         NTSTATUS status;
2106         struct samr_GetDisplayEnumerationIndex r;
2107         BOOL ret = True;
2108         uint16_t levels[] = {1, 2, 3, 4, 5};
2109         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2110         int i;
2111
2112         for (i=0;i<ARRAY_SIZE(levels);i++) {
2113                 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
2114
2115                 r.in.handle = handle;
2116                 r.in.level = levels[i];
2117                 init_samr_Name(&r.in.name, TEST_ACCOUNT_NAME);
2118
2119                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2120
2121                 if (ok_lvl[i] && 
2122                     !NT_STATUS_IS_OK(status) &&
2123                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2124                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
2125                                levels[i], nt_errstr(status));
2126                         ret = False;
2127                 }
2128
2129                 init_samr_Name(&r.in.name, "zzzzzzzz");
2130
2131                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2132                 
2133                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2134                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
2135                                levels[i], nt_errstr(status));
2136                         ret = False;
2137                 }
2138         }
2139         
2140         return ret;     
2141 }
2142
2143 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2144                                              struct policy_handle *handle)
2145 {
2146         NTSTATUS status;
2147         struct samr_GetDisplayEnumerationIndex2 r;
2148         BOOL ret = True;
2149         uint16_t levels[] = {1, 2, 3, 4, 5};
2150         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2151         int i;
2152
2153         for (i=0;i<ARRAY_SIZE(levels);i++) {
2154                 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2155
2156                 r.in.handle = handle;
2157                 r.in.level = levels[i];
2158                 init_samr_Name(&r.in.name, TEST_ACCOUNT_NAME);
2159
2160                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2161                 if (ok_lvl[i] && 
2162                     !NT_STATUS_IS_OK(status) && 
2163                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2164                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
2165                                levels[i], nt_errstr(status));
2166                         ret = False;
2167                 }
2168
2169                 init_samr_Name(&r.in.name, "zzzzzzzz");
2170
2171                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2172                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2173                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
2174                                levels[i], nt_errstr(status));
2175                         ret = False;
2176                 }
2177         }
2178         
2179         return ret;     
2180 }
2181
2182 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2183                                   struct policy_handle *handle)
2184 {
2185         NTSTATUS status;
2186         struct samr_QueryDisplayInfo r;
2187         BOOL ret = True;
2188         uint16_t levels[] = {1, 2, 3, 4, 5};
2189         int i;
2190
2191         for (i=0;i<ARRAY_SIZE(levels);i++) {
2192                 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2193
2194                 r.in.handle = handle;
2195                 r.in.level = levels[i];
2196                 r.in.start_idx = 0;
2197                 r.in.max_entries = 1000;
2198                 r.in.buf_size = (uint32_t)-1;
2199
2200                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2201                 if (!NT_STATUS_IS_OK(status)) {
2202                         printf("QueryDisplayInfo level %u failed - %s\n", 
2203                                levels[i], nt_errstr(status));
2204                         ret = False;
2205                 }
2206         }
2207         
2208         return ret;     
2209 }
2210
2211 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2212                                   struct policy_handle *handle)
2213 {
2214         NTSTATUS status;
2215         struct samr_QueryDisplayInfo2 r;
2216         BOOL ret = True;
2217         uint16_t levels[] = {1, 2, 3, 4, 5};
2218         int i;
2219
2220         for (i=0;i<ARRAY_SIZE(levels);i++) {
2221                 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2222
2223                 r.in.handle = handle;
2224                 r.in.level = levels[i];
2225                 r.in.start_idx = 0;
2226                 r.in.max_entries = 1000;
2227                 r.in.buf_size = (uint32_t)-1;
2228
2229                 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2230                 if (!NT_STATUS_IS_OK(status)) {
2231                         printf("QueryDisplayInfo2 level %u failed - %s\n", 
2232                                levels[i], nt_errstr(status));
2233                         ret = False;
2234                 }
2235         }
2236         
2237         return ret;     
2238 }
2239
2240 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2241                                   struct policy_handle *handle)
2242 {
2243         NTSTATUS status;
2244         struct samr_QueryDisplayInfo3 r;
2245         BOOL ret = True;
2246         uint16_t levels[] = {1, 2, 3, 4, 5};
2247         int i;
2248
2249         for (i=0;i<ARRAY_SIZE(levels);i++) {
2250                 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2251
2252                 r.in.handle = handle;
2253                 r.in.level = levels[i];
2254                 r.in.start_idx = 0;
2255                 r.in.max_entries = 1000;
2256                 r.in.buf_size = (uint32_t)-1;
2257
2258                 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2259                 if (!NT_STATUS_IS_OK(status)) {
2260                         printf("QueryDisplayInfo3 level %u failed - %s\n", 
2261                                levels[i], nt_errstr(status));
2262                         ret = False;
2263                 }
2264         }
2265         
2266         return ret;     
2267 }
2268
2269 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2270                                  struct policy_handle *handle)
2271 {
2272         NTSTATUS status;
2273         struct samr_QueryDomainInfo r;
2274         struct samr_SetDomainInfo s;
2275         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2276         uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
2277         int i;
2278         BOOL ret = True;
2279
2280         for (i=0;i<ARRAY_SIZE(levels);i++) {
2281                 printf("Testing QueryDomainInfo level %u\n", levels[i]);
2282
2283                 r.in.handle = handle;
2284                 r.in.level = levels[i];
2285
2286                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2287                 if (!NT_STATUS_IS_OK(status)) {
2288                         printf("QueryDomainInfo level %u failed - %s\n", 
2289                                r.in.level, nt_errstr(status));
2290                         ret = False;
2291                         continue;
2292                 }
2293
2294                 printf("Testing SetDomainInfo level %u\n", levels[i]);
2295
2296                 s.in.handle = handle;
2297                 s.in.level = levels[i];
2298                 s.in.info = r.out.info;
2299
2300                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2301                 if (set_ok[i]) {
2302                         if (!NT_STATUS_IS_OK(status)) {
2303                                 printf("SetDomainInfo level %u failed - %s\n", 
2304                                        r.in.level, nt_errstr(status));
2305                                 ret = False;
2306                                 continue;
2307                         }
2308                 } else {
2309                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2310                                 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
2311                                        r.in.level, nt_errstr(status));
2312                                 ret = False;
2313                                 continue;
2314                         }
2315                 }
2316
2317                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2318                 if (!NT_STATUS_IS_OK(status)) {
2319                         printf("QueryDomainInfo level %u failed - %s\n", 
2320                                r.in.level, nt_errstr(status));
2321                         ret = False;
2322                         continue;
2323                 }
2324         }
2325
2326         return True;    
2327 }
2328
2329
2330 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2331                                   struct policy_handle *handle)
2332 {
2333         NTSTATUS status;
2334         struct samr_QueryDomainInfo2 r;
2335         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2336         int i;
2337         BOOL ret = True;
2338
2339         for (i=0;i<ARRAY_SIZE(levels);i++) {
2340                 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
2341
2342                 r.in.handle = handle;
2343                 r.in.level = levels[i];
2344
2345                 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
2346                 if (!NT_STATUS_IS_OK(status)) {
2347                         printf("QueryDomainInfo2 level %u failed - %s\n", 
2348                                r.in.level, nt_errstr(status));
2349                         ret = False;
2350                         continue;
2351                 }
2352         }
2353
2354         return True;    
2355 }
2356
2357 /* Test whether querydispinfo level 5 and enumdomgroups return the same
2358    set of group names. */
2359 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2360                            struct policy_handle *handle)
2361 {
2362         struct samr_EnumDomainGroups q1;
2363         struct samr_QueryDisplayInfo q2;
2364         NTSTATUS status;
2365         uint32_t resume_handle=0;
2366         int i;
2367         BOOL ret = True;
2368
2369         int num_names = 0;
2370         const char **names = NULL;
2371
2372         printf("Testing coherency of querydispinfo vs enumdomgroups\n");
2373
2374         q1.in.handle = handle;
2375         q1.in.resume_handle = &resume_handle;
2376         q1.in.max_size = 5;
2377         q1.out.resume_handle = &resume_handle;
2378
2379         status = STATUS_MORE_ENTRIES;
2380         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2381                 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
2382
2383                 if (!NT_STATUS_IS_OK(status) &&
2384                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2385                         break;
2386
2387                 for (i=0; i<q1.out.sam->count; i++) {
2388                         add_string_to_array(mem_ctx,
2389                                             q1.out.sam->entries[i].name.name,
2390                                             &names, &num_names);
2391                 }
2392         }
2393
2394         if (!NT_STATUS_IS_OK(status)) {
2395                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2396                 return False;
2397         }
2398         
2399         if (!q1.out.sam) {
2400                 return False;
2401         }
2402
2403         q2.in.handle = handle;
2404         q2.in.level = 5;
2405         q2.in.start_idx = 0;
2406         q2.in.max_entries = 5;
2407         q2.in.buf_size = (uint32_t)-1;
2408
2409         status = STATUS_MORE_ENTRIES;
2410         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2411                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
2412
2413                 if (!NT_STATUS_IS_OK(status) &&
2414                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2415                         break;
2416
2417                 for (i=0; i<q2.out.info.info5.count; i++) {
2418                         char *name;
2419                         size_t namelen;
2420                         int j;
2421                         BOOL found = False;
2422
2423                         /* Querydisplayinfo returns ascii -- convert */
2424
2425                         namelen = convert_string_allocate(CH_DISPLAY, CH_UNIX,
2426                                                           q2.out.info.info5.entries[i].account_name.name,
2427                                                           q2.out.info.info5.entries[i].account_name.name_len,
2428                                                           (void **)&name);
2429                         name = realloc(name, namelen+1);
2430                         name[namelen] = 0;
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.handle = group_handle;
2479         d.out.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.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.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.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.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.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.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.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.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.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
2709 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2710                             struct policy_handle *handle, struct dom_sid *sid)
2711 {
2712         NTSTATUS status;
2713         struct samr_OpenDomain r;
2714         struct policy_handle domain_handle;
2715         struct policy_handle user_handle;
2716         struct policy_handle alias_handle;
2717         struct policy_handle group_handle;
2718         BOOL ret = True;
2719
2720         ZERO_STRUCT(user_handle);
2721         ZERO_STRUCT(alias_handle);
2722         ZERO_STRUCT(group_handle);
2723         ZERO_STRUCT(domain_handle);
2724
2725         printf("Testing OpenDomain\n");
2726
2727         r.in.handle = handle;
2728         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2729         r.in.sid = sid;
2730         r.out.domain_handle = &domain_handle;
2731
2732         status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
2733         if (!NT_STATUS_IS_OK(status)) {
2734                 printf("OpenDomain failed - %s\n", nt_errstr(status));
2735                 return False;
2736         }
2737
2738         if (!test_QuerySecurity(p, mem_ctx, &domain_handle)) {
2739                 ret = False;
2740         }
2741
2742         if (!test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle)) {
2743                 ret = False;
2744         }
2745
2746         if (!test_CreateUser2(p, mem_ctx, &domain_handle)) {
2747                 ret = False;
2748         }
2749
2750         if (!test_CreateUser(p, mem_ctx, &domain_handle, &user_handle)) {
2751                 ret = False;
2752         }
2753
2754         if (!test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid)) {
2755                 ret = False;
2756         }
2757
2758         if (!test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle)) {
2759                 ret = False;
2760         }
2761
2762         if (!test_QueryDomainInfo(p, mem_ctx, &domain_handle)) {
2763                 ret = False;
2764         }
2765
2766         if (!test_QueryDomainInfo2(p, mem_ctx, &domain_handle)) {
2767                 ret = False;
2768         }
2769
2770         if (!test_EnumDomainUsers(p, mem_ctx, &domain_handle)) {
2771                 ret = False;
2772         }
2773
2774         if (!test_EnumDomainUsers_async(p, mem_ctx, &domain_handle)) {
2775                 ret = False;
2776         }
2777
2778         if (!test_EnumDomainGroups(p, mem_ctx, &domain_handle)) {
2779                 ret = False;
2780         }
2781
2782         if (!test_EnumDomainAliases(p, mem_ctx, &domain_handle)) {
2783                 ret = False;
2784         }
2785
2786         if (!test_QueryDisplayInfo(p, mem_ctx, &domain_handle)) {
2787                 ret = False;
2788         }
2789
2790         if (!test_QueryDisplayInfo2(p, mem_ctx, &domain_handle)) {
2791                 ret = False;
2792         }
2793
2794         if (!test_QueryDisplayInfo3(p, mem_ctx, &domain_handle)) {
2795                 ret = False;
2796         }
2797
2798         if (!test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle)) {
2799                 ret = False;
2800         }
2801
2802         if (!test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle)) {
2803                 ret = False;
2804         }
2805
2806         if (!test_GroupList(p, mem_ctx, &domain_handle)) {
2807                 ret = False;
2808         }
2809
2810         if (!test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle)) {
2811                 ret = False;
2812         }
2813
2814         if (!test_RidToSid(p, mem_ctx, &domain_handle)) {
2815                 ret = False;
2816         }
2817
2818         if (!test_GetBootKeyInformation(p, mem_ctx, &domain_handle)) {
2819                 ret = False;
2820         }
2821
2822         if (!policy_handle_empty(&user_handle) &&
2823             !test_DeleteUser(p, mem_ctx, &user_handle)) {
2824                 ret = False;
2825         }
2826
2827         if (!policy_handle_empty(&alias_handle) &&
2828             !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
2829                 ret = False;
2830         }
2831
2832         if (!policy_handle_empty(&group_handle) &&
2833             !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
2834                 ret = False;
2835         }
2836
2837         if (!test_Close(p, mem_ctx, &domain_handle)) {
2838                 ret = False;
2839         }
2840
2841         return ret;
2842 }
2843
2844 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2845                               struct policy_handle *handle, struct samr_Name *domain)
2846 {
2847         NTSTATUS status;
2848         struct samr_LookupDomain r;
2849         struct samr_Name n2;
2850         BOOL ret = True;
2851
2852         printf("Testing LookupDomain(%s)\n", domain->name);
2853
2854         /* check for correct error codes */
2855         r.in.handle = handle;
2856         r.in.domain = &n2;
2857         n2.name = NULL;
2858
2859         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
2860         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
2861                 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
2862                 ret = False;
2863         }
2864
2865         n2.name = "xxNODOMAINxx";
2866
2867         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
2868         if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
2869                 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
2870                 ret = False;
2871         }
2872
2873         r.in.handle = handle;
2874         r.in.domain = domain;
2875
2876         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
2877         if (!NT_STATUS_IS_OK(status)) {
2878                 printf("LookupDomain failed - %s\n", nt_errstr(status));
2879                 ret = False;
2880         }
2881
2882         if (!test_GetDomPwInfo(p, mem_ctx, domain)) {
2883                 ret = False;
2884         }
2885
2886         if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
2887                 ret = False;
2888         }
2889
2890         return ret;
2891 }
2892
2893
2894 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2895                              struct policy_handle *handle)
2896 {
2897         NTSTATUS status;
2898         struct samr_EnumDomains r;
2899         uint32_t resume_handle = 0;
2900         int i;
2901         BOOL ret = True;
2902
2903         r.in.handle = handle;
2904         r.in.resume_handle = &resume_handle;
2905         r.in.buf_size = (uint32_t)-1;
2906         r.out.resume_handle = &resume_handle;
2907
2908         status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
2909         if (!NT_STATUS_IS_OK(status)) {
2910                 printf("EnumDomains failed - %s\n", nt_errstr(status));
2911                 return False;
2912         }
2913
2914         if (!r.out.sam) {
2915                 return False;
2916         }
2917
2918         for (i=0;i<r.out.sam->count;i++) {
2919                 if (!test_LookupDomain(p, mem_ctx, handle, 
2920                                        &r.out.sam->entries[i].name)) {
2921                         ret = False;
2922                 }
2923         }
2924
2925         status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
2926         if (!NT_STATUS_IS_OK(status)) {
2927                 printf("EnumDomains failed - %s\n", nt_errstr(status));
2928                 return False;
2929         }
2930
2931         return ret;
2932 }
2933
2934
2935 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2936                          struct policy_handle *handle)
2937 {
2938         NTSTATUS status;
2939         struct samr_Connect r;
2940         struct samr_Connect2 r2;
2941         struct samr_Connect3 r3;
2942         struct samr_Connect4 r4;
2943         struct samr_Connect5 r5;
2944         union samr_ConnectInfo info;
2945         BOOL ret = True;
2946
2947         printf("testing samr_Connect\n");
2948
2949         r.in.system_name = 0;
2950         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2951         r.out.handle = handle;
2952
2953         status = dcerpc_samr_Connect(p, mem_ctx, &r);
2954         if (!NT_STATUS_IS_OK(status)) {
2955                 printf("Connect failed - %s\n", nt_errstr(status));
2956                 ret = False;
2957         }
2958
2959         printf("testing samr_Connect2\n");
2960
2961         r2.in.system_name = NULL;
2962         r2.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2963         r2.out.handle = handle;
2964
2965         status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
2966         if (!NT_STATUS_IS_OK(status)) {
2967                 printf("Connect2 failed - %s\n", nt_errstr(status));
2968                 ret = False;
2969         }
2970
2971         printf("testing samr_Connect3\n");
2972
2973         r3.in.system_name = NULL;
2974         r3.in.unknown = 0;
2975         r3.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2976         r3.out.handle = handle;
2977
2978         status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
2979         if (!NT_STATUS_IS_OK(status)) {
2980                 printf("Connect3 failed - %s\n", nt_errstr(status));
2981                 ret = False;
2982         }
2983
2984         printf("testing samr_Connect4\n");
2985
2986         r4.in.system_name = "";
2987         r4.in.unknown = 0;
2988         r4.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2989         r4.out.handle = handle;
2990
2991         status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
2992         if (!NT_STATUS_IS_OK(status)) {
2993                 printf("Connect4 failed - %s\n", nt_errstr(status));
2994                 ret = False;
2995         }
2996
2997         printf("testing samr_Connect5\n");
2998
2999         info.info1.unknown1 = 0;
3000         info.info1.unknown2 = 0;
3001
3002         r5.in.system_name = "";
3003         r5.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
3004         r5.in.level = 1;
3005         r5.in.info = &info;
3006         r5.out.info = &info;
3007         r5.out.handle = handle;
3008
3009         status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
3010         if (!NT_STATUS_IS_OK(status)) {
3011                 printf("Connect5 failed - %s\n", nt_errstr(status));
3012                 ret = False;
3013         }
3014
3015         return ret;
3016 }
3017
3018
3019 BOOL torture_rpc_samr(int dummy)
3020 {
3021         NTSTATUS status;
3022         struct dcerpc_pipe *p;
3023         TALLOC_CTX *mem_ctx;
3024         BOOL ret = True;
3025         struct policy_handle handle;
3026
3027         mem_ctx = talloc_init("torture_rpc_samr");
3028
3029         status = torture_rpc_connection(&p, 
3030                                         DCERPC_SAMR_NAME,
3031                                         DCERPC_SAMR_UUID,
3032                                         DCERPC_SAMR_VERSION);
3033         if (!NT_STATUS_IS_OK(status)) {
3034                 return False;
3035         }
3036
3037         if (!test_Connect(p, mem_ctx, &handle)) {
3038                 ret = False;
3039         }
3040
3041         if (!test_QuerySecurity(p, mem_ctx, &handle)) {
3042                 ret = False;
3043         }
3044
3045         if (!test_EnumDomains(p, mem_ctx, &handle)) {
3046                 ret = False;
3047         }
3048
3049         if (!test_SetDsrmPassword(p, mem_ctx, &handle)) {
3050                 ret = False;
3051         }
3052
3053         if (!test_Shutdown(p, mem_ctx, &handle)) {
3054                 ret = False;
3055         }
3056
3057         if (!test_Close(p, mem_ctx, &handle)) {
3058                 ret = False;
3059         }
3060
3061         talloc_destroy(mem_ctx);
3062
3063         torture_rpc_close(p);
3064
3065         return ret;
3066 }
3067