s4-smbtorture: add samr_rand_pass_silent.
[kai/samba.git] / source4 / torture / rpc / samr.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for samr rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "torture/torture.h"
24 #include "system/time.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_samr_c.h"
27 #include "../lib/crypto/crypto.h"
28 #include "libcli/auth/libcli_auth.h"
29 #include "libcli/security/security.h"
30 #include "torture/rpc/rpc.h"
31
32 #define TEST_ACCOUNT_NAME "samrtorturetest"
33 #define TEST_ALIASNAME "samrtorturetestalias"
34 #define TEST_GROUPNAME "samrtorturetestgroup"
35 #define TEST_MACHINENAME "samrtestmach$"
36 #define TEST_DOMAINNAME "samrtestdom$"
37
38 enum torture_samr_choice {
39         TORTURE_SAMR_PASSWORDS,
40         TORTURE_SAMR_USER_ATTRIBUTES,
41         TORTURE_SAMR_OTHER
42 };
43
44 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
45                                struct policy_handle *handle);
46
47 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
48                                 struct policy_handle *handle);
49
50 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
51                                struct policy_handle *handle);
52
53 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
54                                 const char *acct_name, 
55                                 struct policy_handle *domain_handle, char **password);
56
57 static void init_lsa_String(struct lsa_String *string, const char *s)
58 {
59         string->string = s;
60 }
61
62 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
63 {
64         string->length = length;
65         string->size = length;
66         string->array = (uint16_t *)discard_const(s);
67 }
68
69 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
70                                    struct policy_handle *handle)
71 {
72         NTSTATUS status;
73         struct samr_Close r;
74
75         r.in.handle = handle;
76         r.out.handle = handle;
77
78         status = dcerpc_samr_Close(p, tctx, &r);
79         torture_assert_ntstatus_ok(tctx, status, "Close");
80
81         return true;
82 }
83
84 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
85                        struct policy_handle *handle)
86 {
87         NTSTATUS status;
88         struct samr_Shutdown r;
89
90         if (!torture_setting_bool(tctx, "dangerous", false)) {
91                 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
92                 return true;
93         }
94
95         r.in.connect_handle = handle;
96
97         torture_comment(tctx, "testing samr_Shutdown\n");
98
99         status = dcerpc_samr_Shutdown(p, tctx, &r);
100         torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
101
102         return true;
103 }
104
105 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
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 (!torture_setting_bool(tctx, "dangerous", false)) {
114                 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
115         }
116
117         E_md4hash("TeSTDSRM123", hash.hash);
118
119         init_lsa_String(&string, "Administrator");
120
121         r.in.name = &string;
122         r.in.unknown = 0;
123         r.in.hash = &hash;
124
125         torture_comment(tctx, "testing samr_SetDsrmPassword\n");
126
127         status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
128         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
129
130         return true;
131 }
132
133
134 static bool test_QuerySecurity(struct dcerpc_pipe *p, 
135                                struct torture_context *tctx, 
136                                struct policy_handle *handle)
137 {
138         NTSTATUS status;
139         struct samr_QuerySecurity r;
140         struct samr_SetSecurity s;
141         struct sec_desc_buf *sdbuf = NULL;
142
143         r.in.handle = handle;
144         r.in.sec_info = 7;
145         r.out.sdbuf = &sdbuf;
146
147         status = dcerpc_samr_QuerySecurity(p, tctx, &r);
148         torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
149
150         torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
151
152         s.in.handle = handle;
153         s.in.sec_info = 7;
154         s.in.sdbuf = sdbuf;
155
156         if (torture_setting_bool(tctx, "samba4", false)) {
157                 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
158         }
159
160         status = dcerpc_samr_SetSecurity(p, tctx, &s);
161         torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
162
163         status = dcerpc_samr_QuerySecurity(p, tctx, &r);
164         torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
165
166         return true;
167 }
168
169
170 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx, 
171                              struct policy_handle *handle, uint32_t base_acct_flags,
172                              const char *base_account_name)
173 {
174         NTSTATUS status;
175         struct samr_SetUserInfo s;
176         struct samr_SetUserInfo2 s2;
177         struct samr_QueryUserInfo q;
178         struct samr_QueryUserInfo q0;
179         union samr_UserInfo u;
180         union samr_UserInfo *info;
181         bool ret = true;
182         const char *test_account_name;
183
184         uint32_t user_extra_flags = 0;
185         if (base_acct_flags == ACB_NORMAL) {
186                 /* When created, accounts are expired by default */
187                 user_extra_flags = ACB_PW_EXPIRED;
188         }
189
190         s.in.user_handle = handle;
191         s.in.info = &u;
192
193         s2.in.user_handle = handle;
194         s2.in.info = &u;
195
196         q.in.user_handle = handle;
197         q.out.info = &info;
198         q0 = q;
199
200 #define TESTCALL(call, r) \
201                 status = dcerpc_samr_ ##call(p, tctx, &r); \
202                 if (!NT_STATUS_IS_OK(status)) { \
203                         torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
204                                r.in.level, nt_errstr(status), __location__); \
205                         ret = false; \
206                         break; \
207                 }
208
209 #define STRING_EQUAL(s1, s2, field) \
210                 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
211                         torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
212                                #field, s2, __location__); \
213                         ret = false; \
214                         break; \
215                 }
216
217 #define MEM_EQUAL(s1, s2, length, field) \
218                 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
219                         torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
220                                #field, (const char *)s2, __location__); \
221                         ret = false; \
222                         break; \
223                 }
224
225 #define INT_EQUAL(i1, i2, field) \
226                 if (i1 != i2) { \
227                         torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
228                                #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
229                         ret = false; \
230                         break; \
231                 }
232
233 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
234                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
235                 q.in.level = lvl1; \
236                 TESTCALL(QueryUserInfo, q) \
237                 s.in.level = lvl1; \
238                 s2.in.level = lvl1; \
239                 u = *info; \
240                 if (lvl1 == 21) { \
241                         ZERO_STRUCT(u.info21); \
242                         u.info21.fields_present = fpval; \
243                 } \
244                 init_lsa_String(&u.info ## lvl1.field1, value); \
245                 TESTCALL(SetUserInfo, s) \
246                 TESTCALL(SetUserInfo2, s2) \
247                 init_lsa_String(&u.info ## lvl1.field1, ""); \
248                 TESTCALL(QueryUserInfo, q); \
249                 u = *info; \
250                 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
251                 q.in.level = lvl2; \
252                 TESTCALL(QueryUserInfo, q) \
253                 u = *info; \
254                 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
255         } while (0)
256
257 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
258                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
259                 q.in.level = lvl1; \
260                 TESTCALL(QueryUserInfo, q) \
261                 s.in.level = lvl1; \
262                 s2.in.level = lvl1; \
263                 u = *info; \
264                 if (lvl1 == 21) { \
265                         ZERO_STRUCT(u.info21); \
266                         u.info21.fields_present = fpval; \
267                 } \
268                 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
269                 TESTCALL(SetUserInfo, s) \
270                 TESTCALL(SetUserInfo2, s2) \
271                 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
272                 TESTCALL(QueryUserInfo, q); \
273                 u = *info; \
274                 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
275                 q.in.level = lvl2; \
276                 TESTCALL(QueryUserInfo, q) \
277                 u = *info; \
278                 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
279         } while (0)
280
281 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
282                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
283                 q.in.level = lvl1; \
284                 TESTCALL(QueryUserInfo, q) \
285                 s.in.level = lvl1; \
286                 s2.in.level = lvl1; \
287                 u = *info; \
288                 if (lvl1 == 21) { \
289                         uint8_t *bits = u.info21.logon_hours.bits; \
290                         ZERO_STRUCT(u.info21); \
291                         if (fpval == SAMR_FIELD_LOGON_HOURS) { \
292                                 u.info21.logon_hours.units_per_week = 168; \
293                                 u.info21.logon_hours.bits = bits; \
294                         } \
295                         u.info21.fields_present = fpval; \
296                 } \
297                 u.info ## lvl1.field1 = value; \
298                 TESTCALL(SetUserInfo, s) \
299                 TESTCALL(SetUserInfo2, s2) \
300                 u.info ## lvl1.field1 = 0; \
301                 TESTCALL(QueryUserInfo, q); \
302                 u = *info; \
303                 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
304                 q.in.level = lvl2; \
305                 TESTCALL(QueryUserInfo, q) \
306                 u = *info; \
307                 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
308         } while (0)
309
310 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
311         TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
312         } while (0)
313
314         q0.in.level = 12;
315         do { TESTCALL(QueryUserInfo, q0) } while (0);
316
317         TEST_USERINFO_STRING(2, comment,  1, comment, "xx2-1 comment", 0);
318         TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
319         TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment", 
320                            SAMR_FIELD_COMMENT);
321
322         test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
323         TEST_USERINFO_STRING(7, account_name,  1, account_name, base_account_name, 0);
324         test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
325         TEST_USERINFO_STRING(7, account_name,  3, account_name, base_account_name, 0);
326         test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
327         TEST_USERINFO_STRING(7, account_name,  5, account_name, base_account_name, 0);
328         test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
329         TEST_USERINFO_STRING(7, account_name,  6, account_name, base_account_name, 0);
330         test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
331         TEST_USERINFO_STRING(7, account_name,  7, account_name, base_account_name, 0);
332         test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
333         TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
334         test_account_name = base_account_name;
335         TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name, 
336                            SAMR_FIELD_ACCOUNT_NAME);
337
338         TEST_USERINFO_STRING(6, full_name,  1, full_name, "xx6-1 full_name", 0);
339         TEST_USERINFO_STRING(6, full_name,  3, full_name, "xx6-3 full_name", 0);
340         TEST_USERINFO_STRING(6, full_name,  5, full_name, "xx6-5 full_name", 0);
341         TEST_USERINFO_STRING(6, full_name,  6, full_name, "xx6-6 full_name", 0);
342         TEST_USERINFO_STRING(6, full_name,  8, full_name, "xx6-8 full_name", 0);
343         TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
344         TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
345         TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name", 
346                            SAMR_FIELD_FULL_NAME);
347
348         TEST_USERINFO_STRING(6, full_name,  1, full_name, "", 0);
349         TEST_USERINFO_STRING(6, full_name,  3, full_name, "", 0);
350         TEST_USERINFO_STRING(6, full_name,  5, full_name, "", 0);
351         TEST_USERINFO_STRING(6, full_name,  6, full_name, "", 0);
352         TEST_USERINFO_STRING(6, full_name,  8, full_name, "", 0);
353         TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
354         TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
355         TEST_USERINFO_STRING(21, full_name, 21, full_name, "", 
356                            SAMR_FIELD_FULL_NAME);
357
358         TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
359         TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
360         TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
361         TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script", 
362                            SAMR_FIELD_LOGON_SCRIPT);
363
364         TEST_USERINFO_STRING(12, profile_path,  3, profile_path, "xx12-3 profile_path", 0);
365         TEST_USERINFO_STRING(12, profile_path,  5, profile_path, "xx12-5 profile_path", 0);
366         TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
367         TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path", 
368                            SAMR_FIELD_PROFILE_PATH);
369
370         TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
371         TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
372         TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
373         TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
374                              SAMR_FIELD_HOME_DIRECTORY);
375         TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
376                              SAMR_FIELD_HOME_DIRECTORY);
377
378         TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
379         TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
380         TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
381         TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
382                              SAMR_FIELD_HOME_DRIVE);
383         TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
384                              SAMR_FIELD_HOME_DRIVE);
385         
386         TEST_USERINFO_STRING(13, description,  1, description, "xx13-1 description", 0);
387         TEST_USERINFO_STRING(13, description,  5, description, "xx13-5 description", 0);
388         TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
389         TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description", 
390                            SAMR_FIELD_DESCRIPTION);
391
392         TEST_USERINFO_STRING(14, workstations,  3, workstations, "14workstation3", 0);
393         TEST_USERINFO_STRING(14, workstations,  5, workstations, "14workstation4", 0);
394         TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
395         TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21", 
396                            SAMR_FIELD_WORKSTATIONS);
397         TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3", 
398                            SAMR_FIELD_WORKSTATIONS);
399         TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5", 
400                            SAMR_FIELD_WORKSTATIONS);
401         TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14", 
402                            SAMR_FIELD_WORKSTATIONS);
403
404         TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
405         TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
406                            SAMR_FIELD_PARAMETERS);
407         TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
408                            SAMR_FIELD_PARAMETERS);
409
410         TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
411         TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
412         TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__, 
413                           SAMR_FIELD_COUNTRY_CODE);
414         TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__, 
415                           SAMR_FIELD_COUNTRY_CODE);
416
417         TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
418         TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__, 
419                           SAMR_FIELD_CODE_PAGE);
420         TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__, 
421                           SAMR_FIELD_CODE_PAGE);
422
423         TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
424         TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
425         TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__, 
426                           SAMR_FIELD_ACCT_EXPIRY);
427         TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__, 
428                           SAMR_FIELD_ACCT_EXPIRY);
429         TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__, 
430                           SAMR_FIELD_ACCT_EXPIRY);
431
432         TEST_USERINFO_INT(4, logon_hours.bits[3],  3, logon_hours.bits[3], 1, 0);
433         TEST_USERINFO_INT(4, logon_hours.bits[3],  5, logon_hours.bits[3], 2, 0);
434         TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
435         TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4, 
436                           SAMR_FIELD_LOGON_HOURS);
437
438         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
439                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ), 
440                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags), 
441                               0);
442         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
443                               (base_acct_flags  | ACB_DISABLED), 
444                               (base_acct_flags  | ACB_DISABLED | user_extra_flags), 
445                               0);
446         
447         /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
448         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
449                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP), 
450                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP), 
451                               0);
452         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
453                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ), 
454                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags), 
455                               0);
456
457
458         /* The 'autolock' flag doesn't stick - check this */
459         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
460                               (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK), 
461                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
462                               0);
463 #if 0
464         /* Removing the 'disabled' flag doesn't stick - check this */
465         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
466                               (base_acct_flags), 
467                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
468                               0);
469 #endif
470         /* The 'store plaintext' flag does stick */
471         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
472                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED), 
473                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags), 
474                               0);
475         /* The 'use DES' flag does stick */
476         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
477                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY), 
478                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags), 
479                               0);
480         /* The 'don't require kerberos pre-authentication flag does stick */
481         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
482                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH), 
483                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags), 
484                               0);
485         /* The 'no kerberos PAC required' flag sticks */
486         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
487                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD), 
488                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags), 
489                               0);
490
491         TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags, 
492                               (base_acct_flags | ACB_DISABLED), 
493                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
494                               SAMR_FIELD_ACCT_FLAGS);
495
496 #if 0
497         /* these fail with win2003 - it appears you can't set the primary gid?
498            the set succeeds, but the gid isn't changed. Very weird! */
499         TEST_USERINFO_INT(9, primary_gid,  1, primary_gid, 513);
500         TEST_USERINFO_INT(9, primary_gid,  3, primary_gid, 513);
501         TEST_USERINFO_INT(9, primary_gid,  5, primary_gid, 513);
502         TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
503 #endif
504
505         return ret;
506 }
507
508 /*
509   generate a random password for password change tests
510 */
511 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
512 {
513         size_t len = MAX(8, min_len) + (random() % 6);
514         char *s = generate_random_str(mem_ctx, len);
515         return s;
516 }
517
518 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
519 {
520         char *s = samr_rand_pass_silent(mem_ctx, min_len);
521         printf("Generated password '%s'\n", s);
522         return s;
523
524 }
525
526 /*
527   generate a random password for password change tests
528 */
529 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
530 {
531         int i;
532         DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
533         generate_random_buffer(password.data, password.length);
534
535         for (i=0; i < len; i++) {
536                 if (((uint16_t *)password.data)[i] == 0) {
537                         ((uint16_t *)password.data)[i] = 1;
538                 }
539         }
540
541         return password;
542 }
543
544 /*
545   generate a random password for password change tests (fixed length)
546 */
547 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
548 {
549         char *s = generate_random_str(mem_ctx, len);
550         printf("Generated password '%s'\n", s);
551         return s;
552 }
553
554 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
555                              struct policy_handle *handle, char **password)
556 {
557         NTSTATUS status;
558         struct samr_SetUserInfo s;
559         union samr_UserInfo u;
560         bool ret = true;
561         DATA_BLOB session_key;
562         char *newpass;
563         struct samr_GetUserPwInfo pwp;
564         struct samr_PwInfo info;
565         int policy_min_pw_len = 0;
566         pwp.in.user_handle = handle;
567         pwp.out.info = &info;
568
569         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
570         if (NT_STATUS_IS_OK(status)) {
571                 policy_min_pw_len = pwp.out.info->min_password_length;
572         }
573         newpass = samr_rand_pass(tctx, policy_min_pw_len);
574
575         s.in.user_handle = handle;
576         s.in.info = &u;
577         s.in.level = 24;
578
579         encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
580         u.info24.password_expired = 0;
581
582         status = dcerpc_fetch_session_key(p, &session_key);
583         if (!NT_STATUS_IS_OK(status)) {
584                 printf("SetUserInfo level %u - no session key - %s\n",
585                        s.in.level, nt_errstr(status));
586                 return false;
587         }
588
589         arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
590
591         torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
592
593         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
594         if (!NT_STATUS_IS_OK(status)) {
595                 printf("SetUserInfo level %u failed - %s\n",
596                        s.in.level, nt_errstr(status));
597                 ret = false;
598         } else {
599                 *password = newpass;
600         }
601
602         return ret;
603 }
604
605
606 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
607                                 struct policy_handle *handle, uint32_t fields_present,
608                                 char **password)
609 {
610         NTSTATUS status;
611         struct samr_SetUserInfo s;
612         union samr_UserInfo u;
613         bool ret = true;
614         DATA_BLOB session_key;
615         char *newpass;
616         struct samr_GetUserPwInfo pwp;
617         struct samr_PwInfo info;
618         int policy_min_pw_len = 0;
619         pwp.in.user_handle = handle;
620         pwp.out.info = &info;
621
622         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
623         if (NT_STATUS_IS_OK(status)) {
624                 policy_min_pw_len = pwp.out.info->min_password_length;
625         }
626         newpass = samr_rand_pass(tctx, policy_min_pw_len);
627
628         s.in.user_handle = handle;
629         s.in.info = &u;
630         s.in.level = 23;
631
632         ZERO_STRUCT(u);
633
634         u.info23.info.fields_present = fields_present;
635
636         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
637
638         status = dcerpc_fetch_session_key(p, &session_key);
639         if (!NT_STATUS_IS_OK(status)) {
640                 printf("SetUserInfo level %u - no session key - %s\n",
641                        s.in.level, nt_errstr(status));
642                 return false;
643         }
644
645         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
646
647         torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
648
649         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
650         if (!NT_STATUS_IS_OK(status)) {
651                 printf("SetUserInfo level %u failed - %s\n",
652                        s.in.level, nt_errstr(status));
653                 ret = false;
654         } else {
655                 *password = newpass;
656         }
657
658         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
659
660         status = dcerpc_fetch_session_key(p, &session_key);
661         if (!NT_STATUS_IS_OK(status)) {
662                 printf("SetUserInfo level %u - no session key - %s\n",
663                        s.in.level, nt_errstr(status));
664                 return false;
665         }
666
667         /* This should break the key nicely */
668         session_key.length--;
669         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
670
671         torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
672
673         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
674         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
675                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
676                        s.in.level, nt_errstr(status));
677                 ret = false;
678         }
679
680         return ret;
681 }
682
683
684 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
685                                struct policy_handle *handle, bool makeshort, 
686                                char **password)
687 {
688         NTSTATUS status;
689         struct samr_SetUserInfo s;
690         union samr_UserInfo u;
691         bool ret = true;
692         DATA_BLOB session_key;
693         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
694         uint8_t confounder[16];
695         char *newpass;
696         struct MD5Context ctx;
697         struct samr_GetUserPwInfo pwp;
698         struct samr_PwInfo info;
699         int policy_min_pw_len = 0;
700         pwp.in.user_handle = handle;
701         pwp.out.info = &info;
702
703         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
704         if (NT_STATUS_IS_OK(status)) {
705                 policy_min_pw_len = pwp.out.info->min_password_length;
706         }
707         if (makeshort && policy_min_pw_len) {
708                 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
709         } else {
710                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
711         }
712
713         s.in.user_handle = handle;
714         s.in.info = &u;
715         s.in.level = 26;
716
717         encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
718         u.info26.password_expired = 0;
719
720         status = dcerpc_fetch_session_key(p, &session_key);
721         if (!NT_STATUS_IS_OK(status)) {
722                 printf("SetUserInfo level %u - no session key - %s\n",
723                        s.in.level, nt_errstr(status));
724                 return false;
725         }
726
727         generate_random_buffer((uint8_t *)confounder, 16);
728
729         MD5Init(&ctx);
730         MD5Update(&ctx, confounder, 16);
731         MD5Update(&ctx, session_key.data, session_key.length);
732         MD5Final(confounded_session_key.data, &ctx);
733
734         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
735         memcpy(&u.info26.password.data[516], confounder, 16);
736
737         torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
738
739         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
740         if (!NT_STATUS_IS_OK(status)) {
741                 printf("SetUserInfo level %u failed - %s\n",
742                        s.in.level, nt_errstr(status));
743                 ret = false;
744         } else {
745                 *password = newpass;
746         }
747
748         /* This should break the key nicely */
749         confounded_session_key.data[0]++;
750
751         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
752         memcpy(&u.info26.password.data[516], confounder, 16);
753
754         torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
755
756         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
757         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
758                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
759                        s.in.level, nt_errstr(status));
760                 ret = false;
761         } else {
762                 *password = newpass;
763         }
764
765         return ret;
766 }
767
768 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
769                                 struct policy_handle *handle, uint32_t fields_present,
770                                 char **password)
771 {
772         NTSTATUS status;
773         struct samr_SetUserInfo s;
774         union samr_UserInfo u;
775         bool ret = true;
776         DATA_BLOB session_key;
777         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
778         struct MD5Context ctx;
779         uint8_t confounder[16];
780         char *newpass;
781         struct samr_GetUserPwInfo pwp;
782         struct samr_PwInfo info;
783         int policy_min_pw_len = 0;
784         pwp.in.user_handle = handle;
785         pwp.out.info = &info;
786
787         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
788         if (NT_STATUS_IS_OK(status)) {
789                 policy_min_pw_len = pwp.out.info->min_password_length;
790         }
791         newpass = samr_rand_pass(tctx, policy_min_pw_len);
792
793         s.in.user_handle = handle;
794         s.in.info = &u;
795         s.in.level = 25;
796
797         ZERO_STRUCT(u);
798
799         u.info25.info.fields_present = fields_present;
800
801         encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
802
803         status = dcerpc_fetch_session_key(p, &session_key);
804         if (!NT_STATUS_IS_OK(status)) {
805                 printf("SetUserInfo level %u - no session key - %s\n",
806                        s.in.level, nt_errstr(status));
807                 return false;
808         }
809
810         generate_random_buffer((uint8_t *)confounder, 16);
811
812         MD5Init(&ctx);
813         MD5Update(&ctx, confounder, 16);
814         MD5Update(&ctx, session_key.data, session_key.length);
815         MD5Final(confounded_session_key.data, &ctx);
816
817         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
818         memcpy(&u.info25.password.data[516], confounder, 16);
819
820         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
821
822         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
823         if (!NT_STATUS_IS_OK(status)) {
824                 printf("SetUserInfo level %u failed - %s\n",
825                        s.in.level, nt_errstr(status));
826                 ret = false;
827         } else {
828                 *password = newpass;
829         }
830
831         /* This should break the key nicely */
832         confounded_session_key.data[0]++;
833
834         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
835         memcpy(&u.info25.password.data[516], confounder, 16);
836
837         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
838
839         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
840         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
841                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
842                        s.in.level, nt_errstr(status));
843                 ret = false;
844         }
845
846         return ret;
847 }
848
849 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
850                                struct policy_handle *handle)
851 {
852         NTSTATUS status;
853         struct samr_SetAliasInfo r;
854         struct samr_QueryAliasInfo q;
855         union samr_AliasInfo *info;
856         uint16_t levels[] = {2, 3};
857         int i;
858         bool ret = true;
859
860         /* Ignoring switch level 1, as that includes the number of members for the alias
861          * and setting this to a wrong value might have negative consequences
862          */
863
864         for (i=0;i<ARRAY_SIZE(levels);i++) {
865                 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
866
867                 r.in.alias_handle = handle;
868                 r.in.level = levels[i];
869                 r.in.info  = talloc(tctx, union samr_AliasInfo);
870                 switch (r.in.level) {
871                     case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
872                     case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
873                                 "Test Description, should test I18N as well"); break;
874                     case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
875                 }
876
877                 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
878                 if (!NT_STATUS_IS_OK(status)) {
879                         printf("SetAliasInfo level %u failed - %s\n",
880                                levels[i], nt_errstr(status));
881                         ret = false;
882                 }
883
884                 q.in.alias_handle = handle;
885                 q.in.level = levels[i];
886                 q.out.info = &info;
887
888                 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
889                 if (!NT_STATUS_IS_OK(status)) {
890                         printf("QueryAliasInfo level %u failed - %s\n",
891                                levels[i], nt_errstr(status));
892                         ret = false;
893                 }
894         }
895
896         return ret;
897 }
898
899 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
900                                   struct policy_handle *user_handle)
901 {
902         struct samr_GetGroupsForUser r;
903         struct samr_RidWithAttributeArray *rids = NULL;
904         NTSTATUS status;
905
906         torture_comment(tctx, "testing GetGroupsForUser\n");
907
908         r.in.user_handle = user_handle;
909         r.out.rids = &rids;
910
911         status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
912         torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
913
914         return true;
915
916 }
917
918 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
919                               struct lsa_String *domain_name)
920 {
921         NTSTATUS status;
922         struct samr_GetDomPwInfo r;
923         struct samr_PwInfo info;
924
925         r.in.domain_name = domain_name;
926         r.out.info = &info;
927
928         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
929
930         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
931         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
932
933         r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
934         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
935
936         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
937         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
938
939         r.in.domain_name->string = "\\\\__NONAME__";
940         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
941
942         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
943         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
944
945         r.in.domain_name->string = "\\\\Builtin";
946         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
947
948         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
949         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
950
951         return true;
952 }
953
954 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
955                                struct policy_handle *handle)
956 {
957         NTSTATUS status;
958         struct samr_GetUserPwInfo r;
959         struct samr_PwInfo info;
960
961         torture_comment(tctx, "Testing GetUserPwInfo\n");
962
963         r.in.user_handle = handle;
964         r.out.info = &info;
965
966         status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
967         torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
968
969         return true;
970 }
971
972 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
973                                 struct policy_handle *domain_handle, const char *name,
974                                 uint32_t *rid)
975 {
976         NTSTATUS status;
977         struct samr_LookupNames n;
978         struct lsa_String sname[2];
979         struct samr_Ids rids, types;
980
981         init_lsa_String(&sname[0], name);
982
983         n.in.domain_handle = domain_handle;
984         n.in.num_names = 1;
985         n.in.names = sname;
986         n.out.rids = &rids;
987         n.out.types = &types;
988         status = dcerpc_samr_LookupNames(p, tctx, &n);
989         if (NT_STATUS_IS_OK(status)) {
990                 *rid = n.out.rids->ids[0];
991         } else {
992                 return status;
993         }
994
995         init_lsa_String(&sname[1], "xxNONAMExx");
996         n.in.num_names = 2;
997         status = dcerpc_samr_LookupNames(p, tctx, &n);
998         if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
999                 printf("LookupNames[2] failed - %s\n", nt_errstr(status));              
1000                 if (NT_STATUS_IS_OK(status)) {
1001                         return NT_STATUS_UNSUCCESSFUL;
1002                 }
1003                 return status;
1004         }
1005
1006         n.in.num_names = 0;
1007         status = dcerpc_samr_LookupNames(p, tctx, &n);
1008         if (!NT_STATUS_IS_OK(status)) {
1009                 printf("LookupNames[0] failed - %s\n", nt_errstr(status));              
1010                 return status;
1011         }
1012
1013         init_lsa_String(&sname[0], "xxNONAMExx");
1014         n.in.num_names = 1;
1015         status = dcerpc_samr_LookupNames(p, tctx, &n);
1016         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1017                 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));             
1018                 if (NT_STATUS_IS_OK(status)) {
1019                         return NT_STATUS_UNSUCCESSFUL;
1020                 }
1021                 return status;
1022         }
1023
1024         init_lsa_String(&sname[0], "xxNONAMExx");
1025         init_lsa_String(&sname[1], "xxNONAME2xx");
1026         n.in.num_names = 2;
1027         status = dcerpc_samr_LookupNames(p, tctx, &n);
1028         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1029                 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));            
1030                 if (NT_STATUS_IS_OK(status)) {
1031                         return NT_STATUS_UNSUCCESSFUL;
1032                 }
1033                 return status;
1034         }
1035
1036         return NT_STATUS_OK;
1037 }
1038
1039 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1040                                      struct policy_handle *domain_handle,
1041                                      const char *name, struct policy_handle *user_handle)
1042 {
1043         NTSTATUS status;
1044         struct samr_OpenUser r;
1045         uint32_t rid;
1046
1047         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1048         if (!NT_STATUS_IS_OK(status)) {
1049                 return status;
1050         }
1051
1052         r.in.domain_handle = domain_handle;
1053         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1054         r.in.rid = rid;
1055         r.out.user_handle = user_handle;
1056         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1057         if (!NT_STATUS_IS_OK(status)) {
1058                 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1059         }
1060
1061         return status;
1062 }
1063
1064 #if 0
1065 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1066                                    struct policy_handle *handle)
1067 {
1068         NTSTATUS status;
1069         struct samr_ChangePasswordUser r;
1070         bool ret = true;
1071         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1072         struct policy_handle user_handle;
1073         char *oldpass = "test";
1074         char *newpass = "test2";
1075         uint8_t old_nt_hash[16], new_nt_hash[16];
1076         uint8_t old_lm_hash[16], new_lm_hash[16];
1077
1078         status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1079         if (!NT_STATUS_IS_OK(status)) {
1080                 return false;
1081         }
1082
1083         printf("Testing ChangePasswordUser for user 'testuser'\n");
1084
1085         printf("old password: %s\n", oldpass);
1086         printf("new password: %s\n", newpass);
1087
1088         E_md4hash(oldpass, old_nt_hash);
1089         E_md4hash(newpass, new_nt_hash);
1090         E_deshash(oldpass, old_lm_hash);
1091         E_deshash(newpass, new_lm_hash);
1092
1093         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1094         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1095         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1096         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1097         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1098         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1099
1100         r.in.handle = &user_handle;
1101         r.in.lm_present = 1;
1102         r.in.old_lm_crypted = &hash1;
1103         r.in.new_lm_crypted = &hash2;
1104         r.in.nt_present = 1;
1105         r.in.old_nt_crypted = &hash3;
1106         r.in.new_nt_crypted = &hash4;
1107         r.in.cross1_present = 1;
1108         r.in.nt_cross = &hash5;
1109         r.in.cross2_present = 1;
1110         r.in.lm_cross = &hash6;
1111
1112         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1113         if (!NT_STATUS_IS_OK(status)) {
1114                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1115                 ret = false;
1116         }
1117
1118         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1119                 ret = false;
1120         }
1121
1122         return ret;
1123 }
1124 #endif
1125
1126 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1127                                     const char *acct_name, 
1128                                     struct policy_handle *handle, char **password)
1129 {
1130         NTSTATUS status;
1131         struct samr_ChangePasswordUser r;
1132         bool ret = true;
1133         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1134         struct policy_handle user_handle;
1135         char *oldpass;
1136         uint8_t old_nt_hash[16], new_nt_hash[16];
1137         uint8_t old_lm_hash[16], new_lm_hash[16];
1138         bool changed = true;
1139
1140         char *newpass;
1141         struct samr_GetUserPwInfo pwp;
1142         struct samr_PwInfo info;
1143         int policy_min_pw_len = 0;
1144
1145         status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1146         if (!NT_STATUS_IS_OK(status)) {
1147                 return false;
1148         }
1149         pwp.in.user_handle = &user_handle;
1150         pwp.out.info = &info;
1151
1152         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1153         if (NT_STATUS_IS_OK(status)) {
1154                 policy_min_pw_len = pwp.out.info->min_password_length;
1155         }
1156         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1157
1158         torture_comment(tctx, "Testing ChangePasswordUser\n");
1159
1160         torture_assert(tctx, *password != NULL, 
1161                                    "Failing ChangePasswordUser as old password was NULL.  Previous test failed?");
1162
1163         oldpass = *password;
1164
1165         E_md4hash(oldpass, old_nt_hash);
1166         E_md4hash(newpass, new_nt_hash);
1167         E_deshash(oldpass, old_lm_hash);
1168         E_deshash(newpass, new_lm_hash);
1169
1170         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1171         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1172         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1173         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1174         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1175         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1176
1177         r.in.user_handle = &user_handle;
1178         r.in.lm_present = 1;
1179         /* Break the LM hash */
1180         hash1.hash[0]++;
1181         r.in.old_lm_crypted = &hash1;
1182         r.in.new_lm_crypted = &hash2;
1183         r.in.nt_present = 1;
1184         r.in.old_nt_crypted = &hash3;
1185         r.in.new_nt_crypted = &hash4;
1186         r.in.cross1_present = 1;
1187         r.in.nt_cross = &hash5;
1188         r.in.cross2_present = 1;
1189         r.in.lm_cross = &hash6;
1190
1191         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1192         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1193                 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1194
1195         /* Unbreak the LM hash */
1196         hash1.hash[0]--;
1197
1198         r.in.user_handle = &user_handle;
1199         r.in.lm_present = 1;
1200         r.in.old_lm_crypted = &hash1;
1201         r.in.new_lm_crypted = &hash2;
1202         /* Break the NT hash */
1203         hash3.hash[0]--;
1204         r.in.nt_present = 1;
1205         r.in.old_nt_crypted = &hash3;
1206         r.in.new_nt_crypted = &hash4;
1207         r.in.cross1_present = 1;
1208         r.in.nt_cross = &hash5;
1209         r.in.cross2_present = 1;
1210         r.in.lm_cross = &hash6;
1211
1212         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1213         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD, 
1214                 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1215
1216         /* Unbreak the NT hash */
1217         hash3.hash[0]--;
1218
1219         r.in.user_handle = &user_handle;
1220         r.in.lm_present = 1;
1221         r.in.old_lm_crypted = &hash1;
1222         r.in.new_lm_crypted = &hash2;
1223         r.in.nt_present = 1;
1224         r.in.old_nt_crypted = &hash3;
1225         r.in.new_nt_crypted = &hash4;
1226         r.in.cross1_present = 1;
1227         r.in.nt_cross = &hash5;
1228         r.in.cross2_present = 1;
1229         /* Break the LM cross */
1230         hash6.hash[0]++;
1231         r.in.lm_cross = &hash6;
1232
1233         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1234         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1235                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1236                 ret = false;
1237         }
1238
1239         /* Unbreak the LM cross */
1240         hash6.hash[0]--;
1241
1242         r.in.user_handle = &user_handle;
1243         r.in.lm_present = 1;
1244         r.in.old_lm_crypted = &hash1;
1245         r.in.new_lm_crypted = &hash2;
1246         r.in.nt_present = 1;
1247         r.in.old_nt_crypted = &hash3;
1248         r.in.new_nt_crypted = &hash4;
1249         r.in.cross1_present = 1;
1250         /* Break the NT cross */
1251         hash5.hash[0]++;
1252         r.in.nt_cross = &hash5;
1253         r.in.cross2_present = 1;
1254         r.in.lm_cross = &hash6;
1255
1256         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1257         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1258                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1259                 ret = false;
1260         }
1261
1262         /* Unbreak the NT cross */
1263         hash5.hash[0]--;
1264
1265
1266         /* Reset the hashes to not broken values */
1267         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1268         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1269         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1270         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1271         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1272         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1273
1274         r.in.user_handle = &user_handle;
1275         r.in.lm_present = 1;
1276         r.in.old_lm_crypted = &hash1;
1277         r.in.new_lm_crypted = &hash2;
1278         r.in.nt_present = 1;
1279         r.in.old_nt_crypted = &hash3;
1280         r.in.new_nt_crypted = &hash4;
1281         r.in.cross1_present = 1;
1282         r.in.nt_cross = &hash5;
1283         r.in.cross2_present = 0;
1284         r.in.lm_cross = NULL;
1285
1286         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1287         if (NT_STATUS_IS_OK(status)) {
1288                 changed = true;
1289                 *password = newpass;
1290         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1291                 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1292                 ret = false;
1293         }
1294
1295         oldpass = newpass;
1296         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1297
1298         E_md4hash(oldpass, old_nt_hash);
1299         E_md4hash(newpass, new_nt_hash);
1300         E_deshash(oldpass, old_lm_hash);
1301         E_deshash(newpass, new_lm_hash);
1302
1303
1304         /* Reset the hashes to not broken values */
1305         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1306         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1307         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1308         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1309         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1310         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1311
1312         r.in.user_handle = &user_handle;
1313         r.in.lm_present = 1;
1314         r.in.old_lm_crypted = &hash1;
1315         r.in.new_lm_crypted = &hash2;
1316         r.in.nt_present = 1;
1317         r.in.old_nt_crypted = &hash3;
1318         r.in.new_nt_crypted = &hash4;
1319         r.in.cross1_present = 0;
1320         r.in.nt_cross = NULL;
1321         r.in.cross2_present = 1;
1322         r.in.lm_cross = &hash6;
1323
1324         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1325         if (NT_STATUS_IS_OK(status)) {
1326                 changed = true;
1327                 *password = newpass;
1328         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1329                 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1330                 ret = false;
1331         }
1332
1333         oldpass = newpass;
1334         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1335
1336         E_md4hash(oldpass, old_nt_hash);
1337         E_md4hash(newpass, new_nt_hash);
1338         E_deshash(oldpass, old_lm_hash);
1339         E_deshash(newpass, new_lm_hash);
1340
1341
1342         /* Reset the hashes to not broken values */
1343         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1344         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1345         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1346         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1347         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1348         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1349
1350         r.in.user_handle = &user_handle;
1351         r.in.lm_present = 1;
1352         r.in.old_lm_crypted = &hash1;
1353         r.in.new_lm_crypted = &hash2;
1354         r.in.nt_present = 1;
1355         r.in.old_nt_crypted = &hash3;
1356         r.in.new_nt_crypted = &hash4;
1357         r.in.cross1_present = 1;
1358         r.in.nt_cross = &hash5;
1359         r.in.cross2_present = 1;
1360         r.in.lm_cross = &hash6;
1361
1362         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1363         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1364                 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1365         } else  if (!NT_STATUS_IS_OK(status)) {
1366                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1367                 ret = false;
1368         } else {
1369                 changed = true;
1370                 *password = newpass;
1371         }
1372
1373         r.in.user_handle = &user_handle;
1374         r.in.lm_present = 1;
1375         r.in.old_lm_crypted = &hash1;
1376         r.in.new_lm_crypted = &hash2;
1377         r.in.nt_present = 1;
1378         r.in.old_nt_crypted = &hash3;
1379         r.in.new_nt_crypted = &hash4;
1380         r.in.cross1_present = 1;
1381         r.in.nt_cross = &hash5;
1382         r.in.cross2_present = 1;
1383         r.in.lm_cross = &hash6;
1384
1385         if (changed) {
1386                 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1387                 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1388                         printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1389                 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1390                         printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1391                         ret = false;
1392                 }
1393         }
1394
1395         
1396         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1397                 ret = false;
1398         }
1399
1400         return ret;
1401 }
1402
1403
1404 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1405                                         const char *acct_name,
1406                                         struct policy_handle *handle, char **password)
1407 {
1408         NTSTATUS status;
1409         struct samr_OemChangePasswordUser2 r;
1410         bool ret = true;
1411         struct samr_Password lm_verifier;
1412         struct samr_CryptPassword lm_pass;
1413         struct lsa_AsciiString server, account, account_bad;
1414         char *oldpass;
1415         char *newpass;
1416         uint8_t old_lm_hash[16], new_lm_hash[16];
1417
1418         struct samr_GetDomPwInfo dom_pw_info;
1419         struct samr_PwInfo info;
1420         int policy_min_pw_len = 0;
1421
1422         struct lsa_String domain_name;
1423
1424         domain_name.string = "";
1425         dom_pw_info.in.domain_name = &domain_name;
1426         dom_pw_info.out.info = &info;
1427
1428         torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1429
1430         torture_assert(tctx, *password != NULL, 
1431                                    "Failing OemChangePasswordUser2 as old password was NULL.  Previous test failed?");
1432
1433         oldpass = *password;
1434
1435         status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1436         if (NT_STATUS_IS_OK(status)) {
1437                 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1438         }
1439
1440         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1441
1442         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1443         account.string = acct_name;
1444
1445         E_deshash(oldpass, old_lm_hash);
1446         E_deshash(newpass, new_lm_hash);
1447
1448         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1449         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1450         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1451
1452         r.in.server = &server;
1453         r.in.account = &account;
1454         r.in.password = &lm_pass;
1455         r.in.hash = &lm_verifier;
1456
1457         /* Break the verification */
1458         lm_verifier.hash[0]++;
1459
1460         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1461
1462         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1463             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1464                 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1465                         nt_errstr(status));
1466                 ret = false;
1467         }
1468
1469         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1470         /* Break the old password */
1471         old_lm_hash[0]++;
1472         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1473         /* unbreak it for the next operation */
1474         old_lm_hash[0]--;
1475         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1476
1477         r.in.server = &server;
1478         r.in.account = &account;
1479         r.in.password = &lm_pass;
1480         r.in.hash = &lm_verifier;
1481
1482         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1483
1484         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1485             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1486                 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1487                         nt_errstr(status));
1488                 ret = false;
1489         }
1490
1491         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1492         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1493
1494         r.in.server = &server;
1495         r.in.account = &account;
1496         r.in.password = &lm_pass;
1497         r.in.hash = NULL;
1498
1499         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1500
1501         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1502             && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1503                 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1504                         nt_errstr(status));
1505                 ret = false;
1506         }
1507
1508         /* This shouldn't be a valid name */
1509         account_bad.string = TEST_ACCOUNT_NAME "XX";
1510         r.in.account = &account_bad;
1511
1512         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1513
1514         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1515                 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1516                         nt_errstr(status));
1517                 ret = false;
1518         }
1519
1520         /* This shouldn't be a valid name */
1521         account_bad.string = TEST_ACCOUNT_NAME "XX";
1522         r.in.account = &account_bad;
1523         r.in.password = &lm_pass;
1524         r.in.hash = &lm_verifier;
1525
1526         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1527
1528         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1529                 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1530                         nt_errstr(status));
1531                 ret = false;
1532         }
1533
1534         /* This shouldn't be a valid name */
1535         account_bad.string = TEST_ACCOUNT_NAME "XX";
1536         r.in.account = &account_bad;
1537         r.in.password = NULL;
1538         r.in.hash = &lm_verifier;
1539
1540         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1541
1542         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1543                 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1544                         nt_errstr(status));
1545                 ret = false;
1546         }
1547
1548         E_deshash(oldpass, old_lm_hash);
1549         E_deshash(newpass, new_lm_hash);
1550
1551         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1552         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1553         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1554
1555         r.in.server = &server;
1556         r.in.account = &account;
1557         r.in.password = &lm_pass;
1558         r.in.hash = &lm_verifier;
1559
1560         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1561         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1562                 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1563         } else if (!NT_STATUS_IS_OK(status)) {
1564                 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1565                 ret = false;
1566         } else {
1567                 *password = newpass;
1568         }
1569
1570         return ret;
1571 }
1572
1573
1574 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1575                                      const char *acct_name,
1576                                      char **password,
1577                                      char *newpass, bool allow_password_restriction)
1578 {
1579         NTSTATUS status;
1580         struct samr_ChangePasswordUser2 r;
1581         bool ret = true;
1582         struct lsa_String server, account;
1583         struct samr_CryptPassword nt_pass, lm_pass;
1584         struct samr_Password nt_verifier, lm_verifier;
1585         char *oldpass;
1586         uint8_t old_nt_hash[16], new_nt_hash[16];
1587         uint8_t old_lm_hash[16], new_lm_hash[16];
1588
1589         struct samr_GetDomPwInfo dom_pw_info;
1590         struct samr_PwInfo info;
1591
1592         struct lsa_String domain_name;
1593
1594         domain_name.string = "";
1595         dom_pw_info.in.domain_name = &domain_name;
1596         dom_pw_info.out.info = &info;
1597
1598         torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
1599
1600         torture_assert(tctx, *password != NULL, 
1601                                    "Failing ChangePasswordUser2 as old password was NULL.  Previous test failed?");
1602         oldpass = *password;
1603
1604         if (!newpass) {
1605                 int policy_min_pw_len = 0;
1606                 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1607                 if (NT_STATUS_IS_OK(status)) {
1608                         policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1609                 }
1610
1611                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1612         } 
1613
1614         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1615         init_lsa_String(&account, acct_name);
1616
1617         E_md4hash(oldpass, old_nt_hash);
1618         E_md4hash(newpass, new_nt_hash);
1619
1620         E_deshash(oldpass, old_lm_hash);
1621         E_deshash(newpass, new_lm_hash);
1622
1623         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1624         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1625         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1626
1627         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1628         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1629         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1630
1631         r.in.server = &server;
1632         r.in.account = &account;
1633         r.in.nt_password = &nt_pass;
1634         r.in.nt_verifier = &nt_verifier;
1635         r.in.lm_change = 1;
1636         r.in.lm_password = &lm_pass;
1637         r.in.lm_verifier = &lm_verifier;
1638
1639         status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
1640         if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1641                 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1642         } else if (!NT_STATUS_IS_OK(status)) {
1643                 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1644                 ret = false;
1645         } else {
1646                 *password = newpass;
1647         }
1648
1649         return ret;
1650 }
1651
1652
1653 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx, 
1654                               const char *account_string,
1655                               int policy_min_pw_len,
1656                               char **password,
1657                               const char *newpass,
1658                               NTTIME last_password_change,
1659                               bool handle_reject_reason)
1660 {
1661         NTSTATUS status;
1662         struct samr_ChangePasswordUser3 r;
1663         bool ret = true;
1664         struct lsa_String server, account, account_bad;
1665         struct samr_CryptPassword nt_pass, lm_pass;
1666         struct samr_Password nt_verifier, lm_verifier;
1667         char *oldpass;
1668         uint8_t old_nt_hash[16], new_nt_hash[16];
1669         uint8_t old_lm_hash[16], new_lm_hash[16];
1670         NTTIME t;
1671         struct samr_DomInfo1 *dominfo = NULL;
1672         struct samr_ChangeReject *reject = NULL;
1673
1674         torture_comment(tctx, "Testing ChangePasswordUser3\n");
1675
1676         if (newpass == NULL) {
1677                 do {
1678                         if (policy_min_pw_len == 0) {
1679                                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1680                         } else {
1681                                 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
1682                         }
1683                 } while (check_password_quality(newpass) == false);
1684         } else {
1685                 torture_comment(tctx, "Using password '%s'\n", newpass);
1686         }
1687
1688         torture_assert(tctx, *password != NULL, 
1689                                    "Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?");
1690
1691         oldpass = *password;
1692         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1693         init_lsa_String(&account, account_string);
1694
1695         E_md4hash(oldpass, old_nt_hash);
1696         E_md4hash(newpass, new_nt_hash);
1697
1698         E_deshash(oldpass, old_lm_hash);
1699         E_deshash(newpass, new_lm_hash);
1700
1701         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1702         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1703         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1704
1705         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1706         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1707         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1708         
1709         /* Break the verification */
1710         nt_verifier.hash[0]++;
1711
1712         r.in.server = &server;
1713         r.in.account = &account;
1714         r.in.nt_password = &nt_pass;
1715         r.in.nt_verifier = &nt_verifier;
1716         r.in.lm_change = 1;
1717         r.in.lm_password = &lm_pass;
1718         r.in.lm_verifier = &lm_verifier;
1719         r.in.password3 = NULL;
1720         r.out.dominfo = &dominfo;
1721         r.out.reject = &reject;
1722
1723         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1724         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1725             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1726                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1727                         nt_errstr(status));
1728                 ret = false;
1729         }
1730         
1731         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1732         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1733         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1734
1735         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1736         /* Break the NT hash */
1737         old_nt_hash[0]++;
1738         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1739         /* Unbreak it again */
1740         old_nt_hash[0]--;
1741         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1742         
1743         r.in.server = &server;
1744         r.in.account = &account;
1745         r.in.nt_password = &nt_pass;
1746         r.in.nt_verifier = &nt_verifier;
1747         r.in.lm_change = 1;
1748         r.in.lm_password = &lm_pass;
1749         r.in.lm_verifier = &lm_verifier;
1750         r.in.password3 = NULL;
1751         r.out.dominfo = &dominfo;
1752         r.out.reject = &reject;
1753
1754         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1755         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1756             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1757                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1758                         nt_errstr(status));
1759                 ret = false;
1760         }
1761         
1762         /* This shouldn't be a valid name */
1763         init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
1764
1765         r.in.account = &account_bad;
1766         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1767         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1768                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1769                         nt_errstr(status));
1770                 ret = false;
1771         }
1772
1773         E_md4hash(oldpass, old_nt_hash);
1774         E_md4hash(newpass, new_nt_hash);
1775
1776         E_deshash(oldpass, old_lm_hash);
1777         E_deshash(newpass, new_lm_hash);
1778
1779         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1780         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1781         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1782
1783         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1784         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1785         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1786
1787         r.in.server = &server;
1788         r.in.account = &account;
1789         r.in.nt_password = &nt_pass;
1790         r.in.nt_verifier = &nt_verifier;
1791         r.in.lm_change = 1;
1792         r.in.lm_password = &lm_pass;
1793         r.in.lm_verifier = &lm_verifier;
1794         r.in.password3 = NULL;
1795         r.out.dominfo = &dominfo;
1796         r.out.reject = &reject;
1797
1798         unix_to_nt_time(&t, time(NULL));
1799
1800         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1801
1802         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1803             && dominfo
1804             && reject
1805             && handle_reject_reason
1806             && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
1807                 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1808
1809                         if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
1810                                 printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
1811                                         SAMR_REJECT_OTHER, reject->reason);
1812                                 return false;
1813                         }
1814                 }
1815
1816                 /* We tested the order of precendence which is as follows:
1817                 
1818                 * pwd min_age 
1819                 * pwd length
1820                 * pwd complexity
1821                 * pwd history
1822
1823                 Guenther */
1824
1825                 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1826                            (last_password_change + dominfo->min_password_age > t)) {
1827
1828                         if (reject->reason != SAMR_REJECT_OTHER) {
1829                                 printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
1830                                         SAMR_REJECT_OTHER, reject->reason);
1831                                 return false;
1832                         }
1833
1834                 } else if ((dominfo->min_password_length > 0) &&
1835                            (strlen(newpass) < dominfo->min_password_length)) {
1836
1837                         if (reject->reason != SAMR_REJECT_TOO_SHORT) {
1838                                 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n", 
1839                                         SAMR_REJECT_TOO_SHORT, reject->reason);
1840                                 return false;
1841                         }
1842
1843                 } else if ((dominfo->password_history_length > 0) &&
1844                             strequal(oldpass, newpass)) {
1845
1846                         if (reject->reason != SAMR_REJECT_IN_HISTORY) {
1847                                 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n", 
1848                                         SAMR_REJECT_IN_HISTORY, reject->reason);
1849                                 return false;
1850                         }
1851                 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1852
1853                         if (reject->reason != SAMR_REJECT_COMPLEXITY) {
1854                                 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n", 
1855                                         SAMR_REJECT_COMPLEXITY, reject->reason);
1856                                 return false;
1857                         }
1858
1859                 }
1860
1861                 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
1862                         /* retry with adjusted size */
1863                         return test_ChangePasswordUser3(p, tctx, account_string, 
1864                                                         dominfo->min_password_length,
1865                                                         password, NULL, 0, false); 
1866
1867                 }
1868
1869         } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1870                 if (reject && reject->reason != SAMR_REJECT_OTHER) {
1871                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
1872                                SAMR_REJECT_OTHER, reject->reason);
1873                         return false;
1874                 }
1875                 /* Perhaps the server has a 'min password age' set? */
1876
1877         } else { 
1878                 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
1879                 *password = talloc_strdup(tctx, newpass);
1880         }
1881
1882         return ret;
1883 }
1884
1885 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
1886                                     const char *account_string,
1887                                     struct policy_handle *handle, 
1888                                     char **password)
1889 {
1890         NTSTATUS status;
1891         struct samr_ChangePasswordUser3 r;
1892         struct samr_SetUserInfo s;
1893         union samr_UserInfo u;
1894         DATA_BLOB session_key;
1895         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1896         uint8_t confounder[16];
1897         struct MD5Context ctx;
1898
1899         bool ret = true;
1900         struct lsa_String server, account;
1901         struct samr_CryptPassword nt_pass;
1902         struct samr_Password nt_verifier;
1903         DATA_BLOB new_random_pass;
1904         char *newpass;
1905         char *oldpass;
1906         uint8_t old_nt_hash[16], new_nt_hash[16];
1907         NTTIME t;
1908         struct samr_DomInfo1 *dominfo = NULL;
1909         struct samr_ChangeReject *reject = NULL;
1910
1911         new_random_pass = samr_very_rand_pass(tctx, 128);
1912
1913         torture_assert(tctx, *password != NULL, 
1914                                    "Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?");
1915
1916         oldpass = *password;
1917         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1918         init_lsa_String(&account, account_string);
1919
1920         s.in.user_handle = handle;
1921         s.in.info = &u;
1922         s.in.level = 25;
1923
1924         ZERO_STRUCT(u);
1925
1926         u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
1927
1928         set_pw_in_buffer(u.info25.password.data, &new_random_pass);
1929
1930         status = dcerpc_fetch_session_key(p, &session_key);
1931         if (!NT_STATUS_IS_OK(status)) {
1932                 printf("SetUserInfo level %u - no session key - %s\n",
1933                        s.in.level, nt_errstr(status));
1934                 return false;
1935         }
1936
1937         generate_random_buffer((uint8_t *)confounder, 16);
1938
1939         MD5Init(&ctx);
1940         MD5Update(&ctx, confounder, 16);
1941         MD5Update(&ctx, session_key.data, session_key.length);
1942         MD5Final(confounded_session_key.data, &ctx);
1943
1944         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1945         memcpy(&u.info25.password.data[516], confounder, 16);
1946
1947         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
1948
1949         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1950         if (!NT_STATUS_IS_OK(status)) {
1951                 printf("SetUserInfo level %u failed - %s\n",
1952                        s.in.level, nt_errstr(status));
1953                 ret = false;
1954         }
1955
1956         torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
1957
1958         mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1959
1960         new_random_pass = samr_very_rand_pass(tctx, 128);
1961
1962         mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
1963
1964         set_pw_in_buffer(nt_pass.data, &new_random_pass);
1965         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1966         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1967
1968         r.in.server = &server;
1969         r.in.account = &account;
1970         r.in.nt_password = &nt_pass;
1971         r.in.nt_verifier = &nt_verifier;
1972         r.in.lm_change = 0;
1973         r.in.lm_password = NULL;
1974         r.in.lm_verifier = NULL;
1975         r.in.password3 = NULL;
1976         r.out.dominfo = &dominfo;
1977         r.out.reject = &reject;
1978
1979         unix_to_nt_time(&t, time(NULL));
1980
1981         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1982
1983         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1984                 if (reject && reject->reason != SAMR_REJECT_OTHER) {
1985                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
1986                                SAMR_REJECT_OTHER, reject->reason);
1987                         return false;
1988                 }
1989                 /* Perhaps the server has a 'min password age' set? */
1990
1991         } else if (!NT_STATUS_IS_OK(status)) {
1992                 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1993                 ret = false;
1994         }
1995         
1996         newpass = samr_rand_pass(tctx, 128);
1997
1998         mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1999
2000         E_md4hash(newpass, new_nt_hash);
2001
2002         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2003         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2004         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2005
2006         r.in.server = &server;
2007         r.in.account = &account;
2008         r.in.nt_password = &nt_pass;
2009         r.in.nt_verifier = &nt_verifier;
2010         r.in.lm_change = 0;
2011         r.in.lm_password = NULL;
2012         r.in.lm_verifier = NULL;
2013         r.in.password3 = NULL;
2014         r.out.dominfo = &dominfo;
2015         r.out.reject = &reject;
2016
2017         unix_to_nt_time(&t, time(NULL));
2018
2019         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2020
2021         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2022                 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2023                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
2024                                SAMR_REJECT_OTHER, reject->reason);
2025                         return false;
2026                 }
2027                 /* Perhaps the server has a 'min password age' set? */
2028
2029         } else {
2030                 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2031                 *password = talloc_strdup(tctx, newpass);
2032         }
2033
2034         return ret;
2035 }
2036
2037
2038 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2039                                   struct policy_handle *alias_handle)
2040 {
2041         struct samr_GetMembersInAlias r;
2042         struct lsa_SidArray sids;
2043         NTSTATUS status;
2044
2045         torture_comment(tctx, "Testing GetMembersInAlias\n");
2046
2047         r.in.alias_handle = alias_handle;
2048         r.out.sids = &sids;
2049
2050         status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2051         torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2052
2053         return true;
2054 }
2055
2056 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2057                                   struct policy_handle *alias_handle,
2058                                   const struct dom_sid *domain_sid)
2059 {
2060         struct samr_AddAliasMember r;
2061         struct samr_DeleteAliasMember d;
2062         NTSTATUS status;
2063         struct dom_sid *sid;
2064
2065         sid = dom_sid_add_rid(tctx, domain_sid, 512);
2066
2067         torture_comment(tctx, "testing AddAliasMember\n");
2068         r.in.alias_handle = alias_handle;
2069         r.in.sid = sid;
2070
2071         status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2072         torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2073
2074         d.in.alias_handle = alias_handle;
2075         d.in.sid = sid;
2076
2077         status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2078         torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2079
2080         return true;
2081 }
2082
2083 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2084                                            struct policy_handle *alias_handle)
2085 {
2086         struct samr_AddMultipleMembersToAlias a;
2087         struct samr_RemoveMultipleMembersFromAlias r;
2088         NTSTATUS status;
2089         struct lsa_SidArray sids;
2090
2091         torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2092         a.in.alias_handle = alias_handle;
2093         a.in.sids = &sids;
2094
2095         sids.num_sids = 3;
2096         sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2097
2098         sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2099         sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2100         sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2101
2102         status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2103         torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2104
2105
2106         torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2107         r.in.alias_handle = alias_handle;
2108         r.in.sids = &sids;
2109
2110         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2111         torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2112
2113         /* strange! removing twice doesn't give any error */
2114         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2115         torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2116
2117         /* but removing an alias that isn't there does */
2118         sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2119
2120         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2121         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2122
2123         return true;
2124 }
2125
2126 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2127                                             struct policy_handle *user_handle)
2128 {
2129         struct samr_TestPrivateFunctionsUser r;
2130         NTSTATUS status;
2131
2132         torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2133
2134         r.in.user_handle = user_handle;
2135
2136         status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2137         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2138
2139         return true;
2140 }
2141
2142
2143 static bool test_user_ops(struct dcerpc_pipe *p, 
2144                           struct torture_context *tctx,
2145                           struct policy_handle *user_handle, 
2146                           struct policy_handle *domain_handle, 
2147                           uint32_t base_acct_flags, 
2148                           const char *base_acct_name, enum torture_samr_choice which_ops)
2149 {
2150         char *password = NULL;
2151         struct samr_QueryUserInfo q;
2152         union samr_UserInfo *info;
2153         NTSTATUS status;
2154
2155         bool ret = true;
2156         int i;
2157         uint32_t rid;
2158         const uint32_t password_fields[] = {
2159                 SAMR_FIELD_PASSWORD,
2160                 SAMR_FIELD_PASSWORD2,
2161                 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2162                 0
2163         };
2164         
2165         status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2166         if (!NT_STATUS_IS_OK(status)) {
2167                 ret = false;
2168         }
2169
2170         switch (which_ops) {
2171         case TORTURE_SAMR_USER_ATTRIBUTES:
2172                 if (!test_QuerySecurity(p, tctx, user_handle)) {
2173                         ret = false;
2174                 }
2175
2176                 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2177                         ret = false;
2178                 }
2179
2180                 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2181                         ret = false;
2182                 }
2183
2184                 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2185                                       base_acct_name)) {
2186                         ret = false;
2187                 }       
2188
2189                 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2190                         ret = false;
2191                 }
2192
2193                 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2194                         ret = false;
2195                 }
2196
2197                 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2198                         ret = false;
2199                 }
2200                 break;
2201         case TORTURE_SAMR_PASSWORDS:
2202                 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2203                         char simple_pass[9];
2204                         char *v = generate_random_str(tctx, 1);
2205                         
2206                         ZERO_STRUCT(simple_pass);
2207                         memset(simple_pass, *v, sizeof(simple_pass) - 1);
2208
2209                         printf("Testing machine account password policy rules\n");
2210
2211                         /* Workstation trust accounts don't seem to need to honour password quality policy */
2212                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2213                                 ret = false;
2214                         }
2215
2216                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2217                                 ret = false;
2218                         }
2219
2220                         /* reset again, to allow another 'user' password change */
2221                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2222                                 ret = false;
2223                         }
2224
2225                         /* Try a 'short' password */
2226                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2227                                 ret = false;
2228                         }
2229
2230                         /* Try a compleatly random password */
2231                         if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
2232                                 ret = false;
2233                         }
2234                 }
2235                 
2236                 for (i = 0; password_fields[i]; i++) {
2237                         if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2238                                 ret = false;
2239                         }       
2240                 
2241                         /* check it was set right */
2242                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2243                                 ret = false;
2244                         }
2245                 }               
2246
2247                 for (i = 0; password_fields[i]; i++) {
2248                         if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2249                                 ret = false;
2250                         }       
2251                 
2252                         /* check it was set right */
2253                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2254                                 ret = false;
2255                         }
2256                 }               
2257
2258                 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2259                         ret = false;
2260                 }       
2261
2262                 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2263                         ret = false;
2264                 }       
2265
2266                 q.in.user_handle = user_handle;
2267                 q.in.level = 5;
2268                 q.out.info = &info;
2269                 
2270                 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2271                 if (!NT_STATUS_IS_OK(status)) {
2272                         printf("QueryUserInfo level %u failed - %s\n", 
2273                                q.in.level, nt_errstr(status));
2274                         ret = false;
2275                 } else {
2276                         uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2277                         if ((info->info5.acct_flags) != expected_flags) {
2278                                 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2279                                        info->info5.acct_flags,
2280                                        expected_flags);
2281                                 ret = false;
2282                         }
2283                         if (info->info5.rid != rid) {
2284                                 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2285                                        info->info5.rid, rid);
2286
2287                         }
2288                 }
2289
2290                 break;
2291         case TORTURE_SAMR_OTHER:
2292                 /* We just need the account to exist */
2293                 break;
2294         }
2295         return ret;
2296 }
2297
2298 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2299                            struct policy_handle *alias_handle,
2300                            const struct dom_sid *domain_sid)
2301 {
2302         bool ret = true;
2303
2304         if (!test_QuerySecurity(p, tctx, alias_handle)) {
2305                 ret = false;
2306         }
2307
2308         if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2309                 ret = false;
2310         }
2311
2312         if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2313                 ret = false;
2314         }
2315
2316         if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2317                 ret = false;
2318         }
2319
2320         if (torture_setting_bool(tctx, "samba4", false)) {
2321                 printf("skipping MultipleMembers Alias tests against Samba4\n");
2322                 return ret;
2323         }
2324
2325         if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2326                 ret = false;
2327         }
2328
2329         return ret;
2330 }
2331
2332
2333 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2334                                      struct policy_handle *user_handle)
2335 {
2336         struct samr_DeleteUser d;
2337         NTSTATUS status;
2338         torture_comment(tctx, "Testing DeleteUser\n");
2339
2340         d.in.user_handle = user_handle;
2341         d.out.user_handle = user_handle;
2342
2343         status = dcerpc_samr_DeleteUser(p, tctx, &d);
2344         torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
2345
2346         return true;
2347 }
2348
2349 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2350                             struct policy_handle *handle, const char *name)
2351 {
2352         NTSTATUS status;
2353         struct samr_DeleteUser d;
2354         struct policy_handle user_handle;
2355         uint32_t rid;
2356
2357         status = test_LookupName(p, mem_ctx, handle, name, &rid);
2358         if (!NT_STATUS_IS_OK(status)) {
2359                 goto failed;
2360         }
2361
2362         status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2363         if (!NT_STATUS_IS_OK(status)) {
2364                 goto failed;
2365         }
2366
2367         d.in.user_handle = &user_handle;
2368         d.out.user_handle = &user_handle;
2369         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2370         if (!NT_STATUS_IS_OK(status)) {
2371                 goto failed;
2372         }
2373
2374         return true;
2375
2376 failed:
2377         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2378         return false;
2379 }
2380
2381
2382 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2383                                     struct policy_handle *handle, const char *name)
2384 {
2385         NTSTATUS status;
2386         struct samr_OpenGroup r;
2387         struct samr_DeleteDomainGroup d;
2388         struct policy_handle group_handle;
2389         uint32_t rid;
2390
2391         status = test_LookupName(p, mem_ctx, handle, name, &rid);
2392         if (!NT_STATUS_IS_OK(status)) {
2393                 goto failed;
2394         }
2395
2396         r.in.domain_handle = handle;
2397         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2398         r.in.rid = rid;
2399         r.out.group_handle = &group_handle;
2400         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2401         if (!NT_STATUS_IS_OK(status)) {
2402                 goto failed;
2403         }
2404
2405         d.in.group_handle = &group_handle;
2406         d.out.group_handle = &group_handle;
2407         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2408         if (!NT_STATUS_IS_OK(status)) {
2409                 goto failed;
2410         }
2411
2412         return true;
2413
2414 failed:
2415         printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2416         return false;
2417 }
2418
2419
2420 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2421                                    struct policy_handle *domain_handle, const char *name)
2422 {
2423         NTSTATUS status;
2424         struct samr_OpenAlias r;
2425         struct samr_DeleteDomAlias d;
2426         struct policy_handle alias_handle;
2427         uint32_t rid;
2428
2429         printf("testing DeleteAlias_byname\n");
2430
2431         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2432         if (!NT_STATUS_IS_OK(status)) {
2433                 goto failed;
2434         }
2435
2436         r.in.domain_handle = domain_handle;
2437         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2438         r.in.rid = rid;
2439         r.out.alias_handle = &alias_handle;
2440         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2441         if (!NT_STATUS_IS_OK(status)) {
2442                 goto failed;
2443         }
2444
2445         d.in.alias_handle = &alias_handle;
2446         d.out.alias_handle = &alias_handle;
2447         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2448         if (!NT_STATUS_IS_OK(status)) {
2449                 goto failed;
2450         }
2451
2452         return true;
2453
2454 failed:
2455         printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2456         return false;
2457 }
2458
2459 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2460                                      struct policy_handle *alias_handle)
2461 {
2462         struct samr_DeleteDomAlias d;
2463         NTSTATUS status;
2464         bool ret = true;
2465         printf("Testing DeleteAlias\n");
2466
2467         d.in.alias_handle = alias_handle;
2468         d.out.alias_handle = alias_handle;
2469
2470         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2471         if (!NT_STATUS_IS_OK(status)) {
2472                 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2473                 ret = false;
2474         }
2475
2476         return ret;
2477 }
2478
2479 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2480                             struct policy_handle *domain_handle, 
2481                              struct policy_handle *alias_handle, 
2482                              const struct dom_sid *domain_sid)
2483 {
2484         NTSTATUS status;
2485         struct samr_CreateDomAlias r;
2486         struct lsa_String name;
2487         uint32_t rid;
2488         bool ret = true;
2489
2490         init_lsa_String(&name, TEST_ALIASNAME);
2491         r.in.domain_handle = domain_handle;
2492         r.in.alias_name = &name;
2493         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2494         r.out.alias_handle = alias_handle;
2495         r.out.rid = &rid;
2496
2497         printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2498
2499         status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2500
2501         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2502                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2503                         printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
2504                         return true;
2505                 } else {
2506                         printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string, 
2507                                nt_errstr(status));
2508                         return false;
2509                 }
2510         }
2511
2512         if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2513                 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
2514                         return false;
2515                 }
2516                 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2517         }
2518
2519         if (!NT_STATUS_IS_OK(status)) {
2520                 printf("CreateAlias failed - %s\n", nt_errstr(status));
2521                 return false;
2522         }
2523
2524         if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
2525                 ret = false;
2526         }
2527
2528         return ret;
2529 }
2530
2531 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2532                                 const char *acct_name,
2533                                 struct policy_handle *domain_handle, char **password)
2534 {
2535         bool ret = true;
2536
2537         if (!*password) {
2538                 return false;
2539         }
2540
2541         if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2542                 ret = false;
2543         }
2544
2545         if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
2546                 ret = false;
2547         }
2548
2549         if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2550                 ret = false;
2551         }
2552
2553         /* test what happens when setting the old password again */
2554         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
2555                 ret = false;
2556         }
2557
2558         {
2559                 char simple_pass[9];
2560                 char *v = generate_random_str(mem_ctx, 1);
2561
2562                 ZERO_STRUCT(simple_pass);
2563                 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2564
2565                 /* test what happens when picking a simple password */
2566                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
2567                         ret = false;
2568                 }
2569         }
2570
2571         /* set samr_SetDomainInfo level 1 with min_length 5 */
2572         {
2573                 struct samr_QueryDomainInfo r;
2574                 union samr_DomainInfo *info = NULL;
2575                 struct samr_SetDomainInfo s;
2576                 uint16_t len_old, len;
2577                 uint32_t pwd_prop_old;
2578                 int64_t min_pwd_age_old;
2579                 NTSTATUS status;
2580
2581                 len = 5;
2582
2583                 r.in.domain_handle = domain_handle;
2584                 r.in.level = 1;
2585                 r.out.info = &info;
2586
2587                 printf("testing samr_QueryDomainInfo level 1\n");
2588                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2589                 if (!NT_STATUS_IS_OK(status)) {
2590                         return false;
2591                 }
2592
2593                 s.in.domain_handle = domain_handle;
2594                 s.in.level = 1;
2595                 s.in.info = info;
2596
2597                 /* remember the old min length, so we can reset it */
2598                 len_old = s.in.info->info1.min_password_length;
2599                 s.in.info->info1.min_password_length = len;
2600                 pwd_prop_old = s.in.info->info1.password_properties;
2601                 /* turn off password complexity checks for this test */
2602                 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2603
2604                 min_pwd_age_old = s.in.info->info1.min_password_age;
2605                 s.in.info->info1.min_password_age = 0;
2606
2607                 printf("testing samr_SetDomainInfo level 1\n");
2608                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2609                 if (!NT_STATUS_IS_OK(status)) {
2610                         return false;
2611                 }
2612
2613                 printf("calling test_ChangePasswordUser3 with too short password\n");
2614
2615                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
2616                         ret = false;
2617                 }
2618
2619                 s.in.info->info1.min_password_length = len_old;
2620                 s.in.info->info1.password_properties = pwd_prop_old;
2621                 s.in.info->info1.min_password_age = min_pwd_age_old;
2622                 
2623                 printf("testing samr_SetDomainInfo level 1\n");
2624                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2625                 if (!NT_STATUS_IS_OK(status)) {
2626                         return false;
2627                 }
2628
2629         }
2630
2631         {
2632                 NTSTATUS status;
2633                 struct samr_OpenUser r;
2634                 struct samr_QueryUserInfo q;
2635                 union samr_UserInfo *info;
2636                 struct samr_LookupNames n;
2637                 struct policy_handle user_handle;
2638                 struct samr_Ids rids, types;
2639
2640                 n.in.domain_handle = domain_handle;
2641                 n.in.num_names = 1;
2642                 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2643                 n.in.names[0].string = acct_name; 
2644                 n.out.rids = &rids;
2645                 n.out.types = &types;
2646
2647                 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2648                 if (!NT_STATUS_IS_OK(status)) {
2649                         printf("LookupNames failed - %s\n", nt_errstr(status));
2650                         return false;
2651                 }
2652
2653                 r.in.domain_handle = domain_handle;
2654                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2655                 r.in.rid = n.out.rids->ids[0];
2656                 r.out.user_handle = &user_handle;
2657
2658                 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2659                 if (!NT_STATUS_IS_OK(status)) {
2660                         printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
2661                         return false;
2662                 }
2663
2664                 q.in.user_handle = &user_handle;
2665                 q.in.level = 5;
2666                 q.out.info = &info;
2667
2668                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2669                 if (!NT_STATUS_IS_OK(status)) {
2670                         printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2671                         return false;
2672                 }
2673
2674                 printf("calling test_ChangePasswordUser3 with too early password change\n");
2675
2676                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 
2677                                               info->info5.last_password_change, true)) {
2678                         ret = false;
2679                 }
2680         }
2681
2682         /* we change passwords twice - this has the effect of verifying
2683            they were changed correctly for the final call */
2684         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2685                 ret = false;
2686         }
2687
2688         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2689                 ret = false;
2690         }
2691
2692         return ret;
2693 }
2694
2695 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2696                             struct policy_handle *domain_handle, 
2697                             struct policy_handle *user_handle_out,
2698                             struct dom_sid *domain_sid, 
2699                             enum torture_samr_choice which_ops)
2700 {
2701
2702         TALLOC_CTX *user_ctx;
2703
2704         NTSTATUS status;
2705         struct samr_CreateUser r;
2706         struct samr_QueryUserInfo q;
2707         union samr_UserInfo *info;
2708         struct samr_DeleteUser d;
2709         uint32_t rid;
2710
2711         /* This call creates a 'normal' account - check that it really does */
2712         const uint32_t acct_flags = ACB_NORMAL;
2713         struct lsa_String name;
2714         bool ret = true;
2715
2716         struct policy_handle user_handle;
2717         user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2718         init_lsa_String(&name, TEST_ACCOUNT_NAME);
2719
2720         r.in.domain_handle = domain_handle;
2721         r.in.account_name = &name;
2722         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2723         r.out.user_handle = &user_handle;
2724         r.out.rid = &rid;
2725
2726         printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2727
2728         status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2729
2730         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2731                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2732                         printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2733                         return true;
2734                 } else {
2735                         printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string, 
2736                                nt_errstr(status));
2737                         return false;
2738                 }
2739         }
2740
2741         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2742                 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2743                         talloc_free(user_ctx);
2744                         return false;
2745                 }
2746                 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2747         }
2748         if (!NT_STATUS_IS_OK(status)) {
2749                 talloc_free(user_ctx);
2750                 printf("CreateUser failed - %s\n", nt_errstr(status));
2751                 return false;
2752         } else {
2753                 q.in.user_handle = &user_handle;
2754                 q.in.level = 16;
2755                 q.out.info = &info;
2756                 
2757                 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2758                 if (!NT_STATUS_IS_OK(status)) {
2759                         printf("QueryUserInfo level %u failed - %s\n", 
2760                                q.in.level, nt_errstr(status));
2761                         ret = false;
2762                 } else {
2763                         if ((info->info16.acct_flags & acct_flags) != acct_flags) {
2764                                 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2765                                        info->info16.acct_flags,
2766                                        acct_flags);
2767                                 ret = false;
2768                         }
2769                 }
2770                 
2771                 if (!test_user_ops(p, tctx, &user_handle, domain_handle, 
2772                                    acct_flags, name.string, which_ops)) {
2773                         ret = false;
2774                 }
2775                 
2776                 if (user_handle_out) {
2777                         *user_handle_out = user_handle;
2778                 } else {
2779                         printf("Testing DeleteUser (createuser test)\n");
2780                         
2781                         d.in.user_handle = &user_handle;
2782                         d.out.user_handle = &user_handle;
2783                         
2784                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2785                         if (!NT_STATUS_IS_OK(status)) {
2786                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
2787                                 ret = false;
2788                         }
2789                 }
2790                 
2791         }
2792
2793         talloc_free(user_ctx);
2794         
2795         return ret;
2796 }
2797
2798
2799 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2800                              struct policy_handle *domain_handle,
2801                              struct dom_sid *domain_sid,
2802                              enum torture_samr_choice which_ops)
2803 {
2804         NTSTATUS status;
2805         struct samr_CreateUser2 r;
2806         struct samr_QueryUserInfo q;
2807         union samr_UserInfo *info;
2808         struct samr_DeleteUser d;
2809         struct policy_handle user_handle;
2810         uint32_t rid;
2811         struct lsa_String name;
2812         bool ret = true;
2813         int i;
2814
2815         struct {
2816                 uint32_t acct_flags;
2817                 const char *account_name;
2818                 NTSTATUS nt_status;
2819         } account_types[] = {
2820                 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2821                 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2822                 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2823                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2824                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2825                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2826                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2827                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2828                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2829                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2830                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2831                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2832                 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2833                 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2834                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2835         };
2836
2837         for (i = 0; account_types[i].account_name; i++) {
2838                 TALLOC_CTX *user_ctx;
2839                 uint32_t acct_flags = account_types[i].acct_flags;
2840                 uint32_t access_granted;
2841                 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2842                 init_lsa_String(&name, account_types[i].account_name);
2843
2844                 r.in.domain_handle = domain_handle;
2845                 r.in.account_name = &name;
2846                 r.in.acct_flags = acct_flags;
2847                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2848                 r.out.user_handle = &user_handle;
2849                 r.out.access_granted = &access_granted;
2850                 r.out.rid = &rid;
2851                 
2852                 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2853                 
2854                 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2855                 
2856                 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2857                         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2858                                 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2859                                 continue;
2860                         } else {
2861                                 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string, 
2862                                        nt_errstr(status));
2863                                 ret = false;
2864                                 continue;
2865                         }
2866                 }
2867
2868                 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2869                         if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2870                                 talloc_free(user_ctx);
2871                                 ret = false;
2872                                 continue;
2873                         }
2874                         status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2875
2876                 }
2877                 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2878                         printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n", 
2879                                nt_errstr(status), nt_errstr(account_types[i].nt_status));
2880                         ret = false;
2881                 }
2882                 
2883                 if (NT_STATUS_IS_OK(status)) {
2884                         q.in.user_handle = &user_handle;
2885                         q.in.level = 5;
2886                         q.out.info = &info;
2887                         
2888                         status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2889                         if (!NT_STATUS_IS_OK(status)) {
2890                                 printf("QueryUserInfo level %u failed - %s\n", 
2891                                        q.in.level, nt_errstr(status));
2892                                 ret = false;
2893                         } else {
2894                                 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2895                                 if (acct_flags == ACB_NORMAL) {
2896                                         expected_flags |= ACB_PW_EXPIRED;
2897                                 }
2898                                 if ((info->info5.acct_flags) != expected_flags) {
2899                                         printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2900                                                info->info5.acct_flags,
2901                                                expected_flags);
2902                                         ret = false;
2903                                 } 
2904                                 switch (acct_flags) {
2905                                 case ACB_SVRTRUST:
2906                                         if (info->info5.primary_gid != DOMAIN_RID_DCS) {
2907                                                 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n", 
2908                                                        DOMAIN_RID_DCS, info->info5.primary_gid);
2909                                                 ret = false;
2910                                         }
2911                                         break;
2912                                 case ACB_WSTRUST:
2913                                         if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2914                                                 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n", 
2915                                                        DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
2916                                                 ret = false;
2917                                         }
2918                                         break;
2919                                 case ACB_NORMAL:
2920                                         if (info->info5.primary_gid != DOMAIN_RID_USERS) {
2921                                                 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n", 
2922                                                        DOMAIN_RID_USERS, info->info5.primary_gid);
2923                                                 ret = false;
2924                                         }
2925                                         break;
2926                                 }
2927                         }
2928                 
2929                         if (!test_user_ops(p, tctx, &user_handle, domain_handle, 
2930                                            acct_flags, name.string, which_ops)) {
2931                                 ret = false;
2932                         }
2933
2934                         printf("Testing DeleteUser (createuser2 test)\n");
2935                 
2936                         d.in.user_handle = &user_handle;
2937                         d.out.user_handle = &user_handle;
2938                         
2939                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2940                         if (!NT_STATUS_IS_OK(status)) {
2941                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
2942                                 ret = false;
2943                         }
2944                 }
2945                 talloc_free(user_ctx);
2946         }
2947
2948         return ret;
2949 }
2950
2951 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2952                                 struct policy_handle *handle)
2953 {
2954         NTSTATUS status;
2955         struct samr_QueryAliasInfo r;
2956         union samr_AliasInfo *info;
2957         uint16_t levels[] = {1, 2, 3};
2958         int i;
2959         bool ret = true;
2960
2961         for (i=0;i<ARRAY_SIZE(levels);i++) {
2962                 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2963
2964                 r.in.alias_handle = handle;
2965                 r.in.level = levels[i];
2966                 r.out.info = &info;
2967
2968                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2969                 if (!NT_STATUS_IS_OK(status)) {
2970                         printf("QueryAliasInfo level %u failed - %s\n", 
2971                                levels[i], nt_errstr(status));
2972                         ret = false;
2973                 }
2974         }
2975
2976         return ret;
2977 }
2978
2979 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2980                                 struct policy_handle *handle)
2981 {
2982         NTSTATUS status;
2983         struct samr_QueryGroupInfo r;
2984         union samr_GroupInfo *info;
2985         uint16_t levels[] = {1, 2, 3, 4, 5};
2986         int i;
2987         bool ret = true;
2988
2989         for (i=0;i<ARRAY_SIZE(levels);i++) {
2990                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2991
2992                 r.in.group_handle = handle;
2993                 r.in.level = levels[i];
2994                 r.out.info = &info;
2995
2996                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2997                 if (!NT_STATUS_IS_OK(status)) {
2998                         printf("QueryGroupInfo level %u failed - %s\n", 
2999                                levels[i], nt_errstr(status));
3000                         ret = false;
3001                 }
3002         }
3003
3004         return ret;
3005 }
3006
3007 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3008                                   struct policy_handle *handle)
3009 {
3010         NTSTATUS status;
3011         struct samr_QueryGroupMember r;
3012         struct samr_RidTypeArray *rids = NULL;
3013         bool ret = true;
3014
3015         printf("Testing QueryGroupMember\n");
3016
3017         r.in.group_handle = handle;
3018         r.out.rids = &rids;
3019
3020         status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
3021         if (!NT_STATUS_IS_OK(status)) {
3022                 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
3023                 ret = false;
3024         }
3025
3026         return ret;
3027 }
3028
3029
3030 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3031                               struct policy_handle *handle)
3032 {
3033         NTSTATUS status;
3034         struct samr_QueryGroupInfo r;
3035         union samr_GroupInfo *info;
3036         struct samr_SetGroupInfo s;
3037         uint16_t levels[] = {1, 2, 3, 4};
3038         uint16_t set_ok[] = {0, 1, 1, 1};
3039         int i;
3040         bool ret = true;
3041
3042         for (i=0;i<ARRAY_SIZE(levels);i++) {
3043                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3044
3045                 r.in.group_handle = handle;
3046                 r.in.level = levels[i];
3047                 r.out.info = &info;
3048
3049                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3050                 if (!NT_STATUS_IS_OK(status)) {
3051                         printf("QueryGroupInfo level %u failed - %s\n", 
3052                                levels[i], nt_errstr(status));
3053                         ret = false;
3054                 }
3055
3056                 printf("Testing SetGroupInfo level %u\n", levels[i]);
3057
3058                 s.in.group_handle = handle;
3059                 s.in.level = levels[i];
3060                 s.in.info = *r.out.info;
3061
3062 #if 0
3063                 /* disabled this, as it changes the name only from the point of view of samr, 
3064                    but leaves the name from the point of view of w2k3 internals (and ldap). This means
3065                    the name is still reserved, so creating the old name fails, but deleting by the old name
3066                    also fails */
3067                 if (s.in.level == 2) {
3068                         init_lsa_String(&s.in.info->string, "NewName");
3069                 }
3070 #endif
3071
3072                 if (s.in.level == 4) {
3073                         init_lsa_String(&s.in.info->description, "test description");
3074                 }
3075
3076                 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
3077                 if (set_ok[i]) {
3078                         if (!NT_STATUS_IS_OK(status)) {
3079                                 printf("SetGroupInfo level %u failed - %s\n", 
3080                                        r.in.level, nt_errstr(status));
3081                                 ret = false;
3082                                 continue;
3083                         }
3084                 } else {
3085                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3086                                 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
3087                                        r.in.level, nt_errstr(status));
3088                                 ret = false;
3089                                 continue;
3090                         }
3091                 }
3092         }
3093
3094         return ret;
3095 }
3096
3097 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3098                                struct policy_handle *handle)
3099 {
3100         NTSTATUS status;
3101         struct samr_QueryUserInfo r;
3102         union samr_UserInfo *info;
3103         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3104                            11, 12, 13, 14, 16, 17, 20, 21};
3105         int i;
3106         bool ret = true;
3107
3108         for (i=0;i<ARRAY_SIZE(levels);i++) {
3109                 printf("Testing QueryUserInfo level %u\n", levels[i]);
3110
3111                 r.in.user_handle = handle;
3112                 r.in.level = levels[i];
3113                 r.out.info = &info;
3114
3115                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
3116                 if (!NT_STATUS_IS_OK(status)) {
3117                         printf("QueryUserInfo level %u failed - %s\n", 
3118                                levels[i], nt_errstr(status));
3119                         ret = false;
3120                 }
3121         }
3122
3123         return ret;
3124 }
3125
3126 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3127                                 struct policy_handle *handle)
3128 {
3129         NTSTATUS status;
3130         struct samr_QueryUserInfo2 r;
3131         union samr_UserInfo *info;
3132         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3133                            11, 12, 13, 14, 16, 17, 20, 21};
3134         int i;
3135         bool ret = true;
3136
3137         for (i=0;i<ARRAY_SIZE(levels);i++) {
3138                 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
3139
3140                 r.in.user_handle = handle;
3141                 r.in.level = levels[i];
3142                 r.out.info = &info;
3143
3144                 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
3145                 if (!NT_STATUS_IS_OK(status)) {
3146                         printf("QueryUserInfo2 level %u failed - %s\n", 
3147                                levels[i], nt_errstr(status));
3148                         ret = false;
3149                 }
3150         }
3151
3152         return ret;
3153 }
3154
3155 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3156                           struct policy_handle *handle, uint32_t rid)
3157 {
3158         NTSTATUS status;
3159         struct samr_OpenUser r;
3160         struct policy_handle user_handle;
3161         bool ret = true;
3162
3163         printf("Testing OpenUser(%u)\n", rid);
3164
3165         r.in.domain_handle = handle;
3166         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3167         r.in.rid = rid;
3168         r.out.user_handle = &user_handle;
3169
3170         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3171         if (!NT_STATUS_IS_OK(status)) {
3172                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3173                 return false;
3174         }
3175
3176         if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
3177                 ret = false;
3178         }
3179
3180         if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
3181                 ret = false;
3182         }
3183
3184         if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
3185                 ret = false;
3186         }
3187
3188         if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
3189                 ret = false;
3190         }
3191
3192         if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
3193                 ret = false;
3194         }
3195
3196         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3197                 ret = false;
3198         }
3199
3200         return ret;
3201 }
3202
3203 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3204                            struct policy_handle *handle, uint32_t rid)
3205 {
3206         NTSTATUS status;
3207         struct samr_OpenGroup r;
3208         struct policy_handle group_handle;
3209         bool ret = true;
3210
3211         printf("Testing OpenGroup(%u)\n", rid);
3212
3213         r.in.domain_handle = handle;
3214         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3215         r.in.rid = rid;
3216         r.out.group_handle = &group_handle;
3217
3218         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3219         if (!NT_STATUS_IS_OK(status)) {
3220                 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
3221                 return false;
3222         }
3223
3224         if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
3225                 ret = false;
3226         }
3227
3228         if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
3229                 ret = false;
3230         }
3231
3232         if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
3233                 ret = false;
3234         }
3235
3236         if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3237                 ret = false;
3238         }
3239
3240         return ret;
3241 }
3242
3243 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3244                            struct policy_handle *handle, uint32_t rid)
3245 {
3246         NTSTATUS status;
3247         struct samr_OpenAlias r;
3248         struct policy_handle alias_handle;
3249         bool ret = true;
3250
3251         torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
3252
3253         r.in.domain_handle = handle;
3254         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3255         r.in.rid = rid;
3256         r.out.alias_handle = &alias_handle;
3257
3258         status = dcerpc_samr_OpenAlias(p, tctx, &r);
3259         if (!NT_STATUS_IS_OK(status)) {
3260                 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3261                 return false;
3262         }
3263
3264         if (!test_QuerySecurity(p, tctx, &alias_handle)) {
3265                 ret = false;
3266         }
3267
3268         if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
3269                 ret = false;
3270         }
3271
3272         if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
3273                 ret = false;
3274         }
3275
3276         if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
3277                 ret = false;
3278         }
3279
3280         return ret;
3281 }
3282
3283 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
3284                        struct policy_handle *handle, uint32_t rid, 
3285                        uint32_t acct_flag_mask)
3286 {
3287         NTSTATUS status;
3288         struct samr_OpenUser r;
3289         struct samr_QueryUserInfo q;
3290         union samr_UserInfo *info;
3291         struct policy_handle user_handle;
3292         bool ret = true;
3293
3294         torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
3295
3296         r.in.domain_handle = handle;
3297         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3298         r.in.rid = rid;
3299         r.out.user_handle = &user_handle;
3300
3301         status = dcerpc_samr_OpenUser(p, tctx, &r);
3302         if (!NT_STATUS_IS_OK(status)) {
3303                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3304                 return false;
3305         }
3306
3307         q.in.user_handle = &user_handle;
3308         q.in.level = 16;
3309         q.out.info = &info;
3310         
3311         status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3312         if (!NT_STATUS_IS_OK(status)) {
3313                 printf("QueryUserInfo level 16 failed - %s\n", 
3314                        nt_errstr(status));
3315                 ret = false;
3316         } else {
3317                 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
3318                         printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3319                                acct_flag_mask, info->info16.acct_flags, rid);
3320                         ret = false;
3321                 }
3322         }
3323         
3324         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
3325                 ret = false;
3326         }
3327
3328         return ret;
3329 }
3330
3331 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
3332                                  struct policy_handle *handle)
3333 {
3334         NTSTATUS status = STATUS_MORE_ENTRIES;
3335         struct samr_EnumDomainUsers r;
3336         uint32_t mask, resume_handle=0;
3337         int i, mask_idx;
3338         bool ret = true;
3339         struct samr_LookupNames n;
3340         struct samr_LookupRids  lr ;
3341         struct lsa_Strings names;
3342         struct samr_Ids rids, types;
3343         struct samr_SamArray *sam = NULL;
3344         uint32_t num_entries = 0;
3345
3346         uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST, 
3347                             ACB_DISABLED, ACB_NORMAL | ACB_DISABLED, 
3348                             ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST, 
3349                             ACB_PWNOEXP, 0};
3350
3351         printf("Testing EnumDomainUsers\n");
3352
3353         for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3354                 r.in.domain_handle = handle;
3355                 r.in.resume_handle = &resume_handle;
3356                 r.in.acct_flags = mask = masks[mask_idx];
3357                 r.in.max_size = (uint32_t)-1;
3358                 r.out.resume_handle = &resume_handle;
3359                 r.out.num_entries = &num_entries;
3360                 r.out.sam = &sam;
3361
3362                 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
3363                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&  
3364                     !NT_STATUS_IS_OK(status)) {
3365                         printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3366                         return false;
3367                 }
3368         
3369                 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
3370
3371                 if (sam->count == 0) {
3372                         continue;
3373                 }
3374
3375                 for (i=0;i<sam->count;i++) {
3376                         if (mask) {
3377                                 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
3378                                         ret = false;
3379                                 }
3380                         } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
3381                                 ret = false;
3382                         }
3383                 }
3384         }
3385
3386         printf("Testing LookupNames\n");
3387         n.in.domain_handle = handle;
3388         n.in.num_names = sam->count;
3389         n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
3390         n.out.rids = &rids;
3391         n.out.types = &types;
3392         for (i=0;i<sam->count;i++) {
3393                 n.in.names[i].string = sam->entries[i].name.string;
3394         }
3395         status = dcerpc_samr_LookupNames(p, tctx, &n);
3396         if (!NT_STATUS_IS_OK(status)) {
3397                 printf("LookupNames failed - %s\n", nt_errstr(status));
3398                 ret = false;
3399         }
3400
3401
3402         printf("Testing LookupRids\n");
3403         lr.in.domain_handle = handle;
3404         lr.in.num_rids = sam->count;
3405         lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
3406         lr.out.names = &names;
3407         lr.out.types = &types;
3408         for (i=0;i<sam->count;i++) {
3409                 lr.in.rids[i] = sam->entries[i].idx;
3410         }
3411         status = dcerpc_samr_LookupRids(p, tctx, &lr);
3412         torture_assert_ntstatus_ok(tctx, status, "LookupRids");
3413
3414         return ret;     
3415 }
3416
3417 /*
3418   try blasting the server with a bunch of sync requests
3419 */
3420 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx, 
3421                                        struct policy_handle *handle)
3422 {
3423         NTSTATUS status;
3424         struct samr_EnumDomainUsers r;
3425         uint32_t resume_handle=0;
3426         int i;
3427 #define ASYNC_COUNT 100
3428         struct rpc_request *req[ASYNC_COUNT];
3429
3430         if (!torture_setting_bool(tctx, "dangerous", false)) {
3431                 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
3432         }
3433
3434         torture_comment(tctx, "Testing EnumDomainUsers_async\n");
3435
3436         r.in.domain_handle = handle;
3437         r.in.resume_handle = &resume_handle;
3438         r.in.acct_flags = 0;
3439         r.in.max_size = (uint32_t)-1;
3440         r.out.resume_handle = &resume_handle;
3441
3442         for (i=0;i<ASYNC_COUNT;i++) {
3443                 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
3444         }
3445
3446         for (i=0;i<ASYNC_COUNT;i++) {
3447                 status = dcerpc_ndr_request_recv(req[i]);
3448                 if (!NT_STATUS_IS_OK(status)) {
3449                         printf("EnumDomainUsers[%d] failed - %s\n", 
3450                                i, nt_errstr(status));
3451                         return false;
3452                 }
3453         }
3454         
3455         torture_comment(tctx, "%d async requests OK\n", i);
3456
3457         return true;
3458 }
3459
3460 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3461                                   struct policy_handle *handle)
3462 {
3463         NTSTATUS status;
3464         struct samr_EnumDomainGroups r;
3465         uint32_t resume_handle=0;
3466         struct samr_SamArray *sam = NULL;
3467         uint32_t num_entries = 0;
3468         int i;
3469         bool ret = true;
3470
3471         printf("Testing EnumDomainGroups\n");
3472
3473         r.in.domain_handle = handle;
3474         r.in.resume_handle = &resume_handle;
3475         r.in.max_size = (uint32_t)-1;
3476         r.out.resume_handle = &resume_handle;
3477         r.out.num_entries = &num_entries;
3478         r.out.sam = &sam;
3479
3480         status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3481         if (!NT_STATUS_IS_OK(status)) {
3482                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3483                 return false;
3484         }
3485         
3486         if (!sam) {
3487                 return false;
3488         }
3489
3490         for (i=0;i<sam->count;i++) {
3491                 if (!test_OpenGroup(p, mem_ctx, handle, sam->entries[i].idx)) {
3492                         ret = false;
3493                 }
3494         }
3495
3496         return ret;
3497 }
3498
3499 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3500                                    struct policy_handle *handle)
3501 {
3502         NTSTATUS status;
3503         struct samr_EnumDomainAliases r;
3504         uint32_t resume_handle=0;
3505         struct samr_SamArray *sam = NULL;
3506         uint32_t num_entries = 0;
3507         int i;
3508         bool ret = true;
3509
3510         printf("Testing EnumDomainAliases\n");
3511
3512         r.in.domain_handle = handle;
3513         r.in.resume_handle = &resume_handle;
3514         r.in.max_size = (uint32_t)-1;
3515         r.out.sam = &sam;
3516         r.out.num_entries = &num_entries;
3517         r.out.resume_handle = &resume_handle;
3518
3519         status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3520         if (!NT_STATUS_IS_OK(status)) {
3521                 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3522                 return false;
3523         }
3524         
3525         if (!sam) {
3526                 return false;
3527         }
3528
3529         for (i=0;i<sam->count;i++) {
3530                 if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) {
3531                         ret = false;
3532                 }
3533         }
3534
3535         return ret;     
3536 }
3537
3538 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3539                                             struct policy_handle *handle)
3540 {
3541         NTSTATUS status;
3542         struct samr_GetDisplayEnumerationIndex r;
3543         bool ret = true;
3544         uint16_t levels[] = {1, 2, 3, 4, 5};
3545         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3546         struct lsa_String name;
3547         uint32_t idx = 0;
3548         int i;
3549
3550         for (i=0;i<ARRAY_SIZE(levels);i++) {
3551                 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3552
3553                 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3554
3555                 r.in.domain_handle = handle;
3556                 r.in.level = levels[i];
3557                 r.in.name = &name;
3558                 r.out.idx = &idx;
3559
3560                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3561
3562                 if (ok_lvl[i] && 
3563                     !NT_STATUS_IS_OK(status) &&
3564                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3565                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
3566                                levels[i], nt_errstr(status));
3567                         ret = false;
3568                 }
3569
3570                 init_lsa_String(&name, "zzzzzzzz");
3571
3572                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3573                 
3574                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3575                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
3576                                levels[i], nt_errstr(status));
3577                         ret = false;
3578                 }
3579         }
3580         
3581         return ret;     
3582 }
3583
3584 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3585                                              struct policy_handle *handle)
3586 {
3587         NTSTATUS status;
3588         struct samr_GetDisplayEnumerationIndex2 r;
3589         bool ret = true;
3590         uint16_t levels[] = {1, 2, 3, 4, 5};
3591         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3592         struct lsa_String name;
3593         uint32_t idx = 0;
3594         int i;
3595
3596         for (i=0;i<ARRAY_SIZE(levels);i++) {
3597                 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3598
3599                 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3600
3601                 r.in.domain_handle = handle;
3602                 r.in.level = levels[i];
3603                 r.in.name = &name;
3604                 r.out.idx = &idx;
3605
3606                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3607                 if (ok_lvl[i] && 
3608                     !NT_STATUS_IS_OK(status) && 
3609                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3610                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
3611                                levels[i], nt_errstr(status));
3612                         ret = false;
3613                 }
3614
3615                 init_lsa_String(&name, "zzzzzzzz");
3616
3617                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3618                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3619                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
3620                                levels[i], nt_errstr(status));
3621                         ret = false;
3622                 }
3623         }
3624         
3625         return ret;     
3626 }
3627
3628 #define STRING_EQUAL_QUERY(s1, s2, user)                                        \
3629         if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3630                 /* odd, but valid */                                            \
3631         } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3632                         printf("%s mismatch for %s: %s != %s (%s)\n", \
3633                                #s1, user.string,  s1.string, s2.string, __location__);   \
3634                         ret = false; \
3635         }
3636 #define INT_EQUAL_QUERY(s1, s2, user)           \
3637                 if (s1 != s2) { \
3638                         printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3639                                #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3640                         ret = false; \
3641                 }
3642
3643 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3644                                        struct samr_QueryDisplayInfo *querydisplayinfo,
3645                                        bool *seen_testuser) 
3646 {
3647         struct samr_OpenUser r;
3648         struct samr_QueryUserInfo q;
3649         union samr_UserInfo *info;
3650         struct policy_handle user_handle;
3651         int i, ret = true;
3652         NTSTATUS status;
3653         r.in.domain_handle = querydisplayinfo->in.domain_handle;
3654         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3655         for (i = 0; ; i++) {
3656                 switch (querydisplayinfo->in.level) {
3657                 case 1:
3658                         if (i >= querydisplayinfo->out.info->info1.count) {
3659                                 return ret;
3660                         }
3661                         r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
3662                         break;
3663                 case 2:
3664                         if (i >= querydisplayinfo->out.info->info2.count) {
3665                                 return ret;
3666                         }
3667                         r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
3668                         break;
3669                 case 3:
3670                         /* Groups */
3671                 case 4:
3672                 case 5:
3673                         /* Not interested in validating just the account name */
3674                         return true;
3675                 }
3676                         
3677                 r.out.user_handle = &user_handle;
3678                 
3679                 switch (querydisplayinfo->in.level) {
3680                 case 1:
3681                 case 2:
3682                         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3683                         if (!NT_STATUS_IS_OK(status)) {
3684                                 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3685                                 return false;
3686                         }
3687                 }
3688                 
3689                 q.in.user_handle = &user_handle;
3690                 q.in.level = 21;
3691                 q.out.info = &info;
3692                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3693                 if (!NT_STATUS_IS_OK(status)) {
3694                         printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3695                         return false;
3696                 }
3697                 
3698                 switch (querydisplayinfo->in.level) {
3699                 case 1:
3700                         if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3701                                 *seen_testuser = true;
3702                         }
3703                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
3704                                            info->info21.full_name, info->info21.account_name);
3705                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
3706                                            info->info21.account_name, info->info21.account_name);
3707                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
3708                                            info->info21.description, info->info21.account_name);
3709                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
3710                                         info->info21.rid, info->info21.account_name);
3711                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
3712                                         info->info21.acct_flags, info->info21.account_name);
3713                         
3714                         break;
3715                 case 2:
3716                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
3717                                            info->info21.account_name, info->info21.account_name);
3718                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
3719                                            info->info21.description, info->info21.account_name);
3720                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
3721                                         info->info21.rid, info->info21.account_name);
3722                         INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
3723                                         info->info21.acct_flags, info->info21.account_name);
3724                         
3725                         if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
3726                                 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n", 
3727                                        info->info21.account_name.string);
3728                         }
3729
3730                         if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3731                                 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3732                                        info->info21.account_name.string,
3733                                        querydisplayinfo->out.info->info2.entries[i].acct_flags,
3734                                        info->info21.acct_flags);
3735                                 return false;
3736                         }
3737                         
3738                         break;
3739                 }
3740                 
3741                 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3742                         return false;
3743                 }
3744         }
3745         return ret;
3746 }
3747
3748 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3749                                   struct policy_handle *handle)
3750 {
3751         NTSTATUS status;
3752         struct samr_QueryDisplayInfo r;
3753         struct samr_QueryDomainInfo dom_info;
3754         union samr_DomainInfo *info = NULL;
3755         bool ret = true;
3756         uint16_t levels[] = {1, 2, 3, 4, 5};
3757         int i;
3758         bool seen_testuser = false;
3759         uint32_t total_size;
3760         uint32_t returned_size;
3761         union samr_DispInfo disp_info;
3762
3763
3764         for (i=0;i<ARRAY_SIZE(levels);i++) {
3765                 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3766
3767                 r.in.start_idx = 0;
3768                 status = STATUS_MORE_ENTRIES;
3769                 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3770                         r.in.domain_handle = handle;
3771                         r.in.level = levels[i];
3772                         r.in.max_entries = 2;
3773                         r.in.buf_size = (uint32_t)-1;
3774                         r.out.total_size = &total_size;
3775                         r.out.returned_size = &returned_size;
3776                         r.out.info = &disp_info;
3777                         
3778                         status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3779                         if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3780                                 printf("QueryDisplayInfo level %u failed - %s\n", 
3781                                        levels[i], nt_errstr(status));
3782                                 ret = false;
3783                         }
3784                         switch (r.in.level) {
3785                         case 1:
3786                                 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3787                                         ret = false;
3788                                 }
3789                                 r.in.start_idx += r.out.info->info1.count;
3790                                 break;
3791                         case 2:
3792                                 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3793                                         ret = false;
3794                                 }
3795                                 r.in.start_idx += r.out.info->info2.count;
3796                                 break;
3797                         case 3:
3798                                 r.in.start_idx += r.out.info->info3.count;
3799                                 break;
3800                         case 4:
3801                                 r.in.start_idx += r.out.info->info4.count;
3802                                 break;
3803                         case 5:
3804                                 r.in.start_idx += r.out.info->info5.count;
3805                                 break;
3806                         }
3807                 }
3808                 dom_info.in.domain_handle = handle;
3809                 dom_info.in.level = 2;
3810                 dom_info.out.info = &info;
3811
3812                 /* Check number of users returned is correct */
3813                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3814                 if (!NT_STATUS_IS_OK(status)) {
3815                         printf("QueryDomainInfo level %u failed - %s\n", 
3816                                r.in.level, nt_errstr(status));
3817                                 ret = false;
3818                                 break;
3819                 }
3820                 switch (r.in.level) {
3821                 case 1:
3822                 case 4:
3823                         if (info->general.num_users < r.in.start_idx) {
3824                                 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3825                                        r.in.start_idx, info->general.num_groups,
3826                                        info->general.domain_name.string);
3827                                 ret = false;
3828                         }
3829                         if (!seen_testuser) {
3830                                 struct policy_handle user_handle;
3831                                 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3832                                         printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n", 
3833                                                info->general.domain_name.string);
3834                                         ret = false;
3835                                         test_samr_handle_Close(p, mem_ctx, &user_handle);
3836                                 }
3837                         }
3838                         break;
3839                 case 3:
3840                 case 5:
3841                         if (info->general.num_groups != r.in.start_idx) {
3842                                 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3843                                        r.in.start_idx, info->general.num_groups,
3844                                        info->general.domain_name.string);
3845                                 ret = false;
3846                         }
3847                         
3848                         break;
3849                 }
3850
3851         }
3852         
3853         return ret;     
3854 }
3855
3856 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3857                                   struct policy_handle *handle)
3858 {
3859         NTSTATUS status;
3860         struct samr_QueryDisplayInfo2 r;
3861         bool ret = true;
3862         uint16_t levels[] = {1, 2, 3, 4, 5};
3863         int i;
3864         uint32_t total_size;
3865         uint32_t returned_size;
3866         union samr_DispInfo info;
3867
3868         for (i=0;i<ARRAY_SIZE(levels);i++) {
3869                 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3870
3871                 r.in.domain_handle = handle;
3872                 r.in.level = levels[i];
3873                 r.in.start_idx = 0;
3874                 r.in.max_entries = 1000;
3875                 r.in.buf_size = (uint32_t)-1;
3876                 r.out.total_size = &total_size;
3877                 r.out.returned_size = &returned_size;
3878                 r.out.info = &info;
3879
3880                 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3881                 if (!NT_STATUS_IS_OK(status)) {
3882                         printf("QueryDisplayInfo2 level %u failed - %s\n", 
3883                                levels[i], nt_errstr(status));
3884                         ret = false;
3885                 }
3886         }
3887         
3888         return ret;     
3889 }
3890
3891 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
3892                                   struct policy_handle *handle)
3893 {
3894         NTSTATUS status;
3895         struct samr_QueryDisplayInfo3 r;
3896         bool ret = true;
3897         uint16_t levels[] = {1, 2, 3, 4, 5};
3898         int i;
3899         uint32_t total_size;
3900         uint32_t returned_size;
3901         union samr_DispInfo info;
3902
3903         for (i=0;i<ARRAY_SIZE(levels);i++) {
3904                 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
3905
3906                 r.in.domain_handle = handle;
3907                 r.in.level = levels[i];
3908                 r.in.start_idx = 0;
3909                 r.in.max_entries = 1000;
3910                 r.in.buf_size = (uint32_t)-1;
3911                 r.out.total_size = &total_size;
3912                 r.out.returned_size = &returned_size;
3913                 r.out.info = &info;
3914
3915                 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
3916                 if (!NT_STATUS_IS_OK(status)) {
3917                         printf("QueryDisplayInfo3 level %u failed - %s\n", 
3918                                levels[i], nt_errstr(status));
3919                         ret = false;
3920                 }
3921         }
3922         
3923         return ret;     
3924 }
3925
3926
3927 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3928                                            struct policy_handle *handle)
3929 {
3930         NTSTATUS status;
3931         struct samr_QueryDisplayInfo r;
3932         bool ret = true;
3933         uint32_t total_size;
3934         uint32_t returned_size;
3935         union samr_DispInfo info;
3936
3937         printf("Testing QueryDisplayInfo continuation\n");
3938
3939         r.in.domain_handle = handle;
3940         r.in.level = 1;
3941         r.in.start_idx = 0;
3942         r.in.max_entries = 1;
3943         r.in.buf_size = (uint32_t)-1;
3944         r.out.total_size = &total_size;
3945         r.out.returned_size = &returned_size;
3946         r.out.info = &info;
3947
3948         do {
3949                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3950                 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
3951                         if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
3952                                 printf("expected idx %d but got %d\n",
3953                                        r.in.start_idx + 1,
3954                                        r.out.info->info1.entries[0].idx);
3955                                 break;
3956                         }
3957                 }
3958                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3959                     !NT_STATUS_IS_OK(status)) {
3960                         printf("QueryDisplayInfo level %u failed - %s\n", 
3961                                r.in.level, nt_errstr(status));
3962                         ret = false;
3963                         break;
3964                 }
3965                 r.in.start_idx++;
3966         } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3967                   NT_STATUS_IS_OK(status)) &&
3968                  *r.out.returned_size != 0);
3969         
3970         return ret;     
3971 }
3972
3973 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
3974                                  struct policy_handle *handle)
3975 {
3976         NTSTATUS status;
3977         struct samr_QueryDomainInfo r;
3978         union samr_DomainInfo *info = NULL;
3979         struct samr_SetDomainInfo s;
3980         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3981         uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
3982         int i;
3983         bool ret = true;
3984         const char *domain_comment = talloc_asprintf(tctx, 
3985                                   "Tortured by Samba4 RPC-SAMR: %s", 
3986                                   timestring(tctx, time(NULL)));
3987
3988         s.in.domain_handle = handle;
3989         s.in.level = 4;
3990         s.in.info = talloc(tctx, union samr_DomainInfo);
3991         
3992         s.in.info->oem.oem_information.string = domain_comment;
3993         status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
3994         if (!NT_STATUS_IS_OK(status)) {
3995                 printf("SetDomainInfo level %u (set comment) failed - %s\n", 
3996                        r.in.level, nt_errstr(status));
3997                 return false;
3998         }
3999
4000         for (i=0;i<ARRAY_SIZE(levels);i++) {
4001                 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
4002
4003                 r.in.domain_handle = handle;
4004                 r.in.level = levels[i];
4005                 r.out.info = &info;
4006
4007                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4008                 if (!NT_STATUS_IS_OK(status)) {
4009                         printf("QueryDomainInfo level %u failed - %s\n", 
4010                                r.in.level, nt_errstr(status));
4011                         ret = false;
4012                         continue;
4013                 }
4014
4015                 switch (levels[i]) {
4016                 case 2:
4017                         if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
4018                                 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
4019                                        levels[i], info->general.oem_information.string, domain_comment);
4020                                 ret = false;
4021                         }
4022                         if (!info->general.primary.string) {
4023                                 printf("QueryDomainInfo level %u returned no PDC name\n",
4024                                        levels[i]);
4025                                 ret = false;
4026                         } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
4027                                 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
4028                                         printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
4029                                                levels[i], info->general.primary.string, dcerpc_server_name(p));
4030                                 }
4031                         }
4032                         break;
4033                 case 4:
4034                         if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
4035                                 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
4036                                        levels[i], info->oem.oem_information.string, domain_comment);
4037                                 ret = false;
4038                         }
4039                         break;
4040                 case 6:
4041                         if (!info->info6.primary.string) {
4042                                 printf("QueryDomainInfo level %u returned no PDC name\n",
4043                                        levels[i]);
4044                                 ret = false;
4045                         }
4046                         break;
4047                 case 11:
4048                         if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
4049                                 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
4050                                        levels[i], info->general2.general.oem_information.string, domain_comment);
4051                                 ret = false;
4052                         }
4053                         break;
4054                 }
4055
4056                 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
4057
4058                 s.in.domain_handle = handle;
4059                 s.in.level = levels[i];
4060                 s.in.info = info;
4061
4062                 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4063                 if (set_ok[i]) {
4064                         if (!NT_STATUS_IS_OK(status)) {
4065                                 printf("SetDomainInfo level %u failed - %s\n", 
4066                                        r.in.level, nt_errstr(status));
4067                                 ret = false;
4068                                 continue;
4069                         }
4070                 } else {
4071                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4072                                 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
4073                                        r.in.level, nt_errstr(status));
4074                                 ret = false;
4075                                 continue;
4076                         }
4077                 }
4078
4079                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4080                 if (!NT_STATUS_IS_OK(status)) {
4081                         printf("QueryDomainInfo level %u failed - %s\n", 
4082                                r.in.level, nt_errstr(status));
4083                         ret = false;
4084                         continue;
4085                 }
4086         }
4087
4088         return ret;     
4089 }
4090
4091
4092 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
4093                                   struct policy_handle *handle)
4094 {
4095         NTSTATUS status;
4096         struct samr_QueryDomainInfo2 r;
4097         union samr_DomainInfo *info = NULL;
4098         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4099         int i;
4100         bool ret = true;
4101
4102         for (i=0;i<ARRAY_SIZE(levels);i++) {
4103                 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
4104
4105                 r.in.domain_handle = handle;
4106                 r.in.level = levels[i];
4107                 r.out.info = &info;
4108
4109                 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
4110                 if (!NT_STATUS_IS_OK(status)) {
4111                         printf("QueryDomainInfo2 level %u failed - %s\n", 
4112                                r.in.level, nt_errstr(status));
4113                         ret = false;
4114                         continue;
4115                 }
4116         }
4117
4118         return true;    
4119 }
4120
4121 /* Test whether querydispinfo level 5 and enumdomgroups return the same
4122    set of group names. */
4123 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
4124                            struct policy_handle *handle)
4125 {
4126         struct samr_EnumDomainGroups q1;
4127         struct samr_QueryDisplayInfo q2;
4128         NTSTATUS status;
4129         uint32_t resume_handle=0;
4130         struct samr_SamArray *sam = NULL;
4131         uint32_t num_entries = 0;
4132         int i;
4133         bool ret = true;
4134         uint32_t total_size;
4135         uint32_t returned_size;
4136         union samr_DispInfo info;
4137
4138         int num_names = 0;
4139         const char **names = NULL;
4140
4141         torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
4142
4143         q1.in.domain_handle = handle;
4144         q1.in.resume_handle = &resume_handle;
4145         q1.in.max_size = 5;
4146         q1.out.resume_handle = &resume_handle;
4147         q1.out.num_entries = &num_entries;
4148         q1.out.sam = &sam;
4149
4150         status = STATUS_MORE_ENTRIES;
4151         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4152                 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
4153
4154                 if (!NT_STATUS_IS_OK(status) &&
4155                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4156                         break;
4157
4158                 for (i=0; i<*q1.out.num_entries; i++) {
4159                         add_string_to_array(tctx,
4160                                             sam->entries[i].name.string,
4161                                             &names, &num_names);
4162                 }
4163         }
4164
4165         torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
4166         
4167         torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
4168
4169         q2.in.domain_handle = handle;
4170         q2.in.level = 5;
4171         q2.in.start_idx = 0;
4172         q2.in.max_entries = 5;
4173         q2.in.buf_size = (uint32_t)-1;
4174         q2.out.total_size = &total_size;
4175         q2.out.returned_size = &returned_size;
4176         q2.out.info = &info;
4177
4178         status = STATUS_MORE_ENTRIES;
4179         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4180                 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
4181
4182                 if (!NT_STATUS_IS_OK(status) &&
4183                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4184                         break;
4185
4186                 for (i=0; i<q2.out.info->info5.count; i++) {
4187                         int j;
4188                         const char *name = q2.out.info->info5.entries[i].account_name.string;
4189                         bool found = false;
4190                         for (j=0; j<num_names; j++) {
4191                                 if (names[j] == NULL)
4192                                         continue;
4193                                 if (strequal(names[j], name)) {
4194                                         names[j] = NULL;
4195                                         found = true;
4196                                         break;
4197                                 }
4198                         }
4199
4200                         if (!found) {
4201                                 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
4202                                        name);
4203                                 ret = false;
4204                         }
4205                 }
4206                 q2.in.start_idx += q2.out.info->info5.count;
4207         }
4208
4209         if (!NT_STATUS_IS_OK(status)) {
4210                 printf("QueryDisplayInfo level 5 failed - %s\n",
4211                        nt_errstr(status));
4212                 ret = false;
4213         }
4214
4215         for (i=0; i<num_names; i++) {
4216                 if (names[i] != NULL) {
4217                         printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
4218                                names[i]);
4219                         ret = false;
4220                 }
4221         }
4222
4223         return ret;
4224 }
4225
4226 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
4227                                    struct policy_handle *group_handle)
4228 {
4229         struct samr_DeleteDomainGroup d;
4230         NTSTATUS status;
4231
4232         torture_comment(tctx, "Testing DeleteDomainGroup\n");
4233
4234         d.in.group_handle = group_handle;
4235         d.out.group_handle = group_handle;
4236
4237         status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
4238         torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
4239
4240         return true;
4241 }
4242
4243 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4244                                             struct policy_handle *domain_handle)
4245 {
4246         struct samr_TestPrivateFunctionsDomain r;
4247         NTSTATUS status;
4248         bool ret = true;
4249
4250         torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
4251
4252         r.in.domain_handle = domain_handle;
4253
4254         status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
4255         torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
4256
4257         return ret;
4258 }
4259
4260 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
4261                           struct dom_sid *domain_sid,
4262                           struct policy_handle *domain_handle)
4263 {
4264         struct samr_RidToSid r;
4265         NTSTATUS status;
4266         bool ret = true;
4267         struct dom_sid *calc_sid, *out_sid;
4268         int rids[] = { 0, 42, 512, 10200 };
4269         int i;
4270
4271         for (i=0;i<ARRAY_SIZE(rids);i++) {
4272                 torture_comment(tctx, "Testing RidToSid\n");
4273                 
4274                 calc_sid = dom_sid_dup(tctx, domain_sid);
4275                 r.in.domain_handle = domain_handle;
4276                 r.in.rid = rids[i];
4277                 r.out.sid = &out_sid;
4278                 
4279                 status = dcerpc_samr_RidToSid(p, tctx, &r);
4280                 if (!NT_STATUS_IS_OK(status)) {
4281                         printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
4282                         ret = false;
4283                 } else {
4284                         calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
4285
4286                         if (!dom_sid_equal(calc_sid, out_sid)) {
4287                                 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i], 
4288                                        dom_sid_string(tctx, out_sid),
4289                                        dom_sid_string(tctx, calc_sid));
4290                                 ret = false;
4291                         }
4292                 }
4293         }
4294
4295         return ret;
4296 }
4297
4298 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
4299                                        struct policy_handle *domain_handle)
4300 {
4301         struct samr_GetBootKeyInformation r;
4302         NTSTATUS status;
4303         bool ret = true;
4304         uint32_t unknown = 0;
4305
4306         torture_comment(tctx, "Testing GetBootKeyInformation\n");
4307
4308         r.in.domain_handle = domain_handle;
4309         r.out.unknown = &unknown;
4310
4311         status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
4312         if (!NT_STATUS_IS_OK(status)) {
4313                 /* w2k3 seems to fail this sometimes and pass it sometimes */
4314                 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4315         }
4316
4317         return ret;
4318 }
4319
4320 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx, 
4321                                 struct policy_handle *domain_handle,
4322                                 struct policy_handle *group_handle)
4323 {
4324         NTSTATUS status;
4325         struct samr_AddGroupMember r;
4326         struct samr_DeleteGroupMember d;
4327         struct samr_QueryGroupMember q;
4328         struct samr_RidTypeArray *rids = NULL;
4329         struct samr_SetMemberAttributesOfGroup s;
4330         uint32_t rid;
4331
4332         status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4333         torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
4334
4335         r.in.group_handle = group_handle;
4336         r.in.rid = rid;
4337         r.in.flags = 0; /* ??? */
4338
4339         torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
4340
4341         d.in.group_handle = group_handle;
4342         d.in.rid = rid;
4343
4344         status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4345         torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
4346
4347         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4348         torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4349
4350         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4351         torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
4352
4353         if (torture_setting_bool(tctx, "samba4", false)) {
4354                 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
4355         } else {
4356                 /* this one is quite strange. I am using random inputs in the
4357                    hope of triggering an error that might give us a clue */
4358
4359                 s.in.group_handle = group_handle;
4360                 s.in.unknown1 = random();
4361                 s.in.unknown2 = random();
4362
4363                 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4364                 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
4365         }
4366
4367         q.in.group_handle = group_handle;
4368         q.out.rids = &rids;
4369
4370         status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4371         torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
4372
4373         status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4374         torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
4375
4376         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4377         torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4378
4379         return true;
4380 }
4381
4382
4383 static bool test_CreateDomainGroup(struct dcerpc_pipe *p, 
4384                                                                    struct torture_context *tctx, 
4385                                    struct policy_handle *domain_handle, 
4386                                    struct policy_handle *group_handle,
4387                                    struct dom_sid *domain_sid)
4388 {
4389         NTSTATUS status;
4390         struct samr_CreateDomainGroup r;
4391         uint32_t rid;
4392         struct lsa_String name;
4393         bool ret = true;
4394
4395         init_lsa_String(&name, TEST_GROUPNAME);
4396
4397         r.in.domain_handle = domain_handle;
4398         r.in.name = &name;
4399         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4400         r.out.group_handle = group_handle;
4401         r.out.rid = &rid;
4402
4403         printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4404
4405         status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4406
4407         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4408                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4409                         torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
4410                         return true;
4411                 } else {
4412                         printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string, 
4413                                nt_errstr(status));
4414                         return false;
4415                 }
4416         }
4417
4418         if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4419                 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
4420                         printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string, 
4421                                nt_errstr(status));
4422                         return false;
4423                 }
4424                 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4425         }
4426         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4427                 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
4428                         
4429                         printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string, 
4430                                nt_errstr(status));
4431                         return false;
4432                 }
4433                 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4434         }
4435         torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
4436
4437         if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
4438                 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4439                 ret = false;
4440         }
4441
4442         if (!test_SetGroupInfo(p, tctx, group_handle)) {
4443                 ret = false;
4444         }
4445
4446         return ret;
4447 }
4448
4449
4450 /*
4451   its not totally clear what this does. It seems to accept any sid you like.
4452 */
4453 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p, 
4454                                                struct torture_context *tctx,
4455                                                struct policy_handle *domain_handle)
4456 {
4457         NTSTATUS status;
4458         struct samr_RemoveMemberFromForeignDomain r;
4459
4460         r.in.domain_handle = domain_handle;
4461         r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
4462
4463         status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
4464         torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
4465
4466         return true;
4467 }
4468
4469
4470
4471 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4472                          struct policy_handle *handle);
4473
4474 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx, 
4475                             struct policy_handle *handle, struct dom_sid *sid,
4476                             enum torture_samr_choice which_ops)
4477 {
4478         NTSTATUS status;
4479         struct samr_OpenDomain r;
4480         struct policy_handle domain_handle;
4481         struct policy_handle alias_handle;
4482         struct policy_handle user_handle;
4483         struct policy_handle group_handle;
4484         bool ret = true;
4485
4486         ZERO_STRUCT(alias_handle);
4487         ZERO_STRUCT(user_handle);
4488         ZERO_STRUCT(group_handle);
4489         ZERO_STRUCT(domain_handle);
4490
4491         torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
4492
4493         r.in.connect_handle = handle;
4494         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4495         r.in.sid = sid;
4496         r.out.domain_handle = &domain_handle;
4497
4498         status = dcerpc_samr_OpenDomain(p, tctx, &r);
4499         torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
4500
4501         /* run the domain tests with the main handle closed - this tests
4502            the servers reference counting */
4503         ret &= test_samr_handle_Close(p, tctx, handle);
4504
4505         switch (which_ops) {
4506         case TORTURE_SAMR_USER_ATTRIBUTES:
4507         case TORTURE_SAMR_PASSWORDS:
4508                 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
4509                 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4510                 /* This test needs 'complex' users to validate */
4511                 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
4512                 if (!ret) {
4513                         printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
4514                 }
4515                 break;
4516         case TORTURE_SAMR_OTHER:
4517                 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4518                 if (!ret) {
4519                         printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
4520                 }
4521                 ret &= test_QuerySecurity(p, tctx, &domain_handle);
4522                 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
4523                 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
4524                 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
4525                 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
4526                 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
4527                 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
4528                 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
4529                 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
4530                 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
4531                 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
4532                 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
4533                 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
4534                 
4535                 if (torture_setting_bool(tctx, "samba4", false)) {
4536                         torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
4537                 } else {
4538                         ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
4539                         ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
4540                 }
4541                 ret &= test_GroupList(p, tctx, &domain_handle);
4542                 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
4543                 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
4544                 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
4545                 if (!ret) {
4546                         torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
4547                 }
4548                 break;
4549         }
4550
4551         if (!policy_handle_empty(&user_handle) &&
4552             !test_DeleteUser(p, tctx, &user_handle)) {
4553                 ret = false;
4554         }
4555
4556         if (!policy_handle_empty(&alias_handle) &&
4557             !test_DeleteAlias(p, tctx, &alias_handle)) {
4558                 ret = false;
4559         }
4560
4561         if (!policy_handle_empty(&group_handle) &&
4562             !test_DeleteDomainGroup(p, tctx, &group_handle)) {
4563                 ret = false;
4564         }
4565
4566         ret &= test_samr_handle_Close(p, tctx, &domain_handle);
4567
4568         /* reconnect the main handle */
4569         ret &= test_Connect(p, tctx, handle);
4570
4571         if (!ret) {
4572                 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
4573         }
4574
4575         return ret;
4576 }
4577
4578 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4579                               struct policy_handle *handle, const char *domain,
4580                               enum torture_samr_choice which_ops)
4581 {
4582         NTSTATUS status;
4583         struct samr_LookupDomain r;
4584         struct dom_sid2 *sid = NULL;
4585         struct lsa_String n1;
4586         struct lsa_String n2;
4587         bool ret = true;
4588
4589         torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
4590
4591         /* check for correct error codes */
4592         r.in.connect_handle = handle;
4593         r.in.domain_name = &n2;
4594         r.out.sid = &sid;
4595         n2.string = NULL;
4596
4597         status = dcerpc_samr_LookupDomain(p, tctx, &r);
4598         torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
4599
4600         init_lsa_String(&n2, "xxNODOMAINxx");
4601
4602         status = dcerpc_samr_LookupDomain(p, tctx, &r);
4603         torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
4604
4605         r.in.connect_handle = handle;
4606
4607         init_lsa_String(&n1, domain);
4608         r.in.domain_name = &n1;
4609
4610         status = dcerpc_samr_LookupDomain(p, tctx, &r);
4611         torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
4612
4613         if (!test_GetDomPwInfo(p, tctx, &n1)) {
4614                 ret = false;
4615         }
4616
4617         if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops)) {
4618                 ret = false;
4619         }
4620
4621         return ret;
4622 }
4623
4624
4625 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
4626                              struct policy_handle *handle, enum torture_samr_choice which_ops)
4627 {
4628         NTSTATUS status;
4629         struct samr_EnumDomains r;
4630         uint32_t resume_handle = 0;
4631         uint32_t num_entries = 0;
4632         struct samr_SamArray *sam = NULL;
4633         int i;
4634         bool ret = true;
4635
4636         r.in.connect_handle = handle;
4637         r.in.resume_handle = &resume_handle;
4638         r.in.buf_size = (uint32_t)-1;
4639         r.out.resume_handle = &resume_handle;
4640         r.out.num_entries = &num_entries;
4641         r.out.sam = &sam;
4642
4643         status = dcerpc_samr_EnumDomains(p, tctx, &r);
4644         torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4645
4646         if (!*r.out.sam) {
4647                 return false;
4648         }
4649
4650         for (i=0;i<sam->count;i++) {
4651                 if (!test_LookupDomain(p, tctx, handle, 
4652                                        sam->entries[i].name.string, which_ops)) {
4653                         ret = false;
4654                 }
4655         }
4656
4657         status = dcerpc_samr_EnumDomains(p, tctx, &r);
4658         torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4659
4660         return ret;
4661 }
4662
4663
4664 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4665                          struct policy_handle *handle)
4666 {
4667         NTSTATUS status;
4668         struct samr_Connect r;
4669         struct samr_Connect2 r2;
4670         struct samr_Connect3 r3;
4671         struct samr_Connect4 r4;
4672         struct samr_Connect5 r5;
4673         union samr_ConnectInfo info;
4674         struct policy_handle h;
4675         uint32_t level_out = 0;
4676         bool ret = true, got_handle = false;
4677
4678         torture_comment(tctx, "testing samr_Connect\n");
4679
4680         r.in.system_name = 0;
4681         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4682         r.out.connect_handle = &h;
4683
4684         status = dcerpc_samr_Connect(p, tctx, &r);
4685         if (!NT_STATUS_IS_OK(status)) {
4686                 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
4687                 ret = false;
4688         } else {
4689                 got_handle = true;
4690                 *handle = h;
4691         }
4692
4693         torture_comment(tctx, "testing samr_Connect2\n");
4694
4695         r2.in.system_name = NULL;
4696         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4697         r2.out.connect_handle = &h;
4698
4699         status = dcerpc_samr_Connect2(p, tctx, &r2);
4700         if (!NT_STATUS_IS_OK(status)) {
4701                 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
4702                 ret = false;
4703         } else {
4704                 if (got_handle) {
4705                         test_samr_handle_Close(p, tctx, handle);
4706                 }
4707                 got_handle = true;
4708                 *handle = h;
4709         }
4710
4711         torture_comment(tctx, "testing samr_Connect3\n");
4712
4713         r3.in.system_name = NULL;
4714         r3.in.unknown = 0;
4715         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4716         r3.out.connect_handle = &h;
4717
4718         status = dcerpc_samr_Connect3(p, tctx, &r3);
4719         if (!NT_STATUS_IS_OK(status)) {
4720                 printf("Connect3 failed - %s\n", nt_errstr(status));
4721                 ret = false;
4722         } else {
4723                 if (got_handle) {
4724                         test_samr_handle_Close(p, tctx, handle);
4725                 }
4726                 got_handle = true;
4727                 *handle = h;
4728         }
4729
4730         torture_comment(tctx, "testing samr_Connect4\n");
4731
4732         r4.in.system_name = "";
4733         r4.in.client_version = 0;
4734         r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4735         r4.out.connect_handle = &h;
4736
4737         status = dcerpc_samr_Connect4(p, tctx, &r4);
4738         if (!NT_STATUS_IS_OK(status)) {
4739                 printf("Connect4 failed - %s\n", nt_errstr(status));
4740                 ret = false;
4741         } else {
4742                 if (got_handle) {
4743                         test_samr_handle_Close(p, tctx, handle);
4744                 }
4745                 got_handle = true;
4746                 *handle = h;
4747         }
4748
4749         torture_comment(tctx, "testing samr_Connect5\n");
4750
4751         info.info1.client_version = 0;
4752         info.info1.unknown2 = 0;
4753
4754         r5.in.system_name = "";
4755         r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4756         r5.in.level_in = 1;
4757         r5.out.level_out = &level_out;
4758         r5.in.info_in = &info;
4759         r5.out.info_out = &info;
4760         r5.out.connect_handle = &h;
4761
4762         status = dcerpc_samr_Connect5(p, tctx, &r5);
4763         if (!NT_STATUS_IS_OK(status)) {
4764                 printf("Connect5 failed - %s\n", nt_errstr(status));
4765                 ret = false;
4766         } else {
4767                 if (got_handle) {
4768                         test_samr_handle_Close(p, tctx, handle);
4769                 }
4770                 got_handle = true;
4771                 *handle = h;
4772         }
4773
4774         return ret;
4775 }
4776
4777
4778 bool torture_rpc_samr(struct torture_context *torture)
4779 {
4780         NTSTATUS status;
4781         struct dcerpc_pipe *p;
4782         bool ret = true;
4783         struct policy_handle handle;
4784
4785         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4786         if (!NT_STATUS_IS_OK(status)) {
4787                 return false;
4788         }
4789
4790         ret &= test_Connect(p, torture, &handle);
4791
4792         ret &= test_QuerySecurity(p, torture, &handle);
4793
4794         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4795
4796         ret &= test_SetDsrmPassword(p, torture, &handle);
4797
4798         ret &= test_Shutdown(p, torture, &handle);
4799
4800         ret &= test_samr_handle_Close(p, torture, &handle);
4801
4802         return ret;
4803 }
4804
4805
4806 bool torture_rpc_samr_users(struct torture_context *torture)
4807 {
4808         NTSTATUS status;
4809         struct dcerpc_pipe *p;
4810         bool ret = true;
4811         struct policy_handle handle;
4812
4813         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4814         if (!NT_STATUS_IS_OK(status)) {
4815                 return false;
4816         }
4817
4818         ret &= test_Connect(p, torture, &handle);
4819
4820         ret &= test_QuerySecurity(p, torture, &handle);
4821
4822         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4823
4824         ret &= test_SetDsrmPassword(p, torture, &handle);
4825
4826         ret &= test_Shutdown(p, torture, &handle);
4827
4828         ret &= test_samr_handle_Close(p, torture, &handle);
4829
4830         return ret;
4831 }
4832
4833
4834 bool torture_rpc_samr_passwords(struct torture_context *torture)
4835 {
4836         NTSTATUS status;
4837         struct dcerpc_pipe *p;
4838         bool ret = true;
4839         struct policy_handle handle;
4840
4841         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4842         if (!NT_STATUS_IS_OK(status)) {
4843                 return false;
4844         }
4845
4846         ret &= test_Connect(p, torture, &handle);
4847
4848         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4849
4850         ret &= test_samr_handle_Close(p, torture, &handle);
4851
4852         return ret;
4853 }
4854