2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7 Copyright (C) Guenther Deschner 2008-2010
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "torture/torture.h"
26 #include "system/time.h"
27 #include "librpc/gen_ndr/lsa.h"
28 #include "librpc/gen_ndr/ndr_netlogon.h"
29 #include "librpc/gen_ndr/ndr_netlogon_c.h"
30 #include "librpc/gen_ndr/ndr_samr_c.h"
31 #include "librpc/gen_ndr/ndr_lsa_c.h"
32 #include "../lib/crypto/crypto.h"
33 #include "libcli/auth/libcli_auth.h"
34 #include "libcli/security/security.h"
35 #include "torture/rpc/torture_rpc.h"
36 #include "param/param.h"
37 #include "auth/gensec/gensec.h"
38 #include "auth/gensec/gensec_proto.h"
39 #include "../libcli/auth/schannel.h"
43 #define TEST_ACCOUNT_NAME "samrtorturetest"
44 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
45 #define TEST_ALIASNAME "samrtorturetestalias"
46 #define TEST_GROUPNAME "samrtorturetestgroup"
47 #define TEST_MACHINENAME "samrtestmach$"
48 #define TEST_DOMAINNAME "samrtestdom$"
50 enum torture_samr_choice {
51 TORTURE_SAMR_PASSWORDS,
52 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
53 TORTURE_SAMR_PASSWORDS_BADPWDCOUNT,
54 TORTURE_SAMR_PASSWORDS_LOCKOUT,
55 TORTURE_SAMR_USER_ATTRIBUTES,
56 TORTURE_SAMR_USER_PRIVILEGES,
58 TORTURE_SAMR_MANY_ACCOUNTS,
59 TORTURE_SAMR_MANY_GROUPS,
60 TORTURE_SAMR_MANY_ALIASES
63 struct torture_samr_context {
64 struct policy_handle handle;
65 struct cli_credentials *machine_credentials;
66 enum torture_samr_choice choice;
67 uint32_t num_objects_large_dc;
70 static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
71 struct torture_context *tctx,
72 struct policy_handle *handle);
74 static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
75 struct torture_context *tctx,
76 struct policy_handle *handle);
78 static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
79 struct torture_context *tctx,
80 struct policy_handle *handle);
82 static bool test_ChangePassword(struct dcerpc_pipe *p,
83 struct torture_context *tctx,
84 const char *acct_name,
85 struct policy_handle *domain_handle, char **password);
87 static void init_lsa_String(struct lsa_String *string, const char *s)
92 static void init_lsa_StringLarge(struct lsa_StringLarge *string, const char *s)
97 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
99 string->length = length;
100 string->size = length;
101 string->array = (uint16_t *)discard_const(s);
104 bool test_samr_handle_Close(struct dcerpc_binding_handle *b,
105 struct torture_context *tctx,
106 struct policy_handle *handle)
110 r.in.handle = handle;
111 r.out.handle = handle;
113 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Close_r(b, tctx, &r),
115 torture_assert_ntstatus_ok(tctx, r.out.result, "Close failed");
120 static bool test_Shutdown(struct dcerpc_binding_handle *b,
121 struct torture_context *tctx,
122 struct policy_handle *handle)
124 struct samr_Shutdown r;
126 if (!torture_setting_bool(tctx, "dangerous", false)) {
127 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
131 r.in.connect_handle = handle;
133 torture_comment(tctx, "Testing samr_Shutdown\n");
135 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Shutdown_r(b, tctx, &r),
137 torture_assert_ntstatus_ok(tctx, r.out.result, "Shutdown failed");
142 static bool test_SetDsrmPassword(struct dcerpc_binding_handle *b,
143 struct torture_context *tctx,
144 struct policy_handle *handle)
146 struct samr_SetDsrmPassword r;
147 struct lsa_String string;
148 struct samr_Password hash;
150 if (!torture_setting_bool(tctx, "dangerous", false)) {
151 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
154 E_md4hash("TeSTDSRM123", hash.hash);
156 init_lsa_String(&string, "Administrator");
162 torture_comment(tctx, "Testing samr_SetDsrmPassword\n");
164 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDsrmPassword_r(b, tctx, &r),
165 "SetDsrmPassword failed");
166 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_SUPPORTED, "SetDsrmPassword failed");
172 static bool test_QuerySecurity(struct dcerpc_binding_handle *b,
173 struct torture_context *tctx,
174 struct policy_handle *handle)
176 struct samr_QuerySecurity r;
177 struct samr_SetSecurity s;
178 struct sec_desc_buf *sdbuf = NULL;
180 r.in.handle = handle;
182 r.out.sdbuf = &sdbuf;
184 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QuerySecurity_r(b, tctx, &r),
185 "QuerySecurity failed");
186 torture_assert_ntstatus_ok(tctx, r.out.result, "QuerySecurity failed");
188 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
190 s.in.handle = handle;
194 if (torture_setting_bool(tctx, "samba4", false)) {
195 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
198 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetSecurity_r(b, tctx, &s),
199 "SetSecurity failed");
200 torture_assert_ntstatus_ok(tctx, r.out.result, "SetSecurity failed");
202 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QuerySecurity_r(b, tctx, &r),
203 "QuerySecurity failed");
204 torture_assert_ntstatus_ok(tctx, r.out.result, "QuerySecurity failed");
210 static bool test_SetUserInfo(struct dcerpc_binding_handle *b, struct torture_context *tctx,
211 struct policy_handle *handle, uint32_t base_acct_flags,
212 const char *base_account_name)
214 struct samr_SetUserInfo s;
215 struct samr_SetUserInfo2 s2;
216 struct samr_QueryUserInfo q;
217 struct samr_QueryUserInfo q0;
218 union samr_UserInfo u;
219 union samr_UserInfo *info;
221 const char *test_account_name;
223 uint32_t user_extra_flags = 0;
225 if (!torture_setting_bool(tctx, "samba3", false)) {
226 if (base_acct_flags == ACB_NORMAL) {
227 /* When created, accounts are expired by default */
228 user_extra_flags = ACB_PW_EXPIRED;
232 s.in.user_handle = handle;
235 s2.in.user_handle = handle;
238 q.in.user_handle = handle;
242 #define TESTCALL(call, r) \
243 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ ##call## _r(b, tctx, &r),\
245 if (!NT_STATUS_IS_OK(r.out.result)) { \
246 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
247 r.in.level, nt_errstr(r.out.result), __location__); \
252 #define STRING_EQUAL(s1, s2, field) \
253 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
254 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
255 #field, s2, __location__); \
260 #define MEM_EQUAL(s1, s2, length, field) \
261 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
262 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
263 #field, (const char *)s2, __location__); \
268 #define INT_EQUAL(i1, i2, field) \
270 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
271 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
276 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
277 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
279 TESTCALL(QueryUserInfo, q) \
281 s2.in.level = lvl1; \
284 ZERO_STRUCT(u.info21); \
285 u.info21.fields_present = fpval; \
287 init_lsa_String(&u.info ## lvl1.field1, value); \
288 TESTCALL(SetUserInfo, s) \
289 TESTCALL(SetUserInfo2, s2) \
290 init_lsa_String(&u.info ## lvl1.field1, ""); \
291 TESTCALL(QueryUserInfo, q); \
293 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
295 TESTCALL(QueryUserInfo, q) \
297 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
300 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
301 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
303 TESTCALL(QueryUserInfo, q) \
305 s2.in.level = lvl1; \
308 ZERO_STRUCT(u.info21); \
309 u.info21.fields_present = fpval; \
311 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
312 TESTCALL(SetUserInfo, s) \
313 TESTCALL(SetUserInfo2, s2) \
314 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
315 TESTCALL(QueryUserInfo, q); \
317 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
319 TESTCALL(QueryUserInfo, q) \
321 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
324 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
325 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
327 TESTCALL(QueryUserInfo, q) \
329 s2.in.level = lvl1; \
332 uint8_t *bits = u.info21.logon_hours.bits; \
333 ZERO_STRUCT(u.info21); \
334 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
335 u.info21.logon_hours.units_per_week = 168; \
336 u.info21.logon_hours.bits = bits; \
338 u.info21.fields_present = fpval; \
340 u.info ## lvl1.field1 = value; \
341 TESTCALL(SetUserInfo, s) \
342 TESTCALL(SetUserInfo2, s2) \
343 u.info ## lvl1.field1 = 0; \
344 TESTCALL(QueryUserInfo, q); \
346 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
348 TESTCALL(QueryUserInfo, q) \
350 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
353 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
354 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
358 do { TESTCALL(QueryUserInfo, q0) } while (0);
360 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
361 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
362 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
365 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
366 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
367 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
368 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
369 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
370 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
371 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
372 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
373 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
374 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
375 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
376 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
377 test_account_name = base_account_name;
378 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
379 SAMR_FIELD_ACCOUNT_NAME);
381 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
382 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
383 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
384 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
385 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
386 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
387 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
388 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
389 SAMR_FIELD_FULL_NAME);
391 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
392 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
393 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
394 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
395 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
396 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
397 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
398 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
399 SAMR_FIELD_FULL_NAME);
401 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
402 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
403 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
404 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
405 SAMR_FIELD_LOGON_SCRIPT);
407 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
408 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
409 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
410 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
411 SAMR_FIELD_PROFILE_PATH);
413 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
414 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
415 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
416 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
417 SAMR_FIELD_HOME_DIRECTORY);
418 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
419 SAMR_FIELD_HOME_DIRECTORY);
421 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
422 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
423 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
424 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
425 SAMR_FIELD_HOME_DRIVE);
426 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
427 SAMR_FIELD_HOME_DRIVE);
429 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
430 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
431 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
432 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
433 SAMR_FIELD_DESCRIPTION);
435 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
436 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
437 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
438 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
439 SAMR_FIELD_WORKSTATIONS);
440 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
441 SAMR_FIELD_WORKSTATIONS);
442 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
443 SAMR_FIELD_WORKSTATIONS);
444 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
445 SAMR_FIELD_WORKSTATIONS);
447 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
448 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
449 SAMR_FIELD_PARAMETERS);
450 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
451 SAMR_FIELD_PARAMETERS);
452 /* also empty user parameters are allowed */
453 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
454 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
455 SAMR_FIELD_PARAMETERS);
456 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
457 SAMR_FIELD_PARAMETERS);
459 /* Samba 3 cannot store country_code and copy_page atm. - gd */
460 if (!torture_setting_bool(tctx, "samba3", false)) {
461 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
462 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
463 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
464 SAMR_FIELD_COUNTRY_CODE);
465 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
466 SAMR_FIELD_COUNTRY_CODE);
468 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
469 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
470 SAMR_FIELD_CODE_PAGE);
471 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
472 SAMR_FIELD_CODE_PAGE);
475 if (!torture_setting_bool(tctx, "samba3", false)) {
476 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
477 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
478 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
479 SAMR_FIELD_ACCT_EXPIRY);
480 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
481 SAMR_FIELD_ACCT_EXPIRY);
482 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
483 SAMR_FIELD_ACCT_EXPIRY);
485 /* Samba 3 can only store seconds / time_t in passdb - gd */
487 unix_to_nt_time(&nt, time(NULL) + __LINE__);
488 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
489 unix_to_nt_time(&nt, time(NULL) + __LINE__);
490 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
491 unix_to_nt_time(&nt, time(NULL) + __LINE__);
492 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
493 unix_to_nt_time(&nt, time(NULL) + __LINE__);
494 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
495 unix_to_nt_time(&nt, time(NULL) + __LINE__);
496 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
499 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
500 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
501 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
502 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
503 SAMR_FIELD_LOGON_HOURS);
505 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
506 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
507 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
509 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
510 (base_acct_flags | ACB_DISABLED),
511 (base_acct_flags | ACB_DISABLED | user_extra_flags),
514 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
515 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
516 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
517 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
519 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
520 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
521 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
525 /* The 'autolock' flag doesn't stick - check this */
526 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
527 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
528 (base_acct_flags | ACB_DISABLED | user_extra_flags),
531 /* Removing the 'disabled' flag doesn't stick - check this */
532 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
534 (base_acct_flags | ACB_DISABLED | user_extra_flags),
538 /* Samba3 cannot store these atm */
539 if (!torture_setting_bool(tctx, "samba3", false)) {
540 /* The 'store plaintext' flag does stick */
541 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
542 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
543 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
545 /* The 'use DES' flag does stick */
546 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
547 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
548 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
550 /* The 'don't require kerberos pre-authentication flag does stick */
551 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
552 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
553 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
555 /* The 'no kerberos PAC required' flag sticks */
556 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
557 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
558 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
561 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
562 (base_acct_flags | ACB_DISABLED),
563 (base_acct_flags | ACB_DISABLED | user_extra_flags),
564 SAMR_FIELD_ACCT_FLAGS);
567 /* these fail with win2003 - it appears you can't set the primary gid?
568 the set succeeds, but the gid isn't changed. Very weird! */
569 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
570 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
571 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
572 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
579 generate a random password for password change tests
581 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
583 size_t len = MAX(8, min_len);
584 char *s = generate_random_password(mem_ctx, len, len+6);
588 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
590 char *s = samr_rand_pass_silent(mem_ctx, min_len);
591 printf("Generated password '%s'\n", s);
597 generate a random password for password change tests
599 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
602 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
603 generate_random_buffer(password.data, password.length);
605 for (i=0; i < len; i++) {
606 if (((uint16_t *)password.data)[i] == 0) {
607 ((uint16_t *)password.data)[i] = 1;
615 generate a random password for password change tests (fixed length)
617 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
619 char *s = generate_random_password(mem_ctx, len, len);
620 printf("Generated password '%s'\n", s);
624 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
625 struct policy_handle *handle, char **password)
628 struct samr_SetUserInfo s;
629 union samr_UserInfo u;
631 DATA_BLOB session_key;
633 struct dcerpc_binding_handle *b = p->binding_handle;
634 struct samr_GetUserPwInfo pwp;
635 struct samr_PwInfo info;
636 int policy_min_pw_len = 0;
637 pwp.in.user_handle = handle;
638 pwp.out.info = &info;
640 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
641 "GetUserPwInfo failed");
642 if (NT_STATUS_IS_OK(pwp.out.result)) {
643 policy_min_pw_len = pwp.out.info->min_password_length;
645 newpass = samr_rand_pass(tctx, policy_min_pw_len);
647 s.in.user_handle = handle;
651 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
652 u.info24.password_expired = 0;
654 status = dcerpc_fetch_session_key(p, &session_key);
655 if (!NT_STATUS_IS_OK(status)) {
656 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
657 s.in.level, nt_errstr(status));
661 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
663 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
665 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
666 "SetUserInfo failed");
667 if (!NT_STATUS_IS_OK(s.out.result)) {
668 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
669 s.in.level, nt_errstr(s.out.result));
679 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
680 struct policy_handle *handle, uint32_t fields_present,
684 struct samr_SetUserInfo s;
685 union samr_UserInfo u;
687 DATA_BLOB session_key;
688 struct dcerpc_binding_handle *b = p->binding_handle;
690 struct samr_GetUserPwInfo pwp;
691 struct samr_PwInfo info;
692 int policy_min_pw_len = 0;
693 pwp.in.user_handle = handle;
694 pwp.out.info = &info;
696 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
697 "GetUserPwInfo failed");
698 if (NT_STATUS_IS_OK(pwp.out.result)) {
699 policy_min_pw_len = pwp.out.info->min_password_length;
701 newpass = samr_rand_pass(tctx, policy_min_pw_len);
703 s.in.user_handle = handle;
709 u.info23.info.fields_present = fields_present;
711 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
713 status = dcerpc_fetch_session_key(p, &session_key);
714 if (!NT_STATUS_IS_OK(status)) {
715 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
716 s.in.level, nt_errstr(status));
720 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
722 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
724 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
725 "SetUserInfo failed");
726 if (!NT_STATUS_IS_OK(s.out.result)) {
727 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
728 s.in.level, nt_errstr(s.out.result));
734 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
736 status = dcerpc_fetch_session_key(p, &session_key);
737 if (!NT_STATUS_IS_OK(status)) {
738 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
739 s.in.level, nt_errstr(status));
743 /* This should break the key nicely */
744 session_key.length--;
745 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
747 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
749 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
750 "SetUserInfo failed");
751 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
752 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
753 s.in.level, nt_errstr(s.out.result));
761 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
762 struct policy_handle *handle, bool makeshort,
766 struct samr_SetUserInfo s;
767 union samr_UserInfo u;
769 DATA_BLOB session_key;
770 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
771 uint8_t confounder[16];
773 struct dcerpc_binding_handle *b = p->binding_handle;
774 struct MD5Context ctx;
775 struct samr_GetUserPwInfo pwp;
776 struct samr_PwInfo info;
777 int policy_min_pw_len = 0;
778 pwp.in.user_handle = handle;
779 pwp.out.info = &info;
781 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
782 "GetUserPwInfo failed");
783 if (NT_STATUS_IS_OK(pwp.out.result)) {
784 policy_min_pw_len = pwp.out.info->min_password_length;
786 if (makeshort && policy_min_pw_len) {
787 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
789 newpass = samr_rand_pass(tctx, policy_min_pw_len);
792 s.in.user_handle = handle;
796 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
797 u.info26.password_expired = 0;
799 status = dcerpc_fetch_session_key(p, &session_key);
800 if (!NT_STATUS_IS_OK(status)) {
801 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
802 s.in.level, nt_errstr(status));
806 generate_random_buffer((uint8_t *)confounder, 16);
809 MD5Update(&ctx, confounder, 16);
810 MD5Update(&ctx, session_key.data, session_key.length);
811 MD5Final(confounded_session_key.data, &ctx);
813 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
814 memcpy(&u.info26.password.data[516], confounder, 16);
816 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
818 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
819 "SetUserInfo failed");
820 if (!NT_STATUS_IS_OK(s.out.result)) {
821 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
822 s.in.level, nt_errstr(s.out.result));
828 /* This should break the key nicely */
829 confounded_session_key.data[0]++;
831 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
832 memcpy(&u.info26.password.data[516], confounder, 16);
834 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
836 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
837 "SetUserInfo failed");
838 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
839 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
840 s.in.level, nt_errstr(s.out.result));
849 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
850 struct policy_handle *handle, uint32_t fields_present,
854 struct samr_SetUserInfo s;
855 union samr_UserInfo u;
857 DATA_BLOB session_key;
858 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
859 struct MD5Context ctx;
860 uint8_t confounder[16];
862 struct dcerpc_binding_handle *b = p->binding_handle;
863 struct samr_GetUserPwInfo pwp;
864 struct samr_PwInfo info;
865 int policy_min_pw_len = 0;
866 pwp.in.user_handle = handle;
867 pwp.out.info = &info;
869 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
870 "GetUserPwInfo failed");
871 if (NT_STATUS_IS_OK(pwp.out.result)) {
872 policy_min_pw_len = pwp.out.info->min_password_length;
874 newpass = samr_rand_pass(tctx, policy_min_pw_len);
876 s.in.user_handle = handle;
882 u.info25.info.fields_present = fields_present;
884 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
886 status = dcerpc_fetch_session_key(p, &session_key);
887 if (!NT_STATUS_IS_OK(status)) {
888 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
889 s.in.level, nt_errstr(status));
893 generate_random_buffer((uint8_t *)confounder, 16);
896 MD5Update(&ctx, confounder, 16);
897 MD5Update(&ctx, session_key.data, session_key.length);
898 MD5Final(confounded_session_key.data, &ctx);
900 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
901 memcpy(&u.info25.password.data[516], confounder, 16);
903 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
905 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
906 "SetUserInfo failed");
907 if (!NT_STATUS_IS_OK(s.out.result)) {
908 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
909 s.in.level, nt_errstr(s.out.result));
915 /* This should break the key nicely */
916 confounded_session_key.data[0]++;
918 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
919 memcpy(&u.info25.password.data[516], confounder, 16);
921 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
923 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
924 "SetUserInfo failed");
925 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
926 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
927 s.in.level, nt_errstr(s.out.result));
934 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
935 struct policy_handle *handle, char **password)
938 struct samr_SetUserInfo s;
939 union samr_UserInfo u;
941 DATA_BLOB session_key;
943 struct dcerpc_binding_handle *b = p->binding_handle;
944 struct samr_GetUserPwInfo pwp;
945 struct samr_PwInfo info;
946 int policy_min_pw_len = 0;
947 uint8_t lm_hash[16], nt_hash[16];
949 pwp.in.user_handle = handle;
950 pwp.out.info = &info;
952 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
953 "GetUserPwInfo failed");
954 if (NT_STATUS_IS_OK(pwp.out.result)) {
955 policy_min_pw_len = pwp.out.info->min_password_length;
957 newpass = samr_rand_pass(tctx, policy_min_pw_len);
959 s.in.user_handle = handle;
965 u.info18.nt_pwd_active = true;
966 u.info18.lm_pwd_active = true;
968 E_md4hash(newpass, nt_hash);
969 E_deshash(newpass, lm_hash);
971 status = dcerpc_fetch_session_key(p, &session_key);
972 if (!NT_STATUS_IS_OK(status)) {
973 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
974 s.in.level, nt_errstr(status));
980 in = data_blob_const(nt_hash, 16);
981 out = data_blob_talloc_zero(tctx, 16);
982 sess_crypt_blob(&out, &in, &session_key, true);
983 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
987 in = data_blob_const(lm_hash, 16);
988 out = data_blob_talloc_zero(tctx, 16);
989 sess_crypt_blob(&out, &in, &session_key, true);
990 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
993 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
995 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
996 "SetUserInfo failed");
997 if (!NT_STATUS_IS_OK(s.out.result)) {
998 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
999 s.in.level, nt_errstr(s.out.result));
1002 *password = newpass;
1008 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
1009 struct policy_handle *handle, uint32_t fields_present,
1013 struct samr_SetUserInfo s;
1014 union samr_UserInfo u;
1016 DATA_BLOB session_key;
1018 struct dcerpc_binding_handle *b = p->binding_handle;
1019 struct samr_GetUserPwInfo pwp;
1020 struct samr_PwInfo info;
1021 int policy_min_pw_len = 0;
1022 uint8_t lm_hash[16], nt_hash[16];
1024 pwp.in.user_handle = handle;
1025 pwp.out.info = &info;
1027 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1028 "GetUserPwInfo failed");
1029 if (NT_STATUS_IS_OK(pwp.out.result)) {
1030 policy_min_pw_len = pwp.out.info->min_password_length;
1032 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1034 s.in.user_handle = handle;
1038 E_md4hash(newpass, nt_hash);
1039 E_deshash(newpass, lm_hash);
1043 u.info21.fields_present = fields_present;
1045 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1046 u.info21.lm_owf_password.length = 16;
1047 u.info21.lm_owf_password.size = 16;
1048 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1049 u.info21.lm_password_set = true;
1052 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1053 u.info21.nt_owf_password.length = 16;
1054 u.info21.nt_owf_password.size = 16;
1055 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1056 u.info21.nt_password_set = true;
1059 status = dcerpc_fetch_session_key(p, &session_key);
1060 if (!NT_STATUS_IS_OK(status)) {
1061 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1062 s.in.level, nt_errstr(status));
1066 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1068 in = data_blob_const(u.info21.lm_owf_password.array,
1069 u.info21.lm_owf_password.length);
1070 out = data_blob_talloc_zero(tctx, 16);
1071 sess_crypt_blob(&out, &in, &session_key, true);
1072 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1075 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1077 in = data_blob_const(u.info21.nt_owf_password.array,
1078 u.info21.nt_owf_password.length);
1079 out = data_blob_talloc_zero(tctx, 16);
1080 sess_crypt_blob(&out, &in, &session_key, true);
1081 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1084 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1086 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1087 "SetUserInfo failed");
1088 if (!NT_STATUS_IS_OK(s.out.result)) {
1089 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
1090 s.in.level, nt_errstr(s.out.result));
1093 *password = newpass;
1096 /* try invalid length */
1097 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1099 u.info21.nt_owf_password.length++;
1101 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1102 "SetUserInfo failed");
1103 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_INVALID_PARAMETER)) {
1104 torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1105 s.in.level, nt_errstr(s.out.result));
1110 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1112 u.info21.lm_owf_password.length++;
1114 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1115 "SetUserInfo failed");
1116 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_INVALID_PARAMETER)) {
1117 torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1118 s.in.level, nt_errstr(s.out.result));
1126 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1127 struct torture_context *tctx,
1128 struct policy_handle *handle,
1130 uint32_t fields_present,
1131 char **password, uint8_t password_expired,
1133 bool *matched_expected_error)
1136 NTSTATUS expected_error = NT_STATUS_OK;
1137 struct samr_SetUserInfo s;
1138 struct samr_SetUserInfo2 s2;
1139 union samr_UserInfo u;
1141 DATA_BLOB session_key;
1142 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1143 struct MD5Context ctx;
1144 uint8_t confounder[16];
1146 struct dcerpc_binding_handle *b = p->binding_handle;
1147 struct samr_GetUserPwInfo pwp;
1148 struct samr_PwInfo info;
1149 int policy_min_pw_len = 0;
1150 const char *comment = NULL;
1151 uint8_t lm_hash[16], nt_hash[16];
1153 pwp.in.user_handle = handle;
1154 pwp.out.info = &info;
1156 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1157 "GetUserPwInfo failed");
1158 if (NT_STATUS_IS_OK(pwp.out.result)) {
1159 policy_min_pw_len = pwp.out.info->min_password_length;
1161 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1164 s2.in.user_handle = handle;
1166 s2.in.level = level;
1168 s.in.user_handle = handle;
1173 if (fields_present & SAMR_FIELD_COMMENT) {
1174 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1181 E_md4hash(newpass, nt_hash);
1182 E_deshash(newpass, lm_hash);
1184 u.info18.nt_pwd_active = true;
1185 u.info18.lm_pwd_active = true;
1186 u.info18.password_expired = password_expired;
1188 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1189 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1193 E_md4hash(newpass, nt_hash);
1194 E_deshash(newpass, lm_hash);
1196 u.info21.fields_present = fields_present;
1197 u.info21.password_expired = password_expired;
1198 u.info21.comment.string = comment;
1200 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1201 u.info21.lm_owf_password.length = 16;
1202 u.info21.lm_owf_password.size = 16;
1203 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1204 u.info21.lm_password_set = true;
1207 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1208 u.info21.nt_owf_password.length = 16;
1209 u.info21.nt_owf_password.size = 16;
1210 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1211 u.info21.nt_password_set = true;
1216 u.info23.info.fields_present = fields_present;
1217 u.info23.info.password_expired = password_expired;
1218 u.info23.info.comment.string = comment;
1220 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1224 u.info24.password_expired = password_expired;
1226 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1230 u.info25.info.fields_present = fields_present;
1231 u.info25.info.password_expired = password_expired;
1232 u.info25.info.comment.string = comment;
1234 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1238 u.info26.password_expired = password_expired;
1240 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1245 status = dcerpc_fetch_session_key(p, &session_key);
1246 if (!NT_STATUS_IS_OK(status)) {
1247 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1248 s.in.level, nt_errstr(status));
1252 generate_random_buffer((uint8_t *)confounder, 16);
1255 MD5Update(&ctx, confounder, 16);
1256 MD5Update(&ctx, session_key.data, session_key.length);
1257 MD5Final(confounded_session_key.data, &ctx);
1263 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1264 out = data_blob_talloc_zero(tctx, 16);
1265 sess_crypt_blob(&out, &in, &session_key, true);
1266 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1270 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1271 out = data_blob_talloc_zero(tctx, 16);
1272 sess_crypt_blob(&out, &in, &session_key, true);
1273 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1278 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1280 in = data_blob_const(u.info21.lm_owf_password.array,
1281 u.info21.lm_owf_password.length);
1282 out = data_blob_talloc_zero(tctx, 16);
1283 sess_crypt_blob(&out, &in, &session_key, true);
1284 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1286 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1288 in = data_blob_const(u.info21.nt_owf_password.array,
1289 u.info21.nt_owf_password.length);
1290 out = data_blob_talloc_zero(tctx, 16);
1291 sess_crypt_blob(&out, &in, &session_key, true);
1292 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1296 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1299 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1302 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1303 memcpy(&u.info25.password.data[516], confounder, 16);
1306 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1307 memcpy(&u.info26.password.data[516], confounder, 16);
1312 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo2_r(b, tctx, &s2),
1313 "SetUserInfo2 failed");
1314 status = s2.out.result;
1316 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1317 "SetUserInfo failed");
1318 status = s.out.result;
1321 if (!NT_STATUS_IS_OK(status)) {
1322 if (fields_present == 0) {
1323 expected_error = NT_STATUS_INVALID_PARAMETER;
1325 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1326 expected_error = NT_STATUS_ACCESS_DENIED;
1330 if (!NT_STATUS_IS_OK(expected_error)) {
1332 torture_assert_ntstatus_equal(tctx,
1334 expected_error, "SetUserInfo2 failed");
1336 torture_assert_ntstatus_equal(tctx,
1338 expected_error, "SetUserInfo failed");
1340 *matched_expected_error = true;
1344 if (!NT_STATUS_IS_OK(status)) {
1345 torture_warning(tctx, "SetUserInfo%s level %u failed - %s\n",
1346 use_setinfo2 ? "2":"", level, nt_errstr(status));
1349 *password = newpass;
1355 static bool test_SetAliasInfo(struct dcerpc_binding_handle *b,
1356 struct torture_context *tctx,
1357 struct policy_handle *handle)
1359 struct samr_SetAliasInfo r;
1360 struct samr_QueryAliasInfo q;
1361 union samr_AliasInfo *info;
1362 uint16_t levels[] = {2, 3};
1366 /* Ignoring switch level 1, as that includes the number of members for the alias
1367 * and setting this to a wrong value might have negative consequences
1370 for (i=0;i<ARRAY_SIZE(levels);i++) {
1371 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1373 r.in.alias_handle = handle;
1374 r.in.level = levels[i];
1375 r.in.info = talloc(tctx, union samr_AliasInfo);
1376 switch (r.in.level) {
1377 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1378 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1379 "Test Description, should test I18N as well"); break;
1380 case ALIASINFOALL: torture_comment(tctx, "ALIASINFOALL ignored\n"); break;
1383 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetAliasInfo_r(b, tctx, &r),
1384 "SetAliasInfo failed");
1385 if (!NT_STATUS_IS_OK(r.out.result)) {
1386 torture_warning(tctx, "SetAliasInfo level %u failed - %s\n",
1387 levels[i], nt_errstr(r.out.result));
1391 q.in.alias_handle = handle;
1392 q.in.level = levels[i];
1395 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &q),
1396 "QueryAliasInfo failed");
1397 if (!NT_STATUS_IS_OK(q.out.result)) {
1398 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
1399 levels[i], nt_errstr(q.out.result));
1407 static bool test_GetGroupsForUser(struct dcerpc_binding_handle *b,
1408 struct torture_context *tctx,
1409 struct policy_handle *user_handle)
1411 struct samr_GetGroupsForUser r;
1412 struct samr_RidWithAttributeArray *rids = NULL;
1414 torture_comment(tctx, "Testing GetGroupsForUser\n");
1416 r.in.user_handle = user_handle;
1419 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetGroupsForUser_r(b, tctx, &r),
1420 "GetGroupsForUser failed");
1421 torture_assert_ntstatus_ok(tctx, r.out.result, "GetGroupsForUser failed");
1427 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1428 struct lsa_String *domain_name)
1430 struct samr_GetDomPwInfo r;
1431 struct samr_PwInfo info;
1432 struct dcerpc_binding_handle *b = p->binding_handle;
1434 r.in.domain_name = domain_name;
1437 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1439 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1440 "GetDomPwInfo failed");
1441 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1443 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1444 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1446 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1447 "GetDomPwInfo failed");
1448 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1450 r.in.domain_name->string = "\\\\__NONAME__";
1451 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1453 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1454 "GetDomPwInfo failed");
1455 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1457 r.in.domain_name->string = "\\\\Builtin";
1458 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1460 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1461 "GetDomPwInfo failed");
1462 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1467 static bool test_GetUserPwInfo(struct dcerpc_binding_handle *b,
1468 struct torture_context *tctx,
1469 struct policy_handle *handle)
1471 struct samr_GetUserPwInfo r;
1472 struct samr_PwInfo info;
1474 torture_comment(tctx, "Testing GetUserPwInfo\n");
1476 r.in.user_handle = handle;
1479 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &r),
1480 "GetUserPwInfo failed");
1481 torture_assert_ntstatus_ok(tctx, r.out.result, "GetUserPwInfo");
1486 static NTSTATUS test_LookupName(struct dcerpc_binding_handle *b,
1487 struct torture_context *tctx,
1488 struct policy_handle *domain_handle, const char *name,
1492 struct samr_LookupNames n;
1493 struct lsa_String sname[2];
1494 struct samr_Ids rids, types;
1496 init_lsa_String(&sname[0], name);
1498 n.in.domain_handle = domain_handle;
1502 n.out.types = &types;
1503 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1504 if (!NT_STATUS_IS_OK(status)) {
1507 if (NT_STATUS_IS_OK(n.out.result)) {
1508 *rid = n.out.rids->ids[0];
1510 return n.out.result;
1513 init_lsa_String(&sname[1], "xxNONAMExx");
1515 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1516 if (!NT_STATUS_IS_OK(status)) {
1519 if (!NT_STATUS_EQUAL(n.out.result, STATUS_SOME_UNMAPPED)) {
1520 torture_warning(tctx, "LookupNames[2] failed - %s\n", nt_errstr(n.out.result));
1521 if (NT_STATUS_IS_OK(n.out.result)) {
1522 return NT_STATUS_UNSUCCESSFUL;
1524 return n.out.result;
1528 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1529 if (!NT_STATUS_IS_OK(status)) {
1532 if (!NT_STATUS_IS_OK(n.out.result)) {
1533 torture_warning(tctx, "LookupNames[0] failed - %s\n", nt_errstr(status));
1534 return n.out.result;
1537 init_lsa_String(&sname[0], "xxNONAMExx");
1539 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1540 if (!NT_STATUS_IS_OK(status)) {
1543 if (!NT_STATUS_EQUAL(n.out.result, NT_STATUS_NONE_MAPPED)) {
1544 torture_warning(tctx, "LookupNames[1 bad name] failed - %s\n", nt_errstr(n.out.result));
1545 if (NT_STATUS_IS_OK(n.out.result)) {
1546 return NT_STATUS_UNSUCCESSFUL;
1548 return n.out.result;
1551 init_lsa_String(&sname[0], "xxNONAMExx");
1552 init_lsa_String(&sname[1], "xxNONAME2xx");
1554 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1555 if (!NT_STATUS_IS_OK(status)) {
1558 if (!NT_STATUS_EQUAL(n.out.result, NT_STATUS_NONE_MAPPED)) {
1559 torture_warning(tctx, "LookupNames[2 bad names] failed - %s\n", nt_errstr(n.out.result));
1560 if (NT_STATUS_IS_OK(n.out.result)) {
1561 return NT_STATUS_UNSUCCESSFUL;
1563 return n.out.result;
1566 return NT_STATUS_OK;
1569 static NTSTATUS test_OpenUser_byname(struct dcerpc_binding_handle *b,
1570 struct torture_context *tctx,
1571 struct policy_handle *domain_handle,
1572 const char *name, struct policy_handle *user_handle)
1575 struct samr_OpenUser r;
1578 status = test_LookupName(b, tctx, domain_handle, name, &rid);
1579 if (!NT_STATUS_IS_OK(status)) {
1583 r.in.domain_handle = domain_handle;
1584 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1586 r.out.user_handle = user_handle;
1587 status = dcerpc_samr_OpenUser_r(b, tctx, &r);
1588 if (!NT_STATUS_IS_OK(status)) {
1591 if (!NT_STATUS_IS_OK(r.out.result)) {
1592 torture_warning(tctx, "OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(r.out.result));
1595 return r.out.result;
1599 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
1600 struct torture_context *tctx,
1601 struct policy_handle *handle)
1604 struct samr_ChangePasswordUser r;
1606 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1607 struct policy_handle user_handle;
1608 char *oldpass = "test";
1609 char *newpass = "test2";
1610 uint8_t old_nt_hash[16], new_nt_hash[16];
1611 uint8_t old_lm_hash[16], new_lm_hash[16];
1613 status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
1614 if (!NT_STATUS_IS_OK(status)) {
1618 torture_comment(tctx, "Testing ChangePasswordUser for user 'testuser'\n");
1620 torture_comment(tctx, "old password: %s\n", oldpass);
1621 torture_comment(tctx, "new password: %s\n", newpass);
1623 E_md4hash(oldpass, old_nt_hash);
1624 E_md4hash(newpass, new_nt_hash);
1625 E_deshash(oldpass, old_lm_hash);
1626 E_deshash(newpass, new_lm_hash);
1628 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1629 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1630 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1631 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1632 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1633 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1635 r.in.handle = &user_handle;
1636 r.in.lm_present = 1;
1637 r.in.old_lm_crypted = &hash1;
1638 r.in.new_lm_crypted = &hash2;
1639 r.in.nt_present = 1;
1640 r.in.old_nt_crypted = &hash3;
1641 r.in.new_nt_crypted = &hash4;
1642 r.in.cross1_present = 1;
1643 r.in.nt_cross = &hash5;
1644 r.in.cross2_present = 1;
1645 r.in.lm_cross = &hash6;
1647 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1648 "ChangePasswordUser failed");
1649 if (!NT_STATUS_IS_OK(r.out.result)) {
1650 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(r.out.result));
1654 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1662 static bool test_ChangePasswordUser(struct dcerpc_binding_handle *b,
1663 struct torture_context *tctx,
1664 const char *acct_name,
1665 struct policy_handle *handle, char **password)
1668 struct samr_ChangePasswordUser r;
1670 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1671 struct policy_handle user_handle;
1673 uint8_t old_nt_hash[16], new_nt_hash[16];
1674 uint8_t old_lm_hash[16], new_lm_hash[16];
1675 bool changed = true;
1678 struct samr_GetUserPwInfo pwp;
1679 struct samr_PwInfo info;
1680 int policy_min_pw_len = 0;
1682 status = test_OpenUser_byname(b, tctx, handle, acct_name, &user_handle);
1683 if (!NT_STATUS_IS_OK(status)) {
1686 pwp.in.user_handle = &user_handle;
1687 pwp.out.info = &info;
1689 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1690 "GetUserPwInfo failed");
1691 if (NT_STATUS_IS_OK(pwp.out.result)) {
1692 policy_min_pw_len = pwp.out.info->min_password_length;
1694 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1696 torture_comment(tctx, "Testing ChangePasswordUser\n");
1698 torture_assert(tctx, *password != NULL,
1699 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1701 oldpass = *password;
1703 E_md4hash(oldpass, old_nt_hash);
1704 E_md4hash(newpass, new_nt_hash);
1705 E_deshash(oldpass, old_lm_hash);
1706 E_deshash(newpass, new_lm_hash);
1708 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1709 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1710 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1711 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1712 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1713 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1715 r.in.user_handle = &user_handle;
1716 r.in.lm_present = 1;
1717 /* Break the LM hash */
1719 r.in.old_lm_crypted = &hash1;
1720 r.in.new_lm_crypted = &hash2;
1721 r.in.nt_present = 1;
1722 r.in.old_nt_crypted = &hash3;
1723 r.in.new_nt_crypted = &hash4;
1724 r.in.cross1_present = 1;
1725 r.in.nt_cross = &hash5;
1726 r.in.cross2_present = 1;
1727 r.in.lm_cross = &hash6;
1729 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1730 "ChangePasswordUser failed");
1731 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_WRONG_PASSWORD,
1732 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1734 /* Unbreak the LM hash */
1737 r.in.user_handle = &user_handle;
1738 r.in.lm_present = 1;
1739 r.in.old_lm_crypted = &hash1;
1740 r.in.new_lm_crypted = &hash2;
1741 /* Break the NT hash */
1743 r.in.nt_present = 1;
1744 r.in.old_nt_crypted = &hash3;
1745 r.in.new_nt_crypted = &hash4;
1746 r.in.cross1_present = 1;
1747 r.in.nt_cross = &hash5;
1748 r.in.cross2_present = 1;
1749 r.in.lm_cross = &hash6;
1751 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1752 "ChangePasswordUser failed");
1753 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_WRONG_PASSWORD,
1754 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1756 /* Unbreak the NT hash */
1759 r.in.user_handle = &user_handle;
1760 r.in.lm_present = 1;
1761 r.in.old_lm_crypted = &hash1;
1762 r.in.new_lm_crypted = &hash2;
1763 r.in.nt_present = 1;
1764 r.in.old_nt_crypted = &hash3;
1765 r.in.new_nt_crypted = &hash4;
1766 r.in.cross1_present = 1;
1767 r.in.nt_cross = &hash5;
1768 r.in.cross2_present = 1;
1769 /* Break the LM cross */
1771 r.in.lm_cross = &hash6;
1773 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1774 "ChangePasswordUser failed");
1775 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
1776 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(r.out.result));
1780 /* Unbreak the LM cross */
1783 r.in.user_handle = &user_handle;
1784 r.in.lm_present = 1;
1785 r.in.old_lm_crypted = &hash1;
1786 r.in.new_lm_crypted = &hash2;
1787 r.in.nt_present = 1;
1788 r.in.old_nt_crypted = &hash3;
1789 r.in.new_nt_crypted = &hash4;
1790 r.in.cross1_present = 1;
1791 /* Break the NT cross */
1793 r.in.nt_cross = &hash5;
1794 r.in.cross2_present = 1;
1795 r.in.lm_cross = &hash6;
1797 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1798 "ChangePasswordUser failed");
1799 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
1800 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(r.out.result));
1804 /* Unbreak the NT cross */
1808 /* Reset the hashes to not broken values */
1809 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1810 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1811 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1812 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1813 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1814 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1816 r.in.user_handle = &user_handle;
1817 r.in.lm_present = 1;
1818 r.in.old_lm_crypted = &hash1;
1819 r.in.new_lm_crypted = &hash2;
1820 r.in.nt_present = 1;
1821 r.in.old_nt_crypted = &hash3;
1822 r.in.new_nt_crypted = &hash4;
1823 r.in.cross1_present = 1;
1824 r.in.nt_cross = &hash5;
1825 r.in.cross2_present = 0;
1826 r.in.lm_cross = NULL;
1828 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1829 "ChangePasswordUser failed");
1830 if (NT_STATUS_IS_OK(r.out.result)) {
1832 *password = newpass;
1833 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, r.out.result)) {
1834 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r.out.result));
1839 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1841 E_md4hash(oldpass, old_nt_hash);
1842 E_md4hash(newpass, new_nt_hash);
1843 E_deshash(oldpass, old_lm_hash);
1844 E_deshash(newpass, new_lm_hash);
1847 /* Reset the hashes to not broken values */
1848 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1849 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1850 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1851 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1852 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1853 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1855 r.in.user_handle = &user_handle;
1856 r.in.lm_present = 1;
1857 r.in.old_lm_crypted = &hash1;
1858 r.in.new_lm_crypted = &hash2;
1859 r.in.nt_present = 1;
1860 r.in.old_nt_crypted = &hash3;
1861 r.in.new_nt_crypted = &hash4;
1862 r.in.cross1_present = 0;
1863 r.in.nt_cross = NULL;
1864 r.in.cross2_present = 1;
1865 r.in.lm_cross = &hash6;
1867 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1868 "ChangePasswordUser failed");
1869 if (NT_STATUS_IS_OK(r.out.result)) {
1871 *password = newpass;
1872 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, r.out.result)) {
1873 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(r.out.result));
1878 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1880 E_md4hash(oldpass, old_nt_hash);
1881 E_md4hash(newpass, new_nt_hash);
1882 E_deshash(oldpass, old_lm_hash);
1883 E_deshash(newpass, new_lm_hash);
1886 /* Reset the hashes to not broken values */
1887 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1888 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1889 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1890 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1891 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1892 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1894 r.in.user_handle = &user_handle;
1895 r.in.lm_present = 1;
1896 r.in.old_lm_crypted = &hash1;
1897 r.in.new_lm_crypted = &hash2;
1898 r.in.nt_present = 1;
1899 r.in.old_nt_crypted = &hash3;
1900 r.in.new_nt_crypted = &hash4;
1901 r.in.cross1_present = 1;
1902 r.in.nt_cross = &hash5;
1903 r.in.cross2_present = 1;
1904 r.in.lm_cross = &hash6;
1906 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1907 "ChangePasswordUser failed");
1908 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
1909 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
1910 } else if (!NT_STATUS_IS_OK(r.out.result)) {
1911 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(r.out.result));
1915 *password = newpass;
1918 r.in.user_handle = &user_handle;
1919 r.in.lm_present = 1;
1920 r.in.old_lm_crypted = &hash1;
1921 r.in.new_lm_crypted = &hash2;
1922 r.in.nt_present = 1;
1923 r.in.old_nt_crypted = &hash3;
1924 r.in.new_nt_crypted = &hash4;
1925 r.in.cross1_present = 1;
1926 r.in.nt_cross = &hash5;
1927 r.in.cross2_present = 1;
1928 r.in.lm_cross = &hash6;
1931 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1932 "ChangePasswordUser failed");
1933 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
1934 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
1935 } else if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
1936 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(r.out.result));
1942 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
1950 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p,
1951 struct torture_context *tctx,
1952 const char *acct_name,
1953 struct policy_handle *handle, char **password)
1955 struct samr_OemChangePasswordUser2 r;
1957 struct samr_Password lm_verifier;
1958 struct samr_CryptPassword lm_pass;
1959 struct lsa_AsciiString server, account, account_bad;
1962 struct dcerpc_binding_handle *b = p->binding_handle;
1963 uint8_t old_lm_hash[16], new_lm_hash[16];
1965 struct samr_GetDomPwInfo dom_pw_info;
1966 struct samr_PwInfo info;
1967 int policy_min_pw_len = 0;
1969 struct lsa_String domain_name;
1971 domain_name.string = "";
1972 dom_pw_info.in.domain_name = &domain_name;
1973 dom_pw_info.out.info = &info;
1975 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1977 torture_assert(tctx, *password != NULL,
1978 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1980 oldpass = *password;
1982 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
1983 "GetDomPwInfo failed");
1984 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
1985 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1988 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1990 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1991 account.string = acct_name;
1993 E_deshash(oldpass, old_lm_hash);
1994 E_deshash(newpass, new_lm_hash);
1996 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1997 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1998 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2000 r.in.server = &server;
2001 r.in.account = &account;
2002 r.in.password = &lm_pass;
2003 r.in.hash = &lm_verifier;
2005 /* Break the verification */
2006 lm_verifier.hash[0]++;
2008 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2009 "OemChangePasswordUser2 failed");
2011 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2012 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2013 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2014 nt_errstr(r.out.result));
2018 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2019 /* Break the old password */
2021 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2022 /* unbreak it for the next operation */
2024 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2026 r.in.server = &server;
2027 r.in.account = &account;
2028 r.in.password = &lm_pass;
2029 r.in.hash = &lm_verifier;
2031 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2032 "OemChangePasswordUser2 failed");
2034 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2035 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2036 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2037 nt_errstr(r.out.result));
2041 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2042 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2044 r.in.server = &server;
2045 r.in.account = &account;
2046 r.in.password = &lm_pass;
2049 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2050 "OemChangePasswordUser2 failed");
2052 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2053 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2054 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
2055 nt_errstr(r.out.result));
2059 /* This shouldn't be a valid name */
2060 account_bad.string = TEST_ACCOUNT_NAME "XX";
2061 r.in.account = &account_bad;
2063 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2064 "OemChangePasswordUser2 failed");
2066 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2067 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
2068 nt_errstr(r.out.result));
2072 /* This shouldn't be a valid name */
2073 account_bad.string = TEST_ACCOUNT_NAME "XX";
2074 r.in.account = &account_bad;
2075 r.in.password = &lm_pass;
2076 r.in.hash = &lm_verifier;
2078 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2079 "OemChangePasswordUser2 failed");
2081 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2082 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2083 nt_errstr(r.out.result));
2087 /* This shouldn't be a valid name */
2088 account_bad.string = TEST_ACCOUNT_NAME "XX";
2089 r.in.account = &account_bad;
2090 r.in.password = NULL;
2091 r.in.hash = &lm_verifier;
2093 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2094 "OemChangePasswordUser2 failed");
2096 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2097 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2098 nt_errstr(r.out.result));
2102 E_deshash(oldpass, old_lm_hash);
2103 E_deshash(newpass, new_lm_hash);
2105 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2106 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2107 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2109 r.in.server = &server;
2110 r.in.account = &account;
2111 r.in.password = &lm_pass;
2112 r.in.hash = &lm_verifier;
2114 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2115 "OemChangePasswordUser2 failed");
2117 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2118 torture_comment(tctx, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2119 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2120 torture_warning(tctx, "OemChangePasswordUser2 failed - %s\n", nt_errstr(r.out.result));
2123 *password = newpass;
2130 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2131 const char *acct_name,
2133 char *newpass, bool allow_password_restriction)
2135 struct samr_ChangePasswordUser2 r;
2137 struct lsa_String server, account;
2138 struct samr_CryptPassword nt_pass, lm_pass;
2139 struct samr_Password nt_verifier, lm_verifier;
2141 struct dcerpc_binding_handle *b = p->binding_handle;
2142 uint8_t old_nt_hash[16], new_nt_hash[16];
2143 uint8_t old_lm_hash[16], new_lm_hash[16];
2145 struct samr_GetDomPwInfo dom_pw_info;
2146 struct samr_PwInfo info;
2148 struct lsa_String domain_name;
2150 domain_name.string = "";
2151 dom_pw_info.in.domain_name = &domain_name;
2152 dom_pw_info.out.info = &info;
2154 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2156 torture_assert(tctx, *password != NULL,
2157 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2158 oldpass = *password;
2161 int policy_min_pw_len = 0;
2162 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
2163 "GetDomPwInfo failed");
2164 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
2165 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2168 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2171 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2172 init_lsa_String(&account, acct_name);
2174 E_md4hash(oldpass, old_nt_hash);
2175 E_md4hash(newpass, new_nt_hash);
2177 E_deshash(oldpass, old_lm_hash);
2178 E_deshash(newpass, new_lm_hash);
2180 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2181 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2182 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2184 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2185 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2186 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2188 r.in.server = &server;
2189 r.in.account = &account;
2190 r.in.nt_password = &nt_pass;
2191 r.in.nt_verifier = &nt_verifier;
2193 r.in.lm_password = &lm_pass;
2194 r.in.lm_verifier = &lm_verifier;
2196 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser2_r(b, tctx, &r),
2197 "ChangePasswordUser2 failed");
2199 if (allow_password_restriction && NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2200 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2201 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2202 torture_warning(tctx, "ChangePasswordUser2 failed - %s\n", nt_errstr(r.out.result));
2205 *password = newpass;
2212 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2213 const char *account_string,
2214 int policy_min_pw_len,
2216 const char *newpass,
2217 NTTIME last_password_change,
2218 bool handle_reject_reason)
2220 struct samr_ChangePasswordUser3 r;
2222 struct lsa_String server, account, account_bad;
2223 struct samr_CryptPassword nt_pass, lm_pass;
2224 struct samr_Password nt_verifier, lm_verifier;
2226 struct dcerpc_binding_handle *b = p->binding_handle;
2227 uint8_t old_nt_hash[16], new_nt_hash[16];
2228 uint8_t old_lm_hash[16], new_lm_hash[16];
2230 struct samr_DomInfo1 *dominfo = NULL;
2231 struct userPwdChangeFailureInformation *reject = NULL;
2233 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2235 if (newpass == NULL) {
2237 if (policy_min_pw_len == 0) {
2238 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2240 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2242 } while (check_password_quality(newpass) == false);
2244 torture_comment(tctx, "Using password '%s'\n", newpass);
2247 torture_assert(tctx, *password != NULL,
2248 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2250 oldpass = *password;
2251 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2252 init_lsa_String(&account, account_string);
2254 E_md4hash(oldpass, old_nt_hash);
2255 E_md4hash(newpass, new_nt_hash);
2257 E_deshash(oldpass, old_lm_hash);
2258 E_deshash(newpass, new_lm_hash);
2260 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2261 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2262 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2264 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2265 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2266 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2268 /* Break the verification */
2269 nt_verifier.hash[0]++;
2271 r.in.server = &server;
2272 r.in.account = &account;
2273 r.in.nt_password = &nt_pass;
2274 r.in.nt_verifier = &nt_verifier;
2276 r.in.lm_password = &lm_pass;
2277 r.in.lm_verifier = &lm_verifier;
2278 r.in.password3 = NULL;
2279 r.out.dominfo = &dominfo;
2280 r.out.reject = &reject;
2282 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2283 "ChangePasswordUser3 failed");
2284 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2285 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2286 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2287 nt_errstr(r.out.result));
2291 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2292 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2293 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2295 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2296 /* Break the NT hash */
2298 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2299 /* Unbreak it again */
2301 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2303 r.in.server = &server;
2304 r.in.account = &account;
2305 r.in.nt_password = &nt_pass;
2306 r.in.nt_verifier = &nt_verifier;
2308 r.in.lm_password = &lm_pass;
2309 r.in.lm_verifier = &lm_verifier;
2310 r.in.password3 = NULL;
2311 r.out.dominfo = &dominfo;
2312 r.out.reject = &reject;
2314 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2315 "ChangePasswordUser3 failed");
2316 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2317 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2318 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2319 nt_errstr(r.out.result));
2323 /* This shouldn't be a valid name */
2324 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2326 r.in.account = &account_bad;
2327 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2328 "ChangePasswordUser3 failed");
2329 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2330 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2331 nt_errstr(r.out.result));
2335 E_md4hash(oldpass, old_nt_hash);
2336 E_md4hash(newpass, new_nt_hash);
2338 E_deshash(oldpass, old_lm_hash);
2339 E_deshash(newpass, new_lm_hash);
2341 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2342 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2343 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2345 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2346 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2347 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2349 r.in.server = &server;
2350 r.in.account = &account;
2351 r.in.nt_password = &nt_pass;
2352 r.in.nt_verifier = &nt_verifier;
2354 r.in.lm_password = &lm_pass;
2355 r.in.lm_verifier = &lm_verifier;
2356 r.in.password3 = NULL;
2357 r.out.dominfo = &dominfo;
2358 r.out.reject = &reject;
2360 unix_to_nt_time(&t, time(NULL));
2362 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2363 "ChangePasswordUser3 failed");
2365 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2368 && handle_reject_reason
2369 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2370 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2372 if (reject && (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR)) {
2373 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2374 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2379 /* We tested the order of precendence which is as follows:
2388 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2389 (last_password_change + dominfo->min_password_age > t)) {
2391 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2392 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2393 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2397 } else if ((dominfo->min_password_length > 0) &&
2398 (strlen(newpass) < dominfo->min_password_length)) {
2400 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2401 torture_warning(tctx, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2402 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT, reject->extendedFailureReason);
2406 } else if ((dominfo->password_history_length > 0) &&
2407 strequal(oldpass, newpass)) {
2409 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PWD_IN_HISTORY) {
2410 torture_warning(tctx, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2411 SAM_PWD_CHANGE_PWD_IN_HISTORY, reject->extendedFailureReason);
2414 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2416 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NOT_COMPLEX) {
2417 torture_warning(tctx, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2418 SAM_PWD_CHANGE_NOT_COMPLEX, reject->extendedFailureReason);
2424 if (reject->extendedFailureReason == SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2425 /* retry with adjusted size */
2426 return test_ChangePasswordUser3(p, tctx, account_string,
2427 dominfo->min_password_length,
2428 password, NULL, 0, false);
2432 } else if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2433 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2434 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2435 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2438 /* Perhaps the server has a 'min password age' set? */
2441 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3");
2443 *password = talloc_strdup(tctx, newpass);
2449 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2450 const char *account_string,
2451 struct policy_handle *handle,
2455 struct samr_ChangePasswordUser3 r;
2456 struct samr_SetUserInfo s;
2457 union samr_UserInfo u;
2458 DATA_BLOB session_key;
2459 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2460 uint8_t confounder[16];
2461 struct MD5Context ctx;
2464 struct lsa_String server, account;
2465 struct samr_CryptPassword nt_pass;
2466 struct samr_Password nt_verifier;
2467 DATA_BLOB new_random_pass;
2470 struct dcerpc_binding_handle *b = p->binding_handle;
2471 uint8_t old_nt_hash[16], new_nt_hash[16];
2473 struct samr_DomInfo1 *dominfo = NULL;
2474 struct userPwdChangeFailureInformation *reject = NULL;
2476 new_random_pass = samr_very_rand_pass(tctx, 128);
2478 torture_assert(tctx, *password != NULL,
2479 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2481 oldpass = *password;
2482 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2483 init_lsa_String(&account, account_string);
2485 s.in.user_handle = handle;
2491 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2493 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2495 status = dcerpc_fetch_session_key(p, &session_key);
2496 if (!NT_STATUS_IS_OK(status)) {
2497 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
2498 s.in.level, nt_errstr(status));
2502 generate_random_buffer((uint8_t *)confounder, 16);
2505 MD5Update(&ctx, confounder, 16);
2506 MD5Update(&ctx, session_key.data, session_key.length);
2507 MD5Final(confounded_session_key.data, &ctx);
2509 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2510 memcpy(&u.info25.password.data[516], confounder, 16);
2512 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2514 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
2515 "SetUserInfo failed");
2516 if (!NT_STATUS_IS_OK(s.out.result)) {
2517 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
2518 s.in.level, nt_errstr(s.out.result));
2522 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2524 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2526 new_random_pass = samr_very_rand_pass(tctx, 128);
2528 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2530 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2531 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2532 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2534 r.in.server = &server;
2535 r.in.account = &account;
2536 r.in.nt_password = &nt_pass;
2537 r.in.nt_verifier = &nt_verifier;
2539 r.in.lm_password = NULL;
2540 r.in.lm_verifier = NULL;
2541 r.in.password3 = NULL;
2542 r.out.dominfo = &dominfo;
2543 r.out.reject = &reject;
2545 unix_to_nt_time(&t, time(NULL));
2547 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2548 "ChangePasswordUser3 failed");
2550 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2551 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2552 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2553 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2556 /* Perhaps the server has a 'min password age' set? */
2558 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2559 torture_warning(tctx, "ChangePasswordUser3 failed - %s\n", nt_errstr(r.out.result));
2563 newpass = samr_rand_pass(tctx, 128);
2565 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2567 E_md4hash(newpass, new_nt_hash);
2569 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2570 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2571 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2573 r.in.server = &server;
2574 r.in.account = &account;
2575 r.in.nt_password = &nt_pass;
2576 r.in.nt_verifier = &nt_verifier;
2578 r.in.lm_password = NULL;
2579 r.in.lm_verifier = NULL;
2580 r.in.password3 = NULL;
2581 r.out.dominfo = &dominfo;
2582 r.out.reject = &reject;
2584 unix_to_nt_time(&t, time(NULL));
2586 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2587 "ChangePasswordUser3 failed");
2589 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2590 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2591 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2592 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2595 /* Perhaps the server has a 'min password age' set? */
2598 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3 (on second random password)");
2599 *password = talloc_strdup(tctx, newpass);
2606 static bool test_GetMembersInAlias(struct dcerpc_binding_handle *b,
2607 struct torture_context *tctx,
2608 struct policy_handle *alias_handle)
2610 struct samr_GetMembersInAlias r;
2611 struct lsa_SidArray sids;
2613 torture_comment(tctx, "Testing GetMembersInAlias\n");
2615 r.in.alias_handle = alias_handle;
2618 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetMembersInAlias_r(b, tctx, &r),
2619 "GetMembersInAlias failed");
2620 torture_assert_ntstatus_ok(tctx, r.out.result, "GetMembersInAlias failed");
2625 static bool test_AddMemberToAlias(struct dcerpc_binding_handle *b,
2626 struct torture_context *tctx,
2627 struct policy_handle *alias_handle,
2628 const struct dom_sid *domain_sid)
2630 struct samr_AddAliasMember r;
2631 struct samr_DeleteAliasMember d;
2632 struct dom_sid *sid;
2634 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2636 torture_comment(tctx, "Testing AddAliasMember\n");
2637 r.in.alias_handle = alias_handle;
2640 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddAliasMember_r(b, tctx, &r),
2641 "AddAliasMember failed");
2642 torture_assert_ntstatus_ok(tctx, r.out.result, "AddAliasMember failed");
2644 d.in.alias_handle = alias_handle;
2647 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteAliasMember_r(b, tctx, &d),
2648 "DeleteAliasMember failed");
2649 torture_assert_ntstatus_ok(tctx, d.out.result, "DelAliasMember failed");
2654 static bool test_AddMultipleMembersToAlias(struct dcerpc_binding_handle *b,
2655 struct torture_context *tctx,
2656 struct policy_handle *alias_handle)
2658 struct samr_AddMultipleMembersToAlias a;
2659 struct samr_RemoveMultipleMembersFromAlias r;
2660 struct lsa_SidArray sids;
2662 torture_comment(tctx, "Testing AddMultipleMembersToAlias\n");
2663 a.in.alias_handle = alias_handle;
2667 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2669 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2670 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2671 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2673 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddMultipleMembersToAlias_r(b, tctx, &a),
2674 "AddMultipleMembersToAlias failed");
2675 torture_assert_ntstatus_ok(tctx, a.out.result, "AddMultipleMembersToAlias");
2678 torture_comment(tctx, "Testing RemoveMultipleMembersFromAlias\n");
2679 r.in.alias_handle = alias_handle;
2682 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2683 "RemoveMultipleMembersFromAlias failed");
2684 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2686 /* strange! removing twice doesn't give any error */
2687 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2688 "RemoveMultipleMembersFromAlias failed");
2689 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2691 /* but removing an alias that isn't there does */
2692 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2694 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2695 "RemoveMultipleMembersFromAlias failed");
2696 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2701 static bool test_GetAliasMembership(struct dcerpc_binding_handle *b,
2702 struct torture_context *tctx,
2703 struct policy_handle *domain_handle)
2705 struct samr_GetAliasMembership r;
2706 struct lsa_SidArray sids;
2707 struct samr_Ids rids;
2709 torture_comment(tctx, "Testing GetAliasMembership\n");
2711 r.in.domain_handle = domain_handle;
2716 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2718 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2719 "GetAliasMembership failed");
2720 torture_assert_ntstatus_ok(tctx, r.out.result,
2721 "samr_GetAliasMembership failed");
2723 torture_assert_int_equal(tctx, sids.num_sids, rids.count,
2724 "protocol misbehaviour");
2727 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2728 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2730 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2731 "samr_GetAliasMembership failed");
2732 torture_assert_ntstatus_ok(tctx, r.out.result,
2733 "samr_GetAliasMembership failed");
2736 /* only true for w2k8 it seems
2737 * win7, xp, w2k3 will return a 0 length array pointer */
2739 if (rids.ids && (rids.count == 0)) {
2740 torture_fail(tctx, "samr_GetAliasMembership returned 0 count and a rids array");
2743 if (!rids.ids && rids.count) {
2744 torture_fail(tctx, "samr_GetAliasMembership returned non-0 count but no rids");
2750 static bool test_TestPrivateFunctionsUser(struct dcerpc_binding_handle *b,
2751 struct torture_context *tctx,
2752 struct policy_handle *user_handle)
2754 struct samr_TestPrivateFunctionsUser r;
2756 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2758 r.in.user_handle = user_handle;
2760 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsUser_r(b, tctx, &r),
2761 "TestPrivateFunctionsUser failed");
2762 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2767 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_binding_handle *b,
2768 struct torture_context *tctx,
2769 struct policy_handle *handle,
2774 uint16_t levels[] = { /* 3, */ 5, 21 };
2776 NTTIME pwdlastset3 = 0;
2777 NTTIME pwdlastset5 = 0;
2778 NTTIME pwdlastset21 = 0;
2780 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2781 use_info2 ? "2":"");
2783 for (i=0; i<ARRAY_SIZE(levels); i++) {
2785 struct samr_QueryUserInfo r;
2786 struct samr_QueryUserInfo2 r2;
2787 union samr_UserInfo *info;
2790 r2.in.user_handle = handle;
2791 r2.in.level = levels[i];
2792 r2.out.info = &info;
2793 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r2),
2794 "QueryUserInfo2 failed");
2795 status = r2.out.result;
2798 r.in.user_handle = handle;
2799 r.in.level = levels[i];
2801 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
2802 "QueryUserInfo failed");
2803 status = r.out.result;
2806 if (!NT_STATUS_IS_OK(status) &&
2807 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2808 torture_warning(tctx, "QueryUserInfo%s level %u failed - %s\n",
2809 use_info2 ? "2":"", levels[i], nt_errstr(status));
2813 switch (levels[i]) {
2815 pwdlastset3 = info->info3.last_password_change;
2818 pwdlastset5 = info->info5.last_password_change;
2821 pwdlastset21 = info->info21.last_password_change;
2827 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2828 "pwdlastset mixup"); */
2829 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2830 "pwdlastset mixup");
2832 *pwdlastset = pwdlastset21;
2834 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2839 static bool test_SamLogon(struct torture_context *tctx,
2840 struct dcerpc_pipe *p,
2841 struct cli_credentials *test_credentials,
2842 NTSTATUS expected_result,
2846 struct netr_LogonSamLogonEx r;
2847 union netr_LogonLevel logon;
2848 union netr_Validation validation;
2849 uint8_t authoritative;
2850 struct netr_IdentityInfo identity;
2851 struct netr_NetworkInfo ninfo;
2852 struct netr_PasswordInfo pinfo;
2853 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2854 int flags = CLI_CRED_NTLM_AUTH;
2855 uint32_t samlogon_flags = 0;
2856 struct netlogon_creds_CredentialState *creds;
2857 struct netr_Authenticator a;
2858 struct dcerpc_binding_handle *b = p->binding_handle;
2860 torture_assert_ntstatus_ok(tctx, dcerpc_schannel_creds(p->conn->security_state.generic_state, tctx, &creds), "");
2862 if (lp_client_lanman_auth(tctx->lp_ctx)) {
2863 flags |= CLI_CRED_LANMAN_AUTH;
2866 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2867 flags |= CLI_CRED_NTLMv2_AUTH;
2870 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2871 &identity.account_name.string,
2872 &identity.domain_name.string);
2874 identity.parameter_control =
2875 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2876 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2877 identity.logon_id_low = 0;
2878 identity.logon_id_high = 0;
2879 identity.workstation.string = cli_credentials_get_workstation(test_credentials);
2882 netlogon_creds_client_authenticator(creds, &a);
2884 if (!E_deshash(cli_credentials_get_password(test_credentials), pinfo.lmpassword.hash)) {
2885 ZERO_STRUCT(pinfo.lmpassword.hash);
2887 E_md4hash(cli_credentials_get_password(test_credentials), pinfo.ntpassword.hash);
2889 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
2890 netlogon_creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
2891 netlogon_creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
2893 netlogon_creds_des_encrypt(creds, &pinfo.lmpassword);
2894 netlogon_creds_des_encrypt(creds, &pinfo.ntpassword);
2897 pinfo.identity_info = identity;
2898 logon.password = &pinfo;
2900 r.in.logon_level = NetlogonInteractiveInformation;
2902 generate_random_buffer(ninfo.challenge,
2903 sizeof(ninfo.challenge));
2904 chal = data_blob_const(ninfo.challenge,
2905 sizeof(ninfo.challenge));
2907 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
2908 cli_credentials_get_domain(test_credentials));
2910 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2916 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2918 ninfo.lm.data = lm_resp.data;
2919 ninfo.lm.length = lm_resp.length;
2921 ninfo.nt.data = nt_resp.data;
2922 ninfo.nt.length = nt_resp.length;
2924 ninfo.identity_info = identity;
2925 logon.network = &ninfo;
2927 r.in.logon_level = NetlogonNetworkInformation;
2930 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2931 r.in.computer_name = cli_credentials_get_workstation(test_credentials);
2932 r.in.logon = &logon;
2933 r.in.flags = &samlogon_flags;
2934 r.out.flags = &samlogon_flags;
2935 r.out.validation = &validation;
2936 r.out.authoritative = &authoritative;
2938 torture_comment(tctx, "Testing LogonSamLogon with name %s\n", identity.account_name.string);
2940 r.in.validation_level = 6;
2942 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
2943 "netr_LogonSamLogonEx failed");
2944 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
2945 r.in.validation_level = 3;
2946 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
2947 "netr_LogonSamLogonEx failed");
2949 if (!NT_STATUS_IS_OK(r.out.result)) {
2950 torture_assert_ntstatus_equal(tctx, r.out.result, expected_result, "LogonSamLogonEx failed");
2953 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogonEx failed");
2959 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2960 struct dcerpc_pipe *p,
2961 struct cli_credentials *machine_creds,
2962 const char *acct_name,
2963 const char *password,
2964 NTSTATUS expected_samlogon_result,
2968 struct cli_credentials *test_credentials;
2970 test_credentials = cli_credentials_init(tctx);
2972 cli_credentials_set_workstation(test_credentials,
2973 cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
2974 cli_credentials_set_domain(test_credentials,
2975 cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
2976 cli_credentials_set_username(test_credentials,
2977 acct_name, CRED_SPECIFIED);
2978 cli_credentials_set_password(test_credentials,
2979 password, CRED_SPECIFIED);
2981 torture_comment(tctx, "Testing samlogon (%s) as %s password: %s\n",
2982 interactive ? "interactive" : "network", acct_name, password);
2984 if (!test_SamLogon(tctx, p, test_credentials,
2985 expected_samlogon_result, interactive)) {
2986 torture_warning(tctx, "new password did not work\n");
2993 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2994 struct dcerpc_pipe *np,
2995 struct torture_context *tctx,
2996 struct policy_handle *handle,
2998 uint32_t fields_present,
2999 uint8_t password_expired,
3000 bool *matched_expected_error,
3002 const char *acct_name,
3004 struct cli_credentials *machine_creds,
3005 bool use_queryinfo2,
3007 NTSTATUS expected_samlogon_result)
3009 const char *fields = NULL;
3011 struct dcerpc_binding_handle *b = p->binding_handle;
3017 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
3024 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
3025 "(password_expired: %d) %s\n",
3026 use_setinfo2 ? "2":"", level, password_expired,
3027 fields ? fields : "");
3029 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
3034 matched_expected_error)) {
3038 if (!test_QueryUserInfo_pwdlastset(b, tctx, handle,
3044 if (*matched_expected_error == true) {
3048 if (!test_SamLogon_with_creds(tctx, np,
3052 expected_samlogon_result,
3060 static bool setup_schannel_netlogon_pipe(struct torture_context *tctx,
3061 struct cli_credentials *credentials,
3062 struct dcerpc_pipe **p)
3064 struct dcerpc_binding *b;
3066 torture_assert_ntstatus_ok(tctx, torture_rpc_binding(tctx, &b),
3067 "failed to get rpc binding");
3069 /* We have to use schannel, otherwise the SamLogonEx fails
3070 * with INTERNAL_ERROR */
3072 b->flags &= ~DCERPC_AUTH_OPTIONS;
3073 b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
3075 torture_assert_ntstatus_ok(tctx,
3076 dcerpc_pipe_connect_b(tctx, p, b, &ndr_table_netlogon,
3077 credentials, tctx->ev, tctx->lp_ctx),
3078 "failed to bind to netlogon");
3083 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
3084 struct torture_context *tctx,
3085 uint32_t acct_flags,
3086 const char *acct_name,
3087 struct policy_handle *handle,
3089 struct cli_credentials *machine_credentials)
3091 int s = 0, q = 0, f = 0, l = 0, z = 0;
3094 bool set_levels[] = { false, true };
3095 bool query_levels[] = { false, true };
3096 uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
3097 uint32_t nonzeros[] = { 1, 24 };
3098 uint32_t fields_present[] = {
3100 SAMR_FIELD_EXPIRED_FLAG,
3101 SAMR_FIELD_LAST_PWD_CHANGE,
3102 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
3104 SAMR_FIELD_NT_PASSWORD_PRESENT,
3105 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3106 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3107 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3108 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3109 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3110 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
3112 struct dcerpc_pipe *np = NULL;
3114 if (torture_setting_bool(tctx, "samba3", false)) {
3116 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
3120 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3122 /* set to 1 to enable testing for all possible opcode
3123 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3126 #define TEST_ALL_LEVELS 1
3127 #define TEST_SET_LEVELS 1
3128 #define TEST_QUERY_LEVELS 1
3130 #ifdef TEST_ALL_LEVELS
3131 for (l=0; l<ARRAY_SIZE(levels); l++) {
3133 for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
3135 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
3136 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
3137 #ifdef TEST_SET_LEVELS
3138 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
3140 #ifdef TEST_QUERY_LEVELS
3141 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
3143 NTTIME pwdlastset_old = 0;
3144 NTTIME pwdlastset_new = 0;
3145 bool matched_expected_error = false;
3146 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
3148 torture_comment(tctx, "------------------------------\n"
3149 "Testing pwdLastSet attribute for flags: 0x%08x "
3150 "(s: %d (l: %d), q: %d)\n",
3151 acct_flags, s, levels[l], q);
3153 switch (levels[l]) {
3157 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3158 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
3159 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
3167 /* set a password and force password change (pwdlastset 0) by
3168 * setting the password expired flag to a non-0 value */
3170 if (!test_SetPassword_level(p, np, tctx, handle,
3174 &matched_expected_error,
3178 machine_credentials,
3181 expected_samlogon_result)) {
3185 if (matched_expected_error == true) {
3186 /* skipping on expected failure */
3190 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3191 * set without the SAMR_FIELD_EXPIRED_FLAG */
3193 switch (levels[l]) {
3197 if ((pwdlastset_new != 0) &&
3198 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3199 torture_comment(tctx, "not considering a non-0 "
3200 "pwdLastSet as a an error as the "
3201 "SAMR_FIELD_EXPIRED_FLAG has not "
3207 if (pwdlastset_new != 0) {
3208 torture_warning(tctx, "pwdLastSet test failed: "
3209 "expected pwdLastSet 0 but got %lld\n",
3216 switch (levels[l]) {
3220 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3221 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3222 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3223 (pwdlastset_old >= pwdlastset_new)) {
3224 torture_warning(tctx, "pwdlastset not increasing\n");
3230 pwdlastset_old = pwdlastset_new;
3236 /* set a password, pwdlastset needs to get updated (increased
3237 * value), password_expired value used here is 0 */
3239 if (!test_SetPassword_level(p, np, tctx, handle,
3243 &matched_expected_error,
3247 machine_credentials,
3250 expected_samlogon_result)) {
3254 /* when a password has been changed, pwdlastset must not be 0 afterwards
3255 * and must be larger then the old value */
3257 switch (levels[l]) {
3261 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3262 * password has been changed, old and new pwdlastset
3263 * need to be the same value */
3265 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3266 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3267 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3269 torture_assert_int_equal(tctx, pwdlastset_old,
3270 pwdlastset_new, "pwdlastset must be equal");
3275 if (pwdlastset_old >= pwdlastset_new) {
3276 torture_warning(tctx, "pwdLastSet test failed: "
3277 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3278 pwdlastset_old, pwdlastset_new);
3281 if (pwdlastset_new == 0) {
3282 torture_warning(tctx, "pwdLastSet test failed: "
3283 "expected non-0 pwdlastset, got: %lld\n",
3290 switch (levels[l]) {
3294 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3295 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3296 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3297 (pwdlastset_old >= pwdlastset_new)) {
3298 torture_warning(tctx, "pwdlastset not increasing\n");
3304 pwdlastset_old = pwdlastset_new;
3310 /* set a password, pwdlastset needs to get updated (increased
3311 * value), password_expired value used here is 0 */
3313 if (!test_SetPassword_level(p, np, tctx, handle,
3317 &matched_expected_error,
3321 machine_credentials,
3324 expected_samlogon_result)) {
3328 /* when a password has been changed, pwdlastset must not be 0 afterwards
3329 * and must be larger then the old value */
3331 switch (levels[l]) {
3336 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3337 * password has been changed, old and new pwdlastset
3338 * need to be the same value */
3340 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3341 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3342 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3344 torture_assert_int_equal(tctx, pwdlastset_old,
3345 pwdlastset_new, "pwdlastset must be equal");
3350 if (pwdlastset_old >= pwdlastset_new) {
3351 torture_warning(tctx, "pwdLastSet test failed: "
3352 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3353 pwdlastset_old, pwdlastset_new);
3356 if (pwdlastset_new == 0) {
3357 torture_warning(tctx, "pwdLastSet test failed: "
3358 "expected non-0 pwdlastset, got: %lld\n",
3365 switch (levels[l]) {
3369 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3370 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3371 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3372 (pwdlastset_old >= pwdlastset_new)) {
3373 torture_warning(tctx, "pwdlastset not increasing\n");
3379 pwdlastset_old = pwdlastset_new;
3385 /* set a password and force password change (pwdlastset 0) by
3386 * setting the password expired flag to a non-0 value */
3388 if (!test_SetPassword_level(p, np, tctx, handle,
3392 &matched_expected_error,
3396 machine_credentials,
3399 expected_samlogon_result)) {
3403 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3404 * set without the SAMR_FIELD_EXPIRED_FLAG */
3406 switch (levels[l]) {
3410 if ((pwdlastset_new != 0) &&
3411 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3412 torture_comment(tctx, "not considering a non-0 "
3413 "pwdLastSet as a an error as the "
3414 "SAMR_FIELD_EXPIRED_FLAG has not "
3419 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3420 * password has been changed, old and new pwdlastset
3421 * need to be the same value */
3423 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3424 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3425 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3427 torture_assert_int_equal(tctx, pwdlastset_old,
3428 pwdlastset_new, "pwdlastset must be equal");
3433 if (pwdlastset_new != 0) {
3434 torture_warning(tctx, "pwdLastSet test failed: "
3435 "expected pwdLastSet 0, got %lld\n",
3442 switch (levels[l]) {
3446 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3447 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3448 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3449 (pwdlastset_old >= pwdlastset_new)) {
3450 torture_warning(tctx, "pwdlastset not increasing\n");
3456 /* if the level we are testing does not have a fields_present
3457 * field, skip all fields present tests by setting f to to
3459 switch (levels[l]) {
3463 f = ARRAY_SIZE(fields_present);
3467 #ifdef TEST_QUERY_LEVELS
3470 #ifdef TEST_SET_LEVELS
3473 } /* fields present */
3477 #undef TEST_SET_LEVELS
3478 #undef TEST_QUERY_LEVELS
3485 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_binding_handle *b,
3486 struct torture_context *tctx,
3487 struct policy_handle *handle,
3488 uint32_t *badpwdcount)
3490 union samr_UserInfo *info;
3491 struct samr_QueryUserInfo r;
3493 r.in.user_handle = handle;
3497 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3499 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3500 "failed to query userinfo");
3501 torture_assert_ntstatus_ok(tctx, r.out.result,
3502 "failed to query userinfo");
3504 *badpwdcount = info->info3.bad_password_count;
3506 torture_comment(tctx, " (bad password count: %d)\n", *badpwdcount);
3511 static bool test_SetUserInfo_acct_flags(struct dcerpc_binding_handle *b,
3512 struct torture_context *tctx,
3513 struct policy_handle *user_handle,
3514 uint32_t acct_flags)
3516 struct samr_SetUserInfo r;
3517 union samr_UserInfo user_info;
3519 torture_comment(tctx, "Testing SetUserInfo level 16\n");
3521 user_info.info16.acct_flags = acct_flags;
3523 r.in.user_handle = user_handle;
3525 r.in.info = &user_info;
3527 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &r),
3528 "failed to set account flags");
3529 torture_assert_ntstatus_ok(tctx, r.out.result,
3530 "failed to set account flags");
3535 static bool test_reset_badpwdcount(struct dcerpc_pipe *p,
3536 struct torture_context *tctx,
3537 struct policy_handle *user_handle,
3538 uint32_t acct_flags,
3541 struct dcerpc_binding_handle *b = p->binding_handle;
3543 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3544 "failed to set password");
3546 torture_comment(tctx, "Testing SetUserInfo level 16 (enable account)\n");
3548 torture_assert(tctx,
3549 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3550 acct_flags & ~ACB_DISABLED),
3551 "failed to enable user");
3553 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3554 "failed to set password");
3559 static bool test_SetDomainInfo(struct dcerpc_binding_handle *b,
3560 struct torture_context *tctx,
3561 struct policy_handle *domain_handle,
3562 enum samr_DomainInfoClass level,
3563 union samr_DomainInfo *info)
3565 struct samr_SetDomainInfo r;
3567 r.in.domain_handle = domain_handle;
3571 torture_assert_ntstatus_ok(tctx,
3572 dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3573 "failed to set domain info");
3574 torture_assert_ntstatus_ok(tctx, r.out.result,
3575 "failed to set domain info");
3580 static bool test_SetDomainInfo_ntstatus(struct dcerpc_binding_handle *b,
3581 struct torture_context *tctx,
3582 struct policy_handle *domain_handle,
3583 enum samr_DomainInfoClass level,
3584 union samr_DomainInfo *info,
3587 struct samr_SetDomainInfo r;
3589 r.in.domain_handle = domain_handle;
3593 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3594 "SetDomainInfo failed");
3595 torture_assert_ntstatus_equal(tctx, r.out.result, expected, "");
3600 static bool test_QueryDomainInfo2_level(struct dcerpc_binding_handle *b,
3601 struct torture_context *tctx,
3602 struct policy_handle *domain_handle,
3603 enum samr_DomainInfoClass level,
3604 union samr_DomainInfo **q_info)
3606 struct samr_QueryDomainInfo2 r;
3608 r.in.domain_handle = domain_handle;
3610 r.out.info = q_info;
3612 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
3613 "failed to query domain info");
3614 torture_assert_ntstatus_ok(tctx, r.out.result,
3615 "failed to query domain info");
3620 static bool test_Password_badpwdcount(struct dcerpc_pipe *p,
3621 struct dcerpc_pipe *np,
3622 struct torture_context *tctx,
3623 uint32_t acct_flags,
3624 const char *acct_name,
3625 struct policy_handle *domain_handle,
3626 struct policy_handle *user_handle,
3628 struct cli_credentials *machine_credentials,
3629 const char *comment,
3632 NTSTATUS expected_success_status,
3633 struct samr_DomInfo1 *info1,
3634 struct samr_DomInfo12 *info12)
3636 union samr_DomainInfo info;
3639 uint32_t badpwdcount, tmp;
3640 uint32_t password_history_length = 12;
3641 uint32_t lockout_threshold = 15;
3642 struct dcerpc_binding_handle *b = p->binding_handle;
3644 torture_comment(tctx, "\nTesting bad pwd count with: %s\n", comment);
3646 torture_assert(tctx, password_history_length < lockout_threshold,
3647 "password history length needs to be smaller than account lockout threshold for this test");
3652 info.info1 = *info1;
3653 info.info1.password_history_length = password_history_length;
3655 torture_assert(tctx,
3656 test_SetDomainInfo(b, tctx, domain_handle,
3657 DomainPasswordInformation, &info),
3658 "failed to set password history length");
3660 info.info12 = *info12;
3661 info.info12.lockout_threshold = lockout_threshold;
3663 torture_assert(tctx,
3664 test_SetDomainInfo(b, tctx, domain_handle,
3665 DomainLockoutInformation, &info),
3666 "failed to set lockout threshold");
3668 /* reset bad pwd count */
3670 torture_assert(tctx,
3671 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
3674 /* enable or disable account */
3676 torture_assert(tctx,
3677 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3678 acct_flags | ACB_DISABLED),
3679 "failed to disable user");
3681 torture_assert(tctx,
3682 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3683 acct_flags & ~ACB_DISABLED),
3684 "failed to enable user");
3688 /* setup password history */
3690 passwords = talloc_array(tctx, char *, password_history_length);
3692 for (i=0; i < password_history_length; i++) {
3694 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3695 "failed to set password");
3696 passwords[i] = talloc_strdup(tctx, *password);
3698 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3699 acct_name, passwords[i],
3700 expected_success_status, interactive)) {
3701 torture_fail(tctx, "failed to auth with latest password");
3704 torture_assert(tctx,
3705 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3707 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3711 /* test with wrong password */
3713 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3714 acct_name, "random_crap",
3715 NT_STATUS_WRONG_PASSWORD, interactive)) {
3716 torture_fail(tctx, "succeeded to authenticate with wrong password");
3719 torture_assert(tctx,
3720 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3722 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3725 /* test with latest good password */
3727 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
3728 passwords[password_history_length-1],
3729 expected_success_status, interactive)) {
3730 torture_fail(tctx, "succeeded to authenticate with wrong password");
3733 torture_assert(tctx,
3734 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3737 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3739 /* only enabled accounts get the bad pwd count reset upon
3740 * successful logon */
3741 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3747 /* test password history */
3749 for (i=0; i < password_history_length; i++) {
3751 torture_comment(tctx, "Testing bad password count behavior with "
3752 "password #%d of #%d\n", i, password_history_length);
3754 /* - network samlogon will succeed auth and not
3755 * increase badpwdcount for 2 last entries
3756 * - interactive samlogon only for the last one */
3758 if (i == password_history_length - 1 ||
3759 (i == password_history_length - 2 && !interactive)) {
3761 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3762 acct_name, passwords[i],
3763 expected_success_status, interactive)) {
3764 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3767 torture_assert(tctx,
3768 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3771 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
3772 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3774 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
3775 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3783 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3784 acct_name, passwords[i],
3785 NT_STATUS_WRONG_PASSWORD, interactive)) {
3786 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3789 torture_assert(tctx,
3790 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3792 /* - network samlogon will fail auth but not increase
3793 * badpwdcount for 3rd last entry
3794 * - interactive samlogon for 3rd and 2nd last entry */
3796 if (i == password_history_length - 3 ||
3797 (i == password_history_length - 2 && interactive)) {
3798 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
3799 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3801 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
3802 torture_assert_int_equal(tctx, badpwdcount, tmp + 1, "unexpected badpwdcount");
3811 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe *p,
3812 struct torture_context *tctx,
3813 uint32_t acct_flags,
3814 const char *acct_name,
3815 struct policy_handle *domain_handle,
3816 struct policy_handle *user_handle,
3818 struct cli_credentials *machine_credentials)
3820 union samr_DomainInfo *q_info, s_info;
3821 struct samr_DomInfo1 info1, _info1;
3822 struct samr_DomInfo12 info12, _info12;
3824 struct dcerpc_binding_handle *b = p->binding_handle;
3825 struct dcerpc_pipe *np;
3829 const char *comment;
3832 NTSTATUS expected_success_status;
3835 .comment = "network logon (disabled account)",
3837 .interactive = false,
3838 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
3841 .comment = "network logon (enabled account)",
3843 .interactive = false,
3844 .expected_success_status= NT_STATUS_OK
3847 .comment = "interactive logon (disabled account)",
3849 .interactive = true,
3850 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
3853 .comment = "interactive logon (enabled account)",
3855 .interactive = true,
3856 .expected_success_status= NT_STATUS_OK
3860 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3862 /* backup old policies */
3864 torture_assert(tctx,
3865 test_QueryDomainInfo2_level(b, tctx, domain_handle,
3866 DomainPasswordInformation, &q_info),
3867 "failed to query domain info level 1");
3869 info1 = q_info->info1;
3872 torture_assert(tctx,
3873 test_QueryDomainInfo2_level(b, tctx, domain_handle,
3874 DomainLockoutInformation, &q_info),
3875 "failed to query domain info level 12");
3877 info12 = q_info->info12;
3882 for (i=0; i < ARRAY_SIZE(creds); i++) {
3884 /* skip trust tests for now */
3885 if (acct_flags & ACB_WSTRUST ||
3886 acct_flags & ACB_SVRTRUST ||
3887 acct_flags & ACB_DOMTRUST) {
3891 ret &= test_Password_badpwdcount(p, np, tctx, acct_flags, acct_name,
3892 domain_handle, user_handle, password,
3893 machine_credentials,
3896 creds[i].interactive,
3897 creds[i].expected_success_status,
3900 torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
3902 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
3906 /* restore policies */
3908 s_info.info1 = info1;
3910 torture_assert(tctx,
3911 test_SetDomainInfo(b, tctx, domain_handle,
3912 DomainPasswordInformation, &s_info),
3913 "failed to set password information");
3915 s_info.info12 = info12;
3917 torture_assert(tctx,
3918 test_SetDomainInfo(b, tctx, domain_handle,
3919 DomainLockoutInformation, &s_info),
3920 "failed to set lockout information");
3925 static bool test_QueryUserInfo_acct_flags(struct dcerpc_binding_handle *b,
3926 struct torture_context *tctx,
3927 struct policy_handle *handle,
3928 uint32_t *acct_flags)
3930 union samr_UserInfo *info;
3931 struct samr_QueryUserInfo r;
3933 r.in.user_handle = handle;
3937 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3939 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3940 "failed to query userinfo");
3941 torture_assert_ntstatus_ok(tctx, r.out.result,
3942 "failed to query userinfo");
3944 *acct_flags = info->info16.acct_flags;
3946 torture_comment(tctx, " (acct_flags: 0x%08x)\n", *acct_flags);
3951 static bool test_Password_lockout(struct dcerpc_pipe *p,
3952 struct dcerpc_pipe *np,
3953 struct torture_context *tctx,
3954 uint32_t acct_flags,
3955 const char *acct_name,
3956 struct policy_handle *domain_handle,
3957 struct policy_handle *user_handle,
3959 struct cli_credentials *machine_credentials,
3960 const char *comment,
3963 NTSTATUS expected_success_status,
3964 struct samr_DomInfo1 *info1,
3965 struct samr_DomInfo12 *info12)
3967 union samr_DomainInfo info;
3968 uint32_t badpwdcount;
3969 uint32_t password_history_length = 1;
3970 uint64_t lockout_threshold = 1;
3971 uint32_t lockout_seconds = 5;
3972 uint64_t delta_time_factor = 10 * 1000 * 1000;
3973 struct dcerpc_binding_handle *b = p->binding_handle;
3975 torture_comment(tctx, "\nTesting account lockout: %s\n", comment);
3979 info.info1 = *info1;
3981 torture_comment(tctx, "setting password history length.\n");
3982 info.info1.password_history_length = password_history_length;
3984 torture_assert(tctx,
3985 test_SetDomainInfo(b, tctx, domain_handle,
3986 DomainPasswordInformation, &info),
3987 "failed to set password history length");
3989 info.info12 = *info12;
3990 info.info12.lockout_threshold = lockout_threshold;
3992 /* set lockout duration < lockout window: should fail */
3993 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
3994 info.info12.lockout_window = ~((lockout_seconds + 1) * delta_time_factor);
3996 torture_assert(tctx,
3997 test_SetDomainInfo_ntstatus(b, tctx, domain_handle,
3998 DomainLockoutInformation, &info,
3999 NT_STATUS_INVALID_PARAMETER),
4000 "setting lockout duration < lockout window gave unexpected result");
4002 info.info12.lockout_duration = 0;
4003 info.info12.lockout_window = 0;
4005 torture_assert(tctx,
4006 test_SetDomainInfo(b, tctx, domain_handle,
4007 DomainLockoutInformation, &info),
4008 "failed to set lockout window and duration to 0");
4011 /* set lockout duration of 5 seconds */
4012 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4013 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
4015 torture_assert(tctx,
4016 test_SetDomainInfo(b, tctx, domain_handle,
4017 DomainLockoutInformation, &info),
4018 "failed to set lockout window and duration to 5 seconds");
4020 /* reset bad pwd count */
4022 torture_assert(tctx,
4023 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
4026 /* enable or disable account */
4029 torture_assert(tctx,
4030 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4031 acct_flags | ACB_DISABLED),
4032 "failed to disable user");
4034 torture_assert(tctx,
4035 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4036 acct_flags & ~ACB_DISABLED),
4037 "failed to enable user");
4041 /* test logon with right password */
4043 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4044 acct_name, *password,
4045 expected_success_status, interactive)) {
4046 torture_fail(tctx, "failed to auth with latest password");
4049 torture_assert(tctx,
4050 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4051 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
4054 /* test with wrong password ==> lockout */
4056 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4057 acct_name, "random_crap",
4058 NT_STATUS_WRONG_PASSWORD, interactive)) {
4059 torture_fail(tctx, "succeeded to authenticate with wrong password");
4062 torture_assert(tctx,
4063 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4064 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4066 torture_assert(tctx,
4067 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4068 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4069 "expected account to be locked");
4072 /* test with good password */
4074 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4076 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4078 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4081 /* bad pwd count should not get updated */
4082 torture_assert(tctx,
4083 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4084 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4086 /* curiously, windows does _not_ set the autlock flag */
4087 torture_assert(tctx,
4088 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4089 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4090 "expected account to be locked");
4093 /* with bad password */
4095 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4096 acct_name, "random_crap2",
4097 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4099 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4102 /* bad pwd count should not get updated */
4103 torture_assert(tctx,
4104 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4105 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4107 /* curiously, windows does _not_ set the autlock flag */
4108 torture_assert(tctx,
4109 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4110 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4111 "expected account to be locked");
4114 /* let lockout duration expire ==> unlock */
4116 torture_comment(tctx, "let lockout duration expire...\n");
4117 sleep(lockout_seconds + 1);
4119 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4121 expected_success_status, interactive))
4123 torture_fail(tctx, "failed to authenticate after lockout expired");
4126 torture_assert(tctx,
4127 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4128 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4129 "expected account not to be locked");
4134 static bool test_Password_lockout_wrap(struct dcerpc_pipe *p,
4135 struct torture_context *tctx,
4136 uint32_t acct_flags,
4137 const char *acct_name,
4138 struct policy_handle *domain_handle,
4139 struct policy_handle *user_handle,
4141 struct cli_credentials *machine_credentials)
4143 union samr_DomainInfo *q_info, s_info;
4144 struct samr_DomInfo1 info1, _info1;
4145 struct samr_DomInfo12 info12, _info12;
4147 struct dcerpc_binding_handle *b = p->binding_handle;
4148 struct dcerpc_pipe *np;
4152 const char *comment;
4155 NTSTATUS expected_success_status;
4158 .comment = "network logon (disabled account)",
4160 .interactive = false,
4161 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4164 .comment = "network logon (enabled account)",
4166 .interactive = false,
4167 .expected_success_status= NT_STATUS_OK
4170 .comment = "interactive logon (disabled account)",
4172 .interactive = true,
4173 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4176 .comment = "interactive logon (enabled account)",
4178 .interactive = true,
4179 .expected_success_status= NT_STATUS_OK
4183 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4185 /* backup old policies */
4187 torture_assert(tctx,
4188 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4189 DomainPasswordInformation, &q_info),
4190 "failed to query domain info level 1");
4192 info1 = q_info->info1;
4195 torture_assert(tctx,
4196 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4197 DomainLockoutInformation, &q_info),
4198 "failed to query domain info level 12");
4200 info12 = q_info->info12;
4205 for (i=0; i < ARRAY_SIZE(creds); i++) {
4207 /* skip trust tests for now */
4208 if (acct_flags & ACB_WSTRUST ||
4209 acct_flags & ACB_SVRTRUST ||
4210 acct_flags & ACB_DOMTRUST) {
4214 ret &= test_Password_lockout(p, np, tctx, acct_flags, acct_name,
4215 domain_handle, user_handle, password,
4216 machine_credentials,
4219 creds[i].interactive,
4220 creds[i].expected_success_status,
4223 torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
4225 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4229 /* restore policies */
4231 s_info.info1 = info1;
4233 torture_assert(tctx,
4234 test_SetDomainInfo(b, tctx, domain_handle,
4235 DomainPasswordInformation, &s_info),
4236 "failed to set password information");
4238 s_info.info12 = info12;
4240 torture_assert(tctx,
4241 test_SetDomainInfo(b, tctx, domain_handle,
4242 DomainLockoutInformation, &s_info),
4243 "failed to set lockout information");
4248 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
4249 struct dcerpc_pipe *lp,
4250 struct torture_context *tctx,
4251 struct policy_handle *domain_handle,
4252 struct policy_handle *lsa_handle,
4253 struct policy_handle *user_handle,
4254 const struct dom_sid *domain_sid,
4256 struct cli_credentials *machine_credentials)
4259 struct dcerpc_binding_handle *b = p->binding_handle;
4260 struct dcerpc_binding_handle *lb = lp->binding_handle;
4262 struct policy_handle lsa_acct_handle;
4263 struct dom_sid *user_sid;
4265 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
4268 struct lsa_EnumAccountRights r;
4269 struct lsa_RightSet rights;
4271 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4273 r.in.handle = lsa_handle;
4274 r.in.sid = user_sid;
4275 r.out.rights = &rights;
4277 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4278 "lsa_EnumAccountRights failed");
4279 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4280 "Expected enum rights for account to fail");
4284 struct lsa_RightSet rights;
4285 struct lsa_StringLarge names[2];
4286 struct lsa_AddAccountRights r;
4288 torture_comment(tctx, "Testing LSA AddAccountRights\n");
4290 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
4291 init_lsa_StringLarge(&names[1], NULL);
4294 rights.names = names;
4296 r.in.handle = lsa_handle;
4297 r.in.sid = user_sid;
4298 r.in.rights = &rights;
4300 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
4301 "lsa_AddAccountRights failed");
4302 torture_assert_ntstatus_ok(tctx, r.out.result,
4303 "Failed to add privileges");
4307 struct lsa_EnumAccounts r;
4308 uint32_t resume_handle = 0;
4309 struct lsa_SidArray lsa_sid_array;
4311 bool found_sid = false;
4313 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4315 r.in.handle = lsa_handle;
4316 r.in.num_entries = 0x1000;
4317 r.in.resume_handle = &resume_handle;
4318 r.out.sids = &lsa_sid_array;
4319 r.out.resume_handle = &resume_handle;
4321 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4322 "lsa_EnumAccounts failed");
4323 torture_assert_ntstatus_ok(tctx, r.out.result,
4324 "Failed to enum accounts");
4326 for (i=0; i < lsa_sid_array.num_sids; i++) {
4327 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4332 torture_assert(tctx, found_sid,
4333 "failed to list privileged account");
4337 struct lsa_EnumAccountRights r;
4338 struct lsa_RightSet user_rights;
4340 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4342 r.in.handle = lsa_handle;
4343 r.in.sid = user_sid;
4344 r.out.rights = &user_rights;
4346 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4347 "lsa_EnumAccountRights failed");
4348 torture_assert_ntstatus_ok(tctx, r.out.result,
4349 "Failed to enum rights for account");
4351 if (user_rights.count < 1) {
4352 torture_warning(tctx, "failed to find newly added rights");
4358 struct lsa_OpenAccount r;
4360 torture_comment(tctx, "Testing LSA OpenAccount\n");
4362 r.in.handle = lsa_handle;
4363 r.in.sid = user_sid;
4364 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4365 r.out.acct_handle = &lsa_acct_handle;
4367 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4368 "lsa_OpenAccount failed");
4369 torture_assert_ntstatus_ok(tctx, r.out.result,
4370 "Failed to open lsa account");
4374 struct lsa_GetSystemAccessAccount r;
4375 uint32_t access_mask;
4377 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4379 r.in.handle = &lsa_acct_handle;
4380 r.out.access_mask = &access_mask;
4382 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4383 "lsa_GetSystemAccessAccount failed");
4384 torture_assert_ntstatus_ok(tctx, r.out.result,
4385 "Failed to get lsa system access account");
4391 torture_comment(tctx, "Testing LSA Close\n");
4393 r.in.handle = &lsa_acct_handle;
4394 r.out.handle = &lsa_acct_handle;
4396 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(lb, tctx, &r),
4397 "lsa_Close failed");
4398 torture_assert_ntstatus_ok(tctx, r.out.result,
4399 "Failed to close lsa");
4403 struct samr_DeleteUser r;
4405 torture_comment(tctx, "Testing SAMR DeleteUser\n");
4407 r.in.user_handle = user_handle;
4408 r.out.user_handle = user_handle;
4410 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &r),
4411 "DeleteUser failed");
4412 torture_assert_ntstatus_ok(tctx, r.out.result,
4413 "DeleteUser failed");
4417 struct lsa_EnumAccounts r;
4418 uint32_t resume_handle = 0;
4419 struct lsa_SidArray lsa_sid_array;
4421 bool found_sid = false;
4423 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4425 r.in.handle = lsa_handle;
4426 r.in.num_entries = 0x1000;
4427 r.in.resume_handle = &resume_handle;
4428 r.out.sids = &lsa_sid_array;
4429 r.out.resume_handle = &resume_handle;
4431 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4432 "lsa_EnumAccounts failed");
4433 torture_assert_ntstatus_ok(tctx, r.out.result,
4434 "Failed to enum accounts");
4436 for (i=0; i < lsa_sid_array.num_sids; i++) {
4437 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4442 torture_assert(tctx, found_sid,
4443 "failed to list privileged account");
4447 struct lsa_EnumAccountRights r;
4448 struct lsa_RightSet user_rights;
4450 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4452 r.in.handle = lsa_handle;
4453 r.in.sid = user_sid;
4454 r.out.rights = &user_rights;
4456 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4457 "lsa_EnumAccountRights failed");
4458 torture_assert_ntstatus_ok(tctx, r.out.result,
4459 "Failed to enum rights for account");
4461 if (user_rights.count < 1) {
4462 torture_warning(tctx, "failed to find newly added rights");
4468 struct lsa_OpenAccount r;
4470 torture_comment(tctx, "Testing LSA OpenAccount\n");
4472 r.in.handle = lsa_handle;
4473 r.in.sid = user_sid;
4474 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4475 r.out.acct_handle = &lsa_acct_handle;
4477 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4478 "lsa_OpenAccount failed");
4479 torture_assert_ntstatus_ok(tctx, r.out.result,
4480 "Failed to open lsa account");
4484 struct lsa_GetSystemAccessAccount r;
4485 uint32_t access_mask;
4487 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4489 r.in.handle = &lsa_acct_handle;
4490 r.out.access_mask = &access_mask;
4492 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4493 "lsa_GetSystemAccessAccount failed");
4494 torture_assert_ntstatus_ok(tctx, r.out.result,
4495 "Failed to get lsa system access account");
4499 struct lsa_DeleteObject r;
4501 torture_comment(tctx, "Testing LSA DeleteObject\n");
4503 r.in.handle = &lsa_acct_handle;
4504 r.out.handle = &lsa_acct_handle;
4506 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(lb, tctx, &r),
4507 "lsa_DeleteObject failed");
4508 torture_assert_ntstatus_ok(tctx, r.out.result,
4509 "Failed to delete object");
4513 struct lsa_EnumAccounts r;
4514 uint32_t resume_handle = 0;
4515 struct lsa_SidArray lsa_sid_array;
4517 bool found_sid = false;
4519 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4521 r.in.handle = lsa_handle;
4522 r.in.num_entries = 0x1000;
4523 r.in.resume_handle = &resume_handle;
4524 r.out.sids = &lsa_sid_array;
4525 r.out.resume_handle = &resume_handle;
4527 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4528 "lsa_EnumAccounts failed");
4529 torture_assert_ntstatus_ok(tctx, r.out.result,
4530 "Failed to enum accounts");
4532 for (i=0; i < lsa_sid_array.num_sids; i++) {
4533 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4538 torture_assert(tctx, !found_sid,
4539 "should not have listed privileged account");
4543 struct lsa_EnumAccountRights r;
4544 struct lsa_RightSet user_rights;
4546 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4548 r.in.handle = lsa_handle;
4549 r.in.sid = user_sid;
4550 r.out.rights = &user_rights;
4552 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4553 "lsa_EnumAccountRights failed");
4554 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4555 "Failed to enum rights for account");
4561 static bool test_user_ops(struct dcerpc_pipe *p,
4562 struct torture_context *tctx,
4563 struct policy_handle *user_handle,
4564 struct policy_handle *domain_handle,
4565 const struct dom_sid *domain_sid,
4566 uint32_t base_acct_flags,
4567 const char *base_acct_name, enum torture_samr_choice which_ops,
4568 struct cli_credentials *machine_credentials)
4570 char *password = NULL;
4571 struct samr_QueryUserInfo q;
4572 union samr_UserInfo *info;
4574 struct dcerpc_binding_handle *b = p->binding_handle;
4579 const uint32_t password_fields[] = {
4580 SAMR_FIELD_NT_PASSWORD_PRESENT,
4581 SAMR_FIELD_LM_PASSWORD_PRESENT,
4582 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
4586 status = test_LookupName(b, tctx, domain_handle, base_acct_name, &rid);
4587 if (!NT_STATUS_IS_OK(status)) {
4591 switch (which_ops) {
4592 case TORTURE_SAMR_USER_ATTRIBUTES:
4593 if (!test_QuerySecurity(b, tctx, user_handle)) {
4597 if (!test_QueryUserInfo(b, tctx, user_handle)) {
4601 if (!test_QueryUserInfo2(b, tctx, user_handle)) {
4605 if (!test_SetUserInfo(b, tctx, user_handle, base_acct_flags,
4610 if (!test_GetUserPwInfo(b, tctx, user_handle)) {
4614 if (!test_TestPrivateFunctionsUser(b, tctx, user_handle)) {
4618 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
4622 case TORTURE_SAMR_PASSWORDS:
4623 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
4624 char simple_pass[9];
4625 char *v = generate_random_str(tctx, 1);
4627 ZERO_STRUCT(simple_pass);
4628 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4630 torture_comment(tctx, "Testing machine account password policy rules\n");
4632 /* Workstation trust accounts don't seem to need to honour password quality policy */
4633 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4637 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
4641 /* reset again, to allow another 'user' password change */
4642 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4646 /* Try a 'short' password */
4647 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
4651 /* Try a compleatly random password */
4652 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
4657 for (i = 0; password_fields[i]; i++) {
4658 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
4662 /* check it was set right */
4663 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4668 for (i = 0; password_fields[i]; i++) {
4669 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
4673 /* check it was set right */
4674 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4679 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
4683 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
4687 if (torture_setting_bool(tctx, "samba4", false)) {
4688 torture_comment(tctx, "skipping Set Password level 18 and 21 against Samba4\n");
4691 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
4695 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4699 for (i = 0; password_fields[i]; i++) {
4701 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
4702 /* we need to skip as that would break
4703 * the ChangePasswordUser3 verify */
4707 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
4711 /* check it was set right */
4712 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4718 q.in.user_handle = user_handle;
4722 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
4723 "QueryUserInfo failed");
4724 if (!NT_STATUS_IS_OK(q.out.result)) {
4725 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4726 q.in.level, nt_errstr(q.out.result));
4729 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4730 if ((info->info5.acct_flags) != expected_flags) {
4731 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4732 info->info5.acct_flags,
4735 if (!torture_setting_bool(tctx, "samba3", false)) {
4739 if (info->info5.rid != rid) {
4740 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
4741 info->info5.rid, rid);
4748 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
4750 /* test last password change timestamp behaviour */
4751 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
4753 user_handle, &password,
4754 machine_credentials)) {
4759 torture_comment(tctx, "pwdLastSet test succeeded\n");
4761 torture_warning(tctx, "pwdLastSet test failed\n");
4766 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
4768 /* test bad pwd count change behaviour */
4769 if (!test_Password_badpwdcount_wrap(p, tctx, base_acct_flags,
4772 user_handle, &password,
4773 machine_credentials)) {
4778 torture_comment(tctx, "badPwdCount test succeeded\n");
4780 torture_warning(tctx, "badPwdCount test failed\n");
4785 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
4787 if (!test_Password_lockout_wrap(p, tctx, base_acct_flags,
4790 user_handle, &password,
4791 machine_credentials))
4797 torture_comment(tctx, "lockout test succeeded\n");
4799 torture_warning(tctx, "lockout test failed\n");
4805 case TORTURE_SAMR_USER_PRIVILEGES: {
4807 struct dcerpc_pipe *lp;
4808 struct policy_handle *lsa_handle;
4809 struct dcerpc_binding_handle *lb;
4811 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
4812 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
4813 lb = lp->binding_handle;
4815 if (!test_lsa_OpenPolicy2(lb, tctx, &lsa_handle)) {
4819 if (!test_DeleteUser_with_privs(p, lp, tctx,
4820 domain_handle, lsa_handle, user_handle,
4822 machine_credentials)) {
4826 if (!test_lsa_Close(lb, tctx, lsa_handle)) {
4831 torture_warning(tctx, "privileged user delete test failed\n");
4836 case TORTURE_SAMR_OTHER:
4837 case TORTURE_SAMR_MANY_ACCOUNTS:
4838 case TORTURE_SAMR_MANY_GROUPS:
4839 case TORTURE_SAMR_MANY_ALIASES:
4840 /* We just need the account to exist */
4846 static bool test_alias_ops(struct dcerpc_binding_handle *b,
4847 struct torture_context *tctx,
4848 struct policy_handle *alias_handle,
4849 const struct dom_sid *domain_sid)
4853 if (!torture_setting_bool(tctx, "samba3", false)) {
4854 if (!test_QuerySecurity(b, tctx, alias_handle)) {
4859 if (!test_QueryAliasInfo(b, tctx, alias_handle)) {
4863 if (!test_SetAliasInfo(b, tctx, alias_handle)) {
4867 if (!test_AddMemberToAlias(b, tctx, alias_handle, domain_sid)) {
4871 if (torture_setting_bool(tctx, "samba3", false) ||
4872 torture_setting_bool(tctx, "samba4", false)) {
4873 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
4877 if (!test_AddMultipleMembersToAlias(b, tctx, alias_handle)) {
4885 static bool test_DeleteUser(struct dcerpc_binding_handle *b,
4886 struct torture_context *tctx,
4887 struct policy_handle *user_handle)
4889 struct samr_DeleteUser d;
4890 torture_comment(tctx, "Testing DeleteUser\n");
4892 d.in.user_handle = user_handle;
4893 d.out.user_handle = user_handle;
4895 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
4896 "DeleteUser failed");
4897 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteUser");
4902 bool test_DeleteUser_byname(struct dcerpc_binding_handle *b,
4903 struct torture_context *tctx,
4904 struct policy_handle *handle, const char *name)
4907 struct samr_DeleteUser d;
4908 struct policy_handle user_handle;
4911 status = test_LookupName(b, tctx, handle, name, &rid);
4912 if (!NT_STATUS_IS_OK(status)) {
4916 status = test_OpenUser_byname(b, tctx, handle, name, &user_handle);
4917 if (!NT_STATUS_IS_OK(status)) {
4921 d.in.user_handle = &user_handle;
4922 d.out.user_handle = &user_handle;
4923 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
4924 "DeleteUser failed");
4925 if (!NT_STATUS_IS_OK(d.out.result)) {
4926 status = d.out.result;
4933 torture_warning(tctx, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
4938 static bool test_DeleteGroup_byname(struct dcerpc_binding_handle *b,
4939 struct torture_context *tctx,
4940 struct policy_handle *handle, const char *name)
4943 struct samr_OpenGroup r;
4944 struct samr_DeleteDomainGroup d;
4945 struct policy_handle group_handle;
4948 status = test_LookupName(b, tctx, handle, name, &rid);
4949 if (!NT_STATUS_IS_OK(status)) {
4953 r.in.domain_handle = handle;
4954 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4956 r.out.group_handle = &group_handle;
4957 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
4958 "OpenGroup failed");
4959 if (!NT_STATUS_IS_OK(r.out.result)) {
4960 status = r.out.result;
4964 d.in.group_handle = &group_handle;
4965 d.out.group_handle = &group_handle;
4966 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
4967 "DeleteDomainGroup failed");
4968 if (!NT_STATUS_IS_OK(d.out.result)) {
4969 status = d.out.result;
4976 torture_warning(tctx, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
4981 static bool test_DeleteAlias_byname(struct dcerpc_binding_handle *b,
4982 struct torture_context *tctx,
4983 struct policy_handle *domain_handle,
4987 struct samr_OpenAlias r;
4988 struct samr_DeleteDomAlias d;
4989 struct policy_handle alias_handle;
4992 torture_comment(tctx, "Testing DeleteAlias_byname\n");
4994 status = test_LookupName(b, tctx, domain_handle, name, &rid);
4995 if (!NT_STATUS_IS_OK(status)) {
4999 r.in.domain_handle = domain_handle;
5000 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5002 r.out.alias_handle = &alias_handle;
5003 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5004 "OpenAlias failed");
5005 if (!NT_STATUS_IS_OK(r.out.result)) {
5006 status = r.out.result;
5010 d.in.alias_handle = &alias_handle;
5011 d.out.alias_handle = &alias_handle;
5012 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5013 "DeleteDomAlias failed");
5014 if (!NT_STATUS_IS_OK(d.out.result)) {
5015 status = d.out.result;
5022 torture_warning(tctx, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
5026 static bool test_DeleteAlias(struct dcerpc_binding_handle *b,
5027 struct torture_context *tctx,
5028 struct policy_handle *alias_handle)
5030 struct samr_DeleteDomAlias d;
5033 torture_comment(tctx, "Testing DeleteAlias\n");
5035 d.in.alias_handle = alias_handle;
5036 d.out.alias_handle = alias_handle;
5038 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5039 "DeleteDomAlias failed");
5040 if (!NT_STATUS_IS_OK(d.out.result)) {
5041 torture_warning(tctx, "DeleteAlias failed - %s\n", nt_errstr(d.out.result));
5048 static bool test_CreateAlias(struct dcerpc_binding_handle *b,
5049 struct torture_context *tctx,
5050 struct policy_handle *domain_handle,
5051 const char *alias_name,
5052 struct policy_handle *alias_handle,
5053 const struct dom_sid *domain_sid,
5056 struct samr_CreateDomAlias r;
5057 struct lsa_String name;
5061 init_lsa_String(&name, alias_name);
5062 r.in.domain_handle = domain_handle;
5063 r.in.alias_name = &name;
5064 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5065 r.out.alias_handle = alias_handle;
5068 torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
5070 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5071 "CreateDomAlias failed");
5073 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5074 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
5075 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
5078 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
5079 nt_errstr(r.out.result));
5084 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ALIAS_EXISTS)) {
5085 if (!test_DeleteAlias_byname(b, tctx, domain_handle, r.in.alias_name->string)) {
5088 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5089 "CreateDomAlias failed");
5092 if (!NT_STATUS_IS_OK(r.out.result)) {
5093 torture_warning(tctx, "CreateAlias failed - %s\n", nt_errstr(r.out.result));
5101 if (!test_alias_ops(b, tctx, alias_handle, domain_sid)) {
5108 static bool test_ChangePassword(struct dcerpc_pipe *p,
5109 struct torture_context *tctx,
5110 const char *acct_name,
5111 struct policy_handle *domain_handle, char **password)
5114 struct dcerpc_binding_handle *b = p->binding_handle;
5120 if (!test_ChangePasswordUser(b, tctx, acct_name, domain_handle, password)) {
5124 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
5128 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
5132 /* test what happens when setting the old password again */
5133 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
5138 char simple_pass[9];
5139 char *v = generate_random_str(tctx, 1);
5141 ZERO_STRUCT(simple_pass);
5142 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5144 /* test what happens when picking a simple password */
5145 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
5150 /* set samr_SetDomainInfo level 1 with min_length 5 */
5152 struct samr_QueryDomainInfo r;
5153 union samr_DomainInfo *info = NULL;
5154 struct samr_SetDomainInfo s;
5155 uint16_t len_old, len;
5156 uint32_t pwd_prop_old;
5157 int64_t min_pwd_age_old;
5161 r.in.domain_handle = domain_handle;
5165 torture_comment(tctx, "Testing samr_QueryDomainInfo level 1\n");
5166 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
5167 "QueryDomainInfo failed");
5168 if (!NT_STATUS_IS_OK(r.out.result)) {
5172 s.in.domain_handle = domain_handle;
5176 /* remember the old min length, so we can reset it */
5177 len_old = s.in.info->info1.min_password_length;
5178 s.in.info->info1.min_password_length = len;
5179 pwd_prop_old = s.in.info->info1.password_properties;
5180 /* turn off password complexity checks for this test */
5181 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
5183 min_pwd_age_old = s.in.info->info1.min_password_age;
5184 s.in.info->info1.min_password_age = 0;
5186 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5187 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5188 "SetDomainInfo failed");
5189 if (!NT_STATUS_IS_OK(s.out.result)) {
5193 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
5195 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
5199 s.in.info->info1.min_password_length = len_old;
5200 s.in.info->info1.password_properties = pwd_prop_old;
5201 s.in.info->info1.min_password_age = min_pwd_age_old;
5203 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5204 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5205 "SetDomainInfo failed");
5206 if (!NT_STATUS_IS_OK(s.out.result)) {
5213 struct samr_OpenUser r;
5214 struct samr_QueryUserInfo q;
5215 union samr_UserInfo *info;
5216 struct samr_LookupNames n;
5217 struct policy_handle user_handle;
5218 struct samr_Ids rids, types;
5220 n.in.domain_handle = domain_handle;
5222 n.in.names = talloc_array(tctx, struct lsa_String, 1);
5223 n.in.names[0].string = acct_name;
5225 n.out.types = &types;
5227 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
5228 "LookupNames failed");
5229 if (!NT_STATUS_IS_OK(n.out.result)) {
5230 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(n.out.result));
5234 r.in.domain_handle = domain_handle;
5235 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5236 r.in.rid = n.out.rids->ids[0];
5237 r.out.user_handle = &user_handle;
5239 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5241 if (!NT_STATUS_IS_OK(r.out.result)) {
5242 torture_warning(tctx, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(r.out.result));
5246 q.in.user_handle = &user_handle;
5250 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5251 "QueryUserInfo failed");
5252 if (!NT_STATUS_IS_OK(q.out.result)) {
5253 torture_warning(tctx, "QueryUserInfo failed - %s\n", nt_errstr(q.out.result));
5257 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
5259 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
5260 info->info5.last_password_change, true)) {
5265 /* we change passwords twice - this has the effect of verifying
5266 they were changed correctly for the final call */
5267 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5271 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5278 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
5279 struct policy_handle *domain_handle,
5280 const char *user_name,
5281 struct policy_handle *user_handle_out,
5282 struct dom_sid *domain_sid,
5283 enum torture_samr_choice which_ops,
5284 struct cli_credentials *machine_credentials,
5288 TALLOC_CTX *user_ctx;
5290 struct samr_CreateUser r;
5291 struct samr_QueryUserInfo q;
5292 union samr_UserInfo *info;
5293 struct samr_DeleteUser d;
5296 /* This call creates a 'normal' account - check that it really does */
5297 const uint32_t acct_flags = ACB_NORMAL;
5298 struct lsa_String name;
5300 struct dcerpc_binding_handle *b = p->binding_handle;
5302 struct policy_handle user_handle;
5303 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5304 init_lsa_String(&name, user_name);
5306 r.in.domain_handle = domain_handle;
5307 r.in.account_name = &name;
5308 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5309 r.out.user_handle = &user_handle;
5312 torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
5314 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5315 "CreateUser failed");
5317 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5318 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5319 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5322 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5323 nt_errstr(r.out.result));
5328 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5329 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5330 talloc_free(user_ctx);
5333 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5334 "CreateUser failed");
5337 if (!NT_STATUS_IS_OK(r.out.result)) {
5338 talloc_free(user_ctx);
5339 torture_warning(tctx, "CreateUser failed - %s\n", nt_errstr(r.out.result));
5344 if (user_handle_out) {
5345 *user_handle_out = user_handle;
5351 q.in.user_handle = &user_handle;
5355 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5356 "QueryUserInfo failed");
5357 if (!NT_STATUS_IS_OK(q.out.result)) {
5358 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5359 q.in.level, nt_errstr(q.out.result));
5362 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
5363 torture_warning(tctx, "QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5364 info->info16.acct_flags,
5370 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5371 domain_sid, acct_flags, name.string, which_ops,
5372 machine_credentials)) {
5376 if (user_handle_out) {
5377 *user_handle_out = user_handle;
5379 torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
5381 d.in.user_handle = &user_handle;
5382 d.out.user_handle = &user_handle;
5384 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5385 "DeleteUser failed");
5386 if (!NT_STATUS_IS_OK(d.out.result)) {
5387 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5394 talloc_free(user_ctx);
5400 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
5401 struct policy_handle *domain_handle,
5402 struct dom_sid *domain_sid,
5403 enum torture_samr_choice which_ops,
5404 struct cli_credentials *machine_credentials)
5406 struct samr_CreateUser2 r;
5407 struct samr_QueryUserInfo q;
5408 union samr_UserInfo *info;
5409 struct samr_DeleteUser d;
5410 struct policy_handle user_handle;
5412 struct lsa_String name;
5415 struct dcerpc_binding_handle *b = p->binding_handle;
5418 uint32_t acct_flags;
5419 const char *account_name;
5421 } account_types[] = {
5422 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
5423 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5424 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5425 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5426 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5427 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5428 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5429 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5430 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5431 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
5432 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5433 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5434 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5435 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5436 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
5439 for (i = 0; account_types[i].account_name; i++) {
5440 TALLOC_CTX *user_ctx;
5441 uint32_t acct_flags = account_types[i].acct_flags;
5442 uint32_t access_granted;
5443 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5444 init_lsa_String(&name, account_types[i].account_name);
5446 r.in.domain_handle = domain_handle;
5447 r.in.account_name = &name;
5448 r.in.acct_flags = acct_flags;
5449 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5450 r.out.user_handle = &user_handle;
5451 r.out.access_granted = &access_granted;
5454 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
5456 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5457 "CreateUser2 failed");
5459 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5460 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5461 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5464 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5465 nt_errstr(r.out.result));
5471 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5472 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5473 talloc_free(user_ctx);
5477 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5478 "CreateUser2 failed");
5481 if (!NT_STATUS_EQUAL(r.out.result, account_types[i].nt_status)) {
5482 torture_warning(tctx, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5483 nt_errstr(r.out.result), nt_errstr(account_types[i].nt_status));
5487 if (NT_STATUS_IS_OK(r.out.result)) {
5488 q.in.user_handle = &user_handle;
5492 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5493 "QueryUserInfo failed");
5494 if (!NT_STATUS_IS_OK(q.out.result)) {
5495 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5496 q.in.level, nt_errstr(q.out.result));
5499 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
5500 if (acct_flags == ACB_NORMAL) {
5501 expected_flags |= ACB_PW_EXPIRED;
5503 if ((info->info5.acct_flags) != expected_flags) {
5504 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5505 info->info5.acct_flags,
5509 switch (acct_flags) {
5511 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
5512 torture_warning(tctx, "QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5513 DOMAIN_RID_DCS, info->info5.primary_gid);
5518 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
5519 torture_warning(tctx, "QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5520 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
5525 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
5526 torture_warning(tctx, "QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5527 DOMAIN_RID_USERS, info->info5.primary_gid);
5534 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5535 domain_sid, acct_flags, name.string, which_ops,
5536 machine_credentials)) {
5540 if (!policy_handle_empty(&user_handle)) {
5541 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
5543 d.in.user_handle = &user_handle;
5544 d.out.user_handle = &user_handle;
5546 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5547 "DeleteUser failed");
5548 if (!NT_STATUS_IS_OK(d.out.result)) {
5549 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5554 talloc_free(user_ctx);
5560 static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
5561 struct torture_context *tctx,
5562 struct policy_handle *handle)
5564 struct samr_QueryAliasInfo r;
5565 union samr_AliasInfo *info;
5566 uint16_t levels[] = {1, 2, 3};
5570 for (i=0;i<ARRAY_SIZE(levels);i++) {
5571 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
5573 r.in.alias_handle = handle;
5574 r.in.level = levels[i];
5577 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &r),
5578 "QueryAliasInfo failed");
5579 if (!NT_STATUS_IS_OK(r.out.result)) {
5580 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
5581 levels[i], nt_errstr(r.out.result));
5589 static bool test_QueryGroupInfo(struct dcerpc_binding_handle *b,
5590 struct torture_context *tctx,
5591 struct policy_handle *handle)
5593 struct samr_QueryGroupInfo r;
5594 union samr_GroupInfo *info;
5595 uint16_t levels[] = {1, 2, 3, 4, 5};
5599 for (i=0;i<ARRAY_SIZE(levels);i++) {
5600 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5602 r.in.group_handle = handle;
5603 r.in.level = levels[i];
5606 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
5607 "QueryGroupInfo failed");
5608 if (!NT_STATUS_IS_OK(r.out.result)) {
5609 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5610 levels[i], nt_errstr(r.out.result));
5618 static bool test_QueryGroupMember(struct dcerpc_binding_handle *b,
5619 struct torture_context *tctx,
5620 struct policy_handle *handle)
5622 struct samr_QueryGroupMember r;
5623 struct samr_RidTypeArray *rids = NULL;
5626 torture_comment(tctx, "Testing QueryGroupMember\n");
5628 r.in.group_handle = handle;
5631 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &r),
5632 "QueryGroupMember failed");
5633 if (!NT_STATUS_IS_OK(r.out.result)) {
5634 torture_warning(tctx, "QueryGroupInfo failed - %s\n", nt_errstr(r.out.result));
5642 static bool test_SetGroupInfo(struct dcerpc_binding_handle *b,
5643 struct torture_context *tctx,
5644 struct policy_handle *handle)
5646 struct samr_QueryGroupInfo r;
5647 union samr_GroupInfo *info;
5648 struct samr_SetGroupInfo s;
5649 uint16_t levels[] = {1, 2, 3, 4};
5650 uint16_t set_ok[] = {0, 1, 1, 1};
5654 for (i=0;i<ARRAY_SIZE(levels);i++) {
5655 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5657 r.in.group_handle = handle;
5658 r.in.level = levels[i];
5661 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
5662 "QueryGroupInfo failed");
5663 if (!NT_STATUS_IS_OK(r.out.result)) {
5664 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5665 levels[i], nt_errstr(r.out.result));
5669 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
5671 s.in.group_handle = handle;
5672 s.in.level = levels[i];
5673 s.in.info = *r.out.info;
5676 /* disabled this, as it changes the name only from the point of view of samr,
5677 but leaves the name from the point of view of w2k3 internals (and ldap). This means
5678 the name is still reserved, so creating the old name fails, but deleting by the old name
5680 if (s.in.level == 2) {
5681 init_lsa_String(&s.in.info->string, "NewName");
5685 if (s.in.level == 4) {
5686 init_lsa_String(&s.in.info->description, "test description");
5689 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetGroupInfo_r(b, tctx, &s),
5690 "SetGroupInfo failed");
5692 if (!NT_STATUS_IS_OK(s.out.result)) {
5693 torture_warning(tctx, "SetGroupInfo level %u failed - %s\n",
5694 r.in.level, nt_errstr(s.out.result));
5699 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
5700 torture_warning(tctx, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5701 r.in.level, nt_errstr(s.out.result));
5711 static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
5712 struct torture_context *tctx,
5713 struct policy_handle *handle)
5715 struct samr_QueryUserInfo r;
5716 union samr_UserInfo *info;
5717 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5718 11, 12, 13, 14, 16, 17, 20, 21};
5722 for (i=0;i<ARRAY_SIZE(levels);i++) {
5723 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
5725 r.in.user_handle = handle;
5726 r.in.level = levels[i];
5729 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
5730 "QueryUserInfo failed");
5731 if (!NT_STATUS_IS_OK(r.out.result)) {
5732 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5733 levels[i], nt_errstr(r.out.result));
5741 static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
5742 struct torture_context *tctx,
5743 struct policy_handle *handle)
5745 struct samr_QueryUserInfo2 r;
5746 union samr_UserInfo *info;
5747 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5748 11, 12, 13, 14, 16, 17, 20, 21};
5752 for (i=0;i<ARRAY_SIZE(levels);i++) {
5753 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
5755 r.in.user_handle = handle;
5756 r.in.level = levels[i];
5759 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r),
5760 "QueryUserInfo2 failed");
5761 if (!NT_STATUS_IS_OK(r.out.result)) {
5762 torture_warning(tctx, "QueryUserInfo2 level %u failed - %s\n",
5763 levels[i], nt_errstr(r.out.result));
5771 static bool test_OpenUser(struct dcerpc_binding_handle *b,
5772 struct torture_context *tctx,
5773 struct policy_handle *handle, uint32_t rid)
5775 struct samr_OpenUser r;
5776 struct policy_handle user_handle;
5779 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5781 r.in.domain_handle = handle;
5782 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5784 r.out.user_handle = &user_handle;
5786 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5788 if (!NT_STATUS_IS_OK(r.out.result)) {
5789 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5793 if (!test_QuerySecurity(b, tctx, &user_handle)) {
5797 if (!test_QueryUserInfo(b, tctx, &user_handle)) {
5801 if (!test_QueryUserInfo2(b, tctx, &user_handle)) {
5805 if (!test_GetUserPwInfo(b, tctx, &user_handle)) {
5809 if (!test_GetGroupsForUser(b, tctx, &user_handle)) {
5813 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
5820 static bool test_OpenGroup(struct dcerpc_binding_handle *b,
5821 struct torture_context *tctx,
5822 struct policy_handle *handle, uint32_t rid)
5824 struct samr_OpenGroup r;
5825 struct policy_handle group_handle;
5828 torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
5830 r.in.domain_handle = handle;
5831 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5833 r.out.group_handle = &group_handle;
5835 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
5836 "OpenGroup failed");
5837 if (!NT_STATUS_IS_OK(r.out.result)) {
5838 torture_warning(tctx, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5842 if (!torture_setting_bool(tctx, "samba3", false)) {
5843 if (!test_QuerySecurity(b, tctx, &group_handle)) {
5848 if (!test_QueryGroupInfo(b, tctx, &group_handle)) {
5852 if (!test_QueryGroupMember(b, tctx, &group_handle)) {
5856 if (!test_samr_handle_Close(b, tctx, &group_handle)) {
5863 static bool test_OpenAlias(struct dcerpc_binding_handle *b,
5864 struct torture_context *tctx,
5865 struct policy_handle *handle, uint32_t rid)
5867 struct samr_OpenAlias r;
5868 struct policy_handle alias_handle;
5871 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
5873 r.in.domain_handle = handle;
5874 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5876 r.out.alias_handle = &alias_handle;
5878 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5879 "OpenAlias failed");
5880 if (!NT_STATUS_IS_OK(r.out.result)) {
5881 torture_warning(tctx, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5885 if (!torture_setting_bool(tctx, "samba3", false)) {
5886 if (!test_QuerySecurity(b, tctx, &alias_handle)) {
5891 if (!test_QueryAliasInfo(b, tctx, &alias_handle)) {
5895 if (!test_GetMembersInAlias(b, tctx, &alias_handle)) {
5899 if (!test_samr_handle_Close(b, tctx, &alias_handle)) {
5906 static bool check_mask(struct dcerpc_binding_handle *b,
5907 struct torture_context *tctx,
5908 struct policy_handle *handle, uint32_t rid,
5909 uint32_t acct_flag_mask)
5911 struct samr_OpenUser r;
5912 struct samr_QueryUserInfo q;
5913 union samr_UserInfo *info;
5914 struct policy_handle user_handle;
5917 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5919 r.in.domain_handle = handle;
5920 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5922 r.out.user_handle = &user_handle;
5924 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5926 if (!NT_STATUS_IS_OK(r.out.result)) {
5927 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5931 q.in.user_handle = &user_handle;
5935 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5936 "QueryUserInfo failed");
5937 if (!NT_STATUS_IS_OK(q.out.result)) {
5938 torture_warning(tctx, "QueryUserInfo level 16 failed - %s\n",
5939 nt_errstr(q.out.result));
5942 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
5943 torture_warning(tctx, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
5944 acct_flag_mask, info->info16.acct_flags, rid);
5949 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
5956 static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle *b,
5957 struct torture_context *tctx,
5958 struct policy_handle *handle)
5960 struct samr_EnumDomainUsers r;
5961 uint32_t mask, resume_handle=0;
5964 struct samr_LookupNames n;
5965 struct samr_LookupRids lr ;
5966 struct lsa_Strings names;
5967 struct samr_Ids rids, types;
5968 struct samr_SamArray *sam = NULL;
5969 uint32_t num_entries = 0;
5971 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
5972 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
5973 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
5976 torture_comment(tctx, "Testing EnumDomainUsers\n");
5978 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
5979 r.in.domain_handle = handle;
5980 r.in.resume_handle = &resume_handle;
5981 r.in.acct_flags = mask = masks[mask_idx];
5982 r.in.max_size = (uint32_t)-1;
5983 r.out.resume_handle = &resume_handle;
5984 r.out.num_entries = &num_entries;
5987 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
5988 "EnumDomainUsers failed");
5989 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
5990 !NT_STATUS_IS_OK(r.out.result)) {
5991 torture_warning(tctx, "EnumDomainUsers failed - %s\n", nt_errstr(r.out.result));
5995 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
5997 if (sam->count == 0) {
6001 for (i=0;i<sam->count;i++) {
6003 if (!check_mask(b, tctx, handle, sam->entries[i].idx, mask)) {
6006 } else if (!test_OpenUser(b, tctx, handle, sam->entries[i].idx)) {
6012 torture_comment(tctx, "Testing LookupNames\n");
6013 n.in.domain_handle = handle;
6014 n.in.num_names = sam->count;
6015 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
6017 n.out.types = &types;
6018 for (i=0;i<sam->count;i++) {
6019 n.in.names[i].string = sam->entries[i].name.string;
6021 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
6022 "LookupNames failed");
6023 if (!NT_STATUS_IS_OK(n.out.result)) {
6024 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(n.out.result));
6029 torture_comment(tctx, "Testing LookupRids\n");
6030 lr.in.domain_handle = handle;
6031 lr.in.num_rids = sam->count;
6032 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
6033 lr.out.names = &names;
6034 lr.out.types = &types;
6035 for (i=0;i<sam->count;i++) {
6036 lr.in.rids[i] = sam->entries[i].idx;
6038 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupRids_r(b, tctx, &lr),
6039 "LookupRids failed");
6040 torture_assert_ntstatus_ok(tctx, lr.out.result, "LookupRids");
6046 try blasting the server with a bunch of sync requests
6048 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
6049 struct policy_handle *handle)
6051 struct samr_EnumDomainUsers r;
6052 uint32_t resume_handle=0;
6054 #define ASYNC_COUNT 100
6055 struct tevent_req *req[ASYNC_COUNT];
6057 if (!torture_setting_bool(tctx, "dangerous", false)) {
6058 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
6061 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
6063 r.in.domain_handle = handle;
6064 r.in.resume_handle = &resume_handle;
6065 r.in.acct_flags = 0;
6066 r.in.max_size = (uint32_t)-1;
6067 r.out.resume_handle = &resume_handle;
6069 for (i=0;i<ASYNC_COUNT;i++) {
6070 req[i] = dcerpc_samr_EnumDomainUsers_r_send(tctx, tctx->ev, p->binding_handle, &r);
6073 for (i=0;i<ASYNC_COUNT;i++) {
6074 tevent_req_poll(req[i], tctx->ev);
6075 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r_recv(req[i], tctx),
6076 talloc_asprintf(tctx, "EnumDomainUsers[%d] failed - %s\n",
6077 i, nt_errstr(r.out.result)));
6080 torture_comment(tctx, "%d async requests OK\n", i);
6085 static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle *b,
6086 struct torture_context *tctx,
6087 struct policy_handle *handle)
6089 struct samr_EnumDomainGroups r;
6090 uint32_t resume_handle=0;
6091 struct samr_SamArray *sam = NULL;
6092 uint32_t num_entries = 0;
6095 bool universal_group_found = false;
6097 torture_comment(tctx, "Testing EnumDomainGroups\n");
6099 r.in.domain_handle = handle;
6100 r.in.resume_handle = &resume_handle;
6101 r.in.max_size = (uint32_t)-1;
6102 r.out.resume_handle = &resume_handle;
6103 r.out.num_entries = &num_entries;
6106 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
6107 "EnumDomainGroups failed");
6108 if (!NT_STATUS_IS_OK(r.out.result)) {
6109 torture_warning(tctx, "EnumDomainGroups failed - %s\n", nt_errstr(r.out.result));
6117 for (i=0;i<sam->count;i++) {
6118 if (!test_OpenGroup(b, tctx, handle, sam->entries[i].idx)) {
6121 if ((ret == true) && (strcasecmp(sam->entries[i].name.string,
6122 "Enterprise Admins") == 0)) {
6123 universal_group_found = true;
6127 /* when we are running this on s4 we should get back at least the
6128 * "Enterprise Admins" universal group. If we don't get a group entry
6129 * at all we probably are performing the test on the builtin domain.
6130 * So ignore this case. */
6131 if (torture_setting_bool(tctx, "samba4", false)) {
6132 if ((sam->count > 0) && (!universal_group_found)) {
6140 static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle *b,
6141 struct torture_context *tctx,
6142 struct policy_handle *handle)
6144 struct samr_EnumDomainAliases r;
6145 uint32_t resume_handle=0;
6146 struct samr_SamArray *sam = NULL;
6147 uint32_t num_entries = 0;
6151 torture_comment(tctx, "Testing EnumDomainAliases\n");
6153 r.in.domain_handle = handle;
6154 r.in.resume_handle = &resume_handle;
6155 r.in.max_size = (uint32_t)-1;
6157 r.out.num_entries = &num_entries;
6158 r.out.resume_handle = &resume_handle;
6160 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
6161 "EnumDomainAliases failed");
6162 if (!NT_STATUS_IS_OK(r.out.result)) {
6163 torture_warning(tctx, "EnumDomainAliases failed - %s\n", nt_errstr(r.out.result));
6171 for (i=0;i<sam->count;i++) {
6172 if (!test_OpenAlias(b, tctx, handle, sam->entries[i].idx)) {
6180 static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle *b,
6181 struct torture_context *tctx,
6182 struct policy_handle *handle)
6184 struct samr_GetDisplayEnumerationIndex r;
6186 uint16_t levels[] = {1, 2, 3, 4, 5};
6187 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6188 struct lsa_String name;
6192 for (i=0;i<ARRAY_SIZE(levels);i++) {
6193 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
6195 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6197 r.in.domain_handle = handle;
6198 r.in.level = levels[i];
6202 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6203 "GetDisplayEnumerationIndex failed");
6206 !NT_STATUS_IS_OK(r.out.result) &&
6207 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6208 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6209 levels[i], nt_errstr(r.out.result));
6213 init_lsa_String(&name, "zzzzzzzz");
6215 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6216 "GetDisplayEnumerationIndex failed");
6218 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6219 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6220 levels[i], nt_errstr(r.out.result));
6228 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle *b,
6229 struct torture_context *tctx,
6230 struct policy_handle *handle)
6232 struct samr_GetDisplayEnumerationIndex2 r;
6234 uint16_t levels[] = {1, 2, 3, 4, 5};
6235 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6236 struct lsa_String name;
6240 for (i=0;i<ARRAY_SIZE(levels);i++) {
6241 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
6243 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6245 r.in.domain_handle = handle;
6246 r.in.level = levels[i];
6250 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6251 "GetDisplayEnumerationIndex2 failed");
6253 !NT_STATUS_IS_OK(r.out.result) &&
6254 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6255 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6256 levels[i], nt_errstr(r.out.result));
6260 init_lsa_String(&name, "zzzzzzzz");
6262 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6263 "GetDisplayEnumerationIndex2 failed");
6264 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6265 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6266 levels[i], nt_errstr(r.out.result));
6274 #define STRING_EQUAL_QUERY(s1, s2, user) \
6275 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6276 /* odd, but valid */ \
6277 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6278 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
6279 #s1, user.string, s1.string, s2.string, __location__); \
6282 #define INT_EQUAL_QUERY(s1, s2, user) \
6284 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6285 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6289 static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle *b,
6290 struct torture_context *tctx,
6291 struct samr_QueryDisplayInfo *querydisplayinfo,
6292 bool *seen_testuser)
6294 struct samr_OpenUser r;
6295 struct samr_QueryUserInfo q;
6296 union samr_UserInfo *info;
6297 struct policy_handle user_handle;
6299 r.in.domain_handle = querydisplayinfo->in.domain_handle;
6300 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6301 for (i = 0; ; i++) {
6302 switch (querydisplayinfo->in.level) {
6304 if (i >= querydisplayinfo->out.info->info1.count) {
6307 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
6310 if (i >= querydisplayinfo->out.info->info2.count) {
6313 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
6319 /* Not interested in validating just the account name */
6323 r.out.user_handle = &user_handle;
6325 switch (querydisplayinfo->in.level) {
6328 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6330 if (!NT_STATUS_IS_OK(r.out.result)) {
6331 torture_warning(tctx, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6336 q.in.user_handle = &user_handle;
6339 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6340 "QueryUserInfo failed");
6341 if (!NT_STATUS_IS_OK(r.out.result)) {
6342 torture_warning(tctx, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6346 switch (querydisplayinfo->in.level) {
6348 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
6349 *seen_testuser = true;
6351 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
6352 info->info21.full_name, info->info21.account_name);
6353 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
6354 info->info21.account_name, info->info21.account_name);
6355 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
6356 info->info21.description, info->info21.account_name);
6357 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
6358 info->info21.rid, info->info21.account_name);
6359 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
6360 info->info21.acct_flags, info->info21.account_name);
6364 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
6365 info->info21.account_name, info->info21.account_name);
6366 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
6367 info->info21.description, info->info21.account_name);
6368 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
6369 info->info21.rid, info->info21.account_name);
6370 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
6371 info->info21.acct_flags, info->info21.account_name);
6373 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
6374 torture_warning(tctx, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6375 info->info21.account_name.string);
6378 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
6379 torture_warning(tctx, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6380 info->info21.account_name.string,
6381 querydisplayinfo->out.info->info2.entries[i].acct_flags,
6382 info->info21.acct_flags);
6389 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6396 static bool test_QueryDisplayInfo(struct dcerpc_binding_handle *b,
6397 struct torture_context *tctx,
6398 struct policy_handle *handle)
6400 struct samr_QueryDisplayInfo r;
6401 struct samr_QueryDomainInfo dom_info;
6402 union samr_DomainInfo *info = NULL;
6404 uint16_t levels[] = {1, 2, 3, 4, 5};
6406 bool seen_testuser = false;
6407 uint32_t total_size;
6408 uint32_t returned_size;
6409 union samr_DispInfo disp_info;
6412 for (i=0;i<ARRAY_SIZE(levels);i++) {
6413 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
6416 r.out.result = STATUS_MORE_ENTRIES;
6417 while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
6418 r.in.domain_handle = handle;
6419 r.in.level = levels[i];
6420 r.in.max_entries = 2;
6421 r.in.buf_size = (uint32_t)-1;
6422 r.out.total_size = &total_size;
6423 r.out.returned_size = &returned_size;
6424 r.out.info = &disp_info;
6426 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6427 "QueryDisplayInfo failed");
6428 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(r.out.result)) {
6429 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6430 levels[i], nt_errstr(r.out.result));
6433 switch (r.in.level) {
6435 if (!test_each_DisplayInfo_user(b, tctx, &r, &seen_testuser)) {
6438 r.in.start_idx += r.out.info->info1.count;
6441 if (!test_each_DisplayInfo_user(b, tctx, &r, NULL)) {
6444 r.in.start_idx += r.out.info->info2.count;
6447 r.in.start_idx += r.out.info->info3.count;
6450 r.in.start_idx += r.out.info->info4.count;
6453 r.in.start_idx += r.out.info->info5.count;
6457 dom_info.in.domain_handle = handle;
6458 dom_info.in.level = 2;
6459 dom_info.out.info = &info;
6461 /* Check number of users returned is correct */
6462 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &dom_info),
6463 "QueryDomainInfo failed");
6464 if (!NT_STATUS_IS_OK(dom_info.out.result)) {
6465 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6466 r.in.level, nt_errstr(dom_info.out.result));
6470 switch (r.in.level) {
6473 if (info->general.num_users < r.in.start_idx) {
6474 /* On AD deployments this numbers don't match
6475 * since QueryDisplayInfo returns universal and
6476 * global groups, QueryDomainInfo only global
6478 if (torture_setting_bool(tctx, "samba3", false)) {
6479 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6480 r.in.start_idx, info->general.num_groups,
6481 info->general.domain_name.string);
6485 if (!seen_testuser) {
6486 struct policy_handle user_handle;
6487 if (NT_STATUS_IS_OK(test_OpenUser_byname(b, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
6488 torture_warning(tctx, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
6489 info->general.domain_name.string);
6491 test_samr_handle_Close(b, tctx, &user_handle);
6497 if (info->general.num_groups != r.in.start_idx) {
6498 /* On AD deployments this numbers don't match
6499 * since QueryDisplayInfo returns universal and
6500 * global groups, QueryDomainInfo only global
6502 if (torture_setting_bool(tctx, "samba3", false)) {
6503 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6504 r.in.start_idx, info->general.num_groups,
6505 info->general.domain_name.string);
6518 static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle *b,
6519 struct torture_context *tctx,
6520 struct policy_handle *handle)
6522 struct samr_QueryDisplayInfo2 r;
6524 uint16_t levels[] = {1, 2, 3, 4, 5};
6526 uint32_t total_size;
6527 uint32_t returned_size;
6528 union samr_DispInfo info;
6530 for (i=0;i<ARRAY_SIZE(levels);i++) {
6531 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
6533 r.in.domain_handle = handle;
6534 r.in.level = levels[i];
6536 r.in.max_entries = 1000;
6537 r.in.buf_size = (uint32_t)-1;
6538 r.out.total_size = &total_size;
6539 r.out.returned_size = &returned_size;
6542 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo2_r(b, tctx, &r),
6543 "QueryDisplayInfo2 failed");
6544 if (!NT_STATUS_IS_OK(r.out.result)) {
6545 torture_warning(tctx, "QueryDisplayInfo2 level %u failed - %s\n",
6546 levels[i], nt_errstr(r.out.result));
6554 static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle *b,
6555 struct torture_context *tctx,
6556 struct policy_handle *handle)
6558 struct samr_QueryDisplayInfo3 r;
6560 uint16_t levels[] = {1, 2, 3, 4, 5};
6562 uint32_t total_size;
6563 uint32_t returned_size;
6564 union samr_DispInfo info;
6566 for (i=0;i<ARRAY_SIZE(levels);i++) {
6567 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
6569 r.in.domain_handle = handle;
6570 r.in.level = levels[i];
6572 r.in.max_entries = 1000;
6573 r.in.buf_size = (uint32_t)-1;
6574 r.out.total_size = &total_size;
6575 r.out.returned_size = &returned_size;
6578 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo3_r(b, tctx, &r),
6579 "QueryDisplayInfo3 failed");
6580 if (!NT_STATUS_IS_OK(r.out.result)) {
6581 torture_warning(tctx, "QueryDisplayInfo3 level %u failed - %s\n",
6582 levels[i], nt_errstr(r.out.result));
6591 static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle *b,
6592 struct torture_context *tctx,
6593 struct policy_handle *handle)
6595 struct samr_QueryDisplayInfo r;
6597 uint32_t total_size;
6598 uint32_t returned_size;
6599 union samr_DispInfo info;
6601 torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
6603 r.in.domain_handle = handle;
6606 r.in.max_entries = 1;
6607 r.in.buf_size = (uint32_t)-1;
6608 r.out.total_size = &total_size;
6609 r.out.returned_size = &returned_size;
6613 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6614 "QueryDisplayInfo failed");
6615 if (NT_STATUS_IS_OK(r.out.result) && *r.out.returned_size != 0) {
6616 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
6617 torture_warning(tctx, "expected idx %d but got %d\n",
6619 r.out.info->info1.entries[0].idx);
6623 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
6624 !NT_STATUS_IS_OK(r.out.result)) {
6625 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6626 r.in.level, nt_errstr(r.out.result));
6631 } while ((NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) ||
6632 NT_STATUS_IS_OK(r.out.result)) &&
6633 *r.out.returned_size != 0);
6638 static bool test_QueryDomainInfo(struct dcerpc_pipe *p,
6639 struct torture_context *tctx,
6640 struct policy_handle *handle)
6642 struct samr_QueryDomainInfo r;
6643 union samr_DomainInfo *info = NULL;
6644 struct samr_SetDomainInfo s;
6645 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6646 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
6649 struct dcerpc_binding_handle *b = p->binding_handle;
6650 const char *domain_comment = talloc_asprintf(tctx,
6651 "Tortured by Samba4 RPC-SAMR: %s",
6652 timestring(tctx, time(NULL)));
6654 s.in.domain_handle = handle;
6656 s.in.info = talloc(tctx, union samr_DomainInfo);
6658 s.in.info->oem.oem_information.string = domain_comment;
6659 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
6660 "SetDomainInfo failed");
6661 if (!NT_STATUS_IS_OK(s.out.result)) {
6662 torture_warning(tctx, "SetDomainInfo level %u (set comment) failed - %s\n",
6663 s.in.level, nt_errstr(s.out.result));
6667 for (i=0;i<ARRAY_SIZE(levels);i++) {
6668 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
6670 r.in.domain_handle = handle;
6671 r.in.level = levels[i];
6674 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
6675 "QueryDomainInfo failed");
6676 if (!NT_STATUS_IS_OK(r.out.result)) {
6677 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6678 r.in.level, nt_errstr(r.out.result));
6683 switch (levels[i]) {
6685 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
6686 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6687 levels[i], info->general.oem_information.string, domain_comment);
6688 if (!torture_setting_bool(tctx, "samba3", false)) {
6692 if (!info->general.primary.string) {
6693 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6696 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
6697 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
6698 torture_warning(tctx, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
6699 levels[i], info->general.primary.string, dcerpc_server_name(p));
6704 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
6705 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6706 levels[i], info->oem.oem_information.string, domain_comment);
6707 if (!torture_setting_bool(tctx, "samba3", false)) {
6713 if (!info->info6.primary.string) {
6714 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6720 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
6721 torture_warning(tctx, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
6722 levels[i], info->general2.general.oem_information.string, domain_comment);
6723 if (!torture_setting_bool(tctx, "samba3", false)) {
6730 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
6732 s.in.domain_handle = handle;
6733 s.in.level = levels[i];
6736 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
6737 "SetDomainInfo failed");
6739 if (!NT_STATUS_IS_OK(s.out.result)) {
6740 torture_warning(tctx, "SetDomainInfo level %u failed - %s\n",
6741 r.in.level, nt_errstr(s.out.result));
6746 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
6747 torture_warning(tctx, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6748 r.in.level, nt_errstr(s.out.result));
6754 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
6755 "QueryDomainInfo failed");
6756 if (!NT_STATUS_IS_OK(r.out.result)) {
6757 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6758 r.in.level, nt_errstr(r.out.result));
6768 static bool test_QueryDomainInfo2(struct dcerpc_binding_handle *b,
6769 struct torture_context *tctx,
6770 struct policy_handle *handle)
6772 struct samr_QueryDomainInfo2 r;
6773 union samr_DomainInfo *info = NULL;
6774 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6778 for (i=0;i<ARRAY_SIZE(levels);i++) {
6779 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
6781 r.in.domain_handle = handle;
6782 r.in.level = levels[i];
6785 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
6786 "QueryDomainInfo2 failed");
6787 if (!NT_STATUS_IS_OK(r.out.result)) {
6788 torture_warning(tctx, "QueryDomainInfo2 level %u failed - %s\n",
6789 r.in.level, nt_errstr(r.out.result));
6798 /* Test whether querydispinfo level 5 and enumdomgroups return the same
6799 set of group names. */
6800 static bool test_GroupList(struct dcerpc_binding_handle *b,
6801 struct torture_context *tctx,
6802 struct policy_handle *handle)
6804 struct samr_EnumDomainGroups q1;
6805 struct samr_QueryDisplayInfo q2;
6807 uint32_t resume_handle=0;
6808 struct samr_SamArray *sam = NULL;
6809 uint32_t num_entries = 0;
6812 uint32_t total_size;
6813 uint32_t returned_size;
6814 union samr_DispInfo info;
6817 const char **names = NULL;
6819 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
6821 q1.in.domain_handle = handle;
6822 q1.in.resume_handle = &resume_handle;
6824 q1.out.resume_handle = &resume_handle;
6825 q1.out.num_entries = &num_entries;
6828 status = STATUS_MORE_ENTRIES;
6829 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6830 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &q1),
6831 "EnumDomainGroups failed");
6832 status = q1.out.result;
6834 if (!NT_STATUS_IS_OK(status) &&
6835 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6838 for (i=0; i<*q1.out.num_entries; i++) {
6839 add_string_to_array(tctx,
6840 sam->entries[i].name.string,
6841 &names, &num_names);
6845 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
6847 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
6849 q2.in.domain_handle = handle;
6851 q2.in.start_idx = 0;
6852 q2.in.max_entries = 5;
6853 q2.in.buf_size = (uint32_t)-1;
6854 q2.out.total_size = &total_size;
6855 q2.out.returned_size = &returned_size;
6856 q2.out.info = &info;
6858 status = STATUS_MORE_ENTRIES;
6859 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6860 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &q2),
6861 "QueryDisplayInfo failed");
6862 status = q2.out.result;
6863 if (!NT_STATUS_IS_OK(status) &&
6864 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6867 for (i=0; i<q2.out.info->info5.count; i++) {
6869 const char *name = q2.out.info->info5.entries[i].account_name.string;
6871 for (j=0; j<num_names; j++) {
6872 if (names[j] == NULL)
6874 if (strequal(names[j], name)) {
6882 torture_warning(tctx, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
6887 q2.in.start_idx += q2.out.info->info5.count;
6890 if (!NT_STATUS_IS_OK(status)) {
6891 torture_warning(tctx, "QueryDisplayInfo level 5 failed - %s\n",
6896 for (i=0; i<num_names; i++) {
6897 if (names[i] != NULL) {
6898 torture_warning(tctx, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
6907 static bool test_DeleteDomainGroup(struct dcerpc_binding_handle *b,
6908 struct torture_context *tctx,
6909 struct policy_handle *group_handle)
6911 struct samr_DeleteDomainGroup d;
6913 torture_comment(tctx, "Testing DeleteDomainGroup\n");
6915 d.in.group_handle = group_handle;
6916 d.out.group_handle = group_handle;
6918 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
6919 "DeleteDomainGroup failed");
6920 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteDomainGroup");
6925 static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle *b,
6926 struct torture_context *tctx,
6927 struct policy_handle *domain_handle)
6929 struct samr_TestPrivateFunctionsDomain r;
6932 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
6934 r.in.domain_handle = domain_handle;
6936 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsDomain_r(b, tctx, &r),
6937 "TestPrivateFunctionsDomain failed");
6938 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
6943 static bool test_RidToSid(struct dcerpc_binding_handle *b,
6944 struct torture_context *tctx,
6945 struct dom_sid *domain_sid,
6946 struct policy_handle *domain_handle)
6948 struct samr_RidToSid r;
6950 struct dom_sid *calc_sid, *out_sid;
6951 int rids[] = { 0, 42, 512, 10200 };
6954 for (i=0;i<ARRAY_SIZE(rids);i++) {
6955 torture_comment(tctx, "Testing RidToSid\n");
6957 calc_sid = dom_sid_dup(tctx, domain_sid);
6958 r.in.domain_handle = domain_handle;
6960 r.out.sid = &out_sid;
6962 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RidToSid_r(b, tctx, &r),
6964 if (!NT_STATUS_IS_OK(r.out.result)) {
6965 torture_warning(tctx, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(r.out.result));
6968 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
6970 if (!dom_sid_equal(calc_sid, out_sid)) {
6971 torture_warning(tctx, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
6972 dom_sid_string(tctx, out_sid),
6973 dom_sid_string(tctx, calc_sid));
6982 static bool test_GetBootKeyInformation(struct dcerpc_binding_handle *b,
6983 struct torture_context *tctx,
6984 struct policy_handle *domain_handle)
6986 struct samr_GetBootKeyInformation r;
6988 uint32_t unknown = 0;
6991 torture_comment(tctx, "Testing GetBootKeyInformation\n");
6993 r.in.domain_handle = domain_handle;
6994 r.out.unknown = &unknown;
6996 status = dcerpc_samr_GetBootKeyInformation_r(b, tctx, &r);
6997 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(r.out.result)) {
6998 status = r.out.result;
7000 if (!NT_STATUS_IS_OK(status)) {
7001 /* w2k3 seems to fail this sometimes and pass it sometimes */
7002 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
7008 static bool test_AddGroupMember(struct dcerpc_binding_handle *b,
7009 struct torture_context *tctx,
7010 struct policy_handle *domain_handle,
7011 struct policy_handle *group_handle)
7014 struct samr_AddGroupMember r;
7015 struct samr_DeleteGroupMember d;
7016 struct samr_QueryGroupMember q;
7017 struct samr_RidTypeArray *rids = NULL;
7018 struct samr_SetMemberAttributesOfGroup s;
7020 bool found_member = false;
7023 status = test_LookupName(b, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
7024 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
7026 r.in.group_handle = group_handle;
7028 r.in.flags = 0; /* ??? */
7030 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
7032 d.in.group_handle = group_handle;
7035 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7036 "DeleteGroupMember failed");
7037 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, d.out.result, "DeleteGroupMember");
7039 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7040 "AddGroupMember failed");
7041 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7043 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7044 "AddGroupMember failed");
7045 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, r.out.result, "AddGroupMember");
7047 if (torture_setting_bool(tctx, "samba4", false) ||
7048 torture_setting_bool(tctx, "samba3", false)) {
7049 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
7051 /* this one is quite strange. I am using random inputs in the
7052 hope of triggering an error that might give us a clue */
7054 s.in.group_handle = group_handle;
7055 s.in.unknown1 = random();
7056 s.in.unknown2 = random();
7058 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetMemberAttributesOfGroup_r(b, tctx, &s),
7059 "SetMemberAttributesOfGroup failed");
7060 torture_assert_ntstatus_ok(tctx, s.out.result, "SetMemberAttributesOfGroup");
7063 q.in.group_handle = group_handle;
7066 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7067 "QueryGroupMember failed");
7068 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7069 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7071 for (i=0; i < rids->count; i++) {
7072 if (rids->rids[i] == rid) {
7073 found_member = true;
7077 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
7079 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7080 "DeleteGroupMember failed");
7081 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteGroupMember");
7084 found_member = false;
7086 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7087 "QueryGroupMember failed");
7088 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7089 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7091 for (i=0; i < rids->count; i++) {
7092 if (rids->rids[i] == rid) {
7093 found_member = true;
7097 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
7099 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7100 "AddGroupMember failed");
7101 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7107 static bool test_CreateDomainGroup(struct dcerpc_binding_handle *b,
7108 struct torture_context *tctx,
7109 struct policy_handle *domain_handle,
7110 const char *group_name,
7111 struct policy_handle *group_handle,
7112 struct dom_sid *domain_sid,
7115 struct samr_CreateDomainGroup r;
7117 struct lsa_String name;
7120 init_lsa_String(&name, group_name);
7122 r.in.domain_handle = domain_handle;
7124 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7125 r.out.group_handle = group_handle;
7128 torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
7130 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7131 "CreateDomainGroup failed");
7133 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
7134 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
7135 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
7138 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
7139 nt_errstr(r.out.result));
7144 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_GROUP_EXISTS)) {
7145 if (!test_DeleteGroup_byname(b, tctx, domain_handle, r.in.name->string)) {
7146 torture_warning(tctx, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
7147 nt_errstr(r.out.result));
7150 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7151 "CreateDomainGroup failed");
7153 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
7154 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.name->string)) {
7156 torture_warning(tctx, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
7157 nt_errstr(r.out.result));
7160 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7161 "CreateDomainGroup failed");
7163 torture_assert_ntstatus_ok(tctx, r.out.result, "CreateDomainGroup");
7169 if (!test_AddGroupMember(b, tctx, domain_handle, group_handle)) {
7170 torture_warning(tctx, "CreateDomainGroup failed - %s\n", nt_errstr(r.out.result));
7174 if (!test_SetGroupInfo(b, tctx, group_handle)) {
7183 its not totally clear what this does. It seems to accept any sid you like.
7185 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle *b,
7186 struct torture_context *tctx,
7187 struct policy_handle *domain_handle)
7189 struct samr_RemoveMemberFromForeignDomain r;
7191 r.in.domain_handle = domain_handle;
7192 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
7194 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMemberFromForeignDomain_r(b, tctx, &r),
7195 "RemoveMemberFromForeignDomain failed");
7196 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMemberFromForeignDomain");
7201 static bool test_EnumDomainUsers(struct dcerpc_binding_handle *b,
7202 struct torture_context *tctx,
7203 struct policy_handle *domain_handle,
7204 uint32_t *total_num_entries_p)
7207 struct samr_EnumDomainUsers r;
7208 uint32_t resume_handle = 0;
7209 uint32_t num_entries = 0;
7210 uint32_t total_num_entries = 0;
7211 struct samr_SamArray *sam;
7213 r.in.domain_handle = domain_handle;
7214 r.in.acct_flags = 0;
7215 r.in.max_size = (uint32_t)-1;
7216 r.in.resume_handle = &resume_handle;
7219 r.out.num_entries = &num_entries;
7220 r.out.resume_handle = &resume_handle;
7222 torture_comment(tctx, "Testing EnumDomainUsers\n");
7225 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
7226 "EnumDomainUsers failed");
7227 if (NT_STATUS_IS_ERR(r.out.result)) {
7228 torture_assert_ntstatus_ok(tctx, r.out.result,
7229 "failed to enumerate users");
7232 total_num_entries += num_entries;
7233 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7235 if (total_num_entries_p) {
7236 *total_num_entries_p = total_num_entries;
7242 static bool test_EnumDomainGroups(struct dcerpc_binding_handle *b,
7243 struct torture_context *tctx,
7244 struct policy_handle *domain_handle,
7245 uint32_t *total_num_entries_p)
7248 struct samr_EnumDomainGroups r;
7249 uint32_t resume_handle = 0;
7250 uint32_t num_entries = 0;
7251 uint32_t total_num_entries = 0;
7252 struct samr_SamArray *sam;
7254 r.in.domain_handle = domain_handle;
7255 r.in.max_size = (uint32_t)-1;
7256 r.in.resume_handle = &resume_handle;
7259 r.out.num_entries = &num_entries;
7260 r.out.resume_handle = &resume_handle;
7262 torture_comment(tctx, "Testing EnumDomainGroups\n");
7265 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
7266 "EnumDomainGroups failed");
7267 if (NT_STATUS_IS_ERR(r.out.result)) {
7268 torture_assert_ntstatus_ok(tctx, r.out.result,
7269 "failed to enumerate groups");
7272 total_num_entries += num_entries;
7273 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7275 if (total_num_entries_p) {
7276 *total_num_entries_p = total_num_entries;
7282 static bool test_EnumDomainAliases(struct dcerpc_binding_handle *b,
7283 struct torture_context *tctx,
7284 struct policy_handle *domain_handle,
7285 uint32_t *total_num_entries_p)
7288 struct samr_EnumDomainAliases r;
7289 uint32_t resume_handle = 0;
7290 uint32_t num_entries = 0;
7291 uint32_t total_num_entries = 0;
7292 struct samr_SamArray *sam;
7294 r.in.domain_handle = domain_handle;
7295 r.in.max_size = (uint32_t)-1;
7296 r.in.resume_handle = &resume_handle;
7299 r.out.num_entries = &num_entries;
7300 r.out.resume_handle = &resume_handle;
7302 torture_comment(tctx, "Testing EnumDomainAliases\n");
7305 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
7306 "EnumDomainAliases failed");
7307 if (NT_STATUS_IS_ERR(r.out.result)) {
7308 torture_assert_ntstatus_ok(tctx, r.out.result,
7309 "failed to enumerate aliases");
7312 total_num_entries += num_entries;
7313 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7315 if (total_num_entries_p) {
7316 *total_num_entries_p = total_num_entries;
7322 static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle *b,
7323 struct torture_context *tctx,
7324 struct policy_handle *handle,
7326 uint32_t *total_num_entries_p)
7329 struct samr_QueryDisplayInfo r;
7330 uint32_t total_num_entries = 0;
7332 r.in.domain_handle = handle;
7335 r.in.max_entries = (uint32_t)-1;
7336 r.in.buf_size = (uint32_t)-1;
7338 torture_comment(tctx, "Testing QueryDisplayInfo\n");
7341 uint32_t total_size;
7342 uint32_t returned_size;
7343 union samr_DispInfo info;
7345 r.out.total_size = &total_size;
7346 r.out.returned_size = &returned_size;
7349 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7350 "failed to query displayinfo");
7351 if (NT_STATUS_IS_ERR(r.out.result)) {
7352 torture_assert_ntstatus_ok(tctx, r.out.result,
7353 "failed to query displayinfo");
7356 if (*r.out.returned_size == 0) {
7360 switch (r.in.level) {
7362 total_num_entries += info.info1.count;
7363 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
7366 total_num_entries += info.info2.count;
7367 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
7370 total_num_entries += info.info3.count;
7371 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
7374 total_num_entries += info.info4.count;
7375 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
7378 total_num_entries += info.info5.count;
7379 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
7385 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7387 if (total_num_entries_p) {
7388 *total_num_entries_p = total_num_entries;
7394 static bool test_ManyObjects(struct dcerpc_pipe *p,
7395 struct torture_context *tctx,
7396 struct policy_handle *domain_handle,
7397 struct dom_sid *domain_sid,
7398 struct torture_samr_context *ctx)
7400 uint32_t num_total = ctx->num_objects_large_dc;
7401 uint32_t num_enum = 0;
7402 uint32_t num_disp = 0;
7403 uint32_t num_created = 0;
7404 uint32_t num_anounced = 0;
7407 struct dcerpc_binding_handle *b = p->binding_handle;
7409 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
7414 struct samr_QueryDomainInfo2 r;
7415 union samr_DomainInfo *info;
7416 r.in.domain_handle = domain_handle;
7420 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
7421 "QueryDomainInfo2 failed");
7422 torture_assert_ntstatus_ok(tctx, r.out.result,
7423 "failed to query domain info");
7425 switch (ctx->choice) {
7426 case TORTURE_SAMR_MANY_ACCOUNTS:
7427 num_anounced = info->general.num_users;
7429 case TORTURE_SAMR_MANY_GROUPS:
7430 num_anounced = info->general.num_groups;
7432 case TORTURE_SAMR_MANY_ALIASES:
7433 num_anounced = info->general.num_aliases;
7442 for (i=0; i < num_total; i++) {
7444 const char *name = NULL;
7446 switch (ctx->choice) {
7447 case TORTURE_SAMR_MANY_ACCOUNTS:
7448 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
7449 ret &= test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false);
7451 case TORTURE_SAMR_MANY_GROUPS:
7452 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
7453 ret &= test_CreateDomainGroup(b, tctx, domain_handle, name, &handles[i], domain_sid, false);
7455 case TORTURE_SAMR_MANY_ALIASES:
7456 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
7457 ret &= test_CreateAlias(b, tctx, domain_handle, name, &handles[i], domain_sid, false);
7462 if (!policy_handle_empty(&handles[i])) {
7469 switch (ctx->choice) {
7470 case TORTURE_SAMR_MANY_ACCOUNTS:
7471 ret &= test_EnumDomainUsers(b, tctx, domain_handle, &num_enum);
7473 case TORTURE_SAMR_MANY_GROUPS:
7474 ret &= test_EnumDomainGroups(b, tctx, domain_handle, &num_enum);
7476 case TORTURE_SAMR_MANY_ALIASES:
7477 ret &= test_EnumDomainAliases(b, tctx, domain_handle, &num_enum);
7485 switch (ctx->choice) {
7486 case TORTURE_SAMR_MANY_ACCOUNTS:
7487 ret &= test_QueryDisplayInfo_level(b, tctx, domain_handle, 1, &num_disp);
7489 case TORTURE_SAMR_MANY_GROUPS:
7490 ret &= test_QueryDisplayInfo_level(b, tctx, domain_handle, 3, &num_disp);
7492 case TORTURE_SAMR_MANY_ALIASES:
7493 /* no aliases in dispinfo */
7499 /* close or delete */
7501 for (i=0; i < num_total; i++) {
7503 if (policy_handle_empty(&handles[i])) {
7507 if (torture_setting_bool(tctx, "samba3", false)) {
7508 ret &= test_samr_handle_Close(b, tctx, &handles[i]);
7510 switch (ctx->choice) {
7511 case TORTURE_SAMR_MANY_ACCOUNTS:
7512 ret &= test_DeleteUser(b, tctx, &handles[i]);
7514 case TORTURE_SAMR_MANY_GROUPS:
7515 ret &= test_DeleteDomainGroup(b, tctx, &handles[i]);
7517 case TORTURE_SAMR_MANY_ALIASES:
7518 ret &= test_DeleteAlias(b, tctx, &handles[i]);
7526 talloc_free(handles);
7528 if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
7529 torture_comment(tctx,
7530 "unexpected number of results (%u) returned in enum call, expected %u\n",
7531 num_enum, num_anounced + num_created);
7533 torture_comment(tctx,
7534 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
7535 num_disp, num_anounced + num_created);
7540 static bool test_Connect(struct dcerpc_binding_handle *b,
7541 struct torture_context *tctx,
7542 struct policy_handle *handle);
7544 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7545 struct torture_samr_context *ctx, struct dom_sid *sid)
7547 struct samr_OpenDomain r;
7548 struct policy_handle domain_handle;
7549 struct policy_handle alias_handle;
7550 struct policy_handle user_handle;
7551 struct policy_handle group_handle;
7553 struct dcerpc_binding_handle *b = p->binding_handle;
7555 ZERO_STRUCT(alias_handle);
7556 ZERO_STRUCT(user_handle);
7557 ZERO_STRUCT(group_handle);
7558 ZERO_STRUCT(domain_handle);
7560 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
7562 r.in.connect_handle = &ctx->handle;
7563 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7565 r.out.domain_handle = &domain_handle;
7567 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenDomain_r(b, tctx, &r),
7568 "OpenDomain failed");
7569 torture_assert_ntstatus_ok(tctx, r.out.result, "OpenDomain failed");
7571 /* run the domain tests with the main handle closed - this tests
7572 the servers reference counting */
7573 torture_assert(tctx, test_samr_handle_Close(b, tctx, &ctx->handle), "Failed to close SAMR handle");
7575 switch (ctx->choice) {
7576 case TORTURE_SAMR_PASSWORDS:
7577 case TORTURE_SAMR_USER_PRIVILEGES:
7578 if (!torture_setting_bool(tctx, "samba3", false)) {
7579 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7581 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7583 torture_warning(tctx, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
7586 case TORTURE_SAMR_USER_ATTRIBUTES:
7587 if (!torture_setting_bool(tctx, "samba3", false)) {
7588 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7590 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7591 /* This test needs 'complex' users to validate */
7592 ret &= test_QueryDisplayInfo(b, tctx, &domain_handle);
7594 torture_warning(tctx, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
7597 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
7598 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
7599 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
7600 if (!torture_setting_bool(tctx, "samba3", false)) {
7601 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
7603 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
7605 torture_warning(tctx, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx, sid));
7608 case TORTURE_SAMR_MANY_ACCOUNTS:
7609 case TORTURE_SAMR_MANY_GROUPS:
7610 case TORTURE_SAMR_MANY_ALIASES:
7611 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
7613 torture_warning(tctx, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
7616 case TORTURE_SAMR_OTHER:
7617 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7619 torture_warning(tctx, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
7621 if (!torture_setting_bool(tctx, "samba3", false)) {
7622 ret &= test_QuerySecurity(b, tctx, &domain_handle);
7624 ret &= test_RemoveMemberFromForeignDomain(b, tctx, &domain_handle);
7625 ret &= test_CreateAlias(b, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
7626 ret &= test_CreateDomainGroup(b, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
7627 ret &= test_GetAliasMembership(b, tctx, &domain_handle);
7628 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
7629 ret &= test_QueryDomainInfo2(b, tctx, &domain_handle);
7630 ret &= test_EnumDomainUsers_all(b, tctx, &domain_handle);
7631 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
7632 ret &= test_EnumDomainGroups_all(b, tctx, &domain_handle);
7633 ret &= test_EnumDomainAliases_all(b, tctx, &domain_handle);
7634 ret &= test_QueryDisplayInfo2(b, tctx, &domain_handle);
7635 ret &= test_QueryDisplayInfo3(b, tctx, &domain_handle);
7636 ret &= test_QueryDisplayInfo_continue(b, tctx, &domain_handle);
7638 if (torture_setting_bool(tctx, "samba4", false)) {
7639 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
7641 ret &= test_GetDisplayEnumerationIndex(b, tctx, &domain_handle);
7642 ret &= test_GetDisplayEnumerationIndex2(b, tctx, &domain_handle);
7644 ret &= test_GroupList(b, tctx, &domain_handle);
7645 ret &= test_TestPrivateFunctionsDomain(b, tctx, &domain_handle);
7646 ret &= test_RidToSid(b, tctx, sid, &domain_handle);
7647 ret &= test_GetBootKeyInformation(b, tctx, &domain_handle);
7649 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
7654 if (!policy_handle_empty(&user_handle) &&
7655 !test_DeleteUser(b, tctx, &user_handle)) {
7659 if (!policy_handle_empty(&alias_handle) &&
7660 !test_DeleteAlias(b, tctx, &alias_handle)) {
7664 if (!policy_handle_empty(&group_handle) &&
7665 !test_DeleteDomainGroup(b, tctx, &group_handle)) {
7669 torture_assert(tctx, test_samr_handle_Close(b, tctx, &domain_handle), "Failed to close SAMR domain handle");
7671 torture_assert(tctx, test_Connect(b, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
7672 /* reconnect the main handle */
7675 torture_warning(tctx, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
7681 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7682 struct torture_samr_context *ctx, const char *domain)
7684 struct samr_LookupDomain r;
7685 struct dom_sid2 *sid = NULL;
7686 struct lsa_String n1;
7687 struct lsa_String n2;
7689 struct dcerpc_binding_handle *b = p->binding_handle;
7691 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
7693 /* check for correct error codes */
7694 r.in.connect_handle = &ctx->handle;
7695 r.in.domain_name = &n2;
7699 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7700 "LookupDomain failed");
7701 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, r.out.result, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
7703 init_lsa_String(&n2, "xxNODOMAINxx");
7705 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7706 "LookupDomain failed");
7707 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, r.out.result, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
7709 r.in.connect_handle = &ctx->handle;
7711 init_lsa_String(&n1, domain);
7712 r.in.domain_name = &n1;
7714 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7715 "LookupDomain failed");
7716 torture_assert_ntstatus_ok(tctx, r.out.result, "LookupDomain");
7718 if (!test_GetDomPwInfo(p, tctx, &n1)) {
7722 if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
7730 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
7731 struct torture_samr_context *ctx)
7733 struct samr_EnumDomains r;
7734 uint32_t resume_handle = 0;
7735 uint32_t num_entries = 0;
7736 struct samr_SamArray *sam = NULL;
7739 struct dcerpc_binding_handle *b = p->binding_handle;
7741 r.in.connect_handle = &ctx->handle;
7742 r.in.resume_handle = &resume_handle;
7743 r.in.buf_size = (uint32_t)-1;
7744 r.out.resume_handle = &resume_handle;
7745 r.out.num_entries = &num_entries;
7748 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
7749 "EnumDomains failed");
7750 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
7756 for (i=0;i<sam->count;i++) {
7757 if (!test_LookupDomain(p, tctx, ctx,
7758 sam->entries[i].name.string)) {
7763 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
7764 "EnumDomains failed");
7765 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
7771 static bool test_Connect(struct dcerpc_binding_handle *b,
7772 struct torture_context *tctx,
7773 struct policy_handle *handle)
7775 struct samr_Connect r;
7776 struct samr_Connect2 r2;
7777 struct samr_Connect3 r3;
7778 struct samr_Connect4 r4;
7779 struct samr_Connect5 r5;
7780 union samr_ConnectInfo info;
7781 struct policy_handle h;
7782 uint32_t level_out = 0;
7783 bool ret = true, got_handle = false;
7785 torture_comment(tctx, "Testing samr_Connect\n");
7787 r.in.system_name = 0;
7788 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7789 r.out.connect_handle = &h;
7791 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect_r(b, tctx, &r),
7793 if (!NT_STATUS_IS_OK(r.out.result)) {
7794 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(r.out.result));
7801 torture_comment(tctx, "Testing samr_Connect2\n");
7803 r2.in.system_name = NULL;
7804 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7805 r2.out.connect_handle = &h;
7807 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect2_r(b, tctx, &r2),
7809 if (!NT_STATUS_IS_OK(r2.out.result)) {
7810 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(r2.out.result));
7814 test_samr_handle_Close(b, tctx, handle);
7820 torture_comment(tctx, "Testing samr_Connect3\n");
7822 r3.in.system_name = NULL;
7824 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7825 r3.out.connect_handle = &h;
7827 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect3_r(b, tctx, &r3),
7829 if (!NT_STATUS_IS_OK(r3.out.result)) {
7830 torture_warning(tctx, "Connect3 failed - %s\n", nt_errstr(r3.out.result));
7834 test_samr_handle_Close(b, tctx, handle);
7840 torture_comment(tctx, "Testing samr_Connect4\n");
7842 r4.in.system_name = "";
7843 r4.in.client_version = 0;
7844 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7845 r4.out.connect_handle = &h;
7847 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect4_r(b, tctx, &r4),
7849 if (!NT_STATUS_IS_OK(r4.out.result)) {
7850 torture_warning(tctx, "Connect4 failed - %s\n", nt_errstr(r4.out.result));
7854 test_samr_handle_Close(b, tctx, handle);
7860 torture_comment(tctx, "Testing samr_Connect5\n");
7862 info.info1.client_version = 0;
7863 info.info1.unknown2 = 0;
7865 r5.in.system_name = "";
7866 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7868 r5.out.level_out = &level_out;
7869 r5.in.info_in = &info;
7870 r5.out.info_out = &info;
7871 r5.out.connect_handle = &h;
7873 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect5_r(b, tctx, &r5),
7875 if (!NT_STATUS_IS_OK(r5.out.result)) {
7876 torture_warning(tctx, "Connect5 failed - %s\n", nt_errstr(r5.out.result));
7880 test_samr_handle_Close(b, tctx, handle);
7890 static bool test_samr_ValidatePassword(struct dcerpc_pipe *p,
7891 struct torture_context *tctx)
7893 struct samr_ValidatePassword r;
7894 union samr_ValidatePasswordReq req;
7895 union samr_ValidatePasswordRep *repp = NULL;
7897 const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
7899 struct dcerpc_binding_handle *b = p->binding_handle;
7901 torture_comment(tctx, "Testing samr_ValidatePassword\n");
7904 r.in.level = NetValidatePasswordReset;
7909 req.req3.account.string = "non-existant-account-aklsdji";
7911 for (i=0; passwords[i]; i++) {
7912 req.req3.password.string = passwords[i];
7914 status = dcerpc_samr_ValidatePassword_r(b, tctx, &r);
7915 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
7916 torture_skip(tctx, "ValidatePassword not supported by server\n");
7918 torture_assert_ntstatus_ok(tctx, status,
7919 "samr_ValidatePassword failed");
7920 torture_assert_ntstatus_ok(tctx, r.out.result,
7921 "samr_ValidatePassword failed");
7922 torture_comment(tctx, "Server %s password '%s' with code %i\n",
7923 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
7924 req.req3.password.string, repp->ctr3.status);
7930 bool torture_rpc_samr(struct torture_context *torture)
7933 struct dcerpc_pipe *p;
7935 struct torture_samr_context *ctx;
7936 struct dcerpc_binding_handle *b;
7938 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7939 if (!NT_STATUS_IS_OK(status)) {
7942 b = p->binding_handle;
7944 ctx = talloc_zero(torture, struct torture_samr_context);
7946 ctx->choice = TORTURE_SAMR_OTHER;
7948 ret &= test_Connect(b, torture, &ctx->handle);
7950 if (!torture_setting_bool(torture, "samba3", false)) {
7951 ret &= test_QuerySecurity(b, torture, &ctx->handle);
7954 ret &= test_EnumDomains(p, torture, ctx);
7956 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
7958 ret &= test_Shutdown(b, torture, &ctx->handle);
7960 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
7966 bool torture_rpc_samr_users(struct torture_context *torture)
7969 struct dcerpc_pipe *p;
7971 struct torture_samr_context *ctx;
7972 struct dcerpc_binding_handle *b;
7974 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7975 if (!NT_STATUS_IS_OK(status)) {
7978 b = p->binding_handle;
7980 ctx = talloc_zero(torture, struct torture_samr_context);
7982 ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
7984 ret &= test_Connect(b, torture, &ctx->handle);
7986 if (!torture_setting_bool(torture, "samba3", false)) {
7987 ret &= test_QuerySecurity(b, torture, &ctx->handle);
7990 ret &= test_EnumDomains(p, torture, ctx);
7992 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
7994 ret &= test_Shutdown(b, torture, &ctx->handle);
7996 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8002 bool torture_rpc_samr_passwords(struct torture_context *torture)
8005 struct dcerpc_pipe *p;
8007 struct torture_samr_context *ctx;
8008 struct dcerpc_binding_handle *b;
8010 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8011 if (!NT_STATUS_IS_OK(status)) {
8014 b = p->binding_handle;
8016 ctx = talloc_zero(torture, struct torture_samr_context);
8018 ctx->choice = TORTURE_SAMR_PASSWORDS;
8020 ret &= test_Connect(b, torture, &ctx->handle);
8022 ret &= test_EnumDomains(p, torture, ctx);
8024 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8026 ret &= test_samr_ValidatePassword(p, torture);
8031 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
8032 struct dcerpc_pipe *p2,
8033 struct cli_credentials *machine_credentials)
8036 struct dcerpc_pipe *p;
8038 struct torture_samr_context *ctx;
8039 struct dcerpc_binding_handle *b;
8041 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8042 if (!NT_STATUS_IS_OK(status)) {
8045 b = p->binding_handle;
8047 ctx = talloc_zero(torture, struct torture_samr_context);
8049 ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
8050 ctx->machine_credentials = machine_credentials;
8052 ret &= test_Connect(b, torture, &ctx->handle);
8054 ret &= test_EnumDomains(p, torture, ctx);
8056 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8061 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
8063 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
8064 struct torture_rpc_tcase *tcase;
8066 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8068 TEST_ACCOUNT_NAME_PWD);
8070 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
8071 torture_rpc_samr_pwdlastset);
8076 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
8077 struct dcerpc_pipe *p2,
8078 struct cli_credentials *machine_credentials)
8081 struct dcerpc_pipe *p;
8083 struct torture_samr_context *ctx;
8084 struct dcerpc_binding_handle *b;
8086 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8087 if (!NT_STATUS_IS_OK(status)) {
8090 b = p->binding_handle;
8092 ctx = talloc_zero(torture, struct torture_samr_context);
8094 ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
8095 ctx->machine_credentials = machine_credentials;
8097 ret &= test_Connect(b, torture, &ctx->handle);
8099 ret &= test_EnumDomains(p, torture, ctx);
8101 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8106 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
8108 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-USERS-PRIVILEGES");
8109 struct torture_rpc_tcase *tcase;
8111 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8113 TEST_ACCOUNT_NAME_PWD);
8115 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
8116 torture_rpc_samr_users_privileges_delete_user);
8121 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
8122 struct dcerpc_pipe *p2,
8126 struct dcerpc_pipe *p;
8128 struct torture_samr_context *ctx =
8129 talloc_get_type_abort(data, struct torture_samr_context);
8130 struct dcerpc_binding_handle *b;
8132 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8133 if (!NT_STATUS_IS_OK(status)) {
8136 b = p->binding_handle;
8138 ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
8139 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8140 ctx->num_objects_large_dc);
8142 ret &= test_Connect(b, torture, &ctx->handle);
8144 ret &= test_EnumDomains(p, torture, ctx);
8146 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8151 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
8152 struct dcerpc_pipe *p2,
8156 struct dcerpc_pipe *p;
8158 struct torture_samr_context *ctx =
8159 talloc_get_type_abort(data, struct torture_samr_context);
8160 struct dcerpc_binding_handle *b;
8162 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8163 if (!NT_STATUS_IS_OK(status)) {
8166 b = p->binding_handle;
8168 ctx->choice = TORTURE_SAMR_MANY_GROUPS;
8169 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8170 ctx->num_objects_large_dc);
8172 ret &= test_Connect(b, torture, &ctx->handle);
8174 ret &= test_EnumDomains(p, torture, ctx);
8176 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8181 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
8182 struct dcerpc_pipe *p2,
8186 struct dcerpc_pipe *p;
8188 struct torture_samr_context *ctx =
8189 talloc_get_type_abort(data, struct torture_samr_context);
8190 struct dcerpc_binding_handle *b;
8192 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8193 if (!NT_STATUS_IS_OK(status)) {
8196 b = p->binding_handle;
8198 ctx->choice = TORTURE_SAMR_MANY_ALIASES;
8199 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8200 ctx->num_objects_large_dc);
8202 ret &= test_Connect(b, torture, &ctx->handle);
8204 ret &= test_EnumDomains(p, torture, ctx);
8206 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8211 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
8213 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-LARGE-DC");
8214 struct torture_rpc_tcase *tcase;
8215 struct torture_samr_context *ctx;
8217 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
8219 ctx = talloc_zero(suite, struct torture_samr_context);
8220 ctx->num_objects_large_dc = 150;
8222 torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
8223 torture_rpc_samr_many_aliases, ctx);
8224 torture_rpc_tcase_add_test_ex(tcase, "many_groups",
8225 torture_rpc_samr_many_groups, ctx);
8226 torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
8227 torture_rpc_samr_many_accounts, ctx);
8232 static bool torture_rpc_samr_badpwdcount(struct torture_context *torture,
8233 struct dcerpc_pipe *p2,
8234 struct cli_credentials *machine_credentials)
8237 struct dcerpc_pipe *p;
8239 struct torture_samr_context *ctx;
8240 struct dcerpc_binding_handle *b;
8242 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8243 if (!NT_STATUS_IS_OK(status)) {
8246 b = p->binding_handle;
8248 ctx = talloc_zero(torture, struct torture_samr_context);
8250 ctx->choice = TORTURE_SAMR_PASSWORDS_BADPWDCOUNT;
8251 ctx->machine_credentials = machine_credentials;
8253 ret &= test_Connect(b, torture, &ctx->handle);
8255 ret &= test_EnumDomains(p, torture, ctx);
8257 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8262 struct torture_suite *torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX *mem_ctx)
8264 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-BADPWDCOUNT");
8265 struct torture_rpc_tcase *tcase;
8267 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8269 TEST_ACCOUNT_NAME_PWD);
8271 torture_rpc_tcase_add_test_creds(tcase, "badPwdCount",
8272 torture_rpc_samr_badpwdcount);
8277 static bool torture_rpc_samr_lockout(struct torture_context *torture,
8278 struct dcerpc_pipe *p2,
8279 struct cli_credentials *machine_credentials)
8282 struct dcerpc_pipe *p;
8284 struct torture_samr_context *ctx;
8285 struct dcerpc_binding_handle *b;
8287 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8288 if (!NT_STATUS_IS_OK(status)) {
8291 b = p->binding_handle;
8293 ctx = talloc_zero(torture, struct torture_samr_context);
8295 ctx->choice = TORTURE_SAMR_PASSWORDS_LOCKOUT;
8296 ctx->machine_credentials = machine_credentials;
8298 ret &= test_Connect(b, torture, &ctx->handle);
8300 ret &= test_EnumDomains(p, torture, ctx);
8302 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8307 struct torture_suite *torture_rpc_samr_passwords_lockout(TALLOC_CTX *mem_ctx)
8309 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-LOCKOUT");
8310 struct torture_rpc_tcase *tcase;
8312 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8314 TEST_ACCOUNT_NAME_PWD);
8316 torture_rpc_tcase_add_test_creds(tcase, "lockout",
8317 torture_rpc_samr_lockout);