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