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