2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7 Copyright (C) Guenther Deschner 2008-2010
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "torture/torture.h"
25 #include "system/time.h"
26 #include "librpc/gen_ndr/lsa.h"
27 #include "librpc/gen_ndr/ndr_netlogon.h"
28 #include "librpc/gen_ndr/ndr_netlogon_c.h"
29 #include "librpc/gen_ndr/ndr_samr_c.h"
30 #include "librpc/gen_ndr/ndr_lsa_c.h"
31 #include "../lib/crypto/crypto.h"
32 #include "libcli/auth/libcli_auth.h"
33 #include "libcli/security/security.h"
34 #include "torture/rpc/rpc.h"
35 #include "param/param.h"
36 #include "auth/gensec/gensec.h"
37 #include "auth/gensec/gensec_proto.h"
38 #include "../libcli/auth/schannel.h"
39 #include "auth/gensec/schannel_state.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_pipe *p,
71 struct torture_context *tctx,
72 struct policy_handle *handle);
74 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
75 struct torture_context *tctx,
76 struct policy_handle *handle);
78 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
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_pipe *p, struct torture_context *tctx,
105 struct policy_handle *handle)
110 r.in.handle = handle;
111 r.out.handle = handle;
113 status = dcerpc_samr_Close(p, tctx, &r);
114 torture_assert_ntstatus_ok(tctx, status, "Close");
119 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
120 struct policy_handle *handle)
123 struct samr_Shutdown r;
125 if (!torture_setting_bool(tctx, "dangerous", false)) {
126 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
130 r.in.connect_handle = handle;
132 torture_comment(tctx, "testing samr_Shutdown\n");
134 status = dcerpc_samr_Shutdown(p, tctx, &r);
135 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
140 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
141 struct policy_handle *handle)
144 struct samr_SetDsrmPassword r;
145 struct lsa_String string;
146 struct samr_Password hash;
148 if (!torture_setting_bool(tctx, "dangerous", false)) {
149 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
152 E_md4hash("TeSTDSRM123", hash.hash);
154 init_lsa_String(&string, "Administrator");
160 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
162 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
163 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
169 static bool test_QuerySecurity(struct dcerpc_pipe *p,
170 struct torture_context *tctx,
171 struct policy_handle *handle)
174 struct samr_QuerySecurity r;
175 struct samr_SetSecurity s;
176 struct sec_desc_buf *sdbuf = NULL;
178 r.in.handle = handle;
180 r.out.sdbuf = &sdbuf;
182 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
183 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
185 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
187 s.in.handle = handle;
191 if (torture_setting_bool(tctx, "samba4", false)) {
192 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
195 status = dcerpc_samr_SetSecurity(p, tctx, &s);
196 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
198 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
199 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
205 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
206 struct policy_handle *handle, uint32_t base_acct_flags,
207 const char *base_account_name)
210 struct samr_SetUserInfo s;
211 struct samr_SetUserInfo2 s2;
212 struct samr_QueryUserInfo q;
213 struct samr_QueryUserInfo q0;
214 union samr_UserInfo u;
215 union samr_UserInfo *info;
217 const char *test_account_name;
219 uint32_t user_extra_flags = 0;
221 if (!torture_setting_bool(tctx, "samba3", false)) {
222 if (base_acct_flags == ACB_NORMAL) {
223 /* When created, accounts are expired by default */
224 user_extra_flags = ACB_PW_EXPIRED;
228 s.in.user_handle = handle;
231 s2.in.user_handle = handle;
234 q.in.user_handle = handle;
238 #define TESTCALL(call, r) \
239 status = dcerpc_samr_ ##call(p, tctx, &r); \
240 if (!NT_STATUS_IS_OK(status)) { \
241 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
242 r.in.level, nt_errstr(status), __location__); \
247 #define STRING_EQUAL(s1, s2, field) \
248 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
249 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
250 #field, s2, __location__); \
255 #define MEM_EQUAL(s1, s2, length, field) \
256 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
257 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
258 #field, (const char *)s2, __location__); \
263 #define INT_EQUAL(i1, i2, field) \
265 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
266 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
271 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
272 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
274 TESTCALL(QueryUserInfo, q) \
276 s2.in.level = lvl1; \
279 ZERO_STRUCT(u.info21); \
280 u.info21.fields_present = fpval; \
282 init_lsa_String(&u.info ## lvl1.field1, value); \
283 TESTCALL(SetUserInfo, s) \
284 TESTCALL(SetUserInfo2, s2) \
285 init_lsa_String(&u.info ## lvl1.field1, ""); \
286 TESTCALL(QueryUserInfo, q); \
288 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
290 TESTCALL(QueryUserInfo, q) \
292 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
295 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
296 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
298 TESTCALL(QueryUserInfo, q) \
300 s2.in.level = lvl1; \
303 ZERO_STRUCT(u.info21); \
304 u.info21.fields_present = fpval; \
306 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
307 TESTCALL(SetUserInfo, s) \
308 TESTCALL(SetUserInfo2, s2) \
309 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
310 TESTCALL(QueryUserInfo, q); \
312 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
314 TESTCALL(QueryUserInfo, q) \
316 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
319 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
320 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
322 TESTCALL(QueryUserInfo, q) \
324 s2.in.level = lvl1; \
327 uint8_t *bits = u.info21.logon_hours.bits; \
328 ZERO_STRUCT(u.info21); \
329 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
330 u.info21.logon_hours.units_per_week = 168; \
331 u.info21.logon_hours.bits = bits; \
333 u.info21.fields_present = fpval; \
335 u.info ## lvl1.field1 = value; \
336 TESTCALL(SetUserInfo, s) \
337 TESTCALL(SetUserInfo2, s2) \
338 u.info ## lvl1.field1 = 0; \
339 TESTCALL(QueryUserInfo, q); \
341 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
343 TESTCALL(QueryUserInfo, q) \
345 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
348 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
349 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
353 do { TESTCALL(QueryUserInfo, q0) } while (0);
355 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
356 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
357 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
360 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
361 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
362 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
363 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
364 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
365 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
366 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
367 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
368 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
369 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
370 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
371 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
372 test_account_name = base_account_name;
373 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
374 SAMR_FIELD_ACCOUNT_NAME);
376 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
377 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
378 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
379 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
380 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
381 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
382 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
383 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
384 SAMR_FIELD_FULL_NAME);
386 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
387 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
388 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
389 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
390 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
391 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
392 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
393 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
394 SAMR_FIELD_FULL_NAME);
396 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
397 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
398 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
399 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
400 SAMR_FIELD_LOGON_SCRIPT);
402 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
403 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
404 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
405 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
406 SAMR_FIELD_PROFILE_PATH);
408 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
409 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
410 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
411 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
412 SAMR_FIELD_HOME_DIRECTORY);
413 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
414 SAMR_FIELD_HOME_DIRECTORY);
416 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
417 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
418 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
419 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
420 SAMR_FIELD_HOME_DRIVE);
421 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
422 SAMR_FIELD_HOME_DRIVE);
424 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
425 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
426 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
427 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
428 SAMR_FIELD_DESCRIPTION);
430 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
431 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
432 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
433 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
434 SAMR_FIELD_WORKSTATIONS);
435 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
436 SAMR_FIELD_WORKSTATIONS);
437 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
438 SAMR_FIELD_WORKSTATIONS);
439 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
440 SAMR_FIELD_WORKSTATIONS);
442 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
443 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
444 SAMR_FIELD_PARAMETERS);
445 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
446 SAMR_FIELD_PARAMETERS);
447 /* also empty user parameters are allowed */
448 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
449 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
450 SAMR_FIELD_PARAMETERS);
451 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
452 SAMR_FIELD_PARAMETERS);
454 /* Samba 3 cannot store country_code and copy_page atm. - gd */
455 if (!torture_setting_bool(tctx, "samba3", false)) {
456 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
457 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
458 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
459 SAMR_FIELD_COUNTRY_CODE);
460 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
461 SAMR_FIELD_COUNTRY_CODE);
463 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
464 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
465 SAMR_FIELD_CODE_PAGE);
466 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
467 SAMR_FIELD_CODE_PAGE);
470 if (!torture_setting_bool(tctx, "samba3", false)) {
471 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
472 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
473 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
474 SAMR_FIELD_ACCT_EXPIRY);
475 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
476 SAMR_FIELD_ACCT_EXPIRY);
477 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
478 SAMR_FIELD_ACCT_EXPIRY);
480 /* Samba 3 can only store seconds / time_t in passdb - gd */
482 unix_to_nt_time(&nt, time(NULL) + __LINE__);
483 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
484 unix_to_nt_time(&nt, time(NULL) + __LINE__);
485 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
486 unix_to_nt_time(&nt, time(NULL) + __LINE__);
487 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
488 unix_to_nt_time(&nt, time(NULL) + __LINE__);
489 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
490 unix_to_nt_time(&nt, time(NULL) + __LINE__);
491 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
494 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
495 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
496 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
497 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
498 SAMR_FIELD_LOGON_HOURS);
500 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
501 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
502 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
504 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
505 (base_acct_flags | ACB_DISABLED),
506 (base_acct_flags | ACB_DISABLED | user_extra_flags),
509 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
510 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
511 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
512 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
514 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
515 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
516 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
520 /* The 'autolock' flag doesn't stick - check this */
521 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
522 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
523 (base_acct_flags | ACB_DISABLED | user_extra_flags),
526 /* Removing the 'disabled' flag doesn't stick - check this */
527 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
529 (base_acct_flags | ACB_DISABLED | user_extra_flags),
533 /* Samba3 cannot store these atm */
534 if (!torture_setting_bool(tctx, "samba3", false)) {
535 /* The 'store plaintext' flag does stick */
536 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
537 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
538 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
540 /* The 'use DES' flag does stick */
541 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
542 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
543 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
545 /* The 'don't require kerberos pre-authentication flag does stick */
546 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
547 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
548 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
550 /* The 'no kerberos PAC required' flag sticks */
551 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
552 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
553 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
556 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
557 (base_acct_flags | ACB_DISABLED),
558 (base_acct_flags | ACB_DISABLED | user_extra_flags),
559 SAMR_FIELD_ACCT_FLAGS);
562 /* these fail with win2003 - it appears you can't set the primary gid?
563 the set succeeds, but the gid isn't changed. Very weird! */
564 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
565 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
566 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
567 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
574 generate a random password for password change tests
576 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
578 size_t len = MAX(8, min_len) + (random() % 6);
579 char *s = generate_random_str(mem_ctx, len);
583 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
585 char *s = samr_rand_pass_silent(mem_ctx, min_len);
586 printf("Generated password '%s'\n", s);
592 generate a random password for password change tests
594 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
597 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
598 generate_random_buffer(password.data, password.length);
600 for (i=0; i < len; i++) {
601 if (((uint16_t *)password.data)[i] == 0) {
602 ((uint16_t *)password.data)[i] = 1;
610 generate a random password for password change tests (fixed length)
612 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
614 char *s = generate_random_str(mem_ctx, len);
615 printf("Generated password '%s'\n", s);
619 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
620 struct policy_handle *handle, char **password)
623 struct samr_SetUserInfo s;
624 union samr_UserInfo u;
626 DATA_BLOB session_key;
628 struct samr_GetUserPwInfo pwp;
629 struct samr_PwInfo info;
630 int policy_min_pw_len = 0;
631 pwp.in.user_handle = handle;
632 pwp.out.info = &info;
634 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
635 if (NT_STATUS_IS_OK(status)) {
636 policy_min_pw_len = pwp.out.info->min_password_length;
638 newpass = samr_rand_pass(tctx, policy_min_pw_len);
640 s.in.user_handle = handle;
644 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
645 u.info24.password_expired = 0;
647 status = dcerpc_fetch_session_key(p, &session_key);
648 if (!NT_STATUS_IS_OK(status)) {
649 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
650 s.in.level, nt_errstr(status));
654 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
656 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
658 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
659 if (!NT_STATUS_IS_OK(status)) {
660 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
661 s.in.level, nt_errstr(status));
671 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
672 struct policy_handle *handle, uint32_t fields_present,
676 struct samr_SetUserInfo s;
677 union samr_UserInfo u;
679 DATA_BLOB session_key;
681 struct samr_GetUserPwInfo pwp;
682 struct samr_PwInfo info;
683 int policy_min_pw_len = 0;
684 pwp.in.user_handle = handle;
685 pwp.out.info = &info;
687 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
688 if (NT_STATUS_IS_OK(status)) {
689 policy_min_pw_len = pwp.out.info->min_password_length;
691 newpass = samr_rand_pass(tctx, policy_min_pw_len);
693 s.in.user_handle = handle;
699 u.info23.info.fields_present = fields_present;
701 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
703 status = dcerpc_fetch_session_key(p, &session_key);
704 if (!NT_STATUS_IS_OK(status)) {
705 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
706 s.in.level, nt_errstr(status));
710 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
712 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
714 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
715 if (!NT_STATUS_IS_OK(status)) {
716 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
717 s.in.level, nt_errstr(status));
723 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
725 status = dcerpc_fetch_session_key(p, &session_key);
726 if (!NT_STATUS_IS_OK(status)) {
727 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
728 s.in.level, nt_errstr(status));
732 /* This should break the key nicely */
733 session_key.length--;
734 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
736 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
738 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
739 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
740 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
741 s.in.level, nt_errstr(status));
749 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
750 struct policy_handle *handle, bool makeshort,
754 struct samr_SetUserInfo s;
755 union samr_UserInfo u;
757 DATA_BLOB session_key;
758 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
759 uint8_t confounder[16];
761 struct MD5Context ctx;
762 struct samr_GetUserPwInfo pwp;
763 struct samr_PwInfo info;
764 int policy_min_pw_len = 0;
765 pwp.in.user_handle = handle;
766 pwp.out.info = &info;
768 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
769 if (NT_STATUS_IS_OK(status)) {
770 policy_min_pw_len = pwp.out.info->min_password_length;
772 if (makeshort && policy_min_pw_len) {
773 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
775 newpass = samr_rand_pass(tctx, policy_min_pw_len);
778 s.in.user_handle = handle;
782 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
783 u.info26.password_expired = 0;
785 status = dcerpc_fetch_session_key(p, &session_key);
786 if (!NT_STATUS_IS_OK(status)) {
787 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
788 s.in.level, nt_errstr(status));
792 generate_random_buffer((uint8_t *)confounder, 16);
795 MD5Update(&ctx, confounder, 16);
796 MD5Update(&ctx, session_key.data, session_key.length);
797 MD5Final(confounded_session_key.data, &ctx);
799 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
800 memcpy(&u.info26.password.data[516], confounder, 16);
802 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
804 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
805 if (!NT_STATUS_IS_OK(status)) {
806 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
807 s.in.level, nt_errstr(status));
813 /* This should break the key nicely */
814 confounded_session_key.data[0]++;
816 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
817 memcpy(&u.info26.password.data[516], confounder, 16);
819 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
821 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
822 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
823 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
824 s.in.level, nt_errstr(status));
833 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
834 struct policy_handle *handle, uint32_t fields_present,
838 struct samr_SetUserInfo s;
839 union samr_UserInfo u;
841 DATA_BLOB session_key;
842 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
843 struct MD5Context ctx;
844 uint8_t confounder[16];
846 struct samr_GetUserPwInfo pwp;
847 struct samr_PwInfo info;
848 int policy_min_pw_len = 0;
849 pwp.in.user_handle = handle;
850 pwp.out.info = &info;
852 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
853 if (NT_STATUS_IS_OK(status)) {
854 policy_min_pw_len = pwp.out.info->min_password_length;
856 newpass = samr_rand_pass(tctx, policy_min_pw_len);
858 s.in.user_handle = handle;
864 u.info25.info.fields_present = fields_present;
866 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
868 status = dcerpc_fetch_session_key(p, &session_key);
869 if (!NT_STATUS_IS_OK(status)) {
870 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
871 s.in.level, nt_errstr(status));
875 generate_random_buffer((uint8_t *)confounder, 16);
878 MD5Update(&ctx, confounder, 16);
879 MD5Update(&ctx, session_key.data, session_key.length);
880 MD5Final(confounded_session_key.data, &ctx);
882 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
883 memcpy(&u.info25.password.data[516], confounder, 16);
885 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
887 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
888 if (!NT_STATUS_IS_OK(status)) {
889 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
890 s.in.level, nt_errstr(status));
896 /* This should break the key nicely */
897 confounded_session_key.data[0]++;
899 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
900 memcpy(&u.info25.password.data[516], confounder, 16);
902 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
904 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
905 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
906 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
907 s.in.level, nt_errstr(status));
914 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
915 struct policy_handle *handle, char **password)
918 struct samr_SetUserInfo s;
919 union samr_UserInfo u;
921 DATA_BLOB session_key;
923 struct samr_GetUserPwInfo pwp;
924 struct samr_PwInfo info;
925 int policy_min_pw_len = 0;
926 uint8_t lm_hash[16], nt_hash[16];
928 pwp.in.user_handle = handle;
929 pwp.out.info = &info;
931 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
932 if (NT_STATUS_IS_OK(status)) {
933 policy_min_pw_len = pwp.out.info->min_password_length;
935 newpass = samr_rand_pass(tctx, policy_min_pw_len);
937 s.in.user_handle = handle;
943 u.info18.nt_pwd_active = true;
944 u.info18.lm_pwd_active = true;
946 E_md4hash(newpass, nt_hash);
947 E_deshash(newpass, lm_hash);
949 status = dcerpc_fetch_session_key(p, &session_key);
950 if (!NT_STATUS_IS_OK(status)) {
951 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
952 s.in.level, nt_errstr(status));
958 in = data_blob_const(nt_hash, 16);
959 out = data_blob_talloc_zero(tctx, 16);
960 sess_crypt_blob(&out, &in, &session_key, true);
961 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
965 in = data_blob_const(lm_hash, 16);
966 out = data_blob_talloc_zero(tctx, 16);
967 sess_crypt_blob(&out, &in, &session_key, true);
968 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
971 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
973 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
974 if (!NT_STATUS_IS_OK(status)) {
975 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
976 s.in.level, nt_errstr(status));
985 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
986 struct policy_handle *handle, uint32_t fields_present,
990 struct samr_SetUserInfo s;
991 union samr_UserInfo u;
993 DATA_BLOB session_key;
995 struct samr_GetUserPwInfo pwp;
996 struct samr_PwInfo info;
997 int policy_min_pw_len = 0;
998 uint8_t lm_hash[16], nt_hash[16];
1000 pwp.in.user_handle = handle;
1001 pwp.out.info = &info;
1003 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1004 if (NT_STATUS_IS_OK(status)) {
1005 policy_min_pw_len = pwp.out.info->min_password_length;
1007 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1009 s.in.user_handle = handle;
1013 E_md4hash(newpass, nt_hash);
1014 E_deshash(newpass, lm_hash);
1018 u.info21.fields_present = fields_present;
1020 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1021 u.info21.lm_owf_password.length = 16;
1022 u.info21.lm_owf_password.size = 16;
1023 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1024 u.info21.lm_password_set = true;
1027 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1028 u.info21.nt_owf_password.length = 16;
1029 u.info21.nt_owf_password.size = 16;
1030 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1031 u.info21.nt_password_set = true;
1034 status = dcerpc_fetch_session_key(p, &session_key);
1035 if (!NT_STATUS_IS_OK(status)) {
1036 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1037 s.in.level, nt_errstr(status));
1041 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1043 in = data_blob_const(u.info21.lm_owf_password.array,
1044 u.info21.lm_owf_password.length);
1045 out = data_blob_talloc_zero(tctx, 16);
1046 sess_crypt_blob(&out, &in, &session_key, true);
1047 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1050 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1052 in = data_blob_const(u.info21.nt_owf_password.array,
1053 u.info21.nt_owf_password.length);
1054 out = data_blob_talloc_zero(tctx, 16);
1055 sess_crypt_blob(&out, &in, &session_key, true);
1056 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1059 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1061 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1062 if (!NT_STATUS_IS_OK(status)) {
1063 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
1064 s.in.level, nt_errstr(status));
1067 *password = newpass;
1070 /* try invalid length */
1071 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1073 u.info21.nt_owf_password.length++;
1075 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1077 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1078 torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1079 s.in.level, nt_errstr(status));
1084 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1086 u.info21.lm_owf_password.length++;
1088 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1090 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1091 torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1092 s.in.level, nt_errstr(status));
1100 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1101 struct torture_context *tctx,
1102 struct policy_handle *handle,
1104 uint32_t fields_present,
1105 char **password, uint8_t password_expired,
1107 bool *matched_expected_error)
1110 NTSTATUS expected_error = NT_STATUS_OK;
1111 struct samr_SetUserInfo s;
1112 struct samr_SetUserInfo2 s2;
1113 union samr_UserInfo u;
1115 DATA_BLOB session_key;
1116 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1117 struct MD5Context ctx;
1118 uint8_t confounder[16];
1120 struct samr_GetUserPwInfo pwp;
1121 struct samr_PwInfo info;
1122 int policy_min_pw_len = 0;
1123 const char *comment = NULL;
1124 uint8_t lm_hash[16], nt_hash[16];
1126 pwp.in.user_handle = handle;
1127 pwp.out.info = &info;
1129 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1130 if (NT_STATUS_IS_OK(status)) {
1131 policy_min_pw_len = pwp.out.info->min_password_length;
1133 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1136 s2.in.user_handle = handle;
1138 s2.in.level = level;
1140 s.in.user_handle = handle;
1145 if (fields_present & SAMR_FIELD_COMMENT) {
1146 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1153 E_md4hash(newpass, nt_hash);
1154 E_deshash(newpass, lm_hash);
1156 u.info18.nt_pwd_active = true;
1157 u.info18.lm_pwd_active = true;
1158 u.info18.password_expired = password_expired;
1160 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1161 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1165 E_md4hash(newpass, nt_hash);
1166 E_deshash(newpass, lm_hash);
1168 u.info21.fields_present = fields_present;
1169 u.info21.password_expired = password_expired;
1170 u.info21.comment.string = comment;
1172 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1173 u.info21.lm_owf_password.length = 16;
1174 u.info21.lm_owf_password.size = 16;
1175 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1176 u.info21.lm_password_set = true;
1179 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1180 u.info21.nt_owf_password.length = 16;
1181 u.info21.nt_owf_password.size = 16;
1182 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1183 u.info21.nt_password_set = true;
1188 u.info23.info.fields_present = fields_present;
1189 u.info23.info.password_expired = password_expired;
1190 u.info23.info.comment.string = comment;
1192 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1196 u.info24.password_expired = password_expired;
1198 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1202 u.info25.info.fields_present = fields_present;
1203 u.info25.info.password_expired = password_expired;
1204 u.info25.info.comment.string = comment;
1206 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1210 u.info26.password_expired = password_expired;
1212 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1217 status = dcerpc_fetch_session_key(p, &session_key);
1218 if (!NT_STATUS_IS_OK(status)) {
1219 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1220 s.in.level, nt_errstr(status));
1224 generate_random_buffer((uint8_t *)confounder, 16);
1227 MD5Update(&ctx, confounder, 16);
1228 MD5Update(&ctx, session_key.data, session_key.length);
1229 MD5Final(confounded_session_key.data, &ctx);
1235 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1236 out = data_blob_talloc_zero(tctx, 16);
1237 sess_crypt_blob(&out, &in, &session_key, true);
1238 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1242 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1243 out = data_blob_talloc_zero(tctx, 16);
1244 sess_crypt_blob(&out, &in, &session_key, true);
1245 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1250 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1252 in = data_blob_const(u.info21.lm_owf_password.array,
1253 u.info21.lm_owf_password.length);
1254 out = data_blob_talloc_zero(tctx, 16);
1255 sess_crypt_blob(&out, &in, &session_key, true);
1256 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1258 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1260 in = data_blob_const(u.info21.nt_owf_password.array,
1261 u.info21.nt_owf_password.length);
1262 out = data_blob_talloc_zero(tctx, 16);
1263 sess_crypt_blob(&out, &in, &session_key, true);
1264 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1268 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1271 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1274 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1275 memcpy(&u.info25.password.data[516], confounder, 16);
1278 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1279 memcpy(&u.info26.password.data[516], confounder, 16);
1284 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1286 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1289 if (!NT_STATUS_IS_OK(status)) {
1290 if (fields_present == 0) {
1291 expected_error = NT_STATUS_INVALID_PARAMETER;
1293 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1294 expected_error = NT_STATUS_ACCESS_DENIED;
1298 if (!NT_STATUS_IS_OK(expected_error)) {
1300 torture_assert_ntstatus_equal(tctx,
1302 expected_error, "SetUserInfo2 failed");
1304 torture_assert_ntstatus_equal(tctx,
1306 expected_error, "SetUserInfo failed");
1308 *matched_expected_error = true;
1312 if (!NT_STATUS_IS_OK(status)) {
1313 torture_warning(tctx, "SetUserInfo%s level %u failed - %s\n",
1314 use_setinfo2 ? "2":"", level, nt_errstr(status));
1317 *password = newpass;
1323 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1324 struct policy_handle *handle)
1327 struct samr_SetAliasInfo r;
1328 struct samr_QueryAliasInfo q;
1329 union samr_AliasInfo *info;
1330 uint16_t levels[] = {2, 3};
1334 /* Ignoring switch level 1, as that includes the number of members for the alias
1335 * and setting this to a wrong value might have negative consequences
1338 for (i=0;i<ARRAY_SIZE(levels);i++) {
1339 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1341 r.in.alias_handle = handle;
1342 r.in.level = levels[i];
1343 r.in.info = talloc(tctx, union samr_AliasInfo);
1344 switch (r.in.level) {
1345 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1346 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1347 "Test Description, should test I18N as well"); break;
1348 case ALIASINFOALL: torture_comment(tctx, "ALIASINFOALL ignored\n"); break;
1351 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1352 if (!NT_STATUS_IS_OK(status)) {
1353 torture_warning(tctx, "SetAliasInfo level %u failed - %s\n",
1354 levels[i], nt_errstr(status));
1358 q.in.alias_handle = handle;
1359 q.in.level = levels[i];
1362 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1363 if (!NT_STATUS_IS_OK(status)) {
1364 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
1365 levels[i], nt_errstr(status));
1373 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1374 struct policy_handle *user_handle)
1376 struct samr_GetGroupsForUser r;
1377 struct samr_RidWithAttributeArray *rids = NULL;
1380 torture_comment(tctx, "testing GetGroupsForUser\n");
1382 r.in.user_handle = user_handle;
1385 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1386 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1392 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1393 struct lsa_String *domain_name)
1396 struct samr_GetDomPwInfo r;
1397 struct samr_PwInfo info;
1399 r.in.domain_name = domain_name;
1402 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1404 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1405 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1407 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1408 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1410 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1411 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1413 r.in.domain_name->string = "\\\\__NONAME__";
1414 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1416 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1417 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1419 r.in.domain_name->string = "\\\\Builtin";
1420 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1422 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1423 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1428 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1429 struct policy_handle *handle)
1432 struct samr_GetUserPwInfo r;
1433 struct samr_PwInfo info;
1435 torture_comment(tctx, "Testing GetUserPwInfo\n");
1437 r.in.user_handle = handle;
1440 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1441 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1446 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1447 struct policy_handle *domain_handle, const char *name,
1451 struct samr_LookupNames n;
1452 struct lsa_String sname[2];
1453 struct samr_Ids rids, types;
1455 init_lsa_String(&sname[0], name);
1457 n.in.domain_handle = domain_handle;
1461 n.out.types = &types;
1462 status = dcerpc_samr_LookupNames(p, tctx, &n);
1463 if (NT_STATUS_IS_OK(status)) {
1464 *rid = n.out.rids->ids[0];
1469 init_lsa_String(&sname[1], "xxNONAMExx");
1471 status = dcerpc_samr_LookupNames(p, tctx, &n);
1472 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1473 torture_warning(tctx, "LookupNames[2] failed - %s\n", nt_errstr(status));
1474 if (NT_STATUS_IS_OK(status)) {
1475 return NT_STATUS_UNSUCCESSFUL;
1481 status = dcerpc_samr_LookupNames(p, tctx, &n);
1482 if (!NT_STATUS_IS_OK(status)) {
1483 torture_warning(tctx, "LookupNames[0] failed - %s\n", nt_errstr(status));
1487 init_lsa_String(&sname[0], "xxNONAMExx");
1489 status = dcerpc_samr_LookupNames(p, tctx, &n);
1490 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1491 torture_warning(tctx, "LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1492 if (NT_STATUS_IS_OK(status)) {
1493 return NT_STATUS_UNSUCCESSFUL;
1498 init_lsa_String(&sname[0], "xxNONAMExx");
1499 init_lsa_String(&sname[1], "xxNONAME2xx");
1501 status = dcerpc_samr_LookupNames(p, tctx, &n);
1502 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1503 torture_warning(tctx, "LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1504 if (NT_STATUS_IS_OK(status)) {
1505 return NT_STATUS_UNSUCCESSFUL;
1510 return NT_STATUS_OK;
1513 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p,
1514 struct torture_context *tctx,
1515 struct policy_handle *domain_handle,
1516 const char *name, struct policy_handle *user_handle)
1519 struct samr_OpenUser r;
1522 status = test_LookupName(p, tctx, domain_handle, name, &rid);
1523 if (!NT_STATUS_IS_OK(status)) {
1527 r.in.domain_handle = domain_handle;
1528 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1530 r.out.user_handle = user_handle;
1531 status = dcerpc_samr_OpenUser(p, tctx, &r);
1532 if (!NT_STATUS_IS_OK(status)) {
1533 torture_warning(tctx, "OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1540 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
1541 struct torture_context *tctx,
1542 struct policy_handle *handle)
1545 struct samr_ChangePasswordUser r;
1547 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1548 struct policy_handle user_handle;
1549 char *oldpass = "test";
1550 char *newpass = "test2";
1551 uint8_t old_nt_hash[16], new_nt_hash[16];
1552 uint8_t old_lm_hash[16], new_lm_hash[16];
1554 status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
1555 if (!NT_STATUS_IS_OK(status)) {
1559 torture_comment(tctx, "Testing ChangePasswordUser for user 'testuser'\n");
1561 torture_comment(tctx, "old password: %s\n", oldpass);
1562 torture_comment(tctx, "new password: %s\n", newpass);
1564 E_md4hash(oldpass, old_nt_hash);
1565 E_md4hash(newpass, new_nt_hash);
1566 E_deshash(oldpass, old_lm_hash);
1567 E_deshash(newpass, new_lm_hash);
1569 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1570 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1571 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1572 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1573 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1574 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1576 r.in.handle = &user_handle;
1577 r.in.lm_present = 1;
1578 r.in.old_lm_crypted = &hash1;
1579 r.in.new_lm_crypted = &hash2;
1580 r.in.nt_present = 1;
1581 r.in.old_nt_crypted = &hash3;
1582 r.in.new_nt_crypted = &hash4;
1583 r.in.cross1_present = 1;
1584 r.in.nt_cross = &hash5;
1585 r.in.cross2_present = 1;
1586 r.in.lm_cross = &hash6;
1588 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1589 if (!NT_STATUS_IS_OK(status)) {
1590 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(status));
1594 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1602 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1603 const char *acct_name,
1604 struct policy_handle *handle, char **password)
1607 struct samr_ChangePasswordUser r;
1609 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1610 struct policy_handle user_handle;
1612 uint8_t old_nt_hash[16], new_nt_hash[16];
1613 uint8_t old_lm_hash[16], new_lm_hash[16];
1614 bool changed = true;
1617 struct samr_GetUserPwInfo pwp;
1618 struct samr_PwInfo info;
1619 int policy_min_pw_len = 0;
1621 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1622 if (!NT_STATUS_IS_OK(status)) {
1625 pwp.in.user_handle = &user_handle;
1626 pwp.out.info = &info;
1628 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1629 if (NT_STATUS_IS_OK(status)) {
1630 policy_min_pw_len = pwp.out.info->min_password_length;
1632 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1634 torture_comment(tctx, "Testing ChangePasswordUser\n");
1636 torture_assert(tctx, *password != NULL,
1637 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1639 oldpass = *password;
1641 E_md4hash(oldpass, old_nt_hash);
1642 E_md4hash(newpass, new_nt_hash);
1643 E_deshash(oldpass, old_lm_hash);
1644 E_deshash(newpass, new_lm_hash);
1646 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1647 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1648 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1649 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1650 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1651 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1653 r.in.user_handle = &user_handle;
1654 r.in.lm_present = 1;
1655 /* Break the LM hash */
1657 r.in.old_lm_crypted = &hash1;
1658 r.in.new_lm_crypted = &hash2;
1659 r.in.nt_present = 1;
1660 r.in.old_nt_crypted = &hash3;
1661 r.in.new_nt_crypted = &hash4;
1662 r.in.cross1_present = 1;
1663 r.in.nt_cross = &hash5;
1664 r.in.cross2_present = 1;
1665 r.in.lm_cross = &hash6;
1667 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1668 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1669 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1671 /* Unbreak the LM hash */
1674 r.in.user_handle = &user_handle;
1675 r.in.lm_present = 1;
1676 r.in.old_lm_crypted = &hash1;
1677 r.in.new_lm_crypted = &hash2;
1678 /* Break the NT hash */
1680 r.in.nt_present = 1;
1681 r.in.old_nt_crypted = &hash3;
1682 r.in.new_nt_crypted = &hash4;
1683 r.in.cross1_present = 1;
1684 r.in.nt_cross = &hash5;
1685 r.in.cross2_present = 1;
1686 r.in.lm_cross = &hash6;
1688 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1689 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1690 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1692 /* Unbreak the NT hash */
1695 r.in.user_handle = &user_handle;
1696 r.in.lm_present = 1;
1697 r.in.old_lm_crypted = &hash1;
1698 r.in.new_lm_crypted = &hash2;
1699 r.in.nt_present = 1;
1700 r.in.old_nt_crypted = &hash3;
1701 r.in.new_nt_crypted = &hash4;
1702 r.in.cross1_present = 1;
1703 r.in.nt_cross = &hash5;
1704 r.in.cross2_present = 1;
1705 /* Break the LM cross */
1707 r.in.lm_cross = &hash6;
1709 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1710 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1711 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1715 /* Unbreak the LM cross */
1718 r.in.user_handle = &user_handle;
1719 r.in.lm_present = 1;
1720 r.in.old_lm_crypted = &hash1;
1721 r.in.new_lm_crypted = &hash2;
1722 r.in.nt_present = 1;
1723 r.in.old_nt_crypted = &hash3;
1724 r.in.new_nt_crypted = &hash4;
1725 r.in.cross1_present = 1;
1726 /* Break the NT cross */
1728 r.in.nt_cross = &hash5;
1729 r.in.cross2_present = 1;
1730 r.in.lm_cross = &hash6;
1732 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1733 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1734 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1738 /* Unbreak the NT cross */
1742 /* Reset the hashes to not broken values */
1743 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1744 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1745 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1746 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1747 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1748 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1750 r.in.user_handle = &user_handle;
1751 r.in.lm_present = 1;
1752 r.in.old_lm_crypted = &hash1;
1753 r.in.new_lm_crypted = &hash2;
1754 r.in.nt_present = 1;
1755 r.in.old_nt_crypted = &hash3;
1756 r.in.new_nt_crypted = &hash4;
1757 r.in.cross1_present = 1;
1758 r.in.nt_cross = &hash5;
1759 r.in.cross2_present = 0;
1760 r.in.lm_cross = NULL;
1762 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1763 if (NT_STATUS_IS_OK(status)) {
1765 *password = newpass;
1766 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1767 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1772 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1774 E_md4hash(oldpass, old_nt_hash);
1775 E_md4hash(newpass, new_nt_hash);
1776 E_deshash(oldpass, old_lm_hash);
1777 E_deshash(newpass, new_lm_hash);
1780 /* Reset the hashes to not broken values */
1781 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1782 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1783 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1784 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1785 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1786 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1788 r.in.user_handle = &user_handle;
1789 r.in.lm_present = 1;
1790 r.in.old_lm_crypted = &hash1;
1791 r.in.new_lm_crypted = &hash2;
1792 r.in.nt_present = 1;
1793 r.in.old_nt_crypted = &hash3;
1794 r.in.new_nt_crypted = &hash4;
1795 r.in.cross1_present = 0;
1796 r.in.nt_cross = NULL;
1797 r.in.cross2_present = 1;
1798 r.in.lm_cross = &hash6;
1800 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1801 if (NT_STATUS_IS_OK(status)) {
1803 *password = newpass;
1804 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1805 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1810 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1812 E_md4hash(oldpass, old_nt_hash);
1813 E_md4hash(newpass, new_nt_hash);
1814 E_deshash(oldpass, old_lm_hash);
1815 E_deshash(newpass, new_lm_hash);
1818 /* Reset the hashes to not broken values */
1819 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1820 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1821 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1822 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1823 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1824 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1826 r.in.user_handle = &user_handle;
1827 r.in.lm_present = 1;
1828 r.in.old_lm_crypted = &hash1;
1829 r.in.new_lm_crypted = &hash2;
1830 r.in.nt_present = 1;
1831 r.in.old_nt_crypted = &hash3;
1832 r.in.new_nt_crypted = &hash4;
1833 r.in.cross1_present = 1;
1834 r.in.nt_cross = &hash5;
1835 r.in.cross2_present = 1;
1836 r.in.lm_cross = &hash6;
1838 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1839 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1840 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1841 } else if (!NT_STATUS_IS_OK(status)) {
1842 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(status));
1846 *password = newpass;
1849 r.in.user_handle = &user_handle;
1850 r.in.lm_present = 1;
1851 r.in.old_lm_crypted = &hash1;
1852 r.in.new_lm_crypted = &hash2;
1853 r.in.nt_present = 1;
1854 r.in.old_nt_crypted = &hash3;
1855 r.in.new_nt_crypted = &hash4;
1856 r.in.cross1_present = 1;
1857 r.in.nt_cross = &hash5;
1858 r.in.cross2_present = 1;
1859 r.in.lm_cross = &hash6;
1862 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1863 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1864 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1865 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1866 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1872 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1880 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1881 const char *acct_name,
1882 struct policy_handle *handle, char **password)
1885 struct samr_OemChangePasswordUser2 r;
1887 struct samr_Password lm_verifier;
1888 struct samr_CryptPassword lm_pass;
1889 struct lsa_AsciiString server, account, account_bad;
1892 uint8_t old_lm_hash[16], new_lm_hash[16];
1894 struct samr_GetDomPwInfo dom_pw_info;
1895 struct samr_PwInfo info;
1896 int policy_min_pw_len = 0;
1898 struct lsa_String domain_name;
1900 domain_name.string = "";
1901 dom_pw_info.in.domain_name = &domain_name;
1902 dom_pw_info.out.info = &info;
1904 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1906 torture_assert(tctx, *password != NULL,
1907 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1909 oldpass = *password;
1911 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1912 if (NT_STATUS_IS_OK(status)) {
1913 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1916 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1918 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1919 account.string = acct_name;
1921 E_deshash(oldpass, old_lm_hash);
1922 E_deshash(newpass, new_lm_hash);
1924 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1925 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1926 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1928 r.in.server = &server;
1929 r.in.account = &account;
1930 r.in.password = &lm_pass;
1931 r.in.hash = &lm_verifier;
1933 /* Break the verification */
1934 lm_verifier.hash[0]++;
1936 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1938 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1939 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1940 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1945 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1946 /* Break the old password */
1948 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1949 /* unbreak it for the next operation */
1951 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1953 r.in.server = &server;
1954 r.in.account = &account;
1955 r.in.password = &lm_pass;
1956 r.in.hash = &lm_verifier;
1958 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1960 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1961 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1962 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1967 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1968 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1970 r.in.server = &server;
1971 r.in.account = &account;
1972 r.in.password = &lm_pass;
1975 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1977 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1978 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1979 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1984 /* This shouldn't be a valid name */
1985 account_bad.string = TEST_ACCOUNT_NAME "XX";
1986 r.in.account = &account_bad;
1988 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1990 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1991 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1996 /* This shouldn't be a valid name */
1997 account_bad.string = TEST_ACCOUNT_NAME "XX";
1998 r.in.account = &account_bad;
1999 r.in.password = &lm_pass;
2000 r.in.hash = &lm_verifier;
2002 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2004 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2005 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2010 /* This shouldn't be a valid name */
2011 account_bad.string = TEST_ACCOUNT_NAME "XX";
2012 r.in.account = &account_bad;
2013 r.in.password = NULL;
2014 r.in.hash = &lm_verifier;
2016 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2018 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2019 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2024 E_deshash(oldpass, old_lm_hash);
2025 E_deshash(newpass, new_lm_hash);
2027 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2028 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2029 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2031 r.in.server = &server;
2032 r.in.account = &account;
2033 r.in.password = &lm_pass;
2034 r.in.hash = &lm_verifier;
2036 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2037 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2038 torture_comment(tctx, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2039 } else if (!NT_STATUS_IS_OK(status)) {
2040 torture_warning(tctx, "OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
2043 *password = newpass;
2050 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2051 const char *acct_name,
2053 char *newpass, bool allow_password_restriction)
2056 struct samr_ChangePasswordUser2 r;
2058 struct lsa_String server, account;
2059 struct samr_CryptPassword nt_pass, lm_pass;
2060 struct samr_Password nt_verifier, lm_verifier;
2062 uint8_t old_nt_hash[16], new_nt_hash[16];
2063 uint8_t old_lm_hash[16], new_lm_hash[16];
2065 struct samr_GetDomPwInfo dom_pw_info;
2066 struct samr_PwInfo info;
2068 struct lsa_String domain_name;
2070 domain_name.string = "";
2071 dom_pw_info.in.domain_name = &domain_name;
2072 dom_pw_info.out.info = &info;
2074 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2076 torture_assert(tctx, *password != NULL,
2077 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2078 oldpass = *password;
2081 int policy_min_pw_len = 0;
2082 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2083 if (NT_STATUS_IS_OK(status)) {
2084 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2087 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2090 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2091 init_lsa_String(&account, acct_name);
2093 E_md4hash(oldpass, old_nt_hash);
2094 E_md4hash(newpass, new_nt_hash);
2096 E_deshash(oldpass, old_lm_hash);
2097 E_deshash(newpass, new_lm_hash);
2099 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2100 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2101 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2103 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2104 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2105 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2107 r.in.server = &server;
2108 r.in.account = &account;
2109 r.in.nt_password = &nt_pass;
2110 r.in.nt_verifier = &nt_verifier;
2112 r.in.lm_password = &lm_pass;
2113 r.in.lm_verifier = &lm_verifier;
2115 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2116 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2117 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2118 } else if (!NT_STATUS_IS_OK(status)) {
2119 torture_warning(tctx, "ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2122 *password = newpass;
2129 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2130 const char *account_string,
2131 int policy_min_pw_len,
2133 const char *newpass,
2134 NTTIME last_password_change,
2135 bool handle_reject_reason)
2138 struct samr_ChangePasswordUser3 r;
2140 struct lsa_String server, account, account_bad;
2141 struct samr_CryptPassword nt_pass, lm_pass;
2142 struct samr_Password nt_verifier, lm_verifier;
2144 uint8_t old_nt_hash[16], new_nt_hash[16];
2145 uint8_t old_lm_hash[16], new_lm_hash[16];
2147 struct samr_DomInfo1 *dominfo = NULL;
2148 struct userPwdChangeFailureInformation *reject = NULL;
2150 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2152 if (newpass == NULL) {
2154 if (policy_min_pw_len == 0) {
2155 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2157 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2159 } while (check_password_quality(newpass) == false);
2161 torture_comment(tctx, "Using password '%s'\n", newpass);
2164 torture_assert(tctx, *password != NULL,
2165 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2167 oldpass = *password;
2168 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2169 init_lsa_String(&account, account_string);
2171 E_md4hash(oldpass, old_nt_hash);
2172 E_md4hash(newpass, new_nt_hash);
2174 E_deshash(oldpass, old_lm_hash);
2175 E_deshash(newpass, new_lm_hash);
2177 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2178 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2179 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2181 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2182 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2183 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2185 /* Break the verification */
2186 nt_verifier.hash[0]++;
2188 r.in.server = &server;
2189 r.in.account = &account;
2190 r.in.nt_password = &nt_pass;
2191 r.in.nt_verifier = &nt_verifier;
2193 r.in.lm_password = &lm_pass;
2194 r.in.lm_verifier = &lm_verifier;
2195 r.in.password3 = NULL;
2196 r.out.dominfo = &dominfo;
2197 r.out.reject = &reject;
2199 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2200 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2201 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2202 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2207 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2208 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2209 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2211 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2212 /* Break the NT hash */
2214 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2215 /* Unbreak it again */
2217 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2219 r.in.server = &server;
2220 r.in.account = &account;
2221 r.in.nt_password = &nt_pass;
2222 r.in.nt_verifier = &nt_verifier;
2224 r.in.lm_password = &lm_pass;
2225 r.in.lm_verifier = &lm_verifier;
2226 r.in.password3 = NULL;
2227 r.out.dominfo = &dominfo;
2228 r.out.reject = &reject;
2230 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2231 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2232 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2233 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2238 /* This shouldn't be a valid name */
2239 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2241 r.in.account = &account_bad;
2242 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2243 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2244 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2249 E_md4hash(oldpass, old_nt_hash);
2250 E_md4hash(newpass, new_nt_hash);
2252 E_deshash(oldpass, old_lm_hash);
2253 E_deshash(newpass, new_lm_hash);
2255 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2256 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2257 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2259 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2260 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2261 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2263 r.in.server = &server;
2264 r.in.account = &account;
2265 r.in.nt_password = &nt_pass;
2266 r.in.nt_verifier = &nt_verifier;
2268 r.in.lm_password = &lm_pass;
2269 r.in.lm_verifier = &lm_verifier;
2270 r.in.password3 = NULL;
2271 r.out.dominfo = &dominfo;
2272 r.out.reject = &reject;
2274 unix_to_nt_time(&t, time(NULL));
2276 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2278 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2281 && handle_reject_reason
2282 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2283 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2285 if (reject && (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR)) {
2286 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2287 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2292 /* We tested the order of precendence which is as follows:
2301 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2302 (last_password_change + dominfo->min_password_age > t)) {
2304 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2305 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2306 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2310 } else if ((dominfo->min_password_length > 0) &&
2311 (strlen(newpass) < dominfo->min_password_length)) {
2313 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2314 torture_warning(tctx, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2315 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT, reject->extendedFailureReason);
2319 } else if ((dominfo->password_history_length > 0) &&
2320 strequal(oldpass, newpass)) {
2322 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PWD_IN_HISTORY) {
2323 torture_warning(tctx, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2324 SAM_PWD_CHANGE_PWD_IN_HISTORY, reject->extendedFailureReason);
2327 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2329 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NOT_COMPLEX) {
2330 torture_warning(tctx, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2331 SAM_PWD_CHANGE_NOT_COMPLEX, reject->extendedFailureReason);
2337 if (reject->extendedFailureReason == SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2338 /* retry with adjusted size */
2339 return test_ChangePasswordUser3(p, tctx, account_string,
2340 dominfo->min_password_length,
2341 password, NULL, 0, false);
2345 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2346 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2347 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2348 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2351 /* Perhaps the server has a 'min password age' set? */
2354 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2355 *password = talloc_strdup(tctx, newpass);
2361 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2362 const char *account_string,
2363 struct policy_handle *handle,
2367 struct samr_ChangePasswordUser3 r;
2368 struct samr_SetUserInfo s;
2369 union samr_UserInfo u;
2370 DATA_BLOB session_key;
2371 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2372 uint8_t confounder[16];
2373 struct MD5Context ctx;
2376 struct lsa_String server, account;
2377 struct samr_CryptPassword nt_pass;
2378 struct samr_Password nt_verifier;
2379 DATA_BLOB new_random_pass;
2382 uint8_t old_nt_hash[16], new_nt_hash[16];
2384 struct samr_DomInfo1 *dominfo = NULL;
2385 struct userPwdChangeFailureInformation *reject = NULL;
2387 new_random_pass = samr_very_rand_pass(tctx, 128);
2389 torture_assert(tctx, *password != NULL,
2390 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2392 oldpass = *password;
2393 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2394 init_lsa_String(&account, account_string);
2396 s.in.user_handle = handle;
2402 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2404 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2406 status = dcerpc_fetch_session_key(p, &session_key);
2407 if (!NT_STATUS_IS_OK(status)) {
2408 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
2409 s.in.level, nt_errstr(status));
2413 generate_random_buffer((uint8_t *)confounder, 16);
2416 MD5Update(&ctx, confounder, 16);
2417 MD5Update(&ctx, session_key.data, session_key.length);
2418 MD5Final(confounded_session_key.data, &ctx);
2420 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2421 memcpy(&u.info25.password.data[516], confounder, 16);
2423 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2425 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2426 if (!NT_STATUS_IS_OK(status)) {
2427 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
2428 s.in.level, nt_errstr(status));
2432 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2434 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2436 new_random_pass = samr_very_rand_pass(tctx, 128);
2438 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2440 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2441 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2442 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2444 r.in.server = &server;
2445 r.in.account = &account;
2446 r.in.nt_password = &nt_pass;
2447 r.in.nt_verifier = &nt_verifier;
2449 r.in.lm_password = NULL;
2450 r.in.lm_verifier = NULL;
2451 r.in.password3 = NULL;
2452 r.out.dominfo = &dominfo;
2453 r.out.reject = &reject;
2455 unix_to_nt_time(&t, time(NULL));
2457 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2459 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2460 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2461 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2462 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2465 /* Perhaps the server has a 'min password age' set? */
2467 } else if (!NT_STATUS_IS_OK(status)) {
2468 torture_warning(tctx, "ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2472 newpass = samr_rand_pass(tctx, 128);
2474 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2476 E_md4hash(newpass, new_nt_hash);
2478 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2479 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2480 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2482 r.in.server = &server;
2483 r.in.account = &account;
2484 r.in.nt_password = &nt_pass;
2485 r.in.nt_verifier = &nt_verifier;
2487 r.in.lm_password = NULL;
2488 r.in.lm_verifier = NULL;
2489 r.in.password3 = NULL;
2490 r.out.dominfo = &dominfo;
2491 r.out.reject = &reject;
2493 unix_to_nt_time(&t, time(NULL));
2495 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2497 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2498 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2499 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2500 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2503 /* Perhaps the server has a 'min password age' set? */
2506 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2507 *password = talloc_strdup(tctx, newpass);
2514 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2515 struct policy_handle *alias_handle)
2517 struct samr_GetMembersInAlias r;
2518 struct lsa_SidArray sids;
2521 torture_comment(tctx, "Testing GetMembersInAlias\n");
2523 r.in.alias_handle = alias_handle;
2526 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2527 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2532 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2533 struct policy_handle *alias_handle,
2534 const struct dom_sid *domain_sid)
2536 struct samr_AddAliasMember r;
2537 struct samr_DeleteAliasMember d;
2539 struct dom_sid *sid;
2541 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2543 torture_comment(tctx, "testing AddAliasMember\n");
2544 r.in.alias_handle = alias_handle;
2547 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2548 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2550 d.in.alias_handle = alias_handle;
2553 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2554 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2559 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2560 struct policy_handle *alias_handle)
2562 struct samr_AddMultipleMembersToAlias a;
2563 struct samr_RemoveMultipleMembersFromAlias r;
2565 struct lsa_SidArray sids;
2567 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2568 a.in.alias_handle = alias_handle;
2572 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2574 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2575 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2576 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2578 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2579 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2582 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2583 r.in.alias_handle = alias_handle;
2586 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2587 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2589 /* strange! removing twice doesn't give any error */
2590 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2591 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2593 /* but removing an alias that isn't there does */
2594 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2596 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2597 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2602 static bool test_GetAliasMembership(struct dcerpc_pipe *p,
2603 struct torture_context *tctx,
2604 struct policy_handle *domain_handle)
2606 struct samr_GetAliasMembership r;
2607 struct lsa_SidArray sids;
2608 struct samr_Ids rids;
2611 torture_comment(tctx, "Testing GetAliasMembership\n");
2613 if (torture_setting_bool(tctx, "samba4", false)) {
2614 torture_skip(tctx, "skipping GetAliasMembership against s4");
2617 r.in.domain_handle = domain_handle;
2622 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2624 status = dcerpc_samr_GetAliasMembership(p, tctx, &r);
2625 torture_assert_ntstatus_ok(tctx, status,
2626 "samr_GetAliasMembership failed");
2628 torture_assert_int_equal(tctx, sids.num_sids, rids.count,
2629 "protocol misbehaviour");
2632 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2633 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2635 status = dcerpc_samr_GetAliasMembership(p, tctx, &r);
2636 torture_assert_ntstatus_ok(tctx, status,
2637 "samr_GetAliasMembership failed");
2640 /* only true for w2k8 it seems
2641 * win7, xp, w2k3 will return a 0 length array pointer */
2643 if (rids.ids && (rids.count == 0)) {
2644 torture_fail(tctx, "samr_GetAliasMembership returned 0 count and a rids array");
2647 if (!rids.ids && rids.count) {
2648 torture_fail(tctx, "samr_GetAliasMembership returned non-0 count but no rids");
2654 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2655 struct policy_handle *user_handle)
2657 struct samr_TestPrivateFunctionsUser r;
2660 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2662 r.in.user_handle = user_handle;
2664 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2665 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2670 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2671 struct torture_context *tctx,
2672 struct policy_handle *handle,
2677 uint16_t levels[] = { /* 3, */ 5, 21 };
2679 NTTIME pwdlastset3 = 0;
2680 NTTIME pwdlastset5 = 0;
2681 NTTIME pwdlastset21 = 0;
2683 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2684 use_info2 ? "2":"");
2686 for (i=0; i<ARRAY_SIZE(levels); i++) {
2688 struct samr_QueryUserInfo r;
2689 struct samr_QueryUserInfo2 r2;
2690 union samr_UserInfo *info;
2693 r2.in.user_handle = handle;
2694 r2.in.level = levels[i];
2695 r2.out.info = &info;
2696 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2699 r.in.user_handle = handle;
2700 r.in.level = levels[i];
2702 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2705 if (!NT_STATUS_IS_OK(status) &&
2706 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2707 torture_warning(tctx, "QueryUserInfo%s level %u failed - %s\n",
2708 use_info2 ? "2":"", levels[i], nt_errstr(status));
2712 switch (levels[i]) {
2714 pwdlastset3 = info->info3.last_password_change;
2717 pwdlastset5 = info->info5.last_password_change;
2720 pwdlastset21 = info->info21.last_password_change;
2726 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2727 "pwdlastset mixup"); */
2728 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2729 "pwdlastset mixup");
2731 *pwdlastset = pwdlastset21;
2733 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2738 static bool test_SamLogon(struct torture_context *tctx,
2739 struct dcerpc_pipe *p,
2740 struct cli_credentials *test_credentials,
2741 NTSTATUS expected_result,
2745 struct netr_LogonSamLogonEx r;
2746 union netr_LogonLevel logon;
2747 union netr_Validation validation;
2748 uint8_t authoritative;
2749 struct netr_IdentityInfo identity;
2750 struct netr_NetworkInfo ninfo;
2751 struct netr_PasswordInfo pinfo;
2752 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2753 int flags = CLI_CRED_NTLM_AUTH;
2754 uint32_t samlogon_flags = 0;
2755 struct netlogon_creds_CredentialState *creds;
2756 struct netr_Authenticator a;
2758 torture_assert_ntstatus_ok(tctx, dcerpc_schannel_creds(p->conn->security_state.generic_state, tctx, &creds), "");
2760 if (lp_client_lanman_auth(tctx->lp_ctx)) {
2761 flags |= CLI_CRED_LANMAN_AUTH;
2764 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2765 flags |= CLI_CRED_NTLMv2_AUTH;
2768 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2769 &identity.account_name.string,
2770 &identity.domain_name.string);
2772 identity.parameter_control =
2773 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2774 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2775 identity.logon_id_low = 0;
2776 identity.logon_id_high = 0;
2777 identity.workstation.string = cli_credentials_get_workstation(test_credentials);
2780 netlogon_creds_client_authenticator(creds, &a);
2782 if (!E_deshash(cli_credentials_get_password(test_credentials), pinfo.lmpassword.hash)) {
2783 ZERO_STRUCT(pinfo.lmpassword.hash);
2785 E_md4hash(cli_credentials_get_password(test_credentials), pinfo.ntpassword.hash);
2787 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
2788 netlogon_creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
2789 netlogon_creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
2791 netlogon_creds_des_encrypt(creds, &pinfo.lmpassword);
2792 netlogon_creds_des_encrypt(creds, &pinfo.ntpassword);
2795 pinfo.identity_info = identity;
2796 logon.password = &pinfo;
2798 r.in.logon_level = NetlogonInteractiveInformation;
2800 generate_random_buffer(ninfo.challenge,
2801 sizeof(ninfo.challenge));
2802 chal = data_blob_const(ninfo.challenge,
2803 sizeof(ninfo.challenge));
2805 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
2806 cli_credentials_get_domain(test_credentials));
2808 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2814 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2816 ninfo.lm.data = lm_resp.data;
2817 ninfo.lm.length = lm_resp.length;
2819 ninfo.nt.data = nt_resp.data;
2820 ninfo.nt.length = nt_resp.length;
2822 ninfo.identity_info = identity;
2823 logon.network = &ninfo;
2825 r.in.logon_level = NetlogonNetworkInformation;
2828 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2829 r.in.computer_name = cli_credentials_get_workstation(test_credentials);
2830 r.in.logon = &logon;
2831 r.in.flags = &samlogon_flags;
2832 r.out.flags = &samlogon_flags;
2833 r.out.validation = &validation;
2834 r.out.authoritative = &authoritative;
2836 torture_comment(tctx, "Testing LogonSamLogon with name %s\n", identity.account_name.string);
2838 r.in.validation_level = 6;
2840 status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
2841 if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2842 r.in.validation_level = 3;
2843 status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
2845 if (!NT_STATUS_IS_OK(status)) {
2846 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogonEx failed");
2849 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogonEx failed");
2855 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2856 struct dcerpc_pipe *p,
2857 struct cli_credentials *machine_creds,
2858 const char *acct_name,
2860 NTSTATUS expected_samlogon_result,
2864 struct cli_credentials *test_credentials;
2866 test_credentials = cli_credentials_init(tctx);
2868 cli_credentials_set_workstation(test_credentials,
2869 cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
2870 cli_credentials_set_domain(test_credentials,
2871 cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
2872 cli_credentials_set_username(test_credentials,
2873 acct_name, CRED_SPECIFIED);
2874 cli_credentials_set_password(test_credentials,
2875 password, CRED_SPECIFIED);
2877 torture_comment(tctx, "testing samlogon (%s) as %s password: %s\n",
2878 interactive ? "interactive" : "network", acct_name, password);
2880 if (!test_SamLogon(tctx, p, test_credentials,
2881 expected_samlogon_result, interactive)) {
2882 torture_warning(tctx, "new password did not work\n");
2889 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2890 struct dcerpc_pipe *np,
2891 struct torture_context *tctx,
2892 struct policy_handle *handle,
2894 uint32_t fields_present,
2895 uint8_t password_expired,
2896 bool *matched_expected_error,
2898 const char *acct_name,
2900 struct cli_credentials *machine_creds,
2901 bool use_queryinfo2,
2903 NTSTATUS expected_samlogon_result)
2905 const char *fields = NULL;
2912 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2919 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2920 "(password_expired: %d) %s\n",
2921 use_setinfo2 ? "2":"", level, password_expired,
2922 fields ? fields : "");
2924 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2929 matched_expected_error)) {
2933 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2939 if (*matched_expected_error == true) {
2943 if (!test_SamLogon_with_creds(tctx, np,
2947 expected_samlogon_result,
2955 static bool setup_schannel_netlogon_pipe(struct torture_context *tctx,
2956 struct cli_credentials *credentials,
2957 struct dcerpc_pipe **p)
2959 struct dcerpc_binding *b;
2961 torture_assert_ntstatus_ok(tctx, torture_rpc_binding(tctx, &b),
2962 "failed to get rpc binding");
2964 /* We have to use schannel, otherwise the SamLogonEx fails
2965 * with INTERNAL_ERROR */
2967 b->flags &= ~DCERPC_AUTH_OPTIONS;
2968 b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
2970 torture_assert_ntstatus_ok(tctx,
2971 dcerpc_pipe_connect_b(tctx, p, b, &ndr_table_netlogon,
2972 credentials, tctx->ev, tctx->lp_ctx),
2973 "failed to bind to netlogon");
2978 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2979 struct torture_context *tctx,
2980 uint32_t acct_flags,
2981 const char *acct_name,
2982 struct policy_handle *handle,
2984 struct cli_credentials *machine_credentials)
2986 int s = 0, q = 0, f = 0, l = 0, z = 0;
2989 bool set_levels[] = { false, true };
2990 bool query_levels[] = { false, true };
2991 uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
2992 uint32_t nonzeros[] = { 1, 24 };
2993 uint32_t fields_present[] = {
2995 SAMR_FIELD_EXPIRED_FLAG,
2996 SAMR_FIELD_LAST_PWD_CHANGE,
2997 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2999 SAMR_FIELD_NT_PASSWORD_PRESENT,
3000 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3001 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3002 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3003 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3004 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3005 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
3007 struct dcerpc_pipe *np = NULL;
3009 if (torture_setting_bool(tctx, "samba3", false)) {
3011 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
3015 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3017 /* set to 1 to enable testing for all possible opcode
3018 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3021 #define TEST_ALL_LEVELS 1
3022 #define TEST_SET_LEVELS 1
3023 #define TEST_QUERY_LEVELS 1
3025 #ifdef TEST_ALL_LEVELS
3026 for (l=0; l<ARRAY_SIZE(levels); l++) {
3028 for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
3030 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
3031 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
3032 #ifdef TEST_SET_LEVELS
3033 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
3035 #ifdef TEST_QUERY_LEVELS
3036 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
3038 NTTIME pwdlastset_old = 0;
3039 NTTIME pwdlastset_new = 0;
3040 bool matched_expected_error = false;
3041 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
3043 torture_comment(tctx, "------------------------------\n"
3044 "Testing pwdLastSet attribute for flags: 0x%08x "
3045 "(s: %d (l: %d), q: %d)\n",
3046 acct_flags, s, levels[l], q);
3048 switch (levels[l]) {
3052 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3053 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
3054 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
3062 /* set a password and force password change (pwdlastset 0) by
3063 * setting the password expired flag to a non-0 value */
3065 if (!test_SetPassword_level(p, np, tctx, handle,
3069 &matched_expected_error,
3073 machine_credentials,
3076 expected_samlogon_result)) {
3080 if (matched_expected_error == true) {
3081 /* skipping on expected failure */
3085 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3086 * set without the SAMR_FIELD_EXPIRED_FLAG */
3088 switch (levels[l]) {
3092 if ((pwdlastset_new != 0) &&
3093 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3094 torture_comment(tctx, "not considering a non-0 "
3095 "pwdLastSet as a an error as the "
3096 "SAMR_FIELD_EXPIRED_FLAG has not "
3101 if (pwdlastset_new != 0) {
3102 torture_warning(tctx, "pwdLastSet test failed: "
3103 "expected pwdLastSet 0 but got %lld\n",
3110 switch (levels[l]) {
3114 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3115 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3116 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3117 (pwdlastset_old >= pwdlastset_new)) {
3118 torture_warning(tctx, "pwdlastset not increasing\n");
3123 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3124 (pwdlastset_old >= pwdlastset_new)) {
3125 torture_warning(tctx, "pwdlastset not increasing\n");
3135 /* set a password, pwdlastset needs to get updated (increased
3136 * value), password_expired value used here is 0 */
3138 if (!test_SetPassword_level(p, np, tctx, handle,
3142 &matched_expected_error,
3146 machine_credentials,
3149 expected_samlogon_result)) {
3153 /* when a password has been changed, pwdlastset must not be 0 afterwards
3154 * and must be larger then the old value */
3156 switch (levels[l]) {
3161 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3162 * password has been changed, old and new pwdlastset
3163 * need to be the same value */
3165 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3166 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3167 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3169 torture_assert_int_equal(tctx, pwdlastset_old,
3170 pwdlastset_new, "pwdlastset must be equal");
3174 if (pwdlastset_old >= pwdlastset_new) {
3175 torture_warning(tctx, "pwdLastSet test failed: "
3176 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3177 pwdlastset_old, pwdlastset_new);
3180 if (pwdlastset_new == 0) {
3181 torture_warning(tctx, "pwdLastSet test failed: "
3182 "expected non-0 pwdlastset, got: %lld\n",
3188 switch (levels[l]) {
3192 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3193 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3194 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3195 (pwdlastset_old >= pwdlastset_new)) {
3196 torture_warning(tctx, "pwdlastset not increasing\n");
3201 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3202 (pwdlastset_old >= pwdlastset_new)) {
3203 torture_warning(tctx, "pwdlastset not increasing\n");
3209 pwdlastset_old = pwdlastset_new;
3215 /* set a password, pwdlastset needs to get updated (increased
3216 * value), password_expired value used here is 0 */
3218 if (!test_SetPassword_level(p, np, tctx, handle,
3222 &matched_expected_error,
3226 machine_credentials,
3229 expected_samlogon_result)) {
3233 /* when a password has been changed, pwdlastset must not be 0 afterwards
3234 * and must be larger then the old value */
3236 switch (levels[l]) {
3241 /* if no password has been changed, old and new pwdlastset
3242 * need to be the same value */
3244 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3245 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3247 torture_assert_int_equal(tctx, pwdlastset_old,
3248 pwdlastset_new, "pwdlastset must be equal");
3252 if (pwdlastset_old >= pwdlastset_new) {
3253 torture_warning(tctx, "pwdLastSet test failed: "
3254 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3255 pwdlastset_old, pwdlastset_new);
3258 if (pwdlastset_new == 0) {
3259 torture_warning(tctx, "pwdLastSet test failed: "
3260 "expected non-0 pwdlastset, got: %lld\n",
3268 /* set a password and force password change (pwdlastset 0) by
3269 * setting the password expired flag to a non-0 value */
3271 if (!test_SetPassword_level(p, np, tctx, handle,
3275 &matched_expected_error,
3279 machine_credentials,
3282 expected_samlogon_result)) {
3286 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3287 * set without the SAMR_FIELD_EXPIRED_FLAG */
3289 switch (levels[l]) {
3293 if ((pwdlastset_new != 0) &&
3294 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3295 torture_comment(tctx, "not considering a non-0 "
3296 "pwdLastSet as a an error as the "
3297 "SAMR_FIELD_EXPIRED_FLAG has not "
3302 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3303 * password has been changed, old and new pwdlastset
3304 * need to be the same value */
3306 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3307 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3308 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3310 torture_assert_int_equal(tctx, pwdlastset_old,
3311 pwdlastset_new, "pwdlastset must be equal");
3316 if (pwdlastset_old == pwdlastset_new) {
3317 torture_warning(tctx, "pwdLastSet test failed: "
3318 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3319 pwdlastset_old, pwdlastset_new);
3323 if (pwdlastset_new != 0) {
3324 torture_warning(tctx, "pwdLastSet test failed: "
3325 "expected pwdLastSet 0, got %lld\n",
3332 switch (levels[l]) {
3336 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3337 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3338 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3339 (pwdlastset_old >= pwdlastset_new)) {
3340 torture_warning(tctx, "pwdlastset not increasing\n");
3345 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3346 (pwdlastset_old >= pwdlastset_new)) {
3347 torture_warning(tctx, "pwdlastset not increasing\n");
3353 /* if the level we are testing does not have a fields_present
3354 * field, skip all fields present tests by setting f to to
3356 switch (levels[l]) {
3360 f = ARRAY_SIZE(fields_present);
3364 #ifdef TEST_QUERY_LEVELS
3367 #ifdef TEST_SET_LEVELS
3370 } /* fields present */
3374 #undef TEST_SET_LEVELS
3375 #undef TEST_QUERY_LEVELS
3382 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_pipe *p,
3383 struct torture_context *tctx,
3384 struct policy_handle *handle,
3385 uint32_t *badpwdcount)
3387 union samr_UserInfo *info;
3388 struct samr_QueryUserInfo r;
3390 r.in.user_handle = handle;
3394 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3396 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo(p, tctx, &r),
3397 "failed to query userinfo");
3399 *badpwdcount = info->info3.bad_password_count;
3401 torture_comment(tctx, " (bad password count: %d)\n", *badpwdcount);
3406 static bool test_SetUserInfo_acct_flags(struct dcerpc_pipe *p,
3407 struct torture_context *tctx,
3408 struct policy_handle *user_handle,
3409 uint32_t acct_flags)
3411 struct samr_SetUserInfo r;
3412 union samr_UserInfo user_info;
3414 torture_comment(tctx, "Testing SetUserInfo level 16\n");
3416 user_info.info16.acct_flags = acct_flags;
3418 r.in.user_handle = user_handle;
3420 r.in.info = &user_info;
3422 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo(p, tctx, &r),
3423 "failed to set account flags");
3428 static bool test_reset_badpwdcount(struct dcerpc_pipe *p,
3429 struct torture_context *tctx,
3430 struct policy_handle *user_handle,
3431 uint32_t acct_flags,
3434 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3435 "failed to set password");
3437 torture_comment(tctx, "Testing SetUserInfo level 16 (enable account)\n");
3439 torture_assert(tctx,
3440 test_SetUserInfo_acct_flags(p, tctx, user_handle,
3441 acct_flags & ~ACB_DISABLED),
3442 "failed to enable user");
3444 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3445 "failed to set password");
3450 static bool test_SetDomainInfo(struct dcerpc_pipe *p,
3451 struct torture_context *tctx,
3452 struct policy_handle *domain_handle,
3453 enum samr_DomainInfoClass level,
3454 union samr_DomainInfo *info)
3456 struct samr_SetDomainInfo r;
3458 r.in.domain_handle = domain_handle;
3462 torture_assert_ntstatus_ok(tctx,
3463 dcerpc_samr_SetDomainInfo(p, tctx, &r),
3464 "failed to set domain info");
3470 static bool test_Password_badpwdcount(struct dcerpc_pipe *p,
3471 struct dcerpc_pipe *np,
3472 struct torture_context *tctx,
3473 uint32_t acct_flags,
3474 const char *acct_name,
3475 struct policy_handle *domain_handle,
3476 struct policy_handle *user_handle,
3478 struct cli_credentials *machine_credentials,
3479 const char *comment,
3482 NTSTATUS expected_success_status,
3483 struct samr_DomInfo1 *info1,
3484 struct samr_DomInfo12 *info12)
3486 union samr_DomainInfo info;
3489 uint32_t badpwdcount, tmp;
3490 uint32_t password_history_length = 12;
3491 uint32_t lockout_threshold = 15;
3493 torture_comment(tctx, "\nTesting bad pwd count with: %s\n", comment);
3495 torture_assert(tctx, password_history_length < lockout_threshold,
3496 "password history length needs to be smaller than account lockout threshold for this test");
3501 info.info1 = *info1;
3502 info.info1.password_history_length = password_history_length;
3504 torture_assert(tctx,
3505 test_SetDomainInfo(p, tctx, domain_handle,
3506 DomainPasswordInformation, &info),
3507 "failed to set password history length");
3509 info.info12 = *info12;
3510 info.info12.lockout_threshold = lockout_threshold;
3512 torture_assert(tctx,
3513 test_SetDomainInfo(p, tctx, domain_handle,
3514 DomainLockoutInformation, &info),
3515 "failed to set lockout threshold");
3517 /* reset bad pwd count */
3519 torture_assert(tctx,
3520 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
3523 /* enable or disable account */
3525 torture_assert(tctx,
3526 test_SetUserInfo_acct_flags(p, tctx, user_handle,
3527 acct_flags | ACB_DISABLED),
3528 "failed to disable user");
3530 torture_assert(tctx,
3531 test_SetUserInfo_acct_flags(p, tctx, user_handle,
3532 acct_flags & ~ACB_DISABLED),
3533 "failed to enable user");
3537 /* setup password history */
3539 passwords = talloc_array(tctx, char *, password_history_length);
3541 for (i=0; i < password_history_length; i++) {
3543 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3544 "failed to set password");
3545 passwords[i] = talloc_strdup(tctx, *password);
3547 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3548 acct_name, passwords[i],
3549 expected_success_status, interactive)) {
3550 torture_fail(tctx, "failed to auth with latest password");
3553 torture_assert(tctx,
3554 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3556 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3560 /* test with wrong password */
3562 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3563 acct_name, "random_crap",
3564 NT_STATUS_WRONG_PASSWORD, interactive)) {
3565 torture_fail(tctx, "succeeded to authenticate with wrong password");
3568 torture_assert(tctx,
3569 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3571 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3574 /* test with latest good password */
3576 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
3577 passwords[password_history_length-1],
3578 expected_success_status, interactive)) {
3579 torture_fail(tctx, "succeeded to authenticate with wrong password");
3582 torture_assert(tctx,
3583 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3586 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3588 /* only enabled accounts get the bad pwd count reset upon
3589 * successful logon */
3590 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3596 /* test password history */
3598 for (i=0; i < password_history_length; i++) {
3600 torture_comment(tctx, "Testing bad password count behavior with "
3601 "password #%d of #%d\n", i, password_history_length);
3603 /* - network samlogon will succeed auth and not
3604 * increase badpwdcount for 2 last entries
3605 * - interactive samlogon only for the last one */
3607 if (i == password_history_length - 1 ||
3608 (i == password_history_length - 2 && !interactive)) {
3610 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3611 acct_name, passwords[i],
3612 expected_success_status, interactive)) {
3613 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3616 torture_assert(tctx,
3617 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3620 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
3621 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3623 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
3624 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3632 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3633 acct_name, passwords[i],
3634 NT_STATUS_WRONG_PASSWORD, interactive)) {
3635 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3638 torture_assert(tctx,
3639 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3641 /* - network samlogon will fail auth but not increase
3642 * badpwdcount for 3rd last entry
3643 * - interactive samlogon for 3rd and 2nd last entry */
3645 if (i == password_history_length - 3 ||
3646 (i == password_history_length - 2 && interactive)) {
3647 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
3648 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3650 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
3651 torture_assert_int_equal(tctx, badpwdcount, tmp + 1, "unexpected badpwdcount");
3660 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe *p,
3661 struct torture_context *tctx,
3662 uint32_t acct_flags,
3663 const char *acct_name,
3664 struct policy_handle *domain_handle,
3665 struct policy_handle *user_handle,
3667 struct cli_credentials *machine_credentials)
3669 union samr_DomainInfo *q_info, s_info;
3670 struct samr_DomInfo1 info1, _info1;
3671 struct samr_DomInfo12 info12, _info12;
3673 struct dcerpc_pipe *np;
3677 const char *comment;
3680 NTSTATUS expected_success_status;
3683 .comment = "network logon (disabled account)",
3685 .interactive = false,
3686 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
3689 .comment = "network logon (enabled account)",
3691 .interactive = false,
3692 .expected_success_status= NT_STATUS_OK
3695 .comment = "interactive logon (disabled account)",
3697 .interactive = true,
3698 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
3701 .comment = "interactive logon (enabled account)",
3703 .interactive = true,
3704 .expected_success_status= NT_STATUS_OK
3708 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3710 /* backup old policies */
3713 struct samr_QueryDomainInfo2 r;
3715 r.in.domain_handle = domain_handle;
3716 r.in.level = DomainPasswordInformation;
3717 r.out.info = &q_info;
3719 torture_assert_ntstatus_ok(tctx,
3720 dcerpc_samr_QueryDomainInfo2(p, tctx, &r),
3721 "failed to query domain info level 1");
3723 info1 = q_info->info1;
3727 struct samr_QueryDomainInfo2 r;
3729 r.in.domain_handle = domain_handle;
3730 r.in.level = DomainLockoutInformation;
3731 r.out.info = &q_info;
3733 torture_assert_ntstatus_ok(tctx,
3734 dcerpc_samr_QueryDomainInfo2(p, tctx, &r),
3735 "failed to query domain info level 12");
3737 info12 = q_info->info12;
3745 for (i=0; i < ARRAY_SIZE(creds); i++) {
3747 /* skip trust tests for now */
3748 if (acct_flags & ACB_WSTRUST ||
3749 acct_flags & ACB_SVRTRUST ||
3750 acct_flags & ACB_DOMTRUST) {
3754 ret &= test_Password_badpwdcount(p, np, tctx, acct_flags, acct_name,
3755 domain_handle, user_handle, password,
3756 machine_credentials,
3759 creds[i].interactive,
3760 creds[i].expected_success_status,
3763 torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
3765 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
3769 /* restore policies */
3771 s_info.info1 = info1;
3773 torture_assert(tctx,
3774 test_SetDomainInfo(p, tctx, domain_handle,
3775 DomainPasswordInformation, &s_info),
3776 "failed to set password information");
3778 s_info.info12 = info12;
3780 torture_assert(tctx,
3781 test_SetDomainInfo(p, tctx, domain_handle,
3782 DomainLockoutInformation, &s_info),
3783 "failed to set lockout information");
3788 static bool test_QueryUserInfo_acct_flags(struct dcerpc_pipe *p,
3789 struct torture_context *tctx,
3790 struct policy_handle *handle,
3791 uint32_t *acct_flags)
3793 union samr_UserInfo *info;
3794 struct samr_QueryUserInfo r;
3796 r.in.user_handle = handle;
3800 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3802 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo(p, tctx, &r),
3803 "failed to query userinfo");
3805 *acct_flags = info->info16.acct_flags;
3807 torture_comment(tctx, " (acct_flags: 0x%08x)\n", *acct_flags);
3812 static bool test_Password_lockout(struct dcerpc_pipe *p,
3813 struct dcerpc_pipe *np,
3814 struct torture_context *tctx,
3815 uint32_t acct_flags,
3816 const char *acct_name,
3817 struct policy_handle *domain_handle,
3818 struct policy_handle *user_handle,
3820 struct cli_credentials *machine_credentials,
3821 const char *comment,
3824 NTSTATUS expected_success_status,
3825 struct samr_DomInfo1 *info1,
3826 struct samr_DomInfo12 *info12)
3828 union samr_DomainInfo info;
3829 uint32_t badpwdcount;
3830 uint32_t password_history_length = 1;
3831 uint64_t lockout_threshold = 1;
3832 uint32_t lockout_seconds = 5;
3833 uint64_t delta_time_factor = 10 * 1000 * 1000;
3835 torture_comment(tctx, "\nTesting account lockout: %s\n", comment);
3839 info.info1 = *info1;
3841 torture_comment(tctx, "setting password history lenght.\n");
3842 info.info1.password_history_length = password_history_length;
3844 torture_assert(tctx,
3845 test_SetDomainInfo(p, tctx, domain_handle,
3846 DomainPasswordInformation, &info),
3847 "failed to set password history length");
3849 info.info12 = *info12;
3850 info.info12.lockout_threshold = lockout_threshold;
3852 /* set lockout duration < lockout window: should fail */
3853 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
3854 info.info12.lockout_window = ~((lockout_seconds + 1) * delta_time_factor);
3857 struct samr_SetDomainInfo r;
3859 r.in.domain_handle = domain_handle;
3860 r.in.level = DomainLockoutInformation;
3863 torture_assert_ntstatus_equal(tctx,
3864 dcerpc_samr_SetDomainInfo(p, tctx, &r),
3865 NT_STATUS_INVALID_PARAMETER,
3866 "succeeded setting lockout duration < lockout window");
3869 info.info12.lockout_duration = 0;
3870 info.info12.lockout_window = 0;
3872 torture_assert(tctx,
3873 test_SetDomainInfo(p, tctx, domain_handle,
3874 DomainLockoutInformation, &info),
3875 "failed to set lockout window and duration to 0");
3878 /* set lockout duration of 5 seconds */
3879 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
3880 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
3882 torture_assert(tctx,
3883 test_SetDomainInfo(p, tctx, domain_handle,
3884 DomainLockoutInformation, &info),
3885 "failed to set lockout window and duration to 5 seconds");
3887 /* reset bad pwd count */
3889 torture_assert(tctx,
3890 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
3893 /* enable or disable account */
3896 torture_assert(tctx,
3897 test_SetUserInfo_acct_flags(p, tctx, user_handle,
3898 acct_flags | ACB_DISABLED),
3899 "failed to disable user");
3901 torture_assert(tctx,
3902 test_SetUserInfo_acct_flags(p, tctx, user_handle,
3903 acct_flags & ~ACB_DISABLED),
3904 "failed to enable user");
3908 /* test logon with right password */
3910 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3911 acct_name, *password,
3912 expected_success_status, interactive)) {
3913 torture_fail(tctx, "failed to auth with latest password");
3916 torture_assert(tctx,
3917 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3918 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3921 /* test with wrong password ==> lockout */
3923 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3924 acct_name, "random_crap",
3925 NT_STATUS_WRONG_PASSWORD, interactive)) {
3926 torture_fail(tctx, "succeeded to authenticate with wrong password");
3929 torture_assert(tctx,
3930 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3931 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3933 torture_assert(tctx,
3934 test_QueryUserInfo_acct_flags(p, tctx, user_handle, &acct_flags), "");
3935 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
3936 "expected account to be locked");
3939 /* test with good password */
3941 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
3943 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
3945 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
3948 /* bad pwd count should not get updated */
3949 torture_assert(tctx,
3950 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3951 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3953 /* curiously, windows does _not_ set the autlock flag */
3954 torture_assert(tctx,
3955 test_QueryUserInfo_acct_flags(p, tctx, user_handle, &acct_flags), "");
3956 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
3957 "expected account to be locked");
3960 /* with bad password */
3962 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3963 acct_name, "random_crap2",
3964 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
3966 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
3969 /* bad pwd count should not get updated */
3970 torture_assert(tctx,
3971 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3972 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3974 /* curiously, windows does _not_ set the autlock flag */
3975 torture_assert(tctx,
3976 test_QueryUserInfo_acct_flags(p, tctx, user_handle, &acct_flags), "");
3977 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
3978 "expected account to be locked");
3981 /* let lockout duration expire ==> unlock */
3983 torture_comment(tctx, "let lockout duration expire...\n");
3984 sleep(lockout_seconds + 1);
3986 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
3988 expected_success_status, interactive))
3990 torture_fail(tctx, "failed to authenticate after lockout expired");
3993 torture_assert(tctx,
3994 test_QueryUserInfo_acct_flags(p, tctx, user_handle, &acct_flags), "");
3995 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
3996 "expected account not to be locked");
4001 static bool test_Password_lockout_wrap(struct dcerpc_pipe *p,
4002 struct torture_context *tctx,
4003 uint32_t acct_flags,
4004 const char *acct_name,
4005 struct policy_handle *domain_handle,
4006 struct policy_handle *user_handle,
4008 struct cli_credentials *machine_credentials)
4010 union samr_DomainInfo *q_info, s_info;
4011 struct samr_DomInfo1 info1, _info1;
4012 struct samr_DomInfo12 info12, _info12;
4014 struct dcerpc_pipe *np;
4018 const char *comment;
4021 NTSTATUS expected_success_status;
4024 .comment = "network logon (disabled account)",
4026 .interactive = false,
4027 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4030 .comment = "network logon (enabled account)",
4032 .interactive = false,
4033 .expected_success_status= NT_STATUS_OK
4036 .comment = "interactive logon (disabled account)",
4038 .interactive = true,
4039 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4042 .comment = "interactive logon (enabled account)",
4044 .interactive = true,
4045 .expected_success_status= NT_STATUS_OK
4049 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4051 /* backup old policies */
4054 struct samr_QueryDomainInfo2 r;
4056 r.in.domain_handle = domain_handle;
4057 r.in.level = DomainPasswordInformation;
4058 r.out.info = &q_info;
4060 torture_assert_ntstatus_ok(tctx,
4061 dcerpc_samr_QueryDomainInfo2(p, tctx, &r),
4062 "failed to query domain info level 1");
4064 info1 = q_info->info1;
4068 struct samr_QueryDomainInfo2 r;
4070 r.in.domain_handle = domain_handle;
4071 r.in.level = DomainLockoutInformation;
4072 r.out.info = &q_info;
4074 torture_assert_ntstatus_ok(tctx,
4075 dcerpc_samr_QueryDomainInfo2(p, tctx, &r),
4076 "failed to query domain info level 12");
4078 info12 = q_info->info12;
4086 for (i=0; i < ARRAY_SIZE(creds); i++) {
4088 /* skip trust tests for now */
4089 if (acct_flags & ACB_WSTRUST ||
4090 acct_flags & ACB_SVRTRUST ||
4091 acct_flags & ACB_DOMTRUST) {
4095 ret &= test_Password_lockout(p, np, tctx, acct_flags, acct_name,
4096 domain_handle, user_handle, password,
4097 machine_credentials,
4100 creds[i].interactive,
4101 creds[i].expected_success_status,
4104 torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
4106 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4110 /* restore policies */
4112 s_info.info1 = info1;
4114 torture_assert(tctx,
4115 test_SetDomainInfo(p, tctx, domain_handle,
4116 DomainPasswordInformation, &s_info),
4117 "failed to set password information");
4119 s_info.info12 = info12;
4121 torture_assert(tctx,
4122 test_SetDomainInfo(p, tctx, domain_handle,
4123 DomainLockoutInformation, &s_info),
4124 "failed to set lockout information");
4129 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
4130 struct dcerpc_pipe *lp,
4131 struct torture_context *tctx,
4132 struct policy_handle *domain_handle,
4133 struct policy_handle *lsa_handle,
4134 struct policy_handle *user_handle,
4135 const struct dom_sid *domain_sid,
4137 struct cli_credentials *machine_credentials)
4142 struct policy_handle lsa_acct_handle;
4143 struct dom_sid *user_sid;
4145 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
4148 struct lsa_EnumAccountRights r;
4149 struct lsa_RightSet rights;
4151 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4153 r.in.handle = lsa_handle;
4154 r.in.sid = user_sid;
4155 r.out.rights = &rights;
4157 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
4158 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4159 "Expected enum rights for account to fail");
4163 struct lsa_RightSet rights;
4164 struct lsa_StringLarge names[2];
4165 struct lsa_AddAccountRights r;
4167 torture_comment(tctx, "Testing LSA AddAccountRights\n");
4169 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
4170 init_lsa_StringLarge(&names[1], NULL);
4173 rights.names = names;
4175 r.in.handle = lsa_handle;
4176 r.in.sid = user_sid;
4177 r.in.rights = &rights;
4179 status = dcerpc_lsa_AddAccountRights(lp, tctx, &r);
4180 torture_assert_ntstatus_ok(tctx, status,
4181 "Failed to add privileges");
4185 struct lsa_EnumAccounts r;
4186 uint32_t resume_handle = 0;
4187 struct lsa_SidArray lsa_sid_array;
4189 bool found_sid = false;
4191 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4193 r.in.handle = lsa_handle;
4194 r.in.num_entries = 0x1000;
4195 r.in.resume_handle = &resume_handle;
4196 r.out.sids = &lsa_sid_array;
4197 r.out.resume_handle = &resume_handle;
4199 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
4200 torture_assert_ntstatus_ok(tctx, status,
4201 "Failed to enum accounts");
4203 for (i=0; i < lsa_sid_array.num_sids; i++) {
4204 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4209 torture_assert(tctx, found_sid,
4210 "failed to list privileged account");
4214 struct lsa_EnumAccountRights r;
4215 struct lsa_RightSet user_rights;
4217 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4219 r.in.handle = lsa_handle;
4220 r.in.sid = user_sid;
4221 r.out.rights = &user_rights;
4223 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
4224 torture_assert_ntstatus_ok(tctx, status,
4225 "Failed to enum rights for account");
4227 if (user_rights.count < 1) {
4228 torture_warning(tctx, "failed to find newly added rights");
4234 struct lsa_OpenAccount r;
4236 torture_comment(tctx, "Testing LSA OpenAccount\n");
4238 r.in.handle = lsa_handle;
4239 r.in.sid = user_sid;
4240 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4241 r.out.acct_handle = &lsa_acct_handle;
4243 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
4244 torture_assert_ntstatus_ok(tctx, status,
4245 "Failed to open lsa account");
4249 struct lsa_GetSystemAccessAccount r;
4250 uint32_t access_mask;
4252 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4254 r.in.handle = &lsa_acct_handle;
4255 r.out.access_mask = &access_mask;
4257 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
4258 torture_assert_ntstatus_ok(tctx, status,
4259 "Failed to get lsa system access account");
4265 torture_comment(tctx, "Testing LSA Close\n");
4267 r.in.handle = &lsa_acct_handle;
4268 r.out.handle = &lsa_acct_handle;
4270 status = dcerpc_lsa_Close(lp, tctx, &r);
4271 torture_assert_ntstatus_ok(tctx, status,
4272 "Failed to close lsa");
4276 struct samr_DeleteUser r;
4278 torture_comment(tctx, "Testing SAMR DeleteUser\n");
4280 r.in.user_handle = user_handle;
4281 r.out.user_handle = user_handle;
4283 status = dcerpc_samr_DeleteUser(p, tctx, &r);
4284 torture_assert_ntstatus_ok(tctx, status, "Delete User failed");
4288 struct lsa_EnumAccounts r;
4289 uint32_t resume_handle = 0;
4290 struct lsa_SidArray lsa_sid_array;
4292 bool found_sid = false;
4294 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4296 r.in.handle = lsa_handle;
4297 r.in.num_entries = 0x1000;
4298 r.in.resume_handle = &resume_handle;
4299 r.out.sids = &lsa_sid_array;
4300 r.out.resume_handle = &resume_handle;
4302 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
4303 torture_assert_ntstatus_ok(tctx, status,
4304 "Failed to enum accounts");
4306 for (i=0; i < lsa_sid_array.num_sids; i++) {
4307 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4312 torture_assert(tctx, found_sid,
4313 "failed to list privileged account");
4317 struct lsa_EnumAccountRights r;
4318 struct lsa_RightSet user_rights;
4320 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4322 r.in.handle = lsa_handle;
4323 r.in.sid = user_sid;
4324 r.out.rights = &user_rights;
4326 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
4327 torture_assert_ntstatus_ok(tctx, status,
4328 "Failed to enum rights for account");
4330 if (user_rights.count < 1) {
4331 torture_warning(tctx, "failed to find newly added rights");
4337 struct lsa_OpenAccount r;
4339 torture_comment(tctx, "Testing LSA OpenAccount\n");
4341 r.in.handle = lsa_handle;
4342 r.in.sid = user_sid;
4343 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4344 r.out.acct_handle = &lsa_acct_handle;
4346 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
4347 torture_assert_ntstatus_ok(tctx, status,
4348 "Failed to open lsa account");
4352 struct lsa_GetSystemAccessAccount r;
4353 uint32_t access_mask;
4355 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4357 r.in.handle = &lsa_acct_handle;
4358 r.out.access_mask = &access_mask;
4360 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
4361 torture_assert_ntstatus_ok(tctx, status,
4362 "Failed to get lsa system access account");
4366 struct lsa_DeleteObject r;
4368 torture_comment(tctx, "Testing LSA DeleteObject\n");
4370 r.in.handle = &lsa_acct_handle;
4371 r.out.handle = &lsa_acct_handle;
4373 status = dcerpc_lsa_DeleteObject(lp, tctx, &r);
4374 torture_assert_ntstatus_ok(tctx, status,
4375 "Failed to delete object");
4379 struct lsa_EnumAccounts r;
4380 uint32_t resume_handle = 0;
4381 struct lsa_SidArray lsa_sid_array;
4383 bool found_sid = false;
4385 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4387 r.in.handle = lsa_handle;
4388 r.in.num_entries = 0x1000;
4389 r.in.resume_handle = &resume_handle;
4390 r.out.sids = &lsa_sid_array;
4391 r.out.resume_handle = &resume_handle;
4393 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
4394 torture_assert_ntstatus_ok(tctx, status,
4395 "Failed to enum accounts");
4397 for (i=0; i < lsa_sid_array.num_sids; i++) {
4398 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4403 torture_assert(tctx, !found_sid,
4404 "should not have listed privileged account");
4408 struct lsa_EnumAccountRights r;
4409 struct lsa_RightSet user_rights;
4411 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4413 r.in.handle = lsa_handle;
4414 r.in.sid = user_sid;
4415 r.out.rights = &user_rights;
4417 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
4418 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4419 "Failed to enum rights for account");
4425 static bool test_user_ops(struct dcerpc_pipe *p,
4426 struct torture_context *tctx,
4427 struct policy_handle *user_handle,
4428 struct policy_handle *domain_handle,
4429 const struct dom_sid *domain_sid,
4430 uint32_t base_acct_flags,
4431 const char *base_acct_name, enum torture_samr_choice which_ops,
4432 struct cli_credentials *machine_credentials)
4434 char *password = NULL;
4435 struct samr_QueryUserInfo q;
4436 union samr_UserInfo *info;
4442 const uint32_t password_fields[] = {
4443 SAMR_FIELD_NT_PASSWORD_PRESENT,
4444 SAMR_FIELD_LM_PASSWORD_PRESENT,
4445 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
4449 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
4450 if (!NT_STATUS_IS_OK(status)) {
4454 switch (which_ops) {
4455 case TORTURE_SAMR_USER_ATTRIBUTES:
4456 if (!test_QuerySecurity(p, tctx, user_handle)) {
4460 if (!test_QueryUserInfo(p, tctx, user_handle)) {
4464 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
4468 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
4473 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
4477 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
4481 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
4485 case TORTURE_SAMR_PASSWORDS:
4486 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
4487 char simple_pass[9];
4488 char *v = generate_random_str(tctx, 1);
4490 ZERO_STRUCT(simple_pass);
4491 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4493 torture_comment(tctx, "Testing machine account password policy rules\n");
4495 /* Workstation trust accounts don't seem to need to honour password quality policy */
4496 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4500 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
4504 /* reset again, to allow another 'user' password change */
4505 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4509 /* Try a 'short' password */
4510 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
4514 /* Try a compleatly random password */
4515 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
4520 for (i = 0; password_fields[i]; i++) {
4521 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
4525 /* check it was set right */
4526 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4531 for (i = 0; password_fields[i]; i++) {
4532 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
4536 /* check it was set right */
4537 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4542 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
4546 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
4550 if (torture_setting_bool(tctx, "samba4", false)) {
4551 torture_comment(tctx, "skipping Set Password level 18 and 21 against Samba4\n");
4554 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
4558 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4562 for (i = 0; password_fields[i]; i++) {
4564 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
4565 /* we need to skip as that would break
4566 * the ChangePasswordUser3 verify */
4570 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
4574 /* check it was set right */
4575 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4581 q.in.user_handle = user_handle;
4585 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4586 if (!NT_STATUS_IS_OK(status)) {
4587 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4588 q.in.level, nt_errstr(status));
4591 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4592 if ((info->info5.acct_flags) != expected_flags) {
4593 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4594 info->info5.acct_flags,
4597 if (!torture_setting_bool(tctx, "samba3", false)) {
4601 if (info->info5.rid != rid) {
4602 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
4603 info->info5.rid, rid);
4610 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
4612 /* test last password change timestamp behaviour */
4613 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
4615 user_handle, &password,
4616 machine_credentials)) {
4621 torture_comment(tctx, "pwdLastSet test succeeded\n");
4623 torture_warning(tctx, "pwdLastSet test failed\n");
4628 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
4630 /* test bad pwd count change behaviour */
4631 if (!test_Password_badpwdcount_wrap(p, tctx, base_acct_flags,
4634 user_handle, &password,
4635 machine_credentials)) {
4640 torture_comment(tctx, "badPwdCount test succeeded\n");
4642 torture_warning(tctx, "badPwdCount test failed\n");
4647 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
4649 if (!test_Password_lockout_wrap(p, tctx, base_acct_flags,
4652 user_handle, &password,
4653 machine_credentials))
4659 torture_comment(tctx, "lockout test succeeded\n");
4661 torture_warning(tctx, "lockout test failed\n");
4667 case TORTURE_SAMR_USER_PRIVILEGES: {
4669 struct dcerpc_pipe *lp;
4670 struct policy_handle *lsa_handle;
4672 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
4673 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
4675 if (!test_lsa_OpenPolicy2(lp, tctx, &lsa_handle)) {
4679 if (!test_DeleteUser_with_privs(p, lp, tctx,
4680 domain_handle, lsa_handle, user_handle,
4682 machine_credentials)) {
4686 if (!test_lsa_Close(lp, tctx, lsa_handle)) {
4691 torture_warning(tctx, "privileged user delete test failed\n");
4696 case TORTURE_SAMR_OTHER:
4697 /* We just need the account to exist */
4703 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
4704 struct policy_handle *alias_handle,
4705 const struct dom_sid *domain_sid)
4709 if (!torture_setting_bool(tctx, "samba3", false)) {
4710 if (!test_QuerySecurity(p, tctx, alias_handle)) {
4715 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
4719 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
4723 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
4727 if (torture_setting_bool(tctx, "samba3", false) ||
4728 torture_setting_bool(tctx, "samba4", false)) {
4729 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
4733 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
4741 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
4742 struct policy_handle *user_handle)
4744 struct samr_DeleteUser d;
4746 torture_comment(tctx, "Testing DeleteUser\n");
4748 d.in.user_handle = user_handle;
4749 d.out.user_handle = user_handle;
4751 status = dcerpc_samr_DeleteUser(p, tctx, &d);
4752 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
4757 bool test_DeleteUser_byname(struct dcerpc_pipe *p,
4758 struct torture_context *tctx,
4759 struct policy_handle *handle, const char *name)
4762 struct samr_DeleteUser d;
4763 struct policy_handle user_handle;
4766 status = test_LookupName(p, tctx, handle, name, &rid);
4767 if (!NT_STATUS_IS_OK(status)) {
4771 status = test_OpenUser_byname(p, tctx, handle, name, &user_handle);
4772 if (!NT_STATUS_IS_OK(status)) {
4776 d.in.user_handle = &user_handle;
4777 d.out.user_handle = &user_handle;
4778 status = dcerpc_samr_DeleteUser(p, tctx, &d);
4779 if (!NT_STATUS_IS_OK(status)) {
4786 torture_warning(tctx, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
4791 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p,
4792 struct torture_context *tctx,
4793 struct policy_handle *handle, const char *name)
4796 struct samr_OpenGroup r;
4797 struct samr_DeleteDomainGroup d;
4798 struct policy_handle group_handle;
4801 status = test_LookupName(p, tctx, handle, name, &rid);
4802 if (!NT_STATUS_IS_OK(status)) {
4806 r.in.domain_handle = handle;
4807 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4809 r.out.group_handle = &group_handle;
4810 status = dcerpc_samr_OpenGroup(p, tctx, &r);
4811 if (!NT_STATUS_IS_OK(status)) {
4815 d.in.group_handle = &group_handle;
4816 d.out.group_handle = &group_handle;
4817 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
4818 if (!NT_STATUS_IS_OK(status)) {
4825 torture_warning(tctx, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
4830 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p,
4831 struct torture_context *tctx,
4832 struct policy_handle *domain_handle,
4836 struct samr_OpenAlias r;
4837 struct samr_DeleteDomAlias d;
4838 struct policy_handle alias_handle;
4841 torture_comment(tctx, "testing DeleteAlias_byname\n");
4843 status = test_LookupName(p, tctx, domain_handle, name, &rid);
4844 if (!NT_STATUS_IS_OK(status)) {
4848 r.in.domain_handle = domain_handle;
4849 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4851 r.out.alias_handle = &alias_handle;
4852 status = dcerpc_samr_OpenAlias(p, tctx, &r);
4853 if (!NT_STATUS_IS_OK(status)) {
4857 d.in.alias_handle = &alias_handle;
4858 d.out.alias_handle = &alias_handle;
4859 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
4860 if (!NT_STATUS_IS_OK(status)) {
4867 torture_warning(tctx, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
4871 static bool test_DeleteAlias(struct dcerpc_pipe *p,
4872 struct torture_context *tctx,
4873 struct policy_handle *alias_handle)
4875 struct samr_DeleteDomAlias d;
4879 torture_comment(tctx, "Testing DeleteAlias\n");
4881 d.in.alias_handle = alias_handle;
4882 d.out.alias_handle = alias_handle;
4884 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
4885 if (!NT_STATUS_IS_OK(status)) {
4886 torture_warning(tctx, "DeleteAlias failed - %s\n", nt_errstr(status));
4893 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4894 struct policy_handle *domain_handle,
4895 const char *alias_name,
4896 struct policy_handle *alias_handle,
4897 const struct dom_sid *domain_sid,
4901 struct samr_CreateDomAlias r;
4902 struct lsa_String name;
4906 init_lsa_String(&name, alias_name);
4907 r.in.domain_handle = domain_handle;
4908 r.in.alias_name = &name;
4909 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4910 r.out.alias_handle = alias_handle;
4913 torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
4915 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4917 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4918 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4919 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
4922 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
4928 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
4929 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
4932 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4935 if (!NT_STATUS_IS_OK(status)) {
4936 torture_warning(tctx, "CreateAlias failed - %s\n", nt_errstr(status));
4944 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
4951 static bool test_ChangePassword(struct dcerpc_pipe *p,
4952 struct torture_context *tctx,
4953 const char *acct_name,
4954 struct policy_handle *domain_handle, char **password)
4962 if (!test_ChangePasswordUser(p, tctx, acct_name, domain_handle, password)) {
4966 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
4970 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
4974 /* test what happens when setting the old password again */
4975 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
4980 char simple_pass[9];
4981 char *v = generate_random_str(tctx, 1);
4983 ZERO_STRUCT(simple_pass);
4984 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4986 /* test what happens when picking a simple password */
4987 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
4992 /* set samr_SetDomainInfo level 1 with min_length 5 */
4994 struct samr_QueryDomainInfo r;
4995 union samr_DomainInfo *info = NULL;
4996 struct samr_SetDomainInfo s;
4997 uint16_t len_old, len;
4998 uint32_t pwd_prop_old;
4999 int64_t min_pwd_age_old;
5004 r.in.domain_handle = domain_handle;
5008 torture_comment(tctx, "testing samr_QueryDomainInfo level 1\n");
5009 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5010 if (!NT_STATUS_IS_OK(status)) {
5014 s.in.domain_handle = domain_handle;
5018 /* remember the old min length, so we can reset it */
5019 len_old = s.in.info->info1.min_password_length;
5020 s.in.info->info1.min_password_length = len;
5021 pwd_prop_old = s.in.info->info1.password_properties;
5022 /* turn off password complexity checks for this test */
5023 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
5025 min_pwd_age_old = s.in.info->info1.min_password_age;
5026 s.in.info->info1.min_password_age = 0;
5028 torture_comment(tctx, "testing samr_SetDomainInfo level 1\n");
5029 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5030 if (!NT_STATUS_IS_OK(status)) {
5034 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
5036 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
5040 s.in.info->info1.min_password_length = len_old;
5041 s.in.info->info1.password_properties = pwd_prop_old;
5042 s.in.info->info1.min_password_age = min_pwd_age_old;
5044 torture_comment(tctx, "testing samr_SetDomainInfo level 1\n");
5045 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5046 if (!NT_STATUS_IS_OK(status)) {
5054 struct samr_OpenUser r;
5055 struct samr_QueryUserInfo q;
5056 union samr_UserInfo *info;
5057 struct samr_LookupNames n;
5058 struct policy_handle user_handle;
5059 struct samr_Ids rids, types;
5061 n.in.domain_handle = domain_handle;
5063 n.in.names = talloc_array(tctx, struct lsa_String, 1);
5064 n.in.names[0].string = acct_name;
5066 n.out.types = &types;
5068 status = dcerpc_samr_LookupNames(p, tctx, &n);
5069 if (!NT_STATUS_IS_OK(status)) {
5070 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(status));
5074 r.in.domain_handle = domain_handle;
5075 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5076 r.in.rid = n.out.rids->ids[0];
5077 r.out.user_handle = &user_handle;
5079 status = dcerpc_samr_OpenUser(p, tctx, &r);
5080 if (!NT_STATUS_IS_OK(status)) {
5081 torture_warning(tctx, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
5085 q.in.user_handle = &user_handle;
5089 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
5090 if (!NT_STATUS_IS_OK(status)) {
5091 torture_warning(tctx, "QueryUserInfo failed - %s\n", nt_errstr(status));
5095 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
5097 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
5098 info->info5.last_password_change, true)) {
5103 /* we change passwords twice - this has the effect of verifying
5104 they were changed correctly for the final call */
5105 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5109 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5116 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
5117 struct policy_handle *domain_handle,
5118 const char *user_name,
5119 struct policy_handle *user_handle_out,
5120 struct dom_sid *domain_sid,
5121 enum torture_samr_choice which_ops,
5122 struct cli_credentials *machine_credentials,
5126 TALLOC_CTX *user_ctx;
5129 struct samr_CreateUser r;
5130 struct samr_QueryUserInfo q;
5131 union samr_UserInfo *info;
5132 struct samr_DeleteUser d;
5135 /* This call creates a 'normal' account - check that it really does */
5136 const uint32_t acct_flags = ACB_NORMAL;
5137 struct lsa_String name;
5140 struct policy_handle user_handle;
5141 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5142 init_lsa_String(&name, user_name);
5144 r.in.domain_handle = domain_handle;
5145 r.in.account_name = &name;
5146 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5147 r.out.user_handle = &user_handle;
5150 torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
5152 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
5154 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5155 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
5156 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5159 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5165 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5166 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
5167 talloc_free(user_ctx);
5170 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
5173 if (!NT_STATUS_IS_OK(status)) {
5174 talloc_free(user_ctx);
5175 torture_warning(tctx, "CreateUser failed - %s\n", nt_errstr(status));
5180 if (user_handle_out) {
5181 *user_handle_out = user_handle;
5187 q.in.user_handle = &user_handle;
5191 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
5192 if (!NT_STATUS_IS_OK(status)) {
5193 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5194 q.in.level, nt_errstr(status));
5197 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
5198 torture_warning(tctx, "QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5199 info->info16.acct_flags,
5205 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5206 domain_sid, acct_flags, name.string, which_ops,
5207 machine_credentials)) {
5211 if (user_handle_out) {
5212 *user_handle_out = user_handle;
5214 torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
5216 d.in.user_handle = &user_handle;
5217 d.out.user_handle = &user_handle;
5219 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
5220 if (!NT_STATUS_IS_OK(status)) {
5221 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(status));
5228 talloc_free(user_ctx);
5234 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
5235 struct policy_handle *domain_handle,
5236 struct dom_sid *domain_sid,
5237 enum torture_samr_choice which_ops,
5238 struct cli_credentials *machine_credentials)
5241 struct samr_CreateUser2 r;
5242 struct samr_QueryUserInfo q;
5243 union samr_UserInfo *info;
5244 struct samr_DeleteUser d;
5245 struct policy_handle user_handle;
5247 struct lsa_String name;
5252 uint32_t acct_flags;
5253 const char *account_name;
5255 } account_types[] = {
5256 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
5257 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5258 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5259 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5260 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5261 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5262 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5263 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5264 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5265 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
5266 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5267 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5268 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5269 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5270 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
5273 for (i = 0; account_types[i].account_name; i++) {
5274 TALLOC_CTX *user_ctx;
5275 uint32_t acct_flags = account_types[i].acct_flags;
5276 uint32_t access_granted;
5277 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5278 init_lsa_String(&name, account_types[i].account_name);
5280 r.in.domain_handle = domain_handle;
5281 r.in.account_name = &name;
5282 r.in.acct_flags = acct_flags;
5283 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5284 r.out.user_handle = &user_handle;
5285 r.out.access_granted = &access_granted;
5288 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
5290 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
5292 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5293 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
5294 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5297 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5304 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5305 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
5306 talloc_free(user_ctx);
5310 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
5313 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
5314 torture_warning(tctx, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5315 nt_errstr(status), nt_errstr(account_types[i].nt_status));
5319 if (NT_STATUS_IS_OK(status)) {
5320 q.in.user_handle = &user_handle;
5324 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
5325 if (!NT_STATUS_IS_OK(status)) {
5326 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5327 q.in.level, nt_errstr(status));
5330 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
5331 if (acct_flags == ACB_NORMAL) {
5332 expected_flags |= ACB_PW_EXPIRED;
5334 if ((info->info5.acct_flags) != expected_flags) {
5335 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5336 info->info5.acct_flags,
5340 switch (acct_flags) {
5342 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
5343 torture_warning(tctx, "QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5344 DOMAIN_RID_DCS, info->info5.primary_gid);
5349 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
5350 torture_warning(tctx, "QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5351 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
5356 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
5357 torture_warning(tctx, "QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5358 DOMAIN_RID_USERS, info->info5.primary_gid);
5365 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5366 domain_sid, acct_flags, name.string, which_ops,
5367 machine_credentials)) {
5371 if (!policy_handle_empty(&user_handle)) {
5372 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
5374 d.in.user_handle = &user_handle;
5375 d.out.user_handle = &user_handle;
5377 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
5378 if (!NT_STATUS_IS_OK(status)) {
5379 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(status));
5384 talloc_free(user_ctx);
5390 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
5391 struct torture_context *tctx,
5392 struct policy_handle *handle)
5395 struct samr_QueryAliasInfo r;
5396 union samr_AliasInfo *info;
5397 uint16_t levels[] = {1, 2, 3};
5401 for (i=0;i<ARRAY_SIZE(levels);i++) {
5402 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
5404 r.in.alias_handle = handle;
5405 r.in.level = levels[i];
5408 status = dcerpc_samr_QueryAliasInfo(p, tctx, &r);
5409 if (!NT_STATUS_IS_OK(status)) {
5410 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
5411 levels[i], nt_errstr(status));
5419 static bool test_QueryGroupInfo(struct dcerpc_pipe *p,
5420 struct torture_context *tctx,
5421 struct policy_handle *handle)
5424 struct samr_QueryGroupInfo r;
5425 union samr_GroupInfo *info;
5426 uint16_t levels[] = {1, 2, 3, 4, 5};
5430 for (i=0;i<ARRAY_SIZE(levels);i++) {
5431 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5433 r.in.group_handle = handle;
5434 r.in.level = levels[i];
5437 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
5438 if (!NT_STATUS_IS_OK(status)) {
5439 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5440 levels[i], nt_errstr(status));
5448 static bool test_QueryGroupMember(struct dcerpc_pipe *p,
5449 struct torture_context *tctx,
5450 struct policy_handle *handle)
5453 struct samr_QueryGroupMember r;
5454 struct samr_RidTypeArray *rids = NULL;
5457 torture_comment(tctx, "Testing QueryGroupMember\n");
5459 r.in.group_handle = handle;
5462 status = dcerpc_samr_QueryGroupMember(p, tctx, &r);
5463 if (!NT_STATUS_IS_OK(status)) {
5464 torture_warning(tctx, "QueryGroupInfo failed - %s\n", nt_errstr(status));
5472 static bool test_SetGroupInfo(struct dcerpc_pipe *p,
5473 struct torture_context *tctx,
5474 struct policy_handle *handle)
5477 struct samr_QueryGroupInfo r;
5478 union samr_GroupInfo *info;
5479 struct samr_SetGroupInfo s;
5480 uint16_t levels[] = {1, 2, 3, 4};
5481 uint16_t set_ok[] = {0, 1, 1, 1};
5485 for (i=0;i<ARRAY_SIZE(levels);i++) {
5486 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5488 r.in.group_handle = handle;
5489 r.in.level = levels[i];
5492 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
5493 if (!NT_STATUS_IS_OK(status)) {
5494 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5495 levels[i], nt_errstr(status));
5499 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
5501 s.in.group_handle = handle;
5502 s.in.level = levels[i];
5503 s.in.info = *r.out.info;
5506 /* disabled this, as it changes the name only from the point of view of samr,
5507 but leaves the name from the point of view of w2k3 internals (and ldap). This means
5508 the name is still reserved, so creating the old name fails, but deleting by the old name
5510 if (s.in.level == 2) {
5511 init_lsa_String(&s.in.info->string, "NewName");
5515 if (s.in.level == 4) {
5516 init_lsa_String(&s.in.info->description, "test description");
5519 status = dcerpc_samr_SetGroupInfo(p, tctx, &s);
5521 if (!NT_STATUS_IS_OK(status)) {
5522 torture_warning(tctx, "SetGroupInfo level %u failed - %s\n",
5523 r.in.level, nt_errstr(status));
5528 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5529 torture_warning(tctx, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5530 r.in.level, nt_errstr(status));
5540 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
5541 struct torture_context *tctx,
5542 struct policy_handle *handle)
5545 struct samr_QueryUserInfo r;
5546 union samr_UserInfo *info;
5547 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5548 11, 12, 13, 14, 16, 17, 20, 21};
5552 for (i=0;i<ARRAY_SIZE(levels);i++) {
5553 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
5555 r.in.user_handle = handle;
5556 r.in.level = levels[i];
5559 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
5560 if (!NT_STATUS_IS_OK(status)) {
5561 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5562 levels[i], nt_errstr(status));
5570 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
5571 struct torture_context *tctx,
5572 struct policy_handle *handle)
5575 struct samr_QueryUserInfo2 r;
5576 union samr_UserInfo *info;
5577 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5578 11, 12, 13, 14, 16, 17, 20, 21};
5582 for (i=0;i<ARRAY_SIZE(levels);i++) {
5583 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
5585 r.in.user_handle = handle;
5586 r.in.level = levels[i];
5589 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r);
5590 if (!NT_STATUS_IS_OK(status)) {
5591 torture_warning(tctx, "QueryUserInfo2 level %u failed - %s\n",
5592 levels[i], nt_errstr(status));
5600 static bool test_OpenUser(struct dcerpc_pipe *p,
5601 struct torture_context *tctx,
5602 struct policy_handle *handle, uint32_t rid)
5605 struct samr_OpenUser r;
5606 struct policy_handle user_handle;
5609 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5611 r.in.domain_handle = handle;
5612 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5614 r.out.user_handle = &user_handle;
5616 status = dcerpc_samr_OpenUser(p, tctx, &r);
5617 if (!NT_STATUS_IS_OK(status)) {
5618 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
5622 if (!test_QuerySecurity(p, tctx, &user_handle)) {
5626 if (!test_QueryUserInfo(p, tctx, &user_handle)) {
5630 if (!test_QueryUserInfo2(p, tctx, &user_handle)) {
5634 if (!test_GetUserPwInfo(p, tctx, &user_handle)) {
5638 if (!test_GetGroupsForUser(p,tctx, &user_handle)) {
5642 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
5649 static bool test_OpenGroup(struct dcerpc_pipe *p,
5650 struct torture_context *tctx,
5651 struct policy_handle *handle, uint32_t rid)
5654 struct samr_OpenGroup r;
5655 struct policy_handle group_handle;
5658 torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
5660 r.in.domain_handle = handle;
5661 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5663 r.out.group_handle = &group_handle;
5665 status = dcerpc_samr_OpenGroup(p, tctx, &r);
5666 if (!NT_STATUS_IS_OK(status)) {
5667 torture_warning(tctx, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
5671 if (!torture_setting_bool(tctx, "samba3", false)) {
5672 if (!test_QuerySecurity(p, tctx, &group_handle)) {
5677 if (!test_QueryGroupInfo(p, tctx, &group_handle)) {
5681 if (!test_QueryGroupMember(p, tctx, &group_handle)) {
5685 if (!test_samr_handle_Close(p, tctx, &group_handle)) {
5692 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
5693 struct policy_handle *handle, uint32_t rid)
5696 struct samr_OpenAlias r;
5697 struct policy_handle alias_handle;
5700 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
5702 r.in.domain_handle = handle;
5703 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5705 r.out.alias_handle = &alias_handle;
5707 status = dcerpc_samr_OpenAlias(p, tctx, &r);
5708 if (!NT_STATUS_IS_OK(status)) {
5709 torture_warning(tctx, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
5713 if (!torture_setting_bool(tctx, "samba3", false)) {
5714 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
5719 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
5723 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
5727 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
5734 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
5735 struct policy_handle *handle, uint32_t rid,
5736 uint32_t acct_flag_mask)
5739 struct samr_OpenUser r;
5740 struct samr_QueryUserInfo q;
5741 union samr_UserInfo *info;
5742 struct policy_handle user_handle;
5745 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5747 r.in.domain_handle = handle;
5748 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5750 r.out.user_handle = &user_handle;
5752 status = dcerpc_samr_OpenUser(p, tctx, &r);
5753 if (!NT_STATUS_IS_OK(status)) {
5754 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
5758 q.in.user_handle = &user_handle;
5762 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
5763 if (!NT_STATUS_IS_OK(status)) {
5764 torture_warning(tctx, "QueryUserInfo level 16 failed - %s\n",
5768 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
5769 torture_warning(tctx, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
5770 acct_flag_mask, info->info16.acct_flags, rid);
5775 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
5782 static bool test_EnumDomainUsers_all(struct dcerpc_pipe *p,
5783 struct torture_context *tctx,
5784 struct policy_handle *handle)
5786 NTSTATUS status = STATUS_MORE_ENTRIES;
5787 struct samr_EnumDomainUsers r;
5788 uint32_t mask, resume_handle=0;
5791 struct samr_LookupNames n;
5792 struct samr_LookupRids lr ;
5793 struct lsa_Strings names;
5794 struct samr_Ids rids, types;
5795 struct samr_SamArray *sam = NULL;
5796 uint32_t num_entries = 0;
5798 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
5799 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
5800 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
5803 torture_comment(tctx, "Testing EnumDomainUsers\n");
5805 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
5806 r.in.domain_handle = handle;
5807 r.in.resume_handle = &resume_handle;
5808 r.in.acct_flags = mask = masks[mask_idx];
5809 r.in.max_size = (uint32_t)-1;
5810 r.out.resume_handle = &resume_handle;
5811 r.out.num_entries = &num_entries;
5814 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
5815 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5816 !NT_STATUS_IS_OK(status)) {
5817 torture_warning(tctx, "EnumDomainUsers failed - %s\n", nt_errstr(status));
5821 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
5823 if (sam->count == 0) {
5827 for (i=0;i<sam->count;i++) {
5829 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
5832 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
5838 torture_comment(tctx, "Testing LookupNames\n");
5839 n.in.domain_handle = handle;
5840 n.in.num_names = sam->count;
5841 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
5843 n.out.types = &types;
5844 for (i=0;i<sam->count;i++) {
5845 n.in.names[i].string = sam->entries[i].name.string;
5847 status = dcerpc_samr_LookupNames(p, tctx, &n);
5848 if (!NT_STATUS_IS_OK(status)) {
5849 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(status));
5854 torture_comment(tctx, "Testing LookupRids\n");
5855 lr.in.domain_handle = handle;
5856 lr.in.num_rids = sam->count;
5857 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
5858 lr.out.names = &names;
5859 lr.out.types = &types;
5860 for (i=0;i<sam->count;i++) {
5861 lr.in.rids[i] = sam->entries[i].idx;
5863 status = dcerpc_samr_LookupRids(p, tctx, &lr);
5864 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
5870 try blasting the server with a bunch of sync requests
5872 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
5873 struct policy_handle *handle)
5876 struct samr_EnumDomainUsers r;
5877 uint32_t resume_handle=0;
5879 #define ASYNC_COUNT 100
5880 struct rpc_request *req[ASYNC_COUNT];
5882 if (!torture_setting_bool(tctx, "dangerous", false)) {
5883 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
5886 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
5888 r.in.domain_handle = handle;
5889 r.in.resume_handle = &resume_handle;
5890 r.in.acct_flags = 0;
5891 r.in.max_size = (uint32_t)-1;
5892 r.out.resume_handle = &resume_handle;
5894 for (i=0;i<ASYNC_COUNT;i++) {
5895 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
5898 for (i=0;i<ASYNC_COUNT;i++) {
5899 status = dcerpc_ndr_request_recv(req[i]);
5900 if (!NT_STATUS_IS_OK(status)) {
5901 torture_warning(tctx, "EnumDomainUsers[%d] failed - %s\n",
5902 i, nt_errstr(status));
5907 torture_comment(tctx, "%d async requests OK\n", i);
5912 static bool test_EnumDomainGroups_all(struct dcerpc_pipe *p,
5913 struct torture_context *tctx,
5914 struct policy_handle *handle)
5917 struct samr_EnumDomainGroups r;
5918 uint32_t resume_handle=0;
5919 struct samr_SamArray *sam = NULL;
5920 uint32_t num_entries = 0;
5924 torture_comment(tctx, "Testing EnumDomainGroups\n");
5926 r.in.domain_handle = handle;
5927 r.in.resume_handle = &resume_handle;
5928 r.in.max_size = (uint32_t)-1;
5929 r.out.resume_handle = &resume_handle;
5930 r.out.num_entries = &num_entries;
5933 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
5934 if (!NT_STATUS_IS_OK(status)) {
5935 torture_warning(tctx, "EnumDomainGroups failed - %s\n", nt_errstr(status));
5943 for (i=0;i<sam->count;i++) {
5944 if (!test_OpenGroup(p, tctx, handle, sam->entries[i].idx)) {
5952 static bool test_EnumDomainAliases_all(struct dcerpc_pipe *p,
5953 struct torture_context *tctx,
5954 struct policy_handle *handle)
5957 struct samr_EnumDomainAliases r;
5958 uint32_t resume_handle=0;
5959 struct samr_SamArray *sam = NULL;
5960 uint32_t num_entries = 0;
5964 torture_comment(tctx, "Testing EnumDomainAliases\n");
5966 r.in.domain_handle = handle;
5967 r.in.resume_handle = &resume_handle;
5968 r.in.max_size = (uint32_t)-1;
5970 r.out.num_entries = &num_entries;
5971 r.out.resume_handle = &resume_handle;
5973 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
5974 if (!NT_STATUS_IS_OK(status)) {
5975 torture_warning(tctx, "EnumDomainAliases failed - %s\n", nt_errstr(status));
5983 for (i=0;i<sam->count;i++) {
5984 if (!test_OpenAlias(p, tctx, handle, sam->entries[i].idx)) {
5992 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p,
5993 struct torture_context *tctx,
5994 struct policy_handle *handle)
5997 struct samr_GetDisplayEnumerationIndex r;
5999 uint16_t levels[] = {1, 2, 3, 4, 5};
6000 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6001 struct lsa_String name;
6005 for (i=0;i<ARRAY_SIZE(levels);i++) {
6006 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
6008 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6010 r.in.domain_handle = handle;
6011 r.in.level = levels[i];
6015 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
6018 !NT_STATUS_IS_OK(status) &&
6019 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
6020 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6021 levels[i], nt_errstr(status));
6025 init_lsa_String(&name, "zzzzzzzz");
6027 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
6029 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
6030 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6031 levels[i], nt_errstr(status));
6039 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p,
6040 struct torture_context *tctx,
6041 struct policy_handle *handle)
6044 struct samr_GetDisplayEnumerationIndex2 r;
6046 uint16_t levels[] = {1, 2, 3, 4, 5};
6047 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6048 struct lsa_String name;
6052 for (i=0;i<ARRAY_SIZE(levels);i++) {
6053 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
6055 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6057 r.in.domain_handle = handle;
6058 r.in.level = levels[i];
6062 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
6064 !NT_STATUS_IS_OK(status) &&
6065 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
6066 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6067 levels[i], nt_errstr(status));
6071 init_lsa_String(&name, "zzzzzzzz");
6073 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
6074 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
6075 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6076 levels[i], nt_errstr(status));
6084 #define STRING_EQUAL_QUERY(s1, s2, user) \
6085 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6086 /* odd, but valid */ \
6087 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6088 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
6089 #s1, user.string, s1.string, s2.string, __location__); \
6092 #define INT_EQUAL_QUERY(s1, s2, user) \
6094 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6095 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6099 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p,
6100 struct torture_context *tctx,
6101 struct samr_QueryDisplayInfo *querydisplayinfo,
6102 bool *seen_testuser)
6104 struct samr_OpenUser r;
6105 struct samr_QueryUserInfo q;
6106 union samr_UserInfo *info;
6107 struct policy_handle user_handle;
6110 r.in.domain_handle = querydisplayinfo->in.domain_handle;
6111 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6112 for (i = 0; ; i++) {
6113 switch (querydisplayinfo->in.level) {
6115 if (i >= querydisplayinfo->out.info->info1.count) {
6118 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
6121 if (i >= querydisplayinfo->out.info->info2.count) {
6124 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
6130 /* Not interested in validating just the account name */
6134 r.out.user_handle = &user_handle;
6136 switch (querydisplayinfo->in.level) {
6139 status = dcerpc_samr_OpenUser(p, tctx, &r);
6140 if (!NT_STATUS_IS_OK(status)) {
6141 torture_warning(tctx, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
6146 q.in.user_handle = &user_handle;
6149 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
6150 if (!NT_STATUS_IS_OK(status)) {
6151 torture_warning(tctx, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
6155 switch (querydisplayinfo->in.level) {
6157 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
6158 *seen_testuser = true;
6160 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
6161 info->info21.full_name, info->info21.account_name);
6162 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
6163 info->info21.account_name, info->info21.account_name);
6164 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
6165 info->info21.description, info->info21.account_name);
6166 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
6167 info->info21.rid, info->info21.account_name);
6168 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
6169 info->info21.acct_flags, info->info21.account_name);
6173 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
6174 info->info21.account_name, info->info21.account_name);
6175 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
6176 info->info21.description, info->info21.account_name);
6177 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
6178 info->info21.rid, info->info21.account_name);
6179 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
6180 info->info21.acct_flags, info->info21.account_name);
6182 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
6183 torture_warning(tctx, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6184 info->info21.account_name.string);
6187 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
6188 torture_warning(tctx, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6189 info->info21.account_name.string,
6190 querydisplayinfo->out.info->info2.entries[i].acct_flags,
6191 info->info21.acct_flags);
6198 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
6205 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p,
6206 struct torture_context *tctx,
6207 struct policy_handle *handle)
6210 struct samr_QueryDisplayInfo r;
6211 struct samr_QueryDomainInfo dom_info;
6212 union samr_DomainInfo *info = NULL;
6214 uint16_t levels[] = {1, 2, 3, 4, 5};
6216 bool seen_testuser = false;
6217 uint32_t total_size;
6218 uint32_t returned_size;
6219 union samr_DispInfo disp_info;
6222 for (i=0;i<ARRAY_SIZE(levels);i++) {
6223 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
6226 status = STATUS_MORE_ENTRIES;
6227 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6228 r.in.domain_handle = handle;
6229 r.in.level = levels[i];
6230 r.in.max_entries = 2;
6231 r.in.buf_size = (uint32_t)-1;
6232 r.out.total_size = &total_size;
6233 r.out.returned_size = &returned_size;
6234 r.out.info = &disp_info;
6236 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
6237 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
6238 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6239 levels[i], nt_errstr(status));
6242 switch (r.in.level) {
6244 if (!test_each_DisplayInfo_user(p, tctx, &r, &seen_testuser)) {
6247 r.in.start_idx += r.out.info->info1.count;
6250 if (!test_each_DisplayInfo_user(p, tctx, &r, NULL)) {
6253 r.in.start_idx += r.out.info->info2.count;
6256 r.in.start_idx += r.out.info->info3.count;
6259 r.in.start_idx += r.out.info->info4.count;
6262 r.in.start_idx += r.out.info->info5.count;
6266 dom_info.in.domain_handle = handle;
6267 dom_info.in.level = 2;
6268 dom_info.out.info = &info;
6270 /* Check number of users returned is correct */
6271 status = dcerpc_samr_QueryDomainInfo(p, tctx, &dom_info);
6272 if (!NT_STATUS_IS_OK(status)) {
6273 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6274 r.in.level, nt_errstr(status));
6278 switch (r.in.level) {
6281 if (info->general.num_users < r.in.start_idx) {
6282 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6283 r.in.start_idx, info->general.num_groups,
6284 info->general.domain_name.string);
6287 if (!seen_testuser) {
6288 struct policy_handle user_handle;
6289 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
6290 torture_warning(tctx, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
6291 info->general.domain_name.string);
6293 test_samr_handle_Close(p, tctx, &user_handle);
6299 if (info->general.num_groups != r.in.start_idx) {
6300 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6301 r.in.start_idx, info->general.num_groups,
6302 info->general.domain_name.string);
6314 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p,
6315 struct torture_context *tctx,
6316 struct policy_handle *handle)
6319 struct samr_QueryDisplayInfo2 r;
6321 uint16_t levels[] = {1, 2, 3, 4, 5};
6323 uint32_t total_size;
6324 uint32_t returned_size;
6325 union samr_DispInfo info;
6327 for (i=0;i<ARRAY_SIZE(levels);i++) {
6328 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
6330 r.in.domain_handle = handle;
6331 r.in.level = levels[i];
6333 r.in.max_entries = 1000;
6334 r.in.buf_size = (uint32_t)-1;
6335 r.out.total_size = &total_size;
6336 r.out.returned_size = &returned_size;
6339 status = dcerpc_samr_QueryDisplayInfo2(p, tctx, &r);
6340 if (!NT_STATUS_IS_OK(status)) {
6341 torture_warning(tctx, "QueryDisplayInfo2 level %u failed - %s\n",
6342 levels[i], nt_errstr(status));
6350 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
6351 struct policy_handle *handle)
6354 struct samr_QueryDisplayInfo3 r;
6356 uint16_t levels[] = {1, 2, 3, 4, 5};
6358 uint32_t total_size;
6359 uint32_t returned_size;
6360 union samr_DispInfo info;
6362 for (i=0;i<ARRAY_SIZE(levels);i++) {
6363 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
6365 r.in.domain_handle = handle;
6366 r.in.level = levels[i];
6368 r.in.max_entries = 1000;
6369 r.in.buf_size = (uint32_t)-1;
6370 r.out.total_size = &total_size;
6371 r.out.returned_size = &returned_size;
6374 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
6375 if (!NT_STATUS_IS_OK(status)) {
6376 torture_warning(tctx, "QueryDisplayInfo3 level %u failed - %s\n",
6377 levels[i], nt_errstr(status));
6386 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p,
6387 struct torture_context *tctx,
6388 struct policy_handle *handle)
6391 struct samr_QueryDisplayInfo r;
6393 uint32_t total_size;
6394 uint32_t returned_size;
6395 union samr_DispInfo info;
6397 torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
6399 r.in.domain_handle = handle;
6402 r.in.max_entries = 1;
6403 r.in.buf_size = (uint32_t)-1;
6404 r.out.total_size = &total_size;
6405 r.out.returned_size = &returned_size;
6409 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
6410 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
6411 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
6412 torture_warning(tctx, "expected idx %d but got %d\n",
6414 r.out.info->info1.entries[0].idx);
6418 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
6419 !NT_STATUS_IS_OK(status)) {
6420 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6421 r.in.level, nt_errstr(status));
6426 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
6427 NT_STATUS_IS_OK(status)) &&
6428 *r.out.returned_size != 0);
6433 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
6434 struct policy_handle *handle)
6437 struct samr_QueryDomainInfo r;
6438 union samr_DomainInfo *info = NULL;
6439 struct samr_SetDomainInfo s;
6440 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6441 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
6444 const char *domain_comment = talloc_asprintf(tctx,
6445 "Tortured by Samba4 RPC-SAMR: %s",
6446 timestring(tctx, time(NULL)));
6448 s.in.domain_handle = handle;
6450 s.in.info = talloc(tctx, union samr_DomainInfo);
6452 s.in.info->oem.oem_information.string = domain_comment;
6453 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
6454 if (!NT_STATUS_IS_OK(status)) {
6455 torture_warning(tctx, "SetDomainInfo level %u (set comment) failed - %s\n",
6456 s.in.level, nt_errstr(status));
6460 for (i=0;i<ARRAY_SIZE(levels);i++) {
6461 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
6463 r.in.domain_handle = handle;
6464 r.in.level = levels[i];
6467 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
6468 if (!NT_STATUS_IS_OK(status)) {
6469 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6470 r.in.level, nt_errstr(status));
6475 switch (levels[i]) {
6477 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
6478 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6479 levels[i], info->general.oem_information.string, domain_comment);
6480 if (!torture_setting_bool(tctx, "samba3", false)) {
6484 if (!info->general.primary.string) {
6485 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6488 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
6489 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
6490 torture_warning(tctx, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
6491 levels[i], info->general.primary.string, dcerpc_server_name(p));
6496 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
6497 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6498 levels[i], info->oem.oem_information.string, domain_comment);
6499 if (!torture_setting_bool(tctx, "samba3", false)) {
6505 if (!info->info6.primary.string) {
6506 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6512 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
6513 torture_warning(tctx, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
6514 levels[i], info->general2.general.oem_information.string, domain_comment);
6515 if (!torture_setting_bool(tctx, "samba3", false)) {
6522 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
6524 s.in.domain_handle = handle;
6525 s.in.level = levels[i];
6528 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
6530 if (!NT_STATUS_IS_OK(status)) {
6531 torture_warning(tctx, "SetDomainInfo level %u failed - %s\n",
6532 r.in.level, nt_errstr(status));
6537 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
6538 torture_warning(tctx, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6539 r.in.level, nt_errstr(status));
6545 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
6546 if (!NT_STATUS_IS_OK(status)) {
6547 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6548 r.in.level, nt_errstr(status));
6558 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
6559 struct policy_handle *handle)
6562 struct samr_QueryDomainInfo2 r;
6563 union samr_DomainInfo *info = NULL;
6564 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6568 for (i=0;i<ARRAY_SIZE(levels);i++) {
6569 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
6571 r.in.domain_handle = handle;
6572 r.in.level = levels[i];
6575 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
6576 if (!NT_STATUS_IS_OK(status)) {
6577 torture_warning(tctx, "QueryDomainInfo2 level %u failed - %s\n",
6578 r.in.level, nt_errstr(status));
6587 /* Test whether querydispinfo level 5 and enumdomgroups return the same
6588 set of group names. */
6589 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
6590 struct policy_handle *handle)
6592 struct samr_EnumDomainGroups q1;
6593 struct samr_QueryDisplayInfo q2;
6595 uint32_t resume_handle=0;
6596 struct samr_SamArray *sam = NULL;
6597 uint32_t num_entries = 0;
6600 uint32_t total_size;
6601 uint32_t returned_size;
6602 union samr_DispInfo info;
6605 const char **names = NULL;
6607 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
6609 q1.in.domain_handle = handle;
6610 q1.in.resume_handle = &resume_handle;
6612 q1.out.resume_handle = &resume_handle;
6613 q1.out.num_entries = &num_entries;
6616 status = STATUS_MORE_ENTRIES;
6617 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6618 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
6620 if (!NT_STATUS_IS_OK(status) &&
6621 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6624 for (i=0; i<*q1.out.num_entries; i++) {
6625 add_string_to_array(tctx,
6626 sam->entries[i].name.string,
6627 &names, &num_names);
6631 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
6633 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
6635 q2.in.domain_handle = handle;
6637 q2.in.start_idx = 0;
6638 q2.in.max_entries = 5;
6639 q2.in.buf_size = (uint32_t)-1;
6640 q2.out.total_size = &total_size;
6641 q2.out.returned_size = &returned_size;
6642 q2.out.info = &info;
6644 status = STATUS_MORE_ENTRIES;
6645 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6646 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
6648 if (!NT_STATUS_IS_OK(status) &&
6649 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6652 for (i=0; i<q2.out.info->info5.count; i++) {
6654 const char *name = q2.out.info->info5.entries[i].account_name.string;
6656 for (j=0; j<num_names; j++) {
6657 if (names[j] == NULL)
6659 if (strequal(names[j], name)) {
6667 torture_warning(tctx, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
6672 q2.in.start_idx += q2.out.info->info5.count;
6675 if (!NT_STATUS_IS_OK(status)) {
6676 torture_warning(tctx, "QueryDisplayInfo level 5 failed - %s\n",
6681 for (i=0; i<num_names; i++) {
6682 if (names[i] != NULL) {
6683 torture_warning(tctx, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
6692 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
6693 struct policy_handle *group_handle)
6695 struct samr_DeleteDomainGroup d;
6698 torture_comment(tctx, "Testing DeleteDomainGroup\n");
6700 d.in.group_handle = group_handle;
6701 d.out.group_handle = group_handle;
6703 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
6704 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
6709 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6710 struct policy_handle *domain_handle)
6712 struct samr_TestPrivateFunctionsDomain r;
6716 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
6718 r.in.domain_handle = domain_handle;
6720 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
6721 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
6726 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
6727 struct dom_sid *domain_sid,
6728 struct policy_handle *domain_handle)
6730 struct samr_RidToSid r;
6733 struct dom_sid *calc_sid, *out_sid;
6734 int rids[] = { 0, 42, 512, 10200 };
6737 for (i=0;i<ARRAY_SIZE(rids);i++) {
6738 torture_comment(tctx, "Testing RidToSid\n");
6740 calc_sid = dom_sid_dup(tctx, domain_sid);
6741 r.in.domain_handle = domain_handle;
6743 r.out.sid = &out_sid;
6745 status = dcerpc_samr_RidToSid(p, tctx, &r);
6746 if (!NT_STATUS_IS_OK(status)) {
6747 torture_warning(tctx, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
6750 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
6752 if (!dom_sid_equal(calc_sid, out_sid)) {
6753 torture_warning(tctx, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
6754 dom_sid_string(tctx, out_sid),
6755 dom_sid_string(tctx, calc_sid));
6764 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
6765 struct policy_handle *domain_handle)
6767 struct samr_GetBootKeyInformation r;
6770 uint32_t unknown = 0;
6772 torture_comment(tctx, "Testing GetBootKeyInformation\n");
6774 r.in.domain_handle = domain_handle;
6775 r.out.unknown = &unknown;
6777 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
6778 if (!NT_STATUS_IS_OK(status)) {
6779 /* w2k3 seems to fail this sometimes and pass it sometimes */
6780 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
6786 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
6787 struct policy_handle *domain_handle,
6788 struct policy_handle *group_handle)
6791 struct samr_AddGroupMember r;
6792 struct samr_DeleteGroupMember d;
6793 struct samr_QueryGroupMember q;
6794 struct samr_RidTypeArray *rids = NULL;
6795 struct samr_SetMemberAttributesOfGroup s;
6797 bool found_member = false;
6800 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
6801 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
6803 r.in.group_handle = group_handle;
6805 r.in.flags = 0; /* ??? */
6807 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
6809 d.in.group_handle = group_handle;
6812 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
6813 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
6815 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
6816 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
6818 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
6819 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
6821 if (torture_setting_bool(tctx, "samba4", false) ||
6822 torture_setting_bool(tctx, "samba3", false)) {
6823 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
6825 /* this one is quite strange. I am using random inputs in the
6826 hope of triggering an error that might give us a clue */
6828 s.in.group_handle = group_handle;
6829 s.in.unknown1 = random();
6830 s.in.unknown2 = random();
6832 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
6833 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
6836 q.in.group_handle = group_handle;
6839 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
6840 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
6841 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
6843 for (i=0; i < rids->count; i++) {
6844 if (rids->rids[i] == rid) {
6845 found_member = true;
6849 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
6851 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
6852 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
6855 found_member = false;
6857 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
6858 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
6859 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
6861 for (i=0; i < rids->count; i++) {
6862 if (rids->rids[i] == rid) {
6863 found_member = true;
6867 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
6869 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
6870 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
6876 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
6877 struct torture_context *tctx,
6878 struct policy_handle *domain_handle,
6879 const char *group_name,
6880 struct policy_handle *group_handle,
6881 struct dom_sid *domain_sid,
6885 struct samr_CreateDomainGroup r;
6887 struct lsa_String name;
6890 init_lsa_String(&name, group_name);
6892 r.in.domain_handle = domain_handle;
6894 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6895 r.out.group_handle = group_handle;
6898 torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
6900 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6902 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
6903 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6904 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
6907 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
6913 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
6914 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
6915 torture_warning(tctx, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
6919 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6921 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
6922 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
6924 torture_warning(tctx, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
6928 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6930 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
6936 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
6937 torture_warning(tctx, "CreateDomainGroup failed - %s\n", nt_errstr(status));
6941 if (!test_SetGroupInfo(p, tctx, group_handle)) {
6950 its not totally clear what this does. It seems to accept any sid you like.
6952 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
6953 struct torture_context *tctx,
6954 struct policy_handle *domain_handle)
6957 struct samr_RemoveMemberFromForeignDomain r;
6959 r.in.domain_handle = domain_handle;
6960 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
6962 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
6963 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
6968 static bool test_EnumDomainUsers(struct dcerpc_pipe *p,
6969 struct torture_context *tctx,
6970 struct policy_handle *domain_handle,
6971 uint32_t *total_num_entries_p)
6974 struct samr_EnumDomainUsers r;
6975 uint32_t resume_handle = 0;
6976 uint32_t num_entries = 0;
6977 uint32_t total_num_entries = 0;
6978 struct samr_SamArray *sam;
6980 r.in.domain_handle = domain_handle;
6981 r.in.acct_flags = 0;
6982 r.in.max_size = (uint32_t)-1;
6983 r.in.resume_handle = &resume_handle;
6986 r.out.num_entries = &num_entries;
6987 r.out.resume_handle = &resume_handle;
6989 torture_comment(tctx, "Testing EnumDomainUsers\n");
6992 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
6993 if (NT_STATUS_IS_ERR(status)) {
6994 torture_assert_ntstatus_ok(tctx, status,
6995 "failed to enumerate users");
6998 total_num_entries += num_entries;
6999 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7001 if (total_num_entries_p) {
7002 *total_num_entries_p = total_num_entries;
7008 static bool test_EnumDomainGroups(struct dcerpc_pipe *p,
7009 struct torture_context *tctx,
7010 struct policy_handle *domain_handle,
7011 uint32_t *total_num_entries_p)
7014 struct samr_EnumDomainGroups r;
7015 uint32_t resume_handle = 0;
7016 uint32_t num_entries = 0;
7017 uint32_t total_num_entries = 0;
7018 struct samr_SamArray *sam;
7020 r.in.domain_handle = domain_handle;
7021 r.in.max_size = (uint32_t)-1;
7022 r.in.resume_handle = &resume_handle;
7025 r.out.num_entries = &num_entries;
7026 r.out.resume_handle = &resume_handle;
7028 torture_comment(tctx, "Testing EnumDomainGroups\n");
7031 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
7032 if (NT_STATUS_IS_ERR(status)) {
7033 torture_assert_ntstatus_ok(tctx, status,
7034 "failed to enumerate groups");
7037 total_num_entries += num_entries;
7038 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7040 if (total_num_entries_p) {
7041 *total_num_entries_p = total_num_entries;
7047 static bool test_EnumDomainAliases(struct dcerpc_pipe *p,
7048 struct torture_context *tctx,
7049 struct policy_handle *domain_handle,
7050 uint32_t *total_num_entries_p)
7053 struct samr_EnumDomainAliases r;
7054 uint32_t resume_handle = 0;
7055 uint32_t num_entries = 0;
7056 uint32_t total_num_entries = 0;
7057 struct samr_SamArray *sam;
7059 r.in.domain_handle = domain_handle;
7060 r.in.max_size = (uint32_t)-1;
7061 r.in.resume_handle = &resume_handle;
7064 r.out.num_entries = &num_entries;
7065 r.out.resume_handle = &resume_handle;
7067 torture_comment(tctx, "Testing EnumDomainAliases\n");
7070 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
7071 if (NT_STATUS_IS_ERR(status)) {
7072 torture_assert_ntstatus_ok(tctx, status,
7073 "failed to enumerate aliases");
7076 total_num_entries += num_entries;
7077 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7079 if (total_num_entries_p) {
7080 *total_num_entries_p = total_num_entries;
7086 static bool test_QueryDisplayInfo_level(struct dcerpc_pipe *p,
7087 struct torture_context *tctx,
7088 struct policy_handle *handle,
7090 uint32_t *total_num_entries_p)
7093 struct samr_QueryDisplayInfo r;
7094 uint32_t total_num_entries = 0;
7096 r.in.domain_handle = handle;
7099 r.in.max_entries = (uint32_t)-1;
7100 r.in.buf_size = (uint32_t)-1;
7102 torture_comment(tctx, "Testing QueryDisplayInfo\n");
7105 uint32_t total_size;
7106 uint32_t returned_size;
7107 union samr_DispInfo info;
7109 r.out.total_size = &total_size;
7110 r.out.returned_size = &returned_size;
7113 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
7114 if (NT_STATUS_IS_ERR(status)) {
7115 torture_assert_ntstatus_ok(tctx, status,
7116 "failed to query displayinfo");
7119 if (*r.out.returned_size == 0) {
7123 switch (r.in.level) {
7125 total_num_entries += info.info1.count;
7126 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
7129 total_num_entries += info.info2.count;
7130 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
7133 total_num_entries += info.info3.count;
7134 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
7137 total_num_entries += info.info4.count;
7138 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
7141 total_num_entries += info.info5.count;
7142 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
7148 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7150 if (total_num_entries_p) {
7151 *total_num_entries_p = total_num_entries;
7157 static bool test_ManyObjects(struct dcerpc_pipe *p,
7158 struct torture_context *tctx,
7159 struct policy_handle *domain_handle,
7160 struct dom_sid *domain_sid,
7161 struct torture_samr_context *ctx)
7163 uint32_t num_total = ctx->num_objects_large_dc;
7164 uint32_t num_enum = 0;
7165 uint32_t num_disp = 0;
7166 uint32_t num_created = 0;
7167 uint32_t num_anounced = 0;
7172 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
7177 struct samr_QueryDomainInfo2 r;
7178 union samr_DomainInfo *info;
7179 r.in.domain_handle = domain_handle;
7183 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
7184 torture_assert_ntstatus_ok(tctx, status,
7185 "failed to query domain info");
7187 switch (ctx->choice) {
7188 case TORTURE_SAMR_MANY_ACCOUNTS:
7189 num_anounced = info->general.num_users;
7191 case TORTURE_SAMR_MANY_GROUPS:
7192 num_anounced = info->general.num_groups;
7194 case TORTURE_SAMR_MANY_ALIASES:
7195 num_anounced = info->general.num_aliases;
7204 for (i=0; i < num_total; i++) {
7206 const char *name = NULL;
7208 switch (ctx->choice) {
7209 case TORTURE_SAMR_MANY_ACCOUNTS:
7210 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
7211 ret &= test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false);
7213 case TORTURE_SAMR_MANY_GROUPS:
7214 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
7215 ret &= test_CreateDomainGroup(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
7217 case TORTURE_SAMR_MANY_ALIASES:
7218 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
7219 ret &= test_CreateAlias(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
7224 if (!policy_handle_empty(&handles[i])) {
7231 switch (ctx->choice) {
7232 case TORTURE_SAMR_MANY_ACCOUNTS:
7233 ret &= test_EnumDomainUsers(p, tctx, domain_handle, &num_enum);
7235 case TORTURE_SAMR_MANY_GROUPS:
7236 ret &= test_EnumDomainGroups(p, tctx, domain_handle, &num_enum);
7238 case TORTURE_SAMR_MANY_ALIASES:
7239 ret &= test_EnumDomainAliases(p, tctx, domain_handle, &num_enum);
7247 switch (ctx->choice) {
7248 case TORTURE_SAMR_MANY_ACCOUNTS:
7249 ret &= test_QueryDisplayInfo_level(p, tctx, domain_handle, 1, &num_disp);
7251 case TORTURE_SAMR_MANY_GROUPS:
7252 ret &= test_QueryDisplayInfo_level(p, tctx, domain_handle, 3, &num_disp);
7254 case TORTURE_SAMR_MANY_ALIASES:
7255 /* no aliases in dispinfo */
7261 /* close or delete */
7263 for (i=0; i < num_total; i++) {
7265 if (policy_handle_empty(&handles[i])) {
7269 if (torture_setting_bool(tctx, "samba3", false)) {
7270 ret &= test_samr_handle_Close(p, tctx, &handles[i]);
7272 switch (ctx->choice) {
7273 case TORTURE_SAMR_MANY_ACCOUNTS:
7274 ret &= test_DeleteUser(p, tctx, &handles[i]);
7276 case TORTURE_SAMR_MANY_GROUPS:
7277 ret &= test_DeleteDomainGroup(p, tctx, &handles[i]);
7279 case TORTURE_SAMR_MANY_ALIASES:
7280 ret &= test_DeleteAlias(p, tctx, &handles[i]);
7288 talloc_free(handles);
7290 if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
7291 torture_comment(tctx,
7292 "unexpected number of results (%u) returned in enum call, expected %u\n",
7293 num_enum, num_anounced + num_created);
7295 torture_comment(tctx,
7296 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
7297 num_disp, num_anounced + num_created);
7302 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
7303 struct policy_handle *handle);
7305 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7306 struct torture_samr_context *ctx, struct dom_sid *sid)
7309 struct samr_OpenDomain r;
7310 struct policy_handle domain_handle;
7311 struct policy_handle alias_handle;
7312 struct policy_handle user_handle;
7313 struct policy_handle group_handle;
7316 ZERO_STRUCT(alias_handle);
7317 ZERO_STRUCT(user_handle);
7318 ZERO_STRUCT(group_handle);
7319 ZERO_STRUCT(domain_handle);
7321 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
7323 r.in.connect_handle = &ctx->handle;
7324 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7326 r.out.domain_handle = &domain_handle;
7328 status = dcerpc_samr_OpenDomain(p, tctx, &r);
7329 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
7331 /* run the domain tests with the main handle closed - this tests
7332 the servers reference counting */
7333 torture_assert(tctx, test_samr_handle_Close(p, tctx, &ctx->handle), "Failed to close SAMR handle");
7335 switch (ctx->choice) {
7336 case TORTURE_SAMR_PASSWORDS:
7337 case TORTURE_SAMR_USER_PRIVILEGES:
7338 if (!torture_setting_bool(tctx, "samba3", false)) {
7339 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7341 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7343 torture_warning(tctx, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
7346 case TORTURE_SAMR_USER_ATTRIBUTES:
7347 if (!torture_setting_bool(tctx, "samba3", false)) {
7348 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7350 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7351 /* This test needs 'complex' users to validate */
7352 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
7354 torture_warning(tctx, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
7357 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
7358 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
7359 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
7360 if (!torture_setting_bool(tctx, "samba3", false)) {
7361 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
7363 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
7365 torture_warning(tctx, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx, sid));
7368 case TORTURE_SAMR_MANY_ACCOUNTS:
7369 case TORTURE_SAMR_MANY_GROUPS:
7370 case TORTURE_SAMR_MANY_ALIASES:
7371 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
7373 torture_warning(tctx, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
7376 case TORTURE_SAMR_OTHER:
7377 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7379 torture_warning(tctx, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
7381 if (!torture_setting_bool(tctx, "samba3", false)) {
7382 ret &= test_QuerySecurity(p, tctx, &domain_handle);
7384 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
7385 ret &= test_CreateAlias(p, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
7386 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
7387 ret &= test_GetAliasMembership(p, tctx, &domain_handle);
7388 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
7389 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
7390 ret &= test_EnumDomainUsers_all(p, tctx, &domain_handle);
7391 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
7392 ret &= test_EnumDomainGroups_all(p, tctx, &domain_handle);
7393 ret &= test_EnumDomainAliases_all(p, tctx, &domain_handle);
7394 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
7395 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
7396 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
7398 if (torture_setting_bool(tctx, "samba4", false)) {
7399 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
7401 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
7402 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
7404 ret &= test_GroupList(p, tctx, &domain_handle);
7405 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
7406 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
7407 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
7409 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
7414 if (!policy_handle_empty(&user_handle) &&
7415 !test_DeleteUser(p, tctx, &user_handle)) {
7419 if (!policy_handle_empty(&alias_handle) &&
7420 !test_DeleteAlias(p, tctx, &alias_handle)) {
7424 if (!policy_handle_empty(&group_handle) &&
7425 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
7429 torture_assert(tctx, test_samr_handle_Close(p, tctx, &domain_handle), "Failed to close SAMR domain handle");
7431 torture_assert(tctx, test_Connect(p, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
7432 /* reconnect the main handle */
7435 torture_warning(tctx, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
7441 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7442 struct torture_samr_context *ctx, const char *domain)
7445 struct samr_LookupDomain r;
7446 struct dom_sid2 *sid = NULL;
7447 struct lsa_String n1;
7448 struct lsa_String n2;
7451 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
7453 /* check for correct error codes */
7454 r.in.connect_handle = &ctx->handle;
7455 r.in.domain_name = &n2;
7459 status = dcerpc_samr_LookupDomain(p, tctx, &r);
7460 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
7462 init_lsa_String(&n2, "xxNODOMAINxx");
7464 status = dcerpc_samr_LookupDomain(p, tctx, &r);
7465 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
7467 r.in.connect_handle = &ctx->handle;
7469 init_lsa_String(&n1, domain);
7470 r.in.domain_name = &n1;
7472 status = dcerpc_samr_LookupDomain(p, tctx, &r);
7473 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
7475 if (!test_GetDomPwInfo(p, tctx, &n1)) {
7479 if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
7487 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
7488 struct torture_samr_context *ctx)
7491 struct samr_EnumDomains r;
7492 uint32_t resume_handle = 0;
7493 uint32_t num_entries = 0;
7494 struct samr_SamArray *sam = NULL;
7498 r.in.connect_handle = &ctx->handle;
7499 r.in.resume_handle = &resume_handle;
7500 r.in.buf_size = (uint32_t)-1;
7501 r.out.resume_handle = &resume_handle;
7502 r.out.num_entries = &num_entries;
7505 status = dcerpc_samr_EnumDomains(p, tctx, &r);
7506 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
7512 for (i=0;i<sam->count;i++) {
7513 if (!test_LookupDomain(p, tctx, ctx,
7514 sam->entries[i].name.string)) {
7519 status = dcerpc_samr_EnumDomains(p, tctx, &r);
7520 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
7526 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
7527 struct policy_handle *handle)
7530 struct samr_Connect r;
7531 struct samr_Connect2 r2;
7532 struct samr_Connect3 r3;
7533 struct samr_Connect4 r4;
7534 struct samr_Connect5 r5;
7535 union samr_ConnectInfo info;
7536 struct policy_handle h;
7537 uint32_t level_out = 0;
7538 bool ret = true, got_handle = false;
7540 torture_comment(tctx, "testing samr_Connect\n");
7542 r.in.system_name = 0;
7543 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7544 r.out.connect_handle = &h;
7546 status = dcerpc_samr_Connect(p, tctx, &r);
7547 if (!NT_STATUS_IS_OK(status)) {
7548 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
7555 torture_comment(tctx, "testing samr_Connect2\n");
7557 r2.in.system_name = NULL;
7558 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7559 r2.out.connect_handle = &h;
7561 status = dcerpc_samr_Connect2(p, tctx, &r2);
7562 if (!NT_STATUS_IS_OK(status)) {
7563 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
7567 test_samr_handle_Close(p, tctx, handle);
7573 torture_comment(tctx, "testing samr_Connect3\n");
7575 r3.in.system_name = NULL;
7577 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7578 r3.out.connect_handle = &h;
7580 status = dcerpc_samr_Connect3(p, tctx, &r3);
7581 if (!NT_STATUS_IS_OK(status)) {
7582 torture_warning(tctx, "Connect3 failed - %s\n", nt_errstr(status));
7586 test_samr_handle_Close(p, tctx, handle);
7592 torture_comment(tctx, "testing samr_Connect4\n");
7594 r4.in.system_name = "";
7595 r4.in.client_version = 0;
7596 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7597 r4.out.connect_handle = &h;
7599 status = dcerpc_samr_Connect4(p, tctx, &r4);
7600 if (!NT_STATUS_IS_OK(status)) {
7601 torture_warning(tctx, "Connect4 failed - %s\n", nt_errstr(status));
7605 test_samr_handle_Close(p, tctx, handle);
7611 torture_comment(tctx, "testing samr_Connect5\n");
7613 info.info1.client_version = 0;
7614 info.info1.unknown2 = 0;
7616 r5.in.system_name = "";
7617 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7619 r5.out.level_out = &level_out;
7620 r5.in.info_in = &info;
7621 r5.out.info_out = &info;
7622 r5.out.connect_handle = &h;
7624 status = dcerpc_samr_Connect5(p, tctx, &r5);
7625 if (!NT_STATUS_IS_OK(status)) {
7626 torture_warning(tctx, "Connect5 failed - %s\n", nt_errstr(status));
7630 test_samr_handle_Close(p, tctx, handle);
7640 static bool test_samr_ValidatePassword(struct dcerpc_pipe *p, struct torture_context *tctx)
7642 struct samr_ValidatePassword r;
7643 union samr_ValidatePasswordReq req;
7644 union samr_ValidatePasswordRep *repp = NULL;
7646 const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
7649 torture_comment(tctx, "testing samr_ValidatePassword\n");
7652 r.in.level = NetValidatePasswordReset;
7657 req.req3.account.string = "non-existant-account-aklsdji";
7659 for (i=0; passwords[i]; i++) {
7660 req.req3.password.string = passwords[i];
7661 status = dcerpc_samr_ValidatePassword(p, tctx, &r);
7662 torture_assert_ntstatus_ok(tctx, status, "samr_ValidatePassword");
7663 torture_comment(tctx, "Server %s password '%s' with code %i\n",
7664 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
7665 req.req3.password.string, repp->ctr3.status);
7671 bool torture_rpc_samr(struct torture_context *torture)
7674 struct dcerpc_pipe *p;
7676 struct torture_samr_context *ctx;
7678 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7679 if (!NT_STATUS_IS_OK(status)) {
7683 ctx = talloc_zero(torture, struct torture_samr_context);
7685 ctx->choice = TORTURE_SAMR_OTHER;
7687 ret &= test_Connect(p, torture, &ctx->handle);
7689 if (!torture_setting_bool(torture, "samba3", false)) {
7690 ret &= test_QuerySecurity(p, torture, &ctx->handle);
7693 ret &= test_EnumDomains(p, torture, ctx);
7695 ret &= test_SetDsrmPassword(p, torture, &ctx->handle);
7697 ret &= test_Shutdown(p, torture, &ctx->handle);
7699 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7705 bool torture_rpc_samr_users(struct torture_context *torture)
7708 struct dcerpc_pipe *p;
7710 struct torture_samr_context *ctx;
7712 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7713 if (!NT_STATUS_IS_OK(status)) {
7717 ctx = talloc_zero(torture, struct torture_samr_context);
7719 ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
7721 ret &= test_Connect(p, torture, &ctx->handle);
7723 if (!torture_setting_bool(torture, "samba3", false)) {
7724 ret &= test_QuerySecurity(p, torture, &ctx->handle);
7727 ret &= test_EnumDomains(p, torture, ctx);
7729 ret &= test_SetDsrmPassword(p, torture, &ctx->handle);
7731 ret &= test_Shutdown(p, torture, &ctx->handle);
7733 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7739 bool torture_rpc_samr_passwords(struct torture_context *torture)
7742 struct dcerpc_pipe *p;
7744 struct torture_samr_context *ctx;
7746 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7747 if (!NT_STATUS_IS_OK(status)) {
7751 ctx = talloc_zero(torture, struct torture_samr_context);
7753 ctx->choice = TORTURE_SAMR_PASSWORDS;
7755 ret &= test_Connect(p, torture, &ctx->handle);
7757 ret &= test_EnumDomains(p, torture, ctx);
7759 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7761 ret &= test_samr_ValidatePassword(p, torture);
7766 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
7767 struct dcerpc_pipe *p2,
7768 struct cli_credentials *machine_credentials)
7771 struct dcerpc_pipe *p;
7773 struct torture_samr_context *ctx;
7775 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7776 if (!NT_STATUS_IS_OK(status)) {
7780 ctx = talloc_zero(torture, struct torture_samr_context);
7782 ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
7783 ctx->machine_credentials = machine_credentials;
7785 ret &= test_Connect(p, torture, &ctx->handle);
7787 ret &= test_EnumDomains(p, torture, ctx);
7789 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7794 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
7796 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
7797 struct torture_rpc_tcase *tcase;
7799 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
7801 TEST_ACCOUNT_NAME_PWD);
7803 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
7804 torture_rpc_samr_pwdlastset);
7809 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
7810 struct dcerpc_pipe *p2,
7811 struct cli_credentials *machine_credentials)
7814 struct dcerpc_pipe *p;
7816 struct torture_samr_context *ctx;
7818 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7819 if (!NT_STATUS_IS_OK(status)) {
7823 ctx = talloc_zero(torture, struct torture_samr_context);
7825 ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
7826 ctx->machine_credentials = machine_credentials;
7828 ret &= test_Connect(p, torture, &ctx->handle);
7830 ret &= test_EnumDomains(p, torture, ctx);
7832 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7837 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
7839 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-USERS-PRIVILEGES");
7840 struct torture_rpc_tcase *tcase;
7842 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
7844 TEST_ACCOUNT_NAME_PWD);
7846 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
7847 torture_rpc_samr_users_privileges_delete_user);
7852 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
7853 struct dcerpc_pipe *p2,
7857 struct dcerpc_pipe *p;
7859 struct torture_samr_context *ctx =
7860 talloc_get_type_abort(data, struct torture_samr_context);
7862 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7863 if (!NT_STATUS_IS_OK(status)) {
7867 ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
7868 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
7869 ctx->num_objects_large_dc);
7871 ret &= test_Connect(p, torture, &ctx->handle);
7873 ret &= test_EnumDomains(p, torture, ctx);
7875 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7880 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
7881 struct dcerpc_pipe *p2,
7885 struct dcerpc_pipe *p;
7887 struct torture_samr_context *ctx =
7888 talloc_get_type_abort(data, struct torture_samr_context);
7890 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7891 if (!NT_STATUS_IS_OK(status)) {
7895 ctx->choice = TORTURE_SAMR_MANY_GROUPS;
7896 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
7897 ctx->num_objects_large_dc);
7899 ret &= test_Connect(p, torture, &ctx->handle);
7901 ret &= test_EnumDomains(p, torture, ctx);
7903 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7908 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
7909 struct dcerpc_pipe *p2,
7913 struct dcerpc_pipe *p;
7915 struct torture_samr_context *ctx =
7916 talloc_get_type_abort(data, struct torture_samr_context);
7918 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7919 if (!NT_STATUS_IS_OK(status)) {
7923 ctx->choice = TORTURE_SAMR_MANY_ALIASES;
7924 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
7925 ctx->num_objects_large_dc);
7927 ret &= test_Connect(p, torture, &ctx->handle);
7929 ret &= test_EnumDomains(p, torture, ctx);
7931 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7936 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
7938 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-LARGE-DC");
7939 struct torture_rpc_tcase *tcase;
7940 struct torture_samr_context *ctx;
7942 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
7944 ctx = talloc_zero(suite, struct torture_samr_context);
7945 ctx->num_objects_large_dc = 150;
7947 torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
7948 torture_rpc_samr_many_aliases, ctx);
7949 torture_rpc_tcase_add_test_ex(tcase, "many_groups",
7950 torture_rpc_samr_many_groups, ctx);
7951 torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
7952 torture_rpc_samr_many_accounts, ctx);
7957 static bool torture_rpc_samr_badpwdcount(struct torture_context *torture,
7958 struct dcerpc_pipe *p2,
7959 struct cli_credentials *machine_credentials)
7962 struct dcerpc_pipe *p;
7964 struct torture_samr_context *ctx;
7966 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7967 if (!NT_STATUS_IS_OK(status)) {
7971 ctx = talloc_zero(torture, struct torture_samr_context);
7973 ctx->choice = TORTURE_SAMR_PASSWORDS_BADPWDCOUNT;
7974 ctx->machine_credentials = machine_credentials;
7976 ret &= test_Connect(p, torture, &ctx->handle);
7978 ret &= test_EnumDomains(p, torture, ctx);
7980 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7985 struct torture_suite *torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX *mem_ctx)
7987 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-BADPWDCOUNT");
7988 struct torture_rpc_tcase *tcase;
7990 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
7992 TEST_ACCOUNT_NAME_PWD);
7994 torture_rpc_tcase_add_test_creds(tcase, "badPwdCount",
7995 torture_rpc_samr_badpwdcount);
8000 static bool torture_rpc_samr_lockout(struct torture_context *torture,
8001 struct dcerpc_pipe *p2,
8002 struct cli_credentials *machine_credentials)
8005 struct dcerpc_pipe *p;
8007 struct torture_samr_context *ctx;
8009 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8010 if (!NT_STATUS_IS_OK(status)) {
8014 ctx = talloc_zero(torture, struct torture_samr_context);
8016 ctx->choice = TORTURE_SAMR_PASSWORDS_LOCKOUT;
8017 ctx->machine_credentials = machine_credentials;
8019 ret &= test_Connect(p, torture, &ctx->handle);
8021 ret &= test_EnumDomains(p, torture, ctx);
8023 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
8028 struct torture_suite *torture_rpc_samr_passwords_lockout(TALLOC_CTX *mem_ctx)
8030 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-LOCKOUT");
8031 struct torture_rpc_tcase *tcase;
8033 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8035 TEST_ACCOUNT_NAME_PWD);
8037 torture_rpc_tcase_add_test_creds(tcase, "lockout",
8038 torture_rpc_samr_lockout);