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) Jelmer Vernooij 2005-2007
8 Copyright (C) Guenther Deschner 2008-2010
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "torture/torture.h"
27 #include "system/time.h"
28 #include "system/network.h"
29 #include "librpc/gen_ndr/lsa.h"
30 #include "librpc/gen_ndr/ndr_netlogon.h"
31 #include "librpc/gen_ndr/ndr_netlogon_c.h"
32 #include "librpc/gen_ndr/ndr_samr_c.h"
33 #include "librpc/gen_ndr/ndr_lsa_c.h"
34 #include "../lib/crypto/crypto.h"
35 #include "libcli/auth/libcli_auth.h"
36 #include "libcli/security/security.h"
37 #include "torture/rpc/torture_rpc.h"
38 #include "param/param.h"
39 #include "auth/gensec/gensec.h"
40 #include "auth/gensec/gensec_proto.h"
41 #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_result(tctx, TORTURE_FAIL, #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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "Failed to set %s to '%s' (%s)\n", \
263 #field, (const char *)s2, __location__); \
268 #define INT_EQUAL(i1, i2, field) \
270 torture_result(tctx, TORTURE_FAIL, "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, test_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, test_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, test_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, test_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, test_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, test_account_name, 0);
377 test_account_name = base_account_name;
378 TEST_USERINFO_STRING(21, account_name, 21, account_name, test_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 code_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_result(tctx, TORTURE_FAIL, "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 torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
668 __location__, __FUNCTION__,
669 newpass, nt_errstr(s.out.result));
670 if (!NT_STATUS_IS_OK(s.out.result)) {
671 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
672 s.in.level, nt_errstr(s.out.result));
682 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
683 struct policy_handle *handle, uint32_t fields_present,
687 struct samr_SetUserInfo s;
688 union samr_UserInfo u;
690 DATA_BLOB session_key;
691 struct dcerpc_binding_handle *b = p->binding_handle;
693 struct samr_GetUserPwInfo pwp;
694 struct samr_PwInfo info;
695 int policy_min_pw_len = 0;
696 pwp.in.user_handle = handle;
697 pwp.out.info = &info;
699 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
700 "GetUserPwInfo failed");
701 if (NT_STATUS_IS_OK(pwp.out.result)) {
702 policy_min_pw_len = pwp.out.info->min_password_length;
704 newpass = samr_rand_pass(tctx, policy_min_pw_len);
706 s.in.user_handle = handle;
712 u.info23.info.fields_present = fields_present;
714 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
716 status = dcerpc_fetch_session_key(p, &session_key);
717 if (!NT_STATUS_IS_OK(status)) {
718 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
719 s.in.level, nt_errstr(status));
723 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
725 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
727 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
728 "SetUserInfo failed");
729 torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
730 __location__, __FUNCTION__,
731 newpass, nt_errstr(s.out.result));
732 if (!NT_STATUS_IS_OK(s.out.result)) {
733 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
734 s.in.level, nt_errstr(s.out.result));
740 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
742 status = dcerpc_fetch_session_key(p, &session_key);
743 if (!NT_STATUS_IS_OK(status)) {
744 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
745 s.in.level, nt_errstr(status));
749 /* This should break the key nicely */
750 session_key.length--;
751 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
753 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
755 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
756 "SetUserInfo failed");
757 torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
758 __location__, __FUNCTION__,
759 newpass, nt_errstr(s.out.result));
760 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
761 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
762 s.in.level, nt_errstr(s.out.result));
770 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
771 struct policy_handle *handle, bool makeshort,
775 struct samr_SetUserInfo s;
776 union samr_UserInfo u;
778 DATA_BLOB session_key;
779 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
780 uint8_t confounder[16];
782 struct dcerpc_binding_handle *b = p->binding_handle;
784 struct samr_GetUserPwInfo pwp;
785 struct samr_PwInfo info;
786 int policy_min_pw_len = 0;
787 pwp.in.user_handle = handle;
788 pwp.out.info = &info;
790 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
791 "GetUserPwInfo failed");
792 if (NT_STATUS_IS_OK(pwp.out.result)) {
793 policy_min_pw_len = pwp.out.info->min_password_length;
795 if (makeshort && policy_min_pw_len) {
796 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
798 newpass = samr_rand_pass(tctx, policy_min_pw_len);
801 s.in.user_handle = handle;
805 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
806 u.info26.password_expired = 0;
808 status = dcerpc_fetch_session_key(p, &session_key);
809 if (!NT_STATUS_IS_OK(status)) {
810 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
811 s.in.level, nt_errstr(status));
815 generate_random_buffer((uint8_t *)confounder, 16);
818 MD5Update(&ctx, confounder, 16);
819 MD5Update(&ctx, session_key.data, session_key.length);
820 MD5Final(confounded_session_key.data, &ctx);
822 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
823 memcpy(&u.info26.password.data[516], confounder, 16);
825 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
827 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
828 "SetUserInfo failed");
829 torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
830 __location__, __FUNCTION__,
831 newpass, nt_errstr(s.out.result));
832 if (!NT_STATUS_IS_OK(s.out.result)) {
833 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
834 s.in.level, nt_errstr(s.out.result));
840 /* This should break the key nicely */
841 confounded_session_key.data[0]++;
843 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
844 memcpy(&u.info26.password.data[516], confounder, 16);
846 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
848 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
849 "SetUserInfo failed");
850 torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
851 __location__, __FUNCTION__,
852 newpass, nt_errstr(s.out.result));
853 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
854 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
855 s.in.level, nt_errstr(s.out.result));
864 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
865 struct policy_handle *handle, uint32_t fields_present,
869 struct samr_SetUserInfo s;
870 union samr_UserInfo u;
872 DATA_BLOB session_key;
873 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
875 uint8_t confounder[16];
877 struct dcerpc_binding_handle *b = p->binding_handle;
878 struct samr_GetUserPwInfo pwp;
879 struct samr_PwInfo info;
880 int policy_min_pw_len = 0;
881 pwp.in.user_handle = handle;
882 pwp.out.info = &info;
884 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
885 "GetUserPwInfo failed");
886 if (NT_STATUS_IS_OK(pwp.out.result)) {
887 policy_min_pw_len = pwp.out.info->min_password_length;
889 newpass = samr_rand_pass(tctx, policy_min_pw_len);
891 s.in.user_handle = handle;
897 u.info25.info.fields_present = fields_present;
899 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
901 status = dcerpc_fetch_session_key(p, &session_key);
902 if (!NT_STATUS_IS_OK(status)) {
903 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
904 s.in.level, nt_errstr(status));
908 generate_random_buffer((uint8_t *)confounder, 16);
911 MD5Update(&ctx, confounder, 16);
912 MD5Update(&ctx, session_key.data, session_key.length);
913 MD5Final(confounded_session_key.data, &ctx);
915 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
916 memcpy(&u.info25.password.data[516], confounder, 16);
918 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
920 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
921 "SetUserInfo failed");
922 torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
923 __location__, __FUNCTION__,
924 newpass, nt_errstr(s.out.result));
925 if (!NT_STATUS_IS_OK(s.out.result)) {
926 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
927 s.in.level, nt_errstr(s.out.result));
933 /* This should break the key nicely */
934 confounded_session_key.data[0]++;
936 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
937 memcpy(&u.info25.password.data[516], confounder, 16);
939 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
941 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
942 "SetUserInfo failed");
943 torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
944 __location__, __FUNCTION__,
945 newpass, nt_errstr(s.out.result));
946 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
947 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
948 s.in.level, nt_errstr(s.out.result));
955 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
956 struct policy_handle *handle, char **password)
959 struct samr_SetUserInfo s;
960 union samr_UserInfo u;
962 DATA_BLOB session_key;
964 struct dcerpc_binding_handle *b = p->binding_handle;
965 struct samr_GetUserPwInfo pwp;
966 struct samr_PwInfo info;
967 int policy_min_pw_len = 0;
968 uint8_t lm_hash[16], nt_hash[16];
970 pwp.in.user_handle = handle;
971 pwp.out.info = &info;
973 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
974 "GetUserPwInfo failed");
975 if (NT_STATUS_IS_OK(pwp.out.result)) {
976 policy_min_pw_len = pwp.out.info->min_password_length;
978 newpass = samr_rand_pass(tctx, policy_min_pw_len);
980 s.in.user_handle = handle;
986 u.info18.nt_pwd_active = true;
987 u.info18.lm_pwd_active = true;
989 E_md4hash(newpass, nt_hash);
990 E_deshash(newpass, lm_hash);
992 status = dcerpc_fetch_session_key(p, &session_key);
993 if (!NT_STATUS_IS_OK(status)) {
994 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
995 s.in.level, nt_errstr(status));
1001 in = data_blob_const(nt_hash, 16);
1002 out = data_blob_talloc_zero(tctx, 16);
1003 sess_crypt_blob(&out, &in, &session_key, true);
1004 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1008 in = data_blob_const(lm_hash, 16);
1009 out = data_blob_talloc_zero(tctx, 16);
1010 sess_crypt_blob(&out, &in, &session_key, true);
1011 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1014 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
1016 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1017 "SetUserInfo failed");
1018 if (!NT_STATUS_IS_OK(s.out.result)) {
1019 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
1020 s.in.level, nt_errstr(s.out.result));
1023 *password = newpass;
1029 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
1030 struct policy_handle *handle, uint32_t fields_present,
1034 struct samr_SetUserInfo s;
1035 union samr_UserInfo u;
1037 DATA_BLOB session_key;
1039 struct dcerpc_binding_handle *b = p->binding_handle;
1040 struct samr_GetUserPwInfo pwp;
1041 struct samr_PwInfo info;
1042 int policy_min_pw_len = 0;
1043 uint8_t lm_hash[16], nt_hash[16];
1045 pwp.in.user_handle = handle;
1046 pwp.out.info = &info;
1048 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1049 "GetUserPwInfo failed");
1050 if (NT_STATUS_IS_OK(pwp.out.result)) {
1051 policy_min_pw_len = pwp.out.info->min_password_length;
1053 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1055 s.in.user_handle = handle;
1059 E_md4hash(newpass, nt_hash);
1060 E_deshash(newpass, lm_hash);
1064 u.info21.fields_present = fields_present;
1066 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1067 u.info21.lm_owf_password.length = 16;
1068 u.info21.lm_owf_password.size = 16;
1069 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1070 u.info21.lm_password_set = true;
1073 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1074 u.info21.nt_owf_password.length = 16;
1075 u.info21.nt_owf_password.size = 16;
1076 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1077 u.info21.nt_password_set = true;
1080 status = dcerpc_fetch_session_key(p, &session_key);
1081 if (!NT_STATUS_IS_OK(status)) {
1082 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
1083 s.in.level, nt_errstr(status));
1087 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1089 in = data_blob_const(u.info21.lm_owf_password.array,
1090 u.info21.lm_owf_password.length);
1091 out = data_blob_talloc_zero(tctx, 16);
1092 sess_crypt_blob(&out, &in, &session_key, true);
1093 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1096 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1098 in = data_blob_const(u.info21.nt_owf_password.array,
1099 u.info21.nt_owf_password.length);
1100 out = data_blob_talloc_zero(tctx, 16);
1101 sess_crypt_blob(&out, &in, &session_key, true);
1102 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1105 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1107 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1108 "SetUserInfo failed");
1109 if (!NT_STATUS_IS_OK(s.out.result)) {
1110 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
1111 s.in.level, nt_errstr(s.out.result));
1114 *password = newpass;
1117 /* try invalid length */
1118 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1120 u.info21.nt_owf_password.length++;
1122 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1123 "SetUserInfo failed");
1124 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_INVALID_PARAMETER)) {
1125 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1126 s.in.level, nt_errstr(s.out.result));
1131 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1133 u.info21.lm_owf_password.length++;
1135 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1136 "SetUserInfo failed");
1137 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_INVALID_PARAMETER)) {
1138 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1139 s.in.level, nt_errstr(s.out.result));
1147 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1148 struct torture_context *tctx,
1149 struct policy_handle *handle,
1151 uint32_t fields_present,
1152 char **password, uint8_t password_expired,
1154 bool *matched_expected_error)
1157 NTSTATUS expected_error = NT_STATUS_OK;
1158 struct samr_SetUserInfo s;
1159 struct samr_SetUserInfo2 s2;
1160 union samr_UserInfo u;
1162 DATA_BLOB session_key;
1163 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1165 uint8_t confounder[16];
1167 struct dcerpc_binding_handle *b = p->binding_handle;
1168 struct samr_GetUserPwInfo pwp;
1169 struct samr_PwInfo info;
1170 int policy_min_pw_len = 0;
1171 const char *comment = NULL;
1172 uint8_t lm_hash[16], nt_hash[16];
1174 pwp.in.user_handle = handle;
1175 pwp.out.info = &info;
1177 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1178 "GetUserPwInfo failed");
1179 if (NT_STATUS_IS_OK(pwp.out.result)) {
1180 policy_min_pw_len = pwp.out.info->min_password_length;
1182 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1185 s2.in.user_handle = handle;
1187 s2.in.level = level;
1189 s.in.user_handle = handle;
1194 if (fields_present & SAMR_FIELD_COMMENT) {
1195 comment = talloc_asprintf(tctx, "comment: %ld\n", (long int) time(NULL));
1202 E_md4hash(newpass, nt_hash);
1203 E_deshash(newpass, lm_hash);
1205 u.info18.nt_pwd_active = true;
1206 u.info18.lm_pwd_active = true;
1207 u.info18.password_expired = password_expired;
1209 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1210 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1214 E_md4hash(newpass, nt_hash);
1215 E_deshash(newpass, lm_hash);
1217 u.info21.fields_present = fields_present;
1218 u.info21.password_expired = password_expired;
1219 u.info21.comment.string = comment;
1221 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1222 u.info21.lm_owf_password.length = 16;
1223 u.info21.lm_owf_password.size = 16;
1224 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1225 u.info21.lm_password_set = true;
1228 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1229 u.info21.nt_owf_password.length = 16;
1230 u.info21.nt_owf_password.size = 16;
1231 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1232 u.info21.nt_password_set = true;
1237 u.info23.info.fields_present = fields_present;
1238 u.info23.info.password_expired = password_expired;
1239 u.info23.info.comment.string = comment;
1241 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1245 u.info24.password_expired = password_expired;
1247 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1251 u.info25.info.fields_present = fields_present;
1252 u.info25.info.password_expired = password_expired;
1253 u.info25.info.comment.string = comment;
1255 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1259 u.info26.password_expired = password_expired;
1261 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1266 status = dcerpc_fetch_session_key(p, &session_key);
1267 if (!NT_STATUS_IS_OK(status)) {
1268 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
1269 s.in.level, nt_errstr(status));
1273 generate_random_buffer((uint8_t *)confounder, 16);
1276 MD5Update(&ctx, confounder, 16);
1277 MD5Update(&ctx, session_key.data, session_key.length);
1278 MD5Final(confounded_session_key.data, &ctx);
1284 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1285 out = data_blob_talloc_zero(tctx, 16);
1286 sess_crypt_blob(&out, &in, &session_key, true);
1287 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1291 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1292 out = data_blob_talloc_zero(tctx, 16);
1293 sess_crypt_blob(&out, &in, &session_key, true);
1294 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1299 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1301 in = data_blob_const(u.info21.lm_owf_password.array,
1302 u.info21.lm_owf_password.length);
1303 out = data_blob_talloc_zero(tctx, 16);
1304 sess_crypt_blob(&out, &in, &session_key, true);
1305 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1307 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1309 in = data_blob_const(u.info21.nt_owf_password.array,
1310 u.info21.nt_owf_password.length);
1311 out = data_blob_talloc_zero(tctx, 16);
1312 sess_crypt_blob(&out, &in, &session_key, true);
1313 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1317 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1320 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1323 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1324 memcpy(&u.info25.password.data[516], confounder, 16);
1327 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1328 memcpy(&u.info26.password.data[516], confounder, 16);
1333 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo2_r(b, tctx, &s2),
1334 "SetUserInfo2 failed");
1335 torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
1336 __location__, __FUNCTION__,
1337 newpass, nt_errstr(s2.out.result));
1338 status = s2.out.result;
1340 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1341 "SetUserInfo failed");
1342 torture_comment(tctx, "(%s:%s) new_password[%s] status[%s]\n",
1343 __location__, __FUNCTION__,
1344 newpass, nt_errstr(s.out.result));
1345 status = s.out.result;
1348 if (!NT_STATUS_IS_OK(status)) {
1349 if (fields_present == 0) {
1350 expected_error = NT_STATUS_INVALID_PARAMETER;
1352 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1353 expected_error = NT_STATUS_ACCESS_DENIED;
1357 if (!NT_STATUS_IS_OK(expected_error)) {
1359 torture_assert_ntstatus_equal(tctx,
1361 expected_error, "SetUserInfo2 failed");
1363 torture_assert_ntstatus_equal(tctx,
1365 expected_error, "SetUserInfo failed");
1367 *matched_expected_error = true;
1371 if (!NT_STATUS_IS_OK(status)) {
1372 torture_result(tctx, TORTURE_FAIL, "SetUserInfo%s level %u failed - %s\n",
1373 use_setinfo2 ? "2":"", level, nt_errstr(status));
1376 *password = newpass;
1382 static bool test_SetAliasInfo(struct dcerpc_binding_handle *b,
1383 struct torture_context *tctx,
1384 struct policy_handle *handle)
1386 struct samr_SetAliasInfo r;
1387 struct samr_QueryAliasInfo q;
1388 union samr_AliasInfo *info;
1389 uint16_t levels[] = {2, 3};
1393 /* Ignoring switch level 1, as that includes the number of members for the alias
1394 * and setting this to a wrong value might have negative consequences
1397 for (i=0;i<ARRAY_SIZE(levels);i++) {
1398 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1400 r.in.alias_handle = handle;
1401 r.in.level = levels[i];
1402 r.in.info = talloc(tctx, union samr_AliasInfo);
1403 switch (r.in.level) {
1404 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1405 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1406 "Test Description, should test I18N as well"); break;
1407 case ALIASINFOALL: torture_comment(tctx, "ALIASINFOALL ignored\n"); break;
1410 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetAliasInfo_r(b, tctx, &r),
1411 "SetAliasInfo failed");
1412 if (!NT_STATUS_IS_OK(r.out.result)) {
1413 torture_result(tctx, TORTURE_FAIL, "SetAliasInfo level %u failed - %s\n",
1414 levels[i], nt_errstr(r.out.result));
1418 q.in.alias_handle = handle;
1419 q.in.level = levels[i];
1422 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &q),
1423 "QueryAliasInfo failed");
1424 if (!NT_STATUS_IS_OK(q.out.result)) {
1425 torture_result(tctx, TORTURE_FAIL, "QueryAliasInfo level %u failed - %s\n",
1426 levels[i], nt_errstr(q.out.result));
1434 static bool test_GetGroupsForUser(struct dcerpc_binding_handle *b,
1435 struct torture_context *tctx,
1436 struct policy_handle *user_handle)
1438 struct samr_GetGroupsForUser r;
1439 struct samr_RidWithAttributeArray *rids = NULL;
1441 torture_comment(tctx, "Testing GetGroupsForUser\n");
1443 r.in.user_handle = user_handle;
1446 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetGroupsForUser_r(b, tctx, &r),
1447 "GetGroupsForUser failed");
1448 torture_assert_ntstatus_ok(tctx, r.out.result, "GetGroupsForUser failed");
1454 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1455 struct lsa_String *domain_name)
1457 struct samr_GetDomPwInfo r;
1458 struct samr_PwInfo info;
1459 struct dcerpc_binding_handle *b = p->binding_handle;
1461 r.in.domain_name = domain_name;
1464 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1466 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1467 "GetDomPwInfo failed");
1468 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1470 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1471 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1473 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1474 "GetDomPwInfo failed");
1475 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1477 r.in.domain_name->string = "\\\\__NONAME__";
1478 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1480 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1481 "GetDomPwInfo failed");
1482 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1484 r.in.domain_name->string = "\\\\Builtin";
1485 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1487 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1488 "GetDomPwInfo failed");
1489 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1494 static bool test_GetUserPwInfo(struct dcerpc_binding_handle *b,
1495 struct torture_context *tctx,
1496 struct policy_handle *handle)
1498 struct samr_GetUserPwInfo r;
1499 struct samr_PwInfo info;
1501 torture_comment(tctx, "Testing GetUserPwInfo\n");
1503 r.in.user_handle = handle;
1506 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &r),
1507 "GetUserPwInfo failed");
1508 torture_assert_ntstatus_ok(tctx, r.out.result, "GetUserPwInfo");
1513 static NTSTATUS test_LookupName(struct dcerpc_binding_handle *b,
1514 struct torture_context *tctx,
1515 struct policy_handle *domain_handle, const char *name,
1519 struct samr_LookupNames n;
1520 struct lsa_String sname[2];
1521 struct samr_Ids rids, types;
1523 init_lsa_String(&sname[0], name);
1525 n.in.domain_handle = domain_handle;
1529 n.out.types = &types;
1530 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1531 if (!NT_STATUS_IS_OK(status)) {
1534 if (NT_STATUS_IS_OK(n.out.result)) {
1535 *rid = n.out.rids->ids[0];
1537 return n.out.result;
1540 init_lsa_String(&sname[1], "xxNONAMExx");
1542 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1543 if (!NT_STATUS_IS_OK(status)) {
1546 if (!NT_STATUS_EQUAL(n.out.result, STATUS_SOME_UNMAPPED)) {
1547 torture_result(tctx, TORTURE_FAIL, "LookupNames[2] failed - %s\n", nt_errstr(n.out.result));
1548 if (NT_STATUS_IS_OK(n.out.result)) {
1549 return NT_STATUS_UNSUCCESSFUL;
1551 return n.out.result;
1555 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1556 if (!NT_STATUS_IS_OK(status)) {
1559 if (!NT_STATUS_IS_OK(n.out.result)) {
1560 torture_result(tctx, TORTURE_FAIL, "LookupNames[0] failed - %s\n", nt_errstr(status));
1561 return n.out.result;
1564 init_lsa_String(&sname[0], "xxNONAMExx");
1566 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1567 if (!NT_STATUS_IS_OK(status)) {
1570 if (!NT_STATUS_EQUAL(n.out.result, NT_STATUS_NONE_MAPPED)) {
1571 torture_result(tctx, TORTURE_FAIL, "LookupNames[1 bad name] failed - %s\n", nt_errstr(n.out.result));
1572 if (NT_STATUS_IS_OK(n.out.result)) {
1573 return NT_STATUS_UNSUCCESSFUL;
1575 return n.out.result;
1578 init_lsa_String(&sname[0], "xxNONAMExx");
1579 init_lsa_String(&sname[1], "xxNONAME2xx");
1581 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1582 if (!NT_STATUS_IS_OK(status)) {
1585 if (!NT_STATUS_EQUAL(n.out.result, NT_STATUS_NONE_MAPPED)) {
1586 torture_result(tctx, TORTURE_FAIL, "LookupNames[2 bad names] failed - %s\n", nt_errstr(n.out.result));
1587 if (NT_STATUS_IS_OK(n.out.result)) {
1588 return NT_STATUS_UNSUCCESSFUL;
1590 return n.out.result;
1593 return NT_STATUS_OK;
1596 static NTSTATUS test_OpenUser_byname(struct dcerpc_binding_handle *b,
1597 struct torture_context *tctx,
1598 struct policy_handle *domain_handle,
1599 const char *name, struct policy_handle *user_handle)
1602 struct samr_OpenUser r;
1605 status = test_LookupName(b, tctx, domain_handle, name, &rid);
1606 if (!NT_STATUS_IS_OK(status)) {
1610 r.in.domain_handle = domain_handle;
1611 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1613 r.out.user_handle = user_handle;
1614 status = dcerpc_samr_OpenUser_r(b, tctx, &r);
1615 if (!NT_STATUS_IS_OK(status)) {
1618 if (!NT_STATUS_IS_OK(r.out.result)) {
1619 torture_result(tctx, TORTURE_FAIL, "OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(r.out.result));
1622 return r.out.result;
1626 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
1627 struct torture_context *tctx,
1628 struct policy_handle *handle)
1631 struct samr_ChangePasswordUser r;
1633 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1634 struct policy_handle user_handle;
1635 char *oldpass = "test";
1636 char *newpass = "test2";
1637 uint8_t old_nt_hash[16], new_nt_hash[16];
1638 uint8_t old_lm_hash[16], new_lm_hash[16];
1640 status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
1641 if (!NT_STATUS_IS_OK(status)) {
1645 torture_comment(tctx, "Testing ChangePasswordUser for user 'testuser'\n");
1647 torture_comment(tctx, "old password: %s\n", oldpass);
1648 torture_comment(tctx, "new password: %s\n", newpass);
1650 E_md4hash(oldpass, old_nt_hash);
1651 E_md4hash(newpass, new_nt_hash);
1652 E_deshash(oldpass, old_lm_hash);
1653 E_deshash(newpass, new_lm_hash);
1655 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1656 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1657 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1658 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1659 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1660 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1662 r.in.handle = &user_handle;
1663 r.in.lm_present = 1;
1664 r.in.old_lm_crypted = &hash1;
1665 r.in.new_lm_crypted = &hash2;
1666 r.in.nt_present = 1;
1667 r.in.old_nt_crypted = &hash3;
1668 r.in.new_nt_crypted = &hash4;
1669 r.in.cross1_present = 1;
1670 r.in.nt_cross = &hash5;
1671 r.in.cross2_present = 1;
1672 r.in.lm_cross = &hash6;
1674 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1675 "ChangePasswordUser failed");
1676 if (!NT_STATUS_IS_OK(r.out.result)) {
1677 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser failed - %s\n", nt_errstr(r.out.result));
1681 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1689 static bool test_ChangePasswordUser(struct dcerpc_binding_handle *b,
1690 struct torture_context *tctx,
1691 const char *acct_name,
1692 struct policy_handle *handle, char **password)
1695 struct samr_ChangePasswordUser r;
1697 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1698 struct policy_handle user_handle;
1700 uint8_t old_nt_hash[16], new_nt_hash[16];
1701 uint8_t old_lm_hash[16], new_lm_hash[16];
1702 bool changed = true;
1705 struct samr_GetUserPwInfo pwp;
1706 struct samr_PwInfo info;
1707 int policy_min_pw_len = 0;
1709 status = test_OpenUser_byname(b, tctx, handle, acct_name, &user_handle);
1710 if (!NT_STATUS_IS_OK(status)) {
1713 pwp.in.user_handle = &user_handle;
1714 pwp.out.info = &info;
1716 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1717 "GetUserPwInfo failed");
1718 if (NT_STATUS_IS_OK(pwp.out.result)) {
1719 policy_min_pw_len = pwp.out.info->min_password_length;
1721 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1723 torture_comment(tctx, "Testing ChangePasswordUser\n");
1725 torture_assert(tctx, *password != NULL,
1726 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1728 oldpass = *password;
1730 E_md4hash(oldpass, old_nt_hash);
1731 E_md4hash(newpass, new_nt_hash);
1732 E_deshash(oldpass, old_lm_hash);
1733 E_deshash(newpass, new_lm_hash);
1735 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1736 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1737 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1738 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1739 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1740 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1742 r.in.user_handle = &user_handle;
1743 r.in.lm_present = 1;
1744 /* Break the NT hash */
1746 r.in.old_lm_crypted = &hash1;
1747 r.in.new_lm_crypted = &hash2;
1748 r.in.nt_present = 1;
1749 r.in.old_nt_crypted = &hash3;
1750 r.in.new_nt_crypted = &hash4;
1751 r.in.cross1_present = 1;
1752 r.in.nt_cross = &hash5;
1753 r.in.cross2_present = 1;
1754 r.in.lm_cross = &hash6;
1756 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1757 "ChangePasswordUser failed");
1758 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1759 __location__, __FUNCTION__,
1760 oldpass, newpass, nt_errstr(r.out.result));
1762 /* Do not proceed if this call has been removed */
1763 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
1764 torture_skip(tctx, "ValidatePassword not supported by server\n");
1767 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
1768 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_WRONG_PASSWORD,
1769 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1772 /* Unbreak the NT hash */
1775 r.in.user_handle = &user_handle;
1776 r.in.lm_present = 1;
1777 r.in.old_lm_crypted = &hash1;
1778 r.in.new_lm_crypted = &hash2;
1779 /* Break the LM hash */
1781 r.in.nt_present = 1;
1782 r.in.old_nt_crypted = &hash3;
1783 r.in.new_nt_crypted = &hash4;
1784 r.in.cross1_present = 1;
1785 r.in.nt_cross = &hash5;
1786 r.in.cross2_present = 1;
1787 r.in.lm_cross = &hash6;
1789 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1790 "ChangePasswordUser failed");
1791 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1792 __location__, __FUNCTION__,
1793 oldpass, newpass, nt_errstr(r.out.result));
1794 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
1795 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_WRONG_PASSWORD,
1796 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1799 /* Unbreak the NT hash */
1802 r.in.user_handle = &user_handle;
1803 r.in.lm_present = 1;
1804 r.in.old_lm_crypted = &hash1;
1805 r.in.new_lm_crypted = &hash2;
1806 r.in.nt_present = 1;
1807 r.in.old_nt_crypted = &hash3;
1808 r.in.new_nt_crypted = &hash4;
1809 r.in.cross1_present = 1;
1810 r.in.nt_cross = &hash5;
1811 r.in.cross2_present = 1;
1812 /* Break the LM cross */
1814 r.in.lm_cross = &hash6;
1816 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1817 "ChangePasswordUser failed");
1818 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1819 __location__, __FUNCTION__,
1820 oldpass, newpass, nt_errstr(r.out.result));
1821 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD) &&
1822 !NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION))
1824 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD or NT_STATUS_PASSWORD_RESTRICTION because we broke the LM cross-hash, got %s\n", nt_errstr(r.out.result));
1828 /* Unbreak the LM cross */
1831 r.in.user_handle = &user_handle;
1832 r.in.lm_present = 1;
1833 r.in.old_lm_crypted = &hash1;
1834 r.in.new_lm_crypted = &hash2;
1835 r.in.nt_present = 1;
1836 r.in.old_nt_crypted = &hash3;
1837 r.in.new_nt_crypted = &hash4;
1838 r.in.cross1_present = 1;
1839 /* Break the NT cross */
1841 r.in.nt_cross = &hash5;
1842 r.in.cross2_present = 1;
1843 r.in.lm_cross = &hash6;
1845 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1846 "ChangePasswordUser failed");
1847 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1848 __location__, __FUNCTION__,
1849 oldpass, newpass, nt_errstr(r.out.result));
1850 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD) &&
1851 !NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION))
1853 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD or NT_STATUS_PASSWORD_RESTRICTION because we broke the NT cross-hash, got %s\n", nt_errstr(r.out.result));
1857 /* Unbreak the NT cross */
1861 /* Reset the hashes to not broken values */
1862 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1863 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1864 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1865 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1866 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1867 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1869 r.in.user_handle = &user_handle;
1870 r.in.lm_present = 1;
1871 r.in.old_lm_crypted = &hash1;
1872 r.in.new_lm_crypted = &hash2;
1873 r.in.nt_present = 1;
1874 r.in.old_nt_crypted = &hash3;
1875 r.in.new_nt_crypted = &hash4;
1876 r.in.cross1_present = 1;
1877 r.in.nt_cross = &hash5;
1878 r.in.cross2_present = 0;
1879 r.in.lm_cross = NULL;
1881 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1882 "ChangePasswordUser failed");
1883 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1884 __location__, __FUNCTION__,
1885 oldpass, newpass, nt_errstr(r.out.result));
1886 if (NT_STATUS_IS_OK(r.out.result)) {
1888 *password = newpass;
1889 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, r.out.result)) {
1890 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r.out.result));
1895 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1897 E_md4hash(oldpass, old_nt_hash);
1898 E_md4hash(newpass, new_nt_hash);
1899 E_deshash(oldpass, old_lm_hash);
1900 E_deshash(newpass, new_lm_hash);
1903 /* Reset the hashes to not broken values */
1904 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1905 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1906 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1907 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1908 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1909 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1911 r.in.user_handle = &user_handle;
1912 r.in.lm_present = 1;
1913 r.in.old_lm_crypted = &hash1;
1914 r.in.new_lm_crypted = &hash2;
1915 r.in.nt_present = 1;
1916 r.in.old_nt_crypted = &hash3;
1917 r.in.new_nt_crypted = &hash4;
1918 r.in.cross1_present = 0;
1919 r.in.nt_cross = NULL;
1920 r.in.cross2_present = 1;
1921 r.in.lm_cross = &hash6;
1923 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1924 "ChangePasswordUser failed");
1925 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1926 __location__, __FUNCTION__,
1927 oldpass, newpass, nt_errstr(r.out.result));
1928 if (NT_STATUS_IS_OK(r.out.result)) {
1930 *password = newpass;
1931 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, r.out.result)) {
1932 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r.out.result));
1937 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1939 E_md4hash(oldpass, old_nt_hash);
1940 E_md4hash(newpass, new_nt_hash);
1941 E_deshash(oldpass, old_lm_hash);
1942 E_deshash(newpass, new_lm_hash);
1945 /* Reset the hashes to not broken values */
1946 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1947 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1948 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1949 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1950 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1951 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1953 r.in.user_handle = &user_handle;
1954 r.in.lm_present = 1;
1955 r.in.old_lm_crypted = &hash1;
1956 r.in.new_lm_crypted = &hash2;
1957 r.in.nt_present = 1;
1958 r.in.old_nt_crypted = &hash3;
1959 r.in.new_nt_crypted = &hash4;
1960 r.in.cross1_present = 1;
1961 r.in.nt_cross = &hash5;
1962 r.in.cross2_present = 1;
1963 r.in.lm_cross = &hash6;
1965 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1966 "ChangePasswordUser failed");
1967 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1968 __location__, __FUNCTION__,
1969 oldpass, newpass, nt_errstr(r.out.result));
1970 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
1971 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
1972 } else if (!NT_STATUS_IS_OK(r.out.result)) {
1973 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser failed - %s\n", nt_errstr(r.out.result));
1977 *password = newpass;
1980 r.in.user_handle = &user_handle;
1981 r.in.lm_present = 1;
1982 r.in.old_lm_crypted = &hash1;
1983 r.in.new_lm_crypted = &hash2;
1984 r.in.nt_present = 1;
1985 r.in.old_nt_crypted = &hash3;
1986 r.in.new_nt_crypted = &hash4;
1987 r.in.cross1_present = 1;
1988 r.in.nt_cross = &hash5;
1989 r.in.cross2_present = 1;
1990 r.in.lm_cross = &hash6;
1993 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1994 "ChangePasswordUser failed");
1995 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1996 __location__, __FUNCTION__,
1997 oldpass, newpass, nt_errstr(r.out.result));
1998 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
1999 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2000 } else if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2001 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(r.out.result));
2007 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
2015 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p,
2016 struct torture_context *tctx,
2017 const char *acct_name,
2018 struct policy_handle *handle, char **password)
2020 struct samr_OemChangePasswordUser2 r;
2022 struct samr_Password lm_verifier;
2023 struct samr_CryptPassword lm_pass;
2024 struct lsa_AsciiString server, account, account_bad;
2027 struct dcerpc_binding_handle *b = p->binding_handle;
2028 uint8_t old_lm_hash[16], new_lm_hash[16];
2030 struct samr_GetDomPwInfo dom_pw_info;
2031 struct samr_PwInfo info;
2032 int policy_min_pw_len = 0;
2034 struct lsa_String domain_name;
2036 domain_name.string = "";
2037 dom_pw_info.in.domain_name = &domain_name;
2038 dom_pw_info.out.info = &info;
2040 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
2042 torture_assert(tctx, *password != NULL,
2043 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
2045 oldpass = *password;
2047 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
2048 "GetDomPwInfo failed");
2049 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
2050 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2053 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2055 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2056 account.string = acct_name;
2058 E_deshash(oldpass, old_lm_hash);
2059 E_deshash(newpass, new_lm_hash);
2061 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2062 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2063 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2065 r.in.server = &server;
2066 r.in.account = &account;
2067 r.in.password = &lm_pass;
2068 r.in.hash = &lm_verifier;
2070 /* Break the verification */
2071 lm_verifier.hash[0]++;
2073 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2074 "OemChangePasswordUser2 failed");
2075 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2076 __location__, __FUNCTION__,
2077 oldpass, newpass, nt_errstr(r.out.result));
2079 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2080 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2081 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2082 nt_errstr(r.out.result));
2086 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2087 /* Break the old password */
2089 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2090 /* unbreak it for the next operation */
2092 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2094 r.in.server = &server;
2095 r.in.account = &account;
2096 r.in.password = &lm_pass;
2097 r.in.hash = &lm_verifier;
2099 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2100 "OemChangePasswordUser2 failed");
2101 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2102 __location__, __FUNCTION__,
2103 oldpass, newpass, nt_errstr(r.out.result));
2105 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2106 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2107 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2108 nt_errstr(r.out.result));
2112 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2113 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2115 r.in.server = &server;
2116 r.in.account = &account;
2117 r.in.password = &lm_pass;
2120 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2121 "OemChangePasswordUser2 failed");
2122 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2123 __location__, __FUNCTION__,
2124 oldpass, newpass, nt_errstr(r.out.result));
2126 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2127 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2128 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
2129 nt_errstr(r.out.result));
2133 /* This shouldn't be a valid name */
2134 account_bad.string = TEST_ACCOUNT_NAME "XX";
2135 r.in.account = &account_bad;
2137 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2138 "OemChangePasswordUser2 failed");
2139 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2140 __location__, __FUNCTION__,
2141 oldpass, newpass, nt_errstr(r.out.result));
2143 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2144 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
2145 nt_errstr(r.out.result));
2149 /* This shouldn't be a valid name */
2150 account_bad.string = TEST_ACCOUNT_NAME "XX";
2151 r.in.account = &account_bad;
2152 r.in.password = &lm_pass;
2153 r.in.hash = &lm_verifier;
2155 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2156 "OemChangePasswordUser2 failed");
2157 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2158 __location__, __FUNCTION__,
2159 oldpass, newpass, nt_errstr(r.out.result));
2161 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2162 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2163 nt_errstr(r.out.result));
2167 /* This shouldn't be a valid name */
2168 account_bad.string = TEST_ACCOUNT_NAME "XX";
2169 r.in.account = &account_bad;
2170 r.in.password = NULL;
2171 r.in.hash = &lm_verifier;
2173 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2174 "OemChangePasswordUser2 failed");
2175 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2176 __location__, __FUNCTION__,
2177 oldpass, newpass, nt_errstr(r.out.result));
2179 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2180 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2181 nt_errstr(r.out.result));
2185 E_deshash(oldpass, old_lm_hash);
2186 E_deshash(newpass, new_lm_hash);
2188 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2189 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2190 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2192 r.in.server = &server;
2193 r.in.account = &account;
2194 r.in.password = &lm_pass;
2195 r.in.hash = &lm_verifier;
2197 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2198 "OemChangePasswordUser2 failed");
2199 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2200 __location__, __FUNCTION__,
2201 oldpass, newpass, nt_errstr(r.out.result));
2203 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2204 torture_comment(tctx, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2205 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2206 torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed - %s\n", nt_errstr(r.out.result));
2209 *password = newpass;
2216 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2217 const char *acct_name,
2219 char *newpass, bool allow_password_restriction)
2221 struct samr_ChangePasswordUser2 r;
2223 struct lsa_String server, account;
2224 struct samr_CryptPassword nt_pass, lm_pass;
2225 struct samr_Password nt_verifier, lm_verifier;
2227 struct dcerpc_binding_handle *b = p->binding_handle;
2228 uint8_t old_nt_hash[16], new_nt_hash[16];
2229 uint8_t old_lm_hash[16], new_lm_hash[16];
2231 struct samr_GetDomPwInfo dom_pw_info;
2232 struct samr_PwInfo info;
2234 struct lsa_String domain_name;
2236 domain_name.string = "";
2237 dom_pw_info.in.domain_name = &domain_name;
2238 dom_pw_info.out.info = &info;
2240 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2242 torture_assert(tctx, *password != NULL,
2243 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2244 oldpass = *password;
2247 int policy_min_pw_len = 0;
2248 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
2249 "GetDomPwInfo failed");
2250 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
2251 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2254 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2257 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2258 init_lsa_String(&account, acct_name);
2260 E_md4hash(oldpass, old_nt_hash);
2261 E_md4hash(newpass, new_nt_hash);
2263 E_deshash(oldpass, old_lm_hash);
2264 E_deshash(newpass, new_lm_hash);
2266 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2267 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2268 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2270 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2271 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2272 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2274 r.in.server = &server;
2275 r.in.account = &account;
2276 r.in.nt_password = &nt_pass;
2277 r.in.nt_verifier = &nt_verifier;
2279 r.in.lm_password = &lm_pass;
2280 r.in.lm_verifier = &lm_verifier;
2282 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser2_r(b, tctx, &r),
2283 "ChangePasswordUser2 failed");
2284 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2285 __location__, __FUNCTION__,
2286 oldpass, newpass, nt_errstr(r.out.result));
2288 if (allow_password_restriction && NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2289 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2290 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2291 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser2 failed - %s\n", nt_errstr(r.out.result));
2294 *password = newpass;
2301 static bool test_ChangePasswordUser2_ntstatus(struct dcerpc_pipe *p, struct torture_context *tctx,
2302 const char *acct_name,
2303 const char *password, NTSTATUS status)
2305 struct samr_ChangePasswordUser2 r;
2306 struct lsa_String server, account;
2307 struct samr_CryptPassword nt_pass, lm_pass;
2308 struct samr_Password nt_verifier, lm_verifier;
2309 const char *oldpass;
2310 struct dcerpc_binding_handle *b = p->binding_handle;
2311 uint8_t old_nt_hash[16], new_nt_hash[16];
2312 uint8_t old_lm_hash[16], new_lm_hash[16];
2314 struct samr_GetDomPwInfo dom_pw_info;
2315 struct samr_PwInfo info;
2317 struct lsa_String domain_name;
2319 int policy_min_pw_len = 0;
2321 domain_name.string = "";
2322 dom_pw_info.in.domain_name = &domain_name;
2323 dom_pw_info.out.info = &info;
2325 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2329 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
2330 "GetDomPwInfo failed");
2331 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
2332 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2335 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2337 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2338 init_lsa_String(&account, acct_name);
2340 E_md4hash(oldpass, old_nt_hash);
2341 E_md4hash(newpass, new_nt_hash);
2343 E_deshash(oldpass, old_lm_hash);
2344 E_deshash(newpass, new_lm_hash);
2346 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2347 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2348 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2350 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2351 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2352 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2354 r.in.server = &server;
2355 r.in.account = &account;
2356 r.in.nt_password = &nt_pass;
2357 r.in.nt_verifier = &nt_verifier;
2359 r.in.lm_password = &lm_pass;
2360 r.in.lm_verifier = &lm_verifier;
2362 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser2_r(b, tctx, &r),
2363 "ChangePasswordUser2 failed");
2364 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2365 __location__, __FUNCTION__,
2366 oldpass, newpass, nt_errstr(r.out.result));
2368 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2369 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2371 torture_assert_ntstatus_equal(tctx, r.out.result, status, "ChangePasswordUser2 returned unexpected value");
2378 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2379 const char *account_string,
2380 int policy_min_pw_len,
2382 const char *newpass,
2383 NTTIME last_password_change,
2384 bool handle_reject_reason)
2386 struct samr_ChangePasswordUser3 r;
2388 struct lsa_String server, account, account_bad;
2389 struct samr_CryptPassword nt_pass, lm_pass;
2390 struct samr_Password nt_verifier, lm_verifier;
2392 struct dcerpc_binding_handle *b = p->binding_handle;
2393 uint8_t old_nt_hash[16], new_nt_hash[16];
2394 uint8_t old_lm_hash[16], new_lm_hash[16];
2396 struct samr_DomInfo1 *dominfo = NULL;
2397 struct userPwdChangeFailureInformation *reject = NULL;
2399 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2401 if (newpass == NULL) {
2403 if (policy_min_pw_len == 0) {
2404 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2406 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2408 } while (check_password_quality(newpass) == false);
2410 torture_comment(tctx, "Using password '%s'\n", newpass);
2413 torture_assert(tctx, *password != NULL,
2414 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2416 oldpass = *password;
2417 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2418 init_lsa_String(&account, account_string);
2420 E_md4hash(oldpass, old_nt_hash);
2421 E_md4hash(newpass, new_nt_hash);
2423 E_deshash(oldpass, old_lm_hash);
2424 E_deshash(newpass, new_lm_hash);
2426 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2427 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2428 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2430 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2431 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2432 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2434 /* Break the verification */
2435 nt_verifier.hash[0]++;
2437 r.in.server = &server;
2438 r.in.account = &account;
2439 r.in.nt_password = &nt_pass;
2440 r.in.nt_verifier = &nt_verifier;
2442 r.in.lm_password = &lm_pass;
2443 r.in.lm_verifier = &lm_verifier;
2444 r.in.password3 = NULL;
2445 r.out.dominfo = &dominfo;
2446 r.out.reject = &reject;
2448 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2449 "ChangePasswordUser3 failed");
2450 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2451 __location__, __FUNCTION__,
2452 oldpass, newpass, nt_errstr(r.out.result));
2453 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2454 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2455 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2456 nt_errstr(r.out.result));
2460 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2461 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2462 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2464 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2465 /* Break the NT hash */
2467 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2468 /* Unbreak it again */
2470 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2472 r.in.server = &server;
2473 r.in.account = &account;
2474 r.in.nt_password = &nt_pass;
2475 r.in.nt_verifier = &nt_verifier;
2477 r.in.lm_password = &lm_pass;
2478 r.in.lm_verifier = &lm_verifier;
2479 r.in.password3 = NULL;
2480 r.out.dominfo = &dominfo;
2481 r.out.reject = &reject;
2483 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2484 "ChangePasswordUser3 failed");
2485 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2486 __location__, __FUNCTION__,
2487 oldpass, newpass, nt_errstr(r.out.result));
2488 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2489 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2490 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2491 nt_errstr(r.out.result));
2495 /* This shouldn't be a valid name */
2496 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2498 r.in.account = &account_bad;
2499 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2500 "ChangePasswordUser3 failed");
2501 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2502 __location__, __FUNCTION__,
2503 oldpass, newpass, nt_errstr(r.out.result));
2504 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2505 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2506 nt_errstr(r.out.result));
2510 E_md4hash(oldpass, old_nt_hash);
2511 E_md4hash(newpass, new_nt_hash);
2513 E_deshash(oldpass, old_lm_hash);
2514 E_deshash(newpass, new_lm_hash);
2516 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2517 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2518 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2520 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2521 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2522 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2524 r.in.server = &server;
2525 r.in.account = &account;
2526 r.in.nt_password = &nt_pass;
2527 r.in.nt_verifier = &nt_verifier;
2529 r.in.lm_password = &lm_pass;
2530 r.in.lm_verifier = &lm_verifier;
2531 r.in.password3 = NULL;
2532 r.out.dominfo = &dominfo;
2533 r.out.reject = &reject;
2535 unix_to_nt_time(&t, time(NULL));
2537 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2538 "ChangePasswordUser3 failed");
2539 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2540 __location__, __FUNCTION__,
2541 oldpass, newpass, nt_errstr(r.out.result));
2543 torture_comment(tctx, "(%s): dominfo[%s], reject[%s], handle_reject_reason[%s], "
2544 "last_password_change[%s], dominfo->min_password_age[%lld]\n",
2546 (dominfo == NULL)? "NULL" : "present",
2547 reject ? "true" : "false",
2548 handle_reject_reason ? "true" : "false",
2549 null_nttime(last_password_change) ? "null" : "not null",
2550 dominfo ? (long long)dominfo->min_password_age : (long long)0);
2552 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2555 && handle_reject_reason
2556 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2557 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2559 if (reject && (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR)) {
2560 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2561 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2566 /* We tested the order of precendence which is as follows:
2575 if ((dominfo->min_password_age < 0) && !null_nttime(last_password_change) &&
2576 (last_password_change - dominfo->min_password_age > t)) {
2578 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2579 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2580 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2584 } else if ((dominfo->min_password_length > 0) &&
2585 (strlen(newpass) < dominfo->min_password_length)) {
2587 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2588 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2589 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT, reject->extendedFailureReason);
2593 } else if ((dominfo->password_history_length > 0) &&
2594 strequal(oldpass, newpass)) {
2596 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PWD_IN_HISTORY) {
2597 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2598 SAM_PWD_CHANGE_PWD_IN_HISTORY, reject->extendedFailureReason);
2601 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2603 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NOT_COMPLEX) {
2604 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2605 SAM_PWD_CHANGE_NOT_COMPLEX, reject->extendedFailureReason);
2611 if (reject->extendedFailureReason == SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2612 /* retry with adjusted size */
2613 return test_ChangePasswordUser3(p, tctx, account_string,
2614 dominfo->min_password_length,
2615 password, NULL, 0, false);
2619 } else if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2620 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2621 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2622 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2625 /* Perhaps the server has a 'min password age' set? */
2628 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3");
2630 *password = talloc_strdup(tctx, newpass);
2636 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2637 const char *account_string,
2638 struct policy_handle *handle,
2642 struct samr_ChangePasswordUser3 r;
2643 struct samr_SetUserInfo s;
2644 union samr_UserInfo u;
2645 DATA_BLOB session_key;
2646 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2647 uint8_t confounder[16];
2651 struct lsa_String server, account;
2652 struct samr_CryptPassword nt_pass;
2653 struct samr_Password nt_verifier;
2654 DATA_BLOB new_random_pass;
2657 struct dcerpc_binding_handle *b = p->binding_handle;
2658 uint8_t old_nt_hash[16], new_nt_hash[16];
2660 struct samr_DomInfo1 *dominfo = NULL;
2661 struct userPwdChangeFailureInformation *reject = NULL;
2663 new_random_pass = samr_very_rand_pass(tctx, 128);
2665 torture_assert(tctx, *password != NULL,
2666 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2668 oldpass = *password;
2669 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2670 init_lsa_String(&account, account_string);
2672 s.in.user_handle = handle;
2678 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2680 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2682 status = dcerpc_fetch_session_key(p, &session_key);
2683 if (!NT_STATUS_IS_OK(status)) {
2684 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
2685 s.in.level, nt_errstr(status));
2689 generate_random_buffer((uint8_t *)confounder, 16);
2692 MD5Update(&ctx, confounder, 16);
2693 MD5Update(&ctx, session_key.data, session_key.length);
2694 MD5Final(confounded_session_key.data, &ctx);
2696 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2697 memcpy(&u.info25.password.data[516], confounder, 16);
2699 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2701 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
2702 "SetUserInfo failed");
2703 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2704 __location__, __FUNCTION__,
2705 oldpass, "RANDOM", nt_errstr(s.out.result));
2706 if (!NT_STATUS_IS_OK(s.out.result)) {
2707 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
2708 s.in.level, nt_errstr(s.out.result));
2712 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2714 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2716 new_random_pass = samr_very_rand_pass(tctx, 128);
2718 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2720 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2721 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2722 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2724 r.in.server = &server;
2725 r.in.account = &account;
2726 r.in.nt_password = &nt_pass;
2727 r.in.nt_verifier = &nt_verifier;
2729 r.in.lm_password = NULL;
2730 r.in.lm_verifier = NULL;
2731 r.in.password3 = NULL;
2732 r.out.dominfo = &dominfo;
2733 r.out.reject = &reject;
2735 unix_to_nt_time(&t, time(NULL));
2737 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2738 "ChangePasswordUser3 failed");
2739 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2740 __location__, __FUNCTION__,
2741 oldpass, "RANDOM", nt_errstr(r.out.result));
2743 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2744 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2745 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2746 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2749 /* Perhaps the server has a 'min password age' set? */
2751 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2752 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed - %s\n", nt_errstr(r.out.result));
2756 newpass = samr_rand_pass(tctx, 128);
2758 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2760 E_md4hash(newpass, new_nt_hash);
2762 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2763 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2764 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2766 r.in.server = &server;
2767 r.in.account = &account;
2768 r.in.nt_password = &nt_pass;
2769 r.in.nt_verifier = &nt_verifier;
2771 r.in.lm_password = NULL;
2772 r.in.lm_verifier = NULL;
2773 r.in.password3 = NULL;
2774 r.out.dominfo = &dominfo;
2775 r.out.reject = &reject;
2777 unix_to_nt_time(&t, time(NULL));
2779 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2780 "ChangePasswordUser3 failed");
2781 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2782 __location__, __FUNCTION__,
2783 oldpass, newpass, nt_errstr(r.out.result));
2785 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2786 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2787 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2788 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2791 /* Perhaps the server has a 'min password age' set? */
2794 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3 (on second random password)");
2795 *password = talloc_strdup(tctx, newpass);
2802 static bool test_GetMembersInAlias(struct dcerpc_binding_handle *b,
2803 struct torture_context *tctx,
2804 struct policy_handle *alias_handle)
2806 struct samr_GetMembersInAlias r;
2807 struct lsa_SidArray sids;
2809 torture_comment(tctx, "Testing GetMembersInAlias\n");
2811 r.in.alias_handle = alias_handle;
2814 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetMembersInAlias_r(b, tctx, &r),
2815 "GetMembersInAlias failed");
2816 torture_assert_ntstatus_ok(tctx, r.out.result, "GetMembersInAlias failed");
2821 static bool test_AddMemberToAlias(struct dcerpc_binding_handle *b,
2822 struct torture_context *tctx,
2823 struct policy_handle *alias_handle,
2824 const struct dom_sid *domain_sid)
2826 struct samr_AddAliasMember r;
2827 struct samr_DeleteAliasMember d;
2828 struct dom_sid *sid;
2830 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2832 torture_comment(tctx, "Testing AddAliasMember\n");
2833 r.in.alias_handle = alias_handle;
2836 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddAliasMember_r(b, tctx, &r),
2837 "AddAliasMember failed");
2838 torture_assert_ntstatus_ok(tctx, r.out.result, "AddAliasMember failed");
2840 d.in.alias_handle = alias_handle;
2843 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteAliasMember_r(b, tctx, &d),
2844 "DeleteAliasMember failed");
2845 torture_assert_ntstatus_ok(tctx, d.out.result, "DelAliasMember failed");
2850 static bool test_AddMultipleMembersToAlias(struct dcerpc_binding_handle *b,
2851 struct torture_context *tctx,
2852 struct policy_handle *alias_handle)
2854 struct samr_AddMultipleMembersToAlias a;
2855 struct samr_RemoveMultipleMembersFromAlias r;
2856 struct lsa_SidArray sids;
2858 torture_comment(tctx, "Testing AddMultipleMembersToAlias\n");
2859 a.in.alias_handle = alias_handle;
2863 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2865 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2866 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2867 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2869 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddMultipleMembersToAlias_r(b, tctx, &a),
2870 "AddMultipleMembersToAlias failed");
2871 torture_assert_ntstatus_ok(tctx, a.out.result, "AddMultipleMembersToAlias");
2874 torture_comment(tctx, "Testing RemoveMultipleMembersFromAlias\n");
2875 r.in.alias_handle = alias_handle;
2878 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2879 "RemoveMultipleMembersFromAlias failed");
2880 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2882 /* strange! removing twice doesn't give any error */
2883 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2884 "RemoveMultipleMembersFromAlias failed");
2885 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2887 /* but removing an alias that isn't there does */
2888 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2890 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2891 "RemoveMultipleMembersFromAlias failed");
2892 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2897 static bool test_GetAliasMembership(struct dcerpc_binding_handle *b,
2898 struct torture_context *tctx,
2899 struct policy_handle *domain_handle)
2901 struct samr_GetAliasMembership r;
2902 struct lsa_SidArray sids;
2903 struct samr_Ids rids;
2905 torture_comment(tctx, "Testing GetAliasMembership\n");
2907 r.in.domain_handle = domain_handle;
2912 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2914 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2915 "GetAliasMembership failed");
2916 torture_assert_ntstatus_ok(tctx, r.out.result,
2917 "samr_GetAliasMembership failed");
2919 torture_assert_int_equal(tctx, sids.num_sids, rids.count,
2920 "protocol misbehaviour");
2923 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2924 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2926 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2927 "samr_GetAliasMembership failed");
2928 torture_assert_ntstatus_ok(tctx, r.out.result,
2929 "samr_GetAliasMembership failed");
2932 /* only true for w2k8 it seems
2933 * win7, xp, w2k3 will return a 0 length array pointer */
2935 if (rids.ids && (rids.count == 0)) {
2936 torture_fail(tctx, "samr_GetAliasMembership returned 0 count and a rids array");
2939 if (!rids.ids && rids.count) {
2940 torture_fail(tctx, "samr_GetAliasMembership returned non-0 count but no rids");
2946 static bool test_TestPrivateFunctionsUser(struct dcerpc_binding_handle *b,
2947 struct torture_context *tctx,
2948 struct policy_handle *user_handle)
2950 struct samr_TestPrivateFunctionsUser r;
2952 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2954 r.in.user_handle = user_handle;
2956 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsUser_r(b, tctx, &r),
2957 "TestPrivateFunctionsUser failed");
2958 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2963 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_binding_handle *b,
2964 struct torture_context *tctx,
2965 struct policy_handle *handle,
2970 uint16_t levels[] = { /* 3, */ 5, 21 };
2972 /* NTTIME pwdlastset3 = 0; */
2973 NTTIME pwdlastset5 = 0;
2974 NTTIME pwdlastset21 = 0;
2976 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2977 use_info2 ? "2":"");
2979 for (i=0; i<ARRAY_SIZE(levels); i++) {
2981 struct samr_QueryUserInfo r;
2982 struct samr_QueryUserInfo2 r2;
2983 union samr_UserInfo *info;
2986 r2.in.user_handle = handle;
2987 r2.in.level = levels[i];
2988 r2.out.info = &info;
2989 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r2),
2990 "QueryUserInfo2 failed");
2991 status = r2.out.result;
2994 r.in.user_handle = handle;
2995 r.in.level = levels[i];
2997 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
2998 "QueryUserInfo failed");
2999 status = r.out.result;
3002 if (!NT_STATUS_IS_OK(status) &&
3003 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
3004 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo%s level %u failed - %s\n",
3005 use_info2 ? "2":"", levels[i], nt_errstr(status));
3009 switch (levels[i]) {
3011 /* pwdlastset3 = info->info3.last_password_change; */
3014 pwdlastset5 = info->info5.last_password_change;
3017 pwdlastset21 = info->info21.last_password_change;
3023 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
3024 "pwdlastset mixup"); */
3025 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
3026 "pwdlastset mixup");
3028 *pwdlastset = pwdlastset21;
3030 torture_comment(tctx, "(pwdlastset: %llu)\n",
3031 (unsigned long long) *pwdlastset);
3036 static bool test_SamLogon(struct torture_context *tctx,
3037 struct dcerpc_pipe *p,
3038 struct cli_credentials *machine_credentials,
3039 struct cli_credentials *test_credentials,
3040 NTSTATUS expected_result,
3044 struct netr_LogonSamLogonEx r;
3045 union netr_LogonLevel logon;
3046 union netr_Validation validation;
3047 uint8_t authoritative;
3048 struct netr_IdentityInfo identity;
3049 struct netr_NetworkInfo ninfo;
3050 struct netr_PasswordInfo pinfo;
3051 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
3052 int flags = CLI_CRED_NTLM_AUTH;
3053 uint32_t samlogon_flags = 0;
3054 struct netlogon_creds_CredentialState *creds;
3055 struct netr_Authenticator a;
3056 struct dcerpc_binding_handle *b = p->binding_handle;
3058 torture_assert(tctx, (creds = cli_credentials_get_netlogon_creds(machine_credentials)), "");
3060 if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
3061 flags |= CLI_CRED_LANMAN_AUTH;
3064 if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx)) {
3065 flags |= CLI_CRED_NTLMv2_AUTH;
3068 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
3069 &identity.account_name.string,
3070 &identity.domain_name.string);
3072 identity.parameter_control =
3073 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
3074 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
3075 identity.logon_id_low = 0;
3076 identity.logon_id_high = 0;
3077 identity.workstation.string = cli_credentials_get_workstation(test_credentials);
3080 netlogon_creds_client_authenticator(creds, &a);
3082 if (!E_deshash(cli_credentials_get_password(test_credentials), pinfo.lmpassword.hash)) {
3083 ZERO_STRUCT(pinfo.lmpassword.hash);
3085 E_md4hash(cli_credentials_get_password(test_credentials), pinfo.ntpassword.hash);
3087 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
3088 netlogon_creds_aes_encrypt(creds, pinfo.lmpassword.hash, 16);
3089 netlogon_creds_aes_encrypt(creds, pinfo.ntpassword.hash, 16);
3090 } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
3091 netlogon_creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
3092 netlogon_creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
3094 netlogon_creds_des_encrypt(creds, &pinfo.lmpassword);
3095 netlogon_creds_des_encrypt(creds, &pinfo.ntpassword);
3098 pinfo.identity_info = identity;
3099 logon.password = &pinfo;
3101 r.in.logon_level = NetlogonInteractiveInformation;
3103 generate_random_buffer(ninfo.challenge,
3104 sizeof(ninfo.challenge));
3105 chal = data_blob_const(ninfo.challenge,
3106 sizeof(ninfo.challenge));
3108 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
3109 cli_credentials_get_domain(test_credentials));
3111 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
3117 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
3119 ninfo.lm.data = lm_resp.data;
3120 ninfo.lm.length = lm_resp.length;
3122 ninfo.nt.data = nt_resp.data;
3123 ninfo.nt.length = nt_resp.length;
3125 ninfo.identity_info = identity;
3126 logon.network = &ninfo;
3128 r.in.logon_level = NetlogonNetworkInformation;
3131 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3132 r.in.computer_name = cli_credentials_get_workstation(test_credentials);
3133 r.in.logon = &logon;
3134 r.in.flags = &samlogon_flags;
3135 r.out.flags = &samlogon_flags;
3136 r.out.validation = &validation;
3137 r.out.authoritative = &authoritative;
3139 torture_comment(tctx, "Testing LogonSamLogon with name %s\n", identity.account_name.string);
3141 r.in.validation_level = 6;
3143 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
3144 "netr_LogonSamLogonEx failed");
3145 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
3146 r.in.validation_level = 3;
3147 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
3148 "netr_LogonSamLogonEx failed");
3150 if (!NT_STATUS_IS_OK(r.out.result)) {
3151 torture_assert_ntstatus_equal(tctx, r.out.result, expected_result, "LogonSamLogonEx failed");
3154 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogonEx failed");
3160 static bool test_SamLogon_with_creds(struct torture_context *tctx,
3161 struct dcerpc_pipe *p,
3162 struct cli_credentials *machine_creds,
3163 const char *acct_name,
3164 const char *password,
3165 NTSTATUS expected_samlogon_result,
3169 struct cli_credentials *test_credentials;
3171 test_credentials = cli_credentials_init(tctx);
3173 cli_credentials_set_workstation(test_credentials,
3174 cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
3175 cli_credentials_set_domain(test_credentials,
3176 cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
3177 cli_credentials_set_username(test_credentials,
3178 acct_name, CRED_SPECIFIED);
3179 cli_credentials_set_password(test_credentials,
3180 password, CRED_SPECIFIED);
3182 torture_comment(tctx, "Testing samlogon (%s) as %s password: %s\n",
3183 interactive ? "interactive" : "network", acct_name, password);
3185 if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
3186 expected_samlogon_result, interactive)) {
3187 torture_result(tctx, TORTURE_FAIL, "new password did not work\n");
3194 static bool test_SetPassword_level(struct dcerpc_pipe *p,
3195 struct dcerpc_pipe *np,
3196 struct torture_context *tctx,
3197 struct policy_handle *handle,
3199 uint32_t fields_present,
3200 uint8_t password_expired,
3201 bool *matched_expected_error,
3203 const char *acct_name,
3205 struct cli_credentials *machine_creds,
3206 bool use_queryinfo2,
3208 NTSTATUS expected_samlogon_result)
3210 const char *fields = NULL;
3212 struct dcerpc_binding_handle *b = p->binding_handle;
3218 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
3225 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
3226 "(password_expired: %d) %s\n",
3227 use_setinfo2 ? "2":"", level, password_expired,
3228 fields ? fields : "");
3230 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
3235 matched_expected_error)) {
3239 if (!test_QueryUserInfo_pwdlastset(b, tctx, handle,
3245 if (*matched_expected_error == true) {
3249 if (!test_SamLogon_with_creds(tctx, np,
3253 expected_samlogon_result,
3261 static bool setup_schannel_netlogon_pipe(struct torture_context *tctx,
3262 struct cli_credentials *credentials,
3263 struct dcerpc_pipe **p)
3265 struct dcerpc_binding *b;
3268 torture_assert_ntstatus_ok(tctx, torture_rpc_binding(tctx, &b),
3269 "failed to get rpc binding");
3271 /* We have to use schannel, otherwise the SamLogonEx fails
3272 * with INTERNAL_ERROR */
3274 status = dcerpc_binding_set_flags(b,
3275 DCERPC_SCHANNEL | DCERPC_SIGN |
3276 DCERPC_SCHANNEL_AUTO,
3277 DCERPC_AUTH_OPTIONS);
3278 torture_assert_ntstatus_ok(tctx, status, "set flags");
3280 torture_assert_ntstatus_ok(tctx,
3281 dcerpc_pipe_connect_b(tctx, p, b, &ndr_table_netlogon,
3282 credentials, tctx->ev, tctx->lp_ctx),
3283 "failed to bind to netlogon");
3288 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
3289 struct torture_context *tctx,
3290 uint32_t acct_flags,
3291 const char *acct_name,
3292 struct policy_handle *handle,
3294 struct cli_credentials *machine_credentials)
3296 int s = 0, q = 0, f = 0, l = 0, z = 0;
3299 bool set_levels[] = { false, true };
3300 bool query_levels[] = { false, true };
3301 uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
3302 uint32_t nonzeros[] = { 1, 24 };
3303 uint32_t fields_present[] = {
3305 SAMR_FIELD_EXPIRED_FLAG,
3306 SAMR_FIELD_LAST_PWD_CHANGE,
3307 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
3309 SAMR_FIELD_NT_PASSWORD_PRESENT,
3310 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3311 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3312 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3313 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3314 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3315 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
3317 struct dcerpc_pipe *np = NULL;
3319 if (torture_setting_bool(tctx, "samba3", false) ||
3320 torture_setting_bool(tctx, "samba4", false)) {
3322 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
3326 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3328 /* set to 1 to enable testing for all possible opcode
3329 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3332 #define TEST_ALL_LEVELS 1
3333 #define TEST_SET_LEVELS 1
3334 #define TEST_QUERY_LEVELS 1
3336 #ifdef TEST_ALL_LEVELS
3337 for (l=0; l<ARRAY_SIZE(levels); l++) {
3339 for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
3341 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
3342 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
3343 #ifdef TEST_SET_LEVELS
3344 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
3346 #ifdef TEST_QUERY_LEVELS
3347 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
3349 NTTIME pwdlastset_old = 0;
3350 NTTIME pwdlastset_new = 0;
3351 bool matched_expected_error = false;
3352 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
3354 torture_comment(tctx, "------------------------------\n"
3355 "Testing pwdLastSet attribute for flags: 0x%08x "
3356 "(s: %d (l: %d), q: %d)\n",
3357 acct_flags, s, levels[l], q);
3359 switch (levels[l]) {
3363 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3364 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
3365 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
3373 /* set a password and force password change (pwdlastset 0) by
3374 * setting the password expired flag to a non-0 value */
3376 if (!test_SetPassword_level(p, np, tctx, handle,
3380 &matched_expected_error,
3384 machine_credentials,
3387 expected_samlogon_result)) {
3391 if (matched_expected_error == true) {
3392 /* skipping on expected failure */
3396 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3397 * set without the SAMR_FIELD_EXPIRED_FLAG */
3399 switch (levels[l]) {
3403 if ((pwdlastset_new != 0) &&
3404 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3405 torture_comment(tctx, "not considering a non-0 "
3406 "pwdLastSet as a an error as the "
3407 "SAMR_FIELD_EXPIRED_FLAG has not "
3413 if (pwdlastset_new != 0) {
3414 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3415 "expected pwdLastSet 0 but got %llu\n",
3416 (unsigned long long) pwdlastset_old);
3422 switch (levels[l]) {
3426 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3427 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3428 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3429 (pwdlastset_old >= pwdlastset_new)) {
3430 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3436 pwdlastset_old = pwdlastset_new;
3442 /* set a password, pwdlastset needs to get updated (increased
3443 * value), password_expired value used here is 0 */
3445 if (!test_SetPassword_level(p, np, tctx, handle,
3449 &matched_expected_error,
3453 machine_credentials,
3456 expected_samlogon_result)) {
3460 /* when a password has been changed, pwdlastset must not be 0 afterwards
3461 * and must be larger then the old value */
3463 switch (levels[l]) {
3467 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3468 * password has been changed, old and new pwdlastset
3469 * need to be the same value */
3471 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3472 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3473 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3475 torture_assert_int_equal(tctx, pwdlastset_old,
3476 pwdlastset_new, "pwdlastset must be equal");
3481 if (pwdlastset_old >= pwdlastset_new) {
3482 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3483 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3484 (unsigned long long) pwdlastset_old,
3485 (unsigned long long) pwdlastset_new);
3488 if (pwdlastset_new == 0) {
3489 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3490 "expected non-0 pwdlastset, got: %llu\n",
3491 (unsigned long long) pwdlastset_new);
3497 switch (levels[l]) {
3501 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3502 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3503 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3504 (pwdlastset_old >= pwdlastset_new)) {
3505 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3511 pwdlastset_old = pwdlastset_new;
3517 /* set a password, pwdlastset needs to get updated (increased
3518 * value), password_expired value used here is 0 */
3520 if (!test_SetPassword_level(p, np, tctx, handle,
3524 &matched_expected_error,
3528 machine_credentials,
3531 expected_samlogon_result)) {
3535 /* when a password has been changed, pwdlastset must not be 0 afterwards
3536 * and must be larger then the old value */
3538 switch (levels[l]) {
3543 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3544 * password has been changed, old and new pwdlastset
3545 * need to be the same value */
3547 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3548 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3549 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3551 torture_assert_int_equal(tctx, pwdlastset_old,
3552 pwdlastset_new, "pwdlastset must be equal");
3557 if (pwdlastset_old >= pwdlastset_new) {
3558 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3559 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3560 (unsigned long long) pwdlastset_old,
3561 (unsigned long long) pwdlastset_new);
3564 if (pwdlastset_new == 0) {
3565 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3566 "expected non-0 pwdlastset, got: %llu\n",
3567 (unsigned long long) pwdlastset_new);
3573 switch (levels[l]) {
3577 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3578 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3579 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3580 (pwdlastset_old >= pwdlastset_new)) {
3581 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3587 pwdlastset_old = pwdlastset_new;
3593 /* set a password and force password change (pwdlastset 0) by
3594 * setting the password expired flag to a non-0 value */
3596 if (!test_SetPassword_level(p, np, tctx, handle,
3600 &matched_expected_error,
3604 machine_credentials,
3607 expected_samlogon_result)) {
3611 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3612 * set without the SAMR_FIELD_EXPIRED_FLAG */
3614 switch (levels[l]) {
3618 if ((pwdlastset_new != 0) &&
3619 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3620 torture_comment(tctx, "not considering a non-0 "
3621 "pwdLastSet as a an error as the "
3622 "SAMR_FIELD_EXPIRED_FLAG has not "
3627 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3628 * password has been changed, old and new pwdlastset
3629 * need to be the same value */
3631 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3632 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3633 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3635 torture_assert_int_equal(tctx, pwdlastset_old,
3636 pwdlastset_new, "pwdlastset must be equal");
3641 if (pwdlastset_new != 0) {
3642 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3643 "expected pwdLastSet 0, got %llu\n",
3644 (unsigned long long) pwdlastset_old);
3650 switch (levels[l]) {
3654 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3655 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3656 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3657 (pwdlastset_old >= pwdlastset_new)) {
3658 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3664 /* if the level we are testing does not have a fields_present
3665 * field, skip all fields present tests by setting f to to
3667 switch (levels[l]) {
3671 f = ARRAY_SIZE(fields_present);
3675 #ifdef TEST_QUERY_LEVELS
3678 #ifdef TEST_SET_LEVELS
3681 } /* fields present */
3685 #undef TEST_SET_LEVELS
3686 #undef TEST_QUERY_LEVELS
3693 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_binding_handle *b,
3694 struct torture_context *tctx,
3695 struct policy_handle *handle,
3696 uint32_t *badpwdcount)
3698 union samr_UserInfo *info;
3699 struct samr_QueryUserInfo r;
3701 r.in.user_handle = handle;
3705 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3707 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3708 "failed to query userinfo");
3709 torture_assert_ntstatus_ok(tctx, r.out.result,
3710 "failed to query userinfo");
3712 *badpwdcount = info->info3.bad_password_count;
3714 torture_comment(tctx, " (bad password count: %d)\n", *badpwdcount);
3719 static bool test_SetUserInfo_acct_flags(struct dcerpc_binding_handle *b,
3720 struct torture_context *tctx,
3721 struct policy_handle *user_handle,
3722 uint32_t acct_flags)
3724 struct samr_SetUserInfo r;
3725 union samr_UserInfo user_info;
3727 torture_comment(tctx, "Testing SetUserInfo level 16\n");
3729 user_info.info16.acct_flags = acct_flags;
3731 r.in.user_handle = user_handle;
3733 r.in.info = &user_info;
3735 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &r),
3736 "failed to set account flags");
3737 torture_assert_ntstatus_ok(tctx, r.out.result,
3738 "failed to set account flags");
3743 static bool test_reset_badpwdcount(struct dcerpc_pipe *p,
3744 struct torture_context *tctx,
3745 struct policy_handle *user_handle,
3746 uint32_t acct_flags,
3749 struct dcerpc_binding_handle *b = p->binding_handle;
3751 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3752 "failed to set password");
3754 torture_comment(tctx, "Testing SetUserInfo level 16 (enable account)\n");
3756 torture_assert(tctx,
3757 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3758 acct_flags & ~ACB_DISABLED),
3759 "failed to enable user");
3761 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3762 "failed to set password");
3767 static bool test_SetDomainInfo(struct dcerpc_binding_handle *b,
3768 struct torture_context *tctx,
3769 struct policy_handle *domain_handle,
3770 enum samr_DomainInfoClass level,
3771 union samr_DomainInfo *info)
3773 struct samr_SetDomainInfo r;
3775 r.in.domain_handle = domain_handle;
3779 torture_assert_ntstatus_ok(tctx,
3780 dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3781 "failed to set domain info");
3782 torture_assert_ntstatus_ok(tctx, r.out.result,
3783 "failed to set domain info");
3788 static bool test_SetDomainInfo_ntstatus(struct dcerpc_binding_handle *b,
3789 struct torture_context *tctx,
3790 struct policy_handle *domain_handle,
3791 enum samr_DomainInfoClass level,
3792 union samr_DomainInfo *info,
3795 struct samr_SetDomainInfo r;
3797 r.in.domain_handle = domain_handle;
3801 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3802 "SetDomainInfo failed");
3803 torture_assert_ntstatus_equal(tctx, r.out.result, expected, "");
3808 static bool test_QueryDomainInfo2_level(struct dcerpc_binding_handle *b,
3809 struct torture_context *tctx,
3810 struct policy_handle *domain_handle,
3811 enum samr_DomainInfoClass level,
3812 union samr_DomainInfo **q_info)
3814 struct samr_QueryDomainInfo2 r;
3816 r.in.domain_handle = domain_handle;
3818 r.out.info = q_info;
3820 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
3821 "failed to query domain info");
3822 torture_assert_ntstatus_ok(tctx, r.out.result,
3823 "failed to query domain info");
3828 static bool test_Password_badpwdcount(struct dcerpc_pipe *p,
3829 struct dcerpc_pipe *np,
3830 struct torture_context *tctx,
3831 uint32_t acct_flags,
3832 const char *acct_name,
3833 struct policy_handle *domain_handle,
3834 struct policy_handle *user_handle,
3836 struct cli_credentials *machine_credentials,
3837 const char *comment,
3840 NTSTATUS expected_success_status,
3841 struct samr_DomInfo1 *info1,
3842 struct samr_DomInfo12 *info12)
3844 union samr_DomainInfo info;
3847 uint32_t badpwdcount, tmp;
3848 uint32_t password_history_length = 12;
3849 uint32_t lockout_threshold = 15;
3850 uint32_t lockout_seconds = 5;
3851 uint64_t delta_time_factor = 10 * 1000 * 1000;
3852 struct dcerpc_binding_handle *b = p->binding_handle;
3854 if (torture_setting_bool(tctx, "samba3", false)) {
3855 lockout_seconds = 60;
3858 torture_comment(tctx, "\nTesting bad pwd count with: %s\n", comment);
3860 torture_assert(tctx, password_history_length < lockout_threshold,
3861 "password history length needs to be smaller than account lockout threshold for this test");
3866 info.info1 = *info1;
3867 info.info1.password_history_length = password_history_length;
3868 info.info1.min_password_age = 0;
3870 torture_assert(tctx,
3871 test_SetDomainInfo(b, tctx, domain_handle,
3872 DomainPasswordInformation, &info),
3873 "failed to set password history length and min passwd age");
3875 info.info12 = *info12;
3876 info.info12.lockout_threshold = lockout_threshold;
3878 /* set lockout duration of 5 seconds */
3879 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
3880 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
3882 torture_assert(tctx,
3883 test_SetDomainInfo(b, tctx, domain_handle,
3884 DomainLockoutInformation, &info),
3885 "failed to set lockout threshold");
3887 /* reset bad pwd count */
3889 torture_assert(tctx,
3890 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
3893 /* enable or disable account */
3895 torture_assert(tctx,
3896 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3897 acct_flags | ACB_DISABLED),
3898 "failed to disable user");
3900 torture_assert(tctx,
3901 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3902 acct_flags & ~ACB_DISABLED),
3903 "failed to enable user");
3907 /* setup password history */
3909 passwords = talloc_array(tctx, char *, password_history_length);
3911 for (i=0; i < password_history_length; i++) {
3913 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3914 "failed to set password");
3915 passwords[i] = talloc_strdup(tctx, *password);
3917 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3918 acct_name, passwords[i],
3919 expected_success_status, interactive)) {
3920 torture_fail(tctx, "failed to auth with latest password");
3923 torture_assert(tctx,
3924 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3926 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3930 /* test with wrong password */
3932 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3933 acct_name, "random_crap",
3934 NT_STATUS_WRONG_PASSWORD, interactive)) {
3935 torture_fail(tctx, "succeeded to authenticate with wrong password");
3938 torture_assert(tctx,
3939 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3941 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3944 /* test with latest good password */
3946 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
3947 passwords[password_history_length-1],
3948 expected_success_status, interactive)) {
3949 torture_fail(tctx, "succeeded to authenticate with wrong password");
3952 torture_assert(tctx,
3953 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3956 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3958 /* only enabled accounts get the bad pwd count reset upon
3959 * successful logon */
3960 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3966 /* test password history */
3968 for (i=0; i < password_history_length; i++) {
3970 torture_comment(tctx, "Testing bad password count behavior with "
3971 "password #%d of #%d\n", i, password_history_length);
3973 /* - network samlogon will succeed auth and not
3974 * increase badpwdcount for 2 last entries
3975 * - interactive samlogon only for the last one */
3977 if (i == password_history_length - 1 ||
3978 (i == password_history_length - 2 && !interactive)) {
3980 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3981 acct_name, passwords[i],
3982 expected_success_status, interactive)) {
3983 torture_fail(tctx, talloc_asprintf(tctx, "did not successfully to obtain %s for %s login with old password (#%d of #%d in history)",
3984 nt_errstr(expected_success_status),
3985 interactive ? "interactive" : "network", i, password_history_length));
3988 torture_assert(tctx,
3989 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3992 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
3993 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3995 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
3996 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
4004 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4005 acct_name, passwords[i],
4006 NT_STATUS_WRONG_PASSWORD, interactive)) {
4007 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
4010 torture_assert(tctx,
4011 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4013 /* - network samlogon will fail auth but not increase
4014 * badpwdcount for 3rd last entry
4015 * - interactive samlogon for 3rd and 2nd last entry */
4017 if (i == password_history_length - 3 ||
4018 (i == password_history_length - 2 && interactive)) {
4019 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
4020 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
4022 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
4023 torture_assert_int_equal(tctx, badpwdcount, tmp + 1, "unexpected badpwdcount");
4032 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe *p,
4033 struct torture_context *tctx,
4034 uint32_t acct_flags,
4035 const char *acct_name,
4036 struct policy_handle *domain_handle,
4037 struct policy_handle *user_handle,
4039 struct cli_credentials *machine_credentials)
4041 union samr_DomainInfo *q_info, s_info;
4042 struct samr_DomInfo1 info1, _info1;
4043 struct samr_DomInfo12 info12, _info12;
4045 struct dcerpc_binding_handle *b = p->binding_handle;
4046 struct dcerpc_pipe *np;
4050 const char *comment;
4053 NTSTATUS expected_success_status;
4056 .comment = "network logon (disabled account)",
4058 .interactive = false,
4059 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4062 .comment = "network logon (enabled account)",
4064 .interactive = false,
4065 .expected_success_status= NT_STATUS_OK
4068 .comment = "interactive logon (disabled account)",
4070 .interactive = true,
4071 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4074 .comment = "interactive logon (enabled account)",
4076 .interactive = true,
4077 .expected_success_status= NT_STATUS_OK
4081 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4083 /* backup old policies */
4085 torture_assert(tctx,
4086 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4087 DomainPasswordInformation, &q_info),
4088 "failed to query domain info level 1");
4090 info1 = q_info->info1;
4093 torture_assert(tctx,
4094 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4095 DomainLockoutInformation, &q_info),
4096 "failed to query domain info level 12");
4098 info12 = q_info->info12;
4103 for (i=0; i < ARRAY_SIZE(creds); i++) {
4105 /* skip trust tests for now */
4106 if (acct_flags & ACB_WSTRUST ||
4107 acct_flags & ACB_SVRTRUST ||
4108 acct_flags & ACB_DOMTRUST) {
4112 if (!test_Password_badpwdcount(p, np, tctx, acct_flags, acct_name,
4113 domain_handle, user_handle, password,
4114 machine_credentials,
4117 creds[i].interactive,
4118 creds[i].expected_success_status,
4119 &_info1, &_info12)) {
4120 torture_result(tctx, TORTURE_FAIL, "TEST #%d (%s) failed\n", i, creds[i].comment);
4123 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4127 /* restore policies */
4129 s_info.info1 = info1;
4131 torture_assert(tctx,
4132 test_SetDomainInfo(b, tctx, domain_handle,
4133 DomainPasswordInformation, &s_info),
4134 "failed to set password information");
4136 s_info.info12 = info12;
4138 torture_assert(tctx,
4139 test_SetDomainInfo(b, tctx, domain_handle,
4140 DomainLockoutInformation, &s_info),
4141 "failed to set lockout information");
4146 static bool test_QueryUserInfo_lockout(struct dcerpc_binding_handle *b,
4147 struct torture_context *tctx,
4148 struct policy_handle *domain_handle,
4149 const char *acct_name,
4150 uint16_t raw_bad_password_count,
4151 uint16_t effective_bad_password_count,
4152 uint32_t effective_acb_lockout)
4154 struct policy_handle user_handle;
4155 union samr_UserInfo *i;
4156 struct samr_QueryUserInfo r;
4158 NTSTATUS status = test_OpenUser_byname(b, tctx, domain_handle, acct_name, &user_handle);
4159 if (!NT_STATUS_IS_OK(status)) {
4163 r.in.user_handle = &user_handle;
4166 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4167 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4168 "failed to query userinfo");
4169 torture_assert_ntstatus_ok(tctx, r.out.result,
4170 "failed to query userinfo");
4171 torture_comment(tctx, " (acct_flags: 0x%08x) (raw_bad_pwd_count: %u)\n",
4172 i->info3.acct_flags, i->info3.bad_password_count);
4173 torture_assert_int_equal(tctx, i->info3.bad_password_count,
4174 raw_bad_password_count,
4176 torture_assert_int_equal(tctx, i->info3.acct_flags & ACB_AUTOLOCK,
4177 effective_acb_lockout,
4178 "effective acb_lockout");
4181 r.in.user_handle = &user_handle;
4184 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4185 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4186 "failed to query userinfo");
4187 torture_assert_ntstatus_ok(tctx, r.out.result,
4188 "failed to query userinfo");
4189 torture_comment(tctx, " (acct_flags: 0x%08x) (effective_bad_pwd_count: %u)\n",
4190 i->info5.acct_flags, i->info5.bad_password_count);
4191 torture_assert_int_equal(tctx, i->info5.bad_password_count,
4192 effective_bad_password_count,
4193 "effective badpwdcount");
4194 torture_assert_int_equal(tctx, i->info5.acct_flags & ACB_AUTOLOCK,
4195 effective_acb_lockout,
4196 "effective acb_lockout");
4199 r.in.user_handle = &user_handle;
4202 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4203 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4204 "failed to query userinfo");
4205 torture_assert_ntstatus_ok(tctx, r.out.result,
4206 "failed to query userinfo");
4207 torture_comment(tctx, " (acct_flags: 0x%08x)\n",
4208 i->info16.acct_flags);
4209 torture_assert_int_equal(tctx, i->info16.acct_flags & ACB_AUTOLOCK,
4210 effective_acb_lockout,
4211 "effective acb_lockout");
4214 r.in.user_handle = &user_handle;
4217 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4218 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4219 "failed to query userinfo");
4220 torture_assert_ntstatus_ok(tctx, r.out.result,
4221 "failed to query userinfo");
4222 torture_comment(tctx, " (acct_flags: 0x%08x) (effective_bad_pwd_count: %u)\n",
4223 i->info21.acct_flags, i->info21.bad_password_count);
4224 torture_assert_int_equal(tctx, i->info21.bad_password_count,
4225 effective_bad_password_count,
4226 "effective badpwdcount");
4227 torture_assert_int_equal(tctx, i->info21.acct_flags & ACB_AUTOLOCK,
4228 effective_acb_lockout,
4229 "effective acb_lockout");
4232 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
4239 static bool test_Password_lockout(struct dcerpc_pipe *p,
4240 struct dcerpc_pipe *np,
4241 struct torture_context *tctx,
4242 uint32_t acct_flags,
4243 const char *acct_name,
4244 struct policy_handle *domain_handle,
4245 struct policy_handle *user_handle,
4247 struct cli_credentials *machine_credentials,
4248 const char *comment,
4251 uint32_t password_history_length,
4252 NTSTATUS expected_success_status,
4253 struct samr_DomInfo1 *info1,
4254 struct samr_DomInfo12 *info12)
4256 union samr_DomainInfo info;
4257 uint64_t lockout_threshold = 1;
4258 uint32_t lockout_seconds = 5;
4259 uint64_t delta_time_factor = 10 * 1000 * 1000;
4260 struct dcerpc_binding_handle *b = p->binding_handle;
4262 if (torture_setting_bool(tctx, "samba3", false)) {
4263 lockout_seconds = 60;
4266 torture_comment(tctx, "\nTesting account lockout: %s\n", comment);
4270 info.info1 = *info1;
4272 torture_comment(tctx, "setting password history length to %d.\n", password_history_length);
4273 info.info1.password_history_length = password_history_length;
4275 torture_comment(tctx, "setting min password again.\n");
4276 info.info1.min_password_age = 0;
4278 torture_assert(tctx,
4279 test_SetDomainInfo(b, tctx, domain_handle,
4280 DomainPasswordInformation, &info),
4281 "failed to set password history length");
4283 info.info12 = *info12;
4284 info.info12.lockout_threshold = lockout_threshold;
4286 /* set lockout duration < lockout window: should fail */
4287 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4288 info.info12.lockout_window = ~((lockout_seconds + 1) * delta_time_factor);
4290 torture_assert(tctx,
4291 test_SetDomainInfo_ntstatus(b, tctx, domain_handle,
4292 DomainLockoutInformation, &info,
4293 NT_STATUS_INVALID_PARAMETER),
4294 "setting lockout duration < lockout window gave unexpected result");
4296 info.info12.lockout_duration = 0;
4297 info.info12.lockout_window = 0;
4299 torture_assert(tctx,
4300 test_SetDomainInfo(b, tctx, domain_handle,
4301 DomainLockoutInformation, &info),
4302 "failed to set lockout window and duration to 0");
4305 /* set lockout duration of 5 seconds */
4306 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4307 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
4309 torture_assert(tctx,
4310 test_SetDomainInfo(b, tctx, domain_handle,
4311 DomainLockoutInformation, &info),
4312 "failed to set lockout window and duration to 5 seconds");
4314 /* reset bad pwd count */
4316 torture_assert(tctx,
4317 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
4320 /* enable or disable account */
4323 torture_assert(tctx,
4324 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4325 acct_flags | ACB_DISABLED),
4326 "failed to disable user");
4328 torture_assert(tctx,
4329 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4330 acct_flags & ~ACB_DISABLED),
4331 "failed to enable user");
4335 /* test logon with right password */
4337 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4338 acct_name, *password,
4339 expected_success_status, interactive)) {
4340 torture_fail(tctx, "failed to auth with latest password");
4343 torture_assert(tctx,
4344 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4346 "expected account to not be locked");
4348 /* test with wrong password ==> lockout */
4350 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4351 acct_name, "random_crap",
4352 NT_STATUS_WRONG_PASSWORD, interactive)) {
4353 torture_fail(tctx, "succeeded to authenticate with wrong password");
4357 * curiously, windows does _not_ return fresh values of
4358 * effective bad_password_count and ACB_AUTOLOCK.
4360 torture_assert(tctx,
4361 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4362 1, 1, ACB_AUTOLOCK),
4363 "expected account to not be locked");
4365 /* test with good password */
4367 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4369 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4371 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4374 /* bad pwd count should not get updated */
4375 torture_assert(tctx,
4376 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4377 1, 1, ACB_AUTOLOCK),
4378 "expected account to be locked");
4380 torture_assert(tctx,
4381 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, *password,
4382 NT_STATUS_ACCOUNT_LOCKED_OUT),
4383 "got wrong status from ChangePasswordUser2");
4385 /* bad pwd count should not get updated */
4386 torture_assert(tctx,
4387 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4388 1, 1, ACB_AUTOLOCK),
4389 "expected account to be locked");
4391 torture_assert(tctx,
4392 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_ACCOUNT_LOCKED_OUT),
4393 "got wrong status from ChangePasswordUser2");
4395 /* bad pwd count should not get updated */
4396 torture_assert(tctx,
4397 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4398 1, 1, ACB_AUTOLOCK),
4399 "expected account to be locked");
4401 /* with bad password */
4403 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4404 acct_name, "random_crap2",
4405 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4407 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4410 /* bad pwd count should not get updated */
4411 torture_assert(tctx,
4412 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4413 1, 1, ACB_AUTOLOCK),
4414 "expected account to be locked");
4416 /* let lockout duration expire ==> unlock */
4418 torture_comment(tctx, "let lockout duration expire...\n");
4419 sleep(lockout_seconds + 1);
4421 torture_assert(tctx,
4422 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4424 "expected account to not be locked");
4426 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4428 expected_success_status, interactive))
4430 torture_fail(tctx, "failed to authenticate after lockout expired");
4433 if (NT_STATUS_IS_OK(expected_success_status)) {
4434 torture_assert(tctx,
4435 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4437 "expected account to not be locked");
4439 torture_assert(tctx,
4440 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4442 "expected account to not be locked");
4445 torture_assert(tctx,
4446 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4447 "got wrong status from ChangePasswordUser2");
4449 torture_assert(tctx,
4450 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4451 1, 1, ACB_AUTOLOCK),
4452 "expected account to be locked");
4454 torture_assert(tctx,
4455 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, *password, NT_STATUS_ACCOUNT_LOCKED_OUT),
4456 "got wrong status from ChangePasswordUser2");
4458 torture_assert(tctx,
4459 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4460 1, 1, ACB_AUTOLOCK),
4461 "expected account to be locked");
4463 torture_assert(tctx,
4464 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_ACCOUNT_LOCKED_OUT),
4465 "got wrong status from ChangePasswordUser2");
4467 torture_assert(tctx,
4468 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4469 1, 1, ACB_AUTOLOCK),
4470 "expected account to be locked");
4472 /* let lockout duration expire ==> unlock */
4474 torture_comment(tctx, "let lockout duration expire...\n");
4475 sleep(lockout_seconds + 1);
4477 torture_assert(tctx,
4478 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4480 "expected account to not be locked");
4482 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4484 expected_success_status, interactive))
4486 torture_fail(tctx, "failed to authenticate after lockout expired");
4489 if (NT_STATUS_IS_OK(expected_success_status)) {
4490 torture_assert(tctx,
4491 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4493 "expected account to not be locked");
4495 torture_assert(tctx,
4496 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4498 "expected account to not be locked");
4501 /* Testing ChangePasswordUser behaviour with 3 attempts */
4502 info.info12.lockout_threshold = 3;
4504 torture_assert(tctx,
4505 test_SetDomainInfo(b, tctx, domain_handle,
4506 DomainLockoutInformation, &info),
4507 "failed to set lockout threshold to 3");
4509 if (NT_STATUS_IS_OK(expected_success_status)) {
4510 torture_assert(tctx,
4511 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4513 "expected account to not be locked");
4515 torture_assert(tctx,
4516 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4518 "expected account to not be locked");
4521 torture_assert(tctx,
4522 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4523 "got wrong status from ChangePasswordUser2");
4525 /* bad pwd count will get updated */
4526 torture_assert(tctx,
4527 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4529 "expected account to not be locked");
4531 torture_assert(tctx,
4532 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4533 "got wrong status from ChangePasswordUser2");
4535 /* bad pwd count will get updated */
4536 torture_assert(tctx,
4537 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4539 "expected account to not be locked");
4541 torture_assert(tctx,
4542 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4543 "got wrong status from ChangePasswordUser2");
4545 /* bad pwd count should get updated */
4546 torture_assert(tctx,
4547 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4548 3, 3, ACB_AUTOLOCK),
4549 "expected account to be locked");
4551 torture_assert(tctx,
4552 test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, *password, NT_STATUS_ACCOUNT_LOCKED_OUT),
4553 "got wrong status from ChangePasswordUser2");
4555 /* bad pwd count should not get updated */
4556 torture_assert(tctx,
4557 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4558 3, 3, ACB_AUTOLOCK),
4559 "expected account to be locked");
4561 /* let lockout duration expire ==> unlock */
4563 torture_comment(tctx, "let lockout duration expire...\n");
4564 sleep(lockout_seconds + 1);
4566 torture_assert(tctx,
4567 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4569 "expected account to not be locked");
4571 torture_assert(tctx,
4572 test_ChangePasswordUser2(p, tctx, acct_name, password, NULL, false),
4573 "got wrong status from ChangePasswordUser2");
4575 torture_assert(tctx,
4576 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4578 "expected account to not be locked");
4580 /* Used to reset the badPwdCount for the other tests */
4581 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4583 expected_success_status, interactive))
4585 torture_fail(tctx, "failed to authenticate after lockout expired");
4588 if (NT_STATUS_IS_OK(expected_success_status)) {
4589 torture_assert(tctx,
4590 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4592 "expected account to not be locked");
4594 torture_assert(tctx,
4595 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4597 "expected account to not be locked");
4603 static bool test_Password_lockout_wrap(struct dcerpc_pipe *p,
4604 struct torture_context *tctx,
4605 uint32_t acct_flags,
4606 const char *acct_name,
4607 struct policy_handle *domain_handle,
4608 struct policy_handle *user_handle,
4610 struct cli_credentials *machine_credentials)
4612 union samr_DomainInfo *q_info, s_info;
4613 struct samr_DomInfo1 info1, _info1;
4614 struct samr_DomInfo12 info12, _info12;
4616 struct dcerpc_binding_handle *b = p->binding_handle;
4617 struct dcerpc_pipe *np;
4621 const char *comment;
4624 uint32_t password_history_length;
4625 NTSTATUS expected_success_status;
4628 .comment = "network logon (disabled account)",
4630 .interactive = false,
4631 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4634 .comment = "network logon (enabled account)",
4636 .interactive = false,
4637 .expected_success_status= NT_STATUS_OK
4640 .comment = "network logon (enabled account, history len = 1)",
4642 .interactive = false,
4643 .expected_success_status= NT_STATUS_OK,
4644 .password_history_length = 1
4647 .comment = "interactive logon (disabled account)",
4649 .interactive = true,
4650 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4653 .comment = "interactive logon (enabled account)",
4655 .interactive = true,
4656 .expected_success_status= NT_STATUS_OK
4659 .comment = "interactive logon (enabled account, history len = 1)",
4661 .interactive = true,
4662 .expected_success_status= NT_STATUS_OK,
4663 .password_history_length = 1
4667 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4669 /* backup old policies */
4671 torture_assert(tctx,
4672 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4673 DomainPasswordInformation, &q_info),
4674 "failed to query domain info level 1");
4676 info1 = q_info->info1;
4679 torture_assert(tctx,
4680 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4681 DomainLockoutInformation, &q_info),
4682 "failed to query domain info level 12");
4684 info12 = q_info->info12;
4689 for (i=0; i < ARRAY_SIZE(creds); i++) {
4691 /* skip trust tests for now */
4692 if (acct_flags & ACB_WSTRUST ||
4693 acct_flags & ACB_SVRTRUST ||
4694 acct_flags & ACB_DOMTRUST) {
4698 test_passed = test_Password_lockout(p, np, tctx, acct_flags, acct_name,
4699 domain_handle, user_handle, password,
4700 machine_credentials,
4703 creds[i].interactive,
4704 creds[i].password_history_length,
4705 creds[i].expected_success_status,
4709 torture_result(tctx, TORTURE_FAIL, "TEST #%d (%s) failed\n", i, creds[i].comment);
4712 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4716 /* restore policies */
4718 s_info.info1 = info1;
4720 torture_assert(tctx,
4721 test_SetDomainInfo(b, tctx, domain_handle,
4722 DomainPasswordInformation, &s_info),
4723 "failed to set password information");
4725 s_info.info12 = info12;
4727 torture_assert(tctx,
4728 test_SetDomainInfo(b, tctx, domain_handle,
4729 DomainLockoutInformation, &s_info),
4730 "failed to set lockout information");
4735 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
4736 struct dcerpc_pipe *lp,
4737 struct torture_context *tctx,
4738 struct policy_handle *domain_handle,
4739 struct policy_handle *lsa_handle,
4740 struct policy_handle *user_handle,
4741 const struct dom_sid *domain_sid,
4743 struct cli_credentials *machine_credentials)
4746 struct dcerpc_binding_handle *b = p->binding_handle;
4747 struct dcerpc_binding_handle *lb = lp->binding_handle;
4749 struct policy_handle lsa_acct_handle;
4750 struct dom_sid *user_sid;
4752 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
4755 struct lsa_EnumAccountRights r;
4756 struct lsa_RightSet rights;
4758 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4760 r.in.handle = lsa_handle;
4761 r.in.sid = user_sid;
4762 r.out.rights = &rights;
4764 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4765 "lsa_EnumAccountRights failed");
4766 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4767 "Expected enum rights for account to fail");
4771 struct lsa_RightSet rights;
4772 struct lsa_StringLarge names[2];
4773 struct lsa_AddAccountRights r;
4775 torture_comment(tctx, "Testing LSA AddAccountRights\n");
4777 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
4778 init_lsa_StringLarge(&names[1], NULL);
4781 rights.names = names;
4783 r.in.handle = lsa_handle;
4784 r.in.sid = user_sid;
4785 r.in.rights = &rights;
4787 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
4788 "lsa_AddAccountRights failed");
4789 torture_assert_ntstatus_ok(tctx, r.out.result,
4790 "Failed to add privileges");
4794 struct lsa_EnumAccounts r;
4795 uint32_t resume_handle = 0;
4796 struct lsa_SidArray lsa_sid_array;
4798 bool found_sid = false;
4800 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4802 r.in.handle = lsa_handle;
4803 r.in.num_entries = 0x1000;
4804 r.in.resume_handle = &resume_handle;
4805 r.out.sids = &lsa_sid_array;
4806 r.out.resume_handle = &resume_handle;
4808 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4809 "lsa_EnumAccounts failed");
4810 torture_assert_ntstatus_ok(tctx, r.out.result,
4811 "Failed to enum accounts");
4813 for (i=0; i < lsa_sid_array.num_sids; i++) {
4814 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4819 torture_assert(tctx, found_sid,
4820 "failed to list privileged account");
4824 struct lsa_EnumAccountRights r;
4825 struct lsa_RightSet user_rights;
4827 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4829 r.in.handle = lsa_handle;
4830 r.in.sid = user_sid;
4831 r.out.rights = &user_rights;
4833 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4834 "lsa_EnumAccountRights failed");
4835 torture_assert_ntstatus_ok(tctx, r.out.result,
4836 "Failed to enum rights for account");
4838 if (user_rights.count < 1) {
4839 torture_result(tctx, TORTURE_FAIL, "failed to find newly added rights");
4845 struct lsa_OpenAccount r;
4847 torture_comment(tctx, "Testing LSA OpenAccount\n");
4849 r.in.handle = lsa_handle;
4850 r.in.sid = user_sid;
4851 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4852 r.out.acct_handle = &lsa_acct_handle;
4854 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4855 "lsa_OpenAccount failed");
4856 torture_assert_ntstatus_ok(tctx, r.out.result,
4857 "Failed to open lsa account");
4861 struct lsa_GetSystemAccessAccount r;
4862 uint32_t access_mask;
4864 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4866 r.in.handle = &lsa_acct_handle;
4867 r.out.access_mask = &access_mask;
4869 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4870 "lsa_GetSystemAccessAccount failed");
4871 torture_assert_ntstatus_ok(tctx, r.out.result,
4872 "Failed to get lsa system access account");
4878 torture_comment(tctx, "Testing LSA Close\n");
4880 r.in.handle = &lsa_acct_handle;
4881 r.out.handle = &lsa_acct_handle;
4883 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(lb, tctx, &r),
4884 "lsa_Close failed");
4885 torture_assert_ntstatus_ok(tctx, r.out.result,
4886 "Failed to close lsa");
4890 struct samr_DeleteUser r;
4892 torture_comment(tctx, "Testing SAMR DeleteUser\n");
4894 r.in.user_handle = user_handle;
4895 r.out.user_handle = user_handle;
4897 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &r),
4898 "DeleteUser failed");
4899 torture_assert_ntstatus_ok(tctx, r.out.result,
4900 "DeleteUser failed");
4904 struct lsa_EnumAccounts r;
4905 uint32_t resume_handle = 0;
4906 struct lsa_SidArray lsa_sid_array;
4908 bool found_sid = false;
4910 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4912 r.in.handle = lsa_handle;
4913 r.in.num_entries = 0x1000;
4914 r.in.resume_handle = &resume_handle;
4915 r.out.sids = &lsa_sid_array;
4916 r.out.resume_handle = &resume_handle;
4918 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4919 "lsa_EnumAccounts failed");
4920 torture_assert_ntstatus_ok(tctx, r.out.result,
4921 "Failed to enum accounts");
4923 for (i=0; i < lsa_sid_array.num_sids; i++) {
4924 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4929 torture_assert(tctx, found_sid,
4930 "failed to list privileged account");
4934 struct lsa_EnumAccountRights r;
4935 struct lsa_RightSet user_rights;
4937 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4939 r.in.handle = lsa_handle;
4940 r.in.sid = user_sid;
4941 r.out.rights = &user_rights;
4943 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4944 "lsa_EnumAccountRights failed");
4945 torture_assert_ntstatus_ok(tctx, r.out.result,
4946 "Failed to enum rights for account");
4948 if (user_rights.count < 1) {
4949 torture_result(tctx, TORTURE_FAIL, "failed to find newly added rights");
4955 struct lsa_OpenAccount r;
4957 torture_comment(tctx, "Testing LSA OpenAccount\n");
4959 r.in.handle = lsa_handle;
4960 r.in.sid = user_sid;
4961 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4962 r.out.acct_handle = &lsa_acct_handle;
4964 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4965 "lsa_OpenAccount failed");
4966 torture_assert_ntstatus_ok(tctx, r.out.result,
4967 "Failed to open lsa account");
4971 struct lsa_GetSystemAccessAccount r;
4972 uint32_t access_mask;
4974 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4976 r.in.handle = &lsa_acct_handle;
4977 r.out.access_mask = &access_mask;
4979 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4980 "lsa_GetSystemAccessAccount failed");
4981 torture_assert_ntstatus_ok(tctx, r.out.result,
4982 "Failed to get lsa system access account");
4986 struct lsa_DeleteObject r;
4988 torture_comment(tctx, "Testing LSA DeleteObject\n");
4990 r.in.handle = &lsa_acct_handle;
4991 r.out.handle = &lsa_acct_handle;
4993 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(lb, tctx, &r),
4994 "lsa_DeleteObject failed");
4995 torture_assert_ntstatus_ok(tctx, r.out.result,
4996 "Failed to delete object");
5000 struct lsa_EnumAccounts r;
5001 uint32_t resume_handle = 0;
5002 struct lsa_SidArray lsa_sid_array;
5004 bool found_sid = false;
5006 torture_comment(tctx, "Testing LSA EnumAccounts\n");
5008 r.in.handle = lsa_handle;
5009 r.in.num_entries = 0x1000;
5010 r.in.resume_handle = &resume_handle;
5011 r.out.sids = &lsa_sid_array;
5012 r.out.resume_handle = &resume_handle;
5014 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
5015 "lsa_EnumAccounts failed");
5016 torture_assert_ntstatus_ok(tctx, r.out.result,
5017 "Failed to enum accounts");
5019 for (i=0; i < lsa_sid_array.num_sids; i++) {
5020 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
5025 torture_assert(tctx, !found_sid,
5026 "should not have listed privileged account");
5030 struct lsa_EnumAccountRights r;
5031 struct lsa_RightSet user_rights;
5033 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
5035 r.in.handle = lsa_handle;
5036 r.in.sid = user_sid;
5037 r.out.rights = &user_rights;
5039 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
5040 "lsa_EnumAccountRights failed");
5041 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
5042 "Failed to enum rights for account");
5048 static bool test_user_ops(struct dcerpc_pipe *p,
5049 struct torture_context *tctx,
5050 struct policy_handle *user_handle,
5051 struct policy_handle *domain_handle,
5052 const struct dom_sid *domain_sid,
5053 uint32_t base_acct_flags,
5054 const char *base_acct_name, enum torture_samr_choice which_ops,
5055 struct cli_credentials *machine_credentials)
5057 char *password = NULL;
5058 struct samr_QueryUserInfo q;
5059 union samr_UserInfo *info;
5061 struct dcerpc_binding_handle *b = p->binding_handle;
5066 const uint32_t password_fields[] = {
5067 SAMR_FIELD_NT_PASSWORD_PRESENT,
5068 SAMR_FIELD_LM_PASSWORD_PRESENT,
5069 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
5073 status = test_LookupName(b, tctx, domain_handle, base_acct_name, &rid);
5074 if (!NT_STATUS_IS_OK(status)) {
5078 switch (which_ops) {
5079 case TORTURE_SAMR_USER_ATTRIBUTES:
5080 if (!test_QuerySecurity(b, tctx, user_handle)) {
5084 if (!test_QueryUserInfo(b, tctx, user_handle)) {
5088 if (!test_QueryUserInfo2(b, tctx, user_handle)) {
5092 if (!test_SetUserInfo(b, tctx, user_handle, base_acct_flags,
5097 if (!test_GetUserPwInfo(b, tctx, user_handle)) {
5101 if (!test_TestPrivateFunctionsUser(b, tctx, user_handle)) {
5105 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
5109 case TORTURE_SAMR_PASSWORDS:
5110 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
5111 char simple_pass[9];
5112 char *v = generate_random_str(tctx, 1);
5114 ZERO_STRUCT(simple_pass);
5115 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5117 torture_comment(tctx, "Testing machine account password policy rules\n");
5119 /* Workstation trust accounts don't seem to need to honour password quality policy */
5120 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
5124 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
5128 /* reset again, to allow another 'user' password change */
5129 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
5133 /* Try a 'short' password */
5134 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
5138 /* Try a compleatly random password */
5139 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
5144 for (i = 0; password_fields[i]; i++) {
5145 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
5149 /* check it was set right */
5150 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5155 for (i = 0; password_fields[i]; i++) {
5156 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
5160 /* check it was set right */
5161 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5166 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
5170 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
5174 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
5178 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5182 for (i = 0; password_fields[i]; i++) {
5184 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
5185 /* we need to skip as that would break
5186 * the ChangePasswordUser3 verify */
5190 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
5194 /* check it was set right */
5195 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5200 q.in.user_handle = user_handle;
5204 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5205 "QueryUserInfo failed");
5206 if (!NT_STATUS_IS_OK(q.out.result)) {
5207 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
5208 q.in.level, nt_errstr(q.out.result));
5211 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
5212 if ((info->info5.acct_flags) != expected_flags) {
5214 if (!torture_setting_bool(tctx, "samba3", false)) {
5215 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5216 info->info5.acct_flags,
5221 if (info->info5.rid != rid) {
5222 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
5223 info->info5.rid, rid);
5230 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
5232 /* test last password change timestamp behaviour */
5233 torture_assert(tctx, test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
5235 user_handle, &password,
5236 machine_credentials),
5237 "pwdLastSet test failed\n");
5240 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
5242 /* test bad pwd count change behaviour */
5243 torture_assert(tctx, test_Password_badpwdcount_wrap(p, tctx, base_acct_flags,
5246 user_handle, &password,
5247 machine_credentials),
5248 "badPwdCount test failed\n");
5251 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
5253 torture_assert(tctx, test_Password_lockout_wrap(p, tctx, base_acct_flags,
5256 user_handle, &password,
5257 machine_credentials),
5258 "Lockout test failed");
5262 case TORTURE_SAMR_USER_PRIVILEGES: {
5264 struct dcerpc_pipe *lp;
5265 struct policy_handle *lsa_handle;
5266 struct dcerpc_binding_handle *lb;
5268 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
5269 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
5270 lb = lp->binding_handle;
5272 if (!test_lsa_OpenPolicy2(lb, tctx, &lsa_handle)) {
5276 if (!test_DeleteUser_with_privs(p, lp, tctx,
5277 domain_handle, lsa_handle, user_handle,
5279 machine_credentials)) {
5283 if (!test_lsa_Close(lb, tctx, lsa_handle)) {
5288 torture_result(tctx, TORTURE_FAIL, "privileged user delete test failed\n");
5293 case TORTURE_SAMR_OTHER:
5294 case TORTURE_SAMR_MANY_ACCOUNTS:
5295 case TORTURE_SAMR_MANY_GROUPS:
5296 case TORTURE_SAMR_MANY_ALIASES:
5297 /* We just need the account to exist */
5303 static bool test_alias_ops(struct dcerpc_binding_handle *b,
5304 struct torture_context *tctx,
5305 struct policy_handle *alias_handle,
5306 const struct dom_sid *domain_sid)
5310 if (!torture_setting_bool(tctx, "samba3", false)) {
5311 if (!test_QuerySecurity(b, tctx, alias_handle)) {
5316 if (!test_QueryAliasInfo(b, tctx, alias_handle)) {
5320 if (!test_SetAliasInfo(b, tctx, alias_handle)) {
5324 if (!test_AddMemberToAlias(b, tctx, alias_handle, domain_sid)) {
5328 if (torture_setting_bool(tctx, "samba3", false) ||
5329 torture_setting_bool(tctx, "samba4", false)) {
5330 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
5334 if (!test_AddMultipleMembersToAlias(b, tctx, alias_handle)) {
5342 static bool test_DeleteUser(struct dcerpc_binding_handle *b,
5343 struct torture_context *tctx,
5344 struct policy_handle *user_handle)
5346 struct samr_DeleteUser d;
5347 torture_comment(tctx, "Testing DeleteUser\n");
5349 d.in.user_handle = user_handle;
5350 d.out.user_handle = user_handle;
5352 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
5353 "DeleteUser failed");
5354 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteUser");
5359 bool test_DeleteUser_byname(struct dcerpc_binding_handle *b,
5360 struct torture_context *tctx,
5361 struct policy_handle *handle, const char *name)
5364 struct samr_DeleteUser d;
5365 struct policy_handle user_handle;
5368 status = test_LookupName(b, tctx, handle, name, &rid);
5369 if (!NT_STATUS_IS_OK(status)) {
5373 status = test_OpenUser_byname(b, tctx, handle, name, &user_handle);
5374 if (!NT_STATUS_IS_OK(status)) {
5378 d.in.user_handle = &user_handle;
5379 d.out.user_handle = &user_handle;
5380 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
5381 "DeleteUser failed");
5382 if (!NT_STATUS_IS_OK(d.out.result)) {
5383 status = d.out.result;
5390 torture_result(tctx, TORTURE_FAIL, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
5395 static bool test_DeleteGroup_byname(struct dcerpc_binding_handle *b,
5396 struct torture_context *tctx,
5397 struct policy_handle *handle, const char *name)
5400 struct samr_OpenGroup r;
5401 struct samr_DeleteDomainGroup d;
5402 struct policy_handle group_handle;
5405 status = test_LookupName(b, tctx, handle, name, &rid);
5406 if (!NT_STATUS_IS_OK(status)) {
5410 r.in.domain_handle = handle;
5411 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5413 r.out.group_handle = &group_handle;
5414 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
5415 "OpenGroup failed");
5416 if (!NT_STATUS_IS_OK(r.out.result)) {
5417 status = r.out.result;
5421 d.in.group_handle = &group_handle;
5422 d.out.group_handle = &group_handle;
5423 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
5424 "DeleteDomainGroup failed");
5425 if (!NT_STATUS_IS_OK(d.out.result)) {
5426 status = d.out.result;
5433 torture_result(tctx, TORTURE_FAIL, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
5438 static bool test_DeleteAlias_byname(struct dcerpc_binding_handle *b,
5439 struct torture_context *tctx,
5440 struct policy_handle *domain_handle,
5444 struct samr_OpenAlias r;
5445 struct samr_DeleteDomAlias d;
5446 struct policy_handle alias_handle;
5449 torture_comment(tctx, "Testing DeleteAlias_byname\n");
5451 status = test_LookupName(b, tctx, domain_handle, name, &rid);
5452 if (!NT_STATUS_IS_OK(status)) {
5456 r.in.domain_handle = domain_handle;
5457 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5459 r.out.alias_handle = &alias_handle;
5460 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5461 "OpenAlias failed");
5462 if (!NT_STATUS_IS_OK(r.out.result)) {
5463 status = r.out.result;
5467 d.in.alias_handle = &alias_handle;
5468 d.out.alias_handle = &alias_handle;
5469 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5470 "DeleteDomAlias failed");
5471 if (!NT_STATUS_IS_OK(d.out.result)) {
5472 status = d.out.result;
5479 torture_result(tctx, TORTURE_FAIL, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
5483 static bool test_DeleteAlias(struct dcerpc_binding_handle *b,
5484 struct torture_context *tctx,
5485 struct policy_handle *alias_handle)
5487 struct samr_DeleteDomAlias d;
5490 torture_comment(tctx, "Testing DeleteAlias\n");
5492 d.in.alias_handle = alias_handle;
5493 d.out.alias_handle = alias_handle;
5495 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5496 "DeleteDomAlias failed");
5497 if (!NT_STATUS_IS_OK(d.out.result)) {
5498 torture_result(tctx, TORTURE_FAIL, "DeleteAlias failed - %s\n", nt_errstr(d.out.result));
5505 static bool test_CreateAlias(struct dcerpc_binding_handle *b,
5506 struct torture_context *tctx,
5507 struct policy_handle *domain_handle,
5508 const char *alias_name,
5509 struct policy_handle *alias_handle,
5510 const struct dom_sid *domain_sid,
5513 struct samr_CreateDomAlias r;
5514 struct lsa_String name;
5518 init_lsa_String(&name, alias_name);
5519 r.in.domain_handle = domain_handle;
5520 r.in.alias_name = &name;
5521 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5522 r.out.alias_handle = alias_handle;
5525 torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
5527 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5528 "CreateDomAlias failed");
5530 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5531 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
5532 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
5535 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
5536 nt_errstr(r.out.result));
5541 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ALIAS_EXISTS)) {
5542 if (!test_DeleteAlias_byname(b, tctx, domain_handle, r.in.alias_name->string)) {
5545 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5546 "CreateDomAlias failed");
5549 if (!NT_STATUS_IS_OK(r.out.result)) {
5550 torture_result(tctx, TORTURE_FAIL, "CreateAlias failed - %s\n", nt_errstr(r.out.result));
5558 if (!test_alias_ops(b, tctx, alias_handle, domain_sid)) {
5565 static bool test_ChangePassword(struct dcerpc_pipe *p,
5566 struct torture_context *tctx,
5567 const char *acct_name,
5568 struct policy_handle *domain_handle, char **password)
5571 struct dcerpc_binding_handle *b = p->binding_handle;
5577 if (!test_ChangePasswordUser(b, tctx, acct_name, domain_handle, password)) {
5581 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
5585 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
5589 /* test what happens when setting the old password again */
5590 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
5595 char simple_pass[9];
5596 char *v = generate_random_str(tctx, 1);
5598 ZERO_STRUCT(simple_pass);
5599 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5601 /* test what happens when picking a simple password */
5602 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
5607 /* set samr_SetDomainInfo level 1 with min_length 5 */
5609 struct samr_QueryDomainInfo r;
5610 union samr_DomainInfo *info = NULL;
5611 struct samr_SetDomainInfo s;
5612 uint16_t len_old, len;
5613 uint32_t pwd_prop_old;
5614 int64_t min_pwd_age_old;
5618 r.in.domain_handle = domain_handle;
5622 torture_comment(tctx, "Testing samr_QueryDomainInfo level 1\n");
5623 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
5624 "QueryDomainInfo failed");
5625 if (!NT_STATUS_IS_OK(r.out.result)) {
5629 s.in.domain_handle = domain_handle;
5633 /* remember the old min length, so we can reset it */
5634 len_old = s.in.info->info1.min_password_length;
5635 s.in.info->info1.min_password_length = len;
5636 pwd_prop_old = s.in.info->info1.password_properties;
5637 /* turn off password complexity checks for this test */
5638 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
5640 min_pwd_age_old = s.in.info->info1.min_password_age;
5641 s.in.info->info1.min_password_age = 0;
5643 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5644 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5645 "SetDomainInfo failed");
5646 if (!NT_STATUS_IS_OK(s.out.result)) {
5650 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
5652 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
5656 s.in.info->info1.min_password_length = len_old;
5657 s.in.info->info1.password_properties = pwd_prop_old;
5658 s.in.info->info1.min_password_age = min_pwd_age_old;
5660 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5661 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5662 "SetDomainInfo failed");
5663 if (!NT_STATUS_IS_OK(s.out.result)) {
5670 struct samr_OpenUser r;
5671 struct samr_QueryUserInfo q;
5672 union samr_UserInfo *info;
5673 struct samr_LookupNames n;
5674 struct policy_handle user_handle;
5675 struct samr_Ids rids, types;
5677 n.in.domain_handle = domain_handle;
5679 n.in.names = talloc_array(tctx, struct lsa_String, 1);
5680 n.in.names[0].string = acct_name;
5682 n.out.types = &types;
5684 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
5685 "LookupNames failed");
5686 if (!NT_STATUS_IS_OK(n.out.result)) {
5687 torture_result(tctx, TORTURE_FAIL, "LookupNames failed - %s\n", nt_errstr(n.out.result));
5691 r.in.domain_handle = domain_handle;
5692 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5693 r.in.rid = n.out.rids->ids[0];
5694 r.out.user_handle = &user_handle;
5696 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5698 if (!NT_STATUS_IS_OK(r.out.result)) {
5699 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(r.out.result));
5703 q.in.user_handle = &user_handle;
5707 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5708 "QueryUserInfo failed");
5709 if (!NT_STATUS_IS_OK(q.out.result)) {
5710 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo failed - %s\n", nt_errstr(q.out.result));
5714 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
5716 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
5717 info->info5.last_password_change, true)) {
5722 /* we change passwords twice - this has the effect of verifying
5723 they were changed correctly for the final call */
5724 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5728 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5735 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
5736 struct policy_handle *domain_handle,
5737 const char *user_name,
5738 struct policy_handle *user_handle_out,
5739 struct dom_sid *domain_sid,
5740 enum torture_samr_choice which_ops,
5741 struct cli_credentials *machine_credentials,
5745 TALLOC_CTX *user_ctx;
5747 struct samr_CreateUser r;
5748 struct samr_QueryUserInfo q;
5749 union samr_UserInfo *info;
5750 struct samr_DeleteUser d;
5753 /* This call creates a 'normal' account - check that it really does */
5754 const uint32_t acct_flags = ACB_NORMAL;
5755 struct lsa_String name;
5757 struct dcerpc_binding_handle *b = p->binding_handle;
5759 struct policy_handle user_handle;
5760 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5761 init_lsa_String(&name, user_name);
5763 r.in.domain_handle = domain_handle;
5764 r.in.account_name = &name;
5765 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5766 r.out.user_handle = &user_handle;
5769 torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
5771 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5772 "CreateUser failed");
5774 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5775 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5776 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5779 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5780 nt_errstr(r.out.result));
5785 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5786 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5787 talloc_free(user_ctx);
5790 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5791 "CreateUser failed");
5794 if (!NT_STATUS_IS_OK(r.out.result)) {
5795 talloc_free(user_ctx);
5796 torture_result(tctx, TORTURE_FAIL, "CreateUser failed - %s\n", nt_errstr(r.out.result));
5801 if (user_handle_out) {
5802 *user_handle_out = user_handle;
5808 q.in.user_handle = &user_handle;
5812 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5813 "QueryUserInfo failed");
5814 if (!NT_STATUS_IS_OK(q.out.result)) {
5815 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
5816 q.in.level, nt_errstr(q.out.result));
5819 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
5820 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5821 info->info16.acct_flags,
5827 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5828 domain_sid, acct_flags, name.string, which_ops,
5829 machine_credentials)) {
5833 if (user_handle_out) {
5834 *user_handle_out = user_handle;
5836 torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
5838 d.in.user_handle = &user_handle;
5839 d.out.user_handle = &user_handle;
5841 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5842 "DeleteUser failed");
5843 if (!NT_STATUS_IS_OK(d.out.result)) {
5844 torture_result(tctx, TORTURE_FAIL, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5851 talloc_free(user_ctx);
5857 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
5858 struct policy_handle *domain_handle,
5859 struct dom_sid *domain_sid,
5860 enum torture_samr_choice which_ops,
5861 struct cli_credentials *machine_credentials)
5863 struct samr_CreateUser2 r;
5864 struct samr_QueryUserInfo q;
5865 union samr_UserInfo *info;
5866 struct samr_DeleteUser d;
5867 struct policy_handle user_handle;
5869 struct lsa_String name;
5872 struct dcerpc_binding_handle *b = p->binding_handle;
5875 uint32_t acct_flags;
5876 const char *account_name;
5878 } account_types[] = {
5879 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
5880 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5881 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5882 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5883 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5884 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5885 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5886 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5887 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5888 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
5889 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5890 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5891 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5892 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5893 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
5896 for (i = 0; account_types[i].account_name; i++) {
5897 TALLOC_CTX *user_ctx;
5898 uint32_t acct_flags = account_types[i].acct_flags;
5899 uint32_t access_granted;
5900 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5901 init_lsa_String(&name, account_types[i].account_name);
5903 r.in.domain_handle = domain_handle;
5904 r.in.account_name = &name;
5905 r.in.acct_flags = acct_flags;
5906 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5907 r.out.user_handle = &user_handle;
5908 r.out.access_granted = &access_granted;
5911 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
5913 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5914 "CreateUser2 failed");
5916 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5917 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5918 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5921 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5922 nt_errstr(r.out.result));
5928 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5929 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5930 talloc_free(user_ctx);
5934 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5935 "CreateUser2 failed");
5938 if (!NT_STATUS_EQUAL(r.out.result, account_types[i].nt_status)) {
5939 torture_result(tctx, TORTURE_FAIL, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5940 nt_errstr(r.out.result), nt_errstr(account_types[i].nt_status));
5944 if (NT_STATUS_IS_OK(r.out.result)) {
5945 q.in.user_handle = &user_handle;
5949 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5950 "QueryUserInfo failed");
5951 if (!NT_STATUS_IS_OK(q.out.result)) {
5952 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
5953 q.in.level, nt_errstr(q.out.result));
5956 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
5957 if (acct_flags == ACB_NORMAL) {
5958 expected_flags |= ACB_PW_EXPIRED;
5960 if ((info->info5.acct_flags) != expected_flags) {
5961 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5962 info->info5.acct_flags,
5966 switch (acct_flags) {
5968 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
5969 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5970 DOMAIN_RID_DCS, info->info5.primary_gid);
5975 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
5976 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5977 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
5982 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
5983 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5984 DOMAIN_RID_USERS, info->info5.primary_gid);
5991 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5992 domain_sid, acct_flags, name.string, which_ops,
5993 machine_credentials)) {
5997 if (!ndr_policy_handle_empty(&user_handle)) {
5998 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
6000 d.in.user_handle = &user_handle;
6001 d.out.user_handle = &user_handle;
6003 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
6004 "DeleteUser failed");
6005 if (!NT_STATUS_IS_OK(d.out.result)) {
6006 torture_result(tctx, TORTURE_FAIL, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
6011 talloc_free(user_ctx);
6017 static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
6018 struct torture_context *tctx,
6019 struct policy_handle *handle)
6021 struct samr_QueryAliasInfo r;
6022 union samr_AliasInfo *info;
6023 uint16_t levels[] = {1, 2, 3};
6027 for (i=0;i<ARRAY_SIZE(levels);i++) {
6028 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
6030 r.in.alias_handle = handle;
6031 r.in.level = levels[i];
6034 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &r),
6035 "QueryAliasInfo failed");
6036 if (!NT_STATUS_IS_OK(r.out.result)) {
6037 torture_result(tctx, TORTURE_FAIL, "QueryAliasInfo level %u failed - %s\n",
6038 levels[i], nt_errstr(r.out.result));
6046 static bool test_QueryGroupInfo(struct dcerpc_binding_handle *b,
6047 struct torture_context *tctx,
6048 struct policy_handle *handle)
6050 struct samr_QueryGroupInfo r;
6051 union samr_GroupInfo *info;
6052 uint16_t levels[] = {1, 2, 3, 4, 5};
6056 for (i=0;i<ARRAY_SIZE(levels);i++) {
6057 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
6059 r.in.group_handle = handle;
6060 r.in.level = levels[i];
6063 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
6064 "QueryGroupInfo failed");
6065 if (!NT_STATUS_IS_OK(r.out.result)) {
6066 torture_result(tctx, TORTURE_FAIL, "QueryGroupInfo level %u failed - %s\n",
6067 levels[i], nt_errstr(r.out.result));
6075 static bool test_QueryGroupMember(struct dcerpc_binding_handle *b,
6076 struct torture_context *tctx,
6077 struct policy_handle *handle)
6079 struct samr_QueryGroupMember r;
6080 struct samr_RidAttrArray *rids = NULL;
6083 torture_comment(tctx, "Testing QueryGroupMember\n");
6085 r.in.group_handle = handle;
6088 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &r),
6089 "QueryGroupMember failed");
6090 if (!NT_STATUS_IS_OK(r.out.result)) {
6091 torture_result(tctx, TORTURE_FAIL, "QueryGroupMember failed - %s\n", nt_errstr(r.out.result));
6099 static bool test_SetGroupInfo(struct dcerpc_binding_handle *b,
6100 struct torture_context *tctx,
6101 struct policy_handle *handle)
6103 struct samr_QueryGroupInfo r;
6104 union samr_GroupInfo *info;
6105 struct samr_SetGroupInfo s;
6106 uint16_t levels[] = {1, 2, 3, 4};
6107 uint16_t set_ok[] = {0, 1, 1, 1};
6111 for (i=0;i<ARRAY_SIZE(levels);i++) {
6112 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
6114 r.in.group_handle = handle;
6115 r.in.level = levels[i];
6118 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
6119 "QueryGroupInfo failed");
6120 if (!NT_STATUS_IS_OK(r.out.result)) {
6121 torture_result(tctx, TORTURE_FAIL, "QueryGroupInfo level %u failed - %s\n",
6122 levels[i], nt_errstr(r.out.result));
6126 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
6128 s.in.group_handle = handle;
6129 s.in.level = levels[i];
6130 s.in.info = *r.out.info;
6133 /* disabled this, as it changes the name only from the point of view of samr,
6134 but leaves the name from the point of view of w2k3 internals (and ldap). This means
6135 the name is still reserved, so creating the old name fails, but deleting by the old name
6137 if (s.in.level == 2) {
6138 init_lsa_String(&s.in.info->string, "NewName");
6142 if (s.in.level == 4) {
6143 init_lsa_String(&s.in.info->description, "test description");
6146 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetGroupInfo_r(b, tctx, &s),
6147 "SetGroupInfo failed");
6149 if (!NT_STATUS_IS_OK(s.out.result)) {
6150 torture_result(tctx, TORTURE_FAIL, "SetGroupInfo level %u failed - %s\n",
6151 r.in.level, nt_errstr(s.out.result));
6156 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
6157 torture_result(tctx, TORTURE_FAIL, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6158 r.in.level, nt_errstr(s.out.result));
6168 static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
6169 struct torture_context *tctx,
6170 struct policy_handle *handle)
6172 struct samr_QueryUserInfo r;
6173 union samr_UserInfo *info;
6174 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
6175 11, 12, 13, 14, 16, 17, 20, 21};
6179 for (i=0;i<ARRAY_SIZE(levels);i++) {
6180 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
6182 r.in.user_handle = handle;
6183 r.in.level = levels[i];
6186 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
6187 "QueryUserInfo failed");
6188 if (!NT_STATUS_IS_OK(r.out.result)) {
6189 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
6190 levels[i], nt_errstr(r.out.result));
6198 static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
6199 struct torture_context *tctx,
6200 struct policy_handle *handle)
6202 struct samr_QueryUserInfo2 r;
6203 union samr_UserInfo *info;
6204 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
6205 11, 12, 13, 14, 16, 17, 20, 21};
6209 for (i=0;i<ARRAY_SIZE(levels);i++) {
6210 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
6212 r.in.user_handle = handle;
6213 r.in.level = levels[i];
6216 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r),
6217 "QueryUserInfo2 failed");
6218 if (!NT_STATUS_IS_OK(r.out.result)) {
6219 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo2 level %u failed - %s\n",
6220 levels[i], nt_errstr(r.out.result));
6228 static bool test_OpenUser(struct dcerpc_binding_handle *b,
6229 struct torture_context *tctx,
6230 struct policy_handle *handle, uint32_t rid)
6232 struct samr_OpenUser r;
6233 struct policy_handle user_handle;
6236 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
6238 r.in.domain_handle = handle;
6239 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6241 r.out.user_handle = &user_handle;
6243 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6245 if (!NT_STATUS_IS_OK(r.out.result)) {
6246 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6250 if (!test_QuerySecurity(b, tctx, &user_handle)) {
6254 if (!test_QueryUserInfo(b, tctx, &user_handle)) {
6258 if (!test_QueryUserInfo2(b, tctx, &user_handle)) {
6262 if (!test_GetUserPwInfo(b, tctx, &user_handle)) {
6266 if (!test_GetGroupsForUser(b, tctx, &user_handle)) {
6270 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6277 static bool test_OpenGroup(struct dcerpc_binding_handle *b,
6278 struct torture_context *tctx,
6279 struct policy_handle *handle, uint32_t rid)
6281 struct samr_OpenGroup r;
6282 struct policy_handle group_handle;
6285 torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
6287 r.in.domain_handle = handle;
6288 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6290 r.out.group_handle = &group_handle;
6292 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
6293 "OpenGroup failed");
6294 if (!NT_STATUS_IS_OK(r.out.result)) {
6295 torture_result(tctx, TORTURE_FAIL, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6299 if (!torture_setting_bool(tctx, "samba3", false)) {
6300 if (!test_QuerySecurity(b, tctx, &group_handle)) {
6305 if (!test_QueryGroupInfo(b, tctx, &group_handle)) {
6309 if (!test_QueryGroupMember(b, tctx, &group_handle)) {
6313 if (!test_samr_handle_Close(b, tctx, &group_handle)) {
6320 static bool test_OpenAlias(struct dcerpc_binding_handle *b,
6321 struct torture_context *tctx,
6322 struct policy_handle *handle, uint32_t rid)
6324 struct samr_OpenAlias r;
6325 struct policy_handle alias_handle;
6328 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
6330 r.in.domain_handle = handle;
6331 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6333 r.out.alias_handle = &alias_handle;
6335 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
6336 "OpenAlias failed");
6337 if (!NT_STATUS_IS_OK(r.out.result)) {
6338 torture_result(tctx, TORTURE_FAIL, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6342 if (!torture_setting_bool(tctx, "samba3", false)) {
6343 if (!test_QuerySecurity(b, tctx, &alias_handle)) {
6348 if (!test_QueryAliasInfo(b, tctx, &alias_handle)) {
6352 if (!test_GetMembersInAlias(b, tctx, &alias_handle)) {
6356 if (!test_samr_handle_Close(b, tctx, &alias_handle)) {
6363 static bool check_mask(struct dcerpc_binding_handle *b,
6364 struct torture_context *tctx,
6365 struct policy_handle *handle, uint32_t rid,
6366 uint32_t acct_flag_mask)
6368 struct samr_OpenUser r;
6369 struct samr_QueryUserInfo q;
6370 union samr_UserInfo *info;
6371 struct policy_handle user_handle;
6374 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
6376 r.in.domain_handle = handle;
6377 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6379 r.out.user_handle = &user_handle;
6381 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6383 if (!NT_STATUS_IS_OK(r.out.result)) {
6384 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6388 q.in.user_handle = &user_handle;
6392 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6393 "QueryUserInfo failed");
6394 if (!NT_STATUS_IS_OK(q.out.result)) {
6395 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 16 failed - %s\n",
6396 nt_errstr(q.out.result));
6399 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
6400 torture_result(tctx, TORTURE_FAIL, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
6401 acct_flag_mask, info->info16.acct_flags, rid);
6406 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6413 static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle *b,
6414 struct torture_context *tctx,
6415 struct policy_handle *handle)
6417 struct samr_EnumDomainUsers r;
6418 uint32_t mask, resume_handle=0;
6421 struct samr_LookupNames n;
6422 struct samr_LookupRids lr ;
6423 struct lsa_Strings names;
6424 struct samr_Ids rids, types;
6425 struct samr_SamArray *sam = NULL;
6426 uint32_t num_entries = 0;
6428 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
6429 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
6430 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
6433 torture_comment(tctx, "Testing EnumDomainUsers\n");
6435 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
6436 r.in.domain_handle = handle;
6437 r.in.resume_handle = &resume_handle;
6438 r.in.acct_flags = mask = masks[mask_idx];
6439 r.in.max_size = (uint32_t)-1;
6440 r.out.resume_handle = &resume_handle;
6441 r.out.num_entries = &num_entries;
6444 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
6445 "EnumDomainUsers failed");
6446 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
6447 !NT_STATUS_IS_OK(r.out.result)) {
6448 torture_result(tctx, TORTURE_FAIL, "EnumDomainUsers failed - %s\n", nt_errstr(r.out.result));
6452 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
6454 if (sam->count == 0) {
6458 for (i=0;i<sam->count;i++) {
6460 if (!check_mask(b, tctx, handle, sam->entries[i].idx, mask)) {
6463 } else if (!test_OpenUser(b, tctx, handle, sam->entries[i].idx)) {
6469 torture_comment(tctx, "Testing LookupNames\n");
6470 n.in.domain_handle = handle;
6471 n.in.num_names = sam->count;
6472 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
6474 n.out.types = &types;
6475 for (i=0;i<sam->count;i++) {
6476 n.in.names[i].string = sam->entries[i].name.string;
6478 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
6479 "LookupNames failed");
6480 if (!NT_STATUS_IS_OK(n.out.result)) {
6481 torture_result(tctx, TORTURE_FAIL, "LookupNames failed - %s\n", nt_errstr(n.out.result));
6486 torture_comment(tctx, "Testing LookupRids\n");
6487 lr.in.domain_handle = handle;
6488 lr.in.num_rids = sam->count;
6489 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
6490 lr.out.names = &names;
6491 lr.out.types = &types;
6492 for (i=0;i<sam->count;i++) {
6493 lr.in.rids[i] = sam->entries[i].idx;
6495 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupRids_r(b, tctx, &lr),
6496 "LookupRids failed");
6497 torture_assert_ntstatus_ok(tctx, lr.out.result, "LookupRids");
6503 try blasting the server with a bunch of sync requests
6505 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
6506 struct policy_handle *handle)
6508 struct samr_EnumDomainUsers r;
6509 uint32_t resume_handle=0;
6511 #define ASYNC_COUNT 100
6512 struct tevent_req *req[ASYNC_COUNT];
6514 if (!torture_setting_bool(tctx, "dangerous", false)) {
6515 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
6518 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
6520 r.in.domain_handle = handle;
6521 r.in.resume_handle = &resume_handle;
6522 r.in.acct_flags = 0;
6523 r.in.max_size = (uint32_t)-1;
6524 r.out.resume_handle = &resume_handle;
6526 for (i=0;i<ASYNC_COUNT;i++) {
6527 req[i] = dcerpc_samr_EnumDomainUsers_r_send(tctx, tctx->ev, p->binding_handle, &r);
6530 for (i=0;i<ASYNC_COUNT;i++) {
6531 tevent_req_poll(req[i], tctx->ev);
6532 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r_recv(req[i], tctx),
6533 talloc_asprintf(tctx, "EnumDomainUsers[%d] failed - %s\n",
6534 i, nt_errstr(r.out.result)));
6537 torture_comment(tctx, "%d async requests OK\n", i);
6542 static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle *b,
6543 struct torture_context *tctx,
6544 struct policy_handle *handle)
6546 struct samr_EnumDomainGroups r;
6547 uint32_t resume_handle=0;
6548 struct samr_SamArray *sam = NULL;
6549 uint32_t num_entries = 0;
6552 bool universal_group_found = false;
6554 torture_comment(tctx, "Testing EnumDomainGroups\n");
6556 r.in.domain_handle = handle;
6557 r.in.resume_handle = &resume_handle;
6558 r.in.max_size = (uint32_t)-1;
6559 r.out.resume_handle = &resume_handle;
6560 r.out.num_entries = &num_entries;
6563 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
6564 "EnumDomainGroups failed");
6565 if (!NT_STATUS_IS_OK(r.out.result)) {
6566 torture_result(tctx, TORTURE_FAIL, "EnumDomainGroups failed - %s\n", nt_errstr(r.out.result));
6574 for (i=0;i<sam->count;i++) {
6575 if (!test_OpenGroup(b, tctx, handle, sam->entries[i].idx)) {
6578 if ((ret == true) && (strcasecmp(sam->entries[i].name.string,
6579 "Enterprise Admins") == 0)) {
6580 universal_group_found = true;
6584 /* when we are running this on s4 we should get back at least the
6585 * "Enterprise Admins" universal group. If we don't get a group entry
6586 * at all we probably are performing the test on the builtin domain.
6587 * So ignore this case. */
6588 if (torture_setting_bool(tctx, "samba4", false)) {
6589 if ((sam->count > 0) && (!universal_group_found)) {
6597 static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle *b,
6598 struct torture_context *tctx,
6599 struct policy_handle *handle)
6601 struct samr_EnumDomainAliases r;
6602 uint32_t resume_handle=0;
6603 struct samr_SamArray *sam = NULL;
6604 uint32_t num_entries = 0;
6608 torture_comment(tctx, "Testing EnumDomainAliases\n");
6610 r.in.domain_handle = handle;
6611 r.in.resume_handle = &resume_handle;
6612 r.in.max_size = (uint32_t)-1;
6614 r.out.num_entries = &num_entries;
6615 r.out.resume_handle = &resume_handle;
6617 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
6618 "EnumDomainAliases failed");
6619 if (!NT_STATUS_IS_OK(r.out.result)) {
6620 torture_result(tctx, TORTURE_FAIL, "EnumDomainAliases failed - %s\n", nt_errstr(r.out.result));
6628 for (i=0;i<sam->count;i++) {
6629 if (!test_OpenAlias(b, tctx, handle, sam->entries[i].idx)) {
6637 static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle *b,
6638 struct torture_context *tctx,
6639 struct policy_handle *handle)
6641 struct samr_GetDisplayEnumerationIndex r;
6643 uint16_t levels[] = {1, 2, 3, 4, 5};
6644 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6645 struct lsa_String name;
6649 for (i=0;i<ARRAY_SIZE(levels);i++) {
6650 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
6652 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6654 r.in.domain_handle = handle;
6655 r.in.level = levels[i];
6659 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6660 "GetDisplayEnumerationIndex failed");
6663 !NT_STATUS_IS_OK(r.out.result) &&
6664 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6665 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex level %u failed - %s\n",
6666 levels[i], nt_errstr(r.out.result));
6670 init_lsa_String(&name, "zzzzzzzz");
6672 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6673 "GetDisplayEnumerationIndex failed");
6675 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6676 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex level %u failed - %s\n",
6677 levels[i], nt_errstr(r.out.result));
6685 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle *b,
6686 struct torture_context *tctx,
6687 struct policy_handle *handle)
6689 struct samr_GetDisplayEnumerationIndex2 r;
6691 uint16_t levels[] = {1, 2, 3, 4, 5};
6692 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6693 struct lsa_String name;
6697 for (i=0;i<ARRAY_SIZE(levels);i++) {
6698 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
6700 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6702 r.in.domain_handle = handle;
6703 r.in.level = levels[i];
6707 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6708 "GetDisplayEnumerationIndex2 failed");
6710 !NT_STATUS_IS_OK(r.out.result) &&
6711 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6712 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6713 levels[i], nt_errstr(r.out.result));
6717 init_lsa_String(&name, "zzzzzzzz");
6719 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6720 "GetDisplayEnumerationIndex2 failed");
6721 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6722 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6723 levels[i], nt_errstr(r.out.result));
6731 #define STRING_EQUAL_QUERY(s1, s2, user) \
6732 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6733 /* odd, but valid */ \
6734 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6735 torture_result(tctx, TORTURE_FAIL, "%s mismatch for %s: %s != %s (%s)\n", \
6736 #s1, user.string, s1.string, s2.string, __location__); \
6739 #define INT_EQUAL_QUERY(s1, s2, user) \
6741 torture_result(tctx, TORTURE_FAIL, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6742 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6746 static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle *b,
6747 struct torture_context *tctx,
6748 struct samr_QueryDisplayInfo *querydisplayinfo,
6749 bool *seen_testuser)
6751 struct samr_OpenUser r;
6752 struct samr_QueryUserInfo q;
6753 union samr_UserInfo *info;
6754 struct policy_handle user_handle;
6756 r.in.domain_handle = querydisplayinfo->in.domain_handle;
6757 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6758 for (i = 0; ; i++) {
6759 switch (querydisplayinfo->in.level) {
6761 if (i >= querydisplayinfo->out.info->info1.count) {
6764 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
6767 if (i >= querydisplayinfo->out.info->info2.count) {
6770 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
6776 /* Not interested in validating just the account name */
6780 r.out.user_handle = &user_handle;
6782 switch (querydisplayinfo->in.level) {
6785 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6787 if (!NT_STATUS_IS_OK(r.out.result)) {
6788 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6793 q.in.user_handle = &user_handle;
6796 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6797 "QueryUserInfo failed");
6798 if (!NT_STATUS_IS_OK(r.out.result)) {
6799 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6803 switch (querydisplayinfo->in.level) {
6805 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
6806 *seen_testuser = true;
6808 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
6809 info->info21.full_name, info->info21.account_name);
6810 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
6811 info->info21.account_name, info->info21.account_name);
6812 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
6813 info->info21.description, info->info21.account_name);
6814 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
6815 info->info21.rid, info->info21.account_name);
6816 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
6817 info->info21.acct_flags, info->info21.account_name);
6821 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
6822 info->info21.account_name, info->info21.account_name);
6823 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
6824 info->info21.description, info->info21.account_name);
6825 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
6826 info->info21.rid, info->info21.account_name);
6827 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
6828 info->info21.acct_flags, info->info21.account_name);
6830 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
6831 torture_result(tctx, TORTURE_FAIL, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6832 info->info21.account_name.string);
6835 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
6836 torture_result(tctx, TORTURE_FAIL, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6837 info->info21.account_name.string,
6838 querydisplayinfo->out.info->info2.entries[i].acct_flags,
6839 info->info21.acct_flags);
6846 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6853 static bool test_QueryDisplayInfo(struct dcerpc_binding_handle *b,
6854 struct torture_context *tctx,
6855 struct policy_handle *handle)
6857 struct samr_QueryDisplayInfo r;
6858 struct samr_QueryDomainInfo dom_info;
6859 union samr_DomainInfo *info = NULL;
6861 uint16_t levels[] = {1, 2, 3, 4, 5};
6863 bool seen_testuser = false;
6864 uint32_t total_size;
6865 uint32_t returned_size;
6866 union samr_DispInfo disp_info;
6869 for (i=0;i<ARRAY_SIZE(levels);i++) {
6870 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
6873 r.out.result = STATUS_MORE_ENTRIES;
6874 while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
6875 r.in.domain_handle = handle;
6876 r.in.level = levels[i];
6877 r.in.max_entries = 2;
6878 r.in.buf_size = (uint32_t)-1;
6879 r.out.total_size = &total_size;
6880 r.out.returned_size = &returned_size;
6881 r.out.info = &disp_info;
6883 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6884 "QueryDisplayInfo failed");
6885 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(r.out.result)) {
6886 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level %u failed - %s\n",
6887 levels[i], nt_errstr(r.out.result));
6890 switch (r.in.level) {
6892 if (!test_each_DisplayInfo_user(b, tctx, &r, &seen_testuser)) {
6895 r.in.start_idx += r.out.info->info1.count;
6898 if (!test_each_DisplayInfo_user(b, tctx, &r, NULL)) {
6901 r.in.start_idx += r.out.info->info2.count;
6904 r.in.start_idx += r.out.info->info3.count;
6907 r.in.start_idx += r.out.info->info4.count;
6910 r.in.start_idx += r.out.info->info5.count;
6914 dom_info.in.domain_handle = handle;
6915 dom_info.in.level = 2;
6916 dom_info.out.info = &info;
6918 /* Check number of users returned is correct */
6919 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &dom_info),
6920 "QueryDomainInfo failed");
6921 if (!NT_STATUS_IS_OK(dom_info.out.result)) {
6922 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
6923 r.in.level, nt_errstr(dom_info.out.result));
6927 switch (r.in.level) {
6930 if (info->general.num_users < r.in.start_idx) {
6931 /* On AD deployments this numbers don't match
6932 * since QueryDisplayInfo returns universal and
6933 * global groups, QueryDomainInfo only global
6935 if (torture_setting_bool(tctx, "samba3", false)) {
6936 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6937 r.in.start_idx, info->general.num_groups,
6938 info->general.domain_name.string);
6942 if (!seen_testuser) {
6943 struct policy_handle user_handle;
6944 if (NT_STATUS_IS_OK(test_OpenUser_byname(b, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
6945 torture_result(tctx, TORTURE_FAIL, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
6946 info->general.domain_name.string);
6948 test_samr_handle_Close(b, tctx, &user_handle);
6954 if (info->general.num_groups != r.in.start_idx) {
6955 /* On AD deployments this numbers don't match
6956 * since QueryDisplayInfo returns universal and
6957 * global groups, QueryDomainInfo only global
6959 if (torture_setting_bool(tctx, "samba3", false)) {
6960 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6961 r.in.start_idx, info->general.num_groups,
6962 info->general.domain_name.string);
6975 static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle *b,
6976 struct torture_context *tctx,
6977 struct policy_handle *handle)
6979 struct samr_QueryDisplayInfo2 r;
6981 uint16_t levels[] = {1, 2, 3, 4, 5};
6983 uint32_t total_size;
6984 uint32_t returned_size;
6985 union samr_DispInfo info;
6987 for (i=0;i<ARRAY_SIZE(levels);i++) {
6988 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
6990 r.in.domain_handle = handle;
6991 r.in.level = levels[i];
6993 r.in.max_entries = 1000;
6994 r.in.buf_size = (uint32_t)-1;
6995 r.out.total_size = &total_size;
6996 r.out.returned_size = &returned_size;
6999 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo2_r(b, tctx, &r),
7000 "QueryDisplayInfo2 failed");
7001 if (!NT_STATUS_IS_OK(r.out.result)) {
7002 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo2 level %u failed - %s\n",
7003 levels[i], nt_errstr(r.out.result));
7011 static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle *b,
7012 struct torture_context *tctx,
7013 struct policy_handle *handle)
7015 struct samr_QueryDisplayInfo3 r;
7017 uint16_t levels[] = {1, 2, 3, 4, 5};
7019 uint32_t total_size;
7020 uint32_t returned_size;
7021 union samr_DispInfo info;
7023 for (i=0;i<ARRAY_SIZE(levels);i++) {
7024 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
7026 r.in.domain_handle = handle;
7027 r.in.level = levels[i];
7029 r.in.max_entries = 1000;
7030 r.in.buf_size = (uint32_t)-1;
7031 r.out.total_size = &total_size;
7032 r.out.returned_size = &returned_size;
7035 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo3_r(b, tctx, &r),
7036 "QueryDisplayInfo3 failed");
7037 if (!NT_STATUS_IS_OK(r.out.result)) {
7038 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo3 level %u failed - %s\n",
7039 levels[i], nt_errstr(r.out.result));
7048 static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle *b,
7049 struct torture_context *tctx,
7050 struct policy_handle *handle)
7052 struct samr_QueryDisplayInfo r;
7054 uint32_t total_size;
7055 uint32_t returned_size;
7056 union samr_DispInfo info;
7058 torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
7060 r.in.domain_handle = handle;
7063 r.in.max_entries = 1;
7064 r.in.buf_size = (uint32_t)-1;
7065 r.out.total_size = &total_size;
7066 r.out.returned_size = &returned_size;
7070 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7071 "QueryDisplayInfo failed");
7072 if (NT_STATUS_IS_OK(r.out.result) && *r.out.returned_size != 0) {
7073 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
7074 torture_result(tctx, TORTURE_FAIL, "expected idx %d but got %d\n",
7076 r.out.info->info1.entries[0].idx);
7080 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
7081 !NT_STATUS_IS_OK(r.out.result)) {
7082 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level %u failed - %s\n",
7083 r.in.level, nt_errstr(r.out.result));
7088 } while ((NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) ||
7089 NT_STATUS_IS_OK(r.out.result)) &&
7090 *r.out.returned_size != 0);
7095 static bool test_QueryDomainInfo(struct dcerpc_pipe *p,
7096 struct torture_context *tctx,
7097 struct policy_handle *handle)
7099 struct samr_QueryDomainInfo r;
7100 union samr_DomainInfo *info = NULL;
7101 struct samr_SetDomainInfo s;
7102 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
7103 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
7106 struct dcerpc_binding_handle *b = p->binding_handle;
7107 const char *domain_comment = talloc_asprintf(tctx,
7108 "Tortured by Samba4 RPC-SAMR: %s",
7109 timestring(tctx, time(NULL)));
7111 s.in.domain_handle = handle;
7113 s.in.info = talloc(tctx, union samr_DomainInfo);
7115 s.in.info->oem.oem_information.string = domain_comment;
7116 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
7117 "SetDomainInfo failed");
7118 if (!NT_STATUS_IS_OK(s.out.result)) {
7119 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u (set comment) failed - %s\n",
7120 s.in.level, nt_errstr(s.out.result));
7124 for (i=0;i<ARRAY_SIZE(levels);i++) {
7125 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
7127 r.in.domain_handle = handle;
7128 r.in.level = levels[i];
7131 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
7132 "QueryDomainInfo failed");
7133 if (!NT_STATUS_IS_OK(r.out.result)) {
7134 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
7135 r.in.level, nt_errstr(r.out.result));
7140 switch (levels[i]) {
7142 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
7143 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
7144 levels[i], info->general.oem_information.string, domain_comment);
7145 if (!torture_setting_bool(tctx, "samba3", false)) {
7149 if (!info->general.primary.string) {
7150 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned no PDC name\n",
7153 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
7154 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
7155 if (torture_setting_bool(tctx, "samba3", false)) {
7156 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
7157 levels[i], info->general.primary.string, dcerpc_server_name(p));
7163 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
7164 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
7165 levels[i], info->oem.oem_information.string, domain_comment);
7166 if (!torture_setting_bool(tctx, "samba3", false)) {
7172 if (!info->info6.primary.string) {
7173 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned no PDC name\n",
7179 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
7180 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
7181 levels[i], info->general2.general.oem_information.string, domain_comment);
7182 if (!torture_setting_bool(tctx, "samba3", false)) {
7189 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
7191 s.in.domain_handle = handle;
7192 s.in.level = levels[i];
7195 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
7196 "SetDomainInfo failed");
7198 if (!NT_STATUS_IS_OK(s.out.result)) {
7199 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u failed - %s\n",
7200 r.in.level, nt_errstr(s.out.result));
7205 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
7206 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
7207 r.in.level, nt_errstr(s.out.result));
7213 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
7214 "QueryDomainInfo failed");
7215 if (!NT_STATUS_IS_OK(r.out.result)) {
7216 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
7217 r.in.level, nt_errstr(r.out.result));
7227 static bool test_QueryDomainInfo2(struct dcerpc_binding_handle *b,
7228 struct torture_context *tctx,
7229 struct policy_handle *handle)
7231 struct samr_QueryDomainInfo2 r;
7232 union samr_DomainInfo *info = NULL;
7233 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
7237 for (i=0;i<ARRAY_SIZE(levels);i++) {
7238 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
7240 r.in.domain_handle = handle;
7241 r.in.level = levels[i];
7244 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
7245 "QueryDomainInfo2 failed");
7246 if (!NT_STATUS_IS_OK(r.out.result)) {
7247 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo2 level %u failed - %s\n",
7248 r.in.level, nt_errstr(r.out.result));
7257 /* Test whether querydispinfo level 5 and enumdomgroups return the same
7258 set of group names. */
7259 static bool test_GroupList(struct dcerpc_binding_handle *b,
7260 struct torture_context *tctx,
7261 struct dom_sid *domain_sid,
7262 struct policy_handle *handle)
7264 struct samr_EnumDomainGroups q1;
7265 struct samr_QueryDisplayInfo q2;
7267 uint32_t resume_handle=0;
7268 struct samr_SamArray *sam = NULL;
7269 uint32_t num_entries = 0;
7272 uint32_t total_size;
7273 uint32_t returned_size;
7274 union samr_DispInfo info;
7277 const char **names = NULL;
7279 bool builtin_domain = dom_sid_compare(domain_sid,
7280 &global_sid_Builtin) == 0;
7282 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
7284 q1.in.domain_handle = handle;
7285 q1.in.resume_handle = &resume_handle;
7287 q1.out.resume_handle = &resume_handle;
7288 q1.out.num_entries = &num_entries;
7291 status = STATUS_MORE_ENTRIES;
7292 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
7293 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &q1),
7294 "EnumDomainGroups failed");
7295 status = q1.out.result;
7297 if (!NT_STATUS_IS_OK(status) &&
7298 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
7301 for (i=0; i<*q1.out.num_entries; i++) {
7302 add_string_to_array(tctx,
7303 sam->entries[i].name.string,
7304 &names, &num_names);
7308 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
7310 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
7312 if (builtin_domain) {
7313 torture_assert(tctx, num_names == 0,
7314 "EnumDomainGroups shouldn't return any group in the builtin domain!");
7317 q2.in.domain_handle = handle;
7319 q2.in.start_idx = 0;
7320 q2.in.max_entries = 5;
7321 q2.in.buf_size = (uint32_t)-1;
7322 q2.out.total_size = &total_size;
7323 q2.out.returned_size = &returned_size;
7324 q2.out.info = &info;
7326 status = STATUS_MORE_ENTRIES;
7327 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
7328 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &q2),
7329 "QueryDisplayInfo failed");
7330 status = q2.out.result;
7331 if (!NT_STATUS_IS_OK(status) &&
7332 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
7335 for (i=0; i<q2.out.info->info5.count; i++) {
7337 const char *name = q2.out.info->info5.entries[i].account_name.string;
7339 for (j=0; j<num_names; j++) {
7340 if (names[j] == NULL)
7342 if (strequal(names[j], name)) {
7349 if ((!found) && (!builtin_domain)) {
7350 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
7355 q2.in.start_idx += q2.out.info->info5.count;
7358 if (!NT_STATUS_IS_OK(status)) {
7359 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level 5 failed - %s\n",
7364 if (builtin_domain) {
7365 torture_assert(tctx, q2.in.start_idx != 0,
7366 "QueryDisplayInfo should return all domain groups also on the builtin domain handle!");
7369 for (i=0; i<num_names; i++) {
7370 if (names[i] != NULL) {
7371 torture_result(tctx, TORTURE_FAIL, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
7380 static bool test_DeleteDomainGroup(struct dcerpc_binding_handle *b,
7381 struct torture_context *tctx,
7382 struct policy_handle *group_handle)
7384 struct samr_DeleteDomainGroup d;
7386 torture_comment(tctx, "Testing DeleteDomainGroup\n");
7388 d.in.group_handle = group_handle;
7389 d.out.group_handle = group_handle;
7391 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
7392 "DeleteDomainGroup failed");
7393 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteDomainGroup");
7398 static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle *b,
7399 struct torture_context *tctx,
7400 struct policy_handle *domain_handle)
7402 struct samr_TestPrivateFunctionsDomain r;
7405 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
7407 r.in.domain_handle = domain_handle;
7409 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsDomain_r(b, tctx, &r),
7410 "TestPrivateFunctionsDomain failed");
7411 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
7416 static bool test_RidToSid(struct dcerpc_binding_handle *b,
7417 struct torture_context *tctx,
7418 struct dom_sid *domain_sid,
7419 struct policy_handle *domain_handle)
7421 struct samr_RidToSid r;
7423 struct dom_sid *calc_sid, *out_sid;
7424 int rids[] = { 0, 42, 512, 10200 };
7427 for (i=0;i<ARRAY_SIZE(rids);i++) {
7428 torture_comment(tctx, "Testing RidToSid\n");
7430 calc_sid = dom_sid_dup(tctx, domain_sid);
7431 r.in.domain_handle = domain_handle;
7433 r.out.sid = &out_sid;
7435 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RidToSid_r(b, tctx, &r),
7437 if (!NT_STATUS_IS_OK(r.out.result)) {
7438 torture_result(tctx, TORTURE_FAIL, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(r.out.result));
7441 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
7443 if (!dom_sid_equal(calc_sid, out_sid)) {
7444 torture_result(tctx, TORTURE_FAIL, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
7445 dom_sid_string(tctx, out_sid),
7446 dom_sid_string(tctx, calc_sid));
7455 static bool test_GetBootKeyInformation(struct dcerpc_binding_handle *b,
7456 struct torture_context *tctx,
7457 struct policy_handle *domain_handle)
7459 struct samr_GetBootKeyInformation r;
7461 uint32_t unknown = 0;
7464 torture_comment(tctx, "Testing GetBootKeyInformation\n");
7466 r.in.domain_handle = domain_handle;
7467 r.out.unknown = &unknown;
7469 status = dcerpc_samr_GetBootKeyInformation_r(b, tctx, &r);
7470 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(r.out.result)) {
7471 status = r.out.result;
7473 if (!NT_STATUS_IS_OK(status)) {
7474 /* w2k3 seems to fail this sometimes and pass it sometimes */
7475 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
7481 static bool test_AddGroupMember(struct dcerpc_binding_handle *b,
7482 struct torture_context *tctx,
7483 struct policy_handle *domain_handle,
7484 struct policy_handle *group_handle)
7487 struct samr_AddGroupMember r;
7488 struct samr_DeleteGroupMember d;
7489 struct samr_QueryGroupMember q;
7490 struct samr_RidAttrArray *rids = NULL;
7491 struct samr_SetMemberAttributesOfGroup s;
7493 bool found_member = false;
7496 status = test_LookupName(b, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
7497 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
7499 r.in.group_handle = group_handle;
7501 r.in.flags = 0; /* ??? */
7503 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
7505 d.in.group_handle = group_handle;
7508 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7509 "DeleteGroupMember failed");
7510 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, d.out.result, "DeleteGroupMember");
7512 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7513 "AddGroupMember failed");
7514 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7516 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7517 "AddGroupMember failed");
7518 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, r.out.result, "AddGroupMember");
7520 if (torture_setting_bool(tctx, "samba4", false) ||
7521 torture_setting_bool(tctx, "samba3", false)) {
7522 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
7524 /* this one is quite strange. I am using random inputs in the
7525 hope of triggering an error that might give us a clue */
7527 s.in.group_handle = group_handle;
7528 s.in.unknown1 = random();
7529 s.in.unknown2 = random();
7531 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetMemberAttributesOfGroup_r(b, tctx, &s),
7532 "SetMemberAttributesOfGroup failed");
7533 torture_assert_ntstatus_ok(tctx, s.out.result, "SetMemberAttributesOfGroup");
7536 q.in.group_handle = group_handle;
7539 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7540 "QueryGroupMember failed");
7541 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7542 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7544 for (i=0; i < rids->count; i++) {
7545 if (rids->rids[i] == rid) {
7546 found_member = true;
7550 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
7552 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7553 "DeleteGroupMember failed");
7554 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteGroupMember");
7557 found_member = false;
7559 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7560 "QueryGroupMember failed");
7561 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7562 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7564 for (i=0; i < rids->count; i++) {
7565 if (rids->rids[i] == rid) {
7566 found_member = true;
7570 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
7572 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7573 "AddGroupMember failed");
7574 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7580 static bool test_CreateDomainGroup(struct dcerpc_binding_handle *b,
7581 struct torture_context *tctx,
7582 struct policy_handle *domain_handle,
7583 const char *group_name,
7584 struct policy_handle *group_handle,
7585 struct dom_sid *domain_sid,
7588 struct samr_CreateDomainGroup r;
7590 struct lsa_String name;
7593 init_lsa_String(&name, group_name);
7595 r.in.domain_handle = domain_handle;
7597 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7598 r.out.group_handle = group_handle;
7601 torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
7603 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7604 "CreateDomainGroup failed");
7606 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
7607 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
7608 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
7611 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
7612 nt_errstr(r.out.result));
7617 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_GROUP_EXISTS)) {
7618 if (!test_DeleteGroup_byname(b, tctx, domain_handle, r.in.name->string)) {
7619 torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
7620 nt_errstr(r.out.result));
7623 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7624 "CreateDomainGroup failed");
7626 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
7627 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.name->string)) {
7629 torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
7630 nt_errstr(r.out.result));
7633 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7634 "CreateDomainGroup failed");
7636 torture_assert_ntstatus_ok(tctx, r.out.result, "CreateDomainGroup");
7642 if (!test_AddGroupMember(b, tctx, domain_handle, group_handle)) {
7643 torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed - %s\n", nt_errstr(r.out.result));
7647 if (!test_SetGroupInfo(b, tctx, group_handle)) {
7656 its not totally clear what this does. It seems to accept any sid you like.
7658 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle *b,
7659 struct torture_context *tctx,
7660 struct policy_handle *domain_handle)
7662 struct samr_RemoveMemberFromForeignDomain r;
7664 r.in.domain_handle = domain_handle;
7665 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
7667 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMemberFromForeignDomain_r(b, tctx, &r),
7668 "RemoveMemberFromForeignDomain failed");
7669 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMemberFromForeignDomain");
7674 static bool test_EnumDomainUsers(struct dcerpc_binding_handle *b,
7675 struct torture_context *tctx,
7676 struct policy_handle *domain_handle,
7677 uint32_t *total_num_entries_p)
7680 struct samr_EnumDomainUsers r;
7681 uint32_t resume_handle = 0;
7682 uint32_t num_entries = 0;
7683 uint32_t total_num_entries = 0;
7684 struct samr_SamArray *sam;
7686 r.in.domain_handle = domain_handle;
7687 r.in.acct_flags = 0;
7688 r.in.max_size = (uint32_t)-1;
7689 r.in.resume_handle = &resume_handle;
7692 r.out.num_entries = &num_entries;
7693 r.out.resume_handle = &resume_handle;
7695 torture_comment(tctx, "Testing EnumDomainUsers\n");
7698 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
7699 "EnumDomainUsers failed");
7700 if (NT_STATUS_IS_ERR(r.out.result)) {
7701 torture_assert_ntstatus_ok(tctx, r.out.result,
7702 "failed to enumerate users");
7704 status = r.out.result;
7706 total_num_entries += num_entries;
7707 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7709 if (total_num_entries_p) {
7710 *total_num_entries_p = total_num_entries;
7716 static bool test_EnumDomainGroups(struct dcerpc_binding_handle *b,
7717 struct torture_context *tctx,
7718 struct policy_handle *domain_handle,
7719 uint32_t *total_num_entries_p)
7722 struct samr_EnumDomainGroups r;
7723 uint32_t resume_handle = 0;
7724 uint32_t num_entries = 0;
7725 uint32_t total_num_entries = 0;
7726 struct samr_SamArray *sam;
7728 r.in.domain_handle = domain_handle;
7729 r.in.max_size = (uint32_t)-1;
7730 r.in.resume_handle = &resume_handle;
7733 r.out.num_entries = &num_entries;
7734 r.out.resume_handle = &resume_handle;
7736 torture_comment(tctx, "Testing EnumDomainGroups\n");
7739 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
7740 "EnumDomainGroups failed");
7741 if (NT_STATUS_IS_ERR(r.out.result)) {
7742 torture_assert_ntstatus_ok(tctx, r.out.result,
7743 "failed to enumerate groups");
7745 status = r.out.result;
7747 total_num_entries += num_entries;
7748 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7750 if (total_num_entries_p) {
7751 *total_num_entries_p = total_num_entries;
7757 static bool test_EnumDomainAliases(struct dcerpc_binding_handle *b,
7758 struct torture_context *tctx,
7759 struct policy_handle *domain_handle,
7760 uint32_t *total_num_entries_p)
7763 struct samr_EnumDomainAliases r;
7764 uint32_t resume_handle = 0;
7765 uint32_t num_entries = 0;
7766 uint32_t total_num_entries = 0;
7767 struct samr_SamArray *sam;
7769 r.in.domain_handle = domain_handle;
7770 r.in.max_size = (uint32_t)-1;
7771 r.in.resume_handle = &resume_handle;
7774 r.out.num_entries = &num_entries;
7775 r.out.resume_handle = &resume_handle;
7777 torture_comment(tctx, "Testing EnumDomainAliases\n");
7780 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
7781 "EnumDomainAliases failed");
7782 if (NT_STATUS_IS_ERR(r.out.result)) {
7783 torture_assert_ntstatus_ok(tctx, r.out.result,
7784 "failed to enumerate aliases");
7786 status = r.out.result;
7788 total_num_entries += num_entries;
7789 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7791 if (total_num_entries_p) {
7792 *total_num_entries_p = total_num_entries;
7798 static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle *b,
7799 struct torture_context *tctx,
7800 struct policy_handle *handle,
7802 uint32_t *total_num_entries_p)
7805 struct samr_QueryDisplayInfo r;
7806 uint32_t total_num_entries = 0;
7808 r.in.domain_handle = handle;
7811 r.in.max_entries = (uint32_t)-1;
7812 r.in.buf_size = (uint32_t)-1;
7814 torture_comment(tctx, "Testing QueryDisplayInfo\n");
7817 uint32_t total_size;
7818 uint32_t returned_size;
7819 union samr_DispInfo info;
7821 r.out.total_size = &total_size;
7822 r.out.returned_size = &returned_size;
7825 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7826 "failed to query displayinfo");
7827 if (NT_STATUS_IS_ERR(r.out.result)) {
7828 torture_assert_ntstatus_ok(tctx, r.out.result,
7829 "failed to query displayinfo");
7831 status = r.out.result;
7833 if (*r.out.returned_size == 0) {
7837 switch (r.in.level) {
7839 total_num_entries += info.info1.count;
7840 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
7843 total_num_entries += info.info2.count;
7844 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
7847 total_num_entries += info.info3.count;
7848 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
7851 total_num_entries += info.info4.count;
7852 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
7855 total_num_entries += info.info5.count;
7856 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
7862 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7864 if (total_num_entries_p) {
7865 *total_num_entries_p = total_num_entries;
7871 static bool test_ManyObjects(struct dcerpc_pipe *p,
7872 struct torture_context *tctx,
7873 struct policy_handle *domain_handle,
7874 struct dom_sid *domain_sid,
7875 struct torture_samr_context *ctx)
7877 uint32_t num_total = ctx->num_objects_large_dc;
7878 uint32_t num_enum = 0;
7879 uint32_t num_disp = 0;
7880 uint32_t num_created = 0;
7881 uint32_t num_anounced = 0;
7883 struct dcerpc_binding_handle *b = p->binding_handle;
7885 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
7890 struct samr_QueryDomainInfo2 r;
7891 union samr_DomainInfo *info;
7892 r.in.domain_handle = domain_handle;
7896 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
7897 "QueryDomainInfo2 failed");
7898 torture_assert_ntstatus_ok(tctx, r.out.result,
7899 "failed to query domain info");
7901 switch (ctx->choice) {
7902 case TORTURE_SAMR_MANY_ACCOUNTS:
7903 num_anounced = info->general.num_users;
7905 case TORTURE_SAMR_MANY_GROUPS:
7906 num_anounced = info->general.num_groups;
7908 case TORTURE_SAMR_MANY_ALIASES:
7909 num_anounced = info->general.num_aliases;
7918 for (i=0; i < num_total; i++) {
7920 const char *name = NULL;
7922 switch (ctx->choice) {
7923 case TORTURE_SAMR_MANY_ACCOUNTS:
7924 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
7925 torture_assert(tctx,
7926 test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false),
7927 "failed to create user");
7929 case TORTURE_SAMR_MANY_GROUPS:
7930 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
7931 torture_assert(tctx,
7932 test_CreateDomainGroup(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
7933 "failed to create group");
7935 case TORTURE_SAMR_MANY_ALIASES:
7936 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
7937 torture_assert(tctx,
7938 test_CreateAlias(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
7939 "failed to create alias");
7944 if (!ndr_policy_handle_empty(&handles[i])) {
7951 switch (ctx->choice) {
7952 case TORTURE_SAMR_MANY_ACCOUNTS:
7953 torture_assert(tctx,
7954 test_EnumDomainUsers(b, tctx, domain_handle, &num_enum),
7955 "failed to enum users");
7957 case TORTURE_SAMR_MANY_GROUPS:
7958 torture_assert(tctx,
7959 test_EnumDomainGroups(b, tctx, domain_handle, &num_enum),
7960 "failed to enum groups");
7962 case TORTURE_SAMR_MANY_ALIASES:
7963 torture_assert(tctx,
7964 test_EnumDomainAliases(b, tctx, domain_handle, &num_enum),
7965 "failed to enum aliases");
7973 switch (ctx->choice) {
7974 case TORTURE_SAMR_MANY_ACCOUNTS:
7975 torture_assert(tctx,
7976 test_QueryDisplayInfo_level(b, tctx, domain_handle, 1, &num_disp),
7977 "failed to query display info");
7979 case TORTURE_SAMR_MANY_GROUPS:
7980 torture_assert(tctx,
7981 test_QueryDisplayInfo_level(b, tctx, domain_handle, 3, &num_disp),
7982 "failed to query display info");
7984 case TORTURE_SAMR_MANY_ALIASES:
7985 /* no aliases in dispinfo */
7991 /* close or delete */
7993 for (i=0; i < num_total; i++) {
7995 if (ndr_policy_handle_empty(&handles[i])) {
7999 if (torture_setting_bool(tctx, "samba3", false)) {
8000 torture_assert(tctx,
8001 test_samr_handle_Close(b, tctx, &handles[i]),
8002 "failed to close handle");
8004 switch (ctx->choice) {
8005 case TORTURE_SAMR_MANY_ACCOUNTS:
8006 torture_assert(tctx,
8007 test_DeleteUser(b, tctx, &handles[i]),
8008 "failed to delete user");
8010 case TORTURE_SAMR_MANY_GROUPS:
8011 torture_assert(tctx,
8012 test_DeleteDomainGroup(b, tctx, &handles[i]),
8013 "failed to delete group");
8015 case TORTURE_SAMR_MANY_ALIASES:
8016 torture_assert(tctx,
8017 test_DeleteAlias(b, tctx, &handles[i]),
8018 "failed to delete alias");
8026 talloc_free(handles);
8028 if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
8029 torture_comment(tctx,
8030 "unexpected number of results (%u) returned in enum call, expected %u\n",
8031 num_enum, num_anounced + num_created);
8033 torture_comment(tctx,
8034 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
8035 num_disp, num_anounced + num_created);
8041 static bool test_Connect(struct dcerpc_binding_handle *b,
8042 struct torture_context *tctx,
8043 struct policy_handle *handle);
8045 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
8046 struct torture_samr_context *ctx, struct dom_sid *sid)
8048 struct samr_OpenDomain r;
8049 struct policy_handle domain_handle;
8050 struct policy_handle alias_handle;
8051 struct policy_handle user_handle;
8052 struct policy_handle group_handle;
8054 struct dcerpc_binding_handle *b = p->binding_handle;
8056 ZERO_STRUCT(alias_handle);
8057 ZERO_STRUCT(user_handle);
8058 ZERO_STRUCT(group_handle);
8059 ZERO_STRUCT(domain_handle);
8061 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
8063 r.in.connect_handle = &ctx->handle;
8064 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8066 r.out.domain_handle = &domain_handle;
8068 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenDomain_r(b, tctx, &r),
8069 "OpenDomain failed");
8070 torture_assert_ntstatus_ok(tctx, r.out.result, "OpenDomain failed");
8072 /* run the domain tests with the main handle closed - this tests
8073 the servers reference counting */
8074 torture_assert(tctx, test_samr_handle_Close(b, tctx, &ctx->handle), "Failed to close SAMR handle");
8076 switch (ctx->choice) {
8077 case TORTURE_SAMR_PASSWORDS:
8078 case TORTURE_SAMR_USER_PRIVILEGES:
8079 if (!torture_setting_bool(tctx, "samba3", false)) {
8080 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
8082 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
8084 torture_result(tctx, TORTURE_FAIL, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
8087 case TORTURE_SAMR_USER_ATTRIBUTES:
8088 if (!torture_setting_bool(tctx, "samba3", false)) {
8089 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
8091 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
8092 /* This test needs 'complex' users to validate */
8093 ret &= test_QueryDisplayInfo(b, tctx, &domain_handle);
8095 torture_result(tctx, TORTURE_FAIL, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
8098 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
8099 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
8100 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
8101 if (!torture_setting_bool(tctx, "samba3", false)) {
8102 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
8104 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
8106 torture_result(tctx, TORTURE_FAIL, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx, sid));
8109 case TORTURE_SAMR_MANY_ACCOUNTS:
8110 case TORTURE_SAMR_MANY_GROUPS:
8111 case TORTURE_SAMR_MANY_ALIASES:
8112 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
8114 torture_result(tctx, TORTURE_FAIL, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
8117 case TORTURE_SAMR_OTHER:
8118 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
8120 torture_result(tctx, TORTURE_FAIL, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
8122 if (!torture_setting_bool(tctx, "samba3", false)) {
8123 ret &= test_QuerySecurity(b, tctx, &domain_handle);
8125 ret &= test_RemoveMemberFromForeignDomain(b, tctx, &domain_handle);
8126 ret &= test_CreateAlias(b, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
8127 ret &= test_CreateDomainGroup(b, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
8128 ret &= test_GetAliasMembership(b, tctx, &domain_handle);
8129 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
8130 ret &= test_QueryDomainInfo2(b, tctx, &domain_handle);
8131 ret &= test_EnumDomainUsers_all(b, tctx, &domain_handle);
8132 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
8133 ret &= test_EnumDomainGroups_all(b, tctx, &domain_handle);
8134 ret &= test_EnumDomainAliases_all(b, tctx, &domain_handle);
8135 ret &= test_QueryDisplayInfo2(b, tctx, &domain_handle);
8136 ret &= test_QueryDisplayInfo3(b, tctx, &domain_handle);
8137 ret &= test_QueryDisplayInfo_continue(b, tctx, &domain_handle);
8139 if (torture_setting_bool(tctx, "samba4", false)) {
8140 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
8142 ret &= test_GetDisplayEnumerationIndex(b, tctx, &domain_handle);
8143 ret &= test_GetDisplayEnumerationIndex2(b, tctx, &domain_handle);
8145 ret &= test_GroupList(b, tctx, sid, &domain_handle);
8146 ret &= test_TestPrivateFunctionsDomain(b, tctx, &domain_handle);
8147 ret &= test_RidToSid(b, tctx, sid, &domain_handle);
8148 ret &= test_GetBootKeyInformation(b, tctx, &domain_handle);
8150 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
8155 if (!ndr_policy_handle_empty(&user_handle) &&
8156 !test_DeleteUser(b, tctx, &user_handle)) {
8160 if (!ndr_policy_handle_empty(&alias_handle) &&
8161 !test_DeleteAlias(b, tctx, &alias_handle)) {
8165 if (!ndr_policy_handle_empty(&group_handle) &&
8166 !test_DeleteDomainGroup(b, tctx, &group_handle)) {
8170 torture_assert(tctx, test_samr_handle_Close(b, tctx, &domain_handle), "Failed to close SAMR domain handle");
8172 torture_assert(tctx, test_Connect(b, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
8173 /* reconnect the main handle */
8176 torture_result(tctx, TORTURE_FAIL, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
8182 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
8183 struct torture_samr_context *ctx, const char *domain)
8185 struct samr_LookupDomain r;
8186 struct dom_sid2 *sid = NULL;
8187 struct lsa_String n1;
8188 struct lsa_String n2;
8190 struct dcerpc_binding_handle *b = p->binding_handle;
8192 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
8194 /* check for correct error codes */
8195 r.in.connect_handle = &ctx->handle;
8196 r.in.domain_name = &n2;
8200 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
8201 "LookupDomain failed");
8202 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, r.out.result, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
8204 init_lsa_String(&n2, "xxNODOMAINxx");
8206 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
8207 "LookupDomain failed");
8208 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, r.out.result, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
8210 r.in.connect_handle = &ctx->handle;
8212 init_lsa_String(&n1, domain);
8213 r.in.domain_name = &n1;
8215 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
8216 "LookupDomain failed");
8217 torture_assert_ntstatus_ok(tctx, r.out.result, "LookupDomain");
8219 if (!test_GetDomPwInfo(p, tctx, &n1)) {
8223 if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
8231 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
8232 struct torture_samr_context *ctx)
8234 struct samr_EnumDomains r;
8235 uint32_t resume_handle = 0;
8236 uint32_t num_entries = 0;
8237 struct samr_SamArray *sam = NULL;
8240 struct dcerpc_binding_handle *b = p->binding_handle;
8242 r.in.connect_handle = &ctx->handle;
8243 r.in.resume_handle = &resume_handle;
8244 r.in.buf_size = (uint32_t)-1;
8245 r.out.resume_handle = &resume_handle;
8246 r.out.num_entries = &num_entries;
8249 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
8250 "EnumDomains failed");
8251 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
8257 for (i=0;i<sam->count;i++) {
8258 if (!test_LookupDomain(p, tctx, ctx,
8259 sam->entries[i].name.string)) {
8264 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
8265 "EnumDomains failed");
8266 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
8272 static bool test_Connect(struct dcerpc_binding_handle *b,
8273 struct torture_context *tctx,
8274 struct policy_handle *handle)
8276 struct samr_Connect r;
8277 struct samr_Connect2 r2;
8278 struct samr_Connect3 r3;
8279 struct samr_Connect4 r4;
8280 struct samr_Connect5 r5;
8281 union samr_ConnectInfo info;
8282 struct policy_handle h;
8283 uint32_t level_out = 0;
8284 bool ret = true, got_handle = false;
8286 torture_comment(tctx, "Testing samr_Connect\n");
8288 r.in.system_name = NULL;
8289 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8290 r.out.connect_handle = &h;
8292 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect_r(b, tctx, &r),
8294 if (!NT_STATUS_IS_OK(r.out.result)) {
8295 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(r.out.result));
8302 torture_comment(tctx, "Testing samr_Connect2\n");
8304 r2.in.system_name = NULL;
8305 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8306 r2.out.connect_handle = &h;
8308 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect2_r(b, tctx, &r2),
8310 if (!NT_STATUS_IS_OK(r2.out.result)) {
8311 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(r2.out.result));
8315 test_samr_handle_Close(b, tctx, handle);
8321 torture_comment(tctx, "Testing samr_Connect3\n");
8323 r3.in.system_name = NULL;
8325 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8326 r3.out.connect_handle = &h;
8328 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect3_r(b, tctx, &r3),
8330 if (!NT_STATUS_IS_OK(r3.out.result)) {
8331 torture_result(tctx, TORTURE_FAIL, "Connect3 failed - %s\n", nt_errstr(r3.out.result));
8335 test_samr_handle_Close(b, tctx, handle);
8341 torture_comment(tctx, "Testing samr_Connect4\n");
8343 r4.in.system_name = "";
8344 r4.in.client_version = 0;
8345 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8346 r4.out.connect_handle = &h;
8348 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect4_r(b, tctx, &r4),
8350 if (!NT_STATUS_IS_OK(r4.out.result)) {
8351 torture_result(tctx, TORTURE_FAIL, "Connect4 failed - %s\n", nt_errstr(r4.out.result));
8355 test_samr_handle_Close(b, tctx, handle);
8361 torture_comment(tctx, "Testing samr_Connect5\n");
8363 info.info1.client_version = 0;
8364 info.info1.unknown2 = 0;
8366 r5.in.system_name = "";
8367 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8369 r5.out.level_out = &level_out;
8370 r5.in.info_in = &info;
8371 r5.out.info_out = &info;
8372 r5.out.connect_handle = &h;
8374 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect5_r(b, tctx, &r5),
8376 if (!NT_STATUS_IS_OK(r5.out.result)) {
8377 torture_result(tctx, TORTURE_FAIL, "Connect5 failed - %s\n", nt_errstr(r5.out.result));
8381 test_samr_handle_Close(b, tctx, handle);
8391 static bool test_samr_ValidatePassword(struct torture_context *tctx,
8392 struct dcerpc_pipe *p)
8394 struct samr_ValidatePassword r;
8395 union samr_ValidatePasswordReq req;
8396 union samr_ValidatePasswordRep *repp = NULL;
8398 const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
8400 struct dcerpc_binding_handle *b = p->binding_handle;
8402 torture_comment(tctx, "Testing samr_ValidatePassword\n");
8404 if (p->conn->transport.transport != NCACN_IP_TCP) {
8405 torture_comment(tctx, "samr_ValidatePassword only should succeed over NCACN_IP_TCP!\n");
8409 r.in.level = NetValidatePasswordReset;
8414 req.req3.account.string = "non-existent-account-aklsdji";
8416 for (i=0; passwords[i]; i++) {
8417 req.req3.password.string = passwords[i];
8419 status = dcerpc_samr_ValidatePassword_r(b, tctx, &r);
8420 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
8421 torture_skip(tctx, "ValidatePassword not supported by server\n");
8423 torture_assert_ntstatus_ok(tctx, status,
8424 "samr_ValidatePassword failed");
8425 torture_assert_ntstatus_ok(tctx, r.out.result,
8426 "samr_ValidatePassword failed");
8427 torture_comment(tctx, "Server %s password '%s' with code %i\n",
8428 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
8429 req.req3.password.string, repp->ctr3.status);
8435 bool torture_rpc_samr(struct torture_context *torture)
8438 struct dcerpc_pipe *p;
8440 struct torture_samr_context *ctx;
8441 struct dcerpc_binding_handle *b;
8443 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8444 if (!NT_STATUS_IS_OK(status)) {
8447 b = p->binding_handle;
8449 ctx = talloc_zero(torture, struct torture_samr_context);
8451 ctx->choice = TORTURE_SAMR_OTHER;
8453 ret &= test_Connect(b, torture, &ctx->handle);
8455 if (!torture_setting_bool(torture, "samba3", false)) {
8456 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8459 ret &= test_EnumDomains(p, torture, ctx);
8461 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8463 ret &= test_Shutdown(b, torture, &ctx->handle);
8465 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8471 bool torture_rpc_samr_users(struct torture_context *torture)
8474 struct dcerpc_pipe *p;
8476 struct torture_samr_context *ctx;
8477 struct dcerpc_binding_handle *b;
8479 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8480 if (!NT_STATUS_IS_OK(status)) {
8483 b = p->binding_handle;
8485 ctx = talloc_zero(torture, struct torture_samr_context);
8487 ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
8489 ret &= test_Connect(b, torture, &ctx->handle);
8491 if (!torture_setting_bool(torture, "samba3", false)) {
8492 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8495 ret &= test_EnumDomains(p, torture, ctx);
8497 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8499 ret &= test_Shutdown(b, torture, &ctx->handle);
8501 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8507 bool torture_rpc_samr_passwords(struct torture_context *torture)
8510 struct dcerpc_pipe *p;
8512 struct torture_samr_context *ctx;
8513 struct dcerpc_binding_handle *b;
8515 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8516 if (!NT_STATUS_IS_OK(status)) {
8519 b = p->binding_handle;
8521 ctx = talloc_zero(torture, struct torture_samr_context);
8523 ctx->choice = TORTURE_SAMR_PASSWORDS;
8525 ret &= test_Connect(b, torture, &ctx->handle);
8527 ret &= test_EnumDomains(p, torture, ctx);
8529 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8534 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
8535 struct dcerpc_pipe *p2,
8536 struct cli_credentials *machine_credentials)
8539 struct dcerpc_pipe *p;
8541 struct torture_samr_context *ctx;
8542 struct dcerpc_binding_handle *b;
8544 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8545 if (!NT_STATUS_IS_OK(status)) {
8548 b = p->binding_handle;
8550 ctx = talloc_zero(torture, struct torture_samr_context);
8552 ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
8553 ctx->machine_credentials = machine_credentials;
8555 ret &= test_Connect(b, torture, &ctx->handle);
8557 ret &= test_EnumDomains(p, torture, ctx);
8559 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8564 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
8566 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.pwdlastset");
8567 struct torture_rpc_tcase *tcase;
8569 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8571 TEST_ACCOUNT_NAME_PWD);
8573 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
8574 torture_rpc_samr_pwdlastset);
8579 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
8580 struct dcerpc_pipe *p2,
8581 struct cli_credentials *machine_credentials)
8584 struct dcerpc_pipe *p;
8586 struct torture_samr_context *ctx;
8587 struct dcerpc_binding_handle *b;
8589 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8590 if (!NT_STATUS_IS_OK(status)) {
8593 b = p->binding_handle;
8595 ctx = talloc_zero(torture, struct torture_samr_context);
8597 ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
8598 ctx->machine_credentials = machine_credentials;
8600 ret &= test_Connect(b, torture, &ctx->handle);
8602 ret &= test_EnumDomains(p, torture, ctx);
8604 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8609 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
8611 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.users.privileges");
8612 struct torture_rpc_tcase *tcase;
8614 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8616 TEST_ACCOUNT_NAME_PWD);
8618 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
8619 torture_rpc_samr_users_privileges_delete_user);
8624 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
8625 struct dcerpc_pipe *p2,
8629 struct dcerpc_pipe *p;
8631 struct torture_samr_context *ctx =
8632 talloc_get_type_abort(data, struct torture_samr_context);
8633 struct dcerpc_binding_handle *b;
8635 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8636 if (!NT_STATUS_IS_OK(status)) {
8639 b = p->binding_handle;
8641 ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
8642 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8643 ctx->num_objects_large_dc);
8645 ret &= test_Connect(b, torture, &ctx->handle);
8647 ret &= test_EnumDomains(p, torture, ctx);
8649 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8654 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
8655 struct dcerpc_pipe *p2,
8659 struct dcerpc_pipe *p;
8661 struct torture_samr_context *ctx =
8662 talloc_get_type_abort(data, struct torture_samr_context);
8663 struct dcerpc_binding_handle *b;
8665 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8666 if (!NT_STATUS_IS_OK(status)) {
8669 b = p->binding_handle;
8671 ctx->choice = TORTURE_SAMR_MANY_GROUPS;
8672 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8673 ctx->num_objects_large_dc);
8675 ret &= test_Connect(b, torture, &ctx->handle);
8677 ret &= test_EnumDomains(p, torture, ctx);
8679 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8684 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
8685 struct dcerpc_pipe *p2,
8689 struct dcerpc_pipe *p;
8691 struct torture_samr_context *ctx =
8692 talloc_get_type_abort(data, struct torture_samr_context);
8693 struct dcerpc_binding_handle *b;
8695 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8696 if (!NT_STATUS_IS_OK(status)) {
8699 b = p->binding_handle;
8701 ctx->choice = TORTURE_SAMR_MANY_ALIASES;
8702 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8703 ctx->num_objects_large_dc);
8705 ret &= test_Connect(b, torture, &ctx->handle);
8707 ret &= test_EnumDomains(p, torture, ctx);
8709 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8714 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
8716 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.large-dc");
8717 struct torture_rpc_tcase *tcase;
8718 struct torture_samr_context *ctx;
8720 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
8722 ctx = talloc_zero(suite, struct torture_samr_context);
8723 ctx->num_objects_large_dc = 150;
8725 torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
8726 torture_rpc_samr_many_aliases, ctx);
8727 torture_rpc_tcase_add_test_ex(tcase, "many_groups",
8728 torture_rpc_samr_many_groups, ctx);
8729 torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
8730 torture_rpc_samr_many_accounts, ctx);
8735 static bool torture_rpc_samr_badpwdcount(struct torture_context *torture,
8736 struct dcerpc_pipe *p2,
8737 struct cli_credentials *machine_credentials)
8740 struct dcerpc_pipe *p;
8742 struct torture_samr_context *ctx;
8743 struct dcerpc_binding_handle *b;
8745 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8746 if (!NT_STATUS_IS_OK(status)) {
8749 b = p->binding_handle;
8751 ctx = talloc_zero(torture, struct torture_samr_context);
8753 ctx->choice = TORTURE_SAMR_PASSWORDS_BADPWDCOUNT;
8754 ctx->machine_credentials = machine_credentials;
8756 ret &= test_Connect(b, torture, &ctx->handle);
8758 ret &= test_EnumDomains(p, torture, ctx);
8760 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8765 struct torture_suite *torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX *mem_ctx)
8767 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.badpwdcount");
8768 struct torture_rpc_tcase *tcase;
8770 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8772 TEST_ACCOUNT_NAME_PWD);
8774 torture_rpc_tcase_add_test_creds(tcase, "badPwdCount",
8775 torture_rpc_samr_badpwdcount);
8780 static bool torture_rpc_samr_lockout(struct torture_context *torture,
8781 struct dcerpc_pipe *p2,
8782 struct cli_credentials *machine_credentials)
8785 struct dcerpc_pipe *p;
8787 struct torture_samr_context *ctx;
8788 struct dcerpc_binding_handle *b;
8790 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8791 if (!NT_STATUS_IS_OK(status)) {
8794 b = p->binding_handle;
8796 ctx = talloc_zero(torture, struct torture_samr_context);
8798 ctx->choice = TORTURE_SAMR_PASSWORDS_LOCKOUT;
8799 ctx->machine_credentials = machine_credentials;
8801 ret &= test_Connect(b, torture, &ctx->handle);
8803 ret &= test_EnumDomains(p, torture, ctx);
8805 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8810 struct torture_suite *torture_rpc_samr_passwords_lockout(TALLOC_CTX *mem_ctx)
8812 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.lockout");
8813 struct torture_rpc_tcase *tcase;
8815 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8817 TEST_ACCOUNT_NAME_PWD);
8819 torture_rpc_tcase_add_test_creds(tcase, "lockout",
8820 torture_rpc_samr_lockout);
8825 struct torture_suite *torture_rpc_samr_passwords_validate(TALLOC_CTX *mem_ctx)
8827 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.validate");
8828 struct torture_rpc_tcase *tcase;
8830 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr",
8832 torture_rpc_tcase_add_test(tcase, "validate",
8833 test_samr_ValidatePassword);