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