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