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