2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7 Copyright (C) Guenther Deschner 2008-2010
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "torture/torture.h"
25 #include "system/time.h"
26 #include "librpc/gen_ndr/lsa.h"
27 #include "librpc/gen_ndr/ndr_netlogon.h"
28 #include "librpc/gen_ndr/ndr_netlogon_c.h"
29 #include "librpc/gen_ndr/ndr_samr_c.h"
30 #include "librpc/gen_ndr/ndr_lsa_c.h"
31 #include "../lib/crypto/crypto.h"
32 #include "libcli/auth/libcli_auth.h"
33 #include "libcli/security/security.h"
34 #include "torture/rpc/rpc.h"
35 #include "param/param.h"
36 #include "auth/gensec/gensec.h"
37 #include "auth/gensec/gensec_proto.h"
38 #include "../libcli/auth/schannel.h"
39 #include "auth/gensec/schannel_state.h"
43 #define TEST_ACCOUNT_NAME "samrtorturetest"
44 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
45 #define TEST_ALIASNAME "samrtorturetestalias"
46 #define TEST_GROUPNAME "samrtorturetestgroup"
47 #define TEST_MACHINENAME "samrtestmach$"
48 #define TEST_DOMAINNAME "samrtestdom$"
50 enum torture_samr_choice
{
51 TORTURE_SAMR_PASSWORDS
,
52 TORTURE_SAMR_PASSWORDS_PWDLASTSET
,
53 TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
,
54 TORTURE_SAMR_PASSWORDS_LOCKOUT
,
55 TORTURE_SAMR_USER_ATTRIBUTES
,
56 TORTURE_SAMR_USER_PRIVILEGES
,
58 TORTURE_SAMR_MANY_ACCOUNTS
,
59 TORTURE_SAMR_MANY_GROUPS
,
60 TORTURE_SAMR_MANY_ALIASES
63 struct torture_samr_context
{
64 struct policy_handle handle
;
65 struct cli_credentials
*machine_credentials
;
66 enum torture_samr_choice choice
;
67 uint32_t num_objects_large_dc
;
70 static bool test_QueryUserInfo(struct dcerpc_pipe
*p
,
71 struct torture_context
*tctx
,
72 struct policy_handle
*handle
);
74 static bool test_QueryUserInfo2(struct dcerpc_pipe
*p
,
75 struct torture_context
*tctx
,
76 struct policy_handle
*handle
);
78 static bool test_QueryAliasInfo(struct dcerpc_pipe
*p
,
79 struct torture_context
*tctx
,
80 struct policy_handle
*handle
);
82 static bool test_ChangePassword(struct dcerpc_pipe
*p
,
83 struct torture_context
*tctx
,
84 const char *acct_name
,
85 struct policy_handle
*domain_handle
, char **password
);
87 static void init_lsa_String(struct lsa_String
*string
, const char *s
)
92 static void init_lsa_StringLarge(struct lsa_StringLarge
*string
, const char *s
)
97 static void init_lsa_BinaryString(struct lsa_BinaryString
*string
, const char *s
, uint32_t length
)
99 string
->length
= length
;
100 string
->size
= length
;
101 string
->array
= (uint16_t *)discard_const(s
);
104 bool test_samr_handle_Close(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
105 struct policy_handle
*handle
)
110 r
.in
.handle
= handle
;
111 r
.out
.handle
= handle
;
113 status
= dcerpc_samr_Close(p
, tctx
, &r
);
114 torture_assert_ntstatus_ok(tctx
, status
, "Close");
119 static bool test_Shutdown(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
120 struct policy_handle
*handle
)
123 struct samr_Shutdown r
;
125 if (!torture_setting_bool(tctx
, "dangerous", false)) {
126 torture_skip(tctx
, "samr_Shutdown disabled - enable dangerous tests to use\n");
130 r
.in
.connect_handle
= handle
;
132 torture_comment(tctx
, "testing samr_Shutdown\n");
134 status
= dcerpc_samr_Shutdown(p
, tctx
, &r
);
135 torture_assert_ntstatus_ok(tctx
, status
, "samr_Shutdown");
140 static bool test_SetDsrmPassword(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
141 struct policy_handle
*handle
)
144 struct samr_SetDsrmPassword r
;
145 struct lsa_String string
;
146 struct samr_Password hash
;
148 if (!torture_setting_bool(tctx
, "dangerous", false)) {
149 torture_skip(tctx
, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
152 E_md4hash("TeSTDSRM123", hash
.hash
);
154 init_lsa_String(&string
, "Administrator");
160 torture_comment(tctx
, "testing samr_SetDsrmPassword\n");
162 status
= dcerpc_samr_SetDsrmPassword(p
, tctx
, &r
);
163 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_NOT_SUPPORTED
, "samr_SetDsrmPassword");
169 static bool test_QuerySecurity(struct dcerpc_pipe
*p
,
170 struct torture_context
*tctx
,
171 struct policy_handle
*handle
)
174 struct samr_QuerySecurity r
;
175 struct samr_SetSecurity s
;
176 struct sec_desc_buf
*sdbuf
= NULL
;
178 r
.in
.handle
= handle
;
180 r
.out
.sdbuf
= &sdbuf
;
182 status
= dcerpc_samr_QuerySecurity(p
, tctx
, &r
);
183 torture_assert_ntstatus_ok(tctx
, status
, "QuerySecurity");
185 torture_assert(tctx
, sdbuf
!= NULL
, "sdbuf is NULL");
187 s
.in
.handle
= handle
;
191 if (torture_setting_bool(tctx
, "samba4", false)) {
192 torture_skip(tctx
, "skipping SetSecurity test against Samba4\n");
195 status
= dcerpc_samr_SetSecurity(p
, tctx
, &s
);
196 torture_assert_ntstatus_ok(tctx
, status
, "SetSecurity");
198 status
= dcerpc_samr_QuerySecurity(p
, tctx
, &r
);
199 torture_assert_ntstatus_ok(tctx
, status
, "QuerySecurity");
205 static bool test_SetUserInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
206 struct policy_handle
*handle
, uint32_t base_acct_flags
,
207 const char *base_account_name
)
210 struct samr_SetUserInfo s
;
211 struct samr_SetUserInfo2 s2
;
212 struct samr_QueryUserInfo q
;
213 struct samr_QueryUserInfo q0
;
214 union samr_UserInfo u
;
215 union samr_UserInfo
*info
;
217 const char *test_account_name
;
219 uint32_t user_extra_flags
= 0;
221 if (!torture_setting_bool(tctx
, "samba3", false)) {
222 if (base_acct_flags
== ACB_NORMAL
) {
223 /* When created, accounts are expired by default */
224 user_extra_flags
= ACB_PW_EXPIRED
;
228 s
.in
.user_handle
= handle
;
231 s2
.in
.user_handle
= handle
;
234 q
.in
.user_handle
= handle
;
238 #define TESTCALL(call, r) \
239 status = dcerpc_samr_ ##call(p, tctx, &r); \
240 if (!NT_STATUS_IS_OK(status)) { \
241 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
242 r.in.level, nt_errstr(status), __location__); \
247 #define STRING_EQUAL(s1, s2, field) \
248 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
249 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
250 #field, s2, __location__); \
255 #define MEM_EQUAL(s1, s2, length, field) \
256 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
257 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
258 #field, (const char *)s2, __location__); \
263 #define INT_EQUAL(i1, i2, field) \
265 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
266 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
271 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
272 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
274 TESTCALL(QueryUserInfo, q) \
276 s2.in.level = lvl1; \
279 ZERO_STRUCT(u.info21); \
280 u.info21.fields_present = fpval; \
282 init_lsa_String(&u.info ## lvl1.field1, value); \
283 TESTCALL(SetUserInfo, s) \
284 TESTCALL(SetUserInfo2, s2) \
285 init_lsa_String(&u.info ## lvl1.field1, ""); \
286 TESTCALL(QueryUserInfo, q); \
288 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
290 TESTCALL(QueryUserInfo, q) \
292 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
295 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
296 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
298 TESTCALL(QueryUserInfo, q) \
300 s2.in.level = lvl1; \
303 ZERO_STRUCT(u.info21); \
304 u.info21.fields_present = fpval; \
306 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
307 TESTCALL(SetUserInfo, s) \
308 TESTCALL(SetUserInfo2, s2) \
309 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
310 TESTCALL(QueryUserInfo, q); \
312 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
314 TESTCALL(QueryUserInfo, q) \
316 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
319 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
320 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
322 TESTCALL(QueryUserInfo, q) \
324 s2.in.level = lvl1; \
327 uint8_t *bits = u.info21.logon_hours.bits; \
328 ZERO_STRUCT(u.info21); \
329 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
330 u.info21.logon_hours.units_per_week = 168; \
331 u.info21.logon_hours.bits = bits; \
333 u.info21.fields_present = fpval; \
335 u.info ## lvl1.field1 = value; \
336 TESTCALL(SetUserInfo, s) \
337 TESTCALL(SetUserInfo2, s2) \
338 u.info ## lvl1.field1 = 0; \
339 TESTCALL(QueryUserInfo, q); \
341 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
343 TESTCALL(QueryUserInfo, q) \
345 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
348 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
349 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
353 do { TESTCALL(QueryUserInfo
, q0
) } while (0);
355 TEST_USERINFO_STRING(2, comment
, 1, comment
, "xx2-1 comment", 0);
356 TEST_USERINFO_STRING(2, comment
, 21, comment
, "xx2-21 comment", 0);
357 TEST_USERINFO_STRING(21, comment
, 21, comment
, "xx21-21 comment",
360 test_account_name
= talloc_asprintf(tctx
, "%sxx7-1", base_account_name
);
361 TEST_USERINFO_STRING(7, account_name
, 1, account_name
, base_account_name
, 0);
362 test_account_name
= talloc_asprintf(tctx
, "%sxx7-3", base_account_name
);
363 TEST_USERINFO_STRING(7, account_name
, 3, account_name
, base_account_name
, 0);
364 test_account_name
= talloc_asprintf(tctx
, "%sxx7-5", base_account_name
);
365 TEST_USERINFO_STRING(7, account_name
, 5, account_name
, base_account_name
, 0);
366 test_account_name
= talloc_asprintf(tctx
, "%sxx7-6", base_account_name
);
367 TEST_USERINFO_STRING(7, account_name
, 6, account_name
, base_account_name
, 0);
368 test_account_name
= talloc_asprintf(tctx
, "%sxx7-7", base_account_name
);
369 TEST_USERINFO_STRING(7, account_name
, 7, account_name
, base_account_name
, 0);
370 test_account_name
= talloc_asprintf(tctx
, "%sxx7-21", base_account_name
);
371 TEST_USERINFO_STRING(7, account_name
, 21, account_name
, base_account_name
, 0);
372 test_account_name
= base_account_name
;
373 TEST_USERINFO_STRING(21, account_name
, 21, account_name
, base_account_name
,
374 SAMR_FIELD_ACCOUNT_NAME
);
376 TEST_USERINFO_STRING(6, full_name
, 1, full_name
, "xx6-1 full_name", 0);
377 TEST_USERINFO_STRING(6, full_name
, 3, full_name
, "xx6-3 full_name", 0);
378 TEST_USERINFO_STRING(6, full_name
, 5, full_name
, "xx6-5 full_name", 0);
379 TEST_USERINFO_STRING(6, full_name
, 6, full_name
, "xx6-6 full_name", 0);
380 TEST_USERINFO_STRING(6, full_name
, 8, full_name
, "xx6-8 full_name", 0);
381 TEST_USERINFO_STRING(6, full_name
, 21, full_name
, "xx6-21 full_name", 0);
382 TEST_USERINFO_STRING(8, full_name
, 21, full_name
, "xx8-21 full_name", 0);
383 TEST_USERINFO_STRING(21, full_name
, 21, full_name
, "xx21-21 full_name",
384 SAMR_FIELD_FULL_NAME
);
386 TEST_USERINFO_STRING(6, full_name
, 1, full_name
, "", 0);
387 TEST_USERINFO_STRING(6, full_name
, 3, full_name
, "", 0);
388 TEST_USERINFO_STRING(6, full_name
, 5, full_name
, "", 0);
389 TEST_USERINFO_STRING(6, full_name
, 6, full_name
, "", 0);
390 TEST_USERINFO_STRING(6, full_name
, 8, full_name
, "", 0);
391 TEST_USERINFO_STRING(6, full_name
, 21, full_name
, "", 0);
392 TEST_USERINFO_STRING(8, full_name
, 21, full_name
, "", 0);
393 TEST_USERINFO_STRING(21, full_name
, 21, full_name
, "",
394 SAMR_FIELD_FULL_NAME
);
396 TEST_USERINFO_STRING(11, logon_script
, 3, logon_script
, "xx11-3 logon_script", 0);
397 TEST_USERINFO_STRING(11, logon_script
, 5, logon_script
, "xx11-5 logon_script", 0);
398 TEST_USERINFO_STRING(11, logon_script
, 21, logon_script
, "xx11-21 logon_script", 0);
399 TEST_USERINFO_STRING(21, logon_script
, 21, logon_script
, "xx21-21 logon_script",
400 SAMR_FIELD_LOGON_SCRIPT
);
402 TEST_USERINFO_STRING(12, profile_path
, 3, profile_path
, "xx12-3 profile_path", 0);
403 TEST_USERINFO_STRING(12, profile_path
, 5, profile_path
, "xx12-5 profile_path", 0);
404 TEST_USERINFO_STRING(12, profile_path
, 21, profile_path
, "xx12-21 profile_path", 0);
405 TEST_USERINFO_STRING(21, profile_path
, 21, profile_path
, "xx21-21 profile_path",
406 SAMR_FIELD_PROFILE_PATH
);
408 TEST_USERINFO_STRING(10, home_directory
, 3, home_directory
, "xx10-3 home_directory", 0);
409 TEST_USERINFO_STRING(10, home_directory
, 5, home_directory
, "xx10-5 home_directory", 0);
410 TEST_USERINFO_STRING(10, home_directory
, 21, home_directory
, "xx10-21 home_directory", 0);
411 TEST_USERINFO_STRING(21, home_directory
, 21, home_directory
, "xx21-21 home_directory",
412 SAMR_FIELD_HOME_DIRECTORY
);
413 TEST_USERINFO_STRING(21, home_directory
, 10, home_directory
, "xx21-10 home_directory",
414 SAMR_FIELD_HOME_DIRECTORY
);
416 TEST_USERINFO_STRING(10, home_drive
, 3, home_drive
, "xx10-3 home_drive", 0);
417 TEST_USERINFO_STRING(10, home_drive
, 5, home_drive
, "xx10-5 home_drive", 0);
418 TEST_USERINFO_STRING(10, home_drive
, 21, home_drive
, "xx10-21 home_drive", 0);
419 TEST_USERINFO_STRING(21, home_drive
, 21, home_drive
, "xx21-21 home_drive",
420 SAMR_FIELD_HOME_DRIVE
);
421 TEST_USERINFO_STRING(21, home_drive
, 10, home_drive
, "xx21-10 home_drive",
422 SAMR_FIELD_HOME_DRIVE
);
424 TEST_USERINFO_STRING(13, description
, 1, description
, "xx13-1 description", 0);
425 TEST_USERINFO_STRING(13, description
, 5, description
, "xx13-5 description", 0);
426 TEST_USERINFO_STRING(13, description
, 21, description
, "xx13-21 description", 0);
427 TEST_USERINFO_STRING(21, description
, 21, description
, "xx21-21 description",
428 SAMR_FIELD_DESCRIPTION
);
430 TEST_USERINFO_STRING(14, workstations
, 3, workstations
, "14workstation3", 0);
431 TEST_USERINFO_STRING(14, workstations
, 5, workstations
, "14workstation4", 0);
432 TEST_USERINFO_STRING(14, workstations
, 21, workstations
, "14workstation21", 0);
433 TEST_USERINFO_STRING(21, workstations
, 21, workstations
, "21workstation21",
434 SAMR_FIELD_WORKSTATIONS
);
435 TEST_USERINFO_STRING(21, workstations
, 3, workstations
, "21workstation3",
436 SAMR_FIELD_WORKSTATIONS
);
437 TEST_USERINFO_STRING(21, workstations
, 5, workstations
, "21workstation5",
438 SAMR_FIELD_WORKSTATIONS
);
439 TEST_USERINFO_STRING(21, workstations
, 14, workstations
, "21workstation14",
440 SAMR_FIELD_WORKSTATIONS
);
442 TEST_USERINFO_BINARYSTRING(20, parameters
, 21, parameters
, "xx20-21 parameters", 0);
443 TEST_USERINFO_BINARYSTRING(21, parameters
, 21, parameters
, "xx21-21 parameters",
444 SAMR_FIELD_PARAMETERS
);
445 TEST_USERINFO_BINARYSTRING(21, parameters
, 20, parameters
, "xx21-20 parameters",
446 SAMR_FIELD_PARAMETERS
);
447 /* also empty user parameters are allowed */
448 TEST_USERINFO_BINARYSTRING(20, parameters
, 21, parameters
, "", 0);
449 TEST_USERINFO_BINARYSTRING(21, parameters
, 21, parameters
, "",
450 SAMR_FIELD_PARAMETERS
);
451 TEST_USERINFO_BINARYSTRING(21, parameters
, 20, parameters
, "",
452 SAMR_FIELD_PARAMETERS
);
454 /* Samba 3 cannot store country_code and copy_page atm. - gd */
455 if (!torture_setting_bool(tctx
, "samba3", false)) {
456 TEST_USERINFO_INT(2, country_code
, 2, country_code
, __LINE__
, 0);
457 TEST_USERINFO_INT(2, country_code
, 21, country_code
, __LINE__
, 0);
458 TEST_USERINFO_INT(21, country_code
, 21, country_code
, __LINE__
,
459 SAMR_FIELD_COUNTRY_CODE
);
460 TEST_USERINFO_INT(21, country_code
, 2, country_code
, __LINE__
,
461 SAMR_FIELD_COUNTRY_CODE
);
463 TEST_USERINFO_INT(2, code_page
, 21, code_page
, __LINE__
, 0);
464 TEST_USERINFO_INT(21, code_page
, 21, code_page
, __LINE__
,
465 SAMR_FIELD_CODE_PAGE
);
466 TEST_USERINFO_INT(21, code_page
, 2, code_page
, __LINE__
,
467 SAMR_FIELD_CODE_PAGE
);
470 if (!torture_setting_bool(tctx
, "samba3", false)) {
471 TEST_USERINFO_INT(17, acct_expiry
, 21, acct_expiry
, __LINE__
, 0);
472 TEST_USERINFO_INT(17, acct_expiry
, 5, acct_expiry
, __LINE__
, 0);
473 TEST_USERINFO_INT(21, acct_expiry
, 21, acct_expiry
, __LINE__
,
474 SAMR_FIELD_ACCT_EXPIRY
);
475 TEST_USERINFO_INT(21, acct_expiry
, 5, acct_expiry
, __LINE__
,
476 SAMR_FIELD_ACCT_EXPIRY
);
477 TEST_USERINFO_INT(21, acct_expiry
, 17, acct_expiry
, __LINE__
,
478 SAMR_FIELD_ACCT_EXPIRY
);
480 /* Samba 3 can only store seconds / time_t in passdb - gd */
482 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
483 TEST_USERINFO_INT(17, acct_expiry
, 21, acct_expiry
, nt
, 0);
484 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
485 TEST_USERINFO_INT(17, acct_expiry
, 5, acct_expiry
, nt
, 0);
486 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
487 TEST_USERINFO_INT(21, acct_expiry
, 21, acct_expiry
, nt
, SAMR_FIELD_ACCT_EXPIRY
);
488 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
489 TEST_USERINFO_INT(21, acct_expiry
, 5, acct_expiry
, nt
, SAMR_FIELD_ACCT_EXPIRY
);
490 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
491 TEST_USERINFO_INT(21, acct_expiry
, 17, acct_expiry
, nt
, SAMR_FIELD_ACCT_EXPIRY
);
494 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 3, logon_hours
.bits
[3], 1, 0);
495 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 5, logon_hours
.bits
[3], 2, 0);
496 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 21, logon_hours
.bits
[3], 3, 0);
497 TEST_USERINFO_INT(21, logon_hours
.bits
[3], 21, logon_hours
.bits
[3], 4,
498 SAMR_FIELD_LOGON_HOURS
);
500 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
501 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
),
502 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
| user_extra_flags
),
504 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
505 (base_acct_flags
| ACB_DISABLED
),
506 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
509 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
510 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
511 (base_acct_flags
| ACB_DISABLED
| ACB_PWNOEXP
),
512 (base_acct_flags
| ACB_DISABLED
| ACB_PWNOEXP
),
514 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
515 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
),
516 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
| user_extra_flags
),
520 /* The 'autolock' flag doesn't stick - check this */
521 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
522 (base_acct_flags
| ACB_DISABLED
| ACB_AUTOLOCK
),
523 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
526 /* Removing the 'disabled' flag doesn't stick - check this */
527 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
529 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
533 /* Samba3 cannot store these atm */
534 if (!torture_setting_bool(tctx
, "samba3", false)) {
535 /* The 'store plaintext' flag does stick */
536 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
537 (base_acct_flags
| ACB_DISABLED
| ACB_ENC_TXT_PWD_ALLOWED
),
538 (base_acct_flags
| ACB_DISABLED
| ACB_ENC_TXT_PWD_ALLOWED
| user_extra_flags
),
540 /* The 'use DES' flag does stick */
541 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
542 (base_acct_flags
| ACB_DISABLED
| ACB_USE_DES_KEY_ONLY
),
543 (base_acct_flags
| ACB_DISABLED
| ACB_USE_DES_KEY_ONLY
| user_extra_flags
),
545 /* The 'don't require kerberos pre-authentication flag does stick */
546 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
547 (base_acct_flags
| ACB_DISABLED
| ACB_DONT_REQUIRE_PREAUTH
),
548 (base_acct_flags
| ACB_DISABLED
| ACB_DONT_REQUIRE_PREAUTH
| user_extra_flags
),
550 /* The 'no kerberos PAC required' flag sticks */
551 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
552 (base_acct_flags
| ACB_DISABLED
| ACB_NO_AUTH_DATA_REQD
),
553 (base_acct_flags
| ACB_DISABLED
| ACB_NO_AUTH_DATA_REQD
| user_extra_flags
),
556 TEST_USERINFO_INT_EXP(21, acct_flags
, 21, acct_flags
,
557 (base_acct_flags
| ACB_DISABLED
),
558 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
559 SAMR_FIELD_ACCT_FLAGS
);
562 /* these fail with win2003 - it appears you can't set the primary gid?
563 the set succeeds, but the gid isn't changed. Very weird! */
564 TEST_USERINFO_INT(9, primary_gid
, 1, primary_gid
, 513);
565 TEST_USERINFO_INT(9, primary_gid
, 3, primary_gid
, 513);
566 TEST_USERINFO_INT(9, primary_gid
, 5, primary_gid
, 513);
567 TEST_USERINFO_INT(9, primary_gid
, 21, primary_gid
, 513);
574 generate a random password for password change tests
576 static char *samr_rand_pass_silent(TALLOC_CTX
*mem_ctx
, int min_len
)
578 size_t len
= MAX(8, min_len
) + (random() % 6);
579 char *s
= generate_random_str(mem_ctx
, len
);
583 static char *samr_rand_pass(TALLOC_CTX
*mem_ctx
, int min_len
)
585 char *s
= samr_rand_pass_silent(mem_ctx
, min_len
);
586 printf("Generated password '%s'\n", s
);
592 generate a random password for password change tests
594 static DATA_BLOB
samr_very_rand_pass(TALLOC_CTX
*mem_ctx
, int len
)
597 DATA_BLOB password
= data_blob_talloc(mem_ctx
, NULL
, len
* 2 /* number of unicode chars */);
598 generate_random_buffer(password
.data
, password
.length
);
600 for (i
=0; i
< len
; i
++) {
601 if (((uint16_t *)password
.data
)[i
] == 0) {
602 ((uint16_t *)password
.data
)[i
] = 1;
610 generate a random password for password change tests (fixed length)
612 static char *samr_rand_pass_fixed_len(TALLOC_CTX
*mem_ctx
, int len
)
614 char *s
= generate_random_str(mem_ctx
, len
);
615 printf("Generated password '%s'\n", s
);
619 static bool test_SetUserPass(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
620 struct policy_handle
*handle
, char **password
)
623 struct samr_SetUserInfo s
;
624 union samr_UserInfo u
;
626 DATA_BLOB session_key
;
628 struct samr_GetUserPwInfo pwp
;
629 struct samr_PwInfo info
;
630 int policy_min_pw_len
= 0;
631 pwp
.in
.user_handle
= handle
;
632 pwp
.out
.info
= &info
;
634 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
635 if (NT_STATUS_IS_OK(status
)) {
636 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
638 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
640 s
.in
.user_handle
= handle
;
644 encode_pw_buffer(u
.info24
.password
.data
, newpass
, STR_UNICODE
);
645 u
.info24
.password_expired
= 0;
647 status
= dcerpc_fetch_session_key(p
, &session_key
);
648 if (!NT_STATUS_IS_OK(status
)) {
649 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
650 s
.in
.level
, nt_errstr(status
));
654 arcfour_crypt_blob(u
.info24
.password
.data
, 516, &session_key
);
656 torture_comment(tctx
, "Testing SetUserInfo level 24 (set password)\n");
658 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
659 if (!NT_STATUS_IS_OK(status
)) {
660 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
661 s
.in
.level
, nt_errstr(status
));
671 static bool test_SetUserPass_23(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
672 struct policy_handle
*handle
, uint32_t fields_present
,
676 struct samr_SetUserInfo s
;
677 union samr_UserInfo u
;
679 DATA_BLOB session_key
;
681 struct samr_GetUserPwInfo pwp
;
682 struct samr_PwInfo info
;
683 int policy_min_pw_len
= 0;
684 pwp
.in
.user_handle
= handle
;
685 pwp
.out
.info
= &info
;
687 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
688 if (NT_STATUS_IS_OK(status
)) {
689 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
691 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
693 s
.in
.user_handle
= handle
;
699 u
.info23
.info
.fields_present
= fields_present
;
701 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
703 status
= dcerpc_fetch_session_key(p
, &session_key
);
704 if (!NT_STATUS_IS_OK(status
)) {
705 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
706 s
.in
.level
, nt_errstr(status
));
710 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
712 torture_comment(tctx
, "Testing SetUserInfo level 23 (set password)\n");
714 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
715 if (!NT_STATUS_IS_OK(status
)) {
716 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
717 s
.in
.level
, nt_errstr(status
));
723 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
725 status
= dcerpc_fetch_session_key(p
, &session_key
);
726 if (!NT_STATUS_IS_OK(status
)) {
727 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
728 s
.in
.level
, nt_errstr(status
));
732 /* This should break the key nicely */
733 session_key
.length
--;
734 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
736 torture_comment(tctx
, "Testing SetUserInfo level 23 (set password) with wrong password\n");
738 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
739 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
740 torture_warning(tctx
, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
741 s
.in
.level
, nt_errstr(status
));
749 static bool test_SetUserPassEx(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
750 struct policy_handle
*handle
, bool makeshort
,
754 struct samr_SetUserInfo s
;
755 union samr_UserInfo u
;
757 DATA_BLOB session_key
;
758 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
759 uint8_t confounder
[16];
761 struct MD5Context ctx
;
762 struct samr_GetUserPwInfo pwp
;
763 struct samr_PwInfo info
;
764 int policy_min_pw_len
= 0;
765 pwp
.in
.user_handle
= handle
;
766 pwp
.out
.info
= &info
;
768 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
769 if (NT_STATUS_IS_OK(status
)) {
770 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
772 if (makeshort
&& policy_min_pw_len
) {
773 newpass
= samr_rand_pass_fixed_len(tctx
, policy_min_pw_len
- 1);
775 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
778 s
.in
.user_handle
= handle
;
782 encode_pw_buffer(u
.info26
.password
.data
, newpass
, STR_UNICODE
);
783 u
.info26
.password_expired
= 0;
785 status
= dcerpc_fetch_session_key(p
, &session_key
);
786 if (!NT_STATUS_IS_OK(status
)) {
787 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
788 s
.in
.level
, nt_errstr(status
));
792 generate_random_buffer((uint8_t *)confounder
, 16);
795 MD5Update(&ctx
, confounder
, 16);
796 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
797 MD5Final(confounded_session_key
.data
, &ctx
);
799 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
800 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
802 torture_comment(tctx
, "Testing SetUserInfo level 26 (set password ex)\n");
804 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
805 if (!NT_STATUS_IS_OK(status
)) {
806 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
807 s
.in
.level
, nt_errstr(status
));
813 /* This should break the key nicely */
814 confounded_session_key
.data
[0]++;
816 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
817 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
819 torture_comment(tctx
, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
821 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
822 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
823 torture_warning(tctx
, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
824 s
.in
.level
, nt_errstr(status
));
833 static bool test_SetUserPass_25(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
834 struct policy_handle
*handle
, uint32_t fields_present
,
838 struct samr_SetUserInfo s
;
839 union samr_UserInfo u
;
841 DATA_BLOB session_key
;
842 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
843 struct MD5Context ctx
;
844 uint8_t confounder
[16];
846 struct samr_GetUserPwInfo pwp
;
847 struct samr_PwInfo info
;
848 int policy_min_pw_len
= 0;
849 pwp
.in
.user_handle
= handle
;
850 pwp
.out
.info
= &info
;
852 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
853 if (NT_STATUS_IS_OK(status
)) {
854 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
856 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
858 s
.in
.user_handle
= handle
;
864 u
.info25
.info
.fields_present
= fields_present
;
866 encode_pw_buffer(u
.info25
.password
.data
, newpass
, STR_UNICODE
);
868 status
= dcerpc_fetch_session_key(p
, &session_key
);
869 if (!NT_STATUS_IS_OK(status
)) {
870 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
871 s
.in
.level
, nt_errstr(status
));
875 generate_random_buffer((uint8_t *)confounder
, 16);
878 MD5Update(&ctx
, confounder
, 16);
879 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
880 MD5Final(confounded_session_key
.data
, &ctx
);
882 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
883 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
885 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex)\n");
887 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
888 if (!NT_STATUS_IS_OK(status
)) {
889 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
890 s
.in
.level
, nt_errstr(status
));
896 /* This should break the key nicely */
897 confounded_session_key
.data
[0]++;
899 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
900 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
902 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
904 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
905 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
906 torture_warning(tctx
, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
907 s
.in
.level
, nt_errstr(status
));
914 static bool test_SetUserPass_18(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
915 struct policy_handle
*handle
, char **password
)
918 struct samr_SetUserInfo s
;
919 union samr_UserInfo u
;
921 DATA_BLOB session_key
;
923 struct samr_GetUserPwInfo pwp
;
924 struct samr_PwInfo info
;
925 int policy_min_pw_len
= 0;
926 uint8_t lm_hash
[16], nt_hash
[16];
928 pwp
.in
.user_handle
= handle
;
929 pwp
.out
.info
= &info
;
931 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
932 if (NT_STATUS_IS_OK(status
)) {
933 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
935 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
937 s
.in
.user_handle
= handle
;
943 u
.info18
.nt_pwd_active
= true;
944 u
.info18
.lm_pwd_active
= true;
946 E_md4hash(newpass
, nt_hash
);
947 E_deshash(newpass
, lm_hash
);
949 status
= dcerpc_fetch_session_key(p
, &session_key
);
950 if (!NT_STATUS_IS_OK(status
)) {
951 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
952 s
.in
.level
, nt_errstr(status
));
958 in
= data_blob_const(nt_hash
, 16);
959 out
= data_blob_talloc_zero(tctx
, 16);
960 sess_crypt_blob(&out
, &in
, &session_key
, true);
961 memcpy(u
.info18
.nt_pwd
.hash
, out
.data
, out
.length
);
965 in
= data_blob_const(lm_hash
, 16);
966 out
= data_blob_talloc_zero(tctx
, 16);
967 sess_crypt_blob(&out
, &in
, &session_key
, true);
968 memcpy(u
.info18
.lm_pwd
.hash
, out
.data
, out
.length
);
971 torture_comment(tctx
, "Testing SetUserInfo level 18 (set password hash)\n");
973 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
974 if (!NT_STATUS_IS_OK(status
)) {
975 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
976 s
.in
.level
, nt_errstr(status
));
985 static bool test_SetUserPass_21(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
986 struct policy_handle
*handle
, uint32_t fields_present
,
990 struct samr_SetUserInfo s
;
991 union samr_UserInfo u
;
993 DATA_BLOB session_key
;
995 struct samr_GetUserPwInfo pwp
;
996 struct samr_PwInfo info
;
997 int policy_min_pw_len
= 0;
998 uint8_t lm_hash
[16], nt_hash
[16];
1000 pwp
.in
.user_handle
= handle
;
1001 pwp
.out
.info
= &info
;
1003 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
1004 if (NT_STATUS_IS_OK(status
)) {
1005 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1007 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1009 s
.in
.user_handle
= handle
;
1013 E_md4hash(newpass
, nt_hash
);
1014 E_deshash(newpass
, lm_hash
);
1018 u
.info21
.fields_present
= fields_present
;
1020 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1021 u
.info21
.lm_owf_password
.length
= 16;
1022 u
.info21
.lm_owf_password
.size
= 16;
1023 u
.info21
.lm_owf_password
.array
= (uint16_t *)lm_hash
;
1024 u
.info21
.lm_password_set
= true;
1027 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1028 u
.info21
.nt_owf_password
.length
= 16;
1029 u
.info21
.nt_owf_password
.size
= 16;
1030 u
.info21
.nt_owf_password
.array
= (uint16_t *)nt_hash
;
1031 u
.info21
.nt_password_set
= true;
1034 status
= dcerpc_fetch_session_key(p
, &session_key
);
1035 if (!NT_STATUS_IS_OK(status
)) {
1036 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
1037 s
.in
.level
, nt_errstr(status
));
1041 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1043 in
= data_blob_const(u
.info21
.lm_owf_password
.array
,
1044 u
.info21
.lm_owf_password
.length
);
1045 out
= data_blob_talloc_zero(tctx
, 16);
1046 sess_crypt_blob(&out
, &in
, &session_key
, true);
1047 u
.info21
.lm_owf_password
.array
= (uint16_t *)out
.data
;
1050 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1052 in
= data_blob_const(u
.info21
.nt_owf_password
.array
,
1053 u
.info21
.nt_owf_password
.length
);
1054 out
= data_blob_talloc_zero(tctx
, 16);
1055 sess_crypt_blob(&out
, &in
, &session_key
, true);
1056 u
.info21
.nt_owf_password
.array
= (uint16_t *)out
.data
;
1059 torture_comment(tctx
, "Testing SetUserInfo level 21 (set password hash)\n");
1061 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
1062 if (!NT_STATUS_IS_OK(status
)) {
1063 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
1064 s
.in
.level
, nt_errstr(status
));
1067 *password
= newpass
;
1070 /* try invalid length */
1071 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1073 u
.info21
.nt_owf_password
.length
++;
1075 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
1077 if (!NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
1078 torture_warning(tctx
, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1079 s
.in
.level
, nt_errstr(status
));
1084 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1086 u
.info21
.lm_owf_password
.length
++;
1088 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
1090 if (!NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
1091 torture_warning(tctx
, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1092 s
.in
.level
, nt_errstr(status
));
1100 static bool test_SetUserPass_level_ex(struct dcerpc_pipe
*p
,
1101 struct torture_context
*tctx
,
1102 struct policy_handle
*handle
,
1104 uint32_t fields_present
,
1105 char **password
, uint8_t password_expired
,
1107 bool *matched_expected_error
)
1110 NTSTATUS expected_error
= NT_STATUS_OK
;
1111 struct samr_SetUserInfo s
;
1112 struct samr_SetUserInfo2 s2
;
1113 union samr_UserInfo u
;
1115 DATA_BLOB session_key
;
1116 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
1117 struct MD5Context ctx
;
1118 uint8_t confounder
[16];
1120 struct samr_GetUserPwInfo pwp
;
1121 struct samr_PwInfo info
;
1122 int policy_min_pw_len
= 0;
1123 const char *comment
= NULL
;
1124 uint8_t lm_hash
[16], nt_hash
[16];
1126 pwp
.in
.user_handle
= handle
;
1127 pwp
.out
.info
= &info
;
1129 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
1130 if (NT_STATUS_IS_OK(status
)) {
1131 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1133 newpass
= samr_rand_pass_silent(tctx
, policy_min_pw_len
);
1136 s2
.in
.user_handle
= handle
;
1138 s2
.in
.level
= level
;
1140 s
.in
.user_handle
= handle
;
1145 if (fields_present
& SAMR_FIELD_COMMENT
) {
1146 comment
= talloc_asprintf(tctx
, "comment: %ld\n", time(NULL
));
1153 E_md4hash(newpass
, nt_hash
);
1154 E_deshash(newpass
, lm_hash
);
1156 u
.info18
.nt_pwd_active
= true;
1157 u
.info18
.lm_pwd_active
= true;
1158 u
.info18
.password_expired
= password_expired
;
1160 memcpy(u
.info18
.lm_pwd
.hash
, lm_hash
, 16);
1161 memcpy(u
.info18
.nt_pwd
.hash
, nt_hash
, 16);
1165 E_md4hash(newpass
, nt_hash
);
1166 E_deshash(newpass
, lm_hash
);
1168 u
.info21
.fields_present
= fields_present
;
1169 u
.info21
.password_expired
= password_expired
;
1170 u
.info21
.comment
.string
= comment
;
1172 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1173 u
.info21
.lm_owf_password
.length
= 16;
1174 u
.info21
.lm_owf_password
.size
= 16;
1175 u
.info21
.lm_owf_password
.array
= (uint16_t *)lm_hash
;
1176 u
.info21
.lm_password_set
= true;
1179 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1180 u
.info21
.nt_owf_password
.length
= 16;
1181 u
.info21
.nt_owf_password
.size
= 16;
1182 u
.info21
.nt_owf_password
.array
= (uint16_t *)nt_hash
;
1183 u
.info21
.nt_password_set
= true;
1188 u
.info23
.info
.fields_present
= fields_present
;
1189 u
.info23
.info
.password_expired
= password_expired
;
1190 u
.info23
.info
.comment
.string
= comment
;
1192 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
1196 u
.info24
.password_expired
= password_expired
;
1198 encode_pw_buffer(u
.info24
.password
.data
, newpass
, STR_UNICODE
);
1202 u
.info25
.info
.fields_present
= fields_present
;
1203 u
.info25
.info
.password_expired
= password_expired
;
1204 u
.info25
.info
.comment
.string
= comment
;
1206 encode_pw_buffer(u
.info25
.password
.data
, newpass
, STR_UNICODE
);
1210 u
.info26
.password_expired
= password_expired
;
1212 encode_pw_buffer(u
.info26
.password
.data
, newpass
, STR_UNICODE
);
1217 status
= dcerpc_fetch_session_key(p
, &session_key
);
1218 if (!NT_STATUS_IS_OK(status
)) {
1219 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
1220 s
.in
.level
, nt_errstr(status
));
1224 generate_random_buffer((uint8_t *)confounder
, 16);
1227 MD5Update(&ctx
, confounder
, 16);
1228 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
1229 MD5Final(confounded_session_key
.data
, &ctx
);
1235 in
= data_blob_const(u
.info18
.nt_pwd
.hash
, 16);
1236 out
= data_blob_talloc_zero(tctx
, 16);
1237 sess_crypt_blob(&out
, &in
, &session_key
, true);
1238 memcpy(u
.info18
.nt_pwd
.hash
, out
.data
, out
.length
);
1242 in
= data_blob_const(u
.info18
.lm_pwd
.hash
, 16);
1243 out
= data_blob_talloc_zero(tctx
, 16);
1244 sess_crypt_blob(&out
, &in
, &session_key
, true);
1245 memcpy(u
.info18
.lm_pwd
.hash
, out
.data
, out
.length
);
1250 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1252 in
= data_blob_const(u
.info21
.lm_owf_password
.array
,
1253 u
.info21
.lm_owf_password
.length
);
1254 out
= data_blob_talloc_zero(tctx
, 16);
1255 sess_crypt_blob(&out
, &in
, &session_key
, true);
1256 u
.info21
.lm_owf_password
.array
= (uint16_t *)out
.data
;
1258 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1260 in
= data_blob_const(u
.info21
.nt_owf_password
.array
,
1261 u
.info21
.nt_owf_password
.length
);
1262 out
= data_blob_talloc_zero(tctx
, 16);
1263 sess_crypt_blob(&out
, &in
, &session_key
, true);
1264 u
.info21
.nt_owf_password
.array
= (uint16_t *)out
.data
;
1268 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
1271 arcfour_crypt_blob(u
.info24
.password
.data
, 516, &session_key
);
1274 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
1275 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
1278 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
1279 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
1284 status
= dcerpc_samr_SetUserInfo2(p
, tctx
, &s2
);
1286 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
1289 if (!NT_STATUS_IS_OK(status
)) {
1290 if (fields_present
== 0) {
1291 expected_error
= NT_STATUS_INVALID_PARAMETER
;
1293 if (fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
1294 expected_error
= NT_STATUS_ACCESS_DENIED
;
1298 if (!NT_STATUS_IS_OK(expected_error
)) {
1300 torture_assert_ntstatus_equal(tctx
,
1302 expected_error
, "SetUserInfo2 failed");
1304 torture_assert_ntstatus_equal(tctx
,
1306 expected_error
, "SetUserInfo failed");
1308 *matched_expected_error
= true;
1312 if (!NT_STATUS_IS_OK(status
)) {
1313 torture_warning(tctx
, "SetUserInfo%s level %u failed - %s\n",
1314 use_setinfo2
? "2":"", level
, nt_errstr(status
));
1317 *password
= newpass
;
1323 static bool test_SetAliasInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1324 struct policy_handle
*handle
)
1327 struct samr_SetAliasInfo r
;
1328 struct samr_QueryAliasInfo q
;
1329 union samr_AliasInfo
*info
;
1330 uint16_t levels
[] = {2, 3};
1334 /* Ignoring switch level 1, as that includes the number of members for the alias
1335 * and setting this to a wrong value might have negative consequences
1338 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
1339 torture_comment(tctx
, "Testing SetAliasInfo level %u\n", levels
[i
]);
1341 r
.in
.alias_handle
= handle
;
1342 r
.in
.level
= levels
[i
];
1343 r
.in
.info
= talloc(tctx
, union samr_AliasInfo
);
1344 switch (r
.in
.level
) {
1345 case ALIASINFONAME
: init_lsa_String(&r
.in
.info
->name
,TEST_ALIASNAME
); break;
1346 case ALIASINFODESCRIPTION
: init_lsa_String(&r
.in
.info
->description
,
1347 "Test Description, should test I18N as well"); break;
1348 case ALIASINFOALL
: torture_comment(tctx
, "ALIASINFOALL ignored\n"); break;
1351 status
= dcerpc_samr_SetAliasInfo(p
, tctx
, &r
);
1352 if (!NT_STATUS_IS_OK(status
)) {
1353 torture_warning(tctx
, "SetAliasInfo level %u failed - %s\n",
1354 levels
[i
], nt_errstr(status
));
1358 q
.in
.alias_handle
= handle
;
1359 q
.in
.level
= levels
[i
];
1362 status
= dcerpc_samr_QueryAliasInfo(p
, tctx
, &q
);
1363 if (!NT_STATUS_IS_OK(status
)) {
1364 torture_warning(tctx
, "QueryAliasInfo level %u failed - %s\n",
1365 levels
[i
], nt_errstr(status
));
1373 static bool test_GetGroupsForUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1374 struct policy_handle
*user_handle
)
1376 struct samr_GetGroupsForUser r
;
1377 struct samr_RidWithAttributeArray
*rids
= NULL
;
1380 torture_comment(tctx
, "testing GetGroupsForUser\n");
1382 r
.in
.user_handle
= user_handle
;
1385 status
= dcerpc_samr_GetGroupsForUser(p
, tctx
, &r
);
1386 torture_assert_ntstatus_ok(tctx
, status
, "GetGroupsForUser");
1392 static bool test_GetDomPwInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1393 struct lsa_String
*domain_name
)
1396 struct samr_GetDomPwInfo r
;
1397 struct samr_PwInfo info
;
1399 r
.in
.domain_name
= domain_name
;
1402 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1404 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &r
);
1405 torture_assert_ntstatus_ok(tctx
, status
, "GetDomPwInfo");
1407 r
.in
.domain_name
->string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1408 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1410 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &r
);
1411 torture_assert_ntstatus_ok(tctx
, status
, "GetDomPwInfo");
1413 r
.in
.domain_name
->string
= "\\\\__NONAME__";
1414 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1416 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &r
);
1417 torture_assert_ntstatus_ok(tctx
, status
, "GetDomPwInfo");
1419 r
.in
.domain_name
->string
= "\\\\Builtin";
1420 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1422 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &r
);
1423 torture_assert_ntstatus_ok(tctx
, status
, "GetDomPwInfo");
1428 static bool test_GetUserPwInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1429 struct policy_handle
*handle
)
1432 struct samr_GetUserPwInfo r
;
1433 struct samr_PwInfo info
;
1435 torture_comment(tctx
, "Testing GetUserPwInfo\n");
1437 r
.in
.user_handle
= handle
;
1440 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &r
);
1441 torture_assert_ntstatus_ok(tctx
, status
, "GetUserPwInfo");
1446 static NTSTATUS
test_LookupName(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1447 struct policy_handle
*domain_handle
, const char *name
,
1451 struct samr_LookupNames n
;
1452 struct lsa_String sname
[2];
1453 struct samr_Ids rids
, types
;
1455 init_lsa_String(&sname
[0], name
);
1457 n
.in
.domain_handle
= domain_handle
;
1461 n
.out
.types
= &types
;
1462 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
1463 if (NT_STATUS_IS_OK(status
)) {
1464 *rid
= n
.out
.rids
->ids
[0];
1469 init_lsa_String(&sname
[1], "xxNONAMExx");
1471 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
1472 if (!NT_STATUS_EQUAL(status
, STATUS_SOME_UNMAPPED
)) {
1473 torture_warning(tctx
, "LookupNames[2] failed - %s\n", nt_errstr(status
));
1474 if (NT_STATUS_IS_OK(status
)) {
1475 return NT_STATUS_UNSUCCESSFUL
;
1481 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
1482 if (!NT_STATUS_IS_OK(status
)) {
1483 torture_warning(tctx
, "LookupNames[0] failed - %s\n", nt_errstr(status
));
1487 init_lsa_String(&sname
[0], "xxNONAMExx");
1489 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
1490 if (!NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
)) {
1491 torture_warning(tctx
, "LookupNames[1 bad name] failed - %s\n", nt_errstr(status
));
1492 if (NT_STATUS_IS_OK(status
)) {
1493 return NT_STATUS_UNSUCCESSFUL
;
1498 init_lsa_String(&sname
[0], "xxNONAMExx");
1499 init_lsa_String(&sname
[1], "xxNONAME2xx");
1501 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
1502 if (!NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
)) {
1503 torture_warning(tctx
, "LookupNames[2 bad names] failed - %s\n", nt_errstr(status
));
1504 if (NT_STATUS_IS_OK(status
)) {
1505 return NT_STATUS_UNSUCCESSFUL
;
1510 return NT_STATUS_OK
;
1513 static NTSTATUS
test_OpenUser_byname(struct dcerpc_pipe
*p
,
1514 struct torture_context
*tctx
,
1515 struct policy_handle
*domain_handle
,
1516 const char *name
, struct policy_handle
*user_handle
)
1519 struct samr_OpenUser r
;
1522 status
= test_LookupName(p
, tctx
, domain_handle
, name
, &rid
);
1523 if (!NT_STATUS_IS_OK(status
)) {
1527 r
.in
.domain_handle
= domain_handle
;
1528 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1530 r
.out
.user_handle
= user_handle
;
1531 status
= dcerpc_samr_OpenUser(p
, tctx
, &r
);
1532 if (!NT_STATUS_IS_OK(status
)) {
1533 torture_warning(tctx
, "OpenUser_byname(%s -> %d) failed - %s\n", name
, rid
, nt_errstr(status
));
1540 static bool test_ChangePasswordNT3(struct dcerpc_pipe
*p
,
1541 struct torture_context
*tctx
,
1542 struct policy_handle
*handle
)
1545 struct samr_ChangePasswordUser r
;
1547 struct samr_Password hash1
, hash2
, hash3
, hash4
, hash5
, hash6
;
1548 struct policy_handle user_handle
;
1549 char *oldpass
= "test";
1550 char *newpass
= "test2";
1551 uint8_t old_nt_hash
[16], new_nt_hash
[16];
1552 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1554 status
= test_OpenUser_byname(p
, tctx
, handle
, "testuser", &user_handle
);
1555 if (!NT_STATUS_IS_OK(status
)) {
1559 torture_comment(tctx
, "Testing ChangePasswordUser for user 'testuser'\n");
1561 torture_comment(tctx
, "old password: %s\n", oldpass
);
1562 torture_comment(tctx
, "new password: %s\n", newpass
);
1564 E_md4hash(oldpass
, old_nt_hash
);
1565 E_md4hash(newpass
, new_nt_hash
);
1566 E_deshash(oldpass
, old_lm_hash
);
1567 E_deshash(newpass
, new_lm_hash
);
1569 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1570 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1571 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1572 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1573 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1574 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1576 r
.in
.handle
= &user_handle
;
1577 r
.in
.lm_present
= 1;
1578 r
.in
.old_lm_crypted
= &hash1
;
1579 r
.in
.new_lm_crypted
= &hash2
;
1580 r
.in
.nt_present
= 1;
1581 r
.in
.old_nt_crypted
= &hash3
;
1582 r
.in
.new_nt_crypted
= &hash4
;
1583 r
.in
.cross1_present
= 1;
1584 r
.in
.nt_cross
= &hash5
;
1585 r
.in
.cross2_present
= 1;
1586 r
.in
.lm_cross
= &hash6
;
1588 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1589 if (!NT_STATUS_IS_OK(status
)) {
1590 torture_warning(tctx
, "ChangePasswordUser failed - %s\n", nt_errstr(status
));
1594 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
1602 static bool test_ChangePasswordUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1603 const char *acct_name
,
1604 struct policy_handle
*handle
, char **password
)
1607 struct samr_ChangePasswordUser r
;
1609 struct samr_Password hash1
, hash2
, hash3
, hash4
, hash5
, hash6
;
1610 struct policy_handle user_handle
;
1612 uint8_t old_nt_hash
[16], new_nt_hash
[16];
1613 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1614 bool changed
= true;
1617 struct samr_GetUserPwInfo pwp
;
1618 struct samr_PwInfo info
;
1619 int policy_min_pw_len
= 0;
1621 status
= test_OpenUser_byname(p
, tctx
, handle
, acct_name
, &user_handle
);
1622 if (!NT_STATUS_IS_OK(status
)) {
1625 pwp
.in
.user_handle
= &user_handle
;
1626 pwp
.out
.info
= &info
;
1628 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
1629 if (NT_STATUS_IS_OK(status
)) {
1630 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1632 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1634 torture_comment(tctx
, "Testing ChangePasswordUser\n");
1636 torture_assert(tctx
, *password
!= NULL
,
1637 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1639 oldpass
= *password
;
1641 E_md4hash(oldpass
, old_nt_hash
);
1642 E_md4hash(newpass
, new_nt_hash
);
1643 E_deshash(oldpass
, old_lm_hash
);
1644 E_deshash(newpass
, new_lm_hash
);
1646 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1647 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1648 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1649 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1650 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1651 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1653 r
.in
.user_handle
= &user_handle
;
1654 r
.in
.lm_present
= 1;
1655 /* Break the LM hash */
1657 r
.in
.old_lm_crypted
= &hash1
;
1658 r
.in
.new_lm_crypted
= &hash2
;
1659 r
.in
.nt_present
= 1;
1660 r
.in
.old_nt_crypted
= &hash3
;
1661 r
.in
.new_nt_crypted
= &hash4
;
1662 r
.in
.cross1_present
= 1;
1663 r
.in
.nt_cross
= &hash5
;
1664 r
.in
.cross2_present
= 1;
1665 r
.in
.lm_cross
= &hash6
;
1667 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1668 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_WRONG_PASSWORD
,
1669 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1671 /* Unbreak the LM hash */
1674 r
.in
.user_handle
= &user_handle
;
1675 r
.in
.lm_present
= 1;
1676 r
.in
.old_lm_crypted
= &hash1
;
1677 r
.in
.new_lm_crypted
= &hash2
;
1678 /* Break the NT hash */
1680 r
.in
.nt_present
= 1;
1681 r
.in
.old_nt_crypted
= &hash3
;
1682 r
.in
.new_nt_crypted
= &hash4
;
1683 r
.in
.cross1_present
= 1;
1684 r
.in
.nt_cross
= &hash5
;
1685 r
.in
.cross2_present
= 1;
1686 r
.in
.lm_cross
= &hash6
;
1688 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1689 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_WRONG_PASSWORD
,
1690 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1692 /* Unbreak the NT hash */
1695 r
.in
.user_handle
= &user_handle
;
1696 r
.in
.lm_present
= 1;
1697 r
.in
.old_lm_crypted
= &hash1
;
1698 r
.in
.new_lm_crypted
= &hash2
;
1699 r
.in
.nt_present
= 1;
1700 r
.in
.old_nt_crypted
= &hash3
;
1701 r
.in
.new_nt_crypted
= &hash4
;
1702 r
.in
.cross1_present
= 1;
1703 r
.in
.nt_cross
= &hash5
;
1704 r
.in
.cross2_present
= 1;
1705 /* Break the LM cross */
1707 r
.in
.lm_cross
= &hash6
;
1709 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1710 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1711 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status
));
1715 /* Unbreak the LM cross */
1718 r
.in
.user_handle
= &user_handle
;
1719 r
.in
.lm_present
= 1;
1720 r
.in
.old_lm_crypted
= &hash1
;
1721 r
.in
.new_lm_crypted
= &hash2
;
1722 r
.in
.nt_present
= 1;
1723 r
.in
.old_nt_crypted
= &hash3
;
1724 r
.in
.new_nt_crypted
= &hash4
;
1725 r
.in
.cross1_present
= 1;
1726 /* Break the NT cross */
1728 r
.in
.nt_cross
= &hash5
;
1729 r
.in
.cross2_present
= 1;
1730 r
.in
.lm_cross
= &hash6
;
1732 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1733 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1734 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status
));
1738 /* Unbreak the NT cross */
1742 /* Reset the hashes to not broken values */
1743 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1744 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1745 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1746 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1747 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1748 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1750 r
.in
.user_handle
= &user_handle
;
1751 r
.in
.lm_present
= 1;
1752 r
.in
.old_lm_crypted
= &hash1
;
1753 r
.in
.new_lm_crypted
= &hash2
;
1754 r
.in
.nt_present
= 1;
1755 r
.in
.old_nt_crypted
= &hash3
;
1756 r
.in
.new_nt_crypted
= &hash4
;
1757 r
.in
.cross1_present
= 1;
1758 r
.in
.nt_cross
= &hash5
;
1759 r
.in
.cross2_present
= 0;
1760 r
.in
.lm_cross
= NULL
;
1762 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1763 if (NT_STATUS_IS_OK(status
)) {
1765 *password
= newpass
;
1766 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION
, status
)) {
1767 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status
));
1772 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1774 E_md4hash(oldpass
, old_nt_hash
);
1775 E_md4hash(newpass
, new_nt_hash
);
1776 E_deshash(oldpass
, old_lm_hash
);
1777 E_deshash(newpass
, new_lm_hash
);
1780 /* Reset the hashes to not broken values */
1781 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1782 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1783 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1784 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1785 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1786 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1788 r
.in
.user_handle
= &user_handle
;
1789 r
.in
.lm_present
= 1;
1790 r
.in
.old_lm_crypted
= &hash1
;
1791 r
.in
.new_lm_crypted
= &hash2
;
1792 r
.in
.nt_present
= 1;
1793 r
.in
.old_nt_crypted
= &hash3
;
1794 r
.in
.new_nt_crypted
= &hash4
;
1795 r
.in
.cross1_present
= 0;
1796 r
.in
.nt_cross
= NULL
;
1797 r
.in
.cross2_present
= 1;
1798 r
.in
.lm_cross
= &hash6
;
1800 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1801 if (NT_STATUS_IS_OK(status
)) {
1803 *password
= newpass
;
1804 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION
, status
)) {
1805 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status
));
1810 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1812 E_md4hash(oldpass
, old_nt_hash
);
1813 E_md4hash(newpass
, new_nt_hash
);
1814 E_deshash(oldpass
, old_lm_hash
);
1815 E_deshash(newpass
, new_lm_hash
);
1818 /* Reset the hashes to not broken values */
1819 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1820 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1821 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1822 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1823 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1824 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1826 r
.in
.user_handle
= &user_handle
;
1827 r
.in
.lm_present
= 1;
1828 r
.in
.old_lm_crypted
= &hash1
;
1829 r
.in
.new_lm_crypted
= &hash2
;
1830 r
.in
.nt_present
= 1;
1831 r
.in
.old_nt_crypted
= &hash3
;
1832 r
.in
.new_nt_crypted
= &hash4
;
1833 r
.in
.cross1_present
= 1;
1834 r
.in
.nt_cross
= &hash5
;
1835 r
.in
.cross2_present
= 1;
1836 r
.in
.lm_cross
= &hash6
;
1838 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1839 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1840 torture_comment(tctx
, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status
));
1841 } else if (!NT_STATUS_IS_OK(status
)) {
1842 torture_warning(tctx
, "ChangePasswordUser failed - %s\n", nt_errstr(status
));
1846 *password
= newpass
;
1849 r
.in
.user_handle
= &user_handle
;
1850 r
.in
.lm_present
= 1;
1851 r
.in
.old_lm_crypted
= &hash1
;
1852 r
.in
.new_lm_crypted
= &hash2
;
1853 r
.in
.nt_present
= 1;
1854 r
.in
.old_nt_crypted
= &hash3
;
1855 r
.in
.new_nt_crypted
= &hash4
;
1856 r
.in
.cross1_present
= 1;
1857 r
.in
.nt_cross
= &hash5
;
1858 r
.in
.cross2_present
= 1;
1859 r
.in
.lm_cross
= &hash6
;
1862 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1863 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1864 torture_comment(tctx
, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status
));
1865 } else if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1866 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status
));
1872 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
1880 static bool test_OemChangePasswordUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1881 const char *acct_name
,
1882 struct policy_handle
*handle
, char **password
)
1885 struct samr_OemChangePasswordUser2 r
;
1887 struct samr_Password lm_verifier
;
1888 struct samr_CryptPassword lm_pass
;
1889 struct lsa_AsciiString server
, account
, account_bad
;
1892 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1894 struct samr_GetDomPwInfo dom_pw_info
;
1895 struct samr_PwInfo info
;
1896 int policy_min_pw_len
= 0;
1898 struct lsa_String domain_name
;
1900 domain_name
.string
= "";
1901 dom_pw_info
.in
.domain_name
= &domain_name
;
1902 dom_pw_info
.out
.info
= &info
;
1904 torture_comment(tctx
, "Testing OemChangePasswordUser2\n");
1906 torture_assert(tctx
, *password
!= NULL
,
1907 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1909 oldpass
= *password
;
1911 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &dom_pw_info
);
1912 if (NT_STATUS_IS_OK(status
)) {
1913 policy_min_pw_len
= dom_pw_info
.out
.info
->min_password_length
;
1916 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1918 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1919 account
.string
= acct_name
;
1921 E_deshash(oldpass
, old_lm_hash
);
1922 E_deshash(newpass
, new_lm_hash
);
1924 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
1925 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
1926 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
1928 r
.in
.server
= &server
;
1929 r
.in
.account
= &account
;
1930 r
.in
.password
= &lm_pass
;
1931 r
.in
.hash
= &lm_verifier
;
1933 /* Break the verification */
1934 lm_verifier
.hash
[0]++;
1936 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
1938 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)
1939 && !NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1940 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1945 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
1946 /* Break the old password */
1948 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
1949 /* unbreak it for the next operation */
1951 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
1953 r
.in
.server
= &server
;
1954 r
.in
.account
= &account
;
1955 r
.in
.password
= &lm_pass
;
1956 r
.in
.hash
= &lm_verifier
;
1958 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
1960 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)
1961 && !NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1962 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1967 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
1968 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
1970 r
.in
.server
= &server
;
1971 r
.in
.account
= &account
;
1972 r
.in
.password
= &lm_pass
;
1975 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
1977 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)
1978 && !NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
1979 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1984 /* This shouldn't be a valid name */
1985 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
1986 r
.in
.account
= &account_bad
;
1988 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
1990 if (!NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
1991 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1996 /* This shouldn't be a valid name */
1997 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
1998 r
.in
.account
= &account_bad
;
1999 r
.in
.password
= &lm_pass
;
2000 r
.in
.hash
= &lm_verifier
;
2002 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
2004 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
2005 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2010 /* This shouldn't be a valid name */
2011 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
2012 r
.in
.account
= &account_bad
;
2013 r
.in
.password
= NULL
;
2014 r
.in
.hash
= &lm_verifier
;
2016 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
2018 if (!NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
2019 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2024 E_deshash(oldpass
, old_lm_hash
);
2025 E_deshash(newpass
, new_lm_hash
);
2027 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
2028 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2029 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
2031 r
.in
.server
= &server
;
2032 r
.in
.account
= &account
;
2033 r
.in
.password
= &lm_pass
;
2034 r
.in
.hash
= &lm_verifier
;
2036 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
2037 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2038 torture_comment(tctx
, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status
));
2039 } else if (!NT_STATUS_IS_OK(status
)) {
2040 torture_warning(tctx
, "OemChangePasswordUser2 failed - %s\n", nt_errstr(status
));
2043 *password
= newpass
;
2050 static bool test_ChangePasswordUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2051 const char *acct_name
,
2053 char *newpass
, bool allow_password_restriction
)
2056 struct samr_ChangePasswordUser2 r
;
2058 struct lsa_String server
, account
;
2059 struct samr_CryptPassword nt_pass
, lm_pass
;
2060 struct samr_Password nt_verifier
, lm_verifier
;
2062 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2063 uint8_t old_lm_hash
[16], new_lm_hash
[16];
2065 struct samr_GetDomPwInfo dom_pw_info
;
2066 struct samr_PwInfo info
;
2068 struct lsa_String domain_name
;
2070 domain_name
.string
= "";
2071 dom_pw_info
.in
.domain_name
= &domain_name
;
2072 dom_pw_info
.out
.info
= &info
;
2074 torture_comment(tctx
, "Testing ChangePasswordUser2 on %s\n", acct_name
);
2076 torture_assert(tctx
, *password
!= NULL
,
2077 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2078 oldpass
= *password
;
2081 int policy_min_pw_len
= 0;
2082 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &dom_pw_info
);
2083 if (NT_STATUS_IS_OK(status
)) {
2084 policy_min_pw_len
= dom_pw_info
.out
.info
->min_password_length
;
2087 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2090 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2091 init_lsa_String(&account
, acct_name
);
2093 E_md4hash(oldpass
, old_nt_hash
);
2094 E_md4hash(newpass
, new_nt_hash
);
2096 E_deshash(oldpass
, old_lm_hash
);
2097 E_deshash(newpass
, new_lm_hash
);
2099 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
|STR_TERMINATE
);
2100 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2101 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2103 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2104 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2105 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2107 r
.in
.server
= &server
;
2108 r
.in
.account
= &account
;
2109 r
.in
.nt_password
= &nt_pass
;
2110 r
.in
.nt_verifier
= &nt_verifier
;
2112 r
.in
.lm_password
= &lm_pass
;
2113 r
.in
.lm_verifier
= &lm_verifier
;
2115 status
= dcerpc_samr_ChangePasswordUser2(p
, tctx
, &r
);
2116 if (allow_password_restriction
&& NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2117 torture_comment(tctx
, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status
));
2118 } else if (!NT_STATUS_IS_OK(status
)) {
2119 torture_warning(tctx
, "ChangePasswordUser2 failed - %s\n", nt_errstr(status
));
2122 *password
= newpass
;
2129 bool test_ChangePasswordUser3(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2130 const char *account_string
,
2131 int policy_min_pw_len
,
2133 const char *newpass
,
2134 NTTIME last_password_change
,
2135 bool handle_reject_reason
)
2138 struct samr_ChangePasswordUser3 r
;
2140 struct lsa_String server
, account
, account_bad
;
2141 struct samr_CryptPassword nt_pass
, lm_pass
;
2142 struct samr_Password nt_verifier
, lm_verifier
;
2144 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2145 uint8_t old_lm_hash
[16], new_lm_hash
[16];
2147 struct samr_DomInfo1
*dominfo
= NULL
;
2148 struct userPwdChangeFailureInformation
*reject
= NULL
;
2150 torture_comment(tctx
, "Testing ChangePasswordUser3\n");
2152 if (newpass
== NULL
) {
2154 if (policy_min_pw_len
== 0) {
2155 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2157 newpass
= samr_rand_pass_fixed_len(tctx
, policy_min_pw_len
);
2159 } while (check_password_quality(newpass
) == false);
2161 torture_comment(tctx
, "Using password '%s'\n", newpass
);
2164 torture_assert(tctx
, *password
!= NULL
,
2165 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2167 oldpass
= *password
;
2168 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2169 init_lsa_String(&account
, account_string
);
2171 E_md4hash(oldpass
, old_nt_hash
);
2172 E_md4hash(newpass
, new_nt_hash
);
2174 E_deshash(oldpass
, old_lm_hash
);
2175 E_deshash(newpass
, new_lm_hash
);
2177 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2178 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2179 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2181 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2182 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2183 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2185 /* Break the verification */
2186 nt_verifier
.hash
[0]++;
2188 r
.in
.server
= &server
;
2189 r
.in
.account
= &account
;
2190 r
.in
.nt_password
= &nt_pass
;
2191 r
.in
.nt_verifier
= &nt_verifier
;
2193 r
.in
.lm_password
= &lm_pass
;
2194 r
.in
.lm_verifier
= &lm_verifier
;
2195 r
.in
.password3
= NULL
;
2196 r
.out
.dominfo
= &dominfo
;
2197 r
.out
.reject
= &reject
;
2199 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
2200 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
) &&
2201 (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
))) {
2202 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2207 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2208 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2209 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2211 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2212 /* Break the NT hash */
2214 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2215 /* Unbreak it again */
2217 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2219 r
.in
.server
= &server
;
2220 r
.in
.account
= &account
;
2221 r
.in
.nt_password
= &nt_pass
;
2222 r
.in
.nt_verifier
= &nt_verifier
;
2224 r
.in
.lm_password
= &lm_pass
;
2225 r
.in
.lm_verifier
= &lm_verifier
;
2226 r
.in
.password3
= NULL
;
2227 r
.out
.dominfo
= &dominfo
;
2228 r
.out
.reject
= &reject
;
2230 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
2231 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
) &&
2232 (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
))) {
2233 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2238 /* This shouldn't be a valid name */
2239 init_lsa_String(&account_bad
, talloc_asprintf(tctx
, "%sXX", account_string
));
2241 r
.in
.account
= &account_bad
;
2242 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
2243 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
2244 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2249 E_md4hash(oldpass
, old_nt_hash
);
2250 E_md4hash(newpass
, new_nt_hash
);
2252 E_deshash(oldpass
, old_lm_hash
);
2253 E_deshash(newpass
, new_lm_hash
);
2255 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2256 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2257 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2259 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2260 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2261 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2263 r
.in
.server
= &server
;
2264 r
.in
.account
= &account
;
2265 r
.in
.nt_password
= &nt_pass
;
2266 r
.in
.nt_verifier
= &nt_verifier
;
2268 r
.in
.lm_password
= &lm_pass
;
2269 r
.in
.lm_verifier
= &lm_verifier
;
2270 r
.in
.password3
= NULL
;
2271 r
.out
.dominfo
= &dominfo
;
2272 r
.out
.reject
= &reject
;
2274 unix_to_nt_time(&t
, time(NULL
));
2276 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
2278 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)
2281 && handle_reject_reason
2282 && (!null_nttime(last_password_change
) || !dominfo
->min_password_age
)) {
2283 if (dominfo
->password_properties
& DOMAIN_REFUSE_PASSWORD_CHANGE
) {
2285 if (reject
&& (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
)) {
2286 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2287 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2292 /* We tested the order of precendence which is as follows:
2301 if ((dominfo
->min_password_age
> 0) && !null_nttime(last_password_change
) &&
2302 (last_password_change
+ dominfo
->min_password_age
> t
)) {
2304 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2305 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2306 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2310 } else if ((dominfo
->min_password_length
> 0) &&
2311 (strlen(newpass
) < dominfo
->min_password_length
)) {
2313 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
) {
2314 torture_warning(tctx
, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2315 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
, reject
->extendedFailureReason
);
2319 } else if ((dominfo
->password_history_length
> 0) &&
2320 strequal(oldpass
, newpass
)) {
2322 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_PWD_IN_HISTORY
) {
2323 torture_warning(tctx
, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2324 SAM_PWD_CHANGE_PWD_IN_HISTORY
, reject
->extendedFailureReason
);
2327 } else if (dominfo
->password_properties
& DOMAIN_PASSWORD_COMPLEX
) {
2329 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NOT_COMPLEX
) {
2330 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2331 SAM_PWD_CHANGE_NOT_COMPLEX
, reject
->extendedFailureReason
);
2337 if (reject
->extendedFailureReason
== SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
) {
2338 /* retry with adjusted size */
2339 return test_ChangePasswordUser3(p
, tctx
, account_string
,
2340 dominfo
->min_password_length
,
2341 password
, NULL
, 0, false);
2345 } else if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2346 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2347 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2348 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2351 /* Perhaps the server has a 'min password age' set? */
2354 torture_assert_ntstatus_ok(tctx
, status
, "ChangePasswordUser3");
2355 *password
= talloc_strdup(tctx
, newpass
);
2361 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2362 const char *account_string
,
2363 struct policy_handle
*handle
,
2367 struct samr_ChangePasswordUser3 r
;
2368 struct samr_SetUserInfo s
;
2369 union samr_UserInfo u
;
2370 DATA_BLOB session_key
;
2371 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
2372 uint8_t confounder
[16];
2373 struct MD5Context ctx
;
2376 struct lsa_String server
, account
;
2377 struct samr_CryptPassword nt_pass
;
2378 struct samr_Password nt_verifier
;
2379 DATA_BLOB new_random_pass
;
2382 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2384 struct samr_DomInfo1
*dominfo
= NULL
;
2385 struct userPwdChangeFailureInformation
*reject
= NULL
;
2387 new_random_pass
= samr_very_rand_pass(tctx
, 128);
2389 torture_assert(tctx
, *password
!= NULL
,
2390 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2392 oldpass
= *password
;
2393 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2394 init_lsa_String(&account
, account_string
);
2396 s
.in
.user_handle
= handle
;
2402 u
.info25
.info
.fields_present
= SAMR_FIELD_NT_PASSWORD_PRESENT
;
2404 set_pw_in_buffer(u
.info25
.password
.data
, &new_random_pass
);
2406 status
= dcerpc_fetch_session_key(p
, &session_key
);
2407 if (!NT_STATUS_IS_OK(status
)) {
2408 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
2409 s
.in
.level
, nt_errstr(status
));
2413 generate_random_buffer((uint8_t *)confounder
, 16);
2416 MD5Update(&ctx
, confounder
, 16);
2417 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
2418 MD5Final(confounded_session_key
.data
, &ctx
);
2420 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
2421 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
2423 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2425 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
2426 if (!NT_STATUS_IS_OK(status
)) {
2427 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
2428 s
.in
.level
, nt_errstr(status
));
2432 torture_comment(tctx
, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2434 mdfour(old_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2436 new_random_pass
= samr_very_rand_pass(tctx
, 128);
2438 mdfour(new_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2440 set_pw_in_buffer(nt_pass
.data
, &new_random_pass
);
2441 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2442 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2444 r
.in
.server
= &server
;
2445 r
.in
.account
= &account
;
2446 r
.in
.nt_password
= &nt_pass
;
2447 r
.in
.nt_verifier
= &nt_verifier
;
2449 r
.in
.lm_password
= NULL
;
2450 r
.in
.lm_verifier
= NULL
;
2451 r
.in
.password3
= NULL
;
2452 r
.out
.dominfo
= &dominfo
;
2453 r
.out
.reject
= &reject
;
2455 unix_to_nt_time(&t
, time(NULL
));
2457 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
2459 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2460 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2461 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2462 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2465 /* Perhaps the server has a 'min password age' set? */
2467 } else if (!NT_STATUS_IS_OK(status
)) {
2468 torture_warning(tctx
, "ChangePasswordUser3 failed - %s\n", nt_errstr(status
));
2472 newpass
= samr_rand_pass(tctx
, 128);
2474 mdfour(old_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2476 E_md4hash(newpass
, new_nt_hash
);
2478 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2479 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2480 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2482 r
.in
.server
= &server
;
2483 r
.in
.account
= &account
;
2484 r
.in
.nt_password
= &nt_pass
;
2485 r
.in
.nt_verifier
= &nt_verifier
;
2487 r
.in
.lm_password
= NULL
;
2488 r
.in
.lm_verifier
= NULL
;
2489 r
.in
.password3
= NULL
;
2490 r
.out
.dominfo
= &dominfo
;
2491 r
.out
.reject
= &reject
;
2493 unix_to_nt_time(&t
, time(NULL
));
2495 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
2497 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2498 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2499 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2500 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2503 /* Perhaps the server has a 'min password age' set? */
2506 torture_assert_ntstatus_ok(tctx
, status
, "ChangePasswordUser3 (on second random password)");
2507 *password
= talloc_strdup(tctx
, newpass
);
2514 static bool test_GetMembersInAlias(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2515 struct policy_handle
*alias_handle
)
2517 struct samr_GetMembersInAlias r
;
2518 struct lsa_SidArray sids
;
2521 torture_comment(tctx
, "Testing GetMembersInAlias\n");
2523 r
.in
.alias_handle
= alias_handle
;
2526 status
= dcerpc_samr_GetMembersInAlias(p
, tctx
, &r
);
2527 torture_assert_ntstatus_ok(tctx
, status
, "GetMembersInAlias");
2532 static bool test_AddMemberToAlias(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2533 struct policy_handle
*alias_handle
,
2534 const struct dom_sid
*domain_sid
)
2536 struct samr_AddAliasMember r
;
2537 struct samr_DeleteAliasMember d
;
2539 struct dom_sid
*sid
;
2541 sid
= dom_sid_add_rid(tctx
, domain_sid
, 512);
2543 torture_comment(tctx
, "testing AddAliasMember\n");
2544 r
.in
.alias_handle
= alias_handle
;
2547 status
= dcerpc_samr_AddAliasMember(p
, tctx
, &r
);
2548 torture_assert_ntstatus_ok(tctx
, status
, "AddAliasMember");
2550 d
.in
.alias_handle
= alias_handle
;
2553 status
= dcerpc_samr_DeleteAliasMember(p
, tctx
, &d
);
2554 torture_assert_ntstatus_ok(tctx
, status
, "DelAliasMember");
2559 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2560 struct policy_handle
*alias_handle
)
2562 struct samr_AddMultipleMembersToAlias a
;
2563 struct samr_RemoveMultipleMembersFromAlias r
;
2565 struct lsa_SidArray sids
;
2567 torture_comment(tctx
, "testing AddMultipleMembersToAlias\n");
2568 a
.in
.alias_handle
= alias_handle
;
2572 sids
.sids
= talloc_array(tctx
, struct lsa_SidPtr
, 3);
2574 sids
.sids
[0].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-1");
2575 sids
.sids
[1].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-2");
2576 sids
.sids
[2].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-3");
2578 status
= dcerpc_samr_AddMultipleMembersToAlias(p
, tctx
, &a
);
2579 torture_assert_ntstatus_ok(tctx
, status
, "AddMultipleMembersToAlias");
2582 torture_comment(tctx
, "testing RemoveMultipleMembersFromAlias\n");
2583 r
.in
.alias_handle
= alias_handle
;
2586 status
= dcerpc_samr_RemoveMultipleMembersFromAlias(p
, tctx
, &r
);
2587 torture_assert_ntstatus_ok(tctx
, status
, "RemoveMultipleMembersFromAlias");
2589 /* strange! removing twice doesn't give any error */
2590 status
= dcerpc_samr_RemoveMultipleMembersFromAlias(p
, tctx
, &r
);
2591 torture_assert_ntstatus_ok(tctx
, status
, "RemoveMultipleMembersFromAlias");
2593 /* but removing an alias that isn't there does */
2594 sids
.sids
[2].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-4");
2596 status
= dcerpc_samr_RemoveMultipleMembersFromAlias(p
, tctx
, &r
);
2597 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
, "RemoveMultipleMembersFromAlias");
2602 static bool test_GetAliasMembership(struct dcerpc_pipe
*p
,
2603 struct torture_context
*tctx
,
2604 struct policy_handle
*domain_handle
)
2606 struct samr_GetAliasMembership r
;
2607 struct lsa_SidArray sids
;
2608 struct samr_Ids rids
;
2611 torture_comment(tctx
, "Testing GetAliasMembership\n");
2613 if (torture_setting_bool(tctx
, "samba4", false)) {
2614 torture_skip(tctx
, "skipping GetAliasMembership against s4");
2617 r
.in
.domain_handle
= domain_handle
;
2622 sids
.sids
= talloc_zero_array(tctx
, struct lsa_SidPtr
, sids
.num_sids
);
2624 status
= dcerpc_samr_GetAliasMembership(p
, tctx
, &r
);
2625 torture_assert_ntstatus_ok(tctx
, status
,
2626 "samr_GetAliasMembership failed");
2628 torture_assert_int_equal(tctx
, sids
.num_sids
, rids
.count
,
2629 "protocol misbehaviour");
2632 sids
.sids
= talloc_zero_array(tctx
, struct lsa_SidPtr
, sids
.num_sids
);
2633 sids
.sids
[0].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-1");
2635 status
= dcerpc_samr_GetAliasMembership(p
, tctx
, &r
);
2636 torture_assert_ntstatus_ok(tctx
, status
,
2637 "samr_GetAliasMembership failed");
2640 /* only true for w2k8 it seems
2641 * win7, xp, w2k3 will return a 0 length array pointer */
2643 if (rids
.ids
&& (rids
.count
== 0)) {
2644 torture_fail(tctx
, "samr_GetAliasMembership returned 0 count and a rids array");
2647 if (!rids
.ids
&& rids
.count
) {
2648 torture_fail(tctx
, "samr_GetAliasMembership returned non-0 count but no rids");
2654 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2655 struct policy_handle
*user_handle
)
2657 struct samr_TestPrivateFunctionsUser r
;
2660 torture_comment(tctx
, "Testing TestPrivateFunctionsUser\n");
2662 r
.in
.user_handle
= user_handle
;
2664 status
= dcerpc_samr_TestPrivateFunctionsUser(p
, tctx
, &r
);
2665 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_NOT_IMPLEMENTED
, "TestPrivateFunctionsUser");
2670 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe
*p
,
2671 struct torture_context
*tctx
,
2672 struct policy_handle
*handle
,
2677 uint16_t levels
[] = { /* 3, */ 5, 21 };
2679 NTTIME pwdlastset3
= 0;
2680 NTTIME pwdlastset5
= 0;
2681 NTTIME pwdlastset21
= 0;
2683 torture_comment(tctx
, "Testing QueryUserInfo%s level 5 and 21 call ",
2684 use_info2
? "2":"");
2686 for (i
=0; i
<ARRAY_SIZE(levels
); i
++) {
2688 struct samr_QueryUserInfo r
;
2689 struct samr_QueryUserInfo2 r2
;
2690 union samr_UserInfo
*info
;
2693 r2
.in
.user_handle
= handle
;
2694 r2
.in
.level
= levels
[i
];
2695 r2
.out
.info
= &info
;
2696 status
= dcerpc_samr_QueryUserInfo2(p
, tctx
, &r2
);
2699 r
.in
.user_handle
= handle
;
2700 r
.in
.level
= levels
[i
];
2702 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &r
);
2705 if (!NT_STATUS_IS_OK(status
) &&
2706 !NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_INFO_CLASS
)) {
2707 torture_warning(tctx
, "QueryUserInfo%s level %u failed - %s\n",
2708 use_info2
? "2":"", levels
[i
], nt_errstr(status
));
2712 switch (levels
[i
]) {
2714 pwdlastset3
= info
->info3
.last_password_change
;
2717 pwdlastset5
= info
->info5
.last_password_change
;
2720 pwdlastset21
= info
->info21
.last_password_change
;
2726 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2727 "pwdlastset mixup"); */
2728 torture_assert_int_equal(tctx
, pwdlastset5
, pwdlastset21
,
2729 "pwdlastset mixup");
2731 *pwdlastset
= pwdlastset21
;
2733 torture_comment(tctx
, "(pwdlastset: %lld)\n", *pwdlastset
);
2738 static bool test_SamLogon(struct torture_context
*tctx
,
2739 struct dcerpc_pipe
*p
,
2740 struct cli_credentials
*test_credentials
,
2741 NTSTATUS expected_result
,
2745 struct netr_LogonSamLogonEx r
;
2746 union netr_LogonLevel logon
;
2747 union netr_Validation validation
;
2748 uint8_t authoritative
;
2749 struct netr_IdentityInfo identity
;
2750 struct netr_NetworkInfo ninfo
;
2751 struct netr_PasswordInfo pinfo
;
2752 DATA_BLOB names_blob
, chal
, lm_resp
, nt_resp
;
2753 int flags
= CLI_CRED_NTLM_AUTH
;
2754 uint32_t samlogon_flags
= 0;
2755 struct netlogon_creds_CredentialState
*creds
;
2756 struct netr_Authenticator a
;
2758 torture_assert_ntstatus_ok(tctx
, dcerpc_schannel_creds(p
->conn
->security_state
.generic_state
, tctx
, &creds
), "");
2760 if (lp_client_lanman_auth(tctx
->lp_ctx
)) {
2761 flags
|= CLI_CRED_LANMAN_AUTH
;
2764 if (lp_client_ntlmv2_auth(tctx
->lp_ctx
)) {
2765 flags
|= CLI_CRED_NTLMv2_AUTH
;
2768 cli_credentials_get_ntlm_username_domain(test_credentials
, tctx
,
2769 &identity
.account_name
.string
,
2770 &identity
.domain_name
.string
);
2772 identity
.parameter_control
=
2773 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT
|
2774 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT
;
2775 identity
.logon_id_low
= 0;
2776 identity
.logon_id_high
= 0;
2777 identity
.workstation
.string
= cli_credentials_get_workstation(test_credentials
);
2780 netlogon_creds_client_authenticator(creds
, &a
);
2782 if (!E_deshash(cli_credentials_get_password(test_credentials
), pinfo
.lmpassword
.hash
)) {
2783 ZERO_STRUCT(pinfo
.lmpassword
.hash
);
2785 E_md4hash(cli_credentials_get_password(test_credentials
), pinfo
.ntpassword
.hash
);
2787 if (creds
->negotiate_flags
& NETLOGON_NEG_ARCFOUR
) {
2788 netlogon_creds_arcfour_crypt(creds
, pinfo
.lmpassword
.hash
, 16);
2789 netlogon_creds_arcfour_crypt(creds
, pinfo
.ntpassword
.hash
, 16);
2791 netlogon_creds_des_encrypt(creds
, &pinfo
.lmpassword
);
2792 netlogon_creds_des_encrypt(creds
, &pinfo
.ntpassword
);
2795 pinfo
.identity_info
= identity
;
2796 logon
.password
= &pinfo
;
2798 r
.in
.logon_level
= NetlogonInteractiveInformation
;
2800 generate_random_buffer(ninfo
.challenge
,
2801 sizeof(ninfo
.challenge
));
2802 chal
= data_blob_const(ninfo
.challenge
,
2803 sizeof(ninfo
.challenge
));
2805 names_blob
= NTLMv2_generate_names_blob(tctx
, cli_credentials_get_workstation(test_credentials
),
2806 cli_credentials_get_domain(test_credentials
));
2808 status
= cli_credentials_get_ntlm_response(test_credentials
, tctx
,
2814 torture_assert_ntstatus_ok(tctx
, status
, "cli_credentials_get_ntlm_response failed");
2816 ninfo
.lm
.data
= lm_resp
.data
;
2817 ninfo
.lm
.length
= lm_resp
.length
;
2819 ninfo
.nt
.data
= nt_resp
.data
;
2820 ninfo
.nt
.length
= nt_resp
.length
;
2822 ninfo
.identity_info
= identity
;
2823 logon
.network
= &ninfo
;
2825 r
.in
.logon_level
= NetlogonNetworkInformation
;
2828 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2829 r
.in
.computer_name
= cli_credentials_get_workstation(test_credentials
);
2830 r
.in
.logon
= &logon
;
2831 r
.in
.flags
= &samlogon_flags
;
2832 r
.out
.flags
= &samlogon_flags
;
2833 r
.out
.validation
= &validation
;
2834 r
.out
.authoritative
= &authoritative
;
2836 torture_comment(tctx
, "Testing LogonSamLogon with name %s\n", identity
.account_name
.string
);
2838 r
.in
.validation_level
= 6;
2840 status
= dcerpc_netr_LogonSamLogonEx(p
, tctx
, &r
);
2841 if (NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_INFO_CLASS
)) {
2842 r
.in
.validation_level
= 3;
2843 status
= dcerpc_netr_LogonSamLogonEx(p
, tctx
, &r
);
2845 if (!NT_STATUS_IS_OK(status
)) {
2846 torture_assert_ntstatus_equal(tctx
, status
, expected_result
, "LogonSamLogonEx failed");
2849 torture_assert_ntstatus_ok(tctx
, status
, "LogonSamLogonEx failed");
2855 static bool test_SamLogon_with_creds(struct torture_context
*tctx
,
2856 struct dcerpc_pipe
*p
,
2857 struct cli_credentials
*machine_creds
,
2858 const char *acct_name
,
2860 NTSTATUS expected_samlogon_result
,
2864 struct cli_credentials
*test_credentials
;
2866 test_credentials
= cli_credentials_init(tctx
);
2868 cli_credentials_set_workstation(test_credentials
,
2869 cli_credentials_get_workstation(machine_creds
), CRED_SPECIFIED
);
2870 cli_credentials_set_domain(test_credentials
,
2871 cli_credentials_get_domain(machine_creds
), CRED_SPECIFIED
);
2872 cli_credentials_set_username(test_credentials
,
2873 acct_name
, CRED_SPECIFIED
);
2874 cli_credentials_set_password(test_credentials
,
2875 password
, CRED_SPECIFIED
);
2877 torture_comment(tctx
, "testing samlogon (%s) as %s password: %s\n",
2878 interactive
? "interactive" : "network", acct_name
, password
);
2880 if (!test_SamLogon(tctx
, p
, test_credentials
,
2881 expected_samlogon_result
, interactive
)) {
2882 torture_warning(tctx
, "new password did not work\n");
2889 static bool test_SetPassword_level(struct dcerpc_pipe
*p
,
2890 struct dcerpc_pipe
*np
,
2891 struct torture_context
*tctx
,
2892 struct policy_handle
*handle
,
2894 uint32_t fields_present
,
2895 uint8_t password_expired
,
2896 bool *matched_expected_error
,
2898 const char *acct_name
,
2900 struct cli_credentials
*machine_creds
,
2901 bool use_queryinfo2
,
2903 NTSTATUS expected_samlogon_result
)
2905 const char *fields
= NULL
;
2912 fields
= talloc_asprintf(tctx
, "(fields_present: 0x%08x)",
2919 torture_comment(tctx
, "Testing SetUserInfo%s level %d call "
2920 "(password_expired: %d) %s\n",
2921 use_setinfo2
? "2":"", level
, password_expired
,
2922 fields
? fields
: "");
2924 if (!test_SetUserPass_level_ex(p
, tctx
, handle
, level
,
2929 matched_expected_error
)) {
2933 if (!test_QueryUserInfo_pwdlastset(p
, tctx
, handle
,
2939 if (*matched_expected_error
== true) {
2943 if (!test_SamLogon_with_creds(tctx
, np
,
2947 expected_samlogon_result
,
2955 static bool setup_schannel_netlogon_pipe(struct torture_context
*tctx
,
2956 struct cli_credentials
*credentials
,
2957 struct dcerpc_pipe
**p
)
2959 struct dcerpc_binding
*b
;
2961 torture_assert_ntstatus_ok(tctx
, torture_rpc_binding(tctx
, &b
),
2962 "failed to get rpc binding");
2964 /* We have to use schannel, otherwise the SamLogonEx fails
2965 * with INTERNAL_ERROR */
2967 b
->flags
&= ~DCERPC_AUTH_OPTIONS
;
2968 b
->flags
|= DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_128
;
2970 torture_assert_ntstatus_ok(tctx
,
2971 dcerpc_pipe_connect_b(tctx
, p
, b
, &ndr_table_netlogon
,
2972 credentials
, tctx
->ev
, tctx
->lp_ctx
),
2973 "failed to bind to netlogon");
2978 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe
*p
,
2979 struct torture_context
*tctx
,
2980 uint32_t acct_flags
,
2981 const char *acct_name
,
2982 struct policy_handle
*handle
,
2984 struct cli_credentials
*machine_credentials
)
2986 int s
= 0, q
= 0, f
= 0, l
= 0, z
= 0;
2989 bool set_levels
[] = { false, true };
2990 bool query_levels
[] = { false, true };
2991 uint32_t levels
[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
2992 uint32_t nonzeros
[] = { 1, 24 };
2993 uint32_t fields_present
[] = {
2995 SAMR_FIELD_EXPIRED_FLAG
,
2996 SAMR_FIELD_LAST_PWD_CHANGE
,
2997 SAMR_FIELD_EXPIRED_FLAG
| SAMR_FIELD_LAST_PWD_CHANGE
,
2999 SAMR_FIELD_NT_PASSWORD_PRESENT
,
3000 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
,
3001 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
,
3002 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
,
3003 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_EXPIRED_FLAG
,
3004 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_EXPIRED_FLAG
,
3005 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
| SAMR_FIELD_EXPIRED_FLAG
3007 struct dcerpc_pipe
*np
= NULL
;
3009 if (torture_setting_bool(tctx
, "samba3", false)) {
3011 torture_comment(tctx
, "Samba3 has second granularity, setting delay to: %d\n",
3015 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
3017 /* set to 1 to enable testing for all possible opcode
3018 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3021 #define TEST_ALL_LEVELS 1
3022 #define TEST_SET_LEVELS 1
3023 #define TEST_QUERY_LEVELS 1
3025 #ifdef TEST_ALL_LEVELS
3026 for (l
=0; l
<ARRAY_SIZE(levels
); l
++) {
3028 for (l
=0; l
<(ARRAY_SIZE(levels
))/2; l
++) {
3030 for (z
=0; z
<ARRAY_SIZE(nonzeros
); z
++) {
3031 for (f
=0; f
<ARRAY_SIZE(fields_present
); f
++) {
3032 #ifdef TEST_SET_LEVELS
3033 for (s
=0; s
<ARRAY_SIZE(set_levels
); s
++) {
3035 #ifdef TEST_QUERY_LEVELS
3036 for (q
=0; q
<ARRAY_SIZE(query_levels
); q
++) {
3038 NTTIME pwdlastset_old
= 0;
3039 NTTIME pwdlastset_new
= 0;
3040 bool matched_expected_error
= false;
3041 NTSTATUS expected_samlogon_result
= NT_STATUS_ACCOUNT_DISABLED
;
3043 torture_comment(tctx
, "------------------------------\n"
3044 "Testing pwdLastSet attribute for flags: 0x%08x "
3045 "(s: %d (l: %d), q: %d)\n",
3046 acct_flags
, s
, levels
[l
], q
);
3048 switch (levels
[l
]) {
3052 if (!((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3053 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
))) {
3054 expected_samlogon_result
= NT_STATUS_WRONG_PASSWORD
;
3062 /* set a password and force password change (pwdlastset 0) by
3063 * setting the password expired flag to a non-0 value */
3065 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3069 &matched_expected_error
,
3073 machine_credentials
,
3076 expected_samlogon_result
)) {
3080 if (matched_expected_error
== true) {
3081 /* skipping on expected failure */
3085 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3086 * set without the SAMR_FIELD_EXPIRED_FLAG */
3088 switch (levels
[l
]) {
3092 if ((pwdlastset_new
!= 0) &&
3093 !(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
)) {
3094 torture_comment(tctx
, "not considering a non-0 "
3095 "pwdLastSet as a an error as the "
3096 "SAMR_FIELD_EXPIRED_FLAG has not "
3101 if (pwdlastset_new
!= 0) {
3102 torture_warning(tctx
, "pwdLastSet test failed: "
3103 "expected pwdLastSet 0 but got %lld\n",
3110 switch (levels
[l
]) {
3114 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3115 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3116 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3117 (pwdlastset_old
>= pwdlastset_new
)) {
3118 torture_warning(tctx
, "pwdlastset not increasing\n");
3123 if ((pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3124 (pwdlastset_old
>= pwdlastset_new
)) {
3125 torture_warning(tctx
, "pwdlastset not increasing\n");
3135 /* set a password, pwdlastset needs to get updated (increased
3136 * value), password_expired value used here is 0 */
3138 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3142 &matched_expected_error
,
3146 machine_credentials
,
3149 expected_samlogon_result
)) {
3153 /* when a password has been changed, pwdlastset must not be 0 afterwards
3154 * and must be larger then the old value */
3156 switch (levels
[l
]) {
3161 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3162 * password has been changed, old and new pwdlastset
3163 * need to be the same value */
3165 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
3166 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3167 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3169 torture_assert_int_equal(tctx
, pwdlastset_old
,
3170 pwdlastset_new
, "pwdlastset must be equal");
3174 if (pwdlastset_old
>= pwdlastset_new
) {
3175 torture_warning(tctx
, "pwdLastSet test failed: "
3176 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3177 pwdlastset_old
, pwdlastset_new
);
3180 if (pwdlastset_new
== 0) {
3181 torture_warning(tctx
, "pwdLastSet test failed: "
3182 "expected non-0 pwdlastset, got: %lld\n",
3188 switch (levels
[l
]) {
3192 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3193 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3194 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3195 (pwdlastset_old
>= pwdlastset_new
)) {
3196 torture_warning(tctx
, "pwdlastset not increasing\n");
3201 if ((pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3202 (pwdlastset_old
>= pwdlastset_new
)) {
3203 torture_warning(tctx
, "pwdlastset not increasing\n");
3209 pwdlastset_old
= pwdlastset_new
;
3215 /* set a password, pwdlastset needs to get updated (increased
3216 * value), password_expired value used here is 0 */
3218 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3222 &matched_expected_error
,
3226 machine_credentials
,
3229 expected_samlogon_result
)) {
3233 /* when a password has been changed, pwdlastset must not be 0 afterwards
3234 * and must be larger then the old value */
3236 switch (levels
[l
]) {
3241 /* if no password has been changed, old and new pwdlastset
3242 * need to be the same value */
3244 if (!((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3245 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3247 torture_assert_int_equal(tctx
, pwdlastset_old
,
3248 pwdlastset_new
, "pwdlastset must be equal");
3252 if (pwdlastset_old
>= pwdlastset_new
) {
3253 torture_warning(tctx
, "pwdLastSet test failed: "
3254 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3255 pwdlastset_old
, pwdlastset_new
);
3258 if (pwdlastset_new
== 0) {
3259 torture_warning(tctx
, "pwdLastSet test failed: "
3260 "expected non-0 pwdlastset, got: %lld\n",
3268 /* set a password and force password change (pwdlastset 0) by
3269 * setting the password expired flag to a non-0 value */
3271 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3275 &matched_expected_error
,
3279 machine_credentials
,
3282 expected_samlogon_result
)) {
3286 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3287 * set without the SAMR_FIELD_EXPIRED_FLAG */
3289 switch (levels
[l
]) {
3293 if ((pwdlastset_new
!= 0) &&
3294 !(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
)) {
3295 torture_comment(tctx
, "not considering a non-0 "
3296 "pwdLastSet as a an error as the "
3297 "SAMR_FIELD_EXPIRED_FLAG has not "
3302 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3303 * password has been changed, old and new pwdlastset
3304 * need to be the same value */
3306 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
3307 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3308 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3310 torture_assert_int_equal(tctx
, pwdlastset_old
,
3311 pwdlastset_new
, "pwdlastset must be equal");
3316 if (pwdlastset_old
== pwdlastset_new
) {
3317 torture_warning(tctx
, "pwdLastSet test failed: "
3318 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3319 pwdlastset_old
, pwdlastset_new
);
3323 if (pwdlastset_new
!= 0) {
3324 torture_warning(tctx
, "pwdLastSet test failed: "
3325 "expected pwdLastSet 0, got %lld\n",
3332 switch (levels
[l
]) {
3336 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3337 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3338 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3339 (pwdlastset_old
>= pwdlastset_new
)) {
3340 torture_warning(tctx
, "pwdlastset not increasing\n");
3345 if ((pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3346 (pwdlastset_old
>= pwdlastset_new
)) {
3347 torture_warning(tctx
, "pwdlastset not increasing\n");
3353 /* if the level we are testing does not have a fields_present
3354 * field, skip all fields present tests by setting f to to
3356 switch (levels
[l
]) {
3360 f
= ARRAY_SIZE(fields_present
);
3364 #ifdef TEST_QUERY_LEVELS
3367 #ifdef TEST_SET_LEVELS
3370 } /* fields present */
3374 #undef TEST_SET_LEVELS
3375 #undef TEST_QUERY_LEVELS
3382 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_pipe
*p
,
3383 struct torture_context
*tctx
,
3384 struct policy_handle
*handle
,
3385 uint32_t *badpwdcount
)
3387 union samr_UserInfo
*info
;
3388 struct samr_QueryUserInfo r
;
3390 r
.in
.user_handle
= handle
;
3394 torture_comment(tctx
, "Testing QueryUserInfo level %d", r
.in
.level
);
3396 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo(p
, tctx
, &r
),
3397 "failed to query userinfo");
3399 *badpwdcount
= info
->info3
.bad_password_count
;
3401 torture_comment(tctx
, " (bad password count: %d)\n", *badpwdcount
);
3406 static bool test_SetUserInfo_acct_flags(struct dcerpc_pipe
*p
,
3407 struct torture_context
*tctx
,
3408 struct policy_handle
*user_handle
,
3409 uint32_t acct_flags
)
3411 struct samr_SetUserInfo r
;
3412 union samr_UserInfo user_info
;
3414 torture_comment(tctx
, "Testing SetUserInfo level 16\n");
3416 user_info
.info16
.acct_flags
= acct_flags
;
3418 r
.in
.user_handle
= user_handle
;
3420 r
.in
.info
= &user_info
;
3422 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo(p
, tctx
, &r
),
3423 "failed to set account flags");
3428 static bool test_reset_badpwdcount(struct dcerpc_pipe
*p
,
3429 struct torture_context
*tctx
,
3430 struct policy_handle
*user_handle
,
3431 uint32_t acct_flags
,
3434 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
3435 "failed to set password");
3437 torture_comment(tctx
, "Testing SetUserInfo level 16 (enable account)\n");
3439 torture_assert(tctx
,
3440 test_SetUserInfo_acct_flags(p
, tctx
, user_handle
,
3441 acct_flags
& ~ACB_DISABLED
),
3442 "failed to enable user");
3444 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
3445 "failed to set password");
3450 static bool test_SetDomainInfo(struct dcerpc_pipe
*p
,
3451 struct torture_context
*tctx
,
3452 struct policy_handle
*domain_handle
,
3453 enum samr_DomainInfoClass level
,
3454 union samr_DomainInfo
*info
)
3456 struct samr_SetDomainInfo r
;
3458 r
.in
.domain_handle
= domain_handle
;
3462 torture_assert_ntstatus_ok(tctx
,
3463 dcerpc_samr_SetDomainInfo(p
, tctx
, &r
),
3464 "failed to set domain info");
3469 static bool test_SetDomainInfo_ntstatus(struct dcerpc_pipe
*p
,
3470 struct torture_context
*tctx
,
3471 struct policy_handle
*domain_handle
,
3472 enum samr_DomainInfoClass level
,
3473 union samr_DomainInfo
*info
,
3476 struct samr_SetDomainInfo r
;
3478 r
.in
.domain_handle
= domain_handle
;
3482 torture_assert_ntstatus_equal(tctx
,
3483 dcerpc_samr_SetDomainInfo(p
, tctx
, &r
),
3490 static bool test_QueryDomainInfo2_level(struct dcerpc_pipe
*p
,
3491 struct torture_context
*tctx
,
3492 struct policy_handle
*domain_handle
,
3493 enum samr_DomainInfoClass level
,
3494 union samr_DomainInfo
**q_info
)
3496 struct samr_QueryDomainInfo2 r
;
3498 r
.in
.domain_handle
= domain_handle
;
3500 r
.out
.info
= q_info
;
3502 torture_assert_ntstatus_ok(tctx
,
3503 dcerpc_samr_QueryDomainInfo2(p
, tctx
, &r
),
3504 "failed to query domain info");
3509 static bool test_Password_badpwdcount(struct dcerpc_pipe
*p
,
3510 struct dcerpc_pipe
*np
,
3511 struct torture_context
*tctx
,
3512 uint32_t acct_flags
,
3513 const char *acct_name
,
3514 struct policy_handle
*domain_handle
,
3515 struct policy_handle
*user_handle
,
3517 struct cli_credentials
*machine_credentials
,
3518 const char *comment
,
3521 NTSTATUS expected_success_status
,
3522 struct samr_DomInfo1
*info1
,
3523 struct samr_DomInfo12
*info12
)
3525 union samr_DomainInfo info
;
3528 uint32_t badpwdcount
, tmp
;
3529 uint32_t password_history_length
= 12;
3530 uint32_t lockout_threshold
= 15;
3532 torture_comment(tctx
, "\nTesting bad pwd count with: %s\n", comment
);
3534 torture_assert(tctx
, password_history_length
< lockout_threshold
,
3535 "password history length needs to be smaller than account lockout threshold for this test");
3540 info
.info1
= *info1
;
3541 info
.info1
.password_history_length
= password_history_length
;
3543 torture_assert(tctx
,
3544 test_SetDomainInfo(p
, tctx
, domain_handle
,
3545 DomainPasswordInformation
, &info
),
3546 "failed to set password history length");
3548 info
.info12
= *info12
;
3549 info
.info12
.lockout_threshold
= lockout_threshold
;
3551 torture_assert(tctx
,
3552 test_SetDomainInfo(p
, tctx
, domain_handle
,
3553 DomainLockoutInformation
, &info
),
3554 "failed to set lockout threshold");
3556 /* reset bad pwd count */
3558 torture_assert(tctx
,
3559 test_reset_badpwdcount(p
, tctx
, user_handle
, acct_flags
, password
), "");
3562 /* enable or disable account */
3564 torture_assert(tctx
,
3565 test_SetUserInfo_acct_flags(p
, tctx
, user_handle
,
3566 acct_flags
| ACB_DISABLED
),
3567 "failed to disable user");
3569 torture_assert(tctx
,
3570 test_SetUserInfo_acct_flags(p
, tctx
, user_handle
,
3571 acct_flags
& ~ACB_DISABLED
),
3572 "failed to enable user");
3576 /* setup password history */
3578 passwords
= talloc_array(tctx
, char *, password_history_length
);
3580 for (i
=0; i
< password_history_length
; i
++) {
3582 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
3583 "failed to set password");
3584 passwords
[i
] = talloc_strdup(tctx
, *password
);
3586 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3587 acct_name
, passwords
[i
],
3588 expected_success_status
, interactive
)) {
3589 torture_fail(tctx
, "failed to auth with latest password");
3592 torture_assert(tctx
,
3593 test_QueryUserInfo_badpwdcount(p
, tctx
, user_handle
, &badpwdcount
), "");
3595 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3599 /* test with wrong password */
3601 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3602 acct_name
, "random_crap",
3603 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
3604 torture_fail(tctx
, "succeeded to authenticate with wrong password");
3607 torture_assert(tctx
,
3608 test_QueryUserInfo_badpwdcount(p
, tctx
, user_handle
, &badpwdcount
), "");
3610 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
3613 /* test with latest good password */
3615 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
3616 passwords
[password_history_length
-1],
3617 expected_success_status
, interactive
)) {
3618 torture_fail(tctx
, "succeeded to authenticate with wrong password");
3621 torture_assert(tctx
,
3622 test_QueryUserInfo_badpwdcount(p
, tctx
, user_handle
, &badpwdcount
), "");
3625 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
3627 /* only enabled accounts get the bad pwd count reset upon
3628 * successful logon */
3629 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3635 /* test password history */
3637 for (i
=0; i
< password_history_length
; i
++) {
3639 torture_comment(tctx
, "Testing bad password count behavior with "
3640 "password #%d of #%d\n", i
, password_history_length
);
3642 /* - network samlogon will succeed auth and not
3643 * increase badpwdcount for 2 last entries
3644 * - interactive samlogon only for the last one */
3646 if (i
== password_history_length
- 1 ||
3647 (i
== password_history_length
- 2 && !interactive
)) {
3649 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3650 acct_name
, passwords
[i
],
3651 expected_success_status
, interactive
)) {
3652 torture_fail(tctx
, talloc_asprintf(tctx
, "succeeded to authenticate with old password (#%d of #%d in history)", i
, password_history_length
));
3655 torture_assert(tctx
,
3656 test_QueryUserInfo_badpwdcount(p
, tctx
, user_handle
, &badpwdcount
), "");
3659 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
3660 torture_assert_int_equal(tctx
, badpwdcount
, tmp
, "unexpected badpwdcount");
3662 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
3663 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3671 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3672 acct_name
, passwords
[i
],
3673 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
3674 torture_fail(tctx
, talloc_asprintf(tctx
, "succeeded to authenticate with old password (#%d of #%d in history)", i
, password_history_length
));
3677 torture_assert(tctx
,
3678 test_QueryUserInfo_badpwdcount(p
, tctx
, user_handle
, &badpwdcount
), "");
3680 /* - network samlogon will fail auth but not increase
3681 * badpwdcount for 3rd last entry
3682 * - interactive samlogon for 3rd and 2nd last entry */
3684 if (i
== password_history_length
- 3 ||
3685 (i
== password_history_length
- 2 && interactive
)) {
3686 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
3687 torture_assert_int_equal(tctx
, badpwdcount
, tmp
, "unexpected badpwdcount");
3689 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
3690 torture_assert_int_equal(tctx
, badpwdcount
, tmp
+ 1, "unexpected badpwdcount");
3699 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe
*p
,
3700 struct torture_context
*tctx
,
3701 uint32_t acct_flags
,
3702 const char *acct_name
,
3703 struct policy_handle
*domain_handle
,
3704 struct policy_handle
*user_handle
,
3706 struct cli_credentials
*machine_credentials
)
3708 union samr_DomainInfo
*q_info
, s_info
;
3709 struct samr_DomInfo1 info1
, _info1
;
3710 struct samr_DomInfo12 info12
, _info12
;
3712 struct dcerpc_pipe
*np
;
3716 const char *comment
;
3719 NTSTATUS expected_success_status
;
3722 .comment
= "network logon (disabled account)",
3724 .interactive
= false,
3725 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
3728 .comment
= "network logon (enabled account)",
3730 .interactive
= false,
3731 .expected_success_status
= NT_STATUS_OK
3734 .comment
= "interactive logon (disabled account)",
3736 .interactive
= true,
3737 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
3740 .comment
= "interactive logon (enabled account)",
3742 .interactive
= true,
3743 .expected_success_status
= NT_STATUS_OK
3747 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
3749 /* backup old policies */
3751 torture_assert(tctx
,
3752 test_QueryDomainInfo2_level(p
, tctx
, domain_handle
,
3753 DomainPasswordInformation
, &q_info
),
3754 "failed to query domain info level 1");
3756 info1
= q_info
->info1
;
3759 torture_assert(tctx
,
3760 test_QueryDomainInfo2_level(p
, tctx
, domain_handle
,
3761 DomainLockoutInformation
, &q_info
),
3762 "failed to query domain info level 12");
3764 info12
= q_info
->info12
;
3769 for (i
=0; i
< ARRAY_SIZE(creds
); i
++) {
3771 /* skip trust tests for now */
3772 if (acct_flags
& ACB_WSTRUST
||
3773 acct_flags
& ACB_SVRTRUST
||
3774 acct_flags
& ACB_DOMTRUST
) {
3778 ret
&= test_Password_badpwdcount(p
, np
, tctx
, acct_flags
, acct_name
,
3779 domain_handle
, user_handle
, password
,
3780 machine_credentials
,
3783 creds
[i
].interactive
,
3784 creds
[i
].expected_success_status
,
3787 torture_warning(tctx
, "TEST #%d (%s) failed\n", i
, creds
[i
].comment
);
3789 torture_comment(tctx
, "TEST #%d (%s) succeeded\n", i
, creds
[i
].comment
);
3793 /* restore policies */
3795 s_info
.info1
= info1
;
3797 torture_assert(tctx
,
3798 test_SetDomainInfo(p
, tctx
, domain_handle
,
3799 DomainPasswordInformation
, &s_info
),
3800 "failed to set password information");
3802 s_info
.info12
= info12
;
3804 torture_assert(tctx
,
3805 test_SetDomainInfo(p
, tctx
, domain_handle
,
3806 DomainLockoutInformation
, &s_info
),
3807 "failed to set lockout information");
3812 static bool test_QueryUserInfo_acct_flags(struct dcerpc_pipe
*p
,
3813 struct torture_context
*tctx
,
3814 struct policy_handle
*handle
,
3815 uint32_t *acct_flags
)
3817 union samr_UserInfo
*info
;
3818 struct samr_QueryUserInfo r
;
3820 r
.in
.user_handle
= handle
;
3824 torture_comment(tctx
, "Testing QueryUserInfo level %d", r
.in
.level
);
3826 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo(p
, tctx
, &r
),
3827 "failed to query userinfo");
3829 *acct_flags
= info
->info16
.acct_flags
;
3831 torture_comment(tctx
, " (acct_flags: 0x%08x)\n", *acct_flags
);
3836 static bool test_Password_lockout(struct dcerpc_pipe
*p
,
3837 struct dcerpc_pipe
*np
,
3838 struct torture_context
*tctx
,
3839 uint32_t acct_flags
,
3840 const char *acct_name
,
3841 struct policy_handle
*domain_handle
,
3842 struct policy_handle
*user_handle
,
3844 struct cli_credentials
*machine_credentials
,
3845 const char *comment
,
3848 NTSTATUS expected_success_status
,
3849 struct samr_DomInfo1
*info1
,
3850 struct samr_DomInfo12
*info12
)
3852 union samr_DomainInfo info
;
3853 uint32_t badpwdcount
;
3854 uint32_t password_history_length
= 1;
3855 uint64_t lockout_threshold
= 1;
3856 uint32_t lockout_seconds
= 5;
3857 uint64_t delta_time_factor
= 10 * 1000 * 1000;
3859 torture_comment(tctx
, "\nTesting account lockout: %s\n", comment
);
3863 info
.info1
= *info1
;
3865 torture_comment(tctx
, "setting password history lenght.\n");
3866 info
.info1
.password_history_length
= password_history_length
;
3868 torture_assert(tctx
,
3869 test_SetDomainInfo(p
, tctx
, domain_handle
,
3870 DomainPasswordInformation
, &info
),
3871 "failed to set password history length");
3873 info
.info12
= *info12
;
3874 info
.info12
.lockout_threshold
= lockout_threshold
;
3876 /* set lockout duration < lockout window: should fail */
3877 info
.info12
.lockout_duration
= ~(lockout_seconds
* delta_time_factor
);
3878 info
.info12
.lockout_window
= ~((lockout_seconds
+ 1) * delta_time_factor
);
3880 torture_assert(tctx
,
3881 test_SetDomainInfo_ntstatus(p
, tctx
, domain_handle
,
3882 DomainLockoutInformation
, &info
,
3883 NT_STATUS_INVALID_PARAMETER
),
3884 "setting lockout duration < lockout window gave unexpected result");
3886 info
.info12
.lockout_duration
= 0;
3887 info
.info12
.lockout_window
= 0;
3889 torture_assert(tctx
,
3890 test_SetDomainInfo(p
, tctx
, domain_handle
,
3891 DomainLockoutInformation
, &info
),
3892 "failed to set lockout window and duration to 0");
3895 /* set lockout duration of 5 seconds */
3896 info
.info12
.lockout_duration
= ~(lockout_seconds
* delta_time_factor
);
3897 info
.info12
.lockout_window
= ~(lockout_seconds
* delta_time_factor
);
3899 torture_assert(tctx
,
3900 test_SetDomainInfo(p
, tctx
, domain_handle
,
3901 DomainLockoutInformation
, &info
),
3902 "failed to set lockout window and duration to 5 seconds");
3904 /* reset bad pwd count */
3906 torture_assert(tctx
,
3907 test_reset_badpwdcount(p
, tctx
, user_handle
, acct_flags
, password
), "");
3910 /* enable or disable account */
3913 torture_assert(tctx
,
3914 test_SetUserInfo_acct_flags(p
, tctx
, user_handle
,
3915 acct_flags
| ACB_DISABLED
),
3916 "failed to disable user");
3918 torture_assert(tctx
,
3919 test_SetUserInfo_acct_flags(p
, tctx
, user_handle
,
3920 acct_flags
& ~ACB_DISABLED
),
3921 "failed to enable user");
3925 /* test logon with right password */
3927 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3928 acct_name
, *password
,
3929 expected_success_status
, interactive
)) {
3930 torture_fail(tctx
, "failed to auth with latest password");
3933 torture_assert(tctx
,
3934 test_QueryUserInfo_badpwdcount(p
, tctx
, user_handle
, &badpwdcount
), "");
3935 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3938 /* test with wrong password ==> lockout */
3940 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3941 acct_name
, "random_crap",
3942 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
3943 torture_fail(tctx
, "succeeded to authenticate with wrong password");
3946 torture_assert(tctx
,
3947 test_QueryUserInfo_badpwdcount(p
, tctx
, user_handle
, &badpwdcount
), "");
3948 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
3950 torture_assert(tctx
,
3951 test_QueryUserInfo_acct_flags(p
, tctx
, user_handle
, &acct_flags
), "");
3952 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
3953 "expected account to be locked");
3956 /* test with good password */
3958 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
3960 NT_STATUS_ACCOUNT_LOCKED_OUT
, interactive
))
3962 torture_fail(tctx
, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
3965 /* bad pwd count should not get updated */
3966 torture_assert(tctx
,
3967 test_QueryUserInfo_badpwdcount(p
, tctx
, user_handle
, &badpwdcount
), "");
3968 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
3970 /* curiously, windows does _not_ set the autlock flag */
3971 torture_assert(tctx
,
3972 test_QueryUserInfo_acct_flags(p
, tctx
, user_handle
, &acct_flags
), "");
3973 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
3974 "expected account to be locked");
3977 /* with bad password */
3979 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3980 acct_name
, "random_crap2",
3981 NT_STATUS_ACCOUNT_LOCKED_OUT
, interactive
))
3983 torture_fail(tctx
, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
3986 /* bad pwd count should not get updated */
3987 torture_assert(tctx
,
3988 test_QueryUserInfo_badpwdcount(p
, tctx
, user_handle
, &badpwdcount
), "");
3989 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
3991 /* curiously, windows does _not_ set the autlock flag */
3992 torture_assert(tctx
,
3993 test_QueryUserInfo_acct_flags(p
, tctx
, user_handle
, &acct_flags
), "");
3994 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
3995 "expected account to be locked");
3998 /* let lockout duration expire ==> unlock */
4000 torture_comment(tctx
, "let lockout duration expire...\n");
4001 sleep(lockout_seconds
+ 1);
4003 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
4005 expected_success_status
, interactive
))
4007 torture_fail(tctx
, "failed to authenticate after lockout expired");
4010 torture_assert(tctx
,
4011 test_QueryUserInfo_acct_flags(p
, tctx
, user_handle
, &acct_flags
), "");
4012 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
4013 "expected account not to be locked");
4018 static bool test_Password_lockout_wrap(struct dcerpc_pipe
*p
,
4019 struct torture_context
*tctx
,
4020 uint32_t acct_flags
,
4021 const char *acct_name
,
4022 struct policy_handle
*domain_handle
,
4023 struct policy_handle
*user_handle
,
4025 struct cli_credentials
*machine_credentials
)
4027 union samr_DomainInfo
*q_info
, s_info
;
4028 struct samr_DomInfo1 info1
, _info1
;
4029 struct samr_DomInfo12 info12
, _info12
;
4031 struct dcerpc_pipe
*np
;
4035 const char *comment
;
4038 NTSTATUS expected_success_status
;
4041 .comment
= "network logon (disabled account)",
4043 .interactive
= false,
4044 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
4047 .comment
= "network logon (enabled account)",
4049 .interactive
= false,
4050 .expected_success_status
= NT_STATUS_OK
4053 .comment
= "interactive logon (disabled account)",
4055 .interactive
= true,
4056 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
4059 .comment
= "interactive logon (enabled account)",
4061 .interactive
= true,
4062 .expected_success_status
= NT_STATUS_OK
4066 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
4068 /* backup old policies */
4070 torture_assert(tctx
,
4071 test_QueryDomainInfo2_level(p
, tctx
, domain_handle
,
4072 DomainPasswordInformation
, &q_info
),
4073 "failed to query domain info level 1");
4075 info1
= q_info
->info1
;
4078 torture_assert(tctx
,
4079 test_QueryDomainInfo2_level(p
, tctx
, domain_handle
,
4080 DomainLockoutInformation
, &q_info
),
4081 "failed to query domain info level 12");
4083 info12
= q_info
->info12
;
4088 for (i
=0; i
< ARRAY_SIZE(creds
); i
++) {
4090 /* skip trust tests for now */
4091 if (acct_flags
& ACB_WSTRUST
||
4092 acct_flags
& ACB_SVRTRUST
||
4093 acct_flags
& ACB_DOMTRUST
) {
4097 ret
&= test_Password_lockout(p
, np
, tctx
, acct_flags
, acct_name
,
4098 domain_handle
, user_handle
, password
,
4099 machine_credentials
,
4102 creds
[i
].interactive
,
4103 creds
[i
].expected_success_status
,
4106 torture_warning(tctx
, "TEST #%d (%s) failed\n", i
, creds
[i
].comment
);
4108 torture_comment(tctx
, "TEST #%d (%s) succeeded\n", i
, creds
[i
].comment
);
4112 /* restore policies */
4114 s_info
.info1
= info1
;
4116 torture_assert(tctx
,
4117 test_SetDomainInfo(p
, tctx
, domain_handle
,
4118 DomainPasswordInformation
, &s_info
),
4119 "failed to set password information");
4121 s_info
.info12
= info12
;
4123 torture_assert(tctx
,
4124 test_SetDomainInfo(p
, tctx
, domain_handle
,
4125 DomainLockoutInformation
, &s_info
),
4126 "failed to set lockout information");
4131 static bool test_DeleteUser_with_privs(struct dcerpc_pipe
*p
,
4132 struct dcerpc_pipe
*lp
,
4133 struct torture_context
*tctx
,
4134 struct policy_handle
*domain_handle
,
4135 struct policy_handle
*lsa_handle
,
4136 struct policy_handle
*user_handle
,
4137 const struct dom_sid
*domain_sid
,
4139 struct cli_credentials
*machine_credentials
)
4144 struct policy_handle lsa_acct_handle
;
4145 struct dom_sid
*user_sid
;
4147 user_sid
= dom_sid_add_rid(tctx
, domain_sid
, rid
);
4150 struct lsa_EnumAccountRights r
;
4151 struct lsa_RightSet rights
;
4153 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4155 r
.in
.handle
= lsa_handle
;
4156 r
.in
.sid
= user_sid
;
4157 r
.out
.rights
= &rights
;
4159 status
= dcerpc_lsa_EnumAccountRights(lp
, tctx
, &r
);
4160 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
4161 "Expected enum rights for account to fail");
4165 struct lsa_RightSet rights
;
4166 struct lsa_StringLarge names
[2];
4167 struct lsa_AddAccountRights r
;
4169 torture_comment(tctx
, "Testing LSA AddAccountRights\n");
4171 init_lsa_StringLarge(&names
[0], "SeMachineAccountPrivilege");
4172 init_lsa_StringLarge(&names
[1], NULL
);
4175 rights
.names
= names
;
4177 r
.in
.handle
= lsa_handle
;
4178 r
.in
.sid
= user_sid
;
4179 r
.in
.rights
= &rights
;
4181 status
= dcerpc_lsa_AddAccountRights(lp
, tctx
, &r
);
4182 torture_assert_ntstatus_ok(tctx
, status
,
4183 "Failed to add privileges");
4187 struct lsa_EnumAccounts r
;
4188 uint32_t resume_handle
= 0;
4189 struct lsa_SidArray lsa_sid_array
;
4191 bool found_sid
= false;
4193 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
4195 r
.in
.handle
= lsa_handle
;
4196 r
.in
.num_entries
= 0x1000;
4197 r
.in
.resume_handle
= &resume_handle
;
4198 r
.out
.sids
= &lsa_sid_array
;
4199 r
.out
.resume_handle
= &resume_handle
;
4201 status
= dcerpc_lsa_EnumAccounts(lp
, tctx
, &r
);
4202 torture_assert_ntstatus_ok(tctx
, status
,
4203 "Failed to enum accounts");
4205 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
4206 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
4211 torture_assert(tctx
, found_sid
,
4212 "failed to list privileged account");
4216 struct lsa_EnumAccountRights r
;
4217 struct lsa_RightSet user_rights
;
4219 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4221 r
.in
.handle
= lsa_handle
;
4222 r
.in
.sid
= user_sid
;
4223 r
.out
.rights
= &user_rights
;
4225 status
= dcerpc_lsa_EnumAccountRights(lp
, tctx
, &r
);
4226 torture_assert_ntstatus_ok(tctx
, status
,
4227 "Failed to enum rights for account");
4229 if (user_rights
.count
< 1) {
4230 torture_warning(tctx
, "failed to find newly added rights");
4236 struct lsa_OpenAccount r
;
4238 torture_comment(tctx
, "Testing LSA OpenAccount\n");
4240 r
.in
.handle
= lsa_handle
;
4241 r
.in
.sid
= user_sid
;
4242 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4243 r
.out
.acct_handle
= &lsa_acct_handle
;
4245 status
= dcerpc_lsa_OpenAccount(lp
, tctx
, &r
);
4246 torture_assert_ntstatus_ok(tctx
, status
,
4247 "Failed to open lsa account");
4251 struct lsa_GetSystemAccessAccount r
;
4252 uint32_t access_mask
;
4254 torture_comment(tctx
, "Testing LSA GetSystemAccessAccount\n");
4256 r
.in
.handle
= &lsa_acct_handle
;
4257 r
.out
.access_mask
= &access_mask
;
4259 status
= dcerpc_lsa_GetSystemAccessAccount(lp
, tctx
, &r
);
4260 torture_assert_ntstatus_ok(tctx
, status
,
4261 "Failed to get lsa system access account");
4267 torture_comment(tctx
, "Testing LSA Close\n");
4269 r
.in
.handle
= &lsa_acct_handle
;
4270 r
.out
.handle
= &lsa_acct_handle
;
4272 status
= dcerpc_lsa_Close(lp
, tctx
, &r
);
4273 torture_assert_ntstatus_ok(tctx
, status
,
4274 "Failed to close lsa");
4278 struct samr_DeleteUser r
;
4280 torture_comment(tctx
, "Testing SAMR DeleteUser\n");
4282 r
.in
.user_handle
= user_handle
;
4283 r
.out
.user_handle
= user_handle
;
4285 status
= dcerpc_samr_DeleteUser(p
, tctx
, &r
);
4286 torture_assert_ntstatus_ok(tctx
, status
, "Delete User failed");
4290 struct lsa_EnumAccounts r
;
4291 uint32_t resume_handle
= 0;
4292 struct lsa_SidArray lsa_sid_array
;
4294 bool found_sid
= false;
4296 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
4298 r
.in
.handle
= lsa_handle
;
4299 r
.in
.num_entries
= 0x1000;
4300 r
.in
.resume_handle
= &resume_handle
;
4301 r
.out
.sids
= &lsa_sid_array
;
4302 r
.out
.resume_handle
= &resume_handle
;
4304 status
= dcerpc_lsa_EnumAccounts(lp
, tctx
, &r
);
4305 torture_assert_ntstatus_ok(tctx
, status
,
4306 "Failed to enum accounts");
4308 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
4309 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
4314 torture_assert(tctx
, found_sid
,
4315 "failed to list privileged account");
4319 struct lsa_EnumAccountRights r
;
4320 struct lsa_RightSet user_rights
;
4322 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4324 r
.in
.handle
= lsa_handle
;
4325 r
.in
.sid
= user_sid
;
4326 r
.out
.rights
= &user_rights
;
4328 status
= dcerpc_lsa_EnumAccountRights(lp
, tctx
, &r
);
4329 torture_assert_ntstatus_ok(tctx
, status
,
4330 "Failed to enum rights for account");
4332 if (user_rights
.count
< 1) {
4333 torture_warning(tctx
, "failed to find newly added rights");
4339 struct lsa_OpenAccount r
;
4341 torture_comment(tctx
, "Testing LSA OpenAccount\n");
4343 r
.in
.handle
= lsa_handle
;
4344 r
.in
.sid
= user_sid
;
4345 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4346 r
.out
.acct_handle
= &lsa_acct_handle
;
4348 status
= dcerpc_lsa_OpenAccount(lp
, tctx
, &r
);
4349 torture_assert_ntstatus_ok(tctx
, status
,
4350 "Failed to open lsa account");
4354 struct lsa_GetSystemAccessAccount r
;
4355 uint32_t access_mask
;
4357 torture_comment(tctx
, "Testing LSA GetSystemAccessAccount\n");
4359 r
.in
.handle
= &lsa_acct_handle
;
4360 r
.out
.access_mask
= &access_mask
;
4362 status
= dcerpc_lsa_GetSystemAccessAccount(lp
, tctx
, &r
);
4363 torture_assert_ntstatus_ok(tctx
, status
,
4364 "Failed to get lsa system access account");
4368 struct lsa_DeleteObject r
;
4370 torture_comment(tctx
, "Testing LSA DeleteObject\n");
4372 r
.in
.handle
= &lsa_acct_handle
;
4373 r
.out
.handle
= &lsa_acct_handle
;
4375 status
= dcerpc_lsa_DeleteObject(lp
, tctx
, &r
);
4376 torture_assert_ntstatus_ok(tctx
, status
,
4377 "Failed to delete object");
4381 struct lsa_EnumAccounts r
;
4382 uint32_t resume_handle
= 0;
4383 struct lsa_SidArray lsa_sid_array
;
4385 bool found_sid
= false;
4387 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
4389 r
.in
.handle
= lsa_handle
;
4390 r
.in
.num_entries
= 0x1000;
4391 r
.in
.resume_handle
= &resume_handle
;
4392 r
.out
.sids
= &lsa_sid_array
;
4393 r
.out
.resume_handle
= &resume_handle
;
4395 status
= dcerpc_lsa_EnumAccounts(lp
, tctx
, &r
);
4396 torture_assert_ntstatus_ok(tctx
, status
,
4397 "Failed to enum accounts");
4399 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
4400 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
4405 torture_assert(tctx
, !found_sid
,
4406 "should not have listed privileged account");
4410 struct lsa_EnumAccountRights r
;
4411 struct lsa_RightSet user_rights
;
4413 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4415 r
.in
.handle
= lsa_handle
;
4416 r
.in
.sid
= user_sid
;
4417 r
.out
.rights
= &user_rights
;
4419 status
= dcerpc_lsa_EnumAccountRights(lp
, tctx
, &r
);
4420 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
4421 "Failed to enum rights for account");
4427 static bool test_user_ops(struct dcerpc_pipe
*p
,
4428 struct torture_context
*tctx
,
4429 struct policy_handle
*user_handle
,
4430 struct policy_handle
*domain_handle
,
4431 const struct dom_sid
*domain_sid
,
4432 uint32_t base_acct_flags
,
4433 const char *base_acct_name
, enum torture_samr_choice which_ops
,
4434 struct cli_credentials
*machine_credentials
)
4436 char *password
= NULL
;
4437 struct samr_QueryUserInfo q
;
4438 union samr_UserInfo
*info
;
4444 const uint32_t password_fields
[] = {
4445 SAMR_FIELD_NT_PASSWORD_PRESENT
,
4446 SAMR_FIELD_LM_PASSWORD_PRESENT
,
4447 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
,
4451 status
= test_LookupName(p
, tctx
, domain_handle
, base_acct_name
, &rid
);
4452 if (!NT_STATUS_IS_OK(status
)) {
4456 switch (which_ops
) {
4457 case TORTURE_SAMR_USER_ATTRIBUTES
:
4458 if (!test_QuerySecurity(p
, tctx
, user_handle
)) {
4462 if (!test_QueryUserInfo(p
, tctx
, user_handle
)) {
4466 if (!test_QueryUserInfo2(p
, tctx
, user_handle
)) {
4470 if (!test_SetUserInfo(p
, tctx
, user_handle
, base_acct_flags
,
4475 if (!test_GetUserPwInfo(p
, tctx
, user_handle
)) {
4479 if (!test_TestPrivateFunctionsUser(p
, tctx
, user_handle
)) {
4483 if (!test_SetUserPass(p
, tctx
, user_handle
, &password
)) {
4487 case TORTURE_SAMR_PASSWORDS
:
4488 if (base_acct_flags
& (ACB_WSTRUST
|ACB_DOMTRUST
|ACB_SVRTRUST
)) {
4489 char simple_pass
[9];
4490 char *v
= generate_random_str(tctx
, 1);
4492 ZERO_STRUCT(simple_pass
);
4493 memset(simple_pass
, *v
, sizeof(simple_pass
) - 1);
4495 torture_comment(tctx
, "Testing machine account password policy rules\n");
4497 /* Workstation trust accounts don't seem to need to honour password quality policy */
4498 if (!test_SetUserPassEx(p
, tctx
, user_handle
, true, &password
)) {
4502 if (!test_ChangePasswordUser2(p
, tctx
, base_acct_name
, &password
, simple_pass
, false)) {
4506 /* reset again, to allow another 'user' password change */
4507 if (!test_SetUserPassEx(p
, tctx
, user_handle
, true, &password
)) {
4511 /* Try a 'short' password */
4512 if (!test_ChangePasswordUser2(p
, tctx
, base_acct_name
, &password
, samr_rand_pass(tctx
, 4), false)) {
4516 /* Try a compleatly random password */
4517 if (!test_ChangePasswordRandomBytes(p
, tctx
, base_acct_name
, user_handle
, &password
)) {
4522 for (i
= 0; password_fields
[i
]; i
++) {
4523 if (!test_SetUserPass_23(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
4527 /* check it was set right */
4528 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4533 for (i
= 0; password_fields
[i
]; i
++) {
4534 if (!test_SetUserPass_25(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
4538 /* check it was set right */
4539 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4544 if (!test_SetUserPassEx(p
, tctx
, user_handle
, false, &password
)) {
4548 if (!test_ChangePassword(p
, tctx
, base_acct_name
, domain_handle
, &password
)) {
4552 if (torture_setting_bool(tctx
, "samba4", false)) {
4553 torture_comment(tctx
, "skipping Set Password level 18 and 21 against Samba4\n");
4556 if (!test_SetUserPass_18(p
, tctx
, user_handle
, &password
)) {
4560 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4564 for (i
= 0; password_fields
[i
]; i
++) {
4566 if (password_fields
[i
] == SAMR_FIELD_LM_PASSWORD_PRESENT
) {
4567 /* we need to skip as that would break
4568 * the ChangePasswordUser3 verify */
4572 if (!test_SetUserPass_21(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
4576 /* check it was set right */
4577 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4583 q
.in
.user_handle
= user_handle
;
4587 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &q
);
4588 if (!NT_STATUS_IS_OK(status
)) {
4589 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
4590 q
.in
.level
, nt_errstr(status
));
4593 uint32_t expected_flags
= (base_acct_flags
| ACB_PWNOTREQ
| ACB_DISABLED
);
4594 if ((info
->info5
.acct_flags
) != expected_flags
) {
4595 torture_warning(tctx
, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4596 info
->info5
.acct_flags
,
4599 if (!torture_setting_bool(tctx
, "samba3", false)) {
4603 if (info
->info5
.rid
!= rid
) {
4604 torture_warning(tctx
, "QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
4605 info
->info5
.rid
, rid
);
4612 case TORTURE_SAMR_PASSWORDS_PWDLASTSET
:
4614 /* test last password change timestamp behaviour */
4615 if (!test_SetPassword_pwdlastset(p
, tctx
, base_acct_flags
,
4617 user_handle
, &password
,
4618 machine_credentials
)) {
4623 torture_comment(tctx
, "pwdLastSet test succeeded\n");
4625 torture_warning(tctx
, "pwdLastSet test failed\n");
4630 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
:
4632 /* test bad pwd count change behaviour */
4633 if (!test_Password_badpwdcount_wrap(p
, tctx
, base_acct_flags
,
4636 user_handle
, &password
,
4637 machine_credentials
)) {
4642 torture_comment(tctx
, "badPwdCount test succeeded\n");
4644 torture_warning(tctx
, "badPwdCount test failed\n");
4649 case TORTURE_SAMR_PASSWORDS_LOCKOUT
:
4651 if (!test_Password_lockout_wrap(p
, tctx
, base_acct_flags
,
4654 user_handle
, &password
,
4655 machine_credentials
))
4661 torture_comment(tctx
, "lockout test succeeded\n");
4663 torture_warning(tctx
, "lockout test failed\n");
4669 case TORTURE_SAMR_USER_PRIVILEGES
: {
4671 struct dcerpc_pipe
*lp
;
4672 struct policy_handle
*lsa_handle
;
4674 status
= torture_rpc_connection(tctx
, &lp
, &ndr_table_lsarpc
);
4675 torture_assert_ntstatus_ok(tctx
, status
, "Failed to open LSA pipe");
4677 if (!test_lsa_OpenPolicy2(lp
, tctx
, &lsa_handle
)) {
4681 if (!test_DeleteUser_with_privs(p
, lp
, tctx
,
4682 domain_handle
, lsa_handle
, user_handle
,
4684 machine_credentials
)) {
4688 if (!test_lsa_Close(lp
, tctx
, lsa_handle
)) {
4693 torture_warning(tctx
, "privileged user delete test failed\n");
4698 case TORTURE_SAMR_OTHER
:
4699 /* We just need the account to exist */
4705 static bool test_alias_ops(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4706 struct policy_handle
*alias_handle
,
4707 const struct dom_sid
*domain_sid
)
4711 if (!torture_setting_bool(tctx
, "samba3", false)) {
4712 if (!test_QuerySecurity(p
, tctx
, alias_handle
)) {
4717 if (!test_QueryAliasInfo(p
, tctx
, alias_handle
)) {
4721 if (!test_SetAliasInfo(p
, tctx
, alias_handle
)) {
4725 if (!test_AddMemberToAlias(p
, tctx
, alias_handle
, domain_sid
)) {
4729 if (torture_setting_bool(tctx
, "samba3", false) ||
4730 torture_setting_bool(tctx
, "samba4", false)) {
4731 torture_comment(tctx
, "skipping MultipleMembers Alias tests against Samba\n");
4735 if (!test_AddMultipleMembersToAlias(p
, tctx
, alias_handle
)) {
4743 static bool test_DeleteUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4744 struct policy_handle
*user_handle
)
4746 struct samr_DeleteUser d
;
4748 torture_comment(tctx
, "Testing DeleteUser\n");
4750 d
.in
.user_handle
= user_handle
;
4751 d
.out
.user_handle
= user_handle
;
4753 status
= dcerpc_samr_DeleteUser(p
, tctx
, &d
);
4754 torture_assert_ntstatus_ok(tctx
, status
, "DeleteUser");
4759 bool test_DeleteUser_byname(struct dcerpc_pipe
*p
,
4760 struct torture_context
*tctx
,
4761 struct policy_handle
*handle
, const char *name
)
4764 struct samr_DeleteUser d
;
4765 struct policy_handle user_handle
;
4768 status
= test_LookupName(p
, tctx
, handle
, name
, &rid
);
4769 if (!NT_STATUS_IS_OK(status
)) {
4773 status
= test_OpenUser_byname(p
, tctx
, handle
, name
, &user_handle
);
4774 if (!NT_STATUS_IS_OK(status
)) {
4778 d
.in
.user_handle
= &user_handle
;
4779 d
.out
.user_handle
= &user_handle
;
4780 status
= dcerpc_samr_DeleteUser(p
, tctx
, &d
);
4781 if (!NT_STATUS_IS_OK(status
)) {
4788 torture_warning(tctx
, "DeleteUser_byname(%s) failed - %s\n", name
, nt_errstr(status
));
4793 static bool test_DeleteGroup_byname(struct dcerpc_pipe
*p
,
4794 struct torture_context
*tctx
,
4795 struct policy_handle
*handle
, const char *name
)
4798 struct samr_OpenGroup r
;
4799 struct samr_DeleteDomainGroup d
;
4800 struct policy_handle group_handle
;
4803 status
= test_LookupName(p
, tctx
, handle
, name
, &rid
);
4804 if (!NT_STATUS_IS_OK(status
)) {
4808 r
.in
.domain_handle
= handle
;
4809 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4811 r
.out
.group_handle
= &group_handle
;
4812 status
= dcerpc_samr_OpenGroup(p
, tctx
, &r
);
4813 if (!NT_STATUS_IS_OK(status
)) {
4817 d
.in
.group_handle
= &group_handle
;
4818 d
.out
.group_handle
= &group_handle
;
4819 status
= dcerpc_samr_DeleteDomainGroup(p
, tctx
, &d
);
4820 if (!NT_STATUS_IS_OK(status
)) {
4827 torture_warning(tctx
, "DeleteGroup_byname(%s) failed - %s\n", name
, nt_errstr(status
));
4832 static bool test_DeleteAlias_byname(struct dcerpc_pipe
*p
,
4833 struct torture_context
*tctx
,
4834 struct policy_handle
*domain_handle
,
4838 struct samr_OpenAlias r
;
4839 struct samr_DeleteDomAlias d
;
4840 struct policy_handle alias_handle
;
4843 torture_comment(tctx
, "testing DeleteAlias_byname\n");
4845 status
= test_LookupName(p
, tctx
, domain_handle
, name
, &rid
);
4846 if (!NT_STATUS_IS_OK(status
)) {
4850 r
.in
.domain_handle
= domain_handle
;
4851 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4853 r
.out
.alias_handle
= &alias_handle
;
4854 status
= dcerpc_samr_OpenAlias(p
, tctx
, &r
);
4855 if (!NT_STATUS_IS_OK(status
)) {
4859 d
.in
.alias_handle
= &alias_handle
;
4860 d
.out
.alias_handle
= &alias_handle
;
4861 status
= dcerpc_samr_DeleteDomAlias(p
, tctx
, &d
);
4862 if (!NT_STATUS_IS_OK(status
)) {
4869 torture_warning(tctx
, "DeleteAlias_byname(%s) failed - %s\n", name
, nt_errstr(status
));
4873 static bool test_DeleteAlias(struct dcerpc_pipe
*p
,
4874 struct torture_context
*tctx
,
4875 struct policy_handle
*alias_handle
)
4877 struct samr_DeleteDomAlias d
;
4881 torture_comment(tctx
, "Testing DeleteAlias\n");
4883 d
.in
.alias_handle
= alias_handle
;
4884 d
.out
.alias_handle
= alias_handle
;
4886 status
= dcerpc_samr_DeleteDomAlias(p
, tctx
, &d
);
4887 if (!NT_STATUS_IS_OK(status
)) {
4888 torture_warning(tctx
, "DeleteAlias failed - %s\n", nt_errstr(status
));
4895 static bool test_CreateAlias(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4896 struct policy_handle
*domain_handle
,
4897 const char *alias_name
,
4898 struct policy_handle
*alias_handle
,
4899 const struct dom_sid
*domain_sid
,
4903 struct samr_CreateDomAlias r
;
4904 struct lsa_String name
;
4908 init_lsa_String(&name
, alias_name
);
4909 r
.in
.domain_handle
= domain_handle
;
4910 r
.in
.alias_name
= &name
;
4911 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4912 r
.out
.alias_handle
= alias_handle
;
4915 torture_comment(tctx
, "Testing CreateAlias (%s)\n", r
.in
.alias_name
->string
);
4917 status
= dcerpc_samr_CreateDomAlias(p
, tctx
, &r
);
4919 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
4920 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
4921 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.alias_name
->string
);
4924 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.alias_name
->string
,
4930 if (NT_STATUS_EQUAL(status
, NT_STATUS_ALIAS_EXISTS
)) {
4931 if (!test_DeleteAlias_byname(p
, tctx
, domain_handle
, r
.in
.alias_name
->string
)) {
4934 status
= dcerpc_samr_CreateDomAlias(p
, tctx
, &r
);
4937 if (!NT_STATUS_IS_OK(status
)) {
4938 torture_warning(tctx
, "CreateAlias failed - %s\n", nt_errstr(status
));
4946 if (!test_alias_ops(p
, tctx
, alias_handle
, domain_sid
)) {
4953 static bool test_ChangePassword(struct dcerpc_pipe
*p
,
4954 struct torture_context
*tctx
,
4955 const char *acct_name
,
4956 struct policy_handle
*domain_handle
, char **password
)
4964 if (!test_ChangePasswordUser(p
, tctx
, acct_name
, domain_handle
, password
)) {
4968 if (!test_ChangePasswordUser2(p
, tctx
, acct_name
, password
, 0, true)) {
4972 if (!test_OemChangePasswordUser2(p
, tctx
, acct_name
, domain_handle
, password
)) {
4976 /* test what happens when setting the old password again */
4977 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, *password
, 0, true)) {
4982 char simple_pass
[9];
4983 char *v
= generate_random_str(tctx
, 1);
4985 ZERO_STRUCT(simple_pass
);
4986 memset(simple_pass
, *v
, sizeof(simple_pass
) - 1);
4988 /* test what happens when picking a simple password */
4989 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, simple_pass
, 0, true)) {
4994 /* set samr_SetDomainInfo level 1 with min_length 5 */
4996 struct samr_QueryDomainInfo r
;
4997 union samr_DomainInfo
*info
= NULL
;
4998 struct samr_SetDomainInfo s
;
4999 uint16_t len_old
, len
;
5000 uint32_t pwd_prop_old
;
5001 int64_t min_pwd_age_old
;
5006 r
.in
.domain_handle
= domain_handle
;
5010 torture_comment(tctx
, "testing samr_QueryDomainInfo level 1\n");
5011 status
= dcerpc_samr_QueryDomainInfo(p
, tctx
, &r
);
5012 if (!NT_STATUS_IS_OK(status
)) {
5016 s
.in
.domain_handle
= domain_handle
;
5020 /* remember the old min length, so we can reset it */
5021 len_old
= s
.in
.info
->info1
.min_password_length
;
5022 s
.in
.info
->info1
.min_password_length
= len
;
5023 pwd_prop_old
= s
.in
.info
->info1
.password_properties
;
5024 /* turn off password complexity checks for this test */
5025 s
.in
.info
->info1
.password_properties
&= ~DOMAIN_PASSWORD_COMPLEX
;
5027 min_pwd_age_old
= s
.in
.info
->info1
.min_password_age
;
5028 s
.in
.info
->info1
.min_password_age
= 0;
5030 torture_comment(tctx
, "testing samr_SetDomainInfo level 1\n");
5031 status
= dcerpc_samr_SetDomainInfo(p
, tctx
, &s
);
5032 if (!NT_STATUS_IS_OK(status
)) {
5036 torture_comment(tctx
, "calling test_ChangePasswordUser3 with too short password\n");
5038 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, len
- 1, password
, NULL
, 0, true)) {
5042 s
.in
.info
->info1
.min_password_length
= len_old
;
5043 s
.in
.info
->info1
.password_properties
= pwd_prop_old
;
5044 s
.in
.info
->info1
.min_password_age
= min_pwd_age_old
;
5046 torture_comment(tctx
, "testing samr_SetDomainInfo level 1\n");
5047 status
= dcerpc_samr_SetDomainInfo(p
, tctx
, &s
);
5048 if (!NT_STATUS_IS_OK(status
)) {
5056 struct samr_OpenUser r
;
5057 struct samr_QueryUserInfo q
;
5058 union samr_UserInfo
*info
;
5059 struct samr_LookupNames n
;
5060 struct policy_handle user_handle
;
5061 struct samr_Ids rids
, types
;
5063 n
.in
.domain_handle
= domain_handle
;
5065 n
.in
.names
= talloc_array(tctx
, struct lsa_String
, 1);
5066 n
.in
.names
[0].string
= acct_name
;
5068 n
.out
.types
= &types
;
5070 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
5071 if (!NT_STATUS_IS_OK(status
)) {
5072 torture_warning(tctx
, "LookupNames failed - %s\n", nt_errstr(status
));
5076 r
.in
.domain_handle
= domain_handle
;
5077 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5078 r
.in
.rid
= n
.out
.rids
->ids
[0];
5079 r
.out
.user_handle
= &user_handle
;
5081 status
= dcerpc_samr_OpenUser(p
, tctx
, &r
);
5082 if (!NT_STATUS_IS_OK(status
)) {
5083 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", n
.out
.rids
->ids
[0], nt_errstr(status
));
5087 q
.in
.user_handle
= &user_handle
;
5091 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &q
);
5092 if (!NT_STATUS_IS_OK(status
)) {
5093 torture_warning(tctx
, "QueryUserInfo failed - %s\n", nt_errstr(status
));
5097 torture_comment(tctx
, "calling test_ChangePasswordUser3 with too early password change\n");
5099 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
,
5100 info
->info5
.last_password_change
, true)) {
5105 /* we change passwords twice - this has the effect of verifying
5106 they were changed correctly for the final call */
5107 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
, 0, true)) {
5111 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
, 0, true)) {
5118 static bool test_CreateUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5119 struct policy_handle
*domain_handle
,
5120 const char *user_name
,
5121 struct policy_handle
*user_handle_out
,
5122 struct dom_sid
*domain_sid
,
5123 enum torture_samr_choice which_ops
,
5124 struct cli_credentials
*machine_credentials
,
5128 TALLOC_CTX
*user_ctx
;
5131 struct samr_CreateUser r
;
5132 struct samr_QueryUserInfo q
;
5133 union samr_UserInfo
*info
;
5134 struct samr_DeleteUser d
;
5137 /* This call creates a 'normal' account - check that it really does */
5138 const uint32_t acct_flags
= ACB_NORMAL
;
5139 struct lsa_String name
;
5142 struct policy_handle user_handle
;
5143 user_ctx
= talloc_named(tctx
, 0, "test_CreateUser2 per-user context");
5144 init_lsa_String(&name
, user_name
);
5146 r
.in
.domain_handle
= domain_handle
;
5147 r
.in
.account_name
= &name
;
5148 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5149 r
.out
.user_handle
= &user_handle
;
5152 torture_comment(tctx
, "Testing CreateUser(%s)\n", r
.in
.account_name
->string
);
5154 status
= dcerpc_samr_CreateUser(p
, user_ctx
, &r
);
5156 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
5157 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) || NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
5158 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.account_name
->string
);
5161 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.account_name
->string
,
5167 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_EXISTS
)) {
5168 if (!test_DeleteUser_byname(p
, user_ctx
, domain_handle
, r
.in
.account_name
->string
)) {
5169 talloc_free(user_ctx
);
5172 status
= dcerpc_samr_CreateUser(p
, user_ctx
, &r
);
5175 if (!NT_STATUS_IS_OK(status
)) {
5176 talloc_free(user_ctx
);
5177 torture_warning(tctx
, "CreateUser failed - %s\n", nt_errstr(status
));
5182 if (user_handle_out
) {
5183 *user_handle_out
= user_handle
;
5189 q
.in
.user_handle
= &user_handle
;
5193 status
= dcerpc_samr_QueryUserInfo(p
, user_ctx
, &q
);
5194 if (!NT_STATUS_IS_OK(status
)) {
5195 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
5196 q
.in
.level
, nt_errstr(status
));
5199 if ((info
->info16
.acct_flags
& acct_flags
) != acct_flags
) {
5200 torture_warning(tctx
, "QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5201 info
->info16
.acct_flags
,
5207 if (!test_user_ops(p
, tctx
, &user_handle
, domain_handle
,
5208 domain_sid
, acct_flags
, name
.string
, which_ops
,
5209 machine_credentials
)) {
5213 if (user_handle_out
) {
5214 *user_handle_out
= user_handle
;
5216 torture_comment(tctx
, "Testing DeleteUser (createuser test)\n");
5218 d
.in
.user_handle
= &user_handle
;
5219 d
.out
.user_handle
= &user_handle
;
5221 status
= dcerpc_samr_DeleteUser(p
, user_ctx
, &d
);
5222 if (!NT_STATUS_IS_OK(status
)) {
5223 torture_warning(tctx
, "DeleteUser failed - %s\n", nt_errstr(status
));
5230 talloc_free(user_ctx
);
5236 static bool test_CreateUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5237 struct policy_handle
*domain_handle
,
5238 struct dom_sid
*domain_sid
,
5239 enum torture_samr_choice which_ops
,
5240 struct cli_credentials
*machine_credentials
)
5243 struct samr_CreateUser2 r
;
5244 struct samr_QueryUserInfo q
;
5245 union samr_UserInfo
*info
;
5246 struct samr_DeleteUser d
;
5247 struct policy_handle user_handle
;
5249 struct lsa_String name
;
5254 uint32_t acct_flags
;
5255 const char *account_name
;
5257 } account_types
[] = {
5258 { ACB_NORMAL
, TEST_ACCOUNT_NAME
, NT_STATUS_OK
},
5259 { ACB_NORMAL
| ACB_DISABLED
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5260 { ACB_NORMAL
| ACB_PWNOEXP
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5261 { ACB_WSTRUST
, TEST_MACHINENAME
, NT_STATUS_OK
},
5262 { ACB_WSTRUST
| ACB_DISABLED
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5263 { ACB_WSTRUST
| ACB_PWNOEXP
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5264 { ACB_SVRTRUST
, TEST_MACHINENAME
, NT_STATUS_OK
},
5265 { ACB_SVRTRUST
| ACB_DISABLED
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5266 { ACB_SVRTRUST
| ACB_PWNOEXP
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5267 { ACB_DOMTRUST
, TEST_DOMAINNAME
, NT_STATUS_ACCESS_DENIED
},
5268 { ACB_DOMTRUST
| ACB_DISABLED
, TEST_DOMAINNAME
, NT_STATUS_INVALID_PARAMETER
},
5269 { ACB_DOMTRUST
| ACB_PWNOEXP
, TEST_DOMAINNAME
, NT_STATUS_INVALID_PARAMETER
},
5270 { 0, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5271 { ACB_DISABLED
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5272 { 0, NULL
, NT_STATUS_INVALID_PARAMETER
}
5275 for (i
= 0; account_types
[i
].account_name
; i
++) {
5276 TALLOC_CTX
*user_ctx
;
5277 uint32_t acct_flags
= account_types
[i
].acct_flags
;
5278 uint32_t access_granted
;
5279 user_ctx
= talloc_named(tctx
, 0, "test_CreateUser2 per-user context");
5280 init_lsa_String(&name
, account_types
[i
].account_name
);
5282 r
.in
.domain_handle
= domain_handle
;
5283 r
.in
.account_name
= &name
;
5284 r
.in
.acct_flags
= acct_flags
;
5285 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5286 r
.out
.user_handle
= &user_handle
;
5287 r
.out
.access_granted
= &access_granted
;
5290 torture_comment(tctx
, "Testing CreateUser2(%s, 0x%x)\n", r
.in
.account_name
->string
, acct_flags
);
5292 status
= dcerpc_samr_CreateUser2(p
, user_ctx
, &r
);
5294 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
5295 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) || NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
5296 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.account_name
->string
);
5299 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.account_name
->string
,
5306 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_EXISTS
)) {
5307 if (!test_DeleteUser_byname(p
, user_ctx
, domain_handle
, r
.in
.account_name
->string
)) {
5308 talloc_free(user_ctx
);
5312 status
= dcerpc_samr_CreateUser2(p
, user_ctx
, &r
);
5315 if (!NT_STATUS_EQUAL(status
, account_types
[i
].nt_status
)) {
5316 torture_warning(tctx
, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5317 nt_errstr(status
), nt_errstr(account_types
[i
].nt_status
));
5321 if (NT_STATUS_IS_OK(status
)) {
5322 q
.in
.user_handle
= &user_handle
;
5326 status
= dcerpc_samr_QueryUserInfo(p
, user_ctx
, &q
);
5327 if (!NT_STATUS_IS_OK(status
)) {
5328 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
5329 q
.in
.level
, nt_errstr(status
));
5332 uint32_t expected_flags
= (acct_flags
| ACB_PWNOTREQ
| ACB_DISABLED
);
5333 if (acct_flags
== ACB_NORMAL
) {
5334 expected_flags
|= ACB_PW_EXPIRED
;
5336 if ((info
->info5
.acct_flags
) != expected_flags
) {
5337 torture_warning(tctx
, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5338 info
->info5
.acct_flags
,
5342 switch (acct_flags
) {
5344 if (info
->info5
.primary_gid
!= DOMAIN_RID_DCS
) {
5345 torture_warning(tctx
, "QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5346 DOMAIN_RID_DCS
, info
->info5
.primary_gid
);
5351 if (info
->info5
.primary_gid
!= DOMAIN_RID_DOMAIN_MEMBERS
) {
5352 torture_warning(tctx
, "QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5353 DOMAIN_RID_DOMAIN_MEMBERS
, info
->info5
.primary_gid
);
5358 if (info
->info5
.primary_gid
!= DOMAIN_RID_USERS
) {
5359 torture_warning(tctx
, "QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5360 DOMAIN_RID_USERS
, info
->info5
.primary_gid
);
5367 if (!test_user_ops(p
, tctx
, &user_handle
, domain_handle
,
5368 domain_sid
, acct_flags
, name
.string
, which_ops
,
5369 machine_credentials
)) {
5373 if (!policy_handle_empty(&user_handle
)) {
5374 torture_comment(tctx
, "Testing DeleteUser (createuser2 test)\n");
5376 d
.in
.user_handle
= &user_handle
;
5377 d
.out
.user_handle
= &user_handle
;
5379 status
= dcerpc_samr_DeleteUser(p
, user_ctx
, &d
);
5380 if (!NT_STATUS_IS_OK(status
)) {
5381 torture_warning(tctx
, "DeleteUser failed - %s\n", nt_errstr(status
));
5386 talloc_free(user_ctx
);
5392 static bool test_QueryAliasInfo(struct dcerpc_pipe
*p
,
5393 struct torture_context
*tctx
,
5394 struct policy_handle
*handle
)
5397 struct samr_QueryAliasInfo r
;
5398 union samr_AliasInfo
*info
;
5399 uint16_t levels
[] = {1, 2, 3};
5403 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5404 torture_comment(tctx
, "Testing QueryAliasInfo level %u\n", levels
[i
]);
5406 r
.in
.alias_handle
= handle
;
5407 r
.in
.level
= levels
[i
];
5410 status
= dcerpc_samr_QueryAliasInfo(p
, tctx
, &r
);
5411 if (!NT_STATUS_IS_OK(status
)) {
5412 torture_warning(tctx
, "QueryAliasInfo level %u failed - %s\n",
5413 levels
[i
], nt_errstr(status
));
5421 static bool test_QueryGroupInfo(struct dcerpc_pipe
*p
,
5422 struct torture_context
*tctx
,
5423 struct policy_handle
*handle
)
5426 struct samr_QueryGroupInfo r
;
5427 union samr_GroupInfo
*info
;
5428 uint16_t levels
[] = {1, 2, 3, 4, 5};
5432 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5433 torture_comment(tctx
, "Testing QueryGroupInfo level %u\n", levels
[i
]);
5435 r
.in
.group_handle
= handle
;
5436 r
.in
.level
= levels
[i
];
5439 status
= dcerpc_samr_QueryGroupInfo(p
, tctx
, &r
);
5440 if (!NT_STATUS_IS_OK(status
)) {
5441 torture_warning(tctx
, "QueryGroupInfo level %u failed - %s\n",
5442 levels
[i
], nt_errstr(status
));
5450 static bool test_QueryGroupMember(struct dcerpc_pipe
*p
,
5451 struct torture_context
*tctx
,
5452 struct policy_handle
*handle
)
5455 struct samr_QueryGroupMember r
;
5456 struct samr_RidTypeArray
*rids
= NULL
;
5459 torture_comment(tctx
, "Testing QueryGroupMember\n");
5461 r
.in
.group_handle
= handle
;
5464 status
= dcerpc_samr_QueryGroupMember(p
, tctx
, &r
);
5465 if (!NT_STATUS_IS_OK(status
)) {
5466 torture_warning(tctx
, "QueryGroupInfo failed - %s\n", nt_errstr(status
));
5474 static bool test_SetGroupInfo(struct dcerpc_pipe
*p
,
5475 struct torture_context
*tctx
,
5476 struct policy_handle
*handle
)
5479 struct samr_QueryGroupInfo r
;
5480 union samr_GroupInfo
*info
;
5481 struct samr_SetGroupInfo s
;
5482 uint16_t levels
[] = {1, 2, 3, 4};
5483 uint16_t set_ok
[] = {0, 1, 1, 1};
5487 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5488 torture_comment(tctx
, "Testing QueryGroupInfo level %u\n", levels
[i
]);
5490 r
.in
.group_handle
= handle
;
5491 r
.in
.level
= levels
[i
];
5494 status
= dcerpc_samr_QueryGroupInfo(p
, tctx
, &r
);
5495 if (!NT_STATUS_IS_OK(status
)) {
5496 torture_warning(tctx
, "QueryGroupInfo level %u failed - %s\n",
5497 levels
[i
], nt_errstr(status
));
5501 torture_comment(tctx
, "Testing SetGroupInfo level %u\n", levels
[i
]);
5503 s
.in
.group_handle
= handle
;
5504 s
.in
.level
= levels
[i
];
5505 s
.in
.info
= *r
.out
.info
;
5508 /* disabled this, as it changes the name only from the point of view of samr,
5509 but leaves the name from the point of view of w2k3 internals (and ldap). This means
5510 the name is still reserved, so creating the old name fails, but deleting by the old name
5512 if (s
.in
.level
== 2) {
5513 init_lsa_String(&s
.in
.info
->string
, "NewName");
5517 if (s
.in
.level
== 4) {
5518 init_lsa_String(&s
.in
.info
->description
, "test description");
5521 status
= dcerpc_samr_SetGroupInfo(p
, tctx
, &s
);
5523 if (!NT_STATUS_IS_OK(status
)) {
5524 torture_warning(tctx
, "SetGroupInfo level %u failed - %s\n",
5525 r
.in
.level
, nt_errstr(status
));
5530 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, status
)) {
5531 torture_warning(tctx
, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5532 r
.in
.level
, nt_errstr(status
));
5542 static bool test_QueryUserInfo(struct dcerpc_pipe
*p
,
5543 struct torture_context
*tctx
,
5544 struct policy_handle
*handle
)
5547 struct samr_QueryUserInfo r
;
5548 union samr_UserInfo
*info
;
5549 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5550 11, 12, 13, 14, 16, 17, 20, 21};
5554 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5555 torture_comment(tctx
, "Testing QueryUserInfo level %u\n", levels
[i
]);
5557 r
.in
.user_handle
= handle
;
5558 r
.in
.level
= levels
[i
];
5561 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &r
);
5562 if (!NT_STATUS_IS_OK(status
)) {
5563 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
5564 levels
[i
], nt_errstr(status
));
5572 static bool test_QueryUserInfo2(struct dcerpc_pipe
*p
,
5573 struct torture_context
*tctx
,
5574 struct policy_handle
*handle
)
5577 struct samr_QueryUserInfo2 r
;
5578 union samr_UserInfo
*info
;
5579 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5580 11, 12, 13, 14, 16, 17, 20, 21};
5584 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5585 torture_comment(tctx
, "Testing QueryUserInfo2 level %u\n", levels
[i
]);
5587 r
.in
.user_handle
= handle
;
5588 r
.in
.level
= levels
[i
];
5591 status
= dcerpc_samr_QueryUserInfo2(p
, tctx
, &r
);
5592 if (!NT_STATUS_IS_OK(status
)) {
5593 torture_warning(tctx
, "QueryUserInfo2 level %u failed - %s\n",
5594 levels
[i
], nt_errstr(status
));
5602 static bool test_OpenUser(struct dcerpc_pipe
*p
,
5603 struct torture_context
*tctx
,
5604 struct policy_handle
*handle
, uint32_t rid
)
5607 struct samr_OpenUser r
;
5608 struct policy_handle user_handle
;
5611 torture_comment(tctx
, "Testing OpenUser(%u)\n", rid
);
5613 r
.in
.domain_handle
= handle
;
5614 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5616 r
.out
.user_handle
= &user_handle
;
5618 status
= dcerpc_samr_OpenUser(p
, tctx
, &r
);
5619 if (!NT_STATUS_IS_OK(status
)) {
5620 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", rid
, nt_errstr(status
));
5624 if (!test_QuerySecurity(p
, tctx
, &user_handle
)) {
5628 if (!test_QueryUserInfo(p
, tctx
, &user_handle
)) {
5632 if (!test_QueryUserInfo2(p
, tctx
, &user_handle
)) {
5636 if (!test_GetUserPwInfo(p
, tctx
, &user_handle
)) {
5640 if (!test_GetGroupsForUser(p
,tctx
, &user_handle
)) {
5644 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
5651 static bool test_OpenGroup(struct dcerpc_pipe
*p
,
5652 struct torture_context
*tctx
,
5653 struct policy_handle
*handle
, uint32_t rid
)
5656 struct samr_OpenGroup r
;
5657 struct policy_handle group_handle
;
5660 torture_comment(tctx
, "Testing OpenGroup(%u)\n", rid
);
5662 r
.in
.domain_handle
= handle
;
5663 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5665 r
.out
.group_handle
= &group_handle
;
5667 status
= dcerpc_samr_OpenGroup(p
, tctx
, &r
);
5668 if (!NT_STATUS_IS_OK(status
)) {
5669 torture_warning(tctx
, "OpenGroup(%u) failed - %s\n", rid
, nt_errstr(status
));
5673 if (!torture_setting_bool(tctx
, "samba3", false)) {
5674 if (!test_QuerySecurity(p
, tctx
, &group_handle
)) {
5679 if (!test_QueryGroupInfo(p
, tctx
, &group_handle
)) {
5683 if (!test_QueryGroupMember(p
, tctx
, &group_handle
)) {
5687 if (!test_samr_handle_Close(p
, tctx
, &group_handle
)) {
5694 static bool test_OpenAlias(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5695 struct policy_handle
*handle
, uint32_t rid
)
5698 struct samr_OpenAlias r
;
5699 struct policy_handle alias_handle
;
5702 torture_comment(tctx
, "Testing OpenAlias(%u)\n", rid
);
5704 r
.in
.domain_handle
= handle
;
5705 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5707 r
.out
.alias_handle
= &alias_handle
;
5709 status
= dcerpc_samr_OpenAlias(p
, tctx
, &r
);
5710 if (!NT_STATUS_IS_OK(status
)) {
5711 torture_warning(tctx
, "OpenAlias(%u) failed - %s\n", rid
, nt_errstr(status
));
5715 if (!torture_setting_bool(tctx
, "samba3", false)) {
5716 if (!test_QuerySecurity(p
, tctx
, &alias_handle
)) {
5721 if (!test_QueryAliasInfo(p
, tctx
, &alias_handle
)) {
5725 if (!test_GetMembersInAlias(p
, tctx
, &alias_handle
)) {
5729 if (!test_samr_handle_Close(p
, tctx
, &alias_handle
)) {
5736 static bool check_mask(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5737 struct policy_handle
*handle
, uint32_t rid
,
5738 uint32_t acct_flag_mask
)
5741 struct samr_OpenUser r
;
5742 struct samr_QueryUserInfo q
;
5743 union samr_UserInfo
*info
;
5744 struct policy_handle user_handle
;
5747 torture_comment(tctx
, "Testing OpenUser(%u)\n", rid
);
5749 r
.in
.domain_handle
= handle
;
5750 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5752 r
.out
.user_handle
= &user_handle
;
5754 status
= dcerpc_samr_OpenUser(p
, tctx
, &r
);
5755 if (!NT_STATUS_IS_OK(status
)) {
5756 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", rid
, nt_errstr(status
));
5760 q
.in
.user_handle
= &user_handle
;
5764 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &q
);
5765 if (!NT_STATUS_IS_OK(status
)) {
5766 torture_warning(tctx
, "QueryUserInfo level 16 failed - %s\n",
5770 if ((acct_flag_mask
& info
->info16
.acct_flags
) == 0) {
5771 torture_warning(tctx
, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
5772 acct_flag_mask
, info
->info16
.acct_flags
, rid
);
5777 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
5784 static bool test_EnumDomainUsers_all(struct dcerpc_pipe
*p
,
5785 struct torture_context
*tctx
,
5786 struct policy_handle
*handle
)
5788 NTSTATUS status
= STATUS_MORE_ENTRIES
;
5789 struct samr_EnumDomainUsers r
;
5790 uint32_t mask
, resume_handle
=0;
5793 struct samr_LookupNames n
;
5794 struct samr_LookupRids lr
;
5795 struct lsa_Strings names
;
5796 struct samr_Ids rids
, types
;
5797 struct samr_SamArray
*sam
= NULL
;
5798 uint32_t num_entries
= 0;
5800 uint32_t masks
[] = {ACB_NORMAL
, ACB_DOMTRUST
, ACB_WSTRUST
,
5801 ACB_DISABLED
, ACB_NORMAL
| ACB_DISABLED
,
5802 ACB_SVRTRUST
| ACB_DOMTRUST
| ACB_WSTRUST
,
5805 torture_comment(tctx
, "Testing EnumDomainUsers\n");
5807 for (mask_idx
=0;mask_idx
<ARRAY_SIZE(masks
);mask_idx
++) {
5808 r
.in
.domain_handle
= handle
;
5809 r
.in
.resume_handle
= &resume_handle
;
5810 r
.in
.acct_flags
= mask
= masks
[mask_idx
];
5811 r
.in
.max_size
= (uint32_t)-1;
5812 r
.out
.resume_handle
= &resume_handle
;
5813 r
.out
.num_entries
= &num_entries
;
5816 status
= dcerpc_samr_EnumDomainUsers(p
, tctx
, &r
);
5817 if (!NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) &&
5818 !NT_STATUS_IS_OK(status
)) {
5819 torture_warning(tctx
, "EnumDomainUsers failed - %s\n", nt_errstr(status
));
5823 torture_assert(tctx
, sam
, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
5825 if (sam
->count
== 0) {
5829 for (i
=0;i
<sam
->count
;i
++) {
5831 if (!check_mask(p
, tctx
, handle
, sam
->entries
[i
].idx
, mask
)) {
5834 } else if (!test_OpenUser(p
, tctx
, handle
, sam
->entries
[i
].idx
)) {
5840 torture_comment(tctx
, "Testing LookupNames\n");
5841 n
.in
.domain_handle
= handle
;
5842 n
.in
.num_names
= sam
->count
;
5843 n
.in
.names
= talloc_array(tctx
, struct lsa_String
, sam
->count
);
5845 n
.out
.types
= &types
;
5846 for (i
=0;i
<sam
->count
;i
++) {
5847 n
.in
.names
[i
].string
= sam
->entries
[i
].name
.string
;
5849 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
5850 if (!NT_STATUS_IS_OK(status
)) {
5851 torture_warning(tctx
, "LookupNames failed - %s\n", nt_errstr(status
));
5856 torture_comment(tctx
, "Testing LookupRids\n");
5857 lr
.in
.domain_handle
= handle
;
5858 lr
.in
.num_rids
= sam
->count
;
5859 lr
.in
.rids
= talloc_array(tctx
, uint32_t, sam
->count
);
5860 lr
.out
.names
= &names
;
5861 lr
.out
.types
= &types
;
5862 for (i
=0;i
<sam
->count
;i
++) {
5863 lr
.in
.rids
[i
] = sam
->entries
[i
].idx
;
5865 status
= dcerpc_samr_LookupRids(p
, tctx
, &lr
);
5866 torture_assert_ntstatus_ok(tctx
, status
, "LookupRids");
5872 try blasting the server with a bunch of sync requests
5874 static bool test_EnumDomainUsers_async(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5875 struct policy_handle
*handle
)
5878 struct samr_EnumDomainUsers r
;
5879 uint32_t resume_handle
=0;
5881 #define ASYNC_COUNT 100
5882 struct rpc_request
*req
[ASYNC_COUNT
];
5884 if (!torture_setting_bool(tctx
, "dangerous", false)) {
5885 torture_skip(tctx
, "samr async test disabled - enable dangerous tests to use\n");
5888 torture_comment(tctx
, "Testing EnumDomainUsers_async\n");
5890 r
.in
.domain_handle
= handle
;
5891 r
.in
.resume_handle
= &resume_handle
;
5892 r
.in
.acct_flags
= 0;
5893 r
.in
.max_size
= (uint32_t)-1;
5894 r
.out
.resume_handle
= &resume_handle
;
5896 for (i
=0;i
<ASYNC_COUNT
;i
++) {
5897 req
[i
] = dcerpc_samr_EnumDomainUsers_send(p
, tctx
, &r
);
5900 for (i
=0;i
<ASYNC_COUNT
;i
++) {
5901 status
= dcerpc_ndr_request_recv(req
[i
]);
5902 if (!NT_STATUS_IS_OK(status
)) {
5903 torture_warning(tctx
, "EnumDomainUsers[%d] failed - %s\n",
5904 i
, nt_errstr(status
));
5909 torture_comment(tctx
, "%d async requests OK\n", i
);
5914 static bool test_EnumDomainGroups_all(struct dcerpc_pipe
*p
,
5915 struct torture_context
*tctx
,
5916 struct policy_handle
*handle
)
5919 struct samr_EnumDomainGroups r
;
5920 uint32_t resume_handle
=0;
5921 struct samr_SamArray
*sam
= NULL
;
5922 uint32_t num_entries
= 0;
5926 torture_comment(tctx
, "Testing EnumDomainGroups\n");
5928 r
.in
.domain_handle
= handle
;
5929 r
.in
.resume_handle
= &resume_handle
;
5930 r
.in
.max_size
= (uint32_t)-1;
5931 r
.out
.resume_handle
= &resume_handle
;
5932 r
.out
.num_entries
= &num_entries
;
5935 status
= dcerpc_samr_EnumDomainGroups(p
, tctx
, &r
);
5936 if (!NT_STATUS_IS_OK(status
)) {
5937 torture_warning(tctx
, "EnumDomainGroups failed - %s\n", nt_errstr(status
));
5945 for (i
=0;i
<sam
->count
;i
++) {
5946 if (!test_OpenGroup(p
, tctx
, handle
, sam
->entries
[i
].idx
)) {
5954 static bool test_EnumDomainAliases_all(struct dcerpc_pipe
*p
,
5955 struct torture_context
*tctx
,
5956 struct policy_handle
*handle
)
5959 struct samr_EnumDomainAliases r
;
5960 uint32_t resume_handle
=0;
5961 struct samr_SamArray
*sam
= NULL
;
5962 uint32_t num_entries
= 0;
5966 torture_comment(tctx
, "Testing EnumDomainAliases\n");
5968 r
.in
.domain_handle
= handle
;
5969 r
.in
.resume_handle
= &resume_handle
;
5970 r
.in
.max_size
= (uint32_t)-1;
5972 r
.out
.num_entries
= &num_entries
;
5973 r
.out
.resume_handle
= &resume_handle
;
5975 status
= dcerpc_samr_EnumDomainAliases(p
, tctx
, &r
);
5976 if (!NT_STATUS_IS_OK(status
)) {
5977 torture_warning(tctx
, "EnumDomainAliases failed - %s\n", nt_errstr(status
));
5985 for (i
=0;i
<sam
->count
;i
++) {
5986 if (!test_OpenAlias(p
, tctx
, handle
, sam
->entries
[i
].idx
)) {
5994 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe
*p
,
5995 struct torture_context
*tctx
,
5996 struct policy_handle
*handle
)
5999 struct samr_GetDisplayEnumerationIndex r
;
6001 uint16_t levels
[] = {1, 2, 3, 4, 5};
6002 uint16_t ok_lvl
[] = {1, 1, 1, 0, 0};
6003 struct lsa_String name
;
6007 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6008 torture_comment(tctx
, "Testing GetDisplayEnumerationIndex level %u\n", levels
[i
]);
6010 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
6012 r
.in
.domain_handle
= handle
;
6013 r
.in
.level
= levels
[i
];
6017 status
= dcerpc_samr_GetDisplayEnumerationIndex(p
, tctx
, &r
);
6020 !NT_STATUS_IS_OK(status
) &&
6021 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
6022 torture_warning(tctx
, "GetDisplayEnumerationIndex level %u failed - %s\n",
6023 levels
[i
], nt_errstr(status
));
6027 init_lsa_String(&name
, "zzzzzzzz");
6029 status
= dcerpc_samr_GetDisplayEnumerationIndex(p
, tctx
, &r
);
6031 if (ok_lvl
[i
] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
6032 torture_warning(tctx
, "GetDisplayEnumerationIndex level %u failed - %s\n",
6033 levels
[i
], nt_errstr(status
));
6041 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe
*p
,
6042 struct torture_context
*tctx
,
6043 struct policy_handle
*handle
)
6046 struct samr_GetDisplayEnumerationIndex2 r
;
6048 uint16_t levels
[] = {1, 2, 3, 4, 5};
6049 uint16_t ok_lvl
[] = {1, 1, 1, 0, 0};
6050 struct lsa_String name
;
6054 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6055 torture_comment(tctx
, "Testing GetDisplayEnumerationIndex2 level %u\n", levels
[i
]);
6057 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
6059 r
.in
.domain_handle
= handle
;
6060 r
.in
.level
= levels
[i
];
6064 status
= dcerpc_samr_GetDisplayEnumerationIndex2(p
, tctx
, &r
);
6066 !NT_STATUS_IS_OK(status
) &&
6067 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
6068 torture_warning(tctx
, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6069 levels
[i
], nt_errstr(status
));
6073 init_lsa_String(&name
, "zzzzzzzz");
6075 status
= dcerpc_samr_GetDisplayEnumerationIndex2(p
, tctx
, &r
);
6076 if (ok_lvl
[i
] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
6077 torture_warning(tctx
, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6078 levels
[i
], nt_errstr(status
));
6086 #define STRING_EQUAL_QUERY(s1, s2, user) \
6087 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6088 /* odd, but valid */ \
6089 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6090 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
6091 #s1, user.string, s1.string, s2.string, __location__); \
6094 #define INT_EQUAL_QUERY(s1, s2, user) \
6096 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6097 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6101 static bool test_each_DisplayInfo_user(struct dcerpc_pipe
*p
,
6102 struct torture_context
*tctx
,
6103 struct samr_QueryDisplayInfo
*querydisplayinfo
,
6104 bool *seen_testuser
)
6106 struct samr_OpenUser r
;
6107 struct samr_QueryUserInfo q
;
6108 union samr_UserInfo
*info
;
6109 struct policy_handle user_handle
;
6112 r
.in
.domain_handle
= querydisplayinfo
->in
.domain_handle
;
6113 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6114 for (i
= 0; ; i
++) {
6115 switch (querydisplayinfo
->in
.level
) {
6117 if (i
>= querydisplayinfo
->out
.info
->info1
.count
) {
6120 r
.in
.rid
= querydisplayinfo
->out
.info
->info1
.entries
[i
].rid
;
6123 if (i
>= querydisplayinfo
->out
.info
->info2
.count
) {
6126 r
.in
.rid
= querydisplayinfo
->out
.info
->info2
.entries
[i
].rid
;
6132 /* Not interested in validating just the account name */
6136 r
.out
.user_handle
= &user_handle
;
6138 switch (querydisplayinfo
->in
.level
) {
6141 status
= dcerpc_samr_OpenUser(p
, tctx
, &r
);
6142 if (!NT_STATUS_IS_OK(status
)) {
6143 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", r
.in
.rid
, nt_errstr(status
));
6148 q
.in
.user_handle
= &user_handle
;
6151 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &q
);
6152 if (!NT_STATUS_IS_OK(status
)) {
6153 torture_warning(tctx
, "QueryUserInfo(%u) failed - %s\n", r
.in
.rid
, nt_errstr(status
));
6157 switch (querydisplayinfo
->in
.level
) {
6159 if (seen_testuser
&& strcmp(info
->info21
.account_name
.string
, TEST_ACCOUNT_NAME
) == 0) {
6160 *seen_testuser
= true;
6162 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].full_name
,
6163 info
->info21
.full_name
, info
->info21
.account_name
);
6164 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].account_name
,
6165 info
->info21
.account_name
, info
->info21
.account_name
);
6166 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].description
,
6167 info
->info21
.description
, info
->info21
.account_name
);
6168 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].rid
,
6169 info
->info21
.rid
, info
->info21
.account_name
);
6170 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].acct_flags
,
6171 info
->info21
.acct_flags
, info
->info21
.account_name
);
6175 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].account_name
,
6176 info
->info21
.account_name
, info
->info21
.account_name
);
6177 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].description
,
6178 info
->info21
.description
, info
->info21
.account_name
);
6179 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].rid
,
6180 info
->info21
.rid
, info
->info21
.account_name
);
6181 INT_EQUAL_QUERY((querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
& ~ACB_NORMAL
),
6182 info
->info21
.acct_flags
, info
->info21
.account_name
);
6184 if (!(querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
& ACB_NORMAL
)) {
6185 torture_warning(tctx
, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6186 info
->info21
.account_name
.string
);
6189 if (!(info
->info21
.acct_flags
& (ACB_WSTRUST
| ACB_SVRTRUST
))) {
6190 torture_warning(tctx
, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6191 info
->info21
.account_name
.string
,
6192 querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
,
6193 info
->info21
.acct_flags
);
6200 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
6207 static bool test_QueryDisplayInfo(struct dcerpc_pipe
*p
,
6208 struct torture_context
*tctx
,
6209 struct policy_handle
*handle
)
6212 struct samr_QueryDisplayInfo r
;
6213 struct samr_QueryDomainInfo dom_info
;
6214 union samr_DomainInfo
*info
= NULL
;
6216 uint16_t levels
[] = {1, 2, 3, 4, 5};
6218 bool seen_testuser
= false;
6219 uint32_t total_size
;
6220 uint32_t returned_size
;
6221 union samr_DispInfo disp_info
;
6224 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6225 torture_comment(tctx
, "Testing QueryDisplayInfo level %u\n", levels
[i
]);
6228 status
= STATUS_MORE_ENTRIES
;
6229 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
6230 r
.in
.domain_handle
= handle
;
6231 r
.in
.level
= levels
[i
];
6232 r
.in
.max_entries
= 2;
6233 r
.in
.buf_size
= (uint32_t)-1;
6234 r
.out
.total_size
= &total_size
;
6235 r
.out
.returned_size
= &returned_size
;
6236 r
.out
.info
= &disp_info
;
6238 status
= dcerpc_samr_QueryDisplayInfo(p
, tctx
, &r
);
6239 if (!NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) && !NT_STATUS_IS_OK(status
)) {
6240 torture_warning(tctx
, "QueryDisplayInfo level %u failed - %s\n",
6241 levels
[i
], nt_errstr(status
));
6244 switch (r
.in
.level
) {
6246 if (!test_each_DisplayInfo_user(p
, tctx
, &r
, &seen_testuser
)) {
6249 r
.in
.start_idx
+= r
.out
.info
->info1
.count
;
6252 if (!test_each_DisplayInfo_user(p
, tctx
, &r
, NULL
)) {
6255 r
.in
.start_idx
+= r
.out
.info
->info2
.count
;
6258 r
.in
.start_idx
+= r
.out
.info
->info3
.count
;
6261 r
.in
.start_idx
+= r
.out
.info
->info4
.count
;
6264 r
.in
.start_idx
+= r
.out
.info
->info5
.count
;
6268 dom_info
.in
.domain_handle
= handle
;
6269 dom_info
.in
.level
= 2;
6270 dom_info
.out
.info
= &info
;
6272 /* Check number of users returned is correct */
6273 status
= dcerpc_samr_QueryDomainInfo(p
, tctx
, &dom_info
);
6274 if (!NT_STATUS_IS_OK(status
)) {
6275 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
6276 r
.in
.level
, nt_errstr(status
));
6280 switch (r
.in
.level
) {
6283 if (info
->general
.num_users
< r
.in
.start_idx
) {
6284 torture_warning(tctx
, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6285 r
.in
.start_idx
, info
->general
.num_groups
,
6286 info
->general
.domain_name
.string
);
6289 if (!seen_testuser
) {
6290 struct policy_handle user_handle
;
6291 if (NT_STATUS_IS_OK(test_OpenUser_byname(p
, tctx
, handle
, TEST_ACCOUNT_NAME
, &user_handle
))) {
6292 torture_warning(tctx
, "Didn't find test user " TEST_ACCOUNT_NAME
" in enumeration of %s\n",
6293 info
->general
.domain_name
.string
);
6295 test_samr_handle_Close(p
, tctx
, &user_handle
);
6301 if (info
->general
.num_groups
!= r
.in
.start_idx
) {
6302 torture_warning(tctx
, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6303 r
.in
.start_idx
, info
->general
.num_groups
,
6304 info
->general
.domain_name
.string
);
6316 static bool test_QueryDisplayInfo2(struct dcerpc_pipe
*p
,
6317 struct torture_context
*tctx
,
6318 struct policy_handle
*handle
)
6321 struct samr_QueryDisplayInfo2 r
;
6323 uint16_t levels
[] = {1, 2, 3, 4, 5};
6325 uint32_t total_size
;
6326 uint32_t returned_size
;
6327 union samr_DispInfo info
;
6329 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6330 torture_comment(tctx
, "Testing QueryDisplayInfo2 level %u\n", levels
[i
]);
6332 r
.in
.domain_handle
= handle
;
6333 r
.in
.level
= levels
[i
];
6335 r
.in
.max_entries
= 1000;
6336 r
.in
.buf_size
= (uint32_t)-1;
6337 r
.out
.total_size
= &total_size
;
6338 r
.out
.returned_size
= &returned_size
;
6341 status
= dcerpc_samr_QueryDisplayInfo2(p
, tctx
, &r
);
6342 if (!NT_STATUS_IS_OK(status
)) {
6343 torture_warning(tctx
, "QueryDisplayInfo2 level %u failed - %s\n",
6344 levels
[i
], nt_errstr(status
));
6352 static bool test_QueryDisplayInfo3(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6353 struct policy_handle
*handle
)
6356 struct samr_QueryDisplayInfo3 r
;
6358 uint16_t levels
[] = {1, 2, 3, 4, 5};
6360 uint32_t total_size
;
6361 uint32_t returned_size
;
6362 union samr_DispInfo info
;
6364 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6365 torture_comment(tctx
, "Testing QueryDisplayInfo3 level %u\n", levels
[i
]);
6367 r
.in
.domain_handle
= handle
;
6368 r
.in
.level
= levels
[i
];
6370 r
.in
.max_entries
= 1000;
6371 r
.in
.buf_size
= (uint32_t)-1;
6372 r
.out
.total_size
= &total_size
;
6373 r
.out
.returned_size
= &returned_size
;
6376 status
= dcerpc_samr_QueryDisplayInfo3(p
, tctx
, &r
);
6377 if (!NT_STATUS_IS_OK(status
)) {
6378 torture_warning(tctx
, "QueryDisplayInfo3 level %u failed - %s\n",
6379 levels
[i
], nt_errstr(status
));
6388 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe
*p
,
6389 struct torture_context
*tctx
,
6390 struct policy_handle
*handle
)
6393 struct samr_QueryDisplayInfo r
;
6395 uint32_t total_size
;
6396 uint32_t returned_size
;
6397 union samr_DispInfo info
;
6399 torture_comment(tctx
, "Testing QueryDisplayInfo continuation\n");
6401 r
.in
.domain_handle
= handle
;
6404 r
.in
.max_entries
= 1;
6405 r
.in
.buf_size
= (uint32_t)-1;
6406 r
.out
.total_size
= &total_size
;
6407 r
.out
.returned_size
= &returned_size
;
6411 status
= dcerpc_samr_QueryDisplayInfo(p
, tctx
, &r
);
6412 if (NT_STATUS_IS_OK(status
) && *r
.out
.returned_size
!= 0) {
6413 if (r
.out
.info
->info1
.entries
[0].idx
!= r
.in
.start_idx
+ 1) {
6414 torture_warning(tctx
, "expected idx %d but got %d\n",
6416 r
.out
.info
->info1
.entries
[0].idx
);
6420 if (!NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) &&
6421 !NT_STATUS_IS_OK(status
)) {
6422 torture_warning(tctx
, "QueryDisplayInfo level %u failed - %s\n",
6423 r
.in
.level
, nt_errstr(status
));
6428 } while ((NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) ||
6429 NT_STATUS_IS_OK(status
)) &&
6430 *r
.out
.returned_size
!= 0);
6435 static bool test_QueryDomainInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6436 struct policy_handle
*handle
)
6439 struct samr_QueryDomainInfo r
;
6440 union samr_DomainInfo
*info
= NULL
;
6441 struct samr_SetDomainInfo s
;
6442 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6443 uint16_t set_ok
[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
6446 const char *domain_comment
= talloc_asprintf(tctx
,
6447 "Tortured by Samba4 RPC-SAMR: %s",
6448 timestring(tctx
, time(NULL
)));
6450 s
.in
.domain_handle
= handle
;
6452 s
.in
.info
= talloc(tctx
, union samr_DomainInfo
);
6454 s
.in
.info
->oem
.oem_information
.string
= domain_comment
;
6455 status
= dcerpc_samr_SetDomainInfo(p
, tctx
, &s
);
6456 if (!NT_STATUS_IS_OK(status
)) {
6457 torture_warning(tctx
, "SetDomainInfo level %u (set comment) failed - %s\n",
6458 s
.in
.level
, nt_errstr(status
));
6462 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6463 torture_comment(tctx
, "Testing QueryDomainInfo level %u\n", levels
[i
]);
6465 r
.in
.domain_handle
= handle
;
6466 r
.in
.level
= levels
[i
];
6469 status
= dcerpc_samr_QueryDomainInfo(p
, tctx
, &r
);
6470 if (!NT_STATUS_IS_OK(status
)) {
6471 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
6472 r
.in
.level
, nt_errstr(status
));
6477 switch (levels
[i
]) {
6479 if (strcmp(info
->general
.oem_information
.string
, domain_comment
) != 0) {
6480 torture_warning(tctx
, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6481 levels
[i
], info
->general
.oem_information
.string
, domain_comment
);
6482 if (!torture_setting_bool(tctx
, "samba3", false)) {
6486 if (!info
->general
.primary
.string
) {
6487 torture_warning(tctx
, "QueryDomainInfo level %u returned no PDC name\n",
6490 } else if (info
->general
.role
== SAMR_ROLE_DOMAIN_PDC
) {
6491 if (dcerpc_server_name(p
) && strcasecmp_m(dcerpc_server_name(p
), info
->general
.primary
.string
) != 0) {
6492 torture_warning(tctx
, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
6493 levels
[i
], info
->general
.primary
.string
, dcerpc_server_name(p
));
6498 if (strcmp(info
->oem
.oem_information
.string
, domain_comment
) != 0) {
6499 torture_warning(tctx
, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6500 levels
[i
], info
->oem
.oem_information
.string
, domain_comment
);
6501 if (!torture_setting_bool(tctx
, "samba3", false)) {
6507 if (!info
->info6
.primary
.string
) {
6508 torture_warning(tctx
, "QueryDomainInfo level %u returned no PDC name\n",
6514 if (strcmp(info
->general2
.general
.oem_information
.string
, domain_comment
) != 0) {
6515 torture_warning(tctx
, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
6516 levels
[i
], info
->general2
.general
.oem_information
.string
, domain_comment
);
6517 if (!torture_setting_bool(tctx
, "samba3", false)) {
6524 torture_comment(tctx
, "Testing SetDomainInfo level %u\n", levels
[i
]);
6526 s
.in
.domain_handle
= handle
;
6527 s
.in
.level
= levels
[i
];
6530 status
= dcerpc_samr_SetDomainInfo(p
, tctx
, &s
);
6532 if (!NT_STATUS_IS_OK(status
)) {
6533 torture_warning(tctx
, "SetDomainInfo level %u failed - %s\n",
6534 r
.in
.level
, nt_errstr(status
));
6539 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, status
)) {
6540 torture_warning(tctx
, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6541 r
.in
.level
, nt_errstr(status
));
6547 status
= dcerpc_samr_QueryDomainInfo(p
, tctx
, &r
);
6548 if (!NT_STATUS_IS_OK(status
)) {
6549 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
6550 r
.in
.level
, nt_errstr(status
));
6560 static bool test_QueryDomainInfo2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6561 struct policy_handle
*handle
)
6564 struct samr_QueryDomainInfo2 r
;
6565 union samr_DomainInfo
*info
= NULL
;
6566 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6570 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6571 torture_comment(tctx
, "Testing QueryDomainInfo2 level %u\n", levels
[i
]);
6573 r
.in
.domain_handle
= handle
;
6574 r
.in
.level
= levels
[i
];
6577 status
= dcerpc_samr_QueryDomainInfo2(p
, tctx
, &r
);
6578 if (!NT_STATUS_IS_OK(status
)) {
6579 torture_warning(tctx
, "QueryDomainInfo2 level %u failed - %s\n",
6580 r
.in
.level
, nt_errstr(status
));
6589 /* Test whether querydispinfo level 5 and enumdomgroups return the same
6590 set of group names. */
6591 static bool test_GroupList(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6592 struct policy_handle
*handle
)
6594 struct samr_EnumDomainGroups q1
;
6595 struct samr_QueryDisplayInfo q2
;
6597 uint32_t resume_handle
=0;
6598 struct samr_SamArray
*sam
= NULL
;
6599 uint32_t num_entries
= 0;
6602 uint32_t total_size
;
6603 uint32_t returned_size
;
6604 union samr_DispInfo info
;
6607 const char **names
= NULL
;
6609 torture_comment(tctx
, "Testing coherency of querydispinfo vs enumdomgroups\n");
6611 q1
.in
.domain_handle
= handle
;
6612 q1
.in
.resume_handle
= &resume_handle
;
6614 q1
.out
.resume_handle
= &resume_handle
;
6615 q1
.out
.num_entries
= &num_entries
;
6618 status
= STATUS_MORE_ENTRIES
;
6619 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
6620 status
= dcerpc_samr_EnumDomainGroups(p
, tctx
, &q1
);
6622 if (!NT_STATUS_IS_OK(status
) &&
6623 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
6626 for (i
=0; i
<*q1
.out
.num_entries
; i
++) {
6627 add_string_to_array(tctx
,
6628 sam
->entries
[i
].name
.string
,
6629 &names
, &num_names
);
6633 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomainGroups");
6635 torture_assert(tctx
, sam
, "EnumDomainGroups failed to return sam");
6637 q2
.in
.domain_handle
= handle
;
6639 q2
.in
.start_idx
= 0;
6640 q2
.in
.max_entries
= 5;
6641 q2
.in
.buf_size
= (uint32_t)-1;
6642 q2
.out
.total_size
= &total_size
;
6643 q2
.out
.returned_size
= &returned_size
;
6644 q2
.out
.info
= &info
;
6646 status
= STATUS_MORE_ENTRIES
;
6647 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
6648 status
= dcerpc_samr_QueryDisplayInfo(p
, tctx
, &q2
);
6650 if (!NT_STATUS_IS_OK(status
) &&
6651 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
6654 for (i
=0; i
<q2
.out
.info
->info5
.count
; i
++) {
6656 const char *name
= q2
.out
.info
->info5
.entries
[i
].account_name
.string
;
6658 for (j
=0; j
<num_names
; j
++) {
6659 if (names
[j
] == NULL
)
6661 if (strequal(names
[j
], name
)) {
6669 torture_warning(tctx
, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
6674 q2
.in
.start_idx
+= q2
.out
.info
->info5
.count
;
6677 if (!NT_STATUS_IS_OK(status
)) {
6678 torture_warning(tctx
, "QueryDisplayInfo level 5 failed - %s\n",
6683 for (i
=0; i
<num_names
; i
++) {
6684 if (names
[i
] != NULL
) {
6685 torture_warning(tctx
, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
6694 static bool test_DeleteDomainGroup(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6695 struct policy_handle
*group_handle
)
6697 struct samr_DeleteDomainGroup d
;
6700 torture_comment(tctx
, "Testing DeleteDomainGroup\n");
6702 d
.in
.group_handle
= group_handle
;
6703 d
.out
.group_handle
= group_handle
;
6705 status
= dcerpc_samr_DeleteDomainGroup(p
, tctx
, &d
);
6706 torture_assert_ntstatus_ok(tctx
, status
, "DeleteDomainGroup");
6711 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6712 struct policy_handle
*domain_handle
)
6714 struct samr_TestPrivateFunctionsDomain r
;
6718 torture_comment(tctx
, "Testing TestPrivateFunctionsDomain\n");
6720 r
.in
.domain_handle
= domain_handle
;
6722 status
= dcerpc_samr_TestPrivateFunctionsDomain(p
, tctx
, &r
);
6723 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_NOT_IMPLEMENTED
, "TestPrivateFunctionsDomain");
6728 static bool test_RidToSid(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6729 struct dom_sid
*domain_sid
,
6730 struct policy_handle
*domain_handle
)
6732 struct samr_RidToSid r
;
6735 struct dom_sid
*calc_sid
, *out_sid
;
6736 int rids
[] = { 0, 42, 512, 10200 };
6739 for (i
=0;i
<ARRAY_SIZE(rids
);i
++) {
6740 torture_comment(tctx
, "Testing RidToSid\n");
6742 calc_sid
= dom_sid_dup(tctx
, domain_sid
);
6743 r
.in
.domain_handle
= domain_handle
;
6745 r
.out
.sid
= &out_sid
;
6747 status
= dcerpc_samr_RidToSid(p
, tctx
, &r
);
6748 if (!NT_STATUS_IS_OK(status
)) {
6749 torture_warning(tctx
, "RidToSid for %d failed - %s\n", rids
[i
], nt_errstr(status
));
6752 calc_sid
= dom_sid_add_rid(calc_sid
, calc_sid
, rids
[i
]);
6754 if (!dom_sid_equal(calc_sid
, out_sid
)) {
6755 torture_warning(tctx
, "RidToSid for %d failed - got %s, expected %s\n", rids
[i
],
6756 dom_sid_string(tctx
, out_sid
),
6757 dom_sid_string(tctx
, calc_sid
));
6766 static bool test_GetBootKeyInformation(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6767 struct policy_handle
*domain_handle
)
6769 struct samr_GetBootKeyInformation r
;
6772 uint32_t unknown
= 0;
6774 torture_comment(tctx
, "Testing GetBootKeyInformation\n");
6776 r
.in
.domain_handle
= domain_handle
;
6777 r
.out
.unknown
= &unknown
;
6779 status
= dcerpc_samr_GetBootKeyInformation(p
, tctx
, &r
);
6780 if (!NT_STATUS_IS_OK(status
)) {
6781 /* w2k3 seems to fail this sometimes and pass it sometimes */
6782 torture_comment(tctx
, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status
));
6788 static bool test_AddGroupMember(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6789 struct policy_handle
*domain_handle
,
6790 struct policy_handle
*group_handle
)
6793 struct samr_AddGroupMember r
;
6794 struct samr_DeleteGroupMember d
;
6795 struct samr_QueryGroupMember q
;
6796 struct samr_RidTypeArray
*rids
= NULL
;
6797 struct samr_SetMemberAttributesOfGroup s
;
6799 bool found_member
= false;
6802 status
= test_LookupName(p
, tctx
, domain_handle
, TEST_ACCOUNT_NAME
, &rid
);
6803 torture_assert_ntstatus_ok(tctx
, status
, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME
);
6805 r
.in
.group_handle
= group_handle
;
6807 r
.in
.flags
= 0; /* ??? */
6809 torture_comment(tctx
, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
6811 d
.in
.group_handle
= group_handle
;
6814 status
= dcerpc_samr_DeleteGroupMember(p
, tctx
, &d
);
6815 torture_assert_ntstatus_equal(tctx
, NT_STATUS_MEMBER_NOT_IN_GROUP
, status
, "DeleteGroupMember");
6817 status
= dcerpc_samr_AddGroupMember(p
, tctx
, &r
);
6818 torture_assert_ntstatus_ok(tctx
, status
, "AddGroupMember");
6820 status
= dcerpc_samr_AddGroupMember(p
, tctx
, &r
);
6821 torture_assert_ntstatus_equal(tctx
, NT_STATUS_MEMBER_IN_GROUP
, status
, "AddGroupMember");
6823 if (torture_setting_bool(tctx
, "samba4", false) ||
6824 torture_setting_bool(tctx
, "samba3", false)) {
6825 torture_comment(tctx
, "skipping SetMemberAttributesOfGroup test against Samba\n");
6827 /* this one is quite strange. I am using random inputs in the
6828 hope of triggering an error that might give us a clue */
6830 s
.in
.group_handle
= group_handle
;
6831 s
.in
.unknown1
= random();
6832 s
.in
.unknown2
= random();
6834 status
= dcerpc_samr_SetMemberAttributesOfGroup(p
, tctx
, &s
);
6835 torture_assert_ntstatus_ok(tctx
, status
, "SetMemberAttributesOfGroup");
6838 q
.in
.group_handle
= group_handle
;
6841 status
= dcerpc_samr_QueryGroupMember(p
, tctx
, &q
);
6842 torture_assert_ntstatus_ok(tctx
, status
, "QueryGroupMember");
6843 torture_assert(tctx
, rids
, "QueryGroupMember did not fill in rids structure");
6845 for (i
=0; i
< rids
->count
; i
++) {
6846 if (rids
->rids
[i
] == rid
) {
6847 found_member
= true;
6851 torture_assert(tctx
, found_member
, "QueryGroupMember did not list newly added member");
6853 status
= dcerpc_samr_DeleteGroupMember(p
, tctx
, &d
);
6854 torture_assert_ntstatus_ok(tctx
, status
, "DeleteGroupMember");
6857 found_member
= false;
6859 status
= dcerpc_samr_QueryGroupMember(p
, tctx
, &q
);
6860 torture_assert_ntstatus_ok(tctx
, status
, "QueryGroupMember");
6861 torture_assert(tctx
, rids
, "QueryGroupMember did not fill in rids structure");
6863 for (i
=0; i
< rids
->count
; i
++) {
6864 if (rids
->rids
[i
] == rid
) {
6865 found_member
= true;
6869 torture_assert(tctx
, !found_member
, "QueryGroupMember does still list removed member");
6871 status
= dcerpc_samr_AddGroupMember(p
, tctx
, &r
);
6872 torture_assert_ntstatus_ok(tctx
, status
, "AddGroupMember");
6878 static bool test_CreateDomainGroup(struct dcerpc_pipe
*p
,
6879 struct torture_context
*tctx
,
6880 struct policy_handle
*domain_handle
,
6881 const char *group_name
,
6882 struct policy_handle
*group_handle
,
6883 struct dom_sid
*domain_sid
,
6887 struct samr_CreateDomainGroup r
;
6889 struct lsa_String name
;
6892 init_lsa_String(&name
, group_name
);
6894 r
.in
.domain_handle
= domain_handle
;
6896 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6897 r
.out
.group_handle
= group_handle
;
6900 torture_comment(tctx
, "Testing CreateDomainGroup(%s)\n", r
.in
.name
->string
);
6902 status
= dcerpc_samr_CreateDomainGroup(p
, tctx
, &r
);
6904 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
6905 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
6906 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.name
->string
);
6909 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.name
->string
,
6915 if (NT_STATUS_EQUAL(status
, NT_STATUS_GROUP_EXISTS
)) {
6916 if (!test_DeleteGroup_byname(p
, tctx
, domain_handle
, r
.in
.name
->string
)) {
6917 torture_warning(tctx
, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r
.in
.name
->string
,
6921 status
= dcerpc_samr_CreateDomainGroup(p
, tctx
, &r
);
6923 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_EXISTS
)) {
6924 if (!test_DeleteUser_byname(p
, tctx
, domain_handle
, r
.in
.name
->string
)) {
6926 torture_warning(tctx
, "CreateDomainGroup failed: Could not delete user %s - %s\n", r
.in
.name
->string
,
6930 status
= dcerpc_samr_CreateDomainGroup(p
, tctx
, &r
);
6932 torture_assert_ntstatus_ok(tctx
, status
, "CreateDomainGroup");
6938 if (!test_AddGroupMember(p
, tctx
, domain_handle
, group_handle
)) {
6939 torture_warning(tctx
, "CreateDomainGroup failed - %s\n", nt_errstr(status
));
6943 if (!test_SetGroupInfo(p
, tctx
, group_handle
)) {
6952 its not totally clear what this does. It seems to accept any sid you like.
6954 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe
*p
,
6955 struct torture_context
*tctx
,
6956 struct policy_handle
*domain_handle
)
6959 struct samr_RemoveMemberFromForeignDomain r
;
6961 r
.in
.domain_handle
= domain_handle
;
6962 r
.in
.sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-12-34-56-78");
6964 status
= dcerpc_samr_RemoveMemberFromForeignDomain(p
, tctx
, &r
);
6965 torture_assert_ntstatus_ok(tctx
, status
, "RemoveMemberFromForeignDomain");
6970 static bool test_EnumDomainUsers(struct dcerpc_pipe
*p
,
6971 struct torture_context
*tctx
,
6972 struct policy_handle
*domain_handle
,
6973 uint32_t *total_num_entries_p
)
6976 struct samr_EnumDomainUsers r
;
6977 uint32_t resume_handle
= 0;
6978 uint32_t num_entries
= 0;
6979 uint32_t total_num_entries
= 0;
6980 struct samr_SamArray
*sam
;
6982 r
.in
.domain_handle
= domain_handle
;
6983 r
.in
.acct_flags
= 0;
6984 r
.in
.max_size
= (uint32_t)-1;
6985 r
.in
.resume_handle
= &resume_handle
;
6988 r
.out
.num_entries
= &num_entries
;
6989 r
.out
.resume_handle
= &resume_handle
;
6991 torture_comment(tctx
, "Testing EnumDomainUsers\n");
6994 status
= dcerpc_samr_EnumDomainUsers(p
, tctx
, &r
);
6995 if (NT_STATUS_IS_ERR(status
)) {
6996 torture_assert_ntstatus_ok(tctx
, status
,
6997 "failed to enumerate users");
7000 total_num_entries
+= num_entries
;
7001 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7003 if (total_num_entries_p
) {
7004 *total_num_entries_p
= total_num_entries
;
7010 static bool test_EnumDomainGroups(struct dcerpc_pipe
*p
,
7011 struct torture_context
*tctx
,
7012 struct policy_handle
*domain_handle
,
7013 uint32_t *total_num_entries_p
)
7016 struct samr_EnumDomainGroups r
;
7017 uint32_t resume_handle
= 0;
7018 uint32_t num_entries
= 0;
7019 uint32_t total_num_entries
= 0;
7020 struct samr_SamArray
*sam
;
7022 r
.in
.domain_handle
= domain_handle
;
7023 r
.in
.max_size
= (uint32_t)-1;
7024 r
.in
.resume_handle
= &resume_handle
;
7027 r
.out
.num_entries
= &num_entries
;
7028 r
.out
.resume_handle
= &resume_handle
;
7030 torture_comment(tctx
, "Testing EnumDomainGroups\n");
7033 status
= dcerpc_samr_EnumDomainGroups(p
, tctx
, &r
);
7034 if (NT_STATUS_IS_ERR(status
)) {
7035 torture_assert_ntstatus_ok(tctx
, status
,
7036 "failed to enumerate groups");
7039 total_num_entries
+= num_entries
;
7040 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7042 if (total_num_entries_p
) {
7043 *total_num_entries_p
= total_num_entries
;
7049 static bool test_EnumDomainAliases(struct dcerpc_pipe
*p
,
7050 struct torture_context
*tctx
,
7051 struct policy_handle
*domain_handle
,
7052 uint32_t *total_num_entries_p
)
7055 struct samr_EnumDomainAliases r
;
7056 uint32_t resume_handle
= 0;
7057 uint32_t num_entries
= 0;
7058 uint32_t total_num_entries
= 0;
7059 struct samr_SamArray
*sam
;
7061 r
.in
.domain_handle
= domain_handle
;
7062 r
.in
.max_size
= (uint32_t)-1;
7063 r
.in
.resume_handle
= &resume_handle
;
7066 r
.out
.num_entries
= &num_entries
;
7067 r
.out
.resume_handle
= &resume_handle
;
7069 torture_comment(tctx
, "Testing EnumDomainAliases\n");
7072 status
= dcerpc_samr_EnumDomainAliases(p
, tctx
, &r
);
7073 if (NT_STATUS_IS_ERR(status
)) {
7074 torture_assert_ntstatus_ok(tctx
, status
,
7075 "failed to enumerate aliases");
7078 total_num_entries
+= num_entries
;
7079 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7081 if (total_num_entries_p
) {
7082 *total_num_entries_p
= total_num_entries
;
7088 static bool test_QueryDisplayInfo_level(struct dcerpc_pipe
*p
,
7089 struct torture_context
*tctx
,
7090 struct policy_handle
*handle
,
7092 uint32_t *total_num_entries_p
)
7095 struct samr_QueryDisplayInfo r
;
7096 uint32_t total_num_entries
= 0;
7098 r
.in
.domain_handle
= handle
;
7101 r
.in
.max_entries
= (uint32_t)-1;
7102 r
.in
.buf_size
= (uint32_t)-1;
7104 torture_comment(tctx
, "Testing QueryDisplayInfo\n");
7107 uint32_t total_size
;
7108 uint32_t returned_size
;
7109 union samr_DispInfo info
;
7111 r
.out
.total_size
= &total_size
;
7112 r
.out
.returned_size
= &returned_size
;
7115 status
= dcerpc_samr_QueryDisplayInfo(p
, tctx
, &r
);
7116 if (NT_STATUS_IS_ERR(status
)) {
7117 torture_assert_ntstatus_ok(tctx
, status
,
7118 "failed to query displayinfo");
7121 if (*r
.out
.returned_size
== 0) {
7125 switch (r
.in
.level
) {
7127 total_num_entries
+= info
.info1
.count
;
7128 r
.in
.start_idx
+= info
.info1
.entries
[info
.info1
.count
- 1].idx
+ 1;
7131 total_num_entries
+= info
.info2
.count
;
7132 r
.in
.start_idx
+= info
.info2
.entries
[info
.info2
.count
- 1].idx
+ 1;
7135 total_num_entries
+= info
.info3
.count
;
7136 r
.in
.start_idx
+= info
.info3
.entries
[info
.info3
.count
- 1].idx
+ 1;
7139 total_num_entries
+= info
.info4
.count
;
7140 r
.in
.start_idx
+= info
.info4
.entries
[info
.info4
.count
- 1].idx
+ 1;
7143 total_num_entries
+= info
.info5
.count
;
7144 r
.in
.start_idx
+= info
.info5
.entries
[info
.info5
.count
- 1].idx
+ 1;
7150 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7152 if (total_num_entries_p
) {
7153 *total_num_entries_p
= total_num_entries
;
7159 static bool test_ManyObjects(struct dcerpc_pipe
*p
,
7160 struct torture_context
*tctx
,
7161 struct policy_handle
*domain_handle
,
7162 struct dom_sid
*domain_sid
,
7163 struct torture_samr_context
*ctx
)
7165 uint32_t num_total
= ctx
->num_objects_large_dc
;
7166 uint32_t num_enum
= 0;
7167 uint32_t num_disp
= 0;
7168 uint32_t num_created
= 0;
7169 uint32_t num_anounced
= 0;
7174 struct policy_handle
*handles
= talloc_zero_array(tctx
, struct policy_handle
, num_total
);
7179 struct samr_QueryDomainInfo2 r
;
7180 union samr_DomainInfo
*info
;
7181 r
.in
.domain_handle
= domain_handle
;
7185 status
= dcerpc_samr_QueryDomainInfo2(p
, tctx
, &r
);
7186 torture_assert_ntstatus_ok(tctx
, status
,
7187 "failed to query domain info");
7189 switch (ctx
->choice
) {
7190 case TORTURE_SAMR_MANY_ACCOUNTS
:
7191 num_anounced
= info
->general
.num_users
;
7193 case TORTURE_SAMR_MANY_GROUPS
:
7194 num_anounced
= info
->general
.num_groups
;
7196 case TORTURE_SAMR_MANY_ALIASES
:
7197 num_anounced
= info
->general
.num_aliases
;
7206 for (i
=0; i
< num_total
; i
++) {
7208 const char *name
= NULL
;
7210 switch (ctx
->choice
) {
7211 case TORTURE_SAMR_MANY_ACCOUNTS
:
7212 name
= talloc_asprintf(tctx
, "%s%04d", TEST_ACCOUNT_NAME
, i
);
7213 ret
&= test_CreateUser(p
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, 0, NULL
, false);
7215 case TORTURE_SAMR_MANY_GROUPS
:
7216 name
= talloc_asprintf(tctx
, "%s%04d", TEST_GROUPNAME
, i
);
7217 ret
&= test_CreateDomainGroup(p
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, false);
7219 case TORTURE_SAMR_MANY_ALIASES
:
7220 name
= talloc_asprintf(tctx
, "%s%04d", TEST_ALIASNAME
, i
);
7221 ret
&= test_CreateAlias(p
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, false);
7226 if (!policy_handle_empty(&handles
[i
])) {
7233 switch (ctx
->choice
) {
7234 case TORTURE_SAMR_MANY_ACCOUNTS
:
7235 ret
&= test_EnumDomainUsers(p
, tctx
, domain_handle
, &num_enum
);
7237 case TORTURE_SAMR_MANY_GROUPS
:
7238 ret
&= test_EnumDomainGroups(p
, tctx
, domain_handle
, &num_enum
);
7240 case TORTURE_SAMR_MANY_ALIASES
:
7241 ret
&= test_EnumDomainAliases(p
, tctx
, domain_handle
, &num_enum
);
7249 switch (ctx
->choice
) {
7250 case TORTURE_SAMR_MANY_ACCOUNTS
:
7251 ret
&= test_QueryDisplayInfo_level(p
, tctx
, domain_handle
, 1, &num_disp
);
7253 case TORTURE_SAMR_MANY_GROUPS
:
7254 ret
&= test_QueryDisplayInfo_level(p
, tctx
, domain_handle
, 3, &num_disp
);
7256 case TORTURE_SAMR_MANY_ALIASES
:
7257 /* no aliases in dispinfo */
7263 /* close or delete */
7265 for (i
=0; i
< num_total
; i
++) {
7267 if (policy_handle_empty(&handles
[i
])) {
7271 if (torture_setting_bool(tctx
, "samba3", false)) {
7272 ret
&= test_samr_handle_Close(p
, tctx
, &handles
[i
]);
7274 switch (ctx
->choice
) {
7275 case TORTURE_SAMR_MANY_ACCOUNTS
:
7276 ret
&= test_DeleteUser(p
, tctx
, &handles
[i
]);
7278 case TORTURE_SAMR_MANY_GROUPS
:
7279 ret
&= test_DeleteDomainGroup(p
, tctx
, &handles
[i
]);
7281 case TORTURE_SAMR_MANY_ALIASES
:
7282 ret
&= test_DeleteAlias(p
, tctx
, &handles
[i
]);
7290 talloc_free(handles
);
7292 if (ctx
->choice
== TORTURE_SAMR_MANY_ACCOUNTS
&& num_enum
!= num_anounced
+ num_created
) {
7293 torture_comment(tctx
,
7294 "unexpected number of results (%u) returned in enum call, expected %u\n",
7295 num_enum
, num_anounced
+ num_created
);
7297 torture_comment(tctx
,
7298 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
7299 num_disp
, num_anounced
+ num_created
);
7304 static bool test_Connect(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7305 struct policy_handle
*handle
);
7307 static bool test_OpenDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7308 struct torture_samr_context
*ctx
, struct dom_sid
*sid
)
7311 struct samr_OpenDomain r
;
7312 struct policy_handle domain_handle
;
7313 struct policy_handle alias_handle
;
7314 struct policy_handle user_handle
;
7315 struct policy_handle group_handle
;
7318 ZERO_STRUCT(alias_handle
);
7319 ZERO_STRUCT(user_handle
);
7320 ZERO_STRUCT(group_handle
);
7321 ZERO_STRUCT(domain_handle
);
7323 torture_comment(tctx
, "Testing OpenDomain of %s\n", dom_sid_string(tctx
, sid
));
7325 r
.in
.connect_handle
= &ctx
->handle
;
7326 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7328 r
.out
.domain_handle
= &domain_handle
;
7330 status
= dcerpc_samr_OpenDomain(p
, tctx
, &r
);
7331 torture_assert_ntstatus_ok(tctx
, status
, "OpenDomain");
7333 /* run the domain tests with the main handle closed - this tests
7334 the servers reference counting */
7335 torture_assert(tctx
, test_samr_handle_Close(p
, tctx
, &ctx
->handle
), "Failed to close SAMR handle");
7337 switch (ctx
->choice
) {
7338 case TORTURE_SAMR_PASSWORDS
:
7339 case TORTURE_SAMR_USER_PRIVILEGES
:
7340 if (!torture_setting_bool(tctx
, "samba3", false)) {
7341 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, NULL
);
7343 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
7345 torture_warning(tctx
, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7348 case TORTURE_SAMR_USER_ATTRIBUTES
:
7349 if (!torture_setting_bool(tctx
, "samba3", false)) {
7350 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, NULL
);
7352 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
7353 /* This test needs 'complex' users to validate */
7354 ret
&= test_QueryDisplayInfo(p
, tctx
, &domain_handle
);
7356 torture_warning(tctx
, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7359 case TORTURE_SAMR_PASSWORDS_PWDLASTSET
:
7360 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
:
7361 case TORTURE_SAMR_PASSWORDS_LOCKOUT
:
7362 if (!torture_setting_bool(tctx
, "samba3", false)) {
7363 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, ctx
->machine_credentials
);
7365 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, ctx
->machine_credentials
, true);
7367 torture_warning(tctx
, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7370 case TORTURE_SAMR_MANY_ACCOUNTS
:
7371 case TORTURE_SAMR_MANY_GROUPS
:
7372 case TORTURE_SAMR_MANY_ALIASES
:
7373 ret
&= test_ManyObjects(p
, tctx
, &domain_handle
, sid
, ctx
);
7375 torture_warning(tctx
, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7378 case TORTURE_SAMR_OTHER
:
7379 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
7381 torture_warning(tctx
, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx
, sid
));
7383 if (!torture_setting_bool(tctx
, "samba3", false)) {
7384 ret
&= test_QuerySecurity(p
, tctx
, &domain_handle
);
7386 ret
&= test_RemoveMemberFromForeignDomain(p
, tctx
, &domain_handle
);
7387 ret
&= test_CreateAlias(p
, tctx
, &domain_handle
, TEST_ALIASNAME
, &alias_handle
, sid
, true);
7388 ret
&= test_CreateDomainGroup(p
, tctx
, &domain_handle
, TEST_GROUPNAME
, &group_handle
, sid
, true);
7389 ret
&= test_GetAliasMembership(p
, tctx
, &domain_handle
);
7390 ret
&= test_QueryDomainInfo(p
, tctx
, &domain_handle
);
7391 ret
&= test_QueryDomainInfo2(p
, tctx
, &domain_handle
);
7392 ret
&= test_EnumDomainUsers_all(p
, tctx
, &domain_handle
);
7393 ret
&= test_EnumDomainUsers_async(p
, tctx
, &domain_handle
);
7394 ret
&= test_EnumDomainGroups_all(p
, tctx
, &domain_handle
);
7395 ret
&= test_EnumDomainAliases_all(p
, tctx
, &domain_handle
);
7396 ret
&= test_QueryDisplayInfo2(p
, tctx
, &domain_handle
);
7397 ret
&= test_QueryDisplayInfo3(p
, tctx
, &domain_handle
);
7398 ret
&= test_QueryDisplayInfo_continue(p
, tctx
, &domain_handle
);
7400 if (torture_setting_bool(tctx
, "samba4", false)) {
7401 torture_comment(tctx
, "skipping GetDisplayEnumerationIndex test against Samba4\n");
7403 ret
&= test_GetDisplayEnumerationIndex(p
, tctx
, &domain_handle
);
7404 ret
&= test_GetDisplayEnumerationIndex2(p
, tctx
, &domain_handle
);
7406 ret
&= test_GroupList(p
, tctx
, &domain_handle
);
7407 ret
&= test_TestPrivateFunctionsDomain(p
, tctx
, &domain_handle
);
7408 ret
&= test_RidToSid(p
, tctx
, sid
, &domain_handle
);
7409 ret
&= test_GetBootKeyInformation(p
, tctx
, &domain_handle
);
7411 torture_comment(tctx
, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7416 if (!policy_handle_empty(&user_handle
) &&
7417 !test_DeleteUser(p
, tctx
, &user_handle
)) {
7421 if (!policy_handle_empty(&alias_handle
) &&
7422 !test_DeleteAlias(p
, tctx
, &alias_handle
)) {
7426 if (!policy_handle_empty(&group_handle
) &&
7427 !test_DeleteDomainGroup(p
, tctx
, &group_handle
)) {
7431 torture_assert(tctx
, test_samr_handle_Close(p
, tctx
, &domain_handle
), "Failed to close SAMR domain handle");
7433 torture_assert(tctx
, test_Connect(p
, tctx
, &ctx
->handle
), "Faile to re-connect SAMR handle");
7434 /* reconnect the main handle */
7437 torture_warning(tctx
, "Testing domain %s failed!\n", dom_sid_string(tctx
, sid
));
7443 static bool test_LookupDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7444 struct torture_samr_context
*ctx
, const char *domain
)
7447 struct samr_LookupDomain r
;
7448 struct dom_sid2
*sid
= NULL
;
7449 struct lsa_String n1
;
7450 struct lsa_String n2
;
7453 torture_comment(tctx
, "Testing LookupDomain(%s)\n", domain
);
7455 /* check for correct error codes */
7456 r
.in
.connect_handle
= &ctx
->handle
;
7457 r
.in
.domain_name
= &n2
;
7461 status
= dcerpc_samr_LookupDomain(p
, tctx
, &r
);
7462 torture_assert_ntstatus_equal(tctx
, NT_STATUS_INVALID_PARAMETER
, status
, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
7464 init_lsa_String(&n2
, "xxNODOMAINxx");
7466 status
= dcerpc_samr_LookupDomain(p
, tctx
, &r
);
7467 torture_assert_ntstatus_equal(tctx
, NT_STATUS_NO_SUCH_DOMAIN
, status
, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
7469 r
.in
.connect_handle
= &ctx
->handle
;
7471 init_lsa_String(&n1
, domain
);
7472 r
.in
.domain_name
= &n1
;
7474 status
= dcerpc_samr_LookupDomain(p
, tctx
, &r
);
7475 torture_assert_ntstatus_ok(tctx
, status
, "LookupDomain");
7477 if (!test_GetDomPwInfo(p
, tctx
, &n1
)) {
7481 if (!test_OpenDomain(p
, tctx
, ctx
, *r
.out
.sid
)) {
7489 static bool test_EnumDomains(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7490 struct torture_samr_context
*ctx
)
7493 struct samr_EnumDomains r
;
7494 uint32_t resume_handle
= 0;
7495 uint32_t num_entries
= 0;
7496 struct samr_SamArray
*sam
= NULL
;
7500 r
.in
.connect_handle
= &ctx
->handle
;
7501 r
.in
.resume_handle
= &resume_handle
;
7502 r
.in
.buf_size
= (uint32_t)-1;
7503 r
.out
.resume_handle
= &resume_handle
;
7504 r
.out
.num_entries
= &num_entries
;
7507 status
= dcerpc_samr_EnumDomains(p
, tctx
, &r
);
7508 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomains");
7514 for (i
=0;i
<sam
->count
;i
++) {
7515 if (!test_LookupDomain(p
, tctx
, ctx
,
7516 sam
->entries
[i
].name
.string
)) {
7521 status
= dcerpc_samr_EnumDomains(p
, tctx
, &r
);
7522 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomains");
7528 static bool test_Connect(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7529 struct policy_handle
*handle
)
7532 struct samr_Connect r
;
7533 struct samr_Connect2 r2
;
7534 struct samr_Connect3 r3
;
7535 struct samr_Connect4 r4
;
7536 struct samr_Connect5 r5
;
7537 union samr_ConnectInfo info
;
7538 struct policy_handle h
;
7539 uint32_t level_out
= 0;
7540 bool ret
= true, got_handle
= false;
7542 torture_comment(tctx
, "testing samr_Connect\n");
7544 r
.in
.system_name
= 0;
7545 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7546 r
.out
.connect_handle
= &h
;
7548 status
= dcerpc_samr_Connect(p
, tctx
, &r
);
7549 if (!NT_STATUS_IS_OK(status
)) {
7550 torture_comment(tctx
, "Connect failed - %s\n", nt_errstr(status
));
7557 torture_comment(tctx
, "testing samr_Connect2\n");
7559 r2
.in
.system_name
= NULL
;
7560 r2
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7561 r2
.out
.connect_handle
= &h
;
7563 status
= dcerpc_samr_Connect2(p
, tctx
, &r2
);
7564 if (!NT_STATUS_IS_OK(status
)) {
7565 torture_comment(tctx
, "Connect2 failed - %s\n", nt_errstr(status
));
7569 test_samr_handle_Close(p
, tctx
, handle
);
7575 torture_comment(tctx
, "testing samr_Connect3\n");
7577 r3
.in
.system_name
= NULL
;
7579 r3
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7580 r3
.out
.connect_handle
= &h
;
7582 status
= dcerpc_samr_Connect3(p
, tctx
, &r3
);
7583 if (!NT_STATUS_IS_OK(status
)) {
7584 torture_warning(tctx
, "Connect3 failed - %s\n", nt_errstr(status
));
7588 test_samr_handle_Close(p
, tctx
, handle
);
7594 torture_comment(tctx
, "testing samr_Connect4\n");
7596 r4
.in
.system_name
= "";
7597 r4
.in
.client_version
= 0;
7598 r4
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7599 r4
.out
.connect_handle
= &h
;
7601 status
= dcerpc_samr_Connect4(p
, tctx
, &r4
);
7602 if (!NT_STATUS_IS_OK(status
)) {
7603 torture_warning(tctx
, "Connect4 failed - %s\n", nt_errstr(status
));
7607 test_samr_handle_Close(p
, tctx
, handle
);
7613 torture_comment(tctx
, "testing samr_Connect5\n");
7615 info
.info1
.client_version
= 0;
7616 info
.info1
.unknown2
= 0;
7618 r5
.in
.system_name
= "";
7619 r5
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7621 r5
.out
.level_out
= &level_out
;
7622 r5
.in
.info_in
= &info
;
7623 r5
.out
.info_out
= &info
;
7624 r5
.out
.connect_handle
= &h
;
7626 status
= dcerpc_samr_Connect5(p
, tctx
, &r5
);
7627 if (!NT_STATUS_IS_OK(status
)) {
7628 torture_warning(tctx
, "Connect5 failed - %s\n", nt_errstr(status
));
7632 test_samr_handle_Close(p
, tctx
, handle
);
7642 static bool test_samr_ValidatePassword(struct dcerpc_pipe
*p
, struct torture_context
*tctx
)
7644 struct samr_ValidatePassword r
;
7645 union samr_ValidatePasswordReq req
;
7646 union samr_ValidatePasswordRep
*repp
= NULL
;
7648 const char *passwords
[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL
};
7651 torture_comment(tctx
, "testing samr_ValidatePassword\n");
7654 r
.in
.level
= NetValidatePasswordReset
;
7659 req
.req3
.account
.string
= "non-existant-account-aklsdji";
7661 for (i
=0; passwords
[i
]; i
++) {
7662 req
.req3
.password
.string
= passwords
[i
];
7663 status
= dcerpc_samr_ValidatePassword(p
, tctx
, &r
);
7664 torture_assert_ntstatus_ok(tctx
, status
, "samr_ValidatePassword");
7665 torture_comment(tctx
, "Server %s password '%s' with code %i\n",
7666 repp
->ctr3
.status
==SAMR_VALIDATION_STATUS_SUCCESS
?"allowed":"refused",
7667 req
.req3
.password
.string
, repp
->ctr3
.status
);
7673 bool torture_rpc_samr(struct torture_context
*torture
)
7676 struct dcerpc_pipe
*p
;
7678 struct torture_samr_context
*ctx
;
7680 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7681 if (!NT_STATUS_IS_OK(status
)) {
7685 ctx
= talloc_zero(torture
, struct torture_samr_context
);
7687 ctx
->choice
= TORTURE_SAMR_OTHER
;
7689 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
7691 if (!torture_setting_bool(torture
, "samba3", false)) {
7692 ret
&= test_QuerySecurity(p
, torture
, &ctx
->handle
);
7695 ret
&= test_EnumDomains(p
, torture
, ctx
);
7697 ret
&= test_SetDsrmPassword(p
, torture
, &ctx
->handle
);
7699 ret
&= test_Shutdown(p
, torture
, &ctx
->handle
);
7701 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
7707 bool torture_rpc_samr_users(struct torture_context
*torture
)
7710 struct dcerpc_pipe
*p
;
7712 struct torture_samr_context
*ctx
;
7714 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7715 if (!NT_STATUS_IS_OK(status
)) {
7719 ctx
= talloc_zero(torture
, struct torture_samr_context
);
7721 ctx
->choice
= TORTURE_SAMR_USER_ATTRIBUTES
;
7723 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
7725 if (!torture_setting_bool(torture
, "samba3", false)) {
7726 ret
&= test_QuerySecurity(p
, torture
, &ctx
->handle
);
7729 ret
&= test_EnumDomains(p
, torture
, ctx
);
7731 ret
&= test_SetDsrmPassword(p
, torture
, &ctx
->handle
);
7733 ret
&= test_Shutdown(p
, torture
, &ctx
->handle
);
7735 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
7741 bool torture_rpc_samr_passwords(struct torture_context
*torture
)
7744 struct dcerpc_pipe
*p
;
7746 struct torture_samr_context
*ctx
;
7748 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7749 if (!NT_STATUS_IS_OK(status
)) {
7753 ctx
= talloc_zero(torture
, struct torture_samr_context
);
7755 ctx
->choice
= TORTURE_SAMR_PASSWORDS
;
7757 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
7759 ret
&= test_EnumDomains(p
, torture
, ctx
);
7761 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
7763 ret
&= test_samr_ValidatePassword(p
, torture
);
7768 static bool torture_rpc_samr_pwdlastset(struct torture_context
*torture
,
7769 struct dcerpc_pipe
*p2
,
7770 struct cli_credentials
*machine_credentials
)
7773 struct dcerpc_pipe
*p
;
7775 struct torture_samr_context
*ctx
;
7777 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7778 if (!NT_STATUS_IS_OK(status
)) {
7782 ctx
= talloc_zero(torture
, struct torture_samr_context
);
7784 ctx
->choice
= TORTURE_SAMR_PASSWORDS_PWDLASTSET
;
7785 ctx
->machine_credentials
= machine_credentials
;
7787 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
7789 ret
&= test_EnumDomains(p
, torture
, ctx
);
7791 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
7796 struct torture_suite
*torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX
*mem_ctx
)
7798 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "SAMR-PASSWORDS-PWDLASTSET");
7799 struct torture_rpc_tcase
*tcase
;
7801 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
7803 TEST_ACCOUNT_NAME_PWD
);
7805 torture_rpc_tcase_add_test_creds(tcase
, "pwdLastSet",
7806 torture_rpc_samr_pwdlastset
);
7811 static bool torture_rpc_samr_users_privileges_delete_user(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_USER_PRIVILEGES
;
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_user_privileges(TALLOC_CTX
*mem_ctx
)
7841 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "SAMR-USERS-PRIVILEGES");
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
, "delete_privileged_user",
7849 torture_rpc_samr_users_privileges_delete_user
);
7854 static bool torture_rpc_samr_many_accounts(struct torture_context
*torture
,
7855 struct dcerpc_pipe
*p2
,
7859 struct dcerpc_pipe
*p
;
7861 struct torture_samr_context
*ctx
=
7862 talloc_get_type_abort(data
, struct torture_samr_context
);
7864 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7865 if (!NT_STATUS_IS_OK(status
)) {
7869 ctx
->choice
= TORTURE_SAMR_MANY_ACCOUNTS
;
7870 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
7871 ctx
->num_objects_large_dc
);
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 static bool torture_rpc_samr_many_groups(struct torture_context
*torture
,
7883 struct dcerpc_pipe
*p2
,
7887 struct dcerpc_pipe
*p
;
7889 struct torture_samr_context
*ctx
=
7890 talloc_get_type_abort(data
, struct torture_samr_context
);
7892 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7893 if (!NT_STATUS_IS_OK(status
)) {
7897 ctx
->choice
= TORTURE_SAMR_MANY_GROUPS
;
7898 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
7899 ctx
->num_objects_large_dc
);
7901 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
7903 ret
&= test_EnumDomains(p
, torture
, ctx
);
7905 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
7910 static bool torture_rpc_samr_many_aliases(struct torture_context
*torture
,
7911 struct dcerpc_pipe
*p2
,
7915 struct dcerpc_pipe
*p
;
7917 struct torture_samr_context
*ctx
=
7918 talloc_get_type_abort(data
, struct torture_samr_context
);
7920 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7921 if (!NT_STATUS_IS_OK(status
)) {
7925 ctx
->choice
= TORTURE_SAMR_MANY_ALIASES
;
7926 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
7927 ctx
->num_objects_large_dc
);
7929 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
7931 ret
&= test_EnumDomains(p
, torture
, ctx
);
7933 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
7938 struct torture_suite
*torture_rpc_samr_large_dc(TALLOC_CTX
*mem_ctx
)
7940 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "SAMR-LARGE-DC");
7941 struct torture_rpc_tcase
*tcase
;
7942 struct torture_samr_context
*ctx
;
7944 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "samr", &ndr_table_samr
);
7946 ctx
= talloc_zero(suite
, struct torture_samr_context
);
7947 ctx
->num_objects_large_dc
= 150;
7949 torture_rpc_tcase_add_test_ex(tcase
, "many_aliases",
7950 torture_rpc_samr_many_aliases
, ctx
);
7951 torture_rpc_tcase_add_test_ex(tcase
, "many_groups",
7952 torture_rpc_samr_many_groups
, ctx
);
7953 torture_rpc_tcase_add_test_ex(tcase
, "many_accounts",
7954 torture_rpc_samr_many_accounts
, ctx
);
7959 static bool torture_rpc_samr_badpwdcount(struct torture_context
*torture
,
7960 struct dcerpc_pipe
*p2
,
7961 struct cli_credentials
*machine_credentials
)
7964 struct dcerpc_pipe
*p
;
7966 struct torture_samr_context
*ctx
;
7968 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7969 if (!NT_STATUS_IS_OK(status
)) {
7973 ctx
= talloc_zero(torture
, struct torture_samr_context
);
7975 ctx
->choice
= TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
;
7976 ctx
->machine_credentials
= machine_credentials
;
7978 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
7980 ret
&= test_EnumDomains(p
, torture
, ctx
);
7982 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
7987 struct torture_suite
*torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX
*mem_ctx
)
7989 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "SAMR-PASSWORDS-BADPWDCOUNT");
7990 struct torture_rpc_tcase
*tcase
;
7992 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
7994 TEST_ACCOUNT_NAME_PWD
);
7996 torture_rpc_tcase_add_test_creds(tcase
, "badPwdCount",
7997 torture_rpc_samr_badpwdcount
);
8002 static bool torture_rpc_samr_lockout(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_LOCKOUT
;
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_lockout(TALLOC_CTX
*mem_ctx
)
8032 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "SAMR-PASSWORDS-LOCKOUT");
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
, "lockout",
8040 torture_rpc_samr_lockout
);