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