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_Password_badpwdcount(struct dcerpc_pipe *p,
3451 struct dcerpc_pipe *np,
3452 struct torture_context *tctx,
3453 uint32_t acct_flags,
3454 const char *acct_name,
3455 struct policy_handle *domain_handle,
3456 struct policy_handle *user_handle,
3458 struct cli_credentials *machine_credentials,
3459 const char *comment,
3462 NTSTATUS expected_success_status,
3463 struct samr_DomInfo1 *info1,
3464 struct samr_DomInfo12 *info12)
3466 union samr_DomainInfo info;
3469 uint32_t badpwdcount, tmp;
3470 uint32_t password_history_length = 12;
3471 uint32_t lockout_threshold = 15;
3473 torture_comment(tctx, "\nTesting bad pwd count with: %s\n", comment);
3475 torture_assert(tctx, password_history_length < lockout_threshold,
3476 "password history length needs to be smaller than account lockout threshold for this test");
3481 info.info1 = *info1;
3483 info.info1.password_history_length = password_history_length;
3486 struct samr_SetDomainInfo r;
3488 r.in.domain_handle = domain_handle;
3489 r.in.level = DomainPasswordInformation;
3492 torture_assert_ntstatus_ok(tctx,
3493 dcerpc_samr_SetDomainInfo(p, tctx, &r),
3494 "failed to set domain info level 1");
3497 info.info12 = *info12;
3499 info.info12.lockout_threshold = lockout_threshold;
3502 struct samr_SetDomainInfo r;
3504 r.in.domain_handle = domain_handle;
3505 r.in.level = DomainLockoutInformation;
3508 torture_assert_ntstatus_ok(tctx,
3509 dcerpc_samr_SetDomainInfo(p, tctx, &r),
3510 "failed to set domain info level 12");
3513 /* reset bad pwd count */
3515 torture_assert(tctx,
3516 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
3519 /* enable or disable account */
3521 torture_assert(tctx,
3522 test_SetUserInfo_acct_flags(p, tctx, user_handle,
3523 acct_flags | ACB_DISABLED),
3524 "failed to disable user");
3526 torture_assert(tctx,
3527 test_SetUserInfo_acct_flags(p, tctx, user_handle,
3528 acct_flags & ~ACB_DISABLED),
3529 "failed to enable user");
3533 /* setup password history */
3535 passwords = talloc_array(tctx, char *, password_history_length);
3537 for (i=0; i < password_history_length; i++) {
3539 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3540 "failed to set password");
3541 passwords[i] = talloc_strdup(tctx, *password);
3543 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3544 acct_name, passwords[i],
3545 expected_success_status, interactive)) {
3546 torture_fail(tctx, "failed to auth with latest password");
3549 torture_assert(tctx,
3550 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3552 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3556 /* test with wrong password */
3558 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3559 acct_name, "random_crap",
3560 NT_STATUS_WRONG_PASSWORD, interactive)) {
3561 torture_fail(tctx, "succeeded to authenticate with wrong password");
3564 torture_assert(tctx,
3565 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3567 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3570 /* test with latest good password */
3572 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
3573 passwords[password_history_length-1],
3574 expected_success_status, interactive)) {
3575 torture_fail(tctx, "succeeded to authenticate with wrong password");
3578 torture_assert(tctx,
3579 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3582 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3584 /* only enabled accounts get the bad pwd count reset upon
3585 * successful logon */
3586 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3592 /* test password history */
3594 for (i=0; i < password_history_length; i++) {
3596 torture_comment(tctx, "Testing bad password count behavior with "
3597 "password #%d of #%d\n", i, password_history_length);
3599 /* - network samlogon will succeed auth and not
3600 * increase badpwdcount for 2 last entries
3601 * - interactive samlogon only for the last one */
3603 if (i == password_history_length - 1 ||
3604 (i == password_history_length - 2 && !interactive)) {
3606 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3607 acct_name, passwords[i],
3608 expected_success_status, interactive)) {
3609 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3612 torture_assert(tctx,
3613 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3616 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
3617 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3619 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
3620 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3628 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3629 acct_name, passwords[i],
3630 NT_STATUS_WRONG_PASSWORD, interactive)) {
3631 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3634 torture_assert(tctx,
3635 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3637 /* - network samlogon will fail auth but not increase
3638 * badpwdcount for 3rd last entry
3639 * - interactive samlogon for 3rd and 2nd last entry */
3641 if (i == password_history_length - 3 ||
3642 (i == password_history_length - 2 && interactive)) {
3643 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
3644 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3646 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
3647 torture_assert_int_equal(tctx, badpwdcount, tmp + 1, "unexpected badpwdcount");
3656 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe *p,
3657 struct torture_context *tctx,
3658 uint32_t acct_flags,
3659 const char *acct_name,
3660 struct policy_handle *domain_handle,
3661 struct policy_handle *user_handle,
3663 struct cli_credentials *machine_credentials)
3665 union samr_DomainInfo *q_info, s_info;
3666 struct samr_DomInfo1 info1, _info1;
3667 struct samr_DomInfo12 info12, _info12;
3669 struct dcerpc_pipe *np;
3673 const char *comment;
3676 NTSTATUS expected_success_status;
3679 .comment = "network logon (disabled account)",
3681 .interactive = false,
3682 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
3685 .comment = "network logon (enabled account)",
3687 .interactive = false,
3688 .expected_success_status= NT_STATUS_OK
3691 .comment = "interactive logon (disabled account)",
3693 .interactive = true,
3694 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
3697 .comment = "interactive logon (enabled account)",
3699 .interactive = true,
3700 .expected_success_status= NT_STATUS_OK
3704 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3706 /* backup old policies */
3709 struct samr_QueryDomainInfo2 r;
3711 r.in.domain_handle = domain_handle;
3712 r.in.level = DomainPasswordInformation;
3713 r.out.info = &q_info;
3715 torture_assert_ntstatus_ok(tctx,
3716 dcerpc_samr_QueryDomainInfo2(p, tctx, &r),
3717 "failed to query domain info level 1");
3719 info1 = q_info->info1;
3723 struct samr_QueryDomainInfo2 r;
3725 r.in.domain_handle = domain_handle;
3726 r.in.level = DomainLockoutInformation;
3727 r.out.info = &q_info;
3729 torture_assert_ntstatus_ok(tctx,
3730 dcerpc_samr_QueryDomainInfo2(p, tctx, &r),
3731 "failed to query domain info level 12");
3733 info12 = q_info->info12;
3741 for (i=0; i < ARRAY_SIZE(creds); i++) {
3743 /* skip trust tests for now */
3744 if (acct_flags & ACB_WSTRUST ||
3745 acct_flags & ACB_SVRTRUST ||
3746 acct_flags & ACB_DOMTRUST) {
3750 ret &= test_Password_badpwdcount(p, np, tctx, acct_flags, acct_name,
3751 domain_handle, user_handle, password,
3752 machine_credentials,
3755 creds[i].interactive,
3756 creds[i].expected_success_status,
3759 torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
3761 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
3765 /* restore policies */
3767 s_info.info1 = info1;
3770 struct samr_SetDomainInfo r;
3772 r.in.domain_handle = domain_handle;
3773 r.in.level = DomainPasswordInformation;
3774 r.in.info = &s_info;
3776 torture_assert_ntstatus_ok(tctx,
3777 dcerpc_samr_SetDomainInfo(p, tctx, &r),
3778 "failed to set domain info level 1");
3781 s_info.info12 = info12;
3784 struct samr_SetDomainInfo r;
3786 r.in.domain_handle = domain_handle;
3787 r.in.level = DomainLockoutInformation;
3788 r.in.info = &s_info;
3790 torture_assert_ntstatus_ok(tctx,
3791 dcerpc_samr_SetDomainInfo(p, tctx, &r),
3792 "failed to set domain info level 12");
3798 static bool test_QueryUserInfo_acct_flags(struct dcerpc_pipe *p,
3799 struct torture_context *tctx,
3800 struct policy_handle *handle,
3801 uint32_t *acct_flags)
3803 union samr_UserInfo *info;
3804 struct samr_QueryUserInfo r;
3806 r.in.user_handle = handle;
3810 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3812 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo(p, tctx, &r),
3813 "failed to query userinfo");
3815 *acct_flags = info->info16.acct_flags;
3817 torture_comment(tctx, " (acct_flags: 0x%08x)\n", *acct_flags);
3822 static bool test_Password_lockout(struct dcerpc_pipe *p,
3823 struct dcerpc_pipe *np,
3824 struct torture_context *tctx,
3825 uint32_t acct_flags,
3826 const char *acct_name,
3827 struct policy_handle *domain_handle,
3828 struct policy_handle *user_handle,
3830 struct cli_credentials *machine_credentials,
3831 const char *comment,
3834 NTSTATUS expected_success_status,
3835 struct samr_DomInfo1 *info1,
3836 struct samr_DomInfo12 *info12)
3838 union samr_DomainInfo info;
3839 uint32_t badpwdcount;
3840 uint32_t password_history_length = 1;
3841 uint64_t lockout_threshold = 1;
3842 uint32_t lockout_seconds = 5;
3843 uint64_t delta_time_factor = 10 * 1000 * 1000;
3845 torture_comment(tctx, "\nTesting account lockout: %s\n", comment);
3849 info.info1 = *info1;
3851 torture_comment(tctx, "setting password history lenght.\n");
3852 info.info1.password_history_length = password_history_length;
3855 struct samr_SetDomainInfo r;
3857 r.in.domain_handle = domain_handle;
3858 r.in.level = DomainPasswordInformation;
3861 torture_assert_ntstatus_ok(tctx,
3862 dcerpc_samr_SetDomainInfo(p, tctx, &r),
3863 "failed to set domain info level 1");
3866 info.info12 = *info12;
3868 info.info12.lockout_threshold = lockout_threshold;
3870 /* set lockout duration < lockout window: should fail */
3871 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
3872 info.info12.lockout_window = ~((lockout_seconds + 1) * delta_time_factor);
3875 struct samr_SetDomainInfo r;
3877 r.in.domain_handle = domain_handle;
3878 r.in.level = DomainLockoutInformation;
3881 torture_assert_ntstatus_equal(tctx,
3882 dcerpc_samr_SetDomainInfo(p, tctx, &r),
3883 NT_STATUS_INVALID_PARAMETER,
3884 "succeeded setting lockout duration < lockout window");
3887 info.info12.lockout_duration = 0;
3888 info.info12.lockout_window = 0;
3891 struct samr_SetDomainInfo r;
3893 r.in.domain_handle = domain_handle;
3894 r.in.level = DomainLockoutInformation;
3897 torture_assert_ntstatus_ok(tctx,
3898 dcerpc_samr_SetDomainInfo(p, tctx, &r),
3899 "failed to set lockout window and duration to 0");
3902 /* set lockout duration of 5 seconds */
3903 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
3904 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
3907 struct samr_SetDomainInfo r;
3909 r.in.domain_handle = domain_handle;
3910 r.in.level = DomainLockoutInformation;
3913 torture_assert_ntstatus_ok(tctx,
3914 dcerpc_samr_SetDomainInfo(p, tctx, &r),
3915 "failed to set domain info level 12");
3918 /* reset bad pwd count */
3920 torture_assert(tctx,
3921 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
3924 /* enable or disable account */
3927 torture_assert(tctx,
3928 test_SetUserInfo_acct_flags(p, tctx, user_handle,
3929 acct_flags | ACB_DISABLED),
3930 "failed to disable user");
3932 torture_assert(tctx,
3933 test_SetUserInfo_acct_flags(p, tctx, user_handle,
3934 acct_flags & ~ACB_DISABLED),
3935 "failed to enable user");
3939 /* test logon with right password */
3941 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3942 acct_name, *password,
3943 expected_success_status, interactive)) {
3944 torture_fail(tctx, "failed to auth with latest password");
3947 torture_assert(tctx,
3948 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3949 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3952 /* test with wrong password ==> lockout */
3954 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3955 acct_name, "random_crap",
3956 NT_STATUS_WRONG_PASSWORD, interactive)) {
3957 torture_fail(tctx, "succeeded to authenticate with wrong password");
3960 torture_assert(tctx,
3961 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3962 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3964 torture_assert(tctx,
3965 test_QueryUserInfo_acct_flags(p, tctx, user_handle, &acct_flags), "");
3966 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
3967 "expected account to be locked");
3970 /* test with good password */
3972 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
3974 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
3976 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
3979 /* bad pwd count should not get updated */
3980 torture_assert(tctx,
3981 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
3982 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3984 /* curiously, windows does _not_ set the autlock flag */
3985 torture_assert(tctx,
3986 test_QueryUserInfo_acct_flags(p, tctx, user_handle, &acct_flags), "");
3987 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
3988 "expected account to be locked");
3991 /* with bad password */
3993 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3994 acct_name, "random_crap2",
3995 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
3997 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4000 /* bad pwd count should not get updated */
4001 torture_assert(tctx,
4002 test_QueryUserInfo_badpwdcount(p, tctx, user_handle, &badpwdcount), "");
4003 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4005 /* curiously, windows does _not_ set the autlock flag */
4006 torture_assert(tctx,
4007 test_QueryUserInfo_acct_flags(p, tctx, user_handle, &acct_flags), "");
4008 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4009 "expected account to be locked");
4012 /* let lockout duration expire ==> unlock */
4014 torture_comment(tctx, "let lockout duration expire...\n");
4015 sleep(lockout_seconds + 1);
4017 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4019 expected_success_status, interactive))
4021 torture_fail(tctx, "failed to authenticate after lockout expired");
4024 torture_assert(tctx,
4025 test_QueryUserInfo_acct_flags(p, tctx, user_handle, &acct_flags), "");
4026 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4027 "expected account not to be locked");
4032 static bool test_Password_lockout_wrap(struct dcerpc_pipe *p,
4033 struct torture_context *tctx,
4034 uint32_t acct_flags,
4035 const char *acct_name,
4036 struct policy_handle *domain_handle,
4037 struct policy_handle *user_handle,
4039 struct cli_credentials *machine_credentials)
4041 union samr_DomainInfo *q_info, s_info;
4042 struct samr_DomInfo1 info1, _info1;
4043 struct samr_DomInfo12 info12, _info12;
4045 struct dcerpc_pipe *np;
4049 const char *comment;
4052 NTSTATUS expected_success_status;
4055 .comment = "network logon (disabled account)",
4057 .interactive = false,
4058 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4061 .comment = "network logon (enabled account)",
4063 .interactive = false,
4064 .expected_success_status= NT_STATUS_OK
4067 .comment = "interactive logon (disabled account)",
4069 .interactive = true,
4070 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4073 .comment = "interactive logon (enabled account)",
4075 .interactive = true,
4076 .expected_success_status= NT_STATUS_OK
4080 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4082 /* backup old policies */
4085 struct samr_QueryDomainInfo2 r;
4087 r.in.domain_handle = domain_handle;
4088 r.in.level = DomainPasswordInformation;
4089 r.out.info = &q_info;
4091 torture_assert_ntstatus_ok(tctx,
4092 dcerpc_samr_QueryDomainInfo2(p, tctx, &r),
4093 "failed to query domain info level 1");
4095 info1 = q_info->info1;
4099 struct samr_QueryDomainInfo2 r;
4101 r.in.domain_handle = domain_handle;
4102 r.in.level = DomainLockoutInformation;
4103 r.out.info = &q_info;
4105 torture_assert_ntstatus_ok(tctx,
4106 dcerpc_samr_QueryDomainInfo2(p, tctx, &r),
4107 "failed to query domain info level 12");
4109 info12 = q_info->info12;
4117 for (i=0; i < ARRAY_SIZE(creds); i++) {
4119 /* skip trust tests for now */
4120 if (acct_flags & ACB_WSTRUST ||
4121 acct_flags & ACB_SVRTRUST ||
4122 acct_flags & ACB_DOMTRUST) {
4126 ret &= test_Password_lockout(p, np, tctx, acct_flags, acct_name,
4127 domain_handle, user_handle, password,
4128 machine_credentials,
4131 creds[i].interactive,
4132 creds[i].expected_success_status,
4135 torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
4137 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4141 /* restore policies */
4143 s_info.info1 = info1;
4146 struct samr_SetDomainInfo r;
4148 r.in.domain_handle = domain_handle;
4149 r.in.level = DomainPasswordInformation;
4150 r.in.info = &s_info;
4152 torture_assert_ntstatus_ok(tctx,
4153 dcerpc_samr_SetDomainInfo(p, tctx, &r),
4154 "failed to set domain info level 1");
4157 s_info.info12 = info12;
4160 struct samr_SetDomainInfo r;
4162 r.in.domain_handle = domain_handle;
4163 r.in.level = DomainLockoutInformation;
4164 r.in.info = &s_info;
4166 torture_assert_ntstatus_ok(tctx,
4167 dcerpc_samr_SetDomainInfo(p, tctx, &r),
4168 "failed to set domain info level 12");
4174 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
4175 struct dcerpc_pipe *lp,
4176 struct torture_context *tctx,
4177 struct policy_handle *domain_handle,
4178 struct policy_handle *lsa_handle,
4179 struct policy_handle *user_handle,
4180 const struct dom_sid *domain_sid,
4182 struct cli_credentials *machine_credentials)
4187 struct policy_handle lsa_acct_handle;
4188 struct dom_sid *user_sid;
4190 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
4193 struct lsa_EnumAccountRights r;
4194 struct lsa_RightSet rights;
4196 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4198 r.in.handle = lsa_handle;
4199 r.in.sid = user_sid;
4200 r.out.rights = &rights;
4202 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
4203 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4204 "Expected enum rights for account to fail");
4208 struct lsa_RightSet rights;
4209 struct lsa_StringLarge names[2];
4210 struct lsa_AddAccountRights r;
4212 torture_comment(tctx, "Testing LSA AddAccountRights\n");
4214 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
4215 init_lsa_StringLarge(&names[1], NULL);
4218 rights.names = names;
4220 r.in.handle = lsa_handle;
4221 r.in.sid = user_sid;
4222 r.in.rights = &rights;
4224 status = dcerpc_lsa_AddAccountRights(lp, tctx, &r);
4225 torture_assert_ntstatus_ok(tctx, status,
4226 "Failed to add privileges");
4230 struct lsa_EnumAccounts r;
4231 uint32_t resume_handle = 0;
4232 struct lsa_SidArray lsa_sid_array;
4234 bool found_sid = false;
4236 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4238 r.in.handle = lsa_handle;
4239 r.in.num_entries = 0x1000;
4240 r.in.resume_handle = &resume_handle;
4241 r.out.sids = &lsa_sid_array;
4242 r.out.resume_handle = &resume_handle;
4244 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
4245 torture_assert_ntstatus_ok(tctx, status,
4246 "Failed to enum accounts");
4248 for (i=0; i < lsa_sid_array.num_sids; i++) {
4249 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4254 torture_assert(tctx, found_sid,
4255 "failed to list privileged account");
4259 struct lsa_EnumAccountRights r;
4260 struct lsa_RightSet user_rights;
4262 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4264 r.in.handle = lsa_handle;
4265 r.in.sid = user_sid;
4266 r.out.rights = &user_rights;
4268 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
4269 torture_assert_ntstatus_ok(tctx, status,
4270 "Failed to enum rights for account");
4272 if (user_rights.count < 1) {
4273 torture_warning(tctx, "failed to find newly added rights");
4279 struct lsa_OpenAccount r;
4281 torture_comment(tctx, "Testing LSA OpenAccount\n");
4283 r.in.handle = lsa_handle;
4284 r.in.sid = user_sid;
4285 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4286 r.out.acct_handle = &lsa_acct_handle;
4288 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
4289 torture_assert_ntstatus_ok(tctx, status,
4290 "Failed to open lsa account");
4294 struct lsa_GetSystemAccessAccount r;
4295 uint32_t access_mask;
4297 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4299 r.in.handle = &lsa_acct_handle;
4300 r.out.access_mask = &access_mask;
4302 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
4303 torture_assert_ntstatus_ok(tctx, status,
4304 "Failed to get lsa system access account");
4310 torture_comment(tctx, "Testing LSA Close\n");
4312 r.in.handle = &lsa_acct_handle;
4313 r.out.handle = &lsa_acct_handle;
4315 status = dcerpc_lsa_Close(lp, tctx, &r);
4316 torture_assert_ntstatus_ok(tctx, status,
4317 "Failed to close lsa");
4321 struct samr_DeleteUser r;
4323 torture_comment(tctx, "Testing SAMR DeleteUser\n");
4325 r.in.user_handle = user_handle;
4326 r.out.user_handle = user_handle;
4328 status = dcerpc_samr_DeleteUser(p, tctx, &r);
4329 torture_assert_ntstatus_ok(tctx, status, "Delete User failed");
4333 struct lsa_EnumAccounts r;
4334 uint32_t resume_handle = 0;
4335 struct lsa_SidArray lsa_sid_array;
4337 bool found_sid = false;
4339 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4341 r.in.handle = lsa_handle;
4342 r.in.num_entries = 0x1000;
4343 r.in.resume_handle = &resume_handle;
4344 r.out.sids = &lsa_sid_array;
4345 r.out.resume_handle = &resume_handle;
4347 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
4348 torture_assert_ntstatus_ok(tctx, status,
4349 "Failed to enum accounts");
4351 for (i=0; i < lsa_sid_array.num_sids; i++) {
4352 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4357 torture_assert(tctx, found_sid,
4358 "failed to list privileged account");
4362 struct lsa_EnumAccountRights r;
4363 struct lsa_RightSet user_rights;
4365 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4367 r.in.handle = lsa_handle;
4368 r.in.sid = user_sid;
4369 r.out.rights = &user_rights;
4371 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
4372 torture_assert_ntstatus_ok(tctx, status,
4373 "Failed to enum rights for account");
4375 if (user_rights.count < 1) {
4376 torture_warning(tctx, "failed to find newly added rights");
4382 struct lsa_OpenAccount r;
4384 torture_comment(tctx, "Testing LSA OpenAccount\n");
4386 r.in.handle = lsa_handle;
4387 r.in.sid = user_sid;
4388 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4389 r.out.acct_handle = &lsa_acct_handle;
4391 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
4392 torture_assert_ntstatus_ok(tctx, status,
4393 "Failed to open lsa account");
4397 struct lsa_GetSystemAccessAccount r;
4398 uint32_t access_mask;
4400 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4402 r.in.handle = &lsa_acct_handle;
4403 r.out.access_mask = &access_mask;
4405 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
4406 torture_assert_ntstatus_ok(tctx, status,
4407 "Failed to get lsa system access account");
4411 struct lsa_DeleteObject r;
4413 torture_comment(tctx, "Testing LSA DeleteObject\n");
4415 r.in.handle = &lsa_acct_handle;
4416 r.out.handle = &lsa_acct_handle;
4418 status = dcerpc_lsa_DeleteObject(lp, tctx, &r);
4419 torture_assert_ntstatus_ok(tctx, status,
4420 "Failed to delete object");
4424 struct lsa_EnumAccounts r;
4425 uint32_t resume_handle = 0;
4426 struct lsa_SidArray lsa_sid_array;
4428 bool found_sid = false;
4430 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4432 r.in.handle = lsa_handle;
4433 r.in.num_entries = 0x1000;
4434 r.in.resume_handle = &resume_handle;
4435 r.out.sids = &lsa_sid_array;
4436 r.out.resume_handle = &resume_handle;
4438 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
4439 torture_assert_ntstatus_ok(tctx, status,
4440 "Failed to enum accounts");
4442 for (i=0; i < lsa_sid_array.num_sids; i++) {
4443 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4448 torture_assert(tctx, !found_sid,
4449 "should not have listed privileged account");
4453 struct lsa_EnumAccountRights r;
4454 struct lsa_RightSet user_rights;
4456 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4458 r.in.handle = lsa_handle;
4459 r.in.sid = user_sid;
4460 r.out.rights = &user_rights;
4462 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
4463 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4464 "Failed to enum rights for account");
4470 static bool test_user_ops(struct dcerpc_pipe *p,
4471 struct torture_context *tctx,
4472 struct policy_handle *user_handle,
4473 struct policy_handle *domain_handle,
4474 const struct dom_sid *domain_sid,
4475 uint32_t base_acct_flags,
4476 const char *base_acct_name, enum torture_samr_choice which_ops,
4477 struct cli_credentials *machine_credentials)
4479 char *password = NULL;
4480 struct samr_QueryUserInfo q;
4481 union samr_UserInfo *info;
4487 const uint32_t password_fields[] = {
4488 SAMR_FIELD_NT_PASSWORD_PRESENT,
4489 SAMR_FIELD_LM_PASSWORD_PRESENT,
4490 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
4494 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
4495 if (!NT_STATUS_IS_OK(status)) {
4499 switch (which_ops) {
4500 case TORTURE_SAMR_USER_ATTRIBUTES:
4501 if (!test_QuerySecurity(p, tctx, user_handle)) {
4505 if (!test_QueryUserInfo(p, tctx, user_handle)) {
4509 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
4513 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
4518 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
4522 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
4526 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
4530 case TORTURE_SAMR_PASSWORDS:
4531 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
4532 char simple_pass[9];
4533 char *v = generate_random_str(tctx, 1);
4535 ZERO_STRUCT(simple_pass);
4536 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4538 torture_comment(tctx, "Testing machine account password policy rules\n");
4540 /* Workstation trust accounts don't seem to need to honour password quality policy */
4541 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4545 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
4549 /* reset again, to allow another 'user' password change */
4550 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4554 /* Try a 'short' password */
4555 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
4559 /* Try a compleatly random password */
4560 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
4565 for (i = 0; password_fields[i]; i++) {
4566 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
4570 /* check it was set right */
4571 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4576 for (i = 0; password_fields[i]; i++) {
4577 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
4581 /* check it was set right */
4582 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4587 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
4591 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
4595 if (torture_setting_bool(tctx, "samba4", false)) {
4596 torture_comment(tctx, "skipping Set Password level 18 and 21 against Samba4\n");
4599 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
4603 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4607 for (i = 0; password_fields[i]; i++) {
4609 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
4610 /* we need to skip as that would break
4611 * the ChangePasswordUser3 verify */
4615 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
4619 /* check it was set right */
4620 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4626 q.in.user_handle = user_handle;
4630 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4631 if (!NT_STATUS_IS_OK(status)) {
4632 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4633 q.in.level, nt_errstr(status));
4636 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4637 if ((info->info5.acct_flags) != expected_flags) {
4638 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4639 info->info5.acct_flags,
4642 if (!torture_setting_bool(tctx, "samba3", false)) {
4646 if (info->info5.rid != rid) {
4647 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
4648 info->info5.rid, rid);
4655 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
4657 /* test last password change timestamp behaviour */
4658 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
4660 user_handle, &password,
4661 machine_credentials)) {
4666 torture_comment(tctx, "pwdLastSet test succeeded\n");
4668 torture_warning(tctx, "pwdLastSet test failed\n");
4673 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
4675 /* test bad pwd count change behaviour */
4676 if (!test_Password_badpwdcount_wrap(p, tctx, base_acct_flags,
4679 user_handle, &password,
4680 machine_credentials)) {
4685 torture_comment(tctx, "badPwdCount test succeeded\n");
4687 torture_warning(tctx, "badPwdCount test failed\n");
4692 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
4694 if (!test_Password_lockout_wrap(p, tctx, base_acct_flags,
4697 user_handle, &password,
4698 machine_credentials))
4704 torture_comment(tctx, "lockout test succeeded\n");
4706 torture_warning(tctx, "lockout test failed\n");
4712 case TORTURE_SAMR_USER_PRIVILEGES: {
4714 struct dcerpc_pipe *lp;
4715 struct policy_handle *lsa_handle;
4717 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
4718 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
4720 if (!test_lsa_OpenPolicy2(lp, tctx, &lsa_handle)) {
4724 if (!test_DeleteUser_with_privs(p, lp, tctx,
4725 domain_handle, lsa_handle, user_handle,
4727 machine_credentials)) {
4731 if (!test_lsa_Close(lp, tctx, lsa_handle)) {
4736 torture_warning(tctx, "privileged user delete test failed\n");
4741 case TORTURE_SAMR_OTHER:
4742 /* We just need the account to exist */
4748 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
4749 struct policy_handle *alias_handle,
4750 const struct dom_sid *domain_sid)
4754 if (!torture_setting_bool(tctx, "samba3", false)) {
4755 if (!test_QuerySecurity(p, tctx, alias_handle)) {
4760 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
4764 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
4768 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
4772 if (torture_setting_bool(tctx, "samba3", false) ||
4773 torture_setting_bool(tctx, "samba4", false)) {
4774 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
4778 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
4786 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
4787 struct policy_handle *user_handle)
4789 struct samr_DeleteUser d;
4791 torture_comment(tctx, "Testing DeleteUser\n");
4793 d.in.user_handle = user_handle;
4794 d.out.user_handle = user_handle;
4796 status = dcerpc_samr_DeleteUser(p, tctx, &d);
4797 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
4802 bool test_DeleteUser_byname(struct dcerpc_pipe *p,
4803 struct torture_context *tctx,
4804 struct policy_handle *handle, const char *name)
4807 struct samr_DeleteUser d;
4808 struct policy_handle user_handle;
4811 status = test_LookupName(p, tctx, handle, name, &rid);
4812 if (!NT_STATUS_IS_OK(status)) {
4816 status = test_OpenUser_byname(p, tctx, handle, name, &user_handle);
4817 if (!NT_STATUS_IS_OK(status)) {
4821 d.in.user_handle = &user_handle;
4822 d.out.user_handle = &user_handle;
4823 status = dcerpc_samr_DeleteUser(p, tctx, &d);
4824 if (!NT_STATUS_IS_OK(status)) {
4831 torture_warning(tctx, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
4836 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p,
4837 struct torture_context *tctx,
4838 struct policy_handle *handle, const char *name)
4841 struct samr_OpenGroup r;
4842 struct samr_DeleteDomainGroup d;
4843 struct policy_handle group_handle;
4846 status = test_LookupName(p, tctx, handle, name, &rid);
4847 if (!NT_STATUS_IS_OK(status)) {
4851 r.in.domain_handle = handle;
4852 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4854 r.out.group_handle = &group_handle;
4855 status = dcerpc_samr_OpenGroup(p, tctx, &r);
4856 if (!NT_STATUS_IS_OK(status)) {
4860 d.in.group_handle = &group_handle;
4861 d.out.group_handle = &group_handle;
4862 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
4863 if (!NT_STATUS_IS_OK(status)) {
4870 torture_warning(tctx, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
4875 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p,
4876 struct torture_context *tctx,
4877 struct policy_handle *domain_handle,
4881 struct samr_OpenAlias r;
4882 struct samr_DeleteDomAlias d;
4883 struct policy_handle alias_handle;
4886 torture_comment(tctx, "testing DeleteAlias_byname\n");
4888 status = test_LookupName(p, tctx, domain_handle, name, &rid);
4889 if (!NT_STATUS_IS_OK(status)) {
4893 r.in.domain_handle = domain_handle;
4894 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4896 r.out.alias_handle = &alias_handle;
4897 status = dcerpc_samr_OpenAlias(p, tctx, &r);
4898 if (!NT_STATUS_IS_OK(status)) {
4902 d.in.alias_handle = &alias_handle;
4903 d.out.alias_handle = &alias_handle;
4904 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
4905 if (!NT_STATUS_IS_OK(status)) {
4912 torture_warning(tctx, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
4916 static bool test_DeleteAlias(struct dcerpc_pipe *p,
4917 struct torture_context *tctx,
4918 struct policy_handle *alias_handle)
4920 struct samr_DeleteDomAlias d;
4924 torture_comment(tctx, "Testing DeleteAlias\n");
4926 d.in.alias_handle = alias_handle;
4927 d.out.alias_handle = alias_handle;
4929 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
4930 if (!NT_STATUS_IS_OK(status)) {
4931 torture_warning(tctx, "DeleteAlias failed - %s\n", nt_errstr(status));
4938 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4939 struct policy_handle *domain_handle,
4940 const char *alias_name,
4941 struct policy_handle *alias_handle,
4942 const struct dom_sid *domain_sid,
4946 struct samr_CreateDomAlias r;
4947 struct lsa_String name;
4951 init_lsa_String(&name, alias_name);
4952 r.in.domain_handle = domain_handle;
4953 r.in.alias_name = &name;
4954 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4955 r.out.alias_handle = alias_handle;
4958 torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
4960 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4962 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4963 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4964 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
4967 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
4973 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
4974 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
4977 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4980 if (!NT_STATUS_IS_OK(status)) {
4981 torture_warning(tctx, "CreateAlias failed - %s\n", nt_errstr(status));
4989 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
4996 static bool test_ChangePassword(struct dcerpc_pipe *p,
4997 struct torture_context *tctx,
4998 const char *acct_name,
4999 struct policy_handle *domain_handle, char **password)
5007 if (!test_ChangePasswordUser(p, tctx, acct_name, domain_handle, password)) {
5011 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
5015 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
5019 /* test what happens when setting the old password again */
5020 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
5025 char simple_pass[9];
5026 char *v = generate_random_str(tctx, 1);
5028 ZERO_STRUCT(simple_pass);
5029 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5031 /* test what happens when picking a simple password */
5032 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
5037 /* set samr_SetDomainInfo level 1 with min_length 5 */
5039 struct samr_QueryDomainInfo r;
5040 union samr_DomainInfo *info = NULL;
5041 struct samr_SetDomainInfo s;
5042 uint16_t len_old, len;
5043 uint32_t pwd_prop_old;
5044 int64_t min_pwd_age_old;
5049 r.in.domain_handle = domain_handle;
5053 torture_comment(tctx, "testing samr_QueryDomainInfo level 1\n");
5054 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5055 if (!NT_STATUS_IS_OK(status)) {
5059 s.in.domain_handle = domain_handle;
5063 /* remember the old min length, so we can reset it */
5064 len_old = s.in.info->info1.min_password_length;
5065 s.in.info->info1.min_password_length = len;
5066 pwd_prop_old = s.in.info->info1.password_properties;
5067 /* turn off password complexity checks for this test */
5068 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
5070 min_pwd_age_old = s.in.info->info1.min_password_age;
5071 s.in.info->info1.min_password_age = 0;
5073 torture_comment(tctx, "testing samr_SetDomainInfo level 1\n");
5074 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5075 if (!NT_STATUS_IS_OK(status)) {
5079 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
5081 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
5085 s.in.info->info1.min_password_length = len_old;
5086 s.in.info->info1.password_properties = pwd_prop_old;
5087 s.in.info->info1.min_password_age = min_pwd_age_old;
5089 torture_comment(tctx, "testing samr_SetDomainInfo level 1\n");
5090 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5091 if (!NT_STATUS_IS_OK(status)) {
5099 struct samr_OpenUser r;
5100 struct samr_QueryUserInfo q;
5101 union samr_UserInfo *info;
5102 struct samr_LookupNames n;
5103 struct policy_handle user_handle;
5104 struct samr_Ids rids, types;
5106 n.in.domain_handle = domain_handle;
5108 n.in.names = talloc_array(tctx, struct lsa_String, 1);
5109 n.in.names[0].string = acct_name;
5111 n.out.types = &types;
5113 status = dcerpc_samr_LookupNames(p, tctx, &n);
5114 if (!NT_STATUS_IS_OK(status)) {
5115 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(status));
5119 r.in.domain_handle = domain_handle;
5120 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5121 r.in.rid = n.out.rids->ids[0];
5122 r.out.user_handle = &user_handle;
5124 status = dcerpc_samr_OpenUser(p, tctx, &r);
5125 if (!NT_STATUS_IS_OK(status)) {
5126 torture_warning(tctx, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
5130 q.in.user_handle = &user_handle;
5134 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
5135 if (!NT_STATUS_IS_OK(status)) {
5136 torture_warning(tctx, "QueryUserInfo failed - %s\n", nt_errstr(status));
5140 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
5142 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
5143 info->info5.last_password_change, true)) {
5148 /* we change passwords twice - this has the effect of verifying
5149 they were changed correctly for the final call */
5150 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5154 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5161 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
5162 struct policy_handle *domain_handle,
5163 const char *user_name,
5164 struct policy_handle *user_handle_out,
5165 struct dom_sid *domain_sid,
5166 enum torture_samr_choice which_ops,
5167 struct cli_credentials *machine_credentials,
5171 TALLOC_CTX *user_ctx;
5174 struct samr_CreateUser r;
5175 struct samr_QueryUserInfo q;
5176 union samr_UserInfo *info;
5177 struct samr_DeleteUser d;
5180 /* This call creates a 'normal' account - check that it really does */
5181 const uint32_t acct_flags = ACB_NORMAL;
5182 struct lsa_String name;
5185 struct policy_handle user_handle;
5186 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5187 init_lsa_String(&name, user_name);
5189 r.in.domain_handle = domain_handle;
5190 r.in.account_name = &name;
5191 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5192 r.out.user_handle = &user_handle;
5195 torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
5197 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
5199 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5200 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
5201 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5204 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5210 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5211 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
5212 talloc_free(user_ctx);
5215 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
5218 if (!NT_STATUS_IS_OK(status)) {
5219 talloc_free(user_ctx);
5220 torture_warning(tctx, "CreateUser failed - %s\n", nt_errstr(status));
5225 if (user_handle_out) {
5226 *user_handle_out = user_handle;
5232 q.in.user_handle = &user_handle;
5236 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
5237 if (!NT_STATUS_IS_OK(status)) {
5238 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5239 q.in.level, nt_errstr(status));
5242 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
5243 torture_warning(tctx, "QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5244 info->info16.acct_flags,
5250 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5251 domain_sid, acct_flags, name.string, which_ops,
5252 machine_credentials)) {
5256 if (user_handle_out) {
5257 *user_handle_out = user_handle;
5259 torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
5261 d.in.user_handle = &user_handle;
5262 d.out.user_handle = &user_handle;
5264 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
5265 if (!NT_STATUS_IS_OK(status)) {
5266 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(status));
5273 talloc_free(user_ctx);
5279 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
5280 struct policy_handle *domain_handle,
5281 struct dom_sid *domain_sid,
5282 enum torture_samr_choice which_ops,
5283 struct cli_credentials *machine_credentials)
5286 struct samr_CreateUser2 r;
5287 struct samr_QueryUserInfo q;
5288 union samr_UserInfo *info;
5289 struct samr_DeleteUser d;
5290 struct policy_handle user_handle;
5292 struct lsa_String name;
5297 uint32_t acct_flags;
5298 const char *account_name;
5300 } account_types[] = {
5301 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
5302 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5303 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5304 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5305 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5306 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5307 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5308 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5309 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5310 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
5311 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5312 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5313 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5314 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5315 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
5318 for (i = 0; account_types[i].account_name; i++) {
5319 TALLOC_CTX *user_ctx;
5320 uint32_t acct_flags = account_types[i].acct_flags;
5321 uint32_t access_granted;
5322 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5323 init_lsa_String(&name, account_types[i].account_name);
5325 r.in.domain_handle = domain_handle;
5326 r.in.account_name = &name;
5327 r.in.acct_flags = acct_flags;
5328 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5329 r.out.user_handle = &user_handle;
5330 r.out.access_granted = &access_granted;
5333 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
5335 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
5337 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5338 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
5339 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5342 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5349 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5350 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
5351 talloc_free(user_ctx);
5355 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
5358 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
5359 torture_warning(tctx, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5360 nt_errstr(status), nt_errstr(account_types[i].nt_status));
5364 if (NT_STATUS_IS_OK(status)) {
5365 q.in.user_handle = &user_handle;
5369 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
5370 if (!NT_STATUS_IS_OK(status)) {
5371 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5372 q.in.level, nt_errstr(status));
5375 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
5376 if (acct_flags == ACB_NORMAL) {
5377 expected_flags |= ACB_PW_EXPIRED;
5379 if ((info->info5.acct_flags) != expected_flags) {
5380 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5381 info->info5.acct_flags,
5385 switch (acct_flags) {
5387 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
5388 torture_warning(tctx, "QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5389 DOMAIN_RID_DCS, info->info5.primary_gid);
5394 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
5395 torture_warning(tctx, "QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5396 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
5401 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
5402 torture_warning(tctx, "QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5403 DOMAIN_RID_USERS, info->info5.primary_gid);
5410 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5411 domain_sid, acct_flags, name.string, which_ops,
5412 machine_credentials)) {
5416 if (!policy_handle_empty(&user_handle)) {
5417 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
5419 d.in.user_handle = &user_handle;
5420 d.out.user_handle = &user_handle;
5422 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
5423 if (!NT_STATUS_IS_OK(status)) {
5424 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(status));
5429 talloc_free(user_ctx);
5435 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
5436 struct torture_context *tctx,
5437 struct policy_handle *handle)
5440 struct samr_QueryAliasInfo r;
5441 union samr_AliasInfo *info;
5442 uint16_t levels[] = {1, 2, 3};
5446 for (i=0;i<ARRAY_SIZE(levels);i++) {
5447 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
5449 r.in.alias_handle = handle;
5450 r.in.level = levels[i];
5453 status = dcerpc_samr_QueryAliasInfo(p, tctx, &r);
5454 if (!NT_STATUS_IS_OK(status)) {
5455 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
5456 levels[i], nt_errstr(status));
5464 static bool test_QueryGroupInfo(struct dcerpc_pipe *p,
5465 struct torture_context *tctx,
5466 struct policy_handle *handle)
5469 struct samr_QueryGroupInfo r;
5470 union samr_GroupInfo *info;
5471 uint16_t levels[] = {1, 2, 3, 4, 5};
5475 for (i=0;i<ARRAY_SIZE(levels);i++) {
5476 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5478 r.in.group_handle = handle;
5479 r.in.level = levels[i];
5482 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
5483 if (!NT_STATUS_IS_OK(status)) {
5484 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5485 levels[i], nt_errstr(status));
5493 static bool test_QueryGroupMember(struct dcerpc_pipe *p,
5494 struct torture_context *tctx,
5495 struct policy_handle *handle)
5498 struct samr_QueryGroupMember r;
5499 struct samr_RidTypeArray *rids = NULL;
5502 torture_comment(tctx, "Testing QueryGroupMember\n");
5504 r.in.group_handle = handle;
5507 status = dcerpc_samr_QueryGroupMember(p, tctx, &r);
5508 if (!NT_STATUS_IS_OK(status)) {
5509 torture_warning(tctx, "QueryGroupInfo failed - %s\n", nt_errstr(status));
5517 static bool test_SetGroupInfo(struct dcerpc_pipe *p,
5518 struct torture_context *tctx,
5519 struct policy_handle *handle)
5522 struct samr_QueryGroupInfo r;
5523 union samr_GroupInfo *info;
5524 struct samr_SetGroupInfo s;
5525 uint16_t levels[] = {1, 2, 3, 4};
5526 uint16_t set_ok[] = {0, 1, 1, 1};
5530 for (i=0;i<ARRAY_SIZE(levels);i++) {
5531 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5533 r.in.group_handle = handle;
5534 r.in.level = levels[i];
5537 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
5538 if (!NT_STATUS_IS_OK(status)) {
5539 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5540 levels[i], nt_errstr(status));
5544 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
5546 s.in.group_handle = handle;
5547 s.in.level = levels[i];
5548 s.in.info = *r.out.info;
5551 /* disabled this, as it changes the name only from the point of view of samr,
5552 but leaves the name from the point of view of w2k3 internals (and ldap). This means
5553 the name is still reserved, so creating the old name fails, but deleting by the old name
5555 if (s.in.level == 2) {
5556 init_lsa_String(&s.in.info->string, "NewName");
5560 if (s.in.level == 4) {
5561 init_lsa_String(&s.in.info->description, "test description");
5564 status = dcerpc_samr_SetGroupInfo(p, tctx, &s);
5566 if (!NT_STATUS_IS_OK(status)) {
5567 torture_warning(tctx, "SetGroupInfo level %u failed - %s\n",
5568 r.in.level, nt_errstr(status));
5573 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5574 torture_warning(tctx, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5575 r.in.level, nt_errstr(status));
5585 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
5586 struct torture_context *tctx,
5587 struct policy_handle *handle)
5590 struct samr_QueryUserInfo r;
5591 union samr_UserInfo *info;
5592 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5593 11, 12, 13, 14, 16, 17, 20, 21};
5597 for (i=0;i<ARRAY_SIZE(levels);i++) {
5598 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
5600 r.in.user_handle = handle;
5601 r.in.level = levels[i];
5604 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
5605 if (!NT_STATUS_IS_OK(status)) {
5606 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5607 levels[i], nt_errstr(status));
5615 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
5616 struct torture_context *tctx,
5617 struct policy_handle *handle)
5620 struct samr_QueryUserInfo2 r;
5621 union samr_UserInfo *info;
5622 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5623 11, 12, 13, 14, 16, 17, 20, 21};
5627 for (i=0;i<ARRAY_SIZE(levels);i++) {
5628 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
5630 r.in.user_handle = handle;
5631 r.in.level = levels[i];
5634 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r);
5635 if (!NT_STATUS_IS_OK(status)) {
5636 torture_warning(tctx, "QueryUserInfo2 level %u failed - %s\n",
5637 levels[i], nt_errstr(status));
5645 static bool test_OpenUser(struct dcerpc_pipe *p,
5646 struct torture_context *tctx,
5647 struct policy_handle *handle, uint32_t rid)
5650 struct samr_OpenUser r;
5651 struct policy_handle user_handle;
5654 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5656 r.in.domain_handle = handle;
5657 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5659 r.out.user_handle = &user_handle;
5661 status = dcerpc_samr_OpenUser(p, tctx, &r);
5662 if (!NT_STATUS_IS_OK(status)) {
5663 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
5667 if (!test_QuerySecurity(p, tctx, &user_handle)) {
5671 if (!test_QueryUserInfo(p, tctx, &user_handle)) {
5675 if (!test_QueryUserInfo2(p, tctx, &user_handle)) {
5679 if (!test_GetUserPwInfo(p, tctx, &user_handle)) {
5683 if (!test_GetGroupsForUser(p,tctx, &user_handle)) {
5687 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
5694 static bool test_OpenGroup(struct dcerpc_pipe *p,
5695 struct torture_context *tctx,
5696 struct policy_handle *handle, uint32_t rid)
5699 struct samr_OpenGroup r;
5700 struct policy_handle group_handle;
5703 torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
5705 r.in.domain_handle = handle;
5706 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5708 r.out.group_handle = &group_handle;
5710 status = dcerpc_samr_OpenGroup(p, tctx, &r);
5711 if (!NT_STATUS_IS_OK(status)) {
5712 torture_warning(tctx, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
5716 if (!torture_setting_bool(tctx, "samba3", false)) {
5717 if (!test_QuerySecurity(p, tctx, &group_handle)) {
5722 if (!test_QueryGroupInfo(p, tctx, &group_handle)) {
5726 if (!test_QueryGroupMember(p, tctx, &group_handle)) {
5730 if (!test_samr_handle_Close(p, tctx, &group_handle)) {
5737 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
5738 struct policy_handle *handle, uint32_t rid)
5741 struct samr_OpenAlias r;
5742 struct policy_handle alias_handle;
5745 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
5747 r.in.domain_handle = handle;
5748 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5750 r.out.alias_handle = &alias_handle;
5752 status = dcerpc_samr_OpenAlias(p, tctx, &r);
5753 if (!NT_STATUS_IS_OK(status)) {
5754 torture_warning(tctx, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
5758 if (!torture_setting_bool(tctx, "samba3", false)) {
5759 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
5764 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
5768 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
5772 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
5779 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
5780 struct policy_handle *handle, uint32_t rid,
5781 uint32_t acct_flag_mask)
5784 struct samr_OpenUser r;
5785 struct samr_QueryUserInfo q;
5786 union samr_UserInfo *info;
5787 struct policy_handle user_handle;
5790 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5792 r.in.domain_handle = handle;
5793 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5795 r.out.user_handle = &user_handle;
5797 status = dcerpc_samr_OpenUser(p, tctx, &r);
5798 if (!NT_STATUS_IS_OK(status)) {
5799 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
5803 q.in.user_handle = &user_handle;
5807 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
5808 if (!NT_STATUS_IS_OK(status)) {
5809 torture_warning(tctx, "QueryUserInfo level 16 failed - %s\n",
5813 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
5814 torture_warning(tctx, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
5815 acct_flag_mask, info->info16.acct_flags, rid);
5820 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
5827 static bool test_EnumDomainUsers_all(struct dcerpc_pipe *p,
5828 struct torture_context *tctx,
5829 struct policy_handle *handle)
5831 NTSTATUS status = STATUS_MORE_ENTRIES;
5832 struct samr_EnumDomainUsers r;
5833 uint32_t mask, resume_handle=0;
5836 struct samr_LookupNames n;
5837 struct samr_LookupRids lr ;
5838 struct lsa_Strings names;
5839 struct samr_Ids rids, types;
5840 struct samr_SamArray *sam = NULL;
5841 uint32_t num_entries = 0;
5843 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
5844 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
5845 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
5848 torture_comment(tctx, "Testing EnumDomainUsers\n");
5850 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
5851 r.in.domain_handle = handle;
5852 r.in.resume_handle = &resume_handle;
5853 r.in.acct_flags = mask = masks[mask_idx];
5854 r.in.max_size = (uint32_t)-1;
5855 r.out.resume_handle = &resume_handle;
5856 r.out.num_entries = &num_entries;
5859 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
5860 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5861 !NT_STATUS_IS_OK(status)) {
5862 torture_warning(tctx, "EnumDomainUsers failed - %s\n", nt_errstr(status));
5866 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
5868 if (sam->count == 0) {
5872 for (i=0;i<sam->count;i++) {
5874 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
5877 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
5883 torture_comment(tctx, "Testing LookupNames\n");
5884 n.in.domain_handle = handle;
5885 n.in.num_names = sam->count;
5886 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
5888 n.out.types = &types;
5889 for (i=0;i<sam->count;i++) {
5890 n.in.names[i].string = sam->entries[i].name.string;
5892 status = dcerpc_samr_LookupNames(p, tctx, &n);
5893 if (!NT_STATUS_IS_OK(status)) {
5894 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(status));
5899 torture_comment(tctx, "Testing LookupRids\n");
5900 lr.in.domain_handle = handle;
5901 lr.in.num_rids = sam->count;
5902 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
5903 lr.out.names = &names;
5904 lr.out.types = &types;
5905 for (i=0;i<sam->count;i++) {
5906 lr.in.rids[i] = sam->entries[i].idx;
5908 status = dcerpc_samr_LookupRids(p, tctx, &lr);
5909 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
5915 try blasting the server with a bunch of sync requests
5917 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
5918 struct policy_handle *handle)
5921 struct samr_EnumDomainUsers r;
5922 uint32_t resume_handle=0;
5924 #define ASYNC_COUNT 100
5925 struct rpc_request *req[ASYNC_COUNT];
5927 if (!torture_setting_bool(tctx, "dangerous", false)) {
5928 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
5931 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
5933 r.in.domain_handle = handle;
5934 r.in.resume_handle = &resume_handle;
5935 r.in.acct_flags = 0;
5936 r.in.max_size = (uint32_t)-1;
5937 r.out.resume_handle = &resume_handle;
5939 for (i=0;i<ASYNC_COUNT;i++) {
5940 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
5943 for (i=0;i<ASYNC_COUNT;i++) {
5944 status = dcerpc_ndr_request_recv(req[i]);
5945 if (!NT_STATUS_IS_OK(status)) {
5946 torture_warning(tctx, "EnumDomainUsers[%d] failed - %s\n",
5947 i, nt_errstr(status));
5952 torture_comment(tctx, "%d async requests OK\n", i);
5957 static bool test_EnumDomainGroups_all(struct dcerpc_pipe *p,
5958 struct torture_context *tctx,
5959 struct policy_handle *handle)
5962 struct samr_EnumDomainGroups r;
5963 uint32_t resume_handle=0;
5964 struct samr_SamArray *sam = NULL;
5965 uint32_t num_entries = 0;
5969 torture_comment(tctx, "Testing EnumDomainGroups\n");
5971 r.in.domain_handle = handle;
5972 r.in.resume_handle = &resume_handle;
5973 r.in.max_size = (uint32_t)-1;
5974 r.out.resume_handle = &resume_handle;
5975 r.out.num_entries = &num_entries;
5978 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
5979 if (!NT_STATUS_IS_OK(status)) {
5980 torture_warning(tctx, "EnumDomainGroups failed - %s\n", nt_errstr(status));
5988 for (i=0;i<sam->count;i++) {
5989 if (!test_OpenGroup(p, tctx, handle, sam->entries[i].idx)) {
5997 static bool test_EnumDomainAliases_all(struct dcerpc_pipe *p,
5998 struct torture_context *tctx,
5999 struct policy_handle *handle)
6002 struct samr_EnumDomainAliases r;
6003 uint32_t resume_handle=0;
6004 struct samr_SamArray *sam = NULL;
6005 uint32_t num_entries = 0;
6009 torture_comment(tctx, "Testing EnumDomainAliases\n");
6011 r.in.domain_handle = handle;
6012 r.in.resume_handle = &resume_handle;
6013 r.in.max_size = (uint32_t)-1;
6015 r.out.num_entries = &num_entries;
6016 r.out.resume_handle = &resume_handle;
6018 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
6019 if (!NT_STATUS_IS_OK(status)) {
6020 torture_warning(tctx, "EnumDomainAliases failed - %s\n", nt_errstr(status));
6028 for (i=0;i<sam->count;i++) {
6029 if (!test_OpenAlias(p, tctx, handle, sam->entries[i].idx)) {
6037 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p,
6038 struct torture_context *tctx,
6039 struct policy_handle *handle)
6042 struct samr_GetDisplayEnumerationIndex r;
6044 uint16_t levels[] = {1, 2, 3, 4, 5};
6045 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6046 struct lsa_String name;
6050 for (i=0;i<ARRAY_SIZE(levels);i++) {
6051 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
6053 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6055 r.in.domain_handle = handle;
6056 r.in.level = levels[i];
6060 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
6063 !NT_STATUS_IS_OK(status) &&
6064 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
6065 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6066 levels[i], nt_errstr(status));
6070 init_lsa_String(&name, "zzzzzzzz");
6072 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
6074 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
6075 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6076 levels[i], nt_errstr(status));
6084 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p,
6085 struct torture_context *tctx,
6086 struct policy_handle *handle)
6089 struct samr_GetDisplayEnumerationIndex2 r;
6091 uint16_t levels[] = {1, 2, 3, 4, 5};
6092 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6093 struct lsa_String name;
6097 for (i=0;i<ARRAY_SIZE(levels);i++) {
6098 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
6100 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6102 r.in.domain_handle = handle;
6103 r.in.level = levels[i];
6107 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
6109 !NT_STATUS_IS_OK(status) &&
6110 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
6111 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6112 levels[i], nt_errstr(status));
6116 init_lsa_String(&name, "zzzzzzzz");
6118 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
6119 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
6120 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6121 levels[i], nt_errstr(status));
6129 #define STRING_EQUAL_QUERY(s1, s2, user) \
6130 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6131 /* odd, but valid */ \
6132 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6133 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
6134 #s1, user.string, s1.string, s2.string, __location__); \
6137 #define INT_EQUAL_QUERY(s1, s2, user) \
6139 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6140 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6144 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p,
6145 struct torture_context *tctx,
6146 struct samr_QueryDisplayInfo *querydisplayinfo,
6147 bool *seen_testuser)
6149 struct samr_OpenUser r;
6150 struct samr_QueryUserInfo q;
6151 union samr_UserInfo *info;
6152 struct policy_handle user_handle;
6155 r.in.domain_handle = querydisplayinfo->in.domain_handle;
6156 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6157 for (i = 0; ; i++) {
6158 switch (querydisplayinfo->in.level) {
6160 if (i >= querydisplayinfo->out.info->info1.count) {
6163 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
6166 if (i >= querydisplayinfo->out.info->info2.count) {
6169 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
6175 /* Not interested in validating just the account name */
6179 r.out.user_handle = &user_handle;
6181 switch (querydisplayinfo->in.level) {
6184 status = dcerpc_samr_OpenUser(p, tctx, &r);
6185 if (!NT_STATUS_IS_OK(status)) {
6186 torture_warning(tctx, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
6191 q.in.user_handle = &user_handle;
6194 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
6195 if (!NT_STATUS_IS_OK(status)) {
6196 torture_warning(tctx, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
6200 switch (querydisplayinfo->in.level) {
6202 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
6203 *seen_testuser = true;
6205 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
6206 info->info21.full_name, info->info21.account_name);
6207 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
6208 info->info21.account_name, info->info21.account_name);
6209 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
6210 info->info21.description, info->info21.account_name);
6211 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
6212 info->info21.rid, info->info21.account_name);
6213 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
6214 info->info21.acct_flags, info->info21.account_name);
6218 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
6219 info->info21.account_name, info->info21.account_name);
6220 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
6221 info->info21.description, info->info21.account_name);
6222 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
6223 info->info21.rid, info->info21.account_name);
6224 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
6225 info->info21.acct_flags, info->info21.account_name);
6227 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
6228 torture_warning(tctx, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6229 info->info21.account_name.string);
6232 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
6233 torture_warning(tctx, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6234 info->info21.account_name.string,
6235 querydisplayinfo->out.info->info2.entries[i].acct_flags,
6236 info->info21.acct_flags);
6243 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
6250 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p,
6251 struct torture_context *tctx,
6252 struct policy_handle *handle)
6255 struct samr_QueryDisplayInfo r;
6256 struct samr_QueryDomainInfo dom_info;
6257 union samr_DomainInfo *info = NULL;
6259 uint16_t levels[] = {1, 2, 3, 4, 5};
6261 bool seen_testuser = false;
6262 uint32_t total_size;
6263 uint32_t returned_size;
6264 union samr_DispInfo disp_info;
6267 for (i=0;i<ARRAY_SIZE(levels);i++) {
6268 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
6271 status = STATUS_MORE_ENTRIES;
6272 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6273 r.in.domain_handle = handle;
6274 r.in.level = levels[i];
6275 r.in.max_entries = 2;
6276 r.in.buf_size = (uint32_t)-1;
6277 r.out.total_size = &total_size;
6278 r.out.returned_size = &returned_size;
6279 r.out.info = &disp_info;
6281 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
6282 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
6283 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6284 levels[i], nt_errstr(status));
6287 switch (r.in.level) {
6289 if (!test_each_DisplayInfo_user(p, tctx, &r, &seen_testuser)) {
6292 r.in.start_idx += r.out.info->info1.count;
6295 if (!test_each_DisplayInfo_user(p, tctx, &r, NULL)) {
6298 r.in.start_idx += r.out.info->info2.count;
6301 r.in.start_idx += r.out.info->info3.count;
6304 r.in.start_idx += r.out.info->info4.count;
6307 r.in.start_idx += r.out.info->info5.count;
6311 dom_info.in.domain_handle = handle;
6312 dom_info.in.level = 2;
6313 dom_info.out.info = &info;
6315 /* Check number of users returned is correct */
6316 status = dcerpc_samr_QueryDomainInfo(p, tctx, &dom_info);
6317 if (!NT_STATUS_IS_OK(status)) {
6318 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6319 r.in.level, nt_errstr(status));
6323 switch (r.in.level) {
6326 if (info->general.num_users < r.in.start_idx) {
6327 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6328 r.in.start_idx, info->general.num_groups,
6329 info->general.domain_name.string);
6332 if (!seen_testuser) {
6333 struct policy_handle user_handle;
6334 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
6335 torture_warning(tctx, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
6336 info->general.domain_name.string);
6338 test_samr_handle_Close(p, tctx, &user_handle);
6344 if (info->general.num_groups != r.in.start_idx) {
6345 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6346 r.in.start_idx, info->general.num_groups,
6347 info->general.domain_name.string);
6359 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p,
6360 struct torture_context *tctx,
6361 struct policy_handle *handle)
6364 struct samr_QueryDisplayInfo2 r;
6366 uint16_t levels[] = {1, 2, 3, 4, 5};
6368 uint32_t total_size;
6369 uint32_t returned_size;
6370 union samr_DispInfo info;
6372 for (i=0;i<ARRAY_SIZE(levels);i++) {
6373 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
6375 r.in.domain_handle = handle;
6376 r.in.level = levels[i];
6378 r.in.max_entries = 1000;
6379 r.in.buf_size = (uint32_t)-1;
6380 r.out.total_size = &total_size;
6381 r.out.returned_size = &returned_size;
6384 status = dcerpc_samr_QueryDisplayInfo2(p, tctx, &r);
6385 if (!NT_STATUS_IS_OK(status)) {
6386 torture_warning(tctx, "QueryDisplayInfo2 level %u failed - %s\n",
6387 levels[i], nt_errstr(status));
6395 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
6396 struct policy_handle *handle)
6399 struct samr_QueryDisplayInfo3 r;
6401 uint16_t levels[] = {1, 2, 3, 4, 5};
6403 uint32_t total_size;
6404 uint32_t returned_size;
6405 union samr_DispInfo info;
6407 for (i=0;i<ARRAY_SIZE(levels);i++) {
6408 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
6410 r.in.domain_handle = handle;
6411 r.in.level = levels[i];
6413 r.in.max_entries = 1000;
6414 r.in.buf_size = (uint32_t)-1;
6415 r.out.total_size = &total_size;
6416 r.out.returned_size = &returned_size;
6419 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
6420 if (!NT_STATUS_IS_OK(status)) {
6421 torture_warning(tctx, "QueryDisplayInfo3 level %u failed - %s\n",
6422 levels[i], nt_errstr(status));
6431 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p,
6432 struct torture_context *tctx,
6433 struct policy_handle *handle)
6436 struct samr_QueryDisplayInfo r;
6438 uint32_t total_size;
6439 uint32_t returned_size;
6440 union samr_DispInfo info;
6442 torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
6444 r.in.domain_handle = handle;
6447 r.in.max_entries = 1;
6448 r.in.buf_size = (uint32_t)-1;
6449 r.out.total_size = &total_size;
6450 r.out.returned_size = &returned_size;
6454 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
6455 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
6456 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
6457 torture_warning(tctx, "expected idx %d but got %d\n",
6459 r.out.info->info1.entries[0].idx);
6463 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
6464 !NT_STATUS_IS_OK(status)) {
6465 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6466 r.in.level, nt_errstr(status));
6471 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
6472 NT_STATUS_IS_OK(status)) &&
6473 *r.out.returned_size != 0);
6478 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
6479 struct policy_handle *handle)
6482 struct samr_QueryDomainInfo r;
6483 union samr_DomainInfo *info = NULL;
6484 struct samr_SetDomainInfo s;
6485 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6486 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
6489 const char *domain_comment = talloc_asprintf(tctx,
6490 "Tortured by Samba4 RPC-SAMR: %s",
6491 timestring(tctx, time(NULL)));
6493 s.in.domain_handle = handle;
6495 s.in.info = talloc(tctx, union samr_DomainInfo);
6497 s.in.info->oem.oem_information.string = domain_comment;
6498 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
6499 if (!NT_STATUS_IS_OK(status)) {
6500 torture_warning(tctx, "SetDomainInfo level %u (set comment) failed - %s\n",
6501 s.in.level, nt_errstr(status));
6505 for (i=0;i<ARRAY_SIZE(levels);i++) {
6506 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
6508 r.in.domain_handle = handle;
6509 r.in.level = levels[i];
6512 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
6513 if (!NT_STATUS_IS_OK(status)) {
6514 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6515 r.in.level, nt_errstr(status));
6520 switch (levels[i]) {
6522 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
6523 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6524 levels[i], info->general.oem_information.string, domain_comment);
6525 if (!torture_setting_bool(tctx, "samba3", false)) {
6529 if (!info->general.primary.string) {
6530 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6533 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
6534 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
6535 torture_warning(tctx, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
6536 levels[i], info->general.primary.string, dcerpc_server_name(p));
6541 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
6542 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6543 levels[i], info->oem.oem_information.string, domain_comment);
6544 if (!torture_setting_bool(tctx, "samba3", false)) {
6550 if (!info->info6.primary.string) {
6551 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6557 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
6558 torture_warning(tctx, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
6559 levels[i], info->general2.general.oem_information.string, domain_comment);
6560 if (!torture_setting_bool(tctx, "samba3", false)) {
6567 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
6569 s.in.domain_handle = handle;
6570 s.in.level = levels[i];
6573 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
6575 if (!NT_STATUS_IS_OK(status)) {
6576 torture_warning(tctx, "SetDomainInfo level %u failed - %s\n",
6577 r.in.level, nt_errstr(status));
6582 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
6583 torture_warning(tctx, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6584 r.in.level, nt_errstr(status));
6590 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
6591 if (!NT_STATUS_IS_OK(status)) {
6592 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6593 r.in.level, nt_errstr(status));
6603 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
6604 struct policy_handle *handle)
6607 struct samr_QueryDomainInfo2 r;
6608 union samr_DomainInfo *info = NULL;
6609 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6613 for (i=0;i<ARRAY_SIZE(levels);i++) {
6614 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
6616 r.in.domain_handle = handle;
6617 r.in.level = levels[i];
6620 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
6621 if (!NT_STATUS_IS_OK(status)) {
6622 torture_warning(tctx, "QueryDomainInfo2 level %u failed - %s\n",
6623 r.in.level, nt_errstr(status));
6632 /* Test whether querydispinfo level 5 and enumdomgroups return the same
6633 set of group names. */
6634 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
6635 struct policy_handle *handle)
6637 struct samr_EnumDomainGroups q1;
6638 struct samr_QueryDisplayInfo q2;
6640 uint32_t resume_handle=0;
6641 struct samr_SamArray *sam = NULL;
6642 uint32_t num_entries = 0;
6645 uint32_t total_size;
6646 uint32_t returned_size;
6647 union samr_DispInfo info;
6650 const char **names = NULL;
6652 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
6654 q1.in.domain_handle = handle;
6655 q1.in.resume_handle = &resume_handle;
6657 q1.out.resume_handle = &resume_handle;
6658 q1.out.num_entries = &num_entries;
6661 status = STATUS_MORE_ENTRIES;
6662 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6663 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
6665 if (!NT_STATUS_IS_OK(status) &&
6666 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6669 for (i=0; i<*q1.out.num_entries; i++) {
6670 add_string_to_array(tctx,
6671 sam->entries[i].name.string,
6672 &names, &num_names);
6676 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
6678 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
6680 q2.in.domain_handle = handle;
6682 q2.in.start_idx = 0;
6683 q2.in.max_entries = 5;
6684 q2.in.buf_size = (uint32_t)-1;
6685 q2.out.total_size = &total_size;
6686 q2.out.returned_size = &returned_size;
6687 q2.out.info = &info;
6689 status = STATUS_MORE_ENTRIES;
6690 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6691 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
6693 if (!NT_STATUS_IS_OK(status) &&
6694 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6697 for (i=0; i<q2.out.info->info5.count; i++) {
6699 const char *name = q2.out.info->info5.entries[i].account_name.string;
6701 for (j=0; j<num_names; j++) {
6702 if (names[j] == NULL)
6704 if (strequal(names[j], name)) {
6712 torture_warning(tctx, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
6717 q2.in.start_idx += q2.out.info->info5.count;
6720 if (!NT_STATUS_IS_OK(status)) {
6721 torture_warning(tctx, "QueryDisplayInfo level 5 failed - %s\n",
6726 for (i=0; i<num_names; i++) {
6727 if (names[i] != NULL) {
6728 torture_warning(tctx, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
6737 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
6738 struct policy_handle *group_handle)
6740 struct samr_DeleteDomainGroup d;
6743 torture_comment(tctx, "Testing DeleteDomainGroup\n");
6745 d.in.group_handle = group_handle;
6746 d.out.group_handle = group_handle;
6748 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
6749 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
6754 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6755 struct policy_handle *domain_handle)
6757 struct samr_TestPrivateFunctionsDomain r;
6761 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
6763 r.in.domain_handle = domain_handle;
6765 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
6766 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
6771 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
6772 struct dom_sid *domain_sid,
6773 struct policy_handle *domain_handle)
6775 struct samr_RidToSid r;
6778 struct dom_sid *calc_sid, *out_sid;
6779 int rids[] = { 0, 42, 512, 10200 };
6782 for (i=0;i<ARRAY_SIZE(rids);i++) {
6783 torture_comment(tctx, "Testing RidToSid\n");
6785 calc_sid = dom_sid_dup(tctx, domain_sid);
6786 r.in.domain_handle = domain_handle;
6788 r.out.sid = &out_sid;
6790 status = dcerpc_samr_RidToSid(p, tctx, &r);
6791 if (!NT_STATUS_IS_OK(status)) {
6792 torture_warning(tctx, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
6795 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
6797 if (!dom_sid_equal(calc_sid, out_sid)) {
6798 torture_warning(tctx, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
6799 dom_sid_string(tctx, out_sid),
6800 dom_sid_string(tctx, calc_sid));
6809 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
6810 struct policy_handle *domain_handle)
6812 struct samr_GetBootKeyInformation r;
6815 uint32_t unknown = 0;
6817 torture_comment(tctx, "Testing GetBootKeyInformation\n");
6819 r.in.domain_handle = domain_handle;
6820 r.out.unknown = &unknown;
6822 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
6823 if (!NT_STATUS_IS_OK(status)) {
6824 /* w2k3 seems to fail this sometimes and pass it sometimes */
6825 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
6831 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
6832 struct policy_handle *domain_handle,
6833 struct policy_handle *group_handle)
6836 struct samr_AddGroupMember r;
6837 struct samr_DeleteGroupMember d;
6838 struct samr_QueryGroupMember q;
6839 struct samr_RidTypeArray *rids = NULL;
6840 struct samr_SetMemberAttributesOfGroup s;
6842 bool found_member = false;
6845 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
6846 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
6848 r.in.group_handle = group_handle;
6850 r.in.flags = 0; /* ??? */
6852 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
6854 d.in.group_handle = group_handle;
6857 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
6858 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
6860 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
6861 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
6863 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
6864 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
6866 if (torture_setting_bool(tctx, "samba4", false) ||
6867 torture_setting_bool(tctx, "samba3", false)) {
6868 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
6870 /* this one is quite strange. I am using random inputs in the
6871 hope of triggering an error that might give us a clue */
6873 s.in.group_handle = group_handle;
6874 s.in.unknown1 = random();
6875 s.in.unknown2 = random();
6877 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
6878 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
6881 q.in.group_handle = group_handle;
6884 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
6885 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
6886 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
6888 for (i=0; i < rids->count; i++) {
6889 if (rids->rids[i] == rid) {
6890 found_member = true;
6894 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
6896 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
6897 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
6900 found_member = false;
6902 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
6903 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
6904 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
6906 for (i=0; i < rids->count; i++) {
6907 if (rids->rids[i] == rid) {
6908 found_member = true;
6912 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
6914 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
6915 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
6921 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
6922 struct torture_context *tctx,
6923 struct policy_handle *domain_handle,
6924 const char *group_name,
6925 struct policy_handle *group_handle,
6926 struct dom_sid *domain_sid,
6930 struct samr_CreateDomainGroup r;
6932 struct lsa_String name;
6935 init_lsa_String(&name, group_name);
6937 r.in.domain_handle = domain_handle;
6939 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6940 r.out.group_handle = group_handle;
6943 torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
6945 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6947 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
6948 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6949 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
6952 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
6958 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
6959 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
6960 torture_warning(tctx, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
6964 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6966 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
6967 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
6969 torture_warning(tctx, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
6973 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6975 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
6981 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
6982 torture_warning(tctx, "CreateDomainGroup failed - %s\n", nt_errstr(status));
6986 if (!test_SetGroupInfo(p, tctx, group_handle)) {
6995 its not totally clear what this does. It seems to accept any sid you like.
6997 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
6998 struct torture_context *tctx,
6999 struct policy_handle *domain_handle)
7002 struct samr_RemoveMemberFromForeignDomain r;
7004 r.in.domain_handle = domain_handle;
7005 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
7007 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
7008 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
7013 static bool test_EnumDomainUsers(struct dcerpc_pipe *p,
7014 struct torture_context *tctx,
7015 struct policy_handle *domain_handle,
7016 uint32_t *total_num_entries_p)
7019 struct samr_EnumDomainUsers r;
7020 uint32_t resume_handle = 0;
7021 uint32_t num_entries = 0;
7022 uint32_t total_num_entries = 0;
7023 struct samr_SamArray *sam;
7025 r.in.domain_handle = domain_handle;
7026 r.in.acct_flags = 0;
7027 r.in.max_size = (uint32_t)-1;
7028 r.in.resume_handle = &resume_handle;
7031 r.out.num_entries = &num_entries;
7032 r.out.resume_handle = &resume_handle;
7034 torture_comment(tctx, "Testing EnumDomainUsers\n");
7037 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
7038 if (NT_STATUS_IS_ERR(status)) {
7039 torture_assert_ntstatus_ok(tctx, status,
7040 "failed to enumerate users");
7043 total_num_entries += num_entries;
7044 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7046 if (total_num_entries_p) {
7047 *total_num_entries_p = total_num_entries;
7053 static bool test_EnumDomainGroups(struct dcerpc_pipe *p,
7054 struct torture_context *tctx,
7055 struct policy_handle *domain_handle,
7056 uint32_t *total_num_entries_p)
7059 struct samr_EnumDomainGroups r;
7060 uint32_t resume_handle = 0;
7061 uint32_t num_entries = 0;
7062 uint32_t total_num_entries = 0;
7063 struct samr_SamArray *sam;
7065 r.in.domain_handle = domain_handle;
7066 r.in.max_size = (uint32_t)-1;
7067 r.in.resume_handle = &resume_handle;
7070 r.out.num_entries = &num_entries;
7071 r.out.resume_handle = &resume_handle;
7073 torture_comment(tctx, "Testing EnumDomainGroups\n");
7076 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
7077 if (NT_STATUS_IS_ERR(status)) {
7078 torture_assert_ntstatus_ok(tctx, status,
7079 "failed to enumerate groups");
7082 total_num_entries += num_entries;
7083 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7085 if (total_num_entries_p) {
7086 *total_num_entries_p = total_num_entries;
7092 static bool test_EnumDomainAliases(struct dcerpc_pipe *p,
7093 struct torture_context *tctx,
7094 struct policy_handle *domain_handle,
7095 uint32_t *total_num_entries_p)
7098 struct samr_EnumDomainAliases r;
7099 uint32_t resume_handle = 0;
7100 uint32_t num_entries = 0;
7101 uint32_t total_num_entries = 0;
7102 struct samr_SamArray *sam;
7104 r.in.domain_handle = domain_handle;
7105 r.in.max_size = (uint32_t)-1;
7106 r.in.resume_handle = &resume_handle;
7109 r.out.num_entries = &num_entries;
7110 r.out.resume_handle = &resume_handle;
7112 torture_comment(tctx, "Testing EnumDomainAliases\n");
7115 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
7116 if (NT_STATUS_IS_ERR(status)) {
7117 torture_assert_ntstatus_ok(tctx, status,
7118 "failed to enumerate aliases");
7121 total_num_entries += num_entries;
7122 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7124 if (total_num_entries_p) {
7125 *total_num_entries_p = total_num_entries;
7131 static bool test_QueryDisplayInfo_level(struct dcerpc_pipe *p,
7132 struct torture_context *tctx,
7133 struct policy_handle *handle,
7135 uint32_t *total_num_entries_p)
7138 struct samr_QueryDisplayInfo r;
7139 uint32_t total_num_entries = 0;
7141 r.in.domain_handle = handle;
7144 r.in.max_entries = (uint32_t)-1;
7145 r.in.buf_size = (uint32_t)-1;
7147 torture_comment(tctx, "Testing QueryDisplayInfo\n");
7150 uint32_t total_size;
7151 uint32_t returned_size;
7152 union samr_DispInfo info;
7154 r.out.total_size = &total_size;
7155 r.out.returned_size = &returned_size;
7158 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
7159 if (NT_STATUS_IS_ERR(status)) {
7160 torture_assert_ntstatus_ok(tctx, status,
7161 "failed to query displayinfo");
7164 if (*r.out.returned_size == 0) {
7168 switch (r.in.level) {
7170 total_num_entries += info.info1.count;
7171 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
7174 total_num_entries += info.info2.count;
7175 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
7178 total_num_entries += info.info3.count;
7179 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
7182 total_num_entries += info.info4.count;
7183 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
7186 total_num_entries += info.info5.count;
7187 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
7193 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7195 if (total_num_entries_p) {
7196 *total_num_entries_p = total_num_entries;
7202 static bool test_ManyObjects(struct dcerpc_pipe *p,
7203 struct torture_context *tctx,
7204 struct policy_handle *domain_handle,
7205 struct dom_sid *domain_sid,
7206 struct torture_samr_context *ctx)
7208 uint32_t num_total = ctx->num_objects_large_dc;
7209 uint32_t num_enum = 0;
7210 uint32_t num_disp = 0;
7211 uint32_t num_created = 0;
7212 uint32_t num_anounced = 0;
7217 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
7222 struct samr_QueryDomainInfo2 r;
7223 union samr_DomainInfo *info;
7224 r.in.domain_handle = domain_handle;
7228 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
7229 torture_assert_ntstatus_ok(tctx, status,
7230 "failed to query domain info");
7232 switch (ctx->choice) {
7233 case TORTURE_SAMR_MANY_ACCOUNTS:
7234 num_anounced = info->general.num_users;
7236 case TORTURE_SAMR_MANY_GROUPS:
7237 num_anounced = info->general.num_groups;
7239 case TORTURE_SAMR_MANY_ALIASES:
7240 num_anounced = info->general.num_aliases;
7249 for (i=0; i < num_total; i++) {
7251 const char *name = NULL;
7253 switch (ctx->choice) {
7254 case TORTURE_SAMR_MANY_ACCOUNTS:
7255 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
7256 ret &= test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false);
7258 case TORTURE_SAMR_MANY_GROUPS:
7259 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
7260 ret &= test_CreateDomainGroup(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
7262 case TORTURE_SAMR_MANY_ALIASES:
7263 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
7264 ret &= test_CreateAlias(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
7269 if (!policy_handle_empty(&handles[i])) {
7276 switch (ctx->choice) {
7277 case TORTURE_SAMR_MANY_ACCOUNTS:
7278 ret &= test_EnumDomainUsers(p, tctx, domain_handle, &num_enum);
7280 case TORTURE_SAMR_MANY_GROUPS:
7281 ret &= test_EnumDomainGroups(p, tctx, domain_handle, &num_enum);
7283 case TORTURE_SAMR_MANY_ALIASES:
7284 ret &= test_EnumDomainAliases(p, tctx, domain_handle, &num_enum);
7292 switch (ctx->choice) {
7293 case TORTURE_SAMR_MANY_ACCOUNTS:
7294 ret &= test_QueryDisplayInfo_level(p, tctx, domain_handle, 1, &num_disp);
7296 case TORTURE_SAMR_MANY_GROUPS:
7297 ret &= test_QueryDisplayInfo_level(p, tctx, domain_handle, 3, &num_disp);
7299 case TORTURE_SAMR_MANY_ALIASES:
7300 /* no aliases in dispinfo */
7306 /* close or delete */
7308 for (i=0; i < num_total; i++) {
7310 if (policy_handle_empty(&handles[i])) {
7314 if (torture_setting_bool(tctx, "samba3", false)) {
7315 ret &= test_samr_handle_Close(p, tctx, &handles[i]);
7317 switch (ctx->choice) {
7318 case TORTURE_SAMR_MANY_ACCOUNTS:
7319 ret &= test_DeleteUser(p, tctx, &handles[i]);
7321 case TORTURE_SAMR_MANY_GROUPS:
7322 ret &= test_DeleteDomainGroup(p, tctx, &handles[i]);
7324 case TORTURE_SAMR_MANY_ALIASES:
7325 ret &= test_DeleteAlias(p, tctx, &handles[i]);
7333 talloc_free(handles);
7335 if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
7336 torture_comment(tctx,
7337 "unexpected number of results (%u) returned in enum call, expected %u\n",
7338 num_enum, num_anounced + num_created);
7340 torture_comment(tctx,
7341 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
7342 num_disp, num_anounced + num_created);
7347 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
7348 struct policy_handle *handle);
7350 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7351 struct torture_samr_context *ctx, struct dom_sid *sid)
7354 struct samr_OpenDomain r;
7355 struct policy_handle domain_handle;
7356 struct policy_handle alias_handle;
7357 struct policy_handle user_handle;
7358 struct policy_handle group_handle;
7361 ZERO_STRUCT(alias_handle);
7362 ZERO_STRUCT(user_handle);
7363 ZERO_STRUCT(group_handle);
7364 ZERO_STRUCT(domain_handle);
7366 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
7368 r.in.connect_handle = &ctx->handle;
7369 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7371 r.out.domain_handle = &domain_handle;
7373 status = dcerpc_samr_OpenDomain(p, tctx, &r);
7374 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
7376 /* run the domain tests with the main handle closed - this tests
7377 the servers reference counting */
7378 torture_assert(tctx, test_samr_handle_Close(p, tctx, &ctx->handle), "Failed to close SAMR handle");
7380 switch (ctx->choice) {
7381 case TORTURE_SAMR_PASSWORDS:
7382 case TORTURE_SAMR_USER_PRIVILEGES:
7383 if (!torture_setting_bool(tctx, "samba3", false)) {
7384 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7386 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7388 torture_warning(tctx, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
7391 case TORTURE_SAMR_USER_ATTRIBUTES:
7392 if (!torture_setting_bool(tctx, "samba3", false)) {
7393 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7395 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7396 /* This test needs 'complex' users to validate */
7397 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
7399 torture_warning(tctx, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
7402 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
7403 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
7404 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
7405 if (!torture_setting_bool(tctx, "samba3", false)) {
7406 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
7408 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
7410 torture_warning(tctx, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx, sid));
7413 case TORTURE_SAMR_MANY_ACCOUNTS:
7414 case TORTURE_SAMR_MANY_GROUPS:
7415 case TORTURE_SAMR_MANY_ALIASES:
7416 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
7418 torture_warning(tctx, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
7421 case TORTURE_SAMR_OTHER:
7422 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7424 torture_warning(tctx, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
7426 if (!torture_setting_bool(tctx, "samba3", false)) {
7427 ret &= test_QuerySecurity(p, tctx, &domain_handle);
7429 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
7430 ret &= test_CreateAlias(p, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
7431 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
7432 ret &= test_GetAliasMembership(p, tctx, &domain_handle);
7433 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
7434 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
7435 ret &= test_EnumDomainUsers_all(p, tctx, &domain_handle);
7436 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
7437 ret &= test_EnumDomainGroups_all(p, tctx, &domain_handle);
7438 ret &= test_EnumDomainAliases_all(p, tctx, &domain_handle);
7439 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
7440 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
7441 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
7443 if (torture_setting_bool(tctx, "samba4", false)) {
7444 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
7446 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
7447 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
7449 ret &= test_GroupList(p, tctx, &domain_handle);
7450 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
7451 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
7452 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
7454 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
7459 if (!policy_handle_empty(&user_handle) &&
7460 !test_DeleteUser(p, tctx, &user_handle)) {
7464 if (!policy_handle_empty(&alias_handle) &&
7465 !test_DeleteAlias(p, tctx, &alias_handle)) {
7469 if (!policy_handle_empty(&group_handle) &&
7470 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
7474 torture_assert(tctx, test_samr_handle_Close(p, tctx, &domain_handle), "Failed to close SAMR domain handle");
7476 torture_assert(tctx, test_Connect(p, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
7477 /* reconnect the main handle */
7480 torture_warning(tctx, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
7486 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7487 struct torture_samr_context *ctx, const char *domain)
7490 struct samr_LookupDomain r;
7491 struct dom_sid2 *sid = NULL;
7492 struct lsa_String n1;
7493 struct lsa_String n2;
7496 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
7498 /* check for correct error codes */
7499 r.in.connect_handle = &ctx->handle;
7500 r.in.domain_name = &n2;
7504 status = dcerpc_samr_LookupDomain(p, tctx, &r);
7505 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
7507 init_lsa_String(&n2, "xxNODOMAINxx");
7509 status = dcerpc_samr_LookupDomain(p, tctx, &r);
7510 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
7512 r.in.connect_handle = &ctx->handle;
7514 init_lsa_String(&n1, domain);
7515 r.in.domain_name = &n1;
7517 status = dcerpc_samr_LookupDomain(p, tctx, &r);
7518 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
7520 if (!test_GetDomPwInfo(p, tctx, &n1)) {
7524 if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
7532 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
7533 struct torture_samr_context *ctx)
7536 struct samr_EnumDomains r;
7537 uint32_t resume_handle = 0;
7538 uint32_t num_entries = 0;
7539 struct samr_SamArray *sam = NULL;
7543 r.in.connect_handle = &ctx->handle;
7544 r.in.resume_handle = &resume_handle;
7545 r.in.buf_size = (uint32_t)-1;
7546 r.out.resume_handle = &resume_handle;
7547 r.out.num_entries = &num_entries;
7550 status = dcerpc_samr_EnumDomains(p, tctx, &r);
7551 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
7557 for (i=0;i<sam->count;i++) {
7558 if (!test_LookupDomain(p, tctx, ctx,
7559 sam->entries[i].name.string)) {
7564 status = dcerpc_samr_EnumDomains(p, tctx, &r);
7565 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
7571 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
7572 struct policy_handle *handle)
7575 struct samr_Connect r;
7576 struct samr_Connect2 r2;
7577 struct samr_Connect3 r3;
7578 struct samr_Connect4 r4;
7579 struct samr_Connect5 r5;
7580 union samr_ConnectInfo info;
7581 struct policy_handle h;
7582 uint32_t level_out = 0;
7583 bool ret = true, got_handle = false;
7585 torture_comment(tctx, "testing samr_Connect\n");
7587 r.in.system_name = 0;
7588 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7589 r.out.connect_handle = &h;
7591 status = dcerpc_samr_Connect(p, tctx, &r);
7592 if (!NT_STATUS_IS_OK(status)) {
7593 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
7600 torture_comment(tctx, "testing samr_Connect2\n");
7602 r2.in.system_name = NULL;
7603 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7604 r2.out.connect_handle = &h;
7606 status = dcerpc_samr_Connect2(p, tctx, &r2);
7607 if (!NT_STATUS_IS_OK(status)) {
7608 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
7612 test_samr_handle_Close(p, tctx, handle);
7618 torture_comment(tctx, "testing samr_Connect3\n");
7620 r3.in.system_name = NULL;
7622 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7623 r3.out.connect_handle = &h;
7625 status = dcerpc_samr_Connect3(p, tctx, &r3);
7626 if (!NT_STATUS_IS_OK(status)) {
7627 torture_warning(tctx, "Connect3 failed - %s\n", nt_errstr(status));
7631 test_samr_handle_Close(p, tctx, handle);
7637 torture_comment(tctx, "testing samr_Connect4\n");
7639 r4.in.system_name = "";
7640 r4.in.client_version = 0;
7641 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7642 r4.out.connect_handle = &h;
7644 status = dcerpc_samr_Connect4(p, tctx, &r4);
7645 if (!NT_STATUS_IS_OK(status)) {
7646 torture_warning(tctx, "Connect4 failed - %s\n", nt_errstr(status));
7650 test_samr_handle_Close(p, tctx, handle);
7656 torture_comment(tctx, "testing samr_Connect5\n");
7658 info.info1.client_version = 0;
7659 info.info1.unknown2 = 0;
7661 r5.in.system_name = "";
7662 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7664 r5.out.level_out = &level_out;
7665 r5.in.info_in = &info;
7666 r5.out.info_out = &info;
7667 r5.out.connect_handle = &h;
7669 status = dcerpc_samr_Connect5(p, tctx, &r5);
7670 if (!NT_STATUS_IS_OK(status)) {
7671 torture_warning(tctx, "Connect5 failed - %s\n", nt_errstr(status));
7675 test_samr_handle_Close(p, tctx, handle);
7685 static bool test_samr_ValidatePassword(struct dcerpc_pipe *p, struct torture_context *tctx)
7687 struct samr_ValidatePassword r;
7688 union samr_ValidatePasswordReq req;
7689 union samr_ValidatePasswordRep *repp = NULL;
7691 const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
7694 torture_comment(tctx, "testing samr_ValidatePassword\n");
7697 r.in.level = NetValidatePasswordReset;
7702 req.req3.account.string = "non-existant-account-aklsdji";
7704 for (i=0; passwords[i]; i++) {
7705 req.req3.password.string = passwords[i];
7706 status = dcerpc_samr_ValidatePassword(p, tctx, &r);
7707 torture_assert_ntstatus_ok(tctx, status, "samr_ValidatePassword");
7708 torture_comment(tctx, "Server %s password '%s' with code %i\n",
7709 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
7710 req.req3.password.string, repp->ctr3.status);
7716 bool torture_rpc_samr(struct torture_context *torture)
7719 struct dcerpc_pipe *p;
7721 struct torture_samr_context *ctx;
7723 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7724 if (!NT_STATUS_IS_OK(status)) {
7728 ctx = talloc_zero(torture, struct torture_samr_context);
7730 ctx->choice = TORTURE_SAMR_OTHER;
7732 ret &= test_Connect(p, torture, &ctx->handle);
7734 if (!torture_setting_bool(torture, "samba3", false)) {
7735 ret &= test_QuerySecurity(p, torture, &ctx->handle);
7738 ret &= test_EnumDomains(p, torture, ctx);
7740 ret &= test_SetDsrmPassword(p, torture, &ctx->handle);
7742 ret &= test_Shutdown(p, torture, &ctx->handle);
7744 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7750 bool torture_rpc_samr_users(struct torture_context *torture)
7753 struct dcerpc_pipe *p;
7755 struct torture_samr_context *ctx;
7757 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7758 if (!NT_STATUS_IS_OK(status)) {
7762 ctx = talloc_zero(torture, struct torture_samr_context);
7764 ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
7766 ret &= test_Connect(p, torture, &ctx->handle);
7768 if (!torture_setting_bool(torture, "samba3", false)) {
7769 ret &= test_QuerySecurity(p, torture, &ctx->handle);
7772 ret &= test_EnumDomains(p, torture, ctx);
7774 ret &= test_SetDsrmPassword(p, torture, &ctx->handle);
7776 ret &= test_Shutdown(p, torture, &ctx->handle);
7778 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7784 bool torture_rpc_samr_passwords(struct torture_context *torture)
7787 struct dcerpc_pipe *p;
7789 struct torture_samr_context *ctx;
7791 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7792 if (!NT_STATUS_IS_OK(status)) {
7796 ctx = talloc_zero(torture, struct torture_samr_context);
7798 ctx->choice = TORTURE_SAMR_PASSWORDS;
7800 ret &= test_Connect(p, torture, &ctx->handle);
7802 ret &= test_EnumDomains(p, torture, ctx);
7804 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7806 ret &= test_samr_ValidatePassword(p, torture);
7811 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
7812 struct dcerpc_pipe *p2,
7813 struct cli_credentials *machine_credentials)
7816 struct dcerpc_pipe *p;
7818 struct torture_samr_context *ctx;
7820 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7821 if (!NT_STATUS_IS_OK(status)) {
7825 ctx = talloc_zero(torture, struct torture_samr_context);
7827 ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
7828 ctx->machine_credentials = machine_credentials;
7830 ret &= test_Connect(p, torture, &ctx->handle);
7832 ret &= test_EnumDomains(p, torture, ctx);
7834 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7839 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
7841 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
7842 struct torture_rpc_tcase *tcase;
7844 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
7846 TEST_ACCOUNT_NAME_PWD);
7848 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
7849 torture_rpc_samr_pwdlastset);
7854 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
7855 struct dcerpc_pipe *p2,
7856 struct cli_credentials *machine_credentials)
7859 struct dcerpc_pipe *p;
7861 struct torture_samr_context *ctx;
7863 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7864 if (!NT_STATUS_IS_OK(status)) {
7868 ctx = talloc_zero(torture, struct torture_samr_context);
7870 ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
7871 ctx->machine_credentials = machine_credentials;
7873 ret &= test_Connect(p, torture, &ctx->handle);
7875 ret &= test_EnumDomains(p, torture, ctx);
7877 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7882 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
7884 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-USERS-PRIVILEGES");
7885 struct torture_rpc_tcase *tcase;
7887 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
7889 TEST_ACCOUNT_NAME_PWD);
7891 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
7892 torture_rpc_samr_users_privileges_delete_user);
7897 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
7898 struct dcerpc_pipe *p2,
7902 struct dcerpc_pipe *p;
7904 struct torture_samr_context *ctx =
7905 talloc_get_type_abort(data, struct torture_samr_context);
7907 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7908 if (!NT_STATUS_IS_OK(status)) {
7912 ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
7913 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
7914 ctx->num_objects_large_dc);
7916 ret &= test_Connect(p, torture, &ctx->handle);
7918 ret &= test_EnumDomains(p, torture, ctx);
7920 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7925 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
7926 struct dcerpc_pipe *p2,
7930 struct dcerpc_pipe *p;
7932 struct torture_samr_context *ctx =
7933 talloc_get_type_abort(data, struct torture_samr_context);
7935 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7936 if (!NT_STATUS_IS_OK(status)) {
7940 ctx->choice = TORTURE_SAMR_MANY_GROUPS;
7941 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
7942 ctx->num_objects_large_dc);
7944 ret &= test_Connect(p, torture, &ctx->handle);
7946 ret &= test_EnumDomains(p, torture, ctx);
7948 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7953 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
7954 struct dcerpc_pipe *p2,
7958 struct dcerpc_pipe *p;
7960 struct torture_samr_context *ctx =
7961 talloc_get_type_abort(data, struct torture_samr_context);
7963 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7964 if (!NT_STATUS_IS_OK(status)) {
7968 ctx->choice = TORTURE_SAMR_MANY_ALIASES;
7969 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
7970 ctx->num_objects_large_dc);
7972 ret &= test_Connect(p, torture, &ctx->handle);
7974 ret &= test_EnumDomains(p, torture, ctx);
7976 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7981 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
7983 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-LARGE-DC");
7984 struct torture_rpc_tcase *tcase;
7985 struct torture_samr_context *ctx;
7987 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
7989 ctx = talloc_zero(suite, struct torture_samr_context);
7990 ctx->num_objects_large_dc = 150;
7992 torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
7993 torture_rpc_samr_many_aliases, ctx);
7994 torture_rpc_tcase_add_test_ex(tcase, "many_groups",
7995 torture_rpc_samr_many_groups, ctx);
7996 torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
7997 torture_rpc_samr_many_accounts, ctx);
8002 static bool torture_rpc_samr_badpwdcount(struct torture_context *torture,
8003 struct dcerpc_pipe *p2,
8004 struct cli_credentials *machine_credentials)
8007 struct dcerpc_pipe *p;
8009 struct torture_samr_context *ctx;
8011 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8012 if (!NT_STATUS_IS_OK(status)) {
8016 ctx = talloc_zero(torture, struct torture_samr_context);
8018 ctx->choice = TORTURE_SAMR_PASSWORDS_BADPWDCOUNT;
8019 ctx->machine_credentials = machine_credentials;
8021 ret &= test_Connect(p, torture, &ctx->handle);
8023 ret &= test_EnumDomains(p, torture, ctx);
8025 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
8030 struct torture_suite *torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX *mem_ctx)
8032 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-BADPWDCOUNT");
8033 struct torture_rpc_tcase *tcase;
8035 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8037 TEST_ACCOUNT_NAME_PWD);
8039 torture_rpc_tcase_add_test_creds(tcase, "badPwdCount",
8040 torture_rpc_samr_badpwdcount);
8045 static bool torture_rpc_samr_lockout(struct torture_context *torture,
8046 struct dcerpc_pipe *p2,
8047 struct cli_credentials *machine_credentials)
8050 struct dcerpc_pipe *p;
8052 struct torture_samr_context *ctx;
8054 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8055 if (!NT_STATUS_IS_OK(status)) {
8059 ctx = talloc_zero(torture, struct torture_samr_context);
8061 ctx->choice = TORTURE_SAMR_PASSWORDS_LOCKOUT;
8062 ctx->machine_credentials = machine_credentials;
8064 ret &= test_Connect(p, torture, &ctx->handle);
8066 ret &= test_EnumDomains(p, torture, ctx);
8068 ret &= test_samr_handle_Close(p, torture, &ctx->handle);
8073 struct torture_suite *torture_rpc_samr_passwords_lockout(TALLOC_CTX *mem_ctx)
8075 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-LOCKOUT");
8076 struct torture_rpc_tcase *tcase;
8078 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8080 TEST_ACCOUNT_NAME_PWD);
8082 torture_rpc_tcase_add_test_creds(tcase, "lockout",
8083 torture_rpc_samr_lockout);