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