02124e6f0471df9126270d7649e60f88bd329565
[kai/samba.git] / source4 / torture / rpc / samr.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for samr rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "torture/torture.h"
24 #include "system/time.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_samr_c.h"
27 #include "../lib/crypto/crypto.h"
28 #include "libcli/auth/libcli_auth.h"
29 #include "libcli/security/security.h"
30 #include "torture/rpc/rpc.h"
31
32 #define TEST_ACCOUNT_NAME "samrtorturetest"
33 #define TEST_ALIASNAME "samrtorturetestalias"
34 #define TEST_GROUPNAME "samrtorturetestgroup"
35 #define TEST_MACHINENAME "samrtestmach$"
36 #define TEST_DOMAINNAME "samrtestdom$"
37
38 enum torture_samr_choice {
39         TORTURE_SAMR_PASSWORDS,
40         TORTURE_SAMR_USER_ATTRIBUTES,
41         TORTURE_SAMR_OTHER
42 };
43
44 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
45                                struct policy_handle *handle);
46
47 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
48                                 struct policy_handle *handle);
49
50 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
51                                struct policy_handle *handle);
52
53 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
54                                 const char *acct_name, 
55                                 struct policy_handle *domain_handle, char **password);
56
57 static void init_lsa_String(struct lsa_String *string, const char *s)
58 {
59         string->string = s;
60 }
61
62 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
63 {
64         string->length = length;
65         string->size = length;
66         string->array = (uint16_t *)discard_const(s);
67 }
68
69 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
70                                    struct policy_handle *handle)
71 {
72         NTSTATUS status;
73         struct samr_Close r;
74
75         r.in.handle = handle;
76         r.out.handle = handle;
77
78         status = dcerpc_samr_Close(p, tctx, &r);
79         torture_assert_ntstatus_ok(tctx, status, "Close");
80
81         return true;
82 }
83
84 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
85                        struct policy_handle *handle)
86 {
87         NTSTATUS status;
88         struct samr_Shutdown r;
89
90         if (!torture_setting_bool(tctx, "dangerous", false)) {
91                 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
92                 return true;
93         }
94
95         r.in.connect_handle = handle;
96
97         torture_comment(tctx, "testing samr_Shutdown\n");
98
99         status = dcerpc_samr_Shutdown(p, tctx, &r);
100         torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
101
102         return true;
103 }
104
105 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
106                                  struct policy_handle *handle)
107 {
108         NTSTATUS status;
109         struct samr_SetDsrmPassword r;
110         struct lsa_String string;
111         struct samr_Password hash;
112
113         if (!torture_setting_bool(tctx, "dangerous", false)) {
114                 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
115         }
116
117         E_md4hash("TeSTDSRM123", hash.hash);
118
119         init_lsa_String(&string, "Administrator");
120
121         r.in.name = &string;
122         r.in.unknown = 0;
123         r.in.hash = &hash;
124
125         torture_comment(tctx, "testing samr_SetDsrmPassword\n");
126
127         status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
128         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
129
130         return true;
131 }
132
133
134 static bool test_QuerySecurity(struct dcerpc_pipe *p, 
135                                struct torture_context *tctx, 
136                                struct policy_handle *handle)
137 {
138         NTSTATUS status;
139         struct samr_QuerySecurity r;
140         struct samr_SetSecurity s;
141         struct sec_desc_buf *sdbuf = NULL;
142
143         r.in.handle = handle;
144         r.in.sec_info = 7;
145         r.out.sdbuf = &sdbuf;
146
147         status = dcerpc_samr_QuerySecurity(p, tctx, &r);
148         torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
149
150         torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
151
152         s.in.handle = handle;
153         s.in.sec_info = 7;
154         s.in.sdbuf = sdbuf;
155
156         if (torture_setting_bool(tctx, "samba4", false)) {
157                 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
158         }
159
160         status = dcerpc_samr_SetSecurity(p, tctx, &s);
161         torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
162
163         status = dcerpc_samr_QuerySecurity(p, tctx, &r);
164         torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
165
166         return true;
167 }
168
169
170 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx, 
171                              struct policy_handle *handle, uint32_t base_acct_flags,
172                              const char *base_account_name)
173 {
174         NTSTATUS status;
175         struct samr_SetUserInfo s;
176         struct samr_SetUserInfo2 s2;
177         struct samr_QueryUserInfo q;
178         struct samr_QueryUserInfo q0;
179         union samr_UserInfo u;
180         union samr_UserInfo *info;
181         bool ret = true;
182         const char *test_account_name;
183
184         uint32_t user_extra_flags = 0;
185         if (base_acct_flags == ACB_NORMAL) {
186                 /* When created, accounts are expired by default */
187                 user_extra_flags = ACB_PW_EXPIRED;
188         }
189
190         s.in.user_handle = handle;
191         s.in.info = &u;
192
193         s2.in.user_handle = handle;
194         s2.in.info = &u;
195
196         q.in.user_handle = handle;
197         q.out.info = &info;
198         q0 = q;
199
200 #define TESTCALL(call, r) \
201                 status = dcerpc_samr_ ##call(p, tctx, &r); \
202                 if (!NT_STATUS_IS_OK(status)) { \
203                         torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
204                                r.in.level, nt_errstr(status), __location__); \
205                         ret = false; \
206                         break; \
207                 }
208
209 #define STRING_EQUAL(s1, s2, field) \
210                 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
211                         torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
212                                #field, s2, __location__); \
213                         ret = false; \
214                         break; \
215                 }
216
217 #define MEM_EQUAL(s1, s2, length, field) \
218                 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
219                         torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
220                                #field, (const char *)s2, __location__); \
221                         ret = false; \
222                         break; \
223                 }
224
225 #define INT_EQUAL(i1, i2, field) \
226                 if (i1 != i2) { \
227                         torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
228                                #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
229                         ret = false; \
230                         break; \
231                 }
232
233 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
234                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
235                 q.in.level = lvl1; \
236                 TESTCALL(QueryUserInfo, q) \
237                 s.in.level = lvl1; \
238                 s2.in.level = lvl1; \
239                 u = *info; \
240                 if (lvl1 == 21) { \
241                         ZERO_STRUCT(u.info21); \
242                         u.info21.fields_present = fpval; \
243                 } \
244                 init_lsa_String(&u.info ## lvl1.field1, value); \
245                 TESTCALL(SetUserInfo, s) \
246                 TESTCALL(SetUserInfo2, s2) \
247                 init_lsa_String(&u.info ## lvl1.field1, ""); \
248                 TESTCALL(QueryUserInfo, q); \
249                 u = *info; \
250                 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
251                 q.in.level = lvl2; \
252                 TESTCALL(QueryUserInfo, q) \
253                 u = *info; \
254                 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
255         } while (0)
256
257 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
258                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
259                 q.in.level = lvl1; \
260                 TESTCALL(QueryUserInfo, q) \
261                 s.in.level = lvl1; \
262                 s2.in.level = lvl1; \
263                 u = *info; \
264                 if (lvl1 == 21) { \
265                         ZERO_STRUCT(u.info21); \
266                         u.info21.fields_present = fpval; \
267                 } \
268                 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
269                 TESTCALL(SetUserInfo, s) \
270                 TESTCALL(SetUserInfo2, s2) \
271                 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
272                 TESTCALL(QueryUserInfo, q); \
273                 u = *info; \
274                 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
275                 q.in.level = lvl2; \
276                 TESTCALL(QueryUserInfo, q) \
277                 u = *info; \
278                 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
279         } while (0)
280
281 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
282                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
283                 q.in.level = lvl1; \
284                 TESTCALL(QueryUserInfo, q) \
285                 s.in.level = lvl1; \
286                 s2.in.level = lvl1; \
287                 u = *info; \
288                 if (lvl1 == 21) { \
289                         uint8_t *bits = u.info21.logon_hours.bits; \
290                         ZERO_STRUCT(u.info21); \
291                         if (fpval == SAMR_FIELD_LOGON_HOURS) { \
292                                 u.info21.logon_hours.units_per_week = 168; \
293                                 u.info21.logon_hours.bits = bits; \
294                         } \
295                         u.info21.fields_present = fpval; \
296                 } \
297                 u.info ## lvl1.field1 = value; \
298                 TESTCALL(SetUserInfo, s) \
299                 TESTCALL(SetUserInfo2, s2) \
300                 u.info ## lvl1.field1 = 0; \
301                 TESTCALL(QueryUserInfo, q); \
302                 u = *info; \
303                 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
304                 q.in.level = lvl2; \
305                 TESTCALL(QueryUserInfo, q) \
306                 u = *info; \
307                 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
308         } while (0)
309
310 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
311         TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
312         } while (0)
313
314         q0.in.level = 12;
315         do { TESTCALL(QueryUserInfo, q0) } while (0);
316
317         TEST_USERINFO_STRING(2, comment,  1, comment, "xx2-1 comment", 0);
318         TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
319         TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment", 
320                            SAMR_FIELD_COMMENT);
321
322         test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
323         TEST_USERINFO_STRING(7, account_name,  1, account_name, base_account_name, 0);
324         test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
325         TEST_USERINFO_STRING(7, account_name,  3, account_name, base_account_name, 0);
326         test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
327         TEST_USERINFO_STRING(7, account_name,  5, account_name, base_account_name, 0);
328         test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
329         TEST_USERINFO_STRING(7, account_name,  6, account_name, base_account_name, 0);
330         test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
331         TEST_USERINFO_STRING(7, account_name,  7, account_name, base_account_name, 0);
332         test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
333         TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
334         test_account_name = base_account_name;
335         TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name, 
336                            SAMR_FIELD_ACCOUNT_NAME);
337
338         TEST_USERINFO_STRING(6, full_name,  1, full_name, "xx6-1 full_name", 0);
339         TEST_USERINFO_STRING(6, full_name,  3, full_name, "xx6-3 full_name", 0);
340         TEST_USERINFO_STRING(6, full_name,  5, full_name, "xx6-5 full_name", 0);
341         TEST_USERINFO_STRING(6, full_name,  6, full_name, "xx6-6 full_name", 0);
342         TEST_USERINFO_STRING(6, full_name,  8, full_name, "xx6-8 full_name", 0);
343         TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
344         TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
345         TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name", 
346                            SAMR_FIELD_FULL_NAME);
347
348         TEST_USERINFO_STRING(6, full_name,  1, full_name, "", 0);
349         TEST_USERINFO_STRING(6, full_name,  3, full_name, "", 0);
350         TEST_USERINFO_STRING(6, full_name,  5, full_name, "", 0);
351         TEST_USERINFO_STRING(6, full_name,  6, full_name, "", 0);
352         TEST_USERINFO_STRING(6, full_name,  8, full_name, "", 0);
353         TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
354         TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
355         TEST_USERINFO_STRING(21, full_name, 21, full_name, "", 
356                            SAMR_FIELD_FULL_NAME);
357
358         TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
359         TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
360         TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
361         TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script", 
362                            SAMR_FIELD_LOGON_SCRIPT);
363
364         TEST_USERINFO_STRING(12, profile_path,  3, profile_path, "xx12-3 profile_path", 0);
365         TEST_USERINFO_STRING(12, profile_path,  5, profile_path, "xx12-5 profile_path", 0);
366         TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
367         TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path", 
368                            SAMR_FIELD_PROFILE_PATH);
369
370         TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
371         TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
372         TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
373         TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
374                              SAMR_FIELD_HOME_DIRECTORY);
375         TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
376                              SAMR_FIELD_HOME_DIRECTORY);
377
378         TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
379         TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
380         TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
381         TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
382                              SAMR_FIELD_HOME_DRIVE);
383         TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
384                              SAMR_FIELD_HOME_DRIVE);
385         
386         TEST_USERINFO_STRING(13, description,  1, description, "xx13-1 description", 0);
387         TEST_USERINFO_STRING(13, description,  5, description, "xx13-5 description", 0);
388         TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
389         TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description", 
390                            SAMR_FIELD_DESCRIPTION);
391
392         TEST_USERINFO_STRING(14, workstations,  3, workstations, "14workstation3", 0);
393         TEST_USERINFO_STRING(14, workstations,  5, workstations, "14workstation4", 0);
394         TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
395         TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21", 
396                            SAMR_FIELD_WORKSTATIONS);
397         TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3", 
398                            SAMR_FIELD_WORKSTATIONS);
399         TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5", 
400                            SAMR_FIELD_WORKSTATIONS);
401         TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14", 
402                            SAMR_FIELD_WORKSTATIONS);
403
404         TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
405         TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
406                            SAMR_FIELD_PARAMETERS);
407         TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
408                            SAMR_FIELD_PARAMETERS);
409
410         TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
411         TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
412         TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__, 
413                           SAMR_FIELD_COUNTRY_CODE);
414         TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__, 
415                           SAMR_FIELD_COUNTRY_CODE);
416
417         TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
418         TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__, 
419                           SAMR_FIELD_CODE_PAGE);
420         TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__, 
421                           SAMR_FIELD_CODE_PAGE);
422
423         TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
424         TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
425         TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__, 
426                           SAMR_FIELD_ACCT_EXPIRY);
427         TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__, 
428                           SAMR_FIELD_ACCT_EXPIRY);
429         TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__, 
430                           SAMR_FIELD_ACCT_EXPIRY);
431
432         TEST_USERINFO_INT(4, logon_hours.bits[3],  3, logon_hours.bits[3], 1, 0);
433         TEST_USERINFO_INT(4, logon_hours.bits[3],  5, logon_hours.bits[3], 2, 0);
434         TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
435         TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4, 
436                           SAMR_FIELD_LOGON_HOURS);
437
438         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
439                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ), 
440                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags), 
441                               0);
442         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
443                               (base_acct_flags  | ACB_DISABLED), 
444                               (base_acct_flags  | ACB_DISABLED | user_extra_flags), 
445                               0);
446         
447         /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
448         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
449                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP), 
450                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP), 
451                               0);
452         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
453                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ), 
454                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags), 
455                               0);
456
457
458         /* The 'autolock' flag doesn't stick - check this */
459         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
460                               (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK), 
461                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
462                               0);
463 #if 0
464         /* Removing the 'disabled' flag doesn't stick - check this */
465         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
466                               (base_acct_flags), 
467                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
468                               0);
469 #endif
470         /* The 'store plaintext' flag does stick */
471         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
472                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED), 
473                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags), 
474                               0);
475         /* The 'use DES' flag does stick */
476         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
477                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY), 
478                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags), 
479                               0);
480         /* The 'don't require kerberos pre-authentication flag does stick */
481         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
482                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH), 
483                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags), 
484                               0);
485         /* The 'no kerberos PAC required' flag sticks */
486         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
487                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD), 
488                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags), 
489                               0);
490
491         TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags, 
492                               (base_acct_flags | ACB_DISABLED), 
493                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
494                               SAMR_FIELD_ACCT_FLAGS);
495
496 #if 0
497         /* these fail with win2003 - it appears you can't set the primary gid?
498            the set succeeds, but the gid isn't changed. Very weird! */
499         TEST_USERINFO_INT(9, primary_gid,  1, primary_gid, 513);
500         TEST_USERINFO_INT(9, primary_gid,  3, primary_gid, 513);
501         TEST_USERINFO_INT(9, primary_gid,  5, primary_gid, 513);
502         TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
503 #endif
504
505         return ret;
506 }
507
508 /*
509   generate a random password for password change tests
510 */
511 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
512 {
513         size_t len = MAX(8, min_len) + (random() % 6);
514         char *s = generate_random_str(mem_ctx, len);
515         return s;
516 }
517
518 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
519 {
520         char *s = samr_rand_pass_silent(mem_ctx, min_len);
521         printf("Generated password '%s'\n", s);
522         return s;
523
524 }
525
526 /*
527   generate a random password for password change tests
528 */
529 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
530 {
531         int i;
532         DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
533         generate_random_buffer(password.data, password.length);
534
535         for (i=0; i < len; i++) {
536                 if (((uint16_t *)password.data)[i] == 0) {
537                         ((uint16_t *)password.data)[i] = 1;
538                 }
539         }
540
541         return password;
542 }
543
544 /*
545   generate a random password for password change tests (fixed length)
546 */
547 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
548 {
549         char *s = generate_random_str(mem_ctx, len);
550         printf("Generated password '%s'\n", s);
551         return s;
552 }
553
554 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
555                              struct policy_handle *handle, char **password)
556 {
557         NTSTATUS status;
558         struct samr_SetUserInfo s;
559         union samr_UserInfo u;
560         bool ret = true;
561         DATA_BLOB session_key;
562         char *newpass;
563         struct samr_GetUserPwInfo pwp;
564         struct samr_PwInfo info;
565         int policy_min_pw_len = 0;
566         pwp.in.user_handle = handle;
567         pwp.out.info = &info;
568
569         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
570         if (NT_STATUS_IS_OK(status)) {
571                 policy_min_pw_len = pwp.out.info->min_password_length;
572         }
573         newpass = samr_rand_pass(tctx, policy_min_pw_len);
574
575         s.in.user_handle = handle;
576         s.in.info = &u;
577         s.in.level = 24;
578
579         encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
580         u.info24.password_expired = 0;
581
582         status = dcerpc_fetch_session_key(p, &session_key);
583         if (!NT_STATUS_IS_OK(status)) {
584                 printf("SetUserInfo level %u - no session key - %s\n",
585                        s.in.level, nt_errstr(status));
586                 return false;
587         }
588
589         arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
590
591         torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
592
593         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
594         if (!NT_STATUS_IS_OK(status)) {
595                 printf("SetUserInfo level %u failed - %s\n",
596                        s.in.level, nt_errstr(status));
597                 ret = false;
598         } else {
599                 *password = newpass;
600         }
601
602         return ret;
603 }
604
605
606 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
607                                 struct policy_handle *handle, uint32_t fields_present,
608                                 char **password)
609 {
610         NTSTATUS status;
611         struct samr_SetUserInfo s;
612         union samr_UserInfo u;
613         bool ret = true;
614         DATA_BLOB session_key;
615         char *newpass;
616         struct samr_GetUserPwInfo pwp;
617         struct samr_PwInfo info;
618         int policy_min_pw_len = 0;
619         pwp.in.user_handle = handle;
620         pwp.out.info = &info;
621
622         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
623         if (NT_STATUS_IS_OK(status)) {
624                 policy_min_pw_len = pwp.out.info->min_password_length;
625         }
626         newpass = samr_rand_pass(tctx, policy_min_pw_len);
627
628         s.in.user_handle = handle;
629         s.in.info = &u;
630         s.in.level = 23;
631
632         ZERO_STRUCT(u);
633
634         u.info23.info.fields_present = fields_present;
635
636         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
637
638         status = dcerpc_fetch_session_key(p, &session_key);
639         if (!NT_STATUS_IS_OK(status)) {
640                 printf("SetUserInfo level %u - no session key - %s\n",
641                        s.in.level, nt_errstr(status));
642                 return false;
643         }
644
645         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
646
647         torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
648
649         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
650         if (!NT_STATUS_IS_OK(status)) {
651                 printf("SetUserInfo level %u failed - %s\n",
652                        s.in.level, nt_errstr(status));
653                 ret = false;
654         } else {
655                 *password = newpass;
656         }
657
658         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
659
660         status = dcerpc_fetch_session_key(p, &session_key);
661         if (!NT_STATUS_IS_OK(status)) {
662                 printf("SetUserInfo level %u - no session key - %s\n",
663                        s.in.level, nt_errstr(status));
664                 return false;
665         }
666
667         /* This should break the key nicely */
668         session_key.length--;
669         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
670
671         torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
672
673         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
674         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
675                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
676                        s.in.level, nt_errstr(status));
677                 ret = false;
678         }
679
680         return ret;
681 }
682
683
684 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
685                                struct policy_handle *handle, bool makeshort, 
686                                char **password)
687 {
688         NTSTATUS status;
689         struct samr_SetUserInfo s;
690         union samr_UserInfo u;
691         bool ret = true;
692         DATA_BLOB session_key;
693         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
694         uint8_t confounder[16];
695         char *newpass;
696         struct MD5Context ctx;
697         struct samr_GetUserPwInfo pwp;
698         struct samr_PwInfo info;
699         int policy_min_pw_len = 0;
700         pwp.in.user_handle = handle;
701         pwp.out.info = &info;
702
703         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
704         if (NT_STATUS_IS_OK(status)) {
705                 policy_min_pw_len = pwp.out.info->min_password_length;
706         }
707         if (makeshort && policy_min_pw_len) {
708                 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
709         } else {
710                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
711         }
712
713         s.in.user_handle = handle;
714         s.in.info = &u;
715         s.in.level = 26;
716
717         encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
718         u.info26.password_expired = 0;
719
720         status = dcerpc_fetch_session_key(p, &session_key);
721         if (!NT_STATUS_IS_OK(status)) {
722                 printf("SetUserInfo level %u - no session key - %s\n",
723                        s.in.level, nt_errstr(status));
724                 return false;
725         }
726
727         generate_random_buffer((uint8_t *)confounder, 16);
728
729         MD5Init(&ctx);
730         MD5Update(&ctx, confounder, 16);
731         MD5Update(&ctx, session_key.data, session_key.length);
732         MD5Final(confounded_session_key.data, &ctx);
733
734         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
735         memcpy(&u.info26.password.data[516], confounder, 16);
736
737         torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
738
739         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
740         if (!NT_STATUS_IS_OK(status)) {
741                 printf("SetUserInfo level %u failed - %s\n",
742                        s.in.level, nt_errstr(status));
743                 ret = false;
744         } else {
745                 *password = newpass;
746         }
747
748         /* This should break the key nicely */
749         confounded_session_key.data[0]++;
750
751         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
752         memcpy(&u.info26.password.data[516], confounder, 16);
753
754         torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
755
756         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
757         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
758                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
759                        s.in.level, nt_errstr(status));
760                 ret = false;
761         } else {
762                 *password = newpass;
763         }
764
765         return ret;
766 }
767
768 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
769                                 struct policy_handle *handle, uint32_t fields_present,
770                                 char **password)
771 {
772         NTSTATUS status;
773         struct samr_SetUserInfo s;
774         union samr_UserInfo u;
775         bool ret = true;
776         DATA_BLOB session_key;
777         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
778         struct MD5Context ctx;
779         uint8_t confounder[16];
780         char *newpass;
781         struct samr_GetUserPwInfo pwp;
782         struct samr_PwInfo info;
783         int policy_min_pw_len = 0;
784         pwp.in.user_handle = handle;
785         pwp.out.info = &info;
786
787         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
788         if (NT_STATUS_IS_OK(status)) {
789                 policy_min_pw_len = pwp.out.info->min_password_length;
790         }
791         newpass = samr_rand_pass(tctx, policy_min_pw_len);
792
793         s.in.user_handle = handle;
794         s.in.info = &u;
795         s.in.level = 25;
796
797         ZERO_STRUCT(u);
798
799         u.info25.info.fields_present = fields_present;
800
801         encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
802
803         status = dcerpc_fetch_session_key(p, &session_key);
804         if (!NT_STATUS_IS_OK(status)) {
805                 printf("SetUserInfo level %u - no session key - %s\n",
806                        s.in.level, nt_errstr(status));
807                 return false;
808         }
809
810         generate_random_buffer((uint8_t *)confounder, 16);
811
812         MD5Init(&ctx);
813         MD5Update(&ctx, confounder, 16);
814         MD5Update(&ctx, session_key.data, session_key.length);
815         MD5Final(confounded_session_key.data, &ctx);
816
817         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
818         memcpy(&u.info25.password.data[516], confounder, 16);
819
820         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
821
822         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
823         if (!NT_STATUS_IS_OK(status)) {
824                 printf("SetUserInfo level %u failed - %s\n",
825                        s.in.level, nt_errstr(status));
826                 ret = false;
827         } else {
828                 *password = newpass;
829         }
830
831         /* This should break the key nicely */
832         confounded_session_key.data[0]++;
833
834         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
835         memcpy(&u.info25.password.data[516], confounder, 16);
836
837         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
838
839         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
840         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
841                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
842                        s.in.level, nt_errstr(status));
843                 ret = false;
844         }
845
846         return ret;
847 }
848
849 static bool test_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