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