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