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