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