s4-smbtorture: add test for samr password_expired flag while setting passwords.
[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 #include <unistd.h>
33
34 #define TEST_ACCOUNT_NAME "samrtorturetest"
35 #define TEST_ALIASNAME "samrtorturetestalias"
36 #define TEST_GROUPNAME "samrtorturetestgroup"
37 #define TEST_MACHINENAME "samrtestmach$"
38 #define TEST_DOMAINNAME "samrtestdom$"
39
40 enum torture_samr_choice {
41         TORTURE_SAMR_PASSWORDS,
42         TORTURE_SAMR_USER_ATTRIBUTES,
43         TORTURE_SAMR_OTHER
44 };
45
46 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
47                                struct policy_handle *handle);
48
49 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
50                                 struct policy_handle *handle);
51
52 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
53                                struct policy_handle *handle);
54
55 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
56                                 const char *acct_name, 
57                                 struct policy_handle *domain_handle, char **password);
58
59 static void init_lsa_String(struct lsa_String *string, const char *s)
60 {
61         string->string = s;
62 }
63
64 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
65 {
66         string->length = length;
67         string->size = length;
68         string->array = (uint16_t *)discard_const(s);
69 }
70
71 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
72                                    struct policy_handle *handle)
73 {
74         NTSTATUS status;
75         struct samr_Close r;
76
77         r.in.handle = handle;
78         r.out.handle = handle;
79
80         status = dcerpc_samr_Close(p, tctx, &r);
81         torture_assert_ntstatus_ok(tctx, status, "Close");
82
83         return true;
84 }
85
86 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
87                        struct policy_handle *handle)
88 {
89         NTSTATUS status;
90         struct samr_Shutdown r;
91
92         if (!torture_setting_bool(tctx, "dangerous", false)) {
93                 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
94                 return true;
95         }
96
97         r.in.connect_handle = handle;
98
99         torture_comment(tctx, "testing samr_Shutdown\n");
100
101         status = dcerpc_samr_Shutdown(p, tctx, &r);
102         torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
103
104         return true;
105 }
106
107 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
108                                  struct policy_handle *handle)
109 {
110         NTSTATUS status;
111         struct samr_SetDsrmPassword r;
112         struct lsa_String string;
113         struct samr_Password hash;
114
115         if (!torture_setting_bool(tctx, "dangerous", false)) {
116                 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
117         }
118
119         E_md4hash("TeSTDSRM123", hash.hash);
120
121         init_lsa_String(&string, "Administrator");
122
123         r.in.name = &string;
124         r.in.unknown = 0;
125         r.in.hash = &hash;
126
127         torture_comment(tctx, "testing samr_SetDsrmPassword\n");
128
129         status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
130         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
131
132         return true;
133 }
134
135
136 static bool test_QuerySecurity(struct dcerpc_pipe *p, 
137                                struct torture_context *tctx, 
138                                struct policy_handle *handle)
139 {
140         NTSTATUS status;
141         struct samr_QuerySecurity r;
142         struct samr_SetSecurity s;
143         struct sec_desc_buf *sdbuf = NULL;
144
145         r.in.handle = handle;
146         r.in.sec_info = 7;
147         r.out.sdbuf = &sdbuf;
148
149         status = dcerpc_samr_QuerySecurity(p, tctx, &r);
150         torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
151
152         torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
153
154         s.in.handle = handle;
155         s.in.sec_info = 7;
156         s.in.sdbuf = sdbuf;
157
158         if (torture_setting_bool(tctx, "samba4", false)) {
159                 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
160         }
161
162         status = dcerpc_samr_SetSecurity(p, tctx, &s);
163         torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
164
165         status = dcerpc_samr_QuerySecurity(p, tctx, &r);
166         torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
167
168         return true;
169 }
170
171
172 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx, 
173                              struct policy_handle *handle, uint32_t base_acct_flags,
174                              const char *base_account_name)
175 {
176         NTSTATUS status;
177         struct samr_SetUserInfo s;
178         struct samr_SetUserInfo2 s2;
179         struct samr_QueryUserInfo q;
180         struct samr_QueryUserInfo q0;
181         union samr_UserInfo u;
182         union samr_UserInfo *info;
183         bool ret = true;
184         const char *test_account_name;
185
186         uint32_t user_extra_flags = 0;
187         if (base_acct_flags == ACB_NORMAL) {
188                 /* When created, accounts are expired by default */
189                 user_extra_flags = ACB_PW_EXPIRED;
190         }
191
192         s.in.user_handle = handle;
193         s.in.info = &u;
194
195         s2.in.user_handle = handle;
196         s2.in.info = &u;
197
198         q.in.user_handle = handle;
199         q.out.info = &info;
200         q0 = q;
201
202 #define TESTCALL(call, r) \
203                 status = dcerpc_samr_ ##call(p, tctx, &r); \
204                 if (!NT_STATUS_IS_OK(status)) { \
205                         torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
206                                r.in.level, nt_errstr(status), __location__); \
207                         ret = false; \
208                         break; \
209                 }
210
211 #define STRING_EQUAL(s1, s2, field) \
212                 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
213                         torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
214                                #field, s2, __location__); \
215                         ret = false; \
216                         break; \
217                 }
218
219 #define MEM_EQUAL(s1, s2, length, field) \
220                 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
221                         torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
222                                #field, (const char *)s2, __location__); \
223                         ret = false; \
224                         break; \
225                 }
226
227 #define INT_EQUAL(i1, i2, field) \
228                 if (i1 != i2) { \
229                         torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
230                                #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
231                         ret = false; \
232                         break; \
233                 }
234
235 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
236                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
237                 q.in.level = lvl1; \
238                 TESTCALL(QueryUserInfo, q) \
239                 s.in.level = lvl1; \
240                 s2.in.level = lvl1; \
241                 u = *info; \
242                 if (lvl1 == 21) { \
243                         ZERO_STRUCT(u.info21); \
244                         u.info21.fields_present = fpval; \
245                 } \
246                 init_lsa_String(&u.info ## lvl1.field1, value); \
247                 TESTCALL(SetUserInfo, s) \
248                 TESTCALL(SetUserInfo2, s2) \
249                 init_lsa_String(&u.info ## lvl1.field1, ""); \
250                 TESTCALL(QueryUserInfo, q); \
251                 u = *info; \
252                 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
253                 q.in.level = lvl2; \
254                 TESTCALL(QueryUserInfo, q) \
255                 u = *info; \
256                 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
257         } while (0)
258
259 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
260                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
261                 q.in.level = lvl1; \
262                 TESTCALL(QueryUserInfo, q) \
263                 s.in.level = lvl1; \
264                 s2.in.level = lvl1; \
265                 u = *info; \
266                 if (lvl1 == 21) { \
267                         ZERO_STRUCT(u.info21); \
268                         u.info21.fields_present = fpval; \
269                 } \
270                 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
271                 TESTCALL(SetUserInfo, s) \
272                 TESTCALL(SetUserInfo2, s2) \
273                 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
274                 TESTCALL(QueryUserInfo, q); \
275                 u = *info; \
276                 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
277                 q.in.level = lvl2; \
278                 TESTCALL(QueryUserInfo, q) \
279                 u = *info; \
280                 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
281         } while (0)
282
283 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
284                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
285                 q.in.level = lvl1; \
286                 TESTCALL(QueryUserInfo, q) \
287                 s.in.level = lvl1; \
288                 s2.in.level = lvl1; \
289                 u = *info; \
290                 if (lvl1 == 21) { \
291                         uint8_t *bits = u.info21.logon_hours.bits; \
292                         ZERO_STRUCT(u.info21); \
293                         if (fpval == SAMR_FIELD_LOGON_HOURS) { \
294                                 u.info21.logon_hours.units_per_week = 168; \
295                                 u.info21.logon_hours.bits = bits; \
296                         } \
297                         u.info21.fields_present = fpval; \
298                 } \
299                 u.info ## lvl1.field1 = value; \
300                 TESTCALL(SetUserInfo, s) \
301                 TESTCALL(SetUserInfo2, s2) \
302                 u.info ## lvl1.field1 = 0; \
303                 TESTCALL(QueryUserInfo, q); \
304                 u = *info; \
305                 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
306                 q.in.level = lvl2; \
307                 TESTCALL(QueryUserInfo, q) \
308                 u = *info; \
309                 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
310         } while (0)
311
312 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
313         TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
314         } while (0)
315
316         q0.in.level = 12;
317         do { TESTCALL(QueryUserInfo, q0) } while (0);
318
319         TEST_USERINFO_STRING(2, comment,  1, comment, "xx2-1 comment", 0);
320         TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
321         TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment", 
322                            SAMR_FIELD_COMMENT);
323
324         test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
325         TEST_USERINFO_STRING(7, account_name,  1, account_name, base_account_name, 0);
326         test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
327         TEST_USERINFO_STRING(7, account_name,  3, account_name, base_account_name, 0);
328         test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
329         TEST_USERINFO_STRING(7, account_name,  5, account_name, base_account_name, 0);
330         test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
331         TEST_USERINFO_STRING(7, account_name,  6, account_name, base_account_name, 0);
332         test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
333         TEST_USERINFO_STRING(7, account_name,  7, account_name, base_account_name, 0);
334         test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
335         TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
336         test_account_name = base_account_name;
337         TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name, 
338                            SAMR_FIELD_ACCOUNT_NAME);
339
340         TEST_USERINFO_STRING(6, full_name,  1, full_name, "xx6-1 full_name", 0);
341         TEST_USERINFO_STRING(6, full_name,  3, full_name, "xx6-3 full_name", 0);
342         TEST_USERINFO_STRING(6, full_name,  5, full_name, "xx6-5 full_name", 0);
343         TEST_USERINFO_STRING(6, full_name,  6, full_name, "xx6-6 full_name", 0);
344         TEST_USERINFO_STRING(6, full_name,  8, full_name, "xx6-8 full_name", 0);
345         TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
346         TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
347         TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name", 
348                            SAMR_FIELD_FULL_NAME);
349
350         TEST_USERINFO_STRING(6, full_name,  1, full_name, "", 0);
351         TEST_USERINFO_STRING(6, full_name,  3, full_name, "", 0);
352         TEST_USERINFO_STRING(6, full_name,  5, full_name, "", 0);
353         TEST_USERINFO_STRING(6, full_name,  6, full_name, "", 0);
354         TEST_USERINFO_STRING(6, full_name,  8, full_name, "", 0);
355         TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
356         TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
357         TEST_USERINFO_STRING(21, full_name, 21, full_name, "", 
358                            SAMR_FIELD_FULL_NAME);
359
360         TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
361         TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
362         TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
363         TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script", 
364                            SAMR_FIELD_LOGON_SCRIPT);
365
366         TEST_USERINFO_STRING(12, profile_path,  3, profile_path, "xx12-3 profile_path", 0);
367         TEST_USERINFO_STRING(12, profile_path,  5, profile_path, "xx12-5 profile_path", 0);
368         TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
369         TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path", 
370                            SAMR_FIELD_PROFILE_PATH);
371
372         TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
373         TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
374         TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
375         TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
376                              SAMR_FIELD_HOME_DIRECTORY);
377         TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
378                              SAMR_FIELD_HOME_DIRECTORY);
379
380         TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
381         TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
382         TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
383         TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
384                              SAMR_FIELD_HOME_DRIVE);
385         TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
386                              SAMR_FIELD_HOME_DRIVE);
387         
388         TEST_USERINFO_STRING(13, description,  1, description, "xx13-1 description", 0);
389         TEST_USERINFO_STRING(13, description,  5, description, "xx13-5 description", 0);
390         TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
391         TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description", 
392                            SAMR_FIELD_DESCRIPTION);
393
394         TEST_USERINFO_STRING(14, workstations,  3, workstations, "14workstation3", 0);
395         TEST_USERINFO_STRING(14, workstations,  5, workstations, "14workstation4", 0);
396         TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
397         TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21", 
398                            SAMR_FIELD_WORKSTATIONS);
399         TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3", 
400                            SAMR_FIELD_WORKSTATIONS);
401         TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5", 
402                            SAMR_FIELD_WORKSTATIONS);
403         TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14", 
404                            SAMR_FIELD_WORKSTATIONS);
405
406         TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
407         TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
408                            SAMR_FIELD_PARAMETERS);
409         TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
410                            SAMR_FIELD_PARAMETERS);
411
412         TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
413         TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
414         TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__, 
415                           SAMR_FIELD_COUNTRY_CODE);
416         TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__, 
417                           SAMR_FIELD_COUNTRY_CODE);
418
419         TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
420         TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__, 
421                           SAMR_FIELD_CODE_PAGE);
422         TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__, 
423                           SAMR_FIELD_CODE_PAGE);
424
425         TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
426         TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
427         TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__, 
428                           SAMR_FIELD_ACCT_EXPIRY);
429         TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__, 
430                           SAMR_FIELD_ACCT_EXPIRY);
431         TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__, 
432                           SAMR_FIELD_ACCT_EXPIRY);
433
434         TEST_USERINFO_INT(4, logon_hours.bits[3],  3, logon_hours.bits[3], 1, 0);
435         TEST_USERINFO_INT(4, logon_hours.bits[3],  5, logon_hours.bits[3], 2, 0);
436         TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
437         TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4, 
438                           SAMR_FIELD_LOGON_HOURS);
439
440         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
441                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ), 
442                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags), 
443                               0);
444         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
445                               (base_acct_flags  | ACB_DISABLED), 
446                               (base_acct_flags  | ACB_DISABLED | user_extra_flags), 
447                               0);
448         
449         /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
450         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
451                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP), 
452                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP), 
453                               0);
454         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
455                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ), 
456                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags), 
457                               0);
458
459
460         /* The 'autolock' flag doesn't stick - check this */
461         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
462                               (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK), 
463                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
464                               0);
465 #if 0
466         /* Removing the 'disabled' flag doesn't stick - check this */
467         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
468                               (base_acct_flags), 
469                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
470                               0);
471 #endif
472         /* The 'store plaintext' flag does stick */
473         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
474                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED), 
475                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags), 
476                               0);
477         /* The 'use DES' flag does stick */
478         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
479                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY), 
480                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags), 
481                               0);
482         /* The 'don't require kerberos pre-authentication flag does stick */
483         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
484                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH), 
485                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags), 
486                               0);
487         /* The 'no kerberos PAC required' flag sticks */
488         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
489                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD), 
490                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags), 
491                               0);
492
493         TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags, 
494                               (base_acct_flags | ACB_DISABLED), 
495                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
496                               SAMR_FIELD_ACCT_FLAGS);
497
498 #if 0
499         /* these fail with win2003 - it appears you can't set the primary gid?
500            the set succeeds, but the gid isn't changed. Very weird! */
501         TEST_USERINFO_INT(9, primary_gid,  1, primary_gid, 513);
502         TEST_USERINFO_INT(9, primary_gid,  3, primary_gid, 513);
503         TEST_USERINFO_INT(9, primary_gid,  5, primary_gid, 513);
504         TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
505 #endif
506
507         return ret;
508 }
509
510 /*
511   generate a random password for password change tests
512 */
513 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
514 {
515         size_t len = MAX(8, min_len) + (random() % 6);
516         char *s = generate_random_str(mem_ctx, len);
517         return s;
518 }
519
520 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
521 {
522         char *s = samr_rand_pass_silent(mem_ctx, min_len);
523         printf("Generated password '%s'\n", s);
524         return s;
525
526 }
527
528 /*
529   generate a random password for password change tests
530 */
531 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
532 {
533         int i;
534         DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
535         generate_random_buffer(password.data, password.length);
536
537         for (i=0; i < len; i++) {
538                 if (((uint16_t *)password.data)[i] == 0) {
539                         ((uint16_t *)password.data)[i] = 1;
540                 }
541         }
542
543         return password;
544 }
545
546 /*
547   generate a random password for password change tests (fixed length)
548 */
549 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
550 {
551         char *s = generate_random_str(mem_ctx, len);
552         printf("Generated password '%s'\n", s);
553         return s;
554 }
555
556 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
557                              struct policy_handle *handle, char **password)
558 {
559         NTSTATUS status;
560         struct samr_SetUserInfo s;
561         union samr_UserInfo u;
562         bool ret = true;
563         DATA_BLOB session_key;
564         char *newpass;
565         struct samr_GetUserPwInfo pwp;
566         struct samr_PwInfo info;
567         int policy_min_pw_len = 0;
568         pwp.in.user_handle = handle;
569         pwp.out.info = &info;
570
571         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
572         if (NT_STATUS_IS_OK(status)) {
573                 policy_min_pw_len = pwp.out.info->min_password_length;
574         }
575         newpass = samr_rand_pass(tctx, policy_min_pw_len);
576
577         s.in.user_handle = handle;
578         s.in.info = &u;
579         s.in.level = 24;
580
581         encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
582         u.info24.password_expired = 0;
583
584         status = dcerpc_fetch_session_key(p, &session_key);
585         if (!NT_STATUS_IS_OK(status)) {
586                 printf("SetUserInfo level %u - no session key - %s\n",
587                        s.in.level, nt_errstr(status));
588                 return false;
589         }
590
591         arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
592
593         torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
594
595         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
596         if (!NT_STATUS_IS_OK(status)) {
597                 printf("SetUserInfo level %u failed - %s\n",
598                        s.in.level, nt_errstr(status));
599                 ret = false;
600         } else {
601                 *password = newpass;
602         }
603
604         return ret;
605 }
606
607
608 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
609                                 struct policy_handle *handle, uint32_t fields_present,
610                                 char **password)
611 {
612         NTSTATUS status;
613         struct samr_SetUserInfo s;
614         union samr_UserInfo u;
615         bool ret = true;
616         DATA_BLOB session_key;
617         char *newpass;
618         struct samr_GetUserPwInfo pwp;
619         struct samr_PwInfo info;
620         int policy_min_pw_len = 0;
621         pwp.in.user_handle = handle;
622         pwp.out.info = &info;
623
624         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
625         if (NT_STATUS_IS_OK(status)) {
626                 policy_min_pw_len = pwp.out.info->min_password_length;
627         }
628         newpass = samr_rand_pass(tctx, policy_min_pw_len);
629
630         s.in.user_handle = handle;
631         s.in.info = &u;
632         s.in.level = 23;
633
634         ZERO_STRUCT(u);
635
636         u.info23.info.fields_present = fields_present;
637
638         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
639
640         status = dcerpc_fetch_session_key(p, &session_key);
641         if (!NT_STATUS_IS_OK(status)) {
642                 printf("SetUserInfo level %u - no session key - %s\n",
643                        s.in.level, nt_errstr(status));
644                 return false;
645         }
646
647         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
648
649         torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
650
651         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
652         if (!NT_STATUS_IS_OK(status)) {
653                 printf("SetUserInfo level %u failed - %s\n",
654                        s.in.level, nt_errstr(status));
655                 ret = false;
656         } else {
657                 *password = newpass;
658         }
659
660         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
661
662         status = dcerpc_fetch_session_key(p, &session_key);
663         if (!NT_STATUS_IS_OK(status)) {
664                 printf("SetUserInfo level %u - no session key - %s\n",
665                        s.in.level, nt_errstr(status));
666                 return false;
667         }
668
669         /* This should break the key nicely */
670         session_key.length--;
671         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
672
673         torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
674
675         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
676         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
677                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
678                        s.in.level, nt_errstr(status));
679                 ret = false;
680         }
681
682         return ret;
683 }
684
685
686 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
687                                struct policy_handle *handle, bool makeshort, 
688                                char **password)
689 {
690         NTSTATUS status;
691         struct samr_SetUserInfo s;
692         union samr_UserInfo u;
693         bool ret = true;
694         DATA_BLOB session_key;
695         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
696         uint8_t confounder[16];
697         char *newpass;
698         struct MD5Context ctx;
699         struct samr_GetUserPwInfo pwp;
700         struct samr_PwInfo info;
701         int policy_min_pw_len = 0;
702         pwp.in.user_handle = handle;
703         pwp.out.info = &info;
704
705         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
706         if (NT_STATUS_IS_OK(status)) {
707                 policy_min_pw_len = pwp.out.info->min_password_length;
708         }
709         if (makeshort && policy_min_pw_len) {
710                 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
711         } else {
712                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
713         }
714
715         s.in.user_handle = handle;
716         s.in.info = &u;
717         s.in.level = 26;
718
719         encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
720         u.info26.password_expired = 0;
721
722         status = dcerpc_fetch_session_key(p, &session_key);
723         if (!NT_STATUS_IS_OK(status)) {
724                 printf("SetUserInfo level %u - no session key - %s\n",
725                        s.in.level, nt_errstr(status));
726                 return false;
727         }
728
729         generate_random_buffer((uint8_t *)confounder, 16);
730
731         MD5Init(&ctx);
732         MD5Update(&ctx, confounder, 16);
733         MD5Update(&ctx, session_key.data, session_key.length);
734         MD5Final(confounded_session_key.data, &ctx);
735
736         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
737         memcpy(&u.info26.password.data[516], confounder, 16);
738
739         torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
740
741         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
742         if (!NT_STATUS_IS_OK(status)) {
743                 printf("SetUserInfo level %u failed - %s\n",
744                        s.in.level, nt_errstr(status));
745                 ret = false;
746         } else {
747                 *password = newpass;
748         }
749
750         /* This should break the key nicely */
751         confounded_session_key.data[0]++;
752
753         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
754         memcpy(&u.info26.password.data[516], confounder, 16);
755
756         torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
757
758         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
759         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
760                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
761                        s.in.level, nt_errstr(status));
762                 ret = false;
763         } else {
764                 *password = newpass;
765         }
766
767         return ret;
768 }
769
770 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
771                                 struct policy_handle *handle, uint32_t fields_present,
772                                 char **password)
773 {
774         NTSTATUS status;
775         struct samr_SetUserInfo s;
776         union samr_UserInfo u;
777         bool ret = true;
778         DATA_BLOB session_key;
779         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
780         struct MD5Context ctx;
781         uint8_t confounder[16];
782         char *newpass;
783         struct samr_GetUserPwInfo pwp;
784         struct samr_PwInfo info;
785         int policy_min_pw_len = 0;
786         pwp.in.user_handle = handle;
787         pwp.out.info = &info;
788
789         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
790         if (NT_STATUS_IS_OK(status)) {
791                 policy_min_pw_len = pwp.out.info->min_password_length;
792         }
793         newpass = samr_rand_pass(tctx, policy_min_pw_len);
794
795         s.in.user_handle = handle;
796         s.in.info = &u;
797         s.in.level = 25;
798
799         ZERO_STRUCT(u);
800
801         u.info25.info.fields_present = fields_present;
802
803         encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
804
805         status = dcerpc_fetch_session_key(p, &session_key);
806         if (!NT_STATUS_IS_OK(status)) {
807                 printf("SetUserInfo level %u - no session key - %s\n",
808                        s.in.level, nt_errstr(status));
809                 return false;
810         }
811
812         generate_random_buffer((uint8_t *)confounder, 16);
813
814         MD5Init(&ctx);
815         MD5Update(&ctx, confounder, 16);
816         MD5Update(&ctx, session_key.data, session_key.length);
817         MD5Final(confounded_session_key.data, &ctx);
818
819         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
820         memcpy(&u.info25.password.data[516], confounder, 16);
821
822         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
823
824         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
825         if (!NT_STATUS_IS_OK(status)) {
826                 printf("SetUserInfo level %u failed - %s\n",
827                        s.in.level, nt_errstr(status));
828                 ret = false;
829         } else {
830                 *password = newpass;
831         }
832
833         /* This should break the key nicely */
834         confounded_session_key.data[0]++;
835
836         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
837         memcpy(&u.info25.password.data[516], confounder, 16);
838
839         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
840
841         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
842         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
843                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
844                        s.in.level, nt_errstr(status));
845                 ret = false;
846         }
847
848         return ret;
849 }
850
851 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
852                                       struct torture_context *tctx,
853                                       struct policy_handle *handle,
854                                       uint16_t level,
855                                       uint32_t fields_present,
856                                       char **password, uint8_t password_expired,
857                                       bool use_setinfo2, NTSTATUS expected_error)
858 {
859         NTSTATUS status;
860         struct samr_SetUserInfo s;
861         struct samr_SetUserInfo2 s2;
862         union samr_UserInfo u;
863         bool ret = true;
864         DATA_BLOB session_key;
865         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
866         struct MD5Context ctx;
867         uint8_t confounder[16];
868         char *newpass;
869         struct samr_GetUserPwInfo pwp;
870         struct samr_PwInfo info;
871         int policy_min_pw_len = 0;
872         pwp.in.user_handle = handle;
873         pwp.out.info = &info;
874
875         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
876         if (NT_STATUS_IS_OK(status)) {
877                 policy_min_pw_len = pwp.out.info->min_password_length;
878         }
879         newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
880
881         if (use_setinfo2) {
882                 s2.in.user_handle = handle;
883                 s2.in.info = &u;
884                 s2.in.level = level;
885         } else {
886                 s.in.user_handle = handle;
887                 s.in.info = &u;
888                 s.in.level = level;
889         }
890
891         ZERO_STRUCT(u);
892
893         switch (level) {
894         case 21:
895                 u.info21.fields_present = fields_present;
896                 u.info21.password_expired = password_expired;
897
898                 break;
899         case 23:
900                 u.info23.info.fields_present = fields_present;
901                 u.info23.info.password_expired = password_expired;
902
903                 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
904
905                 break;
906         case 24:
907                 u.info24.password_expired = password_expired;
908
909                 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
910
911                 break;
912         case 25:
913                 u.info25.info.fields_present = fields_present;
914                 u.info25.info.password_expired = password_expired;
915
916                 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
917
918                 break;
919         case 26:
920                 u.info26.password_expired = password_expired;
921
922                 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
923
924                 break;
925         }
926
927         status = dcerpc_fetch_session_key(p, &session_key);
928         if (!NT_STATUS_IS_OK(status)) {
929                 printf("SetUserInfo level %u - no session key - %s\n",
930                        s.in.level, nt_errstr(status));
931                 return false;
932         }
933
934         generate_random_buffer((uint8_t *)confounder, 16);
935
936         MD5Init(&ctx);
937         MD5Update(&ctx, confounder, 16);
938         MD5Update(&ctx, session_key.data, session_key.length);
939         MD5Final(confounded_session_key.data, &ctx);
940
941         switch (level) {
942         case 23:
943                 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
944                 break;
945         case 24:
946                 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
947                 break;
948         case 25:
949                 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
950                 memcpy(&u.info25.password.data[516], confounder, 16);
951                 break;
952         case 26:
953                 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
954                 memcpy(&u.info26.password.data[516], confounder, 16);
955                 break;
956         }
957
958         if (use_setinfo2) {
959                 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
960         } else {
961                 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
962         }
963
964         if (NT_STATUS_IS_ERR(expected_error)) {
965                 torture_assert_ntstatus_equal(tctx, status, expected_error, "");
966                 return true;
967         }
968
969         if (!NT_STATUS_IS_OK(status)) {
970                 printf("SetUserInfo%s level %u failed - %s\n",
971                        use_setinfo2 ? "2":"", level, nt_errstr(status));
972                 ret = false;
973         } else {
974                 if (level != 21) {
975                         *password = newpass;
976                 }
977         }
978
979         return ret;
980 }
981
982 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
983                                struct policy_handle *handle)
984 {
985         NTSTATUS status;
986         struct samr_SetAliasInfo r;
987         struct samr_QueryAliasInfo q;
988         union samr_AliasInfo *info;
989         uint16_t levels[] = {2, 3};
990         int i;
991         bool ret = true;
992
993         /* Ignoring switch level 1, as that includes the number of members for the alias
994          * and setting this to a wrong value might have negative consequences
995          */
996
997         for (i=0;i<ARRAY_SIZE(levels);i++) {
998                 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
999
1000                 r.in.alias_handle = handle;
1001                 r.in.level = levels[i];
1002                 r.in.info  = talloc(tctx, union samr_AliasInfo);
1003                 switch (r.in.level) {
1004                     case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1005                     case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1006                                 "Test Description, should test I18N as well"); break;
1007                     case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1008                 }
1009
1010                 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1011                 if (!NT_STATUS_IS_OK(status)) {
1012                         printf("SetAliasInfo level %u failed - %s\n",
1013                                levels[i], nt_errstr(status));
1014                         ret = false;
1015                 }
1016
1017                 q.in.alias_handle = handle;
1018                 q.in.level = levels[i];
1019                 q.out.info = &info;
1020
1021                 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1022                 if (!NT_STATUS_IS_OK(status)) {
1023                         printf("QueryAliasInfo level %u failed - %s\n",
1024                                levels[i], nt_errstr(status));
1025                         ret = false;
1026                 }
1027         }
1028
1029         return ret;
1030 }
1031
1032 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1033                                   struct policy_handle *user_handle)
1034 {
1035         struct samr_GetGroupsForUser r;
1036         struct samr_RidWithAttributeArray *rids = NULL;
1037         NTSTATUS status;
1038
1039         torture_comment(tctx, "testing GetGroupsForUser\n");
1040
1041         r.in.user_handle = user_handle;
1042         r.out.rids = &rids;
1043
1044         status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1045         torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1046
1047         return true;
1048
1049 }
1050
1051 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1052                               struct lsa_String *domain_name)
1053 {
1054         NTSTATUS status;
1055         struct samr_GetDomPwInfo r;
1056         struct samr_PwInfo info;
1057
1058         r.in.domain_name = domain_name;
1059         r.out.info = &info;
1060
1061         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1062
1063         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1064         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1065
1066         r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1067         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1068
1069         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1070         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1071
1072         r.in.domain_name->string = "\\\\__NONAME__";
1073         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1074
1075         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1076         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1077
1078         r.in.domain_name->string = "\\\\Builtin";
1079         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1080
1081         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1082         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1083
1084         return true;
1085 }
1086
1087 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1088                                struct policy_handle *handle)
1089 {
1090         NTSTATUS status;
1091         struct samr_GetUserPwInfo r;
1092         struct samr_PwInfo info;
1093
1094         torture_comment(tctx, "Testing GetUserPwInfo\n");
1095
1096         r.in.user_handle = handle;
1097         r.out.info = &info;
1098
1099         status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1100         torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1101
1102         return true;
1103 }
1104
1105 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1106                                 struct policy_handle *domain_handle, const char *name,
1107                                 uint32_t *rid)
1108 {
1109         NTSTATUS status;
1110         struct samr_LookupNames n;
1111         struct lsa_String sname[2];
1112         struct samr_Ids rids, types;
1113
1114         init_lsa_String(&sname[0], name);
1115
1116         n.in.domain_handle = domain_handle;
1117         n.in.num_names = 1;
1118         n.in.names = sname;
1119         n.out.rids = &rids;
1120         n.out.types = &types;
1121         status = dcerpc_samr_LookupNames(p, tctx, &n);
1122         if (NT_STATUS_IS_OK(status)) {
1123                 *rid = n.out.rids->ids[0];
1124         } else {
1125                 return status;
1126         }
1127
1128         init_lsa_String(&sname[1], "xxNONAMExx");
1129         n.in.num_names = 2;
1130         status = dcerpc_samr_LookupNames(p, tctx, &n);
1131         if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1132                 printf("LookupNames[2] failed - %s\n", nt_errstr(status));              
1133                 if (NT_STATUS_IS_OK(status)) {
1134                         return NT_STATUS_UNSUCCESSFUL;
1135                 }
1136                 return status;
1137         }
1138
1139         n.in.num_names = 0;
1140         status = dcerpc_samr_LookupNames(p, tctx, &n);
1141         if (!NT_STATUS_IS_OK(status)) {
1142                 printf("LookupNames[0] failed - %s\n", nt_errstr(status));              
1143                 return status;
1144         }
1145
1146         init_lsa_String(&sname[0], "xxNONAMExx");
1147         n.in.num_names = 1;
1148         status = dcerpc_samr_LookupNames(p, tctx, &n);
1149         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1150                 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));             
1151                 if (NT_STATUS_IS_OK(status)) {
1152                         return NT_STATUS_UNSUCCESSFUL;
1153                 }
1154                 return status;
1155         }
1156
1157         init_lsa_String(&sname[0], "xxNONAMExx");
1158         init_lsa_String(&sname[1], "xxNONAME2xx");
1159         n.in.num_names = 2;
1160         status = dcerpc_samr_LookupNames(p, tctx, &n);
1161         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1162                 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));            
1163                 if (NT_STATUS_IS_OK(status)) {
1164                         return NT_STATUS_UNSUCCESSFUL;
1165                 }
1166                 return status;
1167         }
1168
1169         return NT_STATUS_OK;
1170 }
1171
1172 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1173                                      struct policy_handle *domain_handle,
1174                                      const char *name, struct policy_handle *user_handle)
1175 {
1176         NTSTATUS status;
1177         struct samr_OpenUser r;
1178         uint32_t rid;
1179
1180         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1181         if (!NT_STATUS_IS_OK(status)) {
1182                 return status;
1183         }
1184
1185         r.in.domain_handle = domain_handle;
1186         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1187         r.in.rid = rid;
1188         r.out.user_handle = user_handle;
1189         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1190         if (!NT_STATUS_IS_OK(status)) {
1191                 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1192         }
1193
1194         return status;
1195 }
1196
1197 #if 0
1198 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1199                                    struct policy_handle *handle)
1200 {
1201         NTSTATUS status;
1202         struct samr_ChangePasswordUser r;
1203         bool ret = true;
1204         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1205         struct policy_handle user_handle;
1206         char *oldpass = "test";
1207         char *newpass = "test2";
1208         uint8_t old_nt_hash[16], new_nt_hash[16];
1209         uint8_t old_lm_hash[16], new_lm_hash[16];
1210
1211         status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1212         if (!NT_STATUS_IS_OK(status)) {
1213                 return false;
1214         }
1215
1216         printf("Testing ChangePasswordUser for user 'testuser'\n");
1217
1218         printf("old password: %s\n", oldpass);
1219         printf("new password: %s\n", newpass);
1220
1221         E_md4hash(oldpass, old_nt_hash);
1222         E_md4hash(newpass, new_nt_hash);
1223         E_deshash(oldpass, old_lm_hash);
1224         E_deshash(newpass, new_lm_hash);
1225
1226         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1227         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1228         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1229         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1230         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1231         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1232
1233         r.in.handle = &user_handle;
1234         r.in.lm_present = 1;
1235         r.in.old_lm_crypted = &hash1;
1236         r.in.new_lm_crypted = &hash2;
1237         r.in.nt_present = 1;
1238         r.in.old_nt_crypted = &hash3;
1239         r.in.new_nt_crypted = &hash4;
1240         r.in.cross1_present = 1;
1241         r.in.nt_cross = &hash5;
1242         r.in.cross2_present = 1;
1243         r.in.lm_cross = &hash6;
1244
1245         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1246         if (!NT_STATUS_IS_OK(status)) {
1247                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1248                 ret = false;
1249         }
1250
1251         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1252                 ret = false;
1253         }
1254
1255         return ret;
1256 }
1257 #endif
1258
1259 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1260                                     const char *acct_name, 
1261                                     struct policy_handle *handle, char **password)
1262 {
1263         NTSTATUS status;
1264         struct samr_ChangePasswordUser r;
1265         bool ret = true;
1266         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1267         struct policy_handle user_handle;
1268         char *oldpass;
1269         uint8_t old_nt_hash[16], new_nt_hash[16];
1270         uint8_t old_lm_hash[16], new_lm_hash[16];
1271         bool changed = true;
1272
1273         char *newpass;
1274         struct samr_GetUserPwInfo pwp;
1275         struct samr_PwInfo info;
1276         int policy_min_pw_len = 0;
1277
1278         status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1279         if (!NT_STATUS_IS_OK(status)) {
1280                 return false;
1281         }
1282         pwp.in.user_handle = &user_handle;
1283         pwp.out.info = &info;
1284
1285         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1286         if (NT_STATUS_IS_OK(status)) {
1287                 policy_min_pw_len = pwp.out.info->min_password_length;
1288         }
1289         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1290
1291         torture_comment(tctx, "Testing ChangePasswordUser\n");
1292
1293         torture_assert(tctx, *password != NULL, 
1294                                    "Failing ChangePasswordUser as old password was NULL.  Previous test failed?");
1295
1296         oldpass = *password;
1297
1298         E_md4hash(oldpass, old_nt_hash);
1299         E_md4hash(newpass, new_nt_hash);
1300         E_deshash(oldpass, old_lm_hash);
1301         E_deshash(newpass, new_lm_hash);
1302
1303         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1304         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1305         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1306         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1307         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1308         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1309
1310         r.in.user_handle = &user_handle;
1311         r.in.lm_present = 1;
1312         /* Break the LM hash */
1313         hash1.hash[0]++;
1314         r.in.old_lm_crypted = &hash1;
1315         r.in.new_lm_crypted = &hash2;
1316         r.in.nt_present = 1;
1317         r.in.old_nt_crypted = &hash3;
1318         r.in.new_nt_crypted = &hash4;
1319         r.in.cross1_present = 1;
1320         r.in.nt_cross = &hash5;
1321         r.in.cross2_present = 1;
1322         r.in.lm_cross = &hash6;
1323
1324         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1325         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1326                 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1327
1328         /* Unbreak the LM hash */
1329         hash1.hash[0]--;
1330
1331         r.in.user_handle = &user_handle;
1332         r.in.lm_present = 1;
1333         r.in.old_lm_crypted = &hash1;
1334         r.in.new_lm_crypted = &hash2;
1335         /* Break the NT hash */
1336         hash3.hash[0]--;
1337         r.in.nt_present = 1;
1338         r.in.old_nt_crypted = &hash3;
1339         r.in.new_nt_crypted = &hash4;
1340         r.in.cross1_present = 1;
1341         r.in.nt_cross = &hash5;
1342         r.in.cross2_present = 1;
1343         r.in.lm_cross = &hash6;
1344
1345         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1346         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD, 
1347                 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1348
1349         /* Unbreak the NT hash */
1350         hash3.hash[0]--;
1351
1352         r.in.user_handle = &user_handle;
1353         r.in.lm_present = 1;
1354         r.in.old_lm_crypted = &hash1;
1355         r.in.new_lm_crypted = &hash2;
1356         r.in.nt_present = 1;
1357         r.in.old_nt_crypted = &hash3;
1358         r.in.new_nt_crypted = &hash4;
1359         r.in.cross1_present = 1;
1360         r.in.nt_cross = &hash5;
1361         r.in.cross2_present = 1;
1362         /* Break the LM cross */
1363         hash6.hash[0]++;
1364         r.in.lm_cross = &hash6;
1365
1366         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1367         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1368                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1369                 ret = false;
1370         }
1371
1372         /* Unbreak the LM cross */
1373         hash6.hash[0]--;
1374
1375         r.in.user_handle = &user_handle;
1376         r.in.lm_present = 1;
1377         r.in.old_lm_crypted = &hash1;
1378         r.in.new_lm_crypted = &hash2;
1379         r.in.nt_present = 1;
1380         r.in.old_nt_crypted = &hash3;
1381         r.in.new_nt_crypted = &hash4;
1382         r.in.cross1_present = 1;
1383         /* Break the NT cross */
1384         hash5.hash[0]++;
1385         r.in.nt_cross = &hash5;
1386         r.in.cross2_present = 1;
1387         r.in.lm_cross = &hash6;
1388
1389         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1390         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1391                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1392                 ret = false;
1393         }
1394
1395         /* Unbreak the NT cross */
1396         hash5.hash[0]--;
1397
1398
1399         /* Reset the hashes to not broken values */
1400         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1401         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1402         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1403         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1404         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1405         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1406
1407         r.in.user_handle = &user_handle;
1408         r.in.lm_present = 1;
1409         r.in.old_lm_crypted = &hash1;
1410         r.in.new_lm_crypted = &hash2;
1411         r.in.nt_present = 1;
1412         r.in.old_nt_crypted = &hash3;
1413         r.in.new_nt_crypted = &hash4;
1414         r.in.cross1_present = 1;
1415         r.in.nt_cross = &hash5;
1416         r.in.cross2_present = 0;
1417         r.in.lm_cross = NULL;
1418
1419         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1420         if (NT_STATUS_IS_OK(status)) {
1421                 changed = true;
1422                 *password = newpass;
1423         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1424                 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1425                 ret = false;
1426         }
1427
1428         oldpass = newpass;
1429         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1430
1431         E_md4hash(oldpass, old_nt_hash);
1432         E_md4hash(newpass, new_nt_hash);
1433         E_deshash(oldpass, old_lm_hash);
1434         E_deshash(newpass, new_lm_hash);
1435
1436
1437         /* Reset the hashes to not broken values */
1438         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1439         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1440         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1441         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1442         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1443         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1444
1445         r.in.user_handle = &user_handle;
1446         r.in.lm_present = 1;
1447         r.in.old_lm_crypted = &hash1;
1448         r.in.new_lm_crypted = &hash2;
1449         r.in.nt_present = 1;
1450         r.in.old_nt_crypted = &hash3;
1451         r.in.new_nt_crypted = &hash4;
1452         r.in.cross1_present = 0;
1453         r.in.nt_cross = NULL;
1454         r.in.cross2_present = 1;
1455         r.in.lm_cross = &hash6;
1456
1457         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1458         if (NT_STATUS_IS_OK(status)) {
1459                 changed = true;
1460                 *password = newpass;
1461         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1462                 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1463                 ret = false;
1464         }
1465
1466         oldpass = newpass;
1467         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1468
1469         E_md4hash(oldpass, old_nt_hash);
1470         E_md4hash(newpass, new_nt_hash);
1471         E_deshash(oldpass, old_lm_hash);
1472         E_deshash(newpass, new_lm_hash);
1473
1474
1475         /* Reset the hashes to not broken values */
1476         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1477         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1478         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1479         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1480         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1481         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1482
1483         r.in.user_handle = &user_handle;
1484         r.in.lm_present = 1;
1485         r.in.old_lm_crypted = &hash1;
1486         r.in.new_lm_crypted = &hash2;
1487         r.in.nt_present = 1;
1488         r.in.old_nt_crypted = &hash3;
1489         r.in.new_nt_crypted = &hash4;
1490         r.in.cross1_present = 1;
1491         r.in.nt_cross = &hash5;
1492         r.in.cross2_present = 1;
1493         r.in.lm_cross = &hash6;
1494
1495         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1496         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1497                 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1498         } else  if (!NT_STATUS_IS_OK(status)) {
1499                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1500                 ret = false;
1501         } else {
1502                 changed = true;
1503                 *password = newpass;
1504         }
1505
1506         r.in.user_handle = &user_handle;
1507         r.in.lm_present = 1;
1508         r.in.old_lm_crypted = &hash1;
1509         r.in.new_lm_crypted = &hash2;
1510         r.in.nt_present = 1;
1511         r.in.old_nt_crypted = &hash3;
1512         r.in.new_nt_crypted = &hash4;
1513         r.in.cross1_present = 1;
1514         r.in.nt_cross = &hash5;
1515         r.in.cross2_present = 1;
1516         r.in.lm_cross = &hash6;
1517
1518         if (changed) {
1519                 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1520                 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1521                         printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1522                 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1523                         printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1524                         ret = false;
1525                 }
1526         }
1527
1528         
1529         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1530                 ret = false;
1531         }
1532
1533         return ret;
1534 }
1535
1536
1537 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1538                                         const char *acct_name,
1539                                         struct policy_handle *handle, char **password)
1540 {
1541         NTSTATUS status;
1542         struct samr_OemChangePasswordUser2 r;
1543         bool ret = true;
1544         struct samr_Password lm_verifier;
1545         struct samr_CryptPassword lm_pass;
1546         struct lsa_AsciiString server, account, account_bad;
1547         char *oldpass;
1548         char *newpass;
1549         uint8_t old_lm_hash[16], new_lm_hash[16];
1550
1551         struct samr_GetDomPwInfo dom_pw_info;
1552         struct samr_PwInfo info;
1553         int policy_min_pw_len = 0;
1554
1555         struct lsa_String domain_name;
1556
1557         domain_name.string = "";
1558         dom_pw_info.in.domain_name = &domain_name;
1559         dom_pw_info.out.info = &info;
1560
1561         torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1562
1563         torture_assert(tctx, *password != NULL, 
1564                                    "Failing OemChangePasswordUser2 as old password was NULL.  Previous test failed?");
1565
1566         oldpass = *password;
1567
1568         status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1569         if (NT_STATUS_IS_OK(status)) {
1570                 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1571         }
1572
1573         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1574
1575         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1576         account.string = acct_name;
1577
1578         E_deshash(oldpass, old_lm_hash);
1579         E_deshash(newpass, new_lm_hash);
1580
1581         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1582         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1583         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1584
1585         r.in.server = &server;
1586         r.in.account = &account;
1587         r.in.password = &lm_pass;
1588         r.in.hash = &lm_verifier;
1589
1590         /* Break the verification */
1591         lm_verifier.hash[0]++;
1592
1593         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1594
1595         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1596             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1597                 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1598                         nt_errstr(status));
1599                 ret = false;
1600         }
1601
1602         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1603         /* Break the old password */
1604         old_lm_hash[0]++;
1605         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1606         /* unbreak it for the next operation */
1607         old_lm_hash[0]--;
1608         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1609
1610         r.in.server = &server;
1611         r.in.account = &account;
1612         r.in.password = &lm_pass;
1613         r.in.hash = &lm_verifier;
1614
1615         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1616
1617         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1618             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1619                 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1620                         nt_errstr(status));
1621                 ret = false;
1622         }
1623
1624         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1625         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1626
1627         r.in.server = &server;
1628         r.in.account = &account;
1629         r.in.password = &lm_pass;
1630         r.in.hash = NULL;
1631
1632         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1633
1634         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1635             && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1636                 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1637                         nt_errstr(status));
1638                 ret = false;
1639         }
1640
1641         /* This shouldn't be a valid name */
1642         account_bad.string = TEST_ACCOUNT_NAME "XX";
1643         r.in.account = &account_bad;
1644
1645         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1646
1647         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1648                 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1649                         nt_errstr(status));
1650                 ret = false;
1651         }
1652
1653         /* This shouldn't be a valid name */
1654         account_bad.string = TEST_ACCOUNT_NAME "XX";
1655         r.in.account = &account_bad;
1656         r.in.password = &lm_pass;
1657         r.in.hash = &lm_verifier;
1658
1659         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1660
1661         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1662                 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1663                         nt_errstr(status));
1664                 ret = false;
1665         }
1666
1667         /* This shouldn't be a valid name */
1668         account_bad.string = TEST_ACCOUNT_NAME "XX";
1669         r.in.account = &account_bad;
1670         r.in.password = NULL;
1671         r.in.hash = &lm_verifier;
1672
1673         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1674
1675         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1676                 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1677                         nt_errstr(status));
1678                 ret = false;
1679         }
1680
1681         E_deshash(oldpass, old_lm_hash);
1682         E_deshash(newpass, new_lm_hash);
1683
1684         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1685         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1686         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1687
1688         r.in.server = &server;
1689         r.in.account = &account;
1690         r.in.password = &lm_pass;
1691         r.in.hash = &lm_verifier;
1692
1693         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1694         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1695                 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1696         } else if (!NT_STATUS_IS_OK(status)) {
1697                 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1698                 ret = false;
1699         } else {
1700                 *password = newpass;
1701         }
1702
1703         return ret;
1704 }
1705
1706
1707 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1708                                      const char *acct_name,
1709                                      char **password,
1710                                      char *newpass, bool allow_password_restriction)
1711 {
1712         NTSTATUS status;
1713         struct samr_ChangePasswordUser2 r;
1714         bool ret = true;
1715         struct lsa_String server, account;
1716         struct samr_CryptPassword nt_pass, lm_pass;
1717         struct samr_Password nt_verifier, lm_verifier;
1718         char *oldpass;
1719         uint8_t old_nt_hash[16], new_nt_hash[16];
1720         uint8_t old_lm_hash[16], new_lm_hash[16];
1721
1722         struct samr_GetDomPwInfo dom_pw_info;
1723         struct samr_PwInfo info;
1724
1725         struct lsa_String domain_name;
1726
1727         domain_name.string = "";
1728         dom_pw_info.in.domain_name = &domain_name;
1729         dom_pw_info.out.info = &info;
1730
1731         torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
1732
1733         torture_assert(tctx, *password != NULL, 
1734                                    "Failing ChangePasswordUser2 as old password was NULL.  Previous test failed?");
1735         oldpass = *password;
1736
1737         if (!newpass) {
1738                 int policy_min_pw_len = 0;
1739                 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1740                 if (NT_STATUS_IS_OK(status)) {
1741                         policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1742                 }
1743
1744                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1745         } 
1746
1747         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1748         init_lsa_String(&account, acct_name);
1749
1750         E_md4hash(oldpass, old_nt_hash);
1751         E_md4hash(newpass, new_nt_hash);
1752
1753         E_deshash(oldpass, old_lm_hash);
1754         E_deshash(newpass, new_lm_hash);
1755
1756         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1757         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1758         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1759
1760         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1761         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1762         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1763
1764         r.in.server = &server;
1765         r.in.account = &account;
1766         r.in.nt_password = &nt_pass;
1767         r.in.nt_verifier = &nt_verifier;
1768         r.in.lm_change = 1;
1769         r.in.lm_password = &lm_pass;
1770         r.in.lm_verifier = &lm_verifier;
1771
1772         status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
1773         if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1774                 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1775         } else if (!NT_STATUS_IS_OK(status)) {
1776                 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1777                 ret = false;
1778         } else {
1779                 *password = newpass;
1780         }
1781
1782         return ret;
1783 }
1784
1785
1786 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx, 
1787                               const char *account_string,
1788                               int policy_min_pw_len,
1789                               char **password,
1790                               const char *newpass,
1791                               NTTIME last_password_change,
1792                               bool handle_reject_reason)
1793 {
1794         NTSTATUS status;
1795         struct samr_ChangePasswordUser3 r;
1796         bool ret = true;
1797         struct lsa_String server, account, account_bad;
1798         struct samr_CryptPassword nt_pass, lm_pass;
1799         struct samr_Password nt_verifier, lm_verifier;
1800         char *oldpass;
1801         uint8_t old_nt_hash[16], new_nt_hash[16];
1802         uint8_t old_lm_hash[16], new_lm_hash[16];
1803         NTTIME t;
1804         struct samr_DomInfo1 *dominfo = NULL;
1805         struct samr_ChangeReject *reject = NULL;
1806
1807         torture_comment(tctx, "Testing ChangePasswordUser3\n");
1808
1809         if (newpass == NULL) {
1810                 do {
1811                         if (policy_min_pw_len == 0) {
1812                                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1813                         } else {
1814                                 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
1815                         }
1816                 } while (check_password_quality(newpass) == false);
1817         } else {
1818                 torture_comment(tctx, "Using password '%s'\n", newpass);
1819         }
1820
1821         torture_assert(tctx, *password != NULL, 
1822                                    "Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?");
1823
1824         oldpass = *password;
1825         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1826         init_lsa_String(&account, account_string);
1827
1828         E_md4hash(oldpass, old_nt_hash);
1829         E_md4hash(newpass, new_nt_hash);
1830
1831         E_deshash(oldpass, old_lm_hash);
1832         E_deshash(newpass, new_lm_hash);
1833
1834         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1835         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1836         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1837
1838         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1839         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1840         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1841         
1842         /* Break the verification */
1843         nt_verifier.hash[0]++;
1844
1845         r.in.server = &server;
1846         r.in.account = &account;
1847         r.in.nt_password = &nt_pass;
1848         r.in.nt_verifier = &nt_verifier;
1849         r.in.lm_change = 1;
1850         r.in.lm_password = &lm_pass;
1851         r.in.lm_verifier = &lm_verifier;
1852         r.in.password3 = NULL;
1853         r.out.dominfo = &dominfo;
1854         r.out.reject = &reject;
1855
1856         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1857         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1858             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1859                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1860                         nt_errstr(status));
1861                 ret = false;
1862         }
1863         
1864         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1865         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1866         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1867
1868         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1869         /* Break the NT hash */
1870         old_nt_hash[0]++;
1871         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1872         /* Unbreak it again */
1873         old_nt_hash[0]--;
1874         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1875         
1876         r.in.server = &server;
1877         r.in.account = &account;
1878         r.in.nt_password = &nt_pass;
1879         r.in.nt_verifier = &nt_verifier;
1880         r.in.lm_change = 1;
1881         r.in.lm_password = &lm_pass;
1882         r.in.lm_verifier = &lm_verifier;
1883         r.in.password3 = NULL;
1884         r.out.dominfo = &dominfo;
1885         r.out.reject = &reject;
1886
1887         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1888         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1889             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1890                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1891                         nt_errstr(status));
1892                 ret = false;
1893         }
1894         
1895         /* This shouldn't be a valid name */
1896         init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
1897
1898         r.in.account = &account_bad;
1899         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1900         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1901                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1902                         nt_errstr(status));
1903                 ret = false;
1904         }
1905
1906         E_md4hash(oldpass, old_nt_hash);
1907         E_md4hash(newpass, new_nt_hash);
1908
1909         E_deshash(oldpass, old_lm_hash);
1910         E_deshash(newpass, new_lm_hash);
1911
1912         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1913         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1914         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1915
1916         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1917         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1918         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1919
1920         r.in.server = &server;
1921         r.in.account = &account;
1922         r.in.nt_password = &nt_pass;
1923         r.in.nt_verifier = &nt_verifier;
1924         r.in.lm_change = 1;
1925         r.in.lm_password = &lm_pass;
1926         r.in.lm_verifier = &lm_verifier;
1927         r.in.password3 = NULL;
1928         r.out.dominfo = &dominfo;
1929         r.out.reject = &reject;
1930
1931         unix_to_nt_time(&t, time(NULL));
1932
1933         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1934
1935         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1936             && dominfo
1937             && reject
1938             && handle_reject_reason
1939             && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
1940                 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1941
1942                         if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
1943                                 printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
1944                                         SAMR_REJECT_OTHER, reject->reason);
1945                                 return false;
1946                         }
1947                 }
1948
1949                 /* We tested the order of precendence which is as follows:
1950                 
1951                 * pwd min_age 
1952                 * pwd length
1953                 * pwd complexity
1954                 * pwd history
1955
1956                 Guenther */
1957
1958                 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1959                            (last_password_change + dominfo->min_password_age > t)) {
1960
1961                         if (reject->reason != SAMR_REJECT_OTHER) {
1962                                 printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
1963                                         SAMR_REJECT_OTHER, reject->reason);
1964                                 return false;
1965                         }
1966
1967                 } else if ((dominfo->min_password_length > 0) &&
1968                            (strlen(newpass) < dominfo->min_password_length)) {
1969
1970                         if (reject->reason != SAMR_REJECT_TOO_SHORT) {
1971                                 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n", 
1972                                         SAMR_REJECT_TOO_SHORT, reject->reason);
1973                                 return false;
1974                         }
1975
1976                 } else if ((dominfo->password_history_length > 0) &&
1977                             strequal(oldpass, newpass)) {
1978
1979                         if (reject->reason != SAMR_REJECT_IN_HISTORY) {
1980                                 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n", 
1981                                         SAMR_REJECT_IN_HISTORY, reject->reason);
1982                                 return false;
1983                         }
1984                 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1985
1986                         if (reject->reason != SAMR_REJECT_COMPLEXITY) {
1987                                 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n", 
1988                                         SAMR_REJECT_COMPLEXITY, reject->reason);
1989                                 return false;
1990                         }
1991
1992                 }
1993
1994                 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
1995                         /* retry with adjusted size */
1996                         return test_ChangePasswordUser3(p, tctx, account_string, 
1997                                                         dominfo->min_password_length,
1998                                                         password, NULL, 0, false); 
1999
2000                 }
2001
2002         } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2003                 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2004                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
2005                                SAMR_REJECT_OTHER, reject->reason);
2006                         return false;
2007                 }
2008                 /* Perhaps the server has a 'min password age' set? */
2009
2010         } else { 
2011                 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2012                 *password = talloc_strdup(tctx, newpass);
2013         }
2014
2015         return ret;
2016 }
2017
2018 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2019                                     const char *account_string,
2020                                     struct policy_handle *handle, 
2021                                     char **password)
2022 {
2023         NTSTATUS status;
2024         struct samr_ChangePasswordUser3 r;
2025         struct samr_SetUserInfo s;
2026         union samr_UserInfo u;
2027         DATA_BLOB session_key;
2028         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2029         uint8_t confounder[16];
2030         struct MD5Context ctx;
2031
2032         bool ret = true;
2033         struct lsa_String server, account;
2034         struct samr_CryptPassword nt_pass;
2035         struct samr_Password nt_verifier;
2036         DATA_BLOB new_random_pass;
2037         char *newpass;
2038         char *oldpass;
2039         uint8_t old_nt_hash[16], new_nt_hash[16];
2040         NTTIME t;
2041         struct samr_DomInfo1 *dominfo = NULL;
2042         struct samr_ChangeReject *reject = NULL;
2043
2044         new_random_pass = samr_very_rand_pass(tctx, 128);
2045
2046         torture_assert(tctx, *password != NULL, 
2047                                    "Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?");
2048
2049         oldpass = *password;
2050         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2051         init_lsa_String(&account, account_string);
2052
2053         s.in.user_handle = handle;
2054         s.in.info = &u;
2055         s.in.level = 25;
2056
2057         ZERO_STRUCT(u);
2058
2059         u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
2060
2061         set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2062
2063         status = dcerpc_fetch_session_key(p, &session_key);
2064         if (!NT_STATUS_IS_OK(status)) {
2065                 printf("SetUserInfo level %u - no session key - %s\n",
2066                        s.in.level, nt_errstr(status));
2067                 return false;
2068         }
2069
2070         generate_random_buffer((uint8_t *)confounder, 16);
2071
2072         MD5Init(&ctx);
2073         MD5Update(&ctx, confounder, 16);
2074         MD5Update(&ctx, session_key.data, session_key.length);
2075         MD5Final(confounded_session_key.data, &ctx);
2076
2077         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2078         memcpy(&u.info25.password.data[516], confounder, 16);
2079
2080         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2081
2082         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2083         if (!NT_STATUS_IS_OK(status)) {
2084                 printf("SetUserInfo level %u failed - %s\n",
2085                        s.in.level, nt_errstr(status));
2086                 ret = false;
2087         }
2088
2089         torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2090
2091         mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2092
2093         new_random_pass = samr_very_rand_pass(tctx, 128);
2094
2095         mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2096
2097         set_pw_in_buffer(nt_pass.data, &new_random_pass);
2098         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2099         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2100
2101         r.in.server = &server;
2102         r.in.account = &account;
2103         r.in.nt_password = &nt_pass;
2104         r.in.nt_verifier = &nt_verifier;
2105         r.in.lm_change = 0;
2106         r.in.lm_password = NULL;
2107         r.in.lm_verifier = NULL;
2108         r.in.password3 = NULL;
2109         r.out.dominfo = &dominfo;
2110         r.out.reject = &reject;
2111
2112         unix_to_nt_time(&t, time(NULL));
2113
2114         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2115
2116         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2117                 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2118                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
2119                                SAMR_REJECT_OTHER, reject->reason);
2120                         return false;
2121                 }
2122                 /* Perhaps the server has a 'min password age' set? */
2123
2124         } else if (!NT_STATUS_IS_OK(status)) {
2125                 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2126                 ret = false;
2127         }
2128         
2129         newpass = samr_rand_pass(tctx, 128);
2130
2131         mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2132
2133         E_md4hash(newpass, new_nt_hash);
2134
2135         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2136         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2137         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2138
2139         r.in.server = &server;
2140         r.in.account = &account;
2141         r.in.nt_password = &nt_pass;
2142         r.in.nt_verifier = &nt_verifier;
2143         r.in.lm_change = 0;
2144         r.in.lm_password = NULL;
2145         r.in.lm_verifier = NULL;
2146         r.in.password3 = NULL;
2147         r.out.dominfo = &dominfo;
2148         r.out.reject = &reject;
2149
2150         unix_to_nt_time(&t, time(NULL));
2151
2152         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2153
2154         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2155                 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2156                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
2157                                SAMR_REJECT_OTHER, reject->reason);
2158                         return false;
2159                 }
2160                 /* Perhaps the server has a 'min password age' set? */
2161
2162         } else {
2163                 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2164                 *password = talloc_strdup(tctx, newpass);
2165         }
2166
2167         return ret;
2168 }
2169
2170
2171 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2172                                   struct policy_handle *alias_handle)
2173 {
2174         struct samr_GetMembersInAlias r;
2175         struct lsa_SidArray sids;
2176         NTSTATUS status;
2177
2178         torture_comment(tctx, "Testing GetMembersInAlias\n");
2179
2180         r.in.alias_handle = alias_handle;
2181         r.out.sids = &sids;
2182
2183         status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2184         torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2185
2186         return true;
2187 }
2188
2189 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2190                                   struct policy_handle *alias_handle,
2191                                   const struct dom_sid *domain_sid)
2192 {
2193         struct samr_AddAliasMember r;
2194         struct samr_DeleteAliasMember d;
2195         NTSTATUS status;
2196         struct dom_sid *sid;
2197
2198         sid = dom_sid_add_rid(tctx, domain_sid, 512);
2199
2200         torture_comment(tctx, "testing AddAliasMember\n");
2201         r.in.alias_handle = alias_handle;
2202         r.in.sid = sid;
2203
2204         status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2205         torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2206
2207         d.in.alias_handle = alias_handle;
2208         d.in.sid = sid;
2209
2210         status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2211         torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2212
2213         return true;
2214 }
2215
2216 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2217                                            struct policy_handle *alias_handle)
2218 {
2219         struct samr_AddMultipleMembersToAlias a;
2220         struct samr_RemoveMultipleMembersFromAlias r;
2221         NTSTATUS status;
2222         struct lsa_SidArray sids;
2223
2224         torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2225         a.in.alias_handle = alias_handle;
2226         a.in.sids = &sids;
2227
2228         sids.num_sids = 3;
2229         sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2230
2231         sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2232         sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2233         sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2234
2235         status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2236         torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2237
2238
2239         torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2240         r.in.alias_handle = alias_handle;
2241         r.in.sids = &sids;
2242
2243         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2244         torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2245
2246         /* strange! removing twice doesn't give any error */
2247         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2248         torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2249
2250         /* but removing an alias that isn't there does */
2251         sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2252
2253         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2254         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2255
2256         return true;
2257 }
2258
2259 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2260                                             struct policy_handle *user_handle)
2261 {
2262         struct samr_TestPrivateFunctionsUser r;
2263         NTSTATUS status;
2264
2265         torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2266
2267         r.in.user_handle = user_handle;
2268
2269         status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2270         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2271
2272         return true;
2273 }
2274
2275 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2276                                           struct torture_context *tctx,
2277                                           struct policy_handle *handle,
2278                                           bool use_info2,
2279                                           NTTIME *pwdlastset)
2280 {
2281         NTSTATUS status;
2282         uint16_t levels[] = { /* 3, */ 5, 21 };
2283         int i;
2284         NTTIME pwdlastset3 = 0;
2285         NTTIME pwdlastset5 = 0;
2286         NTTIME pwdlastset21 = 0;
2287
2288         torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2289                         use_info2 ? "2":"");
2290
2291         for (i=0; i<ARRAY_SIZE(levels); i++) {
2292
2293                 struct samr_QueryUserInfo r;
2294                 struct samr_QueryUserInfo2 r2;
2295                 union samr_UserInfo *info;
2296
2297                 if (use_info2) {
2298                         r2.in.user_handle = handle;
2299                         r2.in.level = levels[i];
2300                         r2.out.info = &info;
2301                         status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2302
2303                 } else {
2304                         r.in.user_handle = handle;
2305                         r.in.level = levels[i];
2306                         r.out.info = &info;
2307                         status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2308                 }
2309
2310                 if (!NT_STATUS_IS_OK(status) &&
2311                     !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2312                         printf("QueryUserInfo%s level %u failed - %s\n",
2313                                use_info2 ? "2":"", levels[i], nt_errstr(status));
2314                         return false;
2315                 }
2316
2317                 switch (levels[i]) {
2318                 case 3:
2319                         pwdlastset3 = info->info3.last_password_change;
2320                         break;
2321                 case 5:
2322                         pwdlastset5 = info->info5.last_password_change;
2323                         break;
2324                 case 21:
2325                         pwdlastset21 = info->info21.last_password_change;
2326                         break;
2327                 default:
2328                         return false;
2329                 }
2330         }
2331         /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2332                                     "pwdlastset mixup"); */
2333         torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2334                                  "pwdlastset mixup");
2335
2336         *pwdlastset = pwdlastset21;
2337
2338         torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2339
2340         return true;
2341 }
2342
2343 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2344                                    struct torture_context *tctx,
2345                                    struct policy_handle *handle,
2346                                    uint16_t level,
2347                                    uint32_t fields_present,
2348                                    uint8_t password_expired,
2349                                    NTSTATUS expected_error,
2350                                    bool use_setinfo2,
2351                                    char **password,
2352                                    bool use_queryinfo2,
2353                                    NTTIME *pwdlastset)
2354 {
2355         const char *fields = NULL;
2356         bool ret = true;
2357
2358         switch (level) {
2359         case 21:
2360         case 23:
2361         case 25:
2362                 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2363                                          fields_present);
2364                 break;
2365         default:
2366                 break;
2367         }
2368
2369         torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2370                 "(password_expired: %d) %s\n",
2371                 use_setinfo2 ? "2":"", level, password_expired,
2372                 fields ? fields : "");
2373
2374         switch (level) {
2375                 case 21:
2376                 case 23:
2377                 case 24:
2378                 case 25:
2379                 case 26:
2380                         if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2381                                                        fields_present,
2382                                                        password,
2383                                                        password_expired,
2384                                                        use_setinfo2,
2385                                                        expected_error)) {
2386                                 ret = false;
2387                         }
2388                         break;
2389                 default:
2390                         return false;
2391         }
2392
2393         if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2394                                            use_queryinfo2,
2395                                            pwdlastset)) {
2396                 ret = false;
2397         }
2398
2399         return ret;
2400 }
2401
2402 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2403                                         struct torture_context *tctx,
2404                                         uint32_t acct_flags,
2405                                         struct policy_handle *handle,
2406                                         char **password)
2407 {
2408         int i, s, q;
2409         bool ret = true;
2410         int delay = 500000;
2411         bool set_levels[] = { false, true };
2412         bool query_levels[] = { false, true };
2413
2414         struct {
2415                 uint16_t level;
2416                 uint8_t password_expired_nonzero;
2417                 uint32_t fields_present;
2418                 bool query_info2;
2419                 bool set_info2;
2420                 NTSTATUS set_error;
2421         } pwd_tests[] = {
2422
2423                 /* level 21 */
2424                 {
2425                         .level                          = 21,
2426                         .password_expired_nonzero       = 1,
2427                         .fields_present                 = SAMR_FIELD_EXPIRED_FLAG
2428                 },{
2429                         .level                          = 21,
2430                         .password_expired_nonzero       = 1,
2431                         .fields_present                 = SAMR_FIELD_LAST_PWD_CHANGE,
2432                         .set_error                      = NT_STATUS_ACCESS_DENIED
2433 #if 0
2434         /* FIXME */
2435                 },{
2436                         .level                          = 21,
2437                         .password_expired_nonzero       = 1,
2438                         .fields_present                 = SAMR_FIELD_PASSWORD |
2439                                                           SAMR_FIELD_PASSWORD2 |
2440                                                           SAMR_FIELD_LAST_PWD_CHANGE,
2441                         .query_info2                    = false,
2442                         .set_error                      = NT_STATUS_ACCESS_DENIED
2443 #endif
2444
2445                 /* level 23 */
2446                 },{
2447                         .level                          = 23,
2448                         .password_expired_nonzero       = 1,
2449                         .fields_present                 = SAMR_FIELD_EXPIRED_FLAG
2450                 },{
2451                         .level                          = 23,
2452                         .password_expired_nonzero       = 1,
2453                         .fields_present                 = SAMR_FIELD_LAST_PWD_CHANGE,
2454                         .set_error                      = NT_STATUS_ACCESS_DENIED
2455                 },{
2456                         .level                          = 23,
2457                         .password_expired_nonzero       = 1,
2458                         .fields_present                 = SAMR_FIELD_LAST_PWD_CHANGE |
2459                                                           SAMR_FIELD_PASSWORD |
2460                                                           SAMR_FIELD_PASSWORD2,
2461                         .set_error                      = NT_STATUS_ACCESS_DENIED
2462                 },{
2463                         .level                          = 23,
2464                         .password_expired_nonzero       = 1,
2465                         .fields_present                 = SAMR_FIELD_LAST_PWD_CHANGE |
2466                                                           SAMR_FIELD_PASSWORD |
2467                                                           SAMR_FIELD_PASSWORD2 |
2468                                                           SAMR_FIELD_EXPIRED_FLAG,
2469                         .set_error                      = NT_STATUS_ACCESS_DENIED
2470                 },{
2471                         .level                          = 23,
2472                         .password_expired_nonzero       = 1,
2473                         .fields_present                 = SAMR_FIELD_PASSWORD |
2474                                                           SAMR_FIELD_PASSWORD2 |
2475                                                           SAMR_FIELD_EXPIRED_FLAG
2476                 },{
2477                         .level                          = 23,
2478                         .password_expired_nonzero       = 1,
2479                         .fields_present                 = SAMR_FIELD_PASSWORD |
2480                                                           SAMR_FIELD_PASSWORD2
2481                 },{
2482
2483                 /* level 24 */
2484
2485                         .level                          = 24,
2486                         .password_expired_nonzero       = 1
2487                 },{
2488                         .level                          = 24,
2489                         .password_expired_nonzero       = 24
2490                 },{
2491
2492                 /* level 25 */
2493
2494                         .level                          = 25,
2495                         .password_expired_nonzero       = 1,
2496                         .fields_present                 = SAMR_FIELD_LAST_PWD_CHANGE,
2497                         .set_error                      = NT_STATUS_ACCESS_DENIED
2498                 },{
2499                         .level                          = 25,
2500                         .password_expired_nonzero       = 1,
2501                         .fields_present                 = SAMR_FIELD_EXPIRED_FLAG,
2502                 },{
2503                         .level                          = 25,
2504                         .password_expired_nonzero       = 1,
2505                         .fields_present                 = SAMR_FIELD_PASSWORD |
2506                                                           SAMR_FIELD_PASSWORD2 |
2507                                                           SAMR_FIELD_EXPIRED_FLAG
2508                 },{
2509                         .level                          = 25,
2510                         .password_expired_nonzero       = 1,
2511                         .fields_present                 = SAMR_FIELD_PASSWORD |
2512                                                           SAMR_FIELD_PASSWORD2
2513                 },{
2514
2515                 /* level 26 */
2516
2517                         .level                          = 26,
2518                         .password_expired_nonzero       = 1
2519                 },{
2520                         .level                          = 26,
2521                         .password_expired_nonzero       = 24
2522                 }
2523         };
2524
2525         if (torture_setting_bool(tctx, "samba3", false)) {
2526                 delay = 1000000;
2527                 printf("Samba3 has second granularity, setting delay to: %d\n",
2528                         delay);
2529                 return ret;
2530         }
2531
2532         for (i=0; i<ARRAY_SIZE(pwd_tests); i++) {
2533         for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2534         for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2535
2536                 NTTIME pwdlastset_old = 0;
2537                 NTTIME pwdlastset_new = 0;
2538
2539                 /* set #1 */
2540
2541                 torture_comment(tctx, "------------------------------\n"
2542                                 "Testing pwdLastSet attribute for flags: 0x%08x "
2543                                 "(s: %d (l: %d), q: %d)\n",
2544                                 acct_flags, s, pwd_tests[i].level, q);
2545
2546                 if (!test_SetPassword_level(p, tctx, handle,
2547                                             pwd_tests[i].level,
2548                                             pwd_tests[i].fields_present,
2549                                             pwd_tests[i].password_expired_nonzero, /* will set pwdlast to 0 */
2550                                             pwd_tests[i].set_error,
2551                                             set_levels[s],
2552                                             password,
2553                                             query_levels[q],
2554                                             &pwdlastset_old)) {
2555                         ret = false;
2556                 }
2557
2558                 if (!NT_STATUS_IS_OK(pwd_tests[i].set_error)) {
2559                         /* skipping on expected failure */
2560                         continue;
2561                 }
2562
2563                 /* pwdlastset must be 0 afterwards, except for a level 23 and 25
2564                  * set without the SAMR_FIELD_EXPIRED_FLAG */
2565
2566                 switch (pwd_tests[i].level) {
2567                 case 23:
2568                 case 25:
2569                         if ((pwdlastset_new != 0) &&
2570                             !(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG)) {
2571                                 torture_comment(tctx, "not considering a non-0 "
2572                                         "pwdLastSet as a an error as the "
2573                                         "SAMR_FIELD_EXPIRED_FLAG has not "
2574                                         "been set\n");
2575                                 break;
2576                         }
2577                 default:
2578                         if (pwdlastset_new != 0) {
2579                                 torture_warning(tctx, "pwdLastSet test failed: "
2580                                         "expected pwdLastSet 0 but got %lld\n",
2581                                         pwdlastset_old);
2582                                 ret = false;
2583                         }
2584                         break;
2585                 }
2586
2587                 usleep(delay);
2588
2589                 /* set #2 */
2590
2591                 if (!test_SetPassword_level(p, tctx, handle, pwd_tests[i].level,
2592                                             pwd_tests[i].fields_present,
2593                                             0,
2594                                             /* will normally update (increase) the pwdlast */
2595                                             pwd_tests[i].set_error,
2596                                             set_levels[s],
2597                                             password,
2598                                             query_levels[q],
2599                                             &pwdlastset_new)) {
2600
2601                         ret = false;
2602                 }
2603
2604                 /* pwdlastset must not be 0 afterwards and must be larger then
2605                  * the old value */
2606
2607                 if (pwdlastset_old >= pwdlastset_new) {
2608                         torture_warning(tctx, "pwdLastSet test failed: "
2609                                 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
2610                                 pwdlastset_old, pwdlastset_new);
2611                         ret = false;
2612                 }
2613                 if (pwdlastset_new == 0) {
2614                         torture_warning(tctx, "pwdLastSet test failed: "
2615                                 "expected non-0 pwdlastset, got: %lld\n",
2616                                 pwdlastset_new);
2617                         ret = false;
2618                 }
2619                 pwdlastset_old = pwdlastset_new;
2620
2621                 usleep(delay);
2622
2623                 /* set #3 */
2624
2625                 if (!test_SetPassword_level(p, tctx, handle, pwd_tests[i].level,
2626                                             pwd_tests[i].fields_present,
2627                                             pwd_tests[i].password_expired_nonzero,
2628                                             pwd_tests[i].set_error,
2629                                             set_levels[s],
2630                                             password,
2631                                             query_levels[q],
2632                                             &pwdlastset_new)) {
2633                         ret = false;
2634                 }
2635
2636                 if (pwdlastset_old == pwdlastset_new) {
2637                         torture_warning(tctx, "pwdLastSet test failed: "
2638                                 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
2639                                 pwdlastset_old, pwdlastset_new);
2640                         ret = false;
2641                 }
2642
2643                 /* pwdlastset must be 0 afterwards, except for a level 23 and 25
2644                  * set without the SAMR_FIELD_EXPIRED_FLAG */
2645
2646                 switch (pwd_tests[i].level) {
2647                 case 23:
2648                 case 25:
2649                         if ((pwdlastset_new != 0) &&
2650                             !(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG)) {
2651                                 break;
2652                         }
2653                 default:
2654                         if (pwdlastset_new != 0) {
2655                                 torture_warning(tctx, "pwdLastSet test failed: "
2656                                         "expected pwdLastSet 0, got %lld\n",
2657                                         pwdlastset_old);
2658                                 ret = false;
2659                         }
2660                         break;
2661                 }
2662         }
2663         }
2664         }
2665
2666         return ret;
2667 }
2668
2669 static bool test_user_ops(struct dcerpc_pipe *p, 
2670                           struct torture_context *tctx,
2671                           struct policy_handle *user_handle, 
2672                           struct policy_handle *domain_handle, 
2673                           uint32_t base_acct_flags, 
2674                           const char *base_acct_name, enum torture_samr_choice which_ops)
2675 {
2676         char *password = NULL;
2677         struct samr_QueryUserInfo q;
2678         union samr_UserInfo *info;
2679         NTSTATUS status;
2680
2681         bool ret = true;
2682         int i;
2683         uint32_t rid;
2684         const uint32_t password_fields[] = {
2685                 SAMR_FIELD_PASSWORD,
2686                 SAMR_FIELD_PASSWORD2,
2687                 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2688                 0
2689         };
2690         
2691         status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2692         if (!NT_STATUS_IS_OK(status)) {
2693                 ret = false;
2694         }
2695
2696         switch (which_ops) {
2697         case TORTURE_SAMR_USER_ATTRIBUTES:
2698                 if (!test_QuerySecurity(p, tctx, user_handle)) {
2699                         ret = false;
2700                 }
2701
2702                 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2703                         ret = false;
2704                 }
2705
2706                 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2707                         ret = false;
2708                 }
2709
2710                 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2711                                       base_acct_name)) {
2712                         ret = false;
2713                 }       
2714
2715                 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2716                         ret = false;
2717                 }
2718
2719                 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2720                         ret = false;
2721                 }
2722
2723                 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2724                         ret = false;
2725                 }
2726                 break;
2727         case TORTURE_SAMR_PASSWORDS:
2728                 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2729                         char simple_pass[9];
2730                         char *v = generate_random_str(tctx, 1);
2731                         
2732                         ZERO_STRUCT(simple_pass);
2733                         memset(simple_pass, *v, sizeof(simple_pass) - 1);
2734
2735                         printf("Testing machine account password policy rules\n");
2736
2737                         /* Workstation trust accounts don't seem to need to honour password quality policy */
2738                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2739                                 ret = false;
2740                         }
2741
2742                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2743                                 ret = false;
2744                         }
2745
2746                         /* reset again, to allow another 'user' password change */
2747                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2748                                 ret = false;
2749                         }
2750
2751                         /* Try a 'short' password */
2752                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2753                                 ret = false;
2754                         }
2755
2756                         /* Try a compleatly random password */
2757                         if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
2758                                 ret = false;
2759                         }
2760                 }
2761
2762                 /* test last password change timestamp behaviour */
2763                 if (!test_SetPassword_pwdlastset(p, tctx, user_handle, &password)) {
2764                         ret = false;
2765                 }
2766
2767                 for (i = 0; password_fields[i]; i++) {
2768                         if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2769                                 ret = false;
2770                         }       
2771                 
2772                         /* check it was set right */
2773                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2774                                 ret = false;
2775                         }
2776                 }               
2777
2778                 for (i = 0; password_fields[i]; i++) {
2779                         if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2780                                 ret = false;
2781                         }       
2782                 
2783                         /* check it was set right */
2784                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2785                                 ret = false;
2786                         }
2787                 }               
2788
2789                 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2790                         ret = false;
2791                 }       
2792
2793                 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2794                         ret = false;
2795                 }       
2796
2797                 q.in.user_handle = user_handle;
2798                 q.in.level = 5;
2799                 q.out.info = &info;
2800                 
2801                 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2802                 if (!NT_STATUS_IS_OK(status)) {
2803                         printf("QueryUserInfo level %u failed - %s\n", 
2804                                q.in.level, nt_errstr(status));
2805                         ret = false;
2806                 } else {
2807                         uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2808                         if ((info->info5.acct_flags) != expected_flags) {
2809                                 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2810                                        info->info5.acct_flags,
2811                                        expected_flags);
2812                                 ret = false;
2813                         }
2814                         if (info->info5.rid != rid) {
2815                                 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2816                                        info->info5.rid, rid);
2817
2818                         }
2819                 }
2820
2821                 break;
2822         case TORTURE_SAMR_OTHER:
2823                 /* We just need the account to exist */
2824                 break;
2825         }
2826         return ret;
2827 }
2828
2829 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2830                            struct policy_handle *alias_handle,
2831                            const struct dom_sid *domain_sid)
2832 {
2833         bool ret = true;
2834
2835         if (!test_QuerySecurity(p, tctx, alias_handle)) {
2836                 ret = false;
2837         }
2838
2839         if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2840                 ret = false;
2841         }
2842
2843         if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2844                 ret = false;
2845         }
2846
2847         if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2848                 ret = false;
2849         }
2850
2851         if (torture_setting_bool(tctx, "samba4", false)) {
2852                 printf("skipping MultipleMembers Alias tests against Samba4\n");
2853                 return ret;
2854         }
2855
2856         if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2857                 ret = false;
2858         }
2859
2860         return ret;
2861 }
2862
2863
2864 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2865                                      struct policy_handle *user_handle)
2866 {
2867         struct samr_DeleteUser d;
2868         NTSTATUS status;
2869         torture_comment(tctx, "Testing DeleteUser\n");
2870
2871         d.in.user_handle = user_handle;
2872         d.out.user_handle = user_handle;
2873
2874         status = dcerpc_samr_DeleteUser(p, tctx, &d);
2875         torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
2876
2877         return true;
2878 }
2879
2880 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2881                             struct policy_handle *handle, const char *name)
2882 {
2883         NTSTATUS status;
2884         struct samr_DeleteUser d;
2885         struct policy_handle user_handle;
2886         uint32_t rid;
2887
2888         status = test_LookupName(p, mem_ctx, handle, name, &rid);
2889         if (!NT_STATUS_IS_OK(status)) {
2890                 goto failed;
2891         }
2892
2893         status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2894         if (!NT_STATUS_IS_OK(status)) {
2895                 goto failed;
2896         }
2897
2898         d.in.user_handle = &user_handle;
2899         d.out.user_handle = &user_handle;
2900         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2901         if (!NT_STATUS_IS_OK(status)) {
2902                 goto failed;
2903         }
2904
2905         return true;
2906
2907 failed:
2908         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2909         return false;
2910 }
2911
2912
2913 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2914                                     struct policy_handle *handle, const char *name)
2915 {
2916         NTSTATUS status;
2917         struct samr_OpenGroup r;
2918         struct samr_DeleteDomainGroup d;
2919         struct policy_handle group_handle;
2920         uint32_t rid;
2921
2922         status = test_LookupName(p, mem_ctx, handle, name, &rid);
2923         if (!NT_STATUS_IS_OK(status)) {
2924                 goto failed;
2925         }
2926
2927         r.in.domain_handle = handle;
2928         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2929         r.in.rid = rid;
2930         r.out.group_handle = &group_handle;
2931         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2932         if (!NT_STATUS_IS_OK(status)) {
2933                 goto failed;
2934         }
2935
2936         d.in.group_handle = &group_handle;
2937         d.out.group_handle = &group_handle;
2938         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2939         if (!NT_STATUS_IS_OK(status)) {
2940                 goto failed;
2941         }
2942
2943         return true;
2944
2945 failed:
2946         printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2947         return false;
2948 }
2949
2950
2951 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2952                                    struct policy_handle *domain_handle, const char *name)
2953 {
2954         NTSTATUS status;
2955         struct samr_OpenAlias r;
2956         struct samr_DeleteDomAlias d;
2957         struct policy_handle alias_handle;
2958         uint32_t rid;
2959
2960         printf("testing DeleteAlias_byname\n");
2961
2962         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2963         if (!NT_STATUS_IS_OK(status)) {
2964                 goto failed;
2965         }
2966
2967         r.in.domain_handle = domain_handle;
2968         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2969         r.in.rid = rid;
2970         r.out.alias_handle = &alias_handle;
2971         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2972         if (!NT_STATUS_IS_OK(status)) {
2973                 goto failed;
2974         }
2975
2976         d.in.alias_handle = &alias_handle;
2977         d.out.alias_handle = &alias_handle;
2978         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2979         if (!NT_STATUS_IS_OK(status)) {
2980                 goto failed;
2981         }
2982
2983         return true;
2984
2985 failed:
2986         printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2987         return false;
2988 }
2989
2990 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2991                                      struct policy_handle *alias_handle)
2992 {
2993         struct samr_DeleteDomAlias d;
2994         NTSTATUS status;
2995         bool ret = true;
2996         printf("Testing DeleteAlias\n");
2997
2998         d.in.alias_handle = alias_handle;
2999         d.out.alias_handle = alias_handle;
3000
3001         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3002         if (!NT_STATUS_IS_OK(status)) {
3003                 printf("DeleteAlias failed - %s\n", nt_errstr(status));
3004                 ret = false;
3005         }
3006
3007         return ret;
3008 }
3009
3010 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3011                             struct policy_handle *domain_handle, 
3012                              struct policy_handle *alias_handle, 
3013                              const struct dom_sid *domain_sid)
3014 {
3015         NTSTATUS status;
3016         struct samr_CreateDomAlias r;
3017         struct lsa_String name;
3018         uint32_t rid;
3019         bool ret = true;
3020
3021         init_lsa_String(&name, TEST_ALIASNAME);
3022         r.in.domain_handle = domain_handle;
3023         r.in.alias_name = &name;
3024         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3025         r.out.alias_handle = alias_handle;
3026         r.out.rid = &rid;
3027
3028         printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
3029
3030         status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3031
3032         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3033                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3034                         printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
3035                         return true;
3036                 } else {
3037                         printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string, 
3038                                nt_errstr(status));
3039                         return false;
3040                 }
3041         }
3042
3043         if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
3044                 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
3045                         return false;
3046                 }
3047                 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3048         }
3049
3050         if (!NT_STATUS_IS_OK(status)) {
3051                 printf("CreateAlias failed - %s\n", nt_errstr(status));
3052                 return false;
3053         }
3054
3055         if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
3056                 ret = false;
3057         }
3058
3059         return ret;
3060 }
3061
3062 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3063                                 const char *acct_name,
3064                                 struct policy_handle *domain_handle, char **password)
3065 {
3066         bool ret = true;
3067
3068         if (!*password) {
3069                 return false;
3070         }
3071
3072         if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
3073                 ret = false;
3074         }
3075
3076         if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
3077                 ret = false;
3078         }
3079
3080         if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
3081                 ret = false;
3082         }
3083
3084         /* test what happens when setting the old password again */
3085         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
3086                 ret = false;
3087         }
3088
3089         {
3090                 char simple_pass[9];
3091                 char *v = generate_random_str(mem_ctx, 1);
3092
3093                 ZERO_STRUCT(simple_pass);
3094                 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3095
3096                 /* test what happens when picking a simple password */
3097                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
3098                         ret = false;
3099                 }
3100         }
3101
3102         /* set samr_SetDomainInfo level 1 with min_length 5 */
3103         {
3104                 struct samr_QueryDomainInfo r;
3105                 union samr_DomainInfo *info = NULL;
3106                 struct samr_SetDomainInfo s;
3107                 uint16_t len_old, len;
3108                 uint32_t pwd_prop_old;
3109                 int64_t min_pwd_age_old;
3110                 NTSTATUS status;
3111
3112                 len = 5;
3113
3114                 r.in.domain_handle = domain_handle;
3115                 r.in.level = 1;
3116                 r.out.info = &info;
3117
3118                 printf("testing samr_QueryDomainInfo level 1\n");
3119                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3120                 if (!NT_STATUS_IS_OK(status)) {
3121                         return false;
3122                 }
3123
3124                 s.in.domain_handle = domain_handle;
3125                 s.in.level = 1;
3126                 s.in.info = info;
3127
3128                 /* remember the old min length, so we can reset it */
3129                 len_old = s.in.info->info1.min_password_length;
3130                 s.in.info->info1.min_password_length = len;
3131                 pwd_prop_old = s.in.info->info1.password_properties;
3132                 /* turn off password complexity checks for this test */
3133                 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
3134
3135                 min_pwd_age_old = s.in.info->info1.min_password_age;
3136                 s.in.info->info1.min_password_age = 0;
3137
3138                 printf("testing samr_SetDomainInfo level 1\n");
3139                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3140                 if (!NT_STATUS_IS_OK(status)) {
3141                         return false;
3142                 }
3143
3144           &nb