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