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_comment(tctx, #call " level %u failed - %s (%s)\n", \
247 r.in.level, nt_errstr(r.out.result), __location__); \
252 #define STRING_EQUAL(s1, s2, field) \
253 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
254 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
255 #field, s2, __location__); \
260 #define MEM_EQUAL(s1, s2, length, field) \
261 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
262 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
263 #field, (const char *)s2, __location__); \
268 #define INT_EQUAL(i1, i2, field) \
270 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
271 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
276 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
277 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
279 TESTCALL(QueryUserInfo, q) \
281 s2.in.level = lvl1; \
284 ZERO_STRUCT(u.info21); \
285 u.info21.fields_present = fpval; \
287 init_lsa_String(&u.info ## lvl1.field1, value); \
288 TESTCALL(SetUserInfo, s) \
289 TESTCALL(SetUserInfo2, s2) \
290 init_lsa_String(&u.info ## lvl1.field1, ""); \
291 TESTCALL(QueryUserInfo, q); \
293 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
295 TESTCALL(QueryUserInfo, q) \
297 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
300 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
301 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
303 TESTCALL(QueryUserInfo, q) \
305 s2.in.level = lvl1; \
308 ZERO_STRUCT(u.info21); \
309 u.info21.fields_present = fpval; \
311 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
312 TESTCALL(SetUserInfo, s) \
313 TESTCALL(SetUserInfo2, s2) \
314 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
315 TESTCALL(QueryUserInfo, q); \
317 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
319 TESTCALL(QueryUserInfo, q) \
321 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
324 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
325 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
327 TESTCALL(QueryUserInfo, q) \
329 s2.in.level = lvl1; \
332 uint8_t *bits = u.info21.logon_hours.bits; \
333 ZERO_STRUCT(u.info21); \
334 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
335 u.info21.logon_hours.units_per_week = 168; \
336 u.info21.logon_hours.bits = bits; \
338 u.info21.fields_present = fpval; \
340 u.info ## lvl1.field1 = value; \
341 TESTCALL(SetUserInfo, s) \
342 TESTCALL(SetUserInfo2, s2) \
343 u.info ## lvl1.field1 = 0; \
344 TESTCALL(QueryUserInfo, q); \
346 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
348 TESTCALL(QueryUserInfo, q) \
350 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
353 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
354 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
358 do { TESTCALL(QueryUserInfo, q0) } while (0);
360 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
361 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
362 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
365 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
366 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
367 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
368 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
369 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
370 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
371 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
372 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
373 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
374 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
375 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
376 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
377 test_account_name = base_account_name;
378 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
379 SAMR_FIELD_ACCOUNT_NAME);
381 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
382 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
383 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
384 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
385 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
386 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
387 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
388 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
389 SAMR_FIELD_FULL_NAME);
391 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
392 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
393 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
394 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
395 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
396 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
397 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
398 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
399 SAMR_FIELD_FULL_NAME);
401 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
402 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
403 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
404 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
405 SAMR_FIELD_LOGON_SCRIPT);
407 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
408 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
409 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
410 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
411 SAMR_FIELD_PROFILE_PATH);
413 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
414 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
415 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
416 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
417 SAMR_FIELD_HOME_DIRECTORY);
418 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
419 SAMR_FIELD_HOME_DIRECTORY);
421 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
422 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
423 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
424 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
425 SAMR_FIELD_HOME_DRIVE);
426 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
427 SAMR_FIELD_HOME_DRIVE);
429 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
430 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
431 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
432 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
433 SAMR_FIELD_DESCRIPTION);
435 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
436 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
437 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
438 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
439 SAMR_FIELD_WORKSTATIONS);
440 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
441 SAMR_FIELD_WORKSTATIONS);
442 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
443 SAMR_FIELD_WORKSTATIONS);
444 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
445 SAMR_FIELD_WORKSTATIONS);
447 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
448 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
449 SAMR_FIELD_PARAMETERS);
450 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
451 SAMR_FIELD_PARAMETERS);
452 /* also empty user parameters are allowed */
453 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
454 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
455 SAMR_FIELD_PARAMETERS);
456 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
457 SAMR_FIELD_PARAMETERS);
459 /* Samba 3 cannot store country_code and 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_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
657 s.in.level, nt_errstr(status));
661 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
663 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
665 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
666 "SetUserInfo failed");
667 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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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_warning(tctx, "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 *handle,
4059 uint32_t *acct_flags)
4061 union samr_UserInfo *info;
4062 struct samr_QueryUserInfo r;
4064 r.in.user_handle = handle;
4068 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4070 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4071 "failed to query userinfo");
4072 torture_assert_ntstatus_ok(tctx, r.out.result,
4073 "failed to query userinfo");
4075 *acct_flags = info->info16.acct_flags;
4077 torture_comment(tctx, " (acct_flags: 0x%08x)\n", *acct_flags);
4082 static bool test_Password_lockout(struct dcerpc_pipe *p,
4083 struct dcerpc_pipe *np,
4084 struct torture_context *tctx,
4085 uint32_t acct_flags,
4086 const char *acct_name,
4087 struct policy_handle *domain_handle,
4088 struct policy_handle *user_handle,
4090 struct cli_credentials *machine_credentials,
4091 const char *comment,
4094 NTSTATUS expected_success_status,
4095 struct samr_DomInfo1 *info1,
4096 struct samr_DomInfo12 *info12)
4098 union samr_DomainInfo info;
4099 uint32_t badpwdcount;
4100 uint32_t password_history_length = 1;
4101 uint64_t lockout_threshold = 1;
4102 uint32_t lockout_seconds = 5;
4103 uint64_t delta_time_factor = 10 * 1000 * 1000;
4104 struct dcerpc_binding_handle *b = p->binding_handle;
4106 torture_comment(tctx, "\nTesting account lockout: %s\n", comment);
4110 info.info1 = *info1;
4112 torture_comment(tctx, "setting password history length.\n");
4113 info.info1.password_history_length = password_history_length;
4115 torture_assert(tctx,
4116 test_SetDomainInfo(b, tctx, domain_handle,
4117 DomainPasswordInformation, &info),
4118 "failed to set password history length");
4120 info.info12 = *info12;
4121 info.info12.lockout_threshold = lockout_threshold;
4123 /* set lockout duration < lockout window: should fail */
4124 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4125 info.info12.lockout_window = ~((lockout_seconds + 1) * delta_time_factor);
4127 torture_assert(tctx,
4128 test_SetDomainInfo_ntstatus(b, tctx, domain_handle,
4129 DomainLockoutInformation, &info,
4130 NT_STATUS_INVALID_PARAMETER),
4131 "setting lockout duration < lockout window gave unexpected result");
4133 info.info12.lockout_duration = 0;
4134 info.info12.lockout_window = 0;
4136 torture_assert(tctx,
4137 test_SetDomainInfo(b, tctx, domain_handle,
4138 DomainLockoutInformation, &info),
4139 "failed to set lockout window and duration to 0");
4142 /* set lockout duration of 5 seconds */
4143 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4144 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
4146 torture_assert(tctx,
4147 test_SetDomainInfo(b, tctx, domain_handle,
4148 DomainLockoutInformation, &info),
4149 "failed to set lockout window and duration to 5 seconds");
4151 /* reset bad pwd count */
4153 torture_assert(tctx,
4154 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
4157 /* enable or disable account */
4160 torture_assert(tctx,
4161 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4162 acct_flags | ACB_DISABLED),
4163 "failed to disable user");
4165 torture_assert(tctx,
4166 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4167 acct_flags & ~ACB_DISABLED),
4168 "failed to enable user");
4172 /* test logon with right password */
4174 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4175 acct_name, *password,
4176 expected_success_status, interactive)) {
4177 torture_fail(tctx, "failed to auth with latest password");
4180 torture_assert(tctx,
4181 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4182 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
4185 /* test with wrong password ==> lockout */
4187 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4188 acct_name, "random_crap",
4189 NT_STATUS_WRONG_PASSWORD, interactive)) {
4190 torture_fail(tctx, "succeeded to authenticate with wrong password");
4193 torture_assert(tctx,
4194 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4195 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4197 torture_assert(tctx,
4198 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4199 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4200 "expected account to be locked");
4203 /* test with good password */
4205 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4207 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4209 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4212 /* bad pwd count should not get updated */
4213 torture_assert(tctx,
4214 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4215 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4217 /* curiously, windows does _not_ set the autlock flag */
4218 torture_assert(tctx,
4219 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4220 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4221 "expected account to be locked");
4224 /* with bad password */
4226 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4227 acct_name, "random_crap2",
4228 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4230 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4233 /* bad pwd count should not get updated */
4234 torture_assert(tctx,
4235 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4236 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4238 /* curiously, windows does _not_ set the autlock flag */
4239 torture_assert(tctx,
4240 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4241 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4242 "expected account to be locked");
4245 /* let lockout duration expire ==> unlock */
4247 torture_comment(tctx, "let lockout duration expire...\n");
4248 sleep(lockout_seconds + 1);
4250 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4252 expected_success_status, interactive))
4254 torture_fail(tctx, "failed to authenticate after lockout expired");
4257 torture_assert(tctx,
4258 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4259 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4260 "expected account not to be locked");
4265 static bool test_Password_lockout_wrap(struct dcerpc_pipe *p,
4266 struct torture_context *tctx,
4267 uint32_t acct_flags,
4268 const char *acct_name,
4269 struct policy_handle *domain_handle,
4270 struct policy_handle *user_handle,
4272 struct cli_credentials *machine_credentials)
4274 union samr_DomainInfo *q_info, s_info;
4275 struct samr_DomInfo1 info1, _info1;
4276 struct samr_DomInfo12 info12, _info12;
4278 struct dcerpc_binding_handle *b = p->binding_handle;
4279 struct dcerpc_pipe *np;
4283 const char *comment;
4286 NTSTATUS expected_success_status;
4289 .comment = "network logon (disabled account)",
4291 .interactive = false,
4292 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4295 .comment = "network logon (enabled account)",
4297 .interactive = false,
4298 .expected_success_status= NT_STATUS_OK
4301 .comment = "interactive logon (disabled account)",
4303 .interactive = true,
4304 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4307 .comment = "interactive logon (enabled account)",
4309 .interactive = true,
4310 .expected_success_status= NT_STATUS_OK
4314 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4316 /* backup old policies */
4318 torture_assert(tctx,
4319 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4320 DomainPasswordInformation, &q_info),
4321 "failed to query domain info level 1");
4323 info1 = q_info->info1;
4326 torture_assert(tctx,
4327 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4328 DomainLockoutInformation, &q_info),
4329 "failed to query domain info level 12");
4331 info12 = q_info->info12;
4336 for (i=0; i < ARRAY_SIZE(creds); i++) {
4338 /* skip trust tests for now */
4339 if (acct_flags & ACB_WSTRUST ||
4340 acct_flags & ACB_SVRTRUST ||
4341 acct_flags & ACB_DOMTRUST) {
4345 ret &= test_Password_lockout(p, np, tctx, acct_flags, acct_name,
4346 domain_handle, user_handle, password,
4347 machine_credentials,
4350 creds[i].interactive,
4351 creds[i].expected_success_status,
4354 torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
4356 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4360 /* restore policies */
4362 s_info.info1 = info1;
4364 torture_assert(tctx,
4365 test_SetDomainInfo(b, tctx, domain_handle,
4366 DomainPasswordInformation, &s_info),
4367 "failed to set password information");
4369 s_info.info12 = info12;
4371 torture_assert(tctx,
4372 test_SetDomainInfo(b, tctx, domain_handle,
4373 DomainLockoutInformation, &s_info),
4374 "failed to set lockout information");
4379 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
4380 struct dcerpc_pipe *lp,
4381 struct torture_context *tctx,
4382 struct policy_handle *domain_handle,
4383 struct policy_handle *lsa_handle,
4384 struct policy_handle *user_handle,
4385 const struct dom_sid *domain_sid,
4387 struct cli_credentials *machine_credentials)
4390 struct dcerpc_binding_handle *b = p->binding_handle;
4391 struct dcerpc_binding_handle *lb = lp->binding_handle;
4393 struct policy_handle lsa_acct_handle;
4394 struct dom_sid *user_sid;
4396 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
4399 struct lsa_EnumAccountRights r;
4400 struct lsa_RightSet rights;
4402 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4404 r.in.handle = lsa_handle;
4405 r.in.sid = user_sid;
4406 r.out.rights = &rights;
4408 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4409 "lsa_EnumAccountRights failed");
4410 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4411 "Expected enum rights for account to fail");
4415 struct lsa_RightSet rights;
4416 struct lsa_StringLarge names[2];
4417 struct lsa_AddAccountRights r;
4419 torture_comment(tctx, "Testing LSA AddAccountRights\n");
4421 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
4422 init_lsa_StringLarge(&names[1], NULL);
4425 rights.names = names;
4427 r.in.handle = lsa_handle;
4428 r.in.sid = user_sid;
4429 r.in.rights = &rights;
4431 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
4432 "lsa_AddAccountRights failed");
4433 torture_assert_ntstatus_ok(tctx, r.out.result,
4434 "Failed to add privileges");
4438 struct lsa_EnumAccounts r;
4439 uint32_t resume_handle = 0;
4440 struct lsa_SidArray lsa_sid_array;
4442 bool found_sid = false;
4444 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4446 r.in.handle = lsa_handle;
4447 r.in.num_entries = 0x1000;
4448 r.in.resume_handle = &resume_handle;
4449 r.out.sids = &lsa_sid_array;
4450 r.out.resume_handle = &resume_handle;
4452 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4453 "lsa_EnumAccounts failed");
4454 torture_assert_ntstatus_ok(tctx, r.out.result,
4455 "Failed to enum accounts");
4457 for (i=0; i < lsa_sid_array.num_sids; i++) {
4458 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4463 torture_assert(tctx, found_sid,
4464 "failed to list privileged account");
4468 struct lsa_EnumAccountRights r;
4469 struct lsa_RightSet user_rights;
4471 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4473 r.in.handle = lsa_handle;
4474 r.in.sid = user_sid;
4475 r.out.rights = &user_rights;
4477 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4478 "lsa_EnumAccountRights failed");
4479 torture_assert_ntstatus_ok(tctx, r.out.result,
4480 "Failed to enum rights for account");
4482 if (user_rights.count < 1) {
4483 torture_warning(tctx, "failed to find newly added rights");
4489 struct lsa_OpenAccount r;
4491 torture_comment(tctx, "Testing LSA OpenAccount\n");
4493 r.in.handle = lsa_handle;
4494 r.in.sid = user_sid;
4495 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4496 r.out.acct_handle = &lsa_acct_handle;
4498 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4499 "lsa_OpenAccount failed");
4500 torture_assert_ntstatus_ok(tctx, r.out.result,
4501 "Failed to open lsa account");
4505 struct lsa_GetSystemAccessAccount r;
4506 uint32_t access_mask;
4508 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4510 r.in.handle = &lsa_acct_handle;
4511 r.out.access_mask = &access_mask;
4513 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4514 "lsa_GetSystemAccessAccount failed");
4515 torture_assert_ntstatus_ok(tctx, r.out.result,
4516 "Failed to get lsa system access account");
4522 torture_comment(tctx, "Testing LSA Close\n");
4524 r.in.handle = &lsa_acct_handle;
4525 r.out.handle = &lsa_acct_handle;
4527 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(lb, tctx, &r),
4528 "lsa_Close failed");
4529 torture_assert_ntstatus_ok(tctx, r.out.result,
4530 "Failed to close lsa");
4534 struct samr_DeleteUser r;
4536 torture_comment(tctx, "Testing SAMR DeleteUser\n");
4538 r.in.user_handle = user_handle;
4539 r.out.user_handle = user_handle;
4541 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &r),
4542 "DeleteUser failed");
4543 torture_assert_ntstatus_ok(tctx, r.out.result,
4544 "DeleteUser failed");
4548 struct lsa_EnumAccounts r;
4549 uint32_t resume_handle = 0;
4550 struct lsa_SidArray lsa_sid_array;
4552 bool found_sid = false;
4554 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4556 r.in.handle = lsa_handle;
4557 r.in.num_entries = 0x1000;
4558 r.in.resume_handle = &resume_handle;
4559 r.out.sids = &lsa_sid_array;
4560 r.out.resume_handle = &resume_handle;
4562 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4563 "lsa_EnumAccounts failed");
4564 torture_assert_ntstatus_ok(tctx, r.out.result,
4565 "Failed to enum accounts");
4567 for (i=0; i < lsa_sid_array.num_sids; i++) {
4568 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4573 torture_assert(tctx, found_sid,
4574 "failed to list privileged account");
4578 struct lsa_EnumAccountRights r;
4579 struct lsa_RightSet user_rights;
4581 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4583 r.in.handle = lsa_handle;
4584 r.in.sid = user_sid;
4585 r.out.rights = &user_rights;
4587 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4588 "lsa_EnumAccountRights failed");
4589 torture_assert_ntstatus_ok(tctx, r.out.result,
4590 "Failed to enum rights for account");
4592 if (user_rights.count < 1) {
4593 torture_warning(tctx, "failed to find newly added rights");
4599 struct lsa_OpenAccount r;
4601 torture_comment(tctx, "Testing LSA OpenAccount\n");
4603 r.in.handle = lsa_handle;
4604 r.in.sid = user_sid;
4605 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4606 r.out.acct_handle = &lsa_acct_handle;
4608 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4609 "lsa_OpenAccount failed");
4610 torture_assert_ntstatus_ok(tctx, r.out.result,
4611 "Failed to open lsa account");
4615 struct lsa_GetSystemAccessAccount r;
4616 uint32_t access_mask;
4618 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4620 r.in.handle = &lsa_acct_handle;
4621 r.out.access_mask = &access_mask;
4623 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4624 "lsa_GetSystemAccessAccount failed");
4625 torture_assert_ntstatus_ok(tctx, r.out.result,
4626 "Failed to get lsa system access account");
4630 struct lsa_DeleteObject r;
4632 torture_comment(tctx, "Testing LSA DeleteObject\n");
4634 r.in.handle = &lsa_acct_handle;
4635 r.out.handle = &lsa_acct_handle;
4637 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(lb, tctx, &r),
4638 "lsa_DeleteObject failed");
4639 torture_assert_ntstatus_ok(tctx, r.out.result,
4640 "Failed to delete object");
4644 struct lsa_EnumAccounts r;
4645 uint32_t resume_handle = 0;
4646 struct lsa_SidArray lsa_sid_array;
4648 bool found_sid = false;
4650 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4652 r.in.handle = lsa_handle;
4653 r.in.num_entries = 0x1000;
4654 r.in.resume_handle = &resume_handle;
4655 r.out.sids = &lsa_sid_array;
4656 r.out.resume_handle = &resume_handle;
4658 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4659 "lsa_EnumAccounts failed");
4660 torture_assert_ntstatus_ok(tctx, r.out.result,
4661 "Failed to enum accounts");
4663 for (i=0; i < lsa_sid_array.num_sids; i++) {
4664 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4669 torture_assert(tctx, !found_sid,
4670 "should not have listed privileged account");
4674 struct lsa_EnumAccountRights r;
4675 struct lsa_RightSet user_rights;
4677 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4679 r.in.handle = lsa_handle;
4680 r.in.sid = user_sid;
4681 r.out.rights = &user_rights;
4683 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4684 "lsa_EnumAccountRights failed");
4685 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4686 "Failed to enum rights for account");
4692 static bool test_user_ops(struct dcerpc_pipe *p,
4693 struct torture_context *tctx,
4694 struct policy_handle *user_handle,
4695 struct policy_handle *domain_handle,
4696 const struct dom_sid *domain_sid,
4697 uint32_t base_acct_flags,
4698 const char *base_acct_name, enum torture_samr_choice which_ops,
4699 struct cli_credentials *machine_credentials)
4701 char *password = NULL;
4702 struct samr_QueryUserInfo q;
4703 union samr_UserInfo *info;
4705 struct dcerpc_binding_handle *b = p->binding_handle;
4710 const uint32_t password_fields[] = {
4711 SAMR_FIELD_NT_PASSWORD_PRESENT,
4712 SAMR_FIELD_LM_PASSWORD_PRESENT,
4713 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
4717 status = test_LookupName(b, tctx, domain_handle, base_acct_name, &rid);
4718 if (!NT_STATUS_IS_OK(status)) {
4722 switch (which_ops) {
4723 case TORTURE_SAMR_USER_ATTRIBUTES:
4724 if (!test_QuerySecurity(b, tctx, user_handle)) {
4728 if (!test_QueryUserInfo(b, tctx, user_handle)) {
4732 if (!test_QueryUserInfo2(b, tctx, user_handle)) {
4736 if (!test_SetUserInfo(b, tctx, user_handle, base_acct_flags,
4741 if (!test_GetUserPwInfo(b, tctx, user_handle)) {
4745 if (!test_TestPrivateFunctionsUser(b, tctx, user_handle)) {
4749 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
4753 case TORTURE_SAMR_PASSWORDS:
4754 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
4755 char simple_pass[9];
4756 char *v = generate_random_str(tctx, 1);
4758 ZERO_STRUCT(simple_pass);
4759 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4761 torture_comment(tctx, "Testing machine account password policy rules\n");
4763 /* Workstation trust accounts don't seem to need to honour password quality policy */
4764 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4768 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
4772 /* reset again, to allow another 'user' password change */
4773 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4777 /* Try a 'short' password */
4778 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
4782 /* Try a compleatly random password */
4783 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
4788 for (i = 0; password_fields[i]; i++) {
4789 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
4793 /* check it was set right */
4794 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4799 for (i = 0; password_fields[i]; i++) {
4800 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
4804 /* check it was set right */
4805 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4810 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
4814 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
4818 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
4822 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4826 for (i = 0; password_fields[i]; i++) {
4828 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
4829 /* we need to skip as that would break
4830 * the ChangePasswordUser3 verify */
4834 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
4838 /* check it was set right */
4839 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4844 q.in.user_handle = user_handle;
4848 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
4849 "QueryUserInfo failed");
4850 if (!NT_STATUS_IS_OK(q.out.result)) {
4851 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4852 q.in.level, nt_errstr(q.out.result));
4855 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4856 if ((info->info5.acct_flags) != expected_flags) {
4857 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4858 info->info5.acct_flags,
4861 if (!torture_setting_bool(tctx, "samba3", false)) {
4865 if (info->info5.rid != rid) {
4866 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
4867 info->info5.rid, rid);
4874 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
4876 /* test last password change timestamp behaviour */
4877 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
4879 user_handle, &password,
4880 machine_credentials)) {
4885 torture_comment(tctx, "pwdLastSet test succeeded\n");
4887 torture_warning(tctx, "pwdLastSet test failed\n");
4892 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
4894 /* test bad pwd count change behaviour */
4895 if (!test_Password_badpwdcount_wrap(p, tctx, base_acct_flags,
4898 user_handle, &password,
4899 machine_credentials)) {
4904 torture_comment(tctx, "badPwdCount test succeeded\n");
4906 torture_warning(tctx, "badPwdCount test failed\n");
4911 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
4913 if (!test_Password_lockout_wrap(p, tctx, base_acct_flags,
4916 user_handle, &password,
4917 machine_credentials))
4923 torture_comment(tctx, "lockout test succeeded\n");
4925 torture_warning(tctx, "lockout test failed\n");
4931 case TORTURE_SAMR_USER_PRIVILEGES: {
4933 struct dcerpc_pipe *lp;
4934 struct policy_handle *lsa_handle;
4935 struct dcerpc_binding_handle *lb;
4937 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
4938 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
4939 lb = lp->binding_handle;
4941 if (!test_lsa_OpenPolicy2(lb, tctx, &lsa_handle)) {
4945 if (!test_DeleteUser_with_privs(p, lp, tctx,
4946 domain_handle, lsa_handle, user_handle,
4948 machine_credentials)) {
4952 if (!test_lsa_Close(lb, tctx, lsa_handle)) {
4957 torture_warning(tctx, "privileged user delete test failed\n");
4962 case TORTURE_SAMR_OTHER:
4963 case TORTURE_SAMR_MANY_ACCOUNTS:
4964 case TORTURE_SAMR_MANY_GROUPS:
4965 case TORTURE_SAMR_MANY_ALIASES:
4966 /* We just need the account to exist */
4972 static bool test_alias_ops(struct dcerpc_binding_handle *b,
4973 struct torture_context *tctx,
4974 struct policy_handle *alias_handle,
4975 const struct dom_sid *domain_sid)
4979 if (!torture_setting_bool(tctx, "samba3", false)) {
4980 if (!test_QuerySecurity(b, tctx, alias_handle)) {
4985 if (!test_QueryAliasInfo(b, tctx, alias_handle)) {
4989 if (!test_SetAliasInfo(b, tctx, alias_handle)) {
4993 if (!test_AddMemberToAlias(b, tctx, alias_handle, domain_sid)) {
4997 if (torture_setting_bool(tctx, "samba3", false) ||
4998 torture_setting_bool(tctx, "samba4", false)) {
4999 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
5003 if (!test_AddMultipleMembersToAlias(b, tctx, alias_handle)) {
5011 static bool test_DeleteUser(struct dcerpc_binding_handle *b,
5012 struct torture_context *tctx,
5013 struct policy_handle *user_handle)
5015 struct samr_DeleteUser d;
5016 torture_comment(tctx, "Testing DeleteUser\n");
5018 d.in.user_handle = user_handle;
5019 d.out.user_handle = user_handle;
5021 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
5022 "DeleteUser failed");
5023 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteUser");
5028 bool test_DeleteUser_byname(struct dcerpc_binding_handle *b,
5029 struct torture_context *tctx,
5030 struct policy_handle *handle, const char *name)
5033 struct samr_DeleteUser d;
5034 struct policy_handle user_handle;
5037 status = test_LookupName(b, tctx, handle, name, &rid);
5038 if (!NT_STATUS_IS_OK(status)) {
5042 status = test_OpenUser_byname(b, tctx, handle, name, &user_handle);
5043 if (!NT_STATUS_IS_OK(status)) {
5047 d.in.user_handle = &user_handle;
5048 d.out.user_handle = &user_handle;
5049 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
5050 "DeleteUser failed");
5051 if (!NT_STATUS_IS_OK(d.out.result)) {
5052 status = d.out.result;
5059 torture_warning(tctx, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
5064 static bool test_DeleteGroup_byname(struct dcerpc_binding_handle *b,
5065 struct torture_context *tctx,
5066 struct policy_handle *handle, const char *name)
5069 struct samr_OpenGroup r;
5070 struct samr_DeleteDomainGroup d;
5071 struct policy_handle group_handle;
5074 status = test_LookupName(b, tctx, handle, name, &rid);
5075 if (!NT_STATUS_IS_OK(status)) {
5079 r.in.domain_handle = handle;
5080 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5082 r.out.group_handle = &group_handle;
5083 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
5084 "OpenGroup failed");
5085 if (!NT_STATUS_IS_OK(r.out.result)) {
5086 status = r.out.result;
5090 d.in.group_handle = &group_handle;
5091 d.out.group_handle = &group_handle;
5092 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
5093 "DeleteDomainGroup failed");
5094 if (!NT_STATUS_IS_OK(d.out.result)) {
5095 status = d.out.result;
5102 torture_warning(tctx, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
5107 static bool test_DeleteAlias_byname(struct dcerpc_binding_handle *b,
5108 struct torture_context *tctx,
5109 struct policy_handle *domain_handle,
5113 struct samr_OpenAlias r;
5114 struct samr_DeleteDomAlias d;
5115 struct policy_handle alias_handle;
5118 torture_comment(tctx, "Testing DeleteAlias_byname\n");
5120 status = test_LookupName(b, tctx, domain_handle, name, &rid);
5121 if (!NT_STATUS_IS_OK(status)) {
5125 r.in.domain_handle = domain_handle;
5126 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5128 r.out.alias_handle = &alias_handle;
5129 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5130 "OpenAlias failed");
5131 if (!NT_STATUS_IS_OK(r.out.result)) {
5132 status = r.out.result;
5136 d.in.alias_handle = &alias_handle;
5137 d.out.alias_handle = &alias_handle;
5138 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5139 "DeleteDomAlias failed");
5140 if (!NT_STATUS_IS_OK(d.out.result)) {
5141 status = d.out.result;
5148 torture_warning(tctx, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
5152 static bool test_DeleteAlias(struct dcerpc_binding_handle *b,
5153 struct torture_context *tctx,
5154 struct policy_handle *alias_handle)
5156 struct samr_DeleteDomAlias d;
5159 torture_comment(tctx, "Testing DeleteAlias\n");
5161 d.in.alias_handle = alias_handle;
5162 d.out.alias_handle = alias_handle;
5164 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5165 "DeleteDomAlias failed");
5166 if (!NT_STATUS_IS_OK(d.out.result)) {
5167 torture_warning(tctx, "DeleteAlias failed - %s\n", nt_errstr(d.out.result));
5174 static bool test_CreateAlias(struct dcerpc_binding_handle *b,
5175 struct torture_context *tctx,
5176 struct policy_handle *domain_handle,
5177 const char *alias_name,
5178 struct policy_handle *alias_handle,
5179 const struct dom_sid *domain_sid,
5182 struct samr_CreateDomAlias r;
5183 struct lsa_String name;
5187 init_lsa_String(&name, alias_name);
5188 r.in.domain_handle = domain_handle;
5189 r.in.alias_name = &name;
5190 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5191 r.out.alias_handle = alias_handle;
5194 torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
5196 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5197 "CreateDomAlias failed");
5199 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5200 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
5201 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
5204 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
5205 nt_errstr(r.out.result));
5210 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ALIAS_EXISTS)) {
5211 if (!test_DeleteAlias_byname(b, tctx, domain_handle, r.in.alias_name->string)) {
5214 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5215 "CreateDomAlias failed");
5218 if (!NT_STATUS_IS_OK(r.out.result)) {
5219 torture_warning(tctx, "CreateAlias failed - %s\n", nt_errstr(r.out.result));
5227 if (!test_alias_ops(b, tctx, alias_handle, domain_sid)) {
5234 static bool test_ChangePassword(struct dcerpc_pipe *p,
5235 struct torture_context *tctx,
5236 const char *acct_name,
5237 struct policy_handle *domain_handle, char **password)
5240 struct dcerpc_binding_handle *b = p->binding_handle;
5246 if (!test_ChangePasswordUser(b, tctx, acct_name, domain_handle, password)) {
5250 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
5254 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
5258 /* test what happens when setting the old password again */
5259 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
5264 char simple_pass[9];
5265 char *v = generate_random_str(tctx, 1);
5267 ZERO_STRUCT(simple_pass);
5268 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5270 /* test what happens when picking a simple password */
5271 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
5276 /* set samr_SetDomainInfo level 1 with min_length 5 */
5278 struct samr_QueryDomainInfo r;
5279 union samr_DomainInfo *info = NULL;
5280 struct samr_SetDomainInfo s;
5281 uint16_t len_old, len;
5282 uint32_t pwd_prop_old;
5283 int64_t min_pwd_age_old;
5287 r.in.domain_handle = domain_handle;
5291 torture_comment(tctx, "Testing samr_QueryDomainInfo level 1\n");
5292 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
5293 "QueryDomainInfo failed");
5294 if (!NT_STATUS_IS_OK(r.out.result)) {
5298 s.in.domain_handle = domain_handle;
5302 /* remember the old min length, so we can reset it */
5303 len_old = s.in.info->info1.min_password_length;
5304 s.in.info->info1.min_password_length = len;
5305 pwd_prop_old = s.in.info->info1.password_properties;
5306 /* turn off password complexity checks for this test */
5307 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
5309 min_pwd_age_old = s.in.info->info1.min_password_age;
5310 s.in.info->info1.min_password_age = 0;
5312 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5313 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5314 "SetDomainInfo failed");
5315 if (!NT_STATUS_IS_OK(s.out.result)) {
5319 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
5321 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
5325 s.in.info->info1.min_password_length = len_old;
5326 s.in.info->info1.password_properties = pwd_prop_old;
5327 s.in.info->info1.min_password_age = min_pwd_age_old;
5329 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5330 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5331 "SetDomainInfo failed");
5332 if (!NT_STATUS_IS_OK(s.out.result)) {
5339 struct samr_OpenUser r;
5340 struct samr_QueryUserInfo q;
5341 union samr_UserInfo *info;
5342 struct samr_LookupNames n;
5343 struct policy_handle user_handle;
5344 struct samr_Ids rids, types;
5346 n.in.domain_handle = domain_handle;
5348 n.in.names = talloc_array(tctx, struct lsa_String, 1);
5349 n.in.names[0].string = acct_name;
5351 n.out.types = &types;
5353 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
5354 "LookupNames failed");
5355 if (!NT_STATUS_IS_OK(n.out.result)) {
5356 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(n.out.result));
5360 r.in.domain_handle = domain_handle;
5361 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5362 r.in.rid = n.out.rids->ids[0];
5363 r.out.user_handle = &user_handle;
5365 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5367 if (!NT_STATUS_IS_OK(r.out.result)) {
5368 torture_warning(tctx, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(r.out.result));
5372 q.in.user_handle = &user_handle;
5376 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5377 "QueryUserInfo failed");
5378 if (!NT_STATUS_IS_OK(q.out.result)) {
5379 torture_warning(tctx, "QueryUserInfo failed - %s\n", nt_errstr(q.out.result));
5383 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
5385 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
5386 info->info5.last_password_change, true)) {
5391 /* we change passwords twice - this has the effect of verifying
5392 they were changed correctly for the final call */
5393 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5397 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5404 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
5405 struct policy_handle *domain_handle,
5406 const char *user_name,
5407 struct policy_handle *user_handle_out,
5408 struct dom_sid *domain_sid,
5409 enum torture_samr_choice which_ops,
5410 struct cli_credentials *machine_credentials,
5414 TALLOC_CTX *user_ctx;
5416 struct samr_CreateUser r;
5417 struct samr_QueryUserInfo q;
5418 union samr_UserInfo *info;
5419 struct samr_DeleteUser d;
5422 /* This call creates a 'normal' account - check that it really does */
5423 const uint32_t acct_flags = ACB_NORMAL;
5424 struct lsa_String name;
5426 struct dcerpc_binding_handle *b = p->binding_handle;
5428 struct policy_handle user_handle;
5429 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5430 init_lsa_String(&name, user_name);
5432 r.in.domain_handle = domain_handle;
5433 r.in.account_name = &name;
5434 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5435 r.out.user_handle = &user_handle;
5438 torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
5440 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5441 "CreateUser failed");
5443 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5444 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5445 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5448 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5449 nt_errstr(r.out.result));
5454 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5455 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5456 talloc_free(user_ctx);
5459 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5460 "CreateUser failed");
5463 if (!NT_STATUS_IS_OK(r.out.result)) {
5464 talloc_free(user_ctx);
5465 torture_warning(tctx, "CreateUser failed - %s\n", nt_errstr(r.out.result));
5470 if (user_handle_out) {
5471 *user_handle_out = user_handle;
5477 q.in.user_handle = &user_handle;
5481 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5482 "QueryUserInfo failed");
5483 if (!NT_STATUS_IS_OK(q.out.result)) {
5484 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5485 q.in.level, nt_errstr(q.out.result));
5488 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
5489 torture_warning(tctx, "QueryUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5490 info->info16.acct_flags,
5496 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5497 domain_sid, acct_flags, name.string, which_ops,
5498 machine_credentials)) {
5502 if (user_handle_out) {
5503 *user_handle_out = user_handle;
5505 torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
5507 d.in.user_handle = &user_handle;
5508 d.out.user_handle = &user_handle;
5510 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5511 "DeleteUser failed");
5512 if (!NT_STATUS_IS_OK(d.out.result)) {
5513 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5520 talloc_free(user_ctx);
5526 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
5527 struct policy_handle *domain_handle,
5528 struct dom_sid *domain_sid,
5529 enum torture_samr_choice which_ops,
5530 struct cli_credentials *machine_credentials)
5532 struct samr_CreateUser2 r;
5533 struct samr_QueryUserInfo q;
5534 union samr_UserInfo *info;
5535 struct samr_DeleteUser d;
5536 struct policy_handle user_handle;
5538 struct lsa_String name;
5541 struct dcerpc_binding_handle *b = p->binding_handle;
5544 uint32_t acct_flags;
5545 const char *account_name;
5547 } account_types[] = {
5548 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
5549 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5550 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5551 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5552 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5553 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5554 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5555 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5556 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5557 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
5558 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5559 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5560 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5561 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5562 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
5565 for (i = 0; account_types[i].account_name; i++) {
5566 TALLOC_CTX *user_ctx;
5567 uint32_t acct_flags = account_types[i].acct_flags;
5568 uint32_t access_granted;
5569 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5570 init_lsa_String(&name, account_types[i].account_name);
5572 r.in.domain_handle = domain_handle;
5573 r.in.account_name = &name;
5574 r.in.acct_flags = acct_flags;
5575 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5576 r.out.user_handle = &user_handle;
5577 r.out.access_granted = &access_granted;
5580 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
5582 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5583 "CreateUser2 failed");
5585 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5586 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5587 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5590 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5591 nt_errstr(r.out.result));
5597 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5598 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5599 talloc_free(user_ctx);
5603 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5604 "CreateUser2 failed");
5607 if (!NT_STATUS_EQUAL(r.out.result, account_types[i].nt_status)) {
5608 torture_warning(tctx, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5609 nt_errstr(r.out.result), nt_errstr(account_types[i].nt_status));
5613 if (NT_STATUS_IS_OK(r.out.result)) {
5614 q.in.user_handle = &user_handle;
5618 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5619 "QueryUserInfo failed");
5620 if (!NT_STATUS_IS_OK(q.out.result)) {
5621 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5622 q.in.level, nt_errstr(q.out.result));
5625 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
5626 if (acct_flags == ACB_NORMAL) {
5627 expected_flags |= ACB_PW_EXPIRED;
5629 if ((info->info5.acct_flags) != expected_flags) {
5630 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5631 info->info5.acct_flags,
5635 switch (acct_flags) {
5637 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
5638 torture_warning(tctx, "QueryUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5639 DOMAIN_RID_DCS, info->info5.primary_gid);
5644 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
5645 torture_warning(tctx, "QueryUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5646 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
5651 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
5652 torture_warning(tctx, "QueryUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5653 DOMAIN_RID_USERS, info->info5.primary_gid);
5660 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5661 domain_sid, acct_flags, name.string, which_ops,
5662 machine_credentials)) {
5666 if (!ndr_policy_handle_empty(&user_handle)) {
5667 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
5669 d.in.user_handle = &user_handle;
5670 d.out.user_handle = &user_handle;
5672 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5673 "DeleteUser failed");
5674 if (!NT_STATUS_IS_OK(d.out.result)) {
5675 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5680 talloc_free(user_ctx);
5686 static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
5687 struct torture_context *tctx,
5688 struct policy_handle *handle)
5690 struct samr_QueryAliasInfo r;
5691 union samr_AliasInfo *info;
5692 uint16_t levels[] = {1, 2, 3};
5696 for (i=0;i<ARRAY_SIZE(levels);i++) {
5697 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
5699 r.in.alias_handle = handle;
5700 r.in.level = levels[i];
5703 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &r),
5704 "QueryAliasInfo failed");
5705 if (!NT_STATUS_IS_OK(r.out.result)) {
5706 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
5707 levels[i], nt_errstr(r.out.result));
5715 static bool test_QueryGroupInfo(struct dcerpc_binding_handle *b,
5716 struct torture_context *tctx,
5717 struct policy_handle *handle)
5719 struct samr_QueryGroupInfo r;
5720 union samr_GroupInfo *info;
5721 uint16_t levels[] = {1, 2, 3, 4, 5};
5725 for (i=0;i<ARRAY_SIZE(levels);i++) {
5726 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5728 r.in.group_handle = handle;
5729 r.in.level = levels[i];
5732 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
5733 "QueryGroupInfo failed");
5734 if (!NT_STATUS_IS_OK(r.out.result)) {
5735 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5736 levels[i], nt_errstr(r.out.result));
5744 static bool test_QueryGroupMember(struct dcerpc_binding_handle *b,
5745 struct torture_context *tctx,
5746 struct policy_handle *handle)
5748 struct samr_QueryGroupMember r;
5749 struct samr_RidAttrArray *rids = NULL;
5752 torture_comment(tctx, "Testing QueryGroupMember\n");
5754 r.in.group_handle = handle;
5757 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &r),
5758 "QueryGroupMember failed");
5759 if (!NT_STATUS_IS_OK(r.out.result)) {
5760 torture_warning(tctx, "QueryGroupMember failed - %s\n", nt_errstr(r.out.result));
5768 static bool test_SetGroupInfo(struct dcerpc_binding_handle *b,
5769 struct torture_context *tctx,
5770 struct policy_handle *handle)
5772 struct samr_QueryGroupInfo r;
5773 union samr_GroupInfo *info;
5774 struct samr_SetGroupInfo s;
5775 uint16_t levels[] = {1, 2, 3, 4};
5776 uint16_t set_ok[] = {0, 1, 1, 1};
5780 for (i=0;i<ARRAY_SIZE(levels);i++) {
5781 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5783 r.in.group_handle = handle;
5784 r.in.level = levels[i];
5787 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
5788 "QueryGroupInfo failed");
5789 if (!NT_STATUS_IS_OK(r.out.result)) {
5790 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5791 levels[i], nt_errstr(r.out.result));
5795 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
5797 s.in.group_handle = handle;
5798 s.in.level = levels[i];
5799 s.in.info = *r.out.info;
5802 /* disabled this, as it changes the name only from the point of view of samr,
5803 but leaves the name from the point of view of w2k3 internals (and ldap). This means
5804 the name is still reserved, so creating the old name fails, but deleting by the old name
5806 if (s.in.level == 2) {
5807 init_lsa_String(&s.in.info->string, "NewName");
5811 if (s.in.level == 4) {
5812 init_lsa_String(&s.in.info->description, "test description");
5815 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetGroupInfo_r(b, tctx, &s),
5816 "SetGroupInfo failed");
5818 if (!NT_STATUS_IS_OK(s.out.result)) {
5819 torture_warning(tctx, "SetGroupInfo level %u failed - %s\n",
5820 r.in.level, nt_errstr(s.out.result));
5825 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
5826 torture_warning(tctx, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5827 r.in.level, nt_errstr(s.out.result));
5837 static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
5838 struct torture_context *tctx,
5839 struct policy_handle *handle)
5841 struct samr_QueryUserInfo r;
5842 union samr_UserInfo *info;
5843 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5844 11, 12, 13, 14, 16, 17, 20, 21};
5848 for (i=0;i<ARRAY_SIZE(levels);i++) {
5849 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
5851 r.in.user_handle = handle;
5852 r.in.level = levels[i];
5855 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
5856 "QueryUserInfo failed");
5857 if (!NT_STATUS_IS_OK(r.out.result)) {
5858 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5859 levels[i], nt_errstr(r.out.result));
5867 static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
5868 struct torture_context *tctx,
5869 struct policy_handle *handle)
5871 struct samr_QueryUserInfo2 r;
5872 union samr_UserInfo *info;
5873 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5874 11, 12, 13, 14, 16, 17, 20, 21};
5878 for (i=0;i<ARRAY_SIZE(levels);i++) {
5879 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
5881 r.in.user_handle = handle;
5882 r.in.level = levels[i];
5885 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r),
5886 "QueryUserInfo2 failed");
5887 if (!NT_STATUS_IS_OK(r.out.result)) {
5888 torture_warning(tctx, "QueryUserInfo2 level %u failed - %s\n",
5889 levels[i], nt_errstr(r.out.result));
5897 static bool test_OpenUser(struct dcerpc_binding_handle *b,
5898 struct torture_context *tctx,
5899 struct policy_handle *handle, uint32_t rid)
5901 struct samr_OpenUser r;
5902 struct policy_handle user_handle;
5905 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5907 r.in.domain_handle = handle;
5908 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5910 r.out.user_handle = &user_handle;
5912 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5914 if (!NT_STATUS_IS_OK(r.out.result)) {
5915 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5919 if (!test_QuerySecurity(b, tctx, &user_handle)) {
5923 if (!test_QueryUserInfo(b, tctx, &user_handle)) {
5927 if (!test_QueryUserInfo2(b, tctx, &user_handle)) {
5931 if (!test_GetUserPwInfo(b, tctx, &user_handle)) {
5935 if (!test_GetGroupsForUser(b, tctx, &user_handle)) {
5939 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
5946 static bool test_OpenGroup(struct dcerpc_binding_handle *b,
5947 struct torture_context *tctx,
5948 struct policy_handle *handle, uint32_t rid)
5950 struct samr_OpenGroup r;
5951 struct policy_handle group_handle;
5954 torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
5956 r.in.domain_handle = handle;
5957 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5959 r.out.group_handle = &group_handle;
5961 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
5962 "OpenGroup failed");
5963 if (!NT_STATUS_IS_OK(r.out.result)) {
5964 torture_warning(tctx, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5968 if (!torture_setting_bool(tctx, "samba3", false)) {
5969 if (!test_QuerySecurity(b, tctx, &group_handle)) {
5974 if (!test_QueryGroupInfo(b, tctx, &group_handle)) {
5978 if (!test_QueryGroupMember(b, tctx, &group_handle)) {
5982 if (!test_samr_handle_Close(b, tctx, &group_handle)) {
5989 static bool test_OpenAlias(struct dcerpc_binding_handle *b,
5990 struct torture_context *tctx,
5991 struct policy_handle *handle, uint32_t rid)
5993 struct samr_OpenAlias r;
5994 struct policy_handle alias_handle;
5997 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
5999 r.in.domain_handle = handle;
6000 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6002 r.out.alias_handle = &alias_handle;
6004 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
6005 "OpenAlias failed");
6006 if (!NT_STATUS_IS_OK(r.out.result)) {
6007 torture_warning(tctx, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6011 if (!torture_setting_bool(tctx, "samba3", false)) {
6012 if (!test_QuerySecurity(b, tctx, &alias_handle)) {
6017 if (!test_QueryAliasInfo(b, tctx, &alias_handle)) {
6021 if (!test_GetMembersInAlias(b, tctx, &alias_handle)) {
6025 if (!test_samr_handle_Close(b, tctx, &alias_handle)) {
6032 static bool check_mask(struct dcerpc_binding_handle *b,
6033 struct torture_context *tctx,
6034 struct policy_handle *handle, uint32_t rid,
6035 uint32_t acct_flag_mask)
6037 struct samr_OpenUser r;
6038 struct samr_QueryUserInfo q;
6039 union samr_UserInfo *info;
6040 struct policy_handle user_handle;
6043 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
6045 r.in.domain_handle = handle;
6046 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6048 r.out.user_handle = &user_handle;
6050 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6052 if (!NT_STATUS_IS_OK(r.out.result)) {
6053 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6057 q.in.user_handle = &user_handle;
6061 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6062 "QueryUserInfo failed");
6063 if (!NT_STATUS_IS_OK(q.out.result)) {
6064 torture_warning(tctx, "QueryUserInfo level 16 failed - %s\n",
6065 nt_errstr(q.out.result));
6068 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
6069 torture_warning(tctx, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
6070 acct_flag_mask, info->info16.acct_flags, rid);
6075 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6082 static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle *b,
6083 struct torture_context *tctx,
6084 struct policy_handle *handle)
6086 struct samr_EnumDomainUsers r;
6087 uint32_t mask, resume_handle=0;
6090 struct samr_LookupNames n;
6091 struct samr_LookupRids lr ;
6092 struct lsa_Strings names;
6093 struct samr_Ids rids, types;
6094 struct samr_SamArray *sam = NULL;
6095 uint32_t num_entries = 0;
6097 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
6098 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
6099 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
6102 torture_comment(tctx, "Testing EnumDomainUsers\n");
6104 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
6105 r.in.domain_handle = handle;
6106 r.in.resume_handle = &resume_handle;
6107 r.in.acct_flags = mask = masks[mask_idx];
6108 r.in.max_size = (uint32_t)-1;
6109 r.out.resume_handle = &resume_handle;
6110 r.out.num_entries = &num_entries;
6113 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
6114 "EnumDomainUsers failed");
6115 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
6116 !NT_STATUS_IS_OK(r.out.result)) {
6117 torture_warning(tctx, "EnumDomainUsers failed - %s\n", nt_errstr(r.out.result));
6121 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
6123 if (sam->count == 0) {
6127 for (i=0;i<sam->count;i++) {
6129 if (!check_mask(b, tctx, handle, sam->entries[i].idx, mask)) {
6132 } else if (!test_OpenUser(b, tctx, handle, sam->entries[i].idx)) {
6138 torture_comment(tctx, "Testing LookupNames\n");
6139 n.in.domain_handle = handle;
6140 n.in.num_names = sam->count;
6141 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
6143 n.out.types = &types;
6144 for (i=0;i<sam->count;i++) {
6145 n.in.names[i].string = sam->entries[i].name.string;
6147 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
6148 "LookupNames failed");
6149 if (!NT_STATUS_IS_OK(n.out.result)) {
6150 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(n.out.result));
6155 torture_comment(tctx, "Testing LookupRids\n");
6156 lr.in.domain_handle = handle;
6157 lr.in.num_rids = sam->count;
6158 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
6159 lr.out.names = &names;
6160 lr.out.types = &types;
6161 for (i=0;i<sam->count;i++) {
6162 lr.in.rids[i] = sam->entries[i].idx;
6164 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupRids_r(b, tctx, &lr),
6165 "LookupRids failed");
6166 torture_assert_ntstatus_ok(tctx, lr.out.result, "LookupRids");
6172 try blasting the server with a bunch of sync requests
6174 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
6175 struct policy_handle *handle)
6177 struct samr_EnumDomainUsers r;
6178 uint32_t resume_handle=0;
6180 #define ASYNC_COUNT 100
6181 struct tevent_req *req[ASYNC_COUNT];
6183 if (!torture_setting_bool(tctx, "dangerous", false)) {
6184 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
6187 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
6189 r.in.domain_handle = handle;
6190 r.in.resume_handle = &resume_handle;
6191 r.in.acct_flags = 0;
6192 r.in.max_size = (uint32_t)-1;
6193 r.out.resume_handle = &resume_handle;
6195 for (i=0;i<ASYNC_COUNT;i++) {
6196 req[i] = dcerpc_samr_EnumDomainUsers_r_send(tctx, tctx->ev, p->binding_handle, &r);
6199 for (i=0;i<ASYNC_COUNT;i++) {
6200 tevent_req_poll(req[i], tctx->ev);
6201 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r_recv(req[i], tctx),
6202 talloc_asprintf(tctx, "EnumDomainUsers[%d] failed - %s\n",
6203 i, nt_errstr(r.out.result)));
6206 torture_comment(tctx, "%d async requests OK\n", i);
6211 static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle *b,
6212 struct torture_context *tctx,
6213 struct policy_handle *handle)
6215 struct samr_EnumDomainGroups r;
6216 uint32_t resume_handle=0;
6217 struct samr_SamArray *sam = NULL;
6218 uint32_t num_entries = 0;
6221 bool universal_group_found = false;
6223 torture_comment(tctx, "Testing EnumDomainGroups\n");
6225 r.in.domain_handle = handle;
6226 r.in.resume_handle = &resume_handle;
6227 r.in.max_size = (uint32_t)-1;
6228 r.out.resume_handle = &resume_handle;
6229 r.out.num_entries = &num_entries;
6232 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
6233 "EnumDomainGroups failed");
6234 if (!NT_STATUS_IS_OK(r.out.result)) {
6235 torture_warning(tctx, "EnumDomainGroups failed - %s\n", nt_errstr(r.out.result));
6243 for (i=0;i<sam->count;i++) {
6244 if (!test_OpenGroup(b, tctx, handle, sam->entries[i].idx)) {
6247 if ((ret == true) && (strcasecmp(sam->entries[i].name.string,
6248 "Enterprise Admins") == 0)) {
6249 universal_group_found = true;
6253 /* when we are running this on s4 we should get back at least the
6254 * "Enterprise Admins" universal group. If we don't get a group entry
6255 * at all we probably are performing the test on the builtin domain.
6256 * So ignore this case. */
6257 if (torture_setting_bool(tctx, "samba4", false)) {
6258 if ((sam->count > 0) && (!universal_group_found)) {
6266 static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle *b,
6267 struct torture_context *tctx,
6268 struct policy_handle *handle)
6270 struct samr_EnumDomainAliases r;
6271 uint32_t resume_handle=0;
6272 struct samr_SamArray *sam = NULL;
6273 uint32_t num_entries = 0;
6277 torture_comment(tctx, "Testing EnumDomainAliases\n");
6279 r.in.domain_handle = handle;
6280 r.in.resume_handle = &resume_handle;
6281 r.in.max_size = (uint32_t)-1;
6283 r.out.num_entries = &num_entries;
6284 r.out.resume_handle = &resume_handle;
6286 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
6287 "EnumDomainAliases failed");
6288 if (!NT_STATUS_IS_OK(r.out.result)) {
6289 torture_warning(tctx, "EnumDomainAliases failed - %s\n", nt_errstr(r.out.result));
6297 for (i=0;i<sam->count;i++) {
6298 if (!test_OpenAlias(b, tctx, handle, sam->entries[i].idx)) {
6306 static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle *b,
6307 struct torture_context *tctx,
6308 struct policy_handle *handle)
6310 struct samr_GetDisplayEnumerationIndex r;
6312 uint16_t levels[] = {1, 2, 3, 4, 5};
6313 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6314 struct lsa_String name;
6318 for (i=0;i<ARRAY_SIZE(levels);i++) {
6319 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
6321 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6323 r.in.domain_handle = handle;
6324 r.in.level = levels[i];
6328 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6329 "GetDisplayEnumerationIndex failed");
6332 !NT_STATUS_IS_OK(r.out.result) &&
6333 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6334 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6335 levels[i], nt_errstr(r.out.result));
6339 init_lsa_String(&name, "zzzzzzzz");
6341 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6342 "GetDisplayEnumerationIndex failed");
6344 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6345 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6346 levels[i], nt_errstr(r.out.result));
6354 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle *b,
6355 struct torture_context *tctx,
6356 struct policy_handle *handle)
6358 struct samr_GetDisplayEnumerationIndex2 r;
6360 uint16_t levels[] = {1, 2, 3, 4, 5};
6361 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6362 struct lsa_String name;
6366 for (i=0;i<ARRAY_SIZE(levels);i++) {
6367 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
6369 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6371 r.in.domain_handle = handle;
6372 r.in.level = levels[i];
6376 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6377 "GetDisplayEnumerationIndex2 failed");
6379 !NT_STATUS_IS_OK(r.out.result) &&
6380 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6381 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6382 levels[i], nt_errstr(r.out.result));
6386 init_lsa_String(&name, "zzzzzzzz");
6388 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6389 "GetDisplayEnumerationIndex2 failed");
6390 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6391 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6392 levels[i], nt_errstr(r.out.result));
6400 #define STRING_EQUAL_QUERY(s1, s2, user) \
6401 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6402 /* odd, but valid */ \
6403 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6404 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
6405 #s1, user.string, s1.string, s2.string, __location__); \
6408 #define INT_EQUAL_QUERY(s1, s2, user) \
6410 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6411 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6415 static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle *b,
6416 struct torture_context *tctx,
6417 struct samr_QueryDisplayInfo *querydisplayinfo,
6418 bool *seen_testuser)
6420 struct samr_OpenUser r;
6421 struct samr_QueryUserInfo q;
6422 union samr_UserInfo *info;
6423 struct policy_handle user_handle;
6425 r.in.domain_handle = querydisplayinfo->in.domain_handle;
6426 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6427 for (i = 0; ; i++) {
6428 switch (querydisplayinfo->in.level) {
6430 if (i >= querydisplayinfo->out.info->info1.count) {
6433 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
6436 if (i >= querydisplayinfo->out.info->info2.count) {
6439 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
6445 /* Not interested in validating just the account name */
6449 r.out.user_handle = &user_handle;
6451 switch (querydisplayinfo->in.level) {
6454 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6456 if (!NT_STATUS_IS_OK(r.out.result)) {
6457 torture_warning(tctx, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6462 q.in.user_handle = &user_handle;
6465 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6466 "QueryUserInfo failed");
6467 if (!NT_STATUS_IS_OK(r.out.result)) {
6468 torture_warning(tctx, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6472 switch (querydisplayinfo->in.level) {
6474 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
6475 *seen_testuser = true;
6477 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
6478 info->info21.full_name, info->info21.account_name);
6479 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
6480 info->info21.account_name, info->info21.account_name);
6481 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
6482 info->info21.description, info->info21.account_name);
6483 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
6484 info->info21.rid, info->info21.account_name);
6485 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
6486 info->info21.acct_flags, info->info21.account_name);
6490 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
6491 info->info21.account_name, info->info21.account_name);
6492 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
6493 info->info21.description, info->info21.account_name);
6494 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
6495 info->info21.rid, info->info21.account_name);
6496 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
6497 info->info21.acct_flags, info->info21.account_name);
6499 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
6500 torture_warning(tctx, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6501 info->info21.account_name.string);
6504 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
6505 torture_warning(tctx, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6506 info->info21.account_name.string,
6507 querydisplayinfo->out.info->info2.entries[i].acct_flags,
6508 info->info21.acct_flags);
6515 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6522 static bool test_QueryDisplayInfo(struct dcerpc_binding_handle *b,
6523 struct torture_context *tctx,
6524 struct policy_handle *handle)
6526 struct samr_QueryDisplayInfo r;
6527 struct samr_QueryDomainInfo dom_info;
6528 union samr_DomainInfo *info = NULL;
6530 uint16_t levels[] = {1, 2, 3, 4, 5};
6532 bool seen_testuser = false;
6533 uint32_t total_size;
6534 uint32_t returned_size;
6535 union samr_DispInfo disp_info;
6538 for (i=0;i<ARRAY_SIZE(levels);i++) {
6539 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
6542 r.out.result = STATUS_MORE_ENTRIES;
6543 while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
6544 r.in.domain_handle = handle;
6545 r.in.level = levels[i];
6546 r.in.max_entries = 2;
6547 r.in.buf_size = (uint32_t)-1;
6548 r.out.total_size = &total_size;
6549 r.out.returned_size = &returned_size;
6550 r.out.info = &disp_info;
6552 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6553 "QueryDisplayInfo failed");
6554 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(r.out.result)) {
6555 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6556 levels[i], nt_errstr(r.out.result));
6559 switch (r.in.level) {
6561 if (!test_each_DisplayInfo_user(b, tctx, &r, &seen_testuser)) {
6564 r.in.start_idx += r.out.info->info1.count;
6567 if (!test_each_DisplayInfo_user(b, tctx, &r, NULL)) {
6570 r.in.start_idx += r.out.info->info2.count;
6573 r.in.start_idx += r.out.info->info3.count;
6576 r.in.start_idx += r.out.info->info4.count;
6579 r.in.start_idx += r.out.info->info5.count;
6583 dom_info.in.domain_handle = handle;
6584 dom_info.in.level = 2;
6585 dom_info.out.info = &info;
6587 /* Check number of users returned is correct */
6588 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &dom_info),
6589 "QueryDomainInfo failed");
6590 if (!NT_STATUS_IS_OK(dom_info.out.result)) {
6591 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6592 r.in.level, nt_errstr(dom_info.out.result));
6596 switch (r.in.level) {
6599 if (info->general.num_users < r.in.start_idx) {
6600 /* On AD deployments this numbers don't match
6601 * since QueryDisplayInfo returns universal and
6602 * global groups, QueryDomainInfo only global
6604 if (torture_setting_bool(tctx, "samba3", false)) {
6605 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6606 r.in.start_idx, info->general.num_groups,
6607 info->general.domain_name.string);
6611 if (!seen_testuser) {
6612 struct policy_handle user_handle;
6613 if (NT_STATUS_IS_OK(test_OpenUser_byname(b, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
6614 torture_warning(tctx, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
6615 info->general.domain_name.string);
6617 test_samr_handle_Close(b, tctx, &user_handle);
6623 if (info->general.num_groups != r.in.start_idx) {
6624 /* On AD deployments this numbers don't match
6625 * since QueryDisplayInfo returns universal and
6626 * global groups, QueryDomainInfo only global
6628 if (torture_setting_bool(tctx, "samba3", false)) {
6629 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6630 r.in.start_idx, info->general.num_groups,
6631 info->general.domain_name.string);
6644 static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle *b,
6645 struct torture_context *tctx,
6646 struct policy_handle *handle)
6648 struct samr_QueryDisplayInfo2 r;
6650 uint16_t levels[] = {1, 2, 3, 4, 5};
6652 uint32_t total_size;
6653 uint32_t returned_size;
6654 union samr_DispInfo info;
6656 for (i=0;i<ARRAY_SIZE(levels);i++) {
6657 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
6659 r.in.domain_handle = handle;
6660 r.in.level = levels[i];
6662 r.in.max_entries = 1000;
6663 r.in.buf_size = (uint32_t)-1;
6664 r.out.total_size = &total_size;
6665 r.out.returned_size = &returned_size;
6668 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo2_r(b, tctx, &r),
6669 "QueryDisplayInfo2 failed");
6670 if (!NT_STATUS_IS_OK(r.out.result)) {
6671 torture_warning(tctx, "QueryDisplayInfo2 level %u failed - %s\n",
6672 levels[i], nt_errstr(r.out.result));
6680 static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle *b,
6681 struct torture_context *tctx,
6682 struct policy_handle *handle)
6684 struct samr_QueryDisplayInfo3 r;
6686 uint16_t levels[] = {1, 2, 3, 4, 5};
6688 uint32_t total_size;
6689 uint32_t returned_size;
6690 union samr_DispInfo info;
6692 for (i=0;i<ARRAY_SIZE(levels);i++) {
6693 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
6695 r.in.domain_handle = handle;
6696 r.in.level = levels[i];
6698 r.in.max_entries = 1000;
6699 r.in.buf_size = (uint32_t)-1;
6700 r.out.total_size = &total_size;
6701 r.out.returned_size = &returned_size;
6704 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo3_r(b, tctx, &r),
6705 "QueryDisplayInfo3 failed");
6706 if (!NT_STATUS_IS_OK(r.out.result)) {
6707 torture_warning(tctx, "QueryDisplayInfo3 level %u failed - %s\n",
6708 levels[i], nt_errstr(r.out.result));
6717 static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle *b,
6718 struct torture_context *tctx,
6719 struct policy_handle *handle)
6721 struct samr_QueryDisplayInfo r;
6723 uint32_t total_size;
6724 uint32_t returned_size;
6725 union samr_DispInfo info;
6727 torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
6729 r.in.domain_handle = handle;
6732 r.in.max_entries = 1;
6733 r.in.buf_size = (uint32_t)-1;
6734 r.out.total_size = &total_size;
6735 r.out.returned_size = &returned_size;
6739 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6740 "QueryDisplayInfo failed");
6741 if (NT_STATUS_IS_OK(r.out.result) && *r.out.returned_size != 0) {
6742 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
6743 torture_warning(tctx, "expected idx %d but got %d\n",
6745 r.out.info->info1.entries[0].idx);
6749 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
6750 !NT_STATUS_IS_OK(r.out.result)) {
6751 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6752 r.in.level, nt_errstr(r.out.result));
6757 } while ((NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) ||
6758 NT_STATUS_IS_OK(r.out.result)) &&
6759 *r.out.returned_size != 0);
6764 static bool test_QueryDomainInfo(struct dcerpc_pipe *p,
6765 struct torture_context *tctx,
6766 struct policy_handle *handle)
6768 struct samr_QueryDomainInfo r;
6769 union samr_DomainInfo *info = NULL;
6770 struct samr_SetDomainInfo s;
6771 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6772 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
6775 struct dcerpc_binding_handle *b = p->binding_handle;
6776 const char *domain_comment = talloc_asprintf(tctx,
6777 "Tortured by Samba4 RPC-SAMR: %s",
6778 timestring(tctx, time(NULL)));
6780 s.in.domain_handle = handle;
6782 s.in.info = talloc(tctx, union samr_DomainInfo);
6784 s.in.info->oem.oem_information.string = domain_comment;
6785 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
6786 "SetDomainInfo failed");
6787 if (!NT_STATUS_IS_OK(s.out.result)) {
6788 torture_warning(tctx, "SetDomainInfo level %u (set comment) failed - %s\n",
6789 s.in.level, nt_errstr(s.out.result));
6793 for (i=0;i<ARRAY_SIZE(levels);i++) {
6794 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
6796 r.in.domain_handle = handle;
6797 r.in.level = levels[i];
6800 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
6801 "QueryDomainInfo failed");
6802 if (!NT_STATUS_IS_OK(r.out.result)) {
6803 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6804 r.in.level, nt_errstr(r.out.result));
6809 switch (levels[i]) {
6811 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
6812 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6813 levels[i], info->general.oem_information.string, domain_comment);
6814 if (!torture_setting_bool(tctx, "samba3", false)) {
6818 if (!info->general.primary.string) {
6819 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6822 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
6823 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
6824 if (torture_setting_bool(tctx, "samba3", false)) {
6825 torture_warning(tctx, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
6826 levels[i], info->general.primary.string, dcerpc_server_name(p));
6832 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
6833 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6834 levels[i], info->oem.oem_information.string, domain_comment);
6835 if (!torture_setting_bool(tctx, "samba3", false)) {
6841 if (!info->info6.primary.string) {
6842 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6848 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
6849 torture_warning(tctx, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
6850 levels[i], info->general2.general.oem_information.string, domain_comment);
6851 if (!torture_setting_bool(tctx, "samba3", false)) {
6858 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
6860 s.in.domain_handle = handle;
6861 s.in.level = levels[i];
6864 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
6865 "SetDomainInfo failed");
6867 if (!NT_STATUS_IS_OK(s.out.result)) {
6868 torture_warning(tctx, "SetDomainInfo level %u failed - %s\n",
6869 r.in.level, nt_errstr(s.out.result));
6874 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
6875 torture_warning(tctx, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6876 r.in.level, nt_errstr(s.out.result));
6882 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
6883 "QueryDomainInfo failed");
6884 if (!NT_STATUS_IS_OK(r.out.result)) {
6885 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6886 r.in.level, nt_errstr(r.out.result));
6896 static bool test_QueryDomainInfo2(struct dcerpc_binding_handle *b,
6897 struct torture_context *tctx,
6898 struct policy_handle *handle)
6900 struct samr_QueryDomainInfo2 r;
6901 union samr_DomainInfo *info = NULL;
6902 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6906 for (i=0;i<ARRAY_SIZE(levels);i++) {
6907 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
6909 r.in.domain_handle = handle;
6910 r.in.level = levels[i];
6913 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
6914 "QueryDomainInfo2 failed");
6915 if (!NT_STATUS_IS_OK(r.out.result)) {
6916 torture_warning(tctx, "QueryDomainInfo2 level %u failed - %s\n",
6917 r.in.level, nt_errstr(r.out.result));
6926 /* Test whether querydispinfo level 5 and enumdomgroups return the same
6927 set of group names. */
6928 static bool test_GroupList(struct dcerpc_binding_handle *b,
6929 struct torture_context *tctx,
6930 struct dom_sid *domain_sid,
6931 struct policy_handle *handle)
6933 struct samr_EnumDomainGroups q1;
6934 struct samr_QueryDisplayInfo q2;
6936 uint32_t resume_handle=0;
6937 struct samr_SamArray *sam = NULL;
6938 uint32_t num_entries = 0;
6941 uint32_t total_size;
6942 uint32_t returned_size;
6943 union samr_DispInfo info;
6946 const char **names = NULL;
6948 bool builtin_domain = dom_sid_compare(domain_sid,
6949 &global_sid_Builtin) == 0;
6951 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
6953 q1.in.domain_handle = handle;
6954 q1.in.resume_handle = &resume_handle;
6956 q1.out.resume_handle = &resume_handle;
6957 q1.out.num_entries = &num_entries;
6960 status = STATUS_MORE_ENTRIES;
6961 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6962 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &q1),
6963 "EnumDomainGroups failed");
6964 status = q1.out.result;
6966 if (!NT_STATUS_IS_OK(status) &&
6967 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6970 for (i=0; i<*q1.out.num_entries; i++) {
6971 add_string_to_array(tctx,
6972 sam->entries[i].name.string,
6973 &names, &num_names);
6977 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
6979 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
6981 if (builtin_domain) {
6982 torture_assert(tctx, num_names == 0,
6983 "EnumDomainGroups shouldn't return any group in the builtin domain!");
6986 q2.in.domain_handle = handle;
6988 q2.in.start_idx = 0;
6989 q2.in.max_entries = 5;
6990 q2.in.buf_size = (uint32_t)-1;
6991 q2.out.total_size = &total_size;
6992 q2.out.returned_size = &returned_size;
6993 q2.out.info = &info;
6995 status = STATUS_MORE_ENTRIES;
6996 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6997 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &q2),
6998 "QueryDisplayInfo failed");
6999 status = q2.out.result;
7000 if (!NT_STATUS_IS_OK(status) &&
7001 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
7004 for (i=0; i<q2.out.info->info5.count; i++) {
7006 const char *name = q2.out.info->info5.entries[i].account_name.string;
7008 for (j=0; j<num_names; j++) {
7009 if (names[j] == NULL)
7011 if (strequal(names[j], name)) {
7018 if ((!found) && (!builtin_domain)) {
7019 torture_warning(tctx, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
7024 q2.in.start_idx += q2.out.info->info5.count;
7027 if (!NT_STATUS_IS_OK(status)) {
7028 torture_warning(tctx, "QueryDisplayInfo level 5 failed - %s\n",
7033 if (builtin_domain) {
7034 torture_assert(tctx, q2.in.start_idx != 0,
7035 "QueryDisplayInfo should return all domain groups also on the builtin domain handle!");
7038 for (i=0; i<num_names; i++) {
7039 if (names[i] != NULL) {
7040 torture_warning(tctx, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
7049 static bool test_DeleteDomainGroup(struct dcerpc_binding_handle *b,
7050 struct torture_context *tctx,
7051 struct policy_handle *group_handle)
7053 struct samr_DeleteDomainGroup d;
7055 torture_comment(tctx, "Testing DeleteDomainGroup\n");
7057 d.in.group_handle = group_handle;
7058 d.out.group_handle = group_handle;
7060 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
7061 "DeleteDomainGroup failed");
7062 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteDomainGroup");
7067 static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle *b,
7068 struct torture_context *tctx,
7069 struct policy_handle *domain_handle)
7071 struct samr_TestPrivateFunctionsDomain r;
7074 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
7076 r.in.domain_handle = domain_handle;
7078 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsDomain_r(b, tctx, &r),
7079 "TestPrivateFunctionsDomain failed");
7080 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
7085 static bool test_RidToSid(struct dcerpc_binding_handle *b,
7086 struct torture_context *tctx,
7087 struct dom_sid *domain_sid,
7088 struct policy_handle *domain_handle)
7090 struct samr_RidToSid r;
7092 struct dom_sid *calc_sid, *out_sid;
7093 int rids[] = { 0, 42, 512, 10200 };
7096 for (i=0;i<ARRAY_SIZE(rids);i++) {
7097 torture_comment(tctx, "Testing RidToSid\n");
7099 calc_sid = dom_sid_dup(tctx, domain_sid);
7100 r.in.domain_handle = domain_handle;
7102 r.out.sid = &out_sid;
7104 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RidToSid_r(b, tctx, &r),
7106 if (!NT_STATUS_IS_OK(r.out.result)) {
7107 torture_warning(tctx, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(r.out.result));
7110 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
7112 if (!dom_sid_equal(calc_sid, out_sid)) {
7113 torture_warning(tctx, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
7114 dom_sid_string(tctx, out_sid),
7115 dom_sid_string(tctx, calc_sid));
7124 static bool test_GetBootKeyInformation(struct dcerpc_binding_handle *b,
7125 struct torture_context *tctx,
7126 struct policy_handle *domain_handle)
7128 struct samr_GetBootKeyInformation r;
7130 uint32_t unknown = 0;
7133 torture_comment(tctx, "Testing GetBootKeyInformation\n");
7135 r.in.domain_handle = domain_handle;
7136 r.out.unknown = &unknown;
7138 status = dcerpc_samr_GetBootKeyInformation_r(b, tctx, &r);
7139 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(r.out.result)) {
7140 status = r.out.result;
7142 if (!NT_STATUS_IS_OK(status)) {
7143 /* w2k3 seems to fail this sometimes and pass it sometimes */
7144 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
7150 static bool test_AddGroupMember(struct dcerpc_binding_handle *b,
7151 struct torture_context *tctx,
7152 struct policy_handle *domain_handle,
7153 struct policy_handle *group_handle)
7156 struct samr_AddGroupMember r;
7157 struct samr_DeleteGroupMember d;
7158 struct samr_QueryGroupMember q;
7159 struct samr_RidAttrArray *rids = NULL;
7160 struct samr_SetMemberAttributesOfGroup s;
7162 bool found_member = false;
7165 status = test_LookupName(b, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
7166 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
7168 r.in.group_handle = group_handle;
7170 r.in.flags = 0; /* ??? */
7172 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
7174 d.in.group_handle = group_handle;
7177 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7178 "DeleteGroupMember failed");
7179 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, d.out.result, "DeleteGroupMember");
7181 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7182 "AddGroupMember failed");
7183 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7185 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7186 "AddGroupMember failed");
7187 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, r.out.result, "AddGroupMember");
7189 if (torture_setting_bool(tctx, "samba4", false) ||
7190 torture_setting_bool(tctx, "samba3", false)) {
7191 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
7193 /* this one is quite strange. I am using random inputs in the
7194 hope of triggering an error that might give us a clue */
7196 s.in.group_handle = group_handle;
7197 s.in.unknown1 = random();
7198 s.in.unknown2 = random();
7200 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetMemberAttributesOfGroup_r(b, tctx, &s),
7201 "SetMemberAttributesOfGroup failed");
7202 torture_assert_ntstatus_ok(tctx, s.out.result, "SetMemberAttributesOfGroup");
7205 q.in.group_handle = group_handle;
7208 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7209 "QueryGroupMember failed");
7210 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7211 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7213 for (i=0; i < rids->count; i++) {
7214 if (rids->rids[i] == rid) {
7215 found_member = true;
7219 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
7221 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7222 "DeleteGroupMember failed");
7223 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteGroupMember");
7226 found_member = false;
7228 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7229 "QueryGroupMember failed");
7230 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7231 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7233 for (i=0; i < rids->count; i++) {
7234 if (rids->rids[i] == rid) {
7235 found_member = true;
7239 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
7241 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7242 "AddGroupMember failed");
7243 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7249 static bool test_CreateDomainGroup(struct dcerpc_binding_handle *b,
7250 struct torture_context *tctx,
7251 struct policy_handle *domain_handle,
7252 const char *group_name,
7253 struct policy_handle *group_handle,
7254 struct dom_sid *domain_sid,
7257 struct samr_CreateDomainGroup r;
7259 struct lsa_String name;
7262 init_lsa_String(&name, group_name);
7264 r.in.domain_handle = domain_handle;
7266 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7267 r.out.group_handle = group_handle;
7270 torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
7272 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7273 "CreateDomainGroup failed");
7275 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
7276 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
7277 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
7280 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
7281 nt_errstr(r.out.result));
7286 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_GROUP_EXISTS)) {
7287 if (!test_DeleteGroup_byname(b, tctx, domain_handle, r.in.name->string)) {
7288 torture_warning(tctx, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
7289 nt_errstr(r.out.result));
7292 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7293 "CreateDomainGroup failed");
7295 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
7296 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.name->string)) {
7298 torture_warning(tctx, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
7299 nt_errstr(r.out.result));
7302 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7303 "CreateDomainGroup failed");
7305 torture_assert_ntstatus_ok(tctx, r.out.result, "CreateDomainGroup");
7311 if (!test_AddGroupMember(b, tctx, domain_handle, group_handle)) {
7312 torture_warning(tctx, "CreateDomainGroup failed - %s\n", nt_errstr(r.out.result));
7316 if (!test_SetGroupInfo(b, tctx, group_handle)) {
7325 its not totally clear what this does. It seems to accept any sid you like.
7327 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle *b,
7328 struct torture_context *tctx,
7329 struct policy_handle *domain_handle)
7331 struct samr_RemoveMemberFromForeignDomain r;
7333 r.in.domain_handle = domain_handle;
7334 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
7336 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMemberFromForeignDomain_r(b, tctx, &r),
7337 "RemoveMemberFromForeignDomain failed");
7338 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMemberFromForeignDomain");
7343 static bool test_EnumDomainUsers(struct dcerpc_binding_handle *b,
7344 struct torture_context *tctx,
7345 struct policy_handle *domain_handle,
7346 uint32_t *total_num_entries_p)
7349 struct samr_EnumDomainUsers r;
7350 uint32_t resume_handle = 0;
7351 uint32_t num_entries = 0;
7352 uint32_t total_num_entries = 0;
7353 struct samr_SamArray *sam;
7355 r.in.domain_handle = domain_handle;
7356 r.in.acct_flags = 0;
7357 r.in.max_size = (uint32_t)-1;
7358 r.in.resume_handle = &resume_handle;
7361 r.out.num_entries = &num_entries;
7362 r.out.resume_handle = &resume_handle;
7364 torture_comment(tctx, "Testing EnumDomainUsers\n");
7367 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
7368 "EnumDomainUsers failed");
7369 if (NT_STATUS_IS_ERR(r.out.result)) {
7370 torture_assert_ntstatus_ok(tctx, r.out.result,
7371 "failed to enumerate users");
7373 status = r.out.result;
7375 total_num_entries += num_entries;
7376 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7378 if (total_num_entries_p) {
7379 *total_num_entries_p = total_num_entries;
7385 static bool test_EnumDomainGroups(struct dcerpc_binding_handle *b,
7386 struct torture_context *tctx,
7387 struct policy_handle *domain_handle,
7388 uint32_t *total_num_entries_p)
7391 struct samr_EnumDomainGroups r;
7392 uint32_t resume_handle = 0;
7393 uint32_t num_entries = 0;
7394 uint32_t total_num_entries = 0;
7395 struct samr_SamArray *sam;
7397 r.in.domain_handle = domain_handle;
7398 r.in.max_size = (uint32_t)-1;
7399 r.in.resume_handle = &resume_handle;
7402 r.out.num_entries = &num_entries;
7403 r.out.resume_handle = &resume_handle;
7405 torture_comment(tctx, "Testing EnumDomainGroups\n");
7408 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
7409 "EnumDomainGroups failed");
7410 if (NT_STATUS_IS_ERR(r.out.result)) {
7411 torture_assert_ntstatus_ok(tctx, r.out.result,
7412 "failed to enumerate groups");
7414 status = r.out.result;
7416 total_num_entries += num_entries;
7417 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7419 if (total_num_entries_p) {
7420 *total_num_entries_p = total_num_entries;
7426 static bool test_EnumDomainAliases(struct dcerpc_binding_handle *b,
7427 struct torture_context *tctx,
7428 struct policy_handle *domain_handle,
7429 uint32_t *total_num_entries_p)
7432 struct samr_EnumDomainAliases r;
7433 uint32_t resume_handle = 0;
7434 uint32_t num_entries = 0;
7435 uint32_t total_num_entries = 0;
7436 struct samr_SamArray *sam;
7438 r.in.domain_handle = domain_handle;
7439 r.in.max_size = (uint32_t)-1;
7440 r.in.resume_handle = &resume_handle;
7443 r.out.num_entries = &num_entries;
7444 r.out.resume_handle = &resume_handle;
7446 torture_comment(tctx, "Testing EnumDomainAliases\n");
7449 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
7450 "EnumDomainAliases failed");
7451 if (NT_STATUS_IS_ERR(r.out.result)) {
7452 torture_assert_ntstatus_ok(tctx, r.out.result,
7453 "failed to enumerate aliases");
7455 status = r.out.result;
7457 total_num_entries += num_entries;
7458 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7460 if (total_num_entries_p) {
7461 *total_num_entries_p = total_num_entries;
7467 static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle *b,
7468 struct torture_context *tctx,
7469 struct policy_handle *handle,
7471 uint32_t *total_num_entries_p)
7474 struct samr_QueryDisplayInfo r;
7475 uint32_t total_num_entries = 0;
7477 r.in.domain_handle = handle;
7480 r.in.max_entries = (uint32_t)-1;
7481 r.in.buf_size = (uint32_t)-1;
7483 torture_comment(tctx, "Testing QueryDisplayInfo\n");
7486 uint32_t total_size;
7487 uint32_t returned_size;
7488 union samr_DispInfo info;
7490 r.out.total_size = &total_size;
7491 r.out.returned_size = &returned_size;
7494 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7495 "failed to query displayinfo");
7496 if (NT_STATUS_IS_ERR(r.out.result)) {
7497 torture_assert_ntstatus_ok(tctx, r.out.result,
7498 "failed to query displayinfo");
7500 status = r.out.result;
7502 if (*r.out.returned_size == 0) {
7506 switch (r.in.level) {
7508 total_num_entries += info.info1.count;
7509 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
7512 total_num_entries += info.info2.count;
7513 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
7516 total_num_entries += info.info3.count;
7517 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
7520 total_num_entries += info.info4.count;
7521 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
7524 total_num_entries += info.info5.count;
7525 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
7531 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7533 if (total_num_entries_p) {
7534 *total_num_entries_p = total_num_entries;
7540 static bool test_ManyObjects(struct dcerpc_pipe *p,
7541 struct torture_context *tctx,
7542 struct policy_handle *domain_handle,
7543 struct dom_sid *domain_sid,
7544 struct torture_samr_context *ctx)
7546 uint32_t num_total = ctx->num_objects_large_dc;
7547 uint32_t num_enum = 0;
7548 uint32_t num_disp = 0;
7549 uint32_t num_created = 0;
7550 uint32_t num_anounced = 0;
7552 struct dcerpc_binding_handle *b = p->binding_handle;
7554 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
7559 struct samr_QueryDomainInfo2 r;
7560 union samr_DomainInfo *info;
7561 r.in.domain_handle = domain_handle;
7565 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
7566 "QueryDomainInfo2 failed");
7567 torture_assert_ntstatus_ok(tctx, r.out.result,
7568 "failed to query domain info");
7570 switch (ctx->choice) {
7571 case TORTURE_SAMR_MANY_ACCOUNTS:
7572 num_anounced = info->general.num_users;
7574 case TORTURE_SAMR_MANY_GROUPS:
7575 num_anounced = info->general.num_groups;
7577 case TORTURE_SAMR_MANY_ALIASES:
7578 num_anounced = info->general.num_aliases;
7587 for (i=0; i < num_total; i++) {
7589 const char *name = NULL;
7591 switch (ctx->choice) {
7592 case TORTURE_SAMR_MANY_ACCOUNTS:
7593 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
7594 torture_assert(tctx,
7595 test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false),
7596 "failed to create user");
7598 case TORTURE_SAMR_MANY_GROUPS:
7599 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
7600 torture_assert(tctx,
7601 test_CreateDomainGroup(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
7602 "failed to create group");
7604 case TORTURE_SAMR_MANY_ALIASES:
7605 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
7606 torture_assert(tctx,
7607 test_CreateAlias(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
7608 "failed to create alias");
7613 if (!ndr_policy_handle_empty(&handles[i])) {
7620 switch (ctx->choice) {
7621 case TORTURE_SAMR_MANY_ACCOUNTS:
7622 torture_assert(tctx,
7623 test_EnumDomainUsers(b, tctx, domain_handle, &num_enum),
7624 "failed to enum users");
7626 case TORTURE_SAMR_MANY_GROUPS:
7627 torture_assert(tctx,
7628 test_EnumDomainGroups(b, tctx, domain_handle, &num_enum),
7629 "failed to enum groups");
7631 case TORTURE_SAMR_MANY_ALIASES:
7632 torture_assert(tctx,
7633 test_EnumDomainAliases(b, tctx, domain_handle, &num_enum),
7634 "failed to enum aliases");
7642 switch (ctx->choice) {
7643 case TORTURE_SAMR_MANY_ACCOUNTS:
7644 torture_assert(tctx,
7645 test_QueryDisplayInfo_level(b, tctx, domain_handle, 1, &num_disp),
7646 "failed to query display info");
7648 case TORTURE_SAMR_MANY_GROUPS:
7649 torture_assert(tctx,
7650 test_QueryDisplayInfo_level(b, tctx, domain_handle, 3, &num_disp),
7651 "failed to query display info");
7653 case TORTURE_SAMR_MANY_ALIASES:
7654 /* no aliases in dispinfo */
7660 /* close or delete */
7662 for (i=0; i < num_total; i++) {
7664 if (ndr_policy_handle_empty(&handles[i])) {
7668 if (torture_setting_bool(tctx, "samba3", false)) {
7669 torture_assert(tctx,
7670 test_samr_handle_Close(b, tctx, &handles[i]),
7671 "failed to close handle");
7673 switch (ctx->choice) {
7674 case TORTURE_SAMR_MANY_ACCOUNTS:
7675 torture_assert(tctx,
7676 test_DeleteUser(b, tctx, &handles[i]),
7677 "failed to delete user");
7679 case TORTURE_SAMR_MANY_GROUPS:
7680 torture_assert(tctx,
7681 test_DeleteDomainGroup(b, tctx, &handles[i]),
7682 "failed to delete group");
7684 case TORTURE_SAMR_MANY_ALIASES:
7685 torture_assert(tctx,
7686 test_DeleteAlias(b, tctx, &handles[i]),
7687 "failed to delete alias");
7695 talloc_free(handles);
7697 if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
7698 torture_comment(tctx,
7699 "unexpected number of results (%u) returned in enum call, expected %u\n",
7700 num_enum, num_anounced + num_created);
7702 torture_comment(tctx,
7703 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
7704 num_disp, num_anounced + num_created);
7710 static bool test_Connect(struct dcerpc_binding_handle *b,
7711 struct torture_context *tctx,
7712 struct policy_handle *handle);
7714 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7715 struct torture_samr_context *ctx, struct dom_sid *sid)
7717 struct samr_OpenDomain r;
7718 struct policy_handle domain_handle;
7719 struct policy_handle alias_handle;
7720 struct policy_handle user_handle;
7721 struct policy_handle group_handle;
7723 struct dcerpc_binding_handle *b = p->binding_handle;
7725 ZERO_STRUCT(alias_handle);
7726 ZERO_STRUCT(user_handle);
7727 ZERO_STRUCT(group_handle);
7728 ZERO_STRUCT(domain_handle);
7730 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
7732 r.in.connect_handle = &ctx->handle;
7733 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7735 r.out.domain_handle = &domain_handle;
7737 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenDomain_r(b, tctx, &r),
7738 "OpenDomain failed");
7739 torture_assert_ntstatus_ok(tctx, r.out.result, "OpenDomain failed");
7741 /* run the domain tests with the main handle closed - this tests
7742 the servers reference counting */
7743 torture_assert(tctx, test_samr_handle_Close(b, tctx, &ctx->handle), "Failed to close SAMR handle");
7745 switch (ctx->choice) {
7746 case TORTURE_SAMR_PASSWORDS:
7747 case TORTURE_SAMR_USER_PRIVILEGES:
7748 if (!torture_setting_bool(tctx, "samba3", false)) {
7749 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7751 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7753 torture_warning(tctx, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
7756 case TORTURE_SAMR_USER_ATTRIBUTES:
7757 if (!torture_setting_bool(tctx, "samba3", false)) {
7758 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7760 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7761 /* This test needs 'complex' users to validate */
7762 ret &= test_QueryDisplayInfo(b, tctx, &domain_handle);
7764 torture_warning(tctx, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
7767 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
7768 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
7769 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
7770 if (!torture_setting_bool(tctx, "samba3", false)) {
7771 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
7773 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
7775 torture_warning(tctx, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx, sid));
7778 case TORTURE_SAMR_MANY_ACCOUNTS:
7779 case TORTURE_SAMR_MANY_GROUPS:
7780 case TORTURE_SAMR_MANY_ALIASES:
7781 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
7783 torture_warning(tctx, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
7786 case TORTURE_SAMR_OTHER:
7787 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7789 torture_warning(tctx, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
7791 if (!torture_setting_bool(tctx, "samba3", false)) {
7792 ret &= test_QuerySecurity(b, tctx, &domain_handle);
7794 ret &= test_RemoveMemberFromForeignDomain(b, tctx, &domain_handle);
7795 ret &= test_CreateAlias(b, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
7796 ret &= test_CreateDomainGroup(b, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
7797 ret &= test_GetAliasMembership(b, tctx, &domain_handle);
7798 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
7799 ret &= test_QueryDomainInfo2(b, tctx, &domain_handle);
7800 ret &= test_EnumDomainUsers_all(b, tctx, &domain_handle);
7801 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
7802 ret &= test_EnumDomainGroups_all(b, tctx, &domain_handle);
7803 ret &= test_EnumDomainAliases_all(b, tctx, &domain_handle);
7804 ret &= test_QueryDisplayInfo2(b, tctx, &domain_handle);
7805 ret &= test_QueryDisplayInfo3(b, tctx, &domain_handle);
7806 ret &= test_QueryDisplayInfo_continue(b, tctx, &domain_handle);
7808 if (torture_setting_bool(tctx, "samba4", false)) {
7809 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
7811 ret &= test_GetDisplayEnumerationIndex(b, tctx, &domain_handle);
7812 ret &= test_GetDisplayEnumerationIndex2(b, tctx, &domain_handle);
7814 ret &= test_GroupList(b, tctx, sid, &domain_handle);
7815 ret &= test_TestPrivateFunctionsDomain(b, tctx, &domain_handle);
7816 ret &= test_RidToSid(b, tctx, sid, &domain_handle);
7817 ret &= test_GetBootKeyInformation(b, tctx, &domain_handle);
7819 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
7824 if (!ndr_policy_handle_empty(&user_handle) &&
7825 !test_DeleteUser(b, tctx, &user_handle)) {
7829 if (!ndr_policy_handle_empty(&alias_handle) &&
7830 !test_DeleteAlias(b, tctx, &alias_handle)) {
7834 if (!ndr_policy_handle_empty(&group_handle) &&
7835 !test_DeleteDomainGroup(b, tctx, &group_handle)) {
7839 torture_assert(tctx, test_samr_handle_Close(b, tctx, &domain_handle), "Failed to close SAMR domain handle");
7841 torture_assert(tctx, test_Connect(b, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
7842 /* reconnect the main handle */
7845 torture_warning(tctx, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
7851 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7852 struct torture_samr_context *ctx, const char *domain)
7854 struct samr_LookupDomain r;
7855 struct dom_sid2 *sid = NULL;
7856 struct lsa_String n1;
7857 struct lsa_String n2;
7859 struct dcerpc_binding_handle *b = p->binding_handle;
7861 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
7863 /* check for correct error codes */
7864 r.in.connect_handle = &ctx->handle;
7865 r.in.domain_name = &n2;
7869 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7870 "LookupDomain failed");
7871 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, r.out.result, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
7873 init_lsa_String(&n2, "xxNODOMAINxx");
7875 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7876 "LookupDomain failed");
7877 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, r.out.result, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
7879 r.in.connect_handle = &ctx->handle;
7881 init_lsa_String(&n1, domain);
7882 r.in.domain_name = &n1;
7884 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7885 "LookupDomain failed");
7886 torture_assert_ntstatus_ok(tctx, r.out.result, "LookupDomain");
7888 if (!test_GetDomPwInfo(p, tctx, &n1)) {
7892 if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
7900 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
7901 struct torture_samr_context *ctx)
7903 struct samr_EnumDomains r;
7904 uint32_t resume_handle = 0;
7905 uint32_t num_entries = 0;
7906 struct samr_SamArray *sam = NULL;
7909 struct dcerpc_binding_handle *b = p->binding_handle;
7911 r.in.connect_handle = &ctx->handle;
7912 r.in.resume_handle = &resume_handle;
7913 r.in.buf_size = (uint32_t)-1;
7914 r.out.resume_handle = &resume_handle;
7915 r.out.num_entries = &num_entries;
7918 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
7919 "EnumDomains failed");
7920 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
7926 for (i=0;i<sam->count;i++) {
7927 if (!test_LookupDomain(p, tctx, ctx,
7928 sam->entries[i].name.string)) {
7933 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
7934 "EnumDomains failed");
7935 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
7941 static bool test_Connect(struct dcerpc_binding_handle *b,
7942 struct torture_context *tctx,
7943 struct policy_handle *handle)
7945 struct samr_Connect r;
7946 struct samr_Connect2 r2;
7947 struct samr_Connect3 r3;
7948 struct samr_Connect4 r4;
7949 struct samr_Connect5 r5;
7950 union samr_ConnectInfo info;
7951 struct policy_handle h;
7952 uint32_t level_out = 0;
7953 bool ret = true, got_handle = false;
7955 torture_comment(tctx, "Testing samr_Connect\n");
7957 r.in.system_name = NULL;
7958 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7959 r.out.connect_handle = &h;
7961 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect_r(b, tctx, &r),
7963 if (!NT_STATUS_IS_OK(r.out.result)) {
7964 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(r.out.result));
7971 torture_comment(tctx, "Testing samr_Connect2\n");
7973 r2.in.system_name = NULL;
7974 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7975 r2.out.connect_handle = &h;
7977 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect2_r(b, tctx, &r2),
7979 if (!NT_STATUS_IS_OK(r2.out.result)) {
7980 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(r2.out.result));
7984 test_samr_handle_Close(b, tctx, handle);
7990 torture_comment(tctx, "Testing samr_Connect3\n");
7992 r3.in.system_name = NULL;
7994 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7995 r3.out.connect_handle = &h;
7997 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect3_r(b, tctx, &r3),
7999 if (!NT_STATUS_IS_OK(r3.out.result)) {
8000 torture_warning(tctx, "Connect3 failed - %s\n", nt_errstr(r3.out.result));
8004 test_samr_handle_Close(b, tctx, handle);
8010 torture_comment(tctx, "Testing samr_Connect4\n");
8012 r4.in.system_name = "";
8013 r4.in.client_version = 0;
8014 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8015 r4.out.connect_handle = &h;
8017 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect4_r(b, tctx, &r4),
8019 if (!NT_STATUS_IS_OK(r4.out.result)) {
8020 torture_warning(tctx, "Connect4 failed - %s\n", nt_errstr(r4.out.result));
8024 test_samr_handle_Close(b, tctx, handle);
8030 torture_comment(tctx, "Testing samr_Connect5\n");
8032 info.info1.client_version = 0;
8033 info.info1.unknown2 = 0;
8035 r5.in.system_name = "";
8036 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8038 r5.out.level_out = &level_out;
8039 r5.in.info_in = &info;
8040 r5.out.info_out = &info;
8041 r5.out.connect_handle = &h;
8043 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect5_r(b, tctx, &r5),
8045 if (!NT_STATUS_IS_OK(r5.out.result)) {
8046 torture_warning(tctx, "Connect5 failed - %s\n", nt_errstr(r5.out.result));
8050 test_samr_handle_Close(b, tctx, handle);
8060 static bool test_samr_ValidatePassword(struct torture_context *tctx,
8061 struct dcerpc_pipe *p)
8063 struct samr_ValidatePassword r;
8064 union samr_ValidatePasswordReq req;
8065 union samr_ValidatePasswordRep *repp = NULL;
8067 const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
8069 struct dcerpc_binding_handle *b = p->binding_handle;
8071 torture_comment(tctx, "Testing samr_ValidatePassword\n");
8073 if (p->conn->transport.transport != NCACN_IP_TCP) {
8074 torture_comment(tctx, "samr_ValidatePassword only should succeed over NCACN_IP_TCP!\n");
8078 r.in.level = NetValidatePasswordReset;
8083 req.req3.account.string = "non-existent-account-aklsdji";
8085 for (i=0; passwords[i]; i++) {
8086 req.req3.password.string = passwords[i];
8088 status = dcerpc_samr_ValidatePassword_r(b, tctx, &r);
8089 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
8090 torture_skip(tctx, "ValidatePassword not supported by server\n");
8092 torture_assert_ntstatus_ok(tctx, status,
8093 "samr_ValidatePassword failed");
8094 torture_assert_ntstatus_ok(tctx, r.out.result,
8095 "samr_ValidatePassword failed");
8096 torture_comment(tctx, "Server %s password '%s' with code %i\n",
8097 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
8098 req.req3.password.string, repp->ctr3.status);
8104 bool torture_rpc_samr(struct torture_context *torture)
8107 struct dcerpc_pipe *p;
8109 struct torture_samr_context *ctx;
8110 struct dcerpc_binding_handle *b;
8112 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8113 if (!NT_STATUS_IS_OK(status)) {
8116 b = p->binding_handle;
8118 ctx = talloc_zero(torture, struct torture_samr_context);
8120 ctx->choice = TORTURE_SAMR_OTHER;
8122 ret &= test_Connect(b, torture, &ctx->handle);
8124 if (!torture_setting_bool(torture, "samba3", false)) {
8125 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8128 ret &= test_EnumDomains(p, torture, ctx);
8130 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8132 ret &= test_Shutdown(b, torture, &ctx->handle);
8134 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8140 bool torture_rpc_samr_users(struct torture_context *torture)
8143 struct dcerpc_pipe *p;
8145 struct torture_samr_context *ctx;
8146 struct dcerpc_binding_handle *b;
8148 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8149 if (!NT_STATUS_IS_OK(status)) {
8152 b = p->binding_handle;
8154 ctx = talloc_zero(torture, struct torture_samr_context);
8156 ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
8158 ret &= test_Connect(b, torture, &ctx->handle);
8160 if (!torture_setting_bool(torture, "samba3", false)) {
8161 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8164 ret &= test_EnumDomains(p, torture, ctx);
8166 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8168 ret &= test_Shutdown(b, torture, &ctx->handle);
8170 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8176 bool torture_rpc_samr_passwords(struct torture_context *torture)
8179 struct dcerpc_pipe *p;
8181 struct torture_samr_context *ctx;
8182 struct dcerpc_binding_handle *b;
8184 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8185 if (!NT_STATUS_IS_OK(status)) {
8188 b = p->binding_handle;
8190 ctx = talloc_zero(torture, struct torture_samr_context);
8192 ctx->choice = TORTURE_SAMR_PASSWORDS;
8194 ret &= test_Connect(b, torture, &ctx->handle);
8196 ret &= test_EnumDomains(p, torture, ctx);
8198 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8203 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
8204 struct dcerpc_pipe *p2,
8205 struct cli_credentials *machine_credentials)
8208 struct dcerpc_pipe *p;
8210 struct torture_samr_context *ctx;
8211 struct dcerpc_binding_handle *b;
8213 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8214 if (!NT_STATUS_IS_OK(status)) {
8217 b = p->binding_handle;
8219 ctx = talloc_zero(torture, struct torture_samr_context);
8221 ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
8222 ctx->machine_credentials = machine_credentials;
8224 ret &= test_Connect(b, torture, &ctx->handle);
8226 ret &= test_EnumDomains(p, torture, ctx);
8228 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8233 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
8235 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.pwdlastset");
8236 struct torture_rpc_tcase *tcase;
8238 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8240 TEST_ACCOUNT_NAME_PWD);
8242 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
8243 torture_rpc_samr_pwdlastset);
8248 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
8249 struct dcerpc_pipe *p2,
8250 struct cli_credentials *machine_credentials)
8253 struct dcerpc_pipe *p;
8255 struct torture_samr_context *ctx;
8256 struct dcerpc_binding_handle *b;
8258 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8259 if (!NT_STATUS_IS_OK(status)) {
8262 b = p->binding_handle;
8264 ctx = talloc_zero(torture, struct torture_samr_context);
8266 ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
8267 ctx->machine_credentials = machine_credentials;
8269 ret &= test_Connect(b, torture, &ctx->handle);
8271 ret &= test_EnumDomains(p, torture, ctx);
8273 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8278 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
8280 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.users.privileges");
8281 struct torture_rpc_tcase *tcase;
8283 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8285 TEST_ACCOUNT_NAME_PWD);
8287 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
8288 torture_rpc_samr_users_privileges_delete_user);
8293 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
8294 struct dcerpc_pipe *p2,
8298 struct dcerpc_pipe *p;
8300 struct torture_samr_context *ctx =
8301 talloc_get_type_abort(data, struct torture_samr_context);
8302 struct dcerpc_binding_handle *b;
8304 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8305 if (!NT_STATUS_IS_OK(status)) {
8308 b = p->binding_handle;
8310 ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
8311 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8312 ctx->num_objects_large_dc);
8314 ret &= test_Connect(b, torture, &ctx->handle);
8316 ret &= test_EnumDomains(p, torture, ctx);
8318 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8323 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
8324 struct dcerpc_pipe *p2,
8328 struct dcerpc_pipe *p;
8330 struct torture_samr_context *ctx =
8331 talloc_get_type_abort(data, struct torture_samr_context);
8332 struct dcerpc_binding_handle *b;
8334 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8335 if (!NT_STATUS_IS_OK(status)) {
8338 b = p->binding_handle;
8340 ctx->choice = TORTURE_SAMR_MANY_GROUPS;
8341 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8342 ctx->num_objects_large_dc);
8344 ret &= test_Connect(b, torture, &ctx->handle);
8346 ret &= test_EnumDomains(p, torture, ctx);
8348 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8353 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
8354 struct dcerpc_pipe *p2,
8358 struct dcerpc_pipe *p;
8360 struct torture_samr_context *ctx =
8361 talloc_get_type_abort(data, struct torture_samr_context);
8362 struct dcerpc_binding_handle *b;
8364 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8365 if (!NT_STATUS_IS_OK(status)) {
8368 b = p->binding_handle;
8370 ctx->choice = TORTURE_SAMR_MANY_ALIASES;
8371 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8372 ctx->num_objects_large_dc);
8374 ret &= test_Connect(b, torture, &ctx->handle);
8376 ret &= test_EnumDomains(p, torture, ctx);
8378 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8383 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
8385 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.large-dc");
8386 struct torture_rpc_tcase *tcase;
8387 struct torture_samr_context *ctx;
8389 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
8391 ctx = talloc_zero(suite, struct torture_samr_context);
8392 ctx->num_objects_large_dc = 150;
8394 torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
8395 torture_rpc_samr_many_aliases, ctx);
8396 torture_rpc_tcase_add_test_ex(tcase, "many_groups",
8397 torture_rpc_samr_many_groups, ctx);
8398 torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
8399 torture_rpc_samr_many_accounts, ctx);
8404 static bool torture_rpc_samr_badpwdcount(struct torture_context *torture,
8405 struct dcerpc_pipe *p2,
8406 struct cli_credentials *machine_credentials)
8409 struct dcerpc_pipe *p;
8411 struct torture_samr_context *ctx;
8412 struct dcerpc_binding_handle *b;
8414 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8415 if (!NT_STATUS_IS_OK(status)) {
8418 b = p->binding_handle;
8420 ctx = talloc_zero(torture, struct torture_samr_context);
8422 ctx->choice = TORTURE_SAMR_PASSWORDS_BADPWDCOUNT;
8423 ctx->machine_credentials = machine_credentials;
8425 ret &= test_Connect(b, torture, &ctx->handle);
8427 ret &= test_EnumDomains(p, torture, ctx);
8429 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8434 struct torture_suite *torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX *mem_ctx)
8436 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.badpwdcount");
8437 struct torture_rpc_tcase *tcase;
8439 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8441 TEST_ACCOUNT_NAME_PWD);
8443 torture_rpc_tcase_add_test_creds(tcase, "badPwdCount",
8444 torture_rpc_samr_badpwdcount);
8449 static bool torture_rpc_samr_lockout(struct torture_context *torture,
8450 struct dcerpc_pipe *p2,
8451 struct cli_credentials *machine_credentials)
8454 struct dcerpc_pipe *p;
8456 struct torture_samr_context *ctx;
8457 struct dcerpc_binding_handle *b;
8459 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8460 if (!NT_STATUS_IS_OK(status)) {
8463 b = p->binding_handle;
8465 ctx = talloc_zero(torture, struct torture_samr_context);
8467 ctx->choice = TORTURE_SAMR_PASSWORDS_LOCKOUT;
8468 ctx->machine_credentials = machine_credentials;
8470 ret &= test_Connect(b, torture, &ctx->handle);
8472 ret &= test_EnumDomains(p, torture, ctx);
8474 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8479 struct torture_suite *torture_rpc_samr_passwords_lockout(TALLOC_CTX *mem_ctx)
8481 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.lockout");
8482 struct torture_rpc_tcase *tcase;
8484 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8486 TEST_ACCOUNT_NAME_PWD);
8488 torture_rpc_tcase_add_test_creds(tcase, "lockout",
8489 torture_rpc_samr_lockout);
8494 struct torture_suite *torture_rpc_samr_passwords_validate(TALLOC_CTX *mem_ctx)
8496 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.validate");
8497 struct torture_rpc_tcase *tcase;
8499 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr",
8501 torture_rpc_tcase_add_test(tcase, "validate",
8502 test_samr_ValidatePassword);