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