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