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