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