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