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