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