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