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