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