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