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