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