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