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