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