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