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