r24942: Patch from Matthias Wallnöfer <mwallnoefer@yahoo.de> and a testsuite
[gd/samba-autobuild/.git] / source4 / torture / rpc / samr.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for samr rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "torture/torture.h"
24 #include "system/time.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_samr_c.h"
27 #include "lib/crypto/crypto.h"
28 #include "libcli/auth/libcli_auth.h"
29 #include "libcli/security/security.h"
30 #include "torture/rpc/rpc.h"
31
32 #define TEST_ACCOUNT_NAME "samrtorturetest"
33 #define TEST_ALIASNAME "samrtorturetestalias"
34 #define TEST_GROUPNAME "samrtorturetestgroup"
35 #define TEST_MACHINENAME "samrtestmach$"
36 #define TEST_DOMAINNAME "samrtestdom$"
37
38 enum torture_samr_choice {
39         TORTURE_SAMR_PASSWORDS,
40         TORTURE_SAMR_USER_ATTRIBUTES,
41         TORTURE_SAMR_OTHER
42 };
43
44 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
45                                struct policy_handle *handle);
46
47 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
48                                 struct policy_handle *handle);
49
50 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
51                                struct policy_handle *handle);
52
53 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
54                                 const char *acct_name, 
55                                 struct policy_handle *domain_handle, char **password);
56
57 static void init_lsa_String(struct lsa_String *string, const char *s)
58 {
59         string->string = s;
60 }
61
62 BOOL test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
63                                    struct policy_handle *handle)
64 {
65         NTSTATUS status;
66         struct samr_Close r;
67
68         r.in.handle = handle;
69         r.out.handle = handle;
70
71         status = dcerpc_samr_Close(p, mem_ctx, &r);
72         if (!NT_STATUS_IS_OK(status)) {
73                 printf("Close handle failed - %s\n", nt_errstr(status));
74                 return False;
75         }
76
77         return True;
78 }
79
80 static BOOL test_Shutdown(struct dcerpc_pipe *p, 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(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
390         TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
391         TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__, 
392                           SAMR_FIELD_ACCT_EXPIRY);
393
394         TEST_USERINFO_INT(4, logon_hours.bits[3],  3, logon_hours.bits[3], 1, 0);
395         TEST_USERINFO_INT(4, logon_hours.bits[3],  5, logon_hours.bits[3], 2, 0);
396         TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
397         TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4, 
398                           SAMR_FIELD_LOGON_HOURS);
399
400         if (lp_parm_bool(-1, "torture", "samba4", False)) {
401                 printf("skipping Set Account Flag tests against Samba4\n");
402                 return ret;
403         }
404
405         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
406                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ), 
407                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags), 
408                               0);
409         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
410                               (base_acct_flags  | ACB_DISABLED), 
411                               (base_acct_flags  | ACB_DISABLED | user_extra_flags), 
412                               0);
413         
414         /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
415         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
416                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP), 
417                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP), 
418                               0);
419         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
420                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ), 
421                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags), 
422                               0);
423
424
425         /* The 'autolock' flag doesn't stick - check this */
426         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
427                               (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK), 
428                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
429                               0);
430 #if 0
431         /* Removing the 'disabled' flag doesn't stick - check this */
432         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
433                               (base_acct_flags), 
434                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
435                               0);
436 #endif
437         /* The 'store plaintext' flag does stick */
438         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
439                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED), 
440                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags), 
441                               0);
442         /* The 'use DES' flag does stick */
443         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
444                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY), 
445                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags), 
446                               0);
447         /* The 'don't require kerberos pre-authentication flag does stick */
448         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
449                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH), 
450                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags), 
451                               0);
452         /* The 'no kerberos PAC required' flag sticks */
453         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
454                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD), 
455                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags), 
456                               0);
457
458         TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags, 
459                               (base_acct_flags | ACB_DISABLED), 
460                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
461                               SAMR_FIELD_ACCT_FLAGS);
462
463 #if 0
464         /* these fail with win2003 - it appears you can't set the primary gid?
465            the set succeeds, but the gid isn't changed. Very weird! */
466         TEST_USERINFO_INT(9, primary_gid,  1, primary_gid, 513);
467         TEST_USERINFO_INT(9, primary_gid,  3, primary_gid, 513);
468         TEST_USERINFO_INT(9, primary_gid,  5, primary_gid, 513);
469         TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
470 #endif
471
472         return ret;
473 }
474
475 /*
476   generate a random password for password change tests
477 */
478 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
479 {
480         size_t len = MAX(8, min_len) + (random() % 6);
481         char *s = generate_random_str(mem_ctx, len);
482         printf("Generated password '%s'\n", s);
483         return s;
484 }
485
486 /*
487   generate a random password for password change tests (fixed length)
488 */
489 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
490 {
491         char *s = generate_random_str(mem_ctx, len);
492         printf("Generated password '%s'\n", s);
493         return s;
494 }
495
496 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
497                              struct policy_handle *handle, char **password)
498 {
499         NTSTATUS status;
500         struct samr_SetUserInfo s;
501         union samr_UserInfo u;
502         BOOL ret = True;
503         DATA_BLOB session_key;
504         char *newpass;
505         struct samr_GetUserPwInfo pwp;
506         int policy_min_pw_len = 0;
507         pwp.in.user_handle = handle;
508
509         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
510         if (NT_STATUS_IS_OK(status)) {
511                 policy_min_pw_len = pwp.out.info.min_password_length;
512         }
513         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
514
515         s.in.user_handle = handle;
516         s.in.info = &u;
517         s.in.level = 24;
518
519         encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
520         /* w2k3 ignores this length */
521         u.info24.pw_len = strlen_m(newpass) * 2;
522
523         status = dcerpc_fetch_session_key(p, &session_key);
524         if (!NT_STATUS_IS_OK(status)) {
525                 printf("SetUserInfo level %u - no session key - %s\n",
526                        s.in.level, nt_errstr(status));
527                 return False;
528         }
529
530         arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
531
532         printf("Testing SetUserInfo level 24 (set password)\n");
533
534         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
535         if (!NT_STATUS_IS_OK(status)) {
536                 printf("SetUserInfo level %u failed - %s\n",
537                        s.in.level, nt_errstr(status));
538                 ret = False;
539         } else {
540                 *password = newpass;
541         }
542
543         return ret;
544 }
545
546
547 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
548                                 struct policy_handle *handle, uint32_t fields_present,
549                                 char **password)
550 {
551         NTSTATUS status;
552         struct samr_SetUserInfo s;
553         union samr_UserInfo u;
554         BOOL ret = True;
555         DATA_BLOB session_key;
556         char *newpass;
557         struct samr_GetUserPwInfo pwp;
558         int policy_min_pw_len = 0;
559         pwp.in.user_handle = handle;
560
561         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
562         if (NT_STATUS_IS_OK(status)) {
563                 policy_min_pw_len = pwp.out.info.min_password_length;
564         }
565         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
566
567         s.in.user_handle = handle;
568         s.in.info = &u;
569         s.in.level = 23;
570
571         ZERO_STRUCT(u);
572
573         u.info23.info.fields_present = fields_present;
574
575         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
576
577         status = dcerpc_fetch_session_key(p, &session_key);
578         if (!NT_STATUS_IS_OK(status)) {
579                 printf("SetUserInfo level %u - no session key - %s\n",
580                        s.in.level, nt_errstr(status));
581                 return False;
582         }
583
584         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
585
586         printf("Testing SetUserInfo level 23 (set password)\n");
587
588         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
589         if (!NT_STATUS_IS_OK(status)) {
590                 printf("SetUserInfo level %u failed - %s\n",
591                        s.in.level, nt_errstr(status));
592                 ret = False;
593         } else {
594                 *password = newpass;
595         }
596
597         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
598
599         status = dcerpc_fetch_session_key(p, &session_key);
600         if (!NT_STATUS_IS_OK(status)) {
601                 printf("SetUserInfo level %u - no session key - %s\n",
602                        s.in.level, nt_errstr(status));
603                 return False;
604         }
605
606         /* This should break the key nicely */
607         session_key.length--;
608         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
609
610         printf("Testing SetUserInfo level 23 (set password) with wrong password\n");
611
612         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
613         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
614                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
615                        s.in.level, nt_errstr(status));
616                 ret = False;
617         }
618
619         return ret;
620 }
621
622
623 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
624                                struct policy_handle *handle, bool makeshort, 
625                                char **password)
626 {
627         NTSTATUS status;
628         struct samr_SetUserInfo s;
629         union samr_UserInfo u;
630         BOOL ret = True;
631         DATA_BLOB session_key;
632         DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
633         uint8_t confounder[16];
634         char *newpass;
635         struct MD5Context ctx;
636         struct samr_GetUserPwInfo pwp;
637         int policy_min_pw_len = 0;
638         pwp.in.user_handle = handle;
639
640         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
641         if (NT_STATUS_IS_OK(status)) {
642                 policy_min_pw_len = pwp.out.info.min_password_length;
643         }
644         if (makeshort && policy_min_pw_len) {
645                 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len - 1);
646         } else {
647                 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
648         }
649
650         s.in.user_handle = handle;
651         s.in.info = &u;
652         s.in.level = 26;
653
654         encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
655         u.info26.pw_len = strlen(newpass);
656
657         status = dcerpc_fetch_session_key(p, &session_key);
658         if (!NT_STATUS_IS_OK(status)) {
659                 printf("SetUserInfo level %u - no session key - %s\n",
660                        s.in.level, nt_errstr(status));
661                 return False;
662         }
663
664         generate_random_buffer((uint8_t *)confounder, 16);
665
666         MD5Init(&ctx);
667         MD5Update(&ctx, confounder, 16);
668         MD5Update(&ctx, session_key.data, session_key.length);
669         MD5Final(confounded_session_key.data, &ctx);
670
671         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
672         memcpy(&u.info26.password.data[516], confounder, 16);
673
674         printf("Testing SetUserInfo level 26 (set password ex)\n");
675
676         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
677         if (!NT_STATUS_IS_OK(status)) {
678                 printf("SetUserInfo level %u failed - %s\n",
679                        s.in.level, nt_errstr(status));
680                 ret = False;
681         } else {
682                 *password = newpass;
683         }
684
685         /* This should break the key nicely */
686         confounded_session_key.data[0]++;
687
688         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
689         memcpy(&u.info26.password.data[516], confounder, 16);
690
691         printf("Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
692
693         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
694         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
695                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
696                        s.in.level, nt_errstr(status));
697                 ret = False;
698         } else {
699                 *password = newpass;
700         }
701
702         return ret;
703 }
704
705 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
706                                 struct policy_handle *handle, uint32_t fields_present,
707                                 char **password)
708 {
709         NTSTATUS status;
710         struct samr_SetUserInfo s;
711         union samr_UserInfo u;
712         BOOL ret = True;
713         DATA_BLOB session_key;
714         DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
715         struct MD5Context ctx;
716         uint8_t confounder[16];
717         char *newpass;
718         struct samr_GetUserPwInfo pwp;
719         int policy_min_pw_len = 0;
720         pwp.in.user_handle = handle;
721
722         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
723         if (NT_STATUS_IS_OK(status)) {
724                 policy_min_pw_len = pwp.out.info.min_password_length;
725         }
726         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
727
728         s.in.user_handle = handle;
729         s.in.info = &u;
730         s.in.level = 25;
731
732         ZERO_STRUCT(u);
733
734         u.info25.info.fields_present = fields_present;
735
736         encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
737
738         status = dcerpc_fetch_session_key(p, &session_key);
739         if (!NT_STATUS_IS_OK(status)) {
740                 printf("SetUserInfo level %u - no session key - %s\n",
741                        s.in.level, nt_errstr(status));
742                 return False;
743         }
744
745         generate_random_buffer((uint8_t *)confounder, 16);
746
747         MD5Init(&ctx);
748         MD5Update(&ctx, confounder, 16);
749         MD5Update(&ctx, session_key.data, session_key.length);
750         MD5Final(confounded_session_key.data, &ctx);
751
752         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
753         memcpy(&u.info25.password.data[516], confounder, 16);
754
755         printf("Testing SetUserInfo level 25 (set password ex)\n");
756
757         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
758         if (!NT_STATUS_IS_OK(status)) {
759                 printf("SetUserInfo level %u failed - %s\n",
760                        s.in.level, nt_errstr(status));
761                 ret = False;
762         } else {
763                 *password = newpass;
764         }
765
766         /* This should break the key nicely */
767         confounded_session_key.data[0]++;
768
769         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
770         memcpy(&u.info25.password.data[516], confounder, 16);
771
772         printf("Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
773
774         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
775         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
776                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
777                        s.in.level, nt_errstr(status));
778                 ret = False;
779         }
780
781         return ret;
782 }
783
784 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
785                                struct policy_handle *handle)
786 {
787         NTSTATUS status;
788         struct samr_SetAliasInfo r;
789         struct samr_QueryAliasInfo q;
790         uint16_t levels[] = {2, 3};
791         int i;
792         BOOL ret = True;
793
794         /* Ignoring switch level 1, as that includes the number of members for the alias
795          * and setting this to a wrong value might have negative consequences
796          */
797
798         for (i=0;i<ARRAY_SIZE(levels);i++) {
799                 printf("Testing SetAliasInfo level %u\n", levels[i]);
800
801                 r.in.alias_handle = handle;
802                 r.in.level = levels[i];
803                 r.in.info  = talloc(mem_ctx, union samr_AliasInfo);
804                 switch (r.in.level) {
805                     case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
806                     case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
807                                 "Test Description, should test I18N as well"); break;
808                 }
809
810                 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
811                 if (!NT_STATUS_IS_OK(status)) {
812                         printf("SetAliasInfo level %u failed - %s\n",
813                                levels[i], nt_errstr(status));
814                         ret = False;
815                 }
816
817                 q.in.alias_handle = handle;
818                 q.in.level = levels[i];
819
820                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
821                 if (!NT_STATUS_IS_OK(status)) {
822                         printf("QueryAliasInfo level %u failed - %s\n",
823                                levels[i], nt_errstr(status));
824                         ret = False;
825                 }
826         }
827
828         return ret;
829 }
830
831 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
832                                   struct policy_handle *user_handle)
833 {
834         struct samr_GetGroupsForUser r;
835         NTSTATUS status;
836         BOOL ret = True;
837
838         printf("testing GetGroupsForUser\n");
839
840         r.in.user_handle = user_handle;
841
842         status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
843         if (!NT_STATUS_IS_OK(status)) {
844                 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
845                 ret = False;
846         }
847
848         return ret;
849
850 }
851
852 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
853                               struct lsa_String *domain_name)
854 {
855         NTSTATUS status;
856         struct samr_GetDomPwInfo r;
857         BOOL ret = True;
858
859         r.in.domain_name = domain_name;
860         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
861
862         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
863         if (!NT_STATUS_IS_OK(status)) {
864                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
865                 ret = False;
866         }
867
868         r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
869         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
870
871         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
872         if (!NT_STATUS_IS_OK(status)) {
873                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
874                 ret = False;
875         }
876
877         r.in.domain_name->string = "\\\\__NONAME__";
878         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
879
880         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
881         if (!NT_STATUS_IS_OK(status)) {
882                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
883                 ret = False;
884         }
885
886         r.in.domain_name->string = "\\\\Builtin";
887         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
888
889         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
890         if (!NT_STATUS_IS_OK(status)) {
891                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
892                 ret = False;
893         }
894
895
896         return ret;
897 }
898
899 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
900                                struct policy_handle *handle)
901 {
902         NTSTATUS status;
903         struct samr_GetUserPwInfo r;
904         BOOL ret = True;
905
906         printf("Testing GetUserPwInfo\n");
907
908         r.in.user_handle = handle;
909
910         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
911         if (!NT_STATUS_IS_OK(status)) {
912                 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
913                 ret = False;
914         }
915
916         return ret;
917 }
918
919 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
920                                 struct policy_handle *domain_handle, const char *name,
921                                 uint32_t *rid)
922 {
923         NTSTATUS status;
924         struct samr_LookupNames n;
925         struct lsa_String sname[2];
926
927         init_lsa_String(&sname[0], name);
928
929         n.in.domain_handle = domain_handle;
930         n.in.num_names = 1;
931         n.in.names = sname;
932         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
933         if (NT_STATUS_IS_OK(status)) {
934                 *rid = n.out.rids.ids[0];
935         } else {
936                 return status;
937         }
938
939         init_lsa_String(&sname[1], "xxNONAMExx");
940         n.in.num_names = 2;
941         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
942         if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
943                 printf("LookupNames[2] failed - %s\n", nt_errstr(status));              
944                 if (NT_STATUS_IS_OK(status)) {
945                         return NT_STATUS_UNSUCCESSFUL;
946                 }
947                 return status;
948         }
949
950         n.in.num_names = 0;
951         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
952         if (!NT_STATUS_IS_OK(status)) {
953                 printf("LookupNames[0] failed - %s\n", nt_errstr(status));              
954                 return status;
955         }
956
957         init_lsa_String(&sname[0], "xxNONAMExx");
958         n.in.num_names = 1;
959         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
960         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
961                 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));             
962                 if (NT_STATUS_IS_OK(status)) {
963                         return NT_STATUS_UNSUCCESSFUL;
964                 }
965                 return status;
966         }
967
968         init_lsa_String(&sname[0], "xxNONAMExx");
969         init_lsa_String(&sname[1], "xxNONAME2xx");
970         n.in.num_names = 2;
971         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
972         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
973                 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));            
974                 if (NT_STATUS_IS_OK(status)) {
975                         return NT_STATUS_UNSUCCESSFUL;
976                 }
977                 return status;
978         }
979
980         return NT_STATUS_OK;
981 }
982
983 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
984                                      struct policy_handle *domain_handle,
985                                      const char *name, struct policy_handle *user_handle)
986 {
987         NTSTATUS status;
988         struct samr_OpenUser r;
989         uint32_t rid;
990
991         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
992         if (!NT_STATUS_IS_OK(status)) {
993                 return status;
994         }
995
996         r.in.domain_handle = domain_handle;
997         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
998         r.in.rid = rid;
999         r.out.user_handle = user_handle;
1000         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1001         if (!NT_STATUS_IS_OK(status)) {
1002                 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1003         }
1004
1005         return status;
1006 }
1007
1008 #if 0
1009 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1010                                    struct policy_handle *handle)
1011 {
1012         NTSTATUS status;
1013         struct samr_ChangePasswordUser r;
1014         BOOL ret = True;
1015         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1016         struct policy_handle user_handle;
1017         char *oldpass = "test";
1018         char *newpass = "test2";
1019         uint8_t old_nt_hash[16], new_nt_hash[16];
1020         uint8_t old_lm_hash[16], new_lm_hash[16];
1021
1022         status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1023         if (!NT_STATUS_IS_OK(status)) {
1024                 return False;
1025         }
1026
1027         printf("Testing ChangePasswordUser for user 'testuser'\n");
1028
1029         printf("old password: %s\n", oldpass);
1030         printf("new password: %s\n", newpass);
1031
1032         E_md4hash(oldpass, old_nt_hash);
1033         E_md4hash(newpass, new_nt_hash);
1034         E_deshash(oldpass, old_lm_hash);
1035         E_deshash(newpass, new_lm_hash);
1036
1037         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1038         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1039         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1040         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1041         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1042         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1043
1044         r.in.handle = &user_handle;
1045         r.in.lm_present = 1;
1046         r.in.old_lm_crypted = &hash1;
1047         r.in.new_lm_crypted = &hash2;
1048         r.in.nt_present = 1;
1049         r.in.old_nt_crypted = &hash3;
1050         r.in.new_nt_crypted = &hash4;
1051         r.in.cross1_present = 1;
1052         r.in.nt_cross = &hash5;
1053         r.in.cross2_present = 1;
1054         r.in.lm_cross = &hash6;
1055
1056         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1057         if (!NT_STATUS_IS_OK(status)) {
1058                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1059                 ret = False;
1060         }
1061
1062         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1063                 ret = False;
1064         }
1065
1066         return ret;
1067 }
1068 #endif
1069
1070 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1071                                     const char *acct_name, 
1072                                     struct policy_handle *handle, char **password)
1073 {
1074         NTSTATUS status;
1075         struct samr_ChangePasswordUser r;
1076         BOOL ret = True;
1077         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1078         struct policy_handle user_handle;
1079         char *oldpass;
1080         uint8_t old_nt_hash[16], new_nt_hash[16];
1081         uint8_t old_lm_hash[16], new_lm_hash[16];
1082         BOOL changed = True;
1083
1084         char *newpass;
1085         struct samr_GetUserPwInfo pwp;
1086         int policy_min_pw_len = 0;
1087
1088         status = test_OpenUser_byname(p, mem_ctx, handle, acct_name, &user_handle);
1089         if (!NT_STATUS_IS_OK(status)) {
1090                 return False;
1091         }
1092         pwp.in.user_handle = &user_handle;
1093
1094         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
1095         if (NT_STATUS_IS_OK(status)) {
1096                 policy_min_pw_len = pwp.out.info.min_password_length;
1097         }
1098         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1099
1100         printf("Testing ChangePasswordUser\n");
1101
1102         if (!*password) {
1103                 printf("Failing ChangePasswordUser as old password was NULL.  Previous test failed?\n");
1104                 return False;
1105         }
1106
1107         oldpass = *password;
1108
1109         E_md4hash(oldpass, old_nt_hash);
1110         E_md4hash(newpass, new_nt_hash);
1111         E_deshash(oldpass, old_lm_hash);
1112         E_deshash(newpass, new_lm_hash);
1113
1114         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1115         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1116         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1117         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1118         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1119         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1120
1121         r.in.user_handle = &user_handle;
1122         r.in.lm_present = 1;
1123         /* Break the LM hash */
1124         hash1.hash[0]++;
1125         r.in.old_lm_crypted = &hash1;
1126         r.in.new_lm_crypted = &hash2;
1127         r.in.nt_present = 1;
1128         r.in.old_nt_crypted = &hash3;
1129         r.in.new_nt_crypted = &hash4;
1130         r.in.cross1_present = 1;
1131         r.in.nt_cross = &hash5;
1132         r.in.cross2_present = 1;
1133         r.in.lm_cross = &hash6;
1134
1135         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1136         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1137                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash, got %s\n", nt_errstr(status));
1138                 ret = False;
1139         }
1140
1141         /* Unbreak the LM hash */
1142         hash1.hash[0]--;
1143
1144         r.in.user_handle = &user_handle;
1145         r.in.lm_present = 1;
1146         r.in.old_lm_crypted = &hash1;
1147         r.in.new_lm_crypted = &hash2;
1148         /* Break the NT hash */
1149         hash3.hash[0]--;
1150         r.in.nt_present = 1;
1151         r.in.old_nt_crypted = &hash3;
1152         r.in.new_nt_crypted = &hash4;
1153         r.in.cross1_present = 1;
1154         r.in.nt_cross = &hash5;
1155         r.in.cross2_present = 1;
1156         r.in.lm_cross = &hash6;
1157
1158         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1159         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1160                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash, got %s\n", nt_errstr(status));
1161                 ret = False;
1162         }
1163
1164         /* Unbreak the NT hash */
1165         hash3.hash[0]--;
1166
1167         r.in.user_handle = &user_handle;
1168         r.in.lm_present = 1;
1169         r.in.old_lm_crypted = &hash1;
1170         r.in.new_lm_crypted = &hash2;
1171         r.in.nt_present = 1;
1172         r.in.old_nt_crypted = &hash3;
1173         r.in.new_nt_crypted = &hash4;
1174         r.in.cross1_present = 1;
1175         r.in.nt_cross = &hash5;
1176         r.in.cross2_present = 1;
1177         /* Break the LM cross */
1178         hash6.hash[0]++;
1179         r.in.lm_cross = &hash6;
1180
1181         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1182         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1183                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1184                 ret = False;
1185         }
1186
1187         /* Unbreak the LM cross */
1188         hash6.hash[0]--;
1189
1190         r.in.user_handle = &user_handle;
1191         r.in.lm_present = 1;
1192         r.in.old_lm_crypted = &hash1;
1193         r.in.new_lm_crypted = &hash2;
1194         r.in.nt_present = 1;
1195         r.in.old_nt_crypted = &hash3;
1196         r.in.new_nt_crypted = &hash4;
1197         r.in.cross1_present = 1;
1198         /* Break the NT cross */
1199         hash5.hash[0]++;
1200         r.in.nt_cross = &hash5;
1201         r.in.cross2_present = 1;
1202         r.in.lm_cross = &hash6;
1203
1204         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1205         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1206                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1207                 ret = False;
1208         }
1209
1210         /* Unbreak the NT cross */
1211         hash5.hash[0]--;
1212
1213
1214         /* Reset the hashes to not broken values */
1215         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1216         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1217         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1218         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1219         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1220         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1221
1222         r.in.user_handle = &user_handle;
1223         r.in.lm_present = 1;
1224         r.in.old_lm_crypted = &hash1;
1225         r.in.new_lm_crypted = &hash2;
1226         r.in.nt_present = 1;
1227         r.in.old_nt_crypted = &hash3;
1228         r.in.new_nt_crypted = &hash4;
1229         r.in.cross1_present = 1;
1230         r.in.nt_cross = &hash5;
1231         r.in.cross2_present = 0;
1232         r.in.lm_cross = NULL;
1233
1234         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1235         if (NT_STATUS_IS_OK(status)) {
1236                 changed = True;
1237                 *password = newpass;
1238         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1239                 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1240                 ret = False;
1241         }
1242
1243         oldpass = newpass;
1244         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1245
1246         E_md4hash(oldpass, old_nt_hash);
1247         E_md4hash(newpass, new_nt_hash);
1248         E_deshash(oldpass, old_lm_hash);
1249         E_deshash(newpass, new_lm_hash);
1250
1251
1252         /* Reset the hashes to not broken values */
1253         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1254         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1255         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1256         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1257         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1258         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1259
1260         r.in.user_handle = &user_handle;
1261         r.in.lm_present = 1;
1262         r.in.old_lm_crypted = &hash1;
1263         r.in.new_lm_crypted = &hash2;
1264         r.in.nt_present = 1;
1265         r.in.old_nt_crypted = &hash3;
1266         r.in.new_nt_crypted = &hash4;
1267         r.in.cross1_present = 0;
1268         r.in.nt_cross = NULL;
1269         r.in.cross2_present = 1;
1270         r.in.lm_cross = &hash6;
1271
1272         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1273         if (NT_STATUS_IS_OK(status)) {
1274                 changed = True;
1275                 *password = newpass;
1276         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1277                 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1278                 ret = False;
1279         }
1280
1281         oldpass = newpass;
1282         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1283
1284         E_md4hash(oldpass, old_nt_hash);
1285         E_md4hash(newpass, new_nt_hash);
1286         E_deshash(oldpass, old_lm_hash);
1287         E_deshash(newpass, new_lm_hash);
1288
1289
1290         /* Reset the hashes to not broken values */
1291         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1292         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1293         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1294         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1295         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1296         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1297
1298         r.in.user_handle = &user_handle;
1299         r.in.lm_present = 1;
1300         r.in.old_lm_crypted = &hash1;
1301         r.in.new_lm_crypted = &hash2;
1302         r.in.nt_present = 1;
1303         r.in.old_nt_crypted = &hash3;
1304         r.in.new_nt_crypted = &hash4;
1305         r.in.cross1_present = 1;
1306         r.in.nt_cross = &hash5;
1307         r.in.cross2_present = 1;
1308         r.in.lm_cross = &hash6;
1309
1310         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1311         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1312                 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1313         } else  if (!NT_STATUS_IS_OK(status)) {
1314                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1315                 ret = False;
1316         } else {
1317                 changed = True;
1318                 *password = newpass;
1319         }
1320
1321         r.in.user_handle = &user_handle;
1322         r.in.lm_present = 1;
1323         r.in.old_lm_crypted = &hash1;
1324         r.in.new_lm_crypted = &hash2;
1325         r.in.nt_present = 1;
1326         r.in.old_nt_crypted = &hash3;
1327         r.in.new_nt_crypted = &hash4;
1328         r.in.cross1_present = 1;
1329         r.in.nt_cross = &hash5;
1330         r.in.cross2_present = 1;
1331         r.in.lm_cross = &hash6;
1332
1333         if (changed) {
1334                 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1335                 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1336                         printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1337                 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1338                         printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1339                         ret = False;
1340                 }
1341         }
1342
1343         
1344         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1345                 ret = False;
1346         }
1347
1348         return ret;
1349 }
1350
1351
1352 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1353                                         const char *acct_name,
1354                                         struct policy_handle *handle, char **password)
1355 {
1356         NTSTATUS status;
1357         struct samr_OemChangePasswordUser2 r;
1358         BOOL ret = True;
1359         struct samr_Password lm_verifier;
1360         struct samr_CryptPassword lm_pass;
1361         struct lsa_AsciiString server, account, account_bad;
1362         char *oldpass;
1363         char *newpass;
1364         uint8_t old_lm_hash[16], new_lm_hash[16];
1365
1366         struct samr_GetDomPwInfo dom_pw_info;
1367         int policy_min_pw_len = 0;
1368
1369         struct lsa_String domain_name;
1370
1371         domain_name.string = "";
1372         dom_pw_info.in.domain_name = &domain_name;
1373
1374         printf("Testing OemChangePasswordUser2\n");
1375
1376         if (!*password) {
1377                 printf("Failing OemChangePasswordUser2 as old password was NULL.  Previous test failed?\n");
1378                 return False;
1379         }
1380
1381         oldpass = *password;
1382
1383         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1384         if (NT_STATUS_IS_OK(status)) {
1385                 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1386         }
1387
1388         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1389
1390         server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1391         account.string = acct_name;
1392
1393         E_deshash(oldpass, old_lm_hash);
1394         E_deshash(newpass, new_lm_hash);
1395
1396         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1397         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1398         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1399
1400         r.in.server = &server;
1401         r.in.account = &account;
1402         r.in.password = &lm_pass;
1403         r.in.hash = &lm_verifier;
1404
1405         /* Break the verification */
1406         lm_verifier.hash[0]++;
1407
1408         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1409
1410         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1411             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1412                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1413                         nt_errstr(status));
1414                 ret = False;
1415         }
1416
1417         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1418         /* Break the old password */
1419         old_lm_hash[0]++;
1420         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1421         /* unbreak it for the next operation */
1422         old_lm_hash[0]--;
1423         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1424
1425         r.in.server = &server;
1426         r.in.account = &account;
1427         r.in.password = &lm_pass;
1428         r.in.hash = &lm_verifier;
1429
1430         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1431
1432         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1433             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1434                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1435                         nt_errstr(status));
1436                 ret = False;
1437         }
1438
1439         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1440         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1441
1442         r.in.server = &server;
1443         r.in.account = &account;
1444         r.in.password = &lm_pass;
1445         r.in.hash = NULL;
1446
1447         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1448
1449         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1450             && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1451                 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1452                         nt_errstr(status));
1453                 ret = False;
1454         }
1455
1456         /* This shouldn't be a valid name */
1457         account_bad.string = TEST_ACCOUNT_NAME "XX";
1458         r.in.account = &account_bad;
1459
1460         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1461
1462         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1463                 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1464                         nt_errstr(status));
1465                 ret = False;
1466         }
1467
1468         /* This shouldn't be a valid name */
1469         account_bad.string = TEST_ACCOUNT_NAME "XX";
1470         r.in.account = &account_bad;
1471         r.in.password = &lm_pass;
1472         r.in.hash = &lm_verifier;
1473
1474         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1475
1476         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1477                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1478                         nt_errstr(status));
1479                 ret = False;
1480         }
1481
1482         /* This shouldn't be a valid name */
1483         account_bad.string = TEST_ACCOUNT_NAME "XX";
1484         r.in.account = &account_bad;
1485         r.in.password = NULL;
1486         r.in.hash = &lm_verifier;
1487
1488         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1489
1490         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1491                 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1492                         nt_errstr(status));
1493                 ret = False;
1494         }
1495
1496         E_deshash(oldpass, old_lm_hash);
1497         E_deshash(newpass, new_lm_hash);
1498
1499         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1500         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1501         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1502
1503         r.in.server = &server;
1504         r.in.account = &account;
1505         r.in.password = &lm_pass;
1506         r.in.hash = &lm_verifier;
1507
1508         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1509         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1510                 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1511         } else if (!NT_STATUS_IS_OK(status)) {
1512                 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1513                 ret = False;
1514         } else {
1515                 *password = newpass;
1516         }
1517
1518         return ret;
1519 }
1520
1521
1522 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1523                                      const char *acct_name,
1524                                      char **password,
1525                                      char *newpass, bool allow_password_restriction)
1526 {
1527         NTSTATUS status;
1528         struct samr_ChangePasswordUser2 r;
1529         BOOL ret = True;
1530         struct lsa_String server, account;
1531         struct samr_CryptPassword nt_pass, lm_pass;
1532         struct samr_Password nt_verifier, lm_verifier;
1533         char *oldpass;
1534         uint8_t old_nt_hash[16], new_nt_hash[16];
1535         uint8_t old_lm_hash[16], new_lm_hash[16];
1536
1537         struct samr_GetDomPwInfo dom_pw_info;
1538
1539         struct lsa_String domain_name;
1540
1541         domain_name.string = "";
1542         dom_pw_info.in.domain_name = &domain_name;
1543
1544         printf("Testing ChangePasswordUser2 on %s\n", acct_name);
1545
1546         if (!*password) {
1547                 printf("Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?\n");
1548                 return False;
1549         }
1550         oldpass = *password;
1551
1552         if (!newpass) {
1553                 int policy_min_pw_len = 0;
1554                 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1555                 if (NT_STATUS_IS_OK(status)) {
1556                         policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1557                 }
1558
1559                 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1560         } 
1561
1562         server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1563         init_lsa_String(&account, acct_name);
1564
1565         E_md4hash(oldpass, old_nt_hash);
1566         E_md4hash(newpass, new_nt_hash);
1567
1568         E_deshash(oldpass, old_lm_hash);
1569         E_deshash(newpass, new_lm_hash);
1570
1571         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1572         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1573         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1574
1575         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1576         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1577         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1578
1579         r.in.server = &server;
1580         r.in.account = &account;
1581         r.in.nt_password = &nt_pass;
1582         r.in.nt_verifier = &nt_verifier;
1583         r.in.lm_change = 1;
1584         r.in.lm_password = &lm_pass;
1585         r.in.lm_verifier = &lm_verifier;
1586
1587         status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1588         if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1589                 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1590         } else if (!NT_STATUS_IS_OK(status)) {
1591                 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1592                 ret = False;
1593         } else {
1594                 *password = newpass;
1595         }
1596
1597         return ret;
1598 }
1599
1600
1601 BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1602                               const char *account_string,
1603                               int policy_min_pw_len,
1604                               char **password,
1605                               const char *newpass,
1606                               NTTIME last_password_change,
1607                               BOOL handle_reject_reason)
1608 {
1609         NTSTATUS status;
1610         struct samr_ChangePasswordUser3 r;
1611         BOOL ret = True;
1612         struct lsa_String server, account, account_bad;
1613         struct samr_CryptPassword nt_pass, lm_pass;
1614         struct samr_Password nt_verifier, lm_verifier;
1615         char *oldpass;
1616         uint8_t old_nt_hash[16], new_nt_hash[16];
1617         uint8_t old_lm_hash[16], new_lm_hash[16];
1618         NTTIME t;
1619
1620         printf("Testing ChangePasswordUser3\n");
1621
1622         if (newpass == NULL) {
1623                 do {
1624                         if (policy_min_pw_len == 0) {
1625                                 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1626                         } else {
1627                                 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len);
1628                         }
1629                 } while (check_password_quality(newpass) == False);
1630         } else {
1631                 printf("Using password '%s'\n", newpass);
1632         }
1633
1634         if (!*password) {
1635                 printf("Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?\n");
1636                 return False;
1637         }
1638
1639         oldpass = *password;
1640         server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1641         init_lsa_String(&account, account_string);
1642
1643         E_md4hash(oldpass, old_nt_hash);
1644         E_md4hash(newpass, new_nt_hash);
1645
1646         E_deshash(oldpass, old_lm_hash);
1647         E_deshash(newpass, new_lm_hash);
1648
1649         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1650         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1651         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1652
1653         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1654         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1655         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1656         
1657         /* Break the verification */
1658         nt_verifier.hash[0]++;
1659
1660         r.in.server = &server;
1661         r.in.account = &account;
1662         r.in.nt_password = &nt_pass;
1663         r.in.nt_verifier = &nt_verifier;
1664         r.in.lm_change = 1;
1665         r.in.lm_password = &lm_pass;
1666         r.in.lm_verifier = &lm_verifier;
1667         r.in.password3 = NULL;
1668
1669         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1670         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1671             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1672                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1673                         nt_errstr(status));
1674                 ret = False;
1675         }
1676         
1677         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1678         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1679         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1680
1681         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1682         /* Break the NT hash */
1683         old_nt_hash[0]++;
1684         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1685         /* Unbreak it again */
1686         old_nt_hash[0]--;
1687         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1688         
1689         r.in.server = &server;
1690         r.in.account = &account;
1691         r.in.nt_password = &nt_pass;
1692         r.in.nt_verifier = &nt_verifier;
1693         r.in.lm_change = 1;
1694         r.in.lm_password = &lm_pass;
1695         r.in.lm_verifier = &lm_verifier;
1696         r.in.password3 = NULL;
1697
1698         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1699         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1700             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1701                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1702                         nt_errstr(status));
1703                 ret = False;
1704         }
1705         
1706         /* This shouldn't be a valid name */
1707         init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1708
1709         r.in.account = &account_bad;
1710         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1711         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1712                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1713                         nt_errstr(status));
1714                 ret = False;
1715         }
1716
1717         E_md4hash(oldpass, old_nt_hash);
1718         E_md4hash(newpass, new_nt_hash);
1719
1720         E_deshash(oldpass, old_lm_hash);
1721         E_deshash(newpass, new_lm_hash);
1722
1723         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1724         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1725         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1726
1727         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1728         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1729         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1730
1731         r.in.server = &server;
1732         r.in.account = &account;
1733         r.in.nt_password = &nt_pass;
1734         r.in.nt_verifier = &nt_verifier;
1735         r.in.lm_change = 1;
1736         r.in.lm_password = &lm_pass;
1737         r.in.lm_verifier = &lm_verifier;
1738         r.in.password3 = NULL;
1739
1740         unix_to_nt_time(&t, time(NULL));
1741
1742         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1743
1744         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1745             && r.out.dominfo
1746             && r.out.reject
1747             && handle_reject_reason
1748             && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) {
1749                 if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1750
1751                         if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
1752                                 printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
1753                                         SAMR_REJECT_OTHER, r.out.reject->reason);
1754                                 return False;
1755                         }
1756                 }
1757
1758                 /* We tested the order of precendence which is as follows:
1759                 
1760                 * pwd min_age 
1761                 * pwd length
1762                 * pwd complexity
1763                 * pwd history
1764
1765                 Guenther */
1766
1767                 if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) && 
1768                            (last_password_change + r.out.dominfo->min_password_age > t)) {
1769
1770                         if (r.out.reject->reason != SAMR_REJECT_OTHER) {
1771                                 printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
1772                                         SAMR_REJECT_OTHER, r.out.reject->reason);
1773                                 return False;
1774                         }
1775
1776                 } else if ((r.out.dominfo->min_password_length > 0) && 
1777                            (strlen(newpass) < r.out.dominfo->min_password_length)) {
1778
1779                         if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
1780                                 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n", 
1781                                         SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
1782                                 return False;
1783                         }
1784
1785                 } else if ((r.out.dominfo->password_history_length > 0) && 
1786                             strequal(oldpass, newpass)) {
1787
1788                         if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
1789                                 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n", 
1790                                         SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
1791                                 return False;
1792                         }
1793                 } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1794
1795                         if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
1796                                 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n", 
1797                                         SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
1798                                 return False;
1799                         }
1800
1801                 }
1802
1803                 if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
1804                         /* retry with adjusted size */
1805                         return test_ChangePasswordUser3(p, mem_ctx, account_string, 
1806                                                         r.out.dominfo->min_password_length, 
1807                                                         password, NULL, 0, False); 
1808
1809                 }
1810
1811         } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1812                 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1813                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
1814                                SAMR_REJECT_OTHER, r.out.reject->reason);
1815                         return False;
1816                 }
1817                 /* Perhaps the server has a 'min password age' set? */
1818
1819         } else if (!NT_STATUS_IS_OK(status)) {
1820                 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1821                 ret = False;
1822         } else {
1823                 *password = talloc_strdup(mem_ctx, newpass);
1824         }
1825
1826         return ret;
1827 }
1828
1829
1830 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1831                                   struct policy_handle *alias_handle)
1832 {
1833         struct samr_GetMembersInAlias r;
1834         struct lsa_SidArray sids;
1835         NTSTATUS status;
1836         BOOL     ret = True;
1837
1838         printf("Testing GetMembersInAlias\n");
1839
1840         r.in.alias_handle = alias_handle;
1841         r.out.sids = &sids;
1842
1843         status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1844         if (!NT_STATUS_IS_OK(status)) {
1845                 printf("GetMembersInAlias failed - %s\n",
1846                        nt_errstr(status));
1847                 ret = False;
1848         }
1849
1850         return ret;
1851 }
1852
1853 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1854                                   struct policy_handle *alias_handle,
1855                                   const struct dom_sid *domain_sid)
1856 {
1857         struct samr_AddAliasMember r;
1858         struct samr_DeleteAliasMember d;
1859         NTSTATUS status;
1860         BOOL ret = True;
1861         struct dom_sid *sid;
1862
1863         sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1864
1865         printf("testing AddAliasMember\n");
1866         r.in.alias_handle = alias_handle;
1867         r.in.sid = sid;
1868
1869         status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1870         if (!NT_STATUS_IS_OK(status)) {
1871                 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1872                 ret = False;
1873         }
1874
1875         d.in.alias_handle = alias_handle;
1876         d.in.sid = sid;
1877
1878         status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1879         if (!NT_STATUS_IS_OK(status)) {
1880                 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1881                 ret = False;
1882         }
1883
1884         return ret;
1885 }
1886
1887 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1888                                            struct policy_handle *alias_handle)
1889 {
1890         struct samr_AddMultipleMembersToAlias a;
1891         struct samr_RemoveMultipleMembersFromAlias r;
1892         NTSTATUS status;
1893         BOOL ret = True;
1894         struct lsa_SidArray sids;
1895
1896         printf("testing AddMultipleMembersToAlias\n");
1897         a.in.alias_handle = alias_handle;
1898         a.in.sids = &sids;
1899
1900         sids.num_sids = 3;
1901         sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1902
1903         sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1904         sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1905         sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1906
1907         status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1908         if (!NT_STATUS_IS_OK(status)) {
1909                 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1910                 ret = False;
1911         }
1912
1913
1914         printf("testing RemoveMultipleMembersFromAlias\n");
1915         r.in.alias_handle = alias_handle;
1916         r.in.sids = &sids;
1917
1918         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1919         if (!NT_STATUS_IS_OK(status)) {
1920                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1921                 ret = False;
1922         }
1923
1924         /* strange! removing twice doesn't give any error */
1925         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1926         if (!NT_STATUS_IS_OK(status)) {
1927                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1928                 ret = False;
1929         }
1930
1931         /* but removing an alias that isn't there does */
1932         sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1933
1934         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1935         if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1936                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1937                 ret = False;
1938         }
1939
1940         return ret;
1941 }
1942
1943 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1944                                             struct policy_handle *user_handle)
1945 {
1946         struct samr_TestPrivateFunctionsUser r;
1947         NTSTATUS status;
1948         BOOL ret = True;
1949
1950         printf("Testing TestPrivateFunctionsUser\n");
1951
1952         r.in.user_handle = user_handle;
1953
1954         status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1955         if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1956                 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1957                 ret = False;
1958         }
1959
1960         return ret;
1961 }
1962
1963
1964 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1965                           struct policy_handle *user_handle, 
1966                           struct policy_handle *domain_handle, 
1967                           uint32_t base_acct_flags, 
1968                           const char *base_acct_name, enum torture_samr_choice which_ops)
1969 {
1970         TALLOC_CTX *user_ctx;
1971         char *password = NULL;
1972
1973         BOOL ret = True;
1974         int i;
1975         const uint32_t password_fields[] = {
1976                 SAMR_FIELD_PASSWORD,
1977                 SAMR_FIELD_PASSWORD2,
1978                 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1979                 0
1980         };
1981         
1982         user_ctx = talloc_named(mem_ctx, 0, "test_user_ops per-user context");
1983         switch (which_ops) {
1984         case TORTURE_SAMR_USER_ATTRIBUTES:
1985                 if (!test_QuerySecurity(p, user_ctx, user_handle)) {
1986                         ret = False;
1987                 }
1988
1989                 if (!test_QueryUserInfo(p, user_ctx, user_handle)) {
1990                         ret = False;
1991                 }
1992
1993                 if (!test_QueryUserInfo2(p, user_ctx, user_handle)) {
1994                         ret = False;
1995                 }
1996
1997                 if (!test_SetUserInfo(p, user_ctx, user_handle, base_acct_flags,
1998                                       base_acct_name)) {
1999                         ret = False;
2000                 }       
2001
2002                 if (!test_GetUserPwInfo(p, user_ctx, user_handle)) {
2003                         ret = False;
2004                 }
2005
2006                 if (!test_TestPrivateFunctionsUser(p, user_ctx, user_handle)) {
2007                         ret = False;
2008                 }
2009
2010                 if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
2011                         ret = False;
2012                 }
2013                 break;
2014         case TORTURE_SAMR_PASSWORDS:
2015                 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2016                         char simple_pass[9];
2017                         char *v = generate_random_str(mem_ctx, 1);
2018                         
2019                         ZERO_STRUCT(simple_pass);
2020                         memset(simple_pass, *v, sizeof(simple_pass) - 1);
2021
2022                         printf("Testing machine account password policy rules\n");
2023
2024                         /* Workstation trust accounts don't seem to need to honour password quality policy */
2025                         if (!test_SetUserPassEx(p, user_ctx, user_handle, true, &password)) {
2026                                 ret = False;
2027                         }
2028
2029                         if (!test_ChangePasswordUser2(p, user_ctx, base_acct_name, &password, simple_pass, False)) {
2030                                 ret = False;
2031                         }
2032
2033                         /* reset again, to allow another 'user' password change */
2034                         if (!test_SetUserPassEx(p, user_ctx, user_handle, true, &password)) {
2035                                 ret = False;
2036                         }
2037
2038                         /* Try a 'short' password */
2039                         if (!test_ChangePasswordUser2(p, user_ctx, base_acct_name, &password, samr_rand_pass(mem_ctx, 4), False)) {
2040                                 ret = False;
2041                         }
2042                         
2043                 }
2044                 
2045                 for (i = 0; password_fields[i]; i++) {
2046                         if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
2047                                 ret = False;
2048                         }       
2049                 
2050                         /* check it was set right */
2051                         if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password, NULL, 0, False)) {
2052                                 ret = False;
2053                         }
2054                 }               
2055
2056                 for (i = 0; password_fields[i]; i++) {
2057                         if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
2058                                 ret = False;
2059                         }       
2060                 
2061                         /* check it was set right */
2062                         if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password, NULL, 0, False)) {
2063                                 ret = False;
2064                         }
2065                 }               
2066
2067                 if (!test_SetUserPassEx(p, user_ctx, user_handle, false, &password)) {
2068                         ret = False;
2069                 }       
2070
2071                 if (!test_ChangePassword(p, user_ctx, base_acct_name, domain_handle, &password)) {
2072                         ret = False;
2073                 }       
2074
2075                 break;
2076         case TORTURE_SAMR_OTHER:
2077                 /* We just need the account to exist */
2078                 break;
2079         }
2080         talloc_free(user_ctx);
2081         return ret;
2082 }
2083
2084 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2085                            struct policy_handle *alias_handle,
2086                            const struct dom_sid *domain_sid)
2087 {
2088         BOOL ret = True;
2089
2090         if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
2091                 ret = False;
2092         }
2093
2094         if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
2095                 ret = False;
2096         }
2097
2098         if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
2099                 ret = False;
2100         }
2101
2102         if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
2103                 ret = False;
2104         }
2105
2106         if (lp_parm_bool(-1, "torture", "samba4", False)) {
2107                 printf("skipping MultipleMembers Alias tests against Samba4\n");
2108                 return ret;
2109         }
2110
2111         if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
2112                 ret = False;
2113         }
2114
2115         return ret;
2116 }
2117
2118
2119 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2120                                      struct policy_handle *user_handle)
2121 {
2122         struct samr_DeleteUser d;
2123         NTSTATUS status;
2124         BOOL ret = True;
2125         printf("Testing DeleteUser\n");
2126
2127         d.in.user_handle = user_handle;
2128         d.out.user_handle = user_handle;
2129
2130         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2131         if (!NT_STATUS_IS_OK(status)) {
2132                 printf("DeleteUser failed - %s\n", nt_errstr(status));
2133                 ret = False;
2134         }
2135
2136         return ret;
2137 }
2138
2139 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2140                             struct policy_handle *handle, const char *name)
2141 {
2142         NTSTATUS status;
2143         struct samr_DeleteUser d;
2144         struct policy_handle user_handle;
2145         uint32_t rid;
2146
2147         status = test_LookupName(p, mem_ctx, handle, name, &rid);
2148         if (!NT_STATUS_IS_OK(status)) {
2149                 goto failed;
2150         }
2151
2152         status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2153         if (!NT_STATUS_IS_OK(status)) {
2154                 goto failed;
2155         }
2156
2157         d.in.user_handle = &user_handle;
2158         d.out.user_handle = &user_handle;
2159         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2160         if (!NT_STATUS_IS_OK(status)) {
2161                 goto failed;
2162         }
2163
2164         return True;
2165
2166 failed:
2167         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2168         return False;
2169 }
2170
2171
2172 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2173                                     struct policy_handle *handle, const char *name)
2174 {
2175         NTSTATUS status;
2176         struct samr_OpenGroup r;
2177         struct samr_DeleteDomainGroup d;
2178         struct policy_handle group_handle;
2179         uint32_t rid;
2180
2181         status = test_LookupName(p, mem_ctx, handle, name, &rid);
2182         if (!NT_STATUS_IS_OK(status)) {
2183                 goto failed;
2184         }
2185
2186         r.in.domain_handle = handle;
2187         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2188         r.in.rid = rid;
2189         r.out.group_handle = &group_handle;
2190         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2191         if (!NT_STATUS_IS_OK(status)) {
2192                 goto failed;
2193         }
2194
2195         d.in.group_handle = &group_handle;
2196         d.out.group_handle = &group_handle;
2197         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2198         if (!NT_STATUS_IS_OK(status)) {
2199                 goto failed;
2200         }
2201
2202         return True;
2203
2204 failed:
2205         printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2206         return False;
2207 }
2208
2209
2210 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2211                                    struct policy_handle *domain_handle, const char *name)
2212 {
2213         NTSTATUS status;
2214         struct samr_OpenAlias r;
2215         struct samr_DeleteDomAlias d;
2216         struct policy_handle alias_handle;
2217         uint32_t rid;
2218
2219         printf("testing DeleteAlias_byname\n");
2220
2221         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2222         if (!NT_STATUS_IS_OK(status)) {
2223                 goto failed;
2224         }
2225
2226         r.in.domain_handle = domain_handle;
2227         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2228         r.in.rid = rid;
2229         r.out.alias_handle = &alias_handle;
2230         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2231         if (!NT_STATUS_IS_OK(status)) {
2232                 goto failed;
2233         }
2234
2235         d.in.alias_handle = &alias_handle;
2236         d.out.alias_handle = &alias_handle;
2237         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2238         if (!NT_STATUS_IS_OK(status)) {
2239                 goto failed;
2240         }
2241
2242         return True;
2243
2244 failed:
2245         printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2246         return False;
2247 }
2248
2249 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2250                                      struct policy_handle *alias_handle)
2251 {
2252         struct samr_DeleteDomAlias d;
2253         NTSTATUS status;
2254         BOOL ret = True;
2255         printf("Testing DeleteAlias\n");
2256
2257         d.in.alias_handle = alias_handle;
2258         d.out.alias_handle = alias_handle;
2259
2260         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2261         if (!NT_STATUS_IS_OK(status)) {
2262                 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2263                 ret = False;
2264         }
2265
2266         return ret;
2267 }
2268
2269 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2270                             struct policy_handle *domain_handle, 
2271                              struct policy_handle *alias_handle, 
2272                              const struct dom_sid *domain_sid)
2273 {
2274         NTSTATUS status;
2275         struct samr_CreateDomAlias r;
2276         struct lsa_String name;
2277         uint32_t rid;
2278         BOOL ret = True;
2279
2280         init_lsa_String(&name, TEST_ALIASNAME);
2281         r.in.domain_handle = domain_handle;
2282         r.in.alias_name = &name;
2283         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2284         r.out.alias_handle = alias_handle;
2285         r.out.rid = &rid;
2286
2287         printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2288
2289         status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
2290
2291         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2292                 printf("Server refused create of '%s'\n", r.in.alias_name->string);
2293                 return True;
2294         }
2295
2296         if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2297                 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
2298                         return False;
2299                 }
2300                 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
2301         }
2302
2303         if (!NT_STATUS_IS_OK(status)) {
2304                 printf("CreateAlias failed - %s\n", nt_errstr(status));
2305                 return False;
2306         }
2307
2308         if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
2309                 ret = False;
2310         }
2311
2312         return ret;
2313 }
2314
2315 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2316                                 const char *acct_name,
2317                                 struct policy_handle *domain_handle, char **password)
2318 {
2319         BOOL ret = True;
2320
2321         if (!*password) {
2322                 return False;
2323         }
2324
2325         if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2326                 ret = False;
2327         }
2328
2329         if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, True)) {
2330                 ret = False;
2331         }
2332
2333         if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2334                 ret = False;
2335         }
2336
2337         /* test what happens when setting the old password again */
2338         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, True)) {
2339                 ret = False;
2340         }
2341
2342         {
2343                 char simple_pass[9];
2344                 char *v = generate_random_str(mem_ctx, 1);
2345
2346                 ZERO_STRUCT(simple_pass);
2347                 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2348
2349                 /* test what happens when picking a simple password */
2350                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, True)) {
2351                         ret = False;
2352                 }
2353         }
2354
2355         /* set samr_SetDomainInfo level 1 with min_length 5 */
2356         {
2357                 struct samr_QueryDomainInfo r;
2358                 struct samr_SetDomainInfo s;
2359                 uint16_t len_old, len;
2360                 uint32_t pwd_prop_old;
2361                 int64_t min_pwd_age_old;
2362                 NTSTATUS status;
2363
2364                 len = 5;
2365
2366                 r.in.domain_handle = domain_handle;
2367                 r.in.level = 1;
2368
2369                 printf("testing samr_QueryDomainInfo level 1\n");
2370                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2371                 if (!NT_STATUS_IS_OK(status)) {
2372                         return False;
2373                 }
2374
2375                 s.in.domain_handle = domain_handle;
2376                 s.in.level = 1;
2377                 s.in.info = r.out.info;
2378
2379                 /* remember the old min length, so we can reset it */
2380                 len_old = s.in.info->info1.min_password_length;
2381                 s.in.info->info1.min_password_length = len;
2382                 pwd_prop_old = s.in.info->info1.password_properties;
2383                 /* turn off password complexity checks for this test */
2384                 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2385
2386                 min_pwd_age_old = s.in.info->info1.min_password_age;
2387                 s.in.info->info1.min_password_age = 0;
2388
2389                 printf("testing samr_SetDomainInfo level 1\n");
2390                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2391                 if (!NT_STATUS_IS_OK(status)) {
2392                         return False;
2393                 }
2394
2395                 printf("calling test_ChangePasswordUser3 with too short password\n");
2396
2397                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, True)) {
2398                         ret = False;
2399                 }
2400
2401                 s.in.info->info1.min_password_length = len_old;
2402                 s.in.info->info1.password_properties = pwd_prop_old;
2403                 s.in.info->info1.min_password_age = min_pwd_age_old;
2404                 
2405                 printf("testing samr_SetDomainInfo level 1\n");
2406                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2407                 if (!NT_STATUS_IS_OK(status)) {
2408                         return False;
2409                 }
2410
2411         }
2412
2413         {
2414                 NTSTATUS status;
2415                 struct samr_OpenUser r;
2416                 struct samr_QueryUserInfo q;
2417                 struct samr_LookupNames n;
2418                 struct policy_handle user_handle;
2419
2420                 n.in.domain_handle = domain_handle;
2421                 n.in.num_names = 1;
2422                 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2423                 n.in.names[0].string = acct_name; 
2424
2425                 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2426                 if (!NT_STATUS_IS_OK(status)) {
2427                         printf("LookupNames failed - %s\n", nt_errstr(status));
2428                         return False;
2429                 }
2430
2431                 r.in.domain_handle = domain_handle;
2432                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2433                 r.in.rid = n.out.rids.ids[0];
2434                 r.out.user_handle = &user_handle;
2435
2436                 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2437                 if (!NT_STATUS_IS_OK(status)) {
2438                         printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2439                         return False;
2440                 }
2441
2442                 q.in.user_handle = &user_handle;
2443                 q.in.level = 5;
2444
2445                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2446                 if (!NT_STATUS_IS_OK(status)) {
2447                         printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2448                         return False;
2449                 }
2450
2451                 printf("calling test_ChangePasswordUser3 with too early password change\n");
2452
2453                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 
2454                                               q.out.info->info5.last_password_change, True)) {
2455                         ret = False;
2456                 }
2457         }
2458
2459         /* we change passwords twice - this has the effect of verifying
2460            they were changed correctly for the final call */
2461         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {
2462                 ret = False;
2463         }
2464
2465         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {
2466                 ret = False;
2467         }
2468
2469         return ret;
2470 }
2471
2472 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2473                             struct policy_handle *domain_handle, 
2474                             struct policy_handle *user_handle_out, 
2475                             enum torture_samr_choice which_ops)
2476 {
2477
2478         TALLOC_CTX *user_ctx;
2479
2480         NTSTATUS status;
2481         struct samr_CreateUser r;
2482         struct samr_QueryUserInfo q;
2483         struct samr_DeleteUser d;
2484         uint32_t rid;
2485
2486         /* This call creates a 'normal' account - check that it really does */
2487         const uint32_t acct_flags = ACB_NORMAL;
2488         struct lsa_String name;
2489         BOOL ret = True;
2490
2491         struct policy_handle user_handle;
2492         user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2493         init_lsa_String(&name, TEST_ACCOUNT_NAME);
2494
2495         r.in.domain_handle = domain_handle;
2496         r.in.account_name = &name;
2497         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2498         r.out.user_handle = &user_handle;
2499         r.out.rid = &rid;
2500
2501         printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2502
2503         status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2504
2505         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2506                 printf("Server refused create of '%s': %s\n", r.in.account_name->string, nt_errstr(status));
2507                 talloc_free(user_ctx);
2508                 return True;
2509         }
2510
2511         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2512                 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2513                         talloc_free(user_ctx);
2514                         return False;
2515                 }
2516                 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2517         }
2518         if (!NT_STATUS_IS_OK(status)) {
2519                 talloc_free(user_ctx);
2520                 printf("CreateUser failed - %s\n", nt_errstr(status));
2521                 return False;
2522         } else {
2523                 q.in.user_handle = &user_handle;
2524                 q.in.level = 16;
2525                 
2526                 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2527                 if (!NT_STATUS_IS_OK(status)) {
2528                         printf("QueryUserInfo level %u failed - %s\n", 
2529                                q.in.level, nt_errstr(status));
2530                         ret = False;
2531                 } else {
2532                         if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2533                                 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2534                                        q.out.info->info16.acct_flags, 
2535                                        acct_flags);
2536                                 ret = False;
2537                         }
2538                 }
2539                 
2540                 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle, 
2541                                    acct_flags, name.string, which_ops)) {
2542                         ret = False;
2543                 }
2544                 
2545                 if (user_handle_out) {
2546                         *user_handle_out = user_handle;
2547                 } else {
2548                         printf("Testing DeleteUser (createuser test)\n");
2549                         
2550                         d.in.user_handle = &user_handle;
2551                         d.out.user_handle = &user_handle;
2552                         
2553                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2554                         if (!NT_STATUS_IS_OK(status)) {
2555                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
2556                                 ret = False;
2557                         }
2558                 }
2559                 
2560         }
2561
2562         talloc_free(user_ctx);
2563         
2564         return ret;
2565 }
2566
2567
2568 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2569                              struct policy_handle *domain_handle, enum torture_samr_choice which_ops)
2570 {
2571         NTSTATUS status;
2572         struct samr_CreateUser2 r;
2573         struct samr_QueryUserInfo q;
2574         struct samr_DeleteUser d;
2575         struct policy_handle user_handle;
2576         uint32_t rid;
2577         struct lsa_String name;
2578         BOOL ret = True;
2579         int i;
2580
2581         struct {
2582                 uint32_t acct_flags;
2583                 const char *account_name;
2584                 NTSTATUS nt_status;
2585         } account_types[] = {
2586                 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2587                 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2588                 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2589                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2590                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2591                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2592                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2593                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2594                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2595                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2596                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2597                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2598                 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2599                 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2600                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2601         };
2602
2603         for (i = 0; account_types[i].account_name; i++) {
2604                 TALLOC_CTX *user_ctx;
2605                 uint32_t acct_flags = account_types[i].acct_flags;
2606                 uint32_t access_granted;
2607                 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2608                 init_lsa_String(&name, account_types[i].account_name);
2609
2610                 r.in.domain_handle = domain_handle;
2611                 r.in.account_name = &name;
2612                 r.in.acct_flags = acct_flags;
2613                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2614                 r.out.user_handle = &user_handle;
2615                 r.out.access_granted = &access_granted;
2616                 r.out.rid = &rid;
2617                 
2618                 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2619                 
2620                 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2621                 
2622                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2623                         talloc_free(user_ctx);
2624                         printf("Server refused create of '%s'\n", r.in.account_name->string);
2625                         continue;
2626
2627                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2628                         if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2629                                 talloc_free(user_ctx);
2630                                 ret = False;
2631                                 continue;
2632                         }
2633                         status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2634
2635                 }
2636                 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2637                         printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n", 
2638                                nt_errstr(status), nt_errstr(account_types[i].nt_status));
2639                         ret = False;
2640                 }
2641                 
2642                 if (NT_STATUS_IS_OK(status)) {
2643                         q.in.user_handle = &user_handle;
2644                         q.in.level = 5;
2645                         
2646                         status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2647                         if (!NT_STATUS_IS_OK(status)) {
2648                                 printf("QueryUserInfo level %u failed - %s\n", 
2649                                        q.in.level, nt_errstr(status));
2650                                 ret = False;
2651                         } else {
2652                                 if ((q.out.info->info5.acct_flags & acct_flags) != acct_flags) {
2653                                         printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2654                                                q.out.info->info5.acct_flags, 
2655                                                acct_flags);
2656                                         ret = False;
2657                                 } 
2658                                 switch (acct_flags) {
2659                                 case ACB_SVRTRUST:
2660                                         if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2661                                                 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n", 
2662                                                        DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2663                                                 ret = False;
2664                                         }
2665                                         break;
2666                                 case ACB_WSTRUST:
2667                                         if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2668                                                 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n", 
2669                                                        DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2670                                                 ret = False;
2671                                         }
2672                                         break;
2673                                 case ACB_NORMAL:
2674                                         if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2675                                                 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n", 
2676                                                        DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2677                                                 ret = False;
2678                                         }
2679                                         break;
2680                                 }
2681                         }
2682                 
2683                         if (!test_user_ops(p, user_ctx, &user_handle, domain_handle, 
2684                                            acct_flags, name.string, which_ops)) {
2685                                 ret = False;
2686                         }
2687
2688                         printf("Testing DeleteUser (createuser2 test)\n");
2689                 
2690                         d.in.user_handle = &user_handle;
2691                         d.out.user_handle = &user_handle;
2692                         
2693                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2694                         if (!NT_STATUS_IS_OK(status)) {
2695                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
2696                                 ret = False;
2697                         }
2698                 }
2699                 talloc_free(user_ctx);
2700         }
2701
2702         return ret;
2703 }
2704
2705 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2706                                 struct policy_handle *handle)
2707 {
2708         NTSTATUS status;
2709         struct samr_QueryAliasInfo r;
2710         uint16_t levels[] = {1, 2, 3};
2711         int i;
2712         BOOL ret = True;
2713
2714         for (i=0;i<ARRAY_SIZE(levels);i++) {
2715                 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2716
2717                 r.in.alias_handle = handle;
2718                 r.in.level = levels[i];
2719
2720                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2721                 if (!NT_STATUS_IS_OK(status)) {
2722                         printf("QueryAliasInfo level %u failed - %s\n", 
2723                                levels[i], nt_errstr(status));
2724                         ret = False;
2725                 }
2726         }
2727
2728         return ret;
2729 }
2730
2731 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2732                                 struct policy_handle *handle)
2733 {
2734         NTSTATUS status;
2735         struct samr_QueryGroupInfo r;
2736         uint16_t levels[] = {1, 2, 3, 4, 5};
2737         int i;
2738         BOOL ret = True;
2739
2740         for (i=0;i<ARRAY_SIZE(levels);i++) {
2741                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2742
2743                 r.in.group_handle = handle;
2744                 r.in.level = levels[i];
2745
2746                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2747                 if (!NT_STATUS_IS_OK(status)) {
2748                         printf("QueryGroupInfo level %u failed - %s\n", 
2749                                levels[i], nt_errstr(status));
2750                         ret = False;
2751                 }
2752         }
2753
2754         return ret;
2755 }
2756
2757 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2758                                   struct policy_handle *handle)
2759 {
2760         NTSTATUS status;
2761         struct samr_QueryGroupMember r;
2762         BOOL ret = True;
2763
2764         printf("Testing QueryGroupMember\n");
2765
2766         r.in.group_handle = handle;
2767
2768         status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2769         if (!NT_STATUS_IS_OK(status)) {
2770                 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2771                 ret = False;
2772         }
2773
2774         return ret;
2775 }
2776
2777
2778 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2779                               struct policy_handle *handle)
2780 {
2781         NTSTATUS status;
2782         struct samr_QueryGroupInfo r;
2783         struct samr_SetGroupInfo s;
2784         uint16_t levels[] = {1, 2, 3, 4};
2785         uint16_t set_ok[] = {0, 1, 1, 1};
2786         int i;
2787         BOOL ret = True;
2788
2789         for (i=0;i<ARRAY_SIZE(levels);i++) {
2790                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2791
2792                 r.in.group_handle = handle;
2793                 r.in.level = levels[i];
2794
2795                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2796                 if (!NT_STATUS_IS_OK(status)) {
2797                         printf("QueryGroupInfo level %u failed - %s\n", 
2798                                levels[i], nt_errstr(status));
2799                         ret = False;
2800                 }
2801
2802                 printf("Testing SetGroupInfo level %u\n", levels[i]);
2803
2804                 s.in.group_handle = handle;
2805                 s.in.level = levels[i];
2806                 s.in.info = r.out.info;
2807
2808 #if 0
2809                 /* disabled this, as it changes the name only from the point of view of samr, 
2810                    but leaves the name from the point of view of w2k3 internals (and ldap). This means
2811                    the name is still reserved, so creating the old name fails, but deleting by the old name
2812                    also fails */
2813                 if (s.in.level == 2) {
2814                         init_lsa_String(&s.in.info->string, "NewName");
2815                 }
2816 #endif
2817
2818                 if (s.in.level == 4) {
2819                         init_lsa_String(&s.in.info->description, "test description");
2820                 }
2821
2822                 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2823                 if (set_ok[i]) {
2824                         if (!NT_STATUS_IS_OK(status)) {
2825                                 printf("SetGroupInfo level %u failed - %s\n", 
2826                                        r.in.level, nt_errstr(status));
2827                                 ret = False;
2828                                 continue;
2829                         }
2830                 } else {
2831                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2832                                 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
2833                                        r.in.level, nt_errstr(status));
2834                                 ret = False;
2835                                 continue;
2836                         }
2837                 }
2838         }
2839
2840         return ret;
2841 }
2842
2843 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2844                                struct policy_handle *handle)
2845 {
2846         NTSTATUS status;
2847         struct samr_QueryUserInfo r;
2848         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2849                            11, 12, 13, 14, 16, 17, 20, 21};
2850         int i;
2851         BOOL ret = True;
2852
2853         for (i=0;i<ARRAY_SIZE(levels);i++) {
2854                 printf("Testing QueryUserInfo level %u\n", levels[i]);
2855
2856                 r.in.user_handle = handle;
2857                 r.in.level = levels[i];
2858
2859                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2860                 if (!NT_STATUS_IS_OK(status)) {
2861                         printf("QueryUserInfo level %u failed - %s\n", 
2862                                levels[i], nt_errstr(status));
2863                         ret = False;
2864                 }
2865         }
2866
2867         return ret;
2868 }
2869
2870 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2871                                 struct policy_handle *handle)
2872 {
2873         NTSTATUS status;
2874         struct samr_QueryUserInfo2 r;
2875         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2876                            11, 12, 13, 14, 16, 17, 20, 21};
2877         int i;
2878         BOOL ret = True;
2879
2880         for (i=0;i<ARRAY_SIZE(levels);i++) {
2881                 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2882
2883                 r.in.user_handle = handle;
2884                 r.in.level = levels[i];
2885
2886                 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2887                 if (!NT_STATUS_IS_OK(status)) {
2888                         printf("QueryUserInfo2 level %u failed - %s\n", 
2889                                levels[i], nt_errstr(status));
2890                         ret = False;
2891                 }
2892         }
2893
2894         return ret;
2895 }
2896
2897 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2898                           struct policy_handle *handle, uint32_t rid)
2899 {
2900         NTSTATUS status;
2901         struct samr_OpenUser r;
2902         struct policy_handle user_handle;
2903         BOOL ret = True;
2904
2905         printf("Testing OpenUser(%u)\n", rid);
2906
2907         r.in.domain_handle = handle;
2908         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2909         r.in.rid = rid;
2910         r.out.user_handle = &user_handle;
2911
2912         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2913         if (!NT_STATUS_IS_OK(status)) {
2914                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2915                 return False;
2916         }
2917
2918         if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2919                 ret = False;
2920         }
2921
2922         if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2923                 ret = False;
2924         }
2925
2926         if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2927                 ret = False;
2928         }
2929
2930         if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2931                 ret = False;
2932         }
2933
2934         if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2935                 ret = False;
2936         }
2937
2938         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2939                 ret = False;
2940         }
2941
2942         return ret;
2943 }
2944
2945 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2946                            struct policy_handle *handle, uint32_t rid)
2947 {
2948         NTSTATUS status;
2949         struct samr_OpenGroup r;
2950         struct policy_handle group_handle;
2951         BOOL ret = True;
2952
2953         printf("Testing OpenGroup(%u)\n", rid);
2954
2955         r.in.domain_handle = handle;
2956         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2957         r.in.rid = rid;
2958         r.out.group_handle = &group_handle;
2959
2960         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2961         if (!NT_STATUS_IS_OK(status)) {
2962                 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2963                 return False;
2964         }
2965
2966         if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2967                 ret = False;
2968         }
2969
2970         if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2971                 ret = False;
2972         }
2973
2974         if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2975                 ret = False;
2976         }
2977
2978         if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2979                 ret = False;
2980         }
2981
2982         return ret;
2983 }
2984
2985 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2986                            struct policy_handle *handle, uint32_t rid)
2987 {
2988         NTSTATUS status;
2989         struct samr_OpenAlias r;
2990         struct policy_handle alias_handle;
2991         BOOL ret = True;
2992
2993         printf("Testing OpenAlias(%u)\n", rid);
2994
2995         r.in.domain_handle = handle;
2996         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2997         r.in.rid = rid;
2998         r.out.alias_handle = &alias_handle;
2999
3000         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3001         if (!NT_STATUS_IS_OK(status)) {
3002                 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3003                 return False;
3004         }
3005
3006         if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
3007                 ret = False;
3008         }
3009
3010         if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
3011                 ret = False;
3012         }
3013
3014         if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
3015                 ret = False;
3016         }
3017
3018         if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
3019                 ret = False;
3020         }
3021
3022         return ret;
3023 }
3024
3025 static BOOL check_mask(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3026                        struct policy_handle *handle, uint32_t rid, 
3027                        uint32_t acct_flag_mask)
3028 {
3029         NTSTATUS status;
3030         struct samr_OpenUser r;
3031         struct samr_QueryUserInfo q;
3032         struct policy_handle user_handle;
3033         BOOL ret = True;
3034
3035         printf("Testing OpenUser(%u)\n", rid);
3036
3037         r.in.domain_handle = handle;
3038         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3039         r.in.rid = rid;
3040         r.out.user_handle = &user_handle;
3041
3042         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3043         if (!NT_STATUS_IS_OK(status)) {
3044                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3045                 return False;
3046         }
3047
3048         q.in.user_handle = &user_handle;
3049         q.in.level = 16;
3050         
3051         status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3052         if (!NT_STATUS_IS_OK(status)) {
3053                 printf("QueryUserInfo level 16 failed - %s\n", 
3054                        nt_errstr(status));
3055                 ret = False;
3056         } else {
3057                 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
3058                         printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3059                                acct_flag_mask, q.out.info->info16.acct_flags, rid);
3060                         ret = False;
3061                 }
3062         }
3063         
3064         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3065                 ret = False;
3066         }
3067
3068         return ret;
3069 }
3070
3071 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3072                                  struct policy_handle *handle)
3073 {
3074         NTSTATUS status = STATUS_MORE_ENTRIES;
3075         struct samr_EnumDomainUsers r;
3076         uint32_t mask, resume_handle=0;
3077         int i, mask_idx;
3078         BOOL ret = True;
3079         struct samr_LookupNames n;
3080         struct samr_LookupRids  lr ;
3081         uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST, 
3082                             ACB_DISABLED, ACB_NORMAL | ACB_DISABLED, 
3083                             ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST, 
3084                             ACB_PWNOEXP, 0};
3085
3086         printf("Testing EnumDomainUsers\n");
3087
3088         for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3089                 r.in.domain_handle = handle;
3090                 r.in.resume_handle = &resume_handle;
3091                 r.in.acct_flags = mask = masks[mask_idx];
3092                 r.in.max_size = (uint32_t)-1;
3093                 r.out.resume_handle = &resume_handle;
3094
3095                 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
3096                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&  
3097                     !NT_STATUS_IS_OK(status)) {
3098                         printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3099                         return False;
3100                 }
3101         
3102                 if (!r.out.sam) {
3103                         printf("EnumDomainUsers failed: r.out.sam unexpectedly NULL\n");
3104                         return False;
3105                 }
3106
3107                 if (r.out.sam->count == 0) {
3108                         continue;
3109                 }
3110
3111                 for (i=0;i<r.out.sam->count;i++) {
3112                         if (mask) {
3113                                 if (!check_mask(p, mem_ctx, handle, r.out.sam->entries[i].idx, mask)) {
3114                                         ret = False;
3115                                 }
3116                         } else if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3117                                 ret = False;
3118                         }
3119                 }
3120         }
3121
3122         printf("Testing LookupNames\n");
3123         n.in.domain_handle = handle;
3124         n.in.num_names = r.out.sam->count;
3125         n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
3126         for (i=0;i<r.out.sam->count;i++) {
3127                 n.in.names[i].string = r.out.sam->entries[i].name.string;
3128         }
3129         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3130         if (!NT_STATUS_IS_OK(status)) {
3131                 printf("LookupNames failed - %s\n", nt_errstr(status));
3132                 ret = False;
3133         }
3134
3135
3136         printf("Testing LookupRids\n");
3137         lr.in.domain_handle = handle;
3138         lr.in.num_rids = r.out.sam->count;
3139         lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
3140         for (i=0;i<r.out.sam->count;i++) {
3141                 lr.in.rids[i] = r.out.sam->entries[i].idx;
3142         }
3143         status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
3144         if (!NT_STATUS_IS_OK(status)) {
3145                 printf("LookupRids failed - %s\n", nt_errstr(status));
3146                 ret = False;
3147         }
3148
3149         return ret;     
3150 }
3151
3152 /*
3153   try blasting the server with a bunch of sync requests
3154 */
3155 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3156                                        struct policy_handle *handle)
3157 {
3158         NTSTATUS status;
3159         struct samr_EnumDomainUsers r;
3160         uint32_t resume_handle=0;
3161         int i;
3162 #define ASYNC_COUNT 100
3163         struct rpc_request *req[ASYNC_COUNT];
3164
3165         if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
3166                 printf("samr async test disabled - enable dangerous tests to use\n");
3167                 return True;
3168         }
3169
3170         printf("Testing EnumDomainUsers_async\n");
3171
3172         r.in.domain_handle = handle;
3173         r.in.resume_handle = &resume_handle;
3174         r.in.acct_flags = 0;
3175         r.in.max_size = (uint32_t)-1;
3176         r.out.resume_handle = &resume_handle;
3177
3178         for (i=0;i<ASYNC_COUNT;i++) {
3179                 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
3180         }
3181
3182         for (i=0;i<ASYNC_COUNT;i++) {
3183                 status = dcerpc_ndr_request_recv(req[i]);
3184                 if (!NT_STATUS_IS_OK(status)) {
3185                         printf("EnumDomainUsers[%d] failed - %s\n", 
3186                                i, nt_errstr(status));
3187                         return False;
3188                 }
3189         }
3190         
3191         printf("%d async requests OK\n", i);
3192
3193         return True;
3194 }
3195
3196 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3197                                   struct policy_handle *handle)
3198 {
3199         NTSTATUS status;
3200         struct samr_EnumDomainGroups r;
3201         uint32_t resume_handle=0;
3202         int i;
3203         BOOL ret = True;
3204
3205         printf("Testing EnumDomainGroups\n");
3206
3207         r.in.domain_handle = handle;
3208         r.in.resume_handle = &resume_handle;
3209         r.in.max_size = (uint32_t)-1;
3210         r.out.resume_handle = &resume_handle;
3211
3212         status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3213         if (!NT_STATUS_IS_OK(status)) {
3214                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3215                 return False;
3216         }
3217         
3218         if (!r.out.sam) {
3219                 return False;
3220         }
3221
3222         for (i=0;i<r.out.sam->count;i++) {
3223                 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3224                         ret = False;
3225                 }
3226         }
3227
3228         return ret;
3229 }
3230
3231 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3232                                    struct policy_handle *handle)
3233 {
3234         NTSTATUS status;
3235         struct samr_EnumDomainAliases r;
3236         uint32_t resume_handle=0;
3237         int i;
3238         BOOL ret = True;
3239
3240         printf("Testing EnumDomainAliases\n");
3241
3242         r.in.domain_handle = handle;
3243         r.in.resume_handle = &resume_handle;
3244         r.in.acct_flags = (uint32_t)-1;
3245         r.out.resume_handle = &resume_handle;
3246
3247         status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3248         if (!NT_STATUS_IS_OK(status)) {
3249                 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3250                 return False;
3251         }
3252         
3253         if (!r.out.sam) {
3254                 return False;
3255         }
3256
3257         for (i=0;i<r.out.sam->count;i++) {
3258                 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3259                         ret = False;
3260                 }
3261         }
3262
3263         return ret;     
3264 }
3265
3266 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3267                                             struct policy_handle *handle)
3268 {
3269         NTSTATUS status;
3270         struct samr_GetDisplayEnumerationIndex r;
3271         BOOL ret = True;
3272         uint16_t levels[] = {1, 2, 3, 4, 5};
3273         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3274         int i;
3275
3276         for (i=0;i<ARRAY_SIZE(levels);i++) {
3277                 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3278
3279                 r.in.domain_handle = handle;
3280                 r.in.level = levels[i];
3281                 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3282
3283                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3284
3285                 if (ok_lvl[i] && 
3286                     !NT_STATUS_IS_OK(status) &&
3287                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3288                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
3289                                levels[i], nt_errstr(status));
3290                         ret = False;
3291                 }
3292
3293                 init_lsa_String(&r.in.name, "zzzzzzzz");
3294
3295                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3296                 
3297                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3298                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
3299                                levels[i], nt_errstr(status));
3300                         ret = False;
3301                 }
3302         }
3303         
3304         return ret;     
3305 }
3306
3307 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3308                                              struct policy_handle *handle)
3309 {
3310         NTSTATUS status;
3311         struct samr_GetDisplayEnumerationIndex2 r;
3312         BOOL ret = True;
3313         uint16_t levels[] = {1, 2, 3, 4, 5};
3314         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3315         int i;
3316
3317         for (i=0;i<ARRAY_SIZE(levels);i++) {
3318                 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3319
3320                 r.in.domain_handle = handle;
3321                 r.in.level = levels[i];
3322                 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3323
3324                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3325                 if (ok_lvl[i] && 
3326                     !NT_STATUS_IS_OK(status) && 
3327                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3328                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
3329                                levels[i], nt_errstr(status));
3330                         ret = False;
3331                 }
3332
3333                 init_lsa_String(&r.in.name, "zzzzzzzz");
3334
3335                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3336                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3337                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
3338                                levels[i], nt_errstr(status));
3339                         ret = False;
3340                 }
3341         }
3342         
3343         return ret;     
3344 }
3345
3346 #define STRING_EQUAL_QUERY(s1, s2, user)                                        \
3347         if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3348                 /* odd, but valid */                                            \
3349         } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3350                         printf("%s mismatch for %s: %s != %s (%s)\n", \
3351                                #s1, user.string,  s1.string, s2.string, __location__);   \
3352                         ret = False; \
3353         }
3354 #define INT_EQUAL_QUERY(s1, s2, user)           \
3355                 if (s1 != s2) { \
3356                         printf("%s mismatch for %s: 0x%x != 0x%x (%s)\n", \
3357                                #s1, user.string, (unsigned int)s1, (unsigned int)s2, __location__); \
3358                         ret = False; \
3359                 }
3360
3361 static BOOL test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3362                                        struct samr_QueryDisplayInfo *querydisplayinfo,
3363                                        bool *seen_testuser) 
3364 {
3365         struct samr_OpenUser r;
3366         struct samr_QueryUserInfo q;
3367         struct policy_handle user_handle;
3368         int i, ret = True;
3369         NTSTATUS status;
3370         r.in.domain_handle = querydisplayinfo->in.domain_handle;
3371         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3372         for (i = 0; ; i++) {
3373                 switch (querydisplayinfo->in.level) {
3374                 case 1:
3375                         if (i >= querydisplayinfo->out.info.info1.count) {
3376                                 return ret;
3377                         }
3378                         r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
3379                         break;
3380                 case 2:
3381                         if (i >= querydisplayinfo->out.info.info2.count) {
3382                                 return ret;
3383                         }
3384                         r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
3385                         break;
3386                 case 3:
3387                         /* Groups */
3388                 case 4:
3389                 case 5:
3390                         /* Not interested in validating just the account name */
3391                         return true;
3392                 }
3393                         
3394                 r.out.user_handle = &user_handle;
3395                 
3396                 switch (querydisplayinfo->in.level) {
3397                 case 1:
3398                 case 2:
3399                         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3400                         if (!NT_STATUS_IS_OK(status)) {
3401                                 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3402                                 return False;
3403                         }
3404                 }
3405                 
3406                 q.in.user_handle = &user_handle;
3407                 q.in.level = 21;
3408                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3409                 if (!NT_STATUS_IS_OK(status)) {
3410                         printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3411                         return False;
3412                 }
3413                 
3414                 switch (querydisplayinfo->in.level) {
3415                 case 1:
3416                         if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3417                                 *seen_testuser = true;
3418                         }
3419                         STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name, 
3420                                            q.out.info->info21.full_name, q.out.info->info21.account_name);
3421                         STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name, 
3422                                            q.out.info->info21.account_name, q.out.info->info21.account_name);
3423                         STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description, 
3424                                            q.out.info->info21.description, q.out.info->info21.account_name);
3425                         INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid, 
3426                                         q.out.info->info21.rid, q.out.info->info21.account_name);
3427                         INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags, 
3428                                         q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3429                         
3430                         break;
3431                 case 2:
3432                         STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name, 
3433                                            q.out.info->info21.account_name, q.out.info->info21.account_name);
3434                         STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description, 
3435                                            q.out.info->info21.description, q.out.info->info21.account_name);
3436                         INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid, 
3437                                         q.out.info->info21.rid, q.out.info->info21.account_name);
3438                         INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL), 
3439                                         q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3440                         
3441                         if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
3442                                 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n", 
3443                                        q.out.info->info21.account_name.string);
3444                         }
3445
3446                         if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3447                                 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3448                                        q.out.info->info21.account_name.string,
3449                                        querydisplayinfo->out.info.info2.entries[i].acct_flags,
3450                                        q.out.info->info21.acct_flags);
3451                                 return False;
3452                         }
3453                         
3454                         break;
3455                 }
3456                 
3457                 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3458                         return False;
3459                 }
3460         }
3461         return ret;
3462 }
3463
3464 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3465                                   struct policy_handle *handle)
3466 {
3467         NTSTATUS status;
3468         struct samr_QueryDisplayInfo r;
3469         struct samr_QueryDomainInfo dom_info;
3470         BOOL ret = True;
3471         uint16_t levels[] = {1, 2, 3, 4, 5};
3472         int i;
3473         bool seen_testuser = false;
3474
3475         for (i=0;i<ARRAY_SIZE(levels);i++) {
3476                 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3477
3478                 r.in.start_idx = 0;
3479                 status = STATUS_MORE_ENTRIES;
3480                 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3481                         r.in.domain_handle = handle;
3482                         r.in.level = levels[i];
3483                         r.in.max_entries = 2;
3484                         r.in.buf_size = (uint32_t)-1;
3485                         
3486                         status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3487                         if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3488                                 printf("QueryDisplayInfo level %u failed - %s\n", 
3489                                        levels[i], nt_errstr(status));
3490                                 ret = False;
3491                         }
3492                         switch (r.in.level) {
3493                         case 1:
3494                                 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3495                                         ret = False;
3496                                 }
3497                                 r.in.start_idx += r.out.info.info1.count;
3498                                 break;
3499                         case 2:
3500                                 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3501                                         ret = False;
3502                                 }
3503                                 r.in.start_idx += r.out.info.info2.count;
3504                                 break;
3505                         case 3:
3506                                 r.in.start_idx += r.out.info.info3.count;
3507                                 break;
3508                         case 4:
3509                                 r.in.start_idx += r.out.info.info4.count;
3510                                 break;
3511                         case 5:
3512                                 r.in.start_idx += r.out.info.info5.count;
3513                                 break;
3514                         }
3515                 }
3516                 dom_info.in.domain_handle = handle;
3517                 dom_info.in.level = 2;
3518                 /* Check number of users returned is correct */
3519                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3520                 if (!NT_STATUS_IS_OK(status)) {
3521                         printf("QueryDomainInfo level %u failed - %s\n", 
3522                                r.in.level, nt_errstr(status));
3523                                 ret = False;
3524                                 break;
3525                 }
3526                 switch (r.in.level) {
3527                 case 1:
3528                 case 4:
3529                         if (dom_info.out.info->info2.num_users < r.in.start_idx) {
3530                                 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3531                                        r.in.start_idx, dom_info.out.info->info2.num_groups,
3532                                        dom_info.out.info->info2.domain_name.string);
3533                                 ret = False;
3534                         }
3535                         if (!seen_testuser) {
3536                                 struct policy_handle user_handle;
3537                                 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3538                                         printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n", 
3539                                                dom_info.out.info->info2.domain_name.string);
3540                                         ret = False;
3541                                         test_samr_handle_Close(p, mem_ctx, &user_handle);
3542                                 }
3543                         }
3544                         break;
3545                 case 3:
3546                 case 5:
3547                         if (dom_info.out.info->info2.num_groups != r.in.start_idx) {
3548                                 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3549                                        r.in.start_idx, dom_info.out.info->info2.num_groups,
3550                                        dom_info.out.info->info2.domain_name.string);
3551                                 ret = False;
3552                         }
3553                         
3554                         break;
3555                 }
3556
3557         }
3558         
3559         return ret;     
3560 }
3561
3562 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3563                                   struct policy_handle *handle)
3564 {
3565         NTSTATUS status;
3566         struct samr_QueryDisplayInfo2 r;
3567         BOOL ret = True;
3568         uint16_t levels[] = {1, 2, 3, 4, 5};
3569         int i;
3570
3571         for (i=0;i<ARRAY_SIZE(levels);i++) {
3572                 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3573
3574                 r.in.domain_handle = handle;
3575                 r.in.level = levels[i];
3576                 r.in.start_idx = 0;
3577                 r.in.max_entries = 1000;
3578                 r.in.buf_size = (uint32_t)-1;
3579
3580                 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3581                 if (!NT_STATUS_IS_OK(status)) {
3582                         printf("QueryDisplayInfo2 level %u failed - %s\n", 
3583                                levels[i], nt_errstr(status));
3584                         ret = False;
3585                 }
3586         }
3587         
3588         return ret;     
3589 }
3590
3591 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3592                                   struct policy_handle *handle)
3593 {
3594         NTSTATUS status;
3595         struct samr_QueryDisplayInfo3 r;
3596         BOOL ret = True;
3597         uint16_t levels[] = {1, 2, 3, 4, 5};
3598         int i;
3599
3600         for (i=0;i<ARRAY_SIZE(levels);i++) {
3601                 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
3602
3603                 r.in.domain_handle = handle;
3604                 r.in.level = levels[i];
3605                 r.in.start_idx = 0;
3606                 r.in.max_entries = 1000;
3607                 r.in.buf_size = (uint32_t)-1;
3608
3609                 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
3610                 if (!NT_STATUS_IS_OK(status)) {
3611                         printf("QueryDisplayInfo3 level %u failed - %s\n", 
3612                                levels[i], nt_errstr(status));
3613                         ret = False;
3614                 }
3615         }
3616         
3617         return ret;     
3618 }
3619
3620
3621 static BOOL test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3622                                            struct policy_handle *handle)
3623 {
3624         NTSTATUS status;
3625         struct samr_QueryDisplayInfo r;
3626         BOOL ret = True;
3627
3628         printf("Testing QueryDisplayInfo continuation\n");
3629
3630         r.in.domain_handle = handle;
3631         r.in.level = 1;
3632         r.in.start_idx = 0;
3633         r.in.max_entries = 1;
3634         r.in.buf_size = (uint32_t)-1;
3635
3636         do {
3637                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3638                 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
3639                         if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
3640                                 printf("expected idx %d but got %d\n",
3641                                        r.in.start_idx + 1,
3642                                        r.out.info.info1.entries[0].idx);
3643                                 break;
3644                         }
3645                 }
3646                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3647                     !NT_STATUS_IS_OK(status)) {
3648                         printf("QueryDisplayInfo level %u failed - %s\n", 
3649                                r.in.level, nt_errstr(status));
3650                         ret = False;
3651                         break;
3652                 }
3653                 r.in.start_idx++;
3654         } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3655                   NT_STATUS_IS_OK(status)) &&
3656                  r.out.returned_size != 0);
3657         
3658         return ret;     
3659 }
3660
3661 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3662                                  struct policy_handle *handle)
3663 {
3664         NTSTATUS status;
3665         struct samr_QueryDomainInfo r;
3666         struct samr_SetDomainInfo s;
3667         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3668         uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
3669         int i;
3670         BOOL ret = True;
3671         const char *domain_comment = talloc_asprintf(mem_ctx, 
3672                                   "Tortured by Samba4 RPC-SAMR: %s", 
3673                                   timestring(mem_ctx, time(NULL)));
3674
3675         s.in.domain_handle = handle;
3676         s.in.level = 4;
3677         s.in.info = talloc(mem_ctx, union samr_DomainInfo);
3678         
3679         s.in.info->info4.comment.string = domain_comment;
3680         status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3681         if (!NT_STATUS_IS_OK(status)) {
3682                 printf("SetDomainInfo level %u (set comment) failed - %s\n", 
3683                        r.in.level, nt_errstr(status));
3684                 return False;
3685         }
3686
3687         for (i=0;i<ARRAY_SIZE(levels);i++) {
3688                 printf("Testing QueryDomainInfo level %u\n", levels[i]);
3689
3690                 r.in.domain_handle = handle;
3691                 r.in.level = levels[i];
3692
3693                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3694                 if (!NT_STATUS_IS_OK(status)) {
3695                         printf("QueryDomainInfo level %u failed - %s\n", 
3696                                r.in.level, nt_errstr(status));
3697                         ret = False;
3698                         continue;
3699                 }
3700
3701                 switch (levels[i]) {
3702                 case 2:
3703                         if (strcmp(r.out.info->info2.comment.string, domain_comment) != 0) {
3704                                 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3705                                        levels[i], r.out.info->info2.comment.string, domain_comment);
3706                                 ret = False;
3707                         }
3708                         if (!r.out.info->info2.primary.string) {
3709                                 printf("QueryDomainInfo level %u returned no PDC name\n",
3710                                        levels[i]);
3711                                 ret = False;
3712                         } else if (r.out.info->info2.role == SAMR_ROLE_DOMAIN_PDC) {
3713                                 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->info2.primary.string) != 0) {
3714                                         printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3715                                                levels[i], r.out.info->info2.primary.string, dcerpc_server_name(p));
3716                                 }
3717                         }
3718                         break;
3719                 case 4:
3720                         if (strcmp(r.out.info->info4.comment.string, domain_comment) != 0) {
3721                                 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3722                                        levels[i], r.out.info->info4.comment.string, domain_comment);
3723                                 ret = False;
3724                         }
3725                         break;
3726                 case 6:
3727                         if (!r.out.info->info6.primary.string) {
3728                                 printf("QueryDomainInfo level %u returned no PDC name\n",
3729                                        levels[i]);
3730                                 ret = False;
3731                         }
3732                         break;
3733                 case 11:
3734                         if (strcmp(r.out.info->info11.info2.comment.string, domain_comment) != 0) {
3735                                 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3736                                        levels[i], r.out.info->info11.info2.comment.string, domain_comment);
3737                                 ret = False;
3738                         }
3739                         break;
3740                 }
3741
3742                 printf("Testing SetDomainInfo level %u\n", levels[i]);
3743
3744                 s.in.domain_handle = handle;
3745                 s.in.level = levels[i];
3746                 s.in.info = r.out.info;
3747
3748                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3749                 if (set_ok[i]) {
3750                         if (!NT_STATUS_IS_OK(status)) {
3751                                 printf("SetDomainInfo level %u failed - %s\n", 
3752                                        r.in.level, nt_errstr(status));
3753                                 ret = False;
3754                                 continue;
3755                         }
3756                 } else {
3757                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3758                                 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
3759                                        r.in.level, nt_errstr(status));
3760                                 ret = False;
3761                                 continue;
3762                         }
3763                 }
3764
3765                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3766                 if (!NT_STATUS_IS_OK(status)) {
3767                         printf("QueryDomainInfo level %u failed - %s\n", 
3768                                r.in.level, nt_errstr(status));
3769                         ret = False;
3770                         continue;
3771                 }
3772         }
3773
3774         return ret;     
3775 }
3776
3777
3778 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3779                                   struct policy_handle *handle)
3780 {
3781         NTSTATUS status;
3782         struct samr_QueryDomainInfo2 r;
3783         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3784         int i;
3785         BOOL ret = True;
3786
3787         for (i=0;i<ARRAY_SIZE(levels);i++) {
3788                 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
3789
3790                 r.in.domain_handle = handle;
3791                 r.in.level = levels[i];
3792
3793                 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
3794                 if (!NT_STATUS_IS_OK(status)) {
3795                         printf("QueryDomainInfo2 level %u failed - %s\n", 
3796                                r.in.level, nt_errstr(status));
3797                         ret = False;
3798                         continue;
3799                 }
3800         }
3801
3802         return True;    
3803 }
3804
3805 /* Test whether querydispinfo level 5 and enumdomgroups return the same
3806    set of group names. */
3807 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3808                            struct policy_handle *handle)
3809 {
3810         struct samr_EnumDomainGroups q1;
3811         struct samr_QueryDisplayInfo q2;
3812         NTSTATUS status;
3813         uint32_t resume_handle=0;
3814         int i;
3815         BOOL ret = True;
3816
3817         int num_names = 0;
3818         const char **names = NULL;
3819
3820         printf("Testing coherency of querydispinfo vs enumdomgroups\n");
3821
3822         q1.in.domain_handle = handle;
3823         q1.in.resume_handle = &resume_handle;
3824         q1.in.max_size = 5;
3825         q1.out.resume_handle = &resume_handle;
3826
3827         status = STATUS_MORE_ENTRIES;
3828         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3829                 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
3830
3831                 if (!NT_STATUS_IS_OK(status) &&
3832                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3833                         break;
3834
3835                 for (i=0; i<q1.out.num_entries; i++) {
3836                         add_string_to_array(mem_ctx,
3837                                             q1.out.sam->entries[i].name.string,
3838                                             &names, &num_names);
3839                 }
3840         }
3841
3842         if (!NT_STATUS_IS_OK(status)) {
3843                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3844                 return False;
3845         }
3846         
3847         if (!q1.out.sam) {
3848                 return False;
3849         }
3850
3851         q2.in.domain_handle = handle;
3852         q2.in.level = 5;
3853         q2.in.start_idx = 0;
3854         q2.in.max_entries = 5;
3855         q2.in.buf_size = (uint32_t)-1;
3856
3857         status = STATUS_MORE_ENTRIES;
3858         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3859                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
3860
3861                 if (!NT_STATUS_IS_OK(status) &&
3862                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3863                         break;
3864
3865                 for (i=0; i<q2.out.info.info5.count; i++) {
3866                         int j;
3867                         const char *name = q2.out.info.info5.entries[i].account_name.string;
3868                         BOOL found = False;
3869                         for (j=0; j<num_names; j++) {
3870                                 if (names[j] == NULL)
3871                                         continue;
3872                                 /* Hmm. No strequal in samba4 */
3873                                 if (strequal(names[j], name)) {
3874                                         names[j] = NULL;
3875                                         found = True;
3876                                         break;
3877                                 }
3878                         }
3879
3880                         if (!found) {
3881                                 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
3882                                        name);
3883                                 ret = False;
3884                         }
3885                 }
3886                 q2.in.start_idx += q2.out.info.info5.count;
3887         }
3888
3889         if (!NT_STATUS_IS_OK(status)) {
3890                 printf("QueryDisplayInfo level 5 failed - %s\n",
3891                        nt_errstr(status));
3892                 ret = False;
3893         }
3894
3895         for (i=0; i<num_names; i++) {
3896                 if (names[i] != NULL) {
3897                         printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
3898                                names[i]);
3899                         ret = False;
3900                 }
3901         }
3902
3903         return ret;
3904 }
3905
3906 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3907                                    struct policy_handle *group_handle)
3908 {
3909         struct samr_DeleteDomainGroup d;
3910         NTSTATUS status;
3911         BOOL ret = True;
3912
3913         printf("Testing DeleteDomainGroup\n");
3914
3915         d.in.group_handle = group_handle;
3916         d.out.group_handle = group_handle;
3917
3918         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3919         if (!NT_STATUS_IS_OK(status)) {
3920                 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
3921                 ret = False;
3922         }
3923
3924         return ret;
3925 }
3926
3927 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3928                                             struct policy_handle *domain_handle)
3929 {
3930         struct samr_TestPrivateFunctionsDomain r;
3931         NTSTATUS status;
3932         BOOL ret = True;
3933
3934         printf("Testing TestPrivateFunctionsDomain\n");
3935
3936         r.in.domain_handle = domain_handle;
3937
3938         status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
3939         if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
3940                 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
3941                 ret = False;
3942         }
3943
3944         return ret;
3945 }
3946
3947 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3948                           struct dom_sid *domain_sid,
3949                           struct policy_handle *domain_handle)
3950 {
3951         struct samr_RidToSid r;
3952         NTSTATUS status;
3953         BOOL ret = True;
3954         struct dom_sid *calc_sid;
3955         int rids[] = { 0, 42, 512, 10200 };
3956         int i;
3957
3958         for (i=0;i<ARRAY_SIZE(rids);i++) {
3959         
3960                 printf("Testing RidToSid\n");
3961                 
3962                 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
3963                 r.in.domain_handle = domain_handle;
3964                 r.in.rid = rids[i];
3965                 
3966                 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
3967                 if (!NT_STATUS_IS_OK(status)) {
3968                         printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
3969                         ret = False;
3970                 } else {
3971                         calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
3972
3973                         if (!dom_sid_equal(calc_sid, r.out.sid)) {
3974                                 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i], 
3975                                        dom_sid_string(mem_ctx, r.out.sid), 
3976                                        dom_sid_string(mem_ctx, calc_sid));
3977                                 ret = False;
3978                         }
3979                 }
3980         }
3981
3982         return ret;
3983 }
3984
3985 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3986                                        struct policy_handle *domain_handle)
3987 {
3988         struct samr_GetBootKeyInformation r;
3989         NTSTATUS status;
3990         BOOL ret = True;
3991
3992         printf("Testing GetBootKeyInformation\n");
3993
3994         r.in.domain_handle = domain_handle;
3995
3996         status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
3997         if (!NT_STATUS_IS_OK(status)) {
3998                 /* w2k3 seems to fail this sometimes and pass it sometimes */
3999                 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4000         }
4001
4002         return ret;
4003 }
4004
4005 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4006                                 struct policy_handle *domain_handle,
4007                                 struct policy_handle *group_handle)
4008 {
4009         NTSTATUS status;
4010         struct samr_AddGroupMember r;
4011         struct samr_DeleteGroupMember d;
4012         struct samr_QueryGroupMember q;
4013         struct samr_SetMemberAttributesOfGroup s;
4014         BOOL ret = True;
4015         uint32_t rid;
4016
4017         status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4018         if (!NT_STATUS_IS_OK(status)) {
4019                 printf("test_AddGroupMember looking up name " TEST_ACCOUNT_NAME " failed - %s\n", nt_errstr(status));
4020                 return False;
4021         }
4022
4023         r.in.group_handle = group_handle;
4024         r.in.rid = rid;
4025         r.in.flags = 0; /* ??? */
4026
4027         printf("Testing AddGroupMember and DeleteGroupMember\n");
4028
4029         d.in.group_handle = group_handle;
4030         d.in.rid = rid;
4031
4032         status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
4033         if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
4034                 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n", 
4035                        nt_errstr(status));
4036                 return False;
4037         }
4038
4039         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
4040         if (!NT_STATUS_IS_OK(status)) {
4041                 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4042                 return False;
4043         }
4044
4045         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
4046         if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
4047                 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n", 
4048                        nt_errstr(status));
4049                 return False;
4050         }
4051
4052         if (lp_parm_bool(-1, "torture", "samba4", False)) {
4053                 printf("skipping SetMemberAttributesOfGroup test against Samba4\n");
4054         } else {
4055                 /* this one is quite strange. I am using random inputs in the
4056                    hope of triggering an error that might give us a clue */
4057
4058                 s.in.group_handle = group_handle;
4059                 s.in.unknown1 = random();
4060                 s.in.unknown2 = random();
4061
4062                 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
4063                 if (!NT_STATUS_IS_OK(status)) {
4064                         printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
4065                         return False;
4066                 }
4067         }
4068
4069         q.in.group_handle = group_handle;
4070
4071         status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
4072         if (!NT_STATUS_IS_OK(status)) {
4073                 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
4074                 return False;
4075         }
4076
4077         status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
4078         if (!NT_STATUS_IS_OK(status)) {
4079                 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
4080                 return False;
4081         }
4082
4083         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
4084         if (!NT_STATUS_IS_OK(status)) {
4085                 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4086                 return False;
4087         }
4088
4089         return ret;
4090 }
4091
4092
4093 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4094                                    struct policy_handle *domain_handle, struct policy_handle *group_handle)
4095 {
4096         NTSTATUS status;
4097         struct samr_CreateDomainGroup r;
4098         uint32_t rid;
4099         struct lsa_String name;
4100         BOOL ret = True;
4101
4102         init_lsa_String(&name, TEST_GROUPNAME);
4103
4104         r.in.domain_handle = domain_handle;
4105         r.in.name = &name;
4106         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4107         r.out.group_handle = group_handle;
4108         r.out.rid = &rid;
4109
4110         printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4111
4112         status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4113
4114         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4115                 printf("Server refused create of '%s'\n", r.in.name->string);
4116                 ZERO_STRUCTP(group_handle);
4117                 return True;
4118         }
4119
4120         if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4121                 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4122                         
4123                         printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string, 
4124                                nt_errstr(status));
4125                         return False;
4126                 }
4127                 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4128         }
4129         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4130                 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4131                         
4132                         printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string, 
4133                                nt_errstr(status));
4134                         return False;
4135                 }
4136                 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4137         }
4138         if (!NT_STATUS_IS_OK(status)) {
4139                 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4140                 return False;
4141         }
4142
4143         if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
4144                 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4145                 ret = False;
4146         }
4147
4148         if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
4149                 ret = False;
4150         }
4151
4152         return ret;
4153 }
4154
4155
4156 /*
4157   its not totally clear what this does. It seems to accept any sid you like.
4158 */
4159 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p, 
4160                                                TALLOC_CTX *mem_ctx, 
4161                                                struct policy_handle *domain_handle)
4162 {
4163         NTSTATUS status;
4164         struct samr_RemoveMemberFromForeignDomain r;
4165
4166         r.in.domain_handle = domain_handle;
4167         r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
4168
4169         status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
4170         if (!NT_STATUS_IS_OK(status)) {
4171                 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
4172                 return False;
4173         }
4174
4175         return True;
4176 }
4177
4178
4179
4180 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4181                          struct policy_handle *handle);
4182
4183 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4184                             struct policy_handle *handle, struct dom_sid *sid,
4185                             enum torture_samr_choice which_ops)
4186 {
4187         NTSTATUS status;
4188         struct samr_OpenDomain r;
4189         struct policy_handle domain_handle;
4190         struct policy_handle alias_handle;
4191         struct policy_handle user_handle;
4192         struct policy_handle group_handle;
4193         BOOL ret = True;
4194
4195         ZERO_STRUCT(alias_handle);
4196         ZERO_STRUCT(user_handle);
4197         ZERO_STRUCT(group_handle);
4198         ZERO_STRUCT(domain_handle);
4199
4200         printf("Testing OpenDomain\n");
4201
4202         r.in.connect_handle = handle;
4203         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4204         r.in.sid = sid;
4205         r.out.domain_handle = &domain_handle;
4206
4207         status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
4208         if (!NT_STATUS_IS_OK(status)) {
4209                 printf("OpenDomain failed - %s\n", nt_errstr(status));
4210                 return False;
4211         }
4212
4213         /* run the domain tests with the main handle closed - this tests
4214            the servers reference counting */
4215         ret &= test_samr_handle_Close(p, mem_ctx, handle);
4216
4217         switch (which_ops) {
4218         case TORTURE_SAMR_USER_ATTRIBUTES:
4219         case TORTURE_SAMR_PASSWORDS:
4220                 ret &= test_CreateUser2(p, mem_ctx, &domain_handle, which_ops);
4221                 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle, which_ops);
4222                 /* This test needs 'complex' users to validate */
4223                 ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
4224                 break;
4225         case TORTURE_SAMR_OTHER:
4226                 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle, which_ops);
4227                 ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
4228                 ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
4229                 ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
4230                 ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
4231                 ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
4232                 ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
4233                 ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
4234                 ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
4235                 ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
4236                 ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
4237                 ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
4238                 ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
4239                 ret &= test_QueryDisplayInfo_continue(p, mem_ctx, &domain_handle);
4240                 
4241                 if (lp_parm_bool(-1, "torture", "samba4", False)) {
4242                         printf("skipping GetDisplayEnumerationIndex test against Samba4\n");
4243                 } else {
4244                         ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
4245                         ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
4246                 }
4247                 ret &= test_GroupList(p, mem_ctx, &domain_handle);
4248                 ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
4249                 ret &= test_RidToSid(p, mem_ctx, sid, &domain_handle);
4250                 ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
4251                 break;
4252         }
4253
4254         if (!policy_handle_empty(&user_handle) &&
4255             !test_DeleteUser(p, mem_ctx, &user_handle)) {
4256                 ret = False;
4257         }
4258
4259         if (!policy_handle_empty(&alias_handle) &&
4260             !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
4261                 ret = False;
4262         }
4263
4264         if (!policy_handle_empty(&group_handle) &&
4265             !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
4266                 ret = False;
4267         }
4268
4269         ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
4270
4271         /* reconnect the main handle */
4272         ret &= test_Connect(p, mem_ctx, handle);
4273
4274         if (!ret) {
4275                 printf("Testing domain %s failed!\n", dom_sid_string(mem_ctx, sid));
4276         }
4277
4278         return ret;
4279 }
4280
4281 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4282                               struct policy_handle *handle, const char *domain,
4283                               enum torture_samr_choice which_ops)
4284 {
4285         NTSTATUS status;
4286         struct samr_LookupDomain r;
4287         struct lsa_String n1;
4288         struct lsa_String n2;
4289         BOOL ret = True;
4290
4291         printf("Testing LookupDomain(%s)\n", domain);
4292
4293         /* check for correct error codes */
4294         r.in.connect_handle = handle;
4295         r.in.domain_name = &n2;
4296         n2.string = NULL;
4297
4298         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
4299         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
4300                 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
4301                 ret = False;
4302         }
4303
4304         init_lsa_String(&n2, "xxNODOMAINxx");
4305
4306         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
4307         if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
4308                 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
4309                 ret = False;
4310         }
4311
4312         r.in.connect_handle = handle;
4313
4314         init_lsa_String(&n1, domain);
4315         r.in.domain_name = &n1;
4316
4317         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
4318         if (!NT_STATUS_IS_OK(status)) {
4319                 printf("LookupDomain failed - %s\n", nt_errstr(status));
4320                 ret = False;
4321         }
4322
4323         if (!test_GetDomPwInfo(p, mem_ctx, &n1)) {
4324                 ret = False;
4325         }
4326
4327         if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid, which_ops)) {
4328                 ret = False;
4329         }
4330
4331         return ret;
4332 }
4333
4334
4335 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4336                              struct policy_handle *handle, enum torture_samr_choice which_ops)
4337 {
4338         NTSTATUS status;
4339         struct samr_EnumDomains r;
4340         uint32_t resume_handle = 0;
4341         int i;
4342         BOOL ret = True;
4343
4344         r.in.connect_handle = handle;
4345         r.in.resume_handle = &resume_handle;
4346         r.in.buf_size = (uint32_t)-1;
4347         r.out.resume_handle = &resume_handle;
4348
4349         status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
4350         if (!NT_STATUS_IS_OK(status)) {
4351                 printf("EnumDomains failed - %s\n", nt_errstr(status));
4352                 return False;
4353         }
4354
4355         if (!r.out.sam) {
4356                 return False;
4357         }
4358
4359         for (i=0;i<r.out.sam->count;i++) {
4360                 if (!test_LookupDomain(p, mem_ctx, handle, 
4361                                        r.out.sam->entries[i].name.string, which_ops)) {
4362                         ret = False;
4363                 }
4364         }
4365
4366         status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
4367         if (!NT_STATUS_IS_OK(status)) {
4368                 printf("EnumDomains failed - %s\n", nt_errstr(status));
4369                 return False;
4370         }
4371
4372         return ret;
4373 }
4374
4375
4376 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4377                          struct policy_handle *handle)
4378 {
4379         NTSTATUS status;
4380         struct samr_Connect r;
4381         struct samr_Connect2 r2;
4382         struct samr_Connect3 r3;
4383         struct samr_Connect4 r4;
4384         struct samr_Connect5 r5;
4385         union samr_ConnectInfo info;
4386         struct policy_handle h;
4387         BOOL ret = True, got_handle = False;
4388
4389         printf("testing samr_Connect\n");
4390
4391         r.in.system_name = 0;
4392         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4393         r.out.connect_handle = &h;
4394
4395         status = dcerpc_samr_Connect(p, mem_ctx, &r);
4396         if (!NT_STATUS_IS_OK(status)) {
4397                 printf("Connect failed - %s\n", nt_errstr(status));
4398                 ret = False;
4399         } else {
4400                 got_handle = True;
4401                 *handle = h;
4402         }
4403
4404         printf("testing samr_Connect2\n");
4405
4406         r2.in.system_name = NULL;
4407         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4408         r2.out.connect_handle = &h;
4409
4410         status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
4411         if (!NT_STATUS_IS_OK(status)) {
4412                 printf("Connect2 failed - %s\n", nt_errstr(status));
4413                 ret = False;
4414         } else {
4415                 if (got_handle) {
4416                         test_samr_handle_Close(p, mem_ctx, handle);
4417                 }
4418                 got_handle = True;
4419                 *handle = h;
4420         }
4421
4422         printf("testing samr_Connect3\n");
4423
4424         r3.in.system_name = NULL;
4425         r3.in.unknown = 0;
4426         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4427         r3.out.connect_handle = &h;
4428
4429         status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
4430         if (!NT_STATUS_IS_OK(status)) {
4431                 printf("Connect3 failed - %s\n", nt_errstr(status));
4432                 ret = False;
4433         } else {
4434                 if (got_handle) {
4435                         test_samr_handle_Close(p, mem_ctx, handle);
4436                 }
4437                 got_handle = True;
4438                 *handle = h;
4439         }
4440
4441         printf("testing samr_Connect4\n");
4442
4443         r4.in.system_name = "";
4444         r4.in.unknown = 0;
4445         r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4446         r4.out.connect_handle = &h;
4447
4448         status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
4449         if (!NT_STATUS_IS_OK(status)) {
4450                 printf("Connect4 failed - %s\n", nt_errstr(status));
4451                 ret = False;
4452         } else {
4453                 if (got_handle) {
4454                         test_samr_handle_Close(p, mem_ctx, handle);
4455                 }
4456                 got_handle = True;
4457                 *handle = h;
4458         }
4459
4460         printf("testing samr_Connect5\n");
4461
4462         info.info1.unknown1 = 0;
4463         info.info1.unknown2 = 0;
4464
4465         r5.in.system_name = "";
4466         r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4467         r5.in.level = 1;
4468         r5.in.info = &info;
4469         r5.out.info = &info;
4470         r5.out.connect_handle = &h;
4471
4472         status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
4473         if (!NT_STATUS_IS_OK(status)) {
4474                 printf("Connect5 failed - %s\n", nt_errstr(status));
4475                 ret = False;
4476         } else {
4477                 if (got_handle) {
4478                         test_samr_handle_Close(p, mem_ctx, handle);
4479                 }
4480                 got_handle = True;
4481                 *handle = h;
4482         }
4483
4484         return ret;
4485 }
4486
4487
4488 BOOL torture_rpc_samr(struct torture_context *torture)
4489 {
4490         NTSTATUS status;
4491         struct dcerpc_pipe *p;
4492         BOOL ret = True;
4493         struct policy_handle handle;
4494
4495         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4496         if (!NT_STATUS_IS_OK(status)) {
4497                 return False;
4498         }
4499
4500         ret &= test_Connect(p, torture, &handle);
4501
4502         ret &= test_QuerySecurity(p, torture, &handle);
4503
4504         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4505
4506         ret &= test_SetDsrmPassword(p, torture, &handle);
4507
4508         ret &= test_Shutdown(p, torture, &handle);
4509
4510         ret &= test_samr_handle_Close(p, torture, &handle);
4511
4512         return ret;
4513 }
4514
4515
4516 BOOL torture_rpc_samr_users(struct torture_context *torture)
4517 {
4518         NTSTATUS status;
4519         struct dcerpc_pipe *p;
4520         BOOL ret = True;
4521         struct policy_handle handle;
4522
4523         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4524         if (!NT_STATUS_IS_OK(status)) {
4525                 return False;
4526         }
4527
4528         ret &= test_Connect(p, torture, &handle);
4529
4530         ret &= test_QuerySecurity(p, torture, &handle);
4531
4532         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4533
4534         ret &= test_SetDsrmPassword(p, torture, &handle);
4535
4536         ret &= test_Shutdown(p, torture, &handle);
4537
4538         ret &= test_samr_handle_Close(p, torture, &handle);
4539
4540         return ret;
4541 }
4542
4543
4544 BOOL torture_rpc_samr_passwords(struct torture_context *torture)
4545 {
4546         NTSTATUS status;
4547         struct dcerpc_pipe *p;
4548         BOOL ret = True;
4549         struct policy_handle handle;
4550
4551         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4552         if (!NT_STATUS_IS_OK(status)) {
4553                 return False;
4554         }
4555
4556         ret &= test_Connect(p, torture, &handle);
4557
4558         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4559
4560         ret &= test_samr_handle_Close(p, torture, &handle);
4561
4562         return ret;
4563 }
4564