r19392: Use torture_setting_* rather than lp_parm_* where possible.
[samba.git] / source / torture / rpc / samr.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for samr rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "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                 int i;
1905
1906                 ZERO_STRUCT(simple_pass);
1907                 memset(simple_pass, *v, sizeof(simple_pass) - 1);
1908
1909                 /* test what happens when picking a simple password */
1910                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, True)) {
1911                         ret = False;
1912                 }
1913         }
1914
1915         /* set samr_SetDomainInfo level 1 with min_length 5 */
1916         {
1917                 struct samr_QueryDomainInfo r;
1918                 struct samr_SetDomainInfo s;
1919                 uint16_t len_old, len;
1920                 NTSTATUS status;
1921
1922                 len = 3;
1923
1924                 r.in.domain_handle = domain_handle;
1925                 r.in.level = 1;
1926
1927                 printf("testing samr_QueryDomainInfo level 1\n");
1928                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
1929                 if (!NT_STATUS_IS_OK(status)) {
1930                         return False;
1931                 }
1932
1933                 s.in.domain_handle = domain_handle;
1934                 s.in.level = 1;
1935                 s.in.info = r.out.info;
1936
1937                 len_old = s.in.info->info1.min_password_length;
1938                 s.in.info->info1.min_password_length = len;
1939
1940                 printf("testing samr_SetDomainInfo level 1\n");
1941                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
1942                 if (!NT_STATUS_IS_OK(status)) {
1943                         return False;
1944                 }
1945
1946                 printf("calling test_ChangePasswordUser3 with too short password\n");
1947
1948                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, True)) {
1949                         ret = False;
1950                 }
1951
1952                 s.in.info->info1.min_password_length = len_old;
1953                 
1954                 printf("testing samr_SetDomainInfo level 1\n");
1955                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
1956                 if (!NT_STATUS_IS_OK(status)) {
1957                         return False;
1958                 }
1959
1960         }
1961
1962         {
1963                 NTSTATUS status;
1964                 struct samr_OpenUser r;
1965                 struct samr_QueryUserInfo q;
1966                 struct samr_LookupNames n;
1967                 struct policy_handle user_handle;
1968
1969                 n.in.domain_handle = domain_handle;
1970                 n.in.num_names = 1;
1971                 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
1972                 n.in.names[0].string = acct_name; 
1973
1974                 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
1975                 if (!NT_STATUS_IS_OK(status)) {
1976                         printf("LookupNames failed - %s\n", nt_errstr(status));
1977                         return False;
1978                 }
1979
1980                 r.in.domain_handle = domain_handle;
1981                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1982                 r.in.rid = n.out.rids.ids[0];
1983                 r.out.user_handle = &user_handle;
1984
1985                 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1986                 if (!NT_STATUS_IS_OK(status)) {
1987                         printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
1988                         return False;
1989                 }
1990
1991                 q.in.user_handle = &user_handle;
1992                 q.in.level = 5;
1993
1994                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
1995                 if (!NT_STATUS_IS_OK(status)) {
1996                         printf("QueryUserInfo failed - %s\n", nt_errstr(status));
1997                         return False;
1998                 }
1999
2000                 printf("calling test_ChangePasswordUser3 with too early password change\n");
2001
2002                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 
2003                                               q.out.info->info5.last_password_change, True)) {
2004                         ret = False;
2005                 }
2006         }
2007
2008         return True;
2009
2010         /* we change passwords twice - this has the effect of verifying
2011            they were changed correctly for the final call */
2012         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {
2013                 ret = False;
2014         }
2015
2016         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {
2017                 ret = False;
2018         }
2019
2020         return ret;
2021 }
2022
2023 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2024                             struct policy_handle *domain_handle, 
2025                             struct policy_handle *user_handle_out, 
2026                             enum torture_samr_choice which_ops)
2027 {
2028
2029         TALLOC_CTX *user_ctx;
2030
2031         NTSTATUS status;
2032         struct samr_CreateUser r;
2033         struct samr_QueryUserInfo q;
2034         struct samr_DeleteUser d;
2035         uint32_t rid;
2036
2037         /* This call creates a 'normal' account - check that it really does */
2038         const uint32_t acct_flags = ACB_NORMAL;
2039         struct lsa_String name;
2040         BOOL ret = True;
2041
2042         struct policy_handle user_handle;
2043         user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2044         init_lsa_String(&name, TEST_ACCOUNT_NAME);
2045
2046         r.in.domain_handle = domain_handle;
2047         r.in.account_name = &name;
2048         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2049         r.out.user_handle = &user_handle;
2050         r.out.rid = &rid;
2051
2052         printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2053
2054         status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2055
2056         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2057                 printf("Server refused create of '%s': %s\n", r.in.account_name->string, nt_errstr(status));
2058                 talloc_free(user_ctx);
2059                 return True;
2060         }
2061
2062         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2063                 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2064                         talloc_free(user_ctx);
2065                         return False;
2066                 }
2067                 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2068         }
2069         if (!NT_STATUS_IS_OK(status)) {
2070                 talloc_free(user_ctx);
2071                 printf("CreateUser failed - %s\n", nt_errstr(status));
2072                 return False;
2073         } else {
2074                 q.in.user_handle = &user_handle;
2075                 q.in.level = 16;
2076                 
2077                 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2078                 if (!NT_STATUS_IS_OK(status)) {
2079                         printf("QueryUserInfo level %u failed - %s\n", 
2080                                q.in.level, nt_errstr(status));
2081                         ret = False;
2082                 } else {
2083                         if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2084                                 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2085                                        q.out.info->info16.acct_flags, 
2086                                        acct_flags);
2087                                 ret = False;
2088                         }
2089                 }
2090                 
2091                 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle, 
2092                                    acct_flags, name.string, which_ops)) {
2093                         ret = False;
2094                 }
2095                 
2096                 if (user_handle_out) {
2097                         *user_handle_out = user_handle;
2098                 } else {
2099                         printf("Testing DeleteUser (createuser test)\n");
2100                         
2101                         d.in.user_handle = &user_handle;
2102                         d.out.user_handle = &user_handle;
2103                         
2104                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2105                         if (!NT_STATUS_IS_OK(status)) {
2106                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
2107                                 ret = False;
2108                         }
2109                 }
2110                 
2111         }
2112
2113         talloc_free(user_ctx);
2114         
2115         return ret;
2116 }
2117
2118
2119 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2120                              struct policy_handle *domain_handle, enum torture_samr_choice which_ops)
2121 {
2122         NTSTATUS status;
2123         struct samr_CreateUser2 r;
2124         struct samr_QueryUserInfo q;
2125         struct samr_DeleteUser d;
2126         struct policy_handle user_handle;
2127         uint32_t rid;
2128         struct lsa_String name;
2129         BOOL ret = True;
2130         int i;
2131
2132         struct {
2133                 uint32_t acct_flags;
2134                 const char *account_name;
2135                 NTSTATUS nt_status;
2136         } account_types[] = {
2137                 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2138                 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2139                 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2140                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2141                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2142                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2143                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2144                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2145                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2146                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2147                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2148                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2149                 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2150                 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2151                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2152         };
2153
2154         for (i = 0; account_types[i].account_name; i++) {
2155                 TALLOC_CTX *user_ctx;
2156                 uint32_t acct_flags = account_types[i].acct_flags;
2157                 uint32_t access_granted;
2158                 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2159                 init_lsa_String(&name, account_types[i].account_name);
2160
2161                 r.in.domain_handle = domain_handle;
2162                 r.in.account_name = &name;
2163                 r.in.acct_flags = acct_flags;
2164                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2165                 r.out.user_handle = &user_handle;
2166                 r.out.access_granted = &access_granted;
2167                 r.out.rid = &rid;
2168                 
2169                 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2170                 
2171                 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2172                 
2173                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2174                         talloc_free(user_ctx);
2175                         printf("Server refused create of '%s'\n", r.in.account_name->string);
2176                         continue;
2177
2178                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2179                         if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2180                                 talloc_free(user_ctx);
2181                                 ret = False;
2182                                 continue;
2183                         }
2184                         status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2185
2186                 }
2187                 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2188                         printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n", 
2189                                nt_errstr(status), nt_errstr(account_types[i].nt_status));
2190                         ret = False;
2191                 }
2192                 
2193                 if (NT_STATUS_IS_OK(status)) {
2194                         q.in.user_handle = &user_handle;
2195                         q.in.level = 16;
2196                         
2197                         status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2198                         if (!NT_STATUS_IS_OK(status)) {
2199                                 printf("QueryUserInfo level %u failed - %s\n", 
2200                                        q.in.level, nt_errstr(status));
2201                                 ret = False;
2202                         } else {
2203                                 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2204                                         printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2205                                                q.out.info->info16.acct_flags, 
2206                                                acct_flags);
2207                                         ret = False;
2208                                 }
2209                         }
2210                 
2211                         if (!test_user_ops(p, user_ctx, &user_handle, domain_handle, 
2212                                            acct_flags, name.string, which_ops)) {
2213                                 ret = False;
2214                         }
2215
2216                         printf("Testing DeleteUser (createuser2 test)\n");
2217                 
2218                         d.in.user_handle = &user_handle;
2219                         d.out.user_handle = &user_handle;
2220                         
2221                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2222                         if (!NT_STATUS_IS_OK(status)) {
2223                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
2224                                 ret = False;
2225                         }
2226                 }
2227                 talloc_free(user_ctx);
2228         }
2229
2230         return ret;
2231 }
2232
2233 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2234                                 struct policy_handle *handle)
2235 {
2236         NTSTATUS status;
2237         struct samr_QueryAliasInfo r;
2238         uint16_t levels[] = {1, 2, 3};
2239         int i;
2240         BOOL ret = True;
2241
2242         for (i=0;i<ARRAY_SIZE(levels);i++) {
2243                 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2244
2245                 r.in.alias_handle = handle;
2246                 r.in.level = levels[i];
2247
2248                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2249                 if (!NT_STATUS_IS_OK(status)) {
2250                         printf("QueryAliasInfo level %u failed - %s\n", 
2251                                levels[i], nt_errstr(status));
2252                         ret = False;
2253                 }
2254         }
2255
2256         return ret;
2257 }
2258
2259 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2260                                 struct policy_handle *handle)
2261 {
2262         NTSTATUS status;
2263         struct samr_QueryGroupInfo r;
2264         uint16_t levels[] = {1, 2, 3, 4, 5};
2265         int i;
2266         BOOL ret = True;
2267
2268         for (i=0;i<ARRAY_SIZE(levels);i++) {
2269                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2270
2271                 r.in.group_handle = handle;
2272                 r.in.level = levels[i];
2273
2274                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2275                 if (!NT_STATUS_IS_OK(status)) {
2276                         printf("QueryGroupInfo level %u failed - %s\n", 
2277                                levels[i], nt_errstr(status));
2278                         ret = False;
2279                 }
2280         }
2281
2282         return ret;
2283 }
2284
2285 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2286                                   struct policy_handle *handle)
2287 {
2288         NTSTATUS status;
2289         struct samr_QueryGroupMember r;
2290         BOOL ret = True;
2291
2292         printf("Testing QueryGroupMember\n");
2293
2294         r.in.group_handle = handle;
2295
2296         status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2297         if (!NT_STATUS_IS_OK(status)) {
2298                 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2299                 ret = False;
2300         }
2301
2302         return ret;
2303 }
2304
2305
2306 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2307                               struct policy_handle *handle)
2308 {
2309         NTSTATUS status;
2310         struct samr_QueryGroupInfo r;
2311         struct samr_SetGroupInfo s;
2312         uint16_t levels[] = {1, 2, 3, 4};
2313         uint16_t set_ok[] = {0, 1, 1, 1};
2314         int i;
2315         BOOL ret = True;
2316
2317         for (i=0;i<ARRAY_SIZE(levels);i++) {
2318                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2319
2320                 r.in.group_handle = handle;
2321                 r.in.level = levels[i];
2322
2323                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2324                 if (!NT_STATUS_IS_OK(status)) {
2325                         printf("QueryGroupInfo level %u failed - %s\n", 
2326                                levels[i], nt_errstr(status));
2327                         ret = False;
2328                 }
2329
2330                 printf("Testing SetGroupInfo level %u\n", levels[i]);
2331
2332                 s.in.group_handle = handle;
2333                 s.in.level = levels[i];
2334                 s.in.info = r.out.info;
2335
2336 #if 0
2337                 /* disabled this, as it changes the name only from the point of view of samr, 
2338                    but leaves the name from the point of view of w2k3 internals (and ldap). This means
2339                    the name is still reserved, so creating the old name fails, but deleting by the old name
2340                    also fails */
2341                 if (s.in.level == 2) {
2342                         init_lsa_String(&s.in.info->string, "NewName");
2343                 }
2344 #endif
2345
2346                 if (s.in.level == 4) {
2347                         init_lsa_String(&s.in.info->description, "test description");
2348                 }
2349
2350                 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2351                 if (set_ok[i]) {
2352                         if (!NT_STATUS_IS_OK(status)) {
2353                                 printf("SetGroupInfo level %u failed - %s\n", 
2354                                        r.in.level, nt_errstr(status));
2355                                 ret = False;
2356                                 continue;
2357                         }
2358                 } else {
2359                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2360                                 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
2361                                        r.in.level, nt_errstr(status));
2362                                 ret = False;
2363                                 continue;
2364                         }
2365                 }
2366         }
2367
2368         return ret;
2369 }
2370
2371 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2372                                struct policy_handle *handle)
2373 {
2374         NTSTATUS status;
2375         struct samr_QueryUserInfo r;
2376         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2377                            11, 12, 13, 14, 16, 17, 20, 21};
2378         int i;
2379         BOOL ret = True;
2380
2381         for (i=0;i<ARRAY_SIZE(levels);i++) {
2382                 printf("Testing QueryUserInfo level %u\n", levels[i]);
2383
2384                 r.in.user_handle = handle;
2385                 r.in.level = levels[i];
2386
2387                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2388                 if (!NT_STATUS_IS_OK(status)) {
2389                         printf("QueryUserInfo level %u failed - %s\n", 
2390                                levels[i], nt_errstr(status));
2391                         ret = False;
2392                 }
2393         }
2394
2395         return ret;
2396 }
2397
2398 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2399                                 struct policy_handle *handle)
2400 {
2401         NTSTATUS status;
2402         struct samr_QueryUserInfo2 r;
2403         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2404                            11, 12, 13, 14, 16, 17, 20, 21};
2405         int i;
2406         BOOL ret = True;
2407
2408         for (i=0;i<ARRAY_SIZE(levels);i++) {
2409                 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2410
2411                 r.in.user_handle = handle;
2412                 r.in.level = levels[i];
2413
2414                 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2415                 if (!NT_STATUS_IS_OK(status)) {
2416                         printf("QueryUserInfo2 level %u failed - %s\n", 
2417                                levels[i], nt_errstr(status));
2418                         ret = False;
2419                 }
2420         }
2421
2422         return ret;
2423 }
2424
2425 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2426                           struct policy_handle *handle, uint32_t rid)
2427 {
2428         NTSTATUS status;
2429         struct samr_OpenUser r;
2430         struct policy_handle user_handle;
2431         BOOL ret = True;
2432
2433         printf("Testing OpenUser(%u)\n", rid);
2434
2435         r.in.domain_handle = handle;
2436         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2437         r.in.rid = rid;
2438         r.out.user_handle = &user_handle;
2439
2440         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2441         if (!NT_STATUS_IS_OK(status)) {
2442                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2443                 return False;
2444         }
2445
2446         if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2447                 ret = False;
2448         }
2449
2450         if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2451                 ret = False;
2452         }
2453
2454         if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2455                 ret = False;
2456         }
2457
2458         if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2459                 ret = False;
2460         }
2461
2462         if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2463                 ret = False;
2464         }
2465
2466         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2467                 ret = False;
2468         }
2469
2470         return ret;
2471 }
2472
2473 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2474                            struct policy_handle *handle, uint32_t rid)
2475 {
2476         NTSTATUS status;
2477         struct samr_OpenGroup r;
2478         struct policy_handle group_handle;
2479         BOOL ret = True;
2480
2481         printf("Testing OpenGroup(%u)\n", rid);
2482
2483         r.in.domain_handle = handle;
2484         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2485         r.in.rid = rid;
2486         r.out.group_handle = &group_handle;
2487
2488         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2489         if (!NT_STATUS_IS_OK(status)) {
2490                 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2491                 return False;
2492         }
2493
2494         if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2495                 ret = False;
2496         }
2497
2498         if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2499                 ret = False;
2500         }
2501
2502         if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2503                 ret = False;
2504         }
2505
2506         if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2507                 ret = False;
2508         }
2509
2510         return ret;
2511 }
2512
2513 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2514                            struct policy_handle *handle, uint32_t rid)
2515 {
2516         NTSTATUS status;
2517         struct samr_OpenAlias r;
2518         struct policy_handle alias_handle;
2519         BOOL ret = True;
2520
2521         printf("Testing OpenAlias(%u)\n", rid);
2522
2523         r.in.domain_handle = handle;
2524         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2525         r.in.rid = rid;
2526         r.out.alias_handle = &alias_handle;
2527
2528         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2529         if (!NT_STATUS_IS_OK(status)) {
2530                 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
2531                 return False;
2532         }
2533
2534         if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
2535                 ret = False;
2536         }
2537
2538         if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
2539                 ret = False;
2540         }
2541
2542         if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
2543                 ret = False;
2544         }
2545
2546         if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
2547                 ret = False;
2548         }
2549
2550         return ret;
2551 }
2552
2553 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2554                                  struct policy_handle *handle)
2555 {
2556         NTSTATUS status;
2557         struct samr_EnumDomainUsers r;
2558         uint32_t resume_handle=0;
2559         int i;
2560         BOOL ret = True;
2561         struct samr_LookupNames n;
2562         struct samr_LookupRids  lr ;
2563
2564         printf("Testing EnumDomainUsers\n");
2565
2566         r.in.domain_handle = handle;
2567         r.in.resume_handle = &resume_handle;
2568         r.in.acct_flags = 0;
2569         r.in.max_size = (uint32_t)-1;
2570         r.out.resume_handle = &resume_handle;
2571
2572         status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
2573         if (!NT_STATUS_IS_OK(status)) {
2574                 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
2575                 return False;
2576         }
2577         
2578         if (!r.out.sam) {
2579                 return False;
2580         }
2581
2582         if (r.out.sam->count == 0) {
2583                 return True;
2584         }
2585
2586         for (i=0;i<r.out.sam->count;i++) {
2587                 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2588                         ret = False;
2589                 }
2590         }
2591
2592         printf("Testing LookupNames\n");
2593         n.in.domain_handle = handle;
2594         n.in.num_names = r.out.sam->count;
2595         n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
2596         for (i=0;i<r.out.sam->count;i++) {
2597                 n.in.names[i].string = r.out.sam->entries[i].name.string;
2598         }
2599         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2600         if (!NT_STATUS_IS_OK(status)) {
2601                 printf("LookupNames failed - %s\n", nt_errstr(status));
2602                 ret = False;
2603         }
2604
2605
2606         printf("Testing LookupRids\n");
2607         lr.in.domain_handle = handle;
2608         lr.in.num_rids = r.out.sam->count;
2609         lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
2610         for (i=0;i<r.out.sam->count;i++) {
2611                 lr.in.rids[i] = r.out.sam->entries[i].idx;
2612         }
2613         status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
2614         if (!NT_STATUS_IS_OK(status)) {
2615                 printf("LookupRids failed - %s\n", nt_errstr(status));
2616                 ret = False;
2617         }
2618
2619         return ret;     
2620 }
2621
2622 /*
2623   try blasting the server with a bunch of sync requests
2624 */
2625 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2626                                        struct policy_handle *handle)
2627 {
2628         NTSTATUS status;
2629         struct samr_EnumDomainUsers r;
2630         uint32_t resume_handle=0;
2631         int i;
2632 #define ASYNC_COUNT 100
2633         struct rpc_request *req[ASYNC_COUNT];
2634
2635         if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
2636                 printf("samr async test disabled - enable dangerous tests to use\n");
2637                 return True;
2638         }
2639
2640         printf("Testing EnumDomainUsers_async\n");
2641
2642         r.in.domain_handle = handle;
2643         r.in.resume_handle = &resume_handle;
2644         r.in.acct_flags = 0;
2645         r.in.max_size = (uint32_t)-1;
2646         r.out.resume_handle = &resume_handle;
2647
2648         for (i=0;i<ASYNC_COUNT;i++) {
2649                 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
2650         }
2651
2652         for (i=0;i<ASYNC_COUNT;i++) {
2653                 status = dcerpc_ndr_request_recv(req[i]);
2654                 if (!NT_STATUS_IS_OK(status)) {
2655                         printf("EnumDomainUsers[%d] failed - %s\n", 
2656                                i, nt_errstr(status));
2657                         return False;
2658                 }
2659         }
2660         
2661         printf("%d async requests OK\n", i);
2662
2663         return True;
2664 }
2665
2666 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2667                                   struct policy_handle *handle)
2668 {
2669         NTSTATUS status;
2670         struct samr_EnumDomainGroups r;
2671         uint32_t resume_handle=0;
2672         int i;
2673         BOOL ret = True;
2674
2675         printf("Testing EnumDomainGroups\n");
2676
2677         r.in.domain_handle = handle;
2678         r.in.resume_handle = &resume_handle;
2679         r.in.max_size = (uint32_t)-1;
2680         r.out.resume_handle = &resume_handle;
2681
2682         status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2683         if (!NT_STATUS_IS_OK(status)) {
2684                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2685                 return False;
2686         }
2687         
2688         if (!r.out.sam) {
2689                 return False;
2690         }
2691
2692         for (i=0;i<r.out.sam->count;i++) {
2693                 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2694                         ret = False;
2695                 }
2696         }
2697
2698         return ret;
2699 }
2700
2701 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2702                                    struct policy_handle *handle)
2703 {
2704         NTSTATUS status;
2705         struct samr_EnumDomainAliases r;
2706         uint32_t resume_handle=0;
2707         int i;
2708         BOOL ret = True;
2709
2710         printf("Testing EnumDomainAliases\n");
2711
2712         r.in.domain_handle = handle;
2713         r.in.resume_handle = &resume_handle;
2714         r.in.acct_flags = (uint32_t)-1;
2715         r.out.resume_handle = &resume_handle;
2716
2717         status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
2718         if (!NT_STATUS_IS_OK(status)) {
2719                 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
2720                 return False;
2721         }
2722         
2723         if (!r.out.sam) {
2724                 return False;
2725         }
2726
2727         for (i=0;i<r.out.sam->count;i++) {
2728                 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2729                         ret = False;
2730                 }
2731         }
2732
2733         return ret;     
2734 }
2735
2736 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2737                                             struct policy_handle *handle)
2738 {
2739         NTSTATUS status;
2740         struct samr_GetDisplayEnumerationIndex r;
2741         BOOL ret = True;
2742         uint16_t levels[] = {1, 2, 3, 4, 5};
2743         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2744         int i;
2745
2746         for (i=0;i<ARRAY_SIZE(levels);i++) {
2747                 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
2748
2749                 r.in.domain_handle = handle;
2750                 r.in.level = levels[i];
2751                 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2752
2753                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2754
2755                 if (ok_lvl[i] && 
2756                     !NT_STATUS_IS_OK(status) &&
2757                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2758                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
2759                                levels[i], nt_errstr(status));
2760                         ret = False;
2761                 }
2762
2763                 init_lsa_String(&r.in.name, "zzzzzzzz");
2764
2765                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2766                 
2767                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2768                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
2769                                levels[i], nt_errstr(status));
2770                         ret = False;
2771                 }
2772         }
2773         
2774         return ret;     
2775 }
2776
2777 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2778                                              struct policy_handle *handle)
2779 {
2780         NTSTATUS status;
2781         struct samr_GetDisplayEnumerationIndex2 r;
2782         BOOL ret = True;
2783         uint16_t levels[] = {1, 2, 3, 4, 5};
2784         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2785         int i;
2786
2787         for (i=0;i<ARRAY_SIZE(levels);i++) {
2788                 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2789
2790                 r.in.domain_handle = handle;
2791                 r.in.level = levels[i];
2792                 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2793
2794                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2795                 if (ok_lvl[i] && 
2796                     !NT_STATUS_IS_OK(status) && 
2797                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2798                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
2799                                levels[i], nt_errstr(status));
2800                         ret = False;
2801                 }
2802
2803                 init_lsa_String(&r.in.name, "zzzzzzzz");
2804
2805                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2806                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2807                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
2808                                levels[i], nt_errstr(status));
2809                         ret = False;
2810                 }
2811         }
2812         
2813         return ret;     
2814 }
2815
2816 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2817                                   struct policy_handle *handle)
2818 {
2819         NTSTATUS status;
2820         struct samr_QueryDisplayInfo r;
2821         BOOL ret = True;
2822         uint16_t levels[] = {1, 2, 3, 4, 5};
2823         int i;
2824
2825         for (i=0;i<ARRAY_SIZE(levels);i++) {
2826                 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2827
2828                 r.in.domain_handle = handle;
2829                 r.in.level = levels[i];
2830                 r.in.start_idx = 0;
2831                 r.in.max_entries = 1000;
2832                 r.in.buf_size = (uint32_t)-1;
2833
2834                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2835                 if (!NT_STATUS_IS_OK(status)) {
2836                         printf("QueryDisplayInfo level %u failed - %s\n", 
2837                                levels[i], nt_errstr(status));
2838                         ret = False;
2839                 }
2840         }
2841         
2842         return ret;     
2843 }
2844
2845 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2846                                   struct policy_handle *handle)
2847 {
2848         NTSTATUS status;
2849         struct samr_QueryDisplayInfo2 r;
2850         BOOL ret = True;
2851         uint16_t levels[] = {1, 2, 3, 4, 5};
2852         int i;
2853
2854         for (i=0;i<ARRAY_SIZE(levels);i++) {
2855                 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2856
2857                 r.in.domain_handle = handle;
2858                 r.in.level = levels[i];
2859                 r.in.start_idx = 0;
2860                 r.in.max_entries = 1000;
2861                 r.in.buf_size = (uint32_t)-1;
2862
2863                 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2864                 if (!NT_STATUS_IS_OK(status)) {
2865                         printf("QueryDisplayInfo2 level %u failed - %s\n", 
2866                                levels[i], nt_errstr(status));
2867                         ret = False;
2868                 }
2869         }
2870         
2871         return ret;     
2872 }
2873
2874 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2875                                   struct policy_handle *handle)
2876 {
2877         NTSTATUS status;
2878         struct samr_QueryDisplayInfo3 r;
2879         BOOL ret = True;
2880         uint16_t levels[] = {1, 2, 3, 4, 5};
2881         int i;
2882
2883         for (i=0;i<ARRAY_SIZE(levels);i++) {
2884                 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2885
2886                 r.in.domain_handle = handle;
2887                 r.in.level = levels[i];
2888                 r.in.start_idx = 0;
2889                 r.in.max_entries = 1000;
2890                 r.in.buf_size = (uint32_t)-1;
2891
2892                 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2893                 if (!NT_STATUS_IS_OK(status)) {
2894                         printf("QueryDisplayInfo3 level %u failed - %s\n", 
2895                                levels[i], nt_errstr(status));
2896                         ret = False;
2897                 }
2898         }
2899         
2900         return ret;     
2901 }
2902
2903
2904 static BOOL test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2905                                            struct policy_handle *handle)
2906 {
2907         NTSTATUS status;
2908         struct samr_QueryDisplayInfo r;
2909         BOOL ret = True;
2910
2911         printf("Testing QueryDisplayInfo continuation\n");
2912
2913         r.in.domain_handle = handle;
2914         r.in.level = 1;
2915         r.in.start_idx = 0;
2916         r.in.max_entries = 1;
2917         r.in.buf_size = (uint32_t)-1;
2918
2919         do {
2920                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2921                 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
2922                         if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
2923                                 printf("expected idx %d but got %d\n",
2924                                        r.in.start_idx + 1,
2925                                        r.out.info.info1.entries[0].idx);
2926                                 break;
2927                         }
2928                 }
2929                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
2930                     !NT_STATUS_IS_OK(status)) {
2931                         printf("QueryDisplayInfo level %u failed - %s\n", 
2932                                r.in.level, nt_errstr(status));
2933                         ret = False;
2934                         break;
2935                 }
2936                 r.in.start_idx++;
2937         } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
2938                   NT_STATUS_IS_OK(status)) &&
2939                  r.out.returned_size != 0);
2940         
2941         return ret;     
2942 }
2943
2944 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2945                                  struct policy_handle *handle)
2946 {
2947         NTSTATUS status;
2948         struct samr_QueryDomainInfo r;
2949         struct samr_SetDomainInfo s;
2950         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2951         uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
2952         int i;
2953         BOOL ret = True;
2954         const char *domain_comment = talloc_asprintf(mem_ctx, 
2955                                   "Tortured by Samba4 RPC-SAMR: %s", 
2956                                   timestring(mem_ctx, time(NULL)));
2957
2958         s.in.domain_handle = handle;
2959         s.in.level = 4;
2960         s.in.info = talloc(mem_ctx, union samr_DomainInfo);
2961         
2962         s.in.info->info4.comment.string = domain_comment;
2963         status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2964         if (!NT_STATUS_IS_OK(status)) {
2965                 printf("SetDomainInfo level %u (set comment) failed - %s\n", 
2966                        r.in.level, nt_errstr(status));
2967                 return False;
2968         }
2969
2970         for (i=0;i<ARRAY_SIZE(levels);i++) {
2971                 printf("Testing QueryDomainInfo level %u\n", levels[i]);
2972
2973                 r.in.domain_handle = handle;
2974                 r.in.level = levels[i];
2975
2976                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2977                 if (!NT_STATUS_IS_OK(status)) {
2978                         printf("QueryDomainInfo level %u failed - %s\n", 
2979                                r.in.level, nt_errstr(status));
2980                         ret = False;
2981                         continue;
2982                 }
2983
2984                 switch (levels[i]) {
2985                 case 2:
2986                         if (strcmp(r.out.info->info2.comment.string, domain_comment) != 0) {
2987                                 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
2988                                        levels[i], r.out.info->info2.comment.string, domain_comment);
2989                                 ret = False;
2990                         }
2991                         break;
2992                 case 4:
2993                         if (strcmp(r.out.info->info4.comment.string, domain_comment) != 0) {
2994                                 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
2995                                        levels[i], r.out.info->info4.comment.string, domain_comment);
2996                                 ret = False;
2997                         }
2998                         break;
2999                 case 11:
3000                         if (strcmp(r.out.info->info11.info2.comment.string, domain_comment) != 0) {
3001                                 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3002                                        levels[i], r.out.info->info11.info2.comment.string, domain_comment);
3003                                 ret = False;
3004                         }
3005                         break;
3006                 }
3007
3008                 printf("Testing SetDomainInfo level %u\n", levels[i]);
3009
3010                 s.in.domain_handle = handle;
3011                 s.in.level = levels[i];
3012                 s.in.info = r.out.info;
3013
3014                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3015                 if (set_ok[i]) {
3016                         if (!NT_STATUS_IS_OK(status)) {
3017                                 printf("SetDomainInfo level %u failed - %s\n", 
3018                                        r.in.level, nt_errstr(status));
3019                                 ret = False;
3020                                 continue;
3021                         }
3022                 } else {
3023                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3024                                 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
3025                                        r.in.level, nt_errstr(status));
3026                                 ret = False;
3027                                 continue;
3028                         }
3029                 }
3030
3031                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3032                 if (!NT_STATUS_IS_OK(status)) {
3033                         printf("QueryDomainInfo level %u failed - %s\n", 
3034                                r.in.level, nt_errstr(status));
3035                         ret = False;
3036                         continue;
3037                 }
3038         }
3039
3040         return ret;     
3041 }
3042
3043
3044 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3045                                   struct policy_handle *handle)
3046 {
3047         NTSTATUS status;
3048         struct samr_QueryDomainInfo2 r;
3049         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3050         int i;
3051         BOOL ret = True;
3052
3053         for (i=0;i<ARRAY_SIZE(levels);i++) {
3054                 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
3055
3056                 r.in.domain_handle = handle;
3057                 r.in.level = levels[i];
3058
3059                 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
3060                 if (!NT_STATUS_IS_OK(status)) {
3061                         printf("QueryDomainInfo2 level %u failed - %s\n", 
3062                                r.in.level, nt_errstr(status));
3063                         ret = False;
3064                         continue;
3065                 }
3066         }
3067
3068         return True;    
3069 }
3070
3071 /* Test whether querydispinfo level 5 and enumdomgroups return the same
3072    set of group names. */
3073 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3074                            struct policy_handle *handle)
3075 {
3076         struct samr_EnumDomainGroups q1;
3077         struct samr_QueryDisplayInfo q2;
3078         NTSTATUS status;
3079         uint32_t resume_handle=0;
3080         int i;
3081         BOOL ret = True;
3082
3083         int num_names = 0;
3084         const char **names = NULL;
3085
3086         printf("Testing coherency of querydispinfo vs enumdomgroups\n");
3087
3088         q1.in.domain_handle = handle;
3089         q1.in.resume_handle = &resume_handle;
3090         q1.in.max_size = 5;
3091         q1.out.resume_handle = &resume_handle;
3092
3093         status = STATUS_MORE_ENTRIES;
3094         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3095                 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
3096
3097                 if (!NT_STATUS_IS_OK(status) &&
3098                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3099                         break;
3100
3101                 for (i=0; i<q1.out.num_entries; i++) {
3102                         add_string_to_array(mem_ctx,
3103                                             q1.out.sam->entries[i].name.string,
3104                                             &names, &num_names);
3105                 }
3106         }
3107
3108         if (!NT_STATUS_IS_OK(status)) {
3109                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3110                 return False;
3111         }
3112         
3113         if (!q1.out.sam) {
3114                 return False;
3115         }
3116
3117         q2.in.domain_handle = handle;
3118         q2.in.level = 5;
3119         q2.in.start_idx = 0;
3120         q2.in.max_entries = 5;
3121         q2.in.buf_size = (uint32_t)-1;
3122
3123         status = STATUS_MORE_ENTRIES;
3124         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3125                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
3126
3127                 if (!NT_STATUS_IS_OK(status) &&
3128                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3129                         break;
3130
3131                 for (i=0; i<q2.out.info.info5.count; i++) {
3132                         int j;
3133                         const char *name = q2.out.info.info5.entries[i].account_name.string;
3134                         BOOL found = False;
3135                         for (j=0; j<num_names; j++) {
3136                                 if (names[j] == NULL)
3137                                         continue;
3138                                 /* Hmm. No strequal in samba4 */
3139                                 if (strequal(names[j], name)) {
3140                                         names[j] = NULL;
3141                                         found = True;
3142                                         break;
3143                                 }
3144                         }
3145
3146                         if (!found) {
3147                                 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
3148                                        name);
3149                                 ret = False;
3150                         }
3151                 }
3152                 q2.in.start_idx += q2.out.info.info5.count;
3153         }
3154
3155         if (!NT_STATUS_IS_OK(status)) {
3156                 printf("QueryDisplayInfo level 5 failed - %s\n",
3157                        nt_errstr(status));
3158                 ret = False;
3159         }
3160
3161         for (i=0; i<num_names; i++) {
3162                 if (names[i] != NULL) {
3163                         printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
3164                                names[i]);
3165                         ret = False;
3166                 }
3167         }
3168
3169         return ret;
3170 }
3171
3172 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3173                                    struct policy_handle *group_handle)
3174 {
3175         struct samr_DeleteDomainGroup d;
3176         NTSTATUS status;
3177         BOOL ret = True;
3178
3179         printf("Testing DeleteDomainGroup\n");
3180
3181         d.in.group_handle = group_handle;
3182         d.out.group_handle = group_handle;
3183
3184         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3185         if (!NT_STATUS_IS_OK(status)) {
3186                 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
3187                 ret = False;
3188         }
3189
3190         return ret;
3191 }
3192
3193 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3194                                             struct policy_handle *domain_handle)
3195 {
3196         struct samr_TestPrivateFunctionsDomain r;
3197         NTSTATUS status;
3198         BOOL ret = True;
3199
3200         printf("Testing TestPrivateFunctionsDomain\n");
3201
3202         r.in.domain_handle = domain_handle;
3203
3204         status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
3205         if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
3206                 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
3207                 ret = False;
3208         }
3209
3210         return ret;
3211 }
3212
3213 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3214                           struct dom_sid *domain_sid,
3215                           struct policy_handle *domain_handle)
3216 {
3217         struct samr_RidToSid r;
3218         NTSTATUS status;
3219         BOOL ret = True;
3220         struct dom_sid *calc_sid;
3221         int rids[] = { 0, 42, 512, 10200 };
3222         int i;
3223
3224         for (i=0;i<ARRAY_SIZE(rids);i++) {
3225         
3226                 printf("Testing RidToSid\n");
3227                 
3228                 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
3229                 r.in.domain_handle = domain_handle;
3230                 r.in.rid = rids[i];
3231                 
3232                 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
3233                 if (!NT_STATUS_IS_OK(status)) {
3234                         printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
3235                         ret = False;
3236                 } else {
3237                         calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
3238
3239                         if (!dom_sid_equal(calc_sid, r.out.sid)) {
3240                                 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i], 
3241                                        dom_sid_string(mem_ctx, r.out.sid), 
3242                                        dom_sid_string(mem_ctx, calc_sid));
3243                                 ret = False;
3244                         }
3245                 }
3246         }
3247
3248         return ret;
3249 }
3250
3251 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3252                                        struct policy_handle *domain_handle)
3253 {
3254         struct samr_GetBootKeyInformation r;
3255         NTSTATUS status;
3256         BOOL ret = True;
3257
3258         printf("Testing GetBootKeyInformation\n");
3259
3260         r.in.domain_handle = domain_handle;
3261
3262         status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
3263         if (!NT_STATUS_IS_OK(status)) {
3264                 /* w2k3 seems to fail this sometimes and pass it sometimes */
3265                 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
3266         }
3267
3268         return ret;
3269 }
3270
3271 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3272                                 struct policy_handle *domain_handle,
3273                                 struct policy_handle *group_handle)
3274 {
3275         NTSTATUS status;
3276         struct samr_AddGroupMember r;
3277         struct samr_DeleteGroupMember d;
3278         struct samr_QueryGroupMember q;
3279         struct samr_SetMemberAttributesOfGroup s;
3280         BOOL ret = True;
3281         uint32_t rid;
3282
3283         status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
3284         if (!NT_STATUS_IS_OK(status)) {
3285                 printf("test_AddGroupMember looking up name " TEST_ACCOUNT_NAME " failed - %s\n", nt_errstr(status));
3286                 return False;
3287         }
3288
3289         r.in.group_handle = group_handle;
3290         r.in.rid = rid;
3291         r.in.flags = 0; /* ??? */
3292
3293         printf("Testing AddGroupMember and DeleteGroupMember\n");
3294
3295         d.in.group_handle = group_handle;
3296         d.in.rid = rid;
3297
3298         status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
3299         if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
3300                 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n", 
3301                        nt_errstr(status));
3302                 return False;
3303         }
3304
3305         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3306         if (!NT_STATUS_IS_OK(status)) {
3307                 printf("AddGroupMember failed - %s\n", nt_errstr(status));
3308                 return False;
3309         }
3310
3311         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3312         if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
3313                 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n", 
3314                        nt_errstr(status));
3315                 return False;
3316         }
3317
3318         if (lp_parm_bool(-1, "torture", "samba4", False)) {
3319                 printf("skipping SetMemberAttributesOfGroup test against Samba4\n");
3320         } else {
3321                 /* this one is quite strange. I am using random inputs in the
3322                    hope of triggering an error that might give us a clue */
3323
3324                 s.in.group_handle = group_handle;
3325                 s.in.unknown1 = random();
3326                 s.in.unknown2 = random();
3327
3328                 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
3329                 if (!NT_STATUS_IS_OK(status)) {
3330                         printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
3331                         return False;
3332                 }
3333         }
3334
3335         q.in.group_handle = group_handle;
3336
3337         status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
3338         if (!NT_STATUS_IS_OK(status)) {
3339                 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
3340                 return False;
3341         }
3342
3343         status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
3344         if (!NT_STATUS_IS_OK(status)) {
3345                 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
3346                 return False;
3347         }
3348
3349         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3350         if (!NT_STATUS_IS_OK(status)) {
3351                 printf("AddGroupMember failed - %s\n", nt_errstr(status));
3352                 return False;
3353         }
3354
3355         return ret;
3356 }
3357
3358
3359 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3360                                    struct policy_handle *domain_handle, struct policy_handle *group_handle)
3361 {
3362         NTSTATUS status;
3363         struct samr_CreateDomainGroup r;
3364         uint32_t rid;
3365         struct lsa_String name;
3366         BOOL ret = True;
3367
3368         init_lsa_String(&name, TEST_GROUPNAME);
3369
3370         r.in.domain_handle = domain_handle;
3371         r.in.name = &name;
3372         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3373         r.out.group_handle = group_handle;
3374         r.out.rid = &rid;
3375
3376         printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
3377
3378         status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3379
3380         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3381                 printf("Server refused create of '%s'\n", r.in.name->string);
3382                 ZERO_STRUCTP(group_handle);
3383                 return True;
3384         }
3385
3386         if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
3387                 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
3388                         
3389                         printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string, 
3390                                nt_errstr(status));
3391                         return False;
3392                 }
3393                 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3394         }
3395         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3396                 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
3397                         
3398                         printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string, 
3399                                nt_errstr(status));
3400                         return False;
3401                 }
3402                 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3403         }
3404         if (!NT_STATUS_IS_OK(status)) {
3405                 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
3406                 return False;
3407         }
3408
3409         if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
3410                 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
3411                 ret = False;
3412         }
3413
3414         if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
3415                 ret = False;
3416         }
3417
3418         return ret;
3419 }
3420
3421
3422 /*
3423   its not totally clear what this does. It seems to accept any sid you like.
3424 */
3425 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p, 
3426                                                TALLOC_CTX *mem_ctx, 
3427                                                struct policy_handle *domain_handle)
3428 {
3429         NTSTATUS status;
3430         struct samr_RemoveMemberFromForeignDomain r;
3431
3432         r.in.domain_handle = domain_handle;
3433         r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
3434
3435         status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
3436         if (!NT_STATUS_IS_OK(status)) {
3437                 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
3438                 return False;
3439         }
3440
3441         return True;
3442 }
3443
3444
3445
3446 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3447                          struct policy_handle *handle);
3448
3449 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3450                             struct policy_handle *handle, struct dom_sid *sid,
3451                             enum torture_samr_choice which_ops)
3452 {
3453         NTSTATUS status;
3454         struct samr_OpenDomain r;
3455         struct policy_handle domain_handle;
3456         struct policy_handle alias_handle;
3457         struct policy_handle user_handle;
3458         struct policy_handle group_handle;
3459         BOOL ret = True;
3460
3461         ZERO_STRUCT(alias_handle);
3462         ZERO_STRUCT(user_handle);
3463         ZERO_STRUCT(group_handle);
3464         ZERO_STRUCT(domain_handle);
3465
3466         printf("Testing OpenDomain\n");
3467
3468         r.in.connect_handle = handle;
3469         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3470         r.in.sid = sid;
3471         r.out.domain_handle = &domain_handle;
3472
3473         status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
3474         if (!NT_STATUS_IS_OK(status)) {
3475                 printf("OpenDomain failed - %s\n", nt_errstr(status));
3476                 return False;
3477         }
3478
3479         /* run the domain tests with the main handle closed - this tests
3480            the servers reference counting */
3481         ret &= test_samr_handle_Close(p, mem_ctx, handle);
3482
3483         switch (which_ops) {
3484         case TORTURE_SAMR_USER_ATTRIBUTES:
3485         case TORTURE_SAMR_PASSWORDS:
3486                 ret &= test_CreateUser(p, mem_ctx, &domain_handle, NULL, which_ops);
3487                 ret &= test_CreateUser2(p, mem_ctx, &domain_handle, which_ops);
3488                 break;
3489         case TORTURE_SAMR_OTHER:
3490                 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle, which_ops);
3491                 ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
3492                 ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
3493                 ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
3494                 ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
3495                 ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
3496                 ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
3497                 ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
3498                 ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
3499                 ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
3500                 ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
3501                 ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
3502                 ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
3503                 ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
3504                 ret &= test_QueryDisplayInfo_continue(p, mem_ctx, &domain_handle);
3505                 
3506                 if (lp_parm_bool(-1, "torture", "samba4", False)) {
3507                         printf("skipping GetDisplayEnumerationIndex test against Samba4\n");
3508                 } else {
3509                         ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
3510                         ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
3511                 }
3512                 ret &= test_GroupList(p, mem_ctx, &domain_handle);
3513                 ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
3514                 ret &= test_RidToSid(p, mem_ctx, sid, &domain_handle);
3515                 ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
3516                 break;
3517         }
3518
3519         if (!policy_handle_empty(&user_handle) &&
3520             !test_DeleteUser(p, mem_ctx, &user_handle)) {
3521                 ret = False;
3522         }
3523
3524         if (!policy_handle_empty(&alias_handle) &&
3525             !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
3526                 ret = False;
3527         }
3528
3529         if (!policy_handle_empty(&group_handle) &&
3530             !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
3531                 ret = False;
3532         }
3533
3534         ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
3535
3536         /* reconnect the main handle */
3537         ret &= test_Connect(p, mem_ctx, handle);
3538
3539         if (!ret) {
3540                 printf("Testing domain %s failed!\n", dom_sid_string(mem_ctx, sid));
3541         }
3542
3543         return ret;
3544 }
3545
3546 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3547                               struct policy_handle *handle, const char *domain,
3548                               enum torture_samr_choice which_ops)
3549 {
3550         NTSTATUS status;
3551         struct samr_LookupDomain r;
3552         struct lsa_String n1;
3553         struct lsa_String n2;
3554         BOOL ret = True;
3555
3556         printf("Testing LookupDomain(%s)\n", domain);
3557
3558         /* check for correct error codes */
3559         r.in.connect_handle = handle;
3560         r.in.domain_name = &n2;
3561         n2.string = NULL;
3562
3563         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3564         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
3565                 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
3566                 ret = False;
3567         }
3568
3569         init_lsa_String(&n2, "xxNODOMAINxx");
3570
3571         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3572         if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
3573                 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
3574                 ret = False;
3575         }
3576
3577         r.in.connect_handle = handle;
3578
3579         init_lsa_String(&n1, domain);
3580         r.in.domain_name = &n1;
3581
3582         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3583         if (!NT_STATUS_IS_OK(status)) {
3584                 printf("LookupDomain failed - %s\n", nt_errstr(status));
3585                 ret = False;
3586         }
3587
3588         if (!test_GetDomPwInfo(p, mem_ctx, &n1)) {
3589                 ret = False;
3590         }
3591
3592         if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid, which_ops)) {
3593                 ret = False;
3594         }
3595
3596         return ret;
3597 }
3598
3599
3600 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3601                              struct policy_handle *handle, enum torture_samr_choice which_ops)
3602 {
3603         NTSTATUS status;
3604         struct samr_EnumDomains r;
3605         uint32_t resume_handle = 0;
3606         int i;
3607         BOOL ret = True;
3608
3609         r.in.connect_handle = handle;
3610         r.in.resume_handle = &resume_handle;
3611         r.in.buf_size = (uint32_t)-1;
3612         r.out.resume_handle = &resume_handle;
3613
3614         status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3615         if (!NT_STATUS_IS_OK(status)) {
3616                 printf("EnumDomains failed - %s\n", nt_errstr(status));
3617                 return False;
3618         }
3619
3620         if (!r.out.sam) {
3621                 return False;
3622         }
3623
3624         for (i=0;i<r.out.sam->count;i++) {
3625                 if (!test_LookupDomain(p, mem_ctx, handle, 
3626                                        r.out.sam->entries[i].name.string, which_ops)) {
3627                         ret = False;
3628                 }
3629         }
3630
3631         status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3632         if (!NT_STATUS_IS_OK(status)) {
3633                 printf("EnumDomains failed - %s\n", nt_errstr(status));
3634                 return False;
3635         }
3636
3637         return ret;
3638 }
3639
3640
3641 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3642                          struct policy_handle *handle)
3643 {
3644         NTSTATUS status;
3645         struct samr_Connect r;
3646         struct samr_Connect2 r2;
3647         struct samr_Connect3 r3;
3648         struct samr_Connect4 r4;
3649         struct samr_Connect5 r5;
3650         union samr_ConnectInfo info;
3651         struct policy_handle h;
3652         BOOL ret = True, got_handle = False;
3653
3654         printf("testing samr_Connect\n");
3655
3656         r.in.system_name = 0;
3657         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3658         r.out.connect_handle = &h;
3659
3660         status = dcerpc_samr_Connect(p, mem_ctx, &r);
3661         if (!NT_STATUS_IS_OK(status)) {
3662                 printf("Connect failed - %s\n", nt_errstr(status));
3663                 ret = False;
3664         } else {
3665                 got_handle = True;
3666                 *handle = h;
3667         }
3668
3669         printf("testing samr_Connect2\n");
3670
3671         r2.in.system_name = NULL;
3672         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3673         r2.out.connect_handle = &h;
3674
3675         status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
3676         if (!NT_STATUS_IS_OK(status)) {
3677                 printf("Connect2 failed - %s\n", nt_errstr(status));
3678                 ret = False;
3679         } else {
3680                 if (got_handle) {
3681                         test_samr_handle_Close(p, mem_ctx, handle);
3682                 }
3683                 got_handle = True;
3684                 *handle = h;
3685         }
3686
3687         printf("testing samr_Connect3\n");
3688
3689         r3.in.system_name = NULL;
3690         r3.in.unknown = 0;
3691         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3692         r3.out.connect_handle = &h;
3693
3694         status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
3695         if (!NT_STATUS_IS_OK(status)) {
3696                 printf("Connect3 failed - %s\n", nt_errstr(status));
3697                 ret = False;
3698         } else {
3699                 if (got_handle) {
3700                         test_samr_handle_Close(p, mem_ctx, handle);
3701                 }
3702                 got_handle = True;
3703                 *handle = h;
3704         }
3705
3706         printf("testing samr_Connect4\n");
3707
3708         r4.in.system_name = "";
3709         r4.in.unknown = 0;
3710         r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3711         r4.out.connect_handle = &h;
3712
3713         status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
3714         if (!NT_STATUS_IS_OK(status)) {
3715                 printf("Connect4 failed - %s\n", nt_errstr(status));
3716                 ret = False;
3717         } else {
3718                 if (got_handle) {
3719                         test_samr_handle_Close(p, mem_ctx, handle);
3720                 }
3721                 got_handle = True;
3722                 *handle = h;
3723         }
3724
3725         printf("testing samr_Connect5\n");
3726
3727         info.info1.unknown1 = 0;
3728         info.info1.unknown2 = 0;
3729
3730         r5.in.system_name = "";
3731         r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3732         r5.in.level = 1;
3733         r5.in.info = &info;
3734         r5.out.info = &info;
3735         r5.out.connect_handle = &h;
3736
3737         status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
3738         if (!NT_STATUS_IS_OK(status)) {
3739                 printf("Connect5 failed - %s\n", nt_errstr(status));
3740                 ret = False;
3741         } else {
3742                 if (got_handle) {
3743                         test_samr_handle_Close(p, mem_ctx, handle);
3744                 }
3745                 got_handle = True;
3746                 *handle = h;
3747         }
3748
3749         return ret;
3750 }
3751
3752
3753 BOOL torture_rpc_samr(struct torture_context *torture)
3754 {
3755         NTSTATUS status;
3756         struct dcerpc_pipe *p;
3757         BOOL ret = True;
3758         struct policy_handle handle;
3759
3760         status = torture_rpc_connection(torture, &p, &dcerpc_table_samr);
3761         if (!NT_STATUS_IS_OK(status)) {
3762                 return False;
3763         }
3764
3765         ret &= test_Connect(p, torture, &handle);
3766
3767         ret &= test_QuerySecurity(p, torture, &handle);
3768
3769         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
3770
3771         ret &= test_SetDsrmPassword(p, torture, &handle);
3772
3773         ret &= test_Shutdown(p, torture, &handle);
3774
3775         ret &= test_samr_handle_Close(p, torture, &handle);
3776
3777         return ret;
3778 }
3779
3780
3781 BOOL torture_rpc_samr_users(struct torture_context *torture)
3782 {
3783         NTSTATUS status;
3784         struct dcerpc_pipe *p;
3785         BOOL ret = True;
3786         struct policy_handle handle;
3787
3788         status = torture_rpc_connection(torture, &p, &dcerpc_table_samr);
3789         if (!NT_STATUS_IS_OK(status)) {
3790                 return False;
3791         }
3792
3793         ret &= test_Connect(p, torture, &handle);
3794
3795         ret &= test_QuerySecurity(p, torture, &handle);
3796
3797         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
3798
3799         ret &= test_SetDsrmPassword(p, torture, &handle);
3800
3801         ret &= test_Shutdown(p, torture, &handle);
3802
3803         ret &= test_samr_handle_Close(p, torture, &handle);
3804
3805         return ret;
3806 }
3807
3808
3809 BOOL torture_rpc_samr_passwords(struct torture_context *torture)
3810 {
3811         NTSTATUS status;
3812         struct dcerpc_pipe *p;
3813         BOOL ret = True;
3814         struct policy_handle handle;
3815
3816         status = torture_rpc_connection(torture, &p, &dcerpc_table_samr);
3817         if (!NT_STATUS_IS_OK(status)) {
3818                 return False;
3819         }
3820
3821         ret &= test_Connect(p, torture, &handle);
3822
3823         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
3824
3825         ret &= test_samr_handle_Close(p, torture, &handle);
3826
3827         return ret;
3828 }
3829