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_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, 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 (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
2863 flags |= CLI_CRED_LANMAN_AUTH;
2866 if (lpcfg_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) ||
3115 torture_setting_bool(tctx, "samba4", false)) {
3117 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
3121 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3123 /* set to 1 to enable testing for all possible opcode
3124 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3127 #define TEST_ALL_LEVELS 1
3128 #define TEST_SET_LEVELS 1
3129 #define TEST_QUERY_LEVELS 1
3131 #ifdef TEST_ALL_LEVELS
3132 for (l=0; l<ARRAY_SIZE(levels); l++) {
3134 for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
3136 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
3137 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
3138 #ifdef TEST_SET_LEVELS
3139 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
3141 #ifdef TEST_QUERY_LEVELS
3142 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
3144 NTTIME pwdlastset_old = 0;
3145 NTTIME pwdlastset_new = 0;
3146 bool matched_expected_error = false;
3147 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
3149 torture_comment(tctx, "------------------------------\n"
3150 "Testing pwdLastSet attribute for flags: 0x%08x "
3151 "(s: %d (l: %d), q: %d)\n",
3152 acct_flags, s, levels[l], q);
3154 switch (levels[l]) {
3158 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3159 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
3160 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
3168 /* set a password and force password change (pwdlastset 0) by
3169 * setting the password expired flag to a non-0 value */
3171 if (!test_SetPassword_level(p, np, tctx, handle,
3175 &matched_expected_error,
3179 machine_credentials,
3182 expected_samlogon_result)) {
3186 if (matched_expected_error == true) {
3187 /* skipping on expected failure */
3191 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3192 * set without the SAMR_FIELD_EXPIRED_FLAG */
3194 switch (levels[l]) {
3198 if ((pwdlastset_new != 0) &&
3199 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3200 torture_comment(tctx, "not considering a non-0 "
3201 "pwdLastSet as a an error as the "
3202 "SAMR_FIELD_EXPIRED_FLAG has not "
3208 if (pwdlastset_new != 0) {
3209 torture_warning(tctx, "pwdLastSet test failed: "
3210 "expected pwdLastSet 0 but got %lld\n",
3217 switch (levels[l]) {
3221 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3222 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3223 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3224 (pwdlastset_old >= pwdlastset_new)) {
3225 torture_warning(tctx, "pwdlastset not increasing\n");
3231 pwdlastset_old = pwdlastset_new;
3237 /* set a password, pwdlastset needs to get updated (increased
3238 * value), password_expired value used here is 0 */
3240 if (!test_SetPassword_level(p, np, tctx, handle,
3244 &matched_expected_error,
3248 machine_credentials,
3251 expected_samlogon_result)) {
3255 /* when a password has been changed, pwdlastset must not be 0 afterwards
3256 * and must be larger then the old value */
3258 switch (levels[l]) {
3262 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3263 * password has been changed, old and new pwdlastset
3264 * need to be the same value */
3266 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3267 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3268 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3270 torture_assert_int_equal(tctx, pwdlastset_old,
3271 pwdlastset_new, "pwdlastset must be equal");
3276 if (pwdlastset_old >= pwdlastset_new) {
3277 torture_warning(tctx, "pwdLastSet test failed: "
3278 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3279 pwdlastset_old, pwdlastset_new);
3282 if (pwdlastset_new == 0) {
3283 torture_warning(tctx, "pwdLastSet test failed: "
3284 "expected non-0 pwdlastset, got: %lld\n",
3291 switch (levels[l]) {
3295 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3296 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3297 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3298 (pwdlastset_old >= pwdlastset_new)) {
3299 torture_warning(tctx, "pwdlastset not increasing\n");
3305 pwdlastset_old = pwdlastset_new;
3311 /* set a password, pwdlastset needs to get updated (increased
3312 * value), password_expired value used here is 0 */
3314 if (!test_SetPassword_level(p, np, tctx, handle,
3318 &matched_expected_error,
3322 machine_credentials,
3325 expected_samlogon_result)) {
3329 /* when a password has been changed, pwdlastset must not be 0 afterwards
3330 * and must be larger then the old value */
3332 switch (levels[l]) {
3337 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3338 * password has been changed, old and new pwdlastset
3339 * need to be the same value */
3341 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3342 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3343 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3345 torture_assert_int_equal(tctx, pwdlastset_old,
3346 pwdlastset_new, "pwdlastset must be equal");
3351 if (pwdlastset_old >= pwdlastset_new) {
3352 torture_warning(tctx, "pwdLastSet test failed: "
3353 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3354 pwdlastset_old, pwdlastset_new);
3357 if (pwdlastset_new == 0) {
3358 torture_warning(tctx, "pwdLastSet test failed: "
3359 "expected non-0 pwdlastset, got: %lld\n",
3366 switch (levels[l]) {
3370 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3371 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3372 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3373 (pwdlastset_old >= pwdlastset_new)) {
3374 torture_warning(tctx, "pwdlastset not increasing\n");
3380 pwdlastset_old = pwdlastset_new;
3386 /* set a password and force password change (pwdlastset 0) by
3387 * setting the password expired flag to a non-0 value */
3389 if (!test_SetPassword_level(p, np, tctx, handle,
3393 &matched_expected_error,
3397 machine_credentials,
3400 expected_samlogon_result)) {
3404 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3405 * set without the SAMR_FIELD_EXPIRED_FLAG */
3407 switch (levels[l]) {
3411 if ((pwdlastset_new != 0) &&
3412 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3413 torture_comment(tctx, "not considering a non-0 "
3414 "pwdLastSet as a an error as the "
3415 "SAMR_FIELD_EXPIRED_FLAG has not "
3420 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3421 * password has been changed, old and new pwdlastset
3422 * need to be the same value */
3424 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3425 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3426 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3428 torture_assert_int_equal(tctx, pwdlastset_old,
3429 pwdlastset_new, "pwdlastset must be equal");
3434 if (pwdlastset_new != 0) {
3435 torture_warning(tctx, "pwdLastSet test failed: "
3436 "expected pwdLastSet 0, got %lld\n",
3443 switch (levels[l]) {
3447 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3448 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3449 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3450 (pwdlastset_old >= pwdlastset_new)) {
3451 torture_warning(tctx, "pwdlastset not increasing\n");
3457 /* if the level we are testing does not have a fields_present
3458 * field, skip all fields present tests by setting f to to
3460 switch (levels[l]) {
3464 f = ARRAY_SIZE(fields_present);
3468 #ifdef TEST_QUERY_LEVELS
3471 #ifdef TEST_SET_LEVELS
3474 } /* fields present */
3478 #undef TEST_SET_LEVELS
3479 #undef TEST_QUERY_LEVELS
3486 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_binding_handle *b,
3487 struct torture_context *tctx,
3488 struct policy_handle *handle,
3489 uint32_t *badpwdcount)
3491 union samr_UserInfo *info;
3492 struct samr_QueryUserInfo r;
3494 r.in.user_handle = handle;
3498 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3500 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3501 "failed to query userinfo");
3502 torture_assert_ntstatus_ok(tctx, r.out.result,
3503 "failed to query userinfo");
3505 *badpwdcount = info->info3.bad_password_count;
3507 torture_comment(tctx, " (bad password count: %d)\n", *badpwdcount);
3512 static bool test_SetUserInfo_acct_flags(struct dcerpc_binding_handle *b,
3513 struct torture_context *tctx,
3514 struct policy_handle *user_handle,
3515 uint32_t acct_flags)
3517 struct samr_SetUserInfo r;
3518 union samr_UserInfo user_info;
3520 torture_comment(tctx, "Testing SetUserInfo level 16\n");
3522 user_info.info16.acct_flags = acct_flags;
3524 r.in.user_handle = user_handle;
3526 r.in.info = &user_info;
3528 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &r),
3529 "failed to set account flags");
3530 torture_assert_ntstatus_ok(tctx, r.out.result,
3531 "failed to set account flags");
3536 static bool test_reset_badpwdcount(struct dcerpc_pipe *p,
3537 struct torture_context *tctx,
3538 struct policy_handle *user_handle,
3539 uint32_t acct_flags,
3542 struct dcerpc_binding_handle *b = p->binding_handle;
3544 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3545 "failed to set password");
3547 torture_comment(tctx, "Testing SetUserInfo level 16 (enable account)\n");
3549 torture_assert(tctx,
3550 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3551 acct_flags & ~ACB_DISABLED),
3552 "failed to enable user");
3554 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3555 "failed to set password");
3560 static bool test_SetDomainInfo(struct dcerpc_binding_handle *b,
3561 struct torture_context *tctx,
3562 struct policy_handle *domain_handle,
3563 enum samr_DomainInfoClass level,
3564 union samr_DomainInfo *info)
3566 struct samr_SetDomainInfo r;
3568 r.in.domain_handle = domain_handle;
3572 torture_assert_ntstatus_ok(tctx,
3573 dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3574 "failed to set domain info");
3575 torture_assert_ntstatus_ok(tctx, r.out.result,
3576 "failed to set domain info");
3581 static bool test_SetDomainInfo_ntstatus(struct dcerpc_binding_handle *b,
3582 struct torture_context *tctx,
3583 struct policy_handle *domain_handle,
3584 enum samr_DomainInfoClass level,
3585 union samr_DomainInfo *info,
3588 struct samr_SetDomainInfo r;
3590 r.in.domain_handle = domain_handle;
3594 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3595 "SetDomainInfo failed");
3596 torture_assert_ntstatus_equal(tctx, r.out.result, expected, "");
3601 static bool test_QueryDomainInfo2_level(struct dcerpc_binding_handle *b,
3602 struct torture_context *tctx,
3603 struct policy_handle *domain_handle,
3604 enum samr_DomainInfoClass level,
3605 union samr_DomainInfo **q_info)
3607 struct samr_QueryDomainInfo2 r;
3609 r.in.domain_handle = domain_handle;
3611 r.out.info = q_info;
3613 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
3614 "failed to query domain info");
3615 torture_assert_ntstatus_ok(tctx, r.out.result,
3616 "failed to query domain info");
3621 static bool test_Password_badpwdcount(struct dcerpc_pipe *p,
3622 struct dcerpc_pipe *np,
3623 struct torture_context *tctx,
3624 uint32_t acct_flags,
3625 const char *acct_name,
3626 struct policy_handle *domain_handle,
3627 struct policy_handle *user_handle,
3629 struct cli_credentials *machine_credentials,
3630 const char *comment,
3633 NTSTATUS expected_success_status,
3634 struct samr_DomInfo1 *info1,
3635 struct samr_DomInfo12 *info12)
3637 union samr_DomainInfo info;
3640 uint32_t badpwdcount, tmp;
3641 uint32_t password_history_length = 12;
3642 uint32_t lockout_threshold = 15;
3643 struct dcerpc_binding_handle *b = p->binding_handle;
3645 torture_comment(tctx, "\nTesting bad pwd count with: %s\n", comment);
3647 torture_assert(tctx, password_history_length < lockout_threshold,
3648 "password history length needs to be smaller than account lockout threshold for this test");
3653 info.info1 = *info1;
3654 info.info1.password_history_length = password_history_length;
3656 torture_assert(tctx,
3657 test_SetDomainInfo(b, tctx, domain_handle,
3658 DomainPasswordInformation, &info),
3659 "failed to set password history length");
3661 info.info12 = *info12;
3662 info.info12.lockout_threshold = lockout_threshold;
3664 torture_assert(tctx,
3665 test_SetDomainInfo(b, tctx, domain_handle,
3666 DomainLockoutInformation, &info),
3667 "failed to set lockout threshold");
3669 /* reset bad pwd count */
3671 torture_assert(tctx,
3672 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
3675 /* enable or disable account */
3677 torture_assert(tctx,
3678 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3679 acct_flags | ACB_DISABLED),
3680 "failed to disable user");
3682 torture_assert(tctx,
3683 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3684 acct_flags & ~ACB_DISABLED),
3685 "failed to enable user");
3689 /* setup password history */
3691 passwords = talloc_array(tctx, char *, password_history_length);
3693 for (i=0; i < password_history_length; i++) {
3695 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3696 "failed to set password");
3697 passwords[i] = talloc_strdup(tctx, *password);
3699 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3700 acct_name, passwords[i],
3701 expected_success_status, interactive)) {
3702 torture_fail(tctx, "failed to auth with latest password");
3705 torture_assert(tctx,
3706 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3708 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3712 /* test with wrong password */
3714 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3715 acct_name, "random_crap",
3716 NT_STATUS_WRONG_PASSWORD, interactive)) {
3717 torture_fail(tctx, "succeeded to authenticate with wrong password");
3720 torture_assert(tctx,
3721 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3723 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3726 /* test with latest good password */
3728 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
3729 passwords[password_history_length-1],
3730 expected_success_status, interactive)) {
3731 torture_fail(tctx, "succeeded to authenticate with wrong password");
3734 torture_assert(tctx,
3735 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3738 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3740 /* only enabled accounts get the bad pwd count reset upon
3741 * successful logon */
3742 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3748 /* test password history */
3750 for (i=0; i < password_history_length; i++) {
3752 torture_comment(tctx, "Testing bad password count behavior with "
3753 "password #%d of #%d\n", i, password_history_length);
3755 /* - network samlogon will succeed auth and not
3756 * increase badpwdcount for 2 last entries
3757 * - interactive samlogon only for the last one */
3759 if (i == password_history_length - 1 ||
3760 (i == password_history_length - 2 && !interactive)) {
3762 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3763 acct_name, passwords[i],
3764 expected_success_status, interactive)) {
3765 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3768 torture_assert(tctx,
3769 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3772 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
3773 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3775 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
3776 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3784 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3785 acct_name, passwords[i],
3786 NT_STATUS_WRONG_PASSWORD, interactive)) {
3787 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3790 torture_assert(tctx,
3791 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3793 /* - network samlogon will fail auth but not increase
3794 * badpwdcount for 3rd last entry
3795 * - interactive samlogon for 3rd and 2nd last entry */
3797 if (i == password_history_length - 3 ||
3798 (i == password_history_length - 2 && interactive)) {
3799 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
3800 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3802 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
3803 torture_assert_int_equal(tctx, badpwdcount, tmp + 1, "unexpected badpwdcount");
3812 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe *p,
3813 struct torture_context *tctx,
3814 uint32_t acct_flags,
3815 const char *acct_name,
3816 struct policy_handle *domain_handle,
3817 struct policy_handle *user_handle,
3819 struct cli_credentials *machine_credentials)
3821 union samr_DomainInfo *q_info, s_info;
3822 struct samr_DomInfo1 info1, _info1;
3823 struct samr_DomInfo12 info12, _info12;
3825 struct dcerpc_binding_handle *b = p->binding_handle;
3826 struct dcerpc_pipe *np;
3830 const char *comment;
3833 NTSTATUS expected_success_status;
3836 .comment = "network logon (disabled account)",
3838 .interactive = false,
3839 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
3842 .comment = "network logon (enabled account)",
3844 .interactive = false,
3845 .expected_success_status= NT_STATUS_OK
3848 .comment = "interactive logon (disabled account)",
3850 .interactive = true,
3851 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
3854 .comment = "interactive logon (enabled account)",
3856 .interactive = true,
3857 .expected_success_status= NT_STATUS_OK
3861 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3863 /* backup old policies */
3865 torture_assert(tctx,
3866 test_QueryDomainInfo2_level(b, tctx, domain_handle,
3867 DomainPasswordInformation, &q_info),
3868 "failed to query domain info level 1");
3870 info1 = q_info->info1;
3873 torture_assert(tctx,
3874 test_QueryDomainInfo2_level(b, tctx, domain_handle,
3875 DomainLockoutInformation, &q_info),
3876 "failed to query domain info level 12");
3878 info12 = q_info->info12;
3883 for (i=0; i < ARRAY_SIZE(creds); i++) {
3885 /* skip trust tests for now */
3886 if (acct_flags & ACB_WSTRUST ||
3887 acct_flags & ACB_SVRTRUST ||
3888 acct_flags & ACB_DOMTRUST) {
3892 ret &= test_Password_badpwdcount(p, np, tctx, acct_flags, acct_name,
3893 domain_handle, user_handle, password,
3894 machine_credentials,
3897 creds[i].interactive,
3898 creds[i].expected_success_status,
3901 torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
3903 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
3907 /* restore policies */
3909 s_info.info1 = info1;
3911 torture_assert(tctx,
3912 test_SetDomainInfo(b, tctx, domain_handle,
3913 DomainPasswordInformation, &s_info),
3914 "failed to set password information");
3916 s_info.info12 = info12;
3918 torture_assert(tctx,
3919 test_SetDomainInfo(b, tctx, domain_handle,
3920 DomainLockoutInformation, &s_info),
3921 "failed to set lockout information");
3926 static bool test_QueryUserInfo_acct_flags(struct dcerpc_binding_handle *b,
3927 struct torture_context *tctx,
3928 struct policy_handle *handle,
3929 uint32_t *acct_flags)
3931 union samr_UserInfo *info;
3932 struct samr_QueryUserInfo r;
3934 r.in.user_handle = handle;
3938 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3940 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3941 "failed to query userinfo");
3942 torture_assert_ntstatus_ok(tctx, r.out.result,
3943 "failed to query userinfo");
3945 *acct_flags = info->info16.acct_flags;
3947 torture_comment(tctx, " (acct_flags: 0x%08x)\n", *acct_flags);
3952 static bool test_Password_lockout(struct dcerpc_pipe *p,
3953 struct dcerpc_pipe *np,
3954 struct torture_context *tctx,
3955 uint32_t acct_flags,
3956 const char *acct_name,
3957 struct policy_handle *domain_handle,
3958 struct policy_handle *user_handle,
3960 struct cli_credentials *machine_credentials,
3961 const char *comment,
3964 NTSTATUS expected_success_status,
3965 struct samr_DomInfo1 *info1,
3966 struct samr_DomInfo12 *info12)
3968 union samr_DomainInfo info;
3969 uint32_t badpwdcount;
3970 uint32_t password_history_length = 1;
3971 uint64_t lockout_threshold = 1;
3972 uint32_t lockout_seconds = 5;
3973 uint64_t delta_time_factor = 10 * 1000 * 1000;
3974 struct dcerpc_binding_handle *b = p->binding_handle;
3976 torture_comment(tctx, "\nTesting account lockout: %s\n", comment);
3980 info.info1 = *info1;
3982 torture_comment(tctx, "setting password history length.\n");
3983 info.info1.password_history_length = password_history_length;
3985 torture_assert(tctx,
3986 test_SetDomainInfo(b, tctx, domain_handle,
3987 DomainPasswordInformation, &info),
3988 "failed to set password history length");
3990 info.info12 = *info12;
3991 info.info12.lockout_threshold = lockout_threshold;
3993 /* set lockout duration < lockout window: should fail */
3994 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
3995 info.info12.lockout_window = ~((lockout_seconds + 1) * delta_time_factor);
3997 torture_assert(tctx,
3998 test_SetDomainInfo_ntstatus(b, tctx, domain_handle,
3999 DomainLockoutInformation, &info,
4000 NT_STATUS_INVALID_PARAMETER),
4001 "setting lockout duration < lockout window gave unexpected result");
4003 info.info12.lockout_duration = 0;
4004 info.info12.lockout_window = 0;
4006 torture_assert(tctx,
4007 test_SetDomainInfo(b, tctx, domain_handle,
4008 DomainLockoutInformation, &info),
4009 "failed to set lockout window and duration to 0");
4012 /* set lockout duration of 5 seconds */
4013 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4014 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
4016 torture_assert(tctx,
4017 test_SetDomainInfo(b, tctx, domain_handle,
4018 DomainLockoutInformation, &info),
4019 "failed to set lockout window and duration to 5 seconds");
4021 /* reset bad pwd count */
4023 torture_assert(tctx,
4024 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
4027 /* enable or disable account */
4030 torture_assert(tctx,
4031 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4032 acct_flags | ACB_DISABLED),
4033 "failed to disable user");
4035 torture_assert(tctx,
4036 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4037 acct_flags & ~ACB_DISABLED),
4038 "failed to enable user");
4042 /* test logon with right password */
4044 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4045 acct_name, *password,
4046 expected_success_status, interactive)) {
4047 torture_fail(tctx, "failed to auth with latest password");
4050 torture_assert(tctx,
4051 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4052 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
4055 /* test with wrong password ==> lockout */
4057 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4058 acct_name, "random_crap",
4059 NT_STATUS_WRONG_PASSWORD, interactive)) {
4060 torture_fail(tctx, "succeeded to authenticate with wrong password");
4063 torture_assert(tctx,
4064 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4065 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4067 torture_assert(tctx,
4068 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4069 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4070 "expected account to be locked");
4073 /* test with good password */
4075 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4077 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4079 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4082 /* bad pwd count should not get updated */
4083 torture_assert(tctx,
4084 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4085 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4087 /* curiously, windows does _not_ set the autlock flag */
4088 torture_assert(tctx,
4089 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4090 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4091 "expected account to be locked");
4094 /* with bad password */
4096 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4097 acct_name, "random_crap2",
4098 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4100 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4103 /* bad pwd count should not get updated */
4104 torture_assert(tctx,
4105 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4106 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4108 /* curiously, windows does _not_ set the autlock flag */
4109 torture_assert(tctx,
4110 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4111 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4112 "expected account to be locked");
4115 /* let lockout duration expire ==> unlock */
4117 torture_comment(tctx, "let lockout duration expire...\n");
4118 sleep(lockout_seconds + 1);
4120 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4122 expected_success_status, interactive))
4124 torture_fail(tctx, "failed to authenticate after lockout expired");
4127 torture_assert(tctx,
4128 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4129 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4130 "expected account not to be locked");
4135 static bool test_Password_lockout_wrap(struct dcerpc_pipe *p,
4136 struct torture_context *tctx,
4137 uint32_t acct_flags,
4138 const char *acct_name,
4139 struct policy_handle *domain_handle,
4140 struct policy_handle *user_handle,
4142 struct cli_credentials *machine_credentials)
4144 union samr_DomainInfo *q_info, s_info;
4145 struct samr_DomInfo1 info1, _info1;
4146 struct samr_DomInfo12 info12, _info12;
4148 struct dcerpc_binding_handle *b = p->binding_handle;
4149 struct dcerpc_pipe *np;
4153 const char *comment;
4156 NTSTATUS expected_success_status;
4159 .comment = "network logon (disabled account)",
4161 .interactive = false,
4162 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4165 .comment = "network logon (enabled account)",
4167 .interactive = false,
4168 .expected_success_status= NT_STATUS_OK
4171 .comment = "interactive logon (disabled account)",
4173 .interactive = true,
4174 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4177 .comment = "interactive logon (enabled account)",
4179 .interactive = true,
4180 .expected_success_status= NT_STATUS_OK
4184 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4186 /* backup old policies */
4188 torture_assert(tctx,
4189 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4190 DomainPasswordInformation, &q_info),
4191 "failed to query domain info level 1");
4193 info1 = q_info->info1;
4196 torture_assert(tctx,
4197 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4198 DomainLockoutInformation, &q_info),
4199 "failed to query domain info level 12");
4201 info12 = q_info->info12;
4206 for (i=0; i < ARRAY_SIZE(creds); i++) {
4208 /* skip trust tests for now */
4209 if (acct_flags & ACB_WSTRUST ||
4210 acct_flags & ACB_SVRTRUST ||
4211 acct_flags & ACB_DOMTRUST) {
4215 ret &= test_Password_lockout(p, np, tctx, acct_flags, acct_name,
4216 domain_handle, user_handle, password,
4217 machine_credentials,
4220 creds[i].interactive,
4221 creds[i].expected_success_status,
4224 torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
4226 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4230 /* restore policies */
4232 s_info.info1 = info1;
4234 torture_assert(tctx,
4235 test_SetDomainInfo(b, tctx, domain_handle,
4236 DomainPasswordInformation, &s_info),
4237 "failed to set password information");
4239 s_info.info12 = info12;
4241 torture_assert(tctx,
4242 test_SetDomainInfo(b, tctx, domain_handle,
4243 DomainLockoutInformation, &s_info),
4244 "failed to set lockout information");
4249 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
4250 struct dcerpc_pipe *lp,
4251 struct torture_context *tctx,
4252 struct policy_handle *domain_handle,
4253 struct policy_handle *lsa_handle,
4254 struct policy_handle *user_handle,
4255 const struct dom_sid *domain_sid,
4257 struct cli_credentials *machine_credentials)
4260 struct dcerpc_binding_handle *b = p->binding_handle;
4261 struct dcerpc_binding_handle *lb = lp->binding_handle;
4263 struct policy_handle lsa_acct_handle;
4264 struct dom_sid *user_sid;
4266 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
4269 struct lsa_EnumAccountRights r;
4270 struct lsa_RightSet rights;
4272 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4274 r.in.handle = lsa_handle;
4275 r.in.sid = user_sid;
4276 r.out.rights = &rights;
4278 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4279 "lsa_EnumAccountRights failed");
4280 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4281 "Expected enum rights for account to fail");
4285 struct lsa_RightSet rights;
4286 struct lsa_StringLarge names[2];
4287 struct lsa_AddAccountRights r;
4289 torture_comment(tctx, "Testing LSA AddAccountRights\n");
4291 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
4292 init_lsa_StringLarge(&names[1], NULL);
4295 rights.names = names;
4297 r.in.handle = lsa_handle;
4298 r.in.sid = user_sid;
4299 r.in.rights = &rights;
4301 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
4302 "lsa_AddAccountRights failed");
4303 torture_assert_ntstatus_ok(tctx, r.out.result,
4304 "Failed to add privileges");
4308 struct lsa_EnumAccounts r;
4309 uint32_t resume_handle = 0;
4310 struct lsa_SidArray lsa_sid_array;
4312 bool found_sid = false;
4314 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4316 r.in.handle = lsa_handle;
4317 r.in.num_entries = 0x1000;
4318 r.in.resume_handle = &resume_handle;
4319 r.out.sids = &lsa_sid_array;
4320 r.out.resume_handle = &resume_handle;
4322 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4323 "lsa_EnumAccounts failed");
4324 torture_assert_ntstatus_ok(tctx, r.out.result,
4325 "Failed to enum accounts");
4327 for (i=0; i < lsa_sid_array.num_sids; i++) {
4328 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4333 torture_assert(tctx, found_sid,
4334 "failed to list privileged account");
4338 struct lsa_EnumAccountRights r;
4339 struct lsa_RightSet user_rights;
4341 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4343 r.in.handle = lsa_handle;
4344 r.in.sid = user_sid;
4345 r.out.rights = &user_rights;
4347 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4348 "lsa_EnumAccountRights failed");
4349 torture_assert_ntstatus_ok(tctx, r.out.result,
4350 "Failed to enum rights for account");
4352 if (user_rights.count < 1) {
4353 torture_warning(tctx, "failed to find newly added rights");
4359 struct lsa_OpenAccount r;
4361 torture_comment(tctx, "Testing LSA OpenAccount\n");
4363 r.in.handle = lsa_handle;
4364 r.in.sid = user_sid;
4365 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4366 r.out.acct_handle = &lsa_acct_handle;
4368 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4369 "lsa_OpenAccount failed");
4370 torture_assert_ntstatus_ok(tctx, r.out.result,
4371 "Failed to open lsa account");
4375 struct lsa_GetSystemAccessAccount r;
4376 uint32_t access_mask;
4378 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4380 r.in.handle = &lsa_acct_handle;
4381 r.out.access_mask = &access_mask;
4383 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4384 "lsa_GetSystemAccessAccount failed");
4385 torture_assert_ntstatus_ok(tctx, r.out.result,
4386 "Failed to get lsa system access account");
4392 torture_comment(tctx, "Testing LSA Close\n");
4394 r.in.handle = &lsa_acct_handle;
4395 r.out.handle = &lsa_acct_handle;
4397 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(lb, tctx, &r),
4398 "lsa_Close failed");
4399 torture_assert_ntstatus_ok(tctx, r.out.result,
4400 "Failed to close lsa");
4404 struct samr_DeleteUser r;
4406 torture_comment(tctx, "Testing SAMR DeleteUser\n");
4408 r.in.user_handle = user_handle;
4409 r.out.user_handle = user_handle;
4411 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &r),
4412 "DeleteUser failed");
4413 torture_assert_ntstatus_ok(tctx, r.out.result,
4414 "DeleteUser failed");
4418 struct lsa_EnumAccounts r;
4419 uint32_t resume_handle = 0;
4420 struct lsa_SidArray lsa_sid_array;
4422 bool found_sid = false;
4424 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4426 r.in.handle = lsa_handle;
4427 r.in.num_entries = 0x1000;
4428 r.in.resume_handle = &resume_handle;
4429 r.out.sids = &lsa_sid_array;
4430 r.out.resume_handle = &resume_handle;
4432 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4433 "lsa_EnumAccounts failed");
4434 torture_assert_ntstatus_ok(tctx, r.out.result,
4435 "Failed to enum accounts");
4437 for (i=0; i < lsa_sid_array.num_sids; i++) {
4438 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4443 torture_assert(tctx, found_sid,
4444 "failed to list privileged account");
4448 struct lsa_EnumAccountRights r;
4449 struct lsa_RightSet user_rights;
4451 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4453 r.in.handle = lsa_handle;
4454 r.in.sid = user_sid;
4455 r.out.rights = &user_rights;
4457 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4458 "lsa_EnumAccountRights failed");
4459 torture_assert_ntstatus_ok(tctx, r.out.result,
4460 "Failed to enum rights for account");
4462 if (user_rights.count < 1) {
4463 torture_warning(tctx, "failed to find newly added rights");
4469 struct lsa_OpenAccount r;
4471 torture_comment(tctx, "Testing LSA OpenAccount\n");
4473 r.in.handle = lsa_handle;
4474 r.in.sid = user_sid;
4475 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4476 r.out.acct_handle = &lsa_acct_handle;
4478 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4479 "lsa_OpenAccount failed");
4480 torture_assert_ntstatus_ok(tctx, r.out.result,
4481 "Failed to open lsa account");
4485 struct lsa_GetSystemAccessAccount r;
4486 uint32_t access_mask;
4488 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4490 r.in.handle = &lsa_acct_handle;
4491 r.out.access_mask = &access_mask;
4493 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4494 "lsa_GetSystemAccessAccount failed");
4495 torture_assert_ntstatus_ok(tctx, r.out.result,
4496 "Failed to get lsa system access account");
4500 struct lsa_DeleteObject r;
4502 torture_comment(tctx, "Testing LSA DeleteObject\n");
4504 r.in.handle = &lsa_acct_handle;
4505 r.out.handle = &lsa_acct_handle;
4507 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(lb, tctx, &r),
4508 "lsa_DeleteObject failed");
4509 torture_assert_ntstatus_ok(tctx, r.out.result,
4510 "Failed to delete object");
4514 struct lsa_EnumAccounts r;
4515 uint32_t resume_handle = 0;
4516 struct lsa_SidArray lsa_sid_array;
4518 bool found_sid = false;
4520 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4522 r.in.handle = lsa_handle;
4523 r.in.num_entries = 0x1000;
4524 r.in.resume_handle = &resume_handle;
4525 r.out.sids = &lsa_sid_array;
4526 r.out.resume_handle = &resume_handle;
4528 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4529 "lsa_EnumAccounts failed");
4530 torture_assert_ntstatus_ok(tctx, r.out.result,
4531 "Failed to enum accounts");
4533 for (i=0; i < lsa_sid_array.num_sids; i++) {
4534 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4539 torture_assert(tctx, !found_sid,
4540 "should not have listed privileged account");
4544 struct lsa_EnumAccountRights r;
4545 struct lsa_RightSet user_rights;
4547 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4549 r.in.handle = lsa_handle;
4550 r.in.sid = user_sid;
4551 r.out.rights = &user_rights;
4553 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4554 "lsa_EnumAccountRights failed");
4555 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4556 "Failed to enum rights for account");
4562 static bool test_user_ops(struct dcerpc_pipe *p,
4563 struct torture_context *tctx,
4564 struct policy_handle *user_handle,
4565 struct policy_handle *domain_handle,
4566 const struct dom_sid *domain_sid,
4567 uint32_t base_acct_flags,
4568 const char *base_acct_name, enum torture_samr_choice which_ops,
4569 struct cli_credentials *machine_credentials)
4571 char *password = NULL;
4572 struct samr_QueryUserInfo q;
4573 union samr_UserInfo *info;
4575 struct dcerpc_binding_handle *b = p->binding_handle;
4580 const uint32_t password_fields[] = {
4581 SAMR_FIELD_NT_PASSWORD_PRESENT,
4582 SAMR_FIELD_LM_PASSWORD_PRESENT,
4583 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
4587 status = test_LookupName(b, tctx, domain_handle, base_acct_name, &rid);
4588 if (!NT_STATUS_IS_OK(status)) {
4592 switch (which_ops) {
4593 case TORTURE_SAMR_USER_ATTRIBUTES:
4594 if (!test_QuerySecurity(b, tctx, user_handle)) {
4598 if (!test_QueryUserInfo(b, tctx, user_handle)) {
4602 if (!test_QueryUserInfo2(b, tctx, user_handle)) {
4606 if (!test_SetUserInfo(b, tctx, user_handle, base_acct_flags,
4611 if (!test_GetUserPwInfo(b, tctx, user_handle)) {
4615 if (!test_TestPrivateFunctionsUser(b, tctx, user_handle)) {
4619 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
4623 case TORTURE_SAMR_PASSWORDS:
4624 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
4625 char simple_pass[9];
4626 char *v = generate_random_str(tctx, 1);
4628 ZERO_STRUCT(simple_pass);
4629 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4631 torture_comment(tctx, "Testing machine account password policy rules\n");
4633 /* Workstation trust accounts don't seem to need to honour password quality policy */
4634 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4638 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
4642 /* reset again, to allow another 'user' password change */
4643 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4647 /* Try a 'short' password */
4648 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
4652 /* Try a compleatly random password */
4653 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
4658 for (i = 0; password_fields[i]; i++) {
4659 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
4663 /* check it was set right */
4664 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4669 for (i = 0; password_fields[i]; i++) {
4670 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
4674 /* check it was set right */
4675 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4680 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
4684 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
4688 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
4692 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4696 for (i = 0; password_fields[i]; i++) {
4698 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
4699 /* we need to skip as that would break
4700 * the ChangePasswordUser3 verify */
4704 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
4708 /* check it was set right */
4709 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4714 q.in.user_handle = user_handle;
4718 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
4719 "QueryUserInfo failed");
4720 if (!NT_STATUS_IS_OK(q.out.result)) {
4721 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4722 q.in.level, nt_errstr(q.out.result));
4725 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4726 if ((info->info5.acct_flags) != expected_flags) {
4727 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4728 info->info5.acct_flags,
4731 if (!torture_setting_bool(tctx, "samba3", false)) {
4735 if (info->info5.rid != rid) {
4736 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
4737 info->info5.rid, rid);
4744 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
4746 /* test last password change timestamp behaviour */
4747 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
4749 user_handle, &password,
4750 machine_credentials)) {
4755 torture_comment(tctx, "pwdLastSet test succeeded\n");
4757 torture_warning(tctx, "pwdLastSet test failed\n");
4762 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
4764 /* test bad pwd count change behaviour */
4765 if (!test_Password_badpwdcount_wrap(p, tctx, base_acct_flags,
4768 user_handle, &password,
4769 machine_credentials)) {
4774 torture_comment(tctx, "badPwdCount test succeeded\n");
4776 torture_warning(tctx, "badPwdCount test failed\n");
4781 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
4783 if (!test_Password_lockout_wrap(p, tctx, base_acct_flags,
4786 user_handle, &password,
4787 machine_credentials))
4793 torture_comment(tctx, "lockout test succeeded\n");
4795 torture_warning(tctx, "lockout test failed\n");
4801 case TORTURE_SAMR_USER_PRIVILEGES: {
4803 struct dcerpc_pipe *lp;
4804 struct policy_handle *lsa_handle;
4805 struct dcerpc_binding_handle *lb;
4807 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
4808 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
4809 lb = lp->binding_handle;
4811 if (!test_lsa_OpenPolicy2(lb, tctx, &lsa_handle)) {
4815 if (!test_DeleteUser_with_privs(p, lp, tctx,
4816 domain_handle, lsa_handle, user_handle,
4818 machine_credentials)) {
4822 if (!test_lsa_Close(lb, tctx, lsa_handle)) {
4827 torture_warning(tctx, "privileged user delete test failed\n");
4832 case TORTURE_SAMR_OTHER:
4833 case TORTURE_SAMR_MANY_ACCOUNTS:
4834 case TORTURE_SAMR_MANY_GROUPS:
4835 case TORTURE_SAMR_MANY_ALIASES:
4836 /* We just need the account to exist */
4842 static bool test_alias_ops(struct dcerpc_binding_handle *b,
4843 struct torture_context *tctx,
4844 struct policy_handle *alias_handle,
4845 const struct dom_sid *domain_sid)
4849 if (!torture_setting_bool(tctx, "samba3", false)) {
4850 if (!test_QuerySecurity(b, tctx, alias_handle)) {
4855 if (!test_QueryAliasInfo(b, tctx, alias_handle)) {
4859 if (!test_SetAliasInfo(b, tctx, alias_handle)) {
4863 if (!test_AddMemberToAlias(b, tctx, alias_handle, domain_sid)) {
4867 if (torture_setting_bool(tctx, "samba3", false) ||
4868 torture_setting_bool(tctx, "samba4", false)) {
4869 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
4873 if (!test_AddMultipleMembersToAlias(b, tctx, alias_handle)) {
4881 static bool test_DeleteUser(struct dcerpc_binding_handle *b,
4882 struct torture_context *tctx,
4883 struct policy_handle *user_handle)
4885 struct samr_DeleteUser d;
4886 torture_comment(tctx, "Testing DeleteUser\n");
4888 d.in.user_handle = user_handle;
4889 d.out.user_handle = user_handle;
4891 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
4892 "DeleteUser failed");
4893 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteUser");
4898 bool test_DeleteUser_byname(struct dcerpc_binding_handle *b,
4899 struct torture_context *tctx,
4900 struct policy_handle *handle, const char *name)
4903 struct samr_DeleteUser d;
4904 struct policy_handle user_handle;
4907 status = test_LookupName(b, tctx, handle, name, &rid);
4908 if (!NT_STATUS_IS_OK(status)) {
4912 status = test_OpenUser_byname(b, tctx, handle, name, &user_handle);
4913 if (!NT_STATUS_IS_OK(status)) {
4917 d.in.user_handle = &user_handle;
4918 d.out.user_handle = &user_handle;
4919 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
4920 "DeleteUser failed");
4921 if (!NT_STATUS_IS_OK(d.out.result)) {
4922 status = d.out.result;
4929 torture_warning(tctx, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
4934 static bool test_DeleteGroup_byname(struct dcerpc_binding_handle *b,
4935 struct torture_context *tctx,
4936 struct policy_handle *handle, const char *name)
4939 struct samr_OpenGroup r;
4940 struct samr_DeleteDomainGroup d;
4941 struct policy_handle group_handle;
4944 status = test_LookupName(b, tctx, handle, name, &rid);
4945 if (!NT_STATUS_IS_OK(status)) {
4949 r.in.domain_handle = handle;
4950 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4952 r.out.group_handle = &group_handle;
4953 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
4954 "OpenGroup failed");
4955 if (!NT_STATUS_IS_OK(r.out.result)) {
4956 status = r.out.result;
4960 d.in.group_handle = &group_handle;
4961 d.out.group_handle = &group_handle;
4962 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
4963 "DeleteDomainGroup failed");
4964 if (!NT_STATUS_IS_OK(d.out.result)) {
4965 status = d.out.result;
4972 torture_warning(tctx, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
4977 static bool test_DeleteAlias_byname(struct dcerpc_binding_handle *b,
4978 struct torture_context *tctx,
4979 struct policy_handle *domain_handle,
4983 struct samr_OpenAlias r;
4984 struct samr_DeleteDomAlias d;
4985 struct policy_handle alias_handle;
4988 torture_comment(tctx, "Testing DeleteAlias_byname\n");
4990 status = test_LookupName(b, tctx, domain_handle, name, &rid);
4991 if (!NT_STATUS_IS_OK(status)) {
4995 r.in.domain_handle = domain_handle;
4996 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4998 r.out.alias_handle = &alias_handle;
4999 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5000 "OpenAlias failed");
5001 if (!NT_STATUS_IS_OK(r.out.result)) {
5002 status = r.out.result;
5006 d.in.alias_handle = &alias_handle;
5007 d.out.alias_handle = &alias_handle;
5008 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5009 "DeleteDomAlias failed");
5010 if (!NT_STATUS_IS_OK(d.out.result)) {
5011 status = d.out.result;
5018 torture_warning(tctx, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
5022 static bool test_DeleteAlias(struct dcerpc_binding_handle *b,
5023 struct torture_context *tctx,
5024 struct policy_handle *alias_handle)
5026 struct samr_DeleteDomAlias d;
5029 torture_comment(tctx, "Testing DeleteAlias\n");
5031 d.in.alias_handle = alias_handle;
5032 d.out.alias_handle = alias_handle;
5034 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5035 "DeleteDomAlias failed");
5036 if (!NT_STATUS_IS_OK(d.out.result)) {
5037 torture_warning(tctx, "DeleteAlias failed - %s\n", nt_errstr(d.out.result));
5044 static bool test_CreateAlias(struct dcerpc_binding_handle *b,
5045 struct torture_context *tctx,
5046 struct policy_handle *domain_handle,
5047 const char *alias_name,
5048 struct policy_handle *alias_handle,
5049 const struct dom_sid *domain_sid,
5052 struct samr_CreateDomAlias r;
5053 struct lsa_String name;
5057 init_lsa_String(&name, alias_name);
5058 r.in.domain_handle = domain_handle;
5059 r.in.alias_name = &name;
5060 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5061 r.out.alias_handle = alias_handle;
5064 torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
5066 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5067 "CreateDomAlias failed");
5069 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5070 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
5071 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
5074 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
5075 nt_errstr(r.out.result));
5080 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ALIAS_EXISTS)) {
5081 if (!test_DeleteAlias_byname(b, tctx, domain_handle, r.in.alias_name->string)) {
5084 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5085 "CreateDomAlias failed");
5088 if (!NT_STATUS_IS_OK(r.out.result)) {
5089 torture_warning(tctx, "CreateAlias failed - %s\n", nt_errstr(r.out.result));
5097 if (!test_alias_ops(b, tctx, alias_handle, domain_sid)) {
5104 static bool test_ChangePassword(struct dcerpc_pipe *p,
5105 struct torture_context *tctx,
5106 const char *acct_name,
5107 struct policy_handle *domain_handle, char **password)
5110 struct dcerpc_binding_handle *b = p->binding_handle;
5116 if (!test_ChangePasswordUser(b, tctx, acct_name, domain_handle, password)) {
5120 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
5124 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
5128 /* test what happens when setting the old password again */
5129 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
5134 char simple_pass[9];
5135 char *v = generate_random_str(tctx, 1);
5137 ZERO_STRUCT(simple_pass);
5138 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5140 /* test what happens when picking a simple password */
5141 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
5146 /* set samr_SetDomainInfo level 1 with min_length 5 */
5148 struct samr_QueryDomainInfo r;
5149 union samr_DomainInfo *info = NULL;
5150 struct samr_SetDomainInfo s;
5151 uint16_t len_old, len;
5152 uint32_t pwd_prop_old;
5153 int64_t min_pwd_age_old;
5157 r.in.domain_handle = domain_handle;
5161 torture_comment(tctx, "Testing samr_QueryDomainInfo level 1\n");
5162 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
5163 "QueryDomainInfo failed");
5164 if (!NT_STATUS_IS_OK(r.out.result)) {
5168 s.in.domain_handle = domain_handle;
5172 /* remember the old min length, so we can reset it */
5173 len_old = s.in.info->info1.min_password_length;
5174 s.in.info->info1.min_password_length = len;
5175 pwd_prop_old = s.in.info->info1.password_properties;
5176 /* turn off password complexity checks for this test */
5177 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
5179 min_pwd_age_old = s.in.info->info1.min_password_age;
5180 s.in.info->info1.min_password_age = 0;
5182 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5183 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5184 "SetDomainInfo failed");
5185 if (!NT_STATUS_IS_OK(s.out.result)) {
5189 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
5191 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
5195 s.in.info->info1.min_password_length = len_old;
5196 s.in.info->info1.password_properties = pwd_prop_old;
5197 s.in.info->info1.min_password_age = min_pwd_age_old;
5199 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5200 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5201 "SetDomainInfo failed");
5202 if (!NT_STATUS_IS_OK(s.out.result)) {
5209 struct samr_OpenUser r;
5210 struct samr_QueryUserInfo q;
5211 union samr_UserInfo *info;
5212 struct samr_LookupNames n;
5213 struct policy_handle user_handle;
5214 struct samr_Ids rids, types;
5216 n.in.domain_handle = domain_handle;
5218 n.in.names = talloc_array(tctx, struct lsa_String, 1);
5219 n.in.names[0].string = acct_name;
5221 n.out.types = &types;
5223 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
5224 "LookupNames failed");
5225 if (!NT_STATUS_IS_OK(n.out.result)) {
5226 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(n.out.result));
5230 r.in.domain_handle = domain_handle;
5231 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5232 r.in.rid = n.out.rids->ids[0];
5233 r.out.user_handle = &user_handle;
5235 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5237 if (!NT_STATUS_IS_OK(r.out.result)) {
5238 torture_warning(tctx, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(r.out.result));
5242 q.in.user_handle = &user_handle;
5246 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5247 "QueryUserInfo failed");
5248 if (!NT_STATUS_IS_OK(q.out.result)) {
5249 torture_warning(tctx, "QueryUserInfo failed - %s\n", nt_errstr(q.out.result));
5253 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
5255 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
5256 info->info5.last_password_change, true)) {
5261 /* we change passwords twice - this has the effect of verifying
5262 they were changed correctly for the final call */
5263 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5267 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5274 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
5275 struct policy_handle *domain_handle,
5276 const char *user_name,
5277 struct policy_handle *user_handle_out,
5278 struct dom_sid *domain_sid,
5279 enum torture_samr_choice which_ops,
5280 struct cli_credentials *machine_credentials,
5284 TALLOC_CTX *user_ctx;
5286 struct samr_CreateUser r;
5287 struct samr_QueryUserInfo q;
5288 union samr_UserInfo *info;
5289 struct samr_DeleteUser d;
5292 /* This call creates a 'normal' account - check that it really does */
5293 const uint32_t acct_flags = ACB_NORMAL;
5294 struct lsa_String name;
5296 struct dcerpc_binding_handle *b = p->binding_handle;
5298 struct policy_handle user_handle;
5299 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5300 init_lsa_String(&name, user_name);
5302 r.in.domain_handle = domain_handle;
5303 r.in.account_name = &name;
5304 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5305 r.out.user_handle = &user_handle;
5308 torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
5310 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5311 "CreateUser failed");
5313 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5314 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5315 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5318 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5319 nt_errstr(r.out.result));
5324 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5325 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5326 talloc_free(user_ctx);
5329 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5330 "CreateUser failed");
5333 if (!NT_STATUS_IS_OK(r.out.result)) {
5334 talloc_free(user_ctx);
5335 torture_warning(tctx, "CreateUser failed - %s\n", nt_errstr(r.out.result));
5340 if (user_handle_out) {
5341 *user_handle_out = user_handle;
5347 q.in.user_handle = &user_handle;
5351 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5352 "QueryUserInfo failed");
5353 if (!NT_STATUS_IS_OK(q.out.result)) {
5354 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5355 q.in.level, nt_errstr(q.out.result));
5358 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
5359 torture_warning(tctx, "QueryUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5360 info->info16.acct_flags,
5366 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5367 domain_sid, acct_flags, name.string, which_ops,
5368 machine_credentials)) {
5372 if (user_handle_out) {
5373 *user_handle_out = user_handle;
5375 torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
5377 d.in.user_handle = &user_handle;
5378 d.out.user_handle = &user_handle;
5380 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5381 "DeleteUser failed");
5382 if (!NT_STATUS_IS_OK(d.out.result)) {
5383 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5390 talloc_free(user_ctx);
5396 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
5397 struct policy_handle *domain_handle,
5398 struct dom_sid *domain_sid,
5399 enum torture_samr_choice which_ops,
5400 struct cli_credentials *machine_credentials)
5402 struct samr_CreateUser2 r;
5403 struct samr_QueryUserInfo q;
5404 union samr_UserInfo *info;
5405 struct samr_DeleteUser d;
5406 struct policy_handle user_handle;
5408 struct lsa_String name;
5411 struct dcerpc_binding_handle *b = p->binding_handle;
5414 uint32_t acct_flags;
5415 const char *account_name;
5417 } account_types[] = {
5418 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
5419 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5420 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5421 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5422 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5423 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5424 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5425 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5426 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5427 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
5428 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5429 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5430 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5431 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5432 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
5435 for (i = 0; account_types[i].account_name; i++) {
5436 TALLOC_CTX *user_ctx;
5437 uint32_t acct_flags = account_types[i].acct_flags;
5438 uint32_t access_granted;
5439 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5440 init_lsa_String(&name, account_types[i].account_name);
5442 r.in.domain_handle = domain_handle;
5443 r.in.account_name = &name;
5444 r.in.acct_flags = acct_flags;
5445 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5446 r.out.user_handle = &user_handle;
5447 r.out.access_granted = &access_granted;
5450 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
5452 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5453 "CreateUser2 failed");
5455 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5456 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5457 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5460 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5461 nt_errstr(r.out.result));
5467 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5468 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5469 talloc_free(user_ctx);
5473 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5474 "CreateUser2 failed");
5477 if (!NT_STATUS_EQUAL(r.out.result, account_types[i].nt_status)) {
5478 torture_warning(tctx, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5479 nt_errstr(r.out.result), nt_errstr(account_types[i].nt_status));
5483 if (NT_STATUS_IS_OK(r.out.result)) {
5484 q.in.user_handle = &user_handle;
5488 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5489 "QueryUserInfo failed");
5490 if (!NT_STATUS_IS_OK(q.out.result)) {
5491 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5492 q.in.level, nt_errstr(q.out.result));
5495 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
5496 if (acct_flags == ACB_NORMAL) {
5497 expected_flags |= ACB_PW_EXPIRED;
5499 if ((info->info5.acct_flags) != expected_flags) {
5500 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5501 info->info5.acct_flags,
5505 switch (acct_flags) {
5507 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
5508 torture_warning(tctx, "QueryUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5509 DOMAIN_RID_DCS, info->info5.primary_gid);
5514 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
5515 torture_warning(tctx, "QueryUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5516 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
5521 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
5522 torture_warning(tctx, "QueryUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5523 DOMAIN_RID_USERS, info->info5.primary_gid);
5530 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5531 domain_sid, acct_flags, name.string, which_ops,
5532 machine_credentials)) {
5536 if (!policy_handle_empty(&user_handle)) {
5537 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
5539 d.in.user_handle = &user_handle;
5540 d.out.user_handle = &user_handle;
5542 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5543 "DeleteUser failed");
5544 if (!NT_STATUS_IS_OK(d.out.result)) {
5545 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5550 talloc_free(user_ctx);
5556 static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
5557 struct torture_context *tctx,
5558 struct policy_handle *handle)
5560 struct samr_QueryAliasInfo r;
5561 union samr_AliasInfo *info;
5562 uint16_t levels[] = {1, 2, 3};
5566 for (i=0;i<ARRAY_SIZE(levels);i++) {
5567 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
5569 r.in.alias_handle = handle;
5570 r.in.level = levels[i];
5573 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &r),
5574 "QueryAliasInfo failed");
5575 if (!NT_STATUS_IS_OK(r.out.result)) {
5576 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
5577 levels[i], nt_errstr(r.out.result));
5585 static bool test_QueryGroupInfo(struct dcerpc_binding_handle *b,
5586 struct torture_context *tctx,
5587 struct policy_handle *handle)
5589 struct samr_QueryGroupInfo r;
5590 union samr_GroupInfo *info;
5591 uint16_t levels[] = {1, 2, 3, 4, 5};
5595 for (i=0;i<ARRAY_SIZE(levels);i++) {
5596 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5598 r.in.group_handle = handle;
5599 r.in.level = levels[i];
5602 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
5603 "QueryGroupInfo failed");
5604 if (!NT_STATUS_IS_OK(r.out.result)) {
5605 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5606 levels[i], nt_errstr(r.out.result));
5614 static bool test_QueryGroupMember(struct dcerpc_binding_handle *b,
5615 struct torture_context *tctx,
5616 struct policy_handle *handle)
5618 struct samr_QueryGroupMember r;
5619 struct samr_RidAttrArray *rids = NULL;
5622 torture_comment(tctx, "Testing QueryGroupMember\n");
5624 r.in.group_handle = handle;
5627 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &r),
5628 "QueryGroupMember failed");
5629 if (!NT_STATUS_IS_OK(r.out.result)) {
5630 torture_warning(tctx, "QueryGroupInfo failed - %s\n", nt_errstr(r.out.result));
5638 static bool test_SetGroupInfo(struct dcerpc_binding_handle *b,
5639 struct torture_context *tctx,
5640 struct policy_handle *handle)
5642 struct samr_QueryGroupInfo r;
5643 union samr_GroupInfo *info;
5644 struct samr_SetGroupInfo s;
5645 uint16_t levels[] = {1, 2, 3, 4};
5646 uint16_t set_ok[] = {0, 1, 1, 1};
5650 for (i=0;i<ARRAY_SIZE(levels);i++) {
5651 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5653 r.in.group_handle = handle;
5654 r.in.level = levels[i];
5657 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
5658 "QueryGroupInfo failed");
5659 if (!NT_STATUS_IS_OK(r.out.result)) {
5660 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5661 levels[i], nt_errstr(r.out.result));
5665 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
5667 s.in.group_handle = handle;
5668 s.in.level = levels[i];
5669 s.in.info = *r.out.info;
5672 /* disabled this, as it changes the name only from the point of view of samr,
5673 but leaves the name from the point of view of w2k3 internals (and ldap). This means
5674 the name is still reserved, so creating the old name fails, but deleting by the old name
5676 if (s.in.level == 2) {
5677 init_lsa_String(&s.in.info->string, "NewName");
5681 if (s.in.level == 4) {
5682 init_lsa_String(&s.in.info->description, "test description");
5685 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetGroupInfo_r(b, tctx, &s),
5686 "SetGroupInfo failed");
5688 if (!NT_STATUS_IS_OK(s.out.result)) {
5689 torture_warning(tctx, "SetGroupInfo level %u failed - %s\n",
5690 r.in.level, nt_errstr(s.out.result));
5695 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
5696 torture_warning(tctx, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5697 r.in.level, nt_errstr(s.out.result));
5707 static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
5708 struct torture_context *tctx,
5709 struct policy_handle *handle)
5711 struct samr_QueryUserInfo r;
5712 union samr_UserInfo *info;
5713 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5714 11, 12, 13, 14, 16, 17, 20, 21};
5718 for (i=0;i<ARRAY_SIZE(levels);i++) {
5719 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
5721 r.in.user_handle = handle;
5722 r.in.level = levels[i];
5725 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
5726 "QueryUserInfo failed");
5727 if (!NT_STATUS_IS_OK(r.out.result)) {
5728 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5729 levels[i], nt_errstr(r.out.result));
5737 static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
5738 struct torture_context *tctx,
5739 struct policy_handle *handle)
5741 struct samr_QueryUserInfo2 r;
5742 union samr_UserInfo *info;
5743 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5744 11, 12, 13, 14, 16, 17, 20, 21};
5748 for (i=0;i<ARRAY_SIZE(levels);i++) {
5749 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
5751 r.in.user_handle = handle;
5752 r.in.level = levels[i];
5755 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r),
5756 "QueryUserInfo2 failed");
5757 if (!NT_STATUS_IS_OK(r.out.result)) {
5758 torture_warning(tctx, "QueryUserInfo2 level %u failed - %s\n",
5759 levels[i], nt_errstr(r.out.result));
5767 static bool test_OpenUser(struct dcerpc_binding_handle *b,
5768 struct torture_context *tctx,
5769 struct policy_handle *handle, uint32_t rid)
5771 struct samr_OpenUser r;
5772 struct policy_handle user_handle;
5775 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5777 r.in.domain_handle = handle;
5778 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5780 r.out.user_handle = &user_handle;
5782 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5784 if (!NT_STATUS_IS_OK(r.out.result)) {
5785 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5789 if (!test_QuerySecurity(b, tctx, &user_handle)) {
5793 if (!test_QueryUserInfo(b, tctx, &user_handle)) {
5797 if (!test_QueryUserInfo2(b, tctx, &user_handle)) {
5801 if (!test_GetUserPwInfo(b, tctx, &user_handle)) {
5805 if (!test_GetGroupsForUser(b, tctx, &user_handle)) {
5809 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
5816 static bool test_OpenGroup(struct dcerpc_binding_handle *b,
5817 struct torture_context *tctx,
5818 struct policy_handle *handle, uint32_t rid)
5820 struct samr_OpenGroup r;
5821 struct policy_handle group_handle;
5824 torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
5826 r.in.domain_handle = handle;
5827 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5829 r.out.group_handle = &group_handle;
5831 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
5832 "OpenGroup failed");
5833 if (!NT_STATUS_IS_OK(r.out.result)) {
5834 torture_warning(tctx, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5838 if (!torture_setting_bool(tctx, "samba3", false)) {
5839 if (!test_QuerySecurity(b, tctx, &group_handle)) {
5844 if (!test_QueryGroupInfo(b, tctx, &group_handle)) {
5848 if (!test_QueryGroupMember(b, tctx, &group_handle)) {
5852 if (!test_samr_handle_Close(b, tctx, &group_handle)) {
5859 static bool test_OpenAlias(struct dcerpc_binding_handle *b,
5860 struct torture_context *tctx,
5861 struct policy_handle *handle, uint32_t rid)
5863 struct samr_OpenAlias r;
5864 struct policy_handle alias_handle;
5867 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
5869 r.in.domain_handle = handle;
5870 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5872 r.out.alias_handle = &alias_handle;
5874 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5875 "OpenAlias failed");
5876 if (!NT_STATUS_IS_OK(r.out.result)) {
5877 torture_warning(tctx, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5881 if (!torture_setting_bool(tctx, "samba3", false)) {
5882 if (!test_QuerySecurity(b, tctx, &alias_handle)) {
5887 if (!test_QueryAliasInfo(b, tctx, &alias_handle)) {
5891 if (!test_GetMembersInAlias(b, tctx, &alias_handle)) {
5895 if (!test_samr_handle_Close(b, tctx, &alias_handle)) {
5902 static bool check_mask(struct dcerpc_binding_handle *b,
5903 struct torture_context *tctx,
5904 struct policy_handle *handle, uint32_t rid,
5905 uint32_t acct_flag_mask)
5907 struct samr_OpenUser r;
5908 struct samr_QueryUserInfo q;
5909 union samr_UserInfo *info;
5910 struct policy_handle user_handle;
5913 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5915 r.in.domain_handle = handle;
5916 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5918 r.out.user_handle = &user_handle;
5920 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5922 if (!NT_STATUS_IS_OK(r.out.result)) {
5923 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5927 q.in.user_handle = &user_handle;
5931 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5932 "QueryUserInfo failed");
5933 if (!NT_STATUS_IS_OK(q.out.result)) {
5934 torture_warning(tctx, "QueryUserInfo level 16 failed - %s\n",
5935 nt_errstr(q.out.result));
5938 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
5939 torture_warning(tctx, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
5940 acct_flag_mask, info->info16.acct_flags, rid);
5945 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
5952 static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle *b,
5953 struct torture_context *tctx,
5954 struct policy_handle *handle)
5956 struct samr_EnumDomainUsers r;
5957 uint32_t mask, resume_handle=0;
5960 struct samr_LookupNames n;
5961 struct samr_LookupRids lr ;
5962 struct lsa_Strings names;
5963 struct samr_Ids rids, types;
5964 struct samr_SamArray *sam = NULL;
5965 uint32_t num_entries = 0;
5967 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
5968 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
5969 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
5972 torture_comment(tctx, "Testing EnumDomainUsers\n");
5974 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
5975 r.in.domain_handle = handle;
5976 r.in.resume_handle = &resume_handle;
5977 r.in.acct_flags = mask = masks[mask_idx];
5978 r.in.max_size = (uint32_t)-1;
5979 r.out.resume_handle = &resume_handle;
5980 r.out.num_entries = &num_entries;
5983 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
5984 "EnumDomainUsers failed");
5985 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
5986 !NT_STATUS_IS_OK(r.out.result)) {
5987 torture_warning(tctx, "EnumDomainUsers failed - %s\n", nt_errstr(r.out.result));
5991 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
5993 if (sam->count == 0) {
5997 for (i=0;i<sam->count;i++) {
5999 if (!check_mask(b, tctx, handle, sam->entries[i].idx, mask)) {
6002 } else if (!test_OpenUser(b, tctx, handle, sam->entries[i].idx)) {
6008 torture_comment(tctx, "Testing LookupNames\n");
6009 n.in.domain_handle = handle;
6010 n.in.num_names = sam->count;
6011 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
6013 n.out.types = &types;
6014 for (i=0;i<sam->count;i++) {
6015 n.in.names[i].string = sam->entries[i].name.string;
6017 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
6018 "LookupNames failed");
6019 if (!NT_STATUS_IS_OK(n.out.result)) {
6020 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(n.out.result));
6025 torture_comment(tctx, "Testing LookupRids\n");
6026 lr.in.domain_handle = handle;
6027 lr.in.num_rids = sam->count;
6028 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
6029 lr.out.names = &names;
6030 lr.out.types = &types;
6031 for (i=0;i<sam->count;i++) {
6032 lr.in.rids[i] = sam->entries[i].idx;
6034 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupRids_r(b, tctx, &lr),
6035 "LookupRids failed");
6036 torture_assert_ntstatus_ok(tctx, lr.out.result, "LookupRids");
6042 try blasting the server with a bunch of sync requests
6044 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
6045 struct policy_handle *handle)
6047 struct samr_EnumDomainUsers r;
6048 uint32_t resume_handle=0;
6050 #define ASYNC_COUNT 100
6051 struct tevent_req *req[ASYNC_COUNT];
6053 if (!torture_setting_bool(tctx, "dangerous", false)) {
6054 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
6057 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
6059 r.in.domain_handle = handle;
6060 r.in.resume_handle = &resume_handle;
6061 r.in.acct_flags = 0;
6062 r.in.max_size = (uint32_t)-1;
6063 r.out.resume_handle = &resume_handle;
6065 for (i=0;i<ASYNC_COUNT;i++) {
6066 req[i] = dcerpc_samr_EnumDomainUsers_r_send(tctx, tctx->ev, p->binding_handle, &r);
6069 for (i=0;i<ASYNC_COUNT;i++) {
6070 tevent_req_poll(req[i], tctx->ev);
6071 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r_recv(req[i], tctx),
6072 talloc_asprintf(tctx, "EnumDomainUsers[%d] failed - %s\n",
6073 i, nt_errstr(r.out.result)));
6076 torture_comment(tctx, "%d async requests OK\n", i);
6081 static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle *b,
6082 struct torture_context *tctx,
6083 struct policy_handle *handle)
6085 struct samr_EnumDomainGroups r;
6086 uint32_t resume_handle=0;
6087 struct samr_SamArray *sam = NULL;
6088 uint32_t num_entries = 0;
6091 bool universal_group_found = false;
6093 torture_comment(tctx, "Testing EnumDomainGroups\n");
6095 r.in.domain_handle = handle;
6096 r.in.resume_handle = &resume_handle;
6097 r.in.max_size = (uint32_t)-1;
6098 r.out.resume_handle = &resume_handle;
6099 r.out.num_entries = &num_entries;
6102 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
6103 "EnumDomainGroups failed");
6104 if (!NT_STATUS_IS_OK(r.out.result)) {
6105 torture_warning(tctx, "EnumDomainGroups failed - %s\n", nt_errstr(r.out.result));
6113 for (i=0;i<sam->count;i++) {
6114 if (!test_OpenGroup(b, tctx, handle, sam->entries[i].idx)) {
6117 if ((ret == true) && (strcasecmp(sam->entries[i].name.string,
6118 "Enterprise Admins") == 0)) {
6119 universal_group_found = true;
6123 /* when we are running this on s4 we should get back at least the
6124 * "Enterprise Admins" universal group. If we don't get a group entry
6125 * at all we probably are performing the test on the builtin domain.
6126 * So ignore this case. */
6127 if (torture_setting_bool(tctx, "samba4", false)) {
6128 if ((sam->count > 0) && (!universal_group_found)) {
6136 static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle *b,
6137 struct torture_context *tctx,
6138 struct policy_handle *handle)
6140 struct samr_EnumDomainAliases r;
6141 uint32_t resume_handle=0;
6142 struct samr_SamArray *sam = NULL;
6143 uint32_t num_entries = 0;
6147 torture_comment(tctx, "Testing EnumDomainAliases\n");
6149 r.in.domain_handle = handle;
6150 r.in.resume_handle = &resume_handle;
6151 r.in.max_size = (uint32_t)-1;
6153 r.out.num_entries = &num_entries;
6154 r.out.resume_handle = &resume_handle;
6156 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
6157 "EnumDomainAliases failed");
6158 if (!NT_STATUS_IS_OK(r.out.result)) {
6159 torture_warning(tctx, "EnumDomainAliases failed - %s\n", nt_errstr(r.out.result));
6167 for (i=0;i<sam->count;i++) {
6168 if (!test_OpenAlias(b, tctx, handle, sam->entries[i].idx)) {
6176 static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle *b,
6177 struct torture_context *tctx,
6178 struct policy_handle *handle)
6180 struct samr_GetDisplayEnumerationIndex r;
6182 uint16_t levels[] = {1, 2, 3, 4, 5};
6183 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6184 struct lsa_String name;
6188 for (i=0;i<ARRAY_SIZE(levels);i++) {
6189 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
6191 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6193 r.in.domain_handle = handle;
6194 r.in.level = levels[i];
6198 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6199 "GetDisplayEnumerationIndex failed");
6202 !NT_STATUS_IS_OK(r.out.result) &&
6203 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6204 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6205 levels[i], nt_errstr(r.out.result));
6209 init_lsa_String(&name, "zzzzzzzz");
6211 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6212 "GetDisplayEnumerationIndex failed");
6214 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6215 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6216 levels[i], nt_errstr(r.out.result));
6224 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle *b,
6225 struct torture_context *tctx,
6226 struct policy_handle *handle)
6228 struct samr_GetDisplayEnumerationIndex2 r;
6230 uint16_t levels[] = {1, 2, 3, 4, 5};
6231 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6232 struct lsa_String name;
6236 for (i=0;i<ARRAY_SIZE(levels);i++) {
6237 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
6239 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6241 r.in.domain_handle = handle;
6242 r.in.level = levels[i];
6246 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6247 "GetDisplayEnumerationIndex2 failed");
6249 !NT_STATUS_IS_OK(r.out.result) &&
6250 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6251 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6252 levels[i], nt_errstr(r.out.result));
6256 init_lsa_String(&name, "zzzzzzzz");
6258 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6259 "GetDisplayEnumerationIndex2 failed");
6260 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6261 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6262 levels[i], nt_errstr(r.out.result));
6270 #define STRING_EQUAL_QUERY(s1, s2, user) \
6271 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6272 /* odd, but valid */ \
6273 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6274 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
6275 #s1, user.string, s1.string, s2.string, __location__); \
6278 #define INT_EQUAL_QUERY(s1, s2, user) \
6280 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6281 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6285 static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle *b,
6286 struct torture_context *tctx,
6287 struct samr_QueryDisplayInfo *querydisplayinfo,
6288 bool *seen_testuser)
6290 struct samr_OpenUser r;
6291 struct samr_QueryUserInfo q;
6292 union samr_UserInfo *info;
6293 struct policy_handle user_handle;
6295 r.in.domain_handle = querydisplayinfo->in.domain_handle;
6296 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6297 for (i = 0; ; i++) {
6298 switch (querydisplayinfo->in.level) {
6300 if (i >= querydisplayinfo->out.info->info1.count) {
6303 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
6306 if (i >= querydisplayinfo->out.info->info2.count) {
6309 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
6315 /* Not interested in validating just the account name */
6319 r.out.user_handle = &user_handle;
6321 switch (querydisplayinfo->in.level) {
6324 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6326 if (!NT_STATUS_IS_OK(r.out.result)) {
6327 torture_warning(tctx, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6332 q.in.user_handle = &user_handle;
6335 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6336 "QueryUserInfo failed");
6337 if (!NT_STATUS_IS_OK(r.out.result)) {
6338 torture_warning(tctx, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6342 switch (querydisplayinfo->in.level) {
6344 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
6345 *seen_testuser = true;
6347 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
6348 info->info21.full_name, info->info21.account_name);
6349 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
6350 info->info21.account_name, info->info21.account_name);
6351 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
6352 info->info21.description, info->info21.account_name);
6353 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
6354 info->info21.rid, info->info21.account_name);
6355 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
6356 info->info21.acct_flags, info->info21.account_name);
6360 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
6361 info->info21.account_name, info->info21.account_name);
6362 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
6363 info->info21.description, info->info21.account_name);
6364 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
6365 info->info21.rid, info->info21.account_name);
6366 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
6367 info->info21.acct_flags, info->info21.account_name);
6369 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
6370 torture_warning(tctx, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6371 info->info21.account_name.string);
6374 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
6375 torture_warning(tctx, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6376 info->info21.account_name.string,
6377 querydisplayinfo->out.info->info2.entries[i].acct_flags,
6378 info->info21.acct_flags);
6385 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6392 static bool test_QueryDisplayInfo(struct dcerpc_binding_handle *b,
6393 struct torture_context *tctx,
6394 struct policy_handle *handle)
6396 struct samr_QueryDisplayInfo r;
6397 struct samr_QueryDomainInfo dom_info;
6398 union samr_DomainInfo *info = NULL;
6400 uint16_t levels[] = {1, 2, 3, 4, 5};
6402 bool seen_testuser = false;
6403 uint32_t total_size;
6404 uint32_t returned_size;
6405 union samr_DispInfo disp_info;
6408 for (i=0;i<ARRAY_SIZE(levels);i++) {
6409 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
6412 r.out.result = STATUS_MORE_ENTRIES;
6413 while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
6414 r.in.domain_handle = handle;
6415 r.in.level = levels[i];
6416 r.in.max_entries = 2;
6417 r.in.buf_size = (uint32_t)-1;
6418 r.out.total_size = &total_size;
6419 r.out.returned_size = &returned_size;
6420 r.out.info = &disp_info;
6422 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6423 "QueryDisplayInfo failed");
6424 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(r.out.result)) {
6425 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6426 levels[i], nt_errstr(r.out.result));
6429 switch (r.in.level) {
6431 if (!test_each_DisplayInfo_user(b, tctx, &r, &seen_testuser)) {
6434 r.in.start_idx += r.out.info->info1.count;
6437 if (!test_each_DisplayInfo_user(b, tctx, &r, NULL)) {
6440 r.in.start_idx += r.out.info->info2.count;
6443 r.in.start_idx += r.out.info->info3.count;
6446 r.in.start_idx += r.out.info->info4.count;
6449 r.in.start_idx += r.out.info->info5.count;
6453 dom_info.in.domain_handle = handle;
6454 dom_info.in.level = 2;
6455 dom_info.out.info = &info;
6457 /* Check number of users returned is correct */
6458 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &dom_info),
6459 "QueryDomainInfo failed");
6460 if (!NT_STATUS_IS_OK(dom_info.out.result)) {
6461 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6462 r.in.level, nt_errstr(dom_info.out.result));
6466 switch (r.in.level) {
6469 if (info->general.num_users < r.in.start_idx) {
6470 /* On AD deployments this numbers don't match
6471 * since QueryDisplayInfo returns universal and
6472 * global groups, QueryDomainInfo only global
6474 if (torture_setting_bool(tctx, "samba3", false)) {
6475 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6476 r.in.start_idx, info->general.num_groups,
6477 info->general.domain_name.string);
6481 if (!seen_testuser) {
6482 struct policy_handle user_handle;
6483 if (NT_STATUS_IS_OK(test_OpenUser_byname(b, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
6484 torture_warning(tctx, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
6485 info->general.domain_name.string);
6487 test_samr_handle_Close(b, tctx, &user_handle);
6493 if (info->general.num_groups != r.in.start_idx) {
6494 /* On AD deployments this numbers don't match
6495 * since QueryDisplayInfo returns universal and
6496 * global groups, QueryDomainInfo only global
6498 if (torture_setting_bool(tctx, "samba3", false)) {
6499 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6500 r.in.start_idx, info->general.num_groups,
6501 info->general.domain_name.string);
6514 static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle *b,
6515 struct torture_context *tctx,
6516 struct policy_handle *handle)
6518 struct samr_QueryDisplayInfo2 r;
6520 uint16_t levels[] = {1, 2, 3, 4, 5};
6522 uint32_t total_size;
6523 uint32_t returned_size;
6524 union samr_DispInfo info;
6526 for (i=0;i<ARRAY_SIZE(levels);i++) {
6527 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
6529 r.in.domain_handle = handle;
6530 r.in.level = levels[i];
6532 r.in.max_entries = 1000;
6533 r.in.buf_size = (uint32_t)-1;
6534 r.out.total_size = &total_size;
6535 r.out.returned_size = &returned_size;
6538 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo2_r(b, tctx, &r),
6539 "QueryDisplayInfo2 failed");
6540 if (!NT_STATUS_IS_OK(r.out.result)) {
6541 torture_warning(tctx, "QueryDisplayInfo2 level %u failed - %s\n",
6542 levels[i], nt_errstr(r.out.result));
6550 static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle *b,
6551 struct torture_context *tctx,
6552 struct policy_handle *handle)
6554 struct samr_QueryDisplayInfo3 r;
6556 uint16_t levels[] = {1, 2, 3, 4, 5};
6558 uint32_t total_size;
6559 uint32_t returned_size;
6560 union samr_DispInfo info;
6562 for (i=0;i<ARRAY_SIZE(levels);i++) {
6563 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
6565 r.in.domain_handle = handle;
6566 r.in.level = levels[i];
6568 r.in.max_entries = 1000;
6569 r.in.buf_size = (uint32_t)-1;
6570 r.out.total_size = &total_size;
6571 r.out.returned_size = &returned_size;
6574 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo3_r(b, tctx, &r),
6575 "QueryDisplayInfo3 failed");
6576 if (!NT_STATUS_IS_OK(r.out.result)) {
6577 torture_warning(tctx, "QueryDisplayInfo3 level %u failed - %s\n",
6578 levels[i], nt_errstr(r.out.result));
6587 static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle *b,
6588 struct torture_context *tctx,
6589 struct policy_handle *handle)
6591 struct samr_QueryDisplayInfo r;
6593 uint32_t total_size;
6594 uint32_t returned_size;
6595 union samr_DispInfo info;
6597 torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
6599 r.in.domain_handle = handle;
6602 r.in.max_entries = 1;
6603 r.in.buf_size = (uint32_t)-1;
6604 r.out.total_size = &total_size;
6605 r.out.returned_size = &returned_size;
6609 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6610 "QueryDisplayInfo failed");
6611 if (NT_STATUS_IS_OK(r.out.result) && *r.out.returned_size != 0) {
6612 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
6613 torture_warning(tctx, "expected idx %d but got %d\n",
6615 r.out.info->info1.entries[0].idx);
6619 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
6620 !NT_STATUS_IS_OK(r.out.result)) {
6621 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6622 r.in.level, nt_errstr(r.out.result));
6627 } while ((NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) ||
6628 NT_STATUS_IS_OK(r.out.result)) &&
6629 *r.out.returned_size != 0);
6634 static bool test_QueryDomainInfo(struct dcerpc_pipe *p,
6635 struct torture_context *tctx,
6636 struct policy_handle *handle)
6638 struct samr_QueryDomainInfo r;
6639 union samr_DomainInfo *info = NULL;
6640 struct samr_SetDomainInfo s;
6641 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6642 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
6645 struct dcerpc_binding_handle *b = p->binding_handle;
6646 const char *domain_comment = talloc_asprintf(tctx,
6647 "Tortured by Samba4 RPC-SAMR: %s",
6648 timestring(tctx, time(NULL)));
6650 s.in.domain_handle = handle;
6652 s.in.info = talloc(tctx, union samr_DomainInfo);
6654 s.in.info->oem.oem_information.string = domain_comment;
6655 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
6656 "SetDomainInfo failed");
6657 if (!NT_STATUS_IS_OK(s.out.result)) {
6658 torture_warning(tctx, "SetDomainInfo level %u (set comment) failed - %s\n",
6659 s.in.level, nt_errstr(s.out.result));
6663 for (i=0;i<ARRAY_SIZE(levels);i++) {
6664 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
6666 r.in.domain_handle = handle;
6667 r.in.level = levels[i];
6670 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
6671 "QueryDomainInfo failed");
6672 if (!NT_STATUS_IS_OK(r.out.result)) {
6673 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6674 r.in.level, nt_errstr(r.out.result));
6679 switch (levels[i]) {
6681 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
6682 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6683 levels[i], info->general.oem_information.string, domain_comment);
6684 if (!torture_setting_bool(tctx, "samba3", false)) {
6688 if (!info->general.primary.string) {
6689 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6692 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
6693 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
6694 if (torture_setting_bool(tctx, "samba3", false)) {
6695 torture_warning(tctx, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
6696 levels[i], info->general.primary.string, dcerpc_server_name(p));
6702 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
6703 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6704 levels[i], info->oem.oem_information.string, domain_comment);
6705 if (!torture_setting_bool(tctx, "samba3", false)) {
6711 if (!info->info6.primary.string) {
6712 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6718 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
6719 torture_warning(tctx, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
6720 levels[i], info->general2.general.oem_information.string, domain_comment);
6721 if (!torture_setting_bool(tctx, "samba3", false)) {
6728 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
6730 s.in.domain_handle = handle;
6731 s.in.level = levels[i];
6734 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
6735 "SetDomainInfo failed");
6737 if (!NT_STATUS_IS_OK(s.out.result)) {
6738 torture_warning(tctx, "SetDomainInfo level %u failed - %s\n",
6739 r.in.level, nt_errstr(s.out.result));
6744 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
6745 torture_warning(tctx, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6746 r.in.level, nt_errstr(s.out.result));
6752 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
6753 "QueryDomainInfo failed");
6754 if (!NT_STATUS_IS_OK(r.out.result)) {
6755 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6756 r.in.level, nt_errstr(r.out.result));
6766 static bool test_QueryDomainInfo2(struct dcerpc_binding_handle *b,
6767 struct torture_context *tctx,
6768 struct policy_handle *handle)
6770 struct samr_QueryDomainInfo2 r;
6771 union samr_DomainInfo *info = NULL;
6772 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6776 for (i=0;i<ARRAY_SIZE(levels);i++) {
6777 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
6779 r.in.domain_handle = handle;
6780 r.in.level = levels[i];
6783 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
6784 "QueryDomainInfo2 failed");
6785 if (!NT_STATUS_IS_OK(r.out.result)) {
6786 torture_warning(tctx, "QueryDomainInfo2 level %u failed - %s\n",
6787 r.in.level, nt_errstr(r.out.result));
6796 /* Test whether querydispinfo level 5 and enumdomgroups return the same
6797 set of group names. */
6798 static bool test_GroupList(struct dcerpc_binding_handle *b,
6799 struct torture_context *tctx,
6800 struct policy_handle *handle)
6802 struct samr_EnumDomainGroups q1;
6803 struct samr_QueryDisplayInfo q2;
6805 uint32_t resume_handle=0;
6806 struct samr_SamArray *sam = NULL;
6807 uint32_t num_entries = 0;
6810 uint32_t total_size;
6811 uint32_t returned_size;
6812 union samr_DispInfo info;
6815 const char **names = NULL;
6817 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
6819 q1.in.domain_handle = handle;
6820 q1.in.resume_handle = &resume_handle;
6822 q1.out.resume_handle = &resume_handle;
6823 q1.out.num_entries = &num_entries;
6826 status = STATUS_MORE_ENTRIES;
6827 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6828 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &q1),
6829 "EnumDomainGroups failed");
6830 status = q1.out.result;
6832 if (!NT_STATUS_IS_OK(status) &&
6833 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6836 for (i=0; i<*q1.out.num_entries; i++) {
6837 add_string_to_array(tctx,
6838 sam->entries[i].name.string,
6839 &names, &num_names);
6843 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
6845 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
6847 q2.in.domain_handle = handle;
6849 q2.in.start_idx = 0;
6850 q2.in.max_entries = 5;
6851 q2.in.buf_size = (uint32_t)-1;
6852 q2.out.total_size = &total_size;
6853 q2.out.returned_size = &returned_size;
6854 q2.out.info = &info;
6856 status = STATUS_MORE_ENTRIES;
6857 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6858 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &q2),
6859 "QueryDisplayInfo failed");
6860 status = q2.out.result;
6861 if (!NT_STATUS_IS_OK(status) &&
6862 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6865 for (i=0; i<q2.out.info->info5.count; i++) {
6867 const char *name = q2.out.info->info5.entries[i].account_name.string;
6869 for (j=0; j<num_names; j++) {
6870 if (names[j] == NULL)
6872 if (strequal(names[j], name)) {
6880 torture_warning(tctx, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
6885 q2.in.start_idx += q2.out.info->info5.count;
6888 if (!NT_STATUS_IS_OK(status)) {
6889 torture_warning(tctx, "QueryDisplayInfo level 5 failed - %s\n",
6894 for (i=0; i<num_names; i++) {
6895 if (names[i] != NULL) {
6896 torture_warning(tctx, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
6905 static bool test_DeleteDomainGroup(struct dcerpc_binding_handle *b,
6906 struct torture_context *tctx,
6907 struct policy_handle *group_handle)
6909 struct samr_DeleteDomainGroup d;
6911 torture_comment(tctx, "Testing DeleteDomainGroup\n");
6913 d.in.group_handle = group_handle;
6914 d.out.group_handle = group_handle;
6916 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
6917 "DeleteDomainGroup failed");
6918 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteDomainGroup");
6923 static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle *b,
6924 struct torture_context *tctx,
6925 struct policy_handle *domain_handle)
6927 struct samr_TestPrivateFunctionsDomain r;
6930 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
6932 r.in.domain_handle = domain_handle;
6934 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsDomain_r(b, tctx, &r),
6935 "TestPrivateFunctionsDomain failed");
6936 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
6941 static bool test_RidToSid(struct dcerpc_binding_handle *b,
6942 struct torture_context *tctx,
6943 struct dom_sid *domain_sid,
6944 struct policy_handle *domain_handle)
6946 struct samr_RidToSid r;
6948 struct dom_sid *calc_sid, *out_sid;
6949 int rids[] = { 0, 42, 512, 10200 };
6952 for (i=0;i<ARRAY_SIZE(rids);i++) {
6953 torture_comment(tctx, "Testing RidToSid\n");
6955 calc_sid = dom_sid_dup(tctx, domain_sid);
6956 r.in.domain_handle = domain_handle;
6958 r.out.sid = &out_sid;
6960 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RidToSid_r(b, tctx, &r),
6962 if (!NT_STATUS_IS_OK(r.out.result)) {
6963 torture_warning(tctx, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(r.out.result));
6966 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
6968 if (!dom_sid_equal(calc_sid, out_sid)) {
6969 torture_warning(tctx, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
6970 dom_sid_string(tctx, out_sid),
6971 dom_sid_string(tctx, calc_sid));
6980 static bool test_GetBootKeyInformation(struct dcerpc_binding_handle *b,
6981 struct torture_context *tctx,
6982 struct policy_handle *domain_handle)
6984 struct samr_GetBootKeyInformation r;
6986 uint32_t unknown = 0;
6989 torture_comment(tctx, "Testing GetBootKeyInformation\n");
6991 r.in.domain_handle = domain_handle;
6992 r.out.unknown = &unknown;
6994 status = dcerpc_samr_GetBootKeyInformation_r(b, tctx, &r);
6995 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(r.out.result)) {
6996 status = r.out.result;
6998 if (!NT_STATUS_IS_OK(status)) {
6999 /* w2k3 seems to fail this sometimes and pass it sometimes */
7000 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
7006 static bool test_AddGroupMember(struct dcerpc_binding_handle *b,
7007 struct torture_context *tctx,
7008 struct policy_handle *domain_handle,
7009 struct policy_handle *group_handle)
7012 struct samr_AddGroupMember r;
7013 struct samr_DeleteGroupMember d;
7014 struct samr_QueryGroupMember q;
7015 struct samr_RidAttrArray *rids = NULL;
7016 struct samr_SetMemberAttributesOfGroup s;
7018 bool found_member = false;
7021 status = test_LookupName(b, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
7022 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
7024 r.in.group_handle = group_handle;
7026 r.in.flags = 0; /* ??? */
7028 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
7030 d.in.group_handle = group_handle;
7033 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7034 "DeleteGroupMember failed");
7035 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, d.out.result, "DeleteGroupMember");
7037 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7038 "AddGroupMember failed");
7039 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7041 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7042 "AddGroupMember failed");
7043 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, r.out.result, "AddGroupMember");
7045 if (torture_setting_bool(tctx, "samba4", false) ||
7046 torture_setting_bool(tctx, "samba3", false)) {
7047 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
7049 /* this one is quite strange. I am using random inputs in the
7050 hope of triggering an error that might give us a clue */
7052 s.in.group_handle = group_handle;
7053 s.in.unknown1 = random();
7054 s.in.unknown2 = random();
7056 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetMemberAttributesOfGroup_r(b, tctx, &s),
7057 "SetMemberAttributesOfGroup failed");
7058 torture_assert_ntstatus_ok(tctx, s.out.result, "SetMemberAttributesOfGroup");
7061 q.in.group_handle = group_handle;
7064 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7065 "QueryGroupMember failed");
7066 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7067 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7069 for (i=0; i < rids->count; i++) {
7070 if (rids->rids[i] == rid) {
7071 found_member = true;
7075 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
7077 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7078 "DeleteGroupMember failed");
7079 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteGroupMember");
7082 found_member = false;
7084 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7085 "QueryGroupMember failed");
7086 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7087 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7089 for (i=0; i < rids->count; i++) {
7090 if (rids->rids[i] == rid) {
7091 found_member = true;
7095 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
7097 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7098 "AddGroupMember failed");
7099 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7105 static bool test_CreateDomainGroup(struct dcerpc_binding_handle *b,
7106 struct torture_context *tctx,
7107 struct policy_handle *domain_handle,
7108 const char *group_name,
7109 struct policy_handle *group_handle,
7110 struct dom_sid *domain_sid,
7113 struct samr_CreateDomainGroup r;
7115 struct lsa_String name;
7118 init_lsa_String(&name, group_name);
7120 r.in.domain_handle = domain_handle;
7122 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7123 r.out.group_handle = group_handle;
7126 torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
7128 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7129 "CreateDomainGroup failed");
7131 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
7132 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
7133 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
7136 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
7137 nt_errstr(r.out.result));
7142 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_GROUP_EXISTS)) {
7143 if (!test_DeleteGroup_byname(b, tctx, domain_handle, r.in.name->string)) {
7144 torture_warning(tctx, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
7145 nt_errstr(r.out.result));
7148 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7149 "CreateDomainGroup failed");
7151 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
7152 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.name->string)) {
7154 torture_warning(tctx, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
7155 nt_errstr(r.out.result));
7158 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7159 "CreateDomainGroup failed");
7161 torture_assert_ntstatus_ok(tctx, r.out.result, "CreateDomainGroup");
7167 if (!test_AddGroupMember(b, tctx, domain_handle, group_handle)) {
7168 torture_warning(tctx, "CreateDomainGroup failed - %s\n", nt_errstr(r.out.result));
7172 if (!test_SetGroupInfo(b, tctx, group_handle)) {
7181 its not totally clear what this does. It seems to accept any sid you like.
7183 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle *b,
7184 struct torture_context *tctx,
7185 struct policy_handle *domain_handle)
7187 struct samr_RemoveMemberFromForeignDomain r;
7189 r.in.domain_handle = domain_handle;
7190 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
7192 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMemberFromForeignDomain_r(b, tctx, &r),
7193 "RemoveMemberFromForeignDomain failed");
7194 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMemberFromForeignDomain");
7199 static bool test_EnumDomainUsers(struct dcerpc_binding_handle *b,
7200 struct torture_context *tctx,
7201 struct policy_handle *domain_handle,
7202 uint32_t *total_num_entries_p)
7205 struct samr_EnumDomainUsers r;
7206 uint32_t resume_handle = 0;
7207 uint32_t num_entries = 0;
7208 uint32_t total_num_entries = 0;
7209 struct samr_SamArray *sam;
7211 r.in.domain_handle = domain_handle;
7212 r.in.acct_flags = 0;
7213 r.in.max_size = (uint32_t)-1;
7214 r.in.resume_handle = &resume_handle;
7217 r.out.num_entries = &num_entries;
7218 r.out.resume_handle = &resume_handle;
7220 torture_comment(tctx, "Testing EnumDomainUsers\n");
7223 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
7224 "EnumDomainUsers failed");
7225 if (NT_STATUS_IS_ERR(r.out.result)) {
7226 torture_assert_ntstatus_ok(tctx, r.out.result,
7227 "failed to enumerate users");
7230 total_num_entries += num_entries;
7231 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7233 if (total_num_entries_p) {
7234 *total_num_entries_p = total_num_entries;
7240 static bool test_EnumDomainGroups(struct dcerpc_binding_handle *b,
7241 struct torture_context *tctx,
7242 struct policy_handle *domain_handle,
7243 uint32_t *total_num_entries_p)
7246 struct samr_EnumDomainGroups r;
7247 uint32_t resume_handle = 0;
7248 uint32_t num_entries = 0;
7249 uint32_t total_num_entries = 0;
7250 struct samr_SamArray *sam;
7252 r.in.domain_handle = domain_handle;
7253 r.in.max_size = (uint32_t)-1;
7254 r.in.resume_handle = &resume_handle;
7257 r.out.num_entries = &num_entries;
7258 r.out.resume_handle = &resume_handle;
7260 torture_comment(tctx, "Testing EnumDomainGroups\n");
7263 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
7264 "EnumDomainGroups failed");
7265 if (NT_STATUS_IS_ERR(r.out.result)) {
7266 torture_assert_ntstatus_ok(tctx, r.out.result,
7267 "failed to enumerate groups");
7270 total_num_entries += num_entries;
7271 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7273 if (total_num_entries_p) {
7274 *total_num_entries_p = total_num_entries;
7280 static bool test_EnumDomainAliases(struct dcerpc_binding_handle *b,
7281 struct torture_context *tctx,
7282 struct policy_handle *domain_handle,
7283 uint32_t *total_num_entries_p)
7286 struct samr_EnumDomainAliases r;
7287 uint32_t resume_handle = 0;
7288 uint32_t num_entries = 0;
7289 uint32_t total_num_entries = 0;
7290 struct samr_SamArray *sam;
7292 r.in.domain_handle = domain_handle;
7293 r.in.max_size = (uint32_t)-1;
7294 r.in.resume_handle = &resume_handle;
7297 r.out.num_entries = &num_entries;
7298 r.out.resume_handle = &resume_handle;
7300 torture_comment(tctx, "Testing EnumDomainAliases\n");
7303 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
7304 "EnumDomainAliases failed");
7305 if (NT_STATUS_IS_ERR(r.out.result)) {
7306 torture_assert_ntstatus_ok(tctx, r.out.result,
7307 "failed to enumerate aliases");
7310 total_num_entries += num_entries;
7311 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7313 if (total_num_entries_p) {
7314 *total_num_entries_p = total_num_entries;
7320 static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle *b,
7321 struct torture_context *tctx,
7322 struct policy_handle *handle,
7324 uint32_t *total_num_entries_p)
7327 struct samr_QueryDisplayInfo r;
7328 uint32_t total_num_entries = 0;
7330 r.in.domain_handle = handle;
7333 r.in.max_entries = (uint32_t)-1;
7334 r.in.buf_size = (uint32_t)-1;
7336 torture_comment(tctx, "Testing QueryDisplayInfo\n");
7339 uint32_t total_size;
7340 uint32_t returned_size;
7341 union samr_DispInfo info;
7343 r.out.total_size = &total_size;
7344 r.out.returned_size = &returned_size;
7347 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7348 "failed to query displayinfo");
7349 if (NT_STATUS_IS_ERR(r.out.result)) {
7350 torture_assert_ntstatus_ok(tctx, r.out.result,
7351 "failed to query displayinfo");
7354 if (*r.out.returned_size == 0) {
7358 switch (r.in.level) {
7360 total_num_entries += info.info1.count;
7361 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
7364 total_num_entries += info.info2.count;
7365 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
7368 total_num_entries += info.info3.count;
7369 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
7372 total_num_entries += info.info4.count;
7373 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
7376 total_num_entries += info.info5.count;
7377 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
7383 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7385 if (total_num_entries_p) {
7386 *total_num_entries_p = total_num_entries;
7392 static bool test_ManyObjects(struct dcerpc_pipe *p,
7393 struct torture_context *tctx,
7394 struct policy_handle *domain_handle,
7395 struct dom_sid *domain_sid,
7396 struct torture_samr_context *ctx)
7398 uint32_t num_total = ctx->num_objects_large_dc;
7399 uint32_t num_enum = 0;
7400 uint32_t num_disp = 0;
7401 uint32_t num_created = 0;
7402 uint32_t num_anounced = 0;
7405 struct dcerpc_binding_handle *b = p->binding_handle;
7407 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
7412 struct samr_QueryDomainInfo2 r;
7413 union samr_DomainInfo *info;
7414 r.in.domain_handle = domain_handle;
7418 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
7419 "QueryDomainInfo2 failed");
7420 torture_assert_ntstatus_ok(tctx, r.out.result,
7421 "failed to query domain info");
7423 switch (ctx->choice) {
7424 case TORTURE_SAMR_MANY_ACCOUNTS:
7425 num_anounced = info->general.num_users;
7427 case TORTURE_SAMR_MANY_GROUPS:
7428 num_anounced = info->general.num_groups;
7430 case TORTURE_SAMR_MANY_ALIASES:
7431 num_anounced = info->general.num_aliases;
7440 for (i=0; i < num_total; i++) {
7442 const char *name = NULL;
7444 switch (ctx->choice) {
7445 case TORTURE_SAMR_MANY_ACCOUNTS:
7446 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
7447 ret &= test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false);
7449 case TORTURE_SAMR_MANY_GROUPS:
7450 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
7451 ret &= test_CreateDomainGroup(b, tctx, domain_handle, name, &handles[i], domain_sid, false);
7453 case TORTURE_SAMR_MANY_ALIASES:
7454 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
7455 ret &= test_CreateAlias(b, tctx, domain_handle, name, &handles[i], domain_sid, false);
7460 if (!policy_handle_empty(&handles[i])) {
7467 switch (ctx->choice) {
7468 case TORTURE_SAMR_MANY_ACCOUNTS:
7469 ret &= test_EnumDomainUsers(b, tctx, domain_handle, &num_enum);
7471 case TORTURE_SAMR_MANY_GROUPS:
7472 ret &= test_EnumDomainGroups(b, tctx, domain_handle, &num_enum);
7474 case TORTURE_SAMR_MANY_ALIASES:
7475 ret &= test_EnumDomainAliases(b, tctx, domain_handle, &num_enum);
7483 switch (ctx->choice) {
7484 case TORTURE_SAMR_MANY_ACCOUNTS:
7485 ret &= test_QueryDisplayInfo_level(b, tctx, domain_handle, 1, &num_disp);
7487 case TORTURE_SAMR_MANY_GROUPS:
7488 ret &= test_QueryDisplayInfo_level(b, tctx, domain_handle, 3, &num_disp);
7490 case TORTURE_SAMR_MANY_ALIASES:
7491 /* no aliases in dispinfo */
7497 /* close or delete */
7499 for (i=0; i < num_total; i++) {
7501 if (policy_handle_empty(&handles[i])) {
7505 if (torture_setting_bool(tctx, "samba3", false)) {
7506 ret &= test_samr_handle_Close(b, tctx, &handles[i]);
7508 switch (ctx->choice) {
7509 case TORTURE_SAMR_MANY_ACCOUNTS:
7510 ret &= test_DeleteUser(b, tctx, &handles[i]);
7512 case TORTURE_SAMR_MANY_GROUPS:
7513 ret &= test_DeleteDomainGroup(b, tctx, &handles[i]);
7515 case TORTURE_SAMR_MANY_ALIASES:
7516 ret &= test_DeleteAlias(b, tctx, &handles[i]);
7524 talloc_free(handles);
7526 if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
7527 torture_comment(tctx,
7528 "unexpected number of results (%u) returned in enum call, expected %u\n",
7529 num_enum, num_anounced + num_created);
7531 torture_comment(tctx,
7532 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
7533 num_disp, num_anounced + num_created);
7538 static bool test_Connect(struct dcerpc_binding_handle *b,
7539 struct torture_context *tctx,
7540 struct policy_handle *handle);
7542 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7543 struct torture_samr_context *ctx, struct dom_sid *sid)
7545 struct samr_OpenDomain r;
7546 struct policy_handle domain_handle;
7547 struct policy_handle alias_handle;
7548 struct policy_handle user_handle;
7549 struct policy_handle group_handle;
7551 struct dcerpc_binding_handle *b = p->binding_handle;
7553 ZERO_STRUCT(alias_handle);
7554 ZERO_STRUCT(user_handle);
7555 ZERO_STRUCT(group_handle);
7556 ZERO_STRUCT(domain_handle);
7558 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
7560 r.in.connect_handle = &ctx->handle;
7561 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7563 r.out.domain_handle = &domain_handle;
7565 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenDomain_r(b, tctx, &r),
7566 "OpenDomain failed");
7567 torture_assert_ntstatus_ok(tctx, r.out.result, "OpenDomain failed");
7569 /* run the domain tests with the main handle closed - this tests
7570 the servers reference counting */
7571 torture_assert(tctx, test_samr_handle_Close(b, tctx, &ctx->handle), "Failed to close SAMR handle");
7573 switch (ctx->choice) {
7574 case TORTURE_SAMR_PASSWORDS:
7575 case TORTURE_SAMR_USER_PRIVILEGES:
7576 if (!torture_setting_bool(tctx, "samba3", false)) {
7577 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7579 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7581 torture_warning(tctx, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
7584 case TORTURE_SAMR_USER_ATTRIBUTES:
7585 if (!torture_setting_bool(tctx, "samba3", false)) {
7586 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7588 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7589 /* This test needs 'complex' users to validate */
7590 ret &= test_QueryDisplayInfo(b, tctx, &domain_handle);
7592 torture_warning(tctx, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
7595 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
7596 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
7597 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
7598 if (!torture_setting_bool(tctx, "samba3", false)) {
7599 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
7601 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
7603 torture_warning(tctx, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx, sid));
7606 case TORTURE_SAMR_MANY_ACCOUNTS:
7607 case TORTURE_SAMR_MANY_GROUPS:
7608 case TORTURE_SAMR_MANY_ALIASES:
7609 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
7611 torture_warning(tctx, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
7614 case TORTURE_SAMR_OTHER:
7615 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7617 torture_warning(tctx, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
7619 if (!torture_setting_bool(tctx, "samba3", false)) {
7620 ret &= test_QuerySecurity(b, tctx, &domain_handle);
7622 ret &= test_RemoveMemberFromForeignDomain(b, tctx, &domain_handle);
7623 ret &= test_CreateAlias(b, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
7624 ret &= test_CreateDomainGroup(b, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
7625 ret &= test_GetAliasMembership(b, tctx, &domain_handle);
7626 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
7627 ret &= test_QueryDomainInfo2(b, tctx, &domain_handle);
7628 ret &= test_EnumDomainUsers_all(b, tctx, &domain_handle);
7629 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
7630 ret &= test_EnumDomainGroups_all(b, tctx, &domain_handle);
7631 ret &= test_EnumDomainAliases_all(b, tctx, &domain_handle);
7632 ret &= test_QueryDisplayInfo2(b, tctx, &domain_handle);
7633 ret &= test_QueryDisplayInfo3(b, tctx, &domain_handle);
7634 ret &= test_QueryDisplayInfo_continue(b, tctx, &domain_handle);
7636 if (torture_setting_bool(tctx, "samba4", false)) {
7637 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
7639 ret &= test_GetDisplayEnumerationIndex(b, tctx, &domain_handle);
7640 ret &= test_GetDisplayEnumerationIndex2(b, tctx, &domain_handle);
7642 ret &= test_GroupList(b, tctx, &domain_handle);
7643 ret &= test_TestPrivateFunctionsDomain(b, tctx, &domain_handle);
7644 ret &= test_RidToSid(b, tctx, sid, &domain_handle);
7645 ret &= test_GetBootKeyInformation(b, tctx, &domain_handle);
7647 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
7652 if (!policy_handle_empty(&user_handle) &&
7653 !test_DeleteUser(b, tctx, &user_handle)) {
7657 if (!policy_handle_empty(&alias_handle) &&
7658 !test_DeleteAlias(b, tctx, &alias_handle)) {
7662 if (!policy_handle_empty(&group_handle) &&
7663 !test_DeleteDomainGroup(b, tctx, &group_handle)) {
7667 torture_assert(tctx, test_samr_handle_Close(b, tctx, &domain_handle), "Failed to close SAMR domain handle");
7669 torture_assert(tctx, test_Connect(b, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
7670 /* reconnect the main handle */
7673 torture_warning(tctx, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
7679 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7680 struct torture_samr_context *ctx, const char *domain)
7682 struct samr_LookupDomain r;
7683 struct dom_sid2 *sid = NULL;
7684 struct lsa_String n1;
7685 struct lsa_String n2;
7687 struct dcerpc_binding_handle *b = p->binding_handle;
7689 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
7691 /* check for correct error codes */
7692 r.in.connect_handle = &ctx->handle;
7693 r.in.domain_name = &n2;
7697 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7698 "LookupDomain failed");
7699 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, r.out.result, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
7701 init_lsa_String(&n2, "xxNODOMAINxx");
7703 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7704 "LookupDomain failed");
7705 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, r.out.result, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
7707 r.in.connect_handle = &ctx->handle;
7709 init_lsa_String(&n1, domain);
7710 r.in.domain_name = &n1;
7712 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7713 "LookupDomain failed");
7714 torture_assert_ntstatus_ok(tctx, r.out.result, "LookupDomain");
7716 if (!test_GetDomPwInfo(p, tctx, &n1)) {
7720 if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
7728 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
7729 struct torture_samr_context *ctx)
7731 struct samr_EnumDomains r;
7732 uint32_t resume_handle = 0;
7733 uint32_t num_entries = 0;
7734 struct samr_SamArray *sam = NULL;
7737 struct dcerpc_binding_handle *b = p->binding_handle;
7739 r.in.connect_handle = &ctx->handle;
7740 r.in.resume_handle = &resume_handle;
7741 r.in.buf_size = (uint32_t)-1;
7742 r.out.resume_handle = &resume_handle;
7743 r.out.num_entries = &num_entries;
7746 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
7747 "EnumDomains failed");
7748 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
7754 for (i=0;i<sam->count;i++) {
7755 if (!test_LookupDomain(p, tctx, ctx,
7756 sam->entries[i].name.string)) {
7761 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
7762 "EnumDomains failed");
7763 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
7769 static bool test_Connect(struct dcerpc_binding_handle *b,
7770 struct torture_context *tctx,
7771 struct policy_handle *handle)
7773 struct samr_Connect r;
7774 struct samr_Connect2 r2;
7775 struct samr_Connect3 r3;
7776 struct samr_Connect4 r4;
7777 struct samr_Connect5 r5;
7778 union samr_ConnectInfo info;
7779 struct policy_handle h;
7780 uint32_t level_out = 0;
7781 bool ret = true, got_handle = false;
7783 torture_comment(tctx, "Testing samr_Connect\n");
7785 r.in.system_name = 0;
7786 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7787 r.out.connect_handle = &h;
7789 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect_r(b, tctx, &r),
7791 if (!NT_STATUS_IS_OK(r.out.result)) {
7792 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(r.out.result));
7799 torture_comment(tctx, "Testing samr_Connect2\n");
7801 r2.in.system_name = NULL;
7802 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7803 r2.out.connect_handle = &h;
7805 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect2_r(b, tctx, &r2),
7807 if (!NT_STATUS_IS_OK(r2.out.result)) {
7808 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(r2.out.result));
7812 test_samr_handle_Close(b, tctx, handle);
7818 torture_comment(tctx, "Testing samr_Connect3\n");
7820 r3.in.system_name = NULL;
7822 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7823 r3.out.connect_handle = &h;
7825 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect3_r(b, tctx, &r3),
7827 if (!NT_STATUS_IS_OK(r3.out.result)) {
7828 torture_warning(tctx, "Connect3 failed - %s\n", nt_errstr(r3.out.result));
7832 test_samr_handle_Close(b, tctx, handle);
7838 torture_comment(tctx, "Testing samr_Connect4\n");
7840 r4.in.system_name = "";
7841 r4.in.client_version = 0;
7842 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7843 r4.out.connect_handle = &h;
7845 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect4_r(b, tctx, &r4),
7847 if (!NT_STATUS_IS_OK(r4.out.result)) {
7848 torture_warning(tctx, "Connect4 failed - %s\n", nt_errstr(r4.out.result));
7852 test_samr_handle_Close(b, tctx, handle);
7858 torture_comment(tctx, "Testing samr_Connect5\n");
7860 info.info1.client_version = 0;
7861 info.info1.unknown2 = 0;
7863 r5.in.system_name = "";
7864 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7866 r5.out.level_out = &level_out;
7867 r5.in.info_in = &info;
7868 r5.out.info_out = &info;
7869 r5.out.connect_handle = &h;
7871 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect5_r(b, tctx, &r5),
7873 if (!NT_STATUS_IS_OK(r5.out.result)) {
7874 torture_warning(tctx, "Connect5 failed - %s\n", nt_errstr(r5.out.result));
7878 test_samr_handle_Close(b, tctx, handle);
7888 static bool test_samr_ValidatePassword(struct dcerpc_pipe *p,
7889 struct torture_context *tctx)
7891 struct samr_ValidatePassword r;
7892 union samr_ValidatePasswordReq req;
7893 union samr_ValidatePasswordRep *repp = NULL;
7895 const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
7897 struct dcerpc_binding_handle *b = p->binding_handle;
7899 torture_comment(tctx, "Testing samr_ValidatePassword\n");
7902 r.in.level = NetValidatePasswordReset;
7907 req.req3.account.string = "non-existant-account-aklsdji";
7909 for (i=0; passwords[i]; i++) {
7910 req.req3.password.string = passwords[i];
7912 status = dcerpc_samr_ValidatePassword_r(b, tctx, &r);
7913 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
7914 torture_skip(tctx, "ValidatePassword not supported by server\n");
7916 torture_assert_ntstatus_ok(tctx, status,
7917 "samr_ValidatePassword failed");
7918 torture_assert_ntstatus_ok(tctx, r.out.result,
7919 "samr_ValidatePassword failed");
7920 torture_comment(tctx, "Server %s password '%s' with code %i\n",
7921 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
7922 req.req3.password.string, repp->ctr3.status);
7928 bool torture_rpc_samr(struct torture_context *torture)
7931 struct dcerpc_pipe *p;
7933 struct torture_samr_context *ctx;
7934 struct dcerpc_binding_handle *b;
7936 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7937 if (!NT_STATUS_IS_OK(status)) {
7940 b = p->binding_handle;
7942 ctx = talloc_zero(torture, struct torture_samr_context);
7944 ctx->choice = TORTURE_SAMR_OTHER;
7946 ret &= test_Connect(b, torture, &ctx->handle);
7948 if (!torture_setting_bool(torture, "samba3", false)) {
7949 ret &= test_QuerySecurity(b, torture, &ctx->handle);
7952 ret &= test_EnumDomains(p, torture, ctx);
7954 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
7956 ret &= test_Shutdown(b, torture, &ctx->handle);
7958 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
7964 bool torture_rpc_samr_users(struct torture_context *torture)
7967 struct dcerpc_pipe *p;
7969 struct torture_samr_context *ctx;
7970 struct dcerpc_binding_handle *b;
7972 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7973 if (!NT_STATUS_IS_OK(status)) {
7976 b = p->binding_handle;
7978 ctx = talloc_zero(torture, struct torture_samr_context);
7980 ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
7982 ret &= test_Connect(b, torture, &ctx->handle);
7984 if (!torture_setting_bool(torture, "samba3", false)) {
7985 ret &= test_QuerySecurity(b, torture, &ctx->handle);
7988 ret &= test_EnumDomains(p, torture, ctx);
7990 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
7992 ret &= test_Shutdown(b, torture, &ctx->handle);
7994 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8000 bool torture_rpc_samr_passwords(struct torture_context *torture)
8003 struct dcerpc_pipe *p;
8005 struct torture_samr_context *ctx;
8006 struct dcerpc_binding_handle *b;
8008 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8009 if (!NT_STATUS_IS_OK(status)) {
8012 b = p->binding_handle;
8014 ctx = talloc_zero(torture, struct torture_samr_context);
8016 ctx->choice = TORTURE_SAMR_PASSWORDS;
8018 ret &= test_Connect(b, torture, &ctx->handle);
8020 ret &= test_EnumDomains(p, torture, ctx);
8022 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8024 ret &= test_samr_ValidatePassword(p, torture);
8029 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
8030 struct dcerpc_pipe *p2,
8031 struct cli_credentials *machine_credentials)
8034 struct dcerpc_pipe *p;
8036 struct torture_samr_context *ctx;
8037 struct dcerpc_binding_handle *b;
8039 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8040 if (!NT_STATUS_IS_OK(status)) {
8043 b = p->binding_handle;
8045 ctx = talloc_zero(torture, struct torture_samr_context);
8047 ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
8048 ctx->machine_credentials = machine_credentials;
8050 ret &= test_Connect(b, torture, &ctx->handle);
8052 ret &= test_EnumDomains(p, torture, ctx);
8054 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8059 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
8061 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
8062 struct torture_rpc_tcase *tcase;
8064 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8066 TEST_ACCOUNT_NAME_PWD);
8068 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
8069 torture_rpc_samr_pwdlastset);
8074 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
8075 struct dcerpc_pipe *p2,
8076 struct cli_credentials *machine_credentials)
8079 struct dcerpc_pipe *p;
8081 struct torture_samr_context *ctx;
8082 struct dcerpc_binding_handle *b;
8084 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8085 if (!NT_STATUS_IS_OK(status)) {
8088 b = p->binding_handle;
8090 ctx = talloc_zero(torture, struct torture_samr_context);
8092 ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
8093 ctx->machine_credentials = machine_credentials;
8095 ret &= test_Connect(b, torture, &ctx->handle);
8097 ret &= test_EnumDomains(p, torture, ctx);
8099 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8104 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
8106 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-USERS-PRIVILEGES");
8107 struct torture_rpc_tcase *tcase;
8109 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8111 TEST_ACCOUNT_NAME_PWD);
8113 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
8114 torture_rpc_samr_users_privileges_delete_user);
8119 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
8120 struct dcerpc_pipe *p2,
8124 struct dcerpc_pipe *p;
8126 struct torture_samr_context *ctx =
8127 talloc_get_type_abort(data, struct torture_samr_context);
8128 struct dcerpc_binding_handle *b;
8130 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8131 if (!NT_STATUS_IS_OK(status)) {
8134 b = p->binding_handle;
8136 ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
8137 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8138 ctx->num_objects_large_dc);
8140 ret &= test_Connect(b, torture, &ctx->handle);
8142 ret &= test_EnumDomains(p, torture, ctx);
8144 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8149 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
8150 struct dcerpc_pipe *p2,
8154 struct dcerpc_pipe *p;
8156 struct torture_samr_context *ctx =
8157 talloc_get_type_abort(data, struct torture_samr_context);
8158 struct dcerpc_binding_handle *b;
8160 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8161 if (!NT_STATUS_IS_OK(status)) {
8164 b = p->binding_handle;
8166 ctx->choice = TORTURE_SAMR_MANY_GROUPS;
8167 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8168 ctx->num_objects_large_dc);
8170 ret &= test_Connect(b, torture, &ctx->handle);
8172 ret &= test_EnumDomains(p, torture, ctx);
8174 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8179 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
8180 struct dcerpc_pipe *p2,
8184 struct dcerpc_pipe *p;
8186 struct torture_samr_context *ctx =
8187 talloc_get_type_abort(data, struct torture_samr_context);
8188 struct dcerpc_binding_handle *b;
8190 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8191 if (!NT_STATUS_IS_OK(status)) {
8194 b = p->binding_handle;
8196 ctx->choice = TORTURE_SAMR_MANY_ALIASES;
8197 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8198 ctx->num_objects_large_dc);
8200 ret &= test_Connect(b, torture, &ctx->handle);
8202 ret &= test_EnumDomains(p, torture, ctx);
8204 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8209 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
8211 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-LARGE-DC");
8212 struct torture_rpc_tcase *tcase;
8213 struct torture_samr_context *ctx;
8215 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
8217 ctx = talloc_zero(suite, struct torture_samr_context);
8218 ctx->num_objects_large_dc = 150;
8220 torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
8221 torture_rpc_samr_many_aliases, ctx);
8222 torture_rpc_tcase_add_test_ex(tcase, "many_groups",
8223 torture_rpc_samr_many_groups, ctx);
8224 torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
8225 torture_rpc_samr_many_accounts, ctx);
8230 static bool torture_rpc_samr_badpwdcount(struct torture_context *torture,
8231 struct dcerpc_pipe *p2,
8232 struct cli_credentials *machine_credentials)
8235 struct dcerpc_pipe *p;
8237 struct torture_samr_context *ctx;
8238 struct dcerpc_binding_handle *b;
8240 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8241 if (!NT_STATUS_IS_OK(status)) {
8244 b = p->binding_handle;
8246 ctx = talloc_zero(torture, struct torture_samr_context);
8248 ctx->choice = TORTURE_SAMR_PASSWORDS_BADPWDCOUNT;
8249 ctx->machine_credentials = machine_credentials;
8251 ret &= test_Connect(b, torture, &ctx->handle);
8253 ret &= test_EnumDomains(p, torture, ctx);
8255 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8260 struct torture_suite *torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX *mem_ctx)
8262 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-BADPWDCOUNT");
8263 struct torture_rpc_tcase *tcase;
8265 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8267 TEST_ACCOUNT_NAME_PWD);
8269 torture_rpc_tcase_add_test_creds(tcase, "badPwdCount",
8270 torture_rpc_samr_badpwdcount);
8275 static bool torture_rpc_samr_lockout(struct torture_context *torture,
8276 struct dcerpc_pipe *p2,
8277 struct cli_credentials *machine_credentials)
8280 struct dcerpc_pipe *p;
8282 struct torture_samr_context *ctx;
8283 struct dcerpc_binding_handle *b;
8285 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8286 if (!NT_STATUS_IS_OK(status)) {
8289 b = p->binding_handle;
8291 ctx = talloc_zero(torture, struct torture_samr_context);
8293 ctx->choice = TORTURE_SAMR_PASSWORDS_LOCKOUT;
8294 ctx->machine_credentials = machine_credentials;
8296 ret &= test_Connect(b, torture, &ctx->handle);
8298 ret &= test_EnumDomains(p, torture, ctx);
8300 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8305 struct torture_suite *torture_rpc_samr_passwords_lockout(TALLOC_CTX *mem_ctx)
8307 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-LOCKOUT");
8308 struct torture_rpc_tcase *tcase;
8310 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8312 TEST_ACCOUNT_NAME_PWD);
8314 torture_rpc_tcase_add_test_creds(tcase, "lockout",
8315 torture_rpc_samr_lockout);