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