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