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