r16847: Add the parts of the SAMR test that pass back into 'make test'.
[gd/samba-autobuild/.git] / source4 / torture / rpc / samr.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for samr rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "torture/torture.h"
25 #include "system/time.h"
26 #include "librpc/gen_ndr/lsa.h"
27 #include "librpc/gen_ndr/ndr_samr_c.h"
28 #include "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) failed - %s\n", name, 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                 /* Can't happen */
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 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1586                             struct policy_handle *handle, const char *name)
1587 {
1588         NTSTATUS status;
1589         struct samr_DeleteUser d;
1590         struct policy_handle user_handle;
1591         uint32_t rid;
1592
1593         status = test_LookupName(p, mem_ctx, handle, name, &rid);
1594         if (!NT_STATUS_IS_OK(status)) {
1595                 goto failed;
1596         }
1597
1598         status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
1599         if (!NT_STATUS_IS_OK(status)) {
1600                 goto failed;
1601         }
1602
1603         d.in.user_handle = &user_handle;
1604         d.out.user_handle = &user_handle;
1605         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1606         if (!NT_STATUS_IS_OK(status)) {
1607                 goto failed;
1608         }
1609
1610         return True;
1611
1612 failed:
1613         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1614         return False;
1615 }
1616
1617
1618 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1619                                     struct policy_handle *handle, const char *name)
1620 {
1621         NTSTATUS status;
1622         struct samr_OpenGroup r;
1623         struct samr_DeleteDomainGroup d;
1624         struct policy_handle group_handle;
1625         uint32_t rid;
1626
1627         status = test_LookupName(p, mem_ctx, handle, name, &rid);
1628         if (!NT_STATUS_IS_OK(status)) {
1629                 goto failed;
1630         }
1631
1632         r.in.domain_handle = handle;
1633         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1634         r.in.rid = rid;
1635         r.out.group_handle = &group_handle;
1636         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1637         if (!NT_STATUS_IS_OK(status)) {
1638                 goto failed;
1639         }
1640
1641         d.in.group_handle = &group_handle;
1642         d.out.group_handle = &group_handle;
1643         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
1644         if (!NT_STATUS_IS_OK(status)) {
1645                 goto failed;
1646         }
1647
1648         return True;
1649
1650 failed:
1651         printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
1652         return False;
1653 }
1654
1655
1656 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1657                                    struct policy_handle *domain_handle, const char *name)
1658 {
1659         NTSTATUS status;
1660         struct samr_OpenAlias r;
1661         struct samr_DeleteDomAlias d;
1662         struct policy_handle alias_handle;
1663         uint32_t rid;
1664
1665         printf("testing DeleteAlias_byname\n");
1666
1667         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1668         if (!NT_STATUS_IS_OK(status)) {
1669                 goto failed;
1670         }
1671
1672         r.in.domain_handle = domain_handle;
1673         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1674         r.in.rid = rid;
1675         r.out.alias_handle = &alias_handle;
1676         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1677         if (!NT_STATUS_IS_OK(status)) {
1678                 goto failed;
1679         }
1680
1681         d.in.alias_handle = &alias_handle;
1682         d.out.alias_handle = &alias_handle;
1683         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1684         if (!NT_STATUS_IS_OK(status)) {
1685                 goto failed;
1686         }
1687
1688         return True;
1689
1690 failed:
1691         printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
1692         return False;
1693 }
1694
1695 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1696                                      struct policy_handle *alias_handle)
1697 {
1698         struct samr_DeleteDomAlias d;
1699         NTSTATUS status;
1700         BOOL ret = True;
1701         printf("Testing DeleteAlias\n");
1702
1703         d.in.alias_handle = alias_handle;
1704         d.out.alias_handle = alias_handle;
1705
1706         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1707         if (!NT_STATUS_IS_OK(status)) {
1708                 printf("DeleteAlias failed - %s\n", nt_errstr(status));
1709                 ret = False;
1710         }
1711
1712         return ret;
1713 }
1714
1715 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1716                             struct policy_handle *domain_handle, 
1717                              struct policy_handle *alias_handle, 
1718                              const struct dom_sid *domain_sid)
1719 {
1720         NTSTATUS status;
1721         struct samr_CreateDomAlias r;
1722         struct lsa_String name;
1723         uint32_t rid;
1724         BOOL ret = True;
1725
1726         init_lsa_String(&name, TEST_ALIASNAME);
1727         r.in.domain_handle = domain_handle;
1728         r.in.alias_name = &name;
1729         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1730         r.out.alias_handle = alias_handle;
1731         r.out.rid = &rid;
1732
1733         printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
1734
1735         status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1736
1737         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1738                 printf("Server refused create of '%s'\n", r.in.alias_name->string);
1739                 return True;
1740         }
1741
1742         if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
1743                 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
1744                         return False;
1745                 }
1746                 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1747         }
1748
1749         if (!NT_STATUS_IS_OK(status)) {
1750                 printf("CreateAlias failed - %s\n", nt_errstr(status));
1751                 return False;
1752         }
1753
1754         if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
1755                 ret = False;
1756         }
1757
1758         return ret;
1759 }
1760
1761 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1762                                 const char *acct_name,
1763                                 struct policy_handle *domain_handle, char **password)
1764 {
1765         BOOL ret = True;
1766
1767         if (!*password) {
1768                 return False;
1769         }
1770
1771         if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
1772                 ret = False;
1773         }
1774
1775         if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
1776                 ret = False;
1777         }
1778
1779         if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
1780                 ret = False;
1781         }
1782
1783         /* we change passwords twice - this has the effect of verifying
1784            they were changed correctly for the final call */
1785         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password)) {
1786                 ret = False;
1787         }
1788
1789         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password)) {
1790                 ret = False;
1791         }
1792
1793         return ret;
1794 }
1795
1796 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1797                             struct policy_handle *domain_handle, 
1798                             enum torture_samr_choice which_ops)
1799 {
1800
1801         TALLOC_CTX *user_ctx;
1802
1803         NTSTATUS status;
1804         struct samr_CreateUser r;
1805         struct samr_QueryUserInfo q;
1806         struct samr_DeleteUser d;
1807         uint32_t rid;
1808
1809         /* This call creates a 'normal' account - check that it really does */
1810         const uint32_t acct_flags = ACB_NORMAL;
1811         struct lsa_String name;
1812         BOOL ret = True;
1813
1814         struct policy_handle user_handle;
1815         user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1816         init_lsa_String(&name, TEST_ACCOUNT_NAME);
1817
1818         r.in.domain_handle = domain_handle;
1819         r.in.account_name = &name;
1820         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1821         r.out.user_handle = &user_handle;
1822         r.out.rid = &rid;
1823
1824         printf("Testing CreateUser(%s)\n", r.in.account_name->string);
1825
1826         status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1827
1828         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1829                 printf("Server refused create of '%s': %s\n", r.in.account_name->string, nt_errstr(status));
1830                 talloc_free(user_ctx);
1831                 return True;
1832         }
1833
1834         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1835                 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
1836                         talloc_free(user_ctx);
1837                         return False;
1838                 }
1839                 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1840         }
1841         if (!NT_STATUS_IS_OK(status)) {
1842                 talloc_free(user_ctx);
1843                 printf("CreateUser failed - %s\n", nt_errstr(status));
1844                 return False;
1845         } else {
1846                 q.in.user_handle = &user_handle;
1847                 q.in.level = 16;
1848                 
1849                 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1850                 if (!NT_STATUS_IS_OK(status)) {
1851                         printf("QueryUserInfo level %u failed - %s\n", 
1852                                q.in.level, nt_errstr(status));
1853                         ret = False;
1854                 } else {
1855                         if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1856                                 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
1857                                        q.out.info->info16.acct_flags, 
1858                                        acct_flags);
1859                                 ret = False;
1860                         }
1861                 }
1862                 
1863                 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle, 
1864                                    acct_flags, name.string, which_ops)) {
1865                         ret = False;
1866                 }
1867                 
1868                 printf("Testing DeleteUser (createuser2 test)\n");
1869                 
1870                 d.in.user_handle = &user_handle;
1871                 d.out.user_handle = &user_handle;
1872                 
1873                 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
1874                 if (!NT_STATUS_IS_OK(status)) {
1875                         printf("DeleteUser failed - %s\n", nt_errstr(status));
1876                                 ret = False;
1877                 }
1878                 
1879         }
1880
1881         talloc_free(user_ctx);
1882         
1883         return ret;
1884 }
1885
1886
1887 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1888                              struct policy_handle *domain_handle, enum torture_samr_choice which_ops)
1889 {
1890         NTSTATUS status;
1891         struct samr_CreateUser2 r;
1892         struct samr_QueryUserInfo q;
1893         struct samr_DeleteUser d;
1894         struct policy_handle user_handle;
1895         uint32_t rid;
1896         struct lsa_String name;
1897         BOOL ret = True;
1898         int i;
1899
1900         struct {
1901                 uint32_t acct_flags;
1902                 const char *account_name;
1903                 NTSTATUS nt_status;
1904         } account_types[] = {
1905                 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
1906                 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1907                 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1908                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1909                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1910                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1911                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1912                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1913                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1914                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
1915                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1916                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1917                 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1918                 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1919                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
1920         };
1921
1922         for (i = 0; account_types[i].account_name; i++) {
1923                 TALLOC_CTX *user_ctx;
1924                 uint32_t acct_flags = account_types[i].acct_flags;
1925                 uint32_t access_granted;
1926                 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1927                 init_lsa_String(&name, account_types[i].account_name);
1928
1929                 r.in.domain_handle = domain_handle;
1930                 r.in.account_name = &name;
1931                 r.in.acct_flags = acct_flags;
1932                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1933                 r.out.user_handle = &user_handle;
1934                 r.out.access_granted = &access_granted;
1935                 r.out.rid = &rid;
1936                 
1937                 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
1938                 
1939                 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1940                 
1941                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1942                         talloc_free(user_ctx);
1943                         printf("Server refused create of '%s'\n", r.in.account_name->string);
1944                         continue;
1945
1946                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1947                         if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
1948                                 talloc_free(user_ctx);
1949                                 ret = False;
1950                                 continue;
1951                         }
1952                         status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1953
1954                 }
1955                 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
1956                         printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n", 
1957                                nt_errstr(status), nt_errstr(account_types[i].nt_status));
1958                         ret = False;
1959                 }
1960                 
1961                 if (NT_STATUS_IS_OK(status)) {
1962                         q.in.user_handle = &user_handle;
1963                         q.in.level = 16;
1964                         
1965                         status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1966                         if (!NT_STATUS_IS_OK(status)) {
1967                                 printf("QueryUserInfo level %u failed - %s\n", 
1968                                        q.in.level, nt_errstr(status));
1969                                 ret = False;
1970                         } else {
1971                                 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1972                                         printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
1973                                                q.out.info->info16.acct_flags, 
1974                                                acct_flags);
1975                                         ret = False;
1976                                 }
1977                         }
1978                 
1979                         if (!test_user_ops(p, user_ctx, &user_handle, domain_handle, 
1980                                            acct_flags, name.string, which_ops)) {
1981                                 ret = False;
1982                         }
1983
1984                         printf("Testing DeleteUser (createuser2 test)\n");
1985                 
1986                         d.in.user_handle = &user_handle;
1987                         d.out.user_handle = &user_handle;
1988                         
1989                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
1990                         if (!NT_STATUS_IS_OK(status)) {
1991                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
1992                                 ret = False;
1993                         }
1994                 }
1995                 talloc_free(user_ctx);
1996         }
1997
1998         return ret;
1999 }
2000
2001 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2002                                 struct policy_handle *handle)
2003 {
2004         NTSTATUS status;
2005         struct samr_QueryAliasInfo r;
2006         uint16_t levels[] = {1, 2, 3};
2007         int i;
2008         BOOL ret = True;
2009
2010         for (i=0;i<ARRAY_SIZE(levels);i++) {
2011                 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2012
2013                 r.in.alias_handle = handle;
2014                 r.in.level = levels[i];
2015
2016                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2017                 if (!NT_STATUS_IS_OK(status)) {
2018                         printf("QueryAliasInfo level %u failed - %s\n", 
2019                                levels[i], nt_errstr(status));
2020                         ret = False;
2021                 }
2022         }
2023
2024         return ret;
2025 }
2026
2027 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2028                                 struct policy_handle *handle)
2029 {
2030         NTSTATUS status;
2031         struct samr_QueryGroupInfo r;
2032         uint16_t levels[] = {1, 2, 3, 4, 5};
2033         int i;
2034         BOOL ret = True;
2035
2036         for (i=0;i<ARRAY_SIZE(levels);i++) {
2037                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2038
2039                 r.in.group_handle = handle;
2040                 r.in.level = levels[i];
2041
2042                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2043                 if (!NT_STATUS_IS_OK(status)) {
2044                         printf("QueryGroupInfo level %u failed - %s\n", 
2045                                levels[i], nt_errstr(status));
2046                         ret = False;
2047                 }
2048         }
2049
2050         return ret;
2051 }
2052
2053 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2054                                   struct policy_handle *handle)
2055 {
2056         NTSTATUS status;
2057         struct samr_QueryGroupMember r;
2058         BOOL ret = True;
2059
2060         printf("Testing QueryGroupMember\n");
2061
2062         r.in.group_handle = handle;
2063
2064         status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2065         if (!NT_STATUS_IS_OK(status)) {
2066                 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2067                 ret = False;
2068         }
2069
2070         return ret;
2071 }
2072
2073
2074 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2075                               struct policy_handle *handle)
2076 {
2077         NTSTATUS status;
2078         struct samr_QueryGroupInfo r;
2079         struct samr_SetGroupInfo s;
2080         uint16_t levels[] = {1, 2, 3, 4};
2081         uint16_t set_ok[] = {0, 1, 1, 1};
2082         int i;
2083         BOOL ret = True;
2084
2085         for (i=0;i<ARRAY_SIZE(levels);i++) {
2086                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2087
2088                 r.in.group_handle = handle;
2089                 r.in.level = levels[i];
2090
2091                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2092                 if (!NT_STATUS_IS_OK(status)) {
2093                         printf("QueryGroupInfo level %u failed - %s\n", 
2094                                levels[i], nt_errstr(status));
2095                         ret = False;
2096                 }
2097
2098                 printf("Testing SetGroupInfo level %u\n", levels[i]);
2099
2100                 s.in.group_handle = handle;
2101                 s.in.level = levels[i];
2102                 s.in.info = r.out.info;
2103
2104 #if 0
2105                 /* disabled this, as it changes the name only from the point of view of samr, 
2106                    but leaves the name from the point of view of w2k3 internals (and ldap). This means
2107                    the name is still reserved, so creating the old name fails, but deleting by the old name
2108                    also fails */
2109                 if (s.in.level == 2) {
2110                         init_lsa_String(&s.in.info->string, "NewName");
2111                 }
2112 #endif
2113
2114                 if (s.in.level == 4) {
2115                         init_lsa_String(&s.in.info->description, "test description");
2116                 }
2117
2118                 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2119                 if (set_ok[i]) {
2120                         if (!NT_STATUS_IS_OK(status)) {
2121                                 printf("SetGroupInfo level %u failed - %s\n", 
2122                                        r.in.level, nt_errstr(status));
2123                                 ret = False;
2124                                 continue;
2125                         }
2126                 } else {
2127                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2128                                 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
2129                                        r.in.level, nt_errstr(status));
2130                                 ret = False;
2131                                 continue;
2132                         }
2133                 }
2134         }
2135
2136         return ret;
2137 }
2138
2139 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2140                                struct policy_handle *handle)
2141 {
2142         NTSTATUS status;
2143         struct samr_QueryUserInfo r;
2144         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2145                            11, 12, 13, 14, 16, 17, 20, 21};
2146         int i;
2147         BOOL ret = True;
2148
2149         for (i=0;i<ARRAY_SIZE(levels);i++) {
2150                 printf("Testing QueryUserInfo level %u\n", levels[i]);
2151
2152                 r.in.user_handle = handle;
2153                 r.in.level = levels[i];
2154
2155                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2156                 if (!NT_STATUS_IS_OK(status)) {
2157                         printf("QueryUserInfo level %u failed - %s\n", 
2158                                levels[i], nt_errstr(status));
2159                         ret = False;
2160                 }
2161         }
2162
2163         return ret;
2164 }
2165
2166 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2167                                 struct policy_handle *handle)
2168 {
2169         NTSTATUS status;
2170         struct samr_QueryUserInfo2 r;
2171         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2172                            11, 12, 13, 14, 16, 17, 20, 21};
2173         int i;
2174         BOOL ret = True;
2175
2176         for (i=0;i<ARRAY_SIZE(levels);i++) {
2177                 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2178
2179                 r.in.user_handle = handle;
2180                 r.in.level = levels[i];
2181
2182                 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2183                 if (!NT_STATUS_IS_OK(status)) {
2184                         printf("QueryUserInfo2 level %u failed - %s\n", 
2185                                levels[i], nt_errstr(status));
2186                         ret = False;
2187                 }
2188         }
2189
2190         return ret;
2191 }
2192
2193 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2194                           struct policy_handle *handle, uint32_t rid)
2195 {
2196         NTSTATUS status;
2197         struct samr_OpenUser r;
2198         struct policy_handle user_handle;
2199         BOOL ret = True;
2200
2201         printf("Testing OpenUser(%u)\n", rid);
2202
2203         r.in.domain_handle = handle;
2204         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2205         r.in.rid = rid;
2206         r.out.user_handle = &user_handle;
2207
2208         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2209         if (!NT_STATUS_IS_OK(status)) {
2210                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2211                 return False;
2212         }
2213
2214         if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2215                 ret = False;
2216         }
2217
2218         if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2219                 ret = False;
2220         }
2221
2222         if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2223                 ret = False;
2224         }
2225
2226         if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2227                 ret = False;
2228         }
2229
2230         if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2231                 ret = False;
2232         }
2233
2234         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2235                 ret = False;
2236         }
2237
2238         return ret;
2239 }
2240
2241 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2242                            struct policy_handle *handle, uint32_t rid)
2243 {
2244         NTSTATUS status;
2245         struct samr_OpenGroup r;
2246         struct policy_handle group_handle;
2247         BOOL ret = True;
2248
2249         printf("Testing OpenGroup(%u)\n", rid);
2250
2251         r.in.domain_handle = handle;
2252         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2253         r.in.rid = rid;
2254         r.out.group_handle = &group_handle;
2255
2256         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2257         if (!NT_STATUS_IS_OK(status)) {
2258                 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2259                 return False;
2260         }
2261
2262         if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2263                 ret = False;
2264         }
2265
2266         if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2267                 ret = False;
2268         }
2269
2270         if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2271                 ret = False;
2272         }
2273
2274         if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2275                 ret = False;
2276         }
2277
2278         return ret;
2279 }
2280
2281 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2282                            struct policy_handle *handle, uint32_t rid)
2283 {
2284         NTSTATUS status;
2285         struct samr_OpenAlias r;
2286         struct policy_handle alias_handle;
2287         BOOL ret = True;
2288
2289         printf("Testing OpenAlias(%u)\n", rid);
2290
2291         r.in.domain_handle = handle;
2292         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2293         r.in.rid = rid;
2294         r.out.alias_handle = &alias_handle;
2295
2296         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2297         if (!NT_STATUS_IS_OK(status)) {
2298                 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
2299                 return False;
2300         }
2301
2302         if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
2303                 ret = False;
2304         }
2305
2306         if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
2307                 ret = False;
2308         }
2309
2310         if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
2311                 ret = False;
2312         }
2313
2314         if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
2315                 ret = False;
2316         }
2317
2318         return ret;
2319 }
2320
2321 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2322                                  struct policy_handle *handle)
2323 {
2324         NTSTATUS status;
2325         struct samr_EnumDomainUsers r;
2326         uint32_t resume_handle=0;
2327         int i;
2328         BOOL ret = True;
2329         struct samr_LookupNames n;
2330         struct samr_LookupRids  lr ;
2331
2332         printf("Testing EnumDomainUsers\n");
2333
2334         r.in.domain_handle = handle;
2335         r.in.resume_handle = &resume_handle;
2336         r.in.acct_flags = 0;
2337         r.in.max_size = (uint32_t)-1;
2338         r.out.resume_handle = &resume_handle;
2339
2340         status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
2341         if (!NT_STATUS_IS_OK(status)) {
2342                 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
2343                 return False;
2344         }
2345         
2346         if (!r.out.sam) {
2347                 return False;
2348         }
2349
2350         if (r.out.sam->count == 0) {
2351                 return True;
2352         }
2353
2354         for (i=0;i<r.out.sam->count;i++) {
2355                 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2356                         ret = False;
2357                 }
2358         }
2359
2360         printf("Testing LookupNames\n");
2361         n.in.domain_handle = handle;
2362         n.in.num_names = r.out.sam->count;
2363         n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
2364         for (i=0;i<r.out.sam->count;i++) {
2365                 n.in.names[i].string = r.out.sam->entries[i].name.string;
2366         }
2367         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2368         if (!NT_STATUS_IS_OK(status)) {
2369                 printf("LookupNames failed - %s\n", nt_errstr(status));
2370                 ret = False;
2371         }
2372
2373
2374         printf("Testing LookupRids\n");
2375         lr.in.domain_handle = handle;
2376         lr.in.num_rids = r.out.sam->count;
2377         lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
2378         for (i=0;i<r.out.sam->count;i++) {
2379                 lr.in.rids[i] = r.out.sam->entries[i].idx;
2380         }
2381         status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
2382         if (!NT_STATUS_IS_OK(status)) {
2383                 printf("LookupRids failed - %s\n", nt_errstr(status));
2384                 ret = False;
2385         }
2386
2387         return ret;     
2388 }
2389
2390 /*
2391   try blasting the server with a bunch of sync requests
2392 */
2393 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2394                                        struct policy_handle *handle)
2395 {
2396         NTSTATUS status;
2397         struct samr_EnumDomainUsers r;
2398         uint32_t resume_handle=0;
2399         int i;
2400 #define ASYNC_COUNT 100
2401         struct rpc_request *req[ASYNC_COUNT];
2402
2403         if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
2404                 printf("samr async test disabled - enable dangerous tests to use\n");
2405                 return True;
2406         }
2407
2408         printf("Testing EnumDomainUsers_async\n");
2409
2410         r.in.domain_handle = handle;
2411         r.in.resume_handle = &resume_handle;
2412         r.in.acct_flags = 0;
2413         r.in.max_size = (uint32_t)-1;
2414         r.out.resume_handle = &resume_handle;
2415
2416         for (i=0;i<ASYNC_COUNT;i++) {
2417                 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
2418         }
2419
2420         for (i=0;i<ASYNC_COUNT;i++) {
2421                 status = dcerpc_ndr_request_recv(req[i]);
2422                 if (!NT_STATUS_IS_OK(status)) {
2423                         printf("EnumDomainUsers[%d] failed - %s\n", 
2424                                i, nt_errstr(status));
2425                         return False;
2426                 }
2427         }
2428         
2429         printf("%d async requests OK\n", i);
2430
2431         return True;
2432 }
2433
2434 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2435                                   struct policy_handle *handle)
2436 {
2437         NTSTATUS status;
2438         struct samr_EnumDomainGroups r;
2439         uint32_t resume_handle=0;
2440         int i;
2441         BOOL ret = True;
2442
2443         printf("Testing EnumDomainGroups\n");
2444
2445         r.in.domain_handle = handle;
2446         r.in.resume_handle = &resume_handle;
2447         r.in.max_size = (uint32_t)-1;
2448         r.out.resume_handle = &resume_handle;
2449
2450         status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2451         if (!NT_STATUS_IS_OK(status)) {
2452                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2453                 return False;
2454         }
2455         
2456         if (!r.out.sam) {
2457                 return False;
2458         }
2459
2460         for (i=0;i<r.out.sam->count;i++) {
2461                 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2462                         ret = False;
2463                 }
2464         }
2465
2466         return ret;
2467 }
2468
2469 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2470                                    struct policy_handle *handle)
2471 {
2472         NTSTATUS status;
2473         struct samr_EnumDomainAliases r;
2474         uint32_t resume_handle=0;
2475         int i;
2476         BOOL ret = True;
2477
2478         printf("Testing EnumDomainAliases\n");
2479
2480         r.in.domain_handle = handle;
2481         r.in.resume_handle = &resume_handle;
2482         r.in.acct_flags = (uint32_t)-1;
2483         r.out.resume_handle = &resume_handle;
2484
2485         status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
2486         if (!NT_STATUS_IS_OK(status)) {
2487                 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
2488                 return False;
2489         }
2490         
2491         if (!r.out.sam) {
2492                 return False;
2493         }
2494
2495         for (i=0;i<r.out.sam->count;i++) {
2496                 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2497                         ret = False;
2498                 }
2499         }
2500
2501         return ret;     
2502 }
2503
2504 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2505                                             struct policy_handle *handle)
2506 {
2507         NTSTATUS status;
2508         struct samr_GetDisplayEnumerationIndex r;
2509         BOOL ret = True;
2510         uint16_t levels[] = {1, 2, 3, 4, 5};
2511         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2512         int i;
2513
2514         for (i=0;i<ARRAY_SIZE(levels);i++) {
2515                 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
2516
2517                 r.in.domain_handle = handle;
2518                 r.in.level = levels[i];
2519                 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2520
2521                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2522
2523                 if (ok_lvl[i] && 
2524                     !NT_STATUS_IS_OK(status) &&
2525                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2526                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
2527                                levels[i], nt_errstr(status));
2528                         ret = False;
2529                 }
2530
2531                 init_lsa_String(&r.in.name, "zzzzzzzz");
2532
2533                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2534                 
2535                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2536                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
2537                                levels[i], nt_errstr(status));
2538                         ret = False;
2539                 }
2540         }
2541         
2542         return ret;     
2543 }
2544
2545 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2546                                              struct policy_handle *handle)
2547 {
2548         NTSTATUS status;
2549         struct samr_GetDisplayEnumerationIndex2 r;
2550         BOOL ret = True;
2551         uint16_t levels[] = {1, 2, 3, 4, 5};
2552         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2553         int i;
2554
2555         for (i=0;i<ARRAY_SIZE(levels);i++) {
2556                 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2557
2558                 r.in.domain_handle = handle;
2559                 r.in.level = levels[i];
2560                 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2561
2562                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2563                 if (ok_lvl[i] && 
2564                     !NT_STATUS_IS_OK(status) && 
2565                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2566                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
2567                                levels[i], nt_errstr(status));
2568                         ret = False;
2569                 }
2570
2571                 init_lsa_String(&r.in.name, "zzzzzzzz");
2572
2573                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2574                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2575                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
2576                                levels[i], nt_errstr(status));
2577                         ret = False;
2578                 }
2579         }
2580         
2581         return ret;     
2582 }
2583
2584 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2585                                   struct policy_handle *handle)
2586 {
2587         NTSTATUS status;
2588         struct samr_QueryDisplayInfo r;
2589         BOOL ret = True;
2590         uint16_t levels[] = {1, 2, 3, 4, 5};
2591         int i;
2592
2593         for (i=0;i<ARRAY_SIZE(levels);i++) {
2594                 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2595
2596                 r.in.domain_handle = handle;
2597                 r.in.level = levels[i];
2598                 r.in.start_idx = 0;
2599                 r.in.max_entries = 1000;
2600                 r.in.buf_size = (uint32_t)-1;
2601
2602                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2603                 if (!NT_STATUS_IS_OK(status)) {
2604                         printf("QueryDisplayInfo level %u failed - %s\n", 
2605                                levels[i], nt_errstr(status));
2606                         ret = False;
2607                 }
2608         }
2609         
2610         return ret;     
2611 }
2612
2613 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2614                                   struct policy_handle *handle)
2615 {
2616         NTSTATUS status;
2617         struct samr_QueryDisplayInfo2 r;
2618         BOOL ret = True;
2619         uint16_t levels[] = {1, 2, 3, 4, 5};
2620         int i;
2621
2622         for (i=0;i<ARRAY_SIZE(levels);i++) {
2623                 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2624
2625                 r.in.domain_handle = handle;
2626                 r.in.level = levels[i];
2627                 r.in.start_idx = 0;
2628                 r.in.max_entries = 1000;
2629                 r.in.buf_size = (uint32_t)-1;
2630
2631                 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2632                 if (!NT_STATUS_IS_OK(status)) {
2633                         printf("QueryDisplayInfo2 level %u failed - %s\n", 
2634                                levels[i], nt_errstr(status));
2635                         ret = False;
2636                 }
2637         }
2638         
2639         return ret;     
2640 }
2641
2642 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2643                                   struct policy_handle *handle)
2644 {
2645         NTSTATUS status;
2646         struct samr_QueryDisplayInfo3 r;
2647         BOOL ret = True;
2648         uint16_t levels[] = {1, 2, 3, 4, 5};
2649         int i;
2650
2651         for (i=0;i<ARRAY_SIZE(levels);i++) {
2652                 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2653
2654                 r.in.domain_handle = handle;
2655                 r.in.level = levels[i];
2656                 r.in.start_idx = 0;
2657                 r.in.max_entries = 1000;
2658                 r.in.buf_size = (uint32_t)-1;
2659
2660                 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2661                 if (!NT_STATUS_IS_OK(status)) {
2662                         printf("QueryDisplayInfo3 level %u failed - %s\n", 
2663                                levels[i], nt_errstr(status));
2664                         ret = False;
2665                 }
2666         }
2667         
2668         return ret;     
2669 }
2670
2671
2672 static BOOL test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2673                                            struct policy_handle *handle)
2674 {
2675         NTSTATUS status;
2676         struct samr_QueryDisplayInfo r;
2677         BOOL ret = True;
2678
2679         printf("Testing QueryDisplayInfo continuation\n");
2680
2681         r.in.domain_handle = handle;
2682         r.in.level = 1;
2683         r.in.start_idx = 0;
2684         r.in.max_entries = 1;
2685         r.in.buf_size = (uint32_t)-1;
2686
2687         do {
2688                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2689                 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
2690                         if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
2691                                 printf("expected idx %d but got %d\n",
2692                                        r.in.start_idx + 1,
2693                                        r.out.info.info1.entries[0].idx);
2694                                 break;
2695                         }
2696                 }
2697                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
2698                     !NT_STATUS_IS_OK(status)) {
2699                         printf("QueryDisplayInfo level %u failed - %s\n", 
2700                                r.in.level, nt_errstr(status));
2701                         ret = False;
2702                         break;
2703                 }
2704                 r.in.start_idx++;
2705         } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
2706                   NT_STATUS_IS_OK(status)) &&
2707                  r.out.returned_size != 0);
2708         
2709         return ret;     
2710 }
2711
2712 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2713                                  struct policy_handle *handle)
2714 {
2715         NTSTATUS status;
2716         struct samr_QueryDomainInfo r;
2717         struct samr_SetDomainInfo s;
2718         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2719         uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
2720         int i;
2721         BOOL ret = True;
2722         const char *domain_comment = talloc_asprintf(mem_ctx, 
2723                                   "Tortured by Samba4 RPC-SAMR: %s", 
2724                                   timestring(mem_ctx, time(NULL)));
2725
2726         s.in.domain_handle = handle;
2727         s.in.level = 4;
2728         s.in.info = talloc(mem_ctx, union samr_DomainInfo);
2729         
2730         s.in.info->info4.comment.string = domain_comment;
2731         status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2732         if (!NT_STATUS_IS_OK(status)) {
2733                 printf("SetDomainInfo level %u (set comment) failed - %s\n", 
2734                        r.in.level, nt_errstr(status));
2735                 return False;
2736         }
2737
2738         for (i=0;i<ARRAY_SIZE(levels);i++) {
2739                 printf("Testing QueryDomainInfo level %u\n", levels[i]);
2740
2741                 r.in.domain_handle = handle;
2742                 r.in.level = levels[i];
2743
2744                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2745                 if (!NT_STATUS_IS_OK(status)) {
2746                         printf("QueryDomainInfo level %u failed - %s\n", 
2747                                r.in.level, nt_errstr(status));
2748                         ret = False;
2749                         continue;
2750                 }
2751
2752                 switch (levels[i]) {
2753                 case 2:
2754                         if (strcmp(r.out.info->info2.comment.string, domain_comment) != 0) {
2755                                 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
2756                                        levels[i], r.out.info->info2.comment.string, domain_comment);
2757                                 ret = False;
2758                         }
2759                         break;
2760                 case 4:
2761                         if (strcmp(r.out.info->info4.comment.string, domain_comment) != 0) {
2762                                 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
2763                                        levels[i], r.out.info->info4.comment.string, domain_comment);
2764                                 ret = False;
2765                         }
2766                         break;
2767                 case 11:
2768                         if (strcmp(r.out.info->info11.info2.comment.string, domain_comment) != 0) {
2769                                 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
2770                                        levels[i], r.out.info->info11.info2.comment.string, domain_comment);
2771                                 ret = False;
2772                         }
2773                         break;
2774                 }
2775
2776                 printf("Testing SetDomainInfo level %u\n", levels[i]);
2777
2778                 s.in.domain_handle = handle;
2779                 s.in.level = levels[i];
2780                 s.in.info = r.out.info;
2781
2782                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2783                 if (set_ok[i]) {
2784                         if (!NT_STATUS_IS_OK(status)) {
2785                                 printf("SetDomainInfo level %u failed - %s\n", 
2786                                        r.in.level, nt_errstr(status));
2787                                 ret = False;
2788                                 continue;
2789                         }
2790                 } else {
2791                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2792                                 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
2793                                        r.in.level, nt_errstr(status));
2794                                 ret = False;
2795                                 continue;
2796                         }
2797                 }
2798
2799                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2800                 if (!NT_STATUS_IS_OK(status)) {
2801                         printf("QueryDomainInfo level %u failed - %s\n", 
2802                                r.in.level, nt_errstr(status));
2803                         ret = False;
2804                         continue;
2805                 }
2806         }
2807
2808         return True;    
2809 }
2810
2811
2812 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2813                                   struct policy_handle *handle)
2814 {
2815         NTSTATUS status;
2816         struct samr_QueryDomainInfo2 r;
2817         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2818         int i;
2819         BOOL ret = True;
2820
2821         for (i=0;i<ARRAY_SIZE(levels);i++) {
2822                 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
2823
2824                 r.in.domain_handle = handle;
2825                 r.in.level = levels[i];
2826
2827                 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
2828                 if (!NT_STATUS_IS_OK(status)) {
2829                         printf("QueryDomainInfo2 level %u failed - %s\n", 
2830                                r.in.level, nt_errstr(status));
2831                         ret = False;
2832                         continue;
2833                 }
2834         }
2835
2836         return True;    
2837 }
2838
2839 /* Test whether querydispinfo level 5 and enumdomgroups return the same
2840    set of group names. */
2841 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2842                            struct policy_handle *handle)
2843 {
2844         struct samr_EnumDomainGroups q1;
2845         struct samr_QueryDisplayInfo q2;
2846         NTSTATUS status;
2847         uint32_t resume_handle=0;
2848         int i;
2849         BOOL ret = True;
2850
2851         int num_names = 0;
2852         const char **names = NULL;
2853
2854         printf("Testing coherency of querydispinfo vs enumdomgroups\n");
2855
2856         q1.in.domain_handle = handle;
2857         q1.in.resume_handle = &resume_handle;
2858         q1.in.max_size = 5;
2859         q1.out.resume_handle = &resume_handle;
2860
2861         status = STATUS_MORE_ENTRIES;
2862         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2863                 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
2864
2865                 if (!NT_STATUS_IS_OK(status) &&
2866                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2867                         break;
2868
2869                 for (i=0; i<q1.out.num_entries; i++) {
2870                         add_string_to_array(mem_ctx,
2871                                             q1.out.sam->entries[i].name.string,
2872                                             &names, &num_names);
2873                 }
2874         }
2875
2876         if (!NT_STATUS_IS_OK(status)) {
2877                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2878                 return False;
2879         }
2880         
2881         if (!q1.out.sam) {
2882                 return False;
2883         }
2884
2885         q2.in.domain_handle = handle;
2886         q2.in.level = 5;
2887         q2.in.start_idx = 0;
2888         q2.in.max_entries = 5;
2889         q2.in.buf_size = (uint32_t)-1;
2890
2891         status = STATUS_MORE_ENTRIES;
2892         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2893                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
2894
2895                 if (!NT_STATUS_IS_OK(status) &&
2896                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2897                         break;
2898
2899                 for (i=0; i<q2.out.info.info5.count; i++) {
2900                         int j;
2901                         const char *name = q2.out.info.info5.entries[i].account_name.string;
2902                         BOOL found = False;
2903                         for (j=0; j<num_names; j++) {
2904                                 if (names[j] == NULL)
2905                                         continue;
2906                                 /* Hmm. No strequal in samba4 */
2907                                 if (strequal(names[j], name)) {
2908                                         names[j] = NULL;
2909                                         found = True;
2910                                         break;
2911                                 }
2912                         }
2913
2914                         if (!found) {
2915                                 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
2916                                        name);
2917                                 ret = False;
2918                         }
2919                 }
2920                 q2.in.start_idx += q2.out.info.info5.count;
2921         }
2922
2923         if (!NT_STATUS_IS_OK(status)) {
2924                 printf("QueryDisplayInfo level 5 failed - %s\n",
2925                        nt_errstr(status));
2926                 ret = False;
2927         }
2928
2929         for (i=0; i<num_names; i++) {
2930                 if (names[i] != NULL) {
2931                         printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
2932                                names[i]);
2933                         ret = False;
2934                 }
2935         }
2936
2937         return ret;
2938 }
2939
2940 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2941                                    struct policy_handle *group_handle)
2942 {
2943         struct samr_DeleteDomainGroup d;
2944         NTSTATUS status;
2945         BOOL ret = True;
2946
2947         printf("Testing DeleteDomainGroup\n");
2948
2949         d.in.group_handle = group_handle;
2950         d.out.group_handle = group_handle;
2951
2952         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2953         if (!NT_STATUS_IS_OK(status)) {
2954                 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
2955                 ret = False;
2956         }
2957
2958         return ret;
2959 }
2960
2961 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2962                                             struct policy_handle *domain_handle)
2963 {
2964         struct samr_TestPrivateFunctionsDomain r;
2965         NTSTATUS status;
2966         BOOL ret = True;
2967
2968         printf("Testing TestPrivateFunctionsDomain\n");
2969
2970         r.in.domain_handle = domain_handle;
2971
2972         status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
2973         if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2974                 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
2975                 ret = False;
2976         }
2977
2978         return ret;
2979 }
2980
2981 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2982                           struct dom_sid *domain_sid,
2983                           struct policy_handle *domain_handle)
2984 {
2985         struct samr_RidToSid r;
2986         NTSTATUS status;
2987         BOOL ret = True;
2988         struct dom_sid *calc_sid;
2989         int rids[] = { 0, 42, 512, 10200 };
2990         int i;
2991
2992         for (i=0;i<ARRAY_SIZE(rids);i++) {
2993         
2994                 printf("Testing RidToSid\n");
2995                 
2996                 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
2997                 r.in.domain_handle = domain_handle;
2998                 r.in.rid = rids[i];
2999                 
3000                 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
3001                 if (!NT_STATUS_IS_OK(status)) {
3002                         printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
3003                         ret = False;
3004                 } else {
3005                         calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
3006
3007                         if (!dom_sid_equal(calc_sid, r.out.sid)) {
3008                                 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i], 
3009                                        dom_sid_string(mem_ctx, r.out.sid), 
3010                                        dom_sid_string(mem_ctx, calc_sid));
3011                                 ret = False;
3012                         }
3013                 }
3014         }
3015
3016         return ret;
3017 }
3018
3019 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3020                                        struct policy_handle *domain_handle)
3021 {
3022         struct samr_GetBootKeyInformation r;
3023         NTSTATUS status;
3024         BOOL ret = True;
3025
3026         printf("Testing GetBootKeyInformation\n");
3027
3028         r.in.domain_handle = domain_handle;
3029
3030         status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
3031         if (!NT_STATUS_IS_OK(status)) {
3032                 /* w2k3 seems to fail this sometimes and pass it sometimes */
3033                 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
3034         }
3035
3036         return ret;
3037 }
3038
3039 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3040                                 struct policy_handle *domain_handle,
3041                                 struct policy_handle *group_handle)
3042 {
3043         NTSTATUS status;
3044         struct samr_AddGroupMember r;
3045         struct samr_DeleteGroupMember d;
3046         struct samr_QueryGroupMember q;
3047         struct samr_SetMemberAttributesOfGroup s;
3048         BOOL ret = True;
3049         uint32_t rid;
3050
3051         status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
3052         if (!NT_STATUS_IS_OK(status)) {
3053                 return False;
3054         }
3055
3056         r.in.group_handle = group_handle;
3057         r.in.rid = rid;
3058         r.in.flags = 0; /* ??? */
3059
3060         printf("Testing AddGroupMember and DeleteGroupMember\n");
3061
3062         d.in.group_handle = group_handle;
3063         d.in.rid = rid;
3064
3065         status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
3066         if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
3067                 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n", 
3068                        nt_errstr(status));
3069                 return False;
3070         }
3071
3072         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3073         if (!NT_STATUS_IS_OK(status)) {
3074                 printf("AddGroupMember failed - %s\n", nt_errstr(status));
3075                 return False;
3076         }
3077
3078         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3079         if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
3080                 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n", 
3081                        nt_errstr(status));
3082                 return False;
3083         }
3084
3085         if (lp_parm_bool(-1, "target", "samba4", False)) {
3086                 printf("skipping SetMemberAttributesOfGroup test against Samba4\n");
3087         } else {
3088                 /* this one is quite strange. I am using random inputs in the
3089                    hope of triggering an error that might give us a clue */
3090
3091                 s.in.group_handle = group_handle;
3092                 s.in.unknown1 = random();
3093                 s.in.unknown2 = random();
3094
3095                 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
3096                 if (!NT_STATUS_IS_OK(status)) {
3097                         printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
3098                         return False;
3099                 }
3100         }
3101
3102         q.in.group_handle = group_handle;
3103
3104         status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
3105         if (!NT_STATUS_IS_OK(status)) {
3106                 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
3107                 return False;
3108         }
3109
3110         status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
3111         if (!NT_STATUS_IS_OK(status)) {
3112                 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
3113                 return False;
3114         }
3115
3116         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3117         if (!NT_STATUS_IS_OK(status)) {
3118                 printf("AddGroupMember failed - %s\n", nt_errstr(status));
3119                 return False;
3120         }
3121
3122         return ret;
3123 }
3124
3125
3126 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3127                                    struct policy_handle *domain_handle, struct policy_handle *group_handle)
3128 {
3129         NTSTATUS status;
3130         struct samr_CreateDomainGroup r;
3131         uint32_t rid;
3132         struct lsa_String name;
3133         BOOL ret = True;
3134
3135         init_lsa_String(&name, TEST_GROUPNAME);
3136
3137         r.in.domain_handle = domain_handle;
3138         r.in.name = &name;
3139         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3140         r.out.group_handle = group_handle;
3141         r.out.rid = &rid;
3142
3143         printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
3144
3145         status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3146
3147         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3148                 printf("Server refused create of '%s'\n", r.in.name->string);
3149                 ZERO_STRUCTP(group_handle);
3150                 return True;
3151         }
3152
3153         if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS) ||
3154             NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3155                 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
3156                         return False;
3157                 }
3158                 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3159         }
3160         if (!NT_STATUS_IS_OK(status)) {
3161                 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
3162                 return False;
3163         }
3164
3165         if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
3166                 ret = False;
3167         }
3168
3169         if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
3170                 ret = False;
3171         }
3172
3173         return ret;
3174 }
3175
3176
3177 /*
3178   its not totally clear what this does. It seems to accept any sid you like.
3179 */
3180 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p, 
3181                                                TALLOC_CTX *mem_ctx, 
3182                                                struct policy_handle *domain_handle)
3183 {
3184         NTSTATUS status;
3185         struct samr_RemoveMemberFromForeignDomain r;
3186
3187         r.in.domain_handle = domain_handle;
3188         r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
3189
3190         status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
3191         if (!NT_STATUS_IS_OK(status)) {
3192                 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
3193                 return False;
3194         }
3195
3196         return True;
3197 }
3198
3199
3200
3201 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3202                          struct policy_handle *handle);
3203
3204 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3205                             struct policy_handle *handle, struct dom_sid *sid,
3206                             enum torture_samr_choice which_ops)
3207 {
3208         NTSTATUS status;
3209         struct samr_OpenDomain r;
3210         struct policy_handle domain_handle;
3211         struct policy_handle alias_handle;
3212         struct policy_handle group_handle;
3213         BOOL ret = True;
3214
3215         ZERO_STRUCT(alias_handle);
3216         ZERO_STRUCT(group_handle);
3217         ZERO_STRUCT(domain_handle);
3218
3219         printf("Testing OpenDomain\n");
3220
3221         r.in.connect_handle = handle;
3222         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3223         r.in.sid = sid;
3224         r.out.domain_handle = &domain_handle;
3225
3226         status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
3227         if (!NT_STATUS_IS_OK(status)) {
3228                 printf("OpenDomain failed - %s\n", nt_errstr(status));
3229                 return False;
3230         }
3231
3232         /* run the domain tests with the main handle closed - this tests
3233            the servers reference counting */
3234         ret &= test_samr_handle_Close(p, mem_ctx, handle);
3235
3236         switch (which_ops) {
3237         case TORTURE_SAMR_USER_ATTRIBUTES:
3238         case TORTURE_SAMR_PASSWORDS:
3239                 ret &= test_CreateUser(p, mem_ctx, &domain_handle, which_ops);
3240                 ret &= test_CreateUser2(p, mem_ctx, &domain_handle, which_ops);
3241                 break;
3242         case TORTURE_SAMR_OTHER:
3243                 ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
3244                 ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
3245                 ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
3246                 ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
3247                 ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
3248                 ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
3249                 ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
3250                 ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
3251                 ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
3252                 ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
3253                 ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
3254                 ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
3255                 ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
3256                 ret &= test_QueryDisplayInfo_continue(p, mem_ctx, &domain_handle);
3257                 
3258                 if (lp_parm_bool(-1, "target", "samba4", False)) {
3259                         printf("skipping GetDisplayEnumerationIndex test against Samba4\n");
3260                 } else {
3261                         ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
3262                         ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
3263                 }
3264                 ret &= test_GroupList(p, mem_ctx, &domain_handle);
3265                 ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
3266                 ret &= test_RidToSid(p, mem_ctx, sid, &domain_handle);
3267                 ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
3268                 break;
3269         }
3270
3271         if (!policy_handle_empty(&alias_handle) &&
3272             !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
3273                 ret = False;
3274         }
3275
3276         if (!policy_handle_empty(&group_handle) &&
3277             !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
3278                 ret = False;
3279         }
3280
3281         ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
3282
3283         /* reconnect the main handle */
3284         ret &= test_Connect(p, mem_ctx, handle);
3285
3286         return ret;
3287 }
3288
3289 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3290                               struct policy_handle *handle, const char *domain,
3291                               enum torture_samr_choice which_ops)
3292 {
3293         NTSTATUS status;
3294         struct samr_LookupDomain r;
3295         struct lsa_String n1;
3296         struct lsa_String n2;
3297         BOOL ret = True;
3298
3299         printf("Testing LookupDomain(%s)\n", domain);
3300
3301         /* check for correct error codes */
3302         r.in.connect_handle = handle;
3303         r.in.domain_name = &n2;
3304         n2.string = NULL;
3305
3306         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3307         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
3308                 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
3309                 ret = False;
3310         }
3311
3312         init_lsa_String(&n2, "xxNODOMAINxx");
3313
3314         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3315         if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
3316                 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
3317                 ret = False;
3318         }
3319
3320         r.in.connect_handle = handle;
3321
3322         init_lsa_String(&n1, domain);
3323         r.in.domain_name = &n1;
3324
3325         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3326         if (!NT_STATUS_IS_OK(status)) {
3327                 printf("LookupDomain failed - %s\n", nt_errstr(status));
3328                 ret = False;
3329         }
3330
3331         if (!test_GetDomPwInfo(p, mem_ctx, &n1)) {
3332                 ret = False;
3333         }
3334
3335         if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid, which_ops)) {
3336                 ret = False;
3337         }
3338
3339         return ret;
3340 }
3341
3342
3343 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3344                              struct policy_handle *handle, enum torture_samr_choice which_ops)
3345 {
3346         NTSTATUS status;
3347         struct samr_EnumDomains r;
3348         uint32_t resume_handle = 0;
3349         int i;
3350         BOOL ret = True;
3351
3352         r.in.connect_handle = handle;
3353         r.in.resume_handle = &resume_handle;
3354         r.in.buf_size = (uint32_t)-1;
3355         r.out.resume_handle = &resume_handle;
3356
3357         status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3358         if (!NT_STATUS_IS_OK(status)) {
3359                 printf("EnumDomains failed - %s\n", nt_errstr(status));
3360                 return False;
3361         }
3362
3363         if (!r.out.sam) {
3364                 return False;
3365         }
3366
3367         for (i=0;i<r.out.sam->count;i++) {
3368                 if (!test_LookupDomain(p, mem_ctx, handle, 
3369                                        r.out.sam->entries[i].name.string, which_ops)) {
3370                         ret = False;
3371                 }
3372         }
3373
3374         status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3375         if (!NT_STATUS_IS_OK(status)) {
3376                 printf("EnumDomains failed - %s\n", nt_errstr(status));
3377                 return False;
3378         }
3379
3380         return ret;
3381 }
3382
3383
3384 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3385                          struct policy_handle *handle)
3386 {
3387         NTSTATUS status;
3388         struct samr_Connect r;
3389         struct samr_Connect2 r2;
3390         struct samr_Connect3 r3;
3391         struct samr_Connect4 r4;
3392         struct samr_Connect5 r5;
3393         union samr_ConnectInfo info;
3394         struct policy_handle h;
3395         BOOL ret = True, got_handle = False;
3396
3397         printf("testing samr_Connect\n");
3398
3399         r.in.system_name = 0;
3400         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3401         r.out.connect_handle = &h;
3402
3403         status = dcerpc_samr_Connect(p, mem_ctx, &r);
3404         if (!NT_STATUS_IS_OK(status)) {
3405                 printf("Connect failed - %s\n", nt_errstr(status));
3406                 ret = False;
3407         } else {
3408                 got_handle = True;
3409                 *handle = h;
3410         }
3411
3412         printf("testing samr_Connect2\n");
3413
3414         r2.in.system_name = NULL;
3415         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3416         r2.out.connect_handle = &h;
3417
3418         status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
3419         if (!NT_STATUS_IS_OK(status)) {
3420                 printf("Connect2 failed - %s\n", nt_errstr(status));
3421                 ret = False;
3422         } else {
3423                 if (got_handle) {
3424                         test_samr_handle_Close(p, mem_ctx, handle);
3425                 }
3426                 got_handle = True;
3427                 *handle = h;
3428         }
3429
3430         printf("testing samr_Connect3\n");
3431
3432         r3.in.system_name = NULL;
3433         r3.in.unknown = 0;
3434         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3435         r3.out.connect_handle = &h;
3436
3437         status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
3438         if (!NT_STATUS_IS_OK(status)) {
3439                 printf("Connect3 failed - %s\n", nt_errstr(status));
3440                 ret = False;
3441         } else {
3442                 if (got_handle) {
3443                         test_samr_handle_Close(p, mem_ctx, handle);
3444                 }
3445                 got_handle = True;
3446                 *handle = h;
3447         }
3448
3449         printf("testing samr_Connect4\n");
3450
3451         r4.in.system_name = "";
3452         r4.in.unknown = 0;
3453         r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3454         r4.out.connect_handle = &h;
3455
3456         status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
3457         if (!NT_STATUS_IS_OK(status)) {
3458                 printf("Connect4 failed - %s\n", nt_errstr(status));
3459                 ret = False;
3460         } else {
3461                 if (got_handle) {
3462                         test_samr_handle_Close(p, mem_ctx, handle);
3463                 }
3464                 got_handle = True;
3465                 *handle = h;
3466         }
3467
3468         printf("testing samr_Connect5\n");
3469
3470         info.info1.unknown1 = 0;
3471         info.info1.unknown2 = 0;
3472
3473         r5.in.system_name = "";
3474         r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3475         r5.in.level = 1;
3476         r5.in.info = &info;
3477         r5.out.info = &info;
3478         r5.out.connect_handle = &h;
3479
3480         status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
3481         if (!NT_STATUS_IS_OK(status)) {
3482                 printf("Connect5 failed - %s\n", nt_errstr(status));
3483                 ret = False;
3484         } else {
3485                 if (got_handle) {
3486                         test_samr_handle_Close(p, mem_ctx, handle);
3487                 }
3488                 got_handle = True;
3489                 *handle = h;
3490         }
3491
3492         return ret;
3493 }
3494
3495
3496 BOOL torture_rpc_samr(struct torture_context *torture)
3497 {
3498         NTSTATUS status;
3499         struct dcerpc_pipe *p;
3500         BOOL ret = True;
3501         struct policy_handle handle;
3502
3503         status = torture_rpc_connection(torture, &p, &dcerpc_table_samr);
3504         if (!NT_STATUS_IS_OK(status)) {
3505                 return False;
3506         }
3507
3508         ret &= test_Connect(p, torture, &handle);
3509
3510         ret &= test_QuerySecurity(p, torture, &handle);
3511
3512         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
3513
3514         ret &= test_SetDsrmPassword(p, torture, &handle);
3515
3516         ret &= test_Shutdown(p, torture, &handle);
3517
3518         ret &= test_samr_handle_Close(p, torture, &handle);
3519
3520         return ret;
3521 }
3522
3523
3524 BOOL torture_rpc_samr_users(struct torture_context *torture)
3525 {
3526         NTSTATUS status;
3527         struct dcerpc_pipe *p;
3528         BOOL ret = True;
3529         struct policy_handle handle;
3530
3531         status = torture_rpc_connection(torture, &p, &dcerpc_table_samr);
3532         if (!NT_STATUS_IS_OK(status)) {
3533                 return False;
3534         }
3535
3536         ret &= test_Connect(p, torture, &handle);
3537
3538         ret &= test_QuerySecurity(p, torture, &handle);
3539
3540         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
3541
3542         ret &= test_SetDsrmPassword(p, torture, &handle);
3543
3544         ret &= test_Shutdown(p, torture, &handle);
3545
3546         ret &= test_samr_handle_Close(p, torture, &handle);
3547
3548         return ret;
3549 }
3550
3551
3552 BOOL torture_rpc_samr_passwords(struct torture_context *torture)
3553 {
3554         NTSTATUS status;
3555         struct dcerpc_pipe *p;
3556         BOOL ret = True;
3557         struct policy_handle handle;
3558
3559         status = torture_rpc_connection(torture, &p, &dcerpc_table_samr);
3560         if (!NT_STATUS_IS_OK(status)) {
3561                 return False;
3562         }
3563
3564         ret &= test_Connect(p, torture, &handle);
3565
3566         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
3567
3568         ret &= test_samr_handle_Close(p, torture, &handle);
3569
3570         return ret;
3571 }
3572