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