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