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