2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7 Copyright (C) Guenther Deschner 2008-2010
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "torture/torture.h"
26 #include "system/time.h"
27 #include "librpc/gen_ndr/lsa.h"
28 #include "librpc/gen_ndr/ndr_netlogon.h"
29 #include "librpc/gen_ndr/ndr_netlogon_c.h"
30 #include "librpc/gen_ndr/ndr_samr_c.h"
31 #include "librpc/gen_ndr/ndr_lsa_c.h"
32 #include "../lib/crypto/crypto.h"
33 #include "libcli/auth/libcli_auth.h"
34 #include "libcli/security/security.h"
35 #include "torture/rpc/torture_rpc.h"
36 #include "param/param.h"
37 #include "auth/gensec/gensec.h"
38 #include "auth/gensec/gensec_proto.h"
39 #include "../libcli/auth/schannel.h"
43 #define TEST_ACCOUNT_NAME "samrtorturetest"
44 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
45 #define TEST_ALIASNAME "samrtorturetestalias"
46 #define TEST_GROUPNAME "samrtorturetestgroup"
47 #define TEST_MACHINENAME "samrtestmach$"
48 #define TEST_DOMAINNAME "samrtestdom$"
50 enum torture_samr_choice {
51 TORTURE_SAMR_PASSWORDS,
52 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
53 TORTURE_SAMR_PASSWORDS_BADPWDCOUNT,
54 TORTURE_SAMR_PASSWORDS_LOCKOUT,
55 TORTURE_SAMR_USER_ATTRIBUTES,
56 TORTURE_SAMR_USER_PRIVILEGES,
58 TORTURE_SAMR_MANY_ACCOUNTS,
59 TORTURE_SAMR_MANY_GROUPS,
60 TORTURE_SAMR_MANY_ALIASES
63 struct torture_samr_context {
64 struct policy_handle handle;
65 struct cli_credentials *machine_credentials;
66 enum torture_samr_choice choice;
67 uint32_t num_objects_large_dc;
70 static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
71 struct torture_context *tctx,
72 struct policy_handle *handle);
74 static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
75 struct torture_context *tctx,
76 struct policy_handle *handle);
78 static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
79 struct torture_context *tctx,
80 struct policy_handle *handle);
82 static bool test_ChangePassword(struct dcerpc_pipe *p,
83 struct torture_context *tctx,
84 const char *acct_name,
85 struct policy_handle *domain_handle, char **password);
87 static void init_lsa_String(struct lsa_String *string, const char *s)
92 static void init_lsa_StringLarge(struct lsa_StringLarge *string, const char *s)
97 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
99 string->length = length;
100 string->size = length;
101 string->array = (uint16_t *)discard_const(s);
104 bool test_samr_handle_Close(struct dcerpc_binding_handle *b,
105 struct torture_context *tctx,
106 struct policy_handle *handle)
110 r.in.handle = handle;
111 r.out.handle = handle;
113 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Close_r(b, tctx, &r),
115 torture_assert_ntstatus_ok(tctx, r.out.result, "Close failed");
120 static bool test_Shutdown(struct dcerpc_binding_handle *b,
121 struct torture_context *tctx,
122 struct policy_handle *handle)
124 struct samr_Shutdown r;
126 if (!torture_setting_bool(tctx, "dangerous", false)) {
127 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
131 r.in.connect_handle = handle;
133 torture_comment(tctx, "Testing samr_Shutdown\n");
135 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Shutdown_r(b, tctx, &r),
137 torture_assert_ntstatus_ok(tctx, r.out.result, "Shutdown failed");
142 static bool test_SetDsrmPassword(struct dcerpc_binding_handle *b,
143 struct torture_context *tctx,
144 struct policy_handle *handle)
146 struct samr_SetDsrmPassword r;
147 struct lsa_String string;
148 struct samr_Password hash;
150 if (!torture_setting_bool(tctx, "dangerous", false)) {
151 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
154 E_md4hash("TeSTDSRM123", hash.hash);
156 init_lsa_String(&string, "Administrator");
162 torture_comment(tctx, "Testing samr_SetDsrmPassword\n");
164 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDsrmPassword_r(b, tctx, &r),
165 "SetDsrmPassword failed");
166 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_SUPPORTED, "SetDsrmPassword failed");
172 static bool test_QuerySecurity(struct dcerpc_binding_handle *b,
173 struct torture_context *tctx,
174 struct policy_handle *handle)
176 struct samr_QuerySecurity r;
177 struct samr_SetSecurity s;
178 struct sec_desc_buf *sdbuf = NULL;
180 r.in.handle = handle;
182 r.out.sdbuf = &sdbuf;
184 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QuerySecurity_r(b, tctx, &r),
185 "QuerySecurity failed");
186 torture_assert_ntstatus_ok(tctx, r.out.result, "QuerySecurity failed");
188 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
190 s.in.handle = handle;
194 if (torture_setting_bool(tctx, "samba4", false)) {
195 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
198 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetSecurity_r(b, tctx, &s),
199 "SetSecurity failed");
200 torture_assert_ntstatus_ok(tctx, r.out.result, "SetSecurity failed");
202 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QuerySecurity_r(b, tctx, &r),
203 "QuerySecurity failed");
204 torture_assert_ntstatus_ok(tctx, r.out.result, "QuerySecurity failed");
210 static bool test_SetUserInfo(struct dcerpc_binding_handle *b, struct torture_context *tctx,
211 struct policy_handle *handle, uint32_t base_acct_flags,
212 const char *base_account_name)
214 struct samr_SetUserInfo s;
215 struct samr_SetUserInfo2 s2;
216 struct samr_QueryUserInfo q;
217 struct samr_QueryUserInfo q0;
218 union samr_UserInfo u;
219 union samr_UserInfo *info;
221 const char *test_account_name;
223 uint32_t user_extra_flags = 0;
225 if (!torture_setting_bool(tctx, "samba3", false)) {
226 if (base_acct_flags == ACB_NORMAL) {
227 /* When created, accounts are expired by default */
228 user_extra_flags = ACB_PW_EXPIRED;
232 s.in.user_handle = handle;
235 s2.in.user_handle = handle;
238 q.in.user_handle = handle;
242 #define TESTCALL(call, r) \
243 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ ##call## _r(b, tctx, &r),\
245 if (!NT_STATUS_IS_OK(r.out.result)) { \
246 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
247 r.in.level, nt_errstr(r.out.result), __location__); \
252 #define STRING_EQUAL(s1, s2, field) \
253 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
254 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
255 #field, s2, __location__); \
260 #define MEM_EQUAL(s1, s2, length, field) \
261 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
262 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
263 #field, (const char *)s2, __location__); \
268 #define INT_EQUAL(i1, i2, field) \
270 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
271 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
276 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
277 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
279 TESTCALL(QueryUserInfo, q) \
281 s2.in.level = lvl1; \
284 ZERO_STRUCT(u.info21); \
285 u.info21.fields_present = fpval; \
287 init_lsa_String(&u.info ## lvl1.field1, value); \
288 TESTCALL(SetUserInfo, s) \
289 TESTCALL(SetUserInfo2, s2) \
290 init_lsa_String(&u.info ## lvl1.field1, ""); \
291 TESTCALL(QueryUserInfo, q); \
293 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
295 TESTCALL(QueryUserInfo, q) \
297 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
300 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
301 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
303 TESTCALL(QueryUserInfo, q) \
305 s2.in.level = lvl1; \
308 ZERO_STRUCT(u.info21); \
309 u.info21.fields_present = fpval; \
311 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
312 TESTCALL(SetUserInfo, s) \
313 TESTCALL(SetUserInfo2, s2) \
314 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
315 TESTCALL(QueryUserInfo, q); \
317 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
319 TESTCALL(QueryUserInfo, q) \
321 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
324 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
325 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
327 TESTCALL(QueryUserInfo, q) \
329 s2.in.level = lvl1; \
332 uint8_t *bits = u.info21.logon_hours.bits; \
333 ZERO_STRUCT(u.info21); \
334 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
335 u.info21.logon_hours.units_per_week = 168; \
336 u.info21.logon_hours.bits = bits; \
338 u.info21.fields_present = fpval; \
340 u.info ## lvl1.field1 = value; \
341 TESTCALL(SetUserInfo, s) \
342 TESTCALL(SetUserInfo2, s2) \
343 u.info ## lvl1.field1 = 0; \
344 TESTCALL(QueryUserInfo, q); \
346 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
348 TESTCALL(QueryUserInfo, q) \
350 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
353 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
354 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
358 do { TESTCALL(QueryUserInfo, q0) } while (0);
360 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
361 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
362 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
365 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
366 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
367 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
368 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
369 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
370 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
371 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
372 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
373 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
374 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
375 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
376 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
377 test_account_name = base_account_name;
378 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
379 SAMR_FIELD_ACCOUNT_NAME);
381 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
382 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
383 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
384 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
385 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
386 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
387 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
388 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
389 SAMR_FIELD_FULL_NAME);
391 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
392 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
393 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
394 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
395 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
396 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
397 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
398 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
399 SAMR_FIELD_FULL_NAME);
401 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
402 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
403 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
404 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
405 SAMR_FIELD_LOGON_SCRIPT);
407 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
408 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
409 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
410 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
411 SAMR_FIELD_PROFILE_PATH);
413 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
414 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
415 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
416 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
417 SAMR_FIELD_HOME_DIRECTORY);
418 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
419 SAMR_FIELD_HOME_DIRECTORY);
421 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
422 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
423 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
424 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
425 SAMR_FIELD_HOME_DRIVE);
426 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
427 SAMR_FIELD_HOME_DRIVE);
429 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
430 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
431 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
432 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
433 SAMR_FIELD_DESCRIPTION);
435 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
436 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
437 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
438 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
439 SAMR_FIELD_WORKSTATIONS);
440 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
441 SAMR_FIELD_WORKSTATIONS);
442 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
443 SAMR_FIELD_WORKSTATIONS);
444 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
445 SAMR_FIELD_WORKSTATIONS);
447 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
448 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
449 SAMR_FIELD_PARAMETERS);
450 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
451 SAMR_FIELD_PARAMETERS);
452 /* also empty user parameters are allowed */
453 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
454 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
455 SAMR_FIELD_PARAMETERS);
456 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
457 SAMR_FIELD_PARAMETERS);
459 /* Samba 3 cannot store country_code and copy_page atm. - gd */
460 if (!torture_setting_bool(tctx, "samba3", false)) {
461 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
462 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
463 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
464 SAMR_FIELD_COUNTRY_CODE);
465 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
466 SAMR_FIELD_COUNTRY_CODE);
468 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
469 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
470 SAMR_FIELD_CODE_PAGE);
471 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
472 SAMR_FIELD_CODE_PAGE);
475 if (!torture_setting_bool(tctx, "samba3", false)) {
476 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
477 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
478 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
479 SAMR_FIELD_ACCT_EXPIRY);
480 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
481 SAMR_FIELD_ACCT_EXPIRY);
482 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
483 SAMR_FIELD_ACCT_EXPIRY);
485 /* Samba 3 can only store seconds / time_t in passdb - gd */
487 unix_to_nt_time(&nt, time(NULL) + __LINE__);
488 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
489 unix_to_nt_time(&nt, time(NULL) + __LINE__);
490 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
491 unix_to_nt_time(&nt, time(NULL) + __LINE__);
492 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
493 unix_to_nt_time(&nt, time(NULL) + __LINE__);
494 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
495 unix_to_nt_time(&nt, time(NULL) + __LINE__);
496 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
499 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
500 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
501 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
502 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
503 SAMR_FIELD_LOGON_HOURS);
505 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
506 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
507 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
509 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
510 (base_acct_flags | ACB_DISABLED),
511 (base_acct_flags | ACB_DISABLED | user_extra_flags),
514 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
515 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
516 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
517 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
519 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
520 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
521 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
525 /* The 'autolock' flag doesn't stick - check this */
526 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
527 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
528 (base_acct_flags | ACB_DISABLED | user_extra_flags),
531 /* Removing the 'disabled' flag doesn't stick - check this */
532 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
534 (base_acct_flags | ACB_DISABLED | user_extra_flags),
538 /* Samba3 cannot store these atm */
539 if (!torture_setting_bool(tctx, "samba3", false)) {
540 /* The 'store plaintext' flag does stick */
541 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
542 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
543 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
545 /* The 'use DES' flag does stick */
546 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
547 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
548 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
550 /* The 'don't require kerberos pre-authentication flag does stick */
551 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
552 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
553 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
555 /* The 'no kerberos PAC required' flag sticks */
556 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
557 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
558 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
561 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
562 (base_acct_flags | ACB_DISABLED),
563 (base_acct_flags | ACB_DISABLED | user_extra_flags),
564 SAMR_FIELD_ACCT_FLAGS);
567 /* these fail with win2003 - it appears you can't set the primary gid?
568 the set succeeds, but the gid isn't changed. Very weird! */
569 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
570 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
571 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
572 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
579 generate a random password for password change tests
581 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
583 size_t len = MAX(8, min_len);
584 char *s = generate_random_password(mem_ctx, len, len+6);
588 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
590 char *s = samr_rand_pass_silent(mem_ctx, min_len);
591 printf("Generated password '%s'\n", s);
597 generate a random password for password change tests
599 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
602 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
603 generate_random_buffer(password.data, password.length);
605 for (i=0; i < len; i++) {
606 if (((uint16_t *)password.data)[i] == 0) {
607 ((uint16_t *)password.data)[i] = 1;
615 generate a random password for password change tests (fixed length)
617 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
619 char *s = generate_random_password(mem_ctx, len, len);
620 printf("Generated password '%s'\n", s);
624 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
625 struct policy_handle *handle, char **password)
628 struct samr_SetUserInfo s;
629 union samr_UserInfo u;
631 DATA_BLOB session_key;
633 struct dcerpc_binding_handle *b = p->binding_handle;
634 struct samr_GetUserPwInfo pwp;
635 struct samr_PwInfo info;
636 int policy_min_pw_len = 0;
637 pwp.in.user_handle = handle;
638 pwp.out.info = &info;
640 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
641 "GetUserPwInfo failed");
642 if (NT_STATUS_IS_OK(pwp.out.result)) {
643 policy_min_pw_len = pwp.out.info->min_password_length;
645 newpass = samr_rand_pass(tctx, policy_min_pw_len);
647 s.in.user_handle = handle;
651 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
652 u.info24.password_expired = 0;
654 status = dcerpc_fetch_session_key(p, &session_key);
655 if (!NT_STATUS_IS_OK(status)) {
656 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
657 s.in.level, nt_errstr(status));
661 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
663 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
665 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
666 "SetUserInfo failed");
667 if (!NT_STATUS_IS_OK(s.out.result)) {
668 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
669 s.in.level, nt_errstr(s.out.result));
679 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
680 struct policy_handle *handle, uint32_t fields_present,
684 struct samr_SetUserInfo s;
685 union samr_UserInfo u;
687 DATA_BLOB session_key;
688 struct dcerpc_binding_handle *b = p->binding_handle;
690 struct samr_GetUserPwInfo pwp;
691 struct samr_PwInfo info;
692 int policy_min_pw_len = 0;
693 pwp.in.user_handle = handle;
694 pwp.out.info = &info;
696 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
697 "GetUserPwInfo failed");
698 if (NT_STATUS_IS_OK(pwp.out.result)) {
699 policy_min_pw_len = pwp.out.info->min_password_length;
701 newpass = samr_rand_pass(tctx, policy_min_pw_len);
703 s.in.user_handle = handle;
709 u.info23.info.fields_present = fields_present;
711 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
713 status = dcerpc_fetch_session_key(p, &session_key);
714 if (!NT_STATUS_IS_OK(status)) {
715 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
716 s.in.level, nt_errstr(status));
720 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
722 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
724 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
725 "SetUserInfo failed");
726 if (!NT_STATUS_IS_OK(s.out.result)) {
727 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
728 s.in.level, nt_errstr(s.out.result));
734 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
736 status = dcerpc_fetch_session_key(p, &session_key);
737 if (!NT_STATUS_IS_OK(status)) {
738 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
739 s.in.level, nt_errstr(status));
743 /* This should break the key nicely */
744 session_key.length--;
745 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
747 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
749 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
750 "SetUserInfo failed");
751 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
752 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
753 s.in.level, nt_errstr(s.out.result));
761 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
762 struct policy_handle *handle, bool makeshort,
766 struct samr_SetUserInfo s;
767 union samr_UserInfo u;
769 DATA_BLOB session_key;
770 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
771 uint8_t confounder[16];
773 struct dcerpc_binding_handle *b = p->binding_handle;
774 struct MD5Context ctx;
775 struct samr_GetUserPwInfo pwp;
776 struct samr_PwInfo info;
777 int policy_min_pw_len = 0;
778 pwp.in.user_handle = handle;
779 pwp.out.info = &info;
781 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
782 "GetUserPwInfo failed");
783 if (NT_STATUS_IS_OK(pwp.out.result)) {
784 policy_min_pw_len = pwp.out.info->min_password_length;
786 if (makeshort && policy_min_pw_len) {
787 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
789 newpass = samr_rand_pass(tctx, policy_min_pw_len);
792 s.in.user_handle = handle;
796 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
797 u.info26.password_expired = 0;
799 status = dcerpc_fetch_session_key(p, &session_key);
800 if (!NT_STATUS_IS_OK(status)) {
801 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
802 s.in.level, nt_errstr(status));
806 generate_random_buffer((uint8_t *)confounder, 16);
809 MD5Update(&ctx, confounder, 16);
810 MD5Update(&ctx, session_key.data, session_key.length);
811 MD5Final(confounded_session_key.data, &ctx);
813 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
814 memcpy(&u.info26.password.data[516], confounder, 16);
816 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
818 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
819 "SetUserInfo failed");
820 if (!NT_STATUS_IS_OK(s.out.result)) {
821 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
822 s.in.level, nt_errstr(s.out.result));
828 /* This should break the key nicely */
829 confounded_session_key.data[0]++;
831 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
832 memcpy(&u.info26.password.data[516], confounder, 16);
834 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
836 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
837 "SetUserInfo failed");
838 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
839 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
840 s.in.level, nt_errstr(s.out.result));
849 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
850 struct policy_handle *handle, uint32_t fields_present,
854 struct samr_SetUserInfo s;
855 union samr_UserInfo u;
857 DATA_BLOB session_key;
858 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
859 struct MD5Context ctx;
860 uint8_t confounder[16];
862 struct dcerpc_binding_handle *b = p->binding_handle;
863 struct samr_GetUserPwInfo pwp;
864 struct samr_PwInfo info;
865 int policy_min_pw_len = 0;
866 pwp.in.user_handle = handle;
867 pwp.out.info = &info;
869 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
870 "GetUserPwInfo failed");
871 if (NT_STATUS_IS_OK(pwp.out.result)) {
872 policy_min_pw_len = pwp.out.info->min_password_length;
874 newpass = samr_rand_pass(tctx, policy_min_pw_len);
876 s.in.user_handle = handle;
882 u.info25.info.fields_present = fields_present;
884 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
886 status = dcerpc_fetch_session_key(p, &session_key);
887 if (!NT_STATUS_IS_OK(status)) {
888 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
889 s.in.level, nt_errstr(status));
893 generate_random_buffer((uint8_t *)confounder, 16);
896 MD5Update(&ctx, confounder, 16);
897 MD5Update(&ctx, session_key.data, session_key.length);
898 MD5Final(confounded_session_key.data, &ctx);
900 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
901 memcpy(&u.info25.password.data[516], confounder, 16);
903 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
905 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
906 "SetUserInfo failed");
907 if (!NT_STATUS_IS_OK(s.out.result)) {
908 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
909 s.in.level, nt_errstr(s.out.result));
915 /* This should break the key nicely */
916 confounded_session_key.data[0]++;
918 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
919 memcpy(&u.info25.password.data[516], confounder, 16);
921 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
923 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
924 "SetUserInfo failed");
925 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
926 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
927 s.in.level, nt_errstr(s.out.result));
934 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
935 struct policy_handle *handle, char **password)
938 struct samr_SetUserInfo s;
939 union samr_UserInfo u;
941 DATA_BLOB session_key;
943 struct dcerpc_binding_handle *b = p->binding_handle;
944 struct samr_GetUserPwInfo pwp;
945 struct samr_PwInfo info;
946 int policy_min_pw_len = 0;
947 uint8_t lm_hash[16], nt_hash[16];
949 pwp.in.user_handle = handle;
950 pwp.out.info = &info;
952 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
953 "GetUserPwInfo failed");
954 if (NT_STATUS_IS_OK(pwp.out.result)) {
955 policy_min_pw_len = pwp.out.info->min_password_length;
957 newpass = samr_rand_pass(tctx, policy_min_pw_len);
959 s.in.user_handle = handle;
965 u.info18.nt_pwd_active = true;
966 u.info18.lm_pwd_active = true;
968 E_md4hash(newpass, nt_hash);
969 E_deshash(newpass, lm_hash);
971 status = dcerpc_fetch_session_key(p, &session_key);
972 if (!NT_STATUS_IS_OK(status)) {
973 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
974 s.in.level, nt_errstr(status));
980 in = data_blob_const(nt_hash, 16);
981 out = data_blob_talloc_zero(tctx, 16);
982 sess_crypt_blob(&out, &in, &session_key, true);
983 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
987 in = data_blob_const(lm_hash, 16);
988 out = data_blob_talloc_zero(tctx, 16);
989 sess_crypt_blob(&out, &in, &session_key, true);
990 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
993 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
995 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
996 "SetUserInfo failed");
997 if (!NT_STATUS_IS_OK(s.out.result)) {
998 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
999 s.in.level, nt_errstr(s.out.result));
1002 *password = newpass;
1008 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
1009 struct policy_handle *handle, uint32_t fields_present,
1013 struct samr_SetUserInfo s;
1014 union samr_UserInfo u;
1016 DATA_BLOB session_key;
1018 struct dcerpc_binding_handle *b = p->binding_handle;
1019 struct samr_GetUserPwInfo pwp;
1020 struct samr_PwInfo info;
1021 int policy_min_pw_len = 0;
1022 uint8_t lm_hash[16], nt_hash[16];
1024 pwp.in.user_handle = handle;
1025 pwp.out.info = &info;
1027 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1028 "GetUserPwInfo failed");
1029 if (NT_STATUS_IS_OK(pwp.out.result)) {
1030 policy_min_pw_len = pwp.out.info->min_password_length;
1032 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1034 s.in.user_handle = handle;
1038 E_md4hash(newpass, nt_hash);
1039 E_deshash(newpass, lm_hash);
1043 u.info21.fields_present = fields_present;
1045 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1046 u.info21.lm_owf_password.length = 16;
1047 u.info21.lm_owf_password.size = 16;
1048 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1049 u.info21.lm_password_set = true;
1052 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1053 u.info21.nt_owf_password.length = 16;
1054 u.info21.nt_owf_password.size = 16;
1055 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1056 u.info21.nt_password_set = true;
1059 status = dcerpc_fetch_session_key(p, &session_key);
1060 if (!NT_STATUS_IS_OK(status)) {
1061 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1062 s.in.level, nt_errstr(status));
1066 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1068 in = data_blob_const(u.info21.lm_owf_password.array,
1069 u.info21.lm_owf_password.length);
1070 out = data_blob_talloc_zero(tctx, 16);
1071 sess_crypt_blob(&out, &in, &session_key, true);
1072 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1075 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1077 in = data_blob_const(u.info21.nt_owf_password.array,
1078 u.info21.nt_owf_password.length);
1079 out = data_blob_talloc_zero(tctx, 16);
1080 sess_crypt_blob(&out, &in, &session_key, true);
1081 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1084 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1086 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1087 "SetUserInfo failed");
1088 if (!NT_STATUS_IS_OK(s.out.result)) {
1089 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
1090 s.in.level, nt_errstr(s.out.result));
1093 *password = newpass;
1096 /* try invalid length */
1097 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1099 u.info21.nt_owf_password.length++;
1101 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1102 "SetUserInfo failed");
1103 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_INVALID_PARAMETER)) {
1104 torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1105 s.in.level, nt_errstr(s.out.result));
1110 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1112 u.info21.lm_owf_password.length++;
1114 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1115 "SetUserInfo failed");
1116 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_INVALID_PARAMETER)) {
1117 torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1118 s.in.level, nt_errstr(s.out.result));
1126 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1127 struct torture_context *tctx,
1128 struct policy_handle *handle,
1130 uint32_t fields_present,
1131 char **password, uint8_t password_expired,
1133 bool *matched_expected_error)
1136 NTSTATUS expected_error = NT_STATUS_OK;
1137 struct samr_SetUserInfo s;
1138 struct samr_SetUserInfo2 s2;
1139 union samr_UserInfo u;
1141 DATA_BLOB session_key;
1142 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1143 struct MD5Context ctx;
1144 uint8_t confounder[16];
1146 struct dcerpc_binding_handle *b = p->binding_handle;
1147 struct samr_GetUserPwInfo pwp;
1148 struct samr_PwInfo info;
1149 int policy_min_pw_len = 0;
1150 const char *comment = NULL;
1151 uint8_t lm_hash[16], nt_hash[16];
1153 pwp.in.user_handle = handle;
1154 pwp.out.info = &info;
1156 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1157 "GetUserPwInfo failed");
1158 if (NT_STATUS_IS_OK(pwp.out.result)) {
1159 policy_min_pw_len = pwp.out.info->min_password_length;
1161 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1164 s2.in.user_handle = handle;
1166 s2.in.level = level;
1168 s.in.user_handle = handle;
1173 if (fields_present & SAMR_FIELD_COMMENT) {
1174 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1181 E_md4hash(newpass, nt_hash);
1182 E_deshash(newpass, lm_hash);
1184 u.info18.nt_pwd_active = true;
1185 u.info18.lm_pwd_active = true;
1186 u.info18.password_expired = password_expired;
1188 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1189 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1193 E_md4hash(newpass, nt_hash);
1194 E_deshash(newpass, lm_hash);
1196 u.info21.fields_present = fields_present;
1197 u.info21.password_expired = password_expired;
1198 u.info21.comment.string = comment;
1200 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1201 u.info21.lm_owf_password.length = 16;
1202 u.info21.lm_owf_password.size = 16;
1203 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1204 u.info21.lm_password_set = true;
1207 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1208 u.info21.nt_owf_password.length = 16;
1209 u.info21.nt_owf_password.size = 16;
1210 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1211 u.info21.nt_password_set = true;
1216 u.info23.info.fields_present = fields_present;
1217 u.info23.info.password_expired = password_expired;
1218 u.info23.info.comment.string = comment;
1220 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1224 u.info24.password_expired = password_expired;
1226 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1230 u.info25.info.fields_present = fields_present;
1231 u.info25.info.password_expired = password_expired;
1232 u.info25.info.comment.string = comment;
1234 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1238 u.info26.password_expired = password_expired;
1240 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1245 status = dcerpc_fetch_session_key(p, &session_key);
1246 if (!NT_STATUS_IS_OK(status)) {
1247 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1248 s.in.level, nt_errstr(status));
1252 generate_random_buffer((uint8_t *)confounder, 16);
1255 MD5Update(&ctx, confounder, 16);
1256 MD5Update(&ctx, session_key.data, session_key.length);
1257 MD5Final(confounded_session_key.data, &ctx);
1263 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1264 out = data_blob_talloc_zero(tctx, 16);
1265 sess_crypt_blob(&out, &in, &session_key, true);
1266 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1270 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1271 out = data_blob_talloc_zero(tctx, 16);
1272 sess_crypt_blob(&out, &in, &session_key, true);
1273 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1278 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1280 in = data_blob_const(u.info21.lm_owf_password.array,
1281 u.info21.lm_owf_password.length);
1282 out = data_blob_talloc_zero(tctx, 16);
1283 sess_crypt_blob(&out, &in, &session_key, true);
1284 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1286 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1288 in = data_blob_const(u.info21.nt_owf_password.array,
1289 u.info21.nt_owf_password.length);
1290 out = data_blob_talloc_zero(tctx, 16);
1291 sess_crypt_blob(&out, &in, &session_key, true);
1292 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1296 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1299 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1302 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1303 memcpy(&u.info25.password.data[516], confounder, 16);
1306 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1307 memcpy(&u.info26.password.data[516], confounder, 16);
1312 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo2_r(b, tctx, &s2),
1313 "SetUserInfo2 failed");
1314 status = s2.out.result;
1316 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1317 "SetUserInfo failed");
1318 status = s.out.result;
1321 if (!NT_STATUS_IS_OK(status)) {
1322 if (fields_present == 0) {
1323 expected_error = NT_STATUS_INVALID_PARAMETER;
1325 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1326 expected_error = NT_STATUS_ACCESS_DENIED;
1330 if (!NT_STATUS_IS_OK(expected_error)) {
1332 torture_assert_ntstatus_equal(tctx,
1334 expected_error, "SetUserInfo2 failed");
1336 torture_assert_ntstatus_equal(tctx,
1338 expected_error, "SetUserInfo failed");
1340 *matched_expected_error = true;
1344 if (!NT_STATUS_IS_OK(status)) {
1345 torture_warning(tctx, "SetUserInfo%s level %u failed - %s\n",
1346 use_setinfo2 ? "2":"", level, nt_errstr(status));
1349 *password = newpass;
1355 static bool test_SetAliasInfo(struct dcerpc_binding_handle *b,
1356 struct torture_context *tctx,
1357 struct policy_handle *handle)
1359 struct samr_SetAliasInfo r;
1360 struct samr_QueryAliasInfo q;
1361 union samr_AliasInfo *info;
1362 uint16_t levels[] = {2, 3};
1366 /* Ignoring switch level 1, as that includes the number of members for the alias
1367 * and setting this to a wrong value might have negative consequences
1370 for (i=0;i<ARRAY_SIZE(levels);i++) {
1371 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1373 r.in.alias_handle = handle;
1374 r.in.level = levels[i];
1375 r.in.info = talloc(tctx, union samr_AliasInfo);
1376 switch (r.in.level) {
1377 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1378 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1379 "Test Description, should test I18N as well"); break;
1380 case ALIASINFOALL: torture_comment(tctx, "ALIASINFOALL ignored\n"); break;
1383 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetAliasInfo_r(b, tctx, &r),
1384 "SetAliasInfo failed");
1385 if (!NT_STATUS_IS_OK(r.out.result)) {
1386 torture_warning(tctx, "SetAliasInfo level %u failed - %s\n",
1387 levels[i], nt_errstr(r.out.result));
1391 q.in.alias_handle = handle;
1392 q.in.level = levels[i];
1395 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &q),
1396 "QueryAliasInfo failed");
1397 if (!NT_STATUS_IS_OK(q.out.result)) {
1398 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
1399 levels[i], nt_errstr(q.out.result));
1407 static bool test_GetGroupsForUser(struct dcerpc_binding_handle *b,
1408 struct torture_context *tctx,
1409 struct policy_handle *user_handle)
1411 struct samr_GetGroupsForUser r;
1412 struct samr_RidWithAttributeArray *rids = NULL;
1414 torture_comment(tctx, "Testing GetGroupsForUser\n");
1416 r.in.user_handle = user_handle;
1419 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetGroupsForUser_r(b, tctx, &r),
1420 "GetGroupsForUser failed");
1421 torture_assert_ntstatus_ok(tctx, r.out.result, "GetGroupsForUser failed");
1427 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1428 struct lsa_String *domain_name)
1430 struct samr_GetDomPwInfo r;
1431 struct samr_PwInfo info;
1432 struct dcerpc_binding_handle *b = p->binding_handle;
1434 r.in.domain_name = domain_name;
1437 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1439 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1440 "GetDomPwInfo failed");
1441 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1443 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1444 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1446 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1447 "GetDomPwInfo failed");
1448 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1450 r.in.domain_name->string = "\\\\__NONAME__";
1451 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1453 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1454 "GetDomPwInfo failed");
1455 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1457 r.in.domain_name->string = "\\\\Builtin";
1458 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1460 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1461 "GetDomPwInfo failed");
1462 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1467 static bool test_GetUserPwInfo(struct dcerpc_binding_handle *b,
1468 struct torture_context *tctx,
1469 struct policy_handle *handle)
1471 struct samr_GetUserPwInfo r;
1472 struct samr_PwInfo info;
1474 torture_comment(tctx, "Testing GetUserPwInfo\n");
1476 r.in.user_handle = handle;
1479 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &r),
1480 "GetUserPwInfo failed");
1481 torture_assert_ntstatus_ok(tctx, r.out.result, "GetUserPwInfo");
1486 static NTSTATUS test_LookupName(struct dcerpc_binding_handle *b,
1487 struct torture_context *tctx,
1488 struct policy_handle *domain_handle, const char *name,
1492 struct samr_LookupNames n;
1493 struct lsa_String sname[2];
1494 struct samr_Ids rids, types;
1496 init_lsa_String(&sname[0], name);
1498 n.in.domain_handle = domain_handle;
1502 n.out.types = &types;
1503 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1504 if (!NT_STATUS_IS_OK(status)) {
1507 if (NT_STATUS_IS_OK(n.out.result)) {
1508 *rid = n.out.rids->ids[0];
1510 return n.out.result;
1513 init_lsa_String(&sname[1], "xxNONAMExx");
1515 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1516 if (!NT_STATUS_IS_OK(status)) {
1519 if (!NT_STATUS_EQUAL(n.out.result, STATUS_SOME_UNMAPPED)) {
1520 torture_warning(tctx, "LookupNames[2] failed - %s\n", nt_errstr(n.out.result));
1521 if (NT_STATUS_IS_OK(n.out.result)) {
1522 return NT_STATUS_UNSUCCESSFUL;
1524 return n.out.result;
1528 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1529 if (!NT_STATUS_IS_OK(status)) {
1532 if (!NT_STATUS_IS_OK(n.out.result)) {
1533 torture_warning(tctx, "LookupNames[0] failed - %s\n", nt_errstr(status));
1534 return n.out.result;
1537 init_lsa_String(&sname[0], "xxNONAMExx");
1539 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1540 if (!NT_STATUS_IS_OK(status)) {
1543 if (!NT_STATUS_EQUAL(n.out.result, NT_STATUS_NONE_MAPPED)) {
1544 torture_warning(tctx, "LookupNames[1 bad name] failed - %s\n", nt_errstr(n.out.result));
1545 if (NT_STATUS_IS_OK(n.out.result)) {
1546 return NT_STATUS_UNSUCCESSFUL;
1548 return n.out.result;
1551 init_lsa_String(&sname[0], "xxNONAMExx");
1552 init_lsa_String(&sname[1], "xxNONAME2xx");
1554 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1555 if (!NT_STATUS_IS_OK(status)) {
1558 if (!NT_STATUS_EQUAL(n.out.result, NT_STATUS_NONE_MAPPED)) {
1559 torture_warning(tctx, "LookupNames[2 bad names] failed - %s\n", nt_errstr(n.out.result));
1560 if (NT_STATUS_IS_OK(n.out.result)) {
1561 return NT_STATUS_UNSUCCESSFUL;
1563 return n.out.result;
1566 return NT_STATUS_OK;
1569 static NTSTATUS test_OpenUser_byname(struct dcerpc_binding_handle *b,
1570 struct torture_context *tctx,
1571 struct policy_handle *domain_handle,
1572 const char *name, struct policy_handle *user_handle)
1575 struct samr_OpenUser r;
1578 status = test_LookupName(b, tctx, domain_handle, name, &rid);
1579 if (!NT_STATUS_IS_OK(status)) {
1583 r.in.domain_handle = domain_handle;
1584 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1586 r.out.user_handle = user_handle;
1587 status = dcerpc_samr_OpenUser_r(b, tctx, &r);
1588 if (!NT_STATUS_IS_OK(status)) {
1591 if (!NT_STATUS_IS_OK(r.out.result)) {
1592 torture_warning(tctx, "OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(r.out.result));
1595 return r.out.result;
1599 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
1600 struct torture_context *tctx,
1601 struct policy_handle *handle)
1604 struct samr_ChangePasswordUser r;
1606 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1607 struct policy_handle user_handle;
1608 char *oldpass = "test";
1609 char *newpass = "test2";
1610 uint8_t old_nt_hash[16], new_nt_hash[16];
1611 uint8_t old_lm_hash[16], new_lm_hash[16];
1613 status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
1614 if (!NT_STATUS_IS_OK(status)) {
1618 torture_comment(tctx, "Testing ChangePasswordUser for user 'testuser'\n");
1620 torture_comment(tctx, "old password: %s\n", oldpass);
1621 torture_comment(tctx, "new password: %s\n", newpass);
1623 E_md4hash(oldpass, old_nt_hash);
1624 E_md4hash(newpass, new_nt_hash);
1625 E_deshash(oldpass, old_lm_hash);
1626 E_deshash(newpass, new_lm_hash);
1628 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1629 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1630 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1631 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1632 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1633 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1635 r.in.handle = &user_handle;
1636 r.in.lm_present = 1;
1637 r.in.old_lm_crypted = &hash1;
1638 r.in.new_lm_crypted = &hash2;
1639 r.in.nt_present = 1;
1640 r.in.old_nt_crypted = &hash3;
1641 r.in.new_nt_crypted = &hash4;
1642 r.in.cross1_present = 1;
1643 r.in.nt_cross = &hash5;
1644 r.in.cross2_present = 1;
1645 r.in.lm_cross = &hash6;
1647 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1648 "ChangePasswordUser failed");
1649 if (!NT_STATUS_IS_OK(r.out.result)) {
1650 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(r.out.result));
1654 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1662 static bool test_ChangePasswordUser(struct dcerpc_binding_handle *b,
1663 struct torture_context *tctx,
1664 const char *acct_name,
1665 struct policy_handle *handle, char **password)
1668 struct samr_ChangePasswordUser r;
1670 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1671 struct policy_handle user_handle;
1673 uint8_t old_nt_hash[16], new_nt_hash[16];
1674 uint8_t old_lm_hash[16], new_lm_hash[16];
1675 bool changed = true;
1678 struct samr_GetUserPwInfo pwp;
1679 struct samr_PwInfo info;
1680 int policy_min_pw_len = 0;
1682 status = test_OpenUser_byname(b, tctx, handle, acct_name, &user_handle);
1683 if (!NT_STATUS_IS_OK(status)) {
1686 pwp.in.user_handle = &user_handle;
1687 pwp.out.info = &info;
1689 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1690 "GetUserPwInfo failed");
1691 if (NT_STATUS_IS_OK(pwp.out.result)) {
1692 policy_min_pw_len = pwp.out.info->min_password_length;
1694 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1696 torture_comment(tctx, "Testing ChangePasswordUser\n");
1698 torture_assert(tctx, *password != NULL,
1699 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1701 oldpass = *password;
1703 E_md4hash(oldpass, old_nt_hash);
1704 E_md4hash(newpass, new_nt_hash);
1705 E_deshash(oldpass, old_lm_hash);
1706 E_deshash(newpass, new_lm_hash);
1708 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1709 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1710 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1711 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1712 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1713 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1715 r.in.user_handle = &user_handle;
1716 r.in.lm_present = 1;
1717 /* Break the LM hash */
1719 r.in.old_lm_crypted = &hash1;
1720 r.in.new_lm_crypted = &hash2;
1721 r.in.nt_present = 1;
1722 r.in.old_nt_crypted = &hash3;
1723 r.in.new_nt_crypted = &hash4;
1724 r.in.cross1_present = 1;
1725 r.in.nt_cross = &hash5;
1726 r.in.cross2_present = 1;
1727 r.in.lm_cross = &hash6;
1729 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1730 "ChangePasswordUser failed");
1731 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_WRONG_PASSWORD,
1732 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1734 /* Unbreak the LM hash */
1737 r.in.user_handle = &user_handle;
1738 r.in.lm_present = 1;
1739 r.in.old_lm_crypted = &hash1;
1740 r.in.new_lm_crypted = &hash2;
1741 /* Break the NT hash */
1743 r.in.nt_present = 1;
1744 r.in.old_nt_crypted = &hash3;
1745 r.in.new_nt_crypted = &hash4;
1746 r.in.cross1_present = 1;
1747 r.in.nt_cross = &hash5;
1748 r.in.cross2_present = 1;
1749 r.in.lm_cross = &hash6;
1751 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1752 "ChangePasswordUser failed");
1753 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_WRONG_PASSWORD,
1754 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1756 /* Unbreak the NT hash */
1759 r.in.user_handle = &user_handle;
1760 r.in.lm_present = 1;
1761 r.in.old_lm_crypted = &hash1;
1762 r.in.new_lm_crypted = &hash2;
1763 r.in.nt_present = 1;
1764 r.in.old_nt_crypted = &hash3;
1765 r.in.new_nt_crypted = &hash4;
1766 r.in.cross1_present = 1;
1767 r.in.nt_cross = &hash5;
1768 r.in.cross2_present = 1;
1769 /* Break the LM cross */
1771 r.in.lm_cross = &hash6;
1773 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1774 "ChangePasswordUser failed");
1775 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
1776 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(r.out.result));
1780 /* Unbreak the LM cross */
1783 r.in.user_handle = &user_handle;
1784 r.in.lm_present = 1;
1785 r.in.old_lm_crypted = &hash1;
1786 r.in.new_lm_crypted = &hash2;
1787 r.in.nt_present = 1;
1788 r.in.old_nt_crypted = &hash3;
1789 r.in.new_nt_crypted = &hash4;
1790 r.in.cross1_present = 1;
1791 /* Break the NT cross */
1793 r.in.nt_cross = &hash5;
1794 r.in.cross2_present = 1;
1795 r.in.lm_cross = &hash6;
1797 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1798 "ChangePasswordUser failed");
1799 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
1800 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(r.out.result));
1804 /* Unbreak the NT cross */
1808 /* Reset the hashes to not broken values */
1809 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1810 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1811 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1812 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1813 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1814 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1816 r.in.user_handle = &user_handle;
1817 r.in.lm_present = 1;
1818 r.in.old_lm_crypted = &hash1;
1819 r.in.new_lm_crypted = &hash2;
1820 r.in.nt_present = 1;
1821 r.in.old_nt_crypted = &hash3;
1822 r.in.new_nt_crypted = &hash4;
1823 r.in.cross1_present = 1;
1824 r.in.nt_cross = &hash5;
1825 r.in.cross2_present = 0;
1826 r.in.lm_cross = NULL;
1828 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1829 "ChangePasswordUser failed");
1830 if (NT_STATUS_IS_OK(r.out.result)) {
1832 *password = newpass;
1833 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, r.out.result)) {
1834 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r.out.result));
1839 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1841 E_md4hash(oldpass, old_nt_hash);
1842 E_md4hash(newpass, new_nt_hash);
1843 E_deshash(oldpass, old_lm_hash);
1844 E_deshash(newpass, new_lm_hash);
1847 /* Reset the hashes to not broken values */
1848 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1849 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1850 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1851 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1852 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1853 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1855 r.in.user_handle = &user_handle;
1856 r.in.lm_present = 1;
1857 r.in.old_lm_crypted = &hash1;
1858 r.in.new_lm_crypted = &hash2;
1859 r.in.nt_present = 1;
1860 r.in.old_nt_crypted = &hash3;
1861 r.in.new_nt_crypted = &hash4;
1862 r.in.cross1_present = 0;
1863 r.in.nt_cross = NULL;
1864 r.in.cross2_present = 1;
1865 r.in.lm_cross = &hash6;
1867 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1868 "ChangePasswordUser failed");
1869 if (NT_STATUS_IS_OK(r.out.result)) {
1871 *password = newpass;
1872 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, r.out.result)) {
1873 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(r.out.result));
1878 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1880 E_md4hash(oldpass, old_nt_hash);
1881 E_md4hash(newpass, new_nt_hash);
1882 E_deshash(oldpass, old_lm_hash);
1883 E_deshash(newpass, new_lm_hash);
1886 /* Reset the hashes to not broken values */
1887 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1888 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1889 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1890 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1891 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1892 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1894 r.in.user_handle = &user_handle;
1895 r.in.lm_present = 1;
1896 r.in.old_lm_crypted = &hash1;
1897 r.in.new_lm_crypted = &hash2;
1898 r.in.nt_present = 1;
1899 r.in.old_nt_crypted = &hash3;
1900 r.in.new_nt_crypted = &hash4;
1901 r.in.cross1_present = 1;
1902 r.in.nt_cross = &hash5;
1903 r.in.cross2_present = 1;
1904 r.in.lm_cross = &hash6;
1906 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1907 "ChangePasswordUser failed");
1908 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
1909 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
1910 } else if (!NT_STATUS_IS_OK(r.out.result)) {
1911 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(r.out.result));
1915 *password = newpass;
1918 r.in.user_handle = &user_handle;
1919 r.in.lm_present = 1;
1920 r.in.old_lm_crypted = &hash1;
1921 r.in.new_lm_crypted = &hash2;
1922 r.in.nt_present = 1;
1923 r.in.old_nt_crypted = &hash3;
1924 r.in.new_nt_crypted = &hash4;
1925 r.in.cross1_present = 1;
1926 r.in.nt_cross = &hash5;
1927 r.in.cross2_present = 1;
1928 r.in.lm_cross = &hash6;
1931 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1932 "ChangePasswordUser failed");
1933 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
1934 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
1935 } else if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
1936 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(r.out.result));
1942 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
1950 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p,
1951 struct torture_context *tctx,
1952 const char *acct_name,
1953 struct policy_handle *handle, char **password)
1955 struct samr_OemChangePasswordUser2 r;
1957 struct samr_Password lm_verifier;
1958 struct samr_CryptPassword lm_pass;
1959 struct lsa_AsciiString server, account, account_bad;
1962 struct dcerpc_binding_handle *b = p->binding_handle;
1963 uint8_t old_lm_hash[16], new_lm_hash[16];
1965 struct samr_GetDomPwInfo dom_pw_info;
1966 struct samr_PwInfo info;
1967 int policy_min_pw_len = 0;
1969 struct lsa_String domain_name;
1971 domain_name.string = "";
1972 dom_pw_info.in.domain_name = &domain_name;
1973 dom_pw_info.out.info = &info;
1975 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1977 torture_assert(tctx, *password != NULL,
1978 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1980 oldpass = *password;
1982 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
1983 "GetDomPwInfo failed");
1984 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
1985 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1988 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1990 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1991 account.string = acct_name;
1993 E_deshash(oldpass, old_lm_hash);
1994 E_deshash(newpass, new_lm_hash);
1996 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1997 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1998 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2000 r.in.server = &server;
2001 r.in.account = &account;
2002 r.in.password = &lm_pass;
2003 r.in.hash = &lm_verifier;
2005 /* Break the verification */
2006 lm_verifier.hash[0]++;
2008 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2009 "OemChangePasswordUser2 failed");
2011 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2012 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2013 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2014 nt_errstr(r.out.result));
2018 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2019 /* Break the old password */
2021 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2022 /* unbreak it for the next operation */
2024 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2026 r.in.server = &server;
2027 r.in.account = &account;
2028 r.in.password = &lm_pass;
2029 r.in.hash = &lm_verifier;
2031 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2032 "OemChangePasswordUser2 failed");
2034 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2035 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2036 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2037 nt_errstr(r.out.result));
2041 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2042 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2044 r.in.server = &server;
2045 r.in.account = &account;
2046 r.in.password = &lm_pass;
2049 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2050 "OemChangePasswordUser2 failed");
2052 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2053 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2054 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
2055 nt_errstr(r.out.result));
2059 /* This shouldn't be a valid name */
2060 account_bad.string = TEST_ACCOUNT_NAME "XX";
2061 r.in.account = &account_bad;
2063 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2064 "OemChangePasswordUser2 failed");
2066 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2067 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
2068 nt_errstr(r.out.result));
2072 /* This shouldn't be a valid name */
2073 account_bad.string = TEST_ACCOUNT_NAME "XX";
2074 r.in.account = &account_bad;
2075 r.in.password = &lm_pass;
2076 r.in.hash = &lm_verifier;
2078 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2079 "OemChangePasswordUser2 failed");
2081 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2082 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2083 nt_errstr(r.out.result));
2087 /* This shouldn't be a valid name */
2088 account_bad.string = TEST_ACCOUNT_NAME "XX";
2089 r.in.account = &account_bad;
2090 r.in.password = NULL;
2091 r.in.hash = &lm_verifier;
2093 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2094 "OemChangePasswordUser2 failed");
2096 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2097 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2098 nt_errstr(r.out.result));
2102 E_deshash(oldpass, old_lm_hash);
2103 E_deshash(newpass, new_lm_hash);
2105 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2106 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2107 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2109 r.in.server = &server;
2110 r.in.account = &account;
2111 r.in.password = &lm_pass;
2112 r.in.hash = &lm_verifier;
2114 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2115 "OemChangePasswordUser2 failed");
2117 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2118 torture_comment(tctx, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2119 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2120 torture_warning(tctx, "OemChangePasswordUser2 failed - %s\n", nt_errstr(r.out.result));
2123 *password = newpass;
2130 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2131 const char *acct_name,
2133 char *newpass, bool allow_password_restriction)
2135 struct samr_ChangePasswordUser2 r;
2137 struct lsa_String server, account;
2138 struct samr_CryptPassword nt_pass, lm_pass;
2139 struct samr_Password nt_verifier, lm_verifier;
2141 struct dcerpc_binding_handle *b = p->binding_handle;
2142 uint8_t old_nt_hash[16], new_nt_hash[16];
2143 uint8_t old_lm_hash[16], new_lm_hash[16];
2145 struct samr_GetDomPwInfo dom_pw_info;
2146 struct samr_PwInfo info;
2148 struct lsa_String domain_name;
2150 domain_name.string = "";
2151 dom_pw_info.in.domain_name = &domain_name;
2152 dom_pw_info.out.info = &info;
2154 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2156 torture_assert(tctx, *password != NULL,
2157 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2158 oldpass = *password;
2161 int policy_min_pw_len = 0;
2162 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
2163 "GetDomPwInfo failed");
2164 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
2165 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2168 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2171 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2172 init_lsa_String(&account, acct_name);
2174 E_md4hash(oldpass, old_nt_hash);
2175 E_md4hash(newpass, new_nt_hash);
2177 E_deshash(oldpass, old_lm_hash);
2178 E_deshash(newpass, new_lm_hash);
2180 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2181 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2182 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2184 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2185 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2186 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2188 r.in.server = &server;
2189 r.in.account = &account;
2190 r.in.nt_password = &nt_pass;
2191 r.in.nt_verifier = &nt_verifier;
2193 r.in.lm_password = &lm_pass;
2194 r.in.lm_verifier = &lm_verifier;
2196 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser2_r(b, tctx, &r),
2197 "ChangePasswordUser2 failed");
2199 if (allow_password_restriction && NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2200 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2201 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2202 torture_warning(tctx, "ChangePasswordUser2 failed - %s\n", nt_errstr(r.out.result));
2205 *password = newpass;
2212 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2213 const char *account_string,
2214 int policy_min_pw_len,
2216 const char *newpass,
2217 NTTIME last_password_change,
2218 bool handle_reject_reason)
2220 struct samr_ChangePasswordUser3 r;
2222 struct lsa_String server, account, account_bad;
2223 struct samr_CryptPassword nt_pass, lm_pass;
2224 struct samr_Password nt_verifier, lm_verifier;
2226 struct dcerpc_binding_handle *b = p->binding_handle;
2227 uint8_t old_nt_hash[16], new_nt_hash[16];
2228 uint8_t old_lm_hash[16], new_lm_hash[16];
2230 struct samr_DomInfo1 *dominfo = NULL;
2231 struct userPwdChangeFailureInformation *reject = NULL;
2233 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2235 if (newpass == NULL) {
2237 if (policy_min_pw_len == 0) {
2238 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2240 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2242 } while (check_password_quality(newpass) == false);
2244 torture_comment(tctx, "Using password '%s'\n", newpass);
2247 torture_assert(tctx, *password != NULL,
2248 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2250 oldpass = *password;
2251 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2252 init_lsa_String(&account, account_string);
2254 E_md4hash(oldpass, old_nt_hash);
2255 E_md4hash(newpass, new_nt_hash);
2257 E_deshash(oldpass, old_lm_hash);
2258 E_deshash(newpass, new_lm_hash);
2260 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2261 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2262 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2264 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2265 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2266 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2268 /* Break the verification */
2269 nt_verifier.hash[0]++;
2271 r.in.server = &server;
2272 r.in.account = &account;
2273 r.in.nt_password = &nt_pass;
2274 r.in.nt_verifier = &nt_verifier;
2276 r.in.lm_password = &lm_pass;
2277 r.in.lm_verifier = &lm_verifier;
2278 r.in.password3 = NULL;
2279 r.out.dominfo = &dominfo;
2280 r.out.reject = &reject;
2282 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2283 "ChangePasswordUser3 failed");
2284 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2285 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2286 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2287 nt_errstr(r.out.result));
2291 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2292 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2293 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2295 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2296 /* Break the NT hash */
2298 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2299 /* Unbreak it again */
2301 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2303 r.in.server = &server;
2304 r.in.account = &account;
2305 r.in.nt_password = &nt_pass;
2306 r.in.nt_verifier = &nt_verifier;
2308 r.in.lm_password = &lm_pass;
2309 r.in.lm_verifier = &lm_verifier;
2310 r.in.password3 = NULL;
2311 r.out.dominfo = &dominfo;
2312 r.out.reject = &reject;
2314 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2315 "ChangePasswordUser3 failed");
2316 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2317 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2318 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2319 nt_errstr(r.out.result));
2323 /* This shouldn't be a valid name */
2324 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2326 r.in.account = &account_bad;
2327 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2328 "ChangePasswordUser3 failed");
2329 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2330 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2331 nt_errstr(r.out.result));
2335 E_md4hash(oldpass, old_nt_hash);
2336 E_md4hash(newpass, new_nt_hash);
2338 E_deshash(oldpass, old_lm_hash);
2339 E_deshash(newpass, new_lm_hash);
2341 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2342 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2343 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2345 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2346 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2347 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2349 r.in.server = &server;
2350 r.in.account = &account;
2351 r.in.nt_password = &nt_pass;
2352 r.in.nt_verifier = &nt_verifier;
2354 r.in.lm_password = &lm_pass;
2355 r.in.lm_verifier = &lm_verifier;
2356 r.in.password3 = NULL;
2357 r.out.dominfo = &dominfo;
2358 r.out.reject = &reject;
2360 unix_to_nt_time(&t, time(NULL));
2362 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2363 "ChangePasswordUser3 failed");
2365 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2368 && handle_reject_reason
2369 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2370 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2372 if (reject && (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR)) {
2373 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2374 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2379 /* We tested the order of precendence which is as follows:
2388 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2389 (last_password_change + dominfo->min_password_age > t)) {
2391 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2392 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2393 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2397 } else if ((dominfo->min_password_length > 0) &&
2398 (strlen(newpass) < dominfo->min_password_length)) {
2400 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2401 torture_warning(tctx, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2402 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT, reject->extendedFailureReason);
2406 } else if ((dominfo->password_history_length > 0) &&
2407 strequal(oldpass, newpass)) {
2409 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PWD_IN_HISTORY) {
2410 torture_warning(tctx, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2411 SAM_PWD_CHANGE_PWD_IN_HISTORY, reject->extendedFailureReason);
2414 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2416 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NOT_COMPLEX) {
2417 torture_warning(tctx, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2418 SAM_PWD_CHANGE_NOT_COMPLEX, reject->extendedFailureReason);
2424 if (reject->extendedFailureReason == SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2425 /* retry with adjusted size */
2426 return test_ChangePasswordUser3(p, tctx, account_string,
2427 dominfo->min_password_length,
2428 password, NULL, 0, false);
2432 } else if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2433 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2434 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2435 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2438 /* Perhaps the server has a 'min password age' set? */
2441 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3");
2443 *password = talloc_strdup(tctx, newpass);
2449 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2450 const char *account_string,
2451 struct policy_handle *handle,
2455 struct samr_ChangePasswordUser3 r;
2456 struct samr_SetUserInfo s;
2457 union samr_UserInfo u;
2458 DATA_BLOB session_key;
2459 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2460 uint8_t confounder[16];
2461 struct MD5Context ctx;
2464 struct lsa_String server, account;
2465 struct samr_CryptPassword nt_pass;
2466 struct samr_Password nt_verifier;
2467 DATA_BLOB new_random_pass;
2470 struct dcerpc_binding_handle *b = p->binding_handle;
2471 uint8_t old_nt_hash[16], new_nt_hash[16];
2473 struct samr_DomInfo1 *dominfo = NULL;
2474 struct userPwdChangeFailureInformation *reject = NULL;
2476 new_random_pass = samr_very_rand_pass(tctx, 128);
2478 torture_assert(tctx, *password != NULL,
2479 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2481 oldpass = *password;
2482 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2483 init_lsa_String(&account, account_string);
2485 s.in.user_handle = handle;
2491 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2493 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2495 status = dcerpc_fetch_session_key(p, &session_key);
2496 if (!NT_STATUS_IS_OK(status)) {
2497 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
2498 s.in.level, nt_errstr(status));
2502 generate_random_buffer((uint8_t *)confounder, 16);
2505 MD5Update(&ctx, confounder, 16);
2506 MD5Update(&ctx, session_key.data, session_key.length);
2507 MD5Final(confounded_session_key.data, &ctx);
2509 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2510 memcpy(&u.info25.password.data[516], confounder, 16);
2512 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2514 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
2515 "SetUserInfo failed");
2516 if (!NT_STATUS_IS_OK(s.out.result)) {
2517 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
2518 s.in.level, nt_errstr(s.out.result));
2522 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2524 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2526 new_random_pass = samr_very_rand_pass(tctx, 128);
2528 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2530 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2531 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2532 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2534 r.in.server = &server;
2535 r.in.account = &account;
2536 r.in.nt_password = &nt_pass;
2537 r.in.nt_verifier = &nt_verifier;
2539 r.in.lm_password = NULL;
2540 r.in.lm_verifier = NULL;
2541 r.in.password3 = NULL;
2542 r.out.dominfo = &dominfo;
2543 r.out.reject = &reject;
2545 unix_to_nt_time(&t, time(NULL));
2547 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2548 "ChangePasswordUser3 failed");
2550 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2551 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2552 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2553 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2556 /* Perhaps the server has a 'min password age' set? */
2558 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2559 torture_warning(tctx, "ChangePasswordUser3 failed - %s\n", nt_errstr(r.out.result));
2563 newpass = samr_rand_pass(tctx, 128);
2565 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2567 E_md4hash(newpass, new_nt_hash);
2569 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2570 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2571 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2573 r.in.server = &server;
2574 r.in.account = &account;
2575 r.in.nt_password = &nt_pass;
2576 r.in.nt_verifier = &nt_verifier;
2578 r.in.lm_password = NULL;
2579 r.in.lm_verifier = NULL;
2580 r.in.password3 = NULL;
2581 r.out.dominfo = &dominfo;
2582 r.out.reject = &reject;
2584 unix_to_nt_time(&t, time(NULL));
2586 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2587 "ChangePasswordUser3 failed");
2589 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2590 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2591 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2592 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2595 /* Perhaps the server has a 'min password age' set? */
2598 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3 (on second random password)");
2599 *password = talloc_strdup(tctx, newpass);
2606 static bool test_GetMembersInAlias(struct dcerpc_binding_handle *b,
2607 struct torture_context *tctx,
2608 struct policy_handle *alias_handle)
2610 struct samr_GetMembersInAlias r;
2611 struct lsa_SidArray sids;
2613 torture_comment(tctx, "Testing GetMembersInAlias\n");
2615 r.in.alias_handle = alias_handle;
2618 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetMembersInAlias_r(b, tctx, &r),
2619 "GetMembersInAlias failed");
2620 torture_assert_ntstatus_ok(tctx, r.out.result, "GetMembersInAlias failed");
2625 static bool test_AddMemberToAlias(struct dcerpc_binding_handle *b,
2626 struct torture_context *tctx,
2627 struct policy_handle *alias_handle,
2628 const struct dom_sid *domain_sid)
2630 struct samr_AddAliasMember r;
2631 struct samr_DeleteAliasMember d;
2632 struct dom_sid *sid;
2634 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2636 torture_comment(tctx, "Testing AddAliasMember\n");
2637 r.in.alias_handle = alias_handle;
2640 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddAliasMember_r(b, tctx, &r),
2641 "AddAliasMember failed");
2642 torture_assert_ntstatus_ok(tctx, r.out.result, "AddAliasMember failed");
2644 d.in.alias_handle = alias_handle;
2647 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteAliasMember_r(b, tctx, &d),
2648 "DeleteAliasMember failed");
2649 torture_assert_ntstatus_ok(tctx, d.out.result, "DelAliasMember failed");
2654 static bool test_AddMultipleMembersToAlias(struct dcerpc_binding_handle *b,
2655 struct torture_context *tctx,
2656 struct policy_handle *alias_handle)
2658 struct samr_AddMultipleMembersToAlias a;
2659 struct samr_RemoveMultipleMembersFromAlias r;
2660 struct lsa_SidArray sids;
2662 torture_comment(tctx, "Testing AddMultipleMembersToAlias\n");
2663 a.in.alias_handle = alias_handle;
2667 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2669 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2670 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2671 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2673 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddMultipleMembersToAlias_r(b, tctx, &a),
2674 "AddMultipleMembersToAlias failed");
2675 torture_assert_ntstatus_ok(tctx, a.out.result, "AddMultipleMembersToAlias");
2678 torture_comment(tctx, "Testing RemoveMultipleMembersFromAlias\n");
2679 r.in.alias_handle = alias_handle;
2682 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2683 "RemoveMultipleMembersFromAlias failed");
2684 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2686 /* strange! removing twice doesn't give any error */
2687 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2688 "RemoveMultipleMembersFromAlias failed");
2689 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2691 /* but removing an alias that isn't there does */
2692 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2694 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2695 "RemoveMultipleMembersFromAlias failed");
2696 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2701 static bool test_GetAliasMembership(struct dcerpc_binding_handle *b,
2702 struct torture_context *tctx,
2703 struct policy_handle *domain_handle)
2705 struct samr_GetAliasMembership r;
2706 struct lsa_SidArray sids;
2707 struct samr_Ids rids;
2709 torture_comment(tctx, "Testing GetAliasMembership\n");
2711 if (torture_setting_bool(tctx, "samba4", false)) {
2712 torture_skip(tctx, "skipping GetAliasMembership against s4");
2715 r.in.domain_handle = domain_handle;
2720 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2722 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2723 "GetAliasMembership failed");
2724 torture_assert_ntstatus_ok(tctx, r.out.result,
2725 "samr_GetAliasMembership failed");
2727 torture_assert_int_equal(tctx, sids.num_sids, rids.count,
2728 "protocol misbehaviour");
2731 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2732 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2734 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2735 "samr_GetAliasMembership failed");
2736 torture_assert_ntstatus_ok(tctx, r.out.result,
2737 "samr_GetAliasMembership failed");
2740 /* only true for w2k8 it seems
2741 * win7, xp, w2k3 will return a 0 length array pointer */
2743 if (rids.ids && (rids.count == 0)) {
2744 torture_fail(tctx, "samr_GetAliasMembership returned 0 count and a rids array");
2747 if (!rids.ids && rids.count) {
2748 torture_fail(tctx, "samr_GetAliasMembership returned non-0 count but no rids");
2754 static bool test_TestPrivateFunctionsUser(struct dcerpc_binding_handle *b,
2755 struct torture_context *tctx,
2756 struct policy_handle *user_handle)
2758 struct samr_TestPrivateFunctionsUser r;
2760 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2762 r.in.user_handle = user_handle;
2764 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsUser_r(b, tctx, &r),
2765 "TestPrivateFunctionsUser failed");
2766 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2771 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_binding_handle *b,
2772 struct torture_context *tctx,
2773 struct policy_handle *handle,
2778 uint16_t levels[] = { /* 3, */ 5, 21 };
2780 NTTIME pwdlastset3 = 0;
2781 NTTIME pwdlastset5 = 0;
2782 NTTIME pwdlastset21 = 0;
2784 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2785 use_info2 ? "2":"");
2787 for (i=0; i<ARRAY_SIZE(levels); i++) {
2789 struct samr_QueryUserInfo r;
2790 struct samr_QueryUserInfo2 r2;
2791 union samr_UserInfo *info;
2794 r2.in.user_handle = handle;
2795 r2.in.level = levels[i];
2796 r2.out.info = &info;
2797 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r2),
2798 "QueryUserInfo2 failed");
2799 status = r2.out.result;
2802 r.in.user_handle = handle;
2803 r.in.level = levels[i];
2805 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
2806 "QueryUserInfo failed");
2807 status = r.out.result;
2810 if (!NT_STATUS_IS_OK(status) &&
2811 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2812 torture_warning(tctx, "QueryUserInfo%s level %u failed - %s\n",
2813 use_info2 ? "2":"", levels[i], nt_errstr(status));
2817 switch (levels[i]) {
2819 pwdlastset3 = info->info3.last_password_change;
2822 pwdlastset5 = info->info5.last_password_change;
2825 pwdlastset21 = info->info21.last_password_change;
2831 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2832 "pwdlastset mixup"); */
2833 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2834 "pwdlastset mixup");
2836 *pwdlastset = pwdlastset21;
2838 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2843 static bool test_SamLogon(struct torture_context *tctx,
2844 struct dcerpc_pipe *p,
2845 struct cli_credentials *test_credentials,
2846 NTSTATUS expected_result,
2850 struct netr_LogonSamLogonEx r;
2851 union netr_LogonLevel logon;
2852 union netr_Validation validation;
2853 uint8_t authoritative;
2854 struct netr_IdentityInfo identity;
2855 struct netr_NetworkInfo ninfo;
2856 struct netr_PasswordInfo pinfo;
2857 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2858 int flags = CLI_CRED_NTLM_AUTH;
2859 uint32_t samlogon_flags = 0;
2860 struct netlogon_creds_CredentialState *creds;
2861 struct netr_Authenticator a;
2862 struct dcerpc_binding_handle *b = p->binding_handle;
2864 torture_assert_ntstatus_ok(tctx, dcerpc_schannel_creds(p->conn->security_state.generic_state, tctx, &creds), "");
2866 if (lp_client_lanman_auth(tctx->lp_ctx)) {
2867 flags |= CLI_CRED_LANMAN_AUTH;
2870 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2871 flags |= CLI_CRED_NTLMv2_AUTH;
2874 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2875 &identity.account_name.string,
2876 &identity.domain_name.string);
2878 identity.parameter_control =
2879 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2880 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2881 identity.logon_id_low = 0;
2882 identity.logon_id_high = 0;
2883 identity.workstation.string = cli_credentials_get_workstation(test_credentials);
2886 netlogon_creds_client_authenticator(creds, &a);
2888 if (!E_deshash(cli_credentials_get_password(test_credentials), pinfo.lmpassword.hash)) {
2889 ZERO_STRUCT(pinfo.lmpassword.hash);
2891 E_md4hash(cli_credentials_get_password(test_credentials), pinfo.ntpassword.hash);
2893 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
2894 netlogon_creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
2895 netlogon_creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
2897 netlogon_creds_des_encrypt(creds, &pinfo.lmpassword);
2898 netlogon_creds_des_encrypt(creds, &pinfo.ntpassword);
2901 pinfo.identity_info = identity;
2902 logon.password = &pinfo;
2904 r.in.logon_level = NetlogonInteractiveInformation;
2906 generate_random_buffer(ninfo.challenge,
2907 sizeof(ninfo.challenge));
2908 chal = data_blob_const(ninfo.challenge,
2909 sizeof(ninfo.challenge));
2911 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
2912 cli_credentials_get_domain(test_credentials));
2914 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2920 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2922 ninfo.lm.data = lm_resp.data;
2923 ninfo.lm.length = lm_resp.length;
2925 ninfo.nt.data = nt_resp.data;
2926 ninfo.nt.length = nt_resp.length;
2928 ninfo.identity_info = identity;
2929 logon.network = &ninfo;
2931 r.in.logon_level = NetlogonNetworkInformation;
2934 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2935 r.in.computer_name = cli_credentials_get_workstation(test_credentials);
2936 r.in.logon = &logon;
2937 r.in.flags = &samlogon_flags;
2938 r.out.flags = &samlogon_flags;
2939 r.out.validation = &validation;
2940 r.out.authoritative = &authoritative;
2942 torture_comment(tctx, "Testing LogonSamLogon with name %s\n", identity.account_name.string);
2944 r.in.validation_level = 6;
2946 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
2947 "netr_LogonSamLogonEx failed");
2948 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
2949 r.in.validation_level = 3;
2950 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
2951 "netr_LogonSamLogonEx failed");
2953 if (!NT_STATUS_IS_OK(r.out.result)) {
2954 torture_assert_ntstatus_equal(tctx, r.out.result, expected_result, "LogonSamLogonEx failed");
2957 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogonEx failed");
2963 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2964 struct dcerpc_pipe *p,
2965 struct cli_credentials *machine_creds,
2966 const char *acct_name,
2967 const char *password,
2968 NTSTATUS expected_samlogon_result,
2972 struct cli_credentials *test_credentials;
2974 test_credentials = cli_credentials_init(tctx);
2976 cli_credentials_set_workstation(test_credentials,
2977 cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
2978 cli_credentials_set_domain(test_credentials,
2979 cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
2980 cli_credentials_set_username(test_credentials,
2981 acct_name, CRED_SPECIFIED);
2982 cli_credentials_set_password(test_credentials,
2983 password, CRED_SPECIFIED);
2985 torture_comment(tctx, "Testing samlogon (%s) as %s password: %s\n",
2986 interactive ? "interactive" : "network", acct_name, password);
2988 if (!test_SamLogon(tctx, p, test_credentials,
2989 expected_samlogon_result, interactive)) {
2990 torture_warning(tctx, "new password did not work\n");
2997 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2998 struct dcerpc_pipe *np,
2999 struct torture_context *tctx,
3000 struct policy_handle *handle,
3002 uint32_t fields_present,
3003 uint8_t password_expired,
3004 bool *matched_expected_error,
3006 const char *acct_name,
3008 struct cli_credentials *machine_creds,
3009 bool use_queryinfo2,
3011 NTSTATUS expected_samlogon_result)
3013 const char *fields = NULL;
3015 struct dcerpc_binding_handle *b = p->binding_handle;
3021 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
3028 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
3029 "(password_expired: %d) %s\n",
3030 use_setinfo2 ? "2":"", level, password_expired,
3031 fields ? fields : "");
3033 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
3038 matched_expected_error)) {
3042 if (!test_QueryUserInfo_pwdlastset(b, tctx, handle,
3048 if (*matched_expected_error == true) {
3052 if (!test_SamLogon_with_creds(tctx, np,
3056 expected_samlogon_result,
3064 static bool setup_schannel_netlogon_pipe(struct torture_context *tctx,
3065 struct cli_credentials *credentials,
3066 struct dcerpc_pipe **p)
3068 struct dcerpc_binding *b;
3070 torture_assert_ntstatus_ok(tctx, torture_rpc_binding(tctx, &b),
3071 "failed to get rpc binding");
3073 /* We have to use schannel, otherwise the SamLogonEx fails
3074 * with INTERNAL_ERROR */
3076 b->flags &= ~DCERPC_AUTH_OPTIONS;
3077 b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
3079 torture_assert_ntstatus_ok(tctx,
3080 dcerpc_pipe_connect_b(tctx, p, b, &ndr_table_netlogon,
3081 credentials, tctx->ev, tctx->lp_ctx),
3082 "failed to bind to netlogon");
3087 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
3088 struct torture_context *tctx,
3089 uint32_t acct_flags,
3090 const char *acct_name,
3091 struct policy_handle *handle,
3093 struct cli_credentials *machine_credentials)
3095 int s = 0, q = 0, f = 0, l = 0, z = 0;
3098 bool set_levels[] = { false, true };
3099 bool query_levels[] = { false, true };
3100 uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
3101 uint32_t nonzeros[] = { 1, 24 };
3102 uint32_t fields_present[] = {
3104 SAMR_FIELD_EXPIRED_FLAG,
3105 SAMR_FIELD_LAST_PWD_CHANGE,
3106 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
3108 SAMR_FIELD_NT_PASSWORD_PRESENT,
3109 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3110 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3111 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3112 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3113 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3114 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
3116 struct dcerpc_pipe *np = NULL;
3118 if (torture_setting_bool(tctx, "samba3", false)) {
3120 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
3124 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3126 /* set to 1 to enable testing for all possible opcode
3127 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3130 #define TEST_ALL_LEVELS 1
3131 #define TEST_SET_LEVELS 1
3132 #define TEST_QUERY_LEVELS 1
3134 #ifdef TEST_ALL_LEVELS
3135 for (l=0; l<ARRAY_SIZE(levels); l++) {
3137 for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
3139 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
3140 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
3141 #ifdef TEST_SET_LEVELS
3142 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
3144 #ifdef TEST_QUERY_LEVELS
3145 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
3147 NTTIME pwdlastset_old = 0;
3148 NTTIME pwdlastset_new = 0;
3149 bool matched_expected_error = false;
3150 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
3152 torture_comment(tctx, "------------------------------\n"
3153 "Testing pwdLastSet attribute for flags: 0x%08x "
3154 "(s: %d (l: %d), q: %d)\n",
3155 acct_flags, s, levels[l], q);
3157 switch (levels[l]) {
3161 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3162 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
3163 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
3171 /* set a password and force password change (pwdlastset 0) by
3172 * setting the password expired flag to a non-0 value */
3174 if (!test_SetPassword_level(p, np, tctx, handle,
3178 &matched_expected_error,
3182 machine_credentials,
3185 expected_samlogon_result)) {
3189 if (matched_expected_error == true) {
3190 /* skipping on expected failure */
3194 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3195 * set without the SAMR_FIELD_EXPIRED_FLAG */
3197 switch (levels[l]) {
3201 if ((pwdlastset_new != 0) &&
3202 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3203 torture_comment(tctx, "not considering a non-0 "
3204 "pwdLastSet as a an error as the "
3205 "SAMR_FIELD_EXPIRED_FLAG has not "
3210 if (pwdlastset_new != 0) {
3211 torture_warning(tctx, "pwdLastSet test failed: "
3212 "expected pwdLastSet 0 but got %lld\n",
3219 switch (levels[l]) {
3223 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3224 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3225 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3226 (pwdlastset_old >= pwdlastset_new)) {
3227 torture_warning(tctx, "pwdlastset not increasing\n");
3232 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3233 (pwdlastset_old >= pwdlastset_new)) {
3234 torture_warning(tctx, "pwdlastset not increasing\n");
3244 /* set a password, pwdlastset needs to get updated (increased
3245 * value), password_expired value used here is 0 */
3247 if (!test_SetPassword_level(p, np, tctx, handle,
3251 &matched_expected_error,
3255 machine_credentials,
3258 expected_samlogon_result)) {
3262 /* when a password has been changed, pwdlastset must not be 0 afterwards
3263 * and must be larger then the old value */
3265 switch (levels[l]) {
3270 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3271 * password has been changed, old and new pwdlastset
3272 * need to be the same value */
3274 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3275 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3276 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3278 torture_assert_int_equal(tctx, pwdlastset_old,
3279 pwdlastset_new, "pwdlastset must be equal");
3283 if (pwdlastset_old >= pwdlastset_new) {
3284 torture_warning(tctx, "pwdLastSet test failed: "
3285 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3286 pwdlastset_old, pwdlastset_new);
3289 if (pwdlastset_new == 0) {
3290 torture_warning(tctx, "pwdLastSet test failed: "
3291 "expected non-0 pwdlastset, got: %lld\n",
3297 switch (levels[l]) {
3301 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3302 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3303 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3304 (pwdlastset_old >= pwdlastset_new)) {
3305 torture_warning(tctx, "pwdlastset not increasing\n");
3310 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3311 (pwdlastset_old >= pwdlastset_new)) {
3312 torture_warning(tctx, "pwdlastset not increasing\n");
3318 pwdlastset_old = pwdlastset_new;
3324 /* set a password, pwdlastset needs to get updated (increased
3325 * value), password_expired value used here is 0 */
3327 if (!test_SetPassword_level(p, np, tctx, handle,
3331 &matched_expected_error,
3335 machine_credentials,
3338 expected_samlogon_result)) {
3342 /* when a password has been changed, pwdlastset must not be 0 afterwards
3343 * and must be larger then the old value */
3345 switch (levels[l]) {
3350 /* if no password has been changed, old and new pwdlastset
3351 * need to be the same value */
3353 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3354 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3356 torture_assert_int_equal(tctx, pwdlastset_old,
3357 pwdlastset_new, "pwdlastset must be equal");
3361 if (pwdlastset_old >= pwdlastset_new) {
3362 torture_warning(tctx, "pwdLastSet test failed: "
3363 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3364 pwdlastset_old, pwdlastset_new);
3367 if (pwdlastset_new == 0) {
3368 torture_warning(tctx, "pwdLastSet test failed: "
3369 "expected non-0 pwdlastset, got: %lld\n",
3377 /* set a password and force password change (pwdlastset 0) by
3378 * setting the password expired flag to a non-0 value */
3380 if (!test_SetPassword_level(p, np, tctx, handle,
3384 &matched_expected_error,
3388 machine_credentials,
3391 expected_samlogon_result)) {
3395 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3396 * set without the SAMR_FIELD_EXPIRED_FLAG */
3398 switch (levels[l]) {
3402 if ((pwdlastset_new != 0) &&
3403 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3404 torture_comment(tctx, "not considering a non-0 "
3405 "pwdLastSet as a an error as the "
3406 "SAMR_FIELD_EXPIRED_FLAG has not "
3411 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3412 * password has been changed, old and new pwdlastset
3413 * need to be the same value */
3415 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3416 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3417 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3419 torture_assert_int_equal(tctx, pwdlastset_old,
3420 pwdlastset_new, "pwdlastset must be equal");
3425 if (pwdlastset_old == pwdlastset_new) {
3426 torture_warning(tctx, "pwdLastSet test failed: "
3427 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3428 pwdlastset_old, pwdlastset_new);
3432 if (pwdlastset_new != 0) {
3433 torture_warning(tctx, "pwdLastSet test failed: "
3434 "expected pwdLastSet 0, got %lld\n",
3441 switch (levels[l]) {
3445 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3446 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3447 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3448 (pwdlastset_old >= pwdlastset_new)) {
3449 torture_warning(tctx, "pwdlastset not increasing\n");
3454 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3455 (pwdlastset_old >= pwdlastset_new)) {
3456 torture_warning(tctx, "pwdlastset not increasing\n");
3462 /* if the level we are testing does not have a fields_present
3463 * field, skip all fields present tests by setting f to to
3465 switch (levels[l]) {
3469 f = ARRAY_SIZE(fields_present);
3473 #ifdef TEST_QUERY_LEVELS
3476 #ifdef TEST_SET_LEVELS
3479 } /* fields present */
3483 #undef TEST_SET_LEVELS
3484 #undef TEST_QUERY_LEVELS
3491 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_binding_handle *b,
3492 struct torture_context *tctx,
3493 struct policy_handle *handle,
3494 uint32_t *badpwdcount)
3496 union samr_UserInfo *info;
3497 struct samr_QueryUserInfo r;
3499 r.in.user_handle = handle;
3503 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3505 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3506 "failed to query userinfo");
3507 torture_assert_ntstatus_ok(tctx, r.out.result,
3508 "failed to query userinfo");
3510 *badpwdcount = info->info3.bad_password_count;
3512 torture_comment(tctx, " (bad password count: %d)\n", *badpwdcount);
3517 static bool test_SetUserInfo_acct_flags(struct dcerpc_binding_handle *b,
3518 struct torture_context *tctx,
3519 struct policy_handle *user_handle,
3520 uint32_t acct_flags)
3522 struct samr_SetUserInfo r;
3523 union samr_UserInfo user_info;
3525 torture_comment(tctx, "Testing SetUserInfo level 16\n");
3527 user_info.info16.acct_flags = acct_flags;
3529 r.in.user_handle = user_handle;
3531 r.in.info = &user_info;
3533 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &r),
3534 "failed to set account flags");
3535 torture_assert_ntstatus_ok(tctx, r.out.result,
3536 "failed to set account flags");
3541 static bool test_reset_badpwdcount(struct dcerpc_pipe *p,
3542 struct torture_context *tctx,
3543 struct policy_handle *user_handle,
3544 uint32_t acct_flags,
3547 struct dcerpc_binding_handle *b = p->binding_handle;
3549 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3550 "failed to set password");
3552 torture_comment(tctx, "Testing SetUserInfo level 16 (enable account)\n");
3554 torture_assert(tctx,
3555 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3556 acct_flags & ~ACB_DISABLED),
3557 "failed to enable user");
3559 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3560 "failed to set password");
3565 static bool test_SetDomainInfo(struct dcerpc_binding_handle *b,
3566 struct torture_context *tctx,
3567 struct policy_handle *domain_handle,
3568 enum samr_DomainInfoClass level,
3569 union samr_DomainInfo *info)
3571 struct samr_SetDomainInfo r;
3573 r.in.domain_handle = domain_handle;
3577 torture_assert_ntstatus_ok(tctx,
3578 dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3579 "failed to set domain info");
3580 torture_assert_ntstatus_ok(tctx, r.out.result,
3581 "failed to set domain info");
3586 static bool test_SetDomainInfo_ntstatus(struct dcerpc_binding_handle *b,
3587 struct torture_context *tctx,
3588 struct policy_handle *domain_handle,
3589 enum samr_DomainInfoClass level,
3590 union samr_DomainInfo *info,
3593 struct samr_SetDomainInfo r;
3595 r.in.domain_handle = domain_handle;
3599 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3600 "SetDomainInfo failed");
3601 torture_assert_ntstatus_equal(tctx, r.out.result, expected, "");
3606 static bool test_QueryDomainInfo2_level(struct dcerpc_binding_handle *b,
3607 struct torture_context *tctx,
3608 struct policy_handle *domain_handle,
3609 enum samr_DomainInfoClass level,
3610 union samr_DomainInfo **q_info)
3612 struct samr_QueryDomainInfo2 r;
3614 r.in.domain_handle = domain_handle;
3616 r.out.info = q_info;
3618 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
3619 "failed to query domain info");
3620 torture_assert_ntstatus_ok(tctx, r.out.result,
3621 "failed to query domain info");
3626 static bool test_Password_badpwdcount(struct dcerpc_pipe *p,
3627 struct dcerpc_pipe *np,
3628 struct torture_context *tctx,
3629 uint32_t acct_flags,
3630 const char *acct_name,
3631 struct policy_handle *domain_handle,
3632 struct policy_handle *user_handle,
3634 struct cli_credentials *machine_credentials,
3635 const char *comment,
3638 NTSTATUS expected_success_status,
3639 struct samr_DomInfo1 *info1,
3640 struct samr_DomInfo12 *info12)
3642 union samr_DomainInfo info;
3645 uint32_t badpwdcount, tmp;
3646 uint32_t password_history_length = 12;
3647 uint32_t lockout_threshold = 15;
3648 struct dcerpc_binding_handle *b = p->binding_handle;
3650 torture_comment(tctx, "\nTesting bad pwd count with: %s\n", comment);
3652 torture_assert(tctx, password_history_length < lockout_threshold,
3653 "password history length needs to be smaller than account lockout threshold for this test");
3658 info.info1 = *info1;
3659 info.info1.password_history_length = password_history_length;
3661 torture_assert(tctx,
3662 test_SetDomainInfo(b, tctx, domain_handle,
3663 DomainPasswordInformation, &info),
3664 "failed to set password history length");
3666 info.info12 = *info12;
3667 info.info12.lockout_threshold = lockout_threshold;
3669 torture_assert(tctx,
3670 test_SetDomainInfo(b, tctx, domain_handle,
3671 DomainLockoutInformation, &info),
3672 "failed to set lockout threshold");
3674 /* reset bad pwd count */
3676 torture_assert(tctx,
3677 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
3680 /* enable or disable account */
3682 torture_assert(tctx,
3683 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3684 acct_flags | ACB_DISABLED),
3685 "failed to disable user");
3687 torture_assert(tctx,
3688 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3689 acct_flags & ~ACB_DISABLED),
3690 "failed to enable user");
3694 /* setup password history */
3696 passwords = talloc_array(tctx, char *, password_history_length);
3698 for (i=0; i < password_history_length; i++) {
3700 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3701 "failed to set password");
3702 passwords[i] = talloc_strdup(tctx, *password);
3704 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3705 acct_name, passwords[i],
3706 expected_success_status, interactive)) {
3707 torture_fail(tctx, "failed to auth with latest password");
3710 torture_assert(tctx,
3711 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3713 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3717 /* test with wrong password */
3719 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3720 acct_name, "random_crap",
3721 NT_STATUS_WRONG_PASSWORD, interactive)) {
3722 torture_fail(tctx, "succeeded to authenticate with wrong password");
3725 torture_assert(tctx,
3726 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3728 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3731 /* test with latest good password */
3733 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
3734 passwords[password_history_length-1],
3735 expected_success_status, interactive)) {
3736 torture_fail(tctx, "succeeded to authenticate with wrong password");
3739 torture_assert(tctx,
3740 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3743 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3745 /* only enabled accounts get the bad pwd count reset upon
3746 * successful logon */
3747 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3753 /* test password history */
3755 for (i=0; i < password_history_length; i++) {
3757 torture_comment(tctx, "Testing bad password count behavior with "
3758 "password #%d of #%d\n", i, password_history_length);
3760 /* - network samlogon will succeed auth and not
3761 * increase badpwdcount for 2 last entries
3762 * - interactive samlogon only for the last one */
3764 if (i == password_history_length - 1 ||
3765 (i == password_history_length - 2 && !interactive)) {
3767 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3768 acct_name, passwords[i],
3769 expected_success_status, interactive)) {
3770 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3773 torture_assert(tctx,
3774 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3777 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
3778 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3780 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
3781 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3789 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3790 acct_name, passwords[i],
3791 NT_STATUS_WRONG_PASSWORD, interactive)) {
3792 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3795 torture_assert(tctx,
3796 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3798 /* - network samlogon will fail auth but not increase
3799 * badpwdcount for 3rd last entry
3800 * - interactive samlogon for 3rd and 2nd last entry */
3802 if (i == password_history_length - 3 ||
3803 (i == password_history_length - 2 && interactive)) {
3804 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
3805 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3807 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
3808 torture_assert_int_equal(tctx, badpwdcount, tmp + 1, "unexpected badpwdcount");
3817 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe *p,
3818 struct torture_context *tctx,
3819 uint32_t acct_flags,
3820 const char *acct_name,
3821 struct policy_handle *domain_handle,
3822 struct policy_handle *user_handle,
3824 struct cli_credentials *machine_credentials)
3826 union samr_DomainInfo *q_info, s_info;
3827 struct samr_DomInfo1 info1, _info1;
3828 struct samr_DomInfo12 info12, _info12;
3830 struct dcerpc_binding_handle *b = p->binding_handle;
3831 struct dcerpc_pipe *np;
3835 const char *comment;
3838 NTSTATUS expected_success_status;
3841 .comment = "network logon (disabled account)",
3843 .interactive = false,
3844 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
3847 .comment = "network logon (enabled account)",
3849 .interactive = false,
3850 .expected_success_status= NT_STATUS_OK
3853 .comment = "interactive logon (disabled account)",
3855 .interactive = true,
3856 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
3859 .comment = "interactive logon (enabled account)",
3861 .interactive = true,
3862 .expected_success_status= NT_STATUS_OK
3866 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3868 /* backup old policies */
3870 torture_assert(tctx,
3871 test_QueryDomainInfo2_level(b, tctx, domain_handle,
3872 DomainPasswordInformation, &q_info),
3873 "failed to query domain info level 1");
3875 info1 = q_info->info1;
3878 torture_assert(tctx,
3879 test_QueryDomainInfo2_level(b, tctx, domain_handle,
3880 DomainLockoutInformation, &q_info),
3881 "failed to query domain info level 12");
3883 info12 = q_info->info12;
3888 for (i=0; i < ARRAY_SIZE(creds); i++) {
3890 /* skip trust tests for now */
3891 if (acct_flags & ACB_WSTRUST ||
3892 acct_flags & ACB_SVRTRUST ||
3893 acct_flags & ACB_DOMTRUST) {
3897 ret &= test_Password_badpwdcount(p, np, tctx, acct_flags, acct_name,
3898 domain_handle, user_handle, password,
3899 machine_credentials,
3902 creds[i].interactive,
3903 creds[i].expected_success_status,
3906 torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
3908 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
3912 /* restore policies */
3914 s_info.info1 = info1;
3916 torture_assert(tctx,
3917 test_SetDomainInfo(b, tctx, domain_handle,
3918 DomainPasswordInformation, &s_info),
3919 "failed to set password information");
3921 s_info.info12 = info12;
3923 torture_assert(tctx,
3924 test_SetDomainInfo(b, tctx, domain_handle,
3925 DomainLockoutInformation, &s_info),
3926 "failed to set lockout information");
3931 static bool test_QueryUserInfo_acct_flags(struct dcerpc_binding_handle *b,
3932 struct torture_context *tctx,
3933 struct policy_handle *handle,
3934 uint32_t *acct_flags)
3936 union samr_UserInfo *info;
3937 struct samr_QueryUserInfo r;
3939 r.in.user_handle = handle;
3943 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3945 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3946 "failed to query userinfo");
3947 torture_assert_ntstatus_ok(tctx, r.out.result,
3948 "failed to query userinfo");
3950 *acct_flags = info->info16.acct_flags;
3952 torture_comment(tctx, " (acct_flags: 0x%08x)\n", *acct_flags);
3957 static bool test_Password_lockout(struct dcerpc_pipe *p,
3958 struct dcerpc_pipe *np,
3959 struct torture_context *tctx,
3960 uint32_t acct_flags,
3961 const char *acct_name,
3962 struct policy_handle *domain_handle,
3963 struct policy_handle *user_handle,
3965 struct cli_credentials *machine_credentials,
3966 const char *comment,
3969 NTSTATUS expected_success_status,
3970 struct samr_DomInfo1 *info1,
3971 struct samr_DomInfo12 *info12)
3973 union samr_DomainInfo info;
3974 uint32_t badpwdcount;
3975 uint32_t password_history_length = 1;
3976 uint64_t lockout_threshold = 1;
3977 uint32_t lockout_seconds = 5;
3978 uint64_t delta_time_factor = 10 * 1000 * 1000;
3979 struct dcerpc_binding_handle *b = p->binding_handle;
3981 torture_comment(tctx, "\nTesting account lockout: %s\n", comment);
3985 info.info1 = *info1;
3987 torture_comment(tctx, "setting password history length.\n");
3988 info.info1.password_history_length = password_history_length;
3990 torture_assert(tctx,
3991 test_SetDomainInfo(b, tctx, domain_handle,
3992 DomainPasswordInformation, &info),
3993 "failed to set password history length");
3995 info.info12 = *info12;
3996 info.info12.lockout_threshold = lockout_threshold;
3998 /* set lockout duration < lockout window: should fail */
3999 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4000 info.info12.lockout_window = ~((lockout_seconds + 1) * delta_time_factor);
4002 torture_assert(tctx,
4003 test_SetDomainInfo_ntstatus(b, tctx, domain_handle,
4004 DomainLockoutInformation, &info,
4005 NT_STATUS_INVALID_PARAMETER),
4006 "setting lockout duration < lockout window gave unexpected result");
4008 info.info12.lockout_duration = 0;
4009 info.info12.lockout_window = 0;
4011 torture_assert(tctx,
4012 test_SetDomainInfo(b, tctx, domain_handle,
4013 DomainLockoutInformation, &info),
4014 "failed to set lockout window and duration to 0");
4017 /* set lockout duration of 5 seconds */
4018 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4019 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
4021 torture_assert(tctx,
4022 test_SetDomainInfo(b, tctx, domain_handle,
4023 DomainLockoutInformation, &info),
4024 "failed to set lockout window and duration to 5 seconds");
4026 /* reset bad pwd count */
4028 torture_assert(tctx,
4029 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
4032 /* enable or disable account */
4035 torture_assert(tctx,
4036 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4037 acct_flags | ACB_DISABLED),
4038 "failed to disable user");
4040 torture_assert(tctx,
4041 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4042 acct_flags & ~ACB_DISABLED),
4043 "failed to enable user");
4047 /* test logon with right password */
4049 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4050 acct_name, *password,
4051 expected_success_status, interactive)) {
4052 torture_fail(tctx, "failed to auth with latest password");
4055 torture_assert(tctx,
4056 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4057 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
4060 /* test with wrong password ==> lockout */
4062 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4063 acct_name, "random_crap",
4064 NT_STATUS_WRONG_PASSWORD, interactive)) {
4065 torture_fail(tctx, "succeeded to authenticate with wrong password");
4068 torture_assert(tctx,
4069 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4070 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4072 torture_assert(tctx,
4073 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4074 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4075 "expected account to be locked");
4078 /* test with good password */
4080 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4082 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4084 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4087 /* bad pwd count should not get updated */
4088 torture_assert(tctx,
4089 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4090 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4092 /* curiously, windows does _not_ set the autlock flag */
4093 torture_assert(tctx,
4094 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4095 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4096 "expected account to be locked");
4099 /* with bad password */
4101 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4102 acct_name, "random_crap2",
4103 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4105 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4108 /* bad pwd count should not get updated */
4109 torture_assert(tctx,
4110 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4111 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4113 /* curiously, windows does _not_ set the autlock flag */
4114 torture_assert(tctx,
4115 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4116 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4117 "expected account to be locked");
4120 /* let lockout duration expire ==> unlock */
4122 torture_comment(tctx, "let lockout duration expire...\n");
4123 sleep(lockout_seconds + 1);
4125 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4127 expected_success_status, interactive))
4129 torture_fail(tctx, "failed to authenticate after lockout expired");
4132 torture_assert(tctx,
4133 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4134 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4135 "expected account not to be locked");
4140 static bool test_Password_lockout_wrap(struct dcerpc_pipe *p,
4141 struct torture_context *tctx,
4142 uint32_t acct_flags,
4143 const char *acct_name,
4144 struct policy_handle *domain_handle,
4145 struct policy_handle *user_handle,
4147 struct cli_credentials *machine_credentials)
4149 union samr_DomainInfo *q_info, s_info;
4150 struct samr_DomInfo1 info1, _info1;
4151 struct samr_DomInfo12 info12, _info12;
4153 struct dcerpc_binding_handle *b = p->binding_handle;
4154 struct dcerpc_pipe *np;
4158 const char *comment;
4161 NTSTATUS expected_success_status;
4164 .comment = "network logon (disabled account)",
4166 .interactive = false,
4167 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4170 .comment = "network logon (enabled account)",
4172 .interactive = false,
4173 .expected_success_status= NT_STATUS_OK
4176 .comment = "interactive logon (disabled account)",
4178 .interactive = true,
4179 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4182 .comment = "interactive logon (enabled account)",
4184 .interactive = true,
4185 .expected_success_status= NT_STATUS_OK
4189 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4191 /* backup old policies */
4193 torture_assert(tctx,
4194 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4195 DomainPasswordInformation, &q_info),
4196 "failed to query domain info level 1");
4198 info1 = q_info->info1;
4201 torture_assert(tctx,
4202 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4203 DomainLockoutInformation, &q_info),
4204 "failed to query domain info level 12");
4206 info12 = q_info->info12;
4211 for (i=0; i < ARRAY_SIZE(creds); i++) {
4213 /* skip trust tests for now */
4214 if (acct_flags & ACB_WSTRUST ||
4215 acct_flags & ACB_SVRTRUST ||
4216 acct_flags & ACB_DOMTRUST) {
4220 ret &= test_Password_lockout(p, np, tctx, acct_flags, acct_name,
4221 domain_handle, user_handle, password,
4222 machine_credentials,
4225 creds[i].interactive,
4226 creds[i].expected_success_status,
4229 torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
4231 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4235 /* restore policies */
4237 s_info.info1 = info1;
4239 torture_assert(tctx,
4240 test_SetDomainInfo(b, tctx, domain_handle,
4241 DomainPasswordInformation, &s_info),
4242 "failed to set password information");
4244 s_info.info12 = info12;
4246 torture_assert(tctx,
4247 test_SetDomainInfo(b, tctx, domain_handle,
4248 DomainLockoutInformation, &s_info),
4249 "failed to set lockout information");
4254 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
4255 struct dcerpc_pipe *lp,
4256 struct torture_context *tctx,
4257 struct policy_handle *domain_handle,
4258 struct policy_handle *lsa_handle,
4259 struct policy_handle *user_handle,
4260 const struct dom_sid *domain_sid,
4262 struct cli_credentials *machine_credentials)
4265 struct dcerpc_binding_handle *b = p->binding_handle;
4266 struct dcerpc_binding_handle *lb = lp->binding_handle;
4268 struct policy_handle lsa_acct_handle;
4269 struct dom_sid *user_sid;
4271 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
4274 struct lsa_EnumAccountRights r;
4275 struct lsa_RightSet rights;
4277 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4279 r.in.handle = lsa_handle;
4280 r.in.sid = user_sid;
4281 r.out.rights = &rights;
4283 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4284 "lsa_EnumAccountRights failed");
4285 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4286 "Expected enum rights for account to fail");
4290 struct lsa_RightSet rights;
4291 struct lsa_StringLarge names[2];
4292 struct lsa_AddAccountRights r;
4294 torture_comment(tctx, "Testing LSA AddAccountRights\n");
4296 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
4297 init_lsa_StringLarge(&names[1], NULL);
4300 rights.names = names;
4302 r.in.handle = lsa_handle;
4303 r.in.sid = user_sid;
4304 r.in.rights = &rights;
4306 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
4307 "lsa_AddAccountRights failed");
4308 torture_assert_ntstatus_ok(tctx, r.out.result,
4309 "Failed to add privileges");
4313 struct lsa_EnumAccounts r;
4314 uint32_t resume_handle = 0;
4315 struct lsa_SidArray lsa_sid_array;
4317 bool found_sid = false;
4319 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4321 r.in.handle = lsa_handle;
4322 r.in.num_entries = 0x1000;
4323 r.in.resume_handle = &resume_handle;
4324 r.out.sids = &lsa_sid_array;
4325 r.out.resume_handle = &resume_handle;
4327 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4328 "lsa_EnumAccounts failed");
4329 torture_assert_ntstatus_ok(tctx, r.out.result,
4330 "Failed to enum accounts");
4332 for (i=0; i < lsa_sid_array.num_sids; i++) {
4333 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4338 torture_assert(tctx, found_sid,
4339 "failed to list privileged account");
4343 struct lsa_EnumAccountRights r;
4344 struct lsa_RightSet user_rights;
4346 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4348 r.in.handle = lsa_handle;
4349 r.in.sid = user_sid;
4350 r.out.rights = &user_rights;
4352 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4353 "lsa_EnumAccountRights failed");
4354 torture_assert_ntstatus_ok(tctx, r.out.result,
4355 "Failed to enum rights for account");
4357 if (user_rights.count < 1) {
4358 torture_warning(tctx, "failed to find newly added rights");
4364 struct lsa_OpenAccount r;
4366 torture_comment(tctx, "Testing LSA OpenAccount\n");
4368 r.in.handle = lsa_handle;
4369 r.in.sid = user_sid;
4370 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4371 r.out.acct_handle = &lsa_acct_handle;
4373 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4374 "lsa_OpenAccount failed");
4375 torture_assert_ntstatus_ok(tctx, r.out.result,
4376 "Failed to open lsa account");
4380 struct lsa_GetSystemAccessAccount r;
4381 uint32_t access_mask;
4383 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4385 r.in.handle = &lsa_acct_handle;
4386 r.out.access_mask = &access_mask;
4388 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4389 "lsa_GetSystemAccessAccount failed");
4390 torture_assert_ntstatus_ok(tctx, r.out.result,
4391 "Failed to get lsa system access account");
4397 torture_comment(tctx, "Testing LSA Close\n");
4399 r.in.handle = &lsa_acct_handle;
4400 r.out.handle = &lsa_acct_handle;
4402 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(lb, tctx, &r),
4403 "lsa_Close failed");
4404 torture_assert_ntstatus_ok(tctx, r.out.result,
4405 "Failed to close lsa");
4409 struct samr_DeleteUser r;
4411 torture_comment(tctx, "Testing SAMR DeleteUser\n");
4413 r.in.user_handle = user_handle;
4414 r.out.user_handle = user_handle;
4416 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &r),
4417 "DeleteUser failed");
4418 torture_assert_ntstatus_ok(tctx, r.out.result,
4419 "DeleteUser failed");
4423 struct lsa_EnumAccounts r;
4424 uint32_t resume_handle = 0;
4425 struct lsa_SidArray lsa_sid_array;
4427 bool found_sid = false;
4429 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4431 r.in.handle = lsa_handle;
4432 r.in.num_entries = 0x1000;
4433 r.in.resume_handle = &resume_handle;
4434 r.out.sids = &lsa_sid_array;
4435 r.out.resume_handle = &resume_handle;
4437 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4438 "lsa_EnumAccounts failed");
4439 torture_assert_ntstatus_ok(tctx, r.out.result,
4440 "Failed to enum accounts");
4442 for (i=0; i < lsa_sid_array.num_sids; i++) {
4443 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4448 torture_assert(tctx, found_sid,
4449 "failed to list privileged account");
4453 struct lsa_EnumAccountRights r;
4454 struct lsa_RightSet user_rights;
4456 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4458 r.in.handle = lsa_handle;
4459 r.in.sid = user_sid;
4460 r.out.rights = &user_rights;
4462 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4463 "lsa_EnumAccountRights failed");
4464 torture_assert_ntstatus_ok(tctx, r.out.result,
4465 "Failed to enum rights for account");
4467 if (user_rights.count < 1) {
4468 torture_warning(tctx, "failed to find newly added rights");
4474 struct lsa_OpenAccount r;
4476 torture_comment(tctx, "Testing LSA OpenAccount\n");
4478 r.in.handle = lsa_handle;
4479 r.in.sid = user_sid;
4480 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4481 r.out.acct_handle = &lsa_acct_handle;
4483 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4484 "lsa_OpenAccount failed");
4485 torture_assert_ntstatus_ok(tctx, r.out.result,
4486 "Failed to open lsa account");
4490 struct lsa_GetSystemAccessAccount r;
4491 uint32_t access_mask;
4493 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4495 r.in.handle = &lsa_acct_handle;
4496 r.out.access_mask = &access_mask;
4498 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4499 "lsa_GetSystemAccessAccount failed");
4500 torture_assert_ntstatus_ok(tctx, r.out.result,
4501 "Failed to get lsa system access account");
4505 struct lsa_DeleteObject r;
4507 torture_comment(tctx, "Testing LSA DeleteObject\n");
4509 r.in.handle = &lsa_acct_handle;
4510 r.out.handle = &lsa_acct_handle;
4512 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(lb, tctx, &r),
4513 "lsa_DeleteObject failed");
4514 torture_assert_ntstatus_ok(tctx, r.out.result,
4515 "Failed to delete object");
4519 struct lsa_EnumAccounts r;
4520 uint32_t resume_handle = 0;
4521 struct lsa_SidArray lsa_sid_array;
4523 bool found_sid = false;
4525 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4527 r.in.handle = lsa_handle;
4528 r.in.num_entries = 0x1000;
4529 r.in.resume_handle = &resume_handle;
4530 r.out.sids = &lsa_sid_array;
4531 r.out.resume_handle = &resume_handle;
4533 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4534 "lsa_EnumAccounts failed");
4535 torture_assert_ntstatus_ok(tctx, r.out.result,
4536 "Failed to enum accounts");
4538 for (i=0; i < lsa_sid_array.num_sids; i++) {
4539 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4544 torture_assert(tctx, !found_sid,
4545 "should not have listed privileged account");
4549 struct lsa_EnumAccountRights r;
4550 struct lsa_RightSet user_rights;
4552 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4554 r.in.handle = lsa_handle;
4555 r.in.sid = user_sid;
4556 r.out.rights = &user_rights;
4558 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4559 "lsa_EnumAccountRights failed");
4560 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4561 "Failed to enum rights for account");
4567 static bool test_user_ops(struct dcerpc_pipe *p,
4568 struct torture_context *tctx,
4569 struct policy_handle *user_handle,
4570 struct policy_handle *domain_handle,
4571 const struct dom_sid *domain_sid,
4572 uint32_t base_acct_flags,
4573 const char *base_acct_name, enum torture_samr_choice which_ops,
4574 struct cli_credentials *machine_credentials)
4576 char *password = NULL;
4577 struct samr_QueryUserInfo q;
4578 union samr_UserInfo *info;
4580 struct dcerpc_binding_handle *b = p->binding_handle;
4585 const uint32_t password_fields[] = {
4586 SAMR_FIELD_NT_PASSWORD_PRESENT,
4587 SAMR_FIELD_LM_PASSWORD_PRESENT,
4588 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
4592 status = test_LookupName(b, tctx, domain_handle, base_acct_name, &rid);
4593 if (!NT_STATUS_IS_OK(status)) {
4597 switch (which_ops) {
4598 case TORTURE_SAMR_USER_ATTRIBUTES:
4599 if (!test_QuerySecurity(b, tctx, user_handle)) {
4603 if (!test_QueryUserInfo(b, tctx, user_handle)) {
4607 if (!test_QueryUserInfo2(b, tctx, user_handle)) {
4611 if (!test_SetUserInfo(b, tctx, user_handle, base_acct_flags,
4616 if (!test_GetUserPwInfo(b, tctx, user_handle)) {
4620 if (!test_TestPrivateFunctionsUser(b, tctx, user_handle)) {
4624 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
4628 case TORTURE_SAMR_PASSWORDS:
4629 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
4630 char simple_pass[9];
4631 char *v = generate_random_str(tctx, 1);
4633 ZERO_STRUCT(simple_pass);
4634 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4636 torture_comment(tctx, "Testing machine account password policy rules\n");
4638 /* Workstation trust accounts don't seem to need to honour password quality policy */
4639 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4643 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
4647 /* reset again, to allow another 'user' password change */
4648 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4652 /* Try a 'short' password */
4653 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
4657 /* Try a compleatly random password */
4658 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
4663 for (i = 0; password_fields[i]; i++) {
4664 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
4668 /* check it was set right */
4669 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4674 for (i = 0; password_fields[i]; i++) {
4675 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
4679 /* check it was set right */
4680 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4685 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
4689 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
4693 if (torture_setting_bool(tctx, "samba4", false)) {
4694 torture_comment(tctx, "skipping Set Password level 18 and 21 against Samba4\n");
4697 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
4701 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4705 for (i = 0; password_fields[i]; i++) {
4707 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
4708 /* we need to skip as that would break
4709 * the ChangePasswordUser3 verify */
4713 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
4717 /* check it was set right */
4718 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4724 q.in.user_handle = user_handle;
4728 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
4729 "QueryUserInfo failed");
4730 if (!NT_STATUS_IS_OK(q.out.result)) {
4731 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4732 q.in.level, nt_errstr(q.out.result));
4735 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4736 if ((info->info5.acct_flags) != expected_flags) {
4737 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4738 info->info5.acct_flags,
4741 if (!torture_setting_bool(tctx, "samba3", false)) {
4745 if (info->info5.rid != rid) {
4746 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
4747 info->info5.rid, rid);
4754 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
4756 /* test last password change timestamp behaviour */
4757 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
4759 user_handle, &password,
4760 machine_credentials)) {
4765 torture_comment(tctx, "pwdLastSet test succeeded\n");
4767 torture_warning(tctx, "pwdLastSet test failed\n");
4772 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
4774 /* test bad pwd count change behaviour */
4775 if (!test_Password_badpwdcount_wrap(p, tctx, base_acct_flags,
4778 user_handle, &password,
4779 machine_credentials)) {
4784 torture_comment(tctx, "badPwdCount test succeeded\n");
4786 torture_warning(tctx, "badPwdCount test failed\n");
4791 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
4793 if (!test_Password_lockout_wrap(p, tctx, base_acct_flags,
4796 user_handle, &password,
4797 machine_credentials))
4803 torture_comment(tctx, "lockout test succeeded\n");
4805 torture_warning(tctx, "lockout test failed\n");
4811 case TORTURE_SAMR_USER_PRIVILEGES: {
4813 struct dcerpc_pipe *lp;
4814 struct policy_handle *lsa_handle;
4815 struct dcerpc_binding_handle *lb;
4817 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
4818 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
4819 lb = lp->binding_handle;
4821 if (!test_lsa_OpenPolicy2(lb, tctx, &lsa_handle)) {
4825 if (!test_DeleteUser_with_privs(p, lp, tctx,
4826 domain_handle, lsa_handle, user_handle,
4828 machine_credentials)) {
4832 if (!test_lsa_Close(lb, tctx, lsa_handle)) {
4837 torture_warning(tctx, "privileged user delete test failed\n");
4842 case TORTURE_SAMR_OTHER:
4843 case TORTURE_SAMR_MANY_ACCOUNTS:
4844 case TORTURE_SAMR_MANY_GROUPS:
4845 case TORTURE_SAMR_MANY_ALIASES:
4846 /* We just need the account to exist */
4852 static bool test_alias_ops(struct dcerpc_binding_handle *b,
4853 struct torture_context *tctx,
4854 struct policy_handle *alias_handle,
4855 const struct dom_sid *domain_sid)
4859 if (!torture_setting_bool(tctx, "samba3", false)) {
4860 if (!test_QuerySecurity(b, tctx, alias_handle)) {
4865 if (!test_QueryAliasInfo(b, tctx, alias_handle)) {
4869 if (!test_SetAliasInfo(b, tctx, alias_handle)) {
4873 if (!test_AddMemberToAlias(b, tctx, alias_handle, domain_sid)) {
4877 if (torture_setting_bool(tctx, "samba3", false) ||
4878 torture_setting_bool(tctx, "samba4", false)) {
4879 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
4883 if (!test_AddMultipleMembersToAlias(b, tctx, alias_handle)) {
4891 static bool test_DeleteUser(struct dcerpc_binding_handle *b,
4892 struct torture_context *tctx,
4893 struct policy_handle *user_handle)
4895 struct samr_DeleteUser d;
4896 torture_comment(tctx, "Testing DeleteUser\n");
4898 d.in.user_handle = user_handle;
4899 d.out.user_handle = user_handle;
4901 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
4902 "DeleteUser failed");
4903 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteUser");
4908 bool test_DeleteUser_byname(struct dcerpc_binding_handle *b,
4909 struct torture_context *tctx,
4910 struct policy_handle *handle, const char *name)
4913 struct samr_DeleteUser d;
4914 struct policy_handle user_handle;
4917 status = test_LookupName(b, tctx, handle, name, &rid);
4918 if (!NT_STATUS_IS_OK(status)) {
4922 status = test_OpenUser_byname(b, tctx, handle, name, &user_handle);
4923 if (!NT_STATUS_IS_OK(status)) {
4927 d.in.user_handle = &user_handle;
4928 d.out.user_handle = &user_handle;
4929 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
4930 "DeleteUser failed");
4931 if (!NT_STATUS_IS_OK(d.out.result)) {
4932 status = d.out.result;
4939 torture_warning(tctx, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
4944 static bool test_DeleteGroup_byname(struct dcerpc_binding_handle *b,
4945 struct torture_context *tctx,
4946 struct policy_handle *handle, const char *name)
4949 struct samr_OpenGroup r;
4950 struct samr_DeleteDomainGroup d;
4951 struct policy_handle group_handle;
4954 status = test_LookupName(b, tctx, handle, name, &rid);
4955 if (!NT_STATUS_IS_OK(status)) {
4959 r.in.domain_handle = handle;
4960 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4962 r.out.group_handle = &group_handle;
4963 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
4964 "OpenGroup failed");
4965 if (!NT_STATUS_IS_OK(r.out.result)) {
4966 status = r.out.result;
4970 d.in.group_handle = &group_handle;
4971 d.out.group_handle = &group_handle;
4972 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
4973 "DeleteDomainGroup failed");
4974 if (!NT_STATUS_IS_OK(d.out.result)) {
4975 status = d.out.result;
4982 torture_warning(tctx, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
4987 static bool test_DeleteAlias_byname(struct dcerpc_binding_handle *b,
4988 struct torture_context *tctx,
4989 struct policy_handle *domain_handle,
4993 struct samr_OpenAlias r;
4994 struct samr_DeleteDomAlias d;
4995 struct policy_handle alias_handle;
4998 torture_comment(tctx, "Testing DeleteAlias_byname\n");
5000 status = test_LookupName(b, tctx, domain_handle, name, &rid);
5001 if (!NT_STATUS_IS_OK(status)) {
5005 r.in.domain_handle = domain_handle;
5006 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5008 r.out.alias_handle = &alias_handle;
5009 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5010 "OpenAlias failed");
5011 if (!NT_STATUS_IS_OK(r.out.result)) {
5012 status = r.out.result;
5016 d.in.alias_handle = &alias_handle;
5017 d.out.alias_handle = &alias_handle;
5018 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5019 "DeleteDomAlias failed");
5020 if (!NT_STATUS_IS_OK(d.out.result)) {
5021 status = d.out.result;
5028 torture_warning(tctx, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
5032 static bool test_DeleteAlias(struct dcerpc_binding_handle *b,
5033 struct torture_context *tctx,
5034 struct policy_handle *alias_handle)
5036 struct samr_DeleteDomAlias d;
5039 torture_comment(tctx, "Testing DeleteAlias\n");
5041 d.in.alias_handle = alias_handle;
5042 d.out.alias_handle = alias_handle;
5044 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5045 "DeleteDomAlias failed");
5046 if (!NT_STATUS_IS_OK(d.out.result)) {
5047 torture_warning(tctx, "DeleteAlias failed - %s\n", nt_errstr(d.out.result));
5054 static bool test_CreateAlias(struct dcerpc_binding_handle *b,
5055 struct torture_context *tctx,
5056 struct policy_handle *domain_handle,
5057 const char *alias_name,
5058 struct policy_handle *alias_handle,
5059 const struct dom_sid *domain_sid,
5062 struct samr_CreateDomAlias r;
5063 struct lsa_String name;
5067 init_lsa_String(&name, alias_name);
5068 r.in.domain_handle = domain_handle;
5069 r.in.alias_name = &name;
5070 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5071 r.out.alias_handle = alias_handle;
5074 torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
5076 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5077 "CreateDomAlias failed");
5079 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5080 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
5081 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
5084 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
5085 nt_errstr(r.out.result));
5090 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ALIAS_EXISTS)) {
5091 if (!test_DeleteAlias_byname(b, tctx, domain_handle, r.in.alias_name->string)) {
5094 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5095 "CreateDomAlias failed");
5098 if (!NT_STATUS_IS_OK(r.out.result)) {
5099 torture_warning(tctx, "CreateAlias failed - %s\n", nt_errstr(r.out.result));
5107 if (!test_alias_ops(b, tctx, alias_handle, domain_sid)) {
5114 static bool test_ChangePassword(struct dcerpc_pipe *p,
5115 struct torture_context *tctx,
5116 const char *acct_name,
5117 struct policy_handle *domain_handle, char **password)
5120 struct dcerpc_binding_handle *b = p->binding_handle;
5126 if (!test_ChangePasswordUser(b, tctx, acct_name, domain_handle, password)) {
5130 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
5134 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
5138 /* test what happens when setting the old password again */
5139 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
5144 char simple_pass[9];
5145 char *v = generate_random_str(tctx, 1);
5147 ZERO_STRUCT(simple_pass);
5148 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5150 /* test what happens when picking a simple password */
5151 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
5156 /* set samr_SetDomainInfo level 1 with min_length 5 */
5158 struct samr_QueryDomainInfo r;
5159 union samr_DomainInfo *info = NULL;
5160 struct samr_SetDomainInfo s;
5161 uint16_t len_old, len;
5162 uint32_t pwd_prop_old;
5163 int64_t min_pwd_age_old;
5167 r.in.domain_handle = domain_handle;
5171 torture_comment(tctx, "Testing samr_QueryDomainInfo level 1\n");
5172 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
5173 "QueryDomainInfo failed");
5174 if (!NT_STATUS_IS_OK(r.out.result)) {
5178 s.in.domain_handle = domain_handle;
5182 /* remember the old min length, so we can reset it */
5183 len_old = s.in.info->info1.min_password_length;
5184 s.in.info->info1.min_password_length = len;
5185 pwd_prop_old = s.in.info->info1.password_properties;
5186 /* turn off password complexity checks for this test */
5187 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
5189 min_pwd_age_old = s.in.info->info1.min_password_age;
5190 s.in.info->info1.min_password_age = 0;
5192 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5193 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5194 "SetDomainInfo failed");
5195 if (!NT_STATUS_IS_OK(s.out.result)) {
5199 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
5201 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
5205 s.in.info->info1.min_password_length = len_old;
5206 s.in.info->info1.password_properties = pwd_prop_old;
5207 s.in.info->info1.min_password_age = min_pwd_age_old;
5209 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5210 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5211 "SetDomainInfo failed");
5212 if (!NT_STATUS_IS_OK(s.out.result)) {
5219 struct samr_OpenUser r;
5220 struct samr_QueryUserInfo q;
5221 union samr_UserInfo *info;
5222 struct samr_LookupNames n;
5223 struct policy_handle user_handle;
5224 struct samr_Ids rids, types;
5226 n.in.domain_handle = domain_handle;
5228 n.in.names = talloc_array(tctx, struct lsa_String, 1);
5229 n.in.names[0].string = acct_name;
5231 n.out.types = &types;
5233 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
5234 "LookupNames failed");
5235 if (!NT_STATUS_IS_OK(n.out.result)) {
5236 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(n.out.result));
5240 r.in.domain_handle = domain_handle;
5241 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5242 r.in.rid = n.out.rids->ids[0];
5243 r.out.user_handle = &user_handle;
5245 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5247 if (!NT_STATUS_IS_OK(r.out.result)) {
5248 torture_warning(tctx, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(r.out.result));
5252 q.in.user_handle = &user_handle;
5256 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5257 "QueryUserInfo failed");
5258 if (!NT_STATUS_IS_OK(q.out.result)) {
5259 torture_warning(tctx, "QueryUserInfo failed - %s\n", nt_errstr(q.out.result));
5263 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
5265 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
5266 info->info5.last_password_change, true)) {
5271 /* we change passwords twice - this has the effect of verifying
5272 they were changed correctly for the final call */
5273 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5277 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5284 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
5285 struct policy_handle *domain_handle,
5286 const char *user_name,
5287 struct policy_handle *user_handle_out,
5288 struct dom_sid *domain_sid,
5289 enum torture_samr_choice which_ops,
5290 struct cli_credentials *machine_credentials,
5294 TALLOC_CTX *user_ctx;
5296 struct samr_CreateUser r;
5297 struct samr_QueryUserInfo q;
5298 union samr_UserInfo *info;
5299 struct samr_DeleteUser d;
5302 /* This call creates a 'normal' account - check that it really does */
5303 const uint32_t acct_flags = ACB_NORMAL;
5304 struct lsa_String name;
5306 struct dcerpc_binding_handle *b = p->binding_handle;
5308 struct policy_handle user_handle;
5309 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5310 init_lsa_String(&name, user_name);
5312 r.in.domain_handle = domain_handle;
5313 r.in.account_name = &name;
5314 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5315 r.out.user_handle = &user_handle;
5318 torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
5320 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5321 "CreateUser failed");
5323 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5324 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5325 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5328 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5329 nt_errstr(r.out.result));
5334 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5335 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5336 talloc_free(user_ctx);
5339 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5340 "CreateUser failed");
5343 if (!NT_STATUS_IS_OK(r.out.result)) {
5344 talloc_free(user_ctx);
5345 torture_warning(tctx, "CreateUser failed - %s\n", nt_errstr(r.out.result));
5350 if (user_handle_out) {
5351 *user_handle_out = user_handle;
5357 q.in.user_handle = &user_handle;
5361 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5362 "QueryUserInfo failed");
5363 if (!NT_STATUS_IS_OK(q.out.result)) {
5364 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5365 q.in.level, nt_errstr(q.out.result));
5368 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
5369 torture_warning(tctx, "QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5370 info->info16.acct_flags,
5376 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5377 domain_sid, acct_flags, name.string, which_ops,
5378 machine_credentials)) {
5382 if (user_handle_out) {
5383 *user_handle_out = user_handle;
5385 torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
5387 d.in.user_handle = &user_handle;
5388 d.out.user_handle = &user_handle;
5390 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5391 "DeleteUser failed");
5392 if (!NT_STATUS_IS_OK(d.out.result)) {
5393 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5400 talloc_free(user_ctx);
5406 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
5407 struct policy_handle *domain_handle,
5408 struct dom_sid *domain_sid,
5409 enum torture_samr_choice which_ops,
5410 struct cli_credentials *machine_credentials)
5412 struct samr_CreateUser2 r;
5413 struct samr_QueryUserInfo q;
5414 union samr_UserInfo *info;
5415 struct samr_DeleteUser d;
5416 struct policy_handle user_handle;
5418 struct lsa_String name;
5421 struct dcerpc_binding_handle *b = p->binding_handle;
5424 uint32_t acct_flags;
5425 const char *account_name;
5427 } account_types[] = {
5428 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
5429 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5430 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5431 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5432 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5433 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5434 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5435 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5436 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5437 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
5438 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5439 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5440 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5441 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5442 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
5445 for (i = 0; account_types[i].account_name; i++) {
5446 TALLOC_CTX *user_ctx;
5447 uint32_t acct_flags = account_types[i].acct_flags;
5448 uint32_t access_granted;
5449 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5450 init_lsa_String(&name, account_types[i].account_name);
5452 r.in.domain_handle = domain_handle;
5453 r.in.account_name = &name;
5454 r.in.acct_flags = acct_flags;
5455 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5456 r.out.user_handle = &user_handle;
5457 r.out.access_granted = &access_granted;
5460 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
5462 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5463 "CreateUser2 failed");
5465 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5466 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5467 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5470 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5471 nt_errstr(r.out.result));
5477 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5478 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5479 talloc_free(user_ctx);
5483 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5484 "CreateUser2 failed");
5487 if (!NT_STATUS_EQUAL(r.out.result, account_types[i].nt_status)) {
5488 torture_warning(tctx, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5489 nt_errstr(r.out.result), nt_errstr(account_types[i].nt_status));
5493 if (NT_STATUS_IS_OK(r.out.result)) {
5494 q.in.user_handle = &user_handle;
5498 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5499 "QueryUserInfo failed");
5500 if (!NT_STATUS_IS_OK(q.out.result)) {
5501 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5502 q.in.level, nt_errstr(q.out.result));
5505 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
5506 if (acct_flags == ACB_NORMAL) {
5507 expected_flags |= ACB_PW_EXPIRED;
5509 if ((info->info5.acct_flags) != expected_flags) {
5510 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5511 info->info5.acct_flags,
5515 switch (acct_flags) {
5517 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
5518 torture_warning(tctx, "QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5519 DOMAIN_RID_DCS, info->info5.primary_gid);
5524 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
5525 torture_warning(tctx, "QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5526 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
5531 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
5532 torture_warning(tctx, "QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5533 DOMAIN_RID_USERS, info->info5.primary_gid);
5540 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5541 domain_sid, acct_flags, name.string, which_ops,
5542 machine_credentials)) {
5546 if (!policy_handle_empty(&user_handle)) {
5547 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
5549 d.in.user_handle = &user_handle;
5550 d.out.user_handle = &user_handle;
5552 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5553 "DeleteUser failed");
5554 if (!NT_STATUS_IS_OK(d.out.result)) {
5555 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5560 talloc_free(user_ctx);
5566 static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
5567 struct torture_context *tctx,
5568 struct policy_handle *handle)
5570 struct samr_QueryAliasInfo r;
5571 union samr_AliasInfo *info;
5572 uint16_t levels[] = {1, 2, 3};
5576 for (i=0;i<ARRAY_SIZE(levels);i++) {
5577 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
5579 r.in.alias_handle = handle;
5580 r.in.level = levels[i];
5583 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &r),
5584 "QueryAliasInfo failed");
5585 if (!NT_STATUS_IS_OK(r.out.result)) {
5586 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
5587 levels[i], nt_errstr(r.out.result));
5595 static bool test_QueryGroupInfo(struct dcerpc_binding_handle *b,
5596 struct torture_context *tctx,
5597 struct policy_handle *handle)
5599 struct samr_QueryGroupInfo r;
5600 union samr_GroupInfo *info;
5601 uint16_t levels[] = {1, 2, 3, 4, 5};
5605 for (i=0;i<ARRAY_SIZE(levels);i++) {
5606 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5608 r.in.group_handle = handle;
5609 r.in.level = levels[i];
5612 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
5613 "QueryGroupInfo failed");
5614 if (!NT_STATUS_IS_OK(r.out.result)) {
5615 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5616 levels[i], nt_errstr(r.out.result));
5624 static bool test_QueryGroupMember(struct dcerpc_binding_handle *b,
5625 struct torture_context *tctx,
5626 struct policy_handle *handle)
5628 struct samr_QueryGroupMember r;
5629 struct samr_RidTypeArray *rids = NULL;
5632 torture_comment(tctx, "Testing QueryGroupMember\n");
5634 r.in.group_handle = handle;
5637 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &r),
5638 "QueryGroupMember failed");
5639 if (!NT_STATUS_IS_OK(r.out.result)) {
5640 torture_warning(tctx, "QueryGroupInfo failed - %s\n", nt_errstr(r.out.result));
5648 static bool test_SetGroupInfo(struct dcerpc_binding_handle *b,
5649 struct torture_context *tctx,
5650 struct policy_handle *handle)
5652 struct samr_QueryGroupInfo r;
5653 union samr_GroupInfo *info;
5654 struct samr_SetGroupInfo s;
5655 uint16_t levels[] = {1, 2, 3, 4};
5656 uint16_t set_ok[] = {0, 1, 1, 1};
5660 for (i=0;i<ARRAY_SIZE(levels);i++) {
5661 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5663 r.in.group_handle = handle;
5664 r.in.level = levels[i];
5667 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
5668 "QueryGroupInfo failed");
5669 if (!NT_STATUS_IS_OK(r.out.result)) {
5670 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5671 levels[i], nt_errstr(r.out.result));
5675 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
5677 s.in.group_handle = handle;
5678 s.in.level = levels[i];
5679 s.in.info = *r.out.info;
5682 /* disabled this, as it changes the name only from the point of view of samr,
5683 but leaves the name from the point of view of w2k3 internals (and ldap). This means
5684 the name is still reserved, so creating the old name fails, but deleting by the old name
5686 if (s.in.level == 2) {
5687 init_lsa_String(&s.in.info->string, "NewName");
5691 if (s.in.level == 4) {
5692 init_lsa_String(&s.in.info->description, "test description");
5695 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetGroupInfo_r(b, tctx, &s),
5696 "SetGroupInfo failed");
5698 if (!NT_STATUS_IS_OK(s.out.result)) {
5699 torture_warning(tctx, "SetGroupInfo level %u failed - %s\n",
5700 r.in.level, nt_errstr(s.out.result));
5705 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
5706 torture_warning(tctx, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5707 r.in.level, nt_errstr(s.out.result));
5717 static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
5718 struct torture_context *tctx,
5719 struct policy_handle *handle)
5721 struct samr_QueryUserInfo r;
5722 union samr_UserInfo *info;
5723 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5724 11, 12, 13, 14, 16, 17, 20, 21};
5728 for (i=0;i<ARRAY_SIZE(levels);i++) {
5729 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
5731 r.in.user_handle = handle;
5732 r.in.level = levels[i];
5735 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
5736 "QueryUserInfo failed");
5737 if (!NT_STATUS_IS_OK(r.out.result)) {
5738 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5739 levels[i], nt_errstr(r.out.result));
5747 static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
5748 struct torture_context *tctx,
5749 struct policy_handle *handle)
5751 struct samr_QueryUserInfo2 r;
5752 union samr_UserInfo *info;
5753 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5754 11, 12, 13, 14, 16, 17, 20, 21};
5758 for (i=0;i<ARRAY_SIZE(levels);i++) {
5759 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
5761 r.in.user_handle = handle;
5762 r.in.level = levels[i];
5765 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r),
5766 "QueryUserInfo2 failed");
5767 if (!NT_STATUS_IS_OK(r.out.result)) {
5768 torture_warning(tctx, "QueryUserInfo2 level %u failed - %s\n",
5769 levels[i], nt_errstr(r.out.result));
5777 static bool test_OpenUser(struct dcerpc_binding_handle *b,
5778 struct torture_context *tctx,
5779 struct policy_handle *handle, uint32_t rid)
5781 struct samr_OpenUser r;
5782 struct policy_handle user_handle;
5785 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5787 r.in.domain_handle = handle;
5788 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5790 r.out.user_handle = &user_handle;
5792 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5794 if (!NT_STATUS_IS_OK(r.out.result)) {
5795 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5799 if (!test_QuerySecurity(b, tctx, &user_handle)) {
5803 if (!test_QueryUserInfo(b, tctx, &user_handle)) {
5807 if (!test_QueryUserInfo2(b, tctx, &user_handle)) {
5811 if (!test_GetUserPwInfo(b, tctx, &user_handle)) {
5815 if (!test_GetGroupsForUser(b, tctx, &user_handle)) {
5819 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
5826 static bool test_OpenGroup(struct dcerpc_binding_handle *b,
5827 struct torture_context *tctx,
5828 struct policy_handle *handle, uint32_t rid)
5830 struct samr_OpenGroup r;
5831 struct policy_handle group_handle;
5834 torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
5836 r.in.domain_handle = handle;
5837 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5839 r.out.group_handle = &group_handle;
5841 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
5842 "OpenGroup failed");
5843 if (!NT_STATUS_IS_OK(r.out.result)) {
5844 torture_warning(tctx, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5848 if (!torture_setting_bool(tctx, "samba3", false)) {
5849 if (!test_QuerySecurity(b, tctx, &group_handle)) {
5854 if (!test_QueryGroupInfo(b, tctx, &group_handle)) {
5858 if (!test_QueryGroupMember(b, tctx, &group_handle)) {
5862 if (!test_samr_handle_Close(b, tctx, &group_handle)) {
5869 static bool test_OpenAlias(struct dcerpc_binding_handle *b,
5870 struct torture_context *tctx,
5871 struct policy_handle *handle, uint32_t rid)
5873 struct samr_OpenAlias r;
5874 struct policy_handle alias_handle;
5877 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
5879 r.in.domain_handle = handle;
5880 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5882 r.out.alias_handle = &alias_handle;
5884 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5885 "OpenAlias failed");
5886 if (!NT_STATUS_IS_OK(r.out.result)) {
5887 torture_warning(tctx, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5891 if (!torture_setting_bool(tctx, "samba3", false)) {
5892 if (!test_QuerySecurity(b, tctx, &alias_handle)) {
5897 if (!test_QueryAliasInfo(b, tctx, &alias_handle)) {
5901 if (!test_GetMembersInAlias(b, tctx, &alias_handle)) {
5905 if (!test_samr_handle_Close(b, tctx, &alias_handle)) {
5912 static bool check_mask(struct dcerpc_binding_handle *b,
5913 struct torture_context *tctx,
5914 struct policy_handle *handle, uint32_t rid,
5915 uint32_t acct_flag_mask)
5917 struct samr_OpenUser r;
5918 struct samr_QueryUserInfo q;
5919 union samr_UserInfo *info;
5920 struct policy_handle user_handle;
5923 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5925 r.in.domain_handle = handle;
5926 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5928 r.out.user_handle = &user_handle;
5930 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5932 if (!NT_STATUS_IS_OK(r.out.result)) {
5933 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5937 q.in.user_handle = &user_handle;
5941 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5942 "QueryUserInfo failed");
5943 if (!NT_STATUS_IS_OK(q.out.result)) {
5944 torture_warning(tctx, "QueryUserInfo level 16 failed - %s\n",
5945 nt_errstr(q.out.result));
5948 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
5949 torture_warning(tctx, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
5950 acct_flag_mask, info->info16.acct_flags, rid);
5955 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
5962 static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle *b,
5963 struct torture_context *tctx,
5964 struct policy_handle *handle)
5966 struct samr_EnumDomainUsers r;
5967 uint32_t mask, resume_handle=0;
5970 struct samr_LookupNames n;
5971 struct samr_LookupRids lr ;
5972 struct lsa_Strings names;
5973 struct samr_Ids rids, types;
5974 struct samr_SamArray *sam = NULL;
5975 uint32_t num_entries = 0;
5977 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
5978 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
5979 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
5982 torture_comment(tctx, "Testing EnumDomainUsers\n");
5984 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
5985 r.in.domain_handle = handle;
5986 r.in.resume_handle = &resume_handle;
5987 r.in.acct_flags = mask = masks[mask_idx];
5988 r.in.max_size = (uint32_t)-1;
5989 r.out.resume_handle = &resume_handle;
5990 r.out.num_entries = &num_entries;
5993 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
5994 "EnumDomainUsers failed");
5995 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
5996 !NT_STATUS_IS_OK(r.out.result)) {
5997 torture_warning(tctx, "EnumDomainUsers failed - %s\n", nt_errstr(r.out.result));
6001 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
6003 if (sam->count == 0) {
6007 for (i=0;i<sam->count;i++) {
6009 if (!check_mask(b, tctx, handle, sam->entries[i].idx, mask)) {
6012 } else if (!test_OpenUser(b, tctx, handle, sam->entries[i].idx)) {
6018 torture_comment(tctx, "Testing LookupNames\n");
6019 n.in.domain_handle = handle;
6020 n.in.num_names = sam->count;
6021 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
6023 n.out.types = &types;
6024 for (i=0;i<sam->count;i++) {
6025 n.in.names[i].string = sam->entries[i].name.string;
6027 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
6028 "LookupNames failed");
6029 if (!NT_STATUS_IS_OK(n.out.result)) {
6030 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(n.out.result));
6035 torture_comment(tctx, "Testing LookupRids\n");
6036 lr.in.domain_handle = handle;
6037 lr.in.num_rids = sam->count;
6038 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
6039 lr.out.names = &names;
6040 lr.out.types = &types;
6041 for (i=0;i<sam->count;i++) {
6042 lr.in.rids[i] = sam->entries[i].idx;
6044 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupRids_r(b, tctx, &lr),
6045 "LookupRids failed");
6046 torture_assert_ntstatus_ok(tctx, lr.out.result, "LookupRids");
6052 try blasting the server with a bunch of sync requests
6054 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
6055 struct policy_handle *handle)
6057 struct samr_EnumDomainUsers r;
6058 uint32_t resume_handle=0;
6060 #define ASYNC_COUNT 100
6061 struct tevent_req *req[ASYNC_COUNT];
6063 if (!torture_setting_bool(tctx, "dangerous", false)) {
6064 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
6067 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
6069 r.in.domain_handle = handle;
6070 r.in.resume_handle = &resume_handle;
6071 r.in.acct_flags = 0;
6072 r.in.max_size = (uint32_t)-1;
6073 r.out.resume_handle = &resume_handle;
6075 for (i=0;i<ASYNC_COUNT;i++) {
6076 req[i] = dcerpc_samr_EnumDomainUsers_r_send(tctx, tctx->ev, p->binding_handle, &r);
6079 for (i=0;i<ASYNC_COUNT;i++) {
6080 tevent_req_poll(req[i], tctx->ev);
6081 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r_recv(req[i], tctx),
6082 talloc_asprintf(tctx, "EnumDomainUsers[%d] failed - %s\n",
6083 i, nt_errstr(r.out.result)));
6086 torture_comment(tctx, "%d async requests OK\n", i);
6091 static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle *b,
6092 struct torture_context *tctx,
6093 struct policy_handle *handle)
6095 struct samr_EnumDomainGroups r;
6096 uint32_t resume_handle=0;
6097 struct samr_SamArray *sam = NULL;
6098 uint32_t num_entries = 0;
6101 bool universal_group_found = false;
6103 torture_comment(tctx, "Testing EnumDomainGroups\n");
6105 r.in.domain_handle = handle;
6106 r.in.resume_handle = &resume_handle;
6107 r.in.max_size = (uint32_t)-1;
6108 r.out.resume_handle = &resume_handle;
6109 r.out.num_entries = &num_entries;
6112 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
6113 "EnumDomainGroups failed");
6114 if (!NT_STATUS_IS_OK(r.out.result)) {
6115 torture_warning(tctx, "EnumDomainGroups failed - %s\n", nt_errstr(r.out.result));
6123 for (i=0;i<sam->count;i++) {
6124 if (!test_OpenGroup(b, tctx, handle, sam->entries[i].idx)) {
6127 if ((ret == true) && (strcasecmp(sam->entries[i].name.string,
6128 "Enterprise Admins") == 0)) {
6129 universal_group_found = true;
6133 /* when we are running this on s4 we should get back at least the
6134 * "Enterprise Admins" universal group. If we don't get a group entry
6135 * at all we probably are performing the test on the builtin domain.
6136 * So ignore this case. */
6137 if (torture_setting_bool(tctx, "samba4", false)) {
6138 if ((sam->count > 0) && (!universal_group_found)) {
6146 static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle *b,
6147 struct torture_context *tctx,
6148 struct policy_handle *handle)
6150 struct samr_EnumDomainAliases r;
6151 uint32_t resume_handle=0;
6152 struct samr_SamArray *sam = NULL;
6153 uint32_t num_entries = 0;
6157 torture_comment(tctx, "Testing EnumDomainAliases\n");
6159 r.in.domain_handle = handle;
6160 r.in.resume_handle = &resume_handle;
6161 r.in.max_size = (uint32_t)-1;
6163 r.out.num_entries = &num_entries;
6164 r.out.resume_handle = &resume_handle;
6166 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
6167 "EnumDomainAliases failed");
6168 if (!NT_STATUS_IS_OK(r.out.result)) {
6169 torture_warning(tctx, "EnumDomainAliases failed - %s\n", nt_errstr(r.out.result));
6177 for (i=0;i<sam->count;i++) {
6178 if (!test_OpenAlias(b, tctx, handle, sam->entries[i].idx)) {
6186 static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle *b,
6187 struct torture_context *tctx,
6188 struct policy_handle *handle)
6190 struct samr_GetDisplayEnumerationIndex r;
6192 uint16_t levels[] = {1, 2, 3, 4, 5};
6193 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6194 struct lsa_String name;
6198 for (i=0;i<ARRAY_SIZE(levels);i++) {
6199 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
6201 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6203 r.in.domain_handle = handle;
6204 r.in.level = levels[i];
6208 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6209 "GetDisplayEnumerationIndex failed");
6212 !NT_STATUS_IS_OK(r.out.result) &&
6213 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6214 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6215 levels[i], nt_errstr(r.out.result));
6219 init_lsa_String(&name, "zzzzzzzz");
6221 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6222 "GetDisplayEnumerationIndex failed");
6224 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6225 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6226 levels[i], nt_errstr(r.out.result));
6234 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle *b,
6235 struct torture_context *tctx,
6236 struct policy_handle *handle)
6238 struct samr_GetDisplayEnumerationIndex2 r;
6240 uint16_t levels[] = {1, 2, 3, 4, 5};
6241 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6242 struct lsa_String name;
6246 for (i=0;i<ARRAY_SIZE(levels);i++) {
6247 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
6249 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6251 r.in.domain_handle = handle;
6252 r.in.level = levels[i];
6256 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6257 "GetDisplayEnumerationIndex2 failed");
6259 !NT_STATUS_IS_OK(r.out.result) &&
6260 !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));
6266 init_lsa_String(&name, "zzzzzzzz");
6268 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6269 "GetDisplayEnumerationIndex2 failed");
6270 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6271 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6272 levels[i], nt_errstr(r.out.result));
6280 #define STRING_EQUAL_QUERY(s1, s2, user) \
6281 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6282 /* odd, but valid */ \
6283 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6284 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
6285 #s1, user.string, s1.string, s2.string, __location__); \
6288 #define INT_EQUAL_QUERY(s1, s2, user) \
6290 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6291 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6295 static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle *b,
6296 struct torture_context *tctx,
6297 struct samr_QueryDisplayInfo *querydisplayinfo,
6298 bool *seen_testuser)
6300 struct samr_OpenUser r;
6301 struct samr_QueryUserInfo q;
6302 union samr_UserInfo *info;
6303 struct policy_handle user_handle;
6305 r.in.domain_handle = querydisplayinfo->in.domain_handle;
6306 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6307 for (i = 0; ; i++) {
6308 switch (querydisplayinfo->in.level) {
6310 if (i >= querydisplayinfo->out.info->info1.count) {
6313 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
6316 if (i >= querydisplayinfo->out.info->info2.count) {
6319 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
6325 /* Not interested in validating just the account name */
6329 r.out.user_handle = &user_handle;
6331 switch (querydisplayinfo->in.level) {
6334 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6336 if (!NT_STATUS_IS_OK(r.out.result)) {
6337 torture_warning(tctx, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6342 q.in.user_handle = &user_handle;
6345 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6346 "QueryUserInfo failed");
6347 if (!NT_STATUS_IS_OK(r.out.result)) {
6348 torture_warning(tctx, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6352 switch (querydisplayinfo->in.level) {
6354 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
6355 *seen_testuser = true;
6357 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
6358 info->info21.full_name, info->info21.account_name);
6359 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
6360 info->info21.account_name, info->info21.account_name);
6361 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
6362 info->info21.description, info->info21.account_name);
6363 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
6364 info->info21.rid, info->info21.account_name);
6365 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
6366 info->info21.acct_flags, info->info21.account_name);
6370 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
6371 info->info21.account_name, info->info21.account_name);
6372 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
6373 info->info21.description, info->info21.account_name);
6374 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
6375 info->info21.rid, info->info21.account_name);
6376 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
6377 info->info21.acct_flags, info->info21.account_name);
6379 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
6380 torture_warning(tctx, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6381 info->info21.account_name.string);
6384 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
6385 torture_warning(tctx, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6386 info->info21.account_name.string,
6387 querydisplayinfo->out.info->info2.entries[i].acct_flags,
6388 info->info21.acct_flags);
6395 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6402 static bool test_QueryDisplayInfo(struct dcerpc_binding_handle *b,
6403 struct torture_context *tctx,
6404 struct policy_handle *handle)
6406 struct samr_QueryDisplayInfo r;
6407 struct samr_QueryDomainInfo dom_info;
6408 union samr_DomainInfo *info = NULL;
6410 uint16_t levels[] = {1, 2, 3, 4, 5};
6412 bool seen_testuser = false;
6413 uint32_t total_size;
6414 uint32_t returned_size;
6415 union samr_DispInfo disp_info;
6418 for (i=0;i<ARRAY_SIZE(levels);i++) {
6419 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
6422 r.out.result = STATUS_MORE_ENTRIES;
6423 while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
6424 r.in.domain_handle = handle;
6425 r.in.level = levels[i];
6426 r.in.max_entries = 2;
6427 r.in.buf_size = (uint32_t)-1;
6428 r.out.total_size = &total_size;
6429 r.out.returned_size = &returned_size;
6430 r.out.info = &disp_info;
6432 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6433 "QueryDisplayInfo failed");
6434 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(r.out.result)) {
6435 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6436 levels[i], nt_errstr(r.out.result));
6439 switch (r.in.level) {
6441 if (!test_each_DisplayInfo_user(b, tctx, &r, &seen_testuser)) {
6444 r.in.start_idx += r.out.info->info1.count;
6447 if (!test_each_DisplayInfo_user(b, tctx, &r, NULL)) {
6450 r.in.start_idx += r.out.info->info2.count;
6453 r.in.start_idx += r.out.info->info3.count;
6456 r.in.start_idx += r.out.info->info4.count;
6459 r.in.start_idx += r.out.info->info5.count;
6463 dom_info.in.domain_handle = handle;
6464 dom_info.in.level = 2;
6465 dom_info.out.info = &info;
6467 /* Check number of users returned is correct */
6468 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &dom_info),
6469 "QueryDomainInfo failed");
6470 if (!NT_STATUS_IS_OK(dom_info.out.result)) {
6471 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6472 r.in.level, nt_errstr(dom_info.out.result));
6476 switch (r.in.level) {
6479 if (info->general.num_users < r.in.start_idx) {
6480 /* On AD deployments this numbers don't match
6481 * since QueryDisplayInfo returns universal and
6482 * global groups, QueryDomainInfo only global
6484 if (torture_setting_bool(tctx, "samba3", false)) {
6485 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6486 r.in.start_idx, info->general.num_groups,
6487 info->general.domain_name.string);
6491 if (!seen_testuser) {
6492 struct policy_handle user_handle;
6493 if (NT_STATUS_IS_OK(test_OpenUser_byname(b, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
6494 torture_warning(tctx, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
6495 info->general.domain_name.string);
6497 test_samr_handle_Close(b, tctx, &user_handle);
6503 if (info->general.num_groups != r.in.start_idx) {
6504 /* On AD deployments this numbers don't match
6505 * since QueryDisplayInfo returns universal and
6506 * global groups, QueryDomainInfo only global
6508 if (torture_setting_bool(tctx, "samba3", false)) {
6509 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6510 r.in.start_idx, info->general.num_groups,
6511 info->general.domain_name.string);
6524 static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle *b,
6525 struct torture_context *tctx,
6526 struct policy_handle *handle)
6528 struct samr_QueryDisplayInfo2 r;
6530 uint16_t levels[] = {1, 2, 3, 4, 5};
6532 uint32_t total_size;
6533 uint32_t returned_size;
6534 union samr_DispInfo info;
6536 for (i=0;i<ARRAY_SIZE(levels);i++) {
6537 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
6539 r.in.domain_handle = handle;
6540 r.in.level = levels[i];
6542 r.in.max_entries = 1000;
6543 r.in.buf_size = (uint32_t)-1;
6544 r.out.total_size = &total_size;
6545 r.out.returned_size = &returned_size;
6548 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo2_r(b, tctx, &r),
6549 "QueryDisplayInfo2 failed");
6550 if (!NT_STATUS_IS_OK(r.out.result)) {
6551 torture_warning(tctx, "QueryDisplayInfo2 level %u failed - %s\n",
6552 levels[i], nt_errstr(r.out.result));
6560 static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle *b,
6561 struct torture_context *tctx,
6562 struct policy_handle *handle)
6564 struct samr_QueryDisplayInfo3 r;
6566 uint16_t levels[] = {1, 2, 3, 4, 5};
6568 uint32_t total_size;
6569 uint32_t returned_size;
6570 union samr_DispInfo info;
6572 for (i=0;i<ARRAY_SIZE(levels);i++) {
6573 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
6575 r.in.domain_handle = handle;
6576 r.in.level = levels[i];
6578 r.in.max_entries = 1000;
6579 r.in.buf_size = (uint32_t)-1;
6580 r.out.total_size = &total_size;
6581 r.out.returned_size = &returned_size;
6584 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo3_r(b, tctx, &r),
6585 "QueryDisplayInfo3 failed");
6586 if (!NT_STATUS_IS_OK(r.out.result)) {
6587 torture_warning(tctx, "QueryDisplayInfo3 level %u failed - %s\n",
6588 levels[i], nt_errstr(r.out.result));
6597 static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle *b,
6598 struct torture_context *tctx,
6599 struct policy_handle *handle)
6601 struct samr_QueryDisplayInfo r;
6603 uint32_t total_size;
6604 uint32_t returned_size;
6605 union samr_DispInfo info;
6607 torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
6609 r.in.domain_handle = handle;
6612 r.in.max_entries = 1;
6613 r.in.buf_size = (uint32_t)-1;
6614 r.out.total_size = &total_size;
6615 r.out.returned_size = &returned_size;
6619 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6620 "QueryDisplayInfo failed");
6621 if (NT_STATUS_IS_OK(r.out.result) && *r.out.returned_size != 0) {
6622 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
6623 torture_warning(tctx, "expected idx %d but got %d\n",
6625 r.out.info->info1.entries[0].idx);
6629 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
6630 !NT_STATUS_IS_OK(r.out.result)) {
6631 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6632 r.in.level, nt_errstr(r.out.result));
6637 } while ((NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) ||
6638 NT_STATUS_IS_OK(r.out.result)) &&
6639 *r.out.returned_size != 0);
6644 static bool test_QueryDomainInfo(struct dcerpc_pipe *p,
6645 struct torture_context *tctx,
6646 struct policy_handle *handle)
6648 struct samr_QueryDomainInfo r;
6649 union samr_DomainInfo *info = NULL;
6650 struct samr_SetDomainInfo s;
6651 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6652 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
6655 struct dcerpc_binding_handle *b = p->binding_handle;
6656 const char *domain_comment = talloc_asprintf(tctx,
6657 "Tortured by Samba4 RPC-SAMR: %s",
6658 timestring(tctx, time(NULL)));
6660 s.in.domain_handle = handle;
6662 s.in.info = talloc(tctx, union samr_DomainInfo);
6664 s.in.info->oem.oem_information.string = domain_comment;
6665 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
6666 "SetDomainInfo failed");
6667 if (!NT_STATUS_IS_OK(s.out.result)) {
6668 torture_warning(tctx, "SetDomainInfo level %u (set comment) failed - %s\n",
6669 s.in.level, nt_errstr(s.out.result));
6673 for (i=0;i<ARRAY_SIZE(levels);i++) {
6674 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
6676 r.in.domain_handle = handle;
6677 r.in.level = levels[i];
6680 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
6681 "QueryDomainInfo failed");
6682 if (!NT_STATUS_IS_OK(r.out.result)) {
6683 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6684 r.in.level, nt_errstr(r.out.result));
6689 switch (levels[i]) {
6691 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
6692 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6693 levels[i], info->general.oem_information.string, domain_comment);
6694 if (!torture_setting_bool(tctx, "samba3", false)) {
6698 if (!info->general.primary.string) {
6699 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6702 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
6703 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
6704 torture_warning(tctx, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
6705 levels[i], info->general.primary.string, dcerpc_server_name(p));
6710 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
6711 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6712 levels[i], info->oem.oem_information.string, domain_comment);
6713 if (!torture_setting_bool(tctx, "samba3", false)) {
6719 if (!info->info6.primary.string) {
6720 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6726 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
6727 torture_warning(tctx, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
6728 levels[i], info->general2.general.oem_information.string, domain_comment);
6729 if (!torture_setting_bool(tctx, "samba3", false)) {
6736 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
6738 s.in.domain_handle = handle;
6739 s.in.level = levels[i];
6742 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
6743 "SetDomainInfo failed");
6745 if (!NT_STATUS_IS_OK(s.out.result)) {
6746 torture_warning(tctx, "SetDomainInfo level %u failed - %s\n",
6747 r.in.level, nt_errstr(s.out.result));
6752 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
6753 torture_warning(tctx, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6754 r.in.level, nt_errstr(s.out.result));
6760 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
6761 "QueryDomainInfo failed");
6762 if (!NT_STATUS_IS_OK(r.out.result)) {
6763 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6764 r.in.level, nt_errstr(r.out.result));
6774 static bool test_QueryDomainInfo2(struct dcerpc_binding_handle *b,
6775 struct torture_context *tctx,
6776 struct policy_handle *handle)
6778 struct samr_QueryDomainInfo2 r;
6779 union samr_DomainInfo *info = NULL;
6780 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6784 for (i=0;i<ARRAY_SIZE(levels);i++) {
6785 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
6787 r.in.domain_handle = handle;
6788 r.in.level = levels[i];
6791 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
6792 "QueryDomainInfo2 failed");
6793 if (!NT_STATUS_IS_OK(r.out.result)) {
6794 torture_warning(tctx, "QueryDomainInfo2 level %u failed - %s\n",
6795 r.in.level, nt_errstr(r.out.result));
6804 /* Test whether querydispinfo level 5 and enumdomgroups return the same
6805 set of group names. */
6806 static bool test_GroupList(struct dcerpc_binding_handle *b,
6807 struct torture_context *tctx,
6808 struct policy_handle *handle)
6810 struct samr_EnumDomainGroups q1;
6811 struct samr_QueryDisplayInfo q2;
6813 uint32_t resume_handle=0;
6814 struct samr_SamArray *sam = NULL;
6815 uint32_t num_entries = 0;
6818 uint32_t total_size;
6819 uint32_t returned_size;
6820 union samr_DispInfo info;
6823 const char **names = NULL;
6825 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
6827 q1.in.domain_handle = handle;
6828 q1.in.resume_handle = &resume_handle;
6830 q1.out.resume_handle = &resume_handle;
6831 q1.out.num_entries = &num_entries;
6834 status = STATUS_MORE_ENTRIES;
6835 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6836 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &q1),
6837 "EnumDomainGroups failed");
6838 status = q1.out.result;
6840 if (!NT_STATUS_IS_OK(status) &&
6841 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6844 for (i=0; i<*q1.out.num_entries; i++) {
6845 add_string_to_array(tctx,
6846 sam->entries[i].name.string,
6847 &names, &num_names);
6851 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
6853 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
6855 q2.in.domain_handle = handle;
6857 q2.in.start_idx = 0;
6858 q2.in.max_entries = 5;
6859 q2.in.buf_size = (uint32_t)-1;
6860 q2.out.total_size = &total_size;
6861 q2.out.returned_size = &returned_size;
6862 q2.out.info = &info;
6864 status = STATUS_MORE_ENTRIES;
6865 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6866 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &q2),
6867 "QueryDisplayInfo failed");
6868 status = q2.out.result;
6869 if (!NT_STATUS_IS_OK(status) &&
6870 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6873 for (i=0; i<q2.out.info->info5.count; i++) {
6875 const char *name = q2.out.info->info5.entries[i].account_name.string;
6877 for (j=0; j<num_names; j++) {
6878 if (names[j] == NULL)
6880 if (strequal(names[j], name)) {
6888 torture_warning(tctx, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
6893 q2.in.start_idx += q2.out.info->info5.count;
6896 if (!NT_STATUS_IS_OK(status)) {
6897 torture_warning(tctx, "QueryDisplayInfo level 5 failed - %s\n",
6902 for (i=0; i<num_names; i++) {
6903 if (names[i] != NULL) {
6904 torture_warning(tctx, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
6913 static bool test_DeleteDomainGroup(struct dcerpc_binding_handle *b,
6914 struct torture_context *tctx,
6915 struct policy_handle *group_handle)
6917 struct samr_DeleteDomainGroup d;
6919 torture_comment(tctx, "Testing DeleteDomainGroup\n");
6921 d.in.group_handle = group_handle;
6922 d.out.group_handle = group_handle;
6924 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
6925 "DeleteDomainGroup failed");
6926 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteDomainGroup");
6931 static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle *b,
6932 struct torture_context *tctx,
6933 struct policy_handle *domain_handle)
6935 struct samr_TestPrivateFunctionsDomain r;
6938 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
6940 r.in.domain_handle = domain_handle;
6942 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsDomain_r(b, tctx, &r),
6943 "TestPrivateFunctionsDomain failed");
6944 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
6949 static bool test_RidToSid(struct dcerpc_binding_handle *b,
6950 struct torture_context *tctx,
6951 struct dom_sid *domain_sid,
6952 struct policy_handle *domain_handle)
6954 struct samr_RidToSid r;
6956 struct dom_sid *calc_sid, *out_sid;
6957 int rids[] = { 0, 42, 512, 10200 };
6960 for (i=0;i<ARRAY_SIZE(rids);i++) {
6961 torture_comment(tctx, "Testing RidToSid\n");
6963 calc_sid = dom_sid_dup(tctx, domain_sid);
6964 r.in.domain_handle = domain_handle;
6966 r.out.sid = &out_sid;
6968 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RidToSid_r(b, tctx, &r),
6970 if (!NT_STATUS_IS_OK(r.out.result)) {
6971 torture_warning(tctx, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(r.out.result));
6974 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
6976 if (!dom_sid_equal(calc_sid, out_sid)) {
6977 torture_warning(tctx, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
6978 dom_sid_string(tctx, out_sid),
6979 dom_sid_string(tctx, calc_sid));
6988 static bool test_GetBootKeyInformation(struct dcerpc_binding_handle *b,
6989 struct torture_context *tctx,
6990 struct policy_handle *domain_handle)
6992 struct samr_GetBootKeyInformation r;
6994 uint32_t unknown = 0;
6997 torture_comment(tctx, "Testing GetBootKeyInformation\n");
6999 r.in.domain_handle = domain_handle;
7000 r.out.unknown = &unknown;
7002 status = dcerpc_samr_GetBootKeyInformation_r(b, tctx, &r);
7003 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(r.out.result)) {
7004 status = r.out.result;
7006 if (!NT_STATUS_IS_OK(status)) {
7007 /* w2k3 seems to fail this sometimes and pass it sometimes */
7008 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
7014 static bool test_AddGroupMember(struct dcerpc_binding_handle *b,
7015 struct torture_context *tctx,
7016 struct policy_handle *domain_handle,
7017 struct policy_handle *group_handle)
7020 struct samr_AddGroupMember r;
7021 struct samr_DeleteGroupMember d;
7022 struct samr_QueryGroupMember q;
7023 struct samr_RidTypeArray *rids = NULL;
7024 struct samr_SetMemberAttributesOfGroup s;
7026 bool found_member = false;
7029 status = test_LookupName(b, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
7030 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
7032 r.in.group_handle = group_handle;
7034 r.in.flags = 0; /* ??? */
7036 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
7038 d.in.group_handle = group_handle;
7041 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7042 "DeleteGroupMember failed");
7043 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, d.out.result, "DeleteGroupMember");
7045 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7046 "AddGroupMember failed");
7047 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7049 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7050 "AddGroupMember failed");
7051 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, r.out.result, "AddGroupMember");
7053 if (torture_setting_bool(tctx, "samba4", false) ||
7054 torture_setting_bool(tctx, "samba3", false)) {
7055 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
7057 /* this one is quite strange. I am using random inputs in the
7058 hope of triggering an error that might give us a clue */
7060 s.in.group_handle = group_handle;
7061 s.in.unknown1 = random();
7062 s.in.unknown2 = random();
7064 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetMemberAttributesOfGroup_r(b, tctx, &s),
7065 "SetMemberAttributesOfGroup failed");
7066 torture_assert_ntstatus_ok(tctx, s.out.result, "SetMemberAttributesOfGroup");
7069 q.in.group_handle = group_handle;
7072 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7073 "QueryGroupMember failed");
7074 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7075 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7077 for (i=0; i < rids->count; i++) {
7078 if (rids->rids[i] == rid) {
7079 found_member = true;
7083 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
7085 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7086 "DeleteGroupMember failed");
7087 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteGroupMember");
7090 found_member = false;
7092 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7093 "QueryGroupMember failed");
7094 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7095 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7097 for (i=0; i < rids->count; i++) {
7098 if (rids->rids[i] == rid) {
7099 found_member = true;
7103 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
7105 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7106 "AddGroupMember failed");
7107 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7113 static bool test_CreateDomainGroup(struct dcerpc_binding_handle *b,
7114 struct torture_context *tctx,
7115 struct policy_handle *domain_handle,
7116 const char *group_name,
7117 struct policy_handle *group_handle,
7118 struct dom_sid *domain_sid,
7121 struct samr_CreateDomainGroup r;
7123 struct lsa_String name;
7126 init_lsa_String(&name, group_name);
7128 r.in.domain_handle = domain_handle;
7130 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7131 r.out.group_handle = group_handle;
7134 torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
7136 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7137 "CreateDomainGroup failed");
7139 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
7140 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
7141 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
7144 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
7145 nt_errstr(r.out.result));
7150 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_GROUP_EXISTS)) {
7151 if (!test_DeleteGroup_byname(b, tctx, domain_handle, r.in.name->string)) {
7152 torture_warning(tctx, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
7153 nt_errstr(r.out.result));
7156 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7157 "CreateDomainGroup failed");
7159 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
7160 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.name->string)) {
7162 torture_warning(tctx, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
7163 nt_errstr(r.out.result));
7166 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7167 "CreateDomainGroup failed");
7169 torture_assert_ntstatus_ok(tctx, r.out.result, "CreateDomainGroup");
7175 if (!test_AddGroupMember(b, tctx, domain_handle, group_handle)) {
7176 torture_warning(tctx, "CreateDomainGroup failed - %s\n", nt_errstr(r.out.result));
7180 if (!test_SetGroupInfo(b, tctx, group_handle)) {
7189 its not totally clear what this does. It seems to accept any sid you like.
7191 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle *b,
7192 struct torture_context *tctx,
7193 struct policy_handle *domain_handle)
7195 struct samr_RemoveMemberFromForeignDomain r;
7197 r.in.domain_handle = domain_handle;
7198 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
7200 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMemberFromForeignDomain_r(b, tctx, &r),
7201 "RemoveMemberFromForeignDomain failed");
7202 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMemberFromForeignDomain");
7207 static bool test_EnumDomainUsers(struct dcerpc_binding_handle *b,
7208 struct torture_context *tctx,
7209 struct policy_handle *domain_handle,
7210 uint32_t *total_num_entries_p)
7213 struct samr_EnumDomainUsers r;
7214 uint32_t resume_handle = 0;
7215 uint32_t num_entries = 0;
7216 uint32_t total_num_entries = 0;
7217 struct samr_SamArray *sam;
7219 r.in.domain_handle = domain_handle;
7220 r.in.acct_flags = 0;
7221 r.in.max_size = (uint32_t)-1;
7222 r.in.resume_handle = &resume_handle;
7225 r.out.num_entries = &num_entries;
7226 r.out.resume_handle = &resume_handle;
7228 torture_comment(tctx, "Testing EnumDomainUsers\n");
7231 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
7232 "EnumDomainUsers failed");
7233 if (NT_STATUS_IS_ERR(r.out.result)) {
7234 torture_assert_ntstatus_ok(tctx, r.out.result,
7235 "failed to enumerate users");
7238 total_num_entries += num_entries;
7239 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7241 if (total_num_entries_p) {
7242 *total_num_entries_p = total_num_entries;
7248 static bool test_EnumDomainGroups(struct dcerpc_binding_handle *b,
7249 struct torture_context *tctx,
7250 struct policy_handle *domain_handle,
7251 uint32_t *total_num_entries_p)
7254 struct samr_EnumDomainGroups r;
7255 uint32_t resume_handle = 0;
7256 uint32_t num_entries = 0;
7257 uint32_t total_num_entries = 0;
7258 struct samr_SamArray *sam;
7260 r.in.domain_handle = domain_handle;
7261 r.in.max_size = (uint32_t)-1;
7262 r.in.resume_handle = &resume_handle;
7265 r.out.num_entries = &num_entries;
7266 r.out.resume_handle = &resume_handle;
7268 torture_comment(tctx, "Testing EnumDomainGroups\n");
7271 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
7272 "EnumDomainGroups failed");
7273 if (NT_STATUS_IS_ERR(r.out.result)) {
7274 torture_assert_ntstatus_ok(tctx, r.out.result,
7275 "failed to enumerate groups");
7278 total_num_entries += num_entries;
7279 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7281 if (total_num_entries_p) {
7282 *total_num_entries_p = total_num_entries;
7288 static bool test_EnumDomainAliases(struct dcerpc_binding_handle *b,
7289 struct torture_context *tctx,
7290 struct policy_handle *domain_handle,
7291 uint32_t *total_num_entries_p)
7294 struct samr_EnumDomainAliases r;
7295 uint32_t resume_handle = 0;
7296 uint32_t num_entries = 0;
7297 uint32_t total_num_entries = 0;
7298 struct samr_SamArray *sam;
7300 r.in.domain_handle = domain_handle;
7301 r.in.max_size = (uint32_t)-1;
7302 r.in.resume_handle = &resume_handle;
7305 r.out.num_entries = &num_entries;
7306 r.out.resume_handle = &resume_handle;
7308 torture_comment(tctx, "Testing EnumDomainAliases\n");
7311 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
7312 "EnumDomainAliases failed");
7313 if (NT_STATUS_IS_ERR(r.out.result)) {
7314 torture_assert_ntstatus_ok(tctx, r.out.result,
7315 "failed to enumerate aliases");
7318 total_num_entries += num_entries;
7319 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7321 if (total_num_entries_p) {
7322 *total_num_entries_p = total_num_entries;
7328 static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle *b,
7329 struct torture_context *tctx,
7330 struct policy_handle *handle,
7332 uint32_t *total_num_entries_p)
7335 struct samr_QueryDisplayInfo r;
7336 uint32_t total_num_entries = 0;
7338 r.in.domain_handle = handle;
7341 r.in.max_entries = (uint32_t)-1;
7342 r.in.buf_size = (uint32_t)-1;
7344 torture_comment(tctx, "Testing QueryDisplayInfo\n");
7347 uint32_t total_size;
7348 uint32_t returned_size;
7349 union samr_DispInfo info;
7351 r.out.total_size = &total_size;
7352 r.out.returned_size = &returned_size;
7355 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7356 "failed to query displayinfo");
7357 if (NT_STATUS_IS_ERR(r.out.result)) {
7358 torture_assert_ntstatus_ok(tctx, r.out.result,
7359 "failed to query displayinfo");
7362 if (*r.out.returned_size == 0) {
7366 switch (r.in.level) {
7368 total_num_entries += info.info1.count;
7369 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
7372 total_num_entries += info.info2.count;
7373 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
7376 total_num_entries += info.info3.count;
7377 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
7380 total_num_entries += info.info4.count;
7381 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
7384 total_num_entries += info.info5.count;
7385 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
7391 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7393 if (total_num_entries_p) {
7394 *total_num_entries_p = total_num_entries;
7400 static bool test_ManyObjects(struct dcerpc_pipe *p,
7401 struct torture_context *tctx,
7402 struct policy_handle *domain_handle,
7403 struct dom_sid *domain_sid,
7404 struct torture_samr_context *ctx)
7406 uint32_t num_total = ctx->num_objects_large_dc;
7407 uint32_t num_enum = 0;
7408 uint32_t num_disp = 0;
7409 uint32_t num_created = 0;
7410 uint32_t num_anounced = 0;
7413 struct dcerpc_binding_handle *b = p->binding_handle;
7415 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
7420 struct samr_QueryDomainInfo2 r;
7421 union samr_DomainInfo *info;
7422 r.in.domain_handle = domain_handle;
7426 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
7427 "QueryDomainInfo2 failed");
7428 torture_assert_ntstatus_ok(tctx, r.out.result,
7429 "failed to query domain info");
7431 switch (ctx->choice) {
7432 case TORTURE_SAMR_MANY_ACCOUNTS:
7433 num_anounced = info->general.num_users;
7435 case TORTURE_SAMR_MANY_GROUPS:
7436 num_anounced = info->general.num_groups;
7438 case TORTURE_SAMR_MANY_ALIASES:
7439 num_anounced = info->general.num_aliases;
7448 for (i=0; i < num_total; i++) {
7450 const char *name = NULL;
7452 switch (ctx->choice) {
7453 case TORTURE_SAMR_MANY_ACCOUNTS:
7454 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
7455 ret &= test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false);
7457 case TORTURE_SAMR_MANY_GROUPS:
7458 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
7459 ret &= test_CreateDomainGroup(b, tctx, domain_handle, name, &handles[i], domain_sid, false);
7461 case TORTURE_SAMR_MANY_ALIASES:
7462 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
7463 ret &= test_CreateAlias(b, tctx, domain_handle, name, &handles[i], domain_sid, false);
7468 if (!policy_handle_empty(&handles[i])) {
7475 switch (ctx->choice) {
7476 case TORTURE_SAMR_MANY_ACCOUNTS:
7477 ret &= test_EnumDomainUsers(b, tctx, domain_handle, &num_enum);
7479 case TORTURE_SAMR_MANY_GROUPS:
7480 ret &= test_EnumDomainGroups(b, tctx, domain_handle, &num_enum);
7482 case TORTURE_SAMR_MANY_ALIASES:
7483 ret &= test_EnumDomainAliases(b, tctx, domain_handle, &num_enum);
7491 switch (ctx->choice) {
7492 case TORTURE_SAMR_MANY_ACCOUNTS:
7493 ret &= test_QueryDisplayInfo_level(b, tctx, domain_handle, 1, &num_disp);
7495 case TORTURE_SAMR_MANY_GROUPS:
7496 ret &= test_QueryDisplayInfo_level(b, tctx, domain_handle, 3, &num_disp);
7498 case TORTURE_SAMR_MANY_ALIASES:
7499 /* no aliases in dispinfo */
7505 /* close or delete */
7507 for (i=0; i < num_total; i++) {
7509 if (policy_handle_empty(&handles[i])) {
7513 if (torture_setting_bool(tctx, "samba3", false)) {
7514 ret &= test_samr_handle_Close(b, tctx, &handles[i]);
7516 switch (ctx->choice) {
7517 case TORTURE_SAMR_MANY_ACCOUNTS:
7518 ret &= test_DeleteUser(b, tctx, &handles[i]);
7520 case TORTURE_SAMR_MANY_GROUPS:
7521 ret &= test_DeleteDomainGroup(b, tctx, &handles[i]);
7523 case TORTURE_SAMR_MANY_ALIASES:
7524 ret &= test_DeleteAlias(b, tctx, &handles[i]);
7532 talloc_free(handles);
7534 if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
7535 torture_comment(tctx,
7536 "unexpected number of results (%u) returned in enum call, expected %u\n",
7537 num_enum, num_anounced + num_created);
7539 torture_comment(tctx,
7540 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
7541 num_disp, num_anounced + num_created);
7546 static bool test_Connect(struct dcerpc_binding_handle *b,
7547 struct torture_context *tctx,
7548 struct policy_handle *handle);
7550 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7551 struct torture_samr_context *ctx, struct dom_sid *sid)
7553 struct samr_OpenDomain r;
7554 struct policy_handle domain_handle;
7555 struct policy_handle alias_handle;
7556 struct policy_handle user_handle;
7557 struct policy_handle group_handle;
7559 struct dcerpc_binding_handle *b = p->binding_handle;
7561 ZERO_STRUCT(alias_handle);
7562 ZERO_STRUCT(user_handle);
7563 ZERO_STRUCT(group_handle);
7564 ZERO_STRUCT(domain_handle);
7566 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
7568 r.in.connect_handle = &ctx->handle;
7569 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7571 r.out.domain_handle = &domain_handle;
7573 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenDomain_r(b, tctx, &r),
7574 "OpenDomain failed");
7575 torture_assert_ntstatus_ok(tctx, r.out.result, "OpenDomain failed");
7577 /* run the domain tests with the main handle closed - this tests
7578 the servers reference counting */
7579 torture_assert(tctx, test_samr_handle_Close(b, tctx, &ctx->handle), "Failed to close SAMR handle");
7581 switch (ctx->choice) {
7582 case TORTURE_SAMR_PASSWORDS:
7583 case TORTURE_SAMR_USER_PRIVILEGES:
7584 if (!torture_setting_bool(tctx, "samba3", false)) {
7585 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7587 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7589 torture_warning(tctx, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
7592 case TORTURE_SAMR_USER_ATTRIBUTES:
7593 if (!torture_setting_bool(tctx, "samba3", false)) {
7594 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7596 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7597 /* This test needs 'complex' users to validate */
7598 ret &= test_QueryDisplayInfo(b, tctx, &domain_handle);
7600 torture_warning(tctx, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
7603 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
7604 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
7605 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
7606 if (!torture_setting_bool(tctx, "samba3", false)) {
7607 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
7609 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
7611 torture_warning(tctx, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx, sid));
7614 case TORTURE_SAMR_MANY_ACCOUNTS:
7615 case TORTURE_SAMR_MANY_GROUPS:
7616 case TORTURE_SAMR_MANY_ALIASES:
7617 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
7619 torture_warning(tctx, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
7622 case TORTURE_SAMR_OTHER:
7623 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7625 torture_warning(tctx, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
7627 if (!torture_setting_bool(tctx, "samba3", false)) {
7628 ret &= test_QuerySecurity(b, tctx, &domain_handle);
7630 ret &= test_RemoveMemberFromForeignDomain(b, tctx, &domain_handle);
7631 ret &= test_CreateAlias(b, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
7632 ret &= test_CreateDomainGroup(b, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
7633 ret &= test_GetAliasMembership(b, tctx, &domain_handle);
7634 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
7635 ret &= test_QueryDomainInfo2(b, tctx, &domain_handle);
7636 ret &= test_EnumDomainUsers_all(b, tctx, &domain_handle);
7637 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
7638 ret &= test_EnumDomainGroups_all(b, tctx, &domain_handle);
7639 ret &= test_EnumDomainAliases_all(b, tctx, &domain_handle);
7640 ret &= test_QueryDisplayInfo2(b, tctx, &domain_handle);
7641 ret &= test_QueryDisplayInfo3(b, tctx, &domain_handle);
7642 ret &= test_QueryDisplayInfo_continue(b, tctx, &domain_handle);
7644 if (torture_setting_bool(tctx, "samba4", false)) {
7645 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
7647 ret &= test_GetDisplayEnumerationIndex(b, tctx, &domain_handle);
7648 ret &= test_GetDisplayEnumerationIndex2(b, tctx, &domain_handle);
7650 ret &= test_GroupList(b, tctx, &domain_handle);
7651 ret &= test_TestPrivateFunctionsDomain(b, tctx, &domain_handle);
7652 ret &= test_RidToSid(b, tctx, sid, &domain_handle);
7653 ret &= test_GetBootKeyInformation(b, tctx, &domain_handle);
7655 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
7660 if (!policy_handle_empty(&user_handle) &&
7661 !test_DeleteUser(b, tctx, &user_handle)) {
7665 if (!policy_handle_empty(&alias_handle) &&
7666 !test_DeleteAlias(b, tctx, &alias_handle)) {
7670 if (!policy_handle_empty(&group_handle) &&
7671 !test_DeleteDomainGroup(b, tctx, &group_handle)) {
7675 torture_assert(tctx, test_samr_handle_Close(b, tctx, &domain_handle), "Failed to close SAMR domain handle");
7677 torture_assert(tctx, test_Connect(b, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
7678 /* reconnect the main handle */
7681 torture_warning(tctx, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
7687 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7688 struct torture_samr_context *ctx, const char *domain)
7690 struct samr_LookupDomain r;
7691 struct dom_sid2 *sid = NULL;
7692 struct lsa_String n1;
7693 struct lsa_String n2;
7695 struct dcerpc_binding_handle *b = p->binding_handle;
7697 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
7699 /* check for correct error codes */
7700 r.in.connect_handle = &ctx->handle;
7701 r.in.domain_name = &n2;
7705 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7706 "LookupDomain failed");
7707 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, r.out.result, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
7709 init_lsa_String(&n2, "xxNODOMAINxx");
7711 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7712 "LookupDomain failed");
7713 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, r.out.result, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
7715 r.in.connect_handle = &ctx->handle;
7717 init_lsa_String(&n1, domain);
7718 r.in.domain_name = &n1;
7720 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7721 "LookupDomain failed");
7722 torture_assert_ntstatus_ok(tctx, r.out.result, "LookupDomain");
7724 if (!test_GetDomPwInfo(p, tctx, &n1)) {
7728 if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
7736 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
7737 struct torture_samr_context *ctx)
7739 struct samr_EnumDomains r;
7740 uint32_t resume_handle = 0;
7741 uint32_t num_entries = 0;
7742 struct samr_SamArray *sam = NULL;
7745 struct dcerpc_binding_handle *b = p->binding_handle;
7747 r.in.connect_handle = &ctx->handle;
7748 r.in.resume_handle = &resume_handle;
7749 r.in.buf_size = (uint32_t)-1;
7750 r.out.resume_handle = &resume_handle;
7751 r.out.num_entries = &num_entries;
7754 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
7755 "EnumDomains failed");
7756 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
7762 for (i=0;i<sam->count;i++) {
7763 if (!test_LookupDomain(p, tctx, ctx,
7764 sam->entries[i].name.string)) {
7769 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
7770 "EnumDomains failed");
7771 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
7777 static bool test_Connect(struct dcerpc_binding_handle *b,
7778 struct torture_context *tctx,
7779 struct policy_handle *handle)
7781 struct samr_Connect r;
7782 struct samr_Connect2 r2;
7783 struct samr_Connect3 r3;
7784 struct samr_Connect4 r4;
7785 struct samr_Connect5 r5;
7786 union samr_ConnectInfo info;
7787 struct policy_handle h;
7788 uint32_t level_out = 0;
7789 bool ret = true, got_handle = false;
7791 torture_comment(tctx, "Testing samr_Connect\n");
7793 r.in.system_name = 0;
7794 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7795 r.out.connect_handle = &h;
7797 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect_r(b, tctx, &r),
7799 if (!NT_STATUS_IS_OK(r.out.result)) {
7800 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(r.out.result));
7807 torture_comment(tctx, "Testing samr_Connect2\n");
7809 r2.in.system_name = NULL;
7810 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7811 r2.out.connect_handle = &h;
7813 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect2_r(b, tctx, &r2),
7815 if (!NT_STATUS_IS_OK(r2.out.result)) {
7816 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(r2.out.result));
7820 test_samr_handle_Close(b, tctx, handle);
7826 torture_comment(tctx, "Testing samr_Connect3\n");
7828 r3.in.system_name = NULL;
7830 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7831 r3.out.connect_handle = &h;
7833 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect3_r(b, tctx, &r3),
7835 if (!NT_STATUS_IS_OK(r3.out.result)) {
7836 torture_warning(tctx, "Connect3 failed - %s\n", nt_errstr(r3.out.result));
7840 test_samr_handle_Close(b, tctx, handle);
7846 torture_comment(tctx, "Testing samr_Connect4\n");
7848 r4.in.system_name = "";
7849 r4.in.client_version = 0;
7850 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7851 r4.out.connect_handle = &h;
7853 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect4_r(b, tctx, &r4),
7855 if (!NT_STATUS_IS_OK(r4.out.result)) {
7856 torture_warning(tctx, "Connect4 failed - %s\n", nt_errstr(r4.out.result));
7860 test_samr_handle_Close(b, tctx, handle);
7866 torture_comment(tctx, "Testing samr_Connect5\n");
7868 info.info1.client_version = 0;
7869 info.info1.unknown2 = 0;
7871 r5.in.system_name = "";
7872 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7874 r5.out.level_out = &level_out;
7875 r5.in.info_in = &info;
7876 r5.out.info_out = &info;
7877 r5.out.connect_handle = &h;
7879 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect5_r(b, tctx, &r5),
7881 if (!NT_STATUS_IS_OK(r5.out.result)) {
7882 torture_warning(tctx, "Connect5 failed - %s\n", nt_errstr(r5.out.result));
7886 test_samr_handle_Close(b, tctx, handle);
7896 static bool test_samr_ValidatePassword(struct dcerpc_pipe *p,
7897 struct torture_context *tctx)
7899 struct samr_ValidatePassword r;
7900 union samr_ValidatePasswordReq req;
7901 union samr_ValidatePasswordRep *repp = NULL;
7903 const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
7905 struct dcerpc_binding_handle *b = p->binding_handle;
7907 torture_comment(tctx, "Testing samr_ValidatePassword\n");
7910 r.in.level = NetValidatePasswordReset;
7915 req.req3.account.string = "non-existant-account-aklsdji";
7917 for (i=0; passwords[i]; i++) {
7918 req.req3.password.string = passwords[i];
7919 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ValidatePassword_r(b, tctx, &r),
7920 "ValidatePassword failed");
7921 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT) &&
7922 p->last_fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
7923 torture_skip(tctx, "ValidatePassword not supported by server\n");
7925 torture_assert_ntstatus_ok(tctx, r.out.result, "samr_ValidatePassword");
7926 torture_comment(tctx, "Server %s password '%s' with code %i\n",
7927 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
7928 req.req3.password.string, repp->ctr3.status);
7934 bool torture_rpc_samr(struct torture_context *torture)
7937 struct dcerpc_pipe *p;
7939 struct torture_samr_context *ctx;
7940 struct dcerpc_binding_handle *b;
7942 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7943 if (!NT_STATUS_IS_OK(status)) {
7946 b = p->binding_handle;
7948 ctx = talloc_zero(torture, struct torture_samr_context);
7950 ctx->choice = TORTURE_SAMR_OTHER;
7952 ret &= test_Connect(b, torture, &ctx->handle);
7954 if (!torture_setting_bool(torture, "samba3", false)) {
7955 ret &= test_QuerySecurity(b, torture, &ctx->handle);
7958 ret &= test_EnumDomains(p, torture, ctx);
7960 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
7962 ret &= test_Shutdown(b, torture, &ctx->handle);
7964 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
7970 bool torture_rpc_samr_users(struct torture_context *torture)
7973 struct dcerpc_pipe *p;
7975 struct torture_samr_context *ctx;
7976 struct dcerpc_binding_handle *b;
7978 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7979 if (!NT_STATUS_IS_OK(status)) {
7982 b = p->binding_handle;
7984 ctx = talloc_zero(torture, struct torture_samr_context);
7986 ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
7988 ret &= test_Connect(b, torture, &ctx->handle);
7990 if (!torture_setting_bool(torture, "samba3", false)) {
7991 ret &= test_QuerySecurity(b, torture, &ctx->handle);
7994 ret &= test_EnumDomains(p, torture, ctx);
7996 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
7998 ret &= test_Shutdown(b, torture, &ctx->handle);
8000 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8006 bool torture_rpc_samr_passwords(struct torture_context *torture)
8009 struct dcerpc_pipe *p;
8011 struct torture_samr_context *ctx;
8012 struct dcerpc_binding_handle *b;
8014 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8015 if (!NT_STATUS_IS_OK(status)) {
8018 b = p->binding_handle;
8020 ctx = talloc_zero(torture, struct torture_samr_context);
8022 ctx->choice = TORTURE_SAMR_PASSWORDS;
8024 ret &= test_Connect(b, torture, &ctx->handle);
8026 ret &= test_EnumDomains(p, torture, ctx);
8028 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8030 ret &= test_samr_ValidatePassword(p, torture);
8035 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
8036 struct dcerpc_pipe *p2,
8037 struct cli_credentials *machine_credentials)
8040 struct dcerpc_pipe *p;
8042 struct torture_samr_context *ctx;
8043 struct dcerpc_binding_handle *b;
8045 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8046 if (!NT_STATUS_IS_OK(status)) {
8049 b = p->binding_handle;
8051 ctx = talloc_zero(torture, struct torture_samr_context);
8053 ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
8054 ctx->machine_credentials = machine_credentials;
8056 ret &= test_Connect(b, torture, &ctx->handle);
8058 ret &= test_EnumDomains(p, torture, ctx);
8060 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8065 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
8067 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
8068 struct torture_rpc_tcase *tcase;
8070 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8072 TEST_ACCOUNT_NAME_PWD);
8074 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
8075 torture_rpc_samr_pwdlastset);
8080 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
8081 struct dcerpc_pipe *p2,
8082 struct cli_credentials *machine_credentials)
8085 struct dcerpc_pipe *p;
8087 struct torture_samr_context *ctx;
8088 struct dcerpc_binding_handle *b;
8090 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8091 if (!NT_STATUS_IS_OK(status)) {
8094 b = p->binding_handle;
8096 ctx = talloc_zero(torture, struct torture_samr_context);
8098 ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
8099 ctx->machine_credentials = machine_credentials;
8101 ret &= test_Connect(b, torture, &ctx->handle);
8103 ret &= test_EnumDomains(p, torture, ctx);
8105 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8110 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
8112 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-USERS-PRIVILEGES");
8113 struct torture_rpc_tcase *tcase;
8115 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8117 TEST_ACCOUNT_NAME_PWD);
8119 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
8120 torture_rpc_samr_users_privileges_delete_user);
8125 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
8126 struct dcerpc_pipe *p2,
8130 struct dcerpc_pipe *p;
8132 struct torture_samr_context *ctx =
8133 talloc_get_type_abort(data, struct torture_samr_context);
8134 struct dcerpc_binding_handle *b;
8136 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8137 if (!NT_STATUS_IS_OK(status)) {
8140 b = p->binding_handle;
8142 ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
8143 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8144 ctx->num_objects_large_dc);
8146 ret &= test_Connect(b, torture, &ctx->handle);
8148 ret &= test_EnumDomains(p, torture, ctx);
8150 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8155 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
8156 struct dcerpc_pipe *p2,
8160 struct dcerpc_pipe *p;
8162 struct torture_samr_context *ctx =
8163 talloc_get_type_abort(data, struct torture_samr_context);
8164 struct dcerpc_binding_handle *b;
8166 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8167 if (!NT_STATUS_IS_OK(status)) {
8170 b = p->binding_handle;
8172 ctx->choice = TORTURE_SAMR_MANY_GROUPS;
8173 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8174 ctx->num_objects_large_dc);
8176 ret &= test_Connect(b, torture, &ctx->handle);
8178 ret &= test_EnumDomains(p, torture, ctx);
8180 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8185 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
8186 struct dcerpc_pipe *p2,
8190 struct dcerpc_pipe *p;
8192 struct torture_samr_context *ctx =
8193 talloc_get_type_abort(data, struct torture_samr_context);
8194 struct dcerpc_binding_handle *b;
8196 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8197 if (!NT_STATUS_IS_OK(status)) {
8200 b = p->binding_handle;
8202 ctx->choice = TORTURE_SAMR_MANY_ALIASES;
8203 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8204 ctx->num_objects_large_dc);
8206 ret &= test_Connect(b, torture, &ctx->handle);
8208 ret &= test_EnumDomains(p, torture, ctx);
8210 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8215 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
8217 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-LARGE-DC");
8218 struct torture_rpc_tcase *tcase;
8219 struct torture_samr_context *ctx;
8221 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
8223 ctx = talloc_zero(suite, struct torture_samr_context);
8224 ctx->num_objects_large_dc = 150;
8226 torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
8227 torture_rpc_samr_many_aliases, ctx);
8228 torture_rpc_tcase_add_test_ex(tcase, "many_groups",
8229 torture_rpc_samr_many_groups, ctx);
8230 torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
8231 torture_rpc_samr_many_accounts, ctx);
8236 static bool torture_rpc_samr_badpwdcount(struct torture_context *torture,
8237 struct dcerpc_pipe *p2,
8238 struct cli_credentials *machine_credentials)
8241 struct dcerpc_pipe *p;
8243 struct torture_samr_context *ctx;
8244 struct dcerpc_binding_handle *b;
8246 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8247 if (!NT_STATUS_IS_OK(status)) {
8250 b = p->binding_handle;
8252 ctx = talloc_zero(torture, struct torture_samr_context);
8254 ctx->choice = TORTURE_SAMR_PASSWORDS_BADPWDCOUNT;
8255 ctx->machine_credentials = machine_credentials;
8257 ret &= test_Connect(b, torture, &ctx->handle);
8259 ret &= test_EnumDomains(p, torture, ctx);
8261 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8266 struct torture_suite *torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX *mem_ctx)
8268 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-BADPWDCOUNT");
8269 struct torture_rpc_tcase *tcase;
8271 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8273 TEST_ACCOUNT_NAME_PWD);
8275 torture_rpc_tcase_add_test_creds(tcase, "badPwdCount",
8276 torture_rpc_samr_badpwdcount);
8281 static bool torture_rpc_samr_lockout(struct torture_context *torture,
8282 struct dcerpc_pipe *p2,
8283 struct cli_credentials *machine_credentials)
8286 struct dcerpc_pipe *p;
8288 struct torture_samr_context *ctx;
8289 struct dcerpc_binding_handle *b;
8291 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8292 if (!NT_STATUS_IS_OK(status)) {
8295 b = p->binding_handle;
8297 ctx = talloc_zero(torture, struct torture_samr_context);
8299 ctx->choice = TORTURE_SAMR_PASSWORDS_LOCKOUT;
8300 ctx->machine_credentials = machine_credentials;
8302 ret &= test_Connect(b, torture, &ctx->handle);
8304 ret &= test_EnumDomains(p, torture, ctx);
8306 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8311 struct torture_suite *torture_rpc_samr_passwords_lockout(TALLOC_CTX *mem_ctx)
8313 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-LOCKOUT");
8314 struct torture_rpc_tcase *tcase;
8316 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8318 TEST_ACCOUNT_NAME_PWD);
8320 torture_rpc_tcase_add_test_creds(tcase, "lockout",
8321 torture_rpc_samr_lockout);