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