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