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, base_account_name, 0);
367 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
368 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
369 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
370 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
371 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
372 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
373 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
374 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
375 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
376 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
377 test_account_name = base_account_name;
378 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
379 SAMR_FIELD_ACCOUNT_NAME);
381 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
382 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
383 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
384 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
385 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
386 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
387 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
388 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
389 SAMR_FIELD_FULL_NAME);
391 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
392 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
393 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
394 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
395 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
396 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
397 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
398 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
399 SAMR_FIELD_FULL_NAME);
401 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
402 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
403 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
404 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
405 SAMR_FIELD_LOGON_SCRIPT);
407 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
408 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
409 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
410 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
411 SAMR_FIELD_PROFILE_PATH);
413 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
414 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
415 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
416 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
417 SAMR_FIELD_HOME_DIRECTORY);
418 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
419 SAMR_FIELD_HOME_DIRECTORY);
421 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
422 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
423 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
424 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
425 SAMR_FIELD_HOME_DRIVE);
426 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
427 SAMR_FIELD_HOME_DRIVE);
429 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
430 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
431 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
432 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
433 SAMR_FIELD_DESCRIPTION);
435 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
436 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
437 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
438 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
439 SAMR_FIELD_WORKSTATIONS);
440 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
441 SAMR_FIELD_WORKSTATIONS);
442 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
443 SAMR_FIELD_WORKSTATIONS);
444 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
445 SAMR_FIELD_WORKSTATIONS);
447 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
448 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
449 SAMR_FIELD_PARAMETERS);
450 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
451 SAMR_FIELD_PARAMETERS);
452 /* also empty user parameters are allowed */
453 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
454 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
455 SAMR_FIELD_PARAMETERS);
456 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
457 SAMR_FIELD_PARAMETERS);
459 /* Samba 3 cannot store country_code and 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 LM 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 LM 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 NT 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 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2302 const char *account_string,
2303 int policy_min_pw_len,
2305 const char *newpass,
2306 NTTIME last_password_change,
2307 bool handle_reject_reason)
2309 struct samr_ChangePasswordUser3 r;
2311 struct lsa_String server, account, account_bad;
2312 struct samr_CryptPassword nt_pass, lm_pass;
2313 struct samr_Password nt_verifier, lm_verifier;
2315 struct dcerpc_binding_handle *b = p->binding_handle;
2316 uint8_t old_nt_hash[16], new_nt_hash[16];
2317 uint8_t old_lm_hash[16], new_lm_hash[16];
2319 struct samr_DomInfo1 *dominfo = NULL;
2320 struct userPwdChangeFailureInformation *reject = NULL;
2322 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2324 if (newpass == NULL) {
2326 if (policy_min_pw_len == 0) {
2327 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2329 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2331 } while (check_password_quality(newpass) == false);
2333 torture_comment(tctx, "Using password '%s'\n", newpass);
2336 torture_assert(tctx, *password != NULL,
2337 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2339 oldpass = *password;
2340 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2341 init_lsa_String(&account, account_string);
2343 E_md4hash(oldpass, old_nt_hash);
2344 E_md4hash(newpass, new_nt_hash);
2346 E_deshash(oldpass, old_lm_hash);
2347 E_deshash(newpass, new_lm_hash);
2349 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2350 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2351 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2353 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2354 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2355 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2357 /* Break the verification */
2358 nt_verifier.hash[0]++;
2360 r.in.server = &server;
2361 r.in.account = &account;
2362 r.in.nt_password = &nt_pass;
2363 r.in.nt_verifier = &nt_verifier;
2365 r.in.lm_password = &lm_pass;
2366 r.in.lm_verifier = &lm_verifier;
2367 r.in.password3 = NULL;
2368 r.out.dominfo = &dominfo;
2369 r.out.reject = &reject;
2371 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2372 "ChangePasswordUser3 failed");
2373 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2374 __location__, __FUNCTION__,
2375 oldpass, newpass, nt_errstr(r.out.result));
2376 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2377 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2378 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2379 nt_errstr(r.out.result));
2383 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2384 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2385 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2387 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2388 /* Break the NT hash */
2390 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2391 /* Unbreak it again */
2393 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2395 r.in.server = &server;
2396 r.in.account = &account;
2397 r.in.nt_password = &nt_pass;
2398 r.in.nt_verifier = &nt_verifier;
2400 r.in.lm_password = &lm_pass;
2401 r.in.lm_verifier = &lm_verifier;
2402 r.in.password3 = NULL;
2403 r.out.dominfo = &dominfo;
2404 r.out.reject = &reject;
2406 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2407 "ChangePasswordUser3 failed");
2408 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2409 __location__, __FUNCTION__,
2410 oldpass, newpass, nt_errstr(r.out.result));
2411 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2412 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2413 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2414 nt_errstr(r.out.result));
2418 /* This shouldn't be a valid name */
2419 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2421 r.in.account = &account_bad;
2422 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2423 "ChangePasswordUser3 failed");
2424 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2425 __location__, __FUNCTION__,
2426 oldpass, newpass, nt_errstr(r.out.result));
2427 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2428 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2429 nt_errstr(r.out.result));
2433 E_md4hash(oldpass, old_nt_hash);
2434 E_md4hash(newpass, new_nt_hash);
2436 E_deshash(oldpass, old_lm_hash);
2437 E_deshash(newpass, new_lm_hash);
2439 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2440 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2441 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2443 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2444 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2445 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2447 r.in.server = &server;
2448 r.in.account = &account;
2449 r.in.nt_password = &nt_pass;
2450 r.in.nt_verifier = &nt_verifier;
2452 r.in.lm_password = &lm_pass;
2453 r.in.lm_verifier = &lm_verifier;
2454 r.in.password3 = NULL;
2455 r.out.dominfo = &dominfo;
2456 r.out.reject = &reject;
2458 unix_to_nt_time(&t, time(NULL));
2460 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2461 "ChangePasswordUser3 failed");
2462 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2463 __location__, __FUNCTION__,
2464 oldpass, newpass, nt_errstr(r.out.result));
2466 torture_comment(tctx, "(%s): dominfo[%s], reject[%s], handle_reject_reason[%s], "
2467 "last_password_change[%s], dominfo->min_password_age[%lld]\n",
2469 (dominfo == NULL)? "NULL" : "present",
2470 reject ? "true" : "false",
2471 handle_reject_reason ? "true" : "false",
2472 null_nttime(last_password_change) ? "null" : "not null",
2473 dominfo ? (long long)dominfo->min_password_age : (long long)0);
2475 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2478 && handle_reject_reason
2479 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2480 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2482 if (reject && (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR)) {
2483 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2484 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2489 /* We tested the order of precendence which is as follows:
2498 if ((dominfo->min_password_age < 0) && !null_nttime(last_password_change) &&
2499 (last_password_change - dominfo->min_password_age > t)) {
2501 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2502 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2503 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2507 } else if ((dominfo->min_password_length > 0) &&
2508 (strlen(newpass) < dominfo->min_password_length)) {
2510 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2511 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2512 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT, reject->extendedFailureReason);
2516 } else if ((dominfo->password_history_length > 0) &&
2517 strequal(oldpass, newpass)) {
2519 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PWD_IN_HISTORY) {
2520 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2521 SAM_PWD_CHANGE_PWD_IN_HISTORY, reject->extendedFailureReason);
2524 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2526 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NOT_COMPLEX) {
2527 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2528 SAM_PWD_CHANGE_NOT_COMPLEX, reject->extendedFailureReason);
2534 if (reject->extendedFailureReason == SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2535 /* retry with adjusted size */
2536 return test_ChangePasswordUser3(p, tctx, account_string,
2537 dominfo->min_password_length,
2538 password, NULL, 0, false);
2542 } else if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2543 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2544 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2545 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2548 /* Perhaps the server has a 'min password age' set? */
2551 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3");
2553 *password = talloc_strdup(tctx, newpass);
2559 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2560 const char *account_string,
2561 struct policy_handle *handle,
2565 struct samr_ChangePasswordUser3 r;
2566 struct samr_SetUserInfo s;
2567 union samr_UserInfo u;
2568 DATA_BLOB session_key;
2569 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2570 uint8_t confounder[16];
2574 struct lsa_String server, account;
2575 struct samr_CryptPassword nt_pass;
2576 struct samr_Password nt_verifier;
2577 DATA_BLOB new_random_pass;
2580 struct dcerpc_binding_handle *b = p->binding_handle;
2581 uint8_t old_nt_hash[16], new_nt_hash[16];
2583 struct samr_DomInfo1 *dominfo = NULL;
2584 struct userPwdChangeFailureInformation *reject = NULL;
2586 new_random_pass = samr_very_rand_pass(tctx, 128);
2588 torture_assert(tctx, *password != NULL,
2589 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2591 oldpass = *password;
2592 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2593 init_lsa_String(&account, account_string);
2595 s.in.user_handle = handle;
2601 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2603 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2605 status = dcerpc_fetch_session_key(p, &session_key);
2606 if (!NT_STATUS_IS_OK(status)) {
2607 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
2608 s.in.level, nt_errstr(status));
2612 generate_random_buffer((uint8_t *)confounder, 16);
2615 MD5Update(&ctx, confounder, 16);
2616 MD5Update(&ctx, session_key.data, session_key.length);
2617 MD5Final(confounded_session_key.data, &ctx);
2619 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2620 memcpy(&u.info25.password.data[516], confounder, 16);
2622 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2624 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
2625 "SetUserInfo failed");
2626 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2627 __location__, __FUNCTION__,
2628 oldpass, "RANDOM", nt_errstr(s.out.result));
2629 if (!NT_STATUS_IS_OK(s.out.result)) {
2630 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
2631 s.in.level, nt_errstr(s.out.result));
2635 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2637 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2639 new_random_pass = samr_very_rand_pass(tctx, 128);
2641 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2643 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2644 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2645 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2647 r.in.server = &server;
2648 r.in.account = &account;
2649 r.in.nt_password = &nt_pass;
2650 r.in.nt_verifier = &nt_verifier;
2652 r.in.lm_password = NULL;
2653 r.in.lm_verifier = NULL;
2654 r.in.password3 = NULL;
2655 r.out.dominfo = &dominfo;
2656 r.out.reject = &reject;
2658 unix_to_nt_time(&t, time(NULL));
2660 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2661 "ChangePasswordUser3 failed");
2662 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2663 __location__, __FUNCTION__,
2664 oldpass, "RANDOM", nt_errstr(r.out.result));
2666 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2667 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2668 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2669 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2672 /* Perhaps the server has a 'min password age' set? */
2674 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2675 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed - %s\n", nt_errstr(r.out.result));
2679 newpass = samr_rand_pass(tctx, 128);
2681 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2683 E_md4hash(newpass, new_nt_hash);
2685 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2686 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2687 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2689 r.in.server = &server;
2690 r.in.account = &account;
2691 r.in.nt_password = &nt_pass;
2692 r.in.nt_verifier = &nt_verifier;
2694 r.in.lm_password = NULL;
2695 r.in.lm_verifier = NULL;
2696 r.in.password3 = NULL;
2697 r.out.dominfo = &dominfo;
2698 r.out.reject = &reject;
2700 unix_to_nt_time(&t, time(NULL));
2702 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2703 "ChangePasswordUser3 failed");
2704 torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2705 __location__, __FUNCTION__,
2706 oldpass, newpass, nt_errstr(r.out.result));
2708 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2709 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2710 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2711 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2714 /* Perhaps the server has a 'min password age' set? */
2717 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3 (on second random password)");
2718 *password = talloc_strdup(tctx, newpass);
2725 static bool test_GetMembersInAlias(struct dcerpc_binding_handle *b,
2726 struct torture_context *tctx,
2727 struct policy_handle *alias_handle)
2729 struct samr_GetMembersInAlias r;
2730 struct lsa_SidArray sids;
2732 torture_comment(tctx, "Testing GetMembersInAlias\n");
2734 r.in.alias_handle = alias_handle;
2737 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetMembersInAlias_r(b, tctx, &r),
2738 "GetMembersInAlias failed");
2739 torture_assert_ntstatus_ok(tctx, r.out.result, "GetMembersInAlias failed");
2744 static bool test_AddMemberToAlias(struct dcerpc_binding_handle *b,
2745 struct torture_context *tctx,
2746 struct policy_handle *alias_handle,
2747 const struct dom_sid *domain_sid)
2749 struct samr_AddAliasMember r;
2750 struct samr_DeleteAliasMember d;
2751 struct dom_sid *sid;
2753 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2755 torture_comment(tctx, "Testing AddAliasMember\n");
2756 r.in.alias_handle = alias_handle;
2759 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddAliasMember_r(b, tctx, &r),
2760 "AddAliasMember failed");
2761 torture_assert_ntstatus_ok(tctx, r.out.result, "AddAliasMember failed");
2763 d.in.alias_handle = alias_handle;
2766 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteAliasMember_r(b, tctx, &d),
2767 "DeleteAliasMember failed");
2768 torture_assert_ntstatus_ok(tctx, d.out.result, "DelAliasMember failed");
2773 static bool test_AddMultipleMembersToAlias(struct dcerpc_binding_handle *b,
2774 struct torture_context *tctx,
2775 struct policy_handle *alias_handle)
2777 struct samr_AddMultipleMembersToAlias a;
2778 struct samr_RemoveMultipleMembersFromAlias r;
2779 struct lsa_SidArray sids;
2781 torture_comment(tctx, "Testing AddMultipleMembersToAlias\n");
2782 a.in.alias_handle = alias_handle;
2786 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2788 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2789 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2790 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2792 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddMultipleMembersToAlias_r(b, tctx, &a),
2793 "AddMultipleMembersToAlias failed");
2794 torture_assert_ntstatus_ok(tctx, a.out.result, "AddMultipleMembersToAlias");
2797 torture_comment(tctx, "Testing RemoveMultipleMembersFromAlias\n");
2798 r.in.alias_handle = alias_handle;
2801 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2802 "RemoveMultipleMembersFromAlias failed");
2803 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2805 /* strange! removing twice doesn't give any error */
2806 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2807 "RemoveMultipleMembersFromAlias failed");
2808 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2810 /* but removing an alias that isn't there does */
2811 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2813 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2814 "RemoveMultipleMembersFromAlias failed");
2815 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2820 static bool test_GetAliasMembership(struct dcerpc_binding_handle *b,
2821 struct torture_context *tctx,
2822 struct policy_handle *domain_handle)
2824 struct samr_GetAliasMembership r;
2825 struct lsa_SidArray sids;
2826 struct samr_Ids rids;
2828 torture_comment(tctx, "Testing GetAliasMembership\n");
2830 r.in.domain_handle = domain_handle;
2835 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2837 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2838 "GetAliasMembership failed");
2839 torture_assert_ntstatus_ok(tctx, r.out.result,
2840 "samr_GetAliasMembership failed");
2842 torture_assert_int_equal(tctx, sids.num_sids, rids.count,
2843 "protocol misbehaviour");
2846 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2847 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2849 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2850 "samr_GetAliasMembership failed");
2851 torture_assert_ntstatus_ok(tctx, r.out.result,
2852 "samr_GetAliasMembership failed");
2855 /* only true for w2k8 it seems
2856 * win7, xp, w2k3 will return a 0 length array pointer */
2858 if (rids.ids && (rids.count == 0)) {
2859 torture_fail(tctx, "samr_GetAliasMembership returned 0 count and a rids array");
2862 if (!rids.ids && rids.count) {
2863 torture_fail(tctx, "samr_GetAliasMembership returned non-0 count but no rids");
2869 static bool test_TestPrivateFunctionsUser(struct dcerpc_binding_handle *b,
2870 struct torture_context *tctx,
2871 struct policy_handle *user_handle)
2873 struct samr_TestPrivateFunctionsUser r;
2875 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2877 r.in.user_handle = user_handle;
2879 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsUser_r(b, tctx, &r),
2880 "TestPrivateFunctionsUser failed");
2881 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2886 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_binding_handle *b,
2887 struct torture_context *tctx,
2888 struct policy_handle *handle,
2893 uint16_t levels[] = { /* 3, */ 5, 21 };
2895 NTTIME pwdlastset3 = 0;
2896 NTTIME pwdlastset5 = 0;
2897 NTTIME pwdlastset21 = 0;
2899 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2900 use_info2 ? "2":"");
2902 for (i=0; i<ARRAY_SIZE(levels); i++) {
2904 struct samr_QueryUserInfo r;
2905 struct samr_QueryUserInfo2 r2;
2906 union samr_UserInfo *info;
2909 r2.in.user_handle = handle;
2910 r2.in.level = levels[i];
2911 r2.out.info = &info;
2912 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r2),
2913 "QueryUserInfo2 failed");
2914 status = r2.out.result;
2917 r.in.user_handle = handle;
2918 r.in.level = levels[i];
2920 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
2921 "QueryUserInfo failed");
2922 status = r.out.result;
2925 if (!NT_STATUS_IS_OK(status) &&
2926 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2927 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo%s level %u failed - %s\n",
2928 use_info2 ? "2":"", levels[i], nt_errstr(status));
2932 switch (levels[i]) {
2934 pwdlastset3 = info->info3.last_password_change;
2937 pwdlastset5 = info->info5.last_password_change;
2940 pwdlastset21 = info->info21.last_password_change;
2946 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2947 "pwdlastset mixup"); */
2948 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2949 "pwdlastset mixup");
2951 *pwdlastset = pwdlastset21;
2953 torture_comment(tctx, "(pwdlastset: %llu)\n",
2954 (unsigned long long) *pwdlastset);
2959 static bool test_SamLogon(struct torture_context *tctx,
2960 struct dcerpc_pipe *p,
2961 struct cli_credentials *machine_credentials,
2962 struct cli_credentials *test_credentials,
2963 NTSTATUS expected_result,
2967 struct netr_LogonSamLogonEx r;
2968 union netr_LogonLevel logon;
2969 union netr_Validation validation;
2970 uint8_t authoritative;
2971 struct netr_IdentityInfo identity;
2972 struct netr_NetworkInfo ninfo;
2973 struct netr_PasswordInfo pinfo;
2974 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2975 int flags = CLI_CRED_NTLM_AUTH;
2976 uint32_t samlogon_flags = 0;
2977 struct netlogon_creds_CredentialState *creds;
2978 struct netr_Authenticator a;
2979 struct dcerpc_binding_handle *b = p->binding_handle;
2981 torture_assert(tctx, (creds = cli_credentials_get_netlogon_creds(machine_credentials)), "");
2983 if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
2984 flags |= CLI_CRED_LANMAN_AUTH;
2987 if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx)) {
2988 flags |= CLI_CRED_NTLMv2_AUTH;
2991 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2992 &identity.account_name.string,
2993 &identity.domain_name.string);
2995 identity.parameter_control =
2996 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2997 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2998 identity.logon_id_low = 0;
2999 identity.logon_id_high = 0;
3000 identity.workstation.string = cli_credentials_get_workstation(test_credentials);
3003 netlogon_creds_client_authenticator(creds, &a);
3005 if (!E_deshash(cli_credentials_get_password(test_credentials), pinfo.lmpassword.hash)) {
3006 ZERO_STRUCT(pinfo.lmpassword.hash);
3008 E_md4hash(cli_credentials_get_password(test_credentials), pinfo.ntpassword.hash);
3010 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
3011 netlogon_creds_aes_encrypt(creds, pinfo.lmpassword.hash, 16);
3012 netlogon_creds_aes_encrypt(creds, pinfo.ntpassword.hash, 16);
3013 } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
3014 netlogon_creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
3015 netlogon_creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
3017 netlogon_creds_des_encrypt(creds, &pinfo.lmpassword);
3018 netlogon_creds_des_encrypt(creds, &pinfo.ntpassword);
3021 pinfo.identity_info = identity;
3022 logon.password = &pinfo;
3024 r.in.logon_level = NetlogonInteractiveInformation;
3026 generate_random_buffer(ninfo.challenge,
3027 sizeof(ninfo.challenge));
3028 chal = data_blob_const(ninfo.challenge,
3029 sizeof(ninfo.challenge));
3031 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
3032 cli_credentials_get_domain(test_credentials));
3034 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
3040 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
3042 ninfo.lm.data = lm_resp.data;
3043 ninfo.lm.length = lm_resp.length;
3045 ninfo.nt.data = nt_resp.data;
3046 ninfo.nt.length = nt_resp.length;
3048 ninfo.identity_info = identity;
3049 logon.network = &ninfo;
3051 r.in.logon_level = NetlogonNetworkInformation;
3054 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3055 r.in.computer_name = cli_credentials_get_workstation(test_credentials);
3056 r.in.logon = &logon;
3057 r.in.flags = &samlogon_flags;
3058 r.out.flags = &samlogon_flags;
3059 r.out.validation = &validation;
3060 r.out.authoritative = &authoritative;
3062 torture_comment(tctx, "Testing LogonSamLogon with name %s\n", identity.account_name.string);
3064 r.in.validation_level = 6;
3066 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
3067 "netr_LogonSamLogonEx failed");
3068 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
3069 r.in.validation_level = 3;
3070 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
3071 "netr_LogonSamLogonEx failed");
3073 if (!NT_STATUS_IS_OK(r.out.result)) {
3074 torture_assert_ntstatus_equal(tctx, r.out.result, expected_result, "LogonSamLogonEx failed");
3077 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogonEx failed");
3083 static bool test_SamLogon_with_creds(struct torture_context *tctx,
3084 struct dcerpc_pipe *p,
3085 struct cli_credentials *machine_creds,
3086 const char *acct_name,
3087 const char *password,
3088 NTSTATUS expected_samlogon_result,
3092 struct cli_credentials *test_credentials;
3094 test_credentials = cli_credentials_init(tctx);
3096 cli_credentials_set_workstation(test_credentials,
3097 cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
3098 cli_credentials_set_domain(test_credentials,
3099 cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
3100 cli_credentials_set_username(test_credentials,
3101 acct_name, CRED_SPECIFIED);
3102 cli_credentials_set_password(test_credentials,
3103 password, CRED_SPECIFIED);
3105 torture_comment(tctx, "Testing samlogon (%s) as %s password: %s\n",
3106 interactive ? "interactive" : "network", acct_name, password);
3108 if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
3109 expected_samlogon_result, interactive)) {
3110 torture_result(tctx, TORTURE_FAIL, "new password did not work\n");
3117 static bool test_SetPassword_level(struct dcerpc_pipe *p,
3118 struct dcerpc_pipe *np,
3119 struct torture_context *tctx,
3120 struct policy_handle *handle,
3122 uint32_t fields_present,
3123 uint8_t password_expired,
3124 bool *matched_expected_error,
3126 const char *acct_name,
3128 struct cli_credentials *machine_creds,
3129 bool use_queryinfo2,
3131 NTSTATUS expected_samlogon_result)
3133 const char *fields = NULL;
3135 struct dcerpc_binding_handle *b = p->binding_handle;
3141 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
3148 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
3149 "(password_expired: %d) %s\n",
3150 use_setinfo2 ? "2":"", level, password_expired,
3151 fields ? fields : "");
3153 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
3158 matched_expected_error)) {
3162 if (!test_QueryUserInfo_pwdlastset(b, tctx, handle,
3168 if (*matched_expected_error == true) {
3172 if (!test_SamLogon_with_creds(tctx, np,
3176 expected_samlogon_result,
3184 static bool setup_schannel_netlogon_pipe(struct torture_context *tctx,
3185 struct cli_credentials *credentials,
3186 struct dcerpc_pipe **p)
3188 struct dcerpc_binding *b;
3191 torture_assert_ntstatus_ok(tctx, torture_rpc_binding(tctx, &b),
3192 "failed to get rpc binding");
3194 /* We have to use schannel, otherwise the SamLogonEx fails
3195 * with INTERNAL_ERROR */
3197 status = dcerpc_binding_set_flags(b,
3198 DCERPC_SCHANNEL | DCERPC_SIGN |
3199 DCERPC_SCHANNEL_AUTO,
3200 DCERPC_AUTH_OPTIONS);
3201 torture_assert_ntstatus_ok(tctx, status, "set flags");
3203 torture_assert_ntstatus_ok(tctx,
3204 dcerpc_pipe_connect_b(tctx, p, b, &ndr_table_netlogon,
3205 credentials, tctx->ev, tctx->lp_ctx),
3206 "failed to bind to netlogon");
3211 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
3212 struct torture_context *tctx,
3213 uint32_t acct_flags,
3214 const char *acct_name,
3215 struct policy_handle *handle,
3217 struct cli_credentials *machine_credentials)
3219 int s = 0, q = 0, f = 0, l = 0, z = 0;
3222 bool set_levels[] = { false, true };
3223 bool query_levels[] = { false, true };
3224 uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
3225 uint32_t nonzeros[] = { 1, 24 };
3226 uint32_t fields_present[] = {
3228 SAMR_FIELD_EXPIRED_FLAG,
3229 SAMR_FIELD_LAST_PWD_CHANGE,
3230 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
3232 SAMR_FIELD_NT_PASSWORD_PRESENT,
3233 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3234 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3235 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3236 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3237 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3238 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
3240 struct dcerpc_pipe *np = NULL;
3242 if (torture_setting_bool(tctx, "samba3", false) ||
3243 torture_setting_bool(tctx, "samba4", false)) {
3245 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
3249 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3251 /* set to 1 to enable testing for all possible opcode
3252 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3255 #define TEST_ALL_LEVELS 1
3256 #define TEST_SET_LEVELS 1
3257 #define TEST_QUERY_LEVELS 1
3259 #ifdef TEST_ALL_LEVELS
3260 for (l=0; l<ARRAY_SIZE(levels); l++) {
3262 for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
3264 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
3265 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
3266 #ifdef TEST_SET_LEVELS
3267 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
3269 #ifdef TEST_QUERY_LEVELS
3270 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
3272 NTTIME pwdlastset_old = 0;
3273 NTTIME pwdlastset_new = 0;
3274 bool matched_expected_error = false;
3275 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
3277 torture_comment(tctx, "------------------------------\n"
3278 "Testing pwdLastSet attribute for flags: 0x%08x "
3279 "(s: %d (l: %d), q: %d)\n",
3280 acct_flags, s, levels[l], q);
3282 switch (levels[l]) {
3286 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3287 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
3288 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
3296 /* set a password and force password change (pwdlastset 0) by
3297 * setting the password expired flag to a non-0 value */
3299 if (!test_SetPassword_level(p, np, tctx, handle,
3303 &matched_expected_error,
3307 machine_credentials,
3310 expected_samlogon_result)) {
3314 if (matched_expected_error == true) {
3315 /* skipping on expected failure */
3319 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3320 * set without the SAMR_FIELD_EXPIRED_FLAG */
3322 switch (levels[l]) {
3326 if ((pwdlastset_new != 0) &&
3327 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3328 torture_comment(tctx, "not considering a non-0 "
3329 "pwdLastSet as a an error as the "
3330 "SAMR_FIELD_EXPIRED_FLAG has not "
3336 if (pwdlastset_new != 0) {
3337 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3338 "expected pwdLastSet 0 but got %llu\n",
3339 (unsigned long long) pwdlastset_old);
3345 switch (levels[l]) {
3349 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3350 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3351 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3352 (pwdlastset_old >= pwdlastset_new)) {
3353 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3359 pwdlastset_old = pwdlastset_new;
3365 /* set a password, pwdlastset needs to get updated (increased
3366 * value), password_expired value used here is 0 */
3368 if (!test_SetPassword_level(p, np, tctx, handle,
3372 &matched_expected_error,
3376 machine_credentials,
3379 expected_samlogon_result)) {
3383 /* when a password has been changed, pwdlastset must not be 0 afterwards
3384 * and must be larger then the old value */
3386 switch (levels[l]) {
3390 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3391 * password has been changed, old and new pwdlastset
3392 * need to be the same value */
3394 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3395 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3396 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3398 torture_assert_int_equal(tctx, pwdlastset_old,
3399 pwdlastset_new, "pwdlastset must be equal");
3404 if (pwdlastset_old >= pwdlastset_new) {
3405 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3406 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3407 (unsigned long long) pwdlastset_old,
3408 (unsigned long long) pwdlastset_new);
3411 if (pwdlastset_new == 0) {
3412 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3413 "expected non-0 pwdlastset, got: %llu\n",
3414 (unsigned long long) pwdlastset_new);
3420 switch (levels[l]) {
3424 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3425 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3426 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3427 (pwdlastset_old >= pwdlastset_new)) {
3428 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3434 pwdlastset_old = pwdlastset_new;
3440 /* set a password, pwdlastset needs to get updated (increased
3441 * value), password_expired value used here is 0 */
3443 if (!test_SetPassword_level(p, np, tctx, handle,
3447 &matched_expected_error,
3451 machine_credentials,
3454 expected_samlogon_result)) {
3458 /* when a password has been changed, pwdlastset must not be 0 afterwards
3459 * and must be larger then the old value */
3461 switch (levels[l]) {
3466 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3467 * password has been changed, old and new pwdlastset
3468 * need to be the same value */
3470 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3471 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3472 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3474 torture_assert_int_equal(tctx, pwdlastset_old,
3475 pwdlastset_new, "pwdlastset must be equal");
3480 if (pwdlastset_old >= pwdlastset_new) {
3481 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3482 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3483 (unsigned long long) pwdlastset_old,
3484 (unsigned long long) pwdlastset_new);
3487 if (pwdlastset_new == 0) {
3488 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3489 "expected non-0 pwdlastset, got: %llu\n",
3490 (unsigned long long) pwdlastset_new);
3496 switch (levels[l]) {
3500 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3501 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3502 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3503 (pwdlastset_old >= pwdlastset_new)) {
3504 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3510 pwdlastset_old = pwdlastset_new;
3516 /* set a password and force password change (pwdlastset 0) by
3517 * setting the password expired flag to a non-0 value */
3519 if (!test_SetPassword_level(p, np, tctx, handle,
3523 &matched_expected_error,
3527 machine_credentials,
3530 expected_samlogon_result)) {
3534 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3535 * set without the SAMR_FIELD_EXPIRED_FLAG */
3537 switch (levels[l]) {
3541 if ((pwdlastset_new != 0) &&
3542 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3543 torture_comment(tctx, "not considering a non-0 "
3544 "pwdLastSet as a an error as the "
3545 "SAMR_FIELD_EXPIRED_FLAG has not "
3550 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3551 * password has been changed, old and new pwdlastset
3552 * need to be the same value */
3554 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3555 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3556 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3558 torture_assert_int_equal(tctx, pwdlastset_old,
3559 pwdlastset_new, "pwdlastset must be equal");
3564 if (pwdlastset_new != 0) {
3565 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3566 "expected pwdLastSet 0, got %llu\n",
3567 (unsigned long long) pwdlastset_old);
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 /* if the level we are testing does not have a fields_present
3588 * field, skip all fields present tests by setting f to to
3590 switch (levels[l]) {
3594 f = ARRAY_SIZE(fields_present);
3598 #ifdef TEST_QUERY_LEVELS
3601 #ifdef TEST_SET_LEVELS
3604 } /* fields present */
3608 #undef TEST_SET_LEVELS
3609 #undef TEST_QUERY_LEVELS
3616 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_binding_handle *b,
3617 struct torture_context *tctx,
3618 struct policy_handle *handle,
3619 uint32_t *badpwdcount)
3621 union samr_UserInfo *info;
3622 struct samr_QueryUserInfo r;
3624 r.in.user_handle = handle;
3628 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3630 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3631 "failed to query userinfo");
3632 torture_assert_ntstatus_ok(tctx, r.out.result,
3633 "failed to query userinfo");
3635 *badpwdcount = info->info3.bad_password_count;
3637 torture_comment(tctx, " (bad password count: %d)\n", *badpwdcount);
3642 static bool test_SetUserInfo_acct_flags(struct dcerpc_binding_handle *b,
3643 struct torture_context *tctx,
3644 struct policy_handle *user_handle,
3645 uint32_t acct_flags)
3647 struct samr_SetUserInfo r;
3648 union samr_UserInfo user_info;
3650 torture_comment(tctx, "Testing SetUserInfo level 16\n");
3652 user_info.info16.acct_flags = acct_flags;
3654 r.in.user_handle = user_handle;
3656 r.in.info = &user_info;
3658 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &r),
3659 "failed to set account flags");
3660 torture_assert_ntstatus_ok(tctx, r.out.result,
3661 "failed to set account flags");
3666 static bool test_reset_badpwdcount(struct dcerpc_pipe *p,
3667 struct torture_context *tctx,
3668 struct policy_handle *user_handle,
3669 uint32_t acct_flags,
3672 struct dcerpc_binding_handle *b = p->binding_handle;
3674 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3675 "failed to set password");
3677 torture_comment(tctx, "Testing SetUserInfo level 16 (enable account)\n");
3679 torture_assert(tctx,
3680 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3681 acct_flags & ~ACB_DISABLED),
3682 "failed to enable user");
3684 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3685 "failed to set password");
3690 static bool test_SetDomainInfo(struct dcerpc_binding_handle *b,
3691 struct torture_context *tctx,
3692 struct policy_handle *domain_handle,
3693 enum samr_DomainInfoClass level,
3694 union samr_DomainInfo *info)
3696 struct samr_SetDomainInfo r;
3698 r.in.domain_handle = domain_handle;
3702 torture_assert_ntstatus_ok(tctx,
3703 dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3704 "failed to set domain info");
3705 torture_assert_ntstatus_ok(tctx, r.out.result,
3706 "failed to set domain info");
3711 static bool test_SetDomainInfo_ntstatus(struct dcerpc_binding_handle *b,
3712 struct torture_context *tctx,
3713 struct policy_handle *domain_handle,
3714 enum samr_DomainInfoClass level,
3715 union samr_DomainInfo *info,
3718 struct samr_SetDomainInfo r;
3720 r.in.domain_handle = domain_handle;
3724 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3725 "SetDomainInfo failed");
3726 torture_assert_ntstatus_equal(tctx, r.out.result, expected, "");
3731 static bool test_QueryDomainInfo2_level(struct dcerpc_binding_handle *b,
3732 struct torture_context *tctx,
3733 struct policy_handle *domain_handle,
3734 enum samr_DomainInfoClass level,
3735 union samr_DomainInfo **q_info)
3737 struct samr_QueryDomainInfo2 r;
3739 r.in.domain_handle = domain_handle;
3741 r.out.info = q_info;
3743 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
3744 "failed to query domain info");
3745 torture_assert_ntstatus_ok(tctx, r.out.result,
3746 "failed to query domain info");
3751 static bool test_Password_badpwdcount(struct dcerpc_pipe *p,
3752 struct dcerpc_pipe *np,
3753 struct torture_context *tctx,
3754 uint32_t acct_flags,
3755 const char *acct_name,
3756 struct policy_handle *domain_handle,
3757 struct policy_handle *user_handle,
3759 struct cli_credentials *machine_credentials,
3760 const char *comment,
3763 NTSTATUS expected_success_status,
3764 struct samr_DomInfo1 *info1,
3765 struct samr_DomInfo12 *info12)
3767 union samr_DomainInfo info;
3770 uint32_t badpwdcount, tmp;
3771 uint32_t password_history_length = 12;
3772 uint32_t lockout_threshold = 15;
3773 struct dcerpc_binding_handle *b = p->binding_handle;
3775 torture_comment(tctx, "\nTesting bad pwd count with: %s\n", comment);
3777 torture_assert(tctx, password_history_length < lockout_threshold,
3778 "password history length needs to be smaller than account lockout threshold for this test");
3783 info.info1 = *info1;
3784 info.info1.password_history_length = password_history_length;
3786 torture_assert(tctx,
3787 test_SetDomainInfo(b, tctx, domain_handle,
3788 DomainPasswordInformation, &info),
3789 "failed to set password history length");
3791 info.info12 = *info12;
3792 info.info12.lockout_threshold = lockout_threshold;
3794 torture_assert(tctx,
3795 test_SetDomainInfo(b, tctx, domain_handle,
3796 DomainLockoutInformation, &info),
3797 "failed to set lockout threshold");
3799 /* reset bad pwd count */
3801 torture_assert(tctx,
3802 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
3805 /* enable or disable account */
3807 torture_assert(tctx,
3808 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3809 acct_flags | ACB_DISABLED),
3810 "failed to disable user");
3812 torture_assert(tctx,
3813 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3814 acct_flags & ~ACB_DISABLED),
3815 "failed to enable user");
3819 /* setup password history */
3821 passwords = talloc_array(tctx, char *, password_history_length);
3823 for (i=0; i < password_history_length; i++) {
3825 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3826 "failed to set password");
3827 passwords[i] = talloc_strdup(tctx, *password);
3829 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3830 acct_name, passwords[i],
3831 expected_success_status, interactive)) {
3832 torture_fail(tctx, "failed to auth with latest password");
3835 torture_assert(tctx,
3836 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3838 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3842 /* test with wrong password */
3844 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3845 acct_name, "random_crap",
3846 NT_STATUS_WRONG_PASSWORD, interactive)) {
3847 torture_fail(tctx, "succeeded to authenticate with wrong password");
3850 torture_assert(tctx,
3851 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3853 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3856 /* test with latest good password */
3858 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
3859 passwords[password_history_length-1],
3860 expected_success_status, interactive)) {
3861 torture_fail(tctx, "succeeded to authenticate with wrong password");
3864 torture_assert(tctx,
3865 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3868 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3870 /* only enabled accounts get the bad pwd count reset upon
3871 * successful logon */
3872 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3878 /* test password history */
3880 for (i=0; i < password_history_length; i++) {
3882 torture_comment(tctx, "Testing bad password count behavior with "
3883 "password #%d of #%d\n", i, password_history_length);
3885 /* - network samlogon will succeed auth and not
3886 * increase badpwdcount for 2 last entries
3887 * - interactive samlogon only for the last one */
3889 if (i == password_history_length - 1 ||
3890 (i == password_history_length - 2 && !interactive)) {
3892 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3893 acct_name, passwords[i],
3894 expected_success_status, interactive)) {
3895 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3898 torture_assert(tctx,
3899 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3902 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
3903 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3905 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
3906 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3914 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3915 acct_name, passwords[i],
3916 NT_STATUS_WRONG_PASSWORD, interactive)) {
3917 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3920 torture_assert(tctx,
3921 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3923 /* - network samlogon will fail auth but not increase
3924 * badpwdcount for 3rd last entry
3925 * - interactive samlogon for 3rd and 2nd last entry */
3927 if (i == password_history_length - 3 ||
3928 (i == password_history_length - 2 && interactive)) {
3929 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
3930 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3932 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
3933 torture_assert_int_equal(tctx, badpwdcount, tmp + 1, "unexpected badpwdcount");
3942 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe *p,
3943 struct torture_context *tctx,
3944 uint32_t acct_flags,
3945 const char *acct_name,
3946 struct policy_handle *domain_handle,
3947 struct policy_handle *user_handle,
3949 struct cli_credentials *machine_credentials)
3951 union samr_DomainInfo *q_info, s_info;
3952 struct samr_DomInfo1 info1, _info1;
3953 struct samr_DomInfo12 info12, _info12;
3955 struct dcerpc_binding_handle *b = p->binding_handle;
3956 struct dcerpc_pipe *np;
3960 const char *comment;
3963 NTSTATUS expected_success_status;
3966 .comment = "network logon (disabled account)",
3968 .interactive = false,
3969 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
3972 .comment = "network logon (enabled account)",
3974 .interactive = false,
3975 .expected_success_status= NT_STATUS_OK
3978 .comment = "interactive logon (disabled account)",
3980 .interactive = true,
3981 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
3984 .comment = "interactive logon (enabled account)",
3986 .interactive = true,
3987 .expected_success_status= NT_STATUS_OK
3991 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3993 /* backup old policies */
3995 torture_assert(tctx,
3996 test_QueryDomainInfo2_level(b, tctx, domain_handle,
3997 DomainPasswordInformation, &q_info),
3998 "failed to query domain info level 1");
4000 info1 = q_info->info1;
4003 torture_assert(tctx,
4004 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4005 DomainLockoutInformation, &q_info),
4006 "failed to query domain info level 12");
4008 info12 = q_info->info12;
4013 for (i=0; i < ARRAY_SIZE(creds); i++) {
4015 /* skip trust tests for now */
4016 if (acct_flags & ACB_WSTRUST ||
4017 acct_flags & ACB_SVRTRUST ||
4018 acct_flags & ACB_DOMTRUST) {
4022 ret &= test_Password_badpwdcount(p, np, tctx, acct_flags, acct_name,
4023 domain_handle, user_handle, password,
4024 machine_credentials,
4027 creds[i].interactive,
4028 creds[i].expected_success_status,
4031 torture_result(tctx, TORTURE_FAIL, "TEST #%d (%s) failed\n", i, creds[i].comment);
4033 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4037 /* restore policies */
4039 s_info.info1 = info1;
4041 torture_assert(tctx,
4042 test_SetDomainInfo(b, tctx, domain_handle,
4043 DomainPasswordInformation, &s_info),
4044 "failed to set password information");
4046 s_info.info12 = info12;
4048 torture_assert(tctx,
4049 test_SetDomainInfo(b, tctx, domain_handle,
4050 DomainLockoutInformation, &s_info),
4051 "failed to set lockout information");
4056 static bool test_QueryUserInfo_acct_flags(struct dcerpc_binding_handle *b,
4057 struct torture_context *tctx,
4058 struct policy_handle *domain_handle,
4059 const char *acct_name,
4060 uint32_t *acct_flags)
4062 struct policy_handle user_handle;
4063 union samr_UserInfo *info;
4064 struct samr_QueryUserInfo r;
4066 NTSTATUS status = test_OpenUser_byname(b, tctx, domain_handle, acct_name, &user_handle);
4067 if (!NT_STATUS_IS_OK(status)) {
4071 r.in.user_handle = &user_handle;
4075 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4077 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4078 "failed to query userinfo");
4079 torture_assert_ntstatus_ok(tctx, r.out.result,
4080 "failed to query userinfo");
4082 *acct_flags = info->info16.acct_flags;
4084 torture_comment(tctx, " (acct_flags: 0x%08x)\n", *acct_flags);
4086 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
4093 static bool test_Password_lockout(struct dcerpc_pipe *p,
4094 struct dcerpc_pipe *np,
4095 struct torture_context *tctx,
4096 uint32_t acct_flags,
4097 const char *acct_name,
4098 struct policy_handle *domain_handle,
4099 struct policy_handle *user_handle,
4101 struct cli_credentials *machine_credentials,
4102 const char *comment,
4105 NTSTATUS expected_success_status,
4106 struct samr_DomInfo1 *info1,
4107 struct samr_DomInfo12 *info12)
4109 union samr_DomainInfo info;
4110 uint32_t badpwdcount;
4111 uint32_t password_history_length = 1;
4112 uint64_t lockout_threshold = 1;
4113 uint32_t lockout_seconds = 5;
4114 uint64_t delta_time_factor = 10 * 1000 * 1000;
4115 struct dcerpc_binding_handle *b = p->binding_handle;
4117 if (torture_setting_bool(tctx, "samba3", false)) {
4118 lockout_seconds = 60;
4121 torture_comment(tctx, "\nTesting account lockout: %s\n", comment);
4125 info.info1 = *info1;
4127 torture_comment(tctx, "setting password history length.\n");
4128 info.info1.password_history_length = password_history_length;
4130 torture_assert(tctx,
4131 test_SetDomainInfo(b, tctx, domain_handle,
4132 DomainPasswordInformation, &info),
4133 "failed to set password history length");
4135 info.info12 = *info12;
4136 info.info12.lockout_threshold = lockout_threshold;
4138 /* set lockout duration < lockout window: should fail */
4139 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4140 info.info12.lockout_window = ~((lockout_seconds + 1) * delta_time_factor);
4142 torture_assert(tctx,
4143 test_SetDomainInfo_ntstatus(b, tctx, domain_handle,
4144 DomainLockoutInformation, &info,
4145 NT_STATUS_INVALID_PARAMETER),
4146 "setting lockout duration < lockout window gave unexpected result");
4148 info.info12.lockout_duration = 0;
4149 info.info12.lockout_window = 0;
4151 torture_assert(tctx,
4152 test_SetDomainInfo(b, tctx, domain_handle,
4153 DomainLockoutInformation, &info),
4154 "failed to set lockout window and duration to 0");
4157 /* set lockout duration of 5 seconds */
4158 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4159 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
4161 torture_assert(tctx,
4162 test_SetDomainInfo(b, tctx, domain_handle,
4163 DomainLockoutInformation, &info),
4164 "failed to set lockout window and duration to 5 seconds");
4166 /* reset bad pwd count */
4168 torture_assert(tctx,
4169 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
4172 /* enable or disable account */
4175 torture_assert(tctx,
4176 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4177 acct_flags | ACB_DISABLED),
4178 "failed to disable user");
4180 torture_assert(tctx,
4181 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4182 acct_flags & ~ACB_DISABLED),
4183 "failed to enable user");
4187 /* test logon with right password */
4189 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4190 acct_name, *password,
4191 expected_success_status, interactive)) {
4192 torture_fail(tctx, "failed to auth with latest password");
4195 torture_assert(tctx,
4196 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4197 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
4200 /* test with wrong password ==> lockout */
4202 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4203 acct_name, "random_crap",
4204 NT_STATUS_WRONG_PASSWORD, interactive)) {
4205 torture_fail(tctx, "succeeded to authenticate with wrong password");
4208 torture_assert(tctx,
4209 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4210 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4212 /* curiously, windows does _not_ set the autlock flag unless you re-open the user */
4213 torture_assert(tctx,
4214 test_QueryUserInfo_acct_flags(b, tctx, domain_handle, acct_name, &acct_flags), "");
4215 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, ACB_AUTOLOCK,
4216 "expected account to be locked");
4219 /* test with good password */
4221 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4223 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4225 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4228 /* bad pwd count should not get updated */
4229 torture_assert(tctx,
4230 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4231 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4233 /* curiously, windows does _not_ set the autlock flag unless you re-open the user */
4234 torture_assert(tctx,
4235 test_QueryUserInfo_acct_flags(b, tctx, domain_handle, acct_name, &acct_flags), "");
4236 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, ACB_AUTOLOCK,
4237 "expected account to be locked");
4240 /* with bad password */
4242 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4243 acct_name, "random_crap2",
4244 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4246 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4249 /* bad pwd count should not get updated */
4250 torture_assert(tctx,
4251 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4252 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4254 /* curiously, windows does _not_ set the autlock flag untill you re-open the user */
4255 torture_assert(tctx,
4256 test_QueryUserInfo_acct_flags(b, tctx, domain_handle, acct_name, &acct_flags), "");
4257 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, ACB_AUTOLOCK,
4258 "expected account to show ACB_AUTOLOCK");
4261 /* let lockout duration expire ==> unlock */
4263 torture_comment(tctx, "let lockout duration expire...\n");
4264 sleep(lockout_seconds + 1);
4266 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4268 expected_success_status, interactive))
4270 torture_fail(tctx, "failed to authenticate after lockout expired");
4273 torture_assert(tctx,
4274 test_QueryUserInfo_acct_flags(b, tctx, domain_handle, acct_name, &acct_flags), "");
4275 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4276 "expected account not to be locked");
4281 static bool test_Password_lockout_wrap(struct dcerpc_pipe *p,
4282 struct torture_context *tctx,
4283 uint32_t acct_flags,
4284 const char *acct_name,
4285 struct policy_handle *domain_handle,
4286 struct policy_handle *user_handle,
4288 struct cli_credentials *machine_credentials)
4290 union samr_DomainInfo *q_info, s_info;
4291 struct samr_DomInfo1 info1, _info1;
4292 struct samr_DomInfo12 info12, _info12;
4294 struct dcerpc_binding_handle *b = p->binding_handle;
4295 struct dcerpc_pipe *np;
4299 const char *comment;
4302 NTSTATUS expected_success_status;
4305 .comment = "network logon (disabled account)",
4307 .interactive = false,
4308 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4311 .comment = "network logon (enabled account)",
4313 .interactive = false,
4314 .expected_success_status= NT_STATUS_OK
4317 .comment = "interactive logon (disabled account)",
4319 .interactive = true,
4320 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4323 .comment = "interactive logon (enabled account)",
4325 .interactive = true,
4326 .expected_success_status= NT_STATUS_OK
4330 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4332 /* backup old policies */
4334 torture_assert(tctx,
4335 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4336 DomainPasswordInformation, &q_info),
4337 "failed to query domain info level 1");
4339 info1 = q_info->info1;
4342 torture_assert(tctx,
4343 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4344 DomainLockoutInformation, &q_info),
4345 "failed to query domain info level 12");
4347 info12 = q_info->info12;
4352 for (i=0; i < ARRAY_SIZE(creds); i++) {
4354 /* skip trust tests for now */
4355 if (acct_flags & ACB_WSTRUST ||
4356 acct_flags & ACB_SVRTRUST ||
4357 acct_flags & ACB_DOMTRUST) {
4361 ret &= test_Password_lockout(p, np, tctx, acct_flags, acct_name,
4362 domain_handle, user_handle, password,
4363 machine_credentials,
4366 creds[i].interactive,
4367 creds[i].expected_success_status,
4370 torture_result(tctx, TORTURE_FAIL, "TEST #%d (%s) failed\n", i, creds[i].comment);
4372 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4376 /* restore policies */
4378 s_info.info1 = info1;
4380 torture_assert(tctx,
4381 test_SetDomainInfo(b, tctx, domain_handle,
4382 DomainPasswordInformation, &s_info),
4383 "failed to set password information");
4385 s_info.info12 = info12;
4387 torture_assert(tctx,
4388 test_SetDomainInfo(b, tctx, domain_handle,
4389 DomainLockoutInformation, &s_info),
4390 "failed to set lockout information");
4395 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
4396 struct dcerpc_pipe *lp,
4397 struct torture_context *tctx,
4398 struct policy_handle *domain_handle,
4399 struct policy_handle *lsa_handle,
4400 struct policy_handle *user_handle,
4401 const struct dom_sid *domain_sid,
4403 struct cli_credentials *machine_credentials)
4406 struct dcerpc_binding_handle *b = p->binding_handle;
4407 struct dcerpc_binding_handle *lb = lp->binding_handle;
4409 struct policy_handle lsa_acct_handle;
4410 struct dom_sid *user_sid;
4412 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
4415 struct lsa_EnumAccountRights r;
4416 struct lsa_RightSet rights;
4418 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4420 r.in.handle = lsa_handle;
4421 r.in.sid = user_sid;
4422 r.out.rights = &rights;
4424 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4425 "lsa_EnumAccountRights failed");
4426 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4427 "Expected enum rights for account to fail");
4431 struct lsa_RightSet rights;
4432 struct lsa_StringLarge names[2];
4433 struct lsa_AddAccountRights r;
4435 torture_comment(tctx, "Testing LSA AddAccountRights\n");
4437 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
4438 init_lsa_StringLarge(&names[1], NULL);
4441 rights.names = names;
4443 r.in.handle = lsa_handle;
4444 r.in.sid = user_sid;
4445 r.in.rights = &rights;
4447 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
4448 "lsa_AddAccountRights failed");
4449 torture_assert_ntstatus_ok(tctx, r.out.result,
4450 "Failed to add privileges");
4454 struct lsa_EnumAccounts r;
4455 uint32_t resume_handle = 0;
4456 struct lsa_SidArray lsa_sid_array;
4458 bool found_sid = false;
4460 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4462 r.in.handle = lsa_handle;
4463 r.in.num_entries = 0x1000;
4464 r.in.resume_handle = &resume_handle;
4465 r.out.sids = &lsa_sid_array;
4466 r.out.resume_handle = &resume_handle;
4468 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4469 "lsa_EnumAccounts failed");
4470 torture_assert_ntstatus_ok(tctx, r.out.result,
4471 "Failed to enum accounts");
4473 for (i=0; i < lsa_sid_array.num_sids; i++) {
4474 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4479 torture_assert(tctx, found_sid,
4480 "failed to list privileged account");
4484 struct lsa_EnumAccountRights r;
4485 struct lsa_RightSet user_rights;
4487 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4489 r.in.handle = lsa_handle;
4490 r.in.sid = user_sid;
4491 r.out.rights = &user_rights;
4493 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4494 "lsa_EnumAccountRights failed");
4495 torture_assert_ntstatus_ok(tctx, r.out.result,
4496 "Failed to enum rights for account");
4498 if (user_rights.count < 1) {
4499 torture_result(tctx, TORTURE_FAIL, "failed to find newly added rights");
4505 struct lsa_OpenAccount r;
4507 torture_comment(tctx, "Testing LSA OpenAccount\n");
4509 r.in.handle = lsa_handle;
4510 r.in.sid = user_sid;
4511 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4512 r.out.acct_handle = &lsa_acct_handle;
4514 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4515 "lsa_OpenAccount failed");
4516 torture_assert_ntstatus_ok(tctx, r.out.result,
4517 "Failed to open lsa account");
4521 struct lsa_GetSystemAccessAccount r;
4522 uint32_t access_mask;
4524 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4526 r.in.handle = &lsa_acct_handle;
4527 r.out.access_mask = &access_mask;
4529 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4530 "lsa_GetSystemAccessAccount failed");
4531 torture_assert_ntstatus_ok(tctx, r.out.result,
4532 "Failed to get lsa system access account");
4538 torture_comment(tctx, "Testing LSA Close\n");
4540 r.in.handle = &lsa_acct_handle;
4541 r.out.handle = &lsa_acct_handle;
4543 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(lb, tctx, &r),
4544 "lsa_Close failed");
4545 torture_assert_ntstatus_ok(tctx, r.out.result,
4546 "Failed to close lsa");
4550 struct samr_DeleteUser r;
4552 torture_comment(tctx, "Testing SAMR DeleteUser\n");
4554 r.in.user_handle = user_handle;
4555 r.out.user_handle = user_handle;
4557 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &r),
4558 "DeleteUser failed");
4559 torture_assert_ntstatus_ok(tctx, r.out.result,
4560 "DeleteUser failed");
4564 struct lsa_EnumAccounts r;
4565 uint32_t resume_handle = 0;
4566 struct lsa_SidArray lsa_sid_array;
4568 bool found_sid = false;
4570 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4572 r.in.handle = lsa_handle;
4573 r.in.num_entries = 0x1000;
4574 r.in.resume_handle = &resume_handle;
4575 r.out.sids = &lsa_sid_array;
4576 r.out.resume_handle = &resume_handle;
4578 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4579 "lsa_EnumAccounts failed");
4580 torture_assert_ntstatus_ok(tctx, r.out.result,
4581 "Failed to enum accounts");
4583 for (i=0; i < lsa_sid_array.num_sids; i++) {
4584 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4589 torture_assert(tctx, found_sid,
4590 "failed to list privileged account");
4594 struct lsa_EnumAccountRights r;
4595 struct lsa_RightSet user_rights;
4597 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4599 r.in.handle = lsa_handle;
4600 r.in.sid = user_sid;
4601 r.out.rights = &user_rights;
4603 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4604 "lsa_EnumAccountRights failed");
4605 torture_assert_ntstatus_ok(tctx, r.out.result,
4606 "Failed to enum rights for account");
4608 if (user_rights.count < 1) {
4609 torture_result(tctx, TORTURE_FAIL, "failed to find newly added rights");
4615 struct lsa_OpenAccount r;
4617 torture_comment(tctx, "Testing LSA OpenAccount\n");
4619 r.in.handle = lsa_handle;
4620 r.in.sid = user_sid;
4621 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4622 r.out.acct_handle = &lsa_acct_handle;
4624 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4625 "lsa_OpenAccount failed");
4626 torture_assert_ntstatus_ok(tctx, r.out.result,
4627 "Failed to open lsa account");
4631 struct lsa_GetSystemAccessAccount r;
4632 uint32_t access_mask;
4634 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4636 r.in.handle = &lsa_acct_handle;
4637 r.out.access_mask = &access_mask;
4639 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4640 "lsa_GetSystemAccessAccount failed");
4641 torture_assert_ntstatus_ok(tctx, r.out.result,
4642 "Failed to get lsa system access account");
4646 struct lsa_DeleteObject r;
4648 torture_comment(tctx, "Testing LSA DeleteObject\n");
4650 r.in.handle = &lsa_acct_handle;
4651 r.out.handle = &lsa_acct_handle;
4653 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(lb, tctx, &r),
4654 "lsa_DeleteObject failed");
4655 torture_assert_ntstatus_ok(tctx, r.out.result,
4656 "Failed to delete object");
4660 struct lsa_EnumAccounts r;
4661 uint32_t resume_handle = 0;
4662 struct lsa_SidArray lsa_sid_array;
4664 bool found_sid = false;
4666 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4668 r.in.handle = lsa_handle;
4669 r.in.num_entries = 0x1000;
4670 r.in.resume_handle = &resume_handle;
4671 r.out.sids = &lsa_sid_array;
4672 r.out.resume_handle = &resume_handle;
4674 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4675 "lsa_EnumAccounts failed");
4676 torture_assert_ntstatus_ok(tctx, r.out.result,
4677 "Failed to enum accounts");
4679 for (i=0; i < lsa_sid_array.num_sids; i++) {
4680 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4685 torture_assert(tctx, !found_sid,
4686 "should not have listed privileged account");
4690 struct lsa_EnumAccountRights r;
4691 struct lsa_RightSet user_rights;
4693 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4695 r.in.handle = lsa_handle;
4696 r.in.sid = user_sid;
4697 r.out.rights = &user_rights;
4699 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4700 "lsa_EnumAccountRights failed");
4701 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4702 "Failed to enum rights for account");
4708 static bool test_user_ops(struct dcerpc_pipe *p,
4709 struct torture_context *tctx,
4710 struct policy_handle *user_handle,
4711 struct policy_handle *domain_handle,
4712 const struct dom_sid *domain_sid,
4713 uint32_t base_acct_flags,
4714 const char *base_acct_name, enum torture_samr_choice which_ops,
4715 struct cli_credentials *machine_credentials)
4717 char *password = NULL;
4718 struct samr_QueryUserInfo q;
4719 union samr_UserInfo *info;
4721 struct dcerpc_binding_handle *b = p->binding_handle;
4726 const uint32_t password_fields[] = {
4727 SAMR_FIELD_NT_PASSWORD_PRESENT,
4728 SAMR_FIELD_LM_PASSWORD_PRESENT,
4729 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
4733 status = test_LookupName(b, tctx, domain_handle, base_acct_name, &rid);
4734 if (!NT_STATUS_IS_OK(status)) {
4738 switch (which_ops) {
4739 case TORTURE_SAMR_USER_ATTRIBUTES:
4740 if (!test_QuerySecurity(b, tctx, user_handle)) {
4744 if (!test_QueryUserInfo(b, tctx, user_handle)) {
4748 if (!test_QueryUserInfo2(b, tctx, user_handle)) {
4752 if (!test_SetUserInfo(b, tctx, user_handle, base_acct_flags,
4757 if (!test_GetUserPwInfo(b, tctx, user_handle)) {
4761 if (!test_TestPrivateFunctionsUser(b, tctx, user_handle)) {
4765 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
4769 case TORTURE_SAMR_PASSWORDS:
4770 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
4771 char simple_pass[9];
4772 char *v = generate_random_str(tctx, 1);
4774 ZERO_STRUCT(simple_pass);
4775 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4777 torture_comment(tctx, "Testing machine account password policy rules\n");
4779 /* Workstation trust accounts don't seem to need to honour password quality policy */
4780 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4784 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
4788 /* reset again, to allow another 'user' password change */
4789 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4793 /* Try a 'short' password */
4794 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
4798 /* Try a compleatly random password */
4799 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
4804 for (i = 0; password_fields[i]; i++) {
4805 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
4809 /* check it was set right */
4810 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4815 for (i = 0; password_fields[i]; i++) {
4816 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
4820 /* check it was set right */
4821 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4826 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
4830 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
4834 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
4838 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4842 for (i = 0; password_fields[i]; i++) {
4844 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
4845 /* we need to skip as that would break
4846 * the ChangePasswordUser3 verify */
4850 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
4854 /* check it was set right */
4855 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4860 q.in.user_handle = user_handle;
4864 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
4865 "QueryUserInfo failed");
4866 if (!NT_STATUS_IS_OK(q.out.result)) {
4867 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
4868 q.in.level, nt_errstr(q.out.result));
4871 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4872 if ((info->info5.acct_flags) != expected_flags) {
4874 if (!torture_setting_bool(tctx, "samba3", false)) {
4875 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4876 info->info5.acct_flags,
4881 if (info->info5.rid != rid) {
4882 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
4883 info->info5.rid, rid);
4890 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
4892 /* test last password change timestamp behaviour */
4893 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
4895 user_handle, &password,
4896 machine_credentials)) {
4901 torture_comment(tctx, "pwdLastSet test succeeded\n");
4903 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed\n");
4908 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
4910 /* test bad pwd count change behaviour */
4911 if (!test_Password_badpwdcount_wrap(p, tctx, base_acct_flags,
4914 user_handle, &password,
4915 machine_credentials)) {
4920 torture_comment(tctx, "badPwdCount test succeeded\n");
4922 torture_result(tctx, TORTURE_FAIL, "badPwdCount test failed\n");
4927 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
4929 if (!test_Password_lockout_wrap(p, tctx, base_acct_flags,
4932 user_handle, &password,
4933 machine_credentials))
4939 torture_comment(tctx, "lockout test succeeded\n");
4941 torture_result(tctx, TORTURE_FAIL, "lockout test failed\n");
4947 case TORTURE_SAMR_USER_PRIVILEGES: {
4949 struct dcerpc_pipe *lp;
4950 struct policy_handle *lsa_handle;
4951 struct dcerpc_binding_handle *lb;
4953 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
4954 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
4955 lb = lp->binding_handle;
4957 if (!test_lsa_OpenPolicy2(lb, tctx, &lsa_handle)) {
4961 if (!test_DeleteUser_with_privs(p, lp, tctx,
4962 domain_handle, lsa_handle, user_handle,
4964 machine_credentials)) {
4968 if (!test_lsa_Close(lb, tctx, lsa_handle)) {
4973 torture_result(tctx, TORTURE_FAIL, "privileged user delete test failed\n");
4978 case TORTURE_SAMR_OTHER:
4979 case TORTURE_SAMR_MANY_ACCOUNTS:
4980 case TORTURE_SAMR_MANY_GROUPS:
4981 case TORTURE_SAMR_MANY_ALIASES:
4982 /* We just need the account to exist */
4988 static bool test_alias_ops(struct dcerpc_binding_handle *b,
4989 struct torture_context *tctx,
4990 struct policy_handle *alias_handle,
4991 const struct dom_sid *domain_sid)
4995 if (!torture_setting_bool(tctx, "samba3", false)) {
4996 if (!test_QuerySecurity(b, tctx, alias_handle)) {
5001 if (!test_QueryAliasInfo(b, tctx, alias_handle)) {
5005 if (!test_SetAliasInfo(b, tctx, alias_handle)) {
5009 if (!test_AddMemberToAlias(b, tctx, alias_handle, domain_sid)) {
5013 if (torture_setting_bool(tctx, "samba3", false) ||
5014 torture_setting_bool(tctx, "samba4", false)) {
5015 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
5019 if (!test_AddMultipleMembersToAlias(b, tctx, alias_handle)) {
5027 static bool test_DeleteUser(struct dcerpc_binding_handle *b,
5028 struct torture_context *tctx,
5029 struct policy_handle *user_handle)
5031 struct samr_DeleteUser d;
5032 torture_comment(tctx, "Testing DeleteUser\n");
5034 d.in.user_handle = user_handle;
5035 d.out.user_handle = user_handle;
5037 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
5038 "DeleteUser failed");
5039 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteUser");
5044 bool test_DeleteUser_byname(struct dcerpc_binding_handle *b,
5045 struct torture_context *tctx,
5046 struct policy_handle *handle, const char *name)
5049 struct samr_DeleteUser d;
5050 struct policy_handle user_handle;
5053 status = test_LookupName(b, tctx, handle, name, &rid);
5054 if (!NT_STATUS_IS_OK(status)) {
5058 status = test_OpenUser_byname(b, tctx, handle, name, &user_handle);
5059 if (!NT_STATUS_IS_OK(status)) {
5063 d.in.user_handle = &user_handle;
5064 d.out.user_handle = &user_handle;
5065 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
5066 "DeleteUser failed");
5067 if (!NT_STATUS_IS_OK(d.out.result)) {
5068 status = d.out.result;
5075 torture_result(tctx, TORTURE_FAIL, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
5080 static bool test_DeleteGroup_byname(struct dcerpc_binding_handle *b,
5081 struct torture_context *tctx,
5082 struct policy_handle *handle, const char *name)
5085 struct samr_OpenGroup r;
5086 struct samr_DeleteDomainGroup d;
5087 struct policy_handle group_handle;
5090 status = test_LookupName(b, tctx, handle, name, &rid);
5091 if (!NT_STATUS_IS_OK(status)) {
5095 r.in.domain_handle = handle;
5096 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5098 r.out.group_handle = &group_handle;
5099 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
5100 "OpenGroup failed");
5101 if (!NT_STATUS_IS_OK(r.out.result)) {
5102 status = r.out.result;
5106 d.in.group_handle = &group_handle;
5107 d.out.group_handle = &group_handle;
5108 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
5109 "DeleteDomainGroup failed");
5110 if (!NT_STATUS_IS_OK(d.out.result)) {
5111 status = d.out.result;
5118 torture_result(tctx, TORTURE_FAIL, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
5123 static bool test_DeleteAlias_byname(struct dcerpc_binding_handle *b,
5124 struct torture_context *tctx,
5125 struct policy_handle *domain_handle,
5129 struct samr_OpenAlias r;
5130 struct samr_DeleteDomAlias d;
5131 struct policy_handle alias_handle;
5134 torture_comment(tctx, "Testing DeleteAlias_byname\n");
5136 status = test_LookupName(b, tctx, domain_handle, name, &rid);
5137 if (!NT_STATUS_IS_OK(status)) {
5141 r.in.domain_handle = domain_handle;
5142 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5144 r.out.alias_handle = &alias_handle;
5145 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5146 "OpenAlias failed");
5147 if (!NT_STATUS_IS_OK(r.out.result)) {
5148 status = r.out.result;
5152 d.in.alias_handle = &alias_handle;
5153 d.out.alias_handle = &alias_handle;
5154 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5155 "DeleteDomAlias failed");
5156 if (!NT_STATUS_IS_OK(d.out.result)) {
5157 status = d.out.result;
5164 torture_result(tctx, TORTURE_FAIL, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
5168 static bool test_DeleteAlias(struct dcerpc_binding_handle *b,
5169 struct torture_context *tctx,
5170 struct policy_handle *alias_handle)
5172 struct samr_DeleteDomAlias d;
5175 torture_comment(tctx, "Testing DeleteAlias\n");
5177 d.in.alias_handle = alias_handle;
5178 d.out.alias_handle = alias_handle;
5180 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5181 "DeleteDomAlias failed");
5182 if (!NT_STATUS_IS_OK(d.out.result)) {
5183 torture_result(tctx, TORTURE_FAIL, "DeleteAlias failed - %s\n", nt_errstr(d.out.result));
5190 static bool test_CreateAlias(struct dcerpc_binding_handle *b,
5191 struct torture_context *tctx,
5192 struct policy_handle *domain_handle,
5193 const char *alias_name,
5194 struct policy_handle *alias_handle,
5195 const struct dom_sid *domain_sid,
5198 struct samr_CreateDomAlias r;
5199 struct lsa_String name;
5203 init_lsa_String(&name, alias_name);
5204 r.in.domain_handle = domain_handle;
5205 r.in.alias_name = &name;
5206 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5207 r.out.alias_handle = alias_handle;
5210 torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
5212 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5213 "CreateDomAlias failed");
5215 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5216 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
5217 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
5220 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
5221 nt_errstr(r.out.result));
5226 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ALIAS_EXISTS)) {
5227 if (!test_DeleteAlias_byname(b, tctx, domain_handle, r.in.alias_name->string)) {
5230 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5231 "CreateDomAlias failed");
5234 if (!NT_STATUS_IS_OK(r.out.result)) {
5235 torture_result(tctx, TORTURE_FAIL, "CreateAlias failed - %s\n", nt_errstr(r.out.result));
5243 if (!test_alias_ops(b, tctx, alias_handle, domain_sid)) {
5250 static bool test_ChangePassword(struct dcerpc_pipe *p,
5251 struct torture_context *tctx,
5252 const char *acct_name,
5253 struct policy_handle *domain_handle, char **password)
5256 struct dcerpc_binding_handle *b = p->binding_handle;
5262 if (!test_ChangePasswordUser(b, tctx, acct_name, domain_handle, password)) {
5266 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
5270 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
5274 /* test what happens when setting the old password again */
5275 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
5280 char simple_pass[9];
5281 char *v = generate_random_str(tctx, 1);
5283 ZERO_STRUCT(simple_pass);
5284 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5286 /* test what happens when picking a simple password */
5287 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
5292 /* set samr_SetDomainInfo level 1 with min_length 5 */
5294 struct samr_QueryDomainInfo r;
5295 union samr_DomainInfo *info = NULL;
5296 struct samr_SetDomainInfo s;
5297 uint16_t len_old, len;
5298 uint32_t pwd_prop_old;
5299 int64_t min_pwd_age_old;
5303 r.in.domain_handle = domain_handle;
5307 torture_comment(tctx, "Testing samr_QueryDomainInfo level 1\n");
5308 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
5309 "QueryDomainInfo failed");
5310 if (!NT_STATUS_IS_OK(r.out.result)) {
5314 s.in.domain_handle = domain_handle;
5318 /* remember the old min length, so we can reset it */
5319 len_old = s.in.info->info1.min_password_length;
5320 s.in.info->info1.min_password_length = len;
5321 pwd_prop_old = s.in.info->info1.password_properties;
5322 /* turn off password complexity checks for this test */
5323 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
5325 min_pwd_age_old = s.in.info->info1.min_password_age;
5326 s.in.info->info1.min_password_age = 0;
5328 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5329 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5330 "SetDomainInfo failed");
5331 if (!NT_STATUS_IS_OK(s.out.result)) {
5335 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
5337 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
5341 s.in.info->info1.min_password_length = len_old;
5342 s.in.info->info1.password_properties = pwd_prop_old;
5343 s.in.info->info1.min_password_age = min_pwd_age_old;
5345 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5346 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5347 "SetDomainInfo failed");
5348 if (!NT_STATUS_IS_OK(s.out.result)) {
5355 struct samr_OpenUser r;
5356 struct samr_QueryUserInfo q;
5357 union samr_UserInfo *info;
5358 struct samr_LookupNames n;
5359 struct policy_handle user_handle;
5360 struct samr_Ids rids, types;
5362 n.in.domain_handle = domain_handle;
5364 n.in.names = talloc_array(tctx, struct lsa_String, 1);
5365 n.in.names[0].string = acct_name;
5367 n.out.types = &types;
5369 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
5370 "LookupNames failed");
5371 if (!NT_STATUS_IS_OK(n.out.result)) {
5372 torture_result(tctx, TORTURE_FAIL, "LookupNames failed - %s\n", nt_errstr(n.out.result));
5376 r.in.domain_handle = domain_handle;
5377 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5378 r.in.rid = n.out.rids->ids[0];
5379 r.out.user_handle = &user_handle;
5381 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5383 if (!NT_STATUS_IS_OK(r.out.result)) {
5384 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(r.out.result));
5388 q.in.user_handle = &user_handle;
5392 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5393 "QueryUserInfo failed");
5394 if (!NT_STATUS_IS_OK(q.out.result)) {
5395 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo failed - %s\n", nt_errstr(q.out.result));
5399 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
5401 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
5402 info->info5.last_password_change, true)) {
5407 /* we change passwords twice - this has the effect of verifying
5408 they were changed correctly for the final call */
5409 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5413 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5420 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
5421 struct policy_handle *domain_handle,
5422 const char *user_name,
5423 struct policy_handle *user_handle_out,
5424 struct dom_sid *domain_sid,
5425 enum torture_samr_choice which_ops,
5426 struct cli_credentials *machine_credentials,
5430 TALLOC_CTX *user_ctx;
5432 struct samr_CreateUser r;
5433 struct samr_QueryUserInfo q;
5434 union samr_UserInfo *info;
5435 struct samr_DeleteUser d;
5438 /* This call creates a 'normal' account - check that it really does */
5439 const uint32_t acct_flags = ACB_NORMAL;
5440 struct lsa_String name;
5442 struct dcerpc_binding_handle *b = p->binding_handle;
5444 struct policy_handle user_handle;
5445 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5446 init_lsa_String(&name, user_name);
5448 r.in.domain_handle = domain_handle;
5449 r.in.account_name = &name;
5450 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5451 r.out.user_handle = &user_handle;
5454 torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
5456 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5457 "CreateUser failed");
5459 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5460 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5461 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5464 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5465 nt_errstr(r.out.result));
5470 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5471 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5472 talloc_free(user_ctx);
5475 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5476 "CreateUser failed");
5479 if (!NT_STATUS_IS_OK(r.out.result)) {
5480 talloc_free(user_ctx);
5481 torture_result(tctx, TORTURE_FAIL, "CreateUser failed - %s\n", nt_errstr(r.out.result));
5486 if (user_handle_out) {
5487 *user_handle_out = user_handle;
5493 q.in.user_handle = &user_handle;
5497 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5498 "QueryUserInfo failed");
5499 if (!NT_STATUS_IS_OK(q.out.result)) {
5500 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
5501 q.in.level, nt_errstr(q.out.result));
5504 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
5505 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5506 info->info16.acct_flags,
5512 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5513 domain_sid, acct_flags, name.string, which_ops,
5514 machine_credentials)) {
5518 if (user_handle_out) {
5519 *user_handle_out = user_handle;
5521 torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
5523 d.in.user_handle = &user_handle;
5524 d.out.user_handle = &user_handle;
5526 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5527 "DeleteUser failed");
5528 if (!NT_STATUS_IS_OK(d.out.result)) {
5529 torture_result(tctx, TORTURE_FAIL, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5536 talloc_free(user_ctx);
5542 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
5543 struct policy_handle *domain_handle,
5544 struct dom_sid *domain_sid,
5545 enum torture_samr_choice which_ops,
5546 struct cli_credentials *machine_credentials)
5548 struct samr_CreateUser2 r;
5549 struct samr_QueryUserInfo q;
5550 union samr_UserInfo *info;
5551 struct samr_DeleteUser d;
5552 struct policy_handle user_handle;
5554 struct lsa_String name;
5557 struct dcerpc_binding_handle *b = p->binding_handle;
5560 uint32_t acct_flags;
5561 const char *account_name;
5563 } account_types[] = {
5564 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
5565 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5566 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5567 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5568 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5569 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5570 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5571 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5572 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5573 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
5574 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5575 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5576 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5577 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5578 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
5581 for (i = 0; account_types[i].account_name; i++) {
5582 TALLOC_CTX *user_ctx;
5583 uint32_t acct_flags = account_types[i].acct_flags;
5584 uint32_t access_granted;
5585 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5586 init_lsa_String(&name, account_types[i].account_name);
5588 r.in.domain_handle = domain_handle;
5589 r.in.account_name = &name;
5590 r.in.acct_flags = acct_flags;
5591 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5592 r.out.user_handle = &user_handle;
5593 r.out.access_granted = &access_granted;
5596 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
5598 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5599 "CreateUser2 failed");
5601 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5602 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5603 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5606 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5607 nt_errstr(r.out.result));
5613 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5614 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5615 talloc_free(user_ctx);
5619 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5620 "CreateUser2 failed");
5623 if (!NT_STATUS_EQUAL(r.out.result, account_types[i].nt_status)) {
5624 torture_result(tctx, TORTURE_FAIL, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5625 nt_errstr(r.out.result), nt_errstr(account_types[i].nt_status));
5629 if (NT_STATUS_IS_OK(r.out.result)) {
5630 q.in.user_handle = &user_handle;
5634 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5635 "QueryUserInfo failed");
5636 if (!NT_STATUS_IS_OK(q.out.result)) {
5637 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
5638 q.in.level, nt_errstr(q.out.result));
5641 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
5642 if (acct_flags == ACB_NORMAL) {
5643 expected_flags |= ACB_PW_EXPIRED;
5645 if ((info->info5.acct_flags) != expected_flags) {
5646 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5647 info->info5.acct_flags,
5651 switch (acct_flags) {
5653 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
5654 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5655 DOMAIN_RID_DCS, info->info5.primary_gid);
5660 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
5661 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5662 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
5667 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
5668 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5669 DOMAIN_RID_USERS, info->info5.primary_gid);
5676 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5677 domain_sid, acct_flags, name.string, which_ops,
5678 machine_credentials)) {
5682 if (!ndr_policy_handle_empty(&user_handle)) {
5683 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
5685 d.in.user_handle = &user_handle;
5686 d.out.user_handle = &user_handle;
5688 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5689 "DeleteUser failed");
5690 if (!NT_STATUS_IS_OK(d.out.result)) {
5691 torture_result(tctx, TORTURE_FAIL, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5696 talloc_free(user_ctx);
5702 static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
5703 struct torture_context *tctx,
5704 struct policy_handle *handle)
5706 struct samr_QueryAliasInfo r;
5707 union samr_AliasInfo *info;
5708 uint16_t levels[] = {1, 2, 3};
5712 for (i=0;i<ARRAY_SIZE(levels);i++) {
5713 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
5715 r.in.alias_handle = handle;
5716 r.in.level = levels[i];
5719 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &r),
5720 "QueryAliasInfo failed");
5721 if (!NT_STATUS_IS_OK(r.out.result)) {
5722 torture_result(tctx, TORTURE_FAIL, "QueryAliasInfo level %u failed - %s\n",
5723 levels[i], nt_errstr(r.out.result));
5731 static bool test_QueryGroupInfo(struct dcerpc_binding_handle *b,
5732 struct torture_context *tctx,
5733 struct policy_handle *handle)
5735 struct samr_QueryGroupInfo r;
5736 union samr_GroupInfo *info;
5737 uint16_t levels[] = {1, 2, 3, 4, 5};
5741 for (i=0;i<ARRAY_SIZE(levels);i++) {
5742 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5744 r.in.group_handle = handle;
5745 r.in.level = levels[i];
5748 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
5749 "QueryGroupInfo failed");
5750 if (!NT_STATUS_IS_OK(r.out.result)) {
5751 torture_result(tctx, TORTURE_FAIL, "QueryGroupInfo level %u failed - %s\n",
5752 levels[i], nt_errstr(r.out.result));
5760 static bool test_QueryGroupMember(struct dcerpc_binding_handle *b,
5761 struct torture_context *tctx,
5762 struct policy_handle *handle)
5764 struct samr_QueryGroupMember r;
5765 struct samr_RidAttrArray *rids = NULL;
5768 torture_comment(tctx, "Testing QueryGroupMember\n");
5770 r.in.group_handle = handle;
5773 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &r),
5774 "QueryGroupMember failed");
5775 if (!NT_STATUS_IS_OK(r.out.result)) {
5776 torture_result(tctx, TORTURE_FAIL, "QueryGroupMember failed - %s\n", nt_errstr(r.out.result));
5784 static bool test_SetGroupInfo(struct dcerpc_binding_handle *b,
5785 struct torture_context *tctx,
5786 struct policy_handle *handle)
5788 struct samr_QueryGroupInfo r;
5789 union samr_GroupInfo *info;
5790 struct samr_SetGroupInfo s;
5791 uint16_t levels[] = {1, 2, 3, 4};
5792 uint16_t set_ok[] = {0, 1, 1, 1};
5796 for (i=0;i<ARRAY_SIZE(levels);i++) {
5797 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5799 r.in.group_handle = handle;
5800 r.in.level = levels[i];
5803 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
5804 "QueryGroupInfo failed");
5805 if (!NT_STATUS_IS_OK(r.out.result)) {
5806 torture_result(tctx, TORTURE_FAIL, "QueryGroupInfo level %u failed - %s\n",
5807 levels[i], nt_errstr(r.out.result));
5811 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
5813 s.in.group_handle = handle;
5814 s.in.level = levels[i];
5815 s.in.info = *r.out.info;
5818 /* disabled this, as it changes the name only from the point of view of samr,
5819 but leaves the name from the point of view of w2k3 internals (and ldap). This means
5820 the name is still reserved, so creating the old name fails, but deleting by the old name
5822 if (s.in.level == 2) {
5823 init_lsa_String(&s.in.info->string, "NewName");
5827 if (s.in.level == 4) {
5828 init_lsa_String(&s.in.info->description, "test description");
5831 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetGroupInfo_r(b, tctx, &s),
5832 "SetGroupInfo failed");
5834 if (!NT_STATUS_IS_OK(s.out.result)) {
5835 torture_result(tctx, TORTURE_FAIL, "SetGroupInfo level %u failed - %s\n",
5836 r.in.level, nt_errstr(s.out.result));
5841 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
5842 torture_result(tctx, TORTURE_FAIL, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5843 r.in.level, nt_errstr(s.out.result));
5853 static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
5854 struct torture_context *tctx,
5855 struct policy_handle *handle)
5857 struct samr_QueryUserInfo r;
5858 union samr_UserInfo *info;
5859 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5860 11, 12, 13, 14, 16, 17, 20, 21};
5864 for (i=0;i<ARRAY_SIZE(levels);i++) {
5865 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
5867 r.in.user_handle = handle;
5868 r.in.level = levels[i];
5871 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
5872 "QueryUserInfo failed");
5873 if (!NT_STATUS_IS_OK(r.out.result)) {
5874 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
5875 levels[i], nt_errstr(r.out.result));
5883 static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
5884 struct torture_context *tctx,
5885 struct policy_handle *handle)
5887 struct samr_QueryUserInfo2 r;
5888 union samr_UserInfo *info;
5889 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5890 11, 12, 13, 14, 16, 17, 20, 21};
5894 for (i=0;i<ARRAY_SIZE(levels);i++) {
5895 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
5897 r.in.user_handle = handle;
5898 r.in.level = levels[i];
5901 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r),
5902 "QueryUserInfo2 failed");
5903 if (!NT_STATUS_IS_OK(r.out.result)) {
5904 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo2 level %u failed - %s\n",
5905 levels[i], nt_errstr(r.out.result));
5913 static bool test_OpenUser(struct dcerpc_binding_handle *b,
5914 struct torture_context *tctx,
5915 struct policy_handle *handle, uint32_t rid)
5917 struct samr_OpenUser r;
5918 struct policy_handle user_handle;
5921 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5923 r.in.domain_handle = handle;
5924 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5926 r.out.user_handle = &user_handle;
5928 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5930 if (!NT_STATUS_IS_OK(r.out.result)) {
5931 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5935 if (!test_QuerySecurity(b, tctx, &user_handle)) {
5939 if (!test_QueryUserInfo(b, tctx, &user_handle)) {
5943 if (!test_QueryUserInfo2(b, tctx, &user_handle)) {
5947 if (!test_GetUserPwInfo(b, tctx, &user_handle)) {
5951 if (!test_GetGroupsForUser(b, tctx, &user_handle)) {
5955 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
5962 static bool test_OpenGroup(struct dcerpc_binding_handle *b,
5963 struct torture_context *tctx,
5964 struct policy_handle *handle, uint32_t rid)
5966 struct samr_OpenGroup r;
5967 struct policy_handle group_handle;
5970 torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
5972 r.in.domain_handle = handle;
5973 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5975 r.out.group_handle = &group_handle;
5977 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
5978 "OpenGroup failed");
5979 if (!NT_STATUS_IS_OK(r.out.result)) {
5980 torture_result(tctx, TORTURE_FAIL, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5984 if (!torture_setting_bool(tctx, "samba3", false)) {
5985 if (!test_QuerySecurity(b, tctx, &group_handle)) {
5990 if (!test_QueryGroupInfo(b, tctx, &group_handle)) {
5994 if (!test_QueryGroupMember(b, tctx, &group_handle)) {
5998 if (!test_samr_handle_Close(b, tctx, &group_handle)) {
6005 static bool test_OpenAlias(struct dcerpc_binding_handle *b,
6006 struct torture_context *tctx,
6007 struct policy_handle *handle, uint32_t rid)
6009 struct samr_OpenAlias r;
6010 struct policy_handle alias_handle;
6013 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
6015 r.in.domain_handle = handle;
6016 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6018 r.out.alias_handle = &alias_handle;
6020 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
6021 "OpenAlias failed");
6022 if (!NT_STATUS_IS_OK(r.out.result)) {
6023 torture_result(tctx, TORTURE_FAIL, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6027 if (!torture_setting_bool(tctx, "samba3", false)) {
6028 if (!test_QuerySecurity(b, tctx, &alias_handle)) {
6033 if (!test_QueryAliasInfo(b, tctx, &alias_handle)) {
6037 if (!test_GetMembersInAlias(b, tctx, &alias_handle)) {
6041 if (!test_samr_handle_Close(b, tctx, &alias_handle)) {
6048 static bool check_mask(struct dcerpc_binding_handle *b,
6049 struct torture_context *tctx,
6050 struct policy_handle *handle, uint32_t rid,
6051 uint32_t acct_flag_mask)
6053 struct samr_OpenUser r;
6054 struct samr_QueryUserInfo q;
6055 union samr_UserInfo *info;
6056 struct policy_handle user_handle;
6059 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
6061 r.in.domain_handle = handle;
6062 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6064 r.out.user_handle = &user_handle;
6066 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6068 if (!NT_STATUS_IS_OK(r.out.result)) {
6069 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6073 q.in.user_handle = &user_handle;
6077 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6078 "QueryUserInfo failed");
6079 if (!NT_STATUS_IS_OK(q.out.result)) {
6080 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 16 failed - %s\n",
6081 nt_errstr(q.out.result));
6084 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
6085 torture_result(tctx, TORTURE_FAIL, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
6086 acct_flag_mask, info->info16.acct_flags, rid);
6091 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6098 static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle *b,
6099 struct torture_context *tctx,
6100 struct policy_handle *handle)
6102 struct samr_EnumDomainUsers r;
6103 uint32_t mask, resume_handle=0;
6106 struct samr_LookupNames n;
6107 struct samr_LookupRids lr ;
6108 struct lsa_Strings names;
6109 struct samr_Ids rids, types;
6110 struct samr_SamArray *sam = NULL;
6111 uint32_t num_entries = 0;
6113 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
6114 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
6115 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
6118 torture_comment(tctx, "Testing EnumDomainUsers\n");
6120 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
6121 r.in.domain_handle = handle;
6122 r.in.resume_handle = &resume_handle;
6123 r.in.acct_flags = mask = masks[mask_idx];
6124 r.in.max_size = (uint32_t)-1;
6125 r.out.resume_handle = &resume_handle;
6126 r.out.num_entries = &num_entries;
6129 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
6130 "EnumDomainUsers failed");
6131 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
6132 !NT_STATUS_IS_OK(r.out.result)) {
6133 torture_result(tctx, TORTURE_FAIL, "EnumDomainUsers failed - %s\n", nt_errstr(r.out.result));
6137 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
6139 if (sam->count == 0) {
6143 for (i=0;i<sam->count;i++) {
6145 if (!check_mask(b, tctx, handle, sam->entries[i].idx, mask)) {
6148 } else if (!test_OpenUser(b, tctx, handle, sam->entries[i].idx)) {
6154 torture_comment(tctx, "Testing LookupNames\n");
6155 n.in.domain_handle = handle;
6156 n.in.num_names = sam->count;
6157 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
6159 n.out.types = &types;
6160 for (i=0;i<sam->count;i++) {
6161 n.in.names[i].string = sam->entries[i].name.string;
6163 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
6164 "LookupNames failed");
6165 if (!NT_STATUS_IS_OK(n.out.result)) {
6166 torture_result(tctx, TORTURE_FAIL, "LookupNames failed - %s\n", nt_errstr(n.out.result));
6171 torture_comment(tctx, "Testing LookupRids\n");
6172 lr.in.domain_handle = handle;
6173 lr.in.num_rids = sam->count;
6174 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
6175 lr.out.names = &names;
6176 lr.out.types = &types;
6177 for (i=0;i<sam->count;i++) {
6178 lr.in.rids[i] = sam->entries[i].idx;
6180 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupRids_r(b, tctx, &lr),
6181 "LookupRids failed");
6182 torture_assert_ntstatus_ok(tctx, lr.out.result, "LookupRids");
6188 try blasting the server with a bunch of sync requests
6190 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
6191 struct policy_handle *handle)
6193 struct samr_EnumDomainUsers r;
6194 uint32_t resume_handle=0;
6196 #define ASYNC_COUNT 100
6197 struct tevent_req *req[ASYNC_COUNT];
6199 if (!torture_setting_bool(tctx, "dangerous", false)) {
6200 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
6203 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
6205 r.in.domain_handle = handle;
6206 r.in.resume_handle = &resume_handle;
6207 r.in.acct_flags = 0;
6208 r.in.max_size = (uint32_t)-1;
6209 r.out.resume_handle = &resume_handle;
6211 for (i=0;i<ASYNC_COUNT;i++) {
6212 req[i] = dcerpc_samr_EnumDomainUsers_r_send(tctx, tctx->ev, p->binding_handle, &r);
6215 for (i=0;i<ASYNC_COUNT;i++) {
6216 tevent_req_poll(req[i], tctx->ev);
6217 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r_recv(req[i], tctx),
6218 talloc_asprintf(tctx, "EnumDomainUsers[%d] failed - %s\n",
6219 i, nt_errstr(r.out.result)));
6222 torture_comment(tctx, "%d async requests OK\n", i);
6227 static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle *b,
6228 struct torture_context *tctx,
6229 struct policy_handle *handle)
6231 struct samr_EnumDomainGroups r;
6232 uint32_t resume_handle=0;
6233 struct samr_SamArray *sam = NULL;
6234 uint32_t num_entries = 0;
6237 bool universal_group_found = false;
6239 torture_comment(tctx, "Testing EnumDomainGroups\n");
6241 r.in.domain_handle = handle;
6242 r.in.resume_handle = &resume_handle;
6243 r.in.max_size = (uint32_t)-1;
6244 r.out.resume_handle = &resume_handle;
6245 r.out.num_entries = &num_entries;
6248 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
6249 "EnumDomainGroups failed");
6250 if (!NT_STATUS_IS_OK(r.out.result)) {
6251 torture_result(tctx, TORTURE_FAIL, "EnumDomainGroups failed - %s\n", nt_errstr(r.out.result));
6259 for (i=0;i<sam->count;i++) {
6260 if (!test_OpenGroup(b, tctx, handle, sam->entries[i].idx)) {
6263 if ((ret == true) && (strcasecmp(sam->entries[i].name.string,
6264 "Enterprise Admins") == 0)) {
6265 universal_group_found = true;
6269 /* when we are running this on s4 we should get back at least the
6270 * "Enterprise Admins" universal group. If we don't get a group entry
6271 * at all we probably are performing the test on the builtin domain.
6272 * So ignore this case. */
6273 if (torture_setting_bool(tctx, "samba4", false)) {
6274 if ((sam->count > 0) && (!universal_group_found)) {
6282 static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle *b,
6283 struct torture_context *tctx,
6284 struct policy_handle *handle)
6286 struct samr_EnumDomainAliases r;
6287 uint32_t resume_handle=0;
6288 struct samr_SamArray *sam = NULL;
6289 uint32_t num_entries = 0;
6293 torture_comment(tctx, "Testing EnumDomainAliases\n");
6295 r.in.domain_handle = handle;
6296 r.in.resume_handle = &resume_handle;
6297 r.in.max_size = (uint32_t)-1;
6299 r.out.num_entries = &num_entries;
6300 r.out.resume_handle = &resume_handle;
6302 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
6303 "EnumDomainAliases failed");
6304 if (!NT_STATUS_IS_OK(r.out.result)) {
6305 torture_result(tctx, TORTURE_FAIL, "EnumDomainAliases failed - %s\n", nt_errstr(r.out.result));
6313 for (i=0;i<sam->count;i++) {
6314 if (!test_OpenAlias(b, tctx, handle, sam->entries[i].idx)) {
6322 static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle *b,
6323 struct torture_context *tctx,
6324 struct policy_handle *handle)
6326 struct samr_GetDisplayEnumerationIndex r;
6328 uint16_t levels[] = {1, 2, 3, 4, 5};
6329 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6330 struct lsa_String name;
6334 for (i=0;i<ARRAY_SIZE(levels);i++) {
6335 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
6337 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6339 r.in.domain_handle = handle;
6340 r.in.level = levels[i];
6344 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6345 "GetDisplayEnumerationIndex failed");
6348 !NT_STATUS_IS_OK(r.out.result) &&
6349 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6350 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex level %u failed - %s\n",
6351 levels[i], nt_errstr(r.out.result));
6355 init_lsa_String(&name, "zzzzzzzz");
6357 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6358 "GetDisplayEnumerationIndex failed");
6360 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6361 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex level %u failed - %s\n",
6362 levels[i], nt_errstr(r.out.result));
6370 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle *b,
6371 struct torture_context *tctx,
6372 struct policy_handle *handle)
6374 struct samr_GetDisplayEnumerationIndex2 r;
6376 uint16_t levels[] = {1, 2, 3, 4, 5};
6377 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6378 struct lsa_String name;
6382 for (i=0;i<ARRAY_SIZE(levels);i++) {
6383 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
6385 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6387 r.in.domain_handle = handle;
6388 r.in.level = levels[i];
6392 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6393 "GetDisplayEnumerationIndex2 failed");
6395 !NT_STATUS_IS_OK(r.out.result) &&
6396 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6397 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6398 levels[i], nt_errstr(r.out.result));
6402 init_lsa_String(&name, "zzzzzzzz");
6404 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6405 "GetDisplayEnumerationIndex2 failed");
6406 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6407 torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6408 levels[i], nt_errstr(r.out.result));
6416 #define STRING_EQUAL_QUERY(s1, s2, user) \
6417 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6418 /* odd, but valid */ \
6419 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6420 torture_result(tctx, TORTURE_FAIL, "%s mismatch for %s: %s != %s (%s)\n", \
6421 #s1, user.string, s1.string, s2.string, __location__); \
6424 #define INT_EQUAL_QUERY(s1, s2, user) \
6426 torture_result(tctx, TORTURE_FAIL, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6427 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6431 static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle *b,
6432 struct torture_context *tctx,
6433 struct samr_QueryDisplayInfo *querydisplayinfo,
6434 bool *seen_testuser)
6436 struct samr_OpenUser r;
6437 struct samr_QueryUserInfo q;
6438 union samr_UserInfo *info;
6439 struct policy_handle user_handle;
6441 r.in.domain_handle = querydisplayinfo->in.domain_handle;
6442 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6443 for (i = 0; ; i++) {
6444 switch (querydisplayinfo->in.level) {
6446 if (i >= querydisplayinfo->out.info->info1.count) {
6449 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
6452 if (i >= querydisplayinfo->out.info->info2.count) {
6455 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
6461 /* Not interested in validating just the account name */
6465 r.out.user_handle = &user_handle;
6467 switch (querydisplayinfo->in.level) {
6470 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6472 if (!NT_STATUS_IS_OK(r.out.result)) {
6473 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6478 q.in.user_handle = &user_handle;
6481 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6482 "QueryUserInfo failed");
6483 if (!NT_STATUS_IS_OK(r.out.result)) {
6484 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6488 switch (querydisplayinfo->in.level) {
6490 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
6491 *seen_testuser = true;
6493 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
6494 info->info21.full_name, info->info21.account_name);
6495 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
6496 info->info21.account_name, info->info21.account_name);
6497 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
6498 info->info21.description, info->info21.account_name);
6499 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
6500 info->info21.rid, info->info21.account_name);
6501 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
6502 info->info21.acct_flags, info->info21.account_name);
6506 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
6507 info->info21.account_name, info->info21.account_name);
6508 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
6509 info->info21.description, info->info21.account_name);
6510 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
6511 info->info21.rid, info->info21.account_name);
6512 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
6513 info->info21.acct_flags, info->info21.account_name);
6515 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
6516 torture_result(tctx, TORTURE_FAIL, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6517 info->info21.account_name.string);
6520 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
6521 torture_result(tctx, TORTURE_FAIL, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6522 info->info21.account_name.string,
6523 querydisplayinfo->out.info->info2.entries[i].acct_flags,
6524 info->info21.acct_flags);
6531 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6538 static bool test_QueryDisplayInfo(struct dcerpc_binding_handle *b,
6539 struct torture_context *tctx,
6540 struct policy_handle *handle)
6542 struct samr_QueryDisplayInfo r;
6543 struct samr_QueryDomainInfo dom_info;
6544 union samr_DomainInfo *info = NULL;
6546 uint16_t levels[] = {1, 2, 3, 4, 5};
6548 bool seen_testuser = false;
6549 uint32_t total_size;
6550 uint32_t returned_size;
6551 union samr_DispInfo disp_info;
6554 for (i=0;i<ARRAY_SIZE(levels);i++) {
6555 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
6558 r.out.result = STATUS_MORE_ENTRIES;
6559 while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
6560 r.in.domain_handle = handle;
6561 r.in.level = levels[i];
6562 r.in.max_entries = 2;
6563 r.in.buf_size = (uint32_t)-1;
6564 r.out.total_size = &total_size;
6565 r.out.returned_size = &returned_size;
6566 r.out.info = &disp_info;
6568 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6569 "QueryDisplayInfo failed");
6570 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(r.out.result)) {
6571 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level %u failed - %s\n",
6572 levels[i], nt_errstr(r.out.result));
6575 switch (r.in.level) {
6577 if (!test_each_DisplayInfo_user(b, tctx, &r, &seen_testuser)) {
6580 r.in.start_idx += r.out.info->info1.count;
6583 if (!test_each_DisplayInfo_user(b, tctx, &r, NULL)) {
6586 r.in.start_idx += r.out.info->info2.count;
6589 r.in.start_idx += r.out.info->info3.count;
6592 r.in.start_idx += r.out.info->info4.count;
6595 r.in.start_idx += r.out.info->info5.count;
6599 dom_info.in.domain_handle = handle;
6600 dom_info.in.level = 2;
6601 dom_info.out.info = &info;
6603 /* Check number of users returned is correct */
6604 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &dom_info),
6605 "QueryDomainInfo failed");
6606 if (!NT_STATUS_IS_OK(dom_info.out.result)) {
6607 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
6608 r.in.level, nt_errstr(dom_info.out.result));
6612 switch (r.in.level) {
6615 if (info->general.num_users < r.in.start_idx) {
6616 /* On AD deployments this numbers don't match
6617 * since QueryDisplayInfo returns universal and
6618 * global groups, QueryDomainInfo only global
6620 if (torture_setting_bool(tctx, "samba3", false)) {
6621 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6622 r.in.start_idx, info->general.num_groups,
6623 info->general.domain_name.string);
6627 if (!seen_testuser) {
6628 struct policy_handle user_handle;
6629 if (NT_STATUS_IS_OK(test_OpenUser_byname(b, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
6630 torture_result(tctx, TORTURE_FAIL, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
6631 info->general.domain_name.string);
6633 test_samr_handle_Close(b, tctx, &user_handle);
6639 if (info->general.num_groups != r.in.start_idx) {
6640 /* On AD deployments this numbers don't match
6641 * since QueryDisplayInfo returns universal and
6642 * global groups, QueryDomainInfo only global
6644 if (torture_setting_bool(tctx, "samba3", false)) {
6645 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6646 r.in.start_idx, info->general.num_groups,
6647 info->general.domain_name.string);
6660 static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle *b,
6661 struct torture_context *tctx,
6662 struct policy_handle *handle)
6664 struct samr_QueryDisplayInfo2 r;
6666 uint16_t levels[] = {1, 2, 3, 4, 5};
6668 uint32_t total_size;
6669 uint32_t returned_size;
6670 union samr_DispInfo info;
6672 for (i=0;i<ARRAY_SIZE(levels);i++) {
6673 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
6675 r.in.domain_handle = handle;
6676 r.in.level = levels[i];
6678 r.in.max_entries = 1000;
6679 r.in.buf_size = (uint32_t)-1;
6680 r.out.total_size = &total_size;
6681 r.out.returned_size = &returned_size;
6684 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo2_r(b, tctx, &r),
6685 "QueryDisplayInfo2 failed");
6686 if (!NT_STATUS_IS_OK(r.out.result)) {
6687 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo2 level %u failed - %s\n",
6688 levels[i], nt_errstr(r.out.result));
6696 static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle *b,
6697 struct torture_context *tctx,
6698 struct policy_handle *handle)
6700 struct samr_QueryDisplayInfo3 r;
6702 uint16_t levels[] = {1, 2, 3, 4, 5};
6704 uint32_t total_size;
6705 uint32_t returned_size;
6706 union samr_DispInfo info;
6708 for (i=0;i<ARRAY_SIZE(levels);i++) {
6709 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
6711 r.in.domain_handle = handle;
6712 r.in.level = levels[i];
6714 r.in.max_entries = 1000;
6715 r.in.buf_size = (uint32_t)-1;
6716 r.out.total_size = &total_size;
6717 r.out.returned_size = &returned_size;
6720 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo3_r(b, tctx, &r),
6721 "QueryDisplayInfo3 failed");
6722 if (!NT_STATUS_IS_OK(r.out.result)) {
6723 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo3 level %u failed - %s\n",
6724 levels[i], nt_errstr(r.out.result));
6733 static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle *b,
6734 struct torture_context *tctx,
6735 struct policy_handle *handle)
6737 struct samr_QueryDisplayInfo r;
6739 uint32_t total_size;
6740 uint32_t returned_size;
6741 union samr_DispInfo info;
6743 torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
6745 r.in.domain_handle = handle;
6748 r.in.max_entries = 1;
6749 r.in.buf_size = (uint32_t)-1;
6750 r.out.total_size = &total_size;
6751 r.out.returned_size = &returned_size;
6755 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6756 "QueryDisplayInfo failed");
6757 if (NT_STATUS_IS_OK(r.out.result) && *r.out.returned_size != 0) {
6758 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
6759 torture_result(tctx, TORTURE_FAIL, "expected idx %d but got %d\n",
6761 r.out.info->info1.entries[0].idx);
6765 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
6766 !NT_STATUS_IS_OK(r.out.result)) {
6767 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level %u failed - %s\n",
6768 r.in.level, nt_errstr(r.out.result));
6773 } while ((NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) ||
6774 NT_STATUS_IS_OK(r.out.result)) &&
6775 *r.out.returned_size != 0);
6780 static bool test_QueryDomainInfo(struct dcerpc_pipe *p,
6781 struct torture_context *tctx,
6782 struct policy_handle *handle)
6784 struct samr_QueryDomainInfo r;
6785 union samr_DomainInfo *info = NULL;
6786 struct samr_SetDomainInfo s;
6787 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6788 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
6791 struct dcerpc_binding_handle *b = p->binding_handle;
6792 const char *domain_comment = talloc_asprintf(tctx,
6793 "Tortured by Samba4 RPC-SAMR: %s",
6794 timestring(tctx, time(NULL)));
6796 s.in.domain_handle = handle;
6798 s.in.info = talloc(tctx, union samr_DomainInfo);
6800 s.in.info->oem.oem_information.string = domain_comment;
6801 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
6802 "SetDomainInfo failed");
6803 if (!NT_STATUS_IS_OK(s.out.result)) {
6804 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u (set comment) failed - %s\n",
6805 s.in.level, nt_errstr(s.out.result));
6809 for (i=0;i<ARRAY_SIZE(levels);i++) {
6810 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
6812 r.in.domain_handle = handle;
6813 r.in.level = levels[i];
6816 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
6817 "QueryDomainInfo failed");
6818 if (!NT_STATUS_IS_OK(r.out.result)) {
6819 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
6820 r.in.level, nt_errstr(r.out.result));
6825 switch (levels[i]) {
6827 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
6828 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6829 levels[i], info->general.oem_information.string, domain_comment);
6830 if (!torture_setting_bool(tctx, "samba3", false)) {
6834 if (!info->general.primary.string) {
6835 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned no PDC name\n",
6838 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
6839 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
6840 if (torture_setting_bool(tctx, "samba3", false)) {
6841 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",
6842 levels[i], info->general.primary.string, dcerpc_server_name(p));
6848 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
6849 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6850 levels[i], info->oem.oem_information.string, domain_comment);
6851 if (!torture_setting_bool(tctx, "samba3", false)) {
6857 if (!info->info6.primary.string) {
6858 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned no PDC name\n",
6864 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
6865 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
6866 levels[i], info->general2.general.oem_information.string, domain_comment);
6867 if (!torture_setting_bool(tctx, "samba3", false)) {
6874 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
6876 s.in.domain_handle = handle;
6877 s.in.level = levels[i];
6880 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
6881 "SetDomainInfo failed");
6883 if (!NT_STATUS_IS_OK(s.out.result)) {
6884 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u failed - %s\n",
6885 r.in.level, nt_errstr(s.out.result));
6890 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
6891 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6892 r.in.level, nt_errstr(s.out.result));
6898 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
6899 "QueryDomainInfo failed");
6900 if (!NT_STATUS_IS_OK(r.out.result)) {
6901 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
6902 r.in.level, nt_errstr(r.out.result));
6912 static bool test_QueryDomainInfo2(struct dcerpc_binding_handle *b,
6913 struct torture_context *tctx,
6914 struct policy_handle *handle)
6916 struct samr_QueryDomainInfo2 r;
6917 union samr_DomainInfo *info = NULL;
6918 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6922 for (i=0;i<ARRAY_SIZE(levels);i++) {
6923 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
6925 r.in.domain_handle = handle;
6926 r.in.level = levels[i];
6929 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
6930 "QueryDomainInfo2 failed");
6931 if (!NT_STATUS_IS_OK(r.out.result)) {
6932 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo2 level %u failed - %s\n",
6933 r.in.level, nt_errstr(r.out.result));
6942 /* Test whether querydispinfo level 5 and enumdomgroups return the same
6943 set of group names. */
6944 static bool test_GroupList(struct dcerpc_binding_handle *b,
6945 struct torture_context *tctx,
6946 struct dom_sid *domain_sid,
6947 struct policy_handle *handle)
6949 struct samr_EnumDomainGroups q1;
6950 struct samr_QueryDisplayInfo q2;
6952 uint32_t resume_handle=0;
6953 struct samr_SamArray *sam = NULL;
6954 uint32_t num_entries = 0;
6957 uint32_t total_size;
6958 uint32_t returned_size;
6959 union samr_DispInfo info;
6962 const char **names = NULL;
6964 bool builtin_domain = dom_sid_compare(domain_sid,
6965 &global_sid_Builtin) == 0;
6967 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
6969 q1.in.domain_handle = handle;
6970 q1.in.resume_handle = &resume_handle;
6972 q1.out.resume_handle = &resume_handle;
6973 q1.out.num_entries = &num_entries;
6976 status = STATUS_MORE_ENTRIES;
6977 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6978 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &q1),
6979 "EnumDomainGroups failed");
6980 status = q1.out.result;
6982 if (!NT_STATUS_IS_OK(status) &&
6983 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6986 for (i=0; i<*q1.out.num_entries; i++) {
6987 add_string_to_array(tctx,
6988 sam->entries[i].name.string,
6989 &names, &num_names);
6993 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
6995 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
6997 if (builtin_domain) {
6998 torture_assert(tctx, num_names == 0,
6999 "EnumDomainGroups shouldn't return any group in the builtin domain!");
7002 q2.in.domain_handle = handle;
7004 q2.in.start_idx = 0;
7005 q2.in.max_entries = 5;
7006 q2.in.buf_size = (uint32_t)-1;
7007 q2.out.total_size = &total_size;
7008 q2.out.returned_size = &returned_size;
7009 q2.out.info = &info;
7011 status = STATUS_MORE_ENTRIES;
7012 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
7013 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &q2),
7014 "QueryDisplayInfo failed");
7015 status = q2.out.result;
7016 if (!NT_STATUS_IS_OK(status) &&
7017 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
7020 for (i=0; i<q2.out.info->info5.count; i++) {
7022 const char *name = q2.out.info->info5.entries[i].account_name.string;
7024 for (j=0; j<num_names; j++) {
7025 if (names[j] == NULL)
7027 if (strequal(names[j], name)) {
7034 if ((!found) && (!builtin_domain)) {
7035 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
7040 q2.in.start_idx += q2.out.info->info5.count;
7043 if (!NT_STATUS_IS_OK(status)) {
7044 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level 5 failed - %s\n",
7049 if (builtin_domain) {
7050 torture_assert(tctx, q2.in.start_idx != 0,
7051 "QueryDisplayInfo should return all domain groups also on the builtin domain handle!");
7054 for (i=0; i<num_names; i++) {
7055 if (names[i] != NULL) {
7056 torture_result(tctx, TORTURE_FAIL, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
7065 static bool test_DeleteDomainGroup(struct dcerpc_binding_handle *b,
7066 struct torture_context *tctx,
7067 struct policy_handle *group_handle)
7069 struct samr_DeleteDomainGroup d;
7071 torture_comment(tctx, "Testing DeleteDomainGroup\n");
7073 d.in.group_handle = group_handle;
7074 d.out.group_handle = group_handle;
7076 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
7077 "DeleteDomainGroup failed");
7078 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteDomainGroup");
7083 static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle *b,
7084 struct torture_context *tctx,
7085 struct policy_handle *domain_handle)
7087 struct samr_TestPrivateFunctionsDomain r;
7090 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
7092 r.in.domain_handle = domain_handle;
7094 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsDomain_r(b, tctx, &r),
7095 "TestPrivateFunctionsDomain failed");
7096 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
7101 static bool test_RidToSid(struct dcerpc_binding_handle *b,
7102 struct torture_context *tctx,
7103 struct dom_sid *domain_sid,
7104 struct policy_handle *domain_handle)
7106 struct samr_RidToSid r;
7108 struct dom_sid *calc_sid, *out_sid;
7109 int rids[] = { 0, 42, 512, 10200 };
7112 for (i=0;i<ARRAY_SIZE(rids);i++) {
7113 torture_comment(tctx, "Testing RidToSid\n");
7115 calc_sid = dom_sid_dup(tctx, domain_sid);
7116 r.in.domain_handle = domain_handle;
7118 r.out.sid = &out_sid;
7120 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RidToSid_r(b, tctx, &r),
7122 if (!NT_STATUS_IS_OK(r.out.result)) {
7123 torture_result(tctx, TORTURE_FAIL, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(r.out.result));
7126 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
7128 if (!dom_sid_equal(calc_sid, out_sid)) {
7129 torture_result(tctx, TORTURE_FAIL, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
7130 dom_sid_string(tctx, out_sid),
7131 dom_sid_string(tctx, calc_sid));
7140 static bool test_GetBootKeyInformation(struct dcerpc_binding_handle *b,
7141 struct torture_context *tctx,
7142 struct policy_handle *domain_handle)
7144 struct samr_GetBootKeyInformation r;
7146 uint32_t unknown = 0;
7149 torture_comment(tctx, "Testing GetBootKeyInformation\n");
7151 r.in.domain_handle = domain_handle;
7152 r.out.unknown = &unknown;
7154 status = dcerpc_samr_GetBootKeyInformation_r(b, tctx, &r);
7155 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(r.out.result)) {
7156 status = r.out.result;
7158 if (!NT_STATUS_IS_OK(status)) {
7159 /* w2k3 seems to fail this sometimes and pass it sometimes */
7160 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
7166 static bool test_AddGroupMember(struct dcerpc_binding_handle *b,
7167 struct torture_context *tctx,
7168 struct policy_handle *domain_handle,
7169 struct policy_handle *group_handle)
7172 struct samr_AddGroupMember r;
7173 struct samr_DeleteGroupMember d;
7174 struct samr_QueryGroupMember q;
7175 struct samr_RidAttrArray *rids = NULL;
7176 struct samr_SetMemberAttributesOfGroup s;
7178 bool found_member = false;
7181 status = test_LookupName(b, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
7182 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
7184 r.in.group_handle = group_handle;
7186 r.in.flags = 0; /* ??? */
7188 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
7190 d.in.group_handle = group_handle;
7193 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7194 "DeleteGroupMember failed");
7195 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, d.out.result, "DeleteGroupMember");
7197 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7198 "AddGroupMember failed");
7199 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7201 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7202 "AddGroupMember failed");
7203 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, r.out.result, "AddGroupMember");
7205 if (torture_setting_bool(tctx, "samba4", false) ||
7206 torture_setting_bool(tctx, "samba3", false)) {
7207 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
7209 /* this one is quite strange. I am using random inputs in the
7210 hope of triggering an error that might give us a clue */
7212 s.in.group_handle = group_handle;
7213 s.in.unknown1 = random();
7214 s.in.unknown2 = random();
7216 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetMemberAttributesOfGroup_r(b, tctx, &s),
7217 "SetMemberAttributesOfGroup failed");
7218 torture_assert_ntstatus_ok(tctx, s.out.result, "SetMemberAttributesOfGroup");
7221 q.in.group_handle = group_handle;
7224 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7225 "QueryGroupMember failed");
7226 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7227 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7229 for (i=0; i < rids->count; i++) {
7230 if (rids->rids[i] == rid) {
7231 found_member = true;
7235 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
7237 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7238 "DeleteGroupMember failed");
7239 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteGroupMember");
7242 found_member = false;
7244 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7245 "QueryGroupMember failed");
7246 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7247 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7249 for (i=0; i < rids->count; i++) {
7250 if (rids->rids[i] == rid) {
7251 found_member = true;
7255 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
7257 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7258 "AddGroupMember failed");
7259 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7265 static bool test_CreateDomainGroup(struct dcerpc_binding_handle *b,
7266 struct torture_context *tctx,
7267 struct policy_handle *domain_handle,
7268 const char *group_name,
7269 struct policy_handle *group_handle,
7270 struct dom_sid *domain_sid,
7273 struct samr_CreateDomainGroup r;
7275 struct lsa_String name;
7278 init_lsa_String(&name, group_name);
7280 r.in.domain_handle = domain_handle;
7282 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7283 r.out.group_handle = group_handle;
7286 torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
7288 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7289 "CreateDomainGroup failed");
7291 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
7292 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
7293 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
7296 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
7297 nt_errstr(r.out.result));
7302 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_GROUP_EXISTS)) {
7303 if (!test_DeleteGroup_byname(b, tctx, domain_handle, r.in.name->string)) {
7304 torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
7305 nt_errstr(r.out.result));
7308 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7309 "CreateDomainGroup failed");
7311 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
7312 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.name->string)) {
7314 torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
7315 nt_errstr(r.out.result));
7318 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7319 "CreateDomainGroup failed");
7321 torture_assert_ntstatus_ok(tctx, r.out.result, "CreateDomainGroup");
7327 if (!test_AddGroupMember(b, tctx, domain_handle, group_handle)) {
7328 torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed - %s\n", nt_errstr(r.out.result));
7332 if (!test_SetGroupInfo(b, tctx, group_handle)) {
7341 its not totally clear what this does. It seems to accept any sid you like.
7343 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle *b,
7344 struct torture_context *tctx,
7345 struct policy_handle *domain_handle)
7347 struct samr_RemoveMemberFromForeignDomain r;
7349 r.in.domain_handle = domain_handle;
7350 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
7352 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMemberFromForeignDomain_r(b, tctx, &r),
7353 "RemoveMemberFromForeignDomain failed");
7354 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMemberFromForeignDomain");
7359 static bool test_EnumDomainUsers(struct dcerpc_binding_handle *b,
7360 struct torture_context *tctx,
7361 struct policy_handle *domain_handle,
7362 uint32_t *total_num_entries_p)
7365 struct samr_EnumDomainUsers r;
7366 uint32_t resume_handle = 0;
7367 uint32_t num_entries = 0;
7368 uint32_t total_num_entries = 0;
7369 struct samr_SamArray *sam;
7371 r.in.domain_handle = domain_handle;
7372 r.in.acct_flags = 0;
7373 r.in.max_size = (uint32_t)-1;
7374 r.in.resume_handle = &resume_handle;
7377 r.out.num_entries = &num_entries;
7378 r.out.resume_handle = &resume_handle;
7380 torture_comment(tctx, "Testing EnumDomainUsers\n");
7383 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
7384 "EnumDomainUsers failed");
7385 if (NT_STATUS_IS_ERR(r.out.result)) {
7386 torture_assert_ntstatus_ok(tctx, r.out.result,
7387 "failed to enumerate users");
7389 status = r.out.result;
7391 total_num_entries += num_entries;
7392 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7394 if (total_num_entries_p) {
7395 *total_num_entries_p = total_num_entries;
7401 static bool test_EnumDomainGroups(struct dcerpc_binding_handle *b,
7402 struct torture_context *tctx,
7403 struct policy_handle *domain_handle,
7404 uint32_t *total_num_entries_p)
7407 struct samr_EnumDomainGroups r;
7408 uint32_t resume_handle = 0;
7409 uint32_t num_entries = 0;
7410 uint32_t total_num_entries = 0;
7411 struct samr_SamArray *sam;
7413 r.in.domain_handle = domain_handle;
7414 r.in.max_size = (uint32_t)-1;
7415 r.in.resume_handle = &resume_handle;
7418 r.out.num_entries = &num_entries;
7419 r.out.resume_handle = &resume_handle;
7421 torture_comment(tctx, "Testing EnumDomainGroups\n");
7424 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
7425 "EnumDomainGroups failed");
7426 if (NT_STATUS_IS_ERR(r.out.result)) {
7427 torture_assert_ntstatus_ok(tctx, r.out.result,
7428 "failed to enumerate groups");
7430 status = r.out.result;
7432 total_num_entries += num_entries;
7433 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7435 if (total_num_entries_p) {
7436 *total_num_entries_p = total_num_entries;
7442 static bool test_EnumDomainAliases(struct dcerpc_binding_handle *b,
7443 struct torture_context *tctx,
7444 struct policy_handle *domain_handle,
7445 uint32_t *total_num_entries_p)
7448 struct samr_EnumDomainAliases r;
7449 uint32_t resume_handle = 0;
7450 uint32_t num_entries = 0;
7451 uint32_t total_num_entries = 0;
7452 struct samr_SamArray *sam;
7454 r.in.domain_handle = domain_handle;
7455 r.in.max_size = (uint32_t)-1;
7456 r.in.resume_handle = &resume_handle;
7459 r.out.num_entries = &num_entries;
7460 r.out.resume_handle = &resume_handle;
7462 torture_comment(tctx, "Testing EnumDomainAliases\n");
7465 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
7466 "EnumDomainAliases failed");
7467 if (NT_STATUS_IS_ERR(r.out.result)) {
7468 torture_assert_ntstatus_ok(tctx, r.out.result,
7469 "failed to enumerate aliases");
7471 status = r.out.result;
7473 total_num_entries += num_entries;
7474 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7476 if (total_num_entries_p) {
7477 *total_num_entries_p = total_num_entries;
7483 static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle *b,
7484 struct torture_context *tctx,
7485 struct policy_handle *handle,
7487 uint32_t *total_num_entries_p)
7490 struct samr_QueryDisplayInfo r;
7491 uint32_t total_num_entries = 0;
7493 r.in.domain_handle = handle;
7496 r.in.max_entries = (uint32_t)-1;
7497 r.in.buf_size = (uint32_t)-1;
7499 torture_comment(tctx, "Testing QueryDisplayInfo\n");
7502 uint32_t total_size;
7503 uint32_t returned_size;
7504 union samr_DispInfo info;
7506 r.out.total_size = &total_size;
7507 r.out.returned_size = &returned_size;
7510 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7511 "failed to query displayinfo");
7512 if (NT_STATUS_IS_ERR(r.out.result)) {
7513 torture_assert_ntstatus_ok(tctx, r.out.result,
7514 "failed to query displayinfo");
7516 status = r.out.result;
7518 if (*r.out.returned_size == 0) {
7522 switch (r.in.level) {
7524 total_num_entries += info.info1.count;
7525 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
7528 total_num_entries += info.info2.count;
7529 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
7532 total_num_entries += info.info3.count;
7533 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
7536 total_num_entries += info.info4.count;
7537 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
7540 total_num_entries += info.info5.count;
7541 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
7547 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7549 if (total_num_entries_p) {
7550 *total_num_entries_p = total_num_entries;
7556 static bool test_ManyObjects(struct dcerpc_pipe *p,
7557 struct torture_context *tctx,
7558 struct policy_handle *domain_handle,
7559 struct dom_sid *domain_sid,
7560 struct torture_samr_context *ctx)
7562 uint32_t num_total = ctx->num_objects_large_dc;
7563 uint32_t num_enum = 0;
7564 uint32_t num_disp = 0;
7565 uint32_t num_created = 0;
7566 uint32_t num_anounced = 0;
7568 struct dcerpc_binding_handle *b = p->binding_handle;
7570 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
7575 struct samr_QueryDomainInfo2 r;
7576 union samr_DomainInfo *info;
7577 r.in.domain_handle = domain_handle;
7581 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
7582 "QueryDomainInfo2 failed");
7583 torture_assert_ntstatus_ok(tctx, r.out.result,
7584 "failed to query domain info");
7586 switch (ctx->choice) {
7587 case TORTURE_SAMR_MANY_ACCOUNTS:
7588 num_anounced = info->general.num_users;
7590 case TORTURE_SAMR_MANY_GROUPS:
7591 num_anounced = info->general.num_groups;
7593 case TORTURE_SAMR_MANY_ALIASES:
7594 num_anounced = info->general.num_aliases;
7603 for (i=0; i < num_total; i++) {
7605 const char *name = NULL;
7607 switch (ctx->choice) {
7608 case TORTURE_SAMR_MANY_ACCOUNTS:
7609 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
7610 torture_assert(tctx,
7611 test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false),
7612 "failed to create user");
7614 case TORTURE_SAMR_MANY_GROUPS:
7615 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
7616 torture_assert(tctx,
7617 test_CreateDomainGroup(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
7618 "failed to create group");
7620 case TORTURE_SAMR_MANY_ALIASES:
7621 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
7622 torture_assert(tctx,
7623 test_CreateAlias(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
7624 "failed to create alias");
7629 if (!ndr_policy_handle_empty(&handles[i])) {
7636 switch (ctx->choice) {
7637 case TORTURE_SAMR_MANY_ACCOUNTS:
7638 torture_assert(tctx,
7639 test_EnumDomainUsers(b, tctx, domain_handle, &num_enum),
7640 "failed to enum users");
7642 case TORTURE_SAMR_MANY_GROUPS:
7643 torture_assert(tctx,
7644 test_EnumDomainGroups(b, tctx, domain_handle, &num_enum),
7645 "failed to enum groups");
7647 case TORTURE_SAMR_MANY_ALIASES:
7648 torture_assert(tctx,
7649 test_EnumDomainAliases(b, tctx, domain_handle, &num_enum),
7650 "failed to enum aliases");
7658 switch (ctx->choice) {
7659 case TORTURE_SAMR_MANY_ACCOUNTS:
7660 torture_assert(tctx,
7661 test_QueryDisplayInfo_level(b, tctx, domain_handle, 1, &num_disp),
7662 "failed to query display info");
7664 case TORTURE_SAMR_MANY_GROUPS:
7665 torture_assert(tctx,
7666 test_QueryDisplayInfo_level(b, tctx, domain_handle, 3, &num_disp),
7667 "failed to query display info");
7669 case TORTURE_SAMR_MANY_ALIASES:
7670 /* no aliases in dispinfo */
7676 /* close or delete */
7678 for (i=0; i < num_total; i++) {
7680 if (ndr_policy_handle_empty(&handles[i])) {
7684 if (torture_setting_bool(tctx, "samba3", false)) {
7685 torture_assert(tctx,
7686 test_samr_handle_Close(b, tctx, &handles[i]),
7687 "failed to close handle");
7689 switch (ctx->choice) {
7690 case TORTURE_SAMR_MANY_ACCOUNTS:
7691 torture_assert(tctx,
7692 test_DeleteUser(b, tctx, &handles[i]),
7693 "failed to delete user");
7695 case TORTURE_SAMR_MANY_GROUPS:
7696 torture_assert(tctx,
7697 test_DeleteDomainGroup(b, tctx, &handles[i]),
7698 "failed to delete group");
7700 case TORTURE_SAMR_MANY_ALIASES:
7701 torture_assert(tctx,
7702 test_DeleteAlias(b, tctx, &handles[i]),
7703 "failed to delete alias");
7711 talloc_free(handles);
7713 if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
7714 torture_comment(tctx,
7715 "unexpected number of results (%u) returned in enum call, expected %u\n",
7716 num_enum, num_anounced + num_created);
7718 torture_comment(tctx,
7719 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
7720 num_disp, num_anounced + num_created);
7726 static bool test_Connect(struct dcerpc_binding_handle *b,
7727 struct torture_context *tctx,
7728 struct policy_handle *handle);
7730 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7731 struct torture_samr_context *ctx, struct dom_sid *sid)
7733 struct samr_OpenDomain r;
7734 struct policy_handle domain_handle;
7735 struct policy_handle alias_handle;
7736 struct policy_handle user_handle;
7737 struct policy_handle group_handle;
7739 struct dcerpc_binding_handle *b = p->binding_handle;
7741 ZERO_STRUCT(alias_handle);
7742 ZERO_STRUCT(user_handle);
7743 ZERO_STRUCT(group_handle);
7744 ZERO_STRUCT(domain_handle);
7746 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
7748 r.in.connect_handle = &ctx->handle;
7749 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7751 r.out.domain_handle = &domain_handle;
7753 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenDomain_r(b, tctx, &r),
7754 "OpenDomain failed");
7755 torture_assert_ntstatus_ok(tctx, r.out.result, "OpenDomain failed");
7757 /* run the domain tests with the main handle closed - this tests
7758 the servers reference counting */
7759 torture_assert(tctx, test_samr_handle_Close(b, tctx, &ctx->handle), "Failed to close SAMR handle");
7761 switch (ctx->choice) {
7762 case TORTURE_SAMR_PASSWORDS:
7763 case TORTURE_SAMR_USER_PRIVILEGES:
7764 if (!torture_setting_bool(tctx, "samba3", false)) {
7765 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7767 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7769 torture_result(tctx, TORTURE_FAIL, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
7772 case TORTURE_SAMR_USER_ATTRIBUTES:
7773 if (!torture_setting_bool(tctx, "samba3", false)) {
7774 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7776 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7777 /* This test needs 'complex' users to validate */
7778 ret &= test_QueryDisplayInfo(b, tctx, &domain_handle);
7780 torture_result(tctx, TORTURE_FAIL, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
7783 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
7784 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
7785 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
7786 if (!torture_setting_bool(tctx, "samba3", false)) {
7787 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
7789 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
7791 torture_result(tctx, TORTURE_FAIL, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx, sid));
7794 case TORTURE_SAMR_MANY_ACCOUNTS:
7795 case TORTURE_SAMR_MANY_GROUPS:
7796 case TORTURE_SAMR_MANY_ALIASES:
7797 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
7799 torture_result(tctx, TORTURE_FAIL, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
7802 case TORTURE_SAMR_OTHER:
7803 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7805 torture_result(tctx, TORTURE_FAIL, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
7807 if (!torture_setting_bool(tctx, "samba3", false)) {
7808 ret &= test_QuerySecurity(b, tctx, &domain_handle);
7810 ret &= test_RemoveMemberFromForeignDomain(b, tctx, &domain_handle);
7811 ret &= test_CreateAlias(b, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
7812 ret &= test_CreateDomainGroup(b, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
7813 ret &= test_GetAliasMembership(b, tctx, &domain_handle);
7814 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
7815 ret &= test_QueryDomainInfo2(b, tctx, &domain_handle);
7816 ret &= test_EnumDomainUsers_all(b, tctx, &domain_handle);
7817 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
7818 ret &= test_EnumDomainGroups_all(b, tctx, &domain_handle);
7819 ret &= test_EnumDomainAliases_all(b, tctx, &domain_handle);
7820 ret &= test_QueryDisplayInfo2(b, tctx, &domain_handle);
7821 ret &= test_QueryDisplayInfo3(b, tctx, &domain_handle);
7822 ret &= test_QueryDisplayInfo_continue(b, tctx, &domain_handle);
7824 if (torture_setting_bool(tctx, "samba4", false)) {
7825 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
7827 ret &= test_GetDisplayEnumerationIndex(b, tctx, &domain_handle);
7828 ret &= test_GetDisplayEnumerationIndex2(b, tctx, &domain_handle);
7830 ret &= test_GroupList(b, tctx, sid, &domain_handle);
7831 ret &= test_TestPrivateFunctionsDomain(b, tctx, &domain_handle);
7832 ret &= test_RidToSid(b, tctx, sid, &domain_handle);
7833 ret &= test_GetBootKeyInformation(b, tctx, &domain_handle);
7835 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
7840 if (!ndr_policy_handle_empty(&user_handle) &&
7841 !test_DeleteUser(b, tctx, &user_handle)) {
7845 if (!ndr_policy_handle_empty(&alias_handle) &&
7846 !test_DeleteAlias(b, tctx, &alias_handle)) {
7850 if (!ndr_policy_handle_empty(&group_handle) &&
7851 !test_DeleteDomainGroup(b, tctx, &group_handle)) {
7855 torture_assert(tctx, test_samr_handle_Close(b, tctx, &domain_handle), "Failed to close SAMR domain handle");
7857 torture_assert(tctx, test_Connect(b, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
7858 /* reconnect the main handle */
7861 torture_result(tctx, TORTURE_FAIL, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
7867 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7868 struct torture_samr_context *ctx, const char *domain)
7870 struct samr_LookupDomain r;
7871 struct dom_sid2 *sid = NULL;
7872 struct lsa_String n1;
7873 struct lsa_String n2;
7875 struct dcerpc_binding_handle *b = p->binding_handle;
7877 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
7879 /* check for correct error codes */
7880 r.in.connect_handle = &ctx->handle;
7881 r.in.domain_name = &n2;
7885 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7886 "LookupDomain failed");
7887 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, r.out.result, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
7889 init_lsa_String(&n2, "xxNODOMAINxx");
7891 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7892 "LookupDomain failed");
7893 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, r.out.result, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
7895 r.in.connect_handle = &ctx->handle;
7897 init_lsa_String(&n1, domain);
7898 r.in.domain_name = &n1;
7900 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7901 "LookupDomain failed");
7902 torture_assert_ntstatus_ok(tctx, r.out.result, "LookupDomain");
7904 if (!test_GetDomPwInfo(p, tctx, &n1)) {
7908 if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
7916 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
7917 struct torture_samr_context *ctx)
7919 struct samr_EnumDomains r;
7920 uint32_t resume_handle = 0;
7921 uint32_t num_entries = 0;
7922 struct samr_SamArray *sam = NULL;
7925 struct dcerpc_binding_handle *b = p->binding_handle;
7927 r.in.connect_handle = &ctx->handle;
7928 r.in.resume_handle = &resume_handle;
7929 r.in.buf_size = (uint32_t)-1;
7930 r.out.resume_handle = &resume_handle;
7931 r.out.num_entries = &num_entries;
7934 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
7935 "EnumDomains failed");
7936 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
7942 for (i=0;i<sam->count;i++) {
7943 if (!test_LookupDomain(p, tctx, ctx,
7944 sam->entries[i].name.string)) {
7949 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
7950 "EnumDomains failed");
7951 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
7957 static bool test_Connect(struct dcerpc_binding_handle *b,
7958 struct torture_context *tctx,
7959 struct policy_handle *handle)
7961 struct samr_Connect r;
7962 struct samr_Connect2 r2;
7963 struct samr_Connect3 r3;
7964 struct samr_Connect4 r4;
7965 struct samr_Connect5 r5;
7966 union samr_ConnectInfo info;
7967 struct policy_handle h;
7968 uint32_t level_out = 0;
7969 bool ret = true, got_handle = false;
7971 torture_comment(tctx, "Testing samr_Connect\n");
7973 r.in.system_name = NULL;
7974 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7975 r.out.connect_handle = &h;
7977 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect_r(b, tctx, &r),
7979 if (!NT_STATUS_IS_OK(r.out.result)) {
7980 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(r.out.result));
7987 torture_comment(tctx, "Testing samr_Connect2\n");
7989 r2.in.system_name = NULL;
7990 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7991 r2.out.connect_handle = &h;
7993 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect2_r(b, tctx, &r2),
7995 if (!NT_STATUS_IS_OK(r2.out.result)) {
7996 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(r2.out.result));
8000 test_samr_handle_Close(b, tctx, handle);
8006 torture_comment(tctx, "Testing samr_Connect3\n");
8008 r3.in.system_name = NULL;
8010 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8011 r3.out.connect_handle = &h;
8013 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect3_r(b, tctx, &r3),
8015 if (!NT_STATUS_IS_OK(r3.out.result)) {
8016 torture_result(tctx, TORTURE_FAIL, "Connect3 failed - %s\n", nt_errstr(r3.out.result));
8020 test_samr_handle_Close(b, tctx, handle);
8026 torture_comment(tctx, "Testing samr_Connect4\n");
8028 r4.in.system_name = "";
8029 r4.in.client_version = 0;
8030 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8031 r4.out.connect_handle = &h;
8033 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect4_r(b, tctx, &r4),
8035 if (!NT_STATUS_IS_OK(r4.out.result)) {
8036 torture_result(tctx, TORTURE_FAIL, "Connect4 failed - %s\n", nt_errstr(r4.out.result));
8040 test_samr_handle_Close(b, tctx, handle);
8046 torture_comment(tctx, "Testing samr_Connect5\n");
8048 info.info1.client_version = 0;
8049 info.info1.unknown2 = 0;
8051 r5.in.system_name = "";
8052 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8054 r5.out.level_out = &level_out;
8055 r5.in.info_in = &info;
8056 r5.out.info_out = &info;
8057 r5.out.connect_handle = &h;
8059 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect5_r(b, tctx, &r5),
8061 if (!NT_STATUS_IS_OK(r5.out.result)) {
8062 torture_result(tctx, TORTURE_FAIL, "Connect5 failed - %s\n", nt_errstr(r5.out.result));
8066 test_samr_handle_Close(b, tctx, handle);
8076 static bool test_samr_ValidatePassword(struct torture_context *tctx,
8077 struct dcerpc_pipe *p)
8079 struct samr_ValidatePassword r;
8080 union samr_ValidatePasswordReq req;
8081 union samr_ValidatePasswordRep *repp = NULL;
8083 const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
8085 struct dcerpc_binding_handle *b = p->binding_handle;
8087 torture_comment(tctx, "Testing samr_ValidatePassword\n");
8089 if (p->conn->transport.transport != NCACN_IP_TCP) {
8090 torture_comment(tctx, "samr_ValidatePassword only should succeed over NCACN_IP_TCP!\n");
8094 r.in.level = NetValidatePasswordReset;
8099 req.req3.account.string = "non-existent-account-aklsdji";
8101 for (i=0; passwords[i]; i++) {
8102 req.req3.password.string = passwords[i];
8104 status = dcerpc_samr_ValidatePassword_r(b, tctx, &r);
8105 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
8106 torture_skip(tctx, "ValidatePassword not supported by server\n");
8108 torture_assert_ntstatus_ok(tctx, status,
8109 "samr_ValidatePassword failed");
8110 torture_assert_ntstatus_ok(tctx, r.out.result,
8111 "samr_ValidatePassword failed");
8112 torture_comment(tctx, "Server %s password '%s' with code %i\n",
8113 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
8114 req.req3.password.string, repp->ctr3.status);
8120 bool torture_rpc_samr(struct torture_context *torture)
8123 struct dcerpc_pipe *p;
8125 struct torture_samr_context *ctx;
8126 struct dcerpc_binding_handle *b;
8128 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8129 if (!NT_STATUS_IS_OK(status)) {
8132 b = p->binding_handle;
8134 ctx = talloc_zero(torture, struct torture_samr_context);
8136 ctx->choice = TORTURE_SAMR_OTHER;
8138 ret &= test_Connect(b, torture, &ctx->handle);
8140 if (!torture_setting_bool(torture, "samba3", false)) {
8141 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8144 ret &= test_EnumDomains(p, torture, ctx);
8146 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8148 ret &= test_Shutdown(b, torture, &ctx->handle);
8150 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8156 bool torture_rpc_samr_users(struct torture_context *torture)
8159 struct dcerpc_pipe *p;
8161 struct torture_samr_context *ctx;
8162 struct dcerpc_binding_handle *b;
8164 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8165 if (!NT_STATUS_IS_OK(status)) {
8168 b = p->binding_handle;
8170 ctx = talloc_zero(torture, struct torture_samr_context);
8172 ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
8174 ret &= test_Connect(b, torture, &ctx->handle);
8176 if (!torture_setting_bool(torture, "samba3", false)) {
8177 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8180 ret &= test_EnumDomains(p, torture, ctx);
8182 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8184 ret &= test_Shutdown(b, torture, &ctx->handle);
8186 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8192 bool torture_rpc_samr_passwords(struct torture_context *torture)
8195 struct dcerpc_pipe *p;
8197 struct torture_samr_context *ctx;
8198 struct dcerpc_binding_handle *b;
8200 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8201 if (!NT_STATUS_IS_OK(status)) {
8204 b = p->binding_handle;
8206 ctx = talloc_zero(torture, struct torture_samr_context);
8208 ctx->choice = TORTURE_SAMR_PASSWORDS;
8210 ret &= test_Connect(b, torture, &ctx->handle);
8212 ret &= test_EnumDomains(p, torture, ctx);
8214 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8219 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
8220 struct dcerpc_pipe *p2,
8221 struct cli_credentials *machine_credentials)
8224 struct dcerpc_pipe *p;
8226 struct torture_samr_context *ctx;
8227 struct dcerpc_binding_handle *b;
8229 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8230 if (!NT_STATUS_IS_OK(status)) {
8233 b = p->binding_handle;
8235 ctx = talloc_zero(torture, struct torture_samr_context);
8237 ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
8238 ctx->machine_credentials = machine_credentials;
8240 ret &= test_Connect(b, torture, &ctx->handle);
8242 ret &= test_EnumDomains(p, torture, ctx);
8244 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8249 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
8251 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.pwdlastset");
8252 struct torture_rpc_tcase *tcase;
8254 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8256 TEST_ACCOUNT_NAME_PWD);
8258 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
8259 torture_rpc_samr_pwdlastset);
8264 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
8265 struct dcerpc_pipe *p2,
8266 struct cli_credentials *machine_credentials)
8269 struct dcerpc_pipe *p;
8271 struct torture_samr_context *ctx;
8272 struct dcerpc_binding_handle *b;
8274 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8275 if (!NT_STATUS_IS_OK(status)) {
8278 b = p->binding_handle;
8280 ctx = talloc_zero(torture, struct torture_samr_context);
8282 ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
8283 ctx->machine_credentials = machine_credentials;
8285 ret &= test_Connect(b, torture, &ctx->handle);
8287 ret &= test_EnumDomains(p, torture, ctx);
8289 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8294 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
8296 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.users.privileges");
8297 struct torture_rpc_tcase *tcase;
8299 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8301 TEST_ACCOUNT_NAME_PWD);
8303 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
8304 torture_rpc_samr_users_privileges_delete_user);
8309 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
8310 struct dcerpc_pipe *p2,
8314 struct dcerpc_pipe *p;
8316 struct torture_samr_context *ctx =
8317 talloc_get_type_abort(data, struct torture_samr_context);
8318 struct dcerpc_binding_handle *b;
8320 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8321 if (!NT_STATUS_IS_OK(status)) {
8324 b = p->binding_handle;
8326 ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
8327 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8328 ctx->num_objects_large_dc);
8330 ret &= test_Connect(b, torture, &ctx->handle);
8332 ret &= test_EnumDomains(p, torture, ctx);
8334 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8339 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
8340 struct dcerpc_pipe *p2,
8344 struct dcerpc_pipe *p;
8346 struct torture_samr_context *ctx =
8347 talloc_get_type_abort(data, struct torture_samr_context);
8348 struct dcerpc_binding_handle *b;
8350 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8351 if (!NT_STATUS_IS_OK(status)) {
8354 b = p->binding_handle;
8356 ctx->choice = TORTURE_SAMR_MANY_GROUPS;
8357 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8358 ctx->num_objects_large_dc);
8360 ret &= test_Connect(b, torture, &ctx->handle);
8362 ret &= test_EnumDomains(p, torture, ctx);
8364 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8369 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
8370 struct dcerpc_pipe *p2,
8374 struct dcerpc_pipe *p;
8376 struct torture_samr_context *ctx =
8377 talloc_get_type_abort(data, struct torture_samr_context);
8378 struct dcerpc_binding_handle *b;
8380 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8381 if (!NT_STATUS_IS_OK(status)) {
8384 b = p->binding_handle;
8386 ctx->choice = TORTURE_SAMR_MANY_ALIASES;
8387 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8388 ctx->num_objects_large_dc);
8390 ret &= test_Connect(b, torture, &ctx->handle);
8392 ret &= test_EnumDomains(p, torture, ctx);
8394 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8399 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
8401 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.large-dc");
8402 struct torture_rpc_tcase *tcase;
8403 struct torture_samr_context *ctx;
8405 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
8407 ctx = talloc_zero(suite, struct torture_samr_context);
8408 ctx->num_objects_large_dc = 150;
8410 torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
8411 torture_rpc_samr_many_aliases, ctx);
8412 torture_rpc_tcase_add_test_ex(tcase, "many_groups",
8413 torture_rpc_samr_many_groups, ctx);
8414 torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
8415 torture_rpc_samr_many_accounts, ctx);
8420 static bool torture_rpc_samr_badpwdcount(struct torture_context *torture,
8421 struct dcerpc_pipe *p2,
8422 struct cli_credentials *machine_credentials)
8425 struct dcerpc_pipe *p;
8427 struct torture_samr_context *ctx;
8428 struct dcerpc_binding_handle *b;
8430 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8431 if (!NT_STATUS_IS_OK(status)) {
8434 b = p->binding_handle;
8436 ctx = talloc_zero(torture, struct torture_samr_context);
8438 ctx->choice = TORTURE_SAMR_PASSWORDS_BADPWDCOUNT;
8439 ctx->machine_credentials = machine_credentials;
8441 ret &= test_Connect(b, torture, &ctx->handle);
8443 ret &= test_EnumDomains(p, torture, ctx);
8445 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8450 struct torture_suite *torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX *mem_ctx)
8452 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.badpwdcount");
8453 struct torture_rpc_tcase *tcase;
8455 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8457 TEST_ACCOUNT_NAME_PWD);
8459 torture_rpc_tcase_add_test_creds(tcase, "badPwdCount",
8460 torture_rpc_samr_badpwdcount);
8465 static bool torture_rpc_samr_lockout(struct torture_context *torture,
8466 struct dcerpc_pipe *p2,
8467 struct cli_credentials *machine_credentials)
8470 struct dcerpc_pipe *p;
8472 struct torture_samr_context *ctx;
8473 struct dcerpc_binding_handle *b;
8475 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8476 if (!NT_STATUS_IS_OK(status)) {
8479 b = p->binding_handle;
8481 ctx = talloc_zero(torture, struct torture_samr_context);
8483 ctx->choice = TORTURE_SAMR_PASSWORDS_LOCKOUT;
8484 ctx->machine_credentials = machine_credentials;
8486 ret &= test_Connect(b, torture, &ctx->handle);
8488 ret &= test_EnumDomains(p, torture, ctx);
8490 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8495 struct torture_suite *torture_rpc_samr_passwords_lockout(TALLOC_CTX *mem_ctx)
8497 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.lockout");
8498 struct torture_rpc_tcase *tcase;
8500 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8502 TEST_ACCOUNT_NAME_PWD);
8504 torture_rpc_tcase_add_test_creds(tcase, "lockout",
8505 torture_rpc_samr_lockout);
8510 struct torture_suite *torture_rpc_samr_passwords_validate(TALLOC_CTX *mem_ctx)
8512 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.validate");
8513 struct torture_rpc_tcase *tcase;
8515 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr",
8517 torture_rpc_tcase_add_test(tcase, "validate",
8518 test_samr_ValidatePassword);