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");
3469 static bool test_SetDomainInfo_ntstatus(struct dcerpc_pipe *p,
3470 struct torture_context *tctx,
3471 struct policy_handle *domain_handle,
3472 enum samr_DomainInfoClass level,
3473 union samr_DomainInfo *info,
3476 struct samr_SetDomainInfo r;
3478 r.in.domain_handle = domain_handle;
3482 torture_assert_ntstatus_equal(tctx,
3483 dcerpc_samr_SetDomainInfo(p, tctx, &r),
3491 static bool test_Password_badpwdcount(struct dcerpc_pipe *p,
3492 struct dcerpc_pipe *np,
3493 struct torture_context *tctx,
3494 uint32_t acct_flags,
3495 const char *acct_name,
3496 struct policy_handle *domain_handle,
3497 struct policy_handle *user_handle,
3499 struct cli_credentials *machine_credentials,
3500 const char *comment,
3503 NTSTATUS expected_success_status,
3504 struct samr_DomInfo1 *info1,
3505 struct samr_DomInfo12 *info12)
3507 union samr_DomainInfo info;
3510 uint32_t badpwdcount, tmp;
3511 uint32_t password_history_length = 12;
3512 uint32_t lockout_threshold = 15;
3514 torture_comment(tctx, "\nTesting bad pwd count with: %s\n", comment);
3516 torture_assert(tctx, password_history_length < lockout_threshold,
3517 "password history length needs to be smaller than account lockout threshold for this test");
3522 info.info1 = *info1;
3523 info.info1.password_history_length = password_history_length;
3525 torture_assert(tctx,
3526 test_SetDomainInfo(p, tctx, domain_handle,
3527 DomainPasswordInformation, &info),
3528 "failed to set password history length");
3530 info.info12 = *info12;
3531 info.info12.lockout_threshold = lockout_threshold;
3533 torture_assert(tctx,
3534 test_SetDomainInfo(p, tctx, domain_handle,
3535 DomainLockoutInformation, &info),
3536 "failed to set lockout threshold");
3538 /* reset bad pwd count */
3540 torture_assert(tctx,
3541 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
3544 /* enable or disable account */
3546 torture_assert(tctx,
3547 test_SetUserInfo_acct_flags(p, tctx, user_handle,
3548 acct_flags | ACB_DISABLED),
3549 "failed to disable user");
3551 torture_assert(tctx,
3552 test_SetUserInfo_acct_flags(p, tctx, user_handle,
3553 acct_flags & ~ACB_DISABLED),
3554 "failed to enable user");
3558 /* setup password history */
3560 passwords = talloc_array(tctx, char *, password_history_length);
3562 for (i=0; i < password_history_length; i++) {
3564 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3565 "failed to set password");
3566 passwords[i] = talloc_strdup(tctx, *password);
3568 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3569 acct_name, passwords[i],
3570 expected_success_status, interactive)) {
3571 torture_fail(tctx, "failed to auth with latest password");
3574 torture_assert(tctx,
3575 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3577 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3581 /* test with wrong password */
3583 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3584 acct_name, "random_crap",
3585 NT_STATUS_WRONG_PASSWORD, interactive)) {
3586 torture_fail(tctx, "succeeded to authenticate with wrong password");
3589 torture_assert(tctx,
3590 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3592 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3595 /* test with latest good password */
3597 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
3598 passwords[password_history_length-1],
3599 expected_success_status, interactive)) {
3600 torture_fail(tctx, "succeeded to authenticate with wrong password");
3603 torture_assert(tctx,
3604 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3607 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3609 /* only enabled accounts get the bad pwd count reset upon
3610 * successful logon */
3611 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3617 /* test password history */
3619 for (i=0; i < password_history_length; i++) {
3621 torture_comment(tctx, "Testing bad password count behavior with "
3622 "password #%d of #%d\n", i, password_history_length);
3624 /* - network samlogon will succeed auth and not
3625 * increase badpwdcount for 2 last entries
3626 * - interactive samlogon only for the last one */
3628 if (i == password_history_length - 1 ||
3629 (i == password_history_length - 2 && !interactive)) {
3631 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3632 acct_name, passwords[i],
3633 expected_success_status, interactive)) {
3634 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3637 torture_assert(tctx,
3638 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3641 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
3642 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3644 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
3645 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3653 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3654 acct_name, passwords[i],
3655 NT_STATUS_WRONG_PASSWORD, interactive)) {
3656 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3659 torture_assert(tctx,
3660 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3662 /* - network samlogon will fail auth but not increase
3663 * badpwdcount for 3rd last entry
3664 * - interactive samlogon for 3rd and 2nd last entry */
3666 if (i == password_history_length - 3 ||
3667 (i == password_history_length - 2 && interactive)) {
3668 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
3669 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3671 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
3672 torture_assert_int_equal(tctx, badpwdcount, tmp + 1, "unexpected badpwdcount");
3681 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe *p,
3682 struct torture_context *tctx,
3683 uint32_t acct_flags,
3684 const char *acct_name,
3685 struct policy_handle *domain_handle,
3686 struct policy_handle *user_handle,
3688 struct cli_credentials *machine_credentials)
3690 union samr_DomainInfo *q_info, s_info;
3691 struct samr_DomInfo1 info1, _info1;
3692 struct samr_DomInfo12 info12, _info12;
3694 struct dcerpc_pipe *np;
3698 const char *comment;
3701 NTSTATUS expected_success_status;
3704 .comment = "network logon (disabled account)",
3706 .interactive = false,
3707 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
3710 .comment = "network logon (enabled account)",
3712 .interactive = false,
3713 .expected_success_status= NT_STATUS_OK
3716 .comment = "interactive logon (disabled account)",
3718 .interactive = true,
3719 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
3722 .comment = "interactive logon (enabled account)",
3724 .interactive = true,
3725 .expected_success_status= NT_STATUS_OK
3729 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3731 /* backup old policies */
3734 struct samr_QueryDomainInfo2 r;
3736 r.in.domain_handle = domain_handle;
3737 r.in.level = DomainPasswordInformation;
3738 r.out.info = &q_info;
3740 torture_assert_ntstatus_ok(tctx,
3741 dcerpc_samr_QueryDomainInfo2(p, tctx, &r),
3742 "failed to query domain info level 1");
3744 info1 = q_info->info1;
3748 struct samr_QueryDomainInfo2 r;
3750 r.in.domain_handle = domain_handle;
3751 r.in.level = DomainLockoutInformation;
3752 r.out.info = &q_info;
3754 torture_assert_ntstatus_ok(tctx,
3755 dcerpc_samr_QueryDomainInfo2(p, tctx, &r),
3756 "failed to query domain info level 12");
3758 info12 = q_info->info12;
3766 for (i=0; i < ARRAY_SIZE(creds); i++) {
3768 /* skip trust tests for now */
3769 if (acct_flags & ACB_WSTRUST ||
3770 acct_flags & ACB_SVRTRUST ||
3771 acct_flags & ACB_DOMTRUST) {
3775 ret &= test_Password_badpwdcount(p, np, tctx, acct_flags, acct_name,
3776 domain_handle, user_handle, password,
3777 machine_credentials,
3780 creds[i].interactive,
3781 creds[i].expected_success_status,
3784 torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
3786 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
3790 /* restore policies */
3792 s_info.info1 = info1;
3794 torture_assert(tctx,
3795 test_SetDomainInfo(p, tctx, domain_handle,
3796 DomainPasswordInformation, &s_info),
3797 "failed to set password information");
3799 s_info.info12 = info12;
3801 torture_assert(tctx,
3802 test_SetDomainInfo(p, tctx, domain_handle,
3803 DomainLockoutInformation, &s_info),
3804 "failed to set lockout information");
3809 static bool test_QueryUserInfo_acct_flags(struct dcerpc_pipe *p,
3810 struct torture_context *tctx,
3811 struct policy_handle *handle,
3812 uint32_t *acct_flags)
3814 union samr_UserInfo *info;
3815 struct samr_QueryUserInfo r;
3817 r.in.user_handle = handle;
3821 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3823 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo(p, tctx, &r),
3824 "failed to query userinfo");
3826 *acct_flags = info->info16.acct_flags;
3828 torture_comment(tctx, " (acct_flags: 0x%08x)\n", *acct_flags);
3833 static bool test_Password_lockout(struct dcerpc_pipe *p,
3834 struct dcerpc_pipe *np,
3835 struct torture_context *tctx,
3836 uint32_t acct_flags,
3837 const char *acct_name,
3838 struct policy_handle *domain_handle,
3839 struct policy_handle *user_handle,
3841 struct cli_credentials *machine_credentials,
3842 const char *comment,
3845 NTSTATUS expected_success_status,
3846 struct samr_DomInfo1 *info1,
3847 struct samr_DomInfo12 *info12)
3849 union samr_DomainInfo info;
3850 uint32_t badpwdcount;
3851 uint32_t password_history_length = 1;
3852 uint64_t lockout_threshold = 1;
3853 uint32_t lockout_seconds = 5;
3854 uint64_t delta_time_factor = 10 * 1000 * 1000;
3856 torture_comment(tctx, "\nTesting account lockout: %s\n", comment);
3860 info.info1 = *info1;
3862 torture_comment(tctx, "setting password history lenght.\n");
3863 info.info1.password_history_length = password_history_length;
3865 torture_assert(tctx,
3866 test_SetDomainInfo(p, tctx, domain_handle,
3867 DomainPasswordInformation, &info),
3868 "failed to set password history length");
3870 info.info12 = *info12;
3871 info.info12.lockout_threshold = lockout_threshold;
3873 /* set lockout duration < lockout window: should fail */
3874 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
3875 info.info12.lockout_window = ~((lockout_seconds + 1) * delta_time_factor);
3877 torture_assert(tctx,
3878 test_SetDomainInfo_ntstatus(p, tctx, domain_handle,
3879 DomainLockoutInformation, &info,
3880 NT_STATUS_INVALID_PARAMETER),
3881 "setting lockout duration < lockout window gave unexpected result");
3883 info.info12.lockout_duration = 0;
3884 info.info12.lockout_window = 0;
3886 torture_assert(tctx,
3887 test_SetDomainInfo(p, tctx, domain_handle,
3888 DomainLockoutInformation, &info),
3889 "failed to set lockout window and duration to 0");
3892 /* set lockout duration of 5 seconds */
3893 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
3894 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
3896 torture_assert(tctx,
3897 test_SetDomainInfo(p, tctx, domain_handle,
3898 DomainLockoutInformation, &info),
3899 "failed to set lockout window and duration to 5 seconds");
3901 /* reset bad pwd count */
3903 torture_assert(tctx,
3904 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
3907 /* enable or disable account */
3910 torture_assert(tctx,
3911 test_SetUserInfo_acct_flags(p, tctx, user_handle,
3912 acct_flags | ACB_DISABLED),
3913 "failed to disable user");
3915 torture_assert(tctx,
3916 test_SetUserInfo_acct_flags(p, tctx, user_handle,
3917 acct_flags & ~ACB_DISABLED),
3918 "failed to enable user");
3922 /* test logon with right password */
3924 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3925 acct_name, *password,
3926 expected_success_status, interactive)) {
3927 torture_fail(tctx, "failed to auth with latest password");
3930 torture_assert(tctx,
3931 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3932 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3935 /* test with wrong password ==> lockout */
3937 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3938 acct_name, "random_crap",
3939 NT_STATUS_WRONG_PASSWORD, interactive)) {
3940 torture_fail(tctx, "succeeded to authenticate with wrong password");
3943 torture_assert(tctx,
3944 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3945 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3947 torture_assert(tctx,
3948 test_QueryUserInfo_acct_flags(p, tctx, user_handle, &acct_flags), "");
3949 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
3950 "expected account to be locked");
3953 /* test with good password */
3955 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
3957 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
3959 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
3962 /* bad pwd count should not get updated */
3963 torture_assert(tctx,
3964 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3965 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3967 /* curiously, windows does _not_ set the autlock flag */
3968 torture_assert(tctx,
3969 test_QueryUserInfo_acct_flags(p, tctx, user_handle, &acct_flags), "");
3970 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
3971 "expected account to be locked");
3974 /* with bad password */
3976 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3977 acct_name, "random_crap2",
3978 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
3980 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
3983 /* bad pwd count should not get updated */
3984 torture_assert(tctx,
3985 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3986 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3988 /* curiously, windows does _not_ set the autlock flag */
3989 torture_assert(tctx,
3990 test_QueryUserInfo_acct_flags(p, tctx, user_handle, &acct_flags), "");
3991 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
3992 "expected account to be locked");
3995 /* let lockout duration expire ==> unlock */
3997 torture_comment(tctx, "let lockout duration expire...\n");
3998 sleep(lockout_seconds + 1);
4000 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4002 expected_success_status, interactive))
4004 torture_fail(tctx, "failed to authenticate after lockout expired");
4007 torture_assert(tctx,
4008 test_QueryUserInfo_acct_flags(p, tctx, user_handle, &acct_flags), "");
4009 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4010 "expected account not to be locked");
4015 static bool test_Password_lockout_wrap(struct dcerpc_pipe *p,
4016 struct torture_context *tctx,
4017 uint32_t acct_flags,
4018 const char *acct_name,
4019 struct policy_handle *domain_handle,
4020 struct policy_handle *user_handle,
4022 struct cli_credentials *machine_credentials)
4024 union samr_DomainInfo *q_info, s_info;
4025 struct samr_DomInfo1 info1, _info1;
4026 struct samr_DomInfo12 info12, _info12;
4028 struct dcerpc_pipe *np;
4032 const char *comment;
4035 NTSTATUS expected_success_status;
4038 .comment = "network logon (disabled account)",
4040 .interactive = false,
4041 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4044 .comment = "network logon (enabled account)",
4046 .interactive = false,
4047 .expected_success_status= NT_STATUS_OK
4050 .comment = "interactive logon (disabled account)",
4052 .interactive = true,
4053 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4056 .comment = "interactive logon (enabled account)",
4058 .interactive = true,
4059 .expected_success_status= NT_STATUS_OK
4063 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4065 /* backup old policies */
4068 struct samr_QueryDomainInfo2 r;
4070 r.in.domain_handle = domain_handle;
4071 r.in.level = DomainPasswordInformation;
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 1");
4078 info1 = q_info->info1;
4082 struct samr_QueryDomainInfo2 r;
4084 r.in.domain_handle = domain_handle;
4085 r.in.level = DomainLockoutInformation;
4086 r.out.info = &q_info;
4088 torture_assert_ntstatus_ok(tctx,
4089 dcerpc_samr_QueryDomainInfo2(p, tctx, &r),
4090 "failed to query domain info level 12");
4092 info12 = q_info->info12;
4100 for (i=0; i < ARRAY_SIZE(creds); i++) {
4102 /* skip trust tests for now */
4103 if (acct_flags & ACB_WSTRUST ||
4104 acct_flags & ACB_SVRTRUST ||
4105 acct_flags & ACB_DOMTRUST) {
4109 ret &= test_Password_lockout(p, np, tctx, acct_flags, acct_name,
4110 domain_handle, user_handle, password,
4111 machine_credentials,
4114 creds[i].interactive,
4115 creds[i].expected_success_status,
4118 torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
4120 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4124 /* restore policies */
4126 s_info.info1 = info1;
4128 torture_assert(tctx,
4129 test_SetDomainInfo(p, tctx, domain_handle,
4130 DomainPasswordInformation, &s_info),
4131 "failed to set password information");
4133 s_info.info12 = info12;
4135 torture_assert(tctx,
4136 test_SetDomainInfo(p, tctx, domain_handle,
4137 DomainLockoutInformation, &s_info),
4138 "failed to set lockout information");
4143 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
4144 struct dcerpc_pipe *lp,
4145 struct torture_context *tctx,
4146 struct policy_handle *domain_handle,
4147 struct policy_handle *lsa_handle,
4148 struct policy_handle *user_handle,
4149 const struct dom_sid *domain_sid,
4151 struct cli_credentials *machine_credentials)
4156 struct policy_handle lsa_acct_handle;
4157 struct dom_sid *user_sid;
4159 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
4162 struct lsa_EnumAccountRights r;
4163 struct lsa_RightSet rights;
4165 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4167 r.in.handle = lsa_handle;
4168 r.in.sid = user_sid;
4169 r.out.rights = &rights;
4171 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
4172 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4173 "Expected enum rights for account to fail");
4177 struct lsa_RightSet rights;
4178 struct lsa_StringLarge names[2];
4179 struct lsa_AddAccountRights r;
4181 torture_comment(tctx, "Testing LSA AddAccountRights\n");
4183 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
4184 init_lsa_StringLarge(&names[1], NULL);
4187 rights.names = names;
4189 r.in.handle = lsa_handle;
4190 r.in.sid = user_sid;
4191 r.in.rights = &rights;
4193 status = dcerpc_lsa_AddAccountRights(lp, tctx, &r);
4194 torture_assert_ntstatus_ok(tctx, status,
4195 "Failed to add privileges");
4199 struct lsa_EnumAccounts r;
4200 uint32_t resume_handle = 0;
4201 struct lsa_SidArray lsa_sid_array;
4203 bool found_sid = false;
4205 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4207 r.in.handle = lsa_handle;
4208 r.in.num_entries = 0x1000;
4209 r.in.resume_handle = &resume_handle;
4210 r.out.sids = &lsa_sid_array;
4211 r.out.resume_handle = &resume_handle;
4213 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
4214 torture_assert_ntstatus_ok(tctx, status,
4215 "Failed to enum accounts");
4217 for (i=0; i < lsa_sid_array.num_sids; i++) {
4218 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4223 torture_assert(tctx, found_sid,
4224 "failed to list privileged account");
4228 struct lsa_EnumAccountRights r;
4229 struct lsa_RightSet user_rights;
4231 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4233 r.in.handle = lsa_handle;
4234 r.in.sid = user_sid;
4235 r.out.rights = &user_rights;
4237 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
4238 torture_assert_ntstatus_ok(tctx, status,
4239 "Failed to enum rights for account");
4241 if (user_rights.count < 1) {
4242 torture_warning(tctx, "failed to find newly added rights");
4248 struct lsa_OpenAccount r;
4250 torture_comment(tctx, "Testing LSA OpenAccount\n");
4252 r.in.handle = lsa_handle;
4253 r.in.sid = user_sid;
4254 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4255 r.out.acct_handle = &lsa_acct_handle;
4257 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
4258 torture_assert_ntstatus_ok(tctx, status,
4259 "Failed to open lsa account");
4263 struct lsa_GetSystemAccessAccount r;
4264 uint32_t access_mask;
4266 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4268 r.in.handle = &lsa_acct_handle;
4269 r.out.access_mask = &access_mask;
4271 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
4272 torture_assert_ntstatus_ok(tctx, status,
4273 "Failed to get lsa system access account");
4279 torture_comment(tctx, "Testing LSA Close\n");
4281 r.in.handle = &lsa_acct_handle;
4282 r.out.handle = &lsa_acct_handle;
4284 status = dcerpc_lsa_Close(lp, tctx, &r);
4285 torture_assert_ntstatus_ok(tctx, status,
4286 "Failed to close lsa");
4290 struct samr_DeleteUser r;
4292 torture_comment(tctx, "Testing SAMR DeleteUser\n");
4294 r.in.user_handle = user_handle;
4295 r.out.user_handle = user_handle;
4297 status = dcerpc_samr_DeleteUser(p, tctx, &r);
4298 torture_assert_ntstatus_ok(tctx, status, "Delete User failed");
4302 struct lsa_EnumAccounts r;
4303 uint32_t resume_handle = 0;
4304 struct lsa_SidArray lsa_sid_array;
4306 bool found_sid = false;
4308 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4310 r.in.handle = lsa_handle;
4311 r.in.num_entries = 0x1000;
4312 r.in.resume_handle = &resume_handle;
4313 r.out.sids = &lsa_sid_array;
4314 r.out.resume_handle = &resume_handle;
4316 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
4317 torture_assert_ntstatus_ok(tctx, status,
4318 "Failed to enum accounts");
4320 for (i=0; i < lsa_sid_array.num_sids; i++) {
4321 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4326 torture_assert(tctx, found_sid,
4327 "failed to list privileged account");
4331 struct lsa_EnumAccountRights r;
4332 struct lsa_RightSet user_rights;
4334 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4336 r.in.handle = lsa_handle;
4337 r.in.sid = user_sid;
4338 r.out.rights = &user_rights;
4340 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
4341 torture_assert_ntstatus_ok(tctx, status,
4342 "Failed to enum rights for account");
4344 if (user_rights.count < 1) {
4345 torture_warning(tctx, "failed to find newly added rights");
4351 struct lsa_OpenAccount r;
4353 torture_comment(tctx, "Testing LSA OpenAccount\n");
4355 r.in.handle = lsa_handle;
4356 r.in.sid = user_sid;
4357 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4358 r.out.acct_handle = &lsa_acct_handle;
4360 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
4361 torture_assert_ntstatus_ok(tctx, status,
4362 "Failed to open lsa account");
4366 struct lsa_GetSystemAccessAccount r;
4367 uint32_t access_mask;
4369 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4371 r.in.handle = &lsa_acct_handle;
4372 r.out.access_mask = &access_mask;
4374 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
4375 torture_assert_ntstatus_ok(tctx, status,
4376 "Failed to get lsa system access account");
4380 struct lsa_DeleteObject r;
4382 torture_comment(tctx, "Testing LSA DeleteObject\n");
4384 r.in.handle = &lsa_acct_handle;
4385 r.out.handle = &lsa_acct_handle;
4387 status = dcerpc_lsa_DeleteObject(lp, tctx, &r);
4388 torture_assert_ntstatus_ok(tctx, status,
4389 "Failed to delete object");
4393 struct lsa_EnumAccounts r;
4394 uint32_t resume_handle = 0;
4395 struct lsa_SidArray lsa_sid_array;
4397 bool found_sid = false;
4399 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4401 r.in.handle = lsa_handle;
4402 r.in.num_entries = 0x1000;
4403 r.in.resume_handle = &resume_handle;
4404 r.out.sids = &lsa_sid_array;
4405 r.out.resume_handle = &resume_handle;
4407 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
4408 torture_assert_ntstatus_ok(tctx, status,
4409 "Failed to enum accounts");
4411 for (i=0; i < lsa_sid_array.num_sids; i++) {
4412 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4417 torture_assert(tctx, !found_sid,
4418 "should not have listed privileged account");
4422 struct lsa_EnumAccountRights r;
4423 struct lsa_RightSet user_rights;
4425 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4427 r.in.handle = lsa_handle;
4428 r.in.sid = user_sid;
4429 r.out.rights = &user_rights;
4431 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
4432 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4433 "Failed to enum rights for account");
4439 static bool test_user_ops(struct dcerpc_pipe *p,
4440 struct torture_context *tctx,
4441 struct policy_handle *user_handle,
4442 struct policy_handle *domain_handle,
4443 const struct dom_sid *domain_sid,
4444 uint32_t base_acct_flags,
4445 const char *base_acct_name, enum torture_samr_choice which_ops,
4446 struct cli_credentials *machine_credentials)
4448 char *password = NULL;
4449 struct samr_QueryUserInfo q;
4450 union samr_UserInfo *info;
4456 const uint32_t password_fields[] = {
4457 SAMR_FIELD_NT_PASSWORD_PRESENT,
4458 SAMR_FIELD_LM_PASSWORD_PRESENT,
4459 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
4463 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
4464 if (!NT_STATUS_IS_OK(status)) {
4468 switch (which_ops) {
4469 case TORTURE_SAMR_USER_ATTRIBUTES:
4470 if (!test_QuerySecurity(p, tctx, user_handle)) {
4474 if (!test_QueryUserInfo(p, tctx, user_handle)) {
4478 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
4482 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
4487 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
4491 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
4495 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
4499 case TORTURE_SAMR_PASSWORDS:
4500 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
4501 char simple_pass[9];
4502 char *v = generate_random_str(tctx, 1);
4504 ZERO_STRUCT(simple_pass);
4505 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4507 torture_comment(tctx, "Testing machine account password policy rules\n");
4509 /* Workstation trust accounts don't seem to need to honour password quality policy */
4510 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4514 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
4518 /* reset again, to allow another 'user' password change */
4519 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4523 /* Try a 'short' password */
4524 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
4528 /* Try a compleatly random password */
4529 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
4534 for (i = 0; password_fields[i]; i++) {
4535 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
4539 /* check it was set right */
4540 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4545 for (i = 0; password_fields[i]; i++) {
4546 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
4550 /* check it was set right */
4551 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4556 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
4560 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
4564 if (torture_setting_bool(tctx, "samba4", false)) {
4565 torture_comment(tctx, "skipping Set Password level 18 and 21 against Samba4\n");
4568 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
4572 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4576 for (i = 0; password_fields[i]; i++) {
4578 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
4579 /* we need to skip as that would break
4580 * the ChangePasswordUser3 verify */
4584 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
4588 /* check it was set right */
4589 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4595 q.in.user_handle = user_handle;
4599 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4600 if (!NT_STATUS_IS_OK(status)) {
4601 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4602 q.in.level, nt_errstr(status));
4605 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4606 if ((info->info5.acct_flags) != expected_flags) {
4607 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4608 info->info5.acct_flags,
4611 if (!torture_setting_bool(tctx, "samba3", false)) {
4615 if (info->info5.rid != rid) {
4616 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
4617 info->info5.rid, rid);
4624 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
4626 /* test last password change timestamp behaviour */
4627 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
4629 user_handle, &password,
4630 machine_credentials)) {
4635 torture_comment(tctx, "pwdLastSet test succeeded\n");
4637 torture_warning(tctx, "pwdLastSet test failed\n");
4642 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
4644 /* test bad pwd count change behaviour */
4645 if (!test_Password_badpwdcount_wrap(p, tctx, base_acct_flags,
4648 user_handle, &password,
4649 machine_credentials)) {
4654 torture_comment(tctx, "badPwdCount test succeeded\n");
4656 torture_warning(tctx, "badPwdCount test failed\n");
4661 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
4663 if (!test_Password_lockout_wrap(p, tctx, base_acct_flags,
4666 user_handle, &password,
4667 machine_credentials))
4673 torture_comment(tctx, "lockout test succeeded\n");
4675 torture_warning(tctx, "lockout test failed\n");
4681 case TORTURE_SAMR_USER_PRIVILEGES: {
4683 struct dcerpc_pipe *lp;
4684 struct policy_handle *lsa_handle;
4686 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
4687 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
4689 if (!test_lsa_OpenPolicy2(lp, tctx, &lsa_handle)) {
4693 if (!test_DeleteUser_with_privs(p, lp, tctx,
4694 domain_handle, lsa_handle, user_handle,
4696 machine_credentials)) {
4700 if (!test_lsa_Close(lp, tctx, lsa_handle)) {
4705 torture_warning(tctx, "privileged user delete test failed\n");
4710 case TORTURE_SAMR_OTHER:
4711 /* We just need the account to exist */
4717 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
4718 struct policy_handle *alias_handle,
4719 const struct dom_sid *domain_sid)
4723 if (!torture_setting_bool(tctx, "samba3", false)) {
4724 if (!test_QuerySecurity(p, tctx, alias_handle)) {
4729 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
4733 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
4737 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
4741 if (torture_setting_bool(tctx, "samba3", false) ||
4742 torture_setting_bool(tctx, "samba4", false)) {
4743 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
4747 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
4755 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
4756 struct policy_handle *user_handle)
4758 struct samr_DeleteUser d;
4760 torture_comment(tctx, "Testing DeleteUser\n");
4762 d.in.user_handle = user_handle;
4763 d.out.user_handle = user_handle;
4765 status = dcerpc_samr_DeleteUser(p, tctx, &d);
4766 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
4771 bool test_DeleteUser_byname(struct dcerpc_pipe *p,
4772 struct torture_context *tctx,
4773 struct policy_handle *handle, const char *name)
4776 struct samr_DeleteUser d;
4777 struct policy_handle user_handle;
4780 status = test_LookupName(p, tctx, handle, name, &rid);
4781 if (!NT_STATUS_IS_OK(status)) {
4785 status = test_OpenUser_byname(p, tctx, handle, name, &user_handle);
4786 if (!NT_STATUS_IS_OK(status)) {
4790 d.in.user_handle = &user_handle;
4791 d.out.user_handle = &user_handle;
4792 status = dcerpc_samr_DeleteUser(p, tctx, &d);
4793 if (!NT_STATUS_IS_OK(status)) {
4800 torture_warning(tctx, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
4805 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p,
4806 struct torture_context *tctx,
4807 struct policy_handle *handle, const char *name)
4810 struct samr_OpenGroup r;
4811 struct samr_DeleteDomainGroup d;
4812 struct policy_handle group_handle;
4815 status = test_LookupName(p, tctx, handle, name, &rid);
4816 if (!NT_STATUS_IS_OK(status)) {
4820 r.in.domain_handle = handle;
4821 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4823 r.out.group_handle = &group_handle;
4824 status = dcerpc_samr_OpenGroup(p, tctx, &r);
4825 if (!NT_STATUS_IS_OK(status)) {
4829 d.in.group_handle = &group_handle;
4830 d.out.group_handle = &group_handle;
4831 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
4832 if (!NT_STATUS_IS_OK(status)) {
4839 torture_warning(tctx, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
4844 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p,
4845 struct torture_context *tctx,
4846 struct policy_handle *domain_handle,
4850 struct samr_OpenAlias r;
4851 struct samr_DeleteDomAlias d;
4852 struct policy_handle alias_handle;
4855 torture_comment(tctx, "testing DeleteAlias_byname\n");
4857 status = test_LookupName(p, tctx, domain_handle, name, &rid);
4858 if (!NT_STATUS_IS_OK(status)) {
4862 r.in.domain_handle = domain_handle;
4863 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4865 r.out.alias_handle = &alias_handle;
4866 status = dcerpc_samr_OpenAlias(p, tctx, &r);
4867 if (!NT_STATUS_IS_OK(status)) {
4871 d.in.alias_handle = &alias_handle;
4872 d.out.alias_handle = &alias_handle;
4873 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
4874 if (!NT_STATUS_IS_OK(status)) {
4881 torture_warning(tctx, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
4885 static bool test_DeleteAlias(struct dcerpc_pipe *p,
4886 struct torture_context *tctx,
4887 struct policy_handle *alias_handle)
4889 struct samr_DeleteDomAlias d;
4893 torture_comment(tctx, "Testing DeleteAlias\n");
4895 d.in.alias_handle = alias_handle;
4896 d.out.alias_handle = alias_handle;
4898 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
4899 if (!NT_STATUS_IS_OK(status)) {
4900 torture_warning(tctx, "DeleteAlias failed - %s\n", nt_errstr(status));
4907 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4908 struct policy_handle *domain_handle,
4909 const char *alias_name,
4910 struct policy_handle *alias_handle,
4911 const struct dom_sid *domain_sid,
4915 struct samr_CreateDomAlias r;
4916 struct lsa_String name;
4920 init_lsa_String(&name, alias_name);
4921 r.in.domain_handle = domain_handle;
4922 r.in.alias_name = &name;
4923 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4924 r.out.alias_handle = alias_handle;
4927 torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
4929 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4931 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4932 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4933 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
4936 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
4942 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
4943 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
4946 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4949 if (!NT_STATUS_IS_OK(status)) {
4950 torture_warning(tctx, "CreateAlias failed - %s\n", nt_errstr(status));
4958 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
4965 static bool test_ChangePassword(struct dcerpc_pipe *p,
4966 struct torture_context *tctx,
4967 const char *acct_name,
4968 struct policy_handle *domain_handle, char **password)
4976 if (!test_ChangePasswordUser(p, tctx, acct_name, domain_handle, password)) {
4980 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
4984 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
4988 /* test what happens when setting the old password again */
4989 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
4994 char simple_pass[9];
4995 char *v = generate_random_str(tctx, 1);
4997 ZERO_STRUCT(simple_pass);
4998 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5000 /* test what happens when picking a simple password */
5001 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
5006 /* set samr_SetDomainInfo level 1 with min_length 5 */
5008 struct samr_QueryDomainInfo r;
5009 union samr_DomainInfo *info = NULL;
5010 struct samr_SetDomainInfo s;
5011 uint16_t len_old, len;
5012 uint32_t pwd_prop_old;
5013 int64_t min_pwd_age_old;
5018 r.in.domain_handle = domain_handle;
5022 torture_comment(tctx, "testing samr_QueryDomainInfo level 1\n");
5023 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5024 if (!NT_STATUS_IS_OK(status)) {
5028 s.in.domain_handle = domain_handle;
5032 /* remember the old min length, so we can reset it */
5033 len_old = s.in.info->info1.min_password_length;
5034 s.in.info->info1.min_password_length = len;
5035 pwd_prop_old = s.in.info->info1.password_properties;
5036 /* turn off password complexity checks for this test */
5037 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
5039 min_pwd_age_old = s.in.info->info1.min_password_age;
5040 s.in.info->info1.min_password_age = 0;
5042 torture_comment(tctx, "testing samr_SetDomainInfo level 1\n");
5043 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5044 if (!NT_STATUS_IS_OK(status)) {
5048 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
5050 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
5054 s.in.info->info1.min_password_length = len_old;
5055 s.in.info->info1.password_properties = pwd_prop_old;
5056 s.in.info->info1.min_password_age = min_pwd_age_old;
5058 torture_comment(tctx, "testing samr_SetDomainInfo level 1\n");
5059 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5060 if (!NT_STATUS_IS_OK(status)) {
5068 struct samr_OpenUser r;
5069 struct samr_QueryUserInfo q;
5070 union samr_UserInfo *info;
5071 struct samr_LookupNames n;
5072 struct policy_handle user_handle;
5073 struct samr_Ids rids, types;
5075 n.in.domain_handle = domain_handle;
5077 n.in.names = talloc_array(tctx, struct lsa_String, 1);
5078 n.in.names[0].string = acct_name;
5080 n.out.types = &types;
5082 status = dcerpc_samr_LookupNames(p, tctx, &n);
5083 if (!NT_STATUS_IS_OK(status)) {
5084 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(status));
5088 r.in.domain_handle = domain_handle;
5089 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5090 r.in.rid = n.out.rids->ids[0];
5091 r.out.user_handle = &user_handle;
5093 status = dcerpc_samr_OpenUser(p, tctx, &r);
5094 if (!NT_STATUS_IS_OK(status)) {
5095 torture_warning(tctx, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
5099 q.in.user_handle = &user_handle;
5103 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
5104 if (!NT_STATUS_IS_OK(status)) {
5105 torture_warning(tctx, "QueryUserInfo failed - %s\n", nt_errstr(status));
5109 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
5111 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
5112 info->info5.last_password_change, true)) {
5117 /* we change passwords twice - this has the effect of verifying
5118 they were changed correctly for the final call */
5119 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5123 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5130 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
5131 struct policy_handle *domain_handle,
5132 const char *user_name,
5133 struct policy_handle *user_handle_out,
5134 struct dom_sid *domain_sid,
5135 enum torture_samr_choice which_ops,
5136 struct cli_credentials *machine_credentials,
5140 TALLOC_CTX *user_ctx;
5143 struct samr_CreateUser r;
5144 struct samr_QueryUserInfo q;
5145 union samr_UserInfo *info;
5146 struct samr_DeleteUser d;
5149 /* This call creates a 'normal' account - check that it really does */
5150 const uint32_t acct_flags = ACB_NORMAL;
5151 struct lsa_String name;
5154 struct policy_handle user_handle;
5155 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5156 init_lsa_String(&name, user_name);
5158 r.in.domain_handle = domain_handle;
5159 r.in.account_name = &name;
5160 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5161 r.out.user_handle = &user_handle;
5164 torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
5166 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
5168 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5169 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
5170 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5173 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5179 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5180 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
5181 talloc_free(user_ctx);
5184 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
5187 if (!NT_STATUS_IS_OK(status)) {
5188 talloc_free(user_ctx);
5189 torture_warning(tctx, "CreateUser failed - %s\n", nt_errstr(status));
5194 if (user_handle_out) {
5195 *user_handle_out = user_handle;
5201 q.in.user_handle = &user_handle;
5205 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
5206 if (!NT_STATUS_IS_OK(status)) {
5207 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5208 q.in.level, nt_errstr(status));
5211 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
5212 torture_warning(tctx, "QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5213 info->info16.acct_flags,
5219 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5220 domain_sid, acct_flags, name.string, which_ops,
5221 machine_credentials)) {
5225 if (user_handle_out) {
5226 *user_handle_out = user_handle;
5228 torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
5230 d.in.user_handle = &user_handle;
5231 d.out.user_handle = &user_handle;
5233 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
5234 if (!NT_STATUS_IS_OK(status)) {
5235 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(status));
5242 talloc_free(user_ctx);
5248 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
5249 struct policy_handle *domain_handle,
5250 struct dom_sid *domain_sid,
5251 enum torture_samr_choice which_ops,
5252 struct cli_credentials *machine_credentials)
5255 struct samr_CreateUser2 r;
5256 struct samr_QueryUserInfo q;
5257 union samr_UserInfo *info;
5258 struct samr_DeleteUser d;
5259 struct policy_handle user_handle;
5261 struct lsa_String name;
5266 uint32_t acct_flags;
5267 const char *account_name;
5269 } account_types[] = {
5270 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
5271 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5272 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5273 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5274 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5275 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5276 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5277 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5278 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5279 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
5280 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5281 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5282 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5283 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5284 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
5287 for (i = 0; account_types[i].account_name; i++) {
5288 TALLOC_CTX *user_ctx;
5289 uint32_t acct_flags = account_types[i].acct_flags;
5290 uint32_t access_granted;
5291 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5292 init_lsa_String(&name, account_types[i].account_name);
5294 r.in.domain_handle = domain_handle;
5295 r.in.account_name = &name;
5296 r.in.acct_flags = acct_flags;
5297 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5298 r.out.user_handle = &user_handle;
5299 r.out.access_granted = &access_granted;
5302 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
5304 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
5306 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5307 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
5308 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5311 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5318 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5319 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
5320 talloc_free(user_ctx);
5324 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
5327 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
5328 torture_warning(tctx, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5329 nt_errstr(status), nt_errstr(account_types[i].nt_status));
5333 if (NT_STATUS_IS_OK(status)) {
5334 q.in.user_handle = &user_handle;
5338 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
5339 if (!NT_STATUS_IS_OK(status)) {
5340 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5341 q.in.level, nt_errstr(status));
5344 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
5345 if (acct_flags == ACB_NORMAL) {
5346 expected_flags |= ACB_PW_EXPIRED;
5348 if ((info->info5.acct_flags) != expected_flags) {
5349 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5350 info->info5.acct_flags,
5354 switch (acct_flags) {
5356 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
5357 torture_warning(tctx, "QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5358 DOMAIN_RID_DCS, info->info5.primary_gid);
5363 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
5364 torture_warning(tctx, "QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5365 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
5370 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
5371 torture_warning(tctx, "QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5372 DOMAIN_RID_USERS, info->info5.primary_gid);
5379 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5380 domain_sid, acct_flags, name.string, which_ops,
5381 machine_credentials)) {
5385 if (!policy_handle_empty(&user_handle)) {
5386 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
5388 d.in.user_handle = &user_handle;
5389 d.out.user_handle = &user_handle;
5391 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
5392 if (!NT_STATUS_IS_OK(status)) {
5393 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(status));
5398 talloc_free(user_ctx);
5404 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
5405 struct torture_context *tctx,
5406 struct policy_handle *handle)
5409 struct samr_QueryAliasInfo r;
5410 union samr_AliasInfo *info;
5411 uint16_t levels[] = {1, 2, 3};
5415 for (i=0;i<ARRAY_SIZE(levels);i++) {
5416 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
5418 r.in.alias_handle = handle;
5419 r.in.level = levels[i];
5422 status = dcerpc_samr_QueryAliasInfo(p, tctx, &r);
5423 if (!NT_STATUS_IS_OK(status)) {
5424 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
5425 levels[i], nt_errstr(status));
5433 static bool test_QueryGroupInfo(struct dcerpc_pipe *p,
5434 struct torture_context *tctx,
5435 struct policy_handle *handle)
5438 struct samr_QueryGroupInfo r;
5439 union samr_GroupInfo *info;
5440 uint16_t levels[] = {1, 2, 3, 4, 5};
5444 for (i=0;i<ARRAY_SIZE(levels);i++) {
5445 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5447 r.in.group_handle = handle;
5448 r.in.level = levels[i];
5451 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
5452 if (!NT_STATUS_IS_OK(status)) {
5453 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5454 levels[i], nt_errstr(status));
5462 static bool test_QueryGroupMember(struct dcerpc_pipe *p,
5463 struct torture_context *tctx,
5464 struct policy_handle *handle)
5467 struct samr_QueryGroupMember r;
5468 struct samr_RidTypeArray *rids = NULL;
5471 torture_comment(tctx, "Testing QueryGroupMember\n");
5473 r.in.group_handle = handle;
5476 status = dcerpc_samr_QueryGroupMember(p, tctx, &r);
5477 if (!NT_STATUS_IS_OK(status)) {
5478 torture_warning(tctx, "QueryGroupInfo failed - %s\n", nt_errstr(status));
5486 static bool test_SetGroupInfo(struct dcerpc_pipe *p,
5487 struct torture_context *tctx,
5488 struct policy_handle *handle)
5491 struct samr_QueryGroupInfo r;
5492 union samr_GroupInfo *info;
5493 struct samr_SetGroupInfo s;
5494 uint16_t levels[] = {1, 2, 3, 4};
5495 uint16_t set_ok[] = {0, 1, 1, 1};
5499 for (i=0;i<ARRAY_SIZE(levels);i++) {
5500 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5502 r.in.group_handle = handle;
5503 r.in.level = levels[i];
5506 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
5507 if (!NT_STATUS_IS_OK(status)) {
5508 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5509 levels[i], nt_errstr(status));
5513 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
5515 s.in.group_handle = handle;
5516 s.in.level = levels[i];
5517 s.in.info = *r.out.info;
5520 /* disabled this, as it changes the name only from the point of view of samr,
5521 but leaves the name from the point of view of w2k3 internals (and ldap). This means
5522 the name is still reserved, so creating the old name fails, but deleting by the old name
5524 if (s.in.level == 2) {
5525 init_lsa_String(&s.in.info->string, "NewName");
5529 if (s.in.level == 4) {
5530 init_lsa_String(&s.in.info->description, "test description");
5533 status = dcerpc_samr_SetGroupInfo(p, tctx, &s);
5535 if (!NT_STATUS_IS_OK(status)) {
5536 torture_warning(tctx, "SetGroupInfo level %u failed - %s\n",
5537 r.in.level, nt_errstr(status));
5542 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5543 torture_warning(tctx, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5544 r.in.level, nt_errstr(status));
5554 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
5555 struct torture_context *tctx,
5556 struct policy_handle *handle)
5559 struct samr_QueryUserInfo r;
5560 union samr_UserInfo *info;
5561 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5562 11, 12, 13, 14, 16, 17, 20, 21};
5566 for (i=0;i<ARRAY_SIZE(levels);i++) {
5567 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
5569 r.in.user_handle = handle;
5570 r.in.level = levels[i];
5573 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
5574 if (!NT_STATUS_IS_OK(status)) {
5575 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5576 levels[i], nt_errstr(status));
5584 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
5585 struct torture_context *tctx,
5586 struct policy_handle *handle)
5589 struct samr_QueryUserInfo2 r;
5590 union samr_UserInfo *info;
5591 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5592 11, 12, 13, 14, 16, 17, 20, 21};
5596 for (i=0;i<ARRAY_SIZE(levels);i++) {
5597 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
5599 r.in.user_handle = handle;
5600 r.in.level = levels[i];
5603 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r);
5604 if (!NT_STATUS_IS_OK(status)) {
5605 torture_warning(tctx, "QueryUserInfo2 level %u failed - %s\n",
5606 levels[i], nt_errstr(status));
5614 static bool test_OpenUser(struct dcerpc_pipe *p,
5615 struct torture_context *tctx,
5616 struct policy_handle *handle, uint32_t rid)
5619 struct samr_OpenUser r;
5620 struct policy_handle user_handle;
5623 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5625 r.in.domain_handle = handle;
5626 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5628 r.out.user_handle = &user_handle;
5630 status = dcerpc_samr_OpenUser(p, tctx, &r);
5631 if (!NT_STATUS_IS_OK(status)) {
5632 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
5636 if (!test_QuerySecurity(p, tctx, &user_handle)) {
5640 if (!test_QueryUserInfo(p, tctx, &user_handle)) {
5644 if (!test_QueryUserInfo2(p, tctx, &user_handle)) {
5648 if (!test_GetUserPwInfo(p, tctx, &user_handle)) {
5652 if (!test_GetGroupsForUser(p,tctx, &user_handle)) {
5656 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
5663 static bool test_OpenGroup(struct dcerpc_pipe *p,
5664 struct torture_context *tctx,
5665 struct policy_handle *handle, uint32_t rid)
5668 struct samr_OpenGroup r;
5669 struct policy_handle group_handle;
5672 torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
5674 r.in.domain_handle = handle;
5675 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5677 r.out.group_handle = &group_handle;
5679 status = dcerpc_samr_OpenGroup(p, tctx, &r);
5680 if (!NT_STATUS_IS_OK(status)) {
5681 torture_warning(tctx, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
5685 if (!torture_setting_bool(tctx, "samba3", false)) {
5686 if (!test_QuerySecurity(p, tctx, &group_handle)) {
5691 if (!test_QueryGroupInfo(p, tctx, &group_handle)) {
5695 if (!test_QueryGroupMember(p, tctx, &group_handle)) {
5699 if (!test_samr_handle_Close(p, tctx, &group_handle)) {
5706 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
5707 struct policy_handle *handle, uint32_t rid)
5710 struct samr_OpenAlias r;
5711 struct policy_handle alias_handle;
5714 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
5716 r.in.domain_handle = handle;
5717 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5719 r.out.alias_handle = &alias_handle;
5721 status = dcerpc_samr_OpenAlias(p, tctx, &r);
5722 if (!NT_STATUS_IS_OK(status)) {
5723 torture_warning(tctx, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
5727 if (!torture_setting_bool(tctx, "samba3", false)) {
5728 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
5733 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
5737 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
5741 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
5748 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
5749 struct policy_handle *handle, uint32_t rid,
5750 uint32_t acct_flag_mask)
5753 struct samr_OpenUser r;
5754 struct samr_QueryUserInfo q;
5755 union samr_UserInfo *info;
5756 struct policy_handle user_handle;
5759 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5761 r.in.domain_handle = handle;
5762 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5764 r.out.user_handle = &user_handle;
5766 status = dcerpc_samr_OpenUser(p, tctx, &r);
5767 if (!NT_STATUS_IS_OK(status)) {
5768 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
5772 q.in.user_handle = &user_handle;
5776 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
5777 if (!NT_STATUS_IS_OK(status)) {
5778 torture_warning(tctx, "QueryUserInfo level 16 failed - %s\n",
5782 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
5783 torture_warning(tctx, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
5784 acct_flag_mask, info->info16.acct_flags, rid);
5789 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
5796 static bool test_EnumDomainUsers_all(struct dcerpc_pipe *p,
5797 struct torture_context *tctx,
5798 struct policy_handle *handle)
5800 NTSTATUS status = STATUS_MORE_ENTRIES;
5801 struct samr_EnumDomainUsers r;
5802 uint32_t mask, resume_handle=0;
5805 struct samr_LookupNames n;
5806 struct samr_LookupRids lr ;
5807 struct lsa_Strings names;
5808 struct samr_Ids rids, types;
5809 struct samr_SamArray *sam = NULL;
5810 uint32_t num_entries = 0;
5812 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
5813 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
5814 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
5817 torture_comment(tctx, "Testing EnumDomainUsers\n");
5819 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
5820 r.in.domain_handle = handle;
5821 r.in.resume_handle = &resume_handle;
5822 r.in.acct_flags = mask = masks[mask_idx];
5823 r.in.max_size = (uint32_t)-1;
5824 r.out.resume_handle = &resume_handle;
5825 r.out.num_entries = &num_entries;
5828 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
5829 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5830 !NT_STATUS_IS_OK(status)) {
5831 torture_warning(tctx, "EnumDomainUsers failed - %s\n", nt_errstr(status));
5835 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
5837 if (sam->count == 0) {
5841 for (i=0;i<sam->count;i++) {
5843 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
5846 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
5852 torture_comment(tctx, "Testing LookupNames\n");
5853 n.in.domain_handle = handle;
5854 n.in.num_names = sam->count;
5855 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
5857 n.out.types = &types;
5858 for (i=0;i<sam->count;i++) {
5859 n.in.names[i].string = sam->entries[i].name.string;
5861 status = dcerpc_samr_LookupNames(p, tctx, &n);
5862 if (!NT_STATUS_IS_OK(status)) {
5863 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(status));
5868 torture_comment(tctx, "Testing LookupRids\n");
5869 lr.in.domain_handle = handle;
5870 lr.in.num_rids = sam->count;
5871 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
5872 lr.out.names = &names;
5873 lr.out.types = &types;
5874 for (i=0;i<sam->count;i++) {
5875 lr.in.rids[i] = sam->entries[i].idx;
5877 status = dcerpc_samr_LookupRids(p, tctx, &lr);
5878 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
5884 try blasting the server with a bunch of sync requests
5886 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
5887 struct policy_handle *handle)
5890 struct samr_EnumDomainUsers r;
5891 uint32_t resume_handle=0;
5893 #define ASYNC_COUNT 100
5894 struct rpc_request *req[ASYNC_COUNT];
5896 if (!torture_setting_bool(tctx, "dangerous", false)) {
5897 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
5900 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
5902 r.in.domain_handle = handle;
5903 r.in.resume_handle = &resume_handle;
5904 r.in.acct_flags = 0;
5905 r.in.max_size = (uint32_t)-1;
5906 r.out.resume_handle = &resume_handle;
5908 for (i=0;i<ASYNC_COUNT;i++) {
5909 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
5912 for (i=0;i<ASYNC_COUNT;i++) {
5913 status = dcerpc_ndr_request_recv(req[i]);
5914 if (!NT_STATUS_IS_OK(status)) {
5915 torture_warning(tctx, "EnumDomainUsers[%d] failed - %s\n",
5916 i, nt_errstr(status));
5921 torture_comment(tctx, "%d async requests OK\n", i);
5926 static bool test_EnumDomainGroups_all(struct dcerpc_pipe *p,
5927 struct torture_context *tctx,
5928 struct policy_handle *handle)
5931 struct samr_EnumDomainGroups r;
5932 uint32_t resume_handle=0;
5933 struct samr_SamArray *sam = NULL;
5934 uint32_t num_entries = 0;
5938 torture_comment(tctx, "Testing EnumDomainGroups\n");
5940 r.in.domain_handle = handle;
5941 r.in.resume_handle = &resume_handle;
5942 r.in.max_size = (uint32_t)-1;
5943 r.out.resume_handle = &resume_handle;
5944 r.out.num_entries = &num_entries;
5947 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
5948 if (!NT_STATUS_IS_OK(status)) {
5949 torture_warning(tctx, "EnumDomainGroups failed - %s\n", nt_errstr(status));
5957 for (i=0;i<sam->count;i++) {
5958 if (!test_OpenGroup(p, tctx, handle, sam->entries[i].idx)) {
5966 static bool test_EnumDomainAliases_all(struct dcerpc_pipe *p,
5967 struct torture_context *tctx,
5968 struct policy_handle *handle)
5971 struct samr_EnumDomainAliases r;
5972 uint32_t resume_handle=0;
5973 struct samr_SamArray *sam = NULL;
5974 uint32_t num_entries = 0;
5978 torture_comment(tctx, "Testing EnumDomainAliases\n");
5980 r.in.domain_handle = handle;
5981 r.in.resume_handle = &resume_handle;
5982 r.in.max_size = (uint32_t)-1;
5984 r.out.num_entries = &num_entries;
5985 r.out.resume_handle = &resume_handle;
5987 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
5988 if (!NT_STATUS_IS_OK(status)) {
5989 torture_warning(tctx, "EnumDomainAliases failed - %s\n", nt_errstr(status));
5997 for (i=0;i<sam->count;i++) {
5998 if (!test_OpenAlias(p, tctx, handle, sam->entries[i].idx)) {
6006 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p,
6007 struct torture_context *tctx,
6008 struct policy_handle *handle)
6011 struct samr_GetDisplayEnumerationIndex r;
6013 uint16_t levels[] = {1, 2, 3, 4, 5};
6014 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6015 struct lsa_String name;
6019 for (i=0;i<ARRAY_SIZE(levels);i++) {
6020 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
6022 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6024 r.in.domain_handle = handle;
6025 r.in.level = levels[i];
6029 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
6032 !NT_STATUS_IS_OK(status) &&
6033 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
6034 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6035 levels[i], nt_errstr(status));
6039 init_lsa_String(&name, "zzzzzzzz");
6041 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
6043 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
6044 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6045 levels[i], nt_errstr(status));
6053 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p,
6054 struct torture_context *tctx,
6055 struct policy_handle *handle)
6058 struct samr_GetDisplayEnumerationIndex2 r;
6060 uint16_t levels[] = {1, 2, 3, 4, 5};
6061 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6062 struct lsa_String name;
6066 for (i=0;i<ARRAY_SIZE(levels);i++) {
6067 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
6069 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6071 r.in.domain_handle = handle;
6072 r.in.level = levels[i];
6076 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
6078 !NT_STATUS_IS_OK(status) &&
6079 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
6080 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6081 levels[i], nt_errstr(status));
6085 init_lsa_String(&name, "zzzzzzzz");
6087 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
6088 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
6089 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6090 levels[i], nt_errstr(status));
6098 #define STRING_EQUAL_QUERY(s1, s2, user) \
6099 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6100 /* odd, but valid */ \
6101 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6102 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
6103 #s1, user.string, s1.string, s2.string, __location__); \
6106 #define INT_EQUAL_QUERY(s1, s2, user) \
6108 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6109 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6113 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p,
6114 struct torture_context *tctx,
6115 struct samr_QueryDisplayInfo *querydisplayinfo,
6116 bool *seen_testuser)
6118 struct samr_OpenUser r;
6119 struct samr_QueryUserInfo q;
6120 union samr_UserInfo *info;
6121 struct policy_handle user_handle;
6124 r.in.domain_handle = querydisplayinfo->in.domain_handle;
6125 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6126 for (i = 0; ; i++) {
6127 switch (querydisplayinfo->in.level) {
6129 if (i >= querydisplayinfo->out.info->info1.count) {
6132 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
6135 if (i >= querydisplayinfo->out.info->info2.count) {
6138 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
6144 /* Not interested in validating just the account name */
6148 r.out.user_handle = &user_handle;
6150 switch (querydisplayinfo->in.level) {
6153 status = dcerpc_samr_OpenUser(p, tctx, &r);
6154 if (!NT_STATUS_IS_OK(status)) {
6155 torture_warning(tctx, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
6160 q.in.user_handle = &user_handle;
6163 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
6164 if (!NT_STATUS_IS_OK(status)) {
6165 torture_warning(tctx, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
6169 switch (querydisplayinfo->in.level) {
6171 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
6172 *seen_testuser = true;
6174 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
6175 info->info21.full_name, info->info21.account_name);
6176 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
6177 info->info21.account_name, info->info21.account_name);
6178 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
6179 info->info21.description, info->info21.account_name);
6180 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
6181 info->info21.rid, info->info21.account_name);
6182 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
6183 info->info21.acct_flags, info->info21.account_name);
6187 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
6188 info->info21.account_name, info->info21.account_name);
6189 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
6190 info->info21.description, info->info21.account_name);
6191 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
6192 info->info21.rid, info->info21.account_name);
6193 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
6194 info->info21.acct_flags, info->info21.account_name);
6196 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
6197 torture_warning(tctx, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6198 info->info21.account_name.string);
6201 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
6202 torture_warning(tctx, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6203 info->info21.account_name.string,
6204 querydisplayinfo->out.info->info2.entries[i].acct_flags,
6205 info->info21.acct_flags);
6212 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
6219 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p,
6220 struct torture_context *tctx,
6221 struct policy_handle *handle)
6224 struct samr_QueryDisplayInfo r;
6225 struct samr_QueryDomainInfo dom_info;
6226 union samr_DomainInfo *info = NULL;
6228 uint16_t levels[] = {1, 2, 3, 4, 5};
6230 bool seen_testuser = false;
6231 uint32_t total_size;
6232 uint32_t returned_size;
6233 union samr_DispInfo disp_info;
6236 for (i=0;i<ARRAY_SIZE(levels);i++) {
6237 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
6240 status = STATUS_MORE_ENTRIES;
6241 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6242 r.in.domain_handle = handle;
6243 r.in.level = levels[i];
6244 r.in.max_entries = 2;
6245 r.in.buf_size = (uint32_t)-1;
6246 r.out.total_size = &total_size;
6247 r.out.returned_size = &returned_size;
6248 r.out.info = &disp_info;
6250 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
6251 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
6252 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6253 levels[i], nt_errstr(status));
6256 switch (r.in.level) {
6258 if (!test_each_DisplayInfo_user(p, tctx, &r, &seen_testuser)) {
6261 r.in.start_idx += r.out.info->info1.count;
6264 if (!test_each_DisplayInfo_user(p, tctx, &r, NULL)) {
6267 r.in.start_idx += r.out.info->info2.count;
6270 r.in.start_idx += r.out.info->info3.count;
6273 r.in.start_idx += r.out.info->info4.count;
6276 r.in.start_idx += r.out.info->info5.count;
6280 dom_info.in.domain_handle = handle;
6281 dom_info.in.level = 2;
6282 dom_info.out.info = &info;
6284 /* Check number of users returned is correct */
6285 status = dcerpc_samr_QueryDomainInfo(p, tctx, &dom_info);
6286 if (!NT_STATUS_IS_OK(status)) {
6287 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6288 r.in.level, nt_errstr(status));
6292 switch (r.in.level) {
6295 if (info->general.num_users < r.in.start_idx) {
6296 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6297 r.in.start_idx, info->general.num_groups,
6298 info->general.domain_name.string);
6301 if (!seen_testuser) {
6302 struct policy_handle user_handle;
6303 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
6304 torture_warning(tctx, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
6305 info->general.domain_name.string);
6307 test_samr_handle_Close(p, tctx, &user_handle);
6313 if (info->general.num_groups != r.in.start_idx) {
6314 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6315 r.in.start_idx, info->general.num_groups,
6316 info->general.domain_name.string);
6328 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p,
6329 struct torture_context *tctx,
6330 struct policy_handle *handle)
6333 struct samr_QueryDisplayInfo2 r;
6335 uint16_t levels[] = {1, 2, 3, 4, 5};
6337 uint32_t total_size;
6338 uint32_t returned_size;
6339 union samr_DispInfo info;
6341 for (i=0;i<ARRAY_SIZE(levels);i++) {
6342 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
6344 r.in.domain_handle = handle;
6345 r.in.level = levels[i];
6347 r.in.max_entries = 1000;
6348 r.in.buf_size = (uint32_t)-1;
6349 r.out.total_size = &total_size;
6350 r.out.returned_size = &returned_size;
6353 status = dcerpc_samr_QueryDisplayInfo2(p, tctx, &r);
6354 if (!NT_STATUS_IS_OK(status)) {
6355 torture_warning(tctx, "QueryDisplayInfo2 level %u failed - %s\n",
6356 levels[i], nt_errstr(status));
6364 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
6365 struct policy_handle *handle)
6368 struct samr_QueryDisplayInfo3 r;
6370 uint16_t levels[] = {1, 2, 3, 4, 5};
6372 uint32_t total_size;
6373 uint32_t returned_size;
6374 union samr_DispInfo info;
6376 for (i=0;i<ARRAY_SIZE(levels);i++) {
6377 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
6379 r.in.domain_handle = handle;
6380 r.in.level = levels[i];
6382 r.in.max_entries = 1000;
6383 r.in.buf_size = (uint32_t)-1;
6384 r.out.total_size = &total_size;
6385 r.out.returned_size = &returned_size;
6388 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
6389 if (!NT_STATUS_IS_OK(status)) {
6390 torture_warning(tctx, "QueryDisplayInfo3 level %u failed - %s\n",
6391 levels[i], nt_errstr(status));
6400 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p,
6401 struct torture_context *tctx,
6402 struct policy_handle *handle)
6405 struct samr_QueryDisplayInfo r;
6407 uint32_t total_size;
6408 uint32_t returned_size;
6409 union samr_DispInfo info;
6411 torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
6413 r.in.domain_handle = handle;
6416 r.in.max_entries = 1;
6417 r.in.buf_size = (uint32_t)-1;
6418 r.out.total_size = &total_size;
6419 r.out.returned_size = &returned_size;
6423 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
6424 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
6425 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
6426 torture_warning(tctx, "expected idx %d but got %d\n",
6428 r.out.info->info1.entries[0].idx);
6432 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
6433 !NT_STATUS_IS_OK(status)) {
6434 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6435 r.in.level, nt_errstr(status));
6440 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
6441 NT_STATUS_IS_OK(status)) &&
6442 *r.out.returned_size != 0);
6447 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
6448 struct policy_handle *handle)
6451 struct samr_QueryDomainInfo r;
6452 union samr_DomainInfo *info = NULL;
6453 struct samr_SetDomainInfo s;
6454 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6455 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
6458 const char *domain_comment = talloc_asprintf(tctx,
6459 "Tortured by Samba4 RPC-SAMR: %s",
6460 timestring(tctx, time(NULL)));
6462 s.in.domain_handle = handle;
6464 s.in.info = talloc(tctx, union samr_DomainInfo);
6466 s.in.info->oem.oem_information.string = domain_comment;
6467 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
6468 if (!NT_STATUS_IS_OK(status)) {
6469 torture_warning(tctx, "SetDomainInfo level %u (set comment) failed - %s\n",
6470 s.in.level, nt_errstr(status));
6474 for (i=0;i<ARRAY_SIZE(levels);i++) {
6475 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
6477 r.in.domain_handle = handle;
6478 r.in.level = levels[i];
6481 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
6482 if (!NT_STATUS_IS_OK(status)) {
6483 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6484 r.in.level, nt_errstr(status));
6489 switch (levels[i]) {
6491 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
6492 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6493 levels[i], info->general.oem_information.string, domain_comment);
6494 if (!torture_setting_bool(tctx, "samba3", false)) {
6498 if (!info->general.primary.string) {
6499 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6502 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
6503 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
6504 torture_warning(tctx, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
6505 levels[i], info->general.primary.string, dcerpc_server_name(p));
6510 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
6511 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6512 levels[i], info->oem.oem_information.string, domain_comment);
6513 if (!torture_setting_bool(tctx, "samba3", false)) {
6519 if (!info->info6.primary.string) {
6520 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6526 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
6527 torture_warning(tctx, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
6528 levels[i], info->general2.general.oem_information.string, domain_comment);
6529 if (!torture_setting_bool(tctx, "samba3", false)) {
6536 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
6538 s.in.domain_handle = handle;
6539 s.in.level = levels[i];
6542 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
6544 if (!NT_STATUS_IS_OK(status)) {
6545 torture_warning(tctx, "SetDomainInfo level %u failed - %s\n",
6546 r.in.level, nt_errstr(status));
6551 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
6552 torture_warning(tctx, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6553 r.in.level, nt_errstr(status));
6559 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
6560 if (!NT_STATUS_IS_OK(status)) {
6561 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6562 r.in.level, nt_errstr(status));
6572 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
6573 struct policy_handle *handle)
6576 struct samr_QueryDomainInfo2 r;
6577 union samr_DomainInfo *info = NULL;
6578 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6582 for (i=0;i<ARRAY_SIZE(levels);i++) {
6583 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
6585 r.in.domain_handle = handle;
6586 r.in.level = levels[i];
6589 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
6590 if (!NT_STATUS_IS_OK(status)) {
6591 torture_warning(tctx, "QueryDomainInfo2 level %u failed - %s\n",
6592 r.in.level, nt_errstr(status));
6601 /* Test whether querydispinfo level 5 and enumdomgroups return the same
6602 set of group names. */
6603 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
6604 struct policy_handle *handle)
6606 struct samr_EnumDomainGroups q1;
6607 struct samr_QueryDisplayInfo q2;
6609 uint32_t resume_handle=0;
6610 struct samr_SamArray *sam = NULL;
6611 uint32_t num_entries = 0;
6614 uint32_t total_size;
6615 uint32_t returned_size;
6616 union samr_DispInfo info;
6619 const char **names = NULL;
6621 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
6623 q1.in.domain_handle = handle;
6624 q1.in.resume_handle = &resume_handle;
6626 q1.out.resume_handle = &resume_handle;
6627 q1.out.num_entries = &num_entries;
6630 status = STATUS_MORE_ENTRIES;
6631 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6632 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
6634 if (!NT_STATUS_IS_OK(status) &&
6635 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6638 for (i=0; i<*q1.out.num_entries; i++) {
6639 add_string_to_array(tctx,
6640 sam->entries[i].name.string,
6641 &names, &num_names);
6645 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
6647 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
6649 q2.in.domain_handle = handle;
6651 q2.in.start_idx = 0;
6652 q2.in.max_entries = 5;
6653 q2.in.buf_size = (uint32_t)-1;
6654 q2.out.total_size = &total_size;
6655 q2.out.returned_size = &returned_size;
6656 q2.out.info = &info;
6658 status = STATUS_MORE_ENTRIES;
6659 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6660 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
6662 if (!NT_STATUS_IS_OK(status) &&
6663 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6666 for (i=0; i<q2.out.info->info5.count; i++) {
6668 const char *name = q2.out.info->info5.entries[i].account_name.string;
6670 for (j=0; j<num_names; j++) {
6671 if (names[j] == NULL)
6673 if (strequal(names[j], name)) {
6681 torture_warning(tctx, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
6686 q2.in.start_idx += q2.out.info->info5.count;
6689 if (!NT_STATUS_IS_OK(status)) {
6690 torture_warning(tctx, "QueryDisplayInfo level 5 failed - %s\n",
6695 for (i=0; i<num_names; i++) {
6696 if (names[i] != NULL) {
6697 torture_warning(tctx, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
6706 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
6707 struct policy_handle *group_handle)
6709 struct samr_DeleteDomainGroup d;
6712 torture_comment(tctx, "Testing DeleteDomainGroup\n");
6714 d.in.group_handle = group_handle;
6715 d.out.group_handle = group_handle;
6717 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
6718 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
6723 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6724 struct policy_handle *domain_handle)
6726 struct samr_TestPrivateFunctionsDomain r;
6730 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
6732 r.in.domain_handle = domain_handle;
6734 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
6735 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
6740 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
6741 struct dom_sid *domain_sid,
6742 struct policy_handle *domain_handle)
6744 struct samr_RidToSid r;
6747 struct dom_sid *calc_sid, *out_sid;
6748 int rids[] = { 0, 42, 512, 10200 };
6751 for (i=0;i<ARRAY_SIZE(rids);i++) {
6752 torture_comment(tctx, "Testing RidToSid\n");
6754 calc_sid = dom_sid_dup(tctx, domain_sid);
6755 r.in.domain_handle = domain_handle;
6757 r.out.sid = &out_sid;
6759 status = dcerpc_samr_RidToSid(p, tctx, &r);
6760 if (!NT_STATUS_IS_OK(status)) {
6761 torture_warning(tctx, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
6764 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
6766 if (!dom_sid_equal(calc_sid, out_sid)) {
6767 torture_warning(tctx, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
6768 dom_sid_string(tctx, out_sid),
6769 dom_sid_string(tctx, calc_sid));
6778 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
6779 struct policy_handle *domain_handle)
6781 struct samr_GetBootKeyInformation r;
6784 uint32_t unknown = 0;
6786 torture_comment(tctx, "Testing GetBootKeyInformation\n");
6788 r.in.domain_handle = domain_handle;
6789 r.out.unknown = &unknown;
6791 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
6792 if (!NT_STATUS_IS_OK(status)) {
6793 /* w2k3 seems to fail this sometimes and pass it sometimes */
6794 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
6800 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
6801 struct policy_handle *domain_handle,
6802 struct policy_handle *group_handle)
6805 struct samr_AddGroupMember r;
6806 struct samr_DeleteGroupMember d;
6807 struct samr_QueryGroupMember q;
6808 struct samr_RidTypeArray *rids = NULL;
6809 struct samr_SetMemberAttributesOfGroup s;
6811 bool found_member = false;
6814 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
6815 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
6817 r.in.group_handle = group_handle;
6819 r.in.flags = 0; /* ??? */
6821 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
6823 d.in.group_handle = group_handle;
6826 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
6827 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
6829 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
6830 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
6832 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
6833 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
6835 if (torture_setting_bool(tctx, "samba4", false) ||
6836 torture_setting_bool(tctx, "samba3", false)) {
6837 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
6839 /* this one is quite strange. I am using random inputs in the
6840 hope of triggering an error that might give us a clue */
6842 s.in.group_handle = group_handle;
6843 s.in.unknown1 = random();
6844 s.in.unknown2 = random();
6846 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
6847 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
6850 q.in.group_handle = group_handle;
6853 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
6854 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
6855 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
6857 for (i=0; i < rids->count; i++) {
6858 if (rids->rids[i] == rid) {
6859 found_member = true;
6863 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
6865 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
6866 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
6869 found_member = false;
6871 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
6872 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
6873 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
6875 for (i=0; i < rids->count; i++) {
6876 if (rids->rids[i] == rid) {
6877 found_member = true;
6881 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
6883 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
6884 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
6890 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
6891 struct torture_context *tctx,
6892 struct policy_handle *domain_handle,
6893 const char *group_name,
6894 struct policy_handle *group_handle,
6895 struct dom_sid *domain_sid,
6899 struct samr_CreateDomainGroup r;
6901 struct lsa_String name;
6904 init_lsa_String(&name, group_name);
6906 r.in.domain_handle = domain_handle;
6908 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6909 r.out.group_handle = group_handle;
6912 torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
6914 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6916 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
6917 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6918 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
6921 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
6927 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
6928 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
6929 torture_warning(tctx, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
6933 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6935 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
6936 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
6938 torture_warning(tctx, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
6942 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6944 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
6950 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
6951 torture_warning(tctx, "CreateDomainGroup failed - %s\n", nt_errstr(status));
6955 if (!test_SetGroupInfo(p, tctx, group_handle)) {
6964 its not totally clear what this does. It seems to accept any sid you like.
6966 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
6967 struct torture_context *tctx,
6968 struct policy_handle *domain_handle)
6971 struct samr_RemoveMemberFromForeignDomain r;
6973 r.in.domain_handle = domain_handle;
6974 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
6976 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
6977 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
6982 static bool test_EnumDomainUsers(struct dcerpc_pipe *p,
6983 struct torture_context *tctx,
6984 struct policy_handle *domain_handle,
6985 uint32_t *total_num_entries_p)
6988 struct samr_EnumDomainUsers r;
6989 uint32_t resume_handle = 0;
6990 uint32_t num_entries = 0;
6991 uint32_t total_num_entries = 0;
6992 struct samr_SamArray *sam;
6994 r.in.domain_handle = domain_handle;
6995 r.in.acct_flags = 0;
6996 r.in.max_size = (uint32_t)-1;
6997 r.in.resume_handle = &resume_handle;
7000 r.out.num_entries = &num_entries;
7001 r.out.resume_handle = &resume_handle;
7003 torture_comment(tctx, "Testing EnumDomainUsers\n");
7006 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
7007 if (NT_STATUS_IS_ERR(status)) {
7008 torture_assert_ntstatus_ok(tctx, status,
7009 "failed to enumerate users");
7012 total_num_entries += num_entries;
7013 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7015 if (total_num_entries_p) {
7016 *total_num_entries_p = total_num_entries;
7022 static bool test_EnumDomainGroups(struct dcerpc_pipe *p,
7023 struct torture_context *tctx,
7024 struct policy_handle *domain_handle,
7025 uint32_t *total_num_entries_p)
7028 struct samr_EnumDomainGroups r;
7029 uint32_t resume_handle = 0;
7030 uint32_t num_entries = 0;
7031 uint32_t total_num_entries = 0;
7032 struct samr_SamArray *sam;
7034 r.in.domain_handle = domain_handle;
7035 r.in.max_size = (uint32_t)-1;
7036 r.in.resume_handle = &resume_handle;
7039 r.out.num_entries = &num_entries;
7040 r.out.resume_handle = &resume_handle;
7042 torture_comment(tctx, "Testing EnumDomainGroups\n");
7045 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
7046 if (NT_STATUS_IS_ERR(status)) {
7047 torture_assert_ntstatus_ok(tctx, status,
7048 "failed to enumerate groups");
7051 total_num_entries += num_entries;
7052 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7054 if (total_num_entries_p) {
7055 *total_num_entries_p = total_num_entries;
7061 static bool test_EnumDomainAliases(struct dcerpc_pipe *p,
7062 struct torture_context *tctx,
7063 struct policy_handle *domain_handle,
7064 uint32_t *total_num_entries_p)
7067 struct samr_EnumDomainAliases r;
7068 uint32_t resume_handle = 0;
7069 uint32_t num_entries = 0;
7070 uint32_t total_num_entries = 0;
7071 struct samr_SamArray *sam;
7073 r.in.domain_handle = domain_handle;
7074 r.in.max_size = (uint32_t)-1;
7075 r.in.resume_handle = &resume_handle;
7078 r.out.num_entries = &num_entries;
7079 r.out.resume_handle = &resume_handle;
7081 torture_comment(tctx, "Testing EnumDomainAliases\n");
7084 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
7085 if (NT_STATUS_IS_ERR(status)) {
7086 torture_assert_ntstatus_ok(tctx, status,
7087 "failed to enumerate aliases");
7090 total_num_entries += num_entries;
7091 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7093 if (total_num_entries_p) {
7094 *total_num_entries_p = total_num_entries;
7100 static bool test_QueryDisplayInfo_level(struct dcerpc_pipe *p,
7101 struct torture_context *tctx,
7102 struct policy_handle *handle,
7104 uint32_t *total_num_entries_p)
7107 struct samr_QueryDisplayInfo r;
7108 uint32_t total_num_entries = 0;
7110 r.in.domain_handle = handle;
7113 r.in.max_entries = (uint32_t)-1;
7114 r.in.buf_size = (uint32_t)-1;
7116 torture_comment(tctx, "Testing QueryDisplayInfo\n");
7119 uint32_t total_size;
7120 uint32_t returned_size;
7121 union samr_DispInfo info;
7123 r.out.total_size = &total_size;
7124 r.out.returned_size = &returned_size;
7127 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
7128 if (NT_STATUS_IS_ERR(status)) {
7129 torture_assert_ntstatus_ok(tctx, status,
7130 "failed to query displayinfo");
7133 if (*r.out.returned_size == 0) {
7137 switch (r.in.level) {
7139 total_num_entries += info.info1.count;
7140 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
7143 total_num_entries += info.info2.count;
7144 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
7147 total_num_entries += info.info3.count;
7148 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
7151 total_num_entries += info.info4.count;
7152 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
7155 total_num_entries += info.info5.count;
7156 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
7162 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7164 if (total_num_entries_p) {
7165 *total_num_entries_p = total_num_entries;
7171 static bool test_ManyObjects(struct dcerpc_pipe *p,
7172 struct torture_context *tctx,
7173 struct policy_handle *domain_handle,
7174 struct dom_sid *domain_sid,
7175 struct torture_samr_context *ctx)
7177 uint32_t num_total = ctx->num_objects_large_dc;
7178 uint32_t num_enum = 0;
7179 uint32_t num_disp = 0;
7180 uint32_t num_created = 0;
7181 uint32_t num_anounced = 0;
7186 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
7191 struct samr_QueryDomainInfo2 r;
7192 union samr_DomainInfo *info;
7193 r.in.domain_handle = domain_handle;
7197 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
7198 torture_assert_ntstatus_ok(tctx, status,
7199 "failed to query domain info");
7201 switch (ctx->choice) {
7202 case TORTURE_SAMR_MANY_ACCOUNTS:
7203 num_anounced = info->general.num_users;
7205 case TORTURE_SAMR_MANY_GROUPS:
7206 num_anounced = info->general.num_groups;
7208 case TORTURE_SAMR_MANY_ALIASES:
7209 num_anounced = info->general.num_aliases;
7218 for (i=0; i < num_total; i++) {
7220 const char *name = NULL;
7222 switch (ctx->choice) {
7223 case TORTURE_SAMR_MANY_ACCOUNTS:
7224 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
7225 ret &= test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false);
7227 case TORTURE_SAMR_MANY_GROUPS:
7228 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
7229 ret &= test_CreateDomainGroup(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
7231 case TORTURE_SAMR_MANY_ALIASES:
7232 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
7233 ret &= test_CreateAlias(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
7238 if (!policy_handle_empty(&handles[i])) {
7245 switch (ctx->choice) {
7246 case TORTURE_SAMR_MANY_ACCOUNTS:
7247 ret &= test_EnumDomainUsers(p, tctx, domain_handle, &num_enum);
7249 case TORTURE_SAMR_MANY_GROUPS:
7250 ret &= test_EnumDomainGroups(p, tctx, domain_handle, &num_enum);
7252 case TORTURE_SAMR_MANY_ALIASES:
7253 ret &= test_EnumDomainAliases(p, tctx, domain_handle, &num_enum);
7261 switch (ctx->choice) {
7262 case TORTURE_SAMR_MANY_ACCOUNTS:
7263 ret &= test_QueryDisplayInfo_level(p, tctx, domain_handle, 1, &num_disp);
7265 case TORTURE_SAMR_MANY_GROUPS:
7266 ret &= test_QueryDisplayInfo_level(p, tctx, domain_handle, 3, &num_disp);
7268 case TORTURE_SAMR_MANY_ALIASES:
7269 /* no aliases in dispinfo */
7275 /* close or delete */
7277 for (i=0; i < num_total; i++) {
7279 if (policy_handle_empty(&handles[i])) {
7283 if (torture_setting_bool(tctx, "samba3", false)) {
7284 ret &= test_samr_handle_Close(p, tctx, &handles[i]);
7286 switch (ctx->choice) {
7287 case TORTURE_SAMR_MANY_ACCOUNTS:
7288 ret &= test_DeleteUser(p, tctx, &handles[i]);
7290 case TORTURE_SAMR_MANY_GROUPS:
7291 ret &= test_DeleteDomainGroup(p, tctx, &handles[i]);
7293 case TORTURE_SAMR_MANY_ALIASES:
7294 ret &= test_DeleteAlias(p, tctx, &handles[i]);
7302 talloc_free(handles);
7304 if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
7305 torture_comment(tctx,
7306 "unexpected number of results (%u) returned in enum call, expected %u\n",
7307 num_enum, num_anounced + num_created);
7309 torture_comment(tctx,
7310 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
7311 num_disp, num_anounced + num_created);
7316 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
7317 struct policy_handle *handle);
7319 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7320 struct torture_samr_context *ctx, struct dom_sid *sid)
7323 struct samr_OpenDomain r;
7324 struct policy_handle domain_handle;
7325 struct policy_handle alias_handle;
7326 struct policy_handle user_handle;
7327 struct policy_handle group_handle;
7330 ZERO_STRUCT(alias_handle);
7331 ZERO_STRUCT(user_handle);
7332 ZERO_STRUCT(group_handle);
7333 ZERO_STRUCT(domain_handle);
7335 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
7337 r.in.connect_handle = &ctx->handle;
7338 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7340 r.out.domain_handle = &domain_handle;
7342 status = dcerpc_samr_OpenDomain(p, tctx, &r);
7343 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
7345 /* run the domain tests with the main handle closed - this tests
7346 the servers reference counting */
7347 torture_assert(tctx, test_samr_handle_Close(p, tctx, &ctx->handle), "Failed to close SAMR handle");
7349 switch (ctx->choice) {
7350 case TORTURE_SAMR_PASSWORDS:
7351 case TORTURE_SAMR_USER_PRIVILEGES:
7352 if (!torture_setting_bool(tctx, "samba3", false)) {
7353 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7355 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7357 torture_warning(tctx, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
7360 case TORTURE_SAMR_USER_ATTRIBUTES:
7361 if (!torture_setting_bool(tctx, "samba3", false)) {
7362 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7364 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7365 /* This test needs 'complex' users to validate */
7366 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
7368 torture_warning(tctx, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
7371 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
7372 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
7373 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
7374 if (!torture_setting_bool(tctx, "samba3", false)) {
7375 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
7377 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
7379 torture_warning(tctx, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx, sid));
7382 case TORTURE_SAMR_MANY_ACCOUNTS:
7383 case TORTURE_SAMR_MANY_GROUPS:
7384 case TORTURE_SAMR_MANY_ALIASES:
7385 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
7387 torture_warning(tctx, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
7390 case TORTURE_SAMR_OTHER:
7391 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7393 torture_warning(tctx, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
7395 if (!torture_setting_bool(tctx, "samba3", false)) {
7396 ret &= test_QuerySecurity(p, tctx, &domain_handle);
7398 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
7399 ret &= test_CreateAlias(p, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
7400 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
7401 ret &= test_GetAliasMembership(p, tctx, &domain_handle);
7402 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
7403 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
7404 ret &= test_EnumDomainUsers_all(p, tctx, &domain_handle);
7405 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
7406 ret &= test_EnumDomainGroups_all(p, tctx, &domain_handle);
7407 ret &= test_EnumDomainAliases_all(p, tctx, &domain_handle);
7408 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
7409 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
7410 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
7412 if (torture_setting_bool(tctx, "samba4", false)) {
7413 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
7415 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
7416 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
7418 ret &= test_GroupList(p, tctx, &domain_handle);
7419 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
7420 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
7421 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
7423 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
7428 if (!policy_handle_empty(&user_handle) &&
7429 !test_DeleteUser(p, tctx, &user_handle)) {
7433 if (!policy_handle_empty(&alias_handle) &&
7434 !test_DeleteAlias(p, tctx, &alias_handle)) {
7438 if (!policy_handle_empty(&group_handle) &&
7439 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
7443 torture_assert(tctx, test_samr_handle_Close(p, tctx, &domain_handle), "Failed to close SAMR domain handle");
7445 torture_assert(tctx, test_Connect(p, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
7446 /* reconnect the main handle */
7449 torture_warning(tctx, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
7455 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7456 struct torture_samr_context *ctx, const char *domain)
7459 struct samr_LookupDomain r;
7460 struct dom_sid2 *sid = NULL;
7461 struct lsa_String n1;
7462 struct lsa_String n2;
7465 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
7467 /* check for correct error codes */
7468 r.in.connect_handle = &ctx->handle;
7469 r.in.domain_name = &n2;
7473 status = dcerpc_samr_LookupDomain(p, tctx, &r);
7474 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
7476 init_lsa_String(&n2, "xxNODOMAINxx");
7478 status = dcerpc_samr_LookupDomain(p, tctx, &r);
7479 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
7481 r.in.connect_handle = &ctx->handle;
7483 init_lsa_String(&n1, domain);
7484 r.in.domain_name = &n1;
7486 status = dcerpc_samr_LookupDomain(p, tctx, &r);
7487 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
7489 if (!test_GetDomPwInfo(p, tctx, &n1)) {
7493 if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
7501 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
7502 struct torture_samr_context *ctx)
7505 struct samr_EnumDomains r;
7506 uint32_t resume_handle = 0;
7507 uint32_t num_entries = 0;
7508 struct samr_SamArray *sam = NULL;
7512 r.in.connect_handle = &ctx->handle;
7513 r.in.resume_handle = &resume_handle;
7514 r.in.buf_size = (uint32_t)-1;
7515 r.out.resume_handle = &resume_handle;
7516 r.out.num_entries = &num_entries;
7519 status = dcerpc_samr_EnumDomains(p, tctx, &r);
7520 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
7526 for (i=0;i<sam->count;i++) {
7527 if (!test_LookupDomain(p, tctx, ctx,
7528 sam->entries[i].name.string)) {
7533 status = dcerpc_samr_EnumDomains(p, tctx, &r);
7534 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
7540 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
7541 struct policy_handle *handle)
7544 struct samr_Connect r;
7545 struct samr_Connect2 r2;
7546 struct samr_Connect3 r3;
7547 struct samr_Connect4 r4;
7548 struct samr_Connect5 r5;
7549 union samr_ConnectInfo info;
7550 struct policy_handle h;
7551 uint32_t level_out = 0;
7552 bool ret = true, got_handle = false;
7554 torture_comment(tctx, "testing samr_Connect\n");
7556 r.in.system_name = 0;
7557 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7558 r.out.connect_handle = &h;
7560 status = dcerpc_samr_Connect(p, tctx, &r);
7561 if (!NT_STATUS_IS_OK(status)) {
7562 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
7569 torture_comment(tctx, "testing samr_Connect2\n");
7571 r2.in.system_name = NULL;
7572 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7573 r2.out.connect_handle = &h;
7575 status = dcerpc_samr_Connect2(p, tctx, &r2);
7576 if (!NT_STATUS_IS_OK(status)) {
7577 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
7581 test_samr_handle_Close(p, tctx, handle);
7587 torture_comment(tctx, "testing samr_Connect3\n");
7589 r3.in.system_name = NULL;
7591 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7592 r3.out.connect_handle = &h;
7594 status = dcerpc_samr_Connect3(p, tctx, &r3);
7595 if (!NT_STATUS_IS_OK(status)) {
7596 torture_warning(tctx, "Connect3 failed - %s\n", nt_errstr(status));
7600 test_samr_handle_Close(p, tctx, handle);
7606 torture_comment(tctx, "testing samr_Connect4\n");
7608 r4.in.system_name = "";
7609 r4.in.client_version = 0;
7610 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7611 r4.out.connect_handle = &h;
7613 status = dcerpc_samr_Connect4(p, tctx, &r4);
7614 if (!NT_STATUS_IS_OK(status)) {
7615 torture_warning(tctx, "Connect4 failed - %s\n", nt_errstr(status));
7619 test_samr_handle_Close(p, tctx, handle);
7625 torture_comment(tctx, "testing samr_Connect5\n");
7627 info.info1.client_version = 0;
7628 info.info1.unknown2 = 0;
7630 r5.in.system_name = "";
7631 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7633 r5.out.level_out = &level_out;
7634 r5.in.info_in = &info;
7635 r5.out.info_out = &info;
7636 r5.out.connect_handle = &h;
7638 status = dcerpc_samr_Connect5(p, tctx, &r5);
7639 if (!NT_STATUS_IS_OK(status)) {
7640 torture_warning(tctx, "Connect5 failed - %s\n", nt_errstr(status));
7644 test_samr_handle_Close(p, tctx, handle);
7654 static bool test_samr_ValidatePassword(struct dcerpc_pipe *p, struct torture_context *tctx)
7656 struct samr_ValidatePassword r;
7657 union samr_ValidatePasswordReq req;
7658 union samr_ValidatePasswordRep *repp = NULL;
7660 const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
7663 torture_comment(tctx, "testing samr_ValidatePassword\n");
7666 r.in.level = NetValidatePasswordReset;
7671 req.req3.account.string = "non-existant-account-aklsdji";
7673 for (i=0; passwords[i]; i++) {
7674 req.req3.password.string = passwords[i];
7675 status = dcerpc_samr_ValidatePassword(p, tctx, &r);
7676 torture_assert_ntstatus_ok(tctx, status, "samr_ValidatePassword");
7677 torture_comment(tctx, "Server %s password '%s' with code %i\n",
7678 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
7679 req.req3.password.string, repp->ctr3.status);
7685 bool torture_rpc_samr(struct torture_context *torture)
7688 struct dcerpc_pipe *p;
7690 struct torture_samr_context *ctx;
7692 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7693 if (!NT_STATUS_IS_OK(status)) {
7697 ctx = talloc_zero(torture, struct torture_samr_context);
7699 ctx->choice = TORTURE_SAMR_OTHER;
7701 ret &= test_Connect(p, torture, &ctx->handle);
7703 if (!torture_setting_bool(torture, "samba3", false)) {
7704 ret &= test_QuerySecurity(p, torture, &ctx->handle);
7707 ret &= test_EnumDomains(p, torture, ctx);
7709 ret &= test_SetDsrmPassword(p, torture, &ctx->handle);
7711 ret &= test_Shutdown(p, torture, &ctx->handle);
7713 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7719 bool torture_rpc_samr_users(struct torture_context *torture)
7722 struct dcerpc_pipe *p;
7724 struct torture_samr_context *ctx;
7726 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7727 if (!NT_STATUS_IS_OK(status)) {
7731 ctx = talloc_zero(torture, struct torture_samr_context);
7733 ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
7735 ret &= test_Connect(p, torture, &ctx->handle);
7737 if (!torture_setting_bool(torture, "samba3", false)) {
7738 ret &= test_QuerySecurity(p, torture, &ctx->handle);
7741 ret &= test_EnumDomains(p, torture, ctx);
7743 ret &= test_SetDsrmPassword(p, torture, &ctx->handle);
7745 ret &= test_Shutdown(p, torture, &ctx->handle);
7747 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7753 bool torture_rpc_samr_passwords(struct torture_context *torture)
7756 struct dcerpc_pipe *p;
7758 struct torture_samr_context *ctx;
7760 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7761 if (!NT_STATUS_IS_OK(status)) {
7765 ctx = talloc_zero(torture, struct torture_samr_context);
7767 ctx->choice = TORTURE_SAMR_PASSWORDS;
7769 ret &= test_Connect(p, torture, &ctx->handle);
7771 ret &= test_EnumDomains(p, torture, ctx);
7773 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7775 ret &= test_samr_ValidatePassword(p, torture);
7780 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
7781 struct dcerpc_pipe *p2,
7782 struct cli_credentials *machine_credentials)
7785 struct dcerpc_pipe *p;
7787 struct torture_samr_context *ctx;
7789 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7790 if (!NT_STATUS_IS_OK(status)) {
7794 ctx = talloc_zero(torture, struct torture_samr_context);
7796 ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
7797 ctx->machine_credentials = machine_credentials;
7799 ret &= test_Connect(p, torture, &ctx->handle);
7801 ret &= test_EnumDomains(p, torture, ctx);
7803 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7808 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
7810 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
7811 struct torture_rpc_tcase *tcase;
7813 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
7815 TEST_ACCOUNT_NAME_PWD);
7817 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
7818 torture_rpc_samr_pwdlastset);
7823 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
7824 struct dcerpc_pipe *p2,
7825 struct cli_credentials *machine_credentials)
7828 struct dcerpc_pipe *p;
7830 struct torture_samr_context *ctx;
7832 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7833 if (!NT_STATUS_IS_OK(status)) {
7837 ctx = talloc_zero(torture, struct torture_samr_context);
7839 ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
7840 ctx->machine_credentials = machine_credentials;
7842 ret &= test_Connect(p, torture, &ctx->handle);
7844 ret &= test_EnumDomains(p, torture, ctx);
7846 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7851 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
7853 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-USERS-PRIVILEGES");
7854 struct torture_rpc_tcase *tcase;
7856 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
7858 TEST_ACCOUNT_NAME_PWD);
7860 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
7861 torture_rpc_samr_users_privileges_delete_user);
7866 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
7867 struct dcerpc_pipe *p2,
7871 struct dcerpc_pipe *p;
7873 struct torture_samr_context *ctx =
7874 talloc_get_type_abort(data, struct torture_samr_context);
7876 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7877 if (!NT_STATUS_IS_OK(status)) {
7881 ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
7882 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
7883 ctx->num_objects_large_dc);
7885 ret &= test_Connect(p, torture, &ctx->handle);
7887 ret &= test_EnumDomains(p, torture, ctx);
7889 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7894 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
7895 struct dcerpc_pipe *p2,
7899 struct dcerpc_pipe *p;
7901 struct torture_samr_context *ctx =
7902 talloc_get_type_abort(data, struct torture_samr_context);
7904 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7905 if (!NT_STATUS_IS_OK(status)) {
7909 ctx->choice = TORTURE_SAMR_MANY_GROUPS;
7910 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
7911 ctx->num_objects_large_dc);
7913 ret &= test_Connect(p, torture, &ctx->handle);
7915 ret &= test_EnumDomains(p, torture, ctx);
7917 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7922 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
7923 struct dcerpc_pipe *p2,
7927 struct dcerpc_pipe *p;
7929 struct torture_samr_context *ctx =
7930 talloc_get_type_abort(data, struct torture_samr_context);
7932 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7933 if (!NT_STATUS_IS_OK(status)) {
7937 ctx->choice = TORTURE_SAMR_MANY_ALIASES;
7938 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
7939 ctx->num_objects_large_dc);
7941 ret &= test_Connect(p, torture, &ctx->handle);
7943 ret &= test_EnumDomains(p, torture, ctx);
7945 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7950 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
7952 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-LARGE-DC");
7953 struct torture_rpc_tcase *tcase;
7954 struct torture_samr_context *ctx;
7956 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
7958 ctx = talloc_zero(suite, struct torture_samr_context);
7959 ctx->num_objects_large_dc = 150;
7961 torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
7962 torture_rpc_samr_many_aliases, ctx);
7963 torture_rpc_tcase_add_test_ex(tcase, "many_groups",
7964 torture_rpc_samr_many_groups, ctx);
7965 torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
7966 torture_rpc_samr_many_accounts, ctx);
7971 static bool torture_rpc_samr_badpwdcount(struct torture_context *torture,
7972 struct dcerpc_pipe *p2,
7973 struct cli_credentials *machine_credentials)
7976 struct dcerpc_pipe *p;
7978 struct torture_samr_context *ctx;
7980 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7981 if (!NT_STATUS_IS_OK(status)) {
7985 ctx = talloc_zero(torture, struct torture_samr_context);
7987 ctx->choice = TORTURE_SAMR_PASSWORDS_BADPWDCOUNT;
7988 ctx->machine_credentials = machine_credentials;
7990 ret &= test_Connect(p, torture, &ctx->handle);
7992 ret &= test_EnumDomains(p, torture, ctx);
7994 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7999 struct torture_suite *torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX *mem_ctx)
8001 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-BADPWDCOUNT");
8002 struct torture_rpc_tcase *tcase;
8004 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8006 TEST_ACCOUNT_NAME_PWD);
8008 torture_rpc_tcase_add_test_creds(tcase, "badPwdCount",
8009 torture_rpc_samr_badpwdcount);
8014 static bool torture_rpc_samr_lockout(struct torture_context *torture,
8015 struct dcerpc_pipe *p2,
8016 struct cli_credentials *machine_credentials)
8019 struct dcerpc_pipe *p;
8021 struct torture_samr_context *ctx;
8023 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8024 if (!NT_STATUS_IS_OK(status)) {
8028 ctx = talloc_zero(torture, struct torture_samr_context);
8030 ctx->choice = TORTURE_SAMR_PASSWORDS_LOCKOUT;
8031 ctx->machine_credentials = machine_credentials;
8033 ret &= test_Connect(p, torture, &ctx->handle);
8035 ret &= test_EnumDomains(p, torture, ctx);
8037 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
8042 struct torture_suite *torture_rpc_samr_passwords_lockout(TALLOC_CTX *mem_ctx)
8044 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-LOCKOUT");
8045 struct torture_rpc_tcase *tcase;
8047 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8049 TEST_ACCOUNT_NAME_PWD);
8051 torture_rpc_tcase_add_test_creds(tcase, "lockout",
8052 torture_rpc_samr_lockout);