s4-samr: merge samr_GetDisplayEnumerationIndex from s3 idl.
[kai/samba.git] / source4 / torture / rpc / samr.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for samr rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "torture/torture.h"
24 #include "system/time.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_samr_c.h"
27 #include "../lib/crypto/crypto.h"
28 #include "libcli/auth/libcli_auth.h"
29 #include "libcli/security/security.h"
30 #include "torture/rpc/rpc.h"
31
32 #define TEST_ACCOUNT_NAME "samrtorturetest"
33 #define TEST_ALIASNAME "samrtorturetestalias"
34 #define TEST_GROUPNAME "samrtorturetestgroup"
35 #define TEST_MACHINENAME "samrtestmach$"
36 #define TEST_DOMAINNAME "samrtestdom$"
37
38 enum torture_samr_choice {
39         TORTURE_SAMR_PASSWORDS,
40         TORTURE_SAMR_USER_ATTRIBUTES,
41         TORTURE_SAMR_OTHER
42 };
43
44 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
45                                struct policy_handle *handle);
46
47 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
48                                 struct policy_handle *handle);
49
50 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
51                                struct policy_handle *handle);
52
53 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
54                                 const char *acct_name, 
55                                 struct policy_handle *domain_handle, char **password);
56
57 static void init_lsa_String(struct lsa_String *string, const char *s)
58 {
59         string->string = s;
60 }
61
62 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
63 {
64         string->length = length;
65         string->size = length;
66         string->array = (uint16_t *)discard_const(s);
67 }
68
69 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
70                                    struct policy_handle *handle)
71 {
72         NTSTATUS status;
73         struct samr_Close r;
74
75         r.in.handle = handle;
76         r.out.handle = handle;
77
78         status = dcerpc_samr_Close(p, tctx, &r);
79         torture_assert_ntstatus_ok(tctx, status, "Close");
80
81         return true;
82 }
83
84 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
85                        struct policy_handle *handle)
86 {
87         NTSTATUS status;
88         struct samr_Shutdown r;
89
90         if (!torture_setting_bool(tctx, "dangerous", false)) {
91                 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
92                 return true;
93         }
94
95         r.in.connect_handle = handle;
96
97         torture_comment(tctx, "testing samr_Shutdown\n");
98
99         status = dcerpc_samr_Shutdown(p, tctx, &r);
100         torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
101
102         return true;
103 }
104
105 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
106                                  struct policy_handle *handle)
107 {
108         NTSTATUS status;
109         struct samr_SetDsrmPassword r;
110         struct lsa_String string;
111         struct samr_Password hash;
112
113         if (!torture_setting_bool(tctx, "dangerous", false)) {
114                 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
115         }
116
117         E_md4hash("TeSTDSRM123", hash.hash);
118
119         init_lsa_String(&string, "Administrator");
120
121         r.in.name = &string;
122         r.in.unknown = 0;
123         r.in.hash = &hash;
124
125         torture_comment(tctx, "testing samr_SetDsrmPassword\n");
126
127         status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
128         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
129
130         return true;
131 }
132
133
134 static bool test_QuerySecurity(struct dcerpc_pipe *p, 
135                                struct torture_context *tctx, 
136                                struct policy_handle *handle)
137 {
138         NTSTATUS status;
139         struct samr_QuerySecurity r;
140         struct samr_SetSecurity s;
141
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         uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST, 
3280                             ACB_DISABLED, ACB_NORMAL | ACB_DISABLED, 
3281                             ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST, 
3282                             ACB_PWNOEXP, 0};
3283
3284         printf("Testing EnumDomainUsers\n");
3285
3286         for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3287                 r.in.domain_handle = handle;
3288                 r.in.resume_handle = &resume_handle;
3289                 r.in.acct_flags = mask = masks[mask_idx];
3290                 r.in.max_size = (uint32_t)-1;
3291                 r.out.resume_handle = &resume_handle;
3292
3293                 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
3294                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&  
3295                     !NT_STATUS_IS_OK(status)) {
3296                         printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3297                         return false;
3298                 }
3299         
3300                 torture_assert(tctx, r.out.sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
3301
3302                 if (r.out.sam->count == 0) {
3303                         continue;
3304                 }
3305
3306                 for (i=0;i<r.out.sam->count;i++) {
3307                         if (mask) {
3308                                 if (!check_mask(p, tctx, handle, r.out.sam->entries[i].idx, mask)) {
3309                                         ret = false;
3310                                 }
3311                         } else if (!test_OpenUser(p, tctx, handle, r.out.sam->entries[i].idx)) {
3312                                 ret = false;
3313                         }
3314                 }
3315         }
3316
3317         printf("Testing LookupNames\n");
3318         n.in.domain_handle = handle;
3319         n.in.num_names = r.out.sam->count;
3320         n.in.names = talloc_array(tctx, struct lsa_String, r.out.sam->count);
3321         for (i=0;i<r.out.sam->count;i++) {
3322                 n.in.names[i].string = r.out.sam->entries[i].name.string;
3323         }
3324         status = dcerpc_samr_LookupNames(p, tctx, &n);
3325         if (!NT_STATUS_IS_OK(status)) {
3326                 printf("LookupNames failed - %s\n", nt_errstr(status));
3327                 ret = false;
3328         }
3329
3330
3331         printf("Testing LookupRids\n");
3332         lr.in.domain_handle = handle;
3333         lr.in.num_rids = r.out.sam->count;
3334         lr.in.rids = talloc_array(tctx, uint32_t, r.out.sam->count);
3335         for (i=0;i<r.out.sam->count;i++) {
3336                 lr.in.rids[i] = r.out.sam->entries[i].idx;
3337         }
3338         status = dcerpc_samr_LookupRids(p, tctx, &lr);
3339         torture_assert_ntstatus_ok(tctx, status, "LookupRids");
3340
3341         return ret;     
3342 }
3343
3344 /*
3345   try blasting the server with a bunch of sync requests
3346 */
3347 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx, 
3348                                        struct policy_handle *handle)
3349 {
3350         NTSTATUS status;
3351         struct samr_EnumDomainUsers r;
3352         uint32_t resume_handle=0;
3353         int i;
3354 #define ASYNC_COUNT 100
3355         struct rpc_request *req[ASYNC_COUNT];
3356
3357         if (!torture_setting_bool(tctx, "dangerous", false)) {
3358                 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
3359         }
3360
3361         torture_comment(tctx, "Testing EnumDomainUsers_async\n");
3362
3363         r.in.domain_handle = handle;
3364         r.in.resume_handle = &resume_handle;
3365         r.in.acct_flags = 0;
3366         r.in.max_size = (uint32_t)-1;
3367         r.out.resume_handle = &resume_handle;
3368
3369         for (i=0;i<ASYNC_COUNT;i++) {
3370                 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
3371         }
3372
3373         for (i=0;i<ASYNC_COUNT;i++) {
3374                 status = dcerpc_ndr_request_recv(req[i]);
3375                 if (!NT_STATUS_IS_OK(status)) {
3376                         printf("EnumDomainUsers[%d] failed - %s\n", 
3377                                i, nt_errstr(status));
3378                         return false;
3379                 }
3380         }
3381         
3382         torture_comment(tctx, "%d async requests OK\n", i);
3383
3384         return true;
3385 }
3386
3387 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3388                                   struct policy_handle *handle)
3389 {
3390         NTSTATUS status;
3391         struct samr_EnumDomainGroups r;
3392         uint32_t resume_handle=0;
3393         int i;
3394         bool ret = true;
3395
3396         printf("Testing EnumDomainGroups\n");
3397
3398         r.in.domain_handle = handle;
3399         r.in.resume_handle = &resume_handle;
3400         r.in.max_size = (uint32_t)-1;
3401         r.out.resume_handle = &resume_handle;
3402
3403         status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3404         if (!NT_STATUS_IS_OK(status)) {
3405                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3406                 return false;
3407         }
3408         
3409         if (!r.out.sam) {
3410                 return false;
3411         }
3412
3413         for (i=0;i<r.out.sam->count;i++) {
3414                 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3415                         ret = false;
3416                 }
3417         }
3418
3419         return ret;
3420 }
3421
3422 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3423                                    struct policy_handle *handle)
3424 {
3425         NTSTATUS status;
3426         struct samr_EnumDomainAliases r;
3427         uint32_t resume_handle=0;
3428         int i;
3429         bool ret = true;
3430
3431         printf("Testing EnumDomainAliases\n");
3432
3433         r.in.domain_handle = handle;
3434         r.in.resume_handle = &resume_handle;
3435         r.in.acct_flags = (uint32_t)-1;
3436         r.out.resume_handle = &resume_handle;
3437
3438         status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3439         if (!NT_STATUS_IS_OK(status)) {
3440                 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3441                 return false;
3442         }
3443         
3444         if (!r.out.sam) {
3445                 return false;
3446         }
3447
3448         for (i=0;i<r.out.sam->count;i++) {
3449                 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3450                         ret = false;
3451                 }
3452         }
3453
3454         return ret;     
3455 }
3456
3457 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3458                                             struct policy_handle *handle)
3459 {
3460         NTSTATUS status;
3461         struct samr_GetDisplayEnumerationIndex r;
3462         bool ret = true;
3463         uint16_t levels[] = {1, 2, 3, 4, 5};
3464         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3465         struct lsa_String name;
3466         uint32_t idx = 0;
3467         int i;
3468
3469         for (i=0;i<ARRAY_SIZE(levels);i++) {
3470                 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3471
3472                 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3473
3474                 r.in.domain_handle = handle;
3475                 r.in.level = levels[i];
3476                 r.in.name = &name;
3477                 r.out.idx = &idx;
3478
3479                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3480
3481                 if (ok_lvl[i] && 
3482                     !NT_STATUS_IS_OK(status) &&
3483                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3484                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
3485                                levels[i], nt_errstr(status));
3486                         ret = false;
3487                 }
3488
3489                 init_lsa_String(&name, "zzzzzzzz");
3490
3491                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3492                 
3493                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3494                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
3495                                levels[i], nt_errstr(status));
3496                         ret = false;
3497                 }
3498         }
3499         
3500         return ret;     
3501 }
3502
3503 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3504                                              struct policy_handle *handle)
3505 {
3506         NTSTATUS status;
3507         struct samr_GetDisplayEnumerationIndex2 r;
3508         bool ret = true;
3509         uint16_t levels[] = {1, 2, 3, 4, 5};
3510         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3511         int i;
3512
3513         for (i=0;i<ARRAY_SIZE(levels);i++) {
3514                 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3515
3516                 r.in.domain_handle = handle;
3517                 r.in.level = levels[i];
3518                 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3519
3520                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3521                 if (ok_lvl[i] && 
3522                     !NT_STATUS_IS_OK(status) && 
3523                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3524                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
3525                                levels[i], nt_errstr(status));
3526                         ret = false;
3527                 }
3528
3529                 init_lsa_String(&r.in.name, "zzzzzzzz");
3530
3531                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3532                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3533                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
3534                                levels[i], nt_errstr(status));
3535                         ret = false;
3536                 }
3537         }
3538         
3539         return ret;     
3540 }
3541
3542 #define STRING_EQUAL_QUERY(s1, s2, user)                                        \
3543         if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3544                 /* odd, but valid */                                            \
3545         } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3546                         printf("%s mismatch for %s: %s != %s (%s)\n", \
3547                                #s1, user.string,  s1.string, s2.string, __location__);   \
3548                         ret = false; \
3549         }
3550 #define INT_EQUAL_QUERY(s1, s2, user)           \
3551                 if (s1 != s2) { \
3552                         printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3553                                #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3554                         ret = false; \
3555                 }
3556
3557 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3558                                        struct samr_QueryDisplayInfo *querydisplayinfo,
3559                                        bool *seen_testuser) 
3560 {
3561         struct samr_OpenUser r;
3562         struct samr_QueryUserInfo q;
3563         struct policy_handle user_handle;
3564         int i, ret = true;
3565         NTSTATUS status;
3566         r.in.domain_handle = querydisplayinfo->in.domain_handle;
3567         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3568         for (i = 0; ; i++) {
3569                 switch (querydisplayinfo->in.level) {
3570                 case 1:
3571                         if (i >= querydisplayinfo->out.info.info1.count) {
3572                                 return ret;
3573                         }
3574                         r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
3575                         break;
3576                 case 2:
3577                         if (i >= querydisplayinfo->out.info.info2.count) {
3578                                 return ret;
3579                         }
3580                         r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
3581                         break;
3582                 case 3:
3583                         /* Groups */
3584                 case 4:
3585                 case 5:
3586                         /* Not interested in validating just the account name */
3587                         return true;
3588                 }
3589                         
3590                 r.out.user_handle = &user_handle;
3591                 
3592                 switch (querydisplayinfo->in.level) {
3593                 case 1:
3594                 case 2:
3595                         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3596                         if (!NT_STATUS_IS_OK(status)) {
3597                                 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3598                                 return false;
3599                         }
3600                 }
3601                 
3602                 q.in.user_handle = &user_handle;
3603                 q.in.level = 21;
3604                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3605                 if (!NT_STATUS_IS_OK(status)) {
3606                         printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3607                         return false;
3608                 }
3609                 
3610                 switch (querydisplayinfo->in.level) {
3611                 case 1:
3612                         if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3613                                 *seen_testuser = true;
3614                         }
3615                         STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name, 
3616                                            q.out.info->info21.full_name, q.out.info->info21.account_name);
3617                         STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name, 
3618                                            q.out.info->info21.account_name, q.out.info->info21.account_name);
3619                         STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description, 
3620                                            q.out.info->info21.description, q.out.info->info21.account_name);
3621                         INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid, 
3622                                         q.out.info->info21.rid, q.out.info->info21.account_name);
3623                         INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags, 
3624                                         q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3625                         
3626                         break;
3627                 case 2:
3628                         STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name, 
3629                                            q.out.info->info21.account_name, q.out.info->info21.account_name);
3630                         STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description, 
3631                                            q.out.info->info21.description, q.out.info->info21.account_name);
3632                         INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid, 
3633                                         q.out.info->info21.rid, q.out.info->info21.account_name);
3634                         INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL), 
3635                                         q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3636                         
3637                         if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
3638                                 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n", 
3639                                        q.out.info->info21.account_name.string);
3640                         }
3641
3642                         if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3643                                 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3644                                        q.out.info->info21.account_name.string,
3645                                        querydisplayinfo->out.info.info2.entries[i].acct_flags,
3646                                        q.out.info->info21.acct_flags);
3647                                 return false;
3648                         }
3649                         
3650                         break;
3651                 }
3652                 
3653                 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3654                         return false;
3655                 }
3656         }
3657         return ret;
3658 }
3659
3660 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3661                                   struct policy_handle *handle)
3662 {
3663         NTSTATUS status;
3664         struct samr_QueryDisplayInfo r;
3665         struct samr_QueryDomainInfo dom_info;
3666         bool ret = true;
3667         uint16_t levels[] = {1, 2, 3, 4, 5};
3668         int i;
3669         bool seen_testuser = false;
3670
3671         for (i=0;i<ARRAY_SIZE(levels);i++) {
3672                 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3673
3674                 r.in.start_idx = 0;
3675                 status = STATUS_MORE_ENTRIES;
3676                 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3677                         r.in.domain_handle = handle;
3678                         r.in.level = levels[i];
3679                         r.in.max_entries = 2;
3680                         r.in.buf_size = (uint32_t)-1;
3681                         
3682                         status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3683                         if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3684                                 printf("QueryDisplayInfo level %u failed - %s\n", 
3685                                        levels[i], nt_errstr(status));
3686                                 ret = false;
3687                         }
3688                         switch (r.in.level) {
3689                         case 1:
3690                                 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3691                                         ret = false;
3692                                 }
3693                                 r.in.start_idx += r.out.info.info1.count;
3694                                 break;
3695                         case 2:
3696                                 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3697                                         ret = false;
3698                                 }
3699                                 r.in.start_idx += r.out.info.info2.count;
3700                                 break;
3701                         case 3:
3702                                 r.in.start_idx += r.out.info.info3.count;
3703                                 break;
3704                         case 4:
3705                                 r.in.start_idx += r.out.info.info4.count;
3706                                 break;
3707                         case 5:
3708                                 r.in.start_idx += r.out.info.info5.count;
3709                                 break;
3710                         }
3711                 }
3712                 dom_info.in.domain_handle = handle;
3713                 dom_info.in.level = 2;
3714                 /* Check number of users returned is correct */
3715                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3716                 if (!NT_STATUS_IS_OK(status)) {
3717                         printf("QueryDomainInfo level %u failed - %s\n", 
3718                                r.in.level, nt_errstr(status));
3719                                 ret = false;
3720                                 break;
3721                 }
3722                 switch (r.in.level) {
3723                 case 1:
3724                 case 4:
3725                         if (dom_info.out.info->general.num_users < r.in.start_idx) {
3726                                 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3727                                        r.in.start_idx, dom_info.out.info->general.num_groups,
3728                                        dom_info.out.info->general.domain_name.string);
3729                                 ret = false;
3730                         }
3731                         if (!seen_testuser) {
3732                                 struct policy_handle user_handle;
3733                                 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3734                                         printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n", 
3735                                                dom_info.out.info->general.domain_name.string);
3736                                         ret = false;
3737                                         test_samr_handle_Close(p, mem_ctx, &user_handle);
3738                                 }
3739                         }
3740                         break;
3741                 case 3:
3742                 case 5:
3743                         if (dom_info.out.info->general.num_groups != r.in.start_idx) {
3744                                 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3745                                        r.in.start_idx, dom_info.out.info->general.num_groups,
3746                                        dom_info.out.info->general.domain_name.string);
3747                                 ret = false;
3748                         }
3749                         
3750                         break;
3751                 }
3752
3753         }
3754         
3755         return ret;     
3756 }
3757
3758 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3759                                   struct policy_handle *handle)
3760 {
3761         NTSTATUS status;
3762         struct samr_QueryDisplayInfo2 r;
3763         bool ret = true;
3764         uint16_t levels[] = {1, 2, 3, 4, 5};
3765         int i;
3766
3767         for (i=0;i<ARRAY_SIZE(levels);i++) {
3768                 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3769
3770                 r.in.domain_handle = handle;
3771                 r.in.level = levels[i];
3772                 r.in.start_idx = 0;
3773                 r.in.max_entries = 1000;
3774                 r.in.buf_size = (uint32_t)-1;
3775
3776                 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3777                 if (!NT_STATUS_IS_OK(status)) {
3778                         printf("QueryDisplayInfo2 level %u failed - %s\n", 
3779                                levels[i], nt_errstr(status));
3780                         ret = false;
3781                 }
3782         }
3783         
3784         return ret;     
3785 }
3786
3787 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
3788                                   struct policy_handle *handle)
3789 {
3790         NTSTATUS status;
3791         struct samr_QueryDisplayInfo3 r;
3792         bool ret = true;
3793         uint16_t levels[] = {1, 2, 3, 4, 5};
3794         int i;
3795
3796         for (i=0;i<ARRAY_SIZE(levels);i++) {
3797                 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
3798
3799                 r.in.domain_handle = handle;
3800                 r.in.level = levels[i];
3801                 r.in.start_idx = 0;
3802                 r.in.max_entries = 1000;
3803                 r.in.buf_size = (uint32_t)-1;
3804
3805                 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
3806                 if (!NT_STATUS_IS_OK(status)) {
3807                         printf("QueryDisplayInfo3 level %u failed - %s\n", 
3808                                levels[i], nt_errstr(status));
3809                         ret = false;
3810                 }
3811         }
3812         
3813         return ret;     
3814 }
3815
3816
3817 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3818                                            struct policy_handle *handle)
3819 {
3820         NTSTATUS status;
3821         struct samr_QueryDisplayInfo r;
3822         bool ret = true;
3823
3824         printf("Testing QueryDisplayInfo continuation\n");
3825
3826         r.in.domain_handle = handle;
3827         r.in.level = 1;
3828         r.in.start_idx = 0;
3829         r.in.max_entries = 1;
3830         r.in.buf_size = (uint32_t)-1;
3831
3832         do {
3833                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3834                 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
3835                         if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
3836                                 printf("expected idx %d but got %d\n",
3837                                        r.in.start_idx + 1,
3838                                        r.out.info.info1.entries[0].idx);
3839                                 break;
3840                         }
3841                 }
3842                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3843                     !NT_STATUS_IS_OK(status)) {
3844                         printf("QueryDisplayInfo level %u failed - %s\n", 
3845                                r.in.level, nt_errstr(status));
3846                         ret = false;
3847                         break;
3848                 }
3849                 r.in.start_idx++;
3850         } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3851                   NT_STATUS_IS_OK(status)) &&
3852                  r.out.returned_size != 0);
3853         
3854         return ret;     
3855 }
3856
3857 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
3858                                  struct policy_handle *handle)
3859 {
3860         NTSTATUS status;
3861         struct samr_QueryDomainInfo r;
3862         struct samr_SetDomainInfo s;
3863         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3864         uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
3865         int i;
3866         bool ret = true;
3867         const char *domain_comment = talloc_asprintf(tctx, 
3868                                   "Tortured by Samba4 RPC-SAMR: %s", 
3869                                   timestring(tctx, time(NULL)));
3870
3871         s.in.domain_handle = handle;
3872         s.in.level = 4;
3873         s.in.info = talloc(tctx, union samr_DomainInfo);
3874         
3875         s.in.info->oem.oem_information.string = domain_comment;
3876         status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
3877         if (!NT_STATUS_IS_OK(status)) {
3878                 printf("SetDomainInfo level %u (set comment) failed - %s\n", 
3879                        r.in.level, nt_errstr(status));
3880                 return false;
3881         }
3882
3883         for (i=0;i<ARRAY_SIZE(levels);i++) {
3884                 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
3885
3886                 r.in.domain_handle = handle;
3887                 r.in.level = levels[i];
3888
3889                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
3890                 if (!NT_STATUS_IS_OK(status)) {
3891                         printf("QueryDomainInfo level %u failed - %s\n", 
3892                                r.in.level, nt_errstr(status));
3893                         ret = false;
3894                         continue;
3895                 }
3896
3897                 switch (levels[i]) {
3898                 case 2:
3899                         if (strcmp(r.out.info->general.oem_information.string, domain_comment) != 0) {
3900                                 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3901                                        levels[i], r.out.info->general.oem_information.string, domain_comment);
3902                                 ret = false;
3903                         }
3904                         if (!r.out.info->general.primary.string) {
3905                                 printf("QueryDomainInfo level %u returned no PDC name\n",
3906                                        levels[i]);
3907                                 ret = false;
3908                         } else if (r.out.info->general.role == SAMR_ROLE_DOMAIN_PDC) {
3909                                 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->general.primary.string) != 0) {
3910                                         printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3911                                                levels[i], r.out.info->general.primary.string, dcerpc_server_name(p));
3912                                 }
3913                         }
3914                         break;
3915                 case 4:
3916                         if (strcmp(r.out.info->oem.oem_information.string, domain_comment) != 0) {
3917                                 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3918                                        levels[i], r.out.info->oem.oem_information.string, domain_comment);
3919                                 ret = false;
3920                         }
3921                         break;
3922                 case 6:
3923                         if (!r.out.info->info6.primary.string) {
3924                                 printf("QueryDomainInfo level %u returned no PDC name\n",
3925                                        levels[i]);
3926                                 ret = false;
3927                         }
3928                         break;
3929                 case 11:
3930                         if (strcmp(r.out.info->general2.general.oem_information.string, domain_comment) != 0) {
3931                                 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3932                                        levels[i], r.out.info->general2.general.oem_information.string, domain_comment);
3933                                 ret = false;
3934                         }
3935                         break;
3936                 }
3937
3938                 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
3939
3940                 s.in.domain_handle = handle;
3941                 s.in.level = levels[i];
3942                 s.in.info = r.out.info;
3943
3944                 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
3945                 if (set_ok[i]) {
3946                         if (!NT_STATUS_IS_OK(status)) {
3947                                 printf("SetDomainInfo level %u failed - %s\n", 
3948                                        r.in.level, nt_errstr(status));
3949                                 ret = false;
3950                                 continue;
3951                         }
3952                 } else {
3953                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3954                                 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
3955                                        r.in.level, nt_errstr(status));
3956                                 ret = false;
3957                                 continue;
3958                         }
3959                 }
3960
3961                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
3962                 if (!NT_STATUS_IS_OK(status)) {
3963                         printf("QueryDomainInfo level %u failed - %s\n", 
3964                                r.in.level, nt_errstr(status));
3965                         ret = false;
3966                         continue;
3967                 }
3968         }
3969
3970         return ret;     
3971 }
3972
3973
3974 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
3975                                   struct policy_handle *handle)
3976 {
3977         NTSTATUS status;
3978         struct samr_QueryDomainInfo2 r;
3979         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3980         int i;
3981         bool ret = true;
3982
3983         for (i=0;i<ARRAY_SIZE(levels);i++) {
3984                 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
3985
3986                 r.in.domain_handle = handle;
3987                 r.in.level = levels[i];
3988
3989                 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
3990                 if (!NT_STATUS_IS_OK(status)) {
3991                         printf("QueryDomainInfo2 level %u failed - %s\n", 
3992                                r.in.level, nt_errstr(status));
3993                         ret = false;
3994                         continue;
3995                 }
3996         }
3997
3998         return true;    
3999 }
4000
4001 /* Test whether querydispinfo level 5 and enumdomgroups return the same
4002    set of group names. */
4003 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
4004                            struct policy_handle *handle)
4005 {
4006         struct samr_EnumDomainGroups q1;
4007         struct samr_QueryDisplayInfo q2;
4008         NTSTATUS status;
4009         uint32_t resume_handle=0;
4010         int i;
4011         bool ret = true;
4012
4013         int num_names = 0;
4014         const char **names = NULL;
4015
4016         torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
4017
4018         q1.in.domain_handle = handle;
4019         q1.in.resume_handle = &resume_handle;
4020         q1.in.max_size = 5;
4021         q1.out.resume_handle = &resume_handle;
4022
4023         status = STATUS_MORE_ENTRIES;
4024         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4025                 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
4026
4027                 if (!NT_STATUS_IS_OK(status) &&
4028                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4029                         break;
4030
4031                 for (i=0; i<q1.out.num_entries; i++) {
4032                         add_string_to_array(tctx,
4033                                             q1.out.sam->entries[i].name.string,
4034                                             &names, &num_names);
4035                 }
4036         }
4037
4038         torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
4039         
4040         torture_assert(tctx, q1.out.sam, "EnumDomainGroups failed to return q1.out.sam");
4041
4042         q2.in.domain_handle = handle;
4043         q2.in.level = 5;
4044         q2.in.start_idx = 0;
4045         q2.in.max_entries = 5;
4046         q2.in.buf_size = (uint32_t)-1;
4047
4048         status = STATUS_MORE_ENTRIES;
4049         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4050                 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
4051
4052                 if (!NT_STATUS_IS_OK(status) &&
4053                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4054                         break;
4055
4056                 for (i=0; i<q2.out.info.info5.count; i++) {
4057                         int j;
4058                         const char *name = q2.out.info.info5.entries[i].account_name.string;
4059                         bool found = false;
4060                         for (j=0; j<num_names; j++) {
4061                                 if (names[j] == NULL)
4062                                         continue;
4063                                 if (strequal(names[j], name)) {
4064                                         names[j] = NULL;
4065                                         found = true;
4066                                         break;
4067                                 }
4068                         }
4069
4070                         if (!found) {
4071                                 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
4072                                        name);
4073                                 ret = false;
4074                         }
4075                 }
4076                 q2.in.start_idx += q2.out.info.info5.count;
4077         }
4078
4079         if (!NT_STATUS_IS_OK(status)) {
4080                 printf("QueryDisplayInfo level 5 failed - %s\n",
4081                        nt_errstr(status));
4082                 ret = false;
4083         }
4084
4085         for (i=0; i<num_names; i++) {
4086                 if (names[i] != NULL) {
4087                         printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
4088                                names[i]);
4089                         ret = false;
4090                 }
4091         }
4092
4093         return ret;
4094 }
4095
4096 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
4097                                    struct policy_handle *group_handle)
4098 {
4099         struct samr_DeleteDomainGroup d;
4100         NTSTATUS status;
4101
4102         torture_comment(tctx, "Testing DeleteDomainGroup\n");
4103
4104         d.in.group_handle = group_handle;
4105         d.out.group_handle = group_handle;
4106
4107         status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
4108         torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
4109
4110         return true;
4111 }
4112
4113 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4114                                             struct policy_handle *domain_handle)
4115 {
4116         struct samr_TestPrivateFunctionsDomain r;
4117         NTSTATUS status;
4118         bool ret = true;
4119
4120         torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
4121
4122         r.in.domain_handle = domain_handle;
4123
4124         status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
4125         torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
4126
4127         return ret;
4128 }
4129
4130 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
4131                           struct dom_sid *domain_sid,
4132                           struct policy_handle *domain_handle)
4133 {
4134         struct samr_RidToSid r;
4135         NTSTATUS status;
4136         bool ret = true;
4137         struct dom_sid *calc_sid;
4138         int rids[] = { 0, 42, 512, 10200 };
4139         int i;
4140
4141         for (i=0;i<ARRAY_SIZE(rids);i++) {
4142                 torture_comment(tctx, "Testing RidToSid\n");
4143                 
4144                 calc_sid = dom_sid_dup(tctx, domain_sid);
4145                 r.in.domain_handle = domain_handle;
4146                 r.in.rid = rids[i];
4147                 
4148                 status = dcerpc_samr_RidToSid(p, tctx, &r);
4149                 if (!NT_STATUS_IS_OK(status)) {
4150                         printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
4151                         ret = false;
4152                 } else {
4153                         calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
4154
4155                         if (!dom_sid_equal(calc_sid, r.out.sid)) {
4156                                 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i], 
4157                                        dom_sid_string(tctx, r.out.sid), 
4158                                        dom_sid_string(tctx, calc_sid));
4159                                 ret = false;
4160                         }
4161                 }
4162         }
4163
4164         return ret;
4165 }
4166
4167 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
4168                                        struct policy_handle *domain_handle)
4169 {
4170         struct samr_GetBootKeyInformation r;
4171         NTSTATUS status;
4172         bool ret = true;
4173
4174         torture_comment(tctx, "Testing GetBootKeyInformation\n");
4175
4176         r.in.domain_handle = domain_handle;
4177
4178         status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
4179         if (!NT_STATUS_IS_OK(status)) {
4180                 /* w2k3 seems to fail this sometimes and pass it sometimes */
4181                 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4182         }
4183
4184         return ret;
4185 }
4186
4187 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx, 
4188                                 struct policy_handle *domain_handle,
4189                                 struct policy_handle *group_handle)
4190 {
4191         NTSTATUS status;
4192         struct samr_AddGroupMember r;
4193         struct samr_DeleteGroupMember d;
4194         struct samr_QueryGroupMember q;
4195         struct samr_SetMemberAttributesOfGroup s;
4196         uint32_t rid;
4197
4198         status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4199         torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
4200
4201         r.in.group_handle = group_handle;
4202         r.in.rid = rid;
4203         r.in.flags = 0; /* ??? */
4204
4205         torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
4206
4207         d.in.group_handle = group_handle;
4208         d.in.rid = rid;
4209
4210         status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4211         torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
4212
4213         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4214         torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4215
4216         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4217         torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
4218
4219         if (torture_setting_bool(tctx, "samba4", false)) {
4220                 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
4221         } else {
4222                 /* this one is quite strange. I am using random inputs in the
4223                    hope of triggering an error that might give us a clue */
4224
4225                 s.in.group_handle = group_handle;
4226                 s.in.unknown1 = random();
4227                 s.in.unknown2 = random();
4228
4229                 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4230                 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
4231         }
4232
4233         q.in.group_handle = group_handle;
4234
4235         status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4236         torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
4237
4238         status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4239         torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
4240
4241         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4242         torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4243
4244         return true;
4245 }
4246
4247
4248 static bool test_CreateDomainGroup(struct dcerpc_pipe *p, 
4249                                                                    struct torture_context *tctx, 
4250                                    struct policy_handle *domain_handle, 
4251                                    struct policy_handle *group_handle,
4252                                    struct dom_sid *domain_sid)
4253 {
4254         NTSTATUS status;
4255         struct samr_CreateDomainGroup r;
4256         uint32_t rid;
4257         struct lsa_String name;
4258         bool ret = true;
4259
4260         init_lsa_String(&name, TEST_GROUPNAME);
4261
4262         r.in.domain_handle = domain_handle;
4263         r.in.name = &name;
4264         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4265         r.out.group_handle = group_handle;
4266         r.out.rid = &rid;
4267
4268         printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4269
4270         status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4271
4272         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4273                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4274                         torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
4275                         return true;
4276                 } else {
4277                         printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string, 
4278                                nt_errstr(status));
4279                         return false;
4280                 }
4281         }
4282
4283         if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4284                 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
4285                         printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string, 
4286                                nt_errstr(status));
4287                         return false;
4288                 }
4289                 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4290         }
4291         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4292                 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
4293                         
4294                         printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string, 
4295                                nt_errstr(status));
4296                         return false;
4297                 }
4298                 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4299         }
4300         torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
4301
4302         if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
4303                 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4304                 ret = false;
4305         }
4306
4307         if (!test_SetGroupInfo(p, tctx, group_handle)) {
4308                 ret = false;
4309         }
4310
4311         return ret;
4312 }
4313
4314
4315 /*
4316   its not totally clear what this does. It seems to accept any sid you like.
4317 */
4318 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p, 
4319                                                struct torture_context *tctx,
4320                                                struct policy_handle *domain_handle)
4321 {
4322         NTSTATUS status;
4323         struct samr_RemoveMemberFromForeignDomain r;
4324
4325         r.in.domain_handle = domain_handle;
4326         r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
4327
4328         status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
4329         torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
4330
4331         return true;
4332 }
4333
4334
4335
4336 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4337                          struct policy_handle *handle);
4338
4339 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx, 
4340                             struct policy_handle *handle, struct dom_sid *sid,
4341                             enum torture_samr_choice which_ops)
4342 {
4343         NTSTATUS status;
4344         struct samr_OpenDomain r;
4345         struct policy_handle domain_handle;
4346         struct policy_handle alias_handle;
4347         struct policy_handle user_handle;
4348         struct policy_handle group_handle;
4349         bool ret = true;
4350
4351         ZERO_STRUCT(alias_handle);
4352         ZERO_STRUCT(user_handle);
4353         ZERO_STRUCT(group_handle);
4354         ZERO_STRUCT(domain_handle);
4355
4356         torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
4357
4358         r.in.connect_handle = handle;
4359         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4360         r.in.sid = sid;
4361         r.out.domain_handle = &domain_handle;
4362
4363         status = dcerpc_samr_OpenDomain(p, tctx, &r);
4364         torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
4365
4366         /* run the domain tests with the main handle closed - this tests
4367            the servers reference counting */
4368         ret &= test_samr_handle_Close(p, tctx, handle);
4369
4370         switch (which_ops) {
4371         case TORTURE_SAMR_USER_ATTRIBUTES:
4372         case TORTURE_SAMR_PASSWORDS:
4373                 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
4374                 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4375                 /* This test needs 'complex' users to validate */
4376                 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
4377                 if (!ret) {
4378                         printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
4379                 }
4380                 break;
4381         case TORTURE_SAMR_OTHER:
4382                 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4383                 if (!ret) {
4384                         printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
4385                 }
4386                 ret &= test_QuerySecurity(p, tctx, &domain_handle);
4387                 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
4388                 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
4389                 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
4390                 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
4391                 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
4392                 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
4393                 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
4394                 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
4395                 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
4396                 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
4397                 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
4398                 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
4399                 
4400                 if (torture_setting_bool(tctx, "samba4", false)) {
4401                         torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
4402                 } else {
4403                         ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
4404                         ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
4405                 }
4406                 ret &= test_GroupList(p, tctx, &domain_handle);
4407                 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
4408                 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
4409                 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
4410                 if (!ret) {
4411                         torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
4412                 }
4413                 break;
4414         }
4415
4416         if (!policy_handle_empty(&user_handle) &&
4417             !test_DeleteUser(p, tctx, &user_handle)) {
4418                 ret = false;
4419         }
4420
4421         if (!policy_handle_empty(&alias_handle) &&
4422             !test_DeleteAlias(p, tctx, &alias_handle)) {
4423                 ret = false;
4424         }
4425
4426         if (!policy_handle_empty(&group_handle) &&
4427             !test_DeleteDomainGroup(p, tctx, &group_handle)) {
4428                 ret = false;
4429         }
4430
4431         ret &= test_samr_handle_Close(p, tctx, &domain_handle);
4432
4433         /* reconnect the main handle */
4434         ret &= test_Connect(p, tctx, handle);
4435
4436         if (!ret) {
4437                 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
4438         }
4439
4440         return ret;
4441 }
4442
4443 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4444                               struct policy_handle *handle, const char *domain,
4445                               enum torture_samr_choice which_ops)
4446 {
4447         NTSTATUS status;
4448         struct samr_LookupDomain r;
4449         struct lsa_String n1;
4450         struct lsa_String n2;
4451         bool ret = true;
4452
4453         torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
4454
4455         /* check for correct error codes */
4456         r.in.connect_handle = handle;
4457         r.in.domain_name = &n2;
4458         n2.string = NULL;
4459
4460         status = dcerpc_samr_LookupDomain(p, tctx, &r);
4461         torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
4462
4463         init_lsa_String(&n2, "xxNODOMAINxx");
4464
4465         status = dcerpc_samr_LookupDomain(p, tctx, &r);
4466         torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
4467
4468         r.in.connect_handle = handle;
4469
4470         init_lsa_String(&n1, domain);
4471         r.in.domain_name = &n1;
4472
4473         status = dcerpc_samr_LookupDomain(p, tctx, &r);
4474         torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
4475
4476         if (!test_GetDomPwInfo(p, tctx, &n1)) {
4477                 ret = false;
4478         }
4479
4480         if (!test_OpenDomain(p, tctx, handle, r.out.sid, which_ops)) {
4481                 ret = false;
4482         }
4483
4484         return ret;
4485 }
4486
4487
4488 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
4489                              struct policy_handle *handle, enum torture_samr_choice which_ops)
4490 {
4491         NTSTATUS status;
4492         struct samr_EnumDomains r;
4493         uint32_t resume_handle = 0;
4494         int i;
4495         bool ret = true;
4496
4497         r.in.connect_handle = handle;
4498         r.in.resume_handle = &resume_handle;
4499         r.in.buf_size = (uint32_t)-1;
4500         r.out.resume_handle = &resume_handle;
4501
4502         status = dcerpc_samr_EnumDomains(p, tctx, &r);
4503         torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4504
4505         if (!r.out.sam) {
4506                 return false;
4507         }
4508
4509         for (i=0;i<r.out.sam->count;i++) {
4510                 if (!test_LookupDomain(p, tctx, handle, 
4511                                        r.out.sam->entries[i].name.string, which_ops)) {
4512                         ret = false;
4513                 }
4514         }
4515
4516         status = dcerpc_samr_EnumDomains(p, tctx, &r);
4517         torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4518
4519         return ret;
4520 }
4521
4522
4523 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4524                          struct policy_handle *handle)
4525 {
4526         NTSTATUS status;
4527         struct samr_Connect r;
4528         struct samr_Connect2 r2;
4529         struct samr_Connect3 r3;
4530         struct samr_Connect4 r4;
4531         struct samr_Connect5 r5;
4532         union samr_ConnectInfo info;
4533         struct policy_handle h;
4534         bool ret = true, got_handle = false;
4535
4536         torture_comment(tctx, "testing samr_Connect\n");
4537
4538         r.in.system_name = 0;
4539         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4540         r.out.connect_handle = &h;
4541
4542         status = dcerpc_samr_Connect(p, tctx, &r);
4543         if (!NT_STATUS_IS_OK(status)) {
4544                 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
4545                 ret = false;
4546         } else {
4547                 got_handle = true;
4548                 *handle = h;
4549         }
4550
4551         torture_comment(tctx, "testing samr_Connect2\n");
4552
4553         r2.in.system_name = NULL;
4554         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4555         r2.out.connect_handle = &h;
4556
4557         status = dcerpc_samr_Connect2(p, tctx, &r2);
4558         if (!NT_STATUS_IS_OK(status)) {
4559                 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
4560                 ret = false;
4561         } else {
4562                 if (got_handle) {
4563                         test_samr_handle_Close(p, tctx, handle);
4564                 }
4565                 got_handle = true;
4566                 *handle = h;
4567         }
4568
4569         torture_comment(tctx, "testing samr_Connect3\n");
4570
4571         r3.in.system_name = NULL;
4572         r3.in.unknown = 0;
4573         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4574         r3.out.connect_handle = &h;
4575
4576         status = dcerpc_samr_Connect3(p, tctx, &r3);
4577         if (!NT_STATUS_IS_OK(status)) {
4578                 printf("Connect3 failed - %s\n", nt_errstr(status));
4579                 ret = false;
4580         } else {
4581                 if (got_handle) {
4582                         test_samr_handle_Close(p, tctx, handle);
4583                 }
4584                 got_handle = true;
4585                 *handle = h;
4586         }
4587
4588         torture_comment(tctx, "testing samr_Connect4\n");
4589
4590         r4.in.system_name = "";
4591         r4.in.client_version = 0;
4592         r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4593         r4.out.connect_handle = &h;
4594
4595         status = dcerpc_samr_Connect4(p, tctx, &r4);
4596         if (!NT_STATUS_IS_OK(status)) {
4597                 printf("Connect4 failed - %s\n", nt_errstr(status));
4598                 ret = false;
4599         } else {
4600                 if (got_handle) {
4601                         test_samr_handle_Close(p, tctx, handle);
4602                 }
4603                 got_handle = true;
4604                 *handle = h;
4605         }
4606
4607         torture_comment(tctx, "testing samr_Connect5\n");
4608
4609         info.info1.client_version = 0;
4610         info.info1.unknown2 = 0;
4611
4612         r5.in.system_name = "";
4613         r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4614         r5.in.level = 1;
4615         r5.in.info = &info;
4616         r5.out.info = &info;
4617         r5.out.connect_handle = &h;
4618
4619         status = dcerpc_samr_Connect5(p, tctx, &r5);
4620         if (!NT_STATUS_IS_OK(status)) {
4621                 printf("Connect5 failed - %s\n", nt_errstr(status));
4622                 ret = false;
4623         } else {
4624                 if (got_handle) {
4625                         test_samr_handle_Close(p, tctx, handle);
4626                 }
4627                 got_handle = true;
4628                 *handle = h;
4629         }
4630
4631         return ret;
4632 }
4633
4634
4635 bool torture_rpc_samr(struct torture_context *torture)
4636 {
4637         NTSTATUS status;
4638         struct dcerpc_pipe *p;
4639         bool ret = true;
4640         struct policy_handle handle;
4641
4642         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4643         if (!NT_STATUS_IS_OK(status)) {
4644                 return false;
4645         }
4646
4647         ret &= test_Connect(p, torture, &handle);
4648
4649         ret &= test_QuerySecurity(p, torture, &handle);
4650
4651         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4652
4653         ret &= test_SetDsrmPassword(p, torture, &handle);
4654
4655         ret &= test_Shutdown(p, torture, &handle);
4656
4657         ret &= test_samr_handle_Close(p, torture, &handle);
4658
4659         return ret;
4660 }
4661
4662
4663 bool torture_rpc_samr_users(struct torture_context *torture)
4664 {
4665         NTSTATUS status;
4666         struct dcerpc_pipe *p;
4667         bool ret = true;
4668         struct policy_handle handle;
4669
4670         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4671         if (!NT_STATUS_IS_OK(status)) {
4672                 return false;
4673         }
4674
4675         ret &= test_Connect(p, torture, &handle);
4676
4677         ret &= test_QuerySecurity(p, torture, &handle);
4678
4679         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4680
4681         ret &= test_SetDsrmPassword(p, torture, &handle);
4682
4683         ret &= test_Shutdown(p, torture, &handle);
4684
4685         ret &= test_samr_handle_Close(p, torture, &handle);
4686
4687         return ret;
4688 }
4689
4690
4691 bool torture_rpc_samr_passwords(struct torture_context *torture)
4692 {
4693         NTSTATUS status;
4694         struct dcerpc_pipe *p;
4695         bool ret = true;
4696         struct policy_handle handle;
4697
4698         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4699         if (!NT_STATUS_IS_OK(status)) {
4700                 return false;
4701         }
4702
4703         ret &= test_Connect(p, torture, &handle);
4704
4705         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4706
4707         ret &= test_samr_handle_Close(p, torture, &handle);
4708
4709         return ret;
4710 }
4711