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