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", (long int) time(NULL));
1181 E_md4hash(newpass, nt_hash);
1182 E_deshash(newpass, lm_hash);
1184 u.info18.nt_pwd_active = true;
1185 u.info18.lm_pwd_active = true;
1186 u.info18.password_expired = password_expired;
1188 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1189 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1193 E_md4hash(newpass, nt_hash);
1194 E_deshash(newpass, lm_hash);
1196 u.info21.fields_present = fields_present;
1197 u.info21.password_expired = password_expired;
1198 u.info21.comment.string = comment;
1200 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1201 u.info21.lm_owf_password.length = 16;
1202 u.info21.lm_owf_password.size = 16;
1203 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1204 u.info21.lm_password_set = true;
1207 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1208 u.info21.nt_owf_password.length = 16;
1209 u.info21.nt_owf_password.size = 16;
1210 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1211 u.info21.nt_password_set = true;
1216 u.info23.info.fields_present = fields_present;
1217 u.info23.info.password_expired = password_expired;
1218 u.info23.info.comment.string = comment;
1220 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1224 u.info24.password_expired = password_expired;
1226 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1230 u.info25.info.fields_present = fields_present;
1231 u.info25.info.password_expired = password_expired;
1232 u.info25.info.comment.string = comment;
1234 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1238 u.info26.password_expired = password_expired;
1240 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1245 status = dcerpc_fetch_session_key(p, &session_key);
1246 if (!NT_STATUS_IS_OK(status)) {
1247 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1248 s.in.level, nt_errstr(status));
1252 generate_random_buffer((uint8_t *)confounder, 16);
1255 MD5Update(&ctx, confounder, 16);
1256 MD5Update(&ctx, session_key.data, session_key.length);
1257 MD5Final(confounded_session_key.data, &ctx);
1263 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1264 out = data_blob_talloc_zero(tctx, 16);
1265 sess_crypt_blob(&out, &in, &session_key, true);
1266 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1270 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1271 out = data_blob_talloc_zero(tctx, 16);
1272 sess_crypt_blob(&out, &in, &session_key, true);
1273 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1278 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1280 in = data_blob_const(u.info21.lm_owf_password.array,
1281 u.info21.lm_owf_password.length);
1282 out = data_blob_talloc_zero(tctx, 16);
1283 sess_crypt_blob(&out, &in, &session_key, true);
1284 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1286 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1288 in = data_blob_const(u.info21.nt_owf_password.array,
1289 u.info21.nt_owf_password.length);
1290 out = data_blob_talloc_zero(tctx, 16);
1291 sess_crypt_blob(&out, &in, &session_key, true);
1292 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1296 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1299 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1302 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1303 memcpy(&u.info25.password.data[516], confounder, 16);
1306 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1307 memcpy(&u.info26.password.data[516], confounder, 16);
1312 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo2_r(b, tctx, &s2),
1313 "SetUserInfo2 failed");
1314 status = s2.out.result;
1316 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1317 "SetUserInfo failed");
1318 status = s.out.result;
1321 if (!NT_STATUS_IS_OK(status)) {
1322 if (fields_present == 0) {
1323 expected_error = NT_STATUS_INVALID_PARAMETER;
1325 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1326 expected_error = NT_STATUS_ACCESS_DENIED;
1330 if (!NT_STATUS_IS_OK(expected_error)) {
1332 torture_assert_ntstatus_equal(tctx,
1334 expected_error, "SetUserInfo2 failed");
1336 torture_assert_ntstatus_equal(tctx,
1338 expected_error, "SetUserInfo failed");
1340 *matched_expected_error = true;
1344 if (!NT_STATUS_IS_OK(status)) {
1345 torture_warning(tctx, "SetUserInfo%s level %u failed - %s\n",
1346 use_setinfo2 ? "2":"", level, nt_errstr(status));
1349 *password = newpass;
1355 static bool test_SetAliasInfo(struct dcerpc_binding_handle *b,
1356 struct torture_context *tctx,
1357 struct policy_handle *handle)
1359 struct samr_SetAliasInfo r;
1360 struct samr_QueryAliasInfo q;
1361 union samr_AliasInfo *info;
1362 uint16_t levels[] = {2, 3};
1366 /* Ignoring switch level 1, as that includes the number of members for the alias
1367 * and setting this to a wrong value might have negative consequences
1370 for (i=0;i<ARRAY_SIZE(levels);i++) {
1371 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1373 r.in.alias_handle = handle;
1374 r.in.level = levels[i];
1375 r.in.info = talloc(tctx, union samr_AliasInfo);
1376 switch (r.in.level) {
1377 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1378 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1379 "Test Description, should test I18N as well"); break;
1380 case ALIASINFOALL: torture_comment(tctx, "ALIASINFOALL ignored\n"); break;
1383 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetAliasInfo_r(b, tctx, &r),
1384 "SetAliasInfo failed");
1385 if (!NT_STATUS_IS_OK(r.out.result)) {
1386 torture_warning(tctx, "SetAliasInfo level %u failed - %s\n",
1387 levels[i], nt_errstr(r.out.result));
1391 q.in.alias_handle = handle;
1392 q.in.level = levels[i];
1395 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &q),
1396 "QueryAliasInfo failed");
1397 if (!NT_STATUS_IS_OK(q.out.result)) {
1398 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
1399 levels[i], nt_errstr(q.out.result));
1407 static bool test_GetGroupsForUser(struct dcerpc_binding_handle *b,
1408 struct torture_context *tctx,
1409 struct policy_handle *user_handle)
1411 struct samr_GetGroupsForUser r;
1412 struct samr_RidWithAttributeArray *rids = NULL;
1414 torture_comment(tctx, "Testing GetGroupsForUser\n");
1416 r.in.user_handle = user_handle;
1419 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetGroupsForUser_r(b, tctx, &r),
1420 "GetGroupsForUser failed");
1421 torture_assert_ntstatus_ok(tctx, r.out.result, "GetGroupsForUser failed");
1427 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1428 struct lsa_String *domain_name)
1430 struct samr_GetDomPwInfo r;
1431 struct samr_PwInfo info;
1432 struct dcerpc_binding_handle *b = p->binding_handle;
1434 r.in.domain_name = domain_name;
1437 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1439 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1440 "GetDomPwInfo failed");
1441 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1443 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1444 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1446 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1447 "GetDomPwInfo failed");
1448 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1450 r.in.domain_name->string = "\\\\__NONAME__";
1451 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1453 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1454 "GetDomPwInfo failed");
1455 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1457 r.in.domain_name->string = "\\\\Builtin";
1458 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1460 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1461 "GetDomPwInfo failed");
1462 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1467 static bool test_GetUserPwInfo(struct dcerpc_binding_handle *b,
1468 struct torture_context *tctx,
1469 struct policy_handle *handle)
1471 struct samr_GetUserPwInfo r;
1472 struct samr_PwInfo info;
1474 torture_comment(tctx, "Testing GetUserPwInfo\n");
1476 r.in.user_handle = handle;
1479 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &r),
1480 "GetUserPwInfo failed");
1481 torture_assert_ntstatus_ok(tctx, r.out.result, "GetUserPwInfo");
1486 static NTSTATUS test_LookupName(struct dcerpc_binding_handle *b,
1487 struct torture_context *tctx,
1488 struct policy_handle *domain_handle, const char *name,
1492 struct samr_LookupNames n;
1493 struct lsa_String sname[2];
1494 struct samr_Ids rids, types;
1496 init_lsa_String(&sname[0], name);
1498 n.in.domain_handle = domain_handle;
1502 n.out.types = &types;
1503 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1504 if (!NT_STATUS_IS_OK(status)) {
1507 if (NT_STATUS_IS_OK(n.out.result)) {
1508 *rid = n.out.rids->ids[0];
1510 return n.out.result;
1513 init_lsa_String(&sname[1], "xxNONAMExx");
1515 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1516 if (!NT_STATUS_IS_OK(status)) {
1519 if (!NT_STATUS_EQUAL(n.out.result, STATUS_SOME_UNMAPPED)) {
1520 torture_warning(tctx, "LookupNames[2] failed - %s\n", nt_errstr(n.out.result));
1521 if (NT_STATUS_IS_OK(n.out.result)) {
1522 return NT_STATUS_UNSUCCESSFUL;
1524 return n.out.result;
1528 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1529 if (!NT_STATUS_IS_OK(status)) {
1532 if (!NT_STATUS_IS_OK(n.out.result)) {
1533 torture_warning(tctx, "LookupNames[0] failed - %s\n", nt_errstr(status));
1534 return n.out.result;
1537 init_lsa_String(&sname[0], "xxNONAMExx");
1539 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1540 if (!NT_STATUS_IS_OK(status)) {
1543 if (!NT_STATUS_EQUAL(n.out.result, NT_STATUS_NONE_MAPPED)) {
1544 torture_warning(tctx, "LookupNames[1 bad name] failed - %s\n", nt_errstr(n.out.result));
1545 if (NT_STATUS_IS_OK(n.out.result)) {
1546 return NT_STATUS_UNSUCCESSFUL;
1548 return n.out.result;
1551 init_lsa_String(&sname[0], "xxNONAMExx");
1552 init_lsa_String(&sname[1], "xxNONAME2xx");
1554 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1555 if (!NT_STATUS_IS_OK(status)) {
1558 if (!NT_STATUS_EQUAL(n.out.result, NT_STATUS_NONE_MAPPED)) {
1559 torture_warning(tctx, "LookupNames[2 bad names] failed - %s\n", nt_errstr(n.out.result));
1560 if (NT_STATUS_IS_OK(n.out.result)) {
1561 return NT_STATUS_UNSUCCESSFUL;
1563 return n.out.result;
1566 return NT_STATUS_OK;
1569 static NTSTATUS test_OpenUser_byname(struct dcerpc_binding_handle *b,
1570 struct torture_context *tctx,
1571 struct policy_handle *domain_handle,
1572 const char *name, struct policy_handle *user_handle)
1575 struct samr_OpenUser r;
1578 status = test_LookupName(b, tctx, domain_handle, name, &rid);
1579 if (!NT_STATUS_IS_OK(status)) {
1583 r.in.domain_handle = domain_handle;
1584 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1586 r.out.user_handle = user_handle;
1587 status = dcerpc_samr_OpenUser_r(b, tctx, &r);
1588 if (!NT_STATUS_IS_OK(status)) {
1591 if (!NT_STATUS_IS_OK(r.out.result)) {
1592 torture_warning(tctx, "OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(r.out.result));
1595 return r.out.result;
1599 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
1600 struct torture_context *tctx,
1601 struct policy_handle *handle)
1604 struct samr_ChangePasswordUser r;
1606 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1607 struct policy_handle user_handle;
1608 char *oldpass = "test";
1609 char *newpass = "test2";
1610 uint8_t old_nt_hash[16], new_nt_hash[16];
1611 uint8_t old_lm_hash[16], new_lm_hash[16];
1613 status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
1614 if (!NT_STATUS_IS_OK(status)) {
1618 torture_comment(tctx, "Testing ChangePasswordUser for user 'testuser'\n");
1620 torture_comment(tctx, "old password: %s\n", oldpass);
1621 torture_comment(tctx, "new password: %s\n", newpass);
1623 E_md4hash(oldpass, old_nt_hash);
1624 E_md4hash(newpass, new_nt_hash);
1625 E_deshash(oldpass, old_lm_hash);
1626 E_deshash(newpass, new_lm_hash);
1628 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1629 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1630 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1631 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1632 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1633 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1635 r.in.handle = &user_handle;
1636 r.in.lm_present = 1;
1637 r.in.old_lm_crypted = &hash1;
1638 r.in.new_lm_crypted = &hash2;
1639 r.in.nt_present = 1;
1640 r.in.old_nt_crypted = &hash3;
1641 r.in.new_nt_crypted = &hash4;
1642 r.in.cross1_present = 1;
1643 r.in.nt_cross = &hash5;
1644 r.in.cross2_present = 1;
1645 r.in.lm_cross = &hash6;
1647 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1648 "ChangePasswordUser failed");
1649 if (!NT_STATUS_IS_OK(r.out.result)) {
1650 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(r.out.result));
1654 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1662 static bool test_ChangePasswordUser(struct dcerpc_binding_handle *b,
1663 struct torture_context *tctx,
1664 const char *acct_name,
1665 struct policy_handle *handle, char **password)
1668 struct samr_ChangePasswordUser r;
1670 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1671 struct policy_handle user_handle;
1673 uint8_t old_nt_hash[16], new_nt_hash[16];
1674 uint8_t old_lm_hash[16], new_lm_hash[16];
1675 bool changed = true;
1678 struct samr_GetUserPwInfo pwp;
1679 struct samr_PwInfo info;
1680 int policy_min_pw_len = 0;
1682 status = test_OpenUser_byname(b, tctx, handle, acct_name, &user_handle);
1683 if (!NT_STATUS_IS_OK(status)) {
1686 pwp.in.user_handle = &user_handle;
1687 pwp.out.info = &info;
1689 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1690 "GetUserPwInfo failed");
1691 if (NT_STATUS_IS_OK(pwp.out.result)) {
1692 policy_min_pw_len = pwp.out.info->min_password_length;
1694 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1696 torture_comment(tctx, "Testing ChangePasswordUser\n");
1698 torture_assert(tctx, *password != NULL,
1699 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1701 oldpass = *password;
1703 E_md4hash(oldpass, old_nt_hash);
1704 E_md4hash(newpass, new_nt_hash);
1705 E_deshash(oldpass, old_lm_hash);
1706 E_deshash(newpass, new_lm_hash);
1708 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1709 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1710 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1711 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1712 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1713 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1715 r.in.user_handle = &user_handle;
1716 r.in.lm_present = 1;
1717 /* Break the LM hash */
1719 r.in.old_lm_crypted = &hash1;
1720 r.in.new_lm_crypted = &hash2;
1721 r.in.nt_present = 1;
1722 r.in.old_nt_crypted = &hash3;
1723 r.in.new_nt_crypted = &hash4;
1724 r.in.cross1_present = 1;
1725 r.in.nt_cross = &hash5;
1726 r.in.cross2_present = 1;
1727 r.in.lm_cross = &hash6;
1729 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1730 "ChangePasswordUser failed");
1731 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_WRONG_PASSWORD,
1732 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1734 /* Unbreak the LM hash */
1737 r.in.user_handle = &user_handle;
1738 r.in.lm_present = 1;
1739 r.in.old_lm_crypted = &hash1;
1740 r.in.new_lm_crypted = &hash2;
1741 /* Break the NT hash */
1743 r.in.nt_present = 1;
1744 r.in.old_nt_crypted = &hash3;
1745 r.in.new_nt_crypted = &hash4;
1746 r.in.cross1_present = 1;
1747 r.in.nt_cross = &hash5;
1748 r.in.cross2_present = 1;
1749 r.in.lm_cross = &hash6;
1751 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1752 "ChangePasswordUser failed");
1753 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_WRONG_PASSWORD,
1754 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1756 /* Unbreak the NT hash */
1759 r.in.user_handle = &user_handle;
1760 r.in.lm_present = 1;
1761 r.in.old_lm_crypted = &hash1;
1762 r.in.new_lm_crypted = &hash2;
1763 r.in.nt_present = 1;
1764 r.in.old_nt_crypted = &hash3;
1765 r.in.new_nt_crypted = &hash4;
1766 r.in.cross1_present = 1;
1767 r.in.nt_cross = &hash5;
1768 r.in.cross2_present = 1;
1769 /* Break the LM cross */
1771 r.in.lm_cross = &hash6;
1773 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1774 "ChangePasswordUser failed");
1775 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
1776 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(r.out.result));
1780 /* Unbreak the LM cross */
1783 r.in.user_handle = &user_handle;
1784 r.in.lm_present = 1;
1785 r.in.old_lm_crypted = &hash1;
1786 r.in.new_lm_crypted = &hash2;
1787 r.in.nt_present = 1;
1788 r.in.old_nt_crypted = &hash3;
1789 r.in.new_nt_crypted = &hash4;
1790 r.in.cross1_present = 1;
1791 /* Break the NT cross */
1793 r.in.nt_cross = &hash5;
1794 r.in.cross2_present = 1;
1795 r.in.lm_cross = &hash6;
1797 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1798 "ChangePasswordUser failed");
1799 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
1800 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(r.out.result));
1804 /* Unbreak the NT cross */
1808 /* Reset the hashes to not broken values */
1809 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1810 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1811 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1812 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1813 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1814 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1816 r.in.user_handle = &user_handle;
1817 r.in.lm_present = 1;
1818 r.in.old_lm_crypted = &hash1;
1819 r.in.new_lm_crypted = &hash2;
1820 r.in.nt_present = 1;
1821 r.in.old_nt_crypted = &hash3;
1822 r.in.new_nt_crypted = &hash4;
1823 r.in.cross1_present = 1;
1824 r.in.nt_cross = &hash5;
1825 r.in.cross2_present = 0;
1826 r.in.lm_cross = NULL;
1828 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1829 "ChangePasswordUser failed");
1830 if (NT_STATUS_IS_OK(r.out.result)) {
1832 *password = newpass;
1833 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, r.out.result)) {
1834 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r.out.result));
1839 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1841 E_md4hash(oldpass, old_nt_hash);
1842 E_md4hash(newpass, new_nt_hash);
1843 E_deshash(oldpass, old_lm_hash);
1844 E_deshash(newpass, new_lm_hash);
1847 /* Reset the hashes to not broken values */
1848 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1849 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1850 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1851 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1852 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1853 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1855 r.in.user_handle = &user_handle;
1856 r.in.lm_present = 1;
1857 r.in.old_lm_crypted = &hash1;
1858 r.in.new_lm_crypted = &hash2;
1859 r.in.nt_present = 1;
1860 r.in.old_nt_crypted = &hash3;
1861 r.in.new_nt_crypted = &hash4;
1862 r.in.cross1_present = 0;
1863 r.in.nt_cross = NULL;
1864 r.in.cross2_present = 1;
1865 r.in.lm_cross = &hash6;
1867 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1868 "ChangePasswordUser failed");
1869 if (NT_STATUS_IS_OK(r.out.result)) {
1871 *password = newpass;
1872 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, r.out.result)) {
1873 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r.out.result));
1878 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1880 E_md4hash(oldpass, old_nt_hash);
1881 E_md4hash(newpass, new_nt_hash);
1882 E_deshash(oldpass, old_lm_hash);
1883 E_deshash(newpass, new_lm_hash);
1886 /* Reset the hashes to not broken values */
1887 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1888 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1889 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1890 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1891 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1892 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1894 r.in.user_handle = &user_handle;
1895 r.in.lm_present = 1;
1896 r.in.old_lm_crypted = &hash1;
1897 r.in.new_lm_crypted = &hash2;
1898 r.in.nt_present = 1;
1899 r.in.old_nt_crypted = &hash3;
1900 r.in.new_nt_crypted = &hash4;
1901 r.in.cross1_present = 1;
1902 r.in.nt_cross = &hash5;
1903 r.in.cross2_present = 1;
1904 r.in.lm_cross = &hash6;
1906 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1907 "ChangePasswordUser failed");
1908 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
1909 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
1910 } else if (!NT_STATUS_IS_OK(r.out.result)) {
1911 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(r.out.result));
1915 *password = newpass;
1918 r.in.user_handle = &user_handle;
1919 r.in.lm_present = 1;
1920 r.in.old_lm_crypted = &hash1;
1921 r.in.new_lm_crypted = &hash2;
1922 r.in.nt_present = 1;
1923 r.in.old_nt_crypted = &hash3;
1924 r.in.new_nt_crypted = &hash4;
1925 r.in.cross1_present = 1;
1926 r.in.nt_cross = &hash5;
1927 r.in.cross2_present = 1;
1928 r.in.lm_cross = &hash6;
1931 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1932 "ChangePasswordUser failed");
1933 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
1934 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
1935 } else if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
1936 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(r.out.result));
1942 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
1950 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p,
1951 struct torture_context *tctx,
1952 const char *acct_name,
1953 struct policy_handle *handle, char **password)
1955 struct samr_OemChangePasswordUser2 r;
1957 struct samr_Password lm_verifier;
1958 struct samr_CryptPassword lm_pass;
1959 struct lsa_AsciiString server, account, account_bad;
1962 struct dcerpc_binding_handle *b = p->binding_handle;
1963 uint8_t old_lm_hash[16], new_lm_hash[16];
1965 struct samr_GetDomPwInfo dom_pw_info;
1966 struct samr_PwInfo info;
1967 int policy_min_pw_len = 0;
1969 struct lsa_String domain_name;
1971 domain_name.string = "";
1972 dom_pw_info.in.domain_name = &domain_name;
1973 dom_pw_info.out.info = &info;
1975 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1977 torture_assert(tctx, *password != NULL,
1978 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1980 oldpass = *password;
1982 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
1983 "GetDomPwInfo failed");
1984 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
1985 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1988 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1990 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1991 account.string = acct_name;
1993 E_deshash(oldpass, old_lm_hash);
1994 E_deshash(newpass, new_lm_hash);
1996 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1997 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1998 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2000 r.in.server = &server;
2001 r.in.account = &account;
2002 r.in.password = &lm_pass;
2003 r.in.hash = &lm_verifier;
2005 /* Break the verification */
2006 lm_verifier.hash[0]++;
2008 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2009 "OemChangePasswordUser2 failed");
2011 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2012 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2013 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2014 nt_errstr(r.out.result));
2018 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2019 /* Break the old password */
2021 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2022 /* unbreak it for the next operation */
2024 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2026 r.in.server = &server;
2027 r.in.account = &account;
2028 r.in.password = &lm_pass;
2029 r.in.hash = &lm_verifier;
2031 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2032 "OemChangePasswordUser2 failed");
2034 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2035 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2036 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2037 nt_errstr(r.out.result));
2041 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2042 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2044 r.in.server = &server;
2045 r.in.account = &account;
2046 r.in.password = &lm_pass;
2049 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2050 "OemChangePasswordUser2 failed");
2052 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2053 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2054 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
2055 nt_errstr(r.out.result));
2059 /* This shouldn't be a valid name */
2060 account_bad.string = TEST_ACCOUNT_NAME "XX";
2061 r.in.account = &account_bad;
2063 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2064 "OemChangePasswordUser2 failed");
2066 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2067 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
2068 nt_errstr(r.out.result));
2072 /* This shouldn't be a valid name */
2073 account_bad.string = TEST_ACCOUNT_NAME "XX";
2074 r.in.account = &account_bad;
2075 r.in.password = &lm_pass;
2076 r.in.hash = &lm_verifier;
2078 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2079 "OemChangePasswordUser2 failed");
2081 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2082 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2083 nt_errstr(r.out.result));
2087 /* This shouldn't be a valid name */
2088 account_bad.string = TEST_ACCOUNT_NAME "XX";
2089 r.in.account = &account_bad;
2090 r.in.password = NULL;
2091 r.in.hash = &lm_verifier;
2093 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2094 "OemChangePasswordUser2 failed");
2096 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2097 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2098 nt_errstr(r.out.result));
2102 E_deshash(oldpass, old_lm_hash);
2103 E_deshash(newpass, new_lm_hash);
2105 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2106 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2107 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2109 r.in.server = &server;
2110 r.in.account = &account;
2111 r.in.password = &lm_pass;
2112 r.in.hash = &lm_verifier;
2114 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2115 "OemChangePasswordUser2 failed");
2117 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2118 torture_comment(tctx, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2119 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2120 torture_warning(tctx, "OemChangePasswordUser2 failed - %s\n", nt_errstr(r.out.result));
2123 *password = newpass;
2130 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2131 const char *acct_name,
2133 char *newpass, bool allow_password_restriction)
2135 struct samr_ChangePasswordUser2 r;
2137 struct lsa_String server, account;
2138 struct samr_CryptPassword nt_pass, lm_pass;
2139 struct samr_Password nt_verifier, lm_verifier;
2141 struct dcerpc_binding_handle *b = p->binding_handle;
2142 uint8_t old_nt_hash[16], new_nt_hash[16];
2143 uint8_t old_lm_hash[16], new_lm_hash[16];
2145 struct samr_GetDomPwInfo dom_pw_info;
2146 struct samr_PwInfo info;
2148 struct lsa_String domain_name;
2150 domain_name.string = "";
2151 dom_pw_info.in.domain_name = &domain_name;
2152 dom_pw_info.out.info = &info;
2154 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2156 torture_assert(tctx, *password != NULL,
2157 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2158 oldpass = *password;
2161 int policy_min_pw_len = 0;
2162 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
2163 "GetDomPwInfo failed");
2164 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
2165 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2168 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2171 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2172 init_lsa_String(&account, acct_name);
2174 E_md4hash(oldpass, old_nt_hash);
2175 E_md4hash(newpass, new_nt_hash);
2177 E_deshash(oldpass, old_lm_hash);
2178 E_deshash(newpass, new_lm_hash);
2180 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2181 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2182 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2184 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2185 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2186 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2188 r.in.server = &server;
2189 r.in.account = &account;
2190 r.in.nt_password = &nt_pass;
2191 r.in.nt_verifier = &nt_verifier;
2193 r.in.lm_password = &lm_pass;
2194 r.in.lm_verifier = &lm_verifier;
2196 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser2_r(b, tctx, &r),
2197 "ChangePasswordUser2 failed");
2199 if (allow_password_restriction && NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2200 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2201 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2202 torture_warning(tctx, "ChangePasswordUser2 failed - %s\n", nt_errstr(r.out.result));
2205 *password = newpass;
2212 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2213 const char *account_string,
2214 int policy_min_pw_len,
2216 const char *newpass,
2217 NTTIME last_password_change,
2218 bool handle_reject_reason)
2220 struct samr_ChangePasswordUser3 r;
2222 struct lsa_String server, account, account_bad;
2223 struct samr_CryptPassword nt_pass, lm_pass;
2224 struct samr_Password nt_verifier, lm_verifier;
2226 struct dcerpc_binding_handle *b = p->binding_handle;
2227 uint8_t old_nt_hash[16], new_nt_hash[16];
2228 uint8_t old_lm_hash[16], new_lm_hash[16];
2230 struct samr_DomInfo1 *dominfo = NULL;
2231 struct userPwdChangeFailureInformation *reject = NULL;
2233 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2235 if (newpass == NULL) {
2237 if (policy_min_pw_len == 0) {
2238 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2240 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2242 } while (check_password_quality(newpass) == false);
2244 torture_comment(tctx, "Using password '%s'\n", newpass);
2247 torture_assert(tctx, *password != NULL,
2248 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2250 oldpass = *password;
2251 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2252 init_lsa_String(&account, account_string);
2254 E_md4hash(oldpass, old_nt_hash);
2255 E_md4hash(newpass, new_nt_hash);
2257 E_deshash(oldpass, old_lm_hash);
2258 E_deshash(newpass, new_lm_hash);
2260 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2261 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2262 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2264 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2265 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2266 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2268 /* Break the verification */
2269 nt_verifier.hash[0]++;
2271 r.in.server = &server;
2272 r.in.account = &account;
2273 r.in.nt_password = &nt_pass;
2274 r.in.nt_verifier = &nt_verifier;
2276 r.in.lm_password = &lm_pass;
2277 r.in.lm_verifier = &lm_verifier;
2278 r.in.password3 = NULL;
2279 r.out.dominfo = &dominfo;
2280 r.out.reject = &reject;
2282 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2283 "ChangePasswordUser3 failed");
2284 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2285 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2286 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2287 nt_errstr(r.out.result));
2291 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2292 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2293 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2295 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2296 /* Break the NT hash */
2298 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2299 /* Unbreak it again */
2301 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2303 r.in.server = &server;
2304 r.in.account = &account;
2305 r.in.nt_password = &nt_pass;
2306 r.in.nt_verifier = &nt_verifier;
2308 r.in.lm_password = &lm_pass;
2309 r.in.lm_verifier = &lm_verifier;
2310 r.in.password3 = NULL;
2311 r.out.dominfo = &dominfo;
2312 r.out.reject = &reject;
2314 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2315 "ChangePasswordUser3 failed");
2316 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2317 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2318 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2319 nt_errstr(r.out.result));
2323 /* This shouldn't be a valid name */
2324 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2326 r.in.account = &account_bad;
2327 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2328 "ChangePasswordUser3 failed");
2329 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2330 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2331 nt_errstr(r.out.result));
2335 E_md4hash(oldpass, old_nt_hash);
2336 E_md4hash(newpass, new_nt_hash);
2338 E_deshash(oldpass, old_lm_hash);
2339 E_deshash(newpass, new_lm_hash);
2341 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2342 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2343 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2345 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2346 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2347 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2349 r.in.server = &server;
2350 r.in.account = &account;
2351 r.in.nt_password = &nt_pass;
2352 r.in.nt_verifier = &nt_verifier;
2354 r.in.lm_password = &lm_pass;
2355 r.in.lm_verifier = &lm_verifier;
2356 r.in.password3 = NULL;
2357 r.out.dominfo = &dominfo;
2358 r.out.reject = &reject;
2360 unix_to_nt_time(&t, time(NULL));
2362 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2363 "ChangePasswordUser3 failed");
2365 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2368 && handle_reject_reason
2369 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2370 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2372 if (reject && (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR)) {
2373 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2374 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2379 /* We tested the order of precendence which is as follows:
2388 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2389 (last_password_change + dominfo->min_password_age > t)) {
2391 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2392 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2393 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2397 } else if ((dominfo->min_password_length > 0) &&
2398 (strlen(newpass) < dominfo->min_password_length)) {
2400 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2401 torture_warning(tctx, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2402 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT, reject->extendedFailureReason);
2406 } else if ((dominfo->password_history_length > 0) &&
2407 strequal(oldpass, newpass)) {
2409 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PWD_IN_HISTORY) {
2410 torture_warning(tctx, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2411 SAM_PWD_CHANGE_PWD_IN_HISTORY, reject->extendedFailureReason);
2414 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2416 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NOT_COMPLEX) {
2417 torture_warning(tctx, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2418 SAM_PWD_CHANGE_NOT_COMPLEX, reject->extendedFailureReason);
2424 if (reject->extendedFailureReason == SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2425 /* retry with adjusted size */
2426 return test_ChangePasswordUser3(p, tctx, account_string,
2427 dominfo->min_password_length,
2428 password, NULL, 0, false);
2432 } else if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2433 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2434 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2435 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2438 /* Perhaps the server has a 'min password age' set? */
2441 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3");
2443 *password = talloc_strdup(tctx, newpass);
2449 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2450 const char *account_string,
2451 struct policy_handle *handle,
2455 struct samr_ChangePasswordUser3 r;
2456 struct samr_SetUserInfo s;
2457 union samr_UserInfo u;
2458 DATA_BLOB session_key;
2459 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2460 uint8_t confounder[16];
2461 struct MD5Context ctx;
2464 struct lsa_String server, account;
2465 struct samr_CryptPassword nt_pass;
2466 struct samr_Password nt_verifier;
2467 DATA_BLOB new_random_pass;
2470 struct dcerpc_binding_handle *b = p->binding_handle;
2471 uint8_t old_nt_hash[16], new_nt_hash[16];
2473 struct samr_DomInfo1 *dominfo = NULL;
2474 struct userPwdChangeFailureInformation *reject = NULL;
2476 new_random_pass = samr_very_rand_pass(tctx, 128);
2478 torture_assert(tctx, *password != NULL,
2479 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2481 oldpass = *password;
2482 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2483 init_lsa_String(&account, account_string);
2485 s.in.user_handle = handle;
2491 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2493 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2495 status = dcerpc_fetch_session_key(p, &session_key);
2496 if (!NT_STATUS_IS_OK(status)) {
2497 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
2498 s.in.level, nt_errstr(status));
2502 generate_random_buffer((uint8_t *)confounder, 16);
2505 MD5Update(&ctx, confounder, 16);
2506 MD5Update(&ctx, session_key.data, session_key.length);
2507 MD5Final(confounded_session_key.data, &ctx);
2509 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2510 memcpy(&u.info25.password.data[516], confounder, 16);
2512 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2514 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
2515 "SetUserInfo failed");
2516 if (!NT_STATUS_IS_OK(s.out.result)) {
2517 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
2518 s.in.level, nt_errstr(s.out.result));
2522 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2524 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2526 new_random_pass = samr_very_rand_pass(tctx, 128);
2528 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2530 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2531 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2532 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2534 r.in.server = &server;
2535 r.in.account = &account;
2536 r.in.nt_password = &nt_pass;
2537 r.in.nt_verifier = &nt_verifier;
2539 r.in.lm_password = NULL;
2540 r.in.lm_verifier = NULL;
2541 r.in.password3 = NULL;
2542 r.out.dominfo = &dominfo;
2543 r.out.reject = &reject;
2545 unix_to_nt_time(&t, time(NULL));
2547 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2548 "ChangePasswordUser3 failed");
2550 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2551 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2552 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2553 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2556 /* Perhaps the server has a 'min password age' set? */
2558 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2559 torture_warning(tctx, "ChangePasswordUser3 failed - %s\n", nt_errstr(r.out.result));
2563 newpass = samr_rand_pass(tctx, 128);
2565 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2567 E_md4hash(newpass, new_nt_hash);
2569 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2570 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2571 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2573 r.in.server = &server;
2574 r.in.account = &account;
2575 r.in.nt_password = &nt_pass;
2576 r.in.nt_verifier = &nt_verifier;
2578 r.in.lm_password = NULL;
2579 r.in.lm_verifier = NULL;
2580 r.in.password3 = NULL;
2581 r.out.dominfo = &dominfo;
2582 r.out.reject = &reject;
2584 unix_to_nt_time(&t, time(NULL));
2586 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2587 "ChangePasswordUser3 failed");
2589 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2590 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2591 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2592 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2595 /* Perhaps the server has a 'min password age' set? */
2598 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3 (on second random password)");
2599 *password = talloc_strdup(tctx, newpass);
2606 static bool test_GetMembersInAlias(struct dcerpc_binding_handle *b,
2607 struct torture_context *tctx,
2608 struct policy_handle *alias_handle)
2610 struct samr_GetMembersInAlias r;
2611 struct lsa_SidArray sids;
2613 torture_comment(tctx, "Testing GetMembersInAlias\n");
2615 r.in.alias_handle = alias_handle;
2618 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetMembersInAlias_r(b, tctx, &r),
2619 "GetMembersInAlias failed");
2620 torture_assert_ntstatus_ok(tctx, r.out.result, "GetMembersInAlias failed");
2625 static bool test_AddMemberToAlias(struct dcerpc_binding_handle *b,
2626 struct torture_context *tctx,
2627 struct policy_handle *alias_handle,
2628 const struct dom_sid *domain_sid)
2630 struct samr_AddAliasMember r;
2631 struct samr_DeleteAliasMember d;
2632 struct dom_sid *sid;
2634 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2636 torture_comment(tctx, "Testing AddAliasMember\n");
2637 r.in.alias_handle = alias_handle;
2640 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddAliasMember_r(b, tctx, &r),
2641 "AddAliasMember failed");
2642 torture_assert_ntstatus_ok(tctx, r.out.result, "AddAliasMember failed");
2644 d.in.alias_handle = alias_handle;
2647 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteAliasMember_r(b, tctx, &d),
2648 "DeleteAliasMember failed");
2649 torture_assert_ntstatus_ok(tctx, d.out.result, "DelAliasMember failed");
2654 static bool test_AddMultipleMembersToAlias(struct dcerpc_binding_handle *b,
2655 struct torture_context *tctx,
2656 struct policy_handle *alias_handle)
2658 struct samr_AddMultipleMembersToAlias a;
2659 struct samr_RemoveMultipleMembersFromAlias r;
2660 struct lsa_SidArray sids;
2662 torture_comment(tctx, "Testing AddMultipleMembersToAlias\n");
2663 a.in.alias_handle = alias_handle;
2667 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2669 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2670 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2671 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2673 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddMultipleMembersToAlias_r(b, tctx, &a),
2674 "AddMultipleMembersToAlias failed");
2675 torture_assert_ntstatus_ok(tctx, a.out.result, "AddMultipleMembersToAlias");
2678 torture_comment(tctx, "Testing RemoveMultipleMembersFromAlias\n");
2679 r.in.alias_handle = alias_handle;
2682 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2683 "RemoveMultipleMembersFromAlias failed");
2684 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2686 /* strange! removing twice doesn't give any error */
2687 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2688 "RemoveMultipleMembersFromAlias failed");
2689 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2691 /* but removing an alias that isn't there does */
2692 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2694 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2695 "RemoveMultipleMembersFromAlias failed");
2696 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2701 static bool test_GetAliasMembership(struct dcerpc_binding_handle *b,
2702 struct torture_context *tctx,
2703 struct policy_handle *domain_handle)
2705 struct samr_GetAliasMembership r;
2706 struct lsa_SidArray sids;
2707 struct samr_Ids rids;
2709 torture_comment(tctx, "Testing GetAliasMembership\n");
2711 r.in.domain_handle = domain_handle;
2716 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2718 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2719 "GetAliasMembership failed");
2720 torture_assert_ntstatus_ok(tctx, r.out.result,
2721 "samr_GetAliasMembership failed");
2723 torture_assert_int_equal(tctx, sids.num_sids, rids.count,
2724 "protocol misbehaviour");
2727 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2728 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2730 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2731 "samr_GetAliasMembership failed");
2732 torture_assert_ntstatus_ok(tctx, r.out.result,
2733 "samr_GetAliasMembership failed");
2736 /* only true for w2k8 it seems
2737 * win7, xp, w2k3 will return a 0 length array pointer */
2739 if (rids.ids && (rids.count == 0)) {
2740 torture_fail(tctx, "samr_GetAliasMembership returned 0 count and a rids array");
2743 if (!rids.ids && rids.count) {
2744 torture_fail(tctx, "samr_GetAliasMembership returned non-0 count but no rids");
2750 static bool test_TestPrivateFunctionsUser(struct dcerpc_binding_handle *b,
2751 struct torture_context *tctx,
2752 struct policy_handle *user_handle)
2754 struct samr_TestPrivateFunctionsUser r;
2756 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2758 r.in.user_handle = user_handle;
2760 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsUser_r(b, tctx, &r),
2761 "TestPrivateFunctionsUser failed");
2762 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2767 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_binding_handle *b,
2768 struct torture_context *tctx,
2769 struct policy_handle *handle,
2774 uint16_t levels[] = { /* 3, */ 5, 21 };
2776 NTTIME pwdlastset3 = 0;
2777 NTTIME pwdlastset5 = 0;
2778 NTTIME pwdlastset21 = 0;
2780 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2781 use_info2 ? "2":"");
2783 for (i=0; i<ARRAY_SIZE(levels); i++) {
2785 struct samr_QueryUserInfo r;
2786 struct samr_QueryUserInfo2 r2;
2787 union samr_UserInfo *info;
2790 r2.in.user_handle = handle;
2791 r2.in.level = levels[i];
2792 r2.out.info = &info;
2793 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r2),
2794 "QueryUserInfo2 failed");
2795 status = r2.out.result;
2798 r.in.user_handle = handle;
2799 r.in.level = levels[i];
2801 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
2802 "QueryUserInfo failed");
2803 status = r.out.result;
2806 if (!NT_STATUS_IS_OK(status) &&
2807 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2808 torture_warning(tctx, "QueryUserInfo%s level %u failed - %s\n",
2809 use_info2 ? "2":"", levels[i], nt_errstr(status));
2813 switch (levels[i]) {
2815 pwdlastset3 = info->info3.last_password_change;
2818 pwdlastset5 = info->info5.last_password_change;
2821 pwdlastset21 = info->info21.last_password_change;
2827 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2828 "pwdlastset mixup"); */
2829 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2830 "pwdlastset mixup");
2832 *pwdlastset = pwdlastset21;
2834 torture_comment(tctx, "(pwdlastset: %llu)\n",
2835 (unsigned long long) *pwdlastset);
2840 static bool test_SamLogon(struct torture_context *tctx,
2841 struct dcerpc_pipe *p,
2842 struct cli_credentials *test_credentials,
2843 NTSTATUS expected_result,
2847 struct netr_LogonSamLogonEx r;
2848 union netr_LogonLevel logon;
2849 union netr_Validation validation;
2850 uint8_t authoritative;
2851 struct netr_IdentityInfo identity;
2852 struct netr_NetworkInfo ninfo;
2853 struct netr_PasswordInfo pinfo;
2854 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2855 int flags = CLI_CRED_NTLM_AUTH;
2856 uint32_t samlogon_flags = 0;
2857 struct netlogon_creds_CredentialState *creds;
2858 struct netr_Authenticator a;
2859 struct dcerpc_binding_handle *b = p->binding_handle;
2861 torture_assert_ntstatus_ok(tctx, dcerpc_schannel_creds(p->conn->security_state.generic_state, tctx, &creds), "");
2863 if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
2864 flags |= CLI_CRED_LANMAN_AUTH;
2867 if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx)) {
2868 flags |= CLI_CRED_NTLMv2_AUTH;
2871 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2872 &identity.account_name.string,
2873 &identity.domain_name.string);
2875 identity.parameter_control =
2876 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2877 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2878 identity.logon_id_low = 0;
2879 identity.logon_id_high = 0;
2880 identity.workstation.string = cli_credentials_get_workstation(test_credentials);
2883 netlogon_creds_client_authenticator(creds, &a);
2885 if (!E_deshash(cli_credentials_get_password(test_credentials), pinfo.lmpassword.hash)) {
2886 ZERO_STRUCT(pinfo.lmpassword.hash);
2888 E_md4hash(cli_credentials_get_password(test_credentials), pinfo.ntpassword.hash);
2890 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
2891 netlogon_creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
2892 netlogon_creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
2894 netlogon_creds_des_encrypt(creds, &pinfo.lmpassword);
2895 netlogon_creds_des_encrypt(creds, &pinfo.ntpassword);
2898 pinfo.identity_info = identity;
2899 logon.password = &pinfo;
2901 r.in.logon_level = NetlogonInteractiveInformation;
2903 generate_random_buffer(ninfo.challenge,
2904 sizeof(ninfo.challenge));
2905 chal = data_blob_const(ninfo.challenge,
2906 sizeof(ninfo.challenge));
2908 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
2909 cli_credentials_get_domain(test_credentials));
2911 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2917 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2919 ninfo.lm.data = lm_resp.data;
2920 ninfo.lm.length = lm_resp.length;
2922 ninfo.nt.data = nt_resp.data;
2923 ninfo.nt.length = nt_resp.length;
2925 ninfo.identity_info = identity;
2926 logon.network = &ninfo;
2928 r.in.logon_level = NetlogonNetworkInformation;
2931 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2932 r.in.computer_name = cli_credentials_get_workstation(test_credentials);
2933 r.in.logon = &logon;
2934 r.in.flags = &samlogon_flags;
2935 r.out.flags = &samlogon_flags;
2936 r.out.validation = &validation;
2937 r.out.authoritative = &authoritative;
2939 torture_comment(tctx, "Testing LogonSamLogon with name %s\n", identity.account_name.string);
2941 r.in.validation_level = 6;
2943 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
2944 "netr_LogonSamLogonEx failed");
2945 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
2946 r.in.validation_level = 3;
2947 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
2948 "netr_LogonSamLogonEx failed");
2950 if (!NT_STATUS_IS_OK(r.out.result)) {
2951 torture_assert_ntstatus_equal(tctx, r.out.result, expected_result, "LogonSamLogonEx failed");
2954 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogonEx failed");
2960 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2961 struct dcerpc_pipe *p,
2962 struct cli_credentials *machine_creds,
2963 const char *acct_name,
2964 const char *password,
2965 NTSTATUS expected_samlogon_result,
2969 struct cli_credentials *test_credentials;
2971 test_credentials = cli_credentials_init(tctx);
2973 cli_credentials_set_workstation(test_credentials,
2974 cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
2975 cli_credentials_set_domain(test_credentials,
2976 cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
2977 cli_credentials_set_username(test_credentials,
2978 acct_name, CRED_SPECIFIED);
2979 cli_credentials_set_password(test_credentials,
2980 password, CRED_SPECIFIED);
2982 torture_comment(tctx, "Testing samlogon (%s) as %s password: %s\n",
2983 interactive ? "interactive" : "network", acct_name, password);
2985 if (!test_SamLogon(tctx, p, test_credentials,
2986 expected_samlogon_result, interactive)) {
2987 torture_warning(tctx, "new password did not work\n");
2994 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2995 struct dcerpc_pipe *np,
2996 struct torture_context *tctx,
2997 struct policy_handle *handle,
2999 uint32_t fields_present,
3000 uint8_t password_expired,
3001 bool *matched_expected_error,
3003 const char *acct_name,
3005 struct cli_credentials *machine_creds,
3006 bool use_queryinfo2,
3008 NTSTATUS expected_samlogon_result)
3010 const char *fields = NULL;
3012 struct dcerpc_binding_handle *b = p->binding_handle;
3018 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
3025 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
3026 "(password_expired: %d) %s\n",
3027 use_setinfo2 ? "2":"", level, password_expired,
3028 fields ? fields : "");
3030 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
3035 matched_expected_error)) {
3039 if (!test_QueryUserInfo_pwdlastset(b, tctx, handle,
3045 if (*matched_expected_error == true) {
3049 if (!test_SamLogon_with_creds(tctx, np,
3053 expected_samlogon_result,
3061 static bool setup_schannel_netlogon_pipe(struct torture_context *tctx,
3062 struct cli_credentials *credentials,
3063 struct dcerpc_pipe **p)
3065 struct dcerpc_binding *b;
3067 torture_assert_ntstatus_ok(tctx, torture_rpc_binding(tctx, &b),
3068 "failed to get rpc binding");
3070 /* We have to use schannel, otherwise the SamLogonEx fails
3071 * with INTERNAL_ERROR */
3073 b->flags &= ~DCERPC_AUTH_OPTIONS;
3074 b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
3076 torture_assert_ntstatus_ok(tctx,
3077 dcerpc_pipe_connect_b(tctx, p, b, &ndr_table_netlogon,
3078 credentials, tctx->ev, tctx->lp_ctx),
3079 "failed to bind to netlogon");
3084 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
3085 struct torture_context *tctx,
3086 uint32_t acct_flags,
3087 const char *acct_name,
3088 struct policy_handle *handle,
3090 struct cli_credentials *machine_credentials)
3092 int s = 0, q = 0, f = 0, l = 0, z = 0;
3095 bool set_levels[] = { false, true };
3096 bool query_levels[] = { false, true };
3097 uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
3098 uint32_t nonzeros[] = { 1, 24 };
3099 uint32_t fields_present[] = {
3101 SAMR_FIELD_EXPIRED_FLAG,
3102 SAMR_FIELD_LAST_PWD_CHANGE,
3103 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
3105 SAMR_FIELD_NT_PASSWORD_PRESENT,
3106 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3107 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3108 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3109 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3110 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3111 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
3113 struct dcerpc_pipe *np = NULL;
3115 if (torture_setting_bool(tctx, "samba3", false) ||
3116 torture_setting_bool(tctx, "samba4", false)) {
3118 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
3122 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3124 /* set to 1 to enable testing for all possible opcode
3125 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3128 #define TEST_ALL_LEVELS 1
3129 #define TEST_SET_LEVELS 1
3130 #define TEST_QUERY_LEVELS 1
3132 #ifdef TEST_ALL_LEVELS
3133 for (l=0; l<ARRAY_SIZE(levels); l++) {
3135 for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
3137 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
3138 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
3139 #ifdef TEST_SET_LEVELS
3140 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
3142 #ifdef TEST_QUERY_LEVELS
3143 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
3145 NTTIME pwdlastset_old = 0;
3146 NTTIME pwdlastset_new = 0;
3147 bool matched_expected_error = false;
3148 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
3150 torture_comment(tctx, "------------------------------\n"
3151 "Testing pwdLastSet attribute for flags: 0x%08x "
3152 "(s: %d (l: %d), q: %d)\n",
3153 acct_flags, s, levels[l], q);
3155 switch (levels[l]) {
3159 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3160 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
3161 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
3169 /* set a password and force password change (pwdlastset 0) by
3170 * setting the password expired flag to a non-0 value */
3172 if (!test_SetPassword_level(p, np, tctx, handle,
3176 &matched_expected_error,
3180 machine_credentials,
3183 expected_samlogon_result)) {
3187 if (matched_expected_error == true) {
3188 /* skipping on expected failure */
3192 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3193 * set without the SAMR_FIELD_EXPIRED_FLAG */
3195 switch (levels[l]) {
3199 if ((pwdlastset_new != 0) &&
3200 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3201 torture_comment(tctx, "not considering a non-0 "
3202 "pwdLastSet as a an error as the "
3203 "SAMR_FIELD_EXPIRED_FLAG has not "
3209 if (pwdlastset_new != 0) {
3210 torture_warning(tctx, "pwdLastSet test failed: "
3211 "expected pwdLastSet 0 but got %llu\n",
3212 (unsigned long long) pwdlastset_old);
3218 switch (levels[l]) {
3222 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3223 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3224 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3225 (pwdlastset_old >= pwdlastset_new)) {
3226 torture_warning(tctx, "pwdlastset not increasing\n");
3232 pwdlastset_old = pwdlastset_new;
3238 /* set a password, pwdlastset needs to get updated (increased
3239 * value), password_expired value used here is 0 */
3241 if (!test_SetPassword_level(p, np, tctx, handle,
3245 &matched_expected_error,
3249 machine_credentials,
3252 expected_samlogon_result)) {
3256 /* when a password has been changed, pwdlastset must not be 0 afterwards
3257 * and must be larger then the old value */
3259 switch (levels[l]) {
3263 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3264 * password has been changed, old and new pwdlastset
3265 * need to be the same value */
3267 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3268 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3269 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3271 torture_assert_int_equal(tctx, pwdlastset_old,
3272 pwdlastset_new, "pwdlastset must be equal");
3277 if (pwdlastset_old >= pwdlastset_new) {
3278 torture_warning(tctx, "pwdLastSet test failed: "
3279 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3280 (unsigned long long) pwdlastset_old,
3281 (unsigned long long) pwdlastset_new);
3284 if (pwdlastset_new == 0) {
3285 torture_warning(tctx, "pwdLastSet test failed: "
3286 "expected non-0 pwdlastset, got: %llu\n",
3287 (unsigned long long) pwdlastset_new);
3293 switch (levels[l]) {
3297 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3298 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3299 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3300 (pwdlastset_old >= pwdlastset_new)) {
3301 torture_warning(tctx, "pwdlastset not increasing\n");
3307 pwdlastset_old = pwdlastset_new;
3313 /* set a password, pwdlastset needs to get updated (increased
3314 * value), password_expired value used here is 0 */
3316 if (!test_SetPassword_level(p, np, tctx, handle,
3320 &matched_expected_error,
3324 machine_credentials,
3327 expected_samlogon_result)) {
3331 /* when a password has been changed, pwdlastset must not be 0 afterwards
3332 * and must be larger then the old value */
3334 switch (levels[l]) {
3339 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3340 * password has been changed, old and new pwdlastset
3341 * need to be the same value */
3343 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3344 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3345 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3347 torture_assert_int_equal(tctx, pwdlastset_old,
3348 pwdlastset_new, "pwdlastset must be equal");
3353 if (pwdlastset_old >= pwdlastset_new) {
3354 torture_warning(tctx, "pwdLastSet test failed: "
3355 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3356 (unsigned long long) pwdlastset_old,
3357 (unsigned long long) pwdlastset_new);
3360 if (pwdlastset_new == 0) {
3361 torture_warning(tctx, "pwdLastSet test failed: "
3362 "expected non-0 pwdlastset, got: %llu\n",
3363 (unsigned long long) pwdlastset_new);
3369 switch (levels[l]) {
3373 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3374 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3375 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3376 (pwdlastset_old >= pwdlastset_new)) {
3377 torture_warning(tctx, "pwdlastset not increasing\n");
3383 pwdlastset_old = pwdlastset_new;
3389 /* set a password and force password change (pwdlastset 0) by
3390 * setting the password expired flag to a non-0 value */
3392 if (!test_SetPassword_level(p, np, tctx, handle,
3396 &matched_expected_error,
3400 machine_credentials,
3403 expected_samlogon_result)) {
3407 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3408 * set without the SAMR_FIELD_EXPIRED_FLAG */
3410 switch (levels[l]) {
3414 if ((pwdlastset_new != 0) &&
3415 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3416 torture_comment(tctx, "not considering a non-0 "
3417 "pwdLastSet as a an error as the "
3418 "SAMR_FIELD_EXPIRED_FLAG has not "
3423 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3424 * password has been changed, old and new pwdlastset
3425 * need to be the same value */
3427 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3428 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3429 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3431 torture_assert_int_equal(tctx, pwdlastset_old,
3432 pwdlastset_new, "pwdlastset must be equal");
3437 if (pwdlastset_new != 0) {
3438 torture_warning(tctx, "pwdLastSet test failed: "
3439 "expected pwdLastSet 0, got %llu\n",
3440 (unsigned long long) pwdlastset_old);
3446 switch (levels[l]) {
3450 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3451 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3452 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3453 (pwdlastset_old >= pwdlastset_new)) {
3454 torture_warning(tctx, "pwdlastset not increasing\n");
3460 /* if the level we are testing does not have a fields_present
3461 * field, skip all fields present tests by setting f to to
3463 switch (levels[l]) {
3467 f = ARRAY_SIZE(fields_present);
3471 #ifdef TEST_QUERY_LEVELS
3474 #ifdef TEST_SET_LEVELS
3477 } /* fields present */
3481 #undef TEST_SET_LEVELS
3482 #undef TEST_QUERY_LEVELS
3489 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_binding_handle *b,
3490 struct torture_context *tctx,
3491 struct policy_handle *handle,
3492 uint32_t *badpwdcount)
3494 union samr_UserInfo *info;
3495 struct samr_QueryUserInfo r;
3497 r.in.user_handle = handle;
3501 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3503 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3504 "failed to query userinfo");
3505 torture_assert_ntstatus_ok(tctx, r.out.result,
3506 "failed to query userinfo");
3508 *badpwdcount = info->info3.bad_password_count;
3510 torture_comment(tctx, " (bad password count: %d)\n", *badpwdcount);
3515 static bool test_SetUserInfo_acct_flags(struct dcerpc_binding_handle *b,
3516 struct torture_context *tctx,
3517 struct policy_handle *user_handle,
3518 uint32_t acct_flags)
3520 struct samr_SetUserInfo r;
3521 union samr_UserInfo user_info;
3523 torture_comment(tctx, "Testing SetUserInfo level 16\n");
3525 user_info.info16.acct_flags = acct_flags;
3527 r.in.user_handle = user_handle;
3529 r.in.info = &user_info;
3531 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &r),
3532 "failed to set account flags");
3533 torture_assert_ntstatus_ok(tctx, r.out.result,
3534 "failed to set account flags");
3539 static bool test_reset_badpwdcount(struct dcerpc_pipe *p,
3540 struct torture_context *tctx,
3541 struct policy_handle *user_handle,
3542 uint32_t acct_flags,
3545 struct dcerpc_binding_handle *b = p->binding_handle;
3547 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3548 "failed to set password");
3550 torture_comment(tctx, "Testing SetUserInfo level 16 (enable account)\n");
3552 torture_assert(tctx,
3553 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3554 acct_flags & ~ACB_DISABLED),
3555 "failed to enable user");
3557 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3558 "failed to set password");
3563 static bool test_SetDomainInfo(struct dcerpc_binding_handle *b,
3564 struct torture_context *tctx,
3565 struct policy_handle *domain_handle,
3566 enum samr_DomainInfoClass level,
3567 union samr_DomainInfo *info)
3569 struct samr_SetDomainInfo r;
3571 r.in.domain_handle = domain_handle;
3575 torture_assert_ntstatus_ok(tctx,
3576 dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3577 "failed to set domain info");
3578 torture_assert_ntstatus_ok(tctx, r.out.result,
3579 "failed to set domain info");
3584 static bool test_SetDomainInfo_ntstatus(struct dcerpc_binding_handle *b,
3585 struct torture_context *tctx,
3586 struct policy_handle *domain_handle,
3587 enum samr_DomainInfoClass level,
3588 union samr_DomainInfo *info,
3591 struct samr_SetDomainInfo r;
3593 r.in.domain_handle = domain_handle;
3597 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3598 "SetDomainInfo failed");
3599 torture_assert_ntstatus_equal(tctx, r.out.result, expected, "");
3604 static bool test_QueryDomainInfo2_level(struct dcerpc_binding_handle *b,
3605 struct torture_context *tctx,
3606 struct policy_handle *domain_handle,
3607 enum samr_DomainInfoClass level,
3608 union samr_DomainInfo **q_info)
3610 struct samr_QueryDomainInfo2 r;
3612 r.in.domain_handle = domain_handle;
3614 r.out.info = q_info;
3616 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
3617 "failed to query domain info");
3618 torture_assert_ntstatus_ok(tctx, r.out.result,
3619 "failed to query domain info");
3624 static bool test_Password_badpwdcount(struct dcerpc_pipe *p,
3625 struct dcerpc_pipe *np,
3626 struct torture_context *tctx,
3627 uint32_t acct_flags,
3628 const char *acct_name,
3629 struct policy_handle *domain_handle,
3630 struct policy_handle *user_handle,
3632 struct cli_credentials *machine_credentials,
3633 const char *comment,
3636 NTSTATUS expected_success_status,
3637 struct samr_DomInfo1 *info1,
3638 struct samr_DomInfo12 *info12)
3640 union samr_DomainInfo info;
3643 uint32_t badpwdcount, tmp;
3644 uint32_t password_history_length = 12;
3645 uint32_t lockout_threshold = 15;
3646 struct dcerpc_binding_handle *b = p->binding_handle;
3648 torture_comment(tctx, "\nTesting bad pwd count with: %s\n", comment);
3650 torture_assert(tctx, password_history_length < lockout_threshold,
3651 "password history length needs to be smaller than account lockout threshold for this test");
3656 info.info1 = *info1;
3657 info.info1.password_history_length = password_history_length;
3659 torture_assert(tctx,
3660 test_SetDomainInfo(b, tctx, domain_handle,
3661 DomainPasswordInformation, &info),
3662 "failed to set password history length");
3664 info.info12 = *info12;
3665 info.info12.lockout_threshold = lockout_threshold;
3667 torture_assert(tctx,
3668 test_SetDomainInfo(b, tctx, domain_handle,
3669 DomainLockoutInformation, &info),
3670 "failed to set lockout threshold");
3672 /* reset bad pwd count */
3674 torture_assert(tctx,
3675 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
3678 /* enable or disable account */
3680 torture_assert(tctx,
3681 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3682 acct_flags | ACB_DISABLED),
3683 "failed to disable user");
3685 torture_assert(tctx,
3686 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3687 acct_flags & ~ACB_DISABLED),
3688 "failed to enable user");
3692 /* setup password history */
3694 passwords = talloc_array(tctx, char *, password_history_length);
3696 for (i=0; i < password_history_length; i++) {
3698 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3699 "failed to set password");
3700 passwords[i] = talloc_strdup(tctx, *password);
3702 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3703 acct_name, passwords[i],
3704 expected_success_status, interactive)) {
3705 torture_fail(tctx, "failed to auth with latest password");
3708 torture_assert(tctx,
3709 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3711 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3715 /* test with wrong password */
3717 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3718 acct_name, "random_crap",
3719 NT_STATUS_WRONG_PASSWORD, interactive)) {
3720 torture_fail(tctx, "succeeded to authenticate with wrong password");
3723 torture_assert(tctx,
3724 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3726 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3729 /* test with latest good password */
3731 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
3732 passwords[password_history_length-1],
3733 expected_success_status, interactive)) {
3734 torture_fail(tctx, "succeeded to authenticate with wrong password");
3737 torture_assert(tctx,
3738 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3741 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3743 /* only enabled accounts get the bad pwd count reset upon
3744 * successful logon */
3745 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3751 /* test password history */
3753 for (i=0; i < password_history_length; i++) {
3755 torture_comment(tctx, "Testing bad password count behavior with "
3756 "password #%d of #%d\n", i, password_history_length);
3758 /* - network samlogon will succeed auth and not
3759 * increase badpwdcount for 2 last entries
3760 * - interactive samlogon only for the last one */
3762 if (i == password_history_length - 1 ||
3763 (i == password_history_length - 2 && !interactive)) {
3765 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3766 acct_name, passwords[i],
3767 expected_success_status, interactive)) {
3768 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3771 torture_assert(tctx,
3772 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3775 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
3776 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3778 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
3779 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3787 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3788 acct_name, passwords[i],
3789 NT_STATUS_WRONG_PASSWORD, interactive)) {
3790 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3793 torture_assert(tctx,
3794 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3796 /* - network samlogon will fail auth but not increase
3797 * badpwdcount for 3rd last entry
3798 * - interactive samlogon for 3rd and 2nd last entry */
3800 if (i == password_history_length - 3 ||
3801 (i == password_history_length - 2 && interactive)) {
3802 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
3803 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3805 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
3806 torture_assert_int_equal(tctx, badpwdcount, tmp + 1, "unexpected badpwdcount");
3815 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe *p,
3816 struct torture_context *tctx,
3817 uint32_t acct_flags,
3818 const char *acct_name,
3819 struct policy_handle *domain_handle,
3820 struct policy_handle *user_handle,
3822 struct cli_credentials *machine_credentials)
3824 union samr_DomainInfo *q_info, s_info;
3825 struct samr_DomInfo1 info1, _info1;
3826 struct samr_DomInfo12 info12, _info12;
3828 struct dcerpc_binding_handle *b = p->binding_handle;
3829 struct dcerpc_pipe *np;
3833 const char *comment;
3836 NTSTATUS expected_success_status;
3839 .comment = "network logon (disabled account)",
3841 .interactive = false,
3842 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
3845 .comment = "network logon (enabled account)",
3847 .interactive = false,
3848 .expected_success_status= NT_STATUS_OK
3851 .comment = "interactive logon (disabled account)",
3853 .interactive = true,
3854 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
3857 .comment = "interactive logon (enabled account)",
3859 .interactive = true,
3860 .expected_success_status= NT_STATUS_OK
3864 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3866 /* backup old policies */
3868 torture_assert(tctx,
3869 test_QueryDomainInfo2_level(b, tctx, domain_handle,
3870 DomainPasswordInformation, &q_info),
3871 "failed to query domain info level 1");
3873 info1 = q_info->info1;
3876 torture_assert(tctx,
3877 test_QueryDomainInfo2_level(b, tctx, domain_handle,
3878 DomainLockoutInformation, &q_info),
3879 "failed to query domain info level 12");
3881 info12 = q_info->info12;
3886 for (i=0; i < ARRAY_SIZE(creds); i++) {
3888 /* skip trust tests for now */
3889 if (acct_flags & ACB_WSTRUST ||
3890 acct_flags & ACB_SVRTRUST ||
3891 acct_flags & ACB_DOMTRUST) {
3895 ret &= test_Password_badpwdcount(p, np, tctx, acct_flags, acct_name,
3896 domain_handle, user_handle, password,
3897 machine_credentials,
3900 creds[i].interactive,
3901 creds[i].expected_success_status,
3904 torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
3906 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
3910 /* restore policies */
3912 s_info.info1 = info1;
3914 torture_assert(tctx,
3915 test_SetDomainInfo(b, tctx, domain_handle,
3916 DomainPasswordInformation, &s_info),
3917 "failed to set password information");
3919 s_info.info12 = info12;
3921 torture_assert(tctx,
3922 test_SetDomainInfo(b, tctx, domain_handle,
3923 DomainLockoutInformation, &s_info),
3924 "failed to set lockout information");
3929 static bool test_QueryUserInfo_acct_flags(struct dcerpc_binding_handle *b,
3930 struct torture_context *tctx,
3931 struct policy_handle *handle,
3932 uint32_t *acct_flags)
3934 union samr_UserInfo *info;
3935 struct samr_QueryUserInfo r;
3937 r.in.user_handle = handle;
3941 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3943 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3944 "failed to query userinfo");
3945 torture_assert_ntstatus_ok(tctx, r.out.result,
3946 "failed to query userinfo");
3948 *acct_flags = info->info16.acct_flags;
3950 torture_comment(tctx, " (acct_flags: 0x%08x)\n", *acct_flags);
3955 static bool test_Password_lockout(struct dcerpc_pipe *p,
3956 struct dcerpc_pipe *np,
3957 struct torture_context *tctx,
3958 uint32_t acct_flags,
3959 const char *acct_name,
3960 struct policy_handle *domain_handle,
3961 struct policy_handle *user_handle,
3963 struct cli_credentials *machine_credentials,
3964 const char *comment,
3967 NTSTATUS expected_success_status,
3968 struct samr_DomInfo1 *info1,
3969 struct samr_DomInfo12 *info12)
3971 union samr_DomainInfo info;
3972 uint32_t badpwdcount;
3973 uint32_t password_history_length = 1;
3974 uint64_t lockout_threshold = 1;
3975 uint32_t lockout_seconds = 5;
3976 uint64_t delta_time_factor = 10 * 1000 * 1000;
3977 struct dcerpc_binding_handle *b = p->binding_handle;
3979 torture_comment(tctx, "\nTesting account lockout: %s\n", comment);
3983 info.info1 = *info1;
3985 torture_comment(tctx, "setting password history length.\n");
3986 info.info1.password_history_length = password_history_length;
3988 torture_assert(tctx,
3989 test_SetDomainInfo(b, tctx, domain_handle,
3990 DomainPasswordInformation, &info),
3991 "failed to set password history length");
3993 info.info12 = *info12;
3994 info.info12.lockout_threshold = lockout_threshold;
3996 /* set lockout duration < lockout window: should fail */
3997 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
3998 info.info12.lockout_window = ~((lockout_seconds + 1) * delta_time_factor);
4000 torture_assert(tctx,
4001 test_SetDomainInfo_ntstatus(b, tctx, domain_handle,
4002 DomainLockoutInformation, &info,
4003 NT_STATUS_INVALID_PARAMETER),
4004 "setting lockout duration < lockout window gave unexpected result");
4006 info.info12.lockout_duration = 0;
4007 info.info12.lockout_window = 0;
4009 torture_assert(tctx,
4010 test_SetDomainInfo(b, tctx, domain_handle,
4011 DomainLockoutInformation, &info),
4012 "failed to set lockout window and duration to 0");
4015 /* set lockout duration of 5 seconds */
4016 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4017 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
4019 torture_assert(tctx,
4020 test_SetDomainInfo(b, tctx, domain_handle,
4021 DomainLockoutInformation, &info),
4022 "failed to set lockout window and duration to 5 seconds");
4024 /* reset bad pwd count */
4026 torture_assert(tctx,
4027 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
4030 /* enable or disable account */
4033 torture_assert(tctx,
4034 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4035 acct_flags | ACB_DISABLED),
4036 "failed to disable user");
4038 torture_assert(tctx,
4039 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4040 acct_flags & ~ACB_DISABLED),
4041 "failed to enable user");
4045 /* test logon with right password */
4047 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4048 acct_name, *password,
4049 expected_success_status, interactive)) {
4050 torture_fail(tctx, "failed to auth with latest password");
4053 torture_assert(tctx,
4054 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4055 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
4058 /* test with wrong password ==> lockout */
4060 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4061 acct_name, "random_crap",
4062 NT_STATUS_WRONG_PASSWORD, interactive)) {
4063 torture_fail(tctx, "succeeded to authenticate with wrong password");
4066 torture_assert(tctx,
4067 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4068 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4070 torture_assert(tctx,
4071 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4072 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4073 "expected account to be locked");
4076 /* test with good password */
4078 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4080 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4082 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4085 /* bad pwd count should not get updated */
4086 torture_assert(tctx,
4087 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4088 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4090 /* curiously, windows does _not_ set the autlock flag */
4091 torture_assert(tctx,
4092 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4093 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4094 "expected account to be locked");
4097 /* with bad password */
4099 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4100 acct_name, "random_crap2",
4101 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4103 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4106 /* bad pwd count should not get updated */
4107 torture_assert(tctx,
4108 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4109 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4111 /* curiously, windows does _not_ set the autlock flag */
4112 torture_assert(tctx,
4113 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4114 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4115 "expected account to be locked");
4118 /* let lockout duration expire ==> unlock */
4120 torture_comment(tctx, "let lockout duration expire...\n");
4121 sleep(lockout_seconds + 1);
4123 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4125 expected_success_status, interactive))
4127 torture_fail(tctx, "failed to authenticate after lockout expired");
4130 torture_assert(tctx,
4131 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4132 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4133 "expected account not to be locked");
4138 static bool test_Password_lockout_wrap(struct dcerpc_pipe *p,
4139 struct torture_context *tctx,
4140 uint32_t acct_flags,
4141 const char *acct_name,
4142 struct policy_handle *domain_handle,
4143 struct policy_handle *user_handle,
4145 struct cli_credentials *machine_credentials)
4147 union samr_DomainInfo *q_info, s_info;
4148 struct samr_DomInfo1 info1, _info1;
4149 struct samr_DomInfo12 info12, _info12;
4151 struct dcerpc_binding_handle *b = p->binding_handle;
4152 struct dcerpc_pipe *np;
4156 const char *comment;
4159 NTSTATUS expected_success_status;
4162 .comment = "network logon (disabled account)",
4164 .interactive = false,
4165 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4168 .comment = "network logon (enabled account)",
4170 .interactive = false,
4171 .expected_success_status= NT_STATUS_OK
4174 .comment = "interactive logon (disabled account)",
4176 .interactive = true,
4177 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4180 .comment = "interactive logon (enabled account)",
4182 .interactive = true,
4183 .expected_success_status= NT_STATUS_OK
4187 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4189 /* backup old policies */
4191 torture_assert(tctx,
4192 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4193 DomainPasswordInformation, &q_info),
4194 "failed to query domain info level 1");
4196 info1 = q_info->info1;
4199 torture_assert(tctx,
4200 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4201 DomainLockoutInformation, &q_info),
4202 "failed to query domain info level 12");
4204 info12 = q_info->info12;
4209 for (i=0; i < ARRAY_SIZE(creds); i++) {
4211 /* skip trust tests for now */
4212 if (acct_flags & ACB_WSTRUST ||
4213 acct_flags & ACB_SVRTRUST ||
4214 acct_flags & ACB_DOMTRUST) {
4218 ret &= test_Password_lockout(p, np, tctx, acct_flags, acct_name,
4219 domain_handle, user_handle, password,
4220 machine_credentials,
4223 creds[i].interactive,
4224 creds[i].expected_success_status,
4227 torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
4229 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4233 /* restore policies */
4235 s_info.info1 = info1;
4237 torture_assert(tctx,
4238 test_SetDomainInfo(b, tctx, domain_handle,
4239 DomainPasswordInformation, &s_info),
4240 "failed to set password information");
4242 s_info.info12 = info12;
4244 torture_assert(tctx,
4245 test_SetDomainInfo(b, tctx, domain_handle,
4246 DomainLockoutInformation, &s_info),
4247 "failed to set lockout information");
4252 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
4253 struct dcerpc_pipe *lp,
4254 struct torture_context *tctx,
4255 struct policy_handle *domain_handle,
4256 struct policy_handle *lsa_handle,
4257 struct policy_handle *user_handle,
4258 const struct dom_sid *domain_sid,
4260 struct cli_credentials *machine_credentials)
4263 struct dcerpc_binding_handle *b = p->binding_handle;
4264 struct dcerpc_binding_handle *lb = lp->binding_handle;
4266 struct policy_handle lsa_acct_handle;
4267 struct dom_sid *user_sid;
4269 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
4272 struct lsa_EnumAccountRights r;
4273 struct lsa_RightSet rights;
4275 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4277 r.in.handle = lsa_handle;
4278 r.in.sid = user_sid;
4279 r.out.rights = &rights;
4281 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4282 "lsa_EnumAccountRights failed");
4283 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4284 "Expected enum rights for account to fail");
4288 struct lsa_RightSet rights;
4289 struct lsa_StringLarge names[2];
4290 struct lsa_AddAccountRights r;
4292 torture_comment(tctx, "Testing LSA AddAccountRights\n");
4294 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
4295 init_lsa_StringLarge(&names[1], NULL);
4298 rights.names = names;
4300 r.in.handle = lsa_handle;
4301 r.in.sid = user_sid;
4302 r.in.rights = &rights;
4304 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
4305 "lsa_AddAccountRights failed");
4306 torture_assert_ntstatus_ok(tctx, r.out.result,
4307 "Failed to add privileges");
4311 struct lsa_EnumAccounts r;
4312 uint32_t resume_handle = 0;
4313 struct lsa_SidArray lsa_sid_array;
4315 bool found_sid = false;
4317 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4319 r.in.handle = lsa_handle;
4320 r.in.num_entries = 0x1000;
4321 r.in.resume_handle = &resume_handle;
4322 r.out.sids = &lsa_sid_array;
4323 r.out.resume_handle = &resume_handle;
4325 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4326 "lsa_EnumAccounts failed");
4327 torture_assert_ntstatus_ok(tctx, r.out.result,
4328 "Failed to enum accounts");
4330 for (i=0; i < lsa_sid_array.num_sids; i++) {
4331 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4336 torture_assert(tctx, found_sid,
4337 "failed to list privileged account");
4341 struct lsa_EnumAccountRights r;
4342 struct lsa_RightSet user_rights;
4344 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4346 r.in.handle = lsa_handle;
4347 r.in.sid = user_sid;
4348 r.out.rights = &user_rights;
4350 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4351 "lsa_EnumAccountRights failed");
4352 torture_assert_ntstatus_ok(tctx, r.out.result,
4353 "Failed to enum rights for account");
4355 if (user_rights.count < 1) {
4356 torture_warning(tctx, "failed to find newly added rights");
4362 struct lsa_OpenAccount r;
4364 torture_comment(tctx, "Testing LSA OpenAccount\n");
4366 r.in.handle = lsa_handle;
4367 r.in.sid = user_sid;
4368 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4369 r.out.acct_handle = &lsa_acct_handle;
4371 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4372 "lsa_OpenAccount failed");
4373 torture_assert_ntstatus_ok(tctx, r.out.result,
4374 "Failed to open lsa account");
4378 struct lsa_GetSystemAccessAccount r;
4379 uint32_t access_mask;
4381 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4383 r.in.handle = &lsa_acct_handle;
4384 r.out.access_mask = &access_mask;
4386 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4387 "lsa_GetSystemAccessAccount failed");
4388 torture_assert_ntstatus_ok(tctx, r.out.result,
4389 "Failed to get lsa system access account");
4395 torture_comment(tctx, "Testing LSA Close\n");
4397 r.in.handle = &lsa_acct_handle;
4398 r.out.handle = &lsa_acct_handle;
4400 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(lb, tctx, &r),
4401 "lsa_Close failed");
4402 torture_assert_ntstatus_ok(tctx, r.out.result,
4403 "Failed to close lsa");
4407 struct samr_DeleteUser r;
4409 torture_comment(tctx, "Testing SAMR DeleteUser\n");
4411 r.in.user_handle = user_handle;
4412 r.out.user_handle = user_handle;
4414 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &r),
4415 "DeleteUser failed");
4416 torture_assert_ntstatus_ok(tctx, r.out.result,
4417 "DeleteUser failed");
4421 struct lsa_EnumAccounts r;
4422 uint32_t resume_handle = 0;
4423 struct lsa_SidArray lsa_sid_array;
4425 bool found_sid = false;
4427 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4429 r.in.handle = lsa_handle;
4430 r.in.num_entries = 0x1000;
4431 r.in.resume_handle = &resume_handle;
4432 r.out.sids = &lsa_sid_array;
4433 r.out.resume_handle = &resume_handle;
4435 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4436 "lsa_EnumAccounts failed");
4437 torture_assert_ntstatus_ok(tctx, r.out.result,
4438 "Failed to enum accounts");
4440 for (i=0; i < lsa_sid_array.num_sids; i++) {
4441 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4446 torture_assert(tctx, found_sid,
4447 "failed to list privileged account");
4451 struct lsa_EnumAccountRights r;
4452 struct lsa_RightSet user_rights;
4454 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4456 r.in.handle = lsa_handle;
4457 r.in.sid = user_sid;
4458 r.out.rights = &user_rights;
4460 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4461 "lsa_EnumAccountRights failed");
4462 torture_assert_ntstatus_ok(tctx, r.out.result,
4463 "Failed to enum rights for account");
4465 if (user_rights.count < 1) {
4466 torture_warning(tctx, "failed to find newly added rights");
4472 struct lsa_OpenAccount r;
4474 torture_comment(tctx, "Testing LSA OpenAccount\n");
4476 r.in.handle = lsa_handle;
4477 r.in.sid = user_sid;
4478 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4479 r.out.acct_handle = &lsa_acct_handle;
4481 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4482 "lsa_OpenAccount failed");
4483 torture_assert_ntstatus_ok(tctx, r.out.result,
4484 "Failed to open lsa account");
4488 struct lsa_GetSystemAccessAccount r;
4489 uint32_t access_mask;
4491 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4493 r.in.handle = &lsa_acct_handle;
4494 r.out.access_mask = &access_mask;
4496 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4497 "lsa_GetSystemAccessAccount failed");
4498 torture_assert_ntstatus_ok(tctx, r.out.result,
4499 "Failed to get lsa system access account");
4503 struct lsa_DeleteObject r;
4505 torture_comment(tctx, "Testing LSA DeleteObject\n");
4507 r.in.handle = &lsa_acct_handle;
4508 r.out.handle = &lsa_acct_handle;
4510 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(lb, tctx, &r),
4511 "lsa_DeleteObject failed");
4512 torture_assert_ntstatus_ok(tctx, r.out.result,
4513 "Failed to delete object");
4517 struct lsa_EnumAccounts r;
4518 uint32_t resume_handle = 0;
4519 struct lsa_SidArray lsa_sid_array;
4521 bool found_sid = false;
4523 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4525 r.in.handle = lsa_handle;
4526 r.in.num_entries = 0x1000;
4527 r.in.resume_handle = &resume_handle;
4528 r.out.sids = &lsa_sid_array;
4529 r.out.resume_handle = &resume_handle;
4531 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4532 "lsa_EnumAccounts failed");
4533 torture_assert_ntstatus_ok(tctx, r.out.result,
4534 "Failed to enum accounts");
4536 for (i=0; i < lsa_sid_array.num_sids; i++) {
4537 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4542 torture_assert(tctx, !found_sid,
4543 "should not have listed privileged account");
4547 struct lsa_EnumAccountRights r;
4548 struct lsa_RightSet user_rights;
4550 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4552 r.in.handle = lsa_handle;
4553 r.in.sid = user_sid;
4554 r.out.rights = &user_rights;
4556 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4557 "lsa_EnumAccountRights failed");
4558 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4559 "Failed to enum rights for account");
4565 static bool test_user_ops(struct dcerpc_pipe *p,
4566 struct torture_context *tctx,
4567 struct policy_handle *user_handle,
4568 struct policy_handle *domain_handle,
4569 const struct dom_sid *domain_sid,
4570 uint32_t base_acct_flags,
4571 const char *base_acct_name, enum torture_samr_choice which_ops,
4572 struct cli_credentials *machine_credentials)
4574 char *password = NULL;
4575 struct samr_QueryUserInfo q;
4576 union samr_UserInfo *info;
4578 struct dcerpc_binding_handle *b = p->binding_handle;
4583 const uint32_t password_fields[] = {
4584 SAMR_FIELD_NT_PASSWORD_PRESENT,
4585 SAMR_FIELD_LM_PASSWORD_PRESENT,
4586 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
4590 status = test_LookupName(b, tctx, domain_handle, base_acct_name, &rid);
4591 if (!NT_STATUS_IS_OK(status)) {
4595 switch (which_ops) {
4596 case TORTURE_SAMR_USER_ATTRIBUTES:
4597 if (!test_QuerySecurity(b, tctx, user_handle)) {
4601 if (!test_QueryUserInfo(b, tctx, user_handle)) {
4605 if (!test_QueryUserInfo2(b, tctx, user_handle)) {
4609 if (!test_SetUserInfo(b, tctx, user_handle, base_acct_flags,
4614 if (!test_GetUserPwInfo(b, tctx, user_handle)) {
4618 if (!test_TestPrivateFunctionsUser(b, tctx, user_handle)) {
4622 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
4626 case TORTURE_SAMR_PASSWORDS:
4627 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
4628 char simple_pass[9];
4629 char *v = generate_random_str(tctx, 1);
4631 ZERO_STRUCT(simple_pass);
4632 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4634 torture_comment(tctx, "Testing machine account password policy rules\n");
4636 /* Workstation trust accounts don't seem to need to honour password quality policy */
4637 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4641 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
4645 /* reset again, to allow another 'user' password change */
4646 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4650 /* Try a 'short' password */
4651 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
4655 /* Try a compleatly random password */
4656 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
4661 for (i = 0; password_fields[i]; i++) {
4662 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
4666 /* check it was set right */
4667 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4672 for (i = 0; password_fields[i]; i++) {
4673 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
4677 /* check it was set right */
4678 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4683 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
4687 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
4691 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
4695 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4699 for (i = 0; password_fields[i]; i++) {
4701 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
4702 /* we need to skip as that would break
4703 * the ChangePasswordUser3 verify */
4707 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
4711 /* check it was set right */
4712 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4717 q.in.user_handle = user_handle;
4721 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
4722 "QueryUserInfo failed");
4723 if (!NT_STATUS_IS_OK(q.out.result)) {
4724 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4725 q.in.level, nt_errstr(q.out.result));
4728 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4729 if ((info->info5.acct_flags) != expected_flags) {
4730 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4731 info->info5.acct_flags,
4734 if (!torture_setting_bool(tctx, "samba3", false)) {
4738 if (info->info5.rid != rid) {
4739 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
4740 info->info5.rid, rid);
4747 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
4749 /* test last password change timestamp behaviour */
4750 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
4752 user_handle, &password,
4753 machine_credentials)) {
4758 torture_comment(tctx, "pwdLastSet test succeeded\n");
4760 torture_warning(tctx, "pwdLastSet test failed\n");
4765 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
4767 /* test bad pwd count change behaviour */
4768 if (!test_Password_badpwdcount_wrap(p, tctx, base_acct_flags,
4771 user_handle, &password,
4772 machine_credentials)) {
4777 torture_comment(tctx, "badPwdCount test succeeded\n");
4779 torture_warning(tctx, "badPwdCount test failed\n");
4784 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
4786 if (!test_Password_lockout_wrap(p, tctx, base_acct_flags,
4789 user_handle, &password,
4790 machine_credentials))
4796 torture_comment(tctx, "lockout test succeeded\n");
4798 torture_warning(tctx, "lockout test failed\n");
4804 case TORTURE_SAMR_USER_PRIVILEGES: {
4806 struct dcerpc_pipe *lp;
4807 struct policy_handle *lsa_handle;
4808 struct dcerpc_binding_handle *lb;
4810 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
4811 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
4812 lb = lp->binding_handle;
4814 if (!test_lsa_OpenPolicy2(lb, tctx, &lsa_handle)) {
4818 if (!test_DeleteUser_with_privs(p, lp, tctx,
4819 domain_handle, lsa_handle, user_handle,
4821 machine_credentials)) {
4825 if (!test_lsa_Close(lb, tctx, lsa_handle)) {
4830 torture_warning(tctx, "privileged user delete test failed\n");
4835 case TORTURE_SAMR_OTHER:
4836 case TORTURE_SAMR_MANY_ACCOUNTS:
4837 case TORTURE_SAMR_MANY_GROUPS:
4838 case TORTURE_SAMR_MANY_ALIASES:
4839 /* We just need the account to exist */
4845 static bool test_alias_ops(struct dcerpc_binding_handle *b,
4846 struct torture_context *tctx,
4847 struct policy_handle *alias_handle,
4848 const struct dom_sid *domain_sid)
4852 if (!torture_setting_bool(tctx, "samba3", false)) {
4853 if (!test_QuerySecurity(b, tctx, alias_handle)) {
4858 if (!test_QueryAliasInfo(b, tctx, alias_handle)) {
4862 if (!test_SetAliasInfo(b, tctx, alias_handle)) {
4866 if (!test_AddMemberToAlias(b, tctx, alias_handle, domain_sid)) {
4870 if (torture_setting_bool(tctx, "samba3", false) ||
4871 torture_setting_bool(tctx, "samba4", false)) {
4872 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
4876 if (!test_AddMultipleMembersToAlias(b, tctx, alias_handle)) {
4884 static bool test_DeleteUser(struct dcerpc_binding_handle *b,
4885 struct torture_context *tctx,
4886 struct policy_handle *user_handle)
4888 struct samr_DeleteUser d;
4889 torture_comment(tctx, "Testing DeleteUser\n");
4891 d.in.user_handle = user_handle;
4892 d.out.user_handle = user_handle;
4894 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
4895 "DeleteUser failed");
4896 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteUser");
4901 bool test_DeleteUser_byname(struct dcerpc_binding_handle *b,
4902 struct torture_context *tctx,
4903 struct policy_handle *handle, const char *name)
4906 struct samr_DeleteUser d;
4907 struct policy_handle user_handle;
4910 status = test_LookupName(b, tctx, handle, name, &rid);
4911 if (!NT_STATUS_IS_OK(status)) {
4915 status = test_OpenUser_byname(b, tctx, handle, name, &user_handle);
4916 if (!NT_STATUS_IS_OK(status)) {
4920 d.in.user_handle = &user_handle;
4921 d.out.user_handle = &user_handle;
4922 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
4923 "DeleteUser failed");
4924 if (!NT_STATUS_IS_OK(d.out.result)) {
4925 status = d.out.result;
4932 torture_warning(tctx, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
4937 static bool test_DeleteGroup_byname(struct dcerpc_binding_handle *b,
4938 struct torture_context *tctx,
4939 struct policy_handle *handle, const char *name)
4942 struct samr_OpenGroup r;
4943 struct samr_DeleteDomainGroup d;
4944 struct policy_handle group_handle;
4947 status = test_LookupName(b, tctx, handle, name, &rid);
4948 if (!NT_STATUS_IS_OK(status)) {
4952 r.in.domain_handle = handle;
4953 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4955 r.out.group_handle = &group_handle;
4956 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
4957 "OpenGroup failed");
4958 if (!NT_STATUS_IS_OK(r.out.result)) {
4959 status = r.out.result;
4963 d.in.group_handle = &group_handle;
4964 d.out.group_handle = &group_handle;
4965 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
4966 "DeleteDomainGroup failed");
4967 if (!NT_STATUS_IS_OK(d.out.result)) {
4968 status = d.out.result;
4975 torture_warning(tctx, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
4980 static bool test_DeleteAlias_byname(struct dcerpc_binding_handle *b,
4981 struct torture_context *tctx,
4982 struct policy_handle *domain_handle,
4986 struct samr_OpenAlias r;
4987 struct samr_DeleteDomAlias d;
4988 struct policy_handle alias_handle;
4991 torture_comment(tctx, "Testing DeleteAlias_byname\n");
4993 status = test_LookupName(b, tctx, domain_handle, name, &rid);
4994 if (!NT_STATUS_IS_OK(status)) {
4998 r.in.domain_handle = domain_handle;
4999 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5001 r.out.alias_handle = &alias_handle;
5002 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5003 "OpenAlias failed");
5004 if (!NT_STATUS_IS_OK(r.out.result)) {
5005 status = r.out.result;
5009 d.in.alias_handle = &alias_handle;
5010 d.out.alias_handle = &alias_handle;
5011 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5012 "DeleteDomAlias failed");
5013 if (!NT_STATUS_IS_OK(d.out.result)) {
5014 status = d.out.result;
5021 torture_warning(tctx, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
5025 static bool test_DeleteAlias(struct dcerpc_binding_handle *b,
5026 struct torture_context *tctx,
5027 struct policy_handle *alias_handle)
5029 struct samr_DeleteDomAlias d;
5032 torture_comment(tctx, "Testing DeleteAlias\n");
5034 d.in.alias_handle = alias_handle;
5035 d.out.alias_handle = alias_handle;
5037 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5038 "DeleteDomAlias failed");
5039 if (!NT_STATUS_IS_OK(d.out.result)) {
5040 torture_warning(tctx, "DeleteAlias failed - %s\n", nt_errstr(d.out.result));
5047 static bool test_CreateAlias(struct dcerpc_binding_handle *b,
5048 struct torture_context *tctx,
5049 struct policy_handle *domain_handle,
5050 const char *alias_name,
5051 struct policy_handle *alias_handle,
5052 const struct dom_sid *domain_sid,
5055 struct samr_CreateDomAlias r;
5056 struct lsa_String name;
5060 init_lsa_String(&name, alias_name);
5061 r.in.domain_handle = domain_handle;
5062 r.in.alias_name = &name;
5063 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5064 r.out.alias_handle = alias_handle;
5067 torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
5069 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5070 "CreateDomAlias failed");
5072 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5073 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
5074 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
5077 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
5078 nt_errstr(r.out.result));
5083 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ALIAS_EXISTS)) {
5084 if (!test_DeleteAlias_byname(b, tctx, domain_handle, r.in.alias_name->string)) {
5087 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5088 "CreateDomAlias failed");
5091 if (!NT_STATUS_IS_OK(r.out.result)) {
5092 torture_warning(tctx, "CreateAlias failed - %s\n", nt_errstr(r.out.result));
5100 if (!test_alias_ops(b, tctx, alias_handle, domain_sid)) {
5107 static bool test_ChangePassword(struct dcerpc_pipe *p,
5108 struct torture_context *tctx,
5109 const char *acct_name,
5110 struct policy_handle *domain_handle, char **password)
5113 struct dcerpc_binding_handle *b = p->binding_handle;
5119 if (!test_ChangePasswordUser(b, tctx, acct_name, domain_handle, password)) {
5123 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
5127 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
5131 /* test what happens when setting the old password again */
5132 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
5137 char simple_pass[9];
5138 char *v = generate_random_str(tctx, 1);
5140 ZERO_STRUCT(simple_pass);
5141 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5143 /* test what happens when picking a simple password */
5144 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
5149 /* set samr_SetDomainInfo level 1 with min_length 5 */
5151 struct samr_QueryDomainInfo r;
5152 union samr_DomainInfo *info = NULL;
5153 struct samr_SetDomainInfo s;
5154 uint16_t len_old, len;
5155 uint32_t pwd_prop_old;
5156 int64_t min_pwd_age_old;
5160 r.in.domain_handle = domain_handle;
5164 torture_comment(tctx, "Testing samr_QueryDomainInfo level 1\n");
5165 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
5166 "QueryDomainInfo failed");
5167 if (!NT_STATUS_IS_OK(r.out.result)) {
5171 s.in.domain_handle = domain_handle;
5175 /* remember the old min length, so we can reset it */
5176 len_old = s.in.info->info1.min_password_length;
5177 s.in.info->info1.min_password_length = len;
5178 pwd_prop_old = s.in.info->info1.password_properties;
5179 /* turn off password complexity checks for this test */
5180 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
5182 min_pwd_age_old = s.in.info->info1.min_password_age;
5183 s.in.info->info1.min_password_age = 0;
5185 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5186 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5187 "SetDomainInfo failed");
5188 if (!NT_STATUS_IS_OK(s.out.result)) {
5192 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
5194 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
5198 s.in.info->info1.min_password_length = len_old;
5199 s.in.info->info1.password_properties = pwd_prop_old;
5200 s.in.info->info1.min_password_age = min_pwd_age_old;
5202 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5203 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5204 "SetDomainInfo failed");
5205 if (!NT_STATUS_IS_OK(s.out.result)) {
5212 struct samr_OpenUser r;
5213 struct samr_QueryUserInfo q;
5214 union samr_UserInfo *info;
5215 struct samr_LookupNames n;
5216 struct policy_handle user_handle;
5217 struct samr_Ids rids, types;
5219 n.in.domain_handle = domain_handle;
5221 n.in.names = talloc_array(tctx, struct lsa_String, 1);
5222 n.in.names[0].string = acct_name;
5224 n.out.types = &types;
5226 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
5227 "LookupNames failed");
5228 if (!NT_STATUS_IS_OK(n.out.result)) {
5229 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(n.out.result));
5233 r.in.domain_handle = domain_handle;
5234 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5235 r.in.rid = n.out.rids->ids[0];
5236 r.out.user_handle = &user_handle;
5238 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5240 if (!NT_STATUS_IS_OK(r.out.result)) {
5241 torture_warning(tctx, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(r.out.result));
5245 q.in.user_handle = &user_handle;
5249 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5250 "QueryUserInfo failed");
5251 if (!NT_STATUS_IS_OK(q.out.result)) {
5252 torture_warning(tctx, "QueryUserInfo failed - %s\n", nt_errstr(q.out.result));
5256 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
5258 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
5259 info->info5.last_password_change, true)) {
5264 /* we change passwords twice - this has the effect of verifying
5265 they were changed correctly for the final call */
5266 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5270 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5277 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
5278 struct policy_handle *domain_handle,
5279 const char *user_name,
5280 struct policy_handle *user_handle_out,
5281 struct dom_sid *domain_sid,
5282 enum torture_samr_choice which_ops,
5283 struct cli_credentials *machine_credentials,
5287 TALLOC_CTX *user_ctx;
5289 struct samr_CreateUser r;
5290 struct samr_QueryUserInfo q;
5291 union samr_UserInfo *info;
5292 struct samr_DeleteUser d;
5295 /* This call creates a 'normal' account - check that it really does */
5296 const uint32_t acct_flags = ACB_NORMAL;
5297 struct lsa_String name;
5299 struct dcerpc_binding_handle *b = p->binding_handle;
5301 struct policy_handle user_handle;
5302 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5303 init_lsa_String(&name, user_name);
5305 r.in.domain_handle = domain_handle;
5306 r.in.account_name = &name;
5307 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5308 r.out.user_handle = &user_handle;
5311 torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
5313 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5314 "CreateUser failed");
5316 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5317 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5318 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5321 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5322 nt_errstr(r.out.result));
5327 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5328 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5329 talloc_free(user_ctx);
5332 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5333 "CreateUser failed");
5336 if (!NT_STATUS_IS_OK(r.out.result)) {
5337 talloc_free(user_ctx);
5338 torture_warning(tctx, "CreateUser failed - %s\n", nt_errstr(r.out.result));
5343 if (user_handle_out) {
5344 *user_handle_out = user_handle;
5350 q.in.user_handle = &user_handle;
5354 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5355 "QueryUserInfo failed");
5356 if (!NT_STATUS_IS_OK(q.out.result)) {
5357 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5358 q.in.level, nt_errstr(q.out.result));
5361 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
5362 torture_warning(tctx, "QueryUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5363 info->info16.acct_flags,
5369 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5370 domain_sid, acct_flags, name.string, which_ops,
5371 machine_credentials)) {
5375 if (user_handle_out) {
5376 *user_handle_out = user_handle;
5378 torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
5380 d.in.user_handle = &user_handle;
5381 d.out.user_handle = &user_handle;
5383 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5384 "DeleteUser failed");
5385 if (!NT_STATUS_IS_OK(d.out.result)) {
5386 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5393 talloc_free(user_ctx);
5399 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
5400 struct policy_handle *domain_handle,
5401 struct dom_sid *domain_sid,
5402 enum torture_samr_choice which_ops,
5403 struct cli_credentials *machine_credentials)
5405 struct samr_CreateUser2 r;
5406 struct samr_QueryUserInfo q;
5407 union samr_UserInfo *info;
5408 struct samr_DeleteUser d;
5409 struct policy_handle user_handle;
5411 struct lsa_String name;
5414 struct dcerpc_binding_handle *b = p->binding_handle;
5417 uint32_t acct_flags;
5418 const char *account_name;
5420 } account_types[] = {
5421 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
5422 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5423 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5424 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5425 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5426 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5427 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5428 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5429 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5430 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
5431 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5432 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5433 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5434 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5435 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
5438 for (i = 0; account_types[i].account_name; i++) {
5439 TALLOC_CTX *user_ctx;
5440 uint32_t acct_flags = account_types[i].acct_flags;
5441 uint32_t access_granted;
5442 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5443 init_lsa_String(&name, account_types[i].account_name);
5445 r.in.domain_handle = domain_handle;
5446 r.in.account_name = &name;
5447 r.in.acct_flags = acct_flags;
5448 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5449 r.out.user_handle = &user_handle;
5450 r.out.access_granted = &access_granted;
5453 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
5455 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5456 "CreateUser2 failed");
5458 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5459 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5460 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5463 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5464 nt_errstr(r.out.result));
5470 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5471 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5472 talloc_free(user_ctx);
5476 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5477 "CreateUser2 failed");
5480 if (!NT_STATUS_EQUAL(r.out.result, account_types[i].nt_status)) {
5481 torture_warning(tctx, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5482 nt_errstr(r.out.result), nt_errstr(account_types[i].nt_status));
5486 if (NT_STATUS_IS_OK(r.out.result)) {
5487 q.in.user_handle = &user_handle;
5491 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5492 "QueryUserInfo failed");
5493 if (!NT_STATUS_IS_OK(q.out.result)) {
5494 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5495 q.in.level, nt_errstr(q.out.result));
5498 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
5499 if (acct_flags == ACB_NORMAL) {
5500 expected_flags |= ACB_PW_EXPIRED;
5502 if ((info->info5.acct_flags) != expected_flags) {
5503 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5504 info->info5.acct_flags,
5508 switch (acct_flags) {
5510 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
5511 torture_warning(tctx, "QueryUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5512 DOMAIN_RID_DCS, info->info5.primary_gid);
5517 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
5518 torture_warning(tctx, "QueryUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5519 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
5524 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
5525 torture_warning(tctx, "QueryUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5526 DOMAIN_RID_USERS, info->info5.primary_gid);
5533 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5534 domain_sid, acct_flags, name.string, which_ops,
5535 machine_credentials)) {
5539 if (!policy_handle_empty(&user_handle)) {
5540 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
5542 d.in.user_handle = &user_handle;
5543 d.out.user_handle = &user_handle;
5545 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5546 "DeleteUser failed");
5547 if (!NT_STATUS_IS_OK(d.out.result)) {
5548 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5553 talloc_free(user_ctx);
5559 static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
5560 struct torture_context *tctx,
5561 struct policy_handle *handle)
5563 struct samr_QueryAliasInfo r;
5564 union samr_AliasInfo *info;
5565 uint16_t levels[] = {1, 2, 3};
5569 for (i=0;i<ARRAY_SIZE(levels);i++) {
5570 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
5572 r.in.alias_handle = handle;
5573 r.in.level = levels[i];
5576 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &r),
5577 "QueryAliasInfo failed");
5578 if (!NT_STATUS_IS_OK(r.out.result)) {
5579 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
5580 levels[i], nt_errstr(r.out.result));
5588 static bool test_QueryGroupInfo(struct dcerpc_binding_handle *b,
5589 struct torture_context *tctx,
5590 struct policy_handle *handle)
5592 struct samr_QueryGroupInfo r;
5593 union samr_GroupInfo *info;
5594 uint16_t levels[] = {1, 2, 3, 4, 5};
5598 for (i=0;i<ARRAY_SIZE(levels);i++) {
5599 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5601 r.in.group_handle = handle;
5602 r.in.level = levels[i];
5605 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
5606 "QueryGroupInfo failed");
5607 if (!NT_STATUS_IS_OK(r.out.result)) {
5608 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5609 levels[i], nt_errstr(r.out.result));
5617 static bool test_QueryGroupMember(struct dcerpc_binding_handle *b,
5618 struct torture_context *tctx,
5619 struct policy_handle *handle)
5621 struct samr_QueryGroupMember r;
5622 struct samr_RidAttrArray *rids = NULL;
5625 torture_comment(tctx, "Testing QueryGroupMember\n");
5627 r.in.group_handle = handle;
5630 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &r),
5631 "QueryGroupMember failed");
5632 if (!NT_STATUS_IS_OK(r.out.result)) {
5633 torture_warning(tctx, "QueryGroupMember failed - %s\n", nt_errstr(r.out.result));
5641 static bool test_SetGroupInfo(struct dcerpc_binding_handle *b,
5642 struct torture_context *tctx,
5643 struct policy_handle *handle)
5645 struct samr_QueryGroupInfo r;
5646 union samr_GroupInfo *info;
5647 struct samr_SetGroupInfo s;
5648 uint16_t levels[] = {1, 2, 3, 4};
5649 uint16_t set_ok[] = {0, 1, 1, 1};
5653 for (i=0;i<ARRAY_SIZE(levels);i++) {
5654 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5656 r.in.group_handle = handle;
5657 r.in.level = levels[i];
5660 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
5661 "QueryGroupInfo failed");
5662 if (!NT_STATUS_IS_OK(r.out.result)) {
5663 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5664 levels[i], nt_errstr(r.out.result));
5668 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
5670 s.in.group_handle = handle;
5671 s.in.level = levels[i];
5672 s.in.info = *r.out.info;
5675 /* disabled this, as it changes the name only from the point of view of samr,
5676 but leaves the name from the point of view of w2k3 internals (and ldap). This means
5677 the name is still reserved, so creating the old name fails, but deleting by the old name
5679 if (s.in.level == 2) {
5680 init_lsa_String(&s.in.info->string, "NewName");
5684 if (s.in.level == 4) {
5685 init_lsa_String(&s.in.info->description, "test description");
5688 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetGroupInfo_r(b, tctx, &s),
5689 "SetGroupInfo failed");
5691 if (!NT_STATUS_IS_OK(s.out.result)) {
5692 torture_warning(tctx, "SetGroupInfo level %u failed - %s\n",
5693 r.in.level, nt_errstr(s.out.result));
5698 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
5699 torture_warning(tctx, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5700 r.in.level, nt_errstr(s.out.result));
5710 static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
5711 struct torture_context *tctx,
5712 struct policy_handle *handle)
5714 struct samr_QueryUserInfo r;
5715 union samr_UserInfo *info;
5716 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5717 11, 12, 13, 14, 16, 17, 20, 21};
5721 for (i=0;i<ARRAY_SIZE(levels);i++) {
5722 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
5724 r.in.user_handle = handle;
5725 r.in.level = levels[i];
5728 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
5729 "QueryUserInfo failed");
5730 if (!NT_STATUS_IS_OK(r.out.result)) {
5731 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5732 levels[i], nt_errstr(r.out.result));
5740 static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
5741 struct torture_context *tctx,
5742 struct policy_handle *handle)
5744 struct samr_QueryUserInfo2 r;
5745 union samr_UserInfo *info;
5746 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5747 11, 12, 13, 14, 16, 17, 20, 21};
5751 for (i=0;i<ARRAY_SIZE(levels);i++) {
5752 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
5754 r.in.user_handle = handle;
5755 r.in.level = levels[i];
5758 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r),
5759 "QueryUserInfo2 failed");
5760 if (!NT_STATUS_IS_OK(r.out.result)) {
5761 torture_warning(tctx, "QueryUserInfo2 level %u failed - %s\n",
5762 levels[i], nt_errstr(r.out.result));
5770 static bool test_OpenUser(struct dcerpc_binding_handle *b,
5771 struct torture_context *tctx,
5772 struct policy_handle *handle, uint32_t rid)
5774 struct samr_OpenUser r;
5775 struct policy_handle user_handle;
5778 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5780 r.in.domain_handle = handle;
5781 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5783 r.out.user_handle = &user_handle;
5785 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5787 if (!NT_STATUS_IS_OK(r.out.result)) {
5788 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5792 if (!test_QuerySecurity(b, tctx, &user_handle)) {
5796 if (!test_QueryUserInfo(b, tctx, &user_handle)) {
5800 if (!test_QueryUserInfo2(b, tctx, &user_handle)) {
5804 if (!test_GetUserPwInfo(b, tctx, &user_handle)) {
5808 if (!test_GetGroupsForUser(b, tctx, &user_handle)) {
5812 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
5819 static bool test_OpenGroup(struct dcerpc_binding_handle *b,
5820 struct torture_context *tctx,
5821 struct policy_handle *handle, uint32_t rid)
5823 struct samr_OpenGroup r;
5824 struct policy_handle group_handle;
5827 torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
5829 r.in.domain_handle = handle;
5830 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5832 r.out.group_handle = &group_handle;
5834 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
5835 "OpenGroup failed");
5836 if (!NT_STATUS_IS_OK(r.out.result)) {
5837 torture_warning(tctx, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5841 if (!torture_setting_bool(tctx, "samba3", false)) {
5842 if (!test_QuerySecurity(b, tctx, &group_handle)) {
5847 if (!test_QueryGroupInfo(b, tctx, &group_handle)) {
5851 if (!test_QueryGroupMember(b, tctx, &group_handle)) {
5855 if (!test_samr_handle_Close(b, tctx, &group_handle)) {
5862 static bool test_OpenAlias(struct dcerpc_binding_handle *b,
5863 struct torture_context *tctx,
5864 struct policy_handle *handle, uint32_t rid)
5866 struct samr_OpenAlias r;
5867 struct policy_handle alias_handle;
5870 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
5872 r.in.domain_handle = handle;
5873 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5875 r.out.alias_handle = &alias_handle;
5877 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5878 "OpenAlias failed");
5879 if (!NT_STATUS_IS_OK(r.out.result)) {
5880 torture_warning(tctx, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5884 if (!torture_setting_bool(tctx, "samba3", false)) {
5885 if (!test_QuerySecurity(b, tctx, &alias_handle)) {
5890 if (!test_QueryAliasInfo(b, tctx, &alias_handle)) {
5894 if (!test_GetMembersInAlias(b, tctx, &alias_handle)) {
5898 if (!test_samr_handle_Close(b, tctx, &alias_handle)) {
5905 static bool check_mask(struct dcerpc_binding_handle *b,
5906 struct torture_context *tctx,
5907 struct policy_handle *handle, uint32_t rid,
5908 uint32_t acct_flag_mask)
5910 struct samr_OpenUser r;
5911 struct samr_QueryUserInfo q;
5912 union samr_UserInfo *info;
5913 struct policy_handle user_handle;
5916 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5918 r.in.domain_handle = handle;
5919 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5921 r.out.user_handle = &user_handle;
5923 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5925 if (!NT_STATUS_IS_OK(r.out.result)) {
5926 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5930 q.in.user_handle = &user_handle;
5934 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5935 "QueryUserInfo failed");
5936 if (!NT_STATUS_IS_OK(q.out.result)) {
5937 torture_warning(tctx, "QueryUserInfo level 16 failed - %s\n",
5938 nt_errstr(q.out.result));
5941 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
5942 torture_warning(tctx, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
5943 acct_flag_mask, info->info16.acct_flags, rid);
5948 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
5955 static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle *b,
5956 struct torture_context *tctx,
5957 struct policy_handle *handle)
5959 struct samr_EnumDomainUsers r;
5960 uint32_t mask, resume_handle=0;
5963 struct samr_LookupNames n;
5964 struct samr_LookupRids lr ;
5965 struct lsa_Strings names;
5966 struct samr_Ids rids, types;
5967 struct samr_SamArray *sam = NULL;
5968 uint32_t num_entries = 0;
5970 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
5971 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
5972 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
5975 torture_comment(tctx, "Testing EnumDomainUsers\n");
5977 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
5978 r.in.domain_handle = handle;
5979 r.in.resume_handle = &resume_handle;
5980 r.in.acct_flags = mask = masks[mask_idx];
5981 r.in.max_size = (uint32_t)-1;
5982 r.out.resume_handle = &resume_handle;
5983 r.out.num_entries = &num_entries;
5986 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
5987 "EnumDomainUsers failed");
5988 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
5989 !NT_STATUS_IS_OK(r.out.result)) {
5990 torture_warning(tctx, "EnumDomainUsers failed - %s\n", nt_errstr(r.out.result));
5994 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
5996 if (sam->count == 0) {
6000 for (i=0;i<sam->count;i++) {
6002 if (!check_mask(b, tctx, handle, sam->entries[i].idx, mask)) {
6005 } else if (!test_OpenUser(b, tctx, handle, sam->entries[i].idx)) {
6011 torture_comment(tctx, "Testing LookupNames\n");
6012 n.in.domain_handle = handle;
6013 n.in.num_names = sam->count;
6014 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
6016 n.out.types = &types;
6017 for (i=0;i<sam->count;i++) {
6018 n.in.names[i].string = sam->entries[i].name.string;
6020 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
6021 "LookupNames failed");
6022 if (!NT_STATUS_IS_OK(n.out.result)) {
6023 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(n.out.result));
6028 torture_comment(tctx, "Testing LookupRids\n");
6029 lr.in.domain_handle = handle;
6030 lr.in.num_rids = sam->count;
6031 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
6032 lr.out.names = &names;
6033 lr.out.types = &types;
6034 for (i=0;i<sam->count;i++) {
6035 lr.in.rids[i] = sam->entries[i].idx;
6037 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupRids_r(b, tctx, &lr),
6038 "LookupRids failed");
6039 torture_assert_ntstatus_ok(tctx, lr.out.result, "LookupRids");
6045 try blasting the server with a bunch of sync requests
6047 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
6048 struct policy_handle *handle)
6050 struct samr_EnumDomainUsers r;
6051 uint32_t resume_handle=0;
6053 #define ASYNC_COUNT 100
6054 struct tevent_req *req[ASYNC_COUNT];
6056 if (!torture_setting_bool(tctx, "dangerous", false)) {
6057 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
6060 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
6062 r.in.domain_handle = handle;
6063 r.in.resume_handle = &resume_handle;
6064 r.in.acct_flags = 0;
6065 r.in.max_size = (uint32_t)-1;
6066 r.out.resume_handle = &resume_handle;
6068 for (i=0;i<ASYNC_COUNT;i++) {
6069 req[i] = dcerpc_samr_EnumDomainUsers_r_send(tctx, tctx->ev, p->binding_handle, &r);
6072 for (i=0;i<ASYNC_COUNT;i++) {
6073 tevent_req_poll(req[i], tctx->ev);
6074 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r_recv(req[i], tctx),
6075 talloc_asprintf(tctx, "EnumDomainUsers[%d] failed - %s\n",
6076 i, nt_errstr(r.out.result)));
6079 torture_comment(tctx, "%d async requests OK\n", i);
6084 static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle *b,
6085 struct torture_context *tctx,
6086 struct policy_handle *handle)
6088 struct samr_EnumDomainGroups r;
6089 uint32_t resume_handle=0;
6090 struct samr_SamArray *sam = NULL;
6091 uint32_t num_entries = 0;
6094 bool universal_group_found = false;
6096 torture_comment(tctx, "Testing EnumDomainGroups\n");
6098 r.in.domain_handle = handle;
6099 r.in.resume_handle = &resume_handle;
6100 r.in.max_size = (uint32_t)-1;
6101 r.out.resume_handle = &resume_handle;
6102 r.out.num_entries = &num_entries;
6105 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
6106 "EnumDomainGroups failed");
6107 if (!NT_STATUS_IS_OK(r.out.result)) {
6108 torture_warning(tctx, "EnumDomainGroups failed - %s\n", nt_errstr(r.out.result));
6116 for (i=0;i<sam->count;i++) {
6117 if (!test_OpenGroup(b, tctx, handle, sam->entries[i].idx)) {
6120 if ((ret == true) && (strcasecmp(sam->entries[i].name.string,
6121 "Enterprise Admins") == 0)) {
6122 universal_group_found = true;
6126 /* when we are running this on s4 we should get back at least the
6127 * "Enterprise Admins" universal group. If we don't get a group entry
6128 * at all we probably are performing the test on the builtin domain.
6129 * So ignore this case. */
6130 if (torture_setting_bool(tctx, "samba4", false)) {
6131 if ((sam->count > 0) && (!universal_group_found)) {
6139 static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle *b,
6140 struct torture_context *tctx,
6141 struct policy_handle *handle)
6143 struct samr_EnumDomainAliases r;
6144 uint32_t resume_handle=0;
6145 struct samr_SamArray *sam = NULL;
6146 uint32_t num_entries = 0;
6150 torture_comment(tctx, "Testing EnumDomainAliases\n");
6152 r.in.domain_handle = handle;
6153 r.in.resume_handle = &resume_handle;
6154 r.in.max_size = (uint32_t)-1;
6156 r.out.num_entries = &num_entries;
6157 r.out.resume_handle = &resume_handle;
6159 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
6160 "EnumDomainAliases failed");
6161 if (!NT_STATUS_IS_OK(r.out.result)) {
6162 torture_warning(tctx, "EnumDomainAliases failed - %s\n", nt_errstr(r.out.result));
6170 for (i=0;i<sam->count;i++) {
6171 if (!test_OpenAlias(b, tctx, handle, sam->entries[i].idx)) {
6179 static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle *b,
6180 struct torture_context *tctx,
6181 struct policy_handle *handle)
6183 struct samr_GetDisplayEnumerationIndex r;
6185 uint16_t levels[] = {1, 2, 3, 4, 5};
6186 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6187 struct lsa_String name;
6191 for (i=0;i<ARRAY_SIZE(levels);i++) {
6192 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
6194 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6196 r.in.domain_handle = handle;
6197 r.in.level = levels[i];
6201 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6202 "GetDisplayEnumerationIndex failed");
6205 !NT_STATUS_IS_OK(r.out.result) &&
6206 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6207 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6208 levels[i], nt_errstr(r.out.result));
6212 init_lsa_String(&name, "zzzzzzzz");
6214 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6215 "GetDisplayEnumerationIndex failed");
6217 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6218 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6219 levels[i], nt_errstr(r.out.result));
6227 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle *b,
6228 struct torture_context *tctx,
6229 struct policy_handle *handle)
6231 struct samr_GetDisplayEnumerationIndex2 r;
6233 uint16_t levels[] = {1, 2, 3, 4, 5};
6234 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6235 struct lsa_String name;
6239 for (i=0;i<ARRAY_SIZE(levels);i++) {
6240 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
6242 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6244 r.in.domain_handle = handle;
6245 r.in.level = levels[i];
6249 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6250 "GetDisplayEnumerationIndex2 failed");
6252 !NT_STATUS_IS_OK(r.out.result) &&
6253 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6254 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6255 levels[i], nt_errstr(r.out.result));
6259 init_lsa_String(&name, "zzzzzzzz");
6261 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6262 "GetDisplayEnumerationIndex2 failed");
6263 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6264 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6265 levels[i], nt_errstr(r.out.result));
6273 #define STRING_EQUAL_QUERY(s1, s2, user) \
6274 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6275 /* odd, but valid */ \
6276 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6277 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
6278 #s1, user.string, s1.string, s2.string, __location__); \
6281 #define INT_EQUAL_QUERY(s1, s2, user) \
6283 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6284 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6288 static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle *b,
6289 struct torture_context *tctx,
6290 struct samr_QueryDisplayInfo *querydisplayinfo,
6291 bool *seen_testuser)
6293 struct samr_OpenUser r;
6294 struct samr_QueryUserInfo q;
6295 union samr_UserInfo *info;
6296 struct policy_handle user_handle;
6298 r.in.domain_handle = querydisplayinfo->in.domain_handle;
6299 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6300 for (i = 0; ; i++) {
6301 switch (querydisplayinfo->in.level) {
6303 if (i >= querydisplayinfo->out.info->info1.count) {
6306 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
6309 if (i >= querydisplayinfo->out.info->info2.count) {
6312 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
6318 /* Not interested in validating just the account name */
6322 r.out.user_handle = &user_handle;
6324 switch (querydisplayinfo->in.level) {
6327 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6329 if (!NT_STATUS_IS_OK(r.out.result)) {
6330 torture_warning(tctx, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6335 q.in.user_handle = &user_handle;
6338 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6339 "QueryUserInfo failed");
6340 if (!NT_STATUS_IS_OK(r.out.result)) {
6341 torture_warning(tctx, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6345 switch (querydisplayinfo->in.level) {
6347 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
6348 *seen_testuser = true;
6350 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
6351 info->info21.full_name, info->info21.account_name);
6352 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
6353 info->info21.account_name, info->info21.account_name);
6354 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
6355 info->info21.description, info->info21.account_name);
6356 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
6357 info->info21.rid, info->info21.account_name);
6358 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
6359 info->info21.acct_flags, info->info21.account_name);
6363 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
6364 info->info21.account_name, info->info21.account_name);
6365 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
6366 info->info21.description, info->info21.account_name);
6367 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
6368 info->info21.rid, info->info21.account_name);
6369 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
6370 info->info21.acct_flags, info->info21.account_name);
6372 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
6373 torture_warning(tctx, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6374 info->info21.account_name.string);
6377 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
6378 torture_warning(tctx, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6379 info->info21.account_name.string,
6380 querydisplayinfo->out.info->info2.entries[i].acct_flags,
6381 info->info21.acct_flags);
6388 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6395 static bool test_QueryDisplayInfo(struct dcerpc_binding_handle *b,
6396 struct torture_context *tctx,
6397 struct policy_handle *handle)
6399 struct samr_QueryDisplayInfo r;
6400 struct samr_QueryDomainInfo dom_info;
6401 union samr_DomainInfo *info = NULL;
6403 uint16_t levels[] = {1, 2, 3, 4, 5};
6405 bool seen_testuser = false;
6406 uint32_t total_size;
6407 uint32_t returned_size;
6408 union samr_DispInfo disp_info;
6411 for (i=0;i<ARRAY_SIZE(levels);i++) {
6412 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
6415 r.out.result = STATUS_MORE_ENTRIES;
6416 while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
6417 r.in.domain_handle = handle;
6418 r.in.level = levels[i];
6419 r.in.max_entries = 2;
6420 r.in.buf_size = (uint32_t)-1;
6421 r.out.total_size = &total_size;
6422 r.out.returned_size = &returned_size;
6423 r.out.info = &disp_info;
6425 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6426 "QueryDisplayInfo failed");
6427 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(r.out.result)) {
6428 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6429 levels[i], nt_errstr(r.out.result));
6432 switch (r.in.level) {
6434 if (!test_each_DisplayInfo_user(b, tctx, &r, &seen_testuser)) {
6437 r.in.start_idx += r.out.info->info1.count;
6440 if (!test_each_DisplayInfo_user(b, tctx, &r, NULL)) {
6443 r.in.start_idx += r.out.info->info2.count;
6446 r.in.start_idx += r.out.info->info3.count;
6449 r.in.start_idx += r.out.info->info4.count;
6452 r.in.start_idx += r.out.info->info5.count;
6456 dom_info.in.domain_handle = handle;
6457 dom_info.in.level = 2;
6458 dom_info.out.info = &info;
6460 /* Check number of users returned is correct */
6461 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &dom_info),
6462 "QueryDomainInfo failed");
6463 if (!NT_STATUS_IS_OK(dom_info.out.result)) {
6464 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6465 r.in.level, nt_errstr(dom_info.out.result));
6469 switch (r.in.level) {
6472 if (info->general.num_users < r.in.start_idx) {
6473 /* On AD deployments this numbers don't match
6474 * since QueryDisplayInfo returns universal and
6475 * global groups, QueryDomainInfo only global
6477 if (torture_setting_bool(tctx, "samba3", false)) {
6478 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6479 r.in.start_idx, info->general.num_groups,
6480 info->general.domain_name.string);
6484 if (!seen_testuser) {
6485 struct policy_handle user_handle;
6486 if (NT_STATUS_IS_OK(test_OpenUser_byname(b, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
6487 torture_warning(tctx, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
6488 info->general.domain_name.string);
6490 test_samr_handle_Close(b, tctx, &user_handle);
6496 if (info->general.num_groups != r.in.start_idx) {
6497 /* On AD deployments this numbers don't match
6498 * since QueryDisplayInfo returns universal and
6499 * global groups, QueryDomainInfo only global
6501 if (torture_setting_bool(tctx, "samba3", false)) {
6502 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6503 r.in.start_idx, info->general.num_groups,
6504 info->general.domain_name.string);
6517 static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle *b,
6518 struct torture_context *tctx,
6519 struct policy_handle *handle)
6521 struct samr_QueryDisplayInfo2 r;
6523 uint16_t levels[] = {1, 2, 3, 4, 5};
6525 uint32_t total_size;
6526 uint32_t returned_size;
6527 union samr_DispInfo info;
6529 for (i=0;i<ARRAY_SIZE(levels);i++) {
6530 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
6532 r.in.domain_handle = handle;
6533 r.in.level = levels[i];
6535 r.in.max_entries = 1000;
6536 r.in.buf_size = (uint32_t)-1;
6537 r.out.total_size = &total_size;
6538 r.out.returned_size = &returned_size;
6541 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo2_r(b, tctx, &r),
6542 "QueryDisplayInfo2 failed");
6543 if (!NT_STATUS_IS_OK(r.out.result)) {
6544 torture_warning(tctx, "QueryDisplayInfo2 level %u failed - %s\n",
6545 levels[i], nt_errstr(r.out.result));
6553 static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle *b,
6554 struct torture_context *tctx,
6555 struct policy_handle *handle)
6557 struct samr_QueryDisplayInfo3 r;
6559 uint16_t levels[] = {1, 2, 3, 4, 5};
6561 uint32_t total_size;
6562 uint32_t returned_size;
6563 union samr_DispInfo info;
6565 for (i=0;i<ARRAY_SIZE(levels);i++) {
6566 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
6568 r.in.domain_handle = handle;
6569 r.in.level = levels[i];
6571 r.in.max_entries = 1000;
6572 r.in.buf_size = (uint32_t)-1;
6573 r.out.total_size = &total_size;
6574 r.out.returned_size = &returned_size;
6577 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo3_r(b, tctx, &r),
6578 "QueryDisplayInfo3 failed");
6579 if (!NT_STATUS_IS_OK(r.out.result)) {
6580 torture_warning(tctx, "QueryDisplayInfo3 level %u failed - %s\n",
6581 levels[i], nt_errstr(r.out.result));
6590 static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle *b,
6591 struct torture_context *tctx,
6592 struct policy_handle *handle)
6594 struct samr_QueryDisplayInfo r;
6596 uint32_t total_size;
6597 uint32_t returned_size;
6598 union samr_DispInfo info;
6600 torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
6602 r.in.domain_handle = handle;
6605 r.in.max_entries = 1;
6606 r.in.buf_size = (uint32_t)-1;
6607 r.out.total_size = &total_size;
6608 r.out.returned_size = &returned_size;
6612 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6613 "QueryDisplayInfo failed");
6614 if (NT_STATUS_IS_OK(r.out.result) && *r.out.returned_size != 0) {
6615 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
6616 torture_warning(tctx, "expected idx %d but got %d\n",
6618 r.out.info->info1.entries[0].idx);
6622 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
6623 !NT_STATUS_IS_OK(r.out.result)) {
6624 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6625 r.in.level, nt_errstr(r.out.result));
6630 } while ((NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) ||
6631 NT_STATUS_IS_OK(r.out.result)) &&
6632 *r.out.returned_size != 0);
6637 static bool test_QueryDomainInfo(struct dcerpc_pipe *p,
6638 struct torture_context *tctx,
6639 struct policy_handle *handle)
6641 struct samr_QueryDomainInfo r;
6642 union samr_DomainInfo *info = NULL;
6643 struct samr_SetDomainInfo s;
6644 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6645 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
6648 struct dcerpc_binding_handle *b = p->binding_handle;
6649 const char *domain_comment = talloc_asprintf(tctx,
6650 "Tortured by Samba4 RPC-SAMR: %s",
6651 timestring(tctx, time(NULL)));
6653 s.in.domain_handle = handle;
6655 s.in.info = talloc(tctx, union samr_DomainInfo);
6657 s.in.info->oem.oem_information.string = domain_comment;
6658 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
6659 "SetDomainInfo failed");
6660 if (!NT_STATUS_IS_OK(s.out.result)) {
6661 torture_warning(tctx, "SetDomainInfo level %u (set comment) failed - %s\n",
6662 s.in.level, nt_errstr(s.out.result));
6666 for (i=0;i<ARRAY_SIZE(levels);i++) {
6667 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
6669 r.in.domain_handle = handle;
6670 r.in.level = levels[i];
6673 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
6674 "QueryDomainInfo failed");
6675 if (!NT_STATUS_IS_OK(r.out.result)) {
6676 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6677 r.in.level, nt_errstr(r.out.result));
6682 switch (levels[i]) {
6684 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
6685 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6686 levels[i], info->general.oem_information.string, domain_comment);
6687 if (!torture_setting_bool(tctx, "samba3", false)) {
6691 if (!info->general.primary.string) {
6692 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6695 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
6696 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
6697 if (torture_setting_bool(tctx, "samba3", false)) {
6698 torture_warning(tctx, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
6699 levels[i], info->general.primary.string, dcerpc_server_name(p));
6705 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
6706 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6707 levels[i], info->oem.oem_information.string, domain_comment);
6708 if (!torture_setting_bool(tctx, "samba3", false)) {
6714 if (!info->info6.primary.string) {
6715 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6721 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
6722 torture_warning(tctx, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
6723 levels[i], info->general2.general.oem_information.string, domain_comment);
6724 if (!torture_setting_bool(tctx, "samba3", false)) {
6731 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
6733 s.in.domain_handle = handle;
6734 s.in.level = levels[i];
6737 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
6738 "SetDomainInfo failed");
6740 if (!NT_STATUS_IS_OK(s.out.result)) {
6741 torture_warning(tctx, "SetDomainInfo level %u failed - %s\n",
6742 r.in.level, nt_errstr(s.out.result));
6747 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
6748 torture_warning(tctx, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6749 r.in.level, nt_errstr(s.out.result));
6755 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
6756 "QueryDomainInfo failed");
6757 if (!NT_STATUS_IS_OK(r.out.result)) {
6758 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6759 r.in.level, nt_errstr(r.out.result));
6769 static bool test_QueryDomainInfo2(struct dcerpc_binding_handle *b,
6770 struct torture_context *tctx,
6771 struct policy_handle *handle)
6773 struct samr_QueryDomainInfo2 r;
6774 union samr_DomainInfo *info = NULL;
6775 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6779 for (i=0;i<ARRAY_SIZE(levels);i++) {
6780 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
6782 r.in.domain_handle = handle;
6783 r.in.level = levels[i];
6786 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
6787 "QueryDomainInfo2 failed");
6788 if (!NT_STATUS_IS_OK(r.out.result)) {
6789 torture_warning(tctx, "QueryDomainInfo2 level %u failed - %s\n",
6790 r.in.level, nt_errstr(r.out.result));
6799 /* Test whether querydispinfo level 5 and enumdomgroups return the same
6800 set of group names. */
6801 static bool test_GroupList(struct dcerpc_binding_handle *b,
6802 struct torture_context *tctx,
6803 struct policy_handle *handle)
6805 struct samr_EnumDomainGroups q1;
6806 struct samr_QueryDisplayInfo q2;
6808 uint32_t resume_handle=0;
6809 struct samr_SamArray *sam = NULL;
6810 uint32_t num_entries = 0;
6813 uint32_t total_size;
6814 uint32_t returned_size;
6815 union samr_DispInfo info;
6818 const char **names = NULL;
6820 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
6822 q1.in.domain_handle = handle;
6823 q1.in.resume_handle = &resume_handle;
6825 q1.out.resume_handle = &resume_handle;
6826 q1.out.num_entries = &num_entries;
6829 status = STATUS_MORE_ENTRIES;
6830 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6831 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &q1),
6832 "EnumDomainGroups failed");
6833 status = q1.out.result;
6835 if (!NT_STATUS_IS_OK(status) &&
6836 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6839 for (i=0; i<*q1.out.num_entries; i++) {
6840 add_string_to_array(tctx,
6841 sam->entries[i].name.string,
6842 &names, &num_names);
6846 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
6848 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
6850 q2.in.domain_handle = handle;
6852 q2.in.start_idx = 0;
6853 q2.in.max_entries = 5;
6854 q2.in.buf_size = (uint32_t)-1;
6855 q2.out.total_size = &total_size;
6856 q2.out.returned_size = &returned_size;
6857 q2.out.info = &info;
6859 status = STATUS_MORE_ENTRIES;
6860 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6861 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &q2),
6862 "QueryDisplayInfo failed");
6863 status = q2.out.result;
6864 if (!NT_STATUS_IS_OK(status) &&
6865 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6868 for (i=0; i<q2.out.info->info5.count; i++) {
6870 const char *name = q2.out.info->info5.entries[i].account_name.string;
6872 for (j=0; j<num_names; j++) {
6873 if (names[j] == NULL)
6875 if (strequal(names[j], name)) {
6883 torture_warning(tctx, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
6888 q2.in.start_idx += q2.out.info->info5.count;
6891 if (!NT_STATUS_IS_OK(status)) {
6892 torture_warning(tctx, "QueryDisplayInfo level 5 failed - %s\n",
6897 for (i=0; i<num_names; i++) {
6898 if (names[i] != NULL) {
6899 torture_warning(tctx, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
6908 static bool test_DeleteDomainGroup(struct dcerpc_binding_handle *b,
6909 struct torture_context *tctx,
6910 struct policy_handle *group_handle)
6912 struct samr_DeleteDomainGroup d;
6914 torture_comment(tctx, "Testing DeleteDomainGroup\n");
6916 d.in.group_handle = group_handle;
6917 d.out.group_handle = group_handle;
6919 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
6920 "DeleteDomainGroup failed");
6921 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteDomainGroup");
6926 static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle *b,
6927 struct torture_context *tctx,
6928 struct policy_handle *domain_handle)
6930 struct samr_TestPrivateFunctionsDomain r;
6933 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
6935 r.in.domain_handle = domain_handle;
6937 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsDomain_r(b, tctx, &r),
6938 "TestPrivateFunctionsDomain failed");
6939 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
6944 static bool test_RidToSid(struct dcerpc_binding_handle *b,
6945 struct torture_context *tctx,
6946 struct dom_sid *domain_sid,
6947 struct policy_handle *domain_handle)
6949 struct samr_RidToSid r;
6951 struct dom_sid *calc_sid, *out_sid;
6952 int rids[] = { 0, 42, 512, 10200 };
6955 for (i=0;i<ARRAY_SIZE(rids);i++) {
6956 torture_comment(tctx, "Testing RidToSid\n");
6958 calc_sid = dom_sid_dup(tctx, domain_sid);
6959 r.in.domain_handle = domain_handle;
6961 r.out.sid = &out_sid;
6963 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RidToSid_r(b, tctx, &r),
6965 if (!NT_STATUS_IS_OK(r.out.result)) {
6966 torture_warning(tctx, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(r.out.result));
6969 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
6971 if (!dom_sid_equal(calc_sid, out_sid)) {
6972 torture_warning(tctx, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
6973 dom_sid_string(tctx, out_sid),
6974 dom_sid_string(tctx, calc_sid));
6983 static bool test_GetBootKeyInformation(struct dcerpc_binding_handle *b,
6984 struct torture_context *tctx,
6985 struct policy_handle *domain_handle)
6987 struct samr_GetBootKeyInformation r;
6989 uint32_t unknown = 0;
6992 torture_comment(tctx, "Testing GetBootKeyInformation\n");
6994 r.in.domain_handle = domain_handle;
6995 r.out.unknown = &unknown;
6997 status = dcerpc_samr_GetBootKeyInformation_r(b, tctx, &r);
6998 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(r.out.result)) {
6999 status = r.out.result;
7001 if (!NT_STATUS_IS_OK(status)) {
7002 /* w2k3 seems to fail this sometimes and pass it sometimes */
7003 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
7009 static bool test_AddGroupMember(struct dcerpc_binding_handle *b,
7010 struct torture_context *tctx,
7011 struct policy_handle *domain_handle,
7012 struct policy_handle *group_handle)
7015 struct samr_AddGroupMember r;
7016 struct samr_DeleteGroupMember d;
7017 struct samr_QueryGroupMember q;
7018 struct samr_RidAttrArray *rids = NULL;
7019 struct samr_SetMemberAttributesOfGroup s;
7021 bool found_member = false;
7024 status = test_LookupName(b, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
7025 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
7027 r.in.group_handle = group_handle;
7029 r.in.flags = 0; /* ??? */
7031 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
7033 d.in.group_handle = group_handle;
7036 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7037 "DeleteGroupMember failed");
7038 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, d.out.result, "DeleteGroupMember");
7040 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7041 "AddGroupMember failed");
7042 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7044 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7045 "AddGroupMember failed");
7046 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, r.out.result, "AddGroupMember");
7048 if (torture_setting_bool(tctx, "samba4", false) ||
7049 torture_setting_bool(tctx, "samba3", false)) {
7050 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
7052 /* this one is quite strange. I am using random inputs in the
7053 hope of triggering an error that might give us a clue */
7055 s.in.group_handle = group_handle;
7056 s.in.unknown1 = random();
7057 s.in.unknown2 = random();
7059 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetMemberAttributesOfGroup_r(b, tctx, &s),
7060 "SetMemberAttributesOfGroup failed");
7061 torture_assert_ntstatus_ok(tctx, s.out.result, "SetMemberAttributesOfGroup");
7064 q.in.group_handle = group_handle;
7067 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7068 "QueryGroupMember failed");
7069 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7070 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7072 for (i=0; i < rids->count; i++) {
7073 if (rids->rids[i] == rid) {
7074 found_member = true;
7078 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
7080 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7081 "DeleteGroupMember failed");
7082 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteGroupMember");
7085 found_member = false;
7087 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7088 "QueryGroupMember failed");
7089 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7090 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7092 for (i=0; i < rids->count; i++) {
7093 if (rids->rids[i] == rid) {
7094 found_member = true;
7098 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
7100 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7101 "AddGroupMember failed");
7102 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7108 static bool test_CreateDomainGroup(struct dcerpc_binding_handle *b,
7109 struct torture_context *tctx,
7110 struct policy_handle *domain_handle,
7111 const char *group_name,
7112 struct policy_handle *group_handle,
7113 struct dom_sid *domain_sid,
7116 struct samr_CreateDomainGroup r;
7118 struct lsa_String name;
7121 init_lsa_String(&name, group_name);
7123 r.in.domain_handle = domain_handle;
7125 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7126 r.out.group_handle = group_handle;
7129 torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
7131 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7132 "CreateDomainGroup failed");
7134 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
7135 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
7136 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
7139 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
7140 nt_errstr(r.out.result));
7145 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_GROUP_EXISTS)) {
7146 if (!test_DeleteGroup_byname(b, tctx, domain_handle, r.in.name->string)) {
7147 torture_warning(tctx, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
7148 nt_errstr(r.out.result));
7151 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7152 "CreateDomainGroup failed");
7154 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
7155 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.name->string)) {
7157 torture_warning(tctx, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
7158 nt_errstr(r.out.result));
7161 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7162 "CreateDomainGroup failed");
7164 torture_assert_ntstatus_ok(tctx, r.out.result, "CreateDomainGroup");
7170 if (!test_AddGroupMember(b, tctx, domain_handle, group_handle)) {
7171 torture_warning(tctx, "CreateDomainGroup failed - %s\n", nt_errstr(r.out.result));
7175 if (!test_SetGroupInfo(b, tctx, group_handle)) {
7184 its not totally clear what this does. It seems to accept any sid you like.
7186 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle *b,
7187 struct torture_context *tctx,
7188 struct policy_handle *domain_handle)
7190 struct samr_RemoveMemberFromForeignDomain r;
7192 r.in.domain_handle = domain_handle;
7193 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
7195 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMemberFromForeignDomain_r(b, tctx, &r),
7196 "RemoveMemberFromForeignDomain failed");
7197 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMemberFromForeignDomain");
7202 static bool test_EnumDomainUsers(struct dcerpc_binding_handle *b,
7203 struct torture_context *tctx,
7204 struct policy_handle *domain_handle,
7205 uint32_t *total_num_entries_p)
7208 struct samr_EnumDomainUsers r;
7209 uint32_t resume_handle = 0;
7210 uint32_t num_entries = 0;
7211 uint32_t total_num_entries = 0;
7212 struct samr_SamArray *sam;
7214 r.in.domain_handle = domain_handle;
7215 r.in.acct_flags = 0;
7216 r.in.max_size = (uint32_t)-1;
7217 r.in.resume_handle = &resume_handle;
7220 r.out.num_entries = &num_entries;
7221 r.out.resume_handle = &resume_handle;
7223 torture_comment(tctx, "Testing EnumDomainUsers\n");
7226 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
7227 "EnumDomainUsers failed");
7228 if (NT_STATUS_IS_ERR(r.out.result)) {
7229 torture_assert_ntstatus_ok(tctx, r.out.result,
7230 "failed to enumerate users");
7232 status = r.out.result;
7234 total_num_entries += num_entries;
7235 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7237 if (total_num_entries_p) {
7238 *total_num_entries_p = total_num_entries;
7244 static bool test_EnumDomainGroups(struct dcerpc_binding_handle *b,
7245 struct torture_context *tctx,
7246 struct policy_handle *domain_handle,
7247 uint32_t *total_num_entries_p)
7250 struct samr_EnumDomainGroups r;
7251 uint32_t resume_handle = 0;
7252 uint32_t num_entries = 0;
7253 uint32_t total_num_entries = 0;
7254 struct samr_SamArray *sam;
7256 r.in.domain_handle = domain_handle;
7257 r.in.max_size = (uint32_t)-1;
7258 r.in.resume_handle = &resume_handle;
7261 r.out.num_entries = &num_entries;
7262 r.out.resume_handle = &resume_handle;
7264 torture_comment(tctx, "Testing EnumDomainGroups\n");
7267 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
7268 "EnumDomainGroups failed");
7269 if (NT_STATUS_IS_ERR(r.out.result)) {
7270 torture_assert_ntstatus_ok(tctx, r.out.result,
7271 "failed to enumerate groups");
7273 status = r.out.result;
7275 total_num_entries += num_entries;
7276 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7278 if (total_num_entries_p) {
7279 *total_num_entries_p = total_num_entries;
7285 static bool test_EnumDomainAliases(struct dcerpc_binding_handle *b,
7286 struct torture_context *tctx,
7287 struct policy_handle *domain_handle,
7288 uint32_t *total_num_entries_p)
7291 struct samr_EnumDomainAliases r;
7292 uint32_t resume_handle = 0;
7293 uint32_t num_entries = 0;
7294 uint32_t total_num_entries = 0;
7295 struct samr_SamArray *sam;
7297 r.in.domain_handle = domain_handle;
7298 r.in.max_size = (uint32_t)-1;
7299 r.in.resume_handle = &resume_handle;
7302 r.out.num_entries = &num_entries;
7303 r.out.resume_handle = &resume_handle;
7305 torture_comment(tctx, "Testing EnumDomainAliases\n");
7308 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
7309 "EnumDomainAliases failed");
7310 if (NT_STATUS_IS_ERR(r.out.result)) {
7311 torture_assert_ntstatus_ok(tctx, r.out.result,
7312 "failed to enumerate aliases");
7314 status = r.out.result;
7316 total_num_entries += num_entries;
7317 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7319 if (total_num_entries_p) {
7320 *total_num_entries_p = total_num_entries;
7326 static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle *b,
7327 struct torture_context *tctx,
7328 struct policy_handle *handle,
7330 uint32_t *total_num_entries_p)
7333 struct samr_QueryDisplayInfo r;
7334 uint32_t total_num_entries = 0;
7336 r.in.domain_handle = handle;
7339 r.in.max_entries = (uint32_t)-1;
7340 r.in.buf_size = (uint32_t)-1;
7342 torture_comment(tctx, "Testing QueryDisplayInfo\n");
7345 uint32_t total_size;
7346 uint32_t returned_size;
7347 union samr_DispInfo info;
7349 r.out.total_size = &total_size;
7350 r.out.returned_size = &returned_size;
7353 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7354 "failed to query displayinfo");
7355 if (NT_STATUS_IS_ERR(r.out.result)) {
7356 torture_assert_ntstatus_ok(tctx, r.out.result,
7357 "failed to query displayinfo");
7359 status = r.out.result;
7361 if (*r.out.returned_size == 0) {
7365 switch (r.in.level) {
7367 total_num_entries += info.info1.count;
7368 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
7371 total_num_entries += info.info2.count;
7372 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
7375 total_num_entries += info.info3.count;
7376 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
7379 total_num_entries += info.info4.count;
7380 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
7383 total_num_entries += info.info5.count;
7384 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
7390 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7392 if (total_num_entries_p) {
7393 *total_num_entries_p = total_num_entries;
7399 static bool test_ManyObjects(struct dcerpc_pipe *p,
7400 struct torture_context *tctx,
7401 struct policy_handle *domain_handle,
7402 struct dom_sid *domain_sid,
7403 struct torture_samr_context *ctx)
7405 uint32_t num_total = ctx->num_objects_large_dc;
7406 uint32_t num_enum = 0;
7407 uint32_t num_disp = 0;
7408 uint32_t num_created = 0;
7409 uint32_t num_anounced = 0;
7412 struct dcerpc_binding_handle *b = p->binding_handle;
7414 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
7419 struct samr_QueryDomainInfo2 r;
7420 union samr_DomainInfo *info;
7421 r.in.domain_handle = domain_handle;
7425 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
7426 "QueryDomainInfo2 failed");
7427 torture_assert_ntstatus_ok(tctx, r.out.result,
7428 "failed to query domain info");
7430 switch (ctx->choice) {
7431 case TORTURE_SAMR_MANY_ACCOUNTS:
7432 num_anounced = info->general.num_users;
7434 case TORTURE_SAMR_MANY_GROUPS:
7435 num_anounced = info->general.num_groups;
7437 case TORTURE_SAMR_MANY_ALIASES:
7438 num_anounced = info->general.num_aliases;
7447 for (i=0; i < num_total; i++) {
7449 const char *name = NULL;
7451 switch (ctx->choice) {
7452 case TORTURE_SAMR_MANY_ACCOUNTS:
7453 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
7454 ret &= test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false);
7456 case TORTURE_SAMR_MANY_GROUPS:
7457 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
7458 ret &= test_CreateDomainGroup(b, tctx, domain_handle, name, &handles[i], domain_sid, false);
7460 case TORTURE_SAMR_MANY_ALIASES:
7461 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
7462 ret &= test_CreateAlias(b, tctx, domain_handle, name, &handles[i], domain_sid, false);
7467 if (!policy_handle_empty(&handles[i])) {
7474 switch (ctx->choice) {
7475 case TORTURE_SAMR_MANY_ACCOUNTS:
7476 ret &= test_EnumDomainUsers(b, tctx, domain_handle, &num_enum);
7478 case TORTURE_SAMR_MANY_GROUPS:
7479 ret &= test_EnumDomainGroups(b, tctx, domain_handle, &num_enum);
7481 case TORTURE_SAMR_MANY_ALIASES:
7482 ret &= test_EnumDomainAliases(b, tctx, domain_handle, &num_enum);
7490 switch (ctx->choice) {
7491 case TORTURE_SAMR_MANY_ACCOUNTS:
7492 ret &= test_QueryDisplayInfo_level(b, tctx, domain_handle, 1, &num_disp);
7494 case TORTURE_SAMR_MANY_GROUPS:
7495 ret &= test_QueryDisplayInfo_level(b, tctx, domain_handle, 3, &num_disp);
7497 case TORTURE_SAMR_MANY_ALIASES:
7498 /* no aliases in dispinfo */
7504 /* close or delete */
7506 for (i=0; i < num_total; i++) {
7508 if (policy_handle_empty(&handles[i])) {
7512 if (torture_setting_bool(tctx, "samba3", false)) {
7513 ret &= test_samr_handle_Close(b, tctx, &handles[i]);
7515 switch (ctx->choice) {
7516 case TORTURE_SAMR_MANY_ACCOUNTS:
7517 ret &= test_DeleteUser(b, tctx, &handles[i]);
7519 case TORTURE_SAMR_MANY_GROUPS:
7520 ret &= test_DeleteDomainGroup(b, tctx, &handles[i]);
7522 case TORTURE_SAMR_MANY_ALIASES:
7523 ret &= test_DeleteAlias(b, tctx, &handles[i]);
7531 talloc_free(handles);
7533 if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
7534 torture_comment(tctx,
7535 "unexpected number of results (%u) returned in enum call, expected %u\n",
7536 num_enum, num_anounced + num_created);
7538 torture_comment(tctx,
7539 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
7540 num_disp, num_anounced + num_created);
7545 static bool test_Connect(struct dcerpc_binding_handle *b,
7546 struct torture_context *tctx,
7547 struct policy_handle *handle);
7549 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7550 struct torture_samr_context *ctx, struct dom_sid *sid)
7552 struct samr_OpenDomain r;
7553 struct policy_handle domain_handle;
7554 struct policy_handle alias_handle;
7555 struct policy_handle user_handle;
7556 struct policy_handle group_handle;
7558 struct dcerpc_binding_handle *b = p->binding_handle;
7560 ZERO_STRUCT(alias_handle);
7561 ZERO_STRUCT(user_handle);
7562 ZERO_STRUCT(group_handle);
7563 ZERO_STRUCT(domain_handle);
7565 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
7567 r.in.connect_handle = &ctx->handle;
7568 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7570 r.out.domain_handle = &domain_handle;
7572 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenDomain_r(b, tctx, &r),
7573 "OpenDomain failed");
7574 torture_assert_ntstatus_ok(tctx, r.out.result, "OpenDomain failed");
7576 /* run the domain tests with the main handle closed - this tests
7577 the servers reference counting */
7578 torture_assert(tctx, test_samr_handle_Close(b, tctx, &ctx->handle), "Failed to close SAMR handle");
7580 switch (ctx->choice) {
7581 case TORTURE_SAMR_PASSWORDS:
7582 case TORTURE_SAMR_USER_PRIVILEGES:
7583 if (!torture_setting_bool(tctx, "samba3", false)) {
7584 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7586 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7588 torture_warning(tctx, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
7591 case TORTURE_SAMR_USER_ATTRIBUTES:
7592 if (!torture_setting_bool(tctx, "samba3", false)) {
7593 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7595 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7596 /* This test needs 'complex' users to validate */
7597 ret &= test_QueryDisplayInfo(b, tctx, &domain_handle);
7599 torture_warning(tctx, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
7602 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
7603 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
7604 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
7605 if (!torture_setting_bool(tctx, "samba3", false)) {
7606 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
7608 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
7610 torture_warning(tctx, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx, sid));
7613 case TORTURE_SAMR_MANY_ACCOUNTS:
7614 case TORTURE_SAMR_MANY_GROUPS:
7615 case TORTURE_SAMR_MANY_ALIASES:
7616 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
7618 torture_warning(tctx, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
7621 case TORTURE_SAMR_OTHER:
7622 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7624 torture_warning(tctx, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
7626 if (!torture_setting_bool(tctx, "samba3", false)) {
7627 ret &= test_QuerySecurity(b, tctx, &domain_handle);
7629 ret &= test_RemoveMemberFromForeignDomain(b, tctx, &domain_handle);
7630 ret &= test_CreateAlias(b, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
7631 ret &= test_CreateDomainGroup(b, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
7632 ret &= test_GetAliasMembership(b, tctx, &domain_handle);
7633 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
7634 ret &= test_QueryDomainInfo2(b, tctx, &domain_handle);
7635 ret &= test_EnumDomainUsers_all(b, tctx, &domain_handle);
7636 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
7637 ret &= test_EnumDomainGroups_all(b, tctx, &domain_handle);
7638 ret &= test_EnumDomainAliases_all(b, tctx, &domain_handle);
7639 ret &= test_QueryDisplayInfo2(b, tctx, &domain_handle);
7640 ret &= test_QueryDisplayInfo3(b, tctx, &domain_handle);
7641 ret &= test_QueryDisplayInfo_continue(b, tctx, &domain_handle);
7643 if (torture_setting_bool(tctx, "samba4", false)) {
7644 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
7646 ret &= test_GetDisplayEnumerationIndex(b, tctx, &domain_handle);
7647 ret &= test_GetDisplayEnumerationIndex2(b, tctx, &domain_handle);
7649 ret &= test_GroupList(b, tctx, &domain_handle);
7650 ret &= test_TestPrivateFunctionsDomain(b, tctx, &domain_handle);
7651 ret &= test_RidToSid(b, tctx, sid, &domain_handle);
7652 ret &= test_GetBootKeyInformation(b, tctx, &domain_handle);
7654 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
7659 if (!policy_handle_empty(&user_handle) &&
7660 !test_DeleteUser(b, tctx, &user_handle)) {
7664 if (!policy_handle_empty(&alias_handle) &&
7665 !test_DeleteAlias(b, tctx, &alias_handle)) {
7669 if (!policy_handle_empty(&group_handle) &&
7670 !test_DeleteDomainGroup(b, tctx, &group_handle)) {
7674 torture_assert(tctx, test_samr_handle_Close(b, tctx, &domain_handle), "Failed to close SAMR domain handle");
7676 torture_assert(tctx, test_Connect(b, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
7677 /* reconnect the main handle */
7680 torture_warning(tctx, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
7686 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7687 struct torture_samr_context *ctx, const char *domain)
7689 struct samr_LookupDomain r;
7690 struct dom_sid2 *sid = NULL;
7691 struct lsa_String n1;
7692 struct lsa_String n2;
7694 struct dcerpc_binding_handle *b = p->binding_handle;
7696 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
7698 /* check for correct error codes */
7699 r.in.connect_handle = &ctx->handle;
7700 r.in.domain_name = &n2;
7704 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7705 "LookupDomain failed");
7706 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, r.out.result, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
7708 init_lsa_String(&n2, "xxNODOMAINxx");
7710 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7711 "LookupDomain failed");
7712 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, r.out.result, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
7714 r.in.connect_handle = &ctx->handle;
7716 init_lsa_String(&n1, domain);
7717 r.in.domain_name = &n1;
7719 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7720 "LookupDomain failed");
7721 torture_assert_ntstatus_ok(tctx, r.out.result, "LookupDomain");
7723 if (!test_GetDomPwInfo(p, tctx, &n1)) {
7727 if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
7735 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
7736 struct torture_samr_context *ctx)
7738 struct samr_EnumDomains r;
7739 uint32_t resume_handle = 0;
7740 uint32_t num_entries = 0;
7741 struct samr_SamArray *sam = NULL;
7744 struct dcerpc_binding_handle *b = p->binding_handle;
7746 r.in.connect_handle = &ctx->handle;
7747 r.in.resume_handle = &resume_handle;
7748 r.in.buf_size = (uint32_t)-1;
7749 r.out.resume_handle = &resume_handle;
7750 r.out.num_entries = &num_entries;
7753 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
7754 "EnumDomains failed");
7755 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
7761 for (i=0;i<sam->count;i++) {
7762 if (!test_LookupDomain(p, tctx, ctx,
7763 sam->entries[i].name.string)) {
7768 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
7769 "EnumDomains failed");
7770 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
7776 static bool test_Connect(struct dcerpc_binding_handle *b,
7777 struct torture_context *tctx,
7778 struct policy_handle *handle)
7780 struct samr_Connect r;
7781 struct samr_Connect2 r2;
7782 struct samr_Connect3 r3;
7783 struct samr_Connect4 r4;
7784 struct samr_Connect5 r5;
7785 union samr_ConnectInfo info;
7786 struct policy_handle h;
7787 uint32_t level_out = 0;
7788 bool ret = true, got_handle = false;
7790 torture_comment(tctx, "Testing samr_Connect\n");
7792 r.in.system_name = 0;
7793 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7794 r.out.connect_handle = &h;
7796 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect_r(b, tctx, &r),
7798 if (!NT_STATUS_IS_OK(r.out.result)) {
7799 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(r.out.result));
7806 torture_comment(tctx, "Testing samr_Connect2\n");
7808 r2.in.system_name = NULL;
7809 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7810 r2.out.connect_handle = &h;
7812 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect2_r(b, tctx, &r2),
7814 if (!NT_STATUS_IS_OK(r2.out.result)) {
7815 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(r2.out.result));
7819 test_samr_handle_Close(b, tctx, handle);
7825 torture_comment(tctx, "Testing samr_Connect3\n");
7827 r3.in.system_name = NULL;
7829 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7830 r3.out.connect_handle = &h;
7832 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect3_r(b, tctx, &r3),
7834 if (!NT_STATUS_IS_OK(r3.out.result)) {
7835 torture_warning(tctx, "Connect3 failed - %s\n", nt_errstr(r3.out.result));
7839 test_samr_handle_Close(b, tctx, handle);
7845 torture_comment(tctx, "Testing samr_Connect4\n");
7847 r4.in.system_name = "";
7848 r4.in.client_version = 0;
7849 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7850 r4.out.connect_handle = &h;
7852 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect4_r(b, tctx, &r4),
7854 if (!NT_STATUS_IS_OK(r4.out.result)) {
7855 torture_warning(tctx, "Connect4 failed - %s\n", nt_errstr(r4.out.result));
7859 test_samr_handle_Close(b, tctx, handle);
7865 torture_comment(tctx, "Testing samr_Connect5\n");
7867 info.info1.client_version = 0;
7868 info.info1.unknown2 = 0;
7870 r5.in.system_name = "";
7871 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7873 r5.out.level_out = &level_out;
7874 r5.in.info_in = &info;
7875 r5.out.info_out = &info;
7876 r5.out.connect_handle = &h;
7878 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect5_r(b, tctx, &r5),
7880 if (!NT_STATUS_IS_OK(r5.out.result)) {
7881 torture_warning(tctx, "Connect5 failed - %s\n", nt_errstr(r5.out.result));
7885 test_samr_handle_Close(b, tctx, handle);
7895 static bool test_samr_ValidatePassword(struct dcerpc_pipe *p,
7896 struct torture_context *tctx)
7898 struct samr_ValidatePassword r;
7899 union samr_ValidatePasswordReq req;
7900 union samr_ValidatePasswordRep *repp = NULL;
7902 const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
7904 struct dcerpc_binding_handle *b = p->binding_handle;
7906 torture_comment(tctx, "Testing samr_ValidatePassword\n");
7909 r.in.level = NetValidatePasswordReset;
7914 req.req3.account.string = "non-existant-account-aklsdji";
7916 for (i=0; passwords[i]; i++) {
7917 req.req3.password.string = passwords[i];
7919 status = dcerpc_samr_ValidatePassword_r(b, tctx, &r);
7920 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
7921 torture_skip(tctx, "ValidatePassword not supported by server\n");
7923 torture_assert_ntstatus_ok(tctx, status,
7924 "samr_ValidatePassword failed");
7925 torture_assert_ntstatus_ok(tctx, r.out.result,
7926 "samr_ValidatePassword failed");
7927 torture_comment(tctx, "Server %s password '%s' with code %i\n",
7928 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
7929 req.req3.password.string, repp->ctr3.status);
7935 bool torture_rpc_samr(struct torture_context *torture)
7938 struct dcerpc_pipe *p;
7940 struct torture_samr_context *ctx;
7941 struct dcerpc_binding_handle *b;
7943 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7944 if (!NT_STATUS_IS_OK(status)) {
7947 b = p->binding_handle;
7949 ctx = talloc_zero(torture, struct torture_samr_context);
7951 ctx->choice = TORTURE_SAMR_OTHER;
7953 ret &= test_Connect(b, torture, &ctx->handle);
7955 if (!torture_setting_bool(torture, "samba3", false)) {
7956 ret &= test_QuerySecurity(b, torture, &ctx->handle);
7959 ret &= test_EnumDomains(p, torture, ctx);
7961 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
7963 ret &= test_Shutdown(b, torture, &ctx->handle);
7965 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
7971 bool torture_rpc_samr_users(struct torture_context *torture)
7974 struct dcerpc_pipe *p;
7976 struct torture_samr_context *ctx;
7977 struct dcerpc_binding_handle *b;
7979 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7980 if (!NT_STATUS_IS_OK(status)) {
7983 b = p->binding_handle;
7985 ctx = talloc_zero(torture, struct torture_samr_context);
7987 ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
7989 ret &= test_Connect(b, torture, &ctx->handle);
7991 if (!torture_setting_bool(torture, "samba3", false)) {
7992 ret &= test_QuerySecurity(b, torture, &ctx->handle);
7995 ret &= test_EnumDomains(p, torture, ctx);
7997 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
7999 ret &= test_Shutdown(b, torture, &ctx->handle);
8001 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8007 bool torture_rpc_samr_passwords(struct torture_context *torture)
8010 struct dcerpc_pipe *p;
8012 struct torture_samr_context *ctx;
8013 struct dcerpc_binding_handle *b;
8015 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8016 if (!NT_STATUS_IS_OK(status)) {
8019 b = p->binding_handle;
8021 ctx = talloc_zero(torture, struct torture_samr_context);
8023 ctx->choice = TORTURE_SAMR_PASSWORDS;
8025 ret &= test_Connect(b, torture, &ctx->handle);
8027 ret &= test_EnumDomains(p, torture, ctx);
8029 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8031 ret &= test_samr_ValidatePassword(p, torture);
8036 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
8037 struct dcerpc_pipe *p2,
8038 struct cli_credentials *machine_credentials)
8041 struct dcerpc_pipe *p;
8043 struct torture_samr_context *ctx;
8044 struct dcerpc_binding_handle *b;
8046 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8047 if (!NT_STATUS_IS_OK(status)) {
8050 b = p->binding_handle;
8052 ctx = talloc_zero(torture, struct torture_samr_context);
8054 ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
8055 ctx->machine_credentials = machine_credentials;
8057 ret &= test_Connect(b, torture, &ctx->handle);
8059 ret &= test_EnumDomains(p, torture, ctx);
8061 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8066 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
8068 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.pwdlastset");
8069 struct torture_rpc_tcase *tcase;
8071 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8073 TEST_ACCOUNT_NAME_PWD);
8075 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
8076 torture_rpc_samr_pwdlastset);
8081 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
8082 struct dcerpc_pipe *p2,
8083 struct cli_credentials *machine_credentials)
8086 struct dcerpc_pipe *p;
8088 struct torture_samr_context *ctx;
8089 struct dcerpc_binding_handle *b;
8091 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8092 if (!NT_STATUS_IS_OK(status)) {
8095 b = p->binding_handle;
8097 ctx = talloc_zero(torture, struct torture_samr_context);
8099 ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
8100 ctx->machine_credentials = machine_credentials;
8102 ret &= test_Connect(b, torture, &ctx->handle);
8104 ret &= test_EnumDomains(p, torture, ctx);
8106 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8111 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
8113 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.users.privileges");
8114 struct torture_rpc_tcase *tcase;
8116 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8118 TEST_ACCOUNT_NAME_PWD);
8120 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
8121 torture_rpc_samr_users_privileges_delete_user);
8126 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
8127 struct dcerpc_pipe *p2,
8131 struct dcerpc_pipe *p;
8133 struct torture_samr_context *ctx =
8134 talloc_get_type_abort(data, struct torture_samr_context);
8135 struct dcerpc_binding_handle *b;
8137 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8138 if (!NT_STATUS_IS_OK(status)) {
8141 b = p->binding_handle;
8143 ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
8144 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8145 ctx->num_objects_large_dc);
8147 ret &= test_Connect(b, torture, &ctx->handle);
8149 ret &= test_EnumDomains(p, torture, ctx);
8151 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8156 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
8157 struct dcerpc_pipe *p2,
8161 struct dcerpc_pipe *p;
8163 struct torture_samr_context *ctx =
8164 talloc_get_type_abort(data, struct torture_samr_context);
8165 struct dcerpc_binding_handle *b;
8167 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8168 if (!NT_STATUS_IS_OK(status)) {
8171 b = p->binding_handle;
8173 ctx->choice = TORTURE_SAMR_MANY_GROUPS;
8174 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8175 ctx->num_objects_large_dc);
8177 ret &= test_Connect(b, torture, &ctx->handle);
8179 ret &= test_EnumDomains(p, torture, ctx);
8181 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8186 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
8187 struct dcerpc_pipe *p2,
8191 struct dcerpc_pipe *p;
8193 struct torture_samr_context *ctx =
8194 talloc_get_type_abort(data, struct torture_samr_context);
8195 struct dcerpc_binding_handle *b;
8197 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8198 if (!NT_STATUS_IS_OK(status)) {
8201 b = p->binding_handle;
8203 ctx->choice = TORTURE_SAMR_MANY_ALIASES;
8204 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8205 ctx->num_objects_large_dc);
8207 ret &= test_Connect(b, torture, &ctx->handle);
8209 ret &= test_EnumDomains(p, torture, ctx);
8211 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8216 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
8218 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.large-dc");
8219 struct torture_rpc_tcase *tcase;
8220 struct torture_samr_context *ctx;
8222 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
8224 ctx = talloc_zero(suite, struct torture_samr_context);
8225 ctx->num_objects_large_dc = 150;
8227 torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
8228 torture_rpc_samr_many_aliases, ctx);
8229 torture_rpc_tcase_add_test_ex(tcase, "many_groups",
8230 torture_rpc_samr_many_groups, ctx);
8231 torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
8232 torture_rpc_samr_many_accounts, ctx);
8237 static bool torture_rpc_samr_badpwdcount(struct torture_context *torture,
8238 struct dcerpc_pipe *p2,
8239 struct cli_credentials *machine_credentials)
8242 struct dcerpc_pipe *p;
8244 struct torture_samr_context *ctx;
8245 struct dcerpc_binding_handle *b;
8247 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8248 if (!NT_STATUS_IS_OK(status)) {
8251 b = p->binding_handle;
8253 ctx = talloc_zero(torture, struct torture_samr_context);
8255 ctx->choice = TORTURE_SAMR_PASSWORDS_BADPWDCOUNT;
8256 ctx->machine_credentials = machine_credentials;
8258 ret &= test_Connect(b, torture, &ctx->handle);
8260 ret &= test_EnumDomains(p, torture, ctx);
8262 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8267 struct torture_suite *torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX *mem_ctx)
8269 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.badpwdcount");
8270 struct torture_rpc_tcase *tcase;
8272 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8274 TEST_ACCOUNT_NAME_PWD);
8276 torture_rpc_tcase_add_test_creds(tcase, "badPwdCount",
8277 torture_rpc_samr_badpwdcount);
8282 static bool torture_rpc_samr_lockout(struct torture_context *torture,
8283 struct dcerpc_pipe *p2,
8284 struct cli_credentials *machine_credentials)
8287 struct dcerpc_pipe *p;
8289 struct torture_samr_context *ctx;
8290 struct dcerpc_binding_handle *b;
8292 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8293 if (!NT_STATUS_IS_OK(status)) {
8296 b = p->binding_handle;
8298 ctx = talloc_zero(torture, struct torture_samr_context);
8300 ctx->choice = TORTURE_SAMR_PASSWORDS_LOCKOUT;
8301 ctx->machine_credentials = machine_credentials;
8303 ret &= test_Connect(b, torture, &ctx->handle);
8305 ret &= test_EnumDomains(p, torture, ctx);
8307 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8312 struct torture_suite *torture_rpc_samr_passwords_lockout(TALLOC_CTX *mem_ctx)
8314 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.lockout");
8315 struct torture_rpc_tcase *tcase;
8317 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8319 TEST_ACCOUNT_NAME_PWD);
8321 torture_rpc_tcase_add_test_creds(tcase, "lockout",
8322 torture_rpc_samr_lockout);