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 if (torture_setting_bool(tctx, "samba3", false)) {
4107 lockout_seconds = 60;
4110 torture_comment(tctx, "\nTesting account lockout: %s\n", comment);
4114 info.info1 = *info1;
4116 torture_comment(tctx, "setting password history length.\n");
4117 info.info1.password_history_length = password_history_length;
4119 torture_assert(tctx,
4120 test_SetDomainInfo(b, tctx, domain_handle,
4121 DomainPasswordInformation, &info),
4122 "failed to set password history length");
4124 info.info12 = *info12;
4125 info.info12.lockout_threshold = lockout_threshold;
4127 /* set lockout duration < lockout window: should fail */
4128 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4129 info.info12.lockout_window = ~((lockout_seconds + 1) * delta_time_factor);
4131 torture_assert(tctx,
4132 test_SetDomainInfo_ntstatus(b, tctx, domain_handle,
4133 DomainLockoutInformation, &info,
4134 NT_STATUS_INVALID_PARAMETER),
4135 "setting lockout duration < lockout window gave unexpected result");
4137 info.info12.lockout_duration = 0;
4138 info.info12.lockout_window = 0;
4140 torture_assert(tctx,
4141 test_SetDomainInfo(b, tctx, domain_handle,
4142 DomainLockoutInformation, &info),
4143 "failed to set lockout window and duration to 0");
4146 /* set lockout duration of 5 seconds */
4147 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4148 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
4150 torture_assert(tctx,
4151 test_SetDomainInfo(b, tctx, domain_handle,
4152 DomainLockoutInformation, &info),
4153 "failed to set lockout window and duration to 5 seconds");
4155 /* reset bad pwd count */
4157 torture_assert(tctx,
4158 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
4161 /* enable or disable account */
4164 torture_assert(tctx,
4165 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4166 acct_flags | ACB_DISABLED),
4167 "failed to disable user");
4169 torture_assert(tctx,
4170 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4171 acct_flags & ~ACB_DISABLED),
4172 "failed to enable user");
4176 /* test logon with right password */
4178 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4179 acct_name, *password,
4180 expected_success_status, interactive)) {
4181 torture_fail(tctx, "failed to auth with latest password");
4184 torture_assert(tctx,
4185 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4186 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
4189 /* test with wrong password ==> lockout */
4191 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4192 acct_name, "random_crap",
4193 NT_STATUS_WRONG_PASSWORD, interactive)) {
4194 torture_fail(tctx, "succeeded to authenticate with wrong password");
4197 torture_assert(tctx,
4198 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4199 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4201 torture_assert(tctx,
4202 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4203 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4204 "expected account to be locked");
4207 /* test with good password */
4209 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4211 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4213 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4216 /* bad pwd count should not get updated */
4217 torture_assert(tctx,
4218 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4219 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4221 /* curiously, windows does _not_ set the autlock flag */
4222 torture_assert(tctx,
4223 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4224 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4225 "expected account to be locked");
4228 /* with bad password */
4230 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4231 acct_name, "random_crap2",
4232 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4234 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4237 /* bad pwd count should not get updated */
4238 torture_assert(tctx,
4239 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4240 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4242 /* curiously, windows does _not_ set the autlock flag */
4243 torture_assert(tctx,
4244 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4245 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4246 "expected account to be locked");
4249 /* let lockout duration expire ==> unlock */
4251 torture_comment(tctx, "let lockout duration expire...\n");
4252 sleep(lockout_seconds + 1);
4254 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4256 expected_success_status, interactive))
4258 torture_fail(tctx, "failed to authenticate after lockout expired");
4261 torture_assert(tctx,
4262 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4263 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4264 "expected account not to be locked");
4269 static bool test_Password_lockout_wrap(struct dcerpc_pipe *p,
4270 struct torture_context *tctx,
4271 uint32_t acct_flags,
4272 const char *acct_name,
4273 struct policy_handle *domain_handle,
4274 struct policy_handle *user_handle,
4276 struct cli_credentials *machine_credentials)
4278 union samr_DomainInfo *q_info, s_info;
4279 struct samr_DomInfo1 info1, _info1;
4280 struct samr_DomInfo12 info12, _info12;
4282 struct dcerpc_binding_handle *b = p->binding_handle;
4283 struct dcerpc_pipe *np;
4287 const char *comment;
4290 NTSTATUS expected_success_status;
4293 .comment = "network logon (disabled account)",
4295 .interactive = false,
4296 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4299 .comment = "network logon (enabled account)",
4301 .interactive = false,
4302 .expected_success_status= NT_STATUS_OK
4305 .comment = "interactive logon (disabled account)",
4307 .interactive = true,
4308 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4311 .comment = "interactive logon (enabled account)",
4313 .interactive = true,
4314 .expected_success_status= NT_STATUS_OK
4318 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4320 /* backup old policies */
4322 torture_assert(tctx,
4323 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4324 DomainPasswordInformation, &q_info),
4325 "failed to query domain info level 1");
4327 info1 = q_info->info1;
4330 torture_assert(tctx,
4331 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4332 DomainLockoutInformation, &q_info),
4333 "failed to query domain info level 12");
4335 info12 = q_info->info12;
4340 for (i=0; i < ARRAY_SIZE(creds); i++) {
4342 /* skip trust tests for now */
4343 if (acct_flags & ACB_WSTRUST ||
4344 acct_flags & ACB_SVRTRUST ||
4345 acct_flags & ACB_DOMTRUST) {
4349 ret &= test_Password_lockout(p, np, tctx, acct_flags, acct_name,
4350 domain_handle, user_handle, password,
4351 machine_credentials,
4354 creds[i].interactive,
4355 creds[i].expected_success_status,
4358 torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
4360 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4364 /* restore policies */
4366 s_info.info1 = info1;
4368 torture_assert(tctx,
4369 test_SetDomainInfo(b, tctx, domain_handle,
4370 DomainPasswordInformation, &s_info),
4371 "failed to set password information");
4373 s_info.info12 = info12;
4375 torture_assert(tctx,
4376 test_SetDomainInfo(b, tctx, domain_handle,
4377 DomainLockoutInformation, &s_info),
4378 "failed to set lockout information");
4383 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
4384 struct dcerpc_pipe *lp,
4385 struct torture_context *tctx,
4386 struct policy_handle *domain_handle,
4387 struct policy_handle *lsa_handle,
4388 struct policy_handle *user_handle,
4389 const struct dom_sid *domain_sid,
4391 struct cli_credentials *machine_credentials)
4394 struct dcerpc_binding_handle *b = p->binding_handle;
4395 struct dcerpc_binding_handle *lb = lp->binding_handle;
4397 struct policy_handle lsa_acct_handle;
4398 struct dom_sid *user_sid;
4400 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
4403 struct lsa_EnumAccountRights r;
4404 struct lsa_RightSet rights;
4406 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4408 r.in.handle = lsa_handle;
4409 r.in.sid = user_sid;
4410 r.out.rights = &rights;
4412 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4413 "lsa_EnumAccountRights failed");
4414 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4415 "Expected enum rights for account to fail");
4419 struct lsa_RightSet rights;
4420 struct lsa_StringLarge names[2];
4421 struct lsa_AddAccountRights r;
4423 torture_comment(tctx, "Testing LSA AddAccountRights\n");
4425 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
4426 init_lsa_StringLarge(&names[1], NULL);
4429 rights.names = names;
4431 r.in.handle = lsa_handle;
4432 r.in.sid = user_sid;
4433 r.in.rights = &rights;
4435 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
4436 "lsa_AddAccountRights failed");
4437 torture_assert_ntstatus_ok(tctx, r.out.result,
4438 "Failed to add privileges");
4442 struct lsa_EnumAccounts r;
4443 uint32_t resume_handle = 0;
4444 struct lsa_SidArray lsa_sid_array;
4446 bool found_sid = false;
4448 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4450 r.in.handle = lsa_handle;
4451 r.in.num_entries = 0x1000;
4452 r.in.resume_handle = &resume_handle;
4453 r.out.sids = &lsa_sid_array;
4454 r.out.resume_handle = &resume_handle;
4456 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4457 "lsa_EnumAccounts failed");
4458 torture_assert_ntstatus_ok(tctx, r.out.result,
4459 "Failed to enum accounts");
4461 for (i=0; i < lsa_sid_array.num_sids; i++) {
4462 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4467 torture_assert(tctx, found_sid,
4468 "failed to list privileged account");
4472 struct lsa_EnumAccountRights r;
4473 struct lsa_RightSet user_rights;
4475 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4477 r.in.handle = lsa_handle;
4478 r.in.sid = user_sid;
4479 r.out.rights = &user_rights;
4481 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4482 "lsa_EnumAccountRights failed");
4483 torture_assert_ntstatus_ok(tctx, r.out.result,
4484 "Failed to enum rights for account");
4486 if (user_rights.count < 1) {
4487 torture_warning(tctx, "failed to find newly added rights");
4493 struct lsa_OpenAccount r;
4495 torture_comment(tctx, "Testing LSA OpenAccount\n");
4497 r.in.handle = lsa_handle;
4498 r.in.sid = user_sid;
4499 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4500 r.out.acct_handle = &lsa_acct_handle;
4502 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4503 "lsa_OpenAccount failed");
4504 torture_assert_ntstatus_ok(tctx, r.out.result,
4505 "Failed to open lsa account");
4509 struct lsa_GetSystemAccessAccount r;
4510 uint32_t access_mask;
4512 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4514 r.in.handle = &lsa_acct_handle;
4515 r.out.access_mask = &access_mask;
4517 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4518 "lsa_GetSystemAccessAccount failed");
4519 torture_assert_ntstatus_ok(tctx, r.out.result,
4520 "Failed to get lsa system access account");
4526 torture_comment(tctx, "Testing LSA Close\n");
4528 r.in.handle = &lsa_acct_handle;
4529 r.out.handle = &lsa_acct_handle;
4531 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(lb, tctx, &r),
4532 "lsa_Close failed");
4533 torture_assert_ntstatus_ok(tctx, r.out.result,
4534 "Failed to close lsa");
4538 struct samr_DeleteUser r;
4540 torture_comment(tctx, "Testing SAMR DeleteUser\n");
4542 r.in.user_handle = user_handle;
4543 r.out.user_handle = user_handle;
4545 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &r),
4546 "DeleteUser failed");
4547 torture_assert_ntstatus_ok(tctx, r.out.result,
4548 "DeleteUser failed");
4552 struct lsa_EnumAccounts r;
4553 uint32_t resume_handle = 0;
4554 struct lsa_SidArray lsa_sid_array;
4556 bool found_sid = false;
4558 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4560 r.in.handle = lsa_handle;
4561 r.in.num_entries = 0x1000;
4562 r.in.resume_handle = &resume_handle;
4563 r.out.sids = &lsa_sid_array;
4564 r.out.resume_handle = &resume_handle;
4566 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4567 "lsa_EnumAccounts failed");
4568 torture_assert_ntstatus_ok(tctx, r.out.result,
4569 "Failed to enum accounts");
4571 for (i=0; i < lsa_sid_array.num_sids; i++) {
4572 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4577 torture_assert(tctx, found_sid,
4578 "failed to list privileged account");
4582 struct lsa_EnumAccountRights r;
4583 struct lsa_RightSet user_rights;
4585 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4587 r.in.handle = lsa_handle;
4588 r.in.sid = user_sid;
4589 r.out.rights = &user_rights;
4591 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4592 "lsa_EnumAccountRights failed");
4593 torture_assert_ntstatus_ok(tctx, r.out.result,
4594 "Failed to enum rights for account");
4596 if (user_rights.count < 1) {
4597 torture_warning(tctx, "failed to find newly added rights");
4603 struct lsa_OpenAccount r;
4605 torture_comment(tctx, "Testing LSA OpenAccount\n");
4607 r.in.handle = lsa_handle;
4608 r.in.sid = user_sid;
4609 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4610 r.out.acct_handle = &lsa_acct_handle;
4612 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4613 "lsa_OpenAccount failed");
4614 torture_assert_ntstatus_ok(tctx, r.out.result,
4615 "Failed to open lsa account");
4619 struct lsa_GetSystemAccessAccount r;
4620 uint32_t access_mask;
4622 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4624 r.in.handle = &lsa_acct_handle;
4625 r.out.access_mask = &access_mask;
4627 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4628 "lsa_GetSystemAccessAccount failed");
4629 torture_assert_ntstatus_ok(tctx, r.out.result,
4630 "Failed to get lsa system access account");
4634 struct lsa_DeleteObject r;
4636 torture_comment(tctx, "Testing LSA DeleteObject\n");
4638 r.in.handle = &lsa_acct_handle;
4639 r.out.handle = &lsa_acct_handle;
4641 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(lb, tctx, &r),
4642 "lsa_DeleteObject failed");
4643 torture_assert_ntstatus_ok(tctx, r.out.result,
4644 "Failed to delete object");
4648 struct lsa_EnumAccounts r;
4649 uint32_t resume_handle = 0;
4650 struct lsa_SidArray lsa_sid_array;
4652 bool found_sid = false;
4654 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4656 r.in.handle = lsa_handle;
4657 r.in.num_entries = 0x1000;
4658 r.in.resume_handle = &resume_handle;
4659 r.out.sids = &lsa_sid_array;
4660 r.out.resume_handle = &resume_handle;
4662 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4663 "lsa_EnumAccounts failed");
4664 torture_assert_ntstatus_ok(tctx, r.out.result,
4665 "Failed to enum accounts");
4667 for (i=0; i < lsa_sid_array.num_sids; i++) {
4668 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4673 torture_assert(tctx, !found_sid,
4674 "should not have listed privileged account");
4678 struct lsa_EnumAccountRights r;
4679 struct lsa_RightSet user_rights;
4681 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4683 r.in.handle = lsa_handle;
4684 r.in.sid = user_sid;
4685 r.out.rights = &user_rights;
4687 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4688 "lsa_EnumAccountRights failed");
4689 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4690 "Failed to enum rights for account");
4696 static bool test_user_ops(struct dcerpc_pipe *p,
4697 struct torture_context *tctx,
4698 struct policy_handle *user_handle,
4699 struct policy_handle *domain_handle,
4700 const struct dom_sid *domain_sid,
4701 uint32_t base_acct_flags,
4702 const char *base_acct_name, enum torture_samr_choice which_ops,
4703 struct cli_credentials *machine_credentials)
4705 char *password = NULL;
4706 struct samr_QueryUserInfo q;
4707 union samr_UserInfo *info;
4709 struct dcerpc_binding_handle *b = p->binding_handle;
4714 const uint32_t password_fields[] = {
4715 SAMR_FIELD_NT_PASSWORD_PRESENT,
4716 SAMR_FIELD_LM_PASSWORD_PRESENT,
4717 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
4721 status = test_LookupName(b, tctx, domain_handle, base_acct_name, &rid);
4722 if (!NT_STATUS_IS_OK(status)) {
4726 switch (which_ops) {
4727 case TORTURE_SAMR_USER_ATTRIBUTES:
4728 if (!test_QuerySecurity(b, tctx, user_handle)) {
4732 if (!test_QueryUserInfo(b, tctx, user_handle)) {
4736 if (!test_QueryUserInfo2(b, tctx, user_handle)) {
4740 if (!test_SetUserInfo(b, tctx, user_handle, base_acct_flags,
4745 if (!test_GetUserPwInfo(b, tctx, user_handle)) {
4749 if (!test_TestPrivateFunctionsUser(b, tctx, user_handle)) {
4753 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
4757 case TORTURE_SAMR_PASSWORDS:
4758 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
4759 char simple_pass[9];
4760 char *v = generate_random_str(tctx, 1);
4762 ZERO_STRUCT(simple_pass);
4763 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4765 torture_comment(tctx, "Testing machine account password policy rules\n");
4767 /* Workstation trust accounts don't seem to need to honour password quality policy */
4768 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4772 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
4776 /* reset again, to allow another 'user' password change */
4777 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4781 /* Try a 'short' password */
4782 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
4786 /* Try a compleatly random password */
4787 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
4792 for (i = 0; password_fields[i]; i++) {
4793 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
4797 /* check it was set right */
4798 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4803 for (i = 0; password_fields[i]; i++) {
4804 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
4808 /* check it was set right */
4809 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4814 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
4818 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
4822 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
4826 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4830 for (i = 0; password_fields[i]; i++) {
4832 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
4833 /* we need to skip as that would break
4834 * the ChangePasswordUser3 verify */
4838 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
4842 /* check it was set right */
4843 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4848 q.in.user_handle = user_handle;
4852 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
4853 "QueryUserInfo failed");
4854 if (!NT_STATUS_IS_OK(q.out.result)) {
4855 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4856 q.in.level, nt_errstr(q.out.result));
4859 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4860 if ((info->info5.acct_flags) != expected_flags) {
4861 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4862 info->info5.acct_flags,
4865 if (!torture_setting_bool(tctx, "samba3", false)) {
4869 if (info->info5.rid != rid) {
4870 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
4871 info->info5.rid, rid);
4878 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
4880 /* test last password change timestamp behaviour */
4881 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
4883 user_handle, &password,
4884 machine_credentials)) {
4889 torture_comment(tctx, "pwdLastSet test succeeded\n");
4891 torture_warning(tctx, "pwdLastSet test failed\n");
4896 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
4898 /* test bad pwd count change behaviour */
4899 if (!test_Password_badpwdcount_wrap(p, tctx, base_acct_flags,
4902 user_handle, &password,
4903 machine_credentials)) {
4908 torture_comment(tctx, "badPwdCount test succeeded\n");
4910 torture_warning(tctx, "badPwdCount test failed\n");
4915 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
4917 if (!test_Password_lockout_wrap(p, tctx, base_acct_flags,
4920 user_handle, &password,
4921 machine_credentials))
4927 torture_comment(tctx, "lockout test succeeded\n");
4929 torture_warning(tctx, "lockout test failed\n");
4935 case TORTURE_SAMR_USER_PRIVILEGES: {
4937 struct dcerpc_pipe *lp;
4938 struct policy_handle *lsa_handle;
4939 struct dcerpc_binding_handle *lb;
4941 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
4942 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
4943 lb = lp->binding_handle;
4945 if (!test_lsa_OpenPolicy2(lb, tctx, &lsa_handle)) {
4949 if (!test_DeleteUser_with_privs(p, lp, tctx,
4950 domain_handle, lsa_handle, user_handle,
4952 machine_credentials)) {
4956 if (!test_lsa_Close(lb, tctx, lsa_handle)) {
4961 torture_warning(tctx, "privileged user delete test failed\n");
4966 case TORTURE_SAMR_OTHER:
4967 case TORTURE_SAMR_MANY_ACCOUNTS:
4968 case TORTURE_SAMR_MANY_GROUPS:
4969 case TORTURE_SAMR_MANY_ALIASES:
4970 /* We just need the account to exist */
4976 static bool test_alias_ops(struct dcerpc_binding_handle *b,
4977 struct torture_context *tctx,
4978 struct policy_handle *alias_handle,
4979 const struct dom_sid *domain_sid)
4983 if (!torture_setting_bool(tctx, "samba3", false)) {
4984 if (!test_QuerySecurity(b, tctx, alias_handle)) {
4989 if (!test_QueryAliasInfo(b, tctx, alias_handle)) {
4993 if (!test_SetAliasInfo(b, tctx, alias_handle)) {
4997 if (!test_AddMemberToAlias(b, tctx, alias_handle, domain_sid)) {
5001 if (torture_setting_bool(tctx, "samba3", false) ||
5002 torture_setting_bool(tctx, "samba4", false)) {
5003 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
5007 if (!test_AddMultipleMembersToAlias(b, tctx, alias_handle)) {
5015 static bool test_DeleteUser(struct dcerpc_binding_handle *b,
5016 struct torture_context *tctx,
5017 struct policy_handle *user_handle)
5019 struct samr_DeleteUser d;
5020 torture_comment(tctx, "Testing DeleteUser\n");
5022 d.in.user_handle = user_handle;
5023 d.out.user_handle = user_handle;
5025 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
5026 "DeleteUser failed");
5027 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteUser");
5032 bool test_DeleteUser_byname(struct dcerpc_binding_handle *b,
5033 struct torture_context *tctx,
5034 struct policy_handle *handle, const char *name)
5037 struct samr_DeleteUser d;
5038 struct policy_handle user_handle;
5041 status = test_LookupName(b, tctx, handle, name, &rid);
5042 if (!NT_STATUS_IS_OK(status)) {
5046 status = test_OpenUser_byname(b, tctx, handle, name, &user_handle);
5047 if (!NT_STATUS_IS_OK(status)) {
5051 d.in.user_handle = &user_handle;
5052 d.out.user_handle = &user_handle;
5053 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
5054 "DeleteUser failed");
5055 if (!NT_STATUS_IS_OK(d.out.result)) {
5056 status = d.out.result;
5063 torture_warning(tctx, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
5068 static bool test_DeleteGroup_byname(struct dcerpc_binding_handle *b,
5069 struct torture_context *tctx,
5070 struct policy_handle *handle, const char *name)
5073 struct samr_OpenGroup r;
5074 struct samr_DeleteDomainGroup d;
5075 struct policy_handle group_handle;
5078 status = test_LookupName(b, tctx, handle, name, &rid);
5079 if (!NT_STATUS_IS_OK(status)) {
5083 r.in.domain_handle = handle;
5084 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5086 r.out.group_handle = &group_handle;
5087 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
5088 "OpenGroup failed");
5089 if (!NT_STATUS_IS_OK(r.out.result)) {
5090 status = r.out.result;
5094 d.in.group_handle = &group_handle;
5095 d.out.group_handle = &group_handle;
5096 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
5097 "DeleteDomainGroup failed");
5098 if (!NT_STATUS_IS_OK(d.out.result)) {
5099 status = d.out.result;
5106 torture_warning(tctx, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
5111 static bool test_DeleteAlias_byname(struct dcerpc_binding_handle *b,
5112 struct torture_context *tctx,
5113 struct policy_handle *domain_handle,
5117 struct samr_OpenAlias r;
5118 struct samr_DeleteDomAlias d;
5119 struct policy_handle alias_handle;
5122 torture_comment(tctx, "Testing DeleteAlias_byname\n");
5124 status = test_LookupName(b, tctx, domain_handle, name, &rid);
5125 if (!NT_STATUS_IS_OK(status)) {
5129 r.in.domain_handle = domain_handle;
5130 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5132 r.out.alias_handle = &alias_handle;
5133 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5134 "OpenAlias failed");
5135 if (!NT_STATUS_IS_OK(r.out.result)) {
5136 status = r.out.result;
5140 d.in.alias_handle = &alias_handle;
5141 d.out.alias_handle = &alias_handle;
5142 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5143 "DeleteDomAlias failed");
5144 if (!NT_STATUS_IS_OK(d.out.result)) {
5145 status = d.out.result;
5152 torture_warning(tctx, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
5156 static bool test_DeleteAlias(struct dcerpc_binding_handle *b,
5157 struct torture_context *tctx,
5158 struct policy_handle *alias_handle)
5160 struct samr_DeleteDomAlias d;
5163 torture_comment(tctx, "Testing DeleteAlias\n");
5165 d.in.alias_handle = alias_handle;
5166 d.out.alias_handle = alias_handle;
5168 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5169 "DeleteDomAlias failed");
5170 if (!NT_STATUS_IS_OK(d.out.result)) {
5171 torture_warning(tctx, "DeleteAlias failed - %s\n", nt_errstr(d.out.result));
5178 static bool test_CreateAlias(struct dcerpc_binding_handle *b,
5179 struct torture_context *tctx,
5180 struct policy_handle *domain_handle,
5181 const char *alias_name,
5182 struct policy_handle *alias_handle,
5183 const struct dom_sid *domain_sid,
5186 struct samr_CreateDomAlias r;
5187 struct lsa_String name;
5191 init_lsa_String(&name, alias_name);
5192 r.in.domain_handle = domain_handle;
5193 r.in.alias_name = &name;
5194 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5195 r.out.alias_handle = alias_handle;
5198 torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
5200 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5201 "CreateDomAlias failed");
5203 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5204 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
5205 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
5208 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
5209 nt_errstr(r.out.result));
5214 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ALIAS_EXISTS)) {
5215 if (!test_DeleteAlias_byname(b, tctx, domain_handle, r.in.alias_name->string)) {
5218 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5219 "CreateDomAlias failed");
5222 if (!NT_STATUS_IS_OK(r.out.result)) {
5223 torture_warning(tctx, "CreateAlias failed - %s\n", nt_errstr(r.out.result));
5231 if (!test_alias_ops(b, tctx, alias_handle, domain_sid)) {
5238 static bool test_ChangePassword(struct dcerpc_pipe *p,
5239 struct torture_context *tctx,
5240 const char *acct_name,
5241 struct policy_handle *domain_handle, char **password)
5244 struct dcerpc_binding_handle *b = p->binding_handle;
5250 if (!test_ChangePasswordUser(b, tctx, acct_name, domain_handle, password)) {
5254 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
5258 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
5262 /* test what happens when setting the old password again */
5263 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
5268 char simple_pass[9];
5269 char *v = generate_random_str(tctx, 1);
5271 ZERO_STRUCT(simple_pass);
5272 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5274 /* test what happens when picking a simple password */
5275 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
5280 /* set samr_SetDomainInfo level 1 with min_length 5 */
5282 struct samr_QueryDomainInfo r;
5283 union samr_DomainInfo *info = NULL;
5284 struct samr_SetDomainInfo s;
5285 uint16_t len_old, len;
5286 uint32_t pwd_prop_old;
5287 int64_t min_pwd_age_old;
5291 r.in.domain_handle = domain_handle;
5295 torture_comment(tctx, "Testing samr_QueryDomainInfo level 1\n");
5296 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
5297 "QueryDomainInfo failed");
5298 if (!NT_STATUS_IS_OK(r.out.result)) {
5302 s.in.domain_handle = domain_handle;
5306 /* remember the old min length, so we can reset it */
5307 len_old = s.in.info->info1.min_password_length;
5308 s.in.info->info1.min_password_length = len;
5309 pwd_prop_old = s.in.info->info1.password_properties;
5310 /* turn off password complexity checks for this test */
5311 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
5313 min_pwd_age_old = s.in.info->info1.min_password_age;
5314 s.in.info->info1.min_password_age = 0;
5316 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5317 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5318 "SetDomainInfo failed");
5319 if (!NT_STATUS_IS_OK(s.out.result)) {
5323 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
5325 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
5329 s.in.info->info1.min_password_length = len_old;
5330 s.in.info->info1.password_properties = pwd_prop_old;
5331 s.in.info->info1.min_password_age = min_pwd_age_old;
5333 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5334 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5335 "SetDomainInfo failed");
5336 if (!NT_STATUS_IS_OK(s.out.result)) {
5343 struct samr_OpenUser r;
5344 struct samr_QueryUserInfo q;
5345 union samr_UserInfo *info;
5346 struct samr_LookupNames n;
5347 struct policy_handle user_handle;
5348 struct samr_Ids rids, types;
5350 n.in.domain_handle = domain_handle;
5352 n.in.names = talloc_array(tctx, struct lsa_String, 1);
5353 n.in.names[0].string = acct_name;
5355 n.out.types = &types;
5357 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
5358 "LookupNames failed");
5359 if (!NT_STATUS_IS_OK(n.out.result)) {
5360 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(n.out.result));
5364 r.in.domain_handle = domain_handle;
5365 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5366 r.in.rid = n.out.rids->ids[0];
5367 r.out.user_handle = &user_handle;
5369 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5371 if (!NT_STATUS_IS_OK(r.out.result)) {
5372 torture_warning(tctx, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(r.out.result));
5376 q.in.user_handle = &user_handle;
5380 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5381 "QueryUserInfo failed");
5382 if (!NT_STATUS_IS_OK(q.out.result)) {
5383 torture_warning(tctx, "QueryUserInfo failed - %s\n", nt_errstr(q.out.result));
5387 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
5389 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
5390 info->info5.last_password_change, true)) {
5395 /* we change passwords twice - this has the effect of verifying
5396 they were changed correctly for the final call */
5397 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5401 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5408 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
5409 struct policy_handle *domain_handle,
5410 const char *user_name,
5411 struct policy_handle *user_handle_out,
5412 struct dom_sid *domain_sid,
5413 enum torture_samr_choice which_ops,
5414 struct cli_credentials *machine_credentials,
5418 TALLOC_CTX *user_ctx;
5420 struct samr_CreateUser r;
5421 struct samr_QueryUserInfo q;
5422 union samr_UserInfo *info;
5423 struct samr_DeleteUser d;
5426 /* This call creates a 'normal' account - check that it really does */
5427 const uint32_t acct_flags = ACB_NORMAL;
5428 struct lsa_String name;
5430 struct dcerpc_binding_handle *b = p->binding_handle;
5432 struct policy_handle user_handle;
5433 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5434 init_lsa_String(&name, user_name);
5436 r.in.domain_handle = domain_handle;
5437 r.in.account_name = &name;
5438 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5439 r.out.user_handle = &user_handle;
5442 torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
5444 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5445 "CreateUser failed");
5447 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5448 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5449 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5452 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5453 nt_errstr(r.out.result));
5458 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5459 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5460 talloc_free(user_ctx);
5463 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5464 "CreateUser failed");
5467 if (!NT_STATUS_IS_OK(r.out.result)) {
5468 talloc_free(user_ctx);
5469 torture_warning(tctx, "CreateUser failed - %s\n", nt_errstr(r.out.result));
5474 if (user_handle_out) {
5475 *user_handle_out = user_handle;
5481 q.in.user_handle = &user_handle;
5485 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5486 "QueryUserInfo failed");
5487 if (!NT_STATUS_IS_OK(q.out.result)) {
5488 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5489 q.in.level, nt_errstr(q.out.result));
5492 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
5493 torture_warning(tctx, "QueryUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5494 info->info16.acct_flags,
5500 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5501 domain_sid, acct_flags, name.string, which_ops,
5502 machine_credentials)) {
5506 if (user_handle_out) {
5507 *user_handle_out = user_handle;
5509 torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
5511 d.in.user_handle = &user_handle;
5512 d.out.user_handle = &user_handle;
5514 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5515 "DeleteUser failed");
5516 if (!NT_STATUS_IS_OK(d.out.result)) {
5517 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5524 talloc_free(user_ctx);
5530 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
5531 struct policy_handle *domain_handle,
5532 struct dom_sid *domain_sid,
5533 enum torture_samr_choice which_ops,
5534 struct cli_credentials *machine_credentials)
5536 struct samr_CreateUser2 r;
5537 struct samr_QueryUserInfo q;
5538 union samr_UserInfo *info;
5539 struct samr_DeleteUser d;
5540 struct policy_handle user_handle;
5542 struct lsa_String name;
5545 struct dcerpc_binding_handle *b = p->binding_handle;
5548 uint32_t acct_flags;
5549 const char *account_name;
5551 } account_types[] = {
5552 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
5553 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5554 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5555 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5556 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5557 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5558 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5559 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5560 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5561 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
5562 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5563 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5564 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5565 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5566 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
5569 for (i = 0; account_types[i].account_name; i++) {
5570 TALLOC_CTX *user_ctx;
5571 uint32_t acct_flags = account_types[i].acct_flags;
5572 uint32_t access_granted;
5573 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5574 init_lsa_String(&name, account_types[i].account_name);
5576 r.in.domain_handle = domain_handle;
5577 r.in.account_name = &name;
5578 r.in.acct_flags = acct_flags;
5579 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5580 r.out.user_handle = &user_handle;
5581 r.out.access_granted = &access_granted;
5584 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
5586 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5587 "CreateUser2 failed");
5589 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5590 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5591 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5594 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5595 nt_errstr(r.out.result));
5601 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5602 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5603 talloc_free(user_ctx);
5607 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5608 "CreateUser2 failed");
5611 if (!NT_STATUS_EQUAL(r.out.result, account_types[i].nt_status)) {
5612 torture_warning(tctx, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5613 nt_errstr(r.out.result), nt_errstr(account_types[i].nt_status));
5617 if (NT_STATUS_IS_OK(r.out.result)) {
5618 q.in.user_handle = &user_handle;
5622 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5623 "QueryUserInfo failed");
5624 if (!NT_STATUS_IS_OK(q.out.result)) {
5625 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5626 q.in.level, nt_errstr(q.out.result));
5629 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
5630 if (acct_flags == ACB_NORMAL) {
5631 expected_flags |= ACB_PW_EXPIRED;
5633 if ((info->info5.acct_flags) != expected_flags) {
5634 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5635 info->info5.acct_flags,
5639 switch (acct_flags) {
5641 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
5642 torture_warning(tctx, "QueryUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5643 DOMAIN_RID_DCS, info->info5.primary_gid);
5648 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
5649 torture_warning(tctx, "QueryUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5650 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
5655 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
5656 torture_warning(tctx, "QueryUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5657 DOMAIN_RID_USERS, info->info5.primary_gid);
5664 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5665 domain_sid, acct_flags, name.string, which_ops,
5666 machine_credentials)) {
5670 if (!ndr_policy_handle_empty(&user_handle)) {
5671 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
5673 d.in.user_handle = &user_handle;
5674 d.out.user_handle = &user_handle;
5676 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5677 "DeleteUser failed");
5678 if (!NT_STATUS_IS_OK(d.out.result)) {
5679 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5684 talloc_free(user_ctx);
5690 static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
5691 struct torture_context *tctx,
5692 struct policy_handle *handle)
5694 struct samr_QueryAliasInfo r;
5695 union samr_AliasInfo *info;
5696 uint16_t levels[] = {1, 2, 3};
5700 for (i=0;i<ARRAY_SIZE(levels);i++) {
5701 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
5703 r.in.alias_handle = handle;
5704 r.in.level = levels[i];
5707 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &r),
5708 "QueryAliasInfo failed");
5709 if (!NT_STATUS_IS_OK(r.out.result)) {
5710 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
5711 levels[i], nt_errstr(r.out.result));
5719 static bool test_QueryGroupInfo(struct dcerpc_binding_handle *b,
5720 struct torture_context *tctx,
5721 struct policy_handle *handle)
5723 struct samr_QueryGroupInfo r;
5724 union samr_GroupInfo *info;
5725 uint16_t levels[] = {1, 2, 3, 4, 5};
5729 for (i=0;i<ARRAY_SIZE(levels);i++) {
5730 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5732 r.in.group_handle = handle;
5733 r.in.level = levels[i];
5736 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
5737 "QueryGroupInfo failed");
5738 if (!NT_STATUS_IS_OK(r.out.result)) {
5739 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5740 levels[i], nt_errstr(r.out.result));
5748 static bool test_QueryGroupMember(struct dcerpc_binding_handle *b,
5749 struct torture_context *tctx,
5750 struct policy_handle *handle)
5752 struct samr_QueryGroupMember r;
5753 struct samr_RidAttrArray *rids = NULL;
5756 torture_comment(tctx, "Testing QueryGroupMember\n");
5758 r.in.group_handle = handle;
5761 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &r),
5762 "QueryGroupMember failed");
5763 if (!NT_STATUS_IS_OK(r.out.result)) {
5764 torture_warning(tctx, "QueryGroupMember failed - %s\n", nt_errstr(r.out.result));
5772 static bool test_SetGroupInfo(struct dcerpc_binding_handle *b,
5773 struct torture_context *tctx,
5774 struct policy_handle *handle)
5776 struct samr_QueryGroupInfo r;
5777 union samr_GroupInfo *info;
5778 struct samr_SetGroupInfo s;
5779 uint16_t levels[] = {1, 2, 3, 4};
5780 uint16_t set_ok[] = {0, 1, 1, 1};
5784 for (i=0;i<ARRAY_SIZE(levels);i++) {
5785 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5787 r.in.group_handle = handle;
5788 r.in.level = levels[i];
5791 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
5792 "QueryGroupInfo failed");
5793 if (!NT_STATUS_IS_OK(r.out.result)) {
5794 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5795 levels[i], nt_errstr(r.out.result));
5799 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
5801 s.in.group_handle = handle;
5802 s.in.level = levels[i];
5803 s.in.info = *r.out.info;
5806 /* disabled this, as it changes the name only from the point of view of samr,
5807 but leaves the name from the point of view of w2k3 internals (and ldap). This means
5808 the name is still reserved, so creating the old name fails, but deleting by the old name
5810 if (s.in.level == 2) {
5811 init_lsa_String(&s.in.info->string, "NewName");
5815 if (s.in.level == 4) {
5816 init_lsa_String(&s.in.info->description, "test description");
5819 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetGroupInfo_r(b, tctx, &s),
5820 "SetGroupInfo failed");
5822 if (!NT_STATUS_IS_OK(s.out.result)) {
5823 torture_warning(tctx, "SetGroupInfo level %u failed - %s\n",
5824 r.in.level, nt_errstr(s.out.result));
5829 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
5830 torture_warning(tctx, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5831 r.in.level, nt_errstr(s.out.result));
5841 static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
5842 struct torture_context *tctx,
5843 struct policy_handle *handle)
5845 struct samr_QueryUserInfo r;
5846 union samr_UserInfo *info;
5847 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5848 11, 12, 13, 14, 16, 17, 20, 21};
5852 for (i=0;i<ARRAY_SIZE(levels);i++) {
5853 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
5855 r.in.user_handle = handle;
5856 r.in.level = levels[i];
5859 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
5860 "QueryUserInfo failed");
5861 if (!NT_STATUS_IS_OK(r.out.result)) {
5862 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5863 levels[i], nt_errstr(r.out.result));
5871 static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
5872 struct torture_context *tctx,
5873 struct policy_handle *handle)
5875 struct samr_QueryUserInfo2 r;
5876 union samr_UserInfo *info;
5877 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5878 11, 12, 13, 14, 16, 17, 20, 21};
5882 for (i=0;i<ARRAY_SIZE(levels);i++) {
5883 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
5885 r.in.user_handle = handle;
5886 r.in.level = levels[i];
5889 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r),
5890 "QueryUserInfo2 failed");
5891 if (!NT_STATUS_IS_OK(r.out.result)) {
5892 torture_warning(tctx, "QueryUserInfo2 level %u failed - %s\n",
5893 levels[i], nt_errstr(r.out.result));
5901 static bool test_OpenUser(struct dcerpc_binding_handle *b,
5902 struct torture_context *tctx,
5903 struct policy_handle *handle, uint32_t rid)
5905 struct samr_OpenUser r;
5906 struct policy_handle user_handle;
5909 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5911 r.in.domain_handle = handle;
5912 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5914 r.out.user_handle = &user_handle;
5916 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5918 if (!NT_STATUS_IS_OK(r.out.result)) {
5919 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5923 if (!test_QuerySecurity(b, tctx, &user_handle)) {
5927 if (!test_QueryUserInfo(b, tctx, &user_handle)) {
5931 if (!test_QueryUserInfo2(b, tctx, &user_handle)) {
5935 if (!test_GetUserPwInfo(b, tctx, &user_handle)) {
5939 if (!test_GetGroupsForUser(b, tctx, &user_handle)) {
5943 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
5950 static bool test_OpenGroup(struct dcerpc_binding_handle *b,
5951 struct torture_context *tctx,
5952 struct policy_handle *handle, uint32_t rid)
5954 struct samr_OpenGroup r;
5955 struct policy_handle group_handle;
5958 torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
5960 r.in.domain_handle = handle;
5961 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5963 r.out.group_handle = &group_handle;
5965 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
5966 "OpenGroup failed");
5967 if (!NT_STATUS_IS_OK(r.out.result)) {
5968 torture_warning(tctx, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5972 if (!torture_setting_bool(tctx, "samba3", false)) {
5973 if (!test_QuerySecurity(b, tctx, &group_handle)) {
5978 if (!test_QueryGroupInfo(b, tctx, &group_handle)) {
5982 if (!test_QueryGroupMember(b, tctx, &group_handle)) {
5986 if (!test_samr_handle_Close(b, tctx, &group_handle)) {
5993 static bool test_OpenAlias(struct dcerpc_binding_handle *b,
5994 struct torture_context *tctx,
5995 struct policy_handle *handle, uint32_t rid)
5997 struct samr_OpenAlias r;
5998 struct policy_handle alias_handle;
6001 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
6003 r.in.domain_handle = handle;
6004 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6006 r.out.alias_handle = &alias_handle;
6008 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
6009 "OpenAlias failed");
6010 if (!NT_STATUS_IS_OK(r.out.result)) {
6011 torture_warning(tctx, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6015 if (!torture_setting_bool(tctx, "samba3", false)) {
6016 if (!test_QuerySecurity(b, tctx, &alias_handle)) {
6021 if (!test_QueryAliasInfo(b, tctx, &alias_handle)) {
6025 if (!test_GetMembersInAlias(b, tctx, &alias_handle)) {
6029 if (!test_samr_handle_Close(b, tctx, &alias_handle)) {
6036 static bool check_mask(struct dcerpc_binding_handle *b,
6037 struct torture_context *tctx,
6038 struct policy_handle *handle, uint32_t rid,
6039 uint32_t acct_flag_mask)
6041 struct samr_OpenUser r;
6042 struct samr_QueryUserInfo q;
6043 union samr_UserInfo *info;
6044 struct policy_handle user_handle;
6047 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
6049 r.in.domain_handle = handle;
6050 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6052 r.out.user_handle = &user_handle;
6054 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6056 if (!NT_STATUS_IS_OK(r.out.result)) {
6057 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6061 q.in.user_handle = &user_handle;
6065 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6066 "QueryUserInfo failed");
6067 if (!NT_STATUS_IS_OK(q.out.result)) {
6068 torture_warning(tctx, "QueryUserInfo level 16 failed - %s\n",
6069 nt_errstr(q.out.result));
6072 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
6073 torture_warning(tctx, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
6074 acct_flag_mask, info->info16.acct_flags, rid);
6079 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6086 static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle *b,
6087 struct torture_context *tctx,
6088 struct policy_handle *handle)
6090 struct samr_EnumDomainUsers r;
6091 uint32_t mask, resume_handle=0;
6094 struct samr_LookupNames n;
6095 struct samr_LookupRids lr ;
6096 struct lsa_Strings names;
6097 struct samr_Ids rids, types;
6098 struct samr_SamArray *sam = NULL;
6099 uint32_t num_entries = 0;
6101 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
6102 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
6103 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
6106 torture_comment(tctx, "Testing EnumDomainUsers\n");
6108 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
6109 r.in.domain_handle = handle;
6110 r.in.resume_handle = &resume_handle;
6111 r.in.acct_flags = mask = masks[mask_idx];
6112 r.in.max_size = (uint32_t)-1;
6113 r.out.resume_handle = &resume_handle;
6114 r.out.num_entries = &num_entries;
6117 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
6118 "EnumDomainUsers failed");
6119 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
6120 !NT_STATUS_IS_OK(r.out.result)) {
6121 torture_warning(tctx, "EnumDomainUsers failed - %s\n", nt_errstr(r.out.result));
6125 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
6127 if (sam->count == 0) {
6131 for (i=0;i<sam->count;i++) {
6133 if (!check_mask(b, tctx, handle, sam->entries[i].idx, mask)) {
6136 } else if (!test_OpenUser(b, tctx, handle, sam->entries[i].idx)) {
6142 torture_comment(tctx, "Testing LookupNames\n");
6143 n.in.domain_handle = handle;
6144 n.in.num_names = sam->count;
6145 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
6147 n.out.types = &types;
6148 for (i=0;i<sam->count;i++) {
6149 n.in.names[i].string = sam->entries[i].name.string;
6151 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
6152 "LookupNames failed");
6153 if (!NT_STATUS_IS_OK(n.out.result)) {
6154 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(n.out.result));
6159 torture_comment(tctx, "Testing LookupRids\n");
6160 lr.in.domain_handle = handle;
6161 lr.in.num_rids = sam->count;
6162 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
6163 lr.out.names = &names;
6164 lr.out.types = &types;
6165 for (i=0;i<sam->count;i++) {
6166 lr.in.rids[i] = sam->entries[i].idx;
6168 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupRids_r(b, tctx, &lr),
6169 "LookupRids failed");
6170 torture_assert_ntstatus_ok(tctx, lr.out.result, "LookupRids");
6176 try blasting the server with a bunch of sync requests
6178 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
6179 struct policy_handle *handle)
6181 struct samr_EnumDomainUsers r;
6182 uint32_t resume_handle=0;
6184 #define ASYNC_COUNT 100
6185 struct tevent_req *req[ASYNC_COUNT];
6187 if (!torture_setting_bool(tctx, "dangerous", false)) {
6188 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
6191 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
6193 r.in.domain_handle = handle;
6194 r.in.resume_handle = &resume_handle;
6195 r.in.acct_flags = 0;
6196 r.in.max_size = (uint32_t)-1;
6197 r.out.resume_handle = &resume_handle;
6199 for (i=0;i<ASYNC_COUNT;i++) {
6200 req[i] = dcerpc_samr_EnumDomainUsers_r_send(tctx, tctx->ev, p->binding_handle, &r);
6203 for (i=0;i<ASYNC_COUNT;i++) {
6204 tevent_req_poll(req[i], tctx->ev);
6205 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r_recv(req[i], tctx),
6206 talloc_asprintf(tctx, "EnumDomainUsers[%d] failed - %s\n",
6207 i, nt_errstr(r.out.result)));
6210 torture_comment(tctx, "%d async requests OK\n", i);
6215 static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle *b,
6216 struct torture_context *tctx,
6217 struct policy_handle *handle)
6219 struct samr_EnumDomainGroups r;
6220 uint32_t resume_handle=0;
6221 struct samr_SamArray *sam = NULL;
6222 uint32_t num_entries = 0;
6225 bool universal_group_found = false;
6227 torture_comment(tctx, "Testing EnumDomainGroups\n");
6229 r.in.domain_handle = handle;
6230 r.in.resume_handle = &resume_handle;
6231 r.in.max_size = (uint32_t)-1;
6232 r.out.resume_handle = &resume_handle;
6233 r.out.num_entries = &num_entries;
6236 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
6237 "EnumDomainGroups failed");
6238 if (!NT_STATUS_IS_OK(r.out.result)) {
6239 torture_warning(tctx, "EnumDomainGroups failed - %s\n", nt_errstr(r.out.result));
6247 for (i=0;i<sam->count;i++) {
6248 if (!test_OpenGroup(b, tctx, handle, sam->entries[i].idx)) {
6251 if ((ret == true) && (strcasecmp(sam->entries[i].name.string,
6252 "Enterprise Admins") == 0)) {
6253 universal_group_found = true;
6257 /* when we are running this on s4 we should get back at least the
6258 * "Enterprise Admins" universal group. If we don't get a group entry
6259 * at all we probably are performing the test on the builtin domain.
6260 * So ignore this case. */
6261 if (torture_setting_bool(tctx, "samba4", false)) {
6262 if ((sam->count > 0) && (!universal_group_found)) {
6270 static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle *b,
6271 struct torture_context *tctx,
6272 struct policy_handle *handle)
6274 struct samr_EnumDomainAliases r;
6275 uint32_t resume_handle=0;
6276 struct samr_SamArray *sam = NULL;
6277 uint32_t num_entries = 0;
6281 torture_comment(tctx, "Testing EnumDomainAliases\n");
6283 r.in.domain_handle = handle;
6284 r.in.resume_handle = &resume_handle;
6285 r.in.max_size = (uint32_t)-1;
6287 r.out.num_entries = &num_entries;
6288 r.out.resume_handle = &resume_handle;
6290 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
6291 "EnumDomainAliases failed");
6292 if (!NT_STATUS_IS_OK(r.out.result)) {
6293 torture_warning(tctx, "EnumDomainAliases failed - %s\n", nt_errstr(r.out.result));
6301 for (i=0;i<sam->count;i++) {
6302 if (!test_OpenAlias(b, tctx, handle, sam->entries[i].idx)) {
6310 static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle *b,
6311 struct torture_context *tctx,
6312 struct policy_handle *handle)
6314 struct samr_GetDisplayEnumerationIndex r;
6316 uint16_t levels[] = {1, 2, 3, 4, 5};
6317 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6318 struct lsa_String name;
6322 for (i=0;i<ARRAY_SIZE(levels);i++) {
6323 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
6325 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6327 r.in.domain_handle = handle;
6328 r.in.level = levels[i];
6332 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6333 "GetDisplayEnumerationIndex failed");
6336 !NT_STATUS_IS_OK(r.out.result) &&
6337 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6338 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6339 levels[i], nt_errstr(r.out.result));
6343 init_lsa_String(&name, "zzzzzzzz");
6345 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6346 "GetDisplayEnumerationIndex failed");
6348 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6349 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6350 levels[i], nt_errstr(r.out.result));
6358 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle *b,
6359 struct torture_context *tctx,
6360 struct policy_handle *handle)
6362 struct samr_GetDisplayEnumerationIndex2 r;
6364 uint16_t levels[] = {1, 2, 3, 4, 5};
6365 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6366 struct lsa_String name;
6370 for (i=0;i<ARRAY_SIZE(levels);i++) {
6371 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
6373 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6375 r.in.domain_handle = handle;
6376 r.in.level = levels[i];
6380 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6381 "GetDisplayEnumerationIndex2 failed");
6383 !NT_STATUS_IS_OK(r.out.result) &&
6384 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6385 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6386 levels[i], nt_errstr(r.out.result));
6390 init_lsa_String(&name, "zzzzzzzz");
6392 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6393 "GetDisplayEnumerationIndex2 failed");
6394 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6395 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6396 levels[i], nt_errstr(r.out.result));
6404 #define STRING_EQUAL_QUERY(s1, s2, user) \
6405 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6406 /* odd, but valid */ \
6407 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6408 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
6409 #s1, user.string, s1.string, s2.string, __location__); \
6412 #define INT_EQUAL_QUERY(s1, s2, user) \
6414 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6415 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6419 static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle *b,
6420 struct torture_context *tctx,
6421 struct samr_QueryDisplayInfo *querydisplayinfo,
6422 bool *seen_testuser)
6424 struct samr_OpenUser r;
6425 struct samr_QueryUserInfo q;
6426 union samr_UserInfo *info;
6427 struct policy_handle user_handle;
6429 r.in.domain_handle = querydisplayinfo->in.domain_handle;
6430 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6431 for (i = 0; ; i++) {
6432 switch (querydisplayinfo->in.level) {
6434 if (i >= querydisplayinfo->out.info->info1.count) {
6437 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
6440 if (i >= querydisplayinfo->out.info->info2.count) {
6443 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
6449 /* Not interested in validating just the account name */
6453 r.out.user_handle = &user_handle;
6455 switch (querydisplayinfo->in.level) {
6458 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6460 if (!NT_STATUS_IS_OK(r.out.result)) {
6461 torture_warning(tctx, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6466 q.in.user_handle = &user_handle;
6469 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6470 "QueryUserInfo failed");
6471 if (!NT_STATUS_IS_OK(r.out.result)) {
6472 torture_warning(tctx, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6476 switch (querydisplayinfo->in.level) {
6478 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
6479 *seen_testuser = true;
6481 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
6482 info->info21.full_name, info->info21.account_name);
6483 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
6484 info->info21.account_name, info->info21.account_name);
6485 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
6486 info->info21.description, info->info21.account_name);
6487 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
6488 info->info21.rid, info->info21.account_name);
6489 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
6490 info->info21.acct_flags, info->info21.account_name);
6494 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
6495 info->info21.account_name, info->info21.account_name);
6496 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
6497 info->info21.description, info->info21.account_name);
6498 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
6499 info->info21.rid, info->info21.account_name);
6500 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
6501 info->info21.acct_flags, info->info21.account_name);
6503 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
6504 torture_warning(tctx, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6505 info->info21.account_name.string);
6508 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
6509 torture_warning(tctx, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6510 info->info21.account_name.string,
6511 querydisplayinfo->out.info->info2.entries[i].acct_flags,
6512 info->info21.acct_flags);
6519 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6526 static bool test_QueryDisplayInfo(struct dcerpc_binding_handle *b,
6527 struct torture_context *tctx,
6528 struct policy_handle *handle)
6530 struct samr_QueryDisplayInfo r;
6531 struct samr_QueryDomainInfo dom_info;
6532 union samr_DomainInfo *info = NULL;
6534 uint16_t levels[] = {1, 2, 3, 4, 5};
6536 bool seen_testuser = false;
6537 uint32_t total_size;
6538 uint32_t returned_size;
6539 union samr_DispInfo disp_info;
6542 for (i=0;i<ARRAY_SIZE(levels);i++) {
6543 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
6546 r.out.result = STATUS_MORE_ENTRIES;
6547 while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
6548 r.in.domain_handle = handle;
6549 r.in.level = levels[i];
6550 r.in.max_entries = 2;
6551 r.in.buf_size = (uint32_t)-1;
6552 r.out.total_size = &total_size;
6553 r.out.returned_size = &returned_size;
6554 r.out.info = &disp_info;
6556 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6557 "QueryDisplayInfo failed");
6558 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(r.out.result)) {
6559 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6560 levels[i], nt_errstr(r.out.result));
6563 switch (r.in.level) {
6565 if (!test_each_DisplayInfo_user(b, tctx, &r, &seen_testuser)) {
6568 r.in.start_idx += r.out.info->info1.count;
6571 if (!test_each_DisplayInfo_user(b, tctx, &r, NULL)) {
6574 r.in.start_idx += r.out.info->info2.count;
6577 r.in.start_idx += r.out.info->info3.count;
6580 r.in.start_idx += r.out.info->info4.count;
6583 r.in.start_idx += r.out.info->info5.count;
6587 dom_info.in.domain_handle = handle;
6588 dom_info.in.level = 2;
6589 dom_info.out.info = &info;
6591 /* Check number of users returned is correct */
6592 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &dom_info),
6593 "QueryDomainInfo failed");
6594 if (!NT_STATUS_IS_OK(dom_info.out.result)) {
6595 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6596 r.in.level, nt_errstr(dom_info.out.result));
6600 switch (r.in.level) {
6603 if (info->general.num_users < r.in.start_idx) {
6604 /* On AD deployments this numbers don't match
6605 * since QueryDisplayInfo returns universal and
6606 * global groups, QueryDomainInfo only global
6608 if (torture_setting_bool(tctx, "samba3", false)) {
6609 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6610 r.in.start_idx, info->general.num_groups,
6611 info->general.domain_name.string);
6615 if (!seen_testuser) {
6616 struct policy_handle user_handle;
6617 if (NT_STATUS_IS_OK(test_OpenUser_byname(b, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
6618 torture_warning(tctx, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
6619 info->general.domain_name.string);
6621 test_samr_handle_Close(b, tctx, &user_handle);
6627 if (info->general.num_groups != r.in.start_idx) {
6628 /* On AD deployments this numbers don't match
6629 * since QueryDisplayInfo returns universal and
6630 * global groups, QueryDomainInfo only global
6632 if (torture_setting_bool(tctx, "samba3", false)) {
6633 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6634 r.in.start_idx, info->general.num_groups,
6635 info->general.domain_name.string);
6648 static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle *b,
6649 struct torture_context *tctx,
6650 struct policy_handle *handle)
6652 struct samr_QueryDisplayInfo2 r;
6654 uint16_t levels[] = {1, 2, 3, 4, 5};
6656 uint32_t total_size;
6657 uint32_t returned_size;
6658 union samr_DispInfo info;
6660 for (i=0;i<ARRAY_SIZE(levels);i++) {
6661 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
6663 r.in.domain_handle = handle;
6664 r.in.level = levels[i];
6666 r.in.max_entries = 1000;
6667 r.in.buf_size = (uint32_t)-1;
6668 r.out.total_size = &total_size;
6669 r.out.returned_size = &returned_size;
6672 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo2_r(b, tctx, &r),
6673 "QueryDisplayInfo2 failed");
6674 if (!NT_STATUS_IS_OK(r.out.result)) {
6675 torture_warning(tctx, "QueryDisplayInfo2 level %u failed - %s\n",
6676 levels[i], nt_errstr(r.out.result));
6684 static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle *b,
6685 struct torture_context *tctx,
6686 struct policy_handle *handle)
6688 struct samr_QueryDisplayInfo3 r;
6690 uint16_t levels[] = {1, 2, 3, 4, 5};
6692 uint32_t total_size;
6693 uint32_t returned_size;
6694 union samr_DispInfo info;
6696 for (i=0;i<ARRAY_SIZE(levels);i++) {
6697 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
6699 r.in.domain_handle = handle;
6700 r.in.level = levels[i];
6702 r.in.max_entries = 1000;
6703 r.in.buf_size = (uint32_t)-1;
6704 r.out.total_size = &total_size;
6705 r.out.returned_size = &returned_size;
6708 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo3_r(b, tctx, &r),
6709 "QueryDisplayInfo3 failed");
6710 if (!NT_STATUS_IS_OK(r.out.result)) {
6711 torture_warning(tctx, "QueryDisplayInfo3 level %u failed - %s\n",
6712 levels[i], nt_errstr(r.out.result));
6721 static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle *b,
6722 struct torture_context *tctx,
6723 struct policy_handle *handle)
6725 struct samr_QueryDisplayInfo r;
6727 uint32_t total_size;
6728 uint32_t returned_size;
6729 union samr_DispInfo info;
6731 torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
6733 r.in.domain_handle = handle;
6736 r.in.max_entries = 1;
6737 r.in.buf_size = (uint32_t)-1;
6738 r.out.total_size = &total_size;
6739 r.out.returned_size = &returned_size;
6743 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6744 "QueryDisplayInfo failed");
6745 if (NT_STATUS_IS_OK(r.out.result) && *r.out.returned_size != 0) {
6746 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
6747 torture_warning(tctx, "expected idx %d but got %d\n",
6749 r.out.info->info1.entries[0].idx);
6753 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
6754 !NT_STATUS_IS_OK(r.out.result)) {
6755 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6756 r.in.level, nt_errstr(r.out.result));
6761 } while ((NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) ||
6762 NT_STATUS_IS_OK(r.out.result)) &&
6763 *r.out.returned_size != 0);
6768 static bool test_QueryDomainInfo(struct dcerpc_pipe *p,
6769 struct torture_context *tctx,
6770 struct policy_handle *handle)
6772 struct samr_QueryDomainInfo r;
6773 union samr_DomainInfo *info = NULL;
6774 struct samr_SetDomainInfo s;
6775 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6776 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
6779 struct dcerpc_binding_handle *b = p->binding_handle;
6780 const char *domain_comment = talloc_asprintf(tctx,
6781 "Tortured by Samba4 RPC-SAMR: %s",
6782 timestring(tctx, time(NULL)));
6784 s.in.domain_handle = handle;
6786 s.in.info = talloc(tctx, union samr_DomainInfo);
6788 s.in.info->oem.oem_information.string = domain_comment;
6789 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
6790 "SetDomainInfo failed");
6791 if (!NT_STATUS_IS_OK(s.out.result)) {
6792 torture_warning(tctx, "SetDomainInfo level %u (set comment) failed - %s\n",
6793 s.in.level, nt_errstr(s.out.result));
6797 for (i=0;i<ARRAY_SIZE(levels);i++) {
6798 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
6800 r.in.domain_handle = handle;
6801 r.in.level = levels[i];
6804 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
6805 "QueryDomainInfo failed");
6806 if (!NT_STATUS_IS_OK(r.out.result)) {
6807 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6808 r.in.level, nt_errstr(r.out.result));
6813 switch (levels[i]) {
6815 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
6816 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6817 levels[i], info->general.oem_information.string, domain_comment);
6818 if (!torture_setting_bool(tctx, "samba3", false)) {
6822 if (!info->general.primary.string) {
6823 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6826 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
6827 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
6828 if (torture_setting_bool(tctx, "samba3", false)) {
6829 torture_warning(tctx, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
6830 levels[i], info->general.primary.string, dcerpc_server_name(p));
6836 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
6837 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6838 levels[i], info->oem.oem_information.string, domain_comment);
6839 if (!torture_setting_bool(tctx, "samba3", false)) {
6845 if (!info->info6.primary.string) {
6846 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6852 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
6853 torture_warning(tctx, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
6854 levels[i], info->general2.general.oem_information.string, domain_comment);
6855 if (!torture_setting_bool(tctx, "samba3", false)) {
6862 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
6864 s.in.domain_handle = handle;
6865 s.in.level = levels[i];
6868 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
6869 "SetDomainInfo failed");
6871 if (!NT_STATUS_IS_OK(s.out.result)) {
6872 torture_warning(tctx, "SetDomainInfo level %u failed - %s\n",
6873 r.in.level, nt_errstr(s.out.result));
6878 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
6879 torture_warning(tctx, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6880 r.in.level, nt_errstr(s.out.result));
6886 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
6887 "QueryDomainInfo failed");
6888 if (!NT_STATUS_IS_OK(r.out.result)) {
6889 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6890 r.in.level, nt_errstr(r.out.result));
6900 static bool test_QueryDomainInfo2(struct dcerpc_binding_handle *b,
6901 struct torture_context *tctx,
6902 struct policy_handle *handle)
6904 struct samr_QueryDomainInfo2 r;
6905 union samr_DomainInfo *info = NULL;
6906 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6910 for (i=0;i<ARRAY_SIZE(levels);i++) {
6911 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
6913 r.in.domain_handle = handle;
6914 r.in.level = levels[i];
6917 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
6918 "QueryDomainInfo2 failed");
6919 if (!NT_STATUS_IS_OK(r.out.result)) {
6920 torture_warning(tctx, "QueryDomainInfo2 level %u failed - %s\n",
6921 r.in.level, nt_errstr(r.out.result));
6930 /* Test whether querydispinfo level 5 and enumdomgroups return the same
6931 set of group names. */
6932 static bool test_GroupList(struct dcerpc_binding_handle *b,
6933 struct torture_context *tctx,
6934 struct dom_sid *domain_sid,
6935 struct policy_handle *handle)
6937 struct samr_EnumDomainGroups q1;
6938 struct samr_QueryDisplayInfo q2;
6940 uint32_t resume_handle=0;
6941 struct samr_SamArray *sam = NULL;
6942 uint32_t num_entries = 0;
6945 uint32_t total_size;
6946 uint32_t returned_size;
6947 union samr_DispInfo info;
6950 const char **names = NULL;
6952 bool builtin_domain = dom_sid_compare(domain_sid,
6953 &global_sid_Builtin) == 0;
6955 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
6957 q1.in.domain_handle = handle;
6958 q1.in.resume_handle = &resume_handle;
6960 q1.out.resume_handle = &resume_handle;
6961 q1.out.num_entries = &num_entries;
6964 status = STATUS_MORE_ENTRIES;
6965 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6966 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &q1),
6967 "EnumDomainGroups failed");
6968 status = q1.out.result;
6970 if (!NT_STATUS_IS_OK(status) &&
6971 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6974 for (i=0; i<*q1.out.num_entries; i++) {
6975 add_string_to_array(tctx,
6976 sam->entries[i].name.string,
6977 &names, &num_names);
6981 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
6983 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
6985 if (builtin_domain) {
6986 torture_assert(tctx, num_names == 0,
6987 "EnumDomainGroups shouldn't return any group in the builtin domain!");
6990 q2.in.domain_handle = handle;
6992 q2.in.start_idx = 0;
6993 q2.in.max_entries = 5;
6994 q2.in.buf_size = (uint32_t)-1;
6995 q2.out.total_size = &total_size;
6996 q2.out.returned_size = &returned_size;
6997 q2.out.info = &info;
6999 status = STATUS_MORE_ENTRIES;
7000 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
7001 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &q2),
7002 "QueryDisplayInfo failed");
7003 status = q2.out.result;
7004 if (!NT_STATUS_IS_OK(status) &&
7005 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
7008 for (i=0; i<q2.out.info->info5.count; i++) {
7010 const char *name = q2.out.info->info5.entries[i].account_name.string;
7012 for (j=0; j<num_names; j++) {
7013 if (names[j] == NULL)
7015 if (strequal(names[j], name)) {
7022 if ((!found) && (!builtin_domain)) {
7023 torture_warning(tctx, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
7028 q2.in.start_idx += q2.out.info->info5.count;
7031 if (!NT_STATUS_IS_OK(status)) {
7032 torture_warning(tctx, "QueryDisplayInfo level 5 failed - %s\n",
7037 if (builtin_domain) {
7038 torture_assert(tctx, q2.in.start_idx != 0,
7039 "QueryDisplayInfo should return all domain groups also on the builtin domain handle!");
7042 for (i=0; i<num_names; i++) {
7043 if (names[i] != NULL) {
7044 torture_warning(tctx, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
7053 static bool test_DeleteDomainGroup(struct dcerpc_binding_handle *b,
7054 struct torture_context *tctx,
7055 struct policy_handle *group_handle)
7057 struct samr_DeleteDomainGroup d;
7059 torture_comment(tctx, "Testing DeleteDomainGroup\n");
7061 d.in.group_handle = group_handle;
7062 d.out.group_handle = group_handle;
7064 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
7065 "DeleteDomainGroup failed");
7066 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteDomainGroup");
7071 static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle *b,
7072 struct torture_context *tctx,
7073 struct policy_handle *domain_handle)
7075 struct samr_TestPrivateFunctionsDomain r;
7078 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
7080 r.in.domain_handle = domain_handle;
7082 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsDomain_r(b, tctx, &r),
7083 "TestPrivateFunctionsDomain failed");
7084 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
7089 static bool test_RidToSid(struct dcerpc_binding_handle *b,
7090 struct torture_context *tctx,
7091 struct dom_sid *domain_sid,
7092 struct policy_handle *domain_handle)
7094 struct samr_RidToSid r;
7096 struct dom_sid *calc_sid, *out_sid;
7097 int rids[] = { 0, 42, 512, 10200 };
7100 for (i=0;i<ARRAY_SIZE(rids);i++) {
7101 torture_comment(tctx, "Testing RidToSid\n");
7103 calc_sid = dom_sid_dup(tctx, domain_sid);
7104 r.in.domain_handle = domain_handle;
7106 r.out.sid = &out_sid;
7108 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RidToSid_r(b, tctx, &r),
7110 if (!NT_STATUS_IS_OK(r.out.result)) {
7111 torture_warning(tctx, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(r.out.result));
7114 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
7116 if (!dom_sid_equal(calc_sid, out_sid)) {
7117 torture_warning(tctx, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
7118 dom_sid_string(tctx, out_sid),
7119 dom_sid_string(tctx, calc_sid));
7128 static bool test_GetBootKeyInformation(struct dcerpc_binding_handle *b,
7129 struct torture_context *tctx,
7130 struct policy_handle *domain_handle)
7132 struct samr_GetBootKeyInformation r;
7134 uint32_t unknown = 0;
7137 torture_comment(tctx, "Testing GetBootKeyInformation\n");
7139 r.in.domain_handle = domain_handle;
7140 r.out.unknown = &unknown;
7142 status = dcerpc_samr_GetBootKeyInformation_r(b, tctx, &r);
7143 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(r.out.result)) {
7144 status = r.out.result;
7146 if (!NT_STATUS_IS_OK(status)) {
7147 /* w2k3 seems to fail this sometimes and pass it sometimes */
7148 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
7154 static bool test_AddGroupMember(struct dcerpc_binding_handle *b,
7155 struct torture_context *tctx,
7156 struct policy_handle *domain_handle,
7157 struct policy_handle *group_handle)
7160 struct samr_AddGroupMember r;
7161 struct samr_DeleteGroupMember d;
7162 struct samr_QueryGroupMember q;
7163 struct samr_RidAttrArray *rids = NULL;
7164 struct samr_SetMemberAttributesOfGroup s;
7166 bool found_member = false;
7169 status = test_LookupName(b, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
7170 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
7172 r.in.group_handle = group_handle;
7174 r.in.flags = 0; /* ??? */
7176 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
7178 d.in.group_handle = group_handle;
7181 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7182 "DeleteGroupMember failed");
7183 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, d.out.result, "DeleteGroupMember");
7185 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7186 "AddGroupMember failed");
7187 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7189 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7190 "AddGroupMember failed");
7191 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, r.out.result, "AddGroupMember");
7193 if (torture_setting_bool(tctx, "samba4", false) ||
7194 torture_setting_bool(tctx, "samba3", false)) {
7195 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
7197 /* this one is quite strange. I am using random inputs in the
7198 hope of triggering an error that might give us a clue */
7200 s.in.group_handle = group_handle;
7201 s.in.unknown1 = random();
7202 s.in.unknown2 = random();
7204 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetMemberAttributesOfGroup_r(b, tctx, &s),
7205 "SetMemberAttributesOfGroup failed");
7206 torture_assert_ntstatus_ok(tctx, s.out.result, "SetMemberAttributesOfGroup");
7209 q.in.group_handle = group_handle;
7212 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7213 "QueryGroupMember failed");
7214 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7215 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7217 for (i=0; i < rids->count; i++) {
7218 if (rids->rids[i] == rid) {
7219 found_member = true;
7223 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
7225 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7226 "DeleteGroupMember failed");
7227 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteGroupMember");
7230 found_member = false;
7232 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7233 "QueryGroupMember failed");
7234 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7235 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7237 for (i=0; i < rids->count; i++) {
7238 if (rids->rids[i] == rid) {
7239 found_member = true;
7243 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
7245 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7246 "AddGroupMember failed");
7247 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7253 static bool test_CreateDomainGroup(struct dcerpc_binding_handle *b,
7254 struct torture_context *tctx,
7255 struct policy_handle *domain_handle,
7256 const char *group_name,
7257 struct policy_handle *group_handle,
7258 struct dom_sid *domain_sid,
7261 struct samr_CreateDomainGroup r;
7263 struct lsa_String name;
7266 init_lsa_String(&name, group_name);
7268 r.in.domain_handle = domain_handle;
7270 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7271 r.out.group_handle = group_handle;
7274 torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
7276 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7277 "CreateDomainGroup failed");
7279 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
7280 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
7281 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
7284 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
7285 nt_errstr(r.out.result));
7290 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_GROUP_EXISTS)) {
7291 if (!test_DeleteGroup_byname(b, tctx, domain_handle, r.in.name->string)) {
7292 torture_warning(tctx, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
7293 nt_errstr(r.out.result));
7296 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7297 "CreateDomainGroup failed");
7299 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
7300 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.name->string)) {
7302 torture_warning(tctx, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
7303 nt_errstr(r.out.result));
7306 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7307 "CreateDomainGroup failed");
7309 torture_assert_ntstatus_ok(tctx, r.out.result, "CreateDomainGroup");
7315 if (!test_AddGroupMember(b, tctx, domain_handle, group_handle)) {
7316 torture_warning(tctx, "CreateDomainGroup failed - %s\n", nt_errstr(r.out.result));
7320 if (!test_SetGroupInfo(b, tctx, group_handle)) {
7329 its not totally clear what this does. It seems to accept any sid you like.
7331 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle *b,
7332 struct torture_context *tctx,
7333 struct policy_handle *domain_handle)
7335 struct samr_RemoveMemberFromForeignDomain r;
7337 r.in.domain_handle = domain_handle;
7338 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
7340 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMemberFromForeignDomain_r(b, tctx, &r),
7341 "RemoveMemberFromForeignDomain failed");
7342 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMemberFromForeignDomain");
7347 static bool test_EnumDomainUsers(struct dcerpc_binding_handle *b,
7348 struct torture_context *tctx,
7349 struct policy_handle *domain_handle,
7350 uint32_t *total_num_entries_p)
7353 struct samr_EnumDomainUsers r;
7354 uint32_t resume_handle = 0;
7355 uint32_t num_entries = 0;
7356 uint32_t total_num_entries = 0;
7357 struct samr_SamArray *sam;
7359 r.in.domain_handle = domain_handle;
7360 r.in.acct_flags = 0;
7361 r.in.max_size = (uint32_t)-1;
7362 r.in.resume_handle = &resume_handle;
7365 r.out.num_entries = &num_entries;
7366 r.out.resume_handle = &resume_handle;
7368 torture_comment(tctx, "Testing EnumDomainUsers\n");
7371 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
7372 "EnumDomainUsers failed");
7373 if (NT_STATUS_IS_ERR(r.out.result)) {
7374 torture_assert_ntstatus_ok(tctx, r.out.result,
7375 "failed to enumerate users");
7377 status = r.out.result;
7379 total_num_entries += num_entries;
7380 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7382 if (total_num_entries_p) {
7383 *total_num_entries_p = total_num_entries;
7389 static bool test_EnumDomainGroups(struct dcerpc_binding_handle *b,
7390 struct torture_context *tctx,
7391 struct policy_handle *domain_handle,
7392 uint32_t *total_num_entries_p)
7395 struct samr_EnumDomainGroups r;
7396 uint32_t resume_handle = 0;
7397 uint32_t num_entries = 0;
7398 uint32_t total_num_entries = 0;
7399 struct samr_SamArray *sam;
7401 r.in.domain_handle = domain_handle;
7402 r.in.max_size = (uint32_t)-1;
7403 r.in.resume_handle = &resume_handle;
7406 r.out.num_entries = &num_entries;
7407 r.out.resume_handle = &resume_handle;
7409 torture_comment(tctx, "Testing EnumDomainGroups\n");
7412 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
7413 "EnumDomainGroups failed");
7414 if (NT_STATUS_IS_ERR(r.out.result)) {
7415 torture_assert_ntstatus_ok(tctx, r.out.result,
7416 "failed to enumerate groups");
7418 status = r.out.result;
7420 total_num_entries += num_entries;
7421 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7423 if (total_num_entries_p) {
7424 *total_num_entries_p = total_num_entries;
7430 static bool test_EnumDomainAliases(struct dcerpc_binding_handle *b,
7431 struct torture_context *tctx,
7432 struct policy_handle *domain_handle,
7433 uint32_t *total_num_entries_p)
7436 struct samr_EnumDomainAliases r;
7437 uint32_t resume_handle = 0;
7438 uint32_t num_entries = 0;
7439 uint32_t total_num_entries = 0;
7440 struct samr_SamArray *sam;
7442 r.in.domain_handle = domain_handle;
7443 r.in.max_size = (uint32_t)-1;
7444 r.in.resume_handle = &resume_handle;
7447 r.out.num_entries = &num_entries;
7448 r.out.resume_handle = &resume_handle;
7450 torture_comment(tctx, "Testing EnumDomainAliases\n");
7453 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
7454 "EnumDomainAliases failed");
7455 if (NT_STATUS_IS_ERR(r.out.result)) {
7456 torture_assert_ntstatus_ok(tctx, r.out.result,
7457 "failed to enumerate aliases");
7459 status = r.out.result;
7461 total_num_entries += num_entries;
7462 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7464 if (total_num_entries_p) {
7465 *total_num_entries_p = total_num_entries;
7471 static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle *b,
7472 struct torture_context *tctx,
7473 struct policy_handle *handle,
7475 uint32_t *total_num_entries_p)
7478 struct samr_QueryDisplayInfo r;
7479 uint32_t total_num_entries = 0;
7481 r.in.domain_handle = handle;
7484 r.in.max_entries = (uint32_t)-1;
7485 r.in.buf_size = (uint32_t)-1;
7487 torture_comment(tctx, "Testing QueryDisplayInfo\n");
7490 uint32_t total_size;
7491 uint32_t returned_size;
7492 union samr_DispInfo info;
7494 r.out.total_size = &total_size;
7495 r.out.returned_size = &returned_size;
7498 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7499 "failed to query displayinfo");
7500 if (NT_STATUS_IS_ERR(r.out.result)) {
7501 torture_assert_ntstatus_ok(tctx, r.out.result,
7502 "failed to query displayinfo");
7504 status = r.out.result;
7506 if (*r.out.returned_size == 0) {
7510 switch (r.in.level) {
7512 total_num_entries += info.info1.count;
7513 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
7516 total_num_entries += info.info2.count;
7517 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
7520 total_num_entries += info.info3.count;
7521 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
7524 total_num_entries += info.info4.count;
7525 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
7528 total_num_entries += info.info5.count;
7529 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
7535 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7537 if (total_num_entries_p) {
7538 *total_num_entries_p = total_num_entries;
7544 static bool test_ManyObjects(struct dcerpc_pipe *p,
7545 struct torture_context *tctx,
7546 struct policy_handle *domain_handle,
7547 struct dom_sid *domain_sid,
7548 struct torture_samr_context *ctx)
7550 uint32_t num_total = ctx->num_objects_large_dc;
7551 uint32_t num_enum = 0;
7552 uint32_t num_disp = 0;
7553 uint32_t num_created = 0;
7554 uint32_t num_anounced = 0;
7556 struct dcerpc_binding_handle *b = p->binding_handle;
7558 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
7563 struct samr_QueryDomainInfo2 r;
7564 union samr_DomainInfo *info;
7565 r.in.domain_handle = domain_handle;
7569 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
7570 "QueryDomainInfo2 failed");
7571 torture_assert_ntstatus_ok(tctx, r.out.result,
7572 "failed to query domain info");
7574 switch (ctx->choice) {
7575 case TORTURE_SAMR_MANY_ACCOUNTS:
7576 num_anounced = info->general.num_users;
7578 case TORTURE_SAMR_MANY_GROUPS:
7579 num_anounced = info->general.num_groups;
7581 case TORTURE_SAMR_MANY_ALIASES:
7582 num_anounced = info->general.num_aliases;
7591 for (i=0; i < num_total; i++) {
7593 const char *name = NULL;
7595 switch (ctx->choice) {
7596 case TORTURE_SAMR_MANY_ACCOUNTS:
7597 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
7598 torture_assert(tctx,
7599 test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false),
7600 "failed to create user");
7602 case TORTURE_SAMR_MANY_GROUPS:
7603 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
7604 torture_assert(tctx,
7605 test_CreateDomainGroup(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
7606 "failed to create group");
7608 case TORTURE_SAMR_MANY_ALIASES:
7609 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
7610 torture_assert(tctx,
7611 test_CreateAlias(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
7612 "failed to create alias");
7617 if (!ndr_policy_handle_empty(&handles[i])) {
7624 switch (ctx->choice) {
7625 case TORTURE_SAMR_MANY_ACCOUNTS:
7626 torture_assert(tctx,
7627 test_EnumDomainUsers(b, tctx, domain_handle, &num_enum),
7628 "failed to enum users");
7630 case TORTURE_SAMR_MANY_GROUPS:
7631 torture_assert(tctx,
7632 test_EnumDomainGroups(b, tctx, domain_handle, &num_enum),
7633 "failed to enum groups");
7635 case TORTURE_SAMR_MANY_ALIASES:
7636 torture_assert(tctx,
7637 test_EnumDomainAliases(b, tctx, domain_handle, &num_enum),
7638 "failed to enum aliases");
7646 switch (ctx->choice) {
7647 case TORTURE_SAMR_MANY_ACCOUNTS:
7648 torture_assert(tctx,
7649 test_QueryDisplayInfo_level(b, tctx, domain_handle, 1, &num_disp),
7650 "failed to query display info");
7652 case TORTURE_SAMR_MANY_GROUPS:
7653 torture_assert(tctx,
7654 test_QueryDisplayInfo_level(b, tctx, domain_handle, 3, &num_disp),
7655 "failed to query display info");
7657 case TORTURE_SAMR_MANY_ALIASES:
7658 /* no aliases in dispinfo */
7664 /* close or delete */
7666 for (i=0; i < num_total; i++) {
7668 if (ndr_policy_handle_empty(&handles[i])) {
7672 if (torture_setting_bool(tctx, "samba3", false)) {
7673 torture_assert(tctx,
7674 test_samr_handle_Close(b, tctx, &handles[i]),
7675 "failed to close handle");
7677 switch (ctx->choice) {
7678 case TORTURE_SAMR_MANY_ACCOUNTS:
7679 torture_assert(tctx,
7680 test_DeleteUser(b, tctx, &handles[i]),
7681 "failed to delete user");
7683 case TORTURE_SAMR_MANY_GROUPS:
7684 torture_assert(tctx,
7685 test_DeleteDomainGroup(b, tctx, &handles[i]),
7686 "failed to delete group");
7688 case TORTURE_SAMR_MANY_ALIASES:
7689 torture_assert(tctx,
7690 test_DeleteAlias(b, tctx, &handles[i]),
7691 "failed to delete alias");
7699 talloc_free(handles);
7701 if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
7702 torture_comment(tctx,
7703 "unexpected number of results (%u) returned in enum call, expected %u\n",
7704 num_enum, num_anounced + num_created);
7706 torture_comment(tctx,
7707 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
7708 num_disp, num_anounced + num_created);
7714 static bool test_Connect(struct dcerpc_binding_handle *b,
7715 struct torture_context *tctx,
7716 struct policy_handle *handle);
7718 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7719 struct torture_samr_context *ctx, struct dom_sid *sid)
7721 struct samr_OpenDomain r;
7722 struct policy_handle domain_handle;
7723 struct policy_handle alias_handle;
7724 struct policy_handle user_handle;
7725 struct policy_handle group_handle;
7727 struct dcerpc_binding_handle *b = p->binding_handle;
7729 ZERO_STRUCT(alias_handle);
7730 ZERO_STRUCT(user_handle);
7731 ZERO_STRUCT(group_handle);
7732 ZERO_STRUCT(domain_handle);
7734 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
7736 r.in.connect_handle = &ctx->handle;
7737 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7739 r.out.domain_handle = &domain_handle;
7741 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenDomain_r(b, tctx, &r),
7742 "OpenDomain failed");
7743 torture_assert_ntstatus_ok(tctx, r.out.result, "OpenDomain failed");
7745 /* run the domain tests with the main handle closed - this tests
7746 the servers reference counting */
7747 torture_assert(tctx, test_samr_handle_Close(b, tctx, &ctx->handle), "Failed to close SAMR handle");
7749 switch (ctx->choice) {
7750 case TORTURE_SAMR_PASSWORDS:
7751 case TORTURE_SAMR_USER_PRIVILEGES:
7752 if (!torture_setting_bool(tctx, "samba3", false)) {
7753 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7755 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7757 torture_warning(tctx, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
7760 case TORTURE_SAMR_USER_ATTRIBUTES:
7761 if (!torture_setting_bool(tctx, "samba3", false)) {
7762 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7764 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7765 /* This test needs 'complex' users to validate */
7766 ret &= test_QueryDisplayInfo(b, tctx, &domain_handle);
7768 torture_warning(tctx, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
7771 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
7772 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
7773 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
7774 if (!torture_setting_bool(tctx, "samba3", false)) {
7775 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
7777 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
7779 torture_warning(tctx, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx, sid));
7782 case TORTURE_SAMR_MANY_ACCOUNTS:
7783 case TORTURE_SAMR_MANY_GROUPS:
7784 case TORTURE_SAMR_MANY_ALIASES:
7785 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
7787 torture_warning(tctx, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
7790 case TORTURE_SAMR_OTHER:
7791 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7793 torture_warning(tctx, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
7795 if (!torture_setting_bool(tctx, "samba3", false)) {
7796 ret &= test_QuerySecurity(b, tctx, &domain_handle);
7798 ret &= test_RemoveMemberFromForeignDomain(b, tctx, &domain_handle);
7799 ret &= test_CreateAlias(b, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
7800 ret &= test_CreateDomainGroup(b, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
7801 ret &= test_GetAliasMembership(b, tctx, &domain_handle);
7802 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
7803 ret &= test_QueryDomainInfo2(b, tctx, &domain_handle);
7804 ret &= test_EnumDomainUsers_all(b, tctx, &domain_handle);
7805 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
7806 ret &= test_EnumDomainGroups_all(b, tctx, &domain_handle);
7807 ret &= test_EnumDomainAliases_all(b, tctx, &domain_handle);
7808 ret &= test_QueryDisplayInfo2(b, tctx, &domain_handle);
7809 ret &= test_QueryDisplayInfo3(b, tctx, &domain_handle);
7810 ret &= test_QueryDisplayInfo_continue(b, tctx, &domain_handle);
7812 if (torture_setting_bool(tctx, "samba4", false)) {
7813 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
7815 ret &= test_GetDisplayEnumerationIndex(b, tctx, &domain_handle);
7816 ret &= test_GetDisplayEnumerationIndex2(b, tctx, &domain_handle);
7818 ret &= test_GroupList(b, tctx, sid, &domain_handle);
7819 ret &= test_TestPrivateFunctionsDomain(b, tctx, &domain_handle);
7820 ret &= test_RidToSid(b, tctx, sid, &domain_handle);
7821 ret &= test_GetBootKeyInformation(b, tctx, &domain_handle);
7823 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
7828 if (!ndr_policy_handle_empty(&user_handle) &&
7829 !test_DeleteUser(b, tctx, &user_handle)) {
7833 if (!ndr_policy_handle_empty(&alias_handle) &&
7834 !test_DeleteAlias(b, tctx, &alias_handle)) {
7838 if (!ndr_policy_handle_empty(&group_handle) &&
7839 !test_DeleteDomainGroup(b, tctx, &group_handle)) {
7843 torture_assert(tctx, test_samr_handle_Close(b, tctx, &domain_handle), "Failed to close SAMR domain handle");
7845 torture_assert(tctx, test_Connect(b, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
7846 /* reconnect the main handle */
7849 torture_warning(tctx, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
7855 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7856 struct torture_samr_context *ctx, const char *domain)
7858 struct samr_LookupDomain r;
7859 struct dom_sid2 *sid = NULL;
7860 struct lsa_String n1;
7861 struct lsa_String n2;
7863 struct dcerpc_binding_handle *b = p->binding_handle;
7865 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
7867 /* check for correct error codes */
7868 r.in.connect_handle = &ctx->handle;
7869 r.in.domain_name = &n2;
7873 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7874 "LookupDomain failed");
7875 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, r.out.result, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
7877 init_lsa_String(&n2, "xxNODOMAINxx");
7879 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7880 "LookupDomain failed");
7881 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, r.out.result, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
7883 r.in.connect_handle = &ctx->handle;
7885 init_lsa_String(&n1, domain);
7886 r.in.domain_name = &n1;
7888 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7889 "LookupDomain failed");
7890 torture_assert_ntstatus_ok(tctx, r.out.result, "LookupDomain");
7892 if (!test_GetDomPwInfo(p, tctx, &n1)) {
7896 if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
7904 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
7905 struct torture_samr_context *ctx)
7907 struct samr_EnumDomains r;
7908 uint32_t resume_handle = 0;
7909 uint32_t num_entries = 0;
7910 struct samr_SamArray *sam = NULL;
7913 struct dcerpc_binding_handle *b = p->binding_handle;
7915 r.in.connect_handle = &ctx->handle;
7916 r.in.resume_handle = &resume_handle;
7917 r.in.buf_size = (uint32_t)-1;
7918 r.out.resume_handle = &resume_handle;
7919 r.out.num_entries = &num_entries;
7922 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
7923 "EnumDomains failed");
7924 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
7930 for (i=0;i<sam->count;i++) {
7931 if (!test_LookupDomain(p, tctx, ctx,
7932 sam->entries[i].name.string)) {
7937 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
7938 "EnumDomains failed");
7939 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
7945 static bool test_Connect(struct dcerpc_binding_handle *b,
7946 struct torture_context *tctx,
7947 struct policy_handle *handle)
7949 struct samr_Connect r;
7950 struct samr_Connect2 r2;
7951 struct samr_Connect3 r3;
7952 struct samr_Connect4 r4;
7953 struct samr_Connect5 r5;
7954 union samr_ConnectInfo info;
7955 struct policy_handle h;
7956 uint32_t level_out = 0;
7957 bool ret = true, got_handle = false;
7959 torture_comment(tctx, "Testing samr_Connect\n");
7961 r.in.system_name = NULL;
7962 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7963 r.out.connect_handle = &h;
7965 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect_r(b, tctx, &r),
7967 if (!NT_STATUS_IS_OK(r.out.result)) {
7968 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(r.out.result));
7975 torture_comment(tctx, "Testing samr_Connect2\n");
7977 r2.in.system_name = NULL;
7978 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7979 r2.out.connect_handle = &h;
7981 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect2_r(b, tctx, &r2),
7983 if (!NT_STATUS_IS_OK(r2.out.result)) {
7984 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(r2.out.result));
7988 test_samr_handle_Close(b, tctx, handle);
7994 torture_comment(tctx, "Testing samr_Connect3\n");
7996 r3.in.system_name = NULL;
7998 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7999 r3.out.connect_handle = &h;
8001 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect3_r(b, tctx, &r3),
8003 if (!NT_STATUS_IS_OK(r3.out.result)) {
8004 torture_warning(tctx, "Connect3 failed - %s\n", nt_errstr(r3.out.result));
8008 test_samr_handle_Close(b, tctx, handle);
8014 torture_comment(tctx, "Testing samr_Connect4\n");
8016 r4.in.system_name = "";
8017 r4.in.client_version = 0;
8018 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8019 r4.out.connect_handle = &h;
8021 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect4_r(b, tctx, &r4),
8023 if (!NT_STATUS_IS_OK(r4.out.result)) {
8024 torture_warning(tctx, "Connect4 failed - %s\n", nt_errstr(r4.out.result));
8028 test_samr_handle_Close(b, tctx, handle);
8034 torture_comment(tctx, "Testing samr_Connect5\n");
8036 info.info1.client_version = 0;
8037 info.info1.unknown2 = 0;
8039 r5.in.system_name = "";
8040 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8042 r5.out.level_out = &level_out;
8043 r5.in.info_in = &info;
8044 r5.out.info_out = &info;
8045 r5.out.connect_handle = &h;
8047 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect5_r(b, tctx, &r5),
8049 if (!NT_STATUS_IS_OK(r5.out.result)) {
8050 torture_warning(tctx, "Connect5 failed - %s\n", nt_errstr(r5.out.result));
8054 test_samr_handle_Close(b, tctx, handle);
8064 static bool test_samr_ValidatePassword(struct torture_context *tctx,
8065 struct dcerpc_pipe *p)
8067 struct samr_ValidatePassword r;
8068 union samr_ValidatePasswordReq req;
8069 union samr_ValidatePasswordRep *repp = NULL;
8071 const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
8073 struct dcerpc_binding_handle *b = p->binding_handle;
8075 torture_comment(tctx, "Testing samr_ValidatePassword\n");
8077 if (p->conn->transport.transport != NCACN_IP_TCP) {
8078 torture_comment(tctx, "samr_ValidatePassword only should succeed over NCACN_IP_TCP!\n");
8082 r.in.level = NetValidatePasswordReset;
8087 req.req3.account.string = "non-existent-account-aklsdji";
8089 for (i=0; passwords[i]; i++) {
8090 req.req3.password.string = passwords[i];
8092 status = dcerpc_samr_ValidatePassword_r(b, tctx, &r);
8093 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
8094 torture_skip(tctx, "ValidatePassword not supported by server\n");
8096 torture_assert_ntstatus_ok(tctx, status,
8097 "samr_ValidatePassword failed");
8098 torture_assert_ntstatus_ok(tctx, r.out.result,
8099 "samr_ValidatePassword failed");
8100 torture_comment(tctx, "Server %s password '%s' with code %i\n",
8101 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
8102 req.req3.password.string, repp->ctr3.status);
8108 bool torture_rpc_samr(struct torture_context *torture)
8111 struct dcerpc_pipe *p;
8113 struct torture_samr_context *ctx;
8114 struct dcerpc_binding_handle *b;
8116 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8117 if (!NT_STATUS_IS_OK(status)) {
8120 b = p->binding_handle;
8122 ctx = talloc_zero(torture, struct torture_samr_context);
8124 ctx->choice = TORTURE_SAMR_OTHER;
8126 ret &= test_Connect(b, torture, &ctx->handle);
8128 if (!torture_setting_bool(torture, "samba3", false)) {
8129 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8132 ret &= test_EnumDomains(p, torture, ctx);
8134 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8136 ret &= test_Shutdown(b, torture, &ctx->handle);
8138 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8144 bool torture_rpc_samr_users(struct torture_context *torture)
8147 struct dcerpc_pipe *p;
8149 struct torture_samr_context *ctx;
8150 struct dcerpc_binding_handle *b;
8152 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8153 if (!NT_STATUS_IS_OK(status)) {
8156 b = p->binding_handle;
8158 ctx = talloc_zero(torture, struct torture_samr_context);
8160 ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
8162 ret &= test_Connect(b, torture, &ctx->handle);
8164 if (!torture_setting_bool(torture, "samba3", false)) {
8165 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8168 ret &= test_EnumDomains(p, torture, ctx);
8170 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8172 ret &= test_Shutdown(b, torture, &ctx->handle);
8174 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8180 bool torture_rpc_samr_passwords(struct torture_context *torture)
8183 struct dcerpc_pipe *p;
8185 struct torture_samr_context *ctx;
8186 struct dcerpc_binding_handle *b;
8188 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8189 if (!NT_STATUS_IS_OK(status)) {
8192 b = p->binding_handle;
8194 ctx = talloc_zero(torture, struct torture_samr_context);
8196 ctx->choice = TORTURE_SAMR_PASSWORDS;
8198 ret &= test_Connect(b, torture, &ctx->handle);
8200 ret &= test_EnumDomains(p, torture, ctx);
8202 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8207 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
8208 struct dcerpc_pipe *p2,
8209 struct cli_credentials *machine_credentials)
8212 struct dcerpc_pipe *p;
8214 struct torture_samr_context *ctx;
8215 struct dcerpc_binding_handle *b;
8217 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8218 if (!NT_STATUS_IS_OK(status)) {
8221 b = p->binding_handle;
8223 ctx = talloc_zero(torture, struct torture_samr_context);
8225 ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
8226 ctx->machine_credentials = machine_credentials;
8228 ret &= test_Connect(b, torture, &ctx->handle);
8230 ret &= test_EnumDomains(p, torture, ctx);
8232 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8237 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
8239 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.pwdlastset");
8240 struct torture_rpc_tcase *tcase;
8242 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8244 TEST_ACCOUNT_NAME_PWD);
8246 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
8247 torture_rpc_samr_pwdlastset);
8252 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
8253 struct dcerpc_pipe *p2,
8254 struct cli_credentials *machine_credentials)
8257 struct dcerpc_pipe *p;
8259 struct torture_samr_context *ctx;
8260 struct dcerpc_binding_handle *b;
8262 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8263 if (!NT_STATUS_IS_OK(status)) {
8266 b = p->binding_handle;
8268 ctx = talloc_zero(torture, struct torture_samr_context);
8270 ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
8271 ctx->machine_credentials = machine_credentials;
8273 ret &= test_Connect(b, torture, &ctx->handle);
8275 ret &= test_EnumDomains(p, torture, ctx);
8277 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8282 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
8284 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.users.privileges");
8285 struct torture_rpc_tcase *tcase;
8287 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8289 TEST_ACCOUNT_NAME_PWD);
8291 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
8292 torture_rpc_samr_users_privileges_delete_user);
8297 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
8298 struct dcerpc_pipe *p2,
8302 struct dcerpc_pipe *p;
8304 struct torture_samr_context *ctx =
8305 talloc_get_type_abort(data, struct torture_samr_context);
8306 struct dcerpc_binding_handle *b;
8308 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8309 if (!NT_STATUS_IS_OK(status)) {
8312 b = p->binding_handle;
8314 ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
8315 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8316 ctx->num_objects_large_dc);
8318 ret &= test_Connect(b, torture, &ctx->handle);
8320 ret &= test_EnumDomains(p, torture, ctx);
8322 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8327 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
8328 struct dcerpc_pipe *p2,
8332 struct dcerpc_pipe *p;
8334 struct torture_samr_context *ctx =
8335 talloc_get_type_abort(data, struct torture_samr_context);
8336 struct dcerpc_binding_handle *b;
8338 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8339 if (!NT_STATUS_IS_OK(status)) {
8342 b = p->binding_handle;
8344 ctx->choice = TORTURE_SAMR_MANY_GROUPS;
8345 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8346 ctx->num_objects_large_dc);
8348 ret &= test_Connect(b, torture, &ctx->handle);
8350 ret &= test_EnumDomains(p, torture, ctx);
8352 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8357 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
8358 struct dcerpc_pipe *p2,
8362 struct dcerpc_pipe *p;
8364 struct torture_samr_context *ctx =
8365 talloc_get_type_abort(data, struct torture_samr_context);
8366 struct dcerpc_binding_handle *b;
8368 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8369 if (!NT_STATUS_IS_OK(status)) {
8372 b = p->binding_handle;
8374 ctx->choice = TORTURE_SAMR_MANY_ALIASES;
8375 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8376 ctx->num_objects_large_dc);
8378 ret &= test_Connect(b, torture, &ctx->handle);
8380 ret &= test_EnumDomains(p, torture, ctx);
8382 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8387 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
8389 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.large-dc");
8390 struct torture_rpc_tcase *tcase;
8391 struct torture_samr_context *ctx;
8393 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
8395 ctx = talloc_zero(suite, struct torture_samr_context);
8396 ctx->num_objects_large_dc = 150;
8398 torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
8399 torture_rpc_samr_many_aliases, ctx);
8400 torture_rpc_tcase_add_test_ex(tcase, "many_groups",
8401 torture_rpc_samr_many_groups, ctx);
8402 torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
8403 torture_rpc_samr_many_accounts, ctx);
8408 static bool torture_rpc_samr_badpwdcount(struct torture_context *torture,
8409 struct dcerpc_pipe *p2,
8410 struct cli_credentials *machine_credentials)
8413 struct dcerpc_pipe *p;
8415 struct torture_samr_context *ctx;
8416 struct dcerpc_binding_handle *b;
8418 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8419 if (!NT_STATUS_IS_OK(status)) {
8422 b = p->binding_handle;
8424 ctx = talloc_zero(torture, struct torture_samr_context);
8426 ctx->choice = TORTURE_SAMR_PASSWORDS_BADPWDCOUNT;
8427 ctx->machine_credentials = machine_credentials;
8429 ret &= test_Connect(b, torture, &ctx->handle);
8431 ret &= test_EnumDomains(p, torture, ctx);
8433 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8438 struct torture_suite *torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX *mem_ctx)
8440 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.badpwdcount");
8441 struct torture_rpc_tcase *tcase;
8443 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8445 TEST_ACCOUNT_NAME_PWD);
8447 torture_rpc_tcase_add_test_creds(tcase, "badPwdCount",
8448 torture_rpc_samr_badpwdcount);
8453 static bool torture_rpc_samr_lockout(struct torture_context *torture,
8454 struct dcerpc_pipe *p2,
8455 struct cli_credentials *machine_credentials)
8458 struct dcerpc_pipe *p;
8460 struct torture_samr_context *ctx;
8461 struct dcerpc_binding_handle *b;
8463 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8464 if (!NT_STATUS_IS_OK(status)) {
8467 b = p->binding_handle;
8469 ctx = talloc_zero(torture, struct torture_samr_context);
8471 ctx->choice = TORTURE_SAMR_PASSWORDS_LOCKOUT;
8472 ctx->machine_credentials = machine_credentials;
8474 ret &= test_Connect(b, torture, &ctx->handle);
8476 ret &= test_EnumDomains(p, torture, ctx);
8478 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8483 struct torture_suite *torture_rpc_samr_passwords_lockout(TALLOC_CTX *mem_ctx)
8485 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.lockout");
8486 struct torture_rpc_tcase *tcase;
8488 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8490 TEST_ACCOUNT_NAME_PWD);
8492 torture_rpc_tcase_add_test_creds(tcase, "lockout",
8493 torture_rpc_samr_lockout);
8498 struct torture_suite *torture_rpc_samr_passwords_validate(TALLOC_CTX *mem_ctx)
8500 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.validate");
8501 struct torture_rpc_tcase *tcase;
8503 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr",
8505 torture_rpc_tcase_add_test(tcase, "validate",
8506 test_samr_ValidatePassword);