2e59a06f98e74a1eeea6a95375f2a5e2fb1f7581
[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_18(struct dcerpc_pipe *p, struct torture_context *tctx,
853                                 struct policy_handle *handle, char **password)
854 {
855         NTSTATUS status;
856         struct samr_SetUserInfo s;
857         union samr_UserInfo u;
858         bool ret = true;
859         DATA_BLOB session_key;
860         char *newpass;
861         struct samr_GetUserPwInfo pwp;
862         struct samr_PwInfo info;
863         int policy_min_pw_len = 0;
864         uint8_t lm_hash[16], nt_hash[16];
865
866         pwp.in.user_handle = handle;
867         pwp.out.info = &info;
868
869         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
870         if (NT_STATUS_IS_OK(status)) {
871                 policy_min_pw_len = pwp.out.info->min_password_length;
872         }
873         newpass = samr_rand_pass(tctx, policy_min_pw_len);
874
875         s.in.user_handle = handle;
876         s.in.info = &u;
877         s.in.level = 18;
878
879         ZERO_STRUCT(u);
880
881         u.info18.nt_pwd_active = true;
882         u.info18.lm_pwd_active = true;
883
884         E_md4hash(newpass, nt_hash);
885         E_deshash(newpass, lm_hash);
886
887         status = dcerpc_fetch_session_key(p, &session_key);
888         if (!NT_STATUS_IS_OK(status)) {
889                 printf("SetUserInfo level %u - no session key - %s\n",
890                        s.in.level, nt_errstr(status));
891                 return false;
892         }
893
894         {
895                 DATA_BLOB in,out;
896                 in = data_blob_const(nt_hash, 16);
897                 out = data_blob_talloc_zero(tctx, 16);
898                 sess_crypt_blob(&out, &in, &session_key, true);
899                 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
900         }
901         {
902                 DATA_BLOB in,out;
903                 in = data_blob_const(lm_hash, 16);
904                 out = data_blob_talloc_zero(tctx, 16);
905                 sess_crypt_blob(&out, &in, &session_key, true);
906                 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
907         }
908
909         torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
910
911         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
912         if (!NT_STATUS_IS_OK(status)) {
913                 printf("SetUserInfo level %u failed - %s\n",
914                        s.in.level, nt_errstr(status));
915                 ret = false;
916         } else {
917                 *password = newpass;
918         }
919
920         return ret;
921 }
922
923 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
924                                 struct policy_handle *handle, uint32_t fields_present,
925                                 char **password)
926 {
927         NTSTATUS status;
928         struct samr_SetUserInfo s;
929         union samr_UserInfo u;
930         bool ret = true;
931         DATA_BLOB session_key;
932         char *newpass;
933         struct samr_GetUserPwInfo pwp;
934         struct samr_PwInfo info;
935         int policy_min_pw_len = 0;
936         uint8_t lm_hash[16], nt_hash[16];
937
938         pwp.in.user_handle = handle;
939         pwp.out.info = &info;
940
941         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
942         if (NT_STATUS_IS_OK(status)) {
943                 policy_min_pw_len = pwp.out.info->min_password_length;
944         }
945         newpass = samr_rand_pass(tctx, policy_min_pw_len);
946
947         s.in.user_handle = handle;
948         s.in.info = &u;
949         s.in.level = 21;
950
951         E_md4hash(newpass, nt_hash);
952         E_deshash(newpass, lm_hash);
953
954         ZERO_STRUCT(u);
955
956         u.info21.fields_present = fields_present;
957
958         if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
959                 u.info21.lm_owf_password.length = 16;
960                 u.info21.lm_owf_password.size = 16;
961                 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
962                 u.info21.lm_password_set = true;
963         }
964
965         if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
966                 u.info21.nt_owf_password.length = 16;
967                 u.info21.nt_owf_password.size = 16;
968                 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
969                 u.info21.nt_password_set = true;
970         }
971
972         status = dcerpc_fetch_session_key(p, &session_key);
973         if (!NT_STATUS_IS_OK(status)) {
974                 printf("SetUserInfo level %u - no session key - %s\n",
975                        s.in.level, nt_errstr(status));
976                 return false;
977         }
978
979         if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
980                 DATA_BLOB in,out;
981                 in = data_blob_const(u.info21.lm_owf_password.array,
982                                      u.info21.lm_owf_password.length);
983                 out = data_blob_talloc_zero(tctx, 16);
984                 sess_crypt_blob(&out, &in, &session_key, true);
985                 u.info21.lm_owf_password.array = (uint16_t *)out.data;
986         }
987
988         if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
989                 DATA_BLOB in,out;
990                 in = data_blob_const(u.info21.nt_owf_password.array,
991                                      u.info21.nt_owf_password.length);
992                 out = data_blob_talloc_zero(tctx, 16);
993                 sess_crypt_blob(&out, &in, &session_key, true);
994                 u.info21.nt_owf_password.array = (uint16_t *)out.data;
995         }
996
997         torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
998
999         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1000         if (!NT_STATUS_IS_OK(status)) {
1001                 printf("SetUserInfo level %u failed - %s\n",
1002                        s.in.level, nt_errstr(status));
1003                 ret = false;
1004         } else {
1005                 *password = newpass;
1006         }
1007
1008         /* try invalid length */
1009         if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1010
1011                 u.info21.nt_owf_password.length++;
1012
1013                 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1014
1015                 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1016                         printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1017                                s.in.level, nt_errstr(status));
1018                         ret = false;
1019                 }
1020         }
1021
1022         if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1023
1024                 u.info21.lm_owf_password.length++;
1025
1026                 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1027
1028                 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1029                         printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1030                                s.in.level, nt_errstr(status));
1031                         ret = false;
1032                 }
1033         }
1034
1035         return ret;
1036 }
1037
1038 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1039                                       struct torture_context *tctx,
1040                                       struct policy_handle *handle,
1041                                       uint16_t level,
1042                                       uint32_t fields_present,
1043                                       char **password, uint8_t password_expired,
1044                                       bool use_setinfo2, NTSTATUS expected_error)
1045 {
1046         NTSTATUS status;
1047         struct samr_SetUserInfo s;
1048         struct samr_SetUserInfo2 s2;
1049         union samr_UserInfo u;
1050         bool ret = true;
1051         DATA_BLOB session_key;
1052         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1053         struct MD5Context ctx;
1054         uint8_t confounder[16];
1055         char *newpass;
1056         struct samr_GetUserPwInfo pwp;
1057         struct samr_PwInfo info;
1058         int policy_min_pw_len = 0;
1059         const char *comment = NULL;
1060
1061         pwp.in.user_handle = handle;
1062         pwp.out.info = &info;
1063
1064         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1065         if (NT_STATUS_IS_OK(status)) {
1066                 policy_min_pw_len = pwp.out.info->min_password_length;
1067         }
1068         newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1069
1070         if (use_setinfo2) {
1071                 s2.in.user_handle = handle;
1072                 s2.in.info = &u;
1073                 s2.in.level = level;
1074         } else {
1075                 s.in.user_handle = handle;
1076                 s.in.info = &u;
1077                 s.in.level = level;
1078         }
1079
1080         if (fields_present & SAMR_FIELD_COMMENT) {
1081                 comment = talloc_asprintf(tctx, "comment: %d\n", time(NULL));
1082         }
1083
1084         ZERO_STRUCT(u);
1085
1086         switch (level) {
1087         case 21:
1088                 u.info21.fields_present = fields_present;
1089                 u.info21.password_expired = password_expired;
1090                 u.info21.comment.string = comment;
1091
1092                 break;
1093         case 23:
1094                 u.info23.info.fields_present = fields_present;
1095                 u.info23.info.password_expired = password_expired;
1096                 u.info23.info.comment.string = comment;
1097
1098                 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1099
1100                 break;
1101         case 24:
1102                 u.info24.password_expired = password_expired;
1103
1104                 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1105
1106                 break;
1107         case 25:
1108                 u.info25.info.fields_present = fields_present;
1109                 u.info25.info.password_expired = password_expired;
1110                 u.info25.info.comment.string = comment;
1111
1112                 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1113
1114                 break;
1115         case 26:
1116                 u.info26.password_expired = password_expired;
1117
1118                 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1119
1120                 break;
1121         }
1122
1123         status = dcerpc_fetch_session_key(p, &session_key);
1124         if (!NT_STATUS_IS_OK(status)) {
1125                 printf("SetUserInfo level %u - no session key - %s\n",
1126                        s.in.level, nt_errstr(status));
1127                 return false;
1128         }
1129
1130         generate_random_buffer((uint8_t *)confounder, 16);
1131
1132         MD5Init(&ctx);
1133         MD5Update(&ctx, confounder, 16);
1134         MD5Update(&ctx, session_key.data, session_key.length);
1135         MD5Final(confounded_session_key.data, &ctx);
1136
1137         switch (level) {
1138         case 23:
1139                 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1140                 break;
1141         case 24:
1142                 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1143                 break;
1144         case 25:
1145                 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1146                 memcpy(&u.info25.password.data[516], confounder, 16);
1147                 break;
1148         case 26:
1149                 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1150                 memcpy(&u.info26.password.data[516], confounder, 16);
1151                 break;
1152         }
1153
1154         if (use_setinfo2) {
1155                 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1156         } else {
1157                 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1158         }
1159
1160         if (!NT_STATUS_IS_OK(expected_error)) {
1161                 if (use_setinfo2) {
1162                         torture_assert_ntstatus_equal(tctx,
1163                                 s2.out.result,
1164                                 expected_error, "SetUserInfo2 failed");
1165                 } else {
1166                         torture_assert_ntstatus_equal(tctx,
1167                                 s.out.result,
1168                                 expected_error, "SetUserInfo failed");
1169                 }
1170                 return true;
1171         }
1172
1173         if (!NT_STATUS_IS_OK(status)) {
1174                 printf("SetUserInfo%s level %u failed - %s\n",
1175                        use_setinfo2 ? "2":"", level, nt_errstr(status));
1176                 ret = false;
1177         } else {
1178                 if (level != 21) {
1179                         *password = newpass;
1180                 }
1181         }
1182
1183         return ret;
1184 }
1185
1186 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1187                                struct policy_handle *handle)
1188 {
1189         NTSTATUS status;
1190         struct samr_SetAliasInfo r;
1191         struct samr_QueryAliasInfo q;
1192         union samr_AliasInfo *info;
1193         uint16_t levels[] = {2, 3};
1194         int i;
1195         bool ret = true;
1196
1197         /* Ignoring switch level 1, as that includes the number of members for the alias
1198          * and setting this to a wrong value might have negative consequences
1199          */
1200
1201         for (i=0;i<ARRAY_SIZE(levels);i++) {
1202                 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1203
1204                 r.in.alias_handle = handle;
1205                 r.in.level = levels[i];
1206                 r.in.info  = talloc(tctx, union samr_AliasInfo);
1207                 switch (r.in.level) {
1208                     case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1209                     case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1210                                 "Test Description, should test I18N as well"); break;
1211                     case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1212                 }
1213
1214                 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1215                 if (!NT_STATUS_IS_OK(status)) {
1216                         printf("SetAliasInfo level %u failed - %s\n",
1217                                levels[i], nt_errstr(status));
1218                         ret = false;
1219                 }
1220
1221                 q.in.alias_handle = handle;
1222                 q.in.level = levels[i];
1223                 q.out.info = &info;
1224
1225                 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1226                 if (!NT_STATUS_IS_OK(status)) {
1227                         printf("QueryAliasInfo level %u failed - %s\n",
1228                                levels[i], nt_errstr(status));
1229                         ret = false;
1230                 }
1231         }
1232
1233         return ret;
1234 }
1235
1236 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1237                                   struct policy_handle *user_handle)
1238 {
1239         struct samr_GetGroupsForUser r;
1240         struct samr_RidWithAttributeArray *rids = NULL;
1241         NTSTATUS status;
1242
1243         torture_comment(tctx, "testing GetGroupsForUser\n");
1244
1245         r.in.user_handle = user_handle;
1246         r.out.rids = &rids;
1247
1248         status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1249         torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1250
1251         return true;
1252
1253 }
1254
1255 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1256                               struct lsa_String *domain_name)
1257 {
1258         NTSTATUS status;
1259         struct samr_GetDomPwInfo r;
1260         struct samr_PwInfo info;
1261
1262         r.in.domain_name = domain_name;
1263         r.out.info = &info;
1264
1265         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1266
1267         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1268         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1269
1270         r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1271         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1272
1273         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1274         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1275
1276         r.in.domain_name->string = "\\\\__NONAME__";
1277         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1278
1279         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1280         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1281
1282         r.in.domain_name->string = "\\\\Builtin";
1283         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1284
1285         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1286         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1287
1288         return true;
1289 }
1290
1291 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1292                                struct policy_handle *handle)
1293 {
1294         NTSTATUS status;
1295         struct samr_GetUserPwInfo r;
1296         struct samr_PwInfo info;
1297
1298         torture_comment(tctx, "Testing GetUserPwInfo\n");
1299
1300         r.in.user_handle = handle;
1301         r.out.info = &info;
1302
1303         status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1304         torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1305
1306         return true;
1307 }
1308
1309 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1310                                 struct policy_handle *domain_handle, const char *name,
1311                                 uint32_t *rid)
1312 {
1313         NTSTATUS status;
1314         struct samr_LookupNames n;
1315         struct lsa_String sname[2];
1316         struct samr_Ids rids, types;
1317
1318         init_lsa_String(&sname[0], name);
1319
1320         n.in.domain_handle = domain_handle;
1321         n.in.num_names = 1;
1322         n.in.names = sname;
1323         n.out.rids = &rids;
1324         n.out.types = &types;
1325         status = dcerpc_samr_LookupNames(p, tctx, &n);
1326         if (NT_STATUS_IS_OK(status)) {
1327                 *rid = n.out.rids->ids[0];
1328         } else {
1329                 return status;
1330         }
1331
1332         init_lsa_String(&sname[1], "xxNONAMExx");
1333         n.in.num_names = 2;
1334         status = dcerpc_samr_LookupNames(p, tctx, &n);
1335         if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1336                 printf("LookupNames[2] failed - %s\n", nt_errstr(status));              
1337                 if (NT_STATUS_IS_OK(status)) {
1338                         return NT_STATUS_UNSUCCESSFUL;
1339                 }
1340                 return status;
1341         }
1342
1343         n.in.num_names = 0;
1344         status = dcerpc_samr_LookupNames(p, tctx, &n);
1345         if (!NT_STATUS_IS_OK(status)) {
1346                 printf("LookupNames[0] failed - %s\n", nt_errstr(status));              
1347                 return status;
1348         }
1349
1350         init_lsa_String(&sname[0], "xxNONAMExx");
1351         n.in.num_names = 1;
1352         status = dcerpc_samr_LookupNames(p, tctx, &n);
1353         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1354                 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));             
1355                 if (NT_STATUS_IS_OK(status)) {
1356                         return NT_STATUS_UNSUCCESSFUL;
1357                 }
1358                 return status;
1359         }
1360
1361         init_lsa_String(&sname[0], "xxNONAMExx");
1362         init_lsa_String(&sname[1], "xxNONAME2xx");
1363         n.in.num_names = 2;
1364         status = dcerpc_samr_LookupNames(p, tctx, &n);
1365         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1366                 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));            
1367                 if (NT_STATUS_IS_OK(status)) {
1368                         return NT_STATUS_UNSUCCESSFUL;
1369                 }
1370                 return status;
1371         }
1372
1373         return NT_STATUS_OK;
1374 }
1375
1376 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1377                                      struct policy_handle *domain_handle,
1378                                      const char *name, struct policy_handle *user_handle)
1379 {
1380         NTSTATUS status;
1381         struct samr_OpenUser r;
1382         uint32_t rid;
1383
1384         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1385         if (!NT_STATUS_IS_OK(status)) {
1386                 return status;
1387         }
1388
1389         r.in.domain_handle = domain_handle;
1390         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1391         r.in.rid = rid;
1392         r.out.user_handle = user_handle;
1393         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1394         if (!NT_STATUS_IS_OK(status)) {
1395                 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1396         }
1397
1398         return status;
1399 }
1400
1401 #if 0
1402 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1403                                    struct policy_handle *handle)
1404 {
1405         NTSTATUS status;
1406         struct samr_ChangePasswordUser r;
1407         bool ret = true;
1408         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1409         struct policy_handle user_handle;
1410         char *oldpass = "test";
1411         char *newpass = "test2";
1412         uint8_t old_nt_hash[16], new_nt_hash[16];
1413         uint8_t old_lm_hash[16], new_lm_hash[16];
1414
1415         status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1416         if (!NT_STATUS_IS_OK(status)) {
1417                 return false;
1418         }
1419
1420         printf("Testing ChangePasswordUser for user 'testuser'\n");
1421
1422         printf("old password: %s\n", oldpass);
1423         printf("new password: %s\n", newpass);
1424
1425         E_md4hash(oldpass, old_nt_hash);
1426         E_md4hash(newpass, new_nt_hash);
1427         E_deshash(oldpass, old_lm_hash);
1428         E_deshash(newpass, new_lm_hash);
1429
1430         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1431         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1432         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1433         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1434         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1435         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1436
1437         r.in.handle = &user_handle;
1438         r.in.lm_present = 1;
1439         r.in.old_lm_crypted = &hash1;
1440         r.in.new_lm_crypted = &hash2;
1441         r.in.nt_present = 1;
1442         r.in.old_nt_crypted = &hash3;
1443         r.in.new_nt_crypted = &hash4;
1444         r.in.cross1_present = 1;
1445         r.in.nt_cross = &hash5;
1446         r.in.cross2_present = 1;
1447         r.in.lm_cross = &hash6;
1448
1449         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1450         if (!NT_STATUS_IS_OK(status)) {
1451                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1452                 ret = false;
1453         }
1454
1455         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1456                 ret = false;
1457         }
1458
1459         return ret;
1460 }
1461 #endif
1462
1463 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1464                                     const char *acct_name, 
1465                                     struct policy_handle *handle, char **password)
1466 {
1467         NTSTATUS status;
1468         struct samr_ChangePasswordUser r;
1469         bool ret = true;
1470         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1471         struct policy_handle user_handle;
1472         char *oldpass;
1473         uint8_t old_nt_hash[16], new_nt_hash[16];
1474         uint8_t old_lm_hash[16], new_lm_hash[16];
1475         bool changed = true;
1476
1477         char *newpass;
1478         struct samr_GetUserPwInfo pwp;
1479         struct samr_PwInfo info;
1480         int policy_min_pw_len = 0;
1481
1482         status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1483         if (!NT_STATUS_IS_OK(status)) {
1484                 return false;
1485         }
1486         pwp.in.user_handle = &user_handle;
1487         pwp.out.info = &info;
1488
1489         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1490         if (NT_STATUS_IS_OK(status)) {
1491                 policy_min_pw_len = pwp.out.info->min_password_length;
1492         }
1493         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1494
1495         torture_comment(tctx, "Testing ChangePasswordUser\n");
1496
1497         torture_assert(tctx, *password != NULL, 
1498                                    "Failing ChangePasswordUser as old password was NULL.  Previous test failed?");
1499
1500         oldpass = *password;
1501
1502         E_md4hash(oldpass, old_nt_hash);
1503         E_md4hash(newpass, new_nt_hash);
1504         E_deshash(oldpass, old_lm_hash);
1505         E_deshash(newpass, new_lm_hash);
1506
1507         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1508         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1509         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1510         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1511         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1512         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1513
1514         r.in.user_handle = &user_handle;
1515         r.in.lm_present = 1;
1516         /* Break the LM hash */
1517         hash1.hash[0]++;
1518         r.in.old_lm_crypted = &hash1;
1519         r.in.new_lm_crypted = &hash2;
1520         r.in.nt_present = 1;
1521         r.in.old_nt_crypted = &hash3;
1522         r.in.new_nt_crypted = &hash4;
1523         r.in.cross1_present = 1;
1524         r.in.nt_cross = &hash5;
1525         r.in.cross2_present = 1;
1526         r.in.lm_cross = &hash6;
1527
1528         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1529         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1530                 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1531
1532         /* Unbreak the LM hash */
1533         hash1.hash[0]--;
1534
1535         r.in.user_handle = &user_handle;
1536         r.in.lm_present = 1;
1537         r.in.old_lm_crypted = &hash1;
1538         r.in.new_lm_crypted = &hash2;
1539         /* Break the NT hash */
1540         hash3.hash[0]--;
1541         r.in.nt_present = 1;
1542         r.in.old_nt_crypted = &hash3;
1543         r.in.new_nt_crypted = &hash4;
1544         r.in.cross1_present = 1;
1545         r.in.nt_cross = &hash5;
1546         r.in.cross2_present = 1;
1547         r.in.lm_cross = &hash6;
1548
1549         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1550         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD, 
1551                 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1552
1553         /* Unbreak the NT hash */
1554         hash3.hash[0]--;
1555
1556         r.in.user_handle = &user_handle;
1557         r.in.lm_present = 1;
1558         r.in.old_lm_crypted = &hash1;
1559         r.in.new_lm_crypted = &hash2;
1560         r.in.nt_present = 1;
1561         r.in.old_nt_crypted = &hash3;
1562         r.in.new_nt_crypted = &hash4;
1563         r.in.cross1_present = 1;
1564         r.in.nt_cross = &hash5;
1565         r.in.cross2_present = 1;
1566         /* Break the LM cross */
1567         hash6.hash[0]++;
1568         r.in.lm_cross = &hash6;
1569
1570         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1571         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1572                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1573                 ret = false;
1574         }
1575
1576         /* Unbreak the LM cross */
1577         hash6.hash[0]--;
1578
1579         r.in.user_handle = &user_handle;
1580         r.in.lm_present = 1;
1581         r.in.old_lm_crypted = &hash1;
1582         r.in.new_lm_crypted = &hash2;
1583         r.in.nt_present = 1;
1584         r.in.old_nt_crypted = &hash3;
1585         r.in.new_nt_crypted = &hash4;
1586         r.in.cross1_present = 1;
1587         /* Break the NT cross */
1588         hash5.hash[0]++;
1589         r.in.nt_cross = &hash5;
1590         r.in.cross2_present = 1;
1591         r.in.lm_cross = &hash6;
1592
1593         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1594         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1595                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1596                 ret = false;
1597         }
1598
1599         /* Unbreak the NT cross */
1600         hash5.hash[0]--;
1601
1602
1603         /* Reset the hashes to not broken values */
1604         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1605         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1606         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1607         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1608         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1609         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1610
1611         r.in.user_handle = &user_handle;
1612         r.in.lm_present = 1;
1613         r.in.old_lm_crypted = &hash1;
1614         r.in.new_lm_crypted = &hash2;
1615         r.in.nt_present = 1;
1616         r.in.old_nt_crypted = &hash3;
1617         r.in.new_nt_crypted = &hash4;
1618         r.in.cross1_present = 1;
1619         r.in.nt_cross = &hash5;
1620         r.in.cross2_present = 0;
1621         r.in.lm_cross = NULL;
1622
1623         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1624         if (NT_STATUS_IS_OK(status)) {
1625                 changed = true;
1626                 *password = newpass;
1627         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1628                 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1629                 ret = false;
1630         }
1631
1632         oldpass = newpass;
1633         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1634
1635         E_md4hash(oldpass, old_nt_hash);
1636         E_md4hash(newpass, new_nt_hash);
1637         E_deshash(oldpass, old_lm_hash);
1638         E_deshash(newpass, new_lm_hash);
1639
1640
1641         /* Reset the hashes to not broken values */
1642         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1643         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1644         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1645         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1646         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1647         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1648
1649         r.in.user_handle = &user_handle;
1650         r.in.lm_present = 1;
1651         r.in.old_lm_crypted = &hash1;
1652         r.in.new_lm_crypted = &hash2;
1653         r.in.nt_present = 1;
1654         r.in.old_nt_crypted = &hash3;
1655         r.in.new_nt_crypted = &hash4;
1656         r.in.cross1_present = 0;
1657         r.in.nt_cross = NULL;
1658         r.in.cross2_present = 1;
1659         r.in.lm_cross = &hash6;
1660
1661         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1662         if (NT_STATUS_IS_OK(status)) {
1663                 changed = true;
1664                 *password = newpass;
1665         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1666                 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1667                 ret = false;
1668         }
1669
1670         oldpass = newpass;
1671         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1672
1673         E_md4hash(oldpass, old_nt_hash);
1674         E_md4hash(newpass, new_nt_hash);
1675         E_deshash(oldpass, old_lm_hash);
1676         E_deshash(newpass, new_lm_hash);
1677
1678
1679         /* Reset the hashes to not broken values */
1680         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1681         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1682         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1683         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1684         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1685         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1686
1687         r.in.user_handle = &user_handle;
1688         r.in.lm_present = 1;
1689         r.in.old_lm_crypted = &hash1;
1690         r.in.new_lm_crypted = &hash2;
1691         r.in.nt_present = 1;
1692         r.in.old_nt_crypted = &hash3;
1693         r.in.new_nt_crypted = &hash4;
1694         r.in.cross1_present = 1;
1695         r.in.nt_cross = &hash5;
1696         r.in.cross2_present = 1;
1697         r.in.lm_cross = &hash6;
1698
1699         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1700         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1701                 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1702         } else  if (!NT_STATUS_IS_OK(status)) {
1703                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1704                 ret = false;
1705         } else {
1706                 changed = true;
1707                 *password = newpass;
1708         }
1709
1710         r.in.user_handle = &user_handle;
1711         r.in.lm_present = 1;
1712         r.in.old_lm_crypted = &hash1;
1713         r.in.new_lm_crypted = &hash2;
1714         r.in.nt_present = 1;
1715         r.in.old_nt_crypted = &hash3;
1716         r.in.new_nt_crypted = &hash4;
1717         r.in.cross1_present = 1;
1718         r.in.nt_cross = &hash5;
1719         r.in.cross2_present = 1;
1720         r.in.lm_cross = &hash6;
1721
1722         if (changed) {
1723                 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1724                 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1725                         printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1726                 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1727                         printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1728                         ret = false;
1729                 }
1730         }
1731
1732         
1733         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1734                 ret = false;
1735         }
1736
1737         return ret;
1738 }
1739
1740
1741 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1742                                         const char *acct_name,
1743                                         struct policy_handle *handle, char **password)
1744 {
1745         NTSTATUS status;
1746         struct samr_OemChangePasswordUser2 r;
1747         bool ret = true;
1748         struct samr_Password lm_verifier;
1749         struct samr_CryptPassword lm_pass;
1750         struct lsa_AsciiString server, account, account_bad;
1751         char *oldpass;
1752         char *newpass;
1753         uint8_t old_lm_hash[16], new_lm_hash[16];
1754
1755         struct samr_GetDomPwInfo dom_pw_info;
1756         struct samr_PwInfo info;
1757         int policy_min_pw_len = 0;
1758
1759         struct lsa_String domain_name;
1760
1761         domain_name.string = "";
1762         dom_pw_info.in.domain_name = &domain_name;
1763         dom_pw_info.out.info = &info;
1764
1765         torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1766
1767         torture_assert(tctx, *password != NULL, 
1768                                    "Failing OemChangePasswordUser2 as old password was NULL.  Previous test failed?");
1769
1770         oldpass = *password;
1771
1772         status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1773         if (NT_STATUS_IS_OK(status)) {
1774                 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1775         }
1776
1777         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1778
1779         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1780         account.string = acct_name;
1781
1782         E_deshash(oldpass, old_lm_hash);
1783         E_deshash(newpass, new_lm_hash);
1784
1785         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1786         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1787         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1788
1789         r.in.server = &server;
1790         r.in.account = &account;
1791         r.in.password = &lm_pass;
1792         r.in.hash = &lm_verifier;
1793
1794         /* Break the verification */
1795         lm_verifier.hash[0]++;
1796
1797         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1798
1799         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1800             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1801                 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1802                         nt_errstr(status));
1803                 ret = false;
1804         }
1805
1806         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1807         /* Break the old password */
1808         old_lm_hash[0]++;
1809         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1810         /* unbreak it for the next operation */
1811         old_lm_hash[0]--;
1812         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1813
1814         r.in.server = &server;
1815         r.in.account = &account;
1816         r.in.password = &lm_pass;
1817         r.in.hash = &lm_verifier;
1818
1819         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1820
1821         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1822             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1823                 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1824                         nt_errstr(status));
1825                 ret = false;
1826         }
1827
1828         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1829         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1830
1831         r.in.server = &server;
1832         r.in.account = &account;
1833         r.in.password = &lm_pass;
1834         r.in.hash = NULL;
1835
1836         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1837
1838         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1839             && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1840                 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1841                         nt_errstr(status));
1842                 ret = false;
1843         }
1844
1845         /* This shouldn't be a valid name */
1846         account_bad.string = TEST_ACCOUNT_NAME "XX";
1847         r.in.account = &account_bad;
1848
1849         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1850
1851         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1852                 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1853                         nt_errstr(status));
1854                 ret = false;
1855         }
1856
1857         /* This shouldn't be a valid name */
1858         account_bad.string = TEST_ACCOUNT_NAME "XX";
1859         r.in.account = &account_bad;
1860         r.in.password = &lm_pass;
1861         r.in.hash = &lm_verifier;
1862
1863         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1864
1865         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1866                 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1867                         nt_errstr(status));
1868                 ret = false;
1869         }
1870
1871         /* This shouldn't be a valid name */
1872         account_bad.string = TEST_ACCOUNT_NAME "XX";
1873         r.in.account = &account_bad;
1874         r.in.password = NULL;
1875         r.in.hash = &lm_verifier;
1876
1877         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1878
1879         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1880                 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1881                         nt_errstr(status));
1882                 ret = false;
1883         }
1884
1885         E_deshash(oldpass, old_lm_hash);
1886         E_deshash(newpass, new_lm_hash);
1887
1888         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1889         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1890         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1891
1892         r.in.server = &server;
1893         r.in.account = &account;
1894         r.in.password = &lm_pass;
1895         r.in.hash = &lm_verifier;
1896
1897         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1898         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1899                 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1900         } else if (!NT_STATUS_IS_OK(status)) {
1901                 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1902                 ret = false;
1903         } else {
1904                 *password = newpass;
1905         }
1906
1907         return ret;
1908 }
1909
1910
1911 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1912                                      const char *acct_name,
1913                                      char **password,
1914                                      char *newpass, bool allow_password_restriction)
1915 {
1916         NTSTATUS status;
1917         struct samr_ChangePasswordUser2 r;
1918         bool ret = true;
1919         struct lsa_String server, account;
1920         struct samr_CryptPassword nt_pass, lm_pass;
1921         struct samr_Password nt_verifier, lm_verifier;
1922         char *oldpass;
1923         uint8_t old_nt_hash[16], new_nt_hash[16];
1924         uint8_t old_lm_hash[16], new_lm_hash[16];
1925
1926         struct samr_GetDomPwInfo dom_pw_info;
1927         struct samr_PwInfo info;
1928
1929         struct lsa_String domain_name;
1930
1931         domain_name.string = "";
1932         dom_pw_info.in.domain_name = &domain_name;
1933         dom_pw_info.out.info = &info;
1934
1935         torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
1936
1937         torture_assert(tctx, *password != NULL, 
1938                                    "Failing ChangePasswordUser2 as old password was NULL.  Previous test failed?");
1939         oldpass = *password;
1940
1941         if (!newpass) {
1942                 int policy_min_pw_len = 0;
1943                 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1944                 if (NT_STATUS_IS_OK(status)) {
1945                         policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1946                 }
1947
1948                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1949         } 
1950
1951         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1952         init_lsa_String(&account, acct_name);
1953
1954         E_md4hash(oldpass, old_nt_hash);
1955         E_md4hash(newpass, new_nt_hash);
1956
1957         E_deshash(oldpass, old_lm_hash);
1958         E_deshash(newpass, new_lm_hash);
1959
1960         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1961         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1962         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1963
1964         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1965         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1966         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1967
1968         r.in.server = &server;
1969         r.in.account = &account;
1970         r.in.nt_password = &nt_pass;
1971         r.in.nt_verifier = &nt_verifier;
1972         r.in.lm_change = 1;
1973         r.in.lm_password = &lm_pass;
1974         r.in.lm_verifier = &lm_verifier;
1975
1976         status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
1977         if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1978                 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1979         } else if (!NT_STATUS_IS_OK(status)) {
1980                 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1981                 ret = false;
1982         } else {
1983                 *password = newpass;
1984         }
1985
1986         return ret;
1987 }
1988
1989
1990 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx, 
1991                               const char *account_string,
1992                               int policy_min_pw_len,
1993                               char **password,
1994                               const char *newpass,
1995                               NTTIME last_password_change,
1996                               bool handle_reject_reason)
1997 {
1998         NTSTATUS status;
1999         struct samr_ChangePasswordUser3 r;
2000         bool ret = true;
2001         struct lsa_String server, account, account_bad;
2002         struct samr_CryptPassword nt_pass, lm_pass;
2003         struct samr_Password nt_verifier, lm_verifier;
2004         char *oldpass;
2005         uint8_t old_nt_hash[16], new_nt_hash[16];
2006         uint8_t old_lm_hash[16], new_lm_hash[16];
2007         NTTIME t;
2008         struct samr_DomInfo1 *dominfo = NULL;
2009         struct samr_ChangeReject *reject = NULL;
2010
2011         torture_comment(tctx, "Testing ChangePasswordUser3\n");
2012
2013         if (newpass == NULL) {
2014                 do {
2015                         if (policy_min_pw_len == 0) {
2016                                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2017                         } else {
2018                                 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2019                         }
2020                 } while (check_password_quality(newpass) == false);
2021         } else {
2022                 torture_comment(tctx, "Using password '%s'\n", newpass);
2023         }
2024
2025         torture_assert(tctx, *password != NULL, 
2026                                    "Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?");
2027
2028         oldpass = *password;
2029         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2030         init_lsa_String(&account, account_string);
2031
2032         E_md4hash(oldpass, old_nt_hash);
2033         E_md4hash(newpass, new_nt_hash);
2034
2035         E_deshash(oldpass, old_lm_hash);
2036         E_deshash(newpass, new_lm_hash);
2037
2038         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2039         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2040         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2041
2042         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2043         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2044         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2045         
2046         /* Break the verification */
2047         nt_verifier.hash[0]++;
2048
2049         r.in.server = &server;
2050         r.in.account = &account;
2051         r.in.nt_password = &nt_pass;
2052         r.in.nt_verifier = &nt_verifier;
2053         r.in.lm_change = 1;
2054         r.in.lm_password = &lm_pass;
2055         r.in.lm_verifier = &lm_verifier;
2056         r.in.password3 = NULL;
2057         r.out.dominfo = &dominfo;
2058         r.out.reject = &reject;
2059
2060         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2061         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2062             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2063                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2064                         nt_errstr(status));
2065                 ret = false;
2066         }
2067         
2068         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2069         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2070         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2071
2072         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2073         /* Break the NT hash */
2074         old_nt_hash[0]++;
2075         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2076         /* Unbreak it again */
2077         old_nt_hash[0]--;
2078         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2079         
2080         r.in.server = &server;
2081         r.in.account = &account;
2082         r.in.nt_password = &nt_pass;
2083         r.in.nt_verifier = &nt_verifier;
2084         r.in.lm_change = 1;
2085         r.in.lm_password = &lm_pass;
2086         r.in.lm_verifier = &lm_verifier;
2087         r.in.password3 = NULL;
2088         r.out.dominfo = &dominfo;
2089         r.out.reject = &reject;
2090
2091         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2092         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2093             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2094                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2095                         nt_errstr(status));
2096                 ret = false;
2097         }
2098         
2099         /* This shouldn't be a valid name */
2100         init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2101
2102         r.in.account = &account_bad;
2103         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2104         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2105                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2106                         nt_errstr(status));
2107                 ret = false;
2108         }
2109
2110         E_md4hash(oldpass, old_nt_hash);
2111         E_md4hash(newpass, new_nt_hash);
2112
2113         E_deshash(oldpass, old_lm_hash);
2114         E_deshash(newpass, new_lm_hash);
2115
2116         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2117         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2118         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2119
2120         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2121         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2122         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2123
2124         r.in.server = &server;
2125         r.in.account = &account;
2126         r.in.nt_password = &nt_pass;
2127         r.in.nt_verifier = &nt_verifier;
2128         r.in.lm_change = 1;
2129         r.in.lm_password = &lm_pass;
2130         r.in.lm_verifier = &lm_verifier;
2131         r.in.password3 = NULL;
2132         r.out.dominfo = &dominfo;
2133         r.out.reject = &reject;
2134
2135         unix_to_nt_time(&t, time(NULL));
2136
2137         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2138
2139         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2140             && dominfo
2141             && reject
2142             && handle_reject_reason
2143             && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2144                 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2145
2146                         if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
2147                                 printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
2148                                         SAMR_REJECT_OTHER, reject->reason);
2149                                 return false;
2150                         }
2151                 }
2152
2153                 /* We tested the order of precendence which is as follows:
2154                 
2155                 * pwd min_age 
2156                 * pwd length
2157                 * pwd complexity
2158                 * pwd history
2159
2160                 Guenther */
2161
2162                 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2163                            (last_password_change + dominfo->min_password_age > t)) {
2164
2165                         if (reject->reason != SAMR_REJECT_OTHER) {
2166                                 printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
2167                                         SAMR_REJECT_OTHER, reject->reason);
2168                                 return false;
2169                         }
2170
2171                 } else if ((dominfo->min_password_length > 0) &&
2172                            (strlen(newpass) < dominfo->min_password_length)) {
2173
2174                         if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2175                                 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n", 
2176                                         SAMR_REJECT_TOO_SHORT, reject->reason);
2177                                 return false;
2178                         }
2179
2180                 } else if ((dominfo->password_history_length > 0) &&
2181                             strequal(oldpass, newpass)) {
2182
2183                         if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2184                                 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n", 
2185                                         SAMR_REJECT_IN_HISTORY, reject->reason);
2186                                 return false;
2187                         }
2188                 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2189
2190                         if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2191                                 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n", 
2192                                         SAMR_REJECT_COMPLEXITY, reject->reason);
2193                                 return false;
2194                         }
2195
2196                 }
2197
2198                 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2199                         /* retry with adjusted size */
2200                         return test_ChangePasswordUser3(p, tctx, account_string, 
2201                                                         dominfo->min_password_length,
2202                                                         password, NULL, 0, false); 
2203
2204                 }
2205
2206         } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2207                 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2208                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
2209                                SAMR_REJECT_OTHER, reject->reason);
2210                         return false;
2211                 }
2212                 /* Perhaps the server has a 'min password age' set? */
2213
2214         } else { 
2215                 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2216                 *password = talloc_strdup(tctx, newpass);
2217         }
2218
2219         return ret;
2220 }
2221
2222 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2223                                     const char *account_string,
2224                                     struct policy_handle *handle, 
2225                                     char **password)
2226 {
2227         NTSTATUS status;
2228         struct samr_ChangePasswordUser3 r;
2229         struct samr_SetUserInfo s;
2230         union samr_UserInfo u;
2231         DATA_BLOB session_key;
2232         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2233         uint8_t confounder[16];
2234         struct MD5Context ctx;
2235
2236         bool ret = true;
2237         struct lsa_String server, account;
2238         struct samr_CryptPassword nt_pass;
2239         struct samr_Password nt_verifier;
2240         DATA_BLOB new_random_pass;
2241         char *newpass;
2242         char *oldpass;
2243         uint8_t old_nt_hash[16], new_nt_hash[16];
2244         NTTIME t;
2245         struct samr_DomInfo1 *dominfo = NULL;
2246         struct samr_ChangeReject *reject = NULL;
2247
2248         new_random_pass = samr_very_rand_pass(tctx, 128);
2249
2250         torture_assert(tctx, *password != NULL, 
2251                                    "Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?");
2252
2253         oldpass = *password;
2254         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2255         init_lsa_String(&account, account_string);
2256
2257         s.in.user_handle = handle;
2258         s.in.info = &u;
2259         s.in.level = 25;
2260
2261         ZERO_STRUCT(u);
2262
2263         u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2264
2265         set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2266
2267         status = dcerpc_fetch_session_key(p, &session_key);
2268         if (!NT_STATUS_IS_OK(status)) {
2269                 printf("SetUserInfo level %u - no session key - %s\n",
2270                        s.in.level, nt_errstr(status));
2271                 return false;
2272         }
2273
2274         generate_random_buffer((uint8_t *)confounder, 16);
2275
2276         MD5Init(&ctx);
2277         MD5Update(&ctx, confounder, 16);
2278         MD5Update(&ctx, session_key.data, session_key.length);
2279         MD5Final(confounded_session_key.data, &ctx);
2280
2281         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2282         memcpy(&u.info25.password.data[516], confounder, 16);
2283
2284         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2285
2286         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2287         if (!NT_STATUS_IS_OK(status)) {
2288                 printf("SetUserInfo level %u failed - %s\n",
2289                        s.in.level, nt_errstr(status));
2290                 ret = false;
2291         }
2292
2293         torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2294
2295         mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2296
2297         new_random_pass = samr_very_rand_pass(tctx, 128);
2298
2299         mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2300
2301         set_pw_in_buffer(nt_pass.data, &new_random_pass);
2302         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2303         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2304
2305         r.in.server = &server;
2306         r.in.account = &account;
2307         r.in.nt_password = &nt_pass;
2308         r.in.nt_verifier = &nt_verifier;
2309         r.in.lm_change = 0;
2310         r.in.lm_password = NULL;
2311         r.in.lm_verifier = NULL;
2312         r.in.password3 = NULL;
2313         r.out.dominfo = &dominfo;
2314         r.out.reject = &reject;
2315
2316         unix_to_nt_time(&t, time(NULL));
2317
2318         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2319
2320         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2321                 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2322                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
2323                                SAMR_REJECT_OTHER, reject->reason);
2324                         return false;
2325                 }
2326                 /* Perhaps the server has a 'min password age' set? */
2327
2328         } else if (!NT_STATUS_IS_OK(status)) {
2329                 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2330                 ret = false;
2331         }
2332         
2333         newpass = samr_rand_pass(tctx, 128);
2334
2335         mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2336
2337         E_md4hash(newpass, new_nt_hash);
2338
2339         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2340         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2341         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2342
2343         r.in.server = &server;
2344         r.in.account = &account;
2345         r.in.nt_password = &nt_pass;
2346         r.in.nt_verifier = &nt_verifier;
2347         r.in.lm_change = 0;
2348         r.in.lm_password = NULL;
2349         r.in.lm_verifier = NULL;
2350         r.in.password3 = NULL;
2351         r.out.dominfo = &dominfo;
2352         r.out.reject = &reject;
2353
2354         unix_to_nt_time(&t, time(NULL));
2355
2356         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2357
2358         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2359                 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2360                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
2361                                SAMR_REJECT_OTHER, reject->reason);
2362                         return false;
2363                 }
2364                 /* Perhaps the server has a 'min password age' set? */
2365
2366         } else {
2367                 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2368                 *password = talloc_strdup(tctx, newpass);
2369         }
2370
2371         return ret;
2372 }
2373
2374
2375 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2376                                   struct policy_handle *alias_handle)
2377 {
2378         struct samr_GetMembersInAlias r;
2379         struct lsa_SidArray sids;
2380         NTSTATUS status;
2381
2382         torture_comment(tctx, "Testing GetMembersInAlias\n");
2383
2384         r.in.alias_handle = alias_handle;
2385         r.out.sids = &sids;
2386
2387         status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2388         torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2389
2390         return true;
2391 }
2392
2393 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2394                                   struct policy_handle *alias_handle,
2395                                   const struct dom_sid *domain_sid)
2396 {
2397         struct samr_AddAliasMember r;
2398         struct samr_DeleteAliasMember d;
2399         NTSTATUS status;
2400         struct dom_sid *sid;
2401
2402         sid = dom_sid_add_rid(tctx, domain_sid, 512);
2403
2404         torture_comment(tctx, "testing AddAliasMember\n");
2405         r.in.alias_handle = alias_handle;
2406         r.in.sid = sid;
2407
2408         status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2409         torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2410
2411         d.in.alias_handle = alias_handle;
2412         d.in.sid = sid;
2413
2414         status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2415         torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2416
2417         return true;
2418 }
2419
2420 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2421                                            struct policy_handle *alias_handle)
2422 {
2423         struct samr_AddMultipleMembersToAlias a;
2424         struct samr_RemoveMultipleMembersFromAlias r;
2425         NTSTATUS status;
2426         struct lsa_SidArray sids;
2427
2428         torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2429         a.in.alias_handle = alias_handle;
2430         a.in.sids = &sids;
2431
2432         sids.num_sids = 3;
2433         sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2434
2435         sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2436         sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2437         sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2438
2439         status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2440         torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2441
2442
2443         torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2444         r.in.alias_handle = alias_handle;
2445         r.in.sids = &sids;
2446
2447         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2448         torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2449
2450         /* strange! removing twice doesn't give any error */
2451         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2452         torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2453
2454         /* but removing an alias that isn't there does */
2455         sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2456
2457         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2458         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2459
2460         return true;
2461 }
2462
2463 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2464                                             struct policy_handle *user_handle)
2465 {
2466         struct samr_TestPrivateFunctionsUser r;
2467         NTSTATUS status;
2468
2469         torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2470
2471         r.in.user_handle = user_handle;
2472
2473         status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2474         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2475
2476         return true;
2477 }
2478
2479 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2480                                           struct torture_context *tctx,
2481                                           struct policy_handle *handle,
2482                                           bool use_info2,
2483                                           NTTIME *pwdlastset)
2484 {
2485         NTSTATUS status;
2486         uint16_t levels[] = { /* 3, */ 5, 21 };
2487         int i;
2488         NTTIME pwdlastset3 = 0;
2489         NTTIME pwdlastset5 = 0;
2490         NTTIME pwdlastset21 = 0;
2491
2492         torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2493                         use_info2 ? "2":"");
2494
2495         for (i=0; i<ARRAY_SIZE(levels); i++) {
2496
2497                 struct samr_QueryUserInfo r;
2498                 struct samr_QueryUserInfo2 r2;
2499                 union samr_UserInfo *info;
2500
2501                 if (use_info2) {
2502                         r2.in.user_handle = handle;
2503                         r2.in.level = levels[i];
2504                         r2.out.info = &info;
2505                         status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2506
2507                 } else {
2508                         r.in.user_handle = handle;
2509                         r.in.level = levels[i];
2510                         r.out.info = &info;
2511                         status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2512                 }
2513
2514                 if (!NT_STATUS_IS_OK(status) &&
2515                     !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2516                         printf("QueryUserInfo%s level %u failed - %s\n",
2517                                use_info2 ? "2":"", levels[i], nt_errstr(status));
2518                         return false;
2519                 }
2520
2521                 switch (levels[i]) {
2522                 case 3:
2523                         pwdlastset3 = info->info3.last_password_change;
2524                         break;
2525                 case 5:
2526                         pwdlastset5 = info->info5.last_password_change;
2527                         break;
2528                 case 21:
2529                         pwdlastset21 = info->info21.last_password_change;
2530                         break;
2531                 default:
2532                         return false;
2533                 }
2534         }
2535         /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2536                                     "pwdlastset mixup"); */
2537         torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2538                                  "pwdlastset mixup");
2539
2540         *pwdlastset = pwdlastset21;
2541
2542         torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2543
2544         return true;
2545 }
2546
2547 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2548                                    struct torture_context *tctx,
2549                                    struct policy_handle *handle,
2550                                    uint16_t level,
2551                                    uint32_t fields_present,
2552                                    uint8_t password_expired,
2553                                    NTSTATUS expected_error,
2554                                    bool use_setinfo2,
2555                                    char **password,
2556                                    bool use_queryinfo2,
2557                                    NTTIME *pwdlastset)
2558 {
2559         const char *fields = NULL;
2560         bool ret = true;
2561
2562         switch (level) {
2563         case 21:
2564         case 23:
2565         case 25:
2566                 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2567                                          fields_present);
2568                 break;
2569         default:
2570                 break;
2571         }
2572
2573         torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2574                 "(password_expired: %d) %s\n",
2575                 use_setinfo2 ? "2":"", level, password_expired,
2576                 fields ? fields : "");
2577
2578         switch (level) {
2579                 case 21:
2580                 case 23:
2581                 case 24:
2582                 case 25:
2583                 case 26:
2584                         if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2585                                                        fields_present,
2586                                                        password,
2587                                                        password_expired,
2588                                                        use_setinfo2,
2589                                                        expected_error)) {
2590                                 ret = false;
2591                         }
2592                         break;
2593                 default:
2594                         return false;
2595         }
2596
2597         if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2598                                            use_queryinfo2,
2599                                            pwdlastset)) {
2600                 ret = false;
2601         }
2602
2603         return ret;
2604 }
2605
2606 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2607                                         struct torture_context *tctx,
2608                                         uint32_t acct_flags,
2609                                         struct policy_handle *handle,
2610                                         char **password)
2611 {
2612         int i, s = 0, q = 0;
2613         bool ret = true;
2614         int delay = 500000;
2615         bool set_levels[] = { false, true };
2616         bool query_levels[] = { false, true };
2617
2618         struct {
2619                 uint16_t level;
2620                 uint8_t password_expired_nonzero;
2621                 uint32_t fields_present;
2622                 bool query_info2;
2623                 bool set_info2;
2624                 NTSTATUS set_error;
2625         } pwd_tests[] = {
2626
2627                 /* level 21 */
2628                 {
2629                         .level                          = 21,
2630                         .password_expired_nonzero       = 1,
2631                         .fields_present                 = SAMR_FIELD_EXPIRED_FLAG
2632                 },{
2633                         .level                          = 21,
2634                         .password_expired_nonzero       = 1,
2635                         .fields_present                 = SAMR_FIELD_LAST_PWD_CHANGE,
2636                         .set_error                      = NT_STATUS_ACCESS_DENIED
2637                 },{
2638                         .level                          = 21,
2639                         .password_expired_nonzero       = 1,
2640                         .fields_present                 = 0,
2641                         .set_error                      = NT_STATUS_INVALID_PARAMETER
2642                 },{
2643                         .level                          = 21,
2644                         .password_expired_nonzero       = 1,
2645                         .fields_present                 = SAMR_FIELD_COMMENT,
2646
2647 #if 0
2648         /* FIXME */
2649                 },{
2650                         .level                          = 21,
2651                         .password_expired_nonzero       = 1,
2652                         .fields_present                 = SAMR_FIELD_NT_PASSWORD_PRESENT |
2653                                                           SAMR_FIELD_LM_PASSWORD_PRESENT |
2654                                                           SAMR_FIELD_LAST_PWD_CHANGE,
2655                         .query_info2                    = false,
2656                         .set_error                      = NT_STATUS_ACCESS_DENIED
2657 #endif
2658
2659                 /* level 23 */
2660                 },{
2661                         .level                          = 23,
2662                         .password_expired_nonzero       = 1,
2663                         .fields_present                 = SAMR_FIELD_EXPIRED_FLAG
2664                 },{
2665                         .level                          = 23,
2666                         .password_expired_nonzero       = 1,
2667                         .fields_present                 = SAMR_FIELD_LAST_PWD_CHANGE,
2668                         .set_error                      = NT_STATUS_ACCESS_DENIED
2669                 },{
2670                         .level                          = 23,
2671                         .password_expired_nonzero       = 1,
2672                         .fields_present                 = SAMR_FIELD_LAST_PWD_CHANGE |
2673                                                           SAMR_FIELD_NT_PASSWORD_PRESENT |
2674                                                           SAMR_FIELD_LM_PASSWORD_PRESENT,
2675                         .set_error                      = NT_STATUS_ACCESS_DENIED
2676                 },{
2677                         .level                          = 23,
2678                         .password_expired_nonzero       = 1,
2679                         .fields_present                 = SAMR_FIELD_LAST_PWD_CHANGE |
2680                                                           SAMR_FIELD_NT_PASSWORD_PRESENT |
2681                                                           SAMR_FIELD_LM_PASSWORD_PRESENT |
2682                                                           SAMR_FIELD_EXPIRED_FLAG,
2683                         .set_error                      = NT_STATUS_ACCESS_DENIED
2684                 },{
2685                         .level                          = 23,
2686                         .password_expired_nonzero       = 1,
2687                         .fields_present                 = SAMR_FIELD_NT_PASSWORD_PRESENT |
2688                                                           SAMR_FIELD_LM_PASSWORD_PRESENT |
2689                                                           SAMR_FIELD_EXPIRED_FLAG
2690                 },{
2691                         .level                          = 23,
2692                         .password_expired_nonzero       = 1,
2693                         .fields_present                 = SAMR_FIELD_NT_PASSWORD_PRESENT |
2694                                                           SAMR_FIELD_LM_PASSWORD_PRESENT,
2695                 },{
2696                         .level                          = 23,
2697                         .password_expired_nonzero       = 1,
2698                         .fields_present                 = SAMR_FIELD_COMMENT,
2699                 },{
2700                         .level                          = 23,
2701                         .password_expired_nonzero       = 1,
2702                         .fields_present                 = 0,
2703                         .set_error                      = NT_STATUS_INVALID_PARAMETER
2704                 },{
2705
2706                 /* level 24 */
2707
2708                         .level                          = 24,
2709                         .password_expired_nonzero       = 1
2710                 },{
2711                         .level                          = 24,
2712                         .password_expired_nonzero       = 24
2713                 },{
2714
2715                 /* level 25 */
2716
2717                         .level                          = 25,
2718                         .password_expired_nonzero       = 1,
2719                         .fields_present                 = SAMR_FIELD_LAST_PWD_CHANGE,
2720                         .set_error                      = NT_STATUS_ACCESS_DENIED
2721                 },{
2722                         .level                          = 25,
2723                         .password_expired_nonzero       = 1,
2724                         .fields_present                 = SAMR_FIELD_EXPIRED_FLAG,
2725                 },{
2726                         .level                          = 25,
2727                         .password_expired_nonzero       = 1,
2728                         .fields_present                 = SAMR_FIELD_NT_PASSWORD_PRESENT |
2729                                                           SAMR_FIELD_LM_PASSWORD_PRESENT |
2730                                                           SAMR_FIELD_EXPIRED_FLAG
2731                 },{
2732                         .level                          = 25,
2733                         .password_expired_nonzero       = 1,
2734                         .fields_present                 = SAMR_FIELD_NT_PASSWORD_PRESENT |
2735                                                           SAMR_FIELD_LM_PASSWORD_PRESENT,
2736                 },{
2737                         .level                          = 25,
2738                         .password_expired_nonzero       = 1,
2739                         .fields_present                 = SAMR_FIELD_COMMENT,
2740                 },{
2741
2742                 /* level 26 */
2743
2744                         .level                          = 26,
2745                         .password_expired_nonzero       = 1
2746                 },{
2747                         .level                          = 26,
2748                         .password_expired_nonzero       = 24
2749                 }
2750         };
2751
2752         if (torture_setting_bool(tctx, "samba3", false)) {
2753                 delay = 1000000;
2754                 printf("Samba3 has second granularity, setting delay to: %d\n",
2755                         delay);
2756         }
2757
2758         /* set to 1 to enable testing for all possible opcode
2759            (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2760            combinations */
2761 #if 0
2762 #define TEST_SET_LEVELS 1
2763 #define TEST_QUERY_LEVELS 1
2764 #endif
2765         for (i=0; i<ARRAY_SIZE(pwd_tests); i++) {
2766 #ifdef TEST_SET_LEVELS
2767         for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2768 #endif
2769 #ifdef TEST_QUERY_LEVELS
2770         for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2771 #endif
2772                 NTTIME pwdlastset_old = 0;
2773                 NTTIME pwdlastset_new = 0;
2774
2775                 torture_comment(tctx, "------------------------------\n"
2776                                 "Testing pwdLastSet attribute for flags: 0x%08x "
2777                                 "(s: %d (l: %d), q: %d)\n",
2778                                 acct_flags, s, pwd_tests[i].level, q);
2779
2780                 /* set #1 */
2781
2782                 /* set a password and force password change (pwdlastset 0) by
2783                  * setting the password expired flag to a non-0 value */
2784
2785                 if (!test_SetPassword_level(p, tctx, handle,
2786                                             pwd_tests[i].level,
2787                                             pwd_tests[i].fields_present,
2788                                             pwd_tests[i].password_expired_nonzero,
2789                                             pwd_tests[i].set_error,
2790                                             set_levels[s],
2791                                             password,
2792                                             query_levels[q],
2793                                             &pwdlastset_old)) {
2794                         ret = false;
2795                 }
2796
2797                 if (!NT_STATUS_IS_OK(pwd_tests[i].set_error)) {
2798                         /* skipping on expected failure */
2799                         continue;
2800                 }
2801
2802                 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2803                  * set without the SAMR_FIELD_EXPIRED_FLAG */
2804
2805                 switch (pwd_tests[i].level) {
2806                 case 21:
2807                 case 23:
2808                 case 25:
2809                         if ((pwdlastset_new != 0) &&
2810                             !(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG)) {
2811                                 torture_comment(tctx, "not considering a non-0 "
2812                                         "pwdLastSet as a an error as the "
2813                                         "SAMR_FIELD_EXPIRED_FLAG has not "
2814                                         "been set\n");
2815                                 break;
2816                         }
2817                 default:
2818                         if (pwdlastset_new != 0) {
2819                                 torture_warning(tctx, "pwdLastSet test failed: "
2820                                         "expected pwdLastSet 0 but got %lld\n",
2821                                         pwdlastset_old);
2822                                 ret = false;
2823                         }
2824                         break;
2825                 }
2826
2827                 usleep(delay);
2828
2829                 /* set #2 */
2830
2831                 /* set a password, pwdlastset needs to get updated (increased
2832                  * value), password_expired value used here is 0 */
2833
2834                 if (!test_SetPassword_level(p, tctx, handle, pwd_tests[i].level,
2835                                             pwd_tests[i].fields_present,
2836                                             0,
2837                                             pwd_tests[i].set_error,
2838                                             set_levels[s],
2839                                             password,
2840                                             query_levels[q],
2841                                             &pwdlastset_new)) {
2842
2843                         ret = false;
2844                 }
2845
2846                 /* when a password has been changed, pwdlastset must not be 0 afterwards
2847                  * and must be larger then the old value */
2848
2849                 switch (pwd_tests[i].level) {
2850                 case 21:
2851                 case 23:
2852                 case 25:
2853
2854                         /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
2855                          * password has been changed, old and new pwdlastset
2856                          * need to be the same value */
2857
2858                         if (!(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG) &&
2859                             !((pwd_tests[i].fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2860                               (pwd_tests[i].fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)))
2861                         {
2862                                 torture_assert_int_equal(tctx, pwdlastset_old,
2863                                         pwdlastset_new, "pwdlastset must be equal");
2864                                 break;
2865                         }
2866                 default:
2867                         if (pwdlastset_old >= pwdlastset_new) {
2868                                 torture_warning(tctx, "pwdLastSet test failed: "
2869                                         "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
2870                                         pwdlastset_old, pwdlastset_new);
2871                                 ret = false;
2872                         }
2873                         if (pwdlastset_new == 0) {
2874                                 torture_warning(tctx, "pwdLastSet test failed: "
2875                                         "expected non-0 pwdlastset, got: %lld\n",
2876                                         pwdlastset_new);
2877                                 ret = false;
2878                         }
2879                 }
2880
2881                 pwdlastset_old = pwdlastset_new;
2882
2883                 usleep(delay);
2884
2885                 /* set #3 */
2886
2887                 /* set a password and force password change (pwdlastset 0) by
2888                  * setting the password expired flag to a non-0 value */
2889
2890                 if (!test_SetPassword_level(p, tctx, handle, pwd_tests[i].level,
2891                                             pwd_tests[i].fields_present,
2892                                             pwd_tests[i].password_expired_nonzero,
2893                                             pwd_tests[i].set_error,
2894                                             set_levels[s],
2895                                             password,
2896                                             query_levels[q],
2897                                             &pwdlastset_new)) {
2898                         ret = false;
2899                 }
2900
2901                 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2902                  * set without the SAMR_FIELD_EXPIRED_FLAG */
2903
2904                 switch (pwd_tests[i].level) {
2905                 case 21:
2906                 case 23:
2907                 case 25:
2908                         if ((pwdlastset_new != 0) &&
2909                             !(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG)) {
2910                                 torture_comment(tctx, "not considering a non-0 "
2911                                         "pwdLastSet as a an error as the "
2912                                         "SAMR_FIELD_EXPIRED_FLAG has not "
2913                                         "been set\n");
2914                                 break;
2915                         }
2916
2917                         /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
2918                          * password has been changed, old and new pwdlastset
2919                          * need to be the same value */
2920
2921                         if (!(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG) &&
2922                             !((pwd_tests[i].fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2923                               (pwd_tests[i].fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)))
2924                         {
2925                                 torture_assert_int_equal(tctx, pwdlastset_old,
2926                                         pwdlastset_new, "pwdlastset must be equal");
2927                                 break;
2928                         }
2929                 default:
2930
2931                         if (pwdlastset_old == pwdlastset_new) {
2932                                 torture_warning(tctx, "pwdLastSet test failed: "
2933                                         "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
2934                                         pwdlastset_old, pwdlastset_new);
2935                                 ret = false;
2936                         }
2937
2938                         if (pwdlastset_new != 0) {
2939                                 torture_warning(tctx, "pwdLastSet test failed: "
2940                                         "expected pwdLastSet 0, got %lld\n",
2941                                         pwdlastset_old);
2942                                 ret = false;
2943                         }
2944                         break;
2945                 }
2946 #ifdef TEST_QUERY_LEVELS
2947         }
2948 #endif
2949 #ifdef TEST_SET_LEVELS
2950         }
2951 #endif
2952         }
2953
2954 #undef TEST_SET_LEVELS
2955 #undef TEST_QUERY_LEVELS
2956
2957         return ret;
2958 }
2959
2960 static bool test_user_ops(struct dcerpc_pipe *p, 
2961                           struct torture_context *tctx,
2962                           struct policy_handle *user_handle, 
2963                           struct policy_handle *domain_handle, 
2964                           uint32_t base_acct_flags, 
2965                           const char *base_acct_name, enum torture_samr_choice which_ops)
2966 {
2967         char *password = NULL;
2968         struct samr_QueryUserInfo q;
2969         union samr_UserInfo *info;
2970         NTSTATUS status;
2971
2972         bool ret = true;
2973         int i;
2974         uint32_t rid;
2975         const uint32_t password_fields[] = {
2976                 SAMR_FIELD_NT_PASSWORD_PRESENT,
2977                 SAMR_FIELD_LM_PASSWORD_PRESENT,
2978                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2979                 0
2980         };
2981         
2982         status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2983         if (!NT_STATUS_IS_OK(status)) {
2984                 ret = false;
2985         }
2986
2987         switch (which_ops) {
2988         case TORTURE_SAMR_USER_ATTRIBUTES:
2989                 if (!test_QuerySecurity(p, tctx, user_handle)) {
2990                         ret = false;
2991                 }
2992
2993                 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2994                         ret = false;
2995                 }
2996
2997                 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2998                         ret = false;
2999                 }
3000
3001                 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3002                                       base_acct_name)) {
3003                         ret = false;
3004                 }       
3005
3006                 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3007                         ret = false;
3008                 }
3009
3010                 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3011                         ret = false;
3012                 }
3013
3014                 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3015                         ret = false;
3016                 }
3017                 break;
3018         case TORTURE_SAMR_PASSWORDS:
3019                 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3020                         char simple_pass[9];
3021                         char *v = generate_random_str(tctx, 1);
3022                         
3023                         ZERO_STRUCT(simple_pass);
3024                         memset(simple_pass, *v, sizeof(simple_pass) - 1);
3025
3026                         printf("Testing machine account password policy rules\n");
3027
3028                         /* Workstation trust accounts don't seem to need to honour password quality policy */
3029                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3030                                 ret = false;
3031                         }
3032
3033                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3034                                 ret = false;
3035                         }
3036
3037                         /* reset again, to allow another 'user' password change */
3038                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3039                                 ret = false;
3040                         }
3041
3042                         /* Try a 'short' password */
3043                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3044                                 ret = false;
3045                         }
3046
3047                         /* Try a compleatly random password */
3048                         if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3049                                 ret = false;
3050                         }
3051                 }
3052
3053                 for (i = 0; password_fields[i]; i++) {
3054                         if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3055                                 ret = false;
3056                         }       
3057                 
3058                         /* check it was set right */
3059                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3060                                 ret = false;
3061                         }
3062                 }               
3063
3064                 for (i = 0; password_fields[i]; i++) {
3065                         if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3066                                 ret = false;
3067                         }       
3068                 
3069                         /* check it was set right */
3070                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3071                                 ret = false;
3072                         }
3073                 }               
3074
3075                 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3076                         ret = false;
3077                 }       
3078
3079                 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3080                         ret = false;
3081                 }       
3082
3083                 if (torture_setting_bool(tctx, "samba4", false)) {
3084                         printf("skipping Set Password level 18 and 21 against Samba4\n");
3085                 } else {
3086
3087                         if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3088                                 ret = false;
3089                         }
3090
3091                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3092                                 ret = false;
3093                         }
3094
3095                         for (i = 0; password_fields[i]; i++) {
3096
3097                                 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3098                                         /* we need to skip as that would break
3099                                          * the ChangePasswordUser3 verify */
3100                                         continue;
3101                                 }
3102
3103                                 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3104                                         ret = false;
3105                                 }
3106
3107                                 /* check it was set right */
3108                                 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3109                                         ret = false;
3110                                 }
3111                         }
3112                 }
3113
3114                 q.in.user_handle = user_handle;
3115                 q.in.level = 5;