f63e66a18d2bd91464a26e0196a4aff31e04357d
[kai/samba.git] / source4 / torture / rpc / samr.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for samr rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "torture/torture.h"
24 #include "system/time.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_samr_c.h"
27 #include "../lib/crypto/crypto.h"
28 #include "libcli/auth/libcli_auth.h"
29 #include "libcli/security/security.h"
30 #include "torture/rpc/rpc.h"
31
32 #include <unistd.h>
33
34 #define TEST_ACCOUNT_NAME "samrtorturetest"
35 #define TEST_ALIASNAME "samrtorturetestalias"
36 #define TEST_GROUPNAME "samrtorturetestgroup"
37 #define TEST_MACHINENAME "samrtestmach$"
38 #define TEST_DOMAINNAME "samrtestdom$"
39
40 enum torture_samr_choice {
41         TORTURE_SAMR_PASSWORDS,
42         TORTURE_SAMR_PASSWORDS_PWDLASTSET,
43         TORTURE_SAMR_USER_ATTRIBUTES,
44         TORTURE_SAMR_OTHER
45 };
46
47 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
48                                struct policy_handle *handle);
49
50 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
51                                 struct policy_handle *handle);
52
53 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
54                                struct policy_handle *handle);
55
56 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
57                                 const char *acct_name, 
58                                 struct policy_handle *domain_handle, char **password);
59
60 static void init_lsa_String(struct lsa_String *string, const char *s)
61 {
62         string->string = s;
63 }
64
65 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
66 {
67         string->length = length;
68         string->size = length;
69         string->array = (uint16_t *)discard_const(s);
70 }
71
72 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
73                                    struct policy_handle *handle)
74 {
75         NTSTATUS status;
76         struct samr_Close r;
77
78         r.in.handle = handle;
79         r.out.handle = handle;
80
81         status = dcerpc_samr_Close(p, tctx, &r);
82         torture_assert_ntstatus_ok(tctx, status, "Close");
83
84         return true;
85 }
86
87 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
88                        struct policy_handle *handle)
89 {
90         NTSTATUS status;
91         struct samr_Shutdown r;
92
93         if (!torture_setting_bool(tctx, "dangerous", false)) {
94                 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
95                 return true;
96         }
97
98         r.in.connect_handle = handle;
99
100         torture_comment(tctx, "testing samr_Shutdown\n");
101
102         status = dcerpc_samr_Shutdown(p, tctx, &r);
103         torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
104
105         return true;
106 }
107
108 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
109                                  struct policy_handle *handle)
110 {
111         NTSTATUS status;
112         struct samr_SetDsrmPassword r;
113         struct lsa_String string;
114         struct samr_Password hash;
115
116         if (!torture_setting_bool(tctx, "dangerous", false)) {
117                 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
118         }
119
120         E_md4hash("TeSTDSRM123", hash.hash);
121
122         init_lsa_String(&string, "Administrator");
123
124         r.in.name = &string;
125         r.in.unknown = 0;
126         r.in.hash = &hash;
127
128         torture_comment(tctx, "testing samr_SetDsrmPassword\n");
129
130         status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
131         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
132
133         return true;
134 }
135
136
137 static bool test_QuerySecurity(struct dcerpc_pipe *p, 
138                                struct torture_context *tctx, 
139                                struct policy_handle *handle)
140 {
141         NTSTATUS status;
142         struct samr_QuerySecurity r;
143         struct samr_SetSecurity s;
144         struct sec_desc_buf *sdbuf = NULL;
145
146         r.in.handle = handle;
147         r.in.sec_info = 7;
148         r.out.sdbuf = &sdbuf;
149
150         status = dcerpc_samr_QuerySecurity(p, tctx, &r);
151         torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
152
153         torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
154
155         s.in.handle = handle;
156         s.in.sec_info = 7;
157         s.in.sdbuf = sdbuf;
158
159         if (torture_setting_bool(tctx, "samba4", false)) {
160                 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
161         }
162
163         status = dcerpc_samr_SetSecurity(p, tctx, &s);
164         torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
165
166         status = dcerpc_samr_QuerySecurity(p, tctx, &r);
167         torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
168
169         return true;
170 }
171
172
173 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx, 
174                              struct policy_handle *handle, uint32_t base_acct_flags,
175                              const char *base_account_name)
176 {
177         NTSTATUS status;
178         struct samr_SetUserInfo s;
179         struct samr_SetUserInfo2 s2;
180         struct samr_QueryUserInfo q;
181         struct samr_QueryUserInfo q0;
182         union samr_UserInfo u;
183         union samr_UserInfo *info;
184         bool ret = true;
185         const char *test_account_name;
186
187         uint32_t user_extra_flags = 0;
188         if (base_acct_flags == ACB_NORMAL) {
189                 /* When created, accounts are expired by default */
190                 user_extra_flags = ACB_PW_EXPIRED;
191         }
192
193         s.in.user_handle = handle;
194         s.in.info = &u;
195
196         s2.in.user_handle = handle;
197         s2.in.info = &u;
198
199         q.in.user_handle = handle;
200         q.out.info = &info;
201         q0 = q;
202
203 #define TESTCALL(call, r) \
204                 status = dcerpc_samr_ ##call(p, tctx, &r); \
205                 if (!NT_STATUS_IS_OK(status)) { \
206                         torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
207                                r.in.level, nt_errstr(status), __location__); \
208                         ret = false; \
209                         break; \
210                 }
211
212 #define STRING_EQUAL(s1, s2, field) \
213                 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
214                         torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
215                                #field, s2, __location__); \
216                         ret = false; \
217                         break; \
218                 }
219
220 #define MEM_EQUAL(s1, s2, length, field) \
221                 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
222                         torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
223                                #field, (const char *)s2, __location__); \
224                         ret = false; \
225                         break; \
226                 }
227
228 #define INT_EQUAL(i1, i2, field) \
229                 if (i1 != i2) { \
230                         torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
231                                #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
232                         ret = false; \
233                         break; \
234                 }
235
236 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
237                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
238                 q.in.level = lvl1; \
239                 TESTCALL(QueryUserInfo, q) \
240                 s.in.level = lvl1; \
241                 s2.in.level = lvl1; \
242                 u = *info; \
243                 if (lvl1 == 21) { \
244                         ZERO_STRUCT(u.info21); \
245                         u.info21.fields_present = fpval; \
246                 } \
247                 init_lsa_String(&u.info ## lvl1.field1, value); \
248                 TESTCALL(SetUserInfo, s) \
249                 TESTCALL(SetUserInfo2, s2) \
250                 init_lsa_String(&u.info ## lvl1.field1, ""); \
251                 TESTCALL(QueryUserInfo, q); \
252                 u = *info; \
253                 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
254                 q.in.level = lvl2; \
255                 TESTCALL(QueryUserInfo, q) \
256                 u = *info; \
257                 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
258         } while (0)
259
260 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
261                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
262                 q.in.level = lvl1; \
263                 TESTCALL(QueryUserInfo, q) \
264                 s.in.level = lvl1; \
265                 s2.in.level = lvl1; \
266                 u = *info; \
267                 if (lvl1 == 21) { \
268                         ZERO_STRUCT(u.info21); \
269                         u.info21.fields_present = fpval; \
270                 } \
271                 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
272                 TESTCALL(SetUserInfo, s) \
273                 TESTCALL(SetUserInfo2, s2) \
274                 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
275                 TESTCALL(QueryUserInfo, q); \
276                 u = *info; \
277                 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
278                 q.in.level = lvl2; \
279                 TESTCALL(QueryUserInfo, q) \
280                 u = *info; \
281                 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
282         } while (0)
283
284 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
285                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
286                 q.in.level = lvl1; \
287                 TESTCALL(QueryUserInfo, q) \
288                 s.in.level = lvl1; \
289                 s2.in.level = lvl1; \
290                 u = *info; \
291                 if (lvl1 == 21) { \
292                         uint8_t *bits = u.info21.logon_hours.bits; \
293                         ZERO_STRUCT(u.info21); \
294                         if (fpval == SAMR_FIELD_LOGON_HOURS) { \
295                                 u.info21.logon_hours.units_per_week = 168; \
296                                 u.info21.logon_hours.bits = bits; \
297                         } \
298                         u.info21.fields_present = fpval; \
299                 } \
300                 u.info ## lvl1.field1 = value; \
301                 TESTCALL(SetUserInfo, s) \
302                 TESTCALL(SetUserInfo2, s2) \
303                 u.info ## lvl1.field1 = 0; \
304                 TESTCALL(QueryUserInfo, q); \
305                 u = *info; \
306                 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
307                 q.in.level = lvl2; \
308                 TESTCALL(QueryUserInfo, q) \
309                 u = *info; \
310                 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
311         } while (0)
312
313 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
314         TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
315         } while (0)
316
317         q0.in.level = 12;
318         do { TESTCALL(QueryUserInfo, q0) } while (0);
319
320         TEST_USERINFO_STRING(2, comment,  1, comment, "xx2-1 comment", 0);
321         TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
322         TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment", 
323                            SAMR_FIELD_COMMENT);
324
325         test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
326         TEST_USERINFO_STRING(7, account_name,  1, account_name, base_account_name, 0);
327         test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
328         TEST_USERINFO_STRING(7, account_name,  3, account_name, base_account_name, 0);
329         test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
330         TEST_USERINFO_STRING(7, account_name,  5, account_name, base_account_name, 0);
331         test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
332         TEST_USERINFO_STRING(7, account_name,  6, account_name, base_account_name, 0);
333         test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
334         TEST_USERINFO_STRING(7, account_name,  7, account_name, base_account_name, 0);
335         test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
336         TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
337         test_account_name = base_account_name;
338         TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name, 
339                            SAMR_FIELD_ACCOUNT_NAME);
340
341         TEST_USERINFO_STRING(6, full_name,  1, full_name, "xx6-1 full_name", 0);
342         TEST_USERINFO_STRING(6, full_name,  3, full_name, "xx6-3 full_name", 0);
343         TEST_USERINFO_STRING(6, full_name,  5, full_name, "xx6-5 full_name", 0);
344         TEST_USERINFO_STRING(6, full_name,  6, full_name, "xx6-6 full_name", 0);
345         TEST_USERINFO_STRING(6, full_name,  8, full_name, "xx6-8 full_name", 0);
346         TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
347         TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
348         TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name", 
349                            SAMR_FIELD_FULL_NAME);
350
351         TEST_USERINFO_STRING(6, full_name,  1, full_name, "", 0);
352         TEST_USERINFO_STRING(6, full_name,  3, full_name, "", 0);
353         TEST_USERINFO_STRING(6, full_name,  5, full_name, "", 0);
354         TEST_USERINFO_STRING(6, full_name,  6, full_name, "", 0);
355         TEST_USERINFO_STRING(6, full_name,  8, full_name, "", 0);
356         TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
357         TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
358         TEST_USERINFO_STRING(21, full_name, 21, full_name, "", 
359                            SAMR_FIELD_FULL_NAME);
360
361         TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
362         TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
363         TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
364         TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script", 
365                            SAMR_FIELD_LOGON_SCRIPT);
366
367         TEST_USERINFO_STRING(12, profile_path,  3, profile_path, "xx12-3 profile_path", 0);
368         TEST_USERINFO_STRING(12, profile_path,  5, profile_path, "xx12-5 profile_path", 0);
369         TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
370         TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path", 
371                            SAMR_FIELD_PROFILE_PATH);
372
373         TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
374         TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
375         TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
376         TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
377                              SAMR_FIELD_HOME_DIRECTORY);
378         TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
379                              SAMR_FIELD_HOME_DIRECTORY);
380
381         TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
382         TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
383         TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
384         TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
385                              SAMR_FIELD_HOME_DRIVE);
386         TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
387                              SAMR_FIELD_HOME_DRIVE);
388         
389         TEST_USERINFO_STRING(13, description,  1, description, "xx13-1 description", 0);
390         TEST_USERINFO_STRING(13, description,  5, description, "xx13-5 description", 0);
391         TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
392         TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description", 
393                            SAMR_FIELD_DESCRIPTION);
394
395         TEST_USERINFO_STRING(14, workstations,  3, workstations, "14workstation3", 0);
396         TEST_USERINFO_STRING(14, workstations,  5, workstations, "14workstation4", 0);
397         TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
398         TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21", 
399                            SAMR_FIELD_WORKSTATIONS);
400         TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3", 
401                            SAMR_FIELD_WORKSTATIONS);
402         TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5", 
403                            SAMR_FIELD_WORKSTATIONS);
404         TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14", 
405                            SAMR_FIELD_WORKSTATIONS);
406
407         TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
408         TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
409                            SAMR_FIELD_PARAMETERS);
410         TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
411                            SAMR_FIELD_PARAMETERS);
412
413         TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
414         TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
415         TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__, 
416                           SAMR_FIELD_COUNTRY_CODE);
417         TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__, 
418                           SAMR_FIELD_COUNTRY_CODE);
419
420         TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
421         TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__, 
422                           SAMR_FIELD_CODE_PAGE);
423         TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__, 
424                           SAMR_FIELD_CODE_PAGE);
425
426         TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
427         TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
428         TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__, 
429                           SAMR_FIELD_ACCT_EXPIRY);
430         TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__, 
431                           SAMR_FIELD_ACCT_EXPIRY);
432         TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__, 
433                           SAMR_FIELD_ACCT_EXPIRY);
434
435         TEST_USERINFO_INT(4, logon_hours.bits[3],  3, logon_hours.bits[3], 1, 0);
436         TEST_USERINFO_INT(4, logon_hours.bits[3],  5, logon_hours.bits[3], 2, 0);
437         TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
438         TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4, 
439                           SAMR_FIELD_LOGON_HOURS);
440
441         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
442                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ), 
443                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags), 
444                               0);
445         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
446                               (base_acct_flags  | ACB_DISABLED), 
447                               (base_acct_flags  | ACB_DISABLED | user_extra_flags), 
448                               0);
449         
450         /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
451         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
452                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP), 
453                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP), 
454                               0);
455         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
456                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ), 
457                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags), 
458                               0);
459
460
461         /* The 'autolock' flag doesn't stick - check this */
462         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
463                               (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK), 
464                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
465                               0);
466 #if 0
467         /* Removing the 'disabled' flag doesn't stick - check this */
468         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
469                               (base_acct_flags), 
470                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
471                               0);
472 #endif
473         /* The 'store plaintext' flag does stick */
474         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
475                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED), 
476                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags), 
477                               0);
478         /* The 'use DES' flag does stick */
479         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
480                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY), 
481                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags), 
482                               0);
483         /* The 'don't require kerberos pre-authentication flag does stick */
484         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
485                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH), 
486                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags), 
487                               0);
488         /* The 'no kerberos PAC required' flag sticks */
489         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
490                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD), 
491                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags), 
492                               0);
493
494         TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags, 
495                               (base_acct_flags | ACB_DISABLED), 
496                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
497                               SAMR_FIELD_ACCT_FLAGS);
498
499 #if 0
500         /* these fail with win2003 - it appears you can't set the primary gid?
501            the set succeeds, but the gid isn't changed. Very weird! */
502         TEST_USERINFO_INT(9, primary_gid,  1, primary_gid, 513);
503         TEST_USERINFO_INT(9, primary_gid,  3, primary_gid, 513);
504         TEST_USERINFO_INT(9, primary_gid,  5, primary_gid, 513);
505         TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
506 #endif
507
508         return ret;
509 }
510
511 /*
512   generate a random password for password change tests
513 */
514 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
515 {
516         size_t len = MAX(8, min_len) + (random() % 6);
517         char *s = generate_random_str(mem_ctx, len);
518         return s;
519 }
520
521 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
522 {
523         char *s = samr_rand_pass_silent(mem_ctx, min_len);
524         printf("Generated password '%s'\n", s);
525         return s;
526
527 }
528
529 /*
530   generate a random password for password change tests
531 */
532 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
533 {
534         int i;
535         DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
536         generate_random_buffer(password.data, password.length);
537
538         for (i=0; i < len; i++) {
539                 if (((uint16_t *)password.data)[i] == 0) {
540                         ((uint16_t *)password.data)[i] = 1;
541                 }
542         }
543
544         return password;
545 }
546
547 /*
548   generate a random password for password change tests (fixed length)
549 */
550 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
551 {
552         char *s = generate_random_str(mem_ctx, len);
553         printf("Generated password '%s'\n", s);
554         return s;
555 }
556
557 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
558                              struct policy_handle *handle, char **password)
559 {
560         NTSTATUS status;
561         struct samr_SetUserInfo s;
562         union samr_UserInfo u;
563         bool ret = true;
564         DATA_BLOB session_key;
565         char *newpass;
566         struct samr_GetUserPwInfo pwp;
567         struct samr_PwInfo info;
568         int policy_min_pw_len = 0;
569         pwp.in.user_handle = handle;
570         pwp.out.info = &info;
571
572         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
573         if (NT_STATUS_IS_OK(status)) {
574                 policy_min_pw_len = pwp.out.info->min_password_length;
575         }
576         newpass = samr_rand_pass(tctx, policy_min_pw_len);
577
578         s.in.user_handle = handle;
579         s.in.info = &u;
580         s.in.level = 24;
581
582         encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
583         u.info24.password_expired = 0;
584
585         status = dcerpc_fetch_session_key(p, &session_key);
586         if (!NT_STATUS_IS_OK(status)) {
587                 printf("SetUserInfo level %u - no session key - %s\n",
588                        s.in.level, nt_errstr(status));
589                 return false;
590         }
591
592         arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
593
594         torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
595
596         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
597         if (!NT_STATUS_IS_OK(status)) {
598                 printf("SetUserInfo level %u failed - %s\n",
599                        s.in.level, nt_errstr(status));
600                 ret = false;
601         } else {
602                 *password = newpass;
603         }
604
605         return ret;
606 }
607
608
609 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
610                                 struct policy_handle *handle, uint32_t fields_present,
611                                 char **password)
612 {
613         NTSTATUS status;
614         struct samr_SetUserInfo s;
615         union samr_UserInfo u;
616         bool ret = true;
617         DATA_BLOB session_key;
618         char *newpass;
619         struct samr_GetUserPwInfo pwp;
620         struct samr_PwInfo info;
621         int policy_min_pw_len = 0;
622         pwp.in.user_handle = handle;
623         pwp.out.info = &info;
624
625         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
626         if (NT_STATUS_IS_OK(status)) {
627                 policy_min_pw_len = pwp.out.info->min_password_length;
628         }
629         newpass = samr_rand_pass(tctx, policy_min_pw_len);
630
631         s.in.user_handle = handle;
632         s.in.info = &u;
633         s.in.level = 23;
634
635         ZERO_STRUCT(u);
636
637         u.info23.info.fields_present = fields_present;
638
639         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
640
641         status = dcerpc_fetch_session_key(p, &session_key);
642         if (!NT_STATUS_IS_OK(status)) {
643                 printf("SetUserInfo level %u - no session key - %s\n",
644                        s.in.level, nt_errstr(status));
645                 return false;
646         }
647
648         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
649
650         torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
651
652         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
653         if (!NT_STATUS_IS_OK(status)) {
654                 printf("SetUserInfo level %u failed - %s\n",
655                        s.in.level, nt_errstr(status));
656                 ret = false;
657         } else {
658                 *password = newpass;
659         }
660
661         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
662
663         status = dcerpc_fetch_session_key(p, &session_key);
664         if (!NT_STATUS_IS_OK(status)) {
665                 printf("SetUserInfo level %u - no session key - %s\n",
666                        s.in.level, nt_errstr(status));
667                 return false;
668         }
669
670         /* This should break the key nicely */
671         session_key.length--;
672         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
673
674         torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
675
676         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
677         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
678                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
679                        s.in.level, nt_errstr(status));
680                 ret = false;
681         }
682
683         return ret;
684 }
685
686
687 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
688                                struct policy_handle *handle, bool makeshort, 
689                                char **password)
690 {
691         NTSTATUS status;
692         struct samr_SetUserInfo s;
693         union samr_UserInfo u;
694         bool ret = true;
695         DATA_BLOB session_key;
696         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
697         uint8_t confounder[16];
698         char *newpass;
699         struct MD5Context ctx;
700         struct samr_GetUserPwInfo pwp;
701         struct samr_PwInfo info;
702         int policy_min_pw_len = 0;
703         pwp.in.user_handle = handle;
704         pwp.out.info = &info;
705
706         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
707         if (NT_STATUS_IS_OK(status)) {
708                 policy_min_pw_len = pwp.out.info->min_password_length;
709         }
710         if (makeshort && policy_min_pw_len) {
711                 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
712         } else {
713                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
714         }
715
716         s.in.user_handle = handle;
717         s.in.info = &u;
718         s.in.level = 26;
719
720         encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
721         u.info26.password_expired = 0;
722
723         status = dcerpc_fetch_session_key(p, &session_key);
724         if (!NT_STATUS_IS_OK(status)) {
725                 printf("SetUserInfo level %u - no session key - %s\n",
726                        s.in.level, nt_errstr(status));
727                 return false;
728         }
729
730         generate_random_buffer((uint8_t *)confounder, 16);
731
732         MD5Init(&ctx);
733         MD5Update(&ctx, confounder, 16);
734         MD5Update(&ctx, session_key.data, session_key.length);
735         MD5Final(confounded_session_key.data, &ctx);
736
737         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
738         memcpy(&u.info26.password.data[516], confounder, 16);
739
740         torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
741
742         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
743         if (!NT_STATUS_IS_OK(status)) {
744                 printf("SetUserInfo level %u failed - %s\n",
745                        s.in.level, nt_errstr(status));
746                 ret = false;
747         } else {
748                 *password = newpass;
749         }
750
751         /* This should break the key nicely */
752         confounded_session_key.data[0]++;
753
754         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
755         memcpy(&u.info26.password.data[516], confounder, 16);
756
757         torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
758
759         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
760         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
761                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
762                        s.in.level, nt_errstr(status));
763                 ret = false;
764         } else {
765                 *password = newpass;
766         }
767
768         return ret;
769 }
770
771 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
772                                 struct policy_handle *handle, uint32_t fields_present,
773                                 char **password)
774 {
775         NTSTATUS status;
776         struct samr_SetUserInfo s;
777         union samr_UserInfo u;
778         bool ret = true;
779         DATA_BLOB session_key;
780         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
781         struct MD5Context ctx;
782         uint8_t confounder[16];
783         char *newpass;
784         struct samr_GetUserPwInfo pwp;
785         struct samr_PwInfo info;
786         int policy_min_pw_len = 0;
787         pwp.in.user_handle = handle;
788         pwp.out.info = &info;
789
790         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
791         if (NT_STATUS_IS_OK(status)) {
792                 policy_min_pw_len = pwp.out.info->min_password_length;
793         }
794         newpass = samr_rand_pass(tctx, policy_min_pw_len);
795
796         s.in.user_handle = handle;
797         s.in.info = &u;
798         s.in.level = 25;
799
800         ZERO_STRUCT(u);
801
802         u.info25.info.fields_present = fields_present;
803
804         encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
805
806         status = dcerpc_fetch_session_key(p, &session_key);
807         if (!NT_STATUS_IS_OK(status)) {
808                 printf("SetUserInfo level %u - no session key - %s\n",
809                        s.in.level, nt_errstr(status));
810                 return false;
811         }
812
813         generate_random_buffer((uint8_t *)confounder, 16);
814
815         MD5Init(&ctx);
816         MD5Update(&ctx, confounder, 16);
817         MD5Update(&ctx, session_key.data, session_key.length);
818         MD5Final(confounded_session_key.data, &ctx);
819
820         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
821         memcpy(&u.info25.password.data[516], confounder, 16);
822
823         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
824
825         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
826         if (!NT_STATUS_IS_OK(status)) {
827                 printf("SetUserInfo level %u failed - %s\n",
828                        s.in.level, nt_errstr(status));
829                 ret = false;
830         } else {
831                 *password = newpass;
832         }
833
834         /* This should break the key nicely */
835         confounded_session_key.data[0]++;
836
837         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
838         memcpy(&u.info25.password.data[516], confounder, 16);
839
840         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
841
842         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
843         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
844                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
845                        s.in.level, nt_errstr(status));
846                 ret = false;
847         }
848
849         return ret;
850 }
851
852 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
853                                       struct torture_context *tctx,
854                                       struct policy_handle *handle,
855                                       uint16_t level,
856                                       uint32_t fields_present,
857                                       char **password, uint8_t password_expired,
858                                       bool use_setinfo2, NTSTATUS expected_error)
859 {
860         NTSTATUS status;
861         struct samr_SetUserInfo s;
862         struct samr_SetUserInfo2 s2;
863         union samr_UserInfo u;
864         bool ret = true;
865         DATA_BLOB session_key;
866         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
867         struct MD5Context ctx;
868         uint8_t confounder[16];
869         char *newpass;
870         struct samr_GetUserPwInfo pwp;
871         struct samr_PwInfo info;
872         int policy_min_pw_len = 0;
873         pwp.in.user_handle = handle;
874         pwp.out.info = &info;
875
876         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
877         if (NT_STATUS_IS_OK(status)) {
878                 policy_min_pw_len = pwp.out.info->min_password_length;
879         }
880         newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
881
882         if (use_setinfo2) {
883                 s2.in.user_handle = handle;
884                 s2.in.info = &u;
885                 s2.in.level = level;
886         } else {
887                 s.in.user_handle = handle;
888                 s.in.info = &u;
889                 s.in.level = level;
890         }
891
892         ZERO_STRUCT(u);
893
894         switch (level) {
895         case 21:
896                 u.info21.fields_present = fields_present;
897                 u.info21.password_expired = password_expired;
898
899                 break;
900         case 23:
901                 u.info23.info.fields_present = fields_present;
902                 u.info23.info.password_expired = password_expired;
903
904                 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
905
906                 break;
907         case 24:
908                 u.info24.password_expired = password_expired;
909
910                 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
911
912                 break;
913         case 25:
914                 u.info25.info.fields_present = fields_present;
915                 u.info25.info.password_expired = password_expired;
916
917                 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
918
919                 break;
920         case 26:
921                 u.info26.password_expired = password_expired;
922
923                 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
924
925                 break;
926         }
927
928         status = dcerpc_fetch_session_key(p, &session_key);
929         if (!NT_STATUS_IS_OK(status)) {
930                 printf("SetUserInfo level %u - no session key - %s\n",
931                        s.in.level, nt_errstr(status));
932                 return false;
933         }
934
935         generate_random_buffer((uint8_t *)confounder, 16);
936
937         MD5Init(&ctx);
938         MD5Update(&ctx, confounder, 16);
939         MD5Update(&ctx, session_key.data, session_key.length);
940         MD5Final(confounded_session_key.data, &ctx);
941
942         switch (level) {
943         case 23:
944                 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
945                 break;
946         case 24:
947                 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
948                 break;
949         case 25:
950                 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
951                 memcpy(&u.info25.password.data[516], confounder, 16);
952                 break;
953         case 26:
954                 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
955                 memcpy(&u.info26.password.data[516], confounder, 16);
956                 break;
957         }
958
959         if (use_setinfo2) {
960                 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
961         } else {
962                 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
963         }
964
965         if (NT_STATUS_IS_ERR(expected_error)) {
966                 torture_assert_ntstatus_equal(tctx, status, expected_error, "");
967                 return true;
968         }
969
970         if (!NT_STATUS_IS_OK(status)) {
971                 printf("SetUserInfo%s level %u failed - %s\n",
972                        use_setinfo2 ? "2":"", level, nt_errstr(status));
973                 ret = false;
974         } else {
975                 if (level != 21) {
976                         *password = newpass;
977                 }
978         }
979
980         return ret;
981 }
982
983 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
984                                struct policy_handle *handle)
985 {
986         NTSTATUS status;
987         struct samr_SetAliasInfo r;
988         struct samr_QueryAliasInfo q;
989         union samr_AliasInfo *info;
990         uint16_t levels[] = {2, 3};
991         int i;
992         bool ret = true;
993
994         /* Ignoring switch level 1, as that includes the number of members for the alias
995          * and setting this to a wrong value might have negative consequences
996          */
997
998         for (i=0;i<ARRAY_SIZE(levels);i++) {
999                 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1000
1001                 r.in.alias_handle = handle;
1002                 r.in.level = levels[i];
1003                 r.in.info  = talloc(tctx, union samr_AliasInfo);
1004                 switch (r.in.level) {
1005                     case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1006                     case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1007                                 "Test Description, should test I18N as well"); break;
1008                     case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1009                 }
1010
1011                 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1012                 if (!NT_STATUS_IS_OK(status)) {
1013                         printf("SetAliasInfo level %u failed - %s\n",
1014                                levels[i], nt_errstr(status));
1015                         ret = false;
1016                 }
1017
1018                 q.in.alias_handle = handle;
1019                 q.in.level = levels[i];
1020                 q.out.info = &info;
1021
1022                 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1023                 if (!NT_STATUS_IS_OK(status)) {
1024                         printf("QueryAliasInfo level %u failed - %s\n",
1025                                levels[i], nt_errstr(status));
1026                         ret = false;
1027                 }
1028         }
1029
1030         return ret;
1031 }
1032
1033 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1034                                   struct policy_handle *user_handle)
1035 {
1036         struct samr_GetGroupsForUser r;
1037         struct samr_RidWithAttributeArray *rids = NULL;
1038         NTSTATUS status;
1039
1040         torture_comment(tctx, "testing GetGroupsForUser\n");
1041
1042         r.in.user_handle = user_handle;
1043         r.out.rids = &rids;
1044
1045         status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1046         torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1047
1048         return true;
1049
1050 }
1051
1052 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1053                               struct lsa_String *domain_name)
1054 {
1055         NTSTATUS status;
1056         struct samr_GetDomPwInfo r;
1057         struct samr_PwInfo info;
1058
1059         r.in.domain_name = domain_name;
1060         r.out.info = &info;
1061
1062         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1063
1064         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1065         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1066
1067         r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1068         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1069
1070         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1071         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1072
1073         r.in.domain_name->string = "\\\\__NONAME__";
1074         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1075
1076         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1077         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1078
1079         r.in.domain_name->string = "\\\\Builtin";
1080         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1081
1082         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1083         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1084
1085         return true;
1086 }
1087
1088 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1089                                struct policy_handle *handle)
1090 {
1091         NTSTATUS status;
1092         struct samr_GetUserPwInfo r;
1093         struct samr_PwInfo info;
1094
1095         torture_comment(tctx, "Testing GetUserPwInfo\n");
1096
1097         r.in.user_handle = handle;
1098         r.out.info = &info;
1099
1100         status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1101         torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1102
1103         return true;
1104 }
1105
1106 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1107                                 struct policy_handle *domain_handle, const char *name,
1108                                 uint32_t *rid)
1109 {
1110         NTSTATUS status;
1111         struct samr_LookupNames n;
1112         struct lsa_String sname[2];
1113         struct samr_Ids rids, types;
1114
1115         init_lsa_String(&sname[0], name);
1116
1117         n.in.domain_handle = domain_handle;
1118         n.in.num_names = 1;
1119         n.in.names = sname;
1120         n.out.rids = &rids;
1121         n.out.types = &types;
1122         status = dcerpc_samr_LookupNames(p, tctx, &n);
1123         if (NT_STATUS_IS_OK(status)) {
1124                 *rid = n.out.rids->ids[0];
1125         } else {
1126                 return status;
1127         }
1128
1129         init_lsa_String(&sname[1], "xxNONAMExx");
1130         n.in.num_names = 2;
1131         status = dcerpc_samr_LookupNames(p, tctx, &n);
1132         if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1133                 printf("LookupNames[2] failed - %s\n", nt_errstr(status));              
1134                 if (NT_STATUS_IS_OK(status)) {
1135                         return NT_STATUS_UNSUCCESSFUL;
1136                 }
1137                 return status;
1138         }
1139
1140         n.in.num_names = 0;
1141         status = dcerpc_samr_LookupNames(p, tctx, &n);
1142         if (!NT_STATUS_IS_OK(status)) {
1143                 printf("LookupNames[0] failed - %s\n", nt_errstr(status));              
1144                 return status;
1145         }
1146
1147         init_lsa_String(&sname[0], "xxNONAMExx");
1148         n.in.num_names = 1;
1149         status = dcerpc_samr_LookupNames(p, tctx, &n);
1150         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1151                 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));             
1152                 if (NT_STATUS_IS_OK(status)) {
1153                         return NT_STATUS_UNSUCCESSFUL;
1154                 }
1155                 return status;
1156         }
1157
1158         init_lsa_String(&sname[0], "xxNONAMExx");
1159         init_lsa_String(&sname[1], "xxNONAME2xx");
1160         n.in.num_names = 2;
1161         status = dcerpc_samr_LookupNames(p, tctx, &n);
1162         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1163                 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));            
1164                 if (NT_STATUS_IS_OK(status)) {
1165                         return NT_STATUS_UNSUCCESSFUL;
1166                 }
1167                 return status;
1168         }
1169
1170         return NT_STATUS_OK;
1171 }
1172
1173 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1174                                      struct policy_handle *domain_handle,
1175                                      const char *name, struct policy_handle *user_handle)
1176 {
1177         NTSTATUS status;
1178         struct samr_OpenUser r;
1179         uint32_t rid;
1180
1181         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1182         if (!NT_STATUS_IS_OK(status)) {
1183                 return status;
1184         }
1185
1186         r.in.domain_handle = domain_handle;
1187         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1188         r.in.rid = rid;
1189         r.out.user_handle = user_handle;
1190         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1191         if (!NT_STATUS_IS_OK(status)) {
1192                 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1193         }
1194
1195         return status;
1196 }
1197
1198 #if 0
1199 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1200                                    struct policy_handle *handle)
1201 {
1202         NTSTATUS status;
1203         struct samr_ChangePasswordUser r;
1204         bool ret = true;
1205         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1206         struct policy_handle user_handle;
1207         char *oldpass = "test";
1208         char *newpass = "test2";
1209         uint8_t old_nt_hash[16], new_nt_hash[16];
1210         uint8_t old_lm_hash[16], new_lm_hash[16];
1211
1212         status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1213         if (!NT_STATUS_IS_OK(status)) {
1214                 return false;
1215         }
1216
1217         printf("Testing ChangePasswordUser for user 'testuser'\n");
1218
1219         printf("old password: %s\n", oldpass);
1220         printf("new password: %s\n", newpass);
1221
1222         E_md4hash(oldpass, old_nt_hash);
1223         E_md4hash(newpass, new_nt_hash);
1224         E_deshash(oldpass, old_lm_hash);
1225         E_deshash(newpass, new_lm_hash);
1226
1227         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1228         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1229         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1230         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1231         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1232         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1233
1234         r.in.handle = &user_handle;
1235         r.in.lm_present = 1;
1236         r.in.old_lm_crypted = &hash1;
1237         r.in.new_lm_crypted = &hash2;
1238         r.in.nt_present = 1;
1239         r.in.old_nt_crypted = &hash3;
1240         r.in.new_nt_crypted = &hash4;
1241         r.in.cross1_present = 1;
1242         r.in.nt_cross = &hash5;
1243         r.in.cross2_present = 1;
1244         r.in.lm_cross = &hash6;
1245
1246         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1247         if (!NT_STATUS_IS_OK(status)) {
1248                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1249                 ret = false;
1250         }
1251
1252         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1253                 ret = false;
1254         }
1255
1256         return ret;
1257 }
1258 #endif
1259
1260 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1261                                     const char *acct_name, 
1262                                     struct policy_handle *handle, char **password)
1263 {
1264         NTSTATUS status;
1265         struct samr_ChangePasswordUser r;
1266         bool ret = true;
1267         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1268         struct policy_handle user_handle;
1269         char *oldpass;
1270         uint8_t old_nt_hash[16], new_nt_hash[16];
1271         uint8_t old_lm_hash[16], new_lm_hash[16];
1272         bool changed = true;
1273
1274         char *newpass;
1275         struct samr_GetUserPwInfo pwp;
1276         struct samr_PwInfo info;
1277         int policy_min_pw_len = 0;
1278
1279         status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1280         if (!NT_STATUS_IS_OK(status)) {
1281                 return false;
1282         }
1283         pwp.in.user_handle = &user_handle;
1284         pwp.out.info = &info;
1285
1286         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1287         if (NT_STATUS_IS_OK(status)) {
1288                 policy_min_pw_len = pwp.out.info->min_password_length;
1289         }
1290         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1291
1292         torture_comment(tctx, "Testing ChangePasswordUser\n");
1293
1294         torture_assert(tctx, *password != NULL, 
1295                                    "Failing ChangePasswordUser as old password was NULL.  Previous test failed?");
1296
1297         oldpass = *password;
1298
1299         E_md4hash(oldpass, old_nt_hash);
1300         E_md4hash(newpass, new_nt_hash);
1301         E_deshash(oldpass, old_lm_hash);
1302         E_deshash(newpass, new_lm_hash);
1303
1304         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1305         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1306         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1307         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1308         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1309         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1310
1311         r.in.user_handle = &user_handle;
1312         r.in.lm_present = 1;
1313         /* Break the LM hash */
1314         hash1.hash[0]++;
1315         r.in.old_lm_crypted = &hash1;
1316         r.in.new_lm_crypted = &hash2;
1317         r.in.nt_present = 1;
1318         r.in.old_nt_crypted = &hash3;
1319         r.in.new_nt_crypted = &hash4;
1320         r.in.cross1_present = 1;
1321         r.in.nt_cross = &hash5;
1322         r.in.cross2_present = 1;
1323         r.in.lm_cross = &hash6;
1324
1325         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1326         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1327                 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1328
1329         /* Unbreak the LM hash */
1330         hash1.hash[0]--;
1331
1332         r.in.user_handle = &user_handle;
1333         r.in.lm_present = 1;
1334         r.in.old_lm_crypted = &hash1;
1335         r.in.new_lm_crypted = &hash2;
1336         /* Break the NT hash */
1337         hash3.hash[0]--;
1338         r.in.nt_present = 1;
1339         r.in.old_nt_crypted = &hash3;
1340         r.in.new_nt_crypted = &hash4;
1341         r.in.cross1_present = 1;
1342         r.in.nt_cross = &hash5;
1343         r.in.cross2_present = 1;
1344         r.in.lm_cross = &hash6;
1345
1346         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1347         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD, 
1348                 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1349
1350         /* Unbreak the NT hash */
1351         hash3.hash[0]--;
1352
1353         r.in.user_handle = &user_handle;
1354         r.in.lm_present = 1;
1355         r.in.old_lm_crypted = &hash1;
1356         r.in.new_lm_crypted = &hash2;
1357         r.in.nt_present = 1;
1358         r.in.old_nt_crypted = &hash3;
1359         r.in.new_nt_crypted = &hash4;
1360         r.in.cross1_present = 1;
1361         r.in.nt_cross = &hash5;
1362         r.in.cross2_present = 1;
1363         /* Break the LM cross */
1364         hash6.hash[0]++;
1365         r.in.lm_cross = &hash6;
1366
1367         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1368         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1369                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1370                 ret = false;
1371         }
1372
1373         /* Unbreak the LM cross */
1374         hash6.hash[0]--;
1375
1376         r.in.user_handle = &user_handle;
1377         r.in.lm_present = 1;
1378         r.in.old_lm_crypted = &hash1;
1379         r.in.new_lm_crypted = &hash2;
1380         r.in.nt_present = 1;
1381         r.in.old_nt_crypted = &hash3;
1382         r.in.new_nt_crypted = &hash4;
1383         r.in.cross1_present = 1;
1384         /* Break the NT cross */
1385         hash5.hash[0]++;
1386         r.in.nt_cross = &hash5;
1387         r.in.cross2_present = 1;
1388         r.in.lm_cross = &hash6;
1389
1390         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1391         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1392                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1393                 ret = false;
1394         }
1395
1396         /* Unbreak the NT cross */
1397         hash5.hash[0]--;
1398
1399
1400         /* Reset the hashes to not broken values */
1401         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1402         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1403         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1404         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1405         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1406         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1407
1408         r.in.user_handle = &user_handle;
1409         r.in.lm_present = 1;
1410         r.in.old_lm_crypted = &hash1;
1411         r.in.new_lm_crypted = &hash2;
1412         r.in.nt_present = 1;
1413         r.in.old_nt_crypted = &hash3;
1414         r.in.new_nt_crypted = &hash4;
1415         r.in.cross1_present = 1;
1416         r.in.nt_cross = &hash5;
1417         r.in.cross2_present = 0;
1418         r.in.lm_cross = NULL;
1419
1420         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1421         if (NT_STATUS_IS_OK(status)) {
1422                 changed = true;
1423                 *password = newpass;
1424         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1425                 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1426                 ret = false;
1427         }
1428
1429         oldpass = newpass;
1430         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1431
1432         E_md4hash(oldpass, old_nt_hash);
1433         E_md4hash(newpass, new_nt_hash);
1434         E_deshash(oldpass, old_lm_hash);
1435         E_deshash(newpass, new_lm_hash);
1436
1437
1438         /* Reset the hashes to not broken values */
1439         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1440         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1441         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1442         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1443         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1444         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1445
1446         r.in.user_handle = &user_handle;
1447         r.in.lm_present = 1;
1448         r.in.old_lm_crypted = &hash1;
1449         r.in.new_lm_crypted = &hash2;
1450         r.in.nt_present = 1;
1451         r.in.old_nt_crypted = &hash3;
1452         r.in.new_nt_crypted = &hash4;
1453         r.in.cross1_present = 0;
1454         r.in.nt_cross = NULL;
1455         r.in.cross2_present = 1;
1456         r.in.lm_cross = &hash6;
1457
1458         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1459         if (NT_STATUS_IS_OK(status)) {
1460                 changed = true;
1461                 *password = newpass;
1462         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1463                 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1464                 ret = false;
1465         }
1466
1467         oldpass = newpass;
1468         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1469
1470         E_md4hash(oldpass, old_nt_hash);
1471         E_md4hash(newpass, new_nt_hash);
1472         E_deshash(oldpass, old_lm_hash);
1473         E_deshash(newpass, new_lm_hash);
1474
1475
1476         /* Reset the hashes to not broken values */
1477         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1478         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1479         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1480         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1481         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1482         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1483
1484         r.in.user_handle = &user_handle;
1485         r.in.lm_present = 1;
1486         r.in.old_lm_crypted = &hash1;
1487         r.in.new_lm_crypted = &hash2;
1488         r.in.nt_present = 1;
1489         r.in.old_nt_crypted = &hash3;
1490         r.in.new_nt_crypted = &hash4;
1491         r.in.cross1_present = 1;
1492         r.in.nt_cross = &hash5;
1493         r.in.cross2_present = 1;
1494         r.in.lm_cross = &hash6;
1495
1496         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1497         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1498                 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1499         } else  if (!NT_STATUS_IS_OK(status)) {
1500                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1501                 ret = false;
1502         } else {
1503                 changed = true;
1504                 *password = newpass;
1505         }
1506
1507         r.in.user_handle = &user_handle;
1508         r.in.lm_present = 1;
1509         r.in.old_lm_crypted = &hash1;
1510         r.in.new_lm_crypted = &hash2;
1511         r.in.nt_present = 1;
1512         r.in.old_nt_crypted = &hash3;
1513         r.in.new_nt_crypted = &hash4;
1514         r.in.cross1_present = 1;
1515         r.in.nt_cross = &hash5;
1516         r.in.cross2_present = 1;
1517         r.in.lm_cross = &hash6;
1518
1519         if (changed) {
1520                 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1521                 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1522                         printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1523                 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1524                         printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1525                         ret = false;
1526                 }
1527         }
1528
1529         
1530         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1531                 ret = false;
1532         }
1533
1534         return ret;
1535 }
1536
1537
1538 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1539                                         const char *acct_name,
1540                                         struct policy_handle *handle, char **password)
1541 {
1542         NTSTATUS status;
1543         struct samr_OemChangePasswordUser2 r;
1544         bool ret = true;
1545         struct samr_Password lm_verifier;
1546         struct samr_CryptPassword lm_pass;
1547         struct lsa_AsciiString server, account, account_bad;
1548         char *oldpass;
1549         char *newpass;
1550         uint8_t old_lm_hash[16], new_lm_hash[16];
1551
1552         struct samr_GetDomPwInfo dom_pw_info;
1553         struct samr_PwInfo info;
1554         int policy_min_pw_len = 0;
1555
1556         struct lsa_String domain_name;
1557
1558         domain_name.string = "";
1559         dom_pw_info.in.domain_name = &domain_name;
1560         dom_pw_info.out.info = &info;
1561
1562         torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1563
1564         torture_assert(tctx, *password != NULL, 
1565                                    "Failing OemChangePasswordUser2 as old password was NULL.  Previous test failed?");
1566
1567         oldpass = *password;
1568
1569         status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1570         if (NT_STATUS_IS_OK(status)) {
1571                 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1572         }
1573
1574         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1575
1576         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1577         account.string = acct_name;
1578
1579         E_deshash(oldpass, old_lm_hash);
1580         E_deshash(newpass, new_lm_hash);
1581
1582         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1583         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1584         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1585
1586         r.in.server = &server;
1587         r.in.account = &account;
1588         r.in.password = &lm_pass;
1589         r.in.hash = &lm_verifier;
1590
1591         /* Break the verification */
1592         lm_verifier.hash[0]++;
1593
1594         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1595
1596         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1597             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1598                 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1599                         nt_errstr(status));
1600                 ret = false;
1601         }
1602
1603         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1604         /* Break the old password */
1605         old_lm_hash[0]++;
1606         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1607         /* unbreak it for the next operation */
1608         old_lm_hash[0]--;
1609         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1610
1611         r.in.server = &server;
1612         r.in.account = &account;
1613         r.in.password = &lm_pass;
1614         r.in.hash = &lm_verifier;
1615
1616         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1617
1618         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1619             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1620                 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1621                         nt_errstr(status));
1622                 ret = false;
1623         }
1624
1625         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1626         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1627
1628         r.in.server = &server;
1629         r.in.account = &account;
1630         r.in.password = &lm_pass;
1631         r.in.hash = NULL;
1632
1633         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1634
1635         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1636             && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1637                 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1638                         nt_errstr(status));
1639                 ret = false;
1640         }
1641
1642         /* This shouldn't be a valid name */
1643         account_bad.string = TEST_ACCOUNT_NAME "XX";
1644         r.in.account = &account_bad;
1645
1646         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1647
1648         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1649                 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1650                         nt_errstr(status));
1651                 ret = false;
1652         }
1653
1654         /* This shouldn't be a valid name */
1655         account_bad.string = TEST_ACCOUNT_NAME "XX";
1656         r.in.account = &account_bad;
1657         r.in.password = &lm_pass;
1658         r.in.hash = &lm_verifier;
1659
1660         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1661
1662         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1663                 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1664                         nt_errstr(status));
1665                 ret = false;
1666         }
1667
1668         /* This shouldn't be a valid name */
1669         account_bad.string = TEST_ACCOUNT_NAME "XX";
1670         r.in.account = &account_bad;
1671         r.in.password = NULL;
1672         r.in.hash = &lm_verifier;
1673
1674         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1675
1676         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1677                 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1678                         nt_errstr(status));
1679                 ret = false;
1680         }
1681
1682         E_deshash(oldpass, old_lm_hash);
1683         E_deshash(newpass, new_lm_hash);
1684
1685         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1686         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1687         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1688
1689         r.in.server = &server;
1690         r.in.account = &account;
1691         r.in.password = &lm_pass;
1692         r.in.hash = &lm_verifier;
1693
1694         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1695         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1696                 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1697         } else if (!NT_STATUS_IS_OK(status)) {
1698                 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1699                 ret = false;
1700         } else {
1701                 *password = newpass;
1702         }
1703
1704         return ret;
1705 }
1706
1707
1708 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1709                                      const char *acct_name,
1710                                      char **password,
1711                                      char *newpass, bool allow_password_restriction)
1712 {
1713         NTSTATUS status;
1714         struct samr_ChangePasswordUser2 r;
1715         bool ret = true;
1716         struct lsa_String server, account;
1717         struct samr_CryptPassword nt_pass, lm_pass;
1718         struct samr_Password nt_verifier, lm_verifier;
1719         char *oldpass;
1720         uint8_t old_nt_hash[16], new_nt_hash[16];
1721         uint8_t old_lm_hash[16], new_lm_hash[16];
1722
1723         struct samr_GetDomPwInfo dom_pw_info;
1724         struct samr_PwInfo info;
1725
1726         struct lsa_String domain_name;
1727
1728         domain_name.string = "";
1729         dom_pw_info.in.domain_name = &domain_name;
1730         dom_pw_info.out.info = &info;
1731
1732         torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
1733
1734         torture_assert(tctx, *password != NULL, 
1735                                    "Failing ChangePasswordUser2 as old password was NULL.  Previous test failed?");
1736         oldpass = *password;
1737
1738         if (!newpass) {
1739                 int policy_min_pw_len = 0;
1740                 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1741                 if (NT_STATUS_IS_OK(status)) {
1742                         policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1743                 }
1744
1745                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1746         } 
1747
1748         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1749         init_lsa_String(&account, acct_name);
1750
1751         E_md4hash(oldpass, old_nt_hash);
1752         E_md4hash(newpass, new_nt_hash);
1753
1754         E_deshash(oldpass, old_lm_hash);
1755         E_deshash(newpass, new_lm_hash);
1756
1757         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1758         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1759         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1760
1761         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1762         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1763         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1764
1765         r.in.server = &server;
1766         r.in.account = &account;
1767         r.in.nt_password = &nt_pass;
1768         r.in.nt_verifier = &nt_verifier;
1769         r.in.lm_change = 1;
1770         r.in.lm_password = &lm_pass;
1771         r.in.lm_verifier = &lm_verifier;
1772
1773         status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
1774         if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1775                 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1776         } else if (!NT_STATUS_IS_OK(status)) {
1777                 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1778                 ret = false;
1779         } else {
1780                 *password = newpass;
1781         }
1782
1783         return ret;
1784 }
1785
1786
1787 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx, 
1788                               const char *account_string,
1789                               int policy_min_pw_len,
1790                               char **password,
1791                               const char *newpass,
1792                               NTTIME last_password_change,
1793                               bool handle_reject_reason)
1794 {
1795         NTSTATUS status;
1796         struct samr_ChangePasswordUser3 r;
1797         bool ret = true;
1798         struct lsa_String server, account, account_bad;
1799         struct samr_CryptPassword nt_pass, lm_pass;
1800         struct samr_Password nt_verifier, lm_verifier;
1801         char *oldpass;
1802         uint8_t old_nt_hash[16], new_nt_hash[16];
1803         uint8_t old_lm_hash[16], new_lm_hash[16];
1804         NTTIME t;
1805         struct samr_DomInfo1 *dominfo = NULL;
1806         struct samr_ChangeReject *reject = NULL;
1807
1808         torture_comment(tctx, "Testing ChangePasswordUser3\n");
1809
1810         if (newpass == NULL) {
1811                 do {
1812                         if (policy_min_pw_len == 0) {
1813                                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1814                         } else {
1815                                 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
1816                         }
1817                 } while (check_password_quality(newpass) == false);
1818         } else {
1819                 torture_comment(tctx, "Using password '%s'\n", newpass);
1820         }
1821
1822         torture_assert(tctx, *password != NULL, 
1823                                    "Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?");
1824
1825         oldpass = *password;
1826         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1827         init_lsa_String(&account, account_string);
1828
1829         E_md4hash(oldpass, old_nt_hash);
1830         E_md4hash(newpass, new_nt_hash);
1831
1832         E_deshash(oldpass, old_lm_hash);
1833         E_deshash(newpass, new_lm_hash);
1834
1835         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1836         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1837         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1838
1839         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1840         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1841         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1842         
1843         /* Break the verification */
1844         nt_verifier.hash[0]++;
1845
1846         r.in.server = &server;
1847         r.in.account = &account;
1848         r.in.nt_password = &nt_pass;
1849         r.in.nt_verifier = &nt_verifier;
1850         r.in.lm_change = 1;
1851         r.in.lm_password = &lm_pass;
1852         r.in.lm_verifier = &lm_verifier;
1853         r.in.password3 = NULL;
1854         r.out.dominfo = &dominfo;
1855         r.out.reject = &reject;
1856
1857         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1858         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1859             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1860                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1861                         nt_errstr(status));
1862                 ret = false;
1863         }
1864         
1865         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1866         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1867         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1868
1869         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1870         /* Break the NT hash */
1871         old_nt_hash[0]++;
1872         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1873         /* Unbreak it again */
1874         old_nt_hash[0]--;
1875         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1876         
1877         r.in.server = &server;
1878         r.in.account = &account;
1879         r.in.nt_password = &nt_pass;
1880         r.in.nt_verifier = &nt_verifier;
1881         r.in.lm_change = 1;
1882         r.in.lm_password = &lm_pass;
1883         r.in.lm_verifier = &lm_verifier;
1884         r.in.password3 = NULL;
1885         r.out.dominfo = &dominfo;
1886         r.out.reject = &reject;
1887
1888         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1889         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1890             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1891                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1892                         nt_errstr(status));
1893                 ret = false;
1894         }
1895         
1896         /* This shouldn't be a valid name */
1897         init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
1898
1899         r.in.account = &account_bad;
1900         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1901         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1902                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1903                         nt_errstr(status));
1904                 ret = false;
1905         }
1906
1907         E_md4hash(oldpass, old_nt_hash);
1908         E_md4hash(newpass, new_nt_hash);
1909
1910         E_deshash(oldpass, old_lm_hash);
1911         E_deshash(newpass, new_lm_hash);
1912
1913         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1914         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1915         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1916
1917         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1918         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1919         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1920
1921         r.in.server = &server;
1922         r.in.account = &account;
1923         r.in.nt_password = &nt_pass;
1924         r.in.nt_verifier = &nt_verifier;
1925         r.in.lm_change = 1;
1926         r.in.lm_password = &lm_pass;
1927         r.in.lm_verifier = &lm_verifier;
1928         r.in.password3 = NULL;
1929         r.out.dominfo = &dominfo;
1930         r.out.reject = &reject;
1931
1932         unix_to_nt_time(&t, time(NULL));
1933
1934         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1935
1936         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1937             && dominfo
1938             && reject
1939             && handle_reject_reason
1940             && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
1941                 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1942
1943                         if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
1944                                 printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
1945                                         SAMR_REJECT_OTHER, reject->reason);
1946                                 return false;
1947                         }
1948                 }
1949
1950                 /* We tested the order of precendence which is as follows:
1951                 
1952                 * pwd min_age 
1953                 * pwd length
1954                 * pwd complexity
1955                 * pwd history
1956
1957                 Guenther */
1958
1959                 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1960                            (last_password_change + dominfo->min_password_age > t)) {
1961
1962                         if (reject->reason != SAMR_REJECT_OTHER) {
1963                                 printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
1964                                         SAMR_REJECT_OTHER, reject->reason);
1965                                 return false;
1966                         }
1967
1968                 } else if ((dominfo->min_password_length > 0) &&
1969                            (strlen(newpass) < dominfo->min_password_length)) {
1970
1971                         if (reject->reason != SAMR_REJECT_TOO_SHORT) {
1972                                 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n", 
1973                                         SAMR_REJECT_TOO_SHORT, reject->reason);
1974                                 return false;
1975                         }
1976
1977                 } else if ((dominfo->password_history_length > 0) &&
1978                             strequal(oldpass, newpass)) {
1979
1980                         if (reject->reason != SAMR_REJECT_IN_HISTORY) {
1981                                 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n", 
1982                                         SAMR_REJECT_IN_HISTORY, reject->reason);
1983                                 return false;
1984                         }
1985                 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1986
1987                         if (reject->reason != SAMR_REJECT_COMPLEXITY) {
1988                                 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n", 
1989                                         SAMR_REJECT_COMPLEXITY, reject->reason);
1990                                 return false;
1991                         }
1992
1993                 }
1994
1995                 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
1996                         /* retry with adjusted size */
1997                         return test_ChangePasswordUser3(p, tctx, account_string, 
1998                                                         dominfo->min_password_length,
1999                                                         password, NULL, 0, false); 
2000
2001                 }
2002
2003         } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2004                 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2005                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
2006                                SAMR_REJECT_OTHER, reject->reason);
2007                         return false;
2008                 }
2009                 /* Perhaps the server has a 'min password age' set? */
2010
2011         } else { 
2012                 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2013                 *password = talloc_strdup(tctx, newpass);
2014         }
2015
2016         return ret;
2017 }
2018
2019 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2020                                     const char *account_string,
2021                                     struct policy_handle *handle, 
2022                                     char **password)
2023 {
2024         NTSTATUS status;
2025         struct samr_ChangePasswordUser3 r;
2026         struct samr_SetUserInfo s;
2027         union samr_UserInfo u;
2028         DATA_BLOB session_key;
2029         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2030         uint8_t confounder[16];
2031         struct MD5Context ctx;
2032
2033         bool ret = true;
2034         struct lsa_String server, account;
2035         struct samr_CryptPassword nt_pass;
2036         struct samr_Password nt_verifier;
2037         DATA_BLOB new_random_pass;
2038         char *newpass;
2039         char *oldpass;
2040         uint8_t old_nt_hash[16], new_nt_hash[16];
2041         NTTIME t;
2042         struct samr_DomInfo1 *dominfo = NULL;
2043         struct samr_ChangeReject *reject = NULL;
2044
2045         new_random_pass = samr_very_rand_pass(tctx, 128);
2046
2047         torture_assert(tctx, *password != NULL, 
2048                                    "Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?");
2049
2050         oldpass = *password;
2051         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2052         init_lsa_String(&account, account_string);
2053
2054         s.in.user_handle = handle;
2055         s.in.info = &u;
2056         s.in.level = 25;
2057
2058         ZERO_STRUCT(u);
2059
2060         u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
2061
2062         set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2063
2064         status = dcerpc_fetch_session_key(p, &session_key);
2065         if (!NT_STATUS_IS_OK(status)) {
2066                 printf("SetUserInfo level %u - no session key - %s\n",
2067                        s.in.level, nt_errstr(status));
2068                 return false;
2069         }
2070
2071         generate_random_buffer((uint8_t *)confounder, 16);
2072
2073         MD5Init(&ctx);
2074         MD5Update(&ctx, confounder, 16);
2075         MD5Update(&ctx, session_key.data, session_key.length);
2076         MD5Final(confounded_session_key.data, &ctx);
2077
2078         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2079         memcpy(&u.info25.password.data[516], confounder, 16);
2080
2081         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2082
2083         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2084         if (!NT_STATUS_IS_OK(status)) {
2085                 printf("SetUserInfo level %u failed - %s\n",
2086                        s.in.level, nt_errstr(status));
2087                 ret = false;
2088         }
2089
2090         torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2091
2092         mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2093
2094         new_random_pass = samr_very_rand_pass(tctx, 128);
2095
2096         mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2097
2098         set_pw_in_buffer(nt_pass.data, &new_random_pass);
2099         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2100         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2101
2102         r.in.server = &server;
2103         r.in.account = &account;
2104         r.in.nt_password = &nt_pass;
2105         r.in.nt_verifier = &nt_verifier;
2106         r.in.lm_change = 0;
2107         r.in.lm_password = NULL;
2108         r.in.lm_verifier = NULL;
2109         r.in.password3 = NULL;
2110         r.out.dominfo = &dominfo;
2111         r.out.reject = &reject;
2112
2113         unix_to_nt_time(&t, time(NULL));
2114
2115         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2116
2117         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2118                 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2119                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
2120                                SAMR_REJECT_OTHER, reject->reason);
2121                         return false;
2122                 }
2123                 /* Perhaps the server has a 'min password age' set? */
2124
2125         } else if (!NT_STATUS_IS_OK(status)) {
2126                 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2127                 ret = false;
2128         }
2129         
2130         newpass = samr_rand_pass(tctx, 128);
2131
2132         mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2133
2134         E_md4hash(newpass, new_nt_hash);
2135
2136         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2137         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2138         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2139
2140         r.in.server = &server;
2141         r.in.account = &account;
2142         r.in.nt_password = &nt_pass;
2143         r.in.nt_verifier = &nt_verifier;
2144         r.in.lm_change = 0;
2145         r.in.lm_password = NULL;
2146         r.in.lm_verifier = NULL;
2147         r.in.password3 = NULL;
2148         r.out.dominfo = &dominfo;
2149         r.out.reject = &reject;
2150
2151         unix_to_nt_time(&t, time(NULL));
2152
2153         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2154
2155         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2156                 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2157                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
2158                                SAMR_REJECT_OTHER, reject->reason);
2159                         return false;
2160                 }
2161                 /* Perhaps the server has a 'min password age' set? */
2162
2163         } else {
2164                 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2165                 *password = talloc_strdup(tctx, newpass);
2166         }
2167
2168         return ret;
2169 }
2170
2171
2172 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2173                                   struct policy_handle *alias_handle)
2174 {
2175         struct samr_GetMembersInAlias r;
2176         struct lsa_SidArray sids;
2177         NTSTATUS status;
2178
2179         torture_comment(tctx, "Testing GetMembersInAlias\n");
2180
2181         r.in.alias_handle = alias_handle;
2182         r.out.sids = &sids;
2183
2184         status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2185         torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2186
2187         return true;
2188 }
2189
2190 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2191                                   struct policy_handle *alias_handle,
2192                                   const struct dom_sid *domain_sid)
2193 {
2194         struct samr_AddAliasMember r;
2195         struct samr_DeleteAliasMember d;
2196         NTSTATUS status;
2197         struct dom_sid *sid;
2198
2199         sid = dom_sid_add_rid(tctx, domain_sid, 512);
2200
2201         torture_comment(tctx, "testing AddAliasMember\n");
2202         r.in.alias_handle = alias_handle;
2203         r.in.sid = sid;
2204
2205         status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2206         torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2207
2208         d.in.alias_handle = alias_handle;
2209         d.in.sid = sid;
2210
2211         status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2212         torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2213
2214         return true;
2215 }
2216
2217 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2218                                            struct policy_handle *alias_handle)
2219 {
2220         struct samr_AddMultipleMembersToAlias a;
2221         struct samr_RemoveMultipleMembersFromAlias r;
2222         NTSTATUS status;
2223         struct lsa_SidArray sids;
2224
2225         torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2226         a.in.alias_handle = alias_handle;
2227         a.in.sids = &sids;
2228
2229         sids.num_sids = 3;
2230         sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2231
2232         sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2233         sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2234         sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2235
2236         status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2237         torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2238
2239
2240         torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2241         r.in.alias_handle = alias_handle;
2242         r.in.sids = &sids;
2243
2244         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2245         torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2246
2247         /* strange! removing twice doesn't give any error */
2248         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2249         torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2250
2251         /* but removing an alias that isn't there does */
2252         sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2253
2254         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2255         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2256
2257         return true;
2258 }
2259
2260 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2261                                             struct policy_handle *user_handle)
2262 {
2263         struct samr_TestPrivateFunctionsUser r;
2264         NTSTATUS status;
2265
2266         torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2267
2268         r.in.user_handle = user_handle;
2269
2270         status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2271         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2272
2273         return true;
2274 }
2275
2276 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2277                                           struct torture_context *tctx,
2278                                           struct policy_handle *handle,
2279                                           bool use_info2,
2280                                           NTTIME *pwdlastset)
2281 {
2282         NTSTATUS status;
2283         uint16_t levels[] = { /* 3, */ 5, 21 };
2284         int i;
2285         NTTIME pwdlastset3 = 0;
2286         NTTIME pwdlastset5 = 0;
2287         NTTIME pwdlastset21 = 0;
2288
2289         torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2290                         use_info2 ? "2":"");
2291
2292         for (i=0; i<ARRAY_SIZE(levels); i++) {
2293
2294                 struct samr_QueryUserInfo r;
2295                 struct samr_QueryUserInfo2 r2;
2296                 union samr_UserInfo *info;
2297
2298                 if (use_info2) {
2299                         r2.in.user_handle = handle;
2300                         r2.in.level = levels[i];
2301                         r2.out.info = &info;
2302                         status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2303
2304                 } else {
2305                         r.in.user_handle = handle;
2306                         r.in.level = levels[i];
2307                         r.out.info = &info;
2308                         status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2309                 }
2310
2311                 if (!NT_STATUS_IS_OK(status) &&
2312                     !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2313                         printf("QueryUserInfo%s level %u failed - %s\n",
2314                                use_info2 ? "2":"", levels[i], nt_errstr(status));
2315                         return false;
2316                 }
2317
2318                 switch (levels[i]) {
2319                 case 3:
2320                         pwdlastset3 = info->info3.last_password_change;
2321                         break;
2322                 case 5:
2323                         pwdlastset5 = info->info5.last_password_change;
2324                         break;
2325                 case 21:
2326                         pwdlastset21 = info->info21.last_password_change;
2327                         break;
2328                 default:
2329                         return false;
2330                 }
2331         }
2332         /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2333                                     "pwdlastset mixup"); */
2334         torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2335                                  "pwdlastset mixup");
2336
2337         *pwdlastset = pwdlastset21;
2338
2339         torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2340
2341         return true;
2342 }
2343
2344 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2345                                    struct torture_context *tctx,
2346                                    struct policy_handle *handle,
2347                                    uint16_t level,
2348                                    uint32_t fields_present,
2349                                    uint8_t password_expired,
2350                                    NTSTATUS expected_error,
2351                                    bool use_setinfo2,
2352                                    char **password,
2353                                    bool use_queryinfo2,
2354                                    NTTIME *pwdlastset)
2355 {
2356         const char *fields = NULL;
2357         bool ret = true;
2358
2359         switch (level) {
2360         case 21:
2361         case 23:
2362         case 25:
2363                 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2364                                          fields_present);
2365                 break;
2366         default:
2367                 break;
2368         }
2369
2370         torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2371                 "(password_expired: %d) %s\n",
2372                 use_setinfo2 ? "2":"", level, password_expired,
2373                 fields ? fields : "");
2374
2375         switch (level) {
2376                 case 21:
2377                 case 23:
2378                 case 24:
2379                 case 25:
2380                 case 26:
2381                         if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2382                                                        fields_present,
2383                                                        password,
2384                                                        password_expired,
2385                                                        use_setinfo2,
2386                                                        expected_error)) {
2387                                 ret = false;
2388                         }
2389                         break;
2390                 default:
2391                         return false;
2392         }
2393
2394         if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2395                                            use_queryinfo2,
2396                                            pwdlastset)) {
2397                 ret = false;
2398         }
2399
2400         return ret;
2401 }
2402
2403 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2404                                         struct torture_context *tctx,
2405                                         uint32_t acct_flags,
2406                                         struct policy_handle *handle,
2407                                         char **password)
2408 {
2409         int i, s = 0, q = 0;
2410         bool ret = true;
2411         int delay = 500000;
2412         bool set_levels[] = { false, true };
2413         bool query_levels[] = { false, true };
2414
2415         struct {
2416                 uint16_t level;
2417                 uint8_t password_expired_nonzero;
2418                 uint32_t fields_present;
2419                 bool query_info2;
2420                 bool set_info2;
2421                 NTSTATUS set_error;
2422         } pwd_tests[] = {
2423
2424                 /* level 21 */
2425                 {
2426                         .level                          = 21,
2427                         .password_expired_nonzero       = 1,
2428                         .fields_present                 = SAMR_FIELD_EXPIRED_FLAG
2429                 },{
2430                         .level                          = 21,
2431                         .password_expired_nonzero       = 1,
2432                         .fields_present                 = SAMR_FIELD_LAST_PWD_CHANGE,
2433                         .set_error                      = NT_STATUS_ACCESS_DENIED
2434 #if 0
2435         /* FIXME */
2436                 },{
2437                         .level                          = 21,
2438                         .password_expired_nonzero       = 1,
2439                         .fields_present                 = SAMR_FIELD_PASSWORD |
2440                                                           SAMR_FIELD_PASSWORD2 |
2441                                                           SAMR_FIELD_LAST_PWD_CHANGE,
2442                         .query_info2                    = false,
2443                         .set_error                      = NT_STATUS_ACCESS_DENIED
2444 #endif
2445
2446                 /* level 23 */
2447                 },{
2448                         .level                          = 23,
2449                         .password_expired_nonzero       = 1,
2450                         .fields_present                 = SAMR_FIELD_EXPIRED_FLAG
2451                 },{
2452                         .level                          = 23,
2453                         .password_expired_nonzero       = 1,
2454                         .fields_present                 = SAMR_FIELD_LAST_PWD_CHANGE,
2455                         .set_error                      = NT_STATUS_ACCESS_DENIED
2456                 },{
2457                         .level                          = 23,
2458                         .password_expired_nonzero       = 1,
2459                         .fields_present                 = SAMR_FIELD_LAST_PWD_CHANGE |
2460                                                           SAMR_FIELD_PASSWORD |
2461                                                           SAMR_FIELD_PASSWORD2,
2462                         .set_error                      = NT_STATUS_ACCESS_DENIED
2463                 },{
2464                         .level                          = 23,
2465                         .password_expired_nonzero       = 1,
2466                         .fields_present                 = SAMR_FIELD_LAST_PWD_CHANGE |
2467                                                           SAMR_FIELD_PASSWORD |
2468                                                           SAMR_FIELD_PASSWORD2 |
2469                                                           SAMR_FIELD_EXPIRED_FLAG,
2470                         .set_error                      = NT_STATUS_ACCESS_DENIED
2471                 },{
2472                         .level                          = 23,
2473                         .password_expired_nonzero       = 1,
2474                         .fields_present                 = SAMR_FIELD_PASSWORD |
2475                                                           SAMR_FIELD_PASSWORD2 |
2476                                                           SAMR_FIELD_EXPIRED_FLAG
2477                 },{
2478                         .level                          = 23,
2479                         .password_expired_nonzero       = 1,
2480                         .fields_present                 = SAMR_FIELD_PASSWORD |
2481                                                           SAMR_FIELD_PASSWORD2
2482                 },{
2483
2484                 /* level 24 */
2485
2486                         .level                          = 24,
2487                         .password_expired_nonzero       = 1
2488                 },{
2489                         .level                          = 24,
2490                         .password_expired_nonzero       = 24
2491                 },{
2492
2493                 /* level 25 */
2494
2495                         .level                          = 25,
2496                         .password_expired_nonzero       = 1,
2497                         .fields_present                 = SAMR_FIELD_LAST_PWD_CHANGE,
2498                         .set_error                      = NT_STATUS_ACCESS_DENIED
2499                 },{
2500                         .level                          = 25,
2501                         .password_expired_nonzero       = 1,
2502                         .fields_present                 = SAMR_FIELD_EXPIRED_FLAG,
2503                 },{
2504                         .level                          = 25,
2505                         .password_expired_nonzero       = 1,
2506                         .fields_present                 = SAMR_FIELD_PASSWORD |
2507                                                           SAMR_FIELD_PASSWORD2 |
2508                                                           SAMR_FIELD_EXPIRED_FLAG
2509                 },{
2510                         .level                          = 25,
2511                         .password_expired_nonzero       = 1,
2512                         .fields_present                 = SAMR_FIELD_PASSWORD |
2513                                                           SAMR_FIELD_PASSWORD2
2514                 },{
2515
2516                 /* level 26 */
2517
2518                         .level                          = 26,
2519                         .password_expired_nonzero       = 1
2520                 },{
2521                         .level                          = 26,
2522                         .password_expired_nonzero       = 24
2523                 }
2524         };
2525
2526         if (torture_setting_bool(tctx, "samba3", false)) {
2527                 delay = 1000000;
2528                 printf("Samba3 has second granularity, setting delay to: %d\n",
2529                         delay);
2530         }
2531
2532         /* set to 1 to enable testing for all possible opcode
2533            (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2534            combinations */
2535 #if 0
2536 #define TEST_SET_LEVELS 1
2537 #define TEST_QUERY_LEVELS 1
2538 #endif
2539         for (i=0; i<ARRAY_SIZE(pwd_tests); i++) {
2540 #ifdef TEST_SET_LEVELS
2541         for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2542 #endif
2543 #ifdef TEST_QUERY_LEVELS
2544         for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2545 #endif
2546                 NTTIME pwdlastset_old = 0;
2547                 NTTIME pwdlastset_new = 0;
2548
2549                 /* set #1 */
2550
2551                 torture_comment(tctx, "------------------------------\n"
2552                                 "Testing pwdLastSet attribute for flags: 0x%08x "
2553                                 "(s: %d (l: %d), q: %d)\n",
2554                                 acct_flags, s, pwd_tests[i].level, q);
2555
2556                 if (!test_SetPassword_level(p, tctx, handle,
2557                                             pwd_tests[i].level,
2558                                             pwd_tests[i].fields_present,
2559                                             pwd_tests[i].password_expired_nonzero, /* will set pwdlast to 0 */
2560                                             pwd_tests[i].set_error,
2561                                             set_levels[s],
2562                                             password,
2563                                             query_levels[q],
2564                                             &pwdlastset_old)) {
2565                         ret = false;
2566                 }
2567
2568                 if (!NT_STATUS_IS_OK(pwd_tests[i].set_error)) {
2569                         /* skipping on expected failure */
2570                         continue;
2571                 }
2572
2573                 /* pwdlastset must be 0 afterwards, except for a level 23 and 25
2574                  * set without the SAMR_FIELD_EXPIRED_FLAG */
2575
2576                 switch (pwd_tests[i].level) {
2577                 case 23:
2578                 case 25:
2579                         if ((pwdlastset_new != 0) &&
2580                             !(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG)) {
2581                                 torture_comment(tctx, "not considering a non-0 "
2582                                         "pwdLastSet as a an error as the "
2583                                         "SAMR_FIELD_EXPIRED_FLAG has not "
2584                                         "been set\n");
2585                                 break;
2586                         }
2587                 default:
2588                         if (pwdlastset_new != 0) {
2589                                 torture_warning(tctx, "pwdLastSet test failed: "
2590                                         "expected pwdLastSet 0 but got %lld\n",
2591                                         pwdlastset_old);
2592                                 ret = false;
2593                         }
2594                         break;
2595                 }
2596
2597                 usleep(delay);
2598
2599                 /* set #2 */
2600
2601                 if (!test_SetPassword_level(p, tctx, handle, pwd_tests[i].level,
2602                                             pwd_tests[i].fields_present,
2603                                             0,
2604                                             /* will normally update (increase) the pwdlast */
2605                                             pwd_tests[i].set_error,
2606                                             set_levels[s],
2607                                             password,
2608                                             query_levels[q],
2609                                             &pwdlastset_new)) {
2610
2611                         ret = false;
2612                 }
2613
2614                 /* pwdlastset must not be 0 afterwards and must be larger then
2615                  * the old value */
2616
2617                 if (pwdlastset_old >= pwdlastset_new) {
2618                         torture_warning(tctx, "pwdLastSet test failed: "
2619                                 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
2620                                 pwdlastset_old, pwdlastset_new);
2621                         ret = false;
2622                 }
2623                 if (pwdlastset_new == 0) {
2624                         torture_warning(tctx, "pwdLastSet test failed: "
2625                                 "expected non-0 pwdlastset, got: %lld\n",
2626                                 pwdlastset_new);
2627                         ret = false;
2628                 }
2629                 pwdlastset_old = pwdlastset_new;
2630
2631                 usleep(delay);
2632
2633                 /* set #3 */
2634
2635                 if (!test_SetPassword_level(p, tctx, handle, pwd_tests[i].level,
2636                                             pwd_tests[i].fields_present,
2637                                             pwd_tests[i].password_expired_nonzero,
2638                                             pwd_tests[i].set_error,
2639                                             set_levels[s],
2640                                             password,
2641                                             query_levels[q],
2642                                             &pwdlastset_new)) {
2643                         ret = false;
2644                 }
2645
2646                 if (pwdlastset_old == pwdlastset_new) {
2647                         torture_warning(tctx, "pwdLastSet test failed: "
2648                                 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
2649                                 pwdlastset_old, pwdlastset_new);
2650                         ret = false;
2651                 }
2652
2653                 /* pwdlastset must be 0 afterwards, except for a level 23 and 25
2654                  * set without the SAMR_FIELD_EXPIRED_FLAG */
2655
2656                 switch (pwd_tests[i].level) {
2657                 case 23:
2658                 case 25:
2659                         if ((pwdlastset_new != 0) &&
2660                             !(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG)) {
2661                                 break;
2662                         }
2663                 default:
2664                         if (pwdlastset_new != 0) {
2665                                 torture_warning(tctx, "pwdLastSet test failed: "
2666                                         "expected pwdLastSet 0, got %lld\n",
2667                                         pwdlastset_old);
2668                                 ret = false;
2669                         }
2670                         break;
2671                 }
2672 #ifdef TEST_QUERY_LEVELS
2673         }
2674 #endif
2675 #ifdef TEST_SET_LEVELS
2676         }
2677 #endif
2678         }
2679
2680 #undef TEST_SET_LEVELS
2681 #undef TEST_QUERY_LEVELS
2682
2683         return ret;
2684 }
2685
2686 static bool test_user_ops(struct dcerpc_pipe *p, 
2687                           struct torture_context *tctx,
2688                           struct policy_handle *user_handle, 
2689                           struct policy_handle *domain_handle, 
2690                           uint32_t base_acct_flags, 
2691                           const char *base_acct_name, enum torture_samr_choice which_ops)
2692 {
2693         char *password = NULL;
2694         struct samr_QueryUserInfo q;
2695         union samr_UserInfo *info;
2696         NTSTATUS status;
2697
2698         bool ret = true;
2699         int i;
2700         uint32_t rid;
2701         const uint32_t password_fields[] = {
2702                 SAMR_FIELD_PASSWORD,
2703                 SAMR_FIELD_PASSWORD2,
2704                 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2705                 0
2706         };
2707         
2708         status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2709         if (!NT_STATUS_IS_OK(status)) {
2710                 ret = false;
2711         }
2712
2713         switch (which_ops) {
2714         case TORTURE_SAMR_USER_ATTRIBUTES:
2715                 if (!test_QuerySecurity(p, tctx, user_handle)) {
2716                         ret = false;
2717                 }
2718
2719                 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2720                         ret = false;
2721                 }
2722
2723                 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2724                         ret = false;
2725                 }
2726
2727                 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2728                                       base_acct_name)) {
2729                         ret = false;
2730                 }       
2731
2732                 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2733                         ret = false;
2734                 }
2735
2736                 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2737                         ret = false;
2738                 }
2739
2740                 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2741                         ret = false;
2742                 }
2743                 break;
2744         case TORTURE_SAMR_PASSWORDS:
2745                 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2746                         char simple_pass[9];
2747                         char *v = generate_random_str(tctx, 1);
2748                         
2749                         ZERO_STRUCT(simple_pass);
2750                         memset(simple_pass, *v, sizeof(simple_pass) - 1);
2751
2752                         printf("Testing machine account password policy rules\n");
2753
2754                         /* Workstation trust accounts don't seem to need to honour password quality policy */
2755                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2756                                 ret = false;
2757                         }
2758
2759                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2760                                 ret = false;
2761                         }
2762
2763                         /* reset again, to allow another 'user' password change */
2764                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2765                                 ret = false;
2766                         }
2767
2768                         /* Try a 'short' password */
2769                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2770                                 ret = false;
2771                         }
2772
2773                         /* Try a compleatly random password */
2774                         if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
2775                                 ret = false;
2776                         }
2777                 }
2778
2779                 for (i = 0; password_fields[i]; i++) {
2780                         if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2781                                 ret = false;
2782                         }       
2783                 
2784                         /* check it was set right */
2785                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2786                                 ret = false;
2787                         }
2788                 }               
2789
2790                 for (i = 0; password_fields[i]; i++) {
2791                         if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2792                                 ret = false;
2793                         }       
2794                 
2795                         /* check it was set right */
2796                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2797                                 ret = false;
2798                         }
2799                 }               
2800
2801                 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2802                         ret = false;
2803                 }       
2804
2805                 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2806                         ret = false;
2807                 }       
2808
2809                 q.in.user_handle = user_handle;
2810                 q.in.level = 5;
2811                 q.out.info = &info;
2812                 
2813                 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2814                 if (!NT_STATUS_IS_OK(status)) {
2815                         printf("QueryUserInfo level %u failed - %s\n", 
2816                                q.in.level, nt_errstr(status));
2817                         ret = false;
2818                 } else {
2819                         uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2820                         if ((info->info5.acct_flags) != expected_flags) {
2821                                 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2822                                        info->info5.acct_flags,
2823                                        expected_flags);
2824                                 ret = false;
2825                         }
2826                         if (info->info5.rid != rid) {
2827                                 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2828                                        info->info5.rid, rid);
2829
2830                         }
2831                 }
2832
2833                 break;
2834
2835         case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
2836
2837                 /* test last password change timestamp behaviour */
2838                 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
2839                                                  user_handle, &password)) {
2840                         ret = false;
2841                 }
2842
2843                 if (ret == true) {
2844                         torture_comment(tctx, "pwdLastSet test succeeded\n");
2845                 } else {
2846                         torture_warning(tctx, "pwdLastSet test failed\n");
2847                 }
2848
2849                 break;
2850
2851         case TORTURE_SAMR_OTHER:
2852                 /* We just need the account to exist */
2853                 break;
2854         }
2855         return ret;
2856 }
2857
2858 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2859                            struct policy_handle *alias_handle,
2860                            const struct dom_sid *domain_sid)
2861 {
2862         bool ret = true;
2863
2864         if (!test_QuerySecurity(p, tctx, alias_handle)) {
2865                 ret = false;
2866         }
2867
2868         if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2869                 ret = false;
2870         }
2871
2872         if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2873                 ret = false;
2874         }
2875
2876         if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2877                 ret = false;
2878         }
2879
2880         if (torture_setting_bool(tctx, "samba4", false)) {
2881                 printf("skipping MultipleMembers Alias tests against Samba4\n");
2882                 return ret;
2883         }
2884
2885         if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2886                 ret = false;
2887         }
2888
2889         return ret;
2890 }
2891
2892
2893 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2894                                      struct policy_handle *user_handle)
2895 {
2896         struct samr_DeleteUser d;
2897         NTSTATUS status;
2898         torture_comment(tctx, "Testing DeleteUser\n");
2899
2900         d.in.user_handle = user_handle;
2901         d.out.user_handle = user_handle;
2902
2903         status = dcerpc_samr_DeleteUser(p, tctx, &d);
2904         torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
2905
2906         return true;
2907 }
2908
2909 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2910                             struct policy_handle *handle, const char *name)
2911 {
2912         NTSTATUS status;
2913         struct samr_DeleteUser d;
2914         struct policy_handle user_handle;
2915         uint32_t rid;
2916
2917         status = test_LookupName(p, mem_ctx, handle, name, &rid);
2918         if (!NT_STATUS_IS_OK(status)) {
2919                 goto failed;
2920         }
2921
2922         status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2923         if (!NT_STATUS_IS_OK(status)) {
2924                 goto failed;
2925         }
2926
2927         d.in.user_handle = &user_handle;
2928         d.out.user_handle = &user_handle;
2929         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2930         if (!NT_STATUS_IS_OK(status)) {
2931                 goto failed;
2932         }
2933
2934         return true;
2935
2936 failed:
2937         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2938         return false;
2939 }
2940
2941
2942 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2943                                     struct policy_handle *handle, const char *name)
2944 {
2945         NTSTATUS status;
2946         struct samr_OpenGroup r;
2947         struct samr_DeleteDomainGroup d;
2948         struct policy_handle group_handle;
2949         uint32_t rid;
2950
2951         status = test_LookupName(p, mem_ctx, handle, name, &rid);
2952         if (!NT_STATUS_IS_OK(status)) {
2953                 goto failed;
2954         }
2955
2956         r.in.domain_handle = handle;
2957         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2958         r.in.rid = rid;
2959         r.out.group_handle = &group_handle;
2960         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2961         if (!NT_STATUS_IS_OK(status)) {
2962                 goto failed;
2963         }
2964
2965         d.in.group_handle = &group_handle;
2966         d.out.group_handle = &group_handle;
2967         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2968         if (!NT_STATUS_IS_OK(status)) {
2969                 goto failed;
2970         }
2971
2972         return true;
2973
2974 failed:
2975         printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2976         return false;
2977 }
2978
2979
2980 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2981                                    struct policy_handle *domain_handle, const char *name)
2982 {
2983         NTSTATUS status;
2984         struct samr_OpenAlias r;
2985         struct samr_DeleteDomAlias d;
2986         struct policy_handle alias_handle;
2987         uint32_t rid;
2988
2989         printf("testing DeleteAlias_byname\n");
2990
2991         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2992         if (!NT_STATUS_IS_OK(status)) {
2993                 goto failed;
2994         }
2995
2996         r.in.domain_handle = domain_handle;
2997         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2998         r.in.rid = rid;
2999         r.out.alias_handle = &alias_handle;
3000         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3001         if (!NT_STATUS_IS_OK(status)) {
3002                 goto failed;
3003         }
3004
3005         d.in.alias_handle = &alias_handle;
3006         d.out.alias_handle = &alias_handle;
3007         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3008         if (!NT_STATUS_IS_OK(status)) {
3009                 goto failed;
3010         }
3011
3012         return true;
3013
3014 failed:
3015         printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3016         return false;
3017 }
3018
3019 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3020                                      struct policy_handle *alias_handle)
3021 {
3022         struct samr_DeleteDomAlias d;
3023         NTSTATUS status;
3024         bool ret = true;
3025         printf("Testing DeleteAlias\n");
3026
3027         d.in.alias_handle = alias_handle;
3028         d.out.alias_handle = alias_handle;
3029
3030         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3031         if (!NT_STATUS_IS_OK(status)) {
3032                 printf("DeleteAlias failed - %s\n", nt_errstr(status));
3033                 ret = false;
3034         }
3035
3036         return ret;
3037 }
3038
3039 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3040                             struct policy_handle *domain_handle, 
3041                              struct policy_handle *alias_handle, 
3042                              const struct dom_sid *domain_sid)
3043 {
3044         NTSTATUS status;
3045         struct samr_CreateDomAlias r;
3046         struct lsa_String name;
3047         uint32_t rid;
3048         bool ret = true;
3049
3050         init_lsa_String(&name, TEST_ALIASNAME);
3051         r.in.domain_handle = domain_handle;
3052         r.in.alias_name = &name;
3053         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3054         r.out.alias_handle = alias_handle;
3055         r.out.rid = &rid;
3056
3057         printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
3058
3059         status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3060
3061         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3062                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3063                         printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
3064                         return true;
3065                 } else {
3066                         printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string, 
3067                                nt_errstr(status));
3068                         return false;
3069                 }
3070         }
3071
3072         if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
3073                 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
3074                         return false;
3075                 }
3076                 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3077         }
3078
3079         if (!NT_STATUS_IS_OK(status)) {
3080                 printf("CreateAlias failed - %s\n", nt_errstr(status));
3081                 return false;
3082         }
3083
3084         if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
3085                 ret = false;
3086         }
3087
3088         return ret;
3089 }
3090
3091 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3092                                 const char *acct_name,
3093                                 struct policy_handle *domain_handle, char **password)
3094 {
3095         bool ret = true;
3096
3097         if (!*password) {
3098                 return false;
3099         }
3100
3101         if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
3102                 ret = false;
3103         }
3104
3105         if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
3106                 ret = false;
3107         }
3108
3109         if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
3110                 ret = false;
3111         }
3112
3113         /* test what happens when setting the old password again */
3114         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
3115                 ret = false;
3116         }
3117
3118         {
3119                 char simple_pass[9];
3120                 char *v = generate_random_str(mem_ctx, 1);
3121
3122                 ZERO_STRUCT(simple_pass);
3123                 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3124
3125                 /* test what happens when picking a simple password */
3126                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
3127                         ret = false;
3128                 }
3129         }
3130
3131         /* set samr_SetDomainInfo level 1 with min_length 5 */
3132         {
3133                 struct samr_QueryDomainInfo r;
3134                 union samr_DomainInfo *info = NULL;
3135                 struct samr_SetDomainInfo s;
3136                 uint16_t len_old, len;
3137                 uint32_t pwd_prop_old;
3138                 int64_t min_pwd_age_old;
3139                 NTSTATUS status;
3140
3141                 len = 5;
3142
3143                 r.in.domain_handle = domain_handle;
3144                 r.in.level = 1;
3145                 r.out.info = &info;
3146
3147                 printf("testing samr_QueryDomainInfo level 1\n");
3148                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3149                 if (!NT_STATUS_IS_OK(status)) {
3150                         return false;
3151                 }
3152
3153                 s.in.domain_handle = domain_handle;
3154                 s.in.level = 1;
3155                 s.in.info = info;
3156
3157                 /* remember the old min length, so we can reset it */
3158                 len_old = s.in.info->info1.min_password_length;
3159                 s.in.info->info1.min_password_length = len;
3160                 pwd_prop_old = s.in.info->info1.password_properties;
3161                 /* turn off password complexity checks for this test */
3162                 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
3163
3164                 min_pwd_age_old = s.in.info->info1.min_password_age;
3165                 s.in.info->info1.min_password_age = 0;
3166
3167                 printf("testing samr_SetDomainInfo level 1\n");
3168                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3169                 if (!NT_STATUS_IS_OK(status)) {
3170                         return false;
3171                 }
3172
3173                 printf("calling test_ChangePasswordUser3 with too short password\n");
3174
3175                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
3176                         ret = false;
3177                 }
3178
3179                 s.in.info->info1.min_password_length = len_old;
3180                 s.in.info->info1.password_properties = pwd_prop_old;
3181                 s.in.info->info1.min_password_age = min_pwd_age_old;
3182                 
3183                 printf("testing samr_SetDomainInfo level 1\n");
3184                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3185                 if (!NT_STATUS_IS_OK(status)) {
3186                         return false;
3187                 }
3188
3189         }
3190
3191         {
3192                 NTSTATUS status;
3193                 struct samr_OpenUser r;
3194                 struct samr_QueryUserInfo q;
3195                 union samr_UserInfo *info;
3196                 struct samr_LookupNames n;
3197                 struct policy_handle user_handle;
3198                 struct samr_Ids rids, types;
3199
3200                 n.in.domain_handle = domain_handle;
3201                 n.in.num_names = 1;
3202                 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
3203                 n.in.names[0].string = acct_name; 
3204                 n.out.rids = &rids;
3205                 n.out.types = &types;
3206
3207                 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3208                 if (!NT_STATUS_IS_OK(status)) {
3209                         printf("LookupNames failed - %s\n", nt_errstr(status));
3210                         return false;
3211                 }
3212
3213                 r.in.domain_handle = domain_handle;
3214                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3215                 r.in.rid = n.out.rids->ids[0];
3216                 r.out.user_handle = &user_handle;
3217
3218                 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3219                 if (!NT_STATUS_IS_OK(status)) {
3220                         printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
3221                         return false;
3222                 }
3223
3224                 q.in.user_handle = &user_handle;
3225                 q.in.level = 5;
3226                 q.out.info = &info;
3227
3228                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3229                 if (!NT_STATUS_IS_OK(status)) {
3230                         printf("QueryUserInfo failed - %s\n", nt_errstr(status));
3231                         return false;
3232                 }
3233
3234                 printf("calling test_ChangePasswordUser3 with too early password change\n");
3235
3236                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 
3237                                               info->info5.last_password_change, true)) {
3238                         ret = false;
3239                 }
3240         }
3241
3242         /* we change passwords twice - this has the effect of verifying
3243            they were changed correctly for the final call */
3244         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3245                 ret = false;
3246         }
3247
3248         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3249                 ret = false;
3250         }
3251
3252         return ret;
3253 }
3254
3255 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3256                             struct policy_handle *domain_handle, 
3257                             struct policy_handle *user_handle_out,
3258                             struct dom_sid *domain_sid, 
3259                             enum torture_samr_choice which_ops)
3260 {
3261
3262         TALLOC_CTX *user_ctx;
3263
3264         NTSTATUS status;
3265         struct samr_CreateUser r;
3266         struct samr_QueryUserInfo q;
3267         union samr_UserInfo *info;
3268         struct samr_DeleteUser d;
3269         uint32_t rid;
3270
3271         /* This call creates a 'normal' account - check that it really does */
3272         const uint32_t acct_flags = ACB_NORMAL;
3273         struct lsa_String name;
3274         bool ret = true;
3275
3276         struct policy_handle user_handle;
3277         user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3278         init_lsa_String(&name, TEST_ACCOUNT_NAME);
3279
3280         r.in.domain_handle = domain_handle;
3281         r.in.account_name = &name;
3282         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3283         r.out.user_handle = &user_handle;
3284         r.out.rid = &rid;
3285
3286         printf("Testing CreateUser(%s)\n", r.in.account_name->string);
3287
3288         status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3289
3290         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3291                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3292                         printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
3293                         return true;
3294                 } else {
3295                         printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string, 
3296                                nt_errstr(status));
3297                         return false;
3298                 }
3299         }
3300
3301         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3302                 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3303                         talloc_free(user_ctx);
3304                         return false;
3305                 }
3306                 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3307         }
3308         if (!NT_STATUS_IS_OK(status)) {
3309                 talloc_free(user_ctx);
3310                 printf("CreateUser failed - %s\n", nt_errstr(status));
3311                 return false;
3312         } else {
3313                 q.in.user_handle = &user_handle;
3314                 q.in.level = 16;
3315                 q.out.info = &info;
3316                 
3317                 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3318                 if (!NT_STATUS_IS_OK(status)) {
3319                         printf("QueryUserInfo level %u failed - %s\n", 
3320                                q.in.level, nt_errstr(status));
3321                         ret = false;
3322                 } else {
3323                         if ((info->info16.acct_flags & acct_flags) != acct_flags) {
3324                                 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3325                                        info->info16.acct_flags,
3326                                        acct_flags);
3327                                 ret = false;
3328                         }
3329                 }
3330                 
3331                 if (!test_user_ops(p, tctx, &user_handle, domain_handle, 
3332                                    acct_flags, name.string, which_ops)) {
3333                         ret = false;
3334                 }
3335                 
3336                 if (user_handle_out) {
3337                         *user_handle_out = user_handle;
3338                 } else {
3339                         printf("Testing DeleteUser (createuser test)\n");
3340                         
3341                         d.in.user_handle = &user_handle;
3342                         d.out.user_handle = &user_handle;
3343                         
3344                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3345                         if (!NT_STATUS_IS_OK(status)) {
3346                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
3347                                 ret = false;
3348                         }
3349                 }
3350                 
3351         }
3352
3353         talloc_free(user_ctx);
3354         
3355         return ret;
3356 }
3357
3358
3359 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
3360                              struct policy_handle *domain_handle,
3361                              struct dom_sid *domain_sid,
3362                              enum torture_samr_choice which_ops)
3363 {
3364         NTSTATUS status;
3365         struct samr_CreateUser2 r;
3366         struct samr_QueryUserInfo q;
3367         union samr_UserInfo *info;
3368         struct samr_DeleteUser d;
3369         struct policy_handle user_handle;
3370         uint32_t rid;
3371         struct lsa_String name;
3372         bool ret = true;
3373         int i;
3374
3375         struct {
3376                 uint32_t acct_flags;
3377                 const char *account_name;
3378                 NTSTATUS nt_status;
3379         } account_types[] = {
3380                 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
3381                 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3382                 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3383                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3384                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3385                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3386                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3387                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3388                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3389                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
3390                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
3391                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
3392                 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3393                 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3394                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
3395         };
3396
3397         for (i = 0; account_types[i].account_name; i++) {
3398                 TALLOC_CTX *user_ctx;
3399                 uint32_t acct_flags = account_types[i].acct_flags;
3400                 uint32_t access_granted;
3401                 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3402                 init_lsa_String(&name, account_types[i].account_name);
3403
3404                 r.in.domain_handle = domain_handle;
3405                 r.in.account_name = &name;
3406                 r.in.acct_flags = acct_flags;
3407                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3408                 r.out.user_handle = &user_handle;
3409                 r.out.access_granted = &access_granted;
3410                 r.out.rid = &rid;
3411                 
3412                 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
3413                 
3414                 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
3415                 
3416                 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3417                         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3418                                 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
3419                                 continue;
3420                         } else {
3421                                 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string, 
3422                                        nt_errstr(status));
3423                                 ret = false;
3424                                 continue;
3425                         }
3426                 }
3427
3428                 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3429                         if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3430                                 talloc_free(user_ctx);
3431                                 ret = false;
3432                                 continue;
3433                         }
3434                         status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
3435
3436                 }
3437                 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
3438                         printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n", 
3439                                nt_errstr(status), nt_errstr(account_types[i].nt_status));
3440                         ret = false;
3441                 }
3442                 
3443                 if (NT_STATUS_IS_OK(status)) {
3444                         q.in.user_handle = &user_handle;
3445                         q.in.level = 5;
3446                         q.out.info = &info;
3447                         
3448                         status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3449                         if (!NT_STATUS_IS_OK(status)) {
3450                                 printf("QueryUserInfo level %u failed - %s\n", 
3451                                        q.in.level, nt_errstr(status));
3452                                 ret = false;
3453                         } else {
3454                                 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3455                                 if (acct_flags == ACB_NORMAL) {
3456                                         expected_flags |= ACB_PW_EXPIRED;
3457                                 }
3458                                 if ((info->info5.acct_flags) != expected_flags) {
3459                                         printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3460                                                info->info5.acct_flags,
3461                                                expected_flags);
3462                                         ret = false;
3463                                 } 
3464                                 switch (acct_flags) {
3465                                 case ACB_SVRTRUST:
3466                                         if (info->info5.primary_gid != DOMAIN_RID_DCS) {
3467                                                 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n", 
3468                                                        DOMAIN_RID_DCS, info->info5.primary_gid);
3469                                                 ret = false;
3470                                         }
3471                                         break;
3472                                 case ACB_WSTRUST:
3473                                         if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
3474                                                 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n", 
3475                                                        DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
3476                                                 ret = false;
3477                                         }
3478                                         break;
3479                                 case ACB_NORMAL:
3480                                         if (info->info5.primary_gid != DOMAIN_RID_USERS) {
3481                                                 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n", 
3482                                                        DOMAIN_RID_USERS, info->info5.primary_gid);
3483                                                 ret = false;
3484                                         }
3485                                         break;
3486                                 }
3487                         }
3488                 
3489                         if (!test_user_ops(p, tctx, &user_handle, domain_handle, 
3490                                            acct_flags, name.string, which_ops)) {
3491                                 ret = false;
3492                         }
3493
3494                         printf("Testing DeleteUser (createuser2 test)\n");
3495                 
3496                         d.in.user_handle = &user_handle;
3497                         d.out.user_handle = &user_handle;
3498                         
3499                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3500                         if (!NT_STATUS_IS_OK(status)) {
3501                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
3502                                 ret = false;
3503                         }
3504                 }
3505                 talloc_free(user_ctx);
3506         }
3507
3508         return ret;
3509 }
3510
3511 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3512                                 struct policy_handle *handle)
3513 {
3514         NTSTATUS status;
3515         struct samr_QueryAliasInfo r;
3516         union samr_AliasInfo *info;
3517         uint16_t levels[] = {1, 2, 3};
3518         int i;
3519         bool ret = true;
3520
3521         for (i=0;i<ARRAY_SIZE(levels);i++) {
3522                 printf("Testing QueryAliasInfo level %u\n", levels[i]);
3523
3524                 r.in.alias_handle = handle;
3525                 r.in.level = levels[i];
3526                 r.out.info = &info;
3527
3528                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
3529                 if (!NT_STATUS_IS_OK(status)) {
3530                         printf("QueryAliasInfo level %u failed - %s\n", 
3531                                levels[i], nt_errstr(status));
3532                         ret = false;
3533                 }
3534         }
3535
3536         return ret;
3537 }
3538
3539 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3540                                 struct policy_handle *handle)
3541 {
3542         NTSTATUS status;
3543         struct samr_QueryGroupInfo r;
3544         union samr_GroupInfo *info;
3545         uint16_t levels[] = {1, 2, 3, 4, 5};
3546         int i;
3547         bool ret = true;
3548
3549         for (i=0;i<ARRAY_SIZE(levels);i++) {
3550                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3551
3552                 r.in.group_handle = handle;
3553                 r.in.level = levels[i];
3554                 r.out.info = &info;
3555
3556                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3557                 if (!NT_STATUS_IS_OK(status)) {
3558                         printf("QueryGroupInfo level %u failed - %s\n", 
3559                                levels[i], nt_errstr(status));
3560                         ret = false;
3561                 }
3562         }
3563
3564         return ret;
3565 }
3566
3567 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3568                                   struct policy_handle *handle)
3569 {
3570         NTSTATUS status;
3571         struct samr_QueryGroupMember r;
3572         struct samr_RidTypeArray *rids = NULL;
3573         bool ret = true;
3574
3575         printf("Testing QueryGroupMember\n");
3576
3577         r.in.group_handle = handle;
3578         r.out.rids = &rids;
3579
3580         status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
3581         if (!NT_STATUS_IS_OK(status)) {
3582                 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
3583                 ret = false;
3584         }
3585
3586         return ret;
3587 }
3588