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