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"
26 #include "system/time.h"
27 #include "system/network.h"
28 #include "librpc/gen_ndr/lsa.h"
29 #include "librpc/gen_ndr/ndr_netlogon.h"
30 #include "librpc/gen_ndr/ndr_netlogon_c.h"
31 #include "librpc/gen_ndr/ndr_samr_c.h"
32 #include "librpc/gen_ndr/ndr_lsa_c.h"
33 #include "../lib/crypto/crypto.h"
34 #include "libcli/auth/libcli_auth.h"
35 #include "libcli/security/security.h"
36 #include "torture/rpc/torture_rpc.h"
37 #include "param/param.h"
38 #include "auth/gensec/gensec.h"
39 #include "auth/gensec/schannel.h"
40 #include "auth/gensec/gensec_proto.h"
41 #include "../libcli/auth/schannel.h"
43 #define TEST_ACCOUNT_NAME "samrtorturetest"
44 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
45 #define TEST_ALIASNAME "samrtorturetestalias"
46 #define TEST_GROUPNAME "samrtorturetestgroup"
47 #define TEST_MACHINENAME "samrtestmach$"
48 #define TEST_DOMAINNAME "samrtestdom$"
50 enum torture_samr_choice
{
51 TORTURE_SAMR_PASSWORDS
,
52 TORTURE_SAMR_PASSWORDS_PWDLASTSET
,
53 TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
,
54 TORTURE_SAMR_PASSWORDS_LOCKOUT
,
55 TORTURE_SAMR_USER_ATTRIBUTES
,
56 TORTURE_SAMR_USER_PRIVILEGES
,
58 TORTURE_SAMR_MANY_ACCOUNTS
,
59 TORTURE_SAMR_MANY_GROUPS
,
60 TORTURE_SAMR_MANY_ALIASES
63 struct torture_samr_context
{
64 struct policy_handle handle
;
65 struct cli_credentials
*machine_credentials
;
66 enum torture_samr_choice choice
;
67 uint32_t num_objects_large_dc
;
70 static bool test_QueryUserInfo(struct dcerpc_binding_handle
*b
,
71 struct torture_context
*tctx
,
72 struct policy_handle
*handle
);
74 static bool test_QueryUserInfo2(struct dcerpc_binding_handle
*b
,
75 struct torture_context
*tctx
,
76 struct policy_handle
*handle
);
78 static bool test_QueryAliasInfo(struct dcerpc_binding_handle
*b
,
79 struct torture_context
*tctx
,
80 struct policy_handle
*handle
);
82 static bool test_ChangePassword(struct dcerpc_pipe
*p
,
83 struct torture_context
*tctx
,
84 const char *acct_name
,
85 struct policy_handle
*domain_handle
, char **password
);
87 static void init_lsa_String(struct lsa_String
*string
, const char *s
)
92 static void init_lsa_StringLarge(struct lsa_StringLarge
*string
, const char *s
)
97 static void init_lsa_BinaryString(struct lsa_BinaryString
*string
, const char *s
, uint32_t length
)
99 string
->length
= length
;
100 string
->size
= length
;
101 string
->array
= (uint16_t *)discard_const(s
);
104 bool test_samr_handle_Close(struct dcerpc_binding_handle
*b
,
105 struct torture_context
*tctx
,
106 struct policy_handle
*handle
)
110 r
.in
.handle
= handle
;
111 r
.out
.handle
= handle
;
113 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Close_r(b
, tctx
, &r
),
115 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "Close failed");
120 static bool test_Shutdown(struct dcerpc_binding_handle
*b
,
121 struct torture_context
*tctx
,
122 struct policy_handle
*handle
)
124 struct samr_Shutdown r
;
126 if (!torture_setting_bool(tctx
, "dangerous", false)) {
127 torture_skip(tctx
, "samr_Shutdown disabled - enable dangerous tests to use\n");
131 r
.in
.connect_handle
= handle
;
133 torture_comment(tctx
, "Testing samr_Shutdown\n");
135 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Shutdown_r(b
, tctx
, &r
),
137 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "Shutdown failed");
142 static bool test_SetDsrmPassword(struct dcerpc_binding_handle
*b
,
143 struct torture_context
*tctx
,
144 struct policy_handle
*handle
)
146 struct samr_SetDsrmPassword r
;
147 struct lsa_String string
;
148 struct samr_Password hash
;
150 if (!torture_setting_bool(tctx
, "dangerous", false)) {
151 torture_skip(tctx
, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
154 E_md4hash("TeSTDSRM123", hash
.hash
);
156 init_lsa_String(&string
, "Administrator");
162 torture_comment(tctx
, "Testing samr_SetDsrmPassword\n");
164 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDsrmPassword_r(b
, tctx
, &r
),
165 "SetDsrmPassword failed");
166 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_NOT_SUPPORTED
, "SetDsrmPassword failed");
172 static bool test_QuerySecurity(struct dcerpc_binding_handle
*b
,
173 struct torture_context
*tctx
,
174 struct policy_handle
*handle
)
176 struct samr_QuerySecurity r
;
177 struct samr_SetSecurity s
;
178 struct sec_desc_buf
*sdbuf
= NULL
;
180 r
.in
.handle
= handle
;
182 r
.out
.sdbuf
= &sdbuf
;
184 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QuerySecurity_r(b
, tctx
, &r
),
185 "QuerySecurity failed");
186 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "QuerySecurity failed");
188 torture_assert(tctx
, sdbuf
!= NULL
, "sdbuf is NULL");
190 s
.in
.handle
= handle
;
194 if (torture_setting_bool(tctx
, "samba4", false)) {
195 torture_skip(tctx
, "skipping SetSecurity test against Samba4\n");
198 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetSecurity_r(b
, tctx
, &s
),
199 "SetSecurity failed");
200 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "SetSecurity failed");
202 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QuerySecurity_r(b
, tctx
, &r
),
203 "QuerySecurity failed");
204 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "QuerySecurity failed");
210 static bool test_SetUserInfo(struct dcerpc_binding_handle
*b
, struct torture_context
*tctx
,
211 struct policy_handle
*handle
, uint32_t base_acct_flags
,
212 const char *base_account_name
)
214 struct samr_SetUserInfo s
;
215 struct samr_SetUserInfo2 s2
;
216 struct samr_QueryUserInfo q
;
217 struct samr_QueryUserInfo q0
;
218 union samr_UserInfo u
;
219 union samr_UserInfo
*info
;
221 const char *test_account_name
;
223 uint32_t user_extra_flags
= 0;
225 if (!torture_setting_bool(tctx
, "samba3", false)) {
226 if (base_acct_flags
== ACB_NORMAL
) {
227 /* When created, accounts are expired by default */
228 user_extra_flags
= ACB_PW_EXPIRED
;
232 s
.in
.user_handle
= handle
;
235 s2
.in
.user_handle
= handle
;
238 q
.in
.user_handle
= handle
;
242 #define TESTCALL(call, r) \
243 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ ##call## _r(b, tctx, &r),\
245 if (!NT_STATUS_IS_OK(r.out.result)) { \
246 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
247 r.in.level, nt_errstr(r.out.result), __location__); \
252 #define STRING_EQUAL(s1, s2, field) \
253 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
254 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
255 #field, s2, __location__); \
260 #define MEM_EQUAL(s1, s2, length, field) \
261 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
262 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
263 #field, (const char *)s2, __location__); \
268 #define INT_EQUAL(i1, i2, field) \
270 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
271 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
276 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
277 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
279 TESTCALL(QueryUserInfo, q) \
281 s2.in.level = lvl1; \
284 ZERO_STRUCT(u.info21); \
285 u.info21.fields_present = fpval; \
287 init_lsa_String(&u.info ## lvl1.field1, value); \
288 TESTCALL(SetUserInfo, s) \
289 TESTCALL(SetUserInfo2, s2) \
290 init_lsa_String(&u.info ## lvl1.field1, ""); \
291 TESTCALL(QueryUserInfo, q); \
293 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
295 TESTCALL(QueryUserInfo, q) \
297 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
300 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
301 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
303 TESTCALL(QueryUserInfo, q) \
305 s2.in.level = lvl1; \
308 ZERO_STRUCT(u.info21); \
309 u.info21.fields_present = fpval; \
311 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
312 TESTCALL(SetUserInfo, s) \
313 TESTCALL(SetUserInfo2, s2) \
314 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
315 TESTCALL(QueryUserInfo, q); \
317 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
319 TESTCALL(QueryUserInfo, q) \
321 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
324 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
325 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
327 TESTCALL(QueryUserInfo, q) \
329 s2.in.level = lvl1; \
332 uint8_t *bits = u.info21.logon_hours.bits; \
333 ZERO_STRUCT(u.info21); \
334 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
335 u.info21.logon_hours.units_per_week = 168; \
336 u.info21.logon_hours.bits = bits; \
338 u.info21.fields_present = fpval; \
340 u.info ## lvl1.field1 = value; \
341 TESTCALL(SetUserInfo, s) \
342 TESTCALL(SetUserInfo2, s2) \
343 u.info ## lvl1.field1 = 0; \
344 TESTCALL(QueryUserInfo, q); \
346 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
348 TESTCALL(QueryUserInfo, q) \
350 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
353 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
354 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
358 do { TESTCALL(QueryUserInfo
, q0
) } while (0);
360 TEST_USERINFO_STRING(2, comment
, 1, comment
, "xx2-1 comment", 0);
361 TEST_USERINFO_STRING(2, comment
, 21, comment
, "xx2-21 comment", 0);
362 TEST_USERINFO_STRING(21, comment
, 21, comment
, "xx21-21 comment",
365 test_account_name
= talloc_asprintf(tctx
, "%sxx7-1", base_account_name
);
366 TEST_USERINFO_STRING(7, account_name
, 1, account_name
, base_account_name
, 0);
367 test_account_name
= talloc_asprintf(tctx
, "%sxx7-3", base_account_name
);
368 TEST_USERINFO_STRING(7, account_name
, 3, account_name
, base_account_name
, 0);
369 test_account_name
= talloc_asprintf(tctx
, "%sxx7-5", base_account_name
);
370 TEST_USERINFO_STRING(7, account_name
, 5, account_name
, base_account_name
, 0);
371 test_account_name
= talloc_asprintf(tctx
, "%sxx7-6", base_account_name
);
372 TEST_USERINFO_STRING(7, account_name
, 6, account_name
, base_account_name
, 0);
373 test_account_name
= talloc_asprintf(tctx
, "%sxx7-7", base_account_name
);
374 TEST_USERINFO_STRING(7, account_name
, 7, account_name
, base_account_name
, 0);
375 test_account_name
= talloc_asprintf(tctx
, "%sxx7-21", base_account_name
);
376 TEST_USERINFO_STRING(7, account_name
, 21, account_name
, base_account_name
, 0);
377 test_account_name
= base_account_name
;
378 TEST_USERINFO_STRING(21, account_name
, 21, account_name
, base_account_name
,
379 SAMR_FIELD_ACCOUNT_NAME
);
381 TEST_USERINFO_STRING(6, full_name
, 1, full_name
, "xx6-1 full_name", 0);
382 TEST_USERINFO_STRING(6, full_name
, 3, full_name
, "xx6-3 full_name", 0);
383 TEST_USERINFO_STRING(6, full_name
, 5, full_name
, "xx6-5 full_name", 0);
384 TEST_USERINFO_STRING(6, full_name
, 6, full_name
, "xx6-6 full_name", 0);
385 TEST_USERINFO_STRING(6, full_name
, 8, full_name
, "xx6-8 full_name", 0);
386 TEST_USERINFO_STRING(6, full_name
, 21, full_name
, "xx6-21 full_name", 0);
387 TEST_USERINFO_STRING(8, full_name
, 21, full_name
, "xx8-21 full_name", 0);
388 TEST_USERINFO_STRING(21, full_name
, 21, full_name
, "xx21-21 full_name",
389 SAMR_FIELD_FULL_NAME
);
391 TEST_USERINFO_STRING(6, full_name
, 1, full_name
, "", 0);
392 TEST_USERINFO_STRING(6, full_name
, 3, full_name
, "", 0);
393 TEST_USERINFO_STRING(6, full_name
, 5, full_name
, "", 0);
394 TEST_USERINFO_STRING(6, full_name
, 6, full_name
, "", 0);
395 TEST_USERINFO_STRING(6, full_name
, 8, full_name
, "", 0);
396 TEST_USERINFO_STRING(6, full_name
, 21, full_name
, "", 0);
397 TEST_USERINFO_STRING(8, full_name
, 21, full_name
, "", 0);
398 TEST_USERINFO_STRING(21, full_name
, 21, full_name
, "",
399 SAMR_FIELD_FULL_NAME
);
401 TEST_USERINFO_STRING(11, logon_script
, 3, logon_script
, "xx11-3 logon_script", 0);
402 TEST_USERINFO_STRING(11, logon_script
, 5, logon_script
, "xx11-5 logon_script", 0);
403 TEST_USERINFO_STRING(11, logon_script
, 21, logon_script
, "xx11-21 logon_script", 0);
404 TEST_USERINFO_STRING(21, logon_script
, 21, logon_script
, "xx21-21 logon_script",
405 SAMR_FIELD_LOGON_SCRIPT
);
407 TEST_USERINFO_STRING(12, profile_path
, 3, profile_path
, "xx12-3 profile_path", 0);
408 TEST_USERINFO_STRING(12, profile_path
, 5, profile_path
, "xx12-5 profile_path", 0);
409 TEST_USERINFO_STRING(12, profile_path
, 21, profile_path
, "xx12-21 profile_path", 0);
410 TEST_USERINFO_STRING(21, profile_path
, 21, profile_path
, "xx21-21 profile_path",
411 SAMR_FIELD_PROFILE_PATH
);
413 TEST_USERINFO_STRING(10, home_directory
, 3, home_directory
, "xx10-3 home_directory", 0);
414 TEST_USERINFO_STRING(10, home_directory
, 5, home_directory
, "xx10-5 home_directory", 0);
415 TEST_USERINFO_STRING(10, home_directory
, 21, home_directory
, "xx10-21 home_directory", 0);
416 TEST_USERINFO_STRING(21, home_directory
, 21, home_directory
, "xx21-21 home_directory",
417 SAMR_FIELD_HOME_DIRECTORY
);
418 TEST_USERINFO_STRING(21, home_directory
, 10, home_directory
, "xx21-10 home_directory",
419 SAMR_FIELD_HOME_DIRECTORY
);
421 TEST_USERINFO_STRING(10, home_drive
, 3, home_drive
, "xx10-3 home_drive", 0);
422 TEST_USERINFO_STRING(10, home_drive
, 5, home_drive
, "xx10-5 home_drive", 0);
423 TEST_USERINFO_STRING(10, home_drive
, 21, home_drive
, "xx10-21 home_drive", 0);
424 TEST_USERINFO_STRING(21, home_drive
, 21, home_drive
, "xx21-21 home_drive",
425 SAMR_FIELD_HOME_DRIVE
);
426 TEST_USERINFO_STRING(21, home_drive
, 10, home_drive
, "xx21-10 home_drive",
427 SAMR_FIELD_HOME_DRIVE
);
429 TEST_USERINFO_STRING(13, description
, 1, description
, "xx13-1 description", 0);
430 TEST_USERINFO_STRING(13, description
, 5, description
, "xx13-5 description", 0);
431 TEST_USERINFO_STRING(13, description
, 21, description
, "xx13-21 description", 0);
432 TEST_USERINFO_STRING(21, description
, 21, description
, "xx21-21 description",
433 SAMR_FIELD_DESCRIPTION
);
435 TEST_USERINFO_STRING(14, workstations
, 3, workstations
, "14workstation3", 0);
436 TEST_USERINFO_STRING(14, workstations
, 5, workstations
, "14workstation4", 0);
437 TEST_USERINFO_STRING(14, workstations
, 21, workstations
, "14workstation21", 0);
438 TEST_USERINFO_STRING(21, workstations
, 21, workstations
, "21workstation21",
439 SAMR_FIELD_WORKSTATIONS
);
440 TEST_USERINFO_STRING(21, workstations
, 3, workstations
, "21workstation3",
441 SAMR_FIELD_WORKSTATIONS
);
442 TEST_USERINFO_STRING(21, workstations
, 5, workstations
, "21workstation5",
443 SAMR_FIELD_WORKSTATIONS
);
444 TEST_USERINFO_STRING(21, workstations
, 14, workstations
, "21workstation14",
445 SAMR_FIELD_WORKSTATIONS
);
447 TEST_USERINFO_BINARYSTRING(20, parameters
, 21, parameters
, "xx20-21 parameters", 0);
448 TEST_USERINFO_BINARYSTRING(21, parameters
, 21, parameters
, "xx21-21 parameters",
449 SAMR_FIELD_PARAMETERS
);
450 TEST_USERINFO_BINARYSTRING(21, parameters
, 20, parameters
, "xx21-20 parameters",
451 SAMR_FIELD_PARAMETERS
);
452 /* also empty user parameters are allowed */
453 TEST_USERINFO_BINARYSTRING(20, parameters
, 21, parameters
, "", 0);
454 TEST_USERINFO_BINARYSTRING(21, parameters
, 21, parameters
, "",
455 SAMR_FIELD_PARAMETERS
);
456 TEST_USERINFO_BINARYSTRING(21, parameters
, 20, parameters
, "",
457 SAMR_FIELD_PARAMETERS
);
459 /* Samba 3 cannot store country_code and code_page atm. - gd */
460 if (!torture_setting_bool(tctx
, "samba3", false)) {
461 TEST_USERINFO_INT(2, country_code
, 2, country_code
, __LINE__
, 0);
462 TEST_USERINFO_INT(2, country_code
, 21, country_code
, __LINE__
, 0);
463 TEST_USERINFO_INT(21, country_code
, 21, country_code
, __LINE__
,
464 SAMR_FIELD_COUNTRY_CODE
);
465 TEST_USERINFO_INT(21, country_code
, 2, country_code
, __LINE__
,
466 SAMR_FIELD_COUNTRY_CODE
);
468 TEST_USERINFO_INT(2, code_page
, 21, code_page
, __LINE__
, 0);
469 TEST_USERINFO_INT(21, code_page
, 21, code_page
, __LINE__
,
470 SAMR_FIELD_CODE_PAGE
);
471 TEST_USERINFO_INT(21, code_page
, 2, code_page
, __LINE__
,
472 SAMR_FIELD_CODE_PAGE
);
475 if (!torture_setting_bool(tctx
, "samba3", false)) {
476 TEST_USERINFO_INT(17, acct_expiry
, 21, acct_expiry
, __LINE__
, 0);
477 TEST_USERINFO_INT(17, acct_expiry
, 5, acct_expiry
, __LINE__
, 0);
478 TEST_USERINFO_INT(21, acct_expiry
, 21, acct_expiry
, __LINE__
,
479 SAMR_FIELD_ACCT_EXPIRY
);
480 TEST_USERINFO_INT(21, acct_expiry
, 5, acct_expiry
, __LINE__
,
481 SAMR_FIELD_ACCT_EXPIRY
);
482 TEST_USERINFO_INT(21, acct_expiry
, 17, acct_expiry
, __LINE__
,
483 SAMR_FIELD_ACCT_EXPIRY
);
485 /* Samba 3 can only store seconds / time_t in passdb - gd */
487 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
488 TEST_USERINFO_INT(17, acct_expiry
, 21, acct_expiry
, nt
, 0);
489 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
490 TEST_USERINFO_INT(17, acct_expiry
, 5, acct_expiry
, nt
, 0);
491 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
492 TEST_USERINFO_INT(21, acct_expiry
, 21, acct_expiry
, nt
, SAMR_FIELD_ACCT_EXPIRY
);
493 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
494 TEST_USERINFO_INT(21, acct_expiry
, 5, acct_expiry
, nt
, SAMR_FIELD_ACCT_EXPIRY
);
495 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
496 TEST_USERINFO_INT(21, acct_expiry
, 17, acct_expiry
, nt
, SAMR_FIELD_ACCT_EXPIRY
);
499 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 3, logon_hours
.bits
[3], 1, 0);
500 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 5, logon_hours
.bits
[3], 2, 0);
501 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 21, logon_hours
.bits
[3], 3, 0);
502 TEST_USERINFO_INT(21, logon_hours
.bits
[3], 21, logon_hours
.bits
[3], 4,
503 SAMR_FIELD_LOGON_HOURS
);
505 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
506 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
),
507 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
| user_extra_flags
),
509 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
510 (base_acct_flags
| ACB_DISABLED
),
511 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
514 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
515 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
516 (base_acct_flags
| ACB_DISABLED
| ACB_PWNOEXP
),
517 (base_acct_flags
| ACB_DISABLED
| ACB_PWNOEXP
),
519 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
520 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
),
521 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
| user_extra_flags
),
525 /* The 'autolock' flag doesn't stick - check this */
526 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
527 (base_acct_flags
| ACB_DISABLED
| ACB_AUTOLOCK
),
528 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
531 /* Removing the 'disabled' flag doesn't stick - check this */
532 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
534 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
538 /* Samba3 cannot store these atm */
539 if (!torture_setting_bool(tctx
, "samba3", false)) {
540 /* The 'store plaintext' flag does stick */
541 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
542 (base_acct_flags
| ACB_DISABLED
| ACB_ENC_TXT_PWD_ALLOWED
),
543 (base_acct_flags
| ACB_DISABLED
| ACB_ENC_TXT_PWD_ALLOWED
| user_extra_flags
),
545 /* The 'use DES' flag does stick */
546 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
547 (base_acct_flags
| ACB_DISABLED
| ACB_USE_DES_KEY_ONLY
),
548 (base_acct_flags
| ACB_DISABLED
| ACB_USE_DES_KEY_ONLY
| user_extra_flags
),
550 /* The 'don't require kerberos pre-authentication flag does stick */
551 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
552 (base_acct_flags
| ACB_DISABLED
| ACB_DONT_REQUIRE_PREAUTH
),
553 (base_acct_flags
| ACB_DISABLED
| ACB_DONT_REQUIRE_PREAUTH
| user_extra_flags
),
555 /* The 'no kerberos PAC required' flag sticks */
556 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
557 (base_acct_flags
| ACB_DISABLED
| ACB_NO_AUTH_DATA_REQD
),
558 (base_acct_flags
| ACB_DISABLED
| ACB_NO_AUTH_DATA_REQD
| user_extra_flags
),
561 TEST_USERINFO_INT_EXP(21, acct_flags
, 21, acct_flags
,
562 (base_acct_flags
| ACB_DISABLED
),
563 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
564 SAMR_FIELD_ACCT_FLAGS
);
567 /* these fail with win2003 - it appears you can't set the primary gid?
568 the set succeeds, but the gid isn't changed. Very weird! */
569 TEST_USERINFO_INT(9, primary_gid
, 1, primary_gid
, 513);
570 TEST_USERINFO_INT(9, primary_gid
, 3, primary_gid
, 513);
571 TEST_USERINFO_INT(9, primary_gid
, 5, primary_gid
, 513);
572 TEST_USERINFO_INT(9, primary_gid
, 21, primary_gid
, 513);
579 generate a random password for password change tests
581 static char *samr_rand_pass_silent(TALLOC_CTX
*mem_ctx
, int min_len
)
583 size_t len
= MAX(8, min_len
);
584 char *s
= generate_random_password(mem_ctx
, len
, len
+6);
588 static char *samr_rand_pass(TALLOC_CTX
*mem_ctx
, int min_len
)
590 char *s
= samr_rand_pass_silent(mem_ctx
, min_len
);
591 printf("Generated password '%s'\n", s
);
597 generate a random password for password change tests
599 static DATA_BLOB
samr_very_rand_pass(TALLOC_CTX
*mem_ctx
, int len
)
602 DATA_BLOB password
= data_blob_talloc(mem_ctx
, NULL
, len
* 2 /* number of unicode chars */);
603 generate_random_buffer(password
.data
, password
.length
);
605 for (i
=0; i
< len
; i
++) {
606 if (((uint16_t *)password
.data
)[i
] == 0) {
607 ((uint16_t *)password
.data
)[i
] = 1;
615 generate a random password for password change tests (fixed length)
617 static char *samr_rand_pass_fixed_len(TALLOC_CTX
*mem_ctx
, int len
)
619 char *s
= generate_random_password(mem_ctx
, len
, len
);
620 printf("Generated password '%s'\n", s
);
624 static bool test_SetUserPass(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
625 struct policy_handle
*handle
, char **password
)
628 struct samr_SetUserInfo s
;
629 union samr_UserInfo u
;
631 DATA_BLOB session_key
;
633 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
634 struct samr_GetUserPwInfo pwp
;
635 struct samr_PwInfo info
;
636 int policy_min_pw_len
= 0;
637 pwp
.in
.user_handle
= handle
;
638 pwp
.out
.info
= &info
;
640 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
641 "GetUserPwInfo failed");
642 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
643 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
645 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
647 s
.in
.user_handle
= handle
;
651 encode_pw_buffer(u
.info24
.password
.data
, newpass
, STR_UNICODE
);
652 u
.info24
.password_expired
= 0;
654 status
= dcerpc_fetch_session_key(p
, &session_key
);
655 if (!NT_STATUS_IS_OK(status
)) {
656 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
657 s
.in
.level
, nt_errstr(status
));
661 arcfour_crypt_blob(u
.info24
.password
.data
, 516, &session_key
);
663 torture_comment(tctx
, "Testing SetUserInfo level 24 (set password)\n");
665 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
666 "SetUserInfo failed");
667 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
668 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
669 s
.in
.level
, nt_errstr(s
.out
.result
));
679 static bool test_SetUserPass_23(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
680 struct policy_handle
*handle
, uint32_t fields_present
,
684 struct samr_SetUserInfo s
;
685 union samr_UserInfo u
;
687 DATA_BLOB session_key
;
688 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
690 struct samr_GetUserPwInfo pwp
;
691 struct samr_PwInfo info
;
692 int policy_min_pw_len
= 0;
693 pwp
.in
.user_handle
= handle
;
694 pwp
.out
.info
= &info
;
696 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
697 "GetUserPwInfo failed");
698 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
699 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
701 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
703 s
.in
.user_handle
= handle
;
709 u
.info23
.info
.fields_present
= fields_present
;
711 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
713 status
= dcerpc_fetch_session_key(p
, &session_key
);
714 if (!NT_STATUS_IS_OK(status
)) {
715 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
716 s
.in
.level
, nt_errstr(status
));
720 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
722 torture_comment(tctx
, "Testing SetUserInfo level 23 (set password)\n");
724 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
725 "SetUserInfo failed");
726 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
727 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
728 s
.in
.level
, nt_errstr(s
.out
.result
));
734 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
736 status
= dcerpc_fetch_session_key(p
, &session_key
);
737 if (!NT_STATUS_IS_OK(status
)) {
738 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
739 s
.in
.level
, nt_errstr(status
));
743 /* This should break the key nicely */
744 session_key
.length
--;
745 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
747 torture_comment(tctx
, "Testing SetUserInfo level 23 (set password) with wrong password\n");
749 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
750 "SetUserInfo failed");
751 if (!NT_STATUS_EQUAL(s
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
752 torture_warning(tctx
, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
753 s
.in
.level
, nt_errstr(s
.out
.result
));
761 static bool test_SetUserPassEx(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
762 struct policy_handle
*handle
, bool makeshort
,
766 struct samr_SetUserInfo s
;
767 union samr_UserInfo u
;
769 DATA_BLOB session_key
;
770 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
771 uint8_t confounder
[16];
773 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
774 struct MD5Context ctx
;
775 struct samr_GetUserPwInfo pwp
;
776 struct samr_PwInfo info
;
777 int policy_min_pw_len
= 0;
778 pwp
.in
.user_handle
= handle
;
779 pwp
.out
.info
= &info
;
781 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
782 "GetUserPwInfo failed");
783 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
784 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
786 if (makeshort
&& policy_min_pw_len
) {
787 newpass
= samr_rand_pass_fixed_len(tctx
, policy_min_pw_len
- 1);
789 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
792 s
.in
.user_handle
= handle
;
796 encode_pw_buffer(u
.info26
.password
.data
, newpass
, STR_UNICODE
);
797 u
.info26
.password_expired
= 0;
799 status
= dcerpc_fetch_session_key(p
, &session_key
);
800 if (!NT_STATUS_IS_OK(status
)) {
801 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
802 s
.in
.level
, nt_errstr(status
));
806 generate_random_buffer((uint8_t *)confounder
, 16);
809 MD5Update(&ctx
, confounder
, 16);
810 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
811 MD5Final(confounded_session_key
.data
, &ctx
);
813 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
814 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
816 torture_comment(tctx
, "Testing SetUserInfo level 26 (set password ex)\n");
818 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
819 "SetUserInfo failed");
820 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
821 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
822 s
.in
.level
, nt_errstr(s
.out
.result
));
828 /* This should break the key nicely */
829 confounded_session_key
.data
[0]++;
831 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
832 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
834 torture_comment(tctx
, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
836 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
837 "SetUserInfo failed");
838 if (!NT_STATUS_EQUAL(s
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
839 torture_warning(tctx
, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
840 s
.in
.level
, nt_errstr(s
.out
.result
));
849 static bool test_SetUserPass_25(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
850 struct policy_handle
*handle
, uint32_t fields_present
,
854 struct samr_SetUserInfo s
;
855 union samr_UserInfo u
;
857 DATA_BLOB session_key
;
858 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
859 struct MD5Context ctx
;
860 uint8_t confounder
[16];
862 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
863 struct samr_GetUserPwInfo pwp
;
864 struct samr_PwInfo info
;
865 int policy_min_pw_len
= 0;
866 pwp
.in
.user_handle
= handle
;
867 pwp
.out
.info
= &info
;
869 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
870 "GetUserPwInfo failed");
871 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
872 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
874 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
876 s
.in
.user_handle
= handle
;
882 u
.info25
.info
.fields_present
= fields_present
;
884 encode_pw_buffer(u
.info25
.password
.data
, newpass
, STR_UNICODE
);
886 status
= dcerpc_fetch_session_key(p
, &session_key
);
887 if (!NT_STATUS_IS_OK(status
)) {
888 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
889 s
.in
.level
, nt_errstr(status
));
893 generate_random_buffer((uint8_t *)confounder
, 16);
896 MD5Update(&ctx
, confounder
, 16);
897 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
898 MD5Final(confounded_session_key
.data
, &ctx
);
900 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
901 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
903 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex)\n");
905 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
906 "SetUserInfo failed");
907 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
908 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
909 s
.in
.level
, nt_errstr(s
.out
.result
));
915 /* This should break the key nicely */
916 confounded_session_key
.data
[0]++;
918 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
919 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
921 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
923 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
924 "SetUserInfo failed");
925 if (!NT_STATUS_EQUAL(s
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
926 torture_warning(tctx
, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
927 s
.in
.level
, nt_errstr(s
.out
.result
));
934 static bool test_SetUserPass_18(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
935 struct policy_handle
*handle
, char **password
)
938 struct samr_SetUserInfo s
;
939 union samr_UserInfo u
;
941 DATA_BLOB session_key
;
943 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
944 struct samr_GetUserPwInfo pwp
;
945 struct samr_PwInfo info
;
946 int policy_min_pw_len
= 0;
947 uint8_t lm_hash
[16], nt_hash
[16];
949 pwp
.in
.user_handle
= handle
;
950 pwp
.out
.info
= &info
;
952 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
953 "GetUserPwInfo failed");
954 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
955 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
957 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
959 s
.in
.user_handle
= handle
;
965 u
.info18
.nt_pwd_active
= true;
966 u
.info18
.lm_pwd_active
= true;
968 E_md4hash(newpass
, nt_hash
);
969 E_deshash(newpass
, lm_hash
);
971 status
= dcerpc_fetch_session_key(p
, &session_key
);
972 if (!NT_STATUS_IS_OK(status
)) {
973 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
974 s
.in
.level
, nt_errstr(status
));
980 in
= data_blob_const(nt_hash
, 16);
981 out
= data_blob_talloc_zero(tctx
, 16);
982 sess_crypt_blob(&out
, &in
, &session_key
, true);
983 memcpy(u
.info18
.nt_pwd
.hash
, out
.data
, out
.length
);
987 in
= data_blob_const(lm_hash
, 16);
988 out
= data_blob_talloc_zero(tctx
, 16);
989 sess_crypt_blob(&out
, &in
, &session_key
, true);
990 memcpy(u
.info18
.lm_pwd
.hash
, out
.data
, out
.length
);
993 torture_comment(tctx
, "Testing SetUserInfo level 18 (set password hash)\n");
995 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
996 "SetUserInfo failed");
997 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
998 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
999 s
.in
.level
, nt_errstr(s
.out
.result
));
1002 *password
= newpass
;
1008 static bool test_SetUserPass_21(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1009 struct policy_handle
*handle
, uint32_t fields_present
,
1013 struct samr_SetUserInfo s
;
1014 union samr_UserInfo u
;
1016 DATA_BLOB session_key
;
1018 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1019 struct samr_GetUserPwInfo pwp
;
1020 struct samr_PwInfo info
;
1021 int policy_min_pw_len
= 0;
1022 uint8_t lm_hash
[16], nt_hash
[16];
1024 pwp
.in
.user_handle
= handle
;
1025 pwp
.out
.info
= &info
;
1027 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
1028 "GetUserPwInfo failed");
1029 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
1030 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1032 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1034 s
.in
.user_handle
= handle
;
1038 E_md4hash(newpass
, nt_hash
);
1039 E_deshash(newpass
, lm_hash
);
1043 u
.info21
.fields_present
= fields_present
;
1045 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1046 u
.info21
.lm_owf_password
.length
= 16;
1047 u
.info21
.lm_owf_password
.size
= 16;
1048 u
.info21
.lm_owf_password
.array
= (uint16_t *)lm_hash
;
1049 u
.info21
.lm_password_set
= true;
1052 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1053 u
.info21
.nt_owf_password
.length
= 16;
1054 u
.info21
.nt_owf_password
.size
= 16;
1055 u
.info21
.nt_owf_password
.array
= (uint16_t *)nt_hash
;
1056 u
.info21
.nt_password_set
= true;
1059 status
= dcerpc_fetch_session_key(p
, &session_key
);
1060 if (!NT_STATUS_IS_OK(status
)) {
1061 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
1062 s
.in
.level
, nt_errstr(status
));
1066 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1068 in
= data_blob_const(u
.info21
.lm_owf_password
.array
,
1069 u
.info21
.lm_owf_password
.length
);
1070 out
= data_blob_talloc_zero(tctx
, 16);
1071 sess_crypt_blob(&out
, &in
, &session_key
, true);
1072 u
.info21
.lm_owf_password
.array
= (uint16_t *)out
.data
;
1075 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1077 in
= data_blob_const(u
.info21
.nt_owf_password
.array
,
1078 u
.info21
.nt_owf_password
.length
);
1079 out
= data_blob_talloc_zero(tctx
, 16);
1080 sess_crypt_blob(&out
, &in
, &session_key
, true);
1081 u
.info21
.nt_owf_password
.array
= (uint16_t *)out
.data
;
1084 torture_comment(tctx
, "Testing SetUserInfo level 21 (set password hash)\n");
1086 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
1087 "SetUserInfo failed");
1088 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
1089 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
1090 s
.in
.level
, nt_errstr(s
.out
.result
));
1093 *password
= newpass
;
1096 /* try invalid length */
1097 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1099 u
.info21
.nt_owf_password
.length
++;
1101 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
1102 "SetUserInfo failed");
1103 if (!NT_STATUS_EQUAL(s
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
1104 torture_warning(tctx
, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1105 s
.in
.level
, nt_errstr(s
.out
.result
));
1110 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1112 u
.info21
.lm_owf_password
.length
++;
1114 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
1115 "SetUserInfo failed");
1116 if (!NT_STATUS_EQUAL(s
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
1117 torture_warning(tctx
, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1118 s
.in
.level
, nt_errstr(s
.out
.result
));
1126 static bool test_SetUserPass_level_ex(struct dcerpc_pipe
*p
,
1127 struct torture_context
*tctx
,
1128 struct policy_handle
*handle
,
1130 uint32_t fields_present
,
1131 char **password
, uint8_t password_expired
,
1133 bool *matched_expected_error
)
1136 NTSTATUS expected_error
= NT_STATUS_OK
;
1137 struct samr_SetUserInfo s
;
1138 struct samr_SetUserInfo2 s2
;
1139 union samr_UserInfo u
;
1141 DATA_BLOB session_key
;
1142 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
1143 struct MD5Context ctx
;
1144 uint8_t confounder
[16];
1146 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1147 struct samr_GetUserPwInfo pwp
;
1148 struct samr_PwInfo info
;
1149 int policy_min_pw_len
= 0;
1150 const char *comment
= NULL
;
1151 uint8_t lm_hash
[16], nt_hash
[16];
1153 pwp
.in
.user_handle
= handle
;
1154 pwp
.out
.info
= &info
;
1156 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
1157 "GetUserPwInfo failed");
1158 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
1159 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1161 newpass
= samr_rand_pass_silent(tctx
, policy_min_pw_len
);
1164 s2
.in
.user_handle
= handle
;
1166 s2
.in
.level
= level
;
1168 s
.in
.user_handle
= handle
;
1173 if (fields_present
& SAMR_FIELD_COMMENT
) {
1174 comment
= talloc_asprintf(tctx
, "comment: %ld\n", (long int) time(NULL
));
1181 E_md4hash(newpass
, nt_hash
);
1182 E_deshash(newpass
, lm_hash
);
1184 u
.info18
.nt_pwd_active
= true;
1185 u
.info18
.lm_pwd_active
= true;
1186 u
.info18
.password_expired
= password_expired
;
1188 memcpy(u
.info18
.lm_pwd
.hash
, lm_hash
, 16);
1189 memcpy(u
.info18
.nt_pwd
.hash
, nt_hash
, 16);
1193 E_md4hash(newpass
, nt_hash
);
1194 E_deshash(newpass
, lm_hash
);
1196 u
.info21
.fields_present
= fields_present
;
1197 u
.info21
.password_expired
= password_expired
;
1198 u
.info21
.comment
.string
= comment
;
1200 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1201 u
.info21
.lm_owf_password
.length
= 16;
1202 u
.info21
.lm_owf_password
.size
= 16;
1203 u
.info21
.lm_owf_password
.array
= (uint16_t *)lm_hash
;
1204 u
.info21
.lm_password_set
= true;
1207 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1208 u
.info21
.nt_owf_password
.length
= 16;
1209 u
.info21
.nt_owf_password
.size
= 16;
1210 u
.info21
.nt_owf_password
.array
= (uint16_t *)nt_hash
;
1211 u
.info21
.nt_password_set
= true;
1216 u
.info23
.info
.fields_present
= fields_present
;
1217 u
.info23
.info
.password_expired
= password_expired
;
1218 u
.info23
.info
.comment
.string
= comment
;
1220 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
1224 u
.info24
.password_expired
= password_expired
;
1226 encode_pw_buffer(u
.info24
.password
.data
, newpass
, STR_UNICODE
);
1230 u
.info25
.info
.fields_present
= fields_present
;
1231 u
.info25
.info
.password_expired
= password_expired
;
1232 u
.info25
.info
.comment
.string
= comment
;
1234 encode_pw_buffer(u
.info25
.password
.data
, newpass
, STR_UNICODE
);
1238 u
.info26
.password_expired
= password_expired
;
1240 encode_pw_buffer(u
.info26
.password
.data
, newpass
, STR_UNICODE
);
1245 status
= dcerpc_fetch_session_key(p
, &session_key
);
1246 if (!NT_STATUS_IS_OK(status
)) {
1247 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
1248 s
.in
.level
, nt_errstr(status
));
1252 generate_random_buffer((uint8_t *)confounder
, 16);
1255 MD5Update(&ctx
, confounder
, 16);
1256 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
1257 MD5Final(confounded_session_key
.data
, &ctx
);
1263 in
= data_blob_const(u
.info18
.nt_pwd
.hash
, 16);
1264 out
= data_blob_talloc_zero(tctx
, 16);
1265 sess_crypt_blob(&out
, &in
, &session_key
, true);
1266 memcpy(u
.info18
.nt_pwd
.hash
, out
.data
, out
.length
);
1270 in
= data_blob_const(u
.info18
.lm_pwd
.hash
, 16);
1271 out
= data_blob_talloc_zero(tctx
, 16);
1272 sess_crypt_blob(&out
, &in
, &session_key
, true);
1273 memcpy(u
.info18
.lm_pwd
.hash
, out
.data
, out
.length
);
1278 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1280 in
= data_blob_const(u
.info21
.lm_owf_password
.array
,
1281 u
.info21
.lm_owf_password
.length
);
1282 out
= data_blob_talloc_zero(tctx
, 16);
1283 sess_crypt_blob(&out
, &in
, &session_key
, true);
1284 u
.info21
.lm_owf_password
.array
= (uint16_t *)out
.data
;
1286 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1288 in
= data_blob_const(u
.info21
.nt_owf_password
.array
,
1289 u
.info21
.nt_owf_password
.length
);
1290 out
= data_blob_talloc_zero(tctx
, 16);
1291 sess_crypt_blob(&out
, &in
, &session_key
, true);
1292 u
.info21
.nt_owf_password
.array
= (uint16_t *)out
.data
;
1296 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
1299 arcfour_crypt_blob(u
.info24
.password
.data
, 516, &session_key
);
1302 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
1303 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
1306 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
1307 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
1312 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo2_r(b
, tctx
, &s2
),
1313 "SetUserInfo2 failed");
1314 status
= s2
.out
.result
;
1316 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
1317 "SetUserInfo failed");
1318 status
= s
.out
.result
;
1321 if (!NT_STATUS_IS_OK(status
)) {
1322 if (fields_present
== 0) {
1323 expected_error
= NT_STATUS_INVALID_PARAMETER
;
1325 if (fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
1326 expected_error
= NT_STATUS_ACCESS_DENIED
;
1330 if (!NT_STATUS_IS_OK(expected_error
)) {
1332 torture_assert_ntstatus_equal(tctx
,
1334 expected_error
, "SetUserInfo2 failed");
1336 torture_assert_ntstatus_equal(tctx
,
1338 expected_error
, "SetUserInfo failed");
1340 *matched_expected_error
= true;
1344 if (!NT_STATUS_IS_OK(status
)) {
1345 torture_warning(tctx
, "SetUserInfo%s level %u failed - %s\n",
1346 use_setinfo2
? "2":"", level
, nt_errstr(status
));
1349 *password
= newpass
;
1355 static bool test_SetAliasInfo(struct dcerpc_binding_handle
*b
,
1356 struct torture_context
*tctx
,
1357 struct policy_handle
*handle
)
1359 struct samr_SetAliasInfo r
;
1360 struct samr_QueryAliasInfo q
;
1361 union samr_AliasInfo
*info
;
1362 uint16_t levels
[] = {2, 3};
1366 /* Ignoring switch level 1, as that includes the number of members for the alias
1367 * and setting this to a wrong value might have negative consequences
1370 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
1371 torture_comment(tctx
, "Testing SetAliasInfo level %u\n", levels
[i
]);
1373 r
.in
.alias_handle
= handle
;
1374 r
.in
.level
= levels
[i
];
1375 r
.in
.info
= talloc(tctx
, union samr_AliasInfo
);
1376 switch (r
.in
.level
) {
1377 case ALIASINFONAME
: init_lsa_String(&r
.in
.info
->name
,TEST_ALIASNAME
); break;
1378 case ALIASINFODESCRIPTION
: init_lsa_String(&r
.in
.info
->description
,
1379 "Test Description, should test I18N as well"); break;
1380 case ALIASINFOALL
: torture_comment(tctx
, "ALIASINFOALL ignored\n"); break;
1383 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetAliasInfo_r(b
, tctx
, &r
),
1384 "SetAliasInfo failed");
1385 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1386 torture_warning(tctx
, "SetAliasInfo level %u failed - %s\n",
1387 levels
[i
], nt_errstr(r
.out
.result
));
1391 q
.in
.alias_handle
= handle
;
1392 q
.in
.level
= levels
[i
];
1395 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryAliasInfo_r(b
, tctx
, &q
),
1396 "QueryAliasInfo failed");
1397 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
1398 torture_warning(tctx
, "QueryAliasInfo level %u failed - %s\n",
1399 levels
[i
], nt_errstr(q
.out
.result
));
1407 static bool test_GetGroupsForUser(struct dcerpc_binding_handle
*b
,
1408 struct torture_context
*tctx
,
1409 struct policy_handle
*user_handle
)
1411 struct samr_GetGroupsForUser r
;
1412 struct samr_RidWithAttributeArray
*rids
= NULL
;
1414 torture_comment(tctx
, "Testing GetGroupsForUser\n");
1416 r
.in
.user_handle
= user_handle
;
1419 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetGroupsForUser_r(b
, tctx
, &r
),
1420 "GetGroupsForUser failed");
1421 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetGroupsForUser failed");
1427 static bool test_GetDomPwInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1428 struct lsa_String
*domain_name
)
1430 struct samr_GetDomPwInfo r
;
1431 struct samr_PwInfo info
;
1432 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1434 r
.in
.domain_name
= domain_name
;
1437 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1439 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &r
),
1440 "GetDomPwInfo failed");
1441 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetDomPwInfo failed");
1443 r
.in
.domain_name
->string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1444 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1446 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &r
),
1447 "GetDomPwInfo failed");
1448 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetDomPwInfo failed");
1450 r
.in
.domain_name
->string
= "\\\\__NONAME__";
1451 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1453 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &r
),
1454 "GetDomPwInfo failed");
1455 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetDomPwInfo failed");
1457 r
.in
.domain_name
->string
= "\\\\Builtin";
1458 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1460 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &r
),
1461 "GetDomPwInfo failed");
1462 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetDomPwInfo failed");
1467 static bool test_GetUserPwInfo(struct dcerpc_binding_handle
*b
,
1468 struct torture_context
*tctx
,
1469 struct policy_handle
*handle
)
1471 struct samr_GetUserPwInfo r
;
1472 struct samr_PwInfo info
;
1474 torture_comment(tctx
, "Testing GetUserPwInfo\n");
1476 r
.in
.user_handle
= handle
;
1479 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &r
),
1480 "GetUserPwInfo failed");
1481 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetUserPwInfo");
1486 static NTSTATUS
test_LookupName(struct dcerpc_binding_handle
*b
,
1487 struct torture_context
*tctx
,
1488 struct policy_handle
*domain_handle
, const char *name
,
1492 struct samr_LookupNames n
;
1493 struct lsa_String sname
[2];
1494 struct samr_Ids rids
, types
;
1496 init_lsa_String(&sname
[0], name
);
1498 n
.in
.domain_handle
= domain_handle
;
1502 n
.out
.types
= &types
;
1503 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1504 if (!NT_STATUS_IS_OK(status
)) {
1507 if (NT_STATUS_IS_OK(n
.out
.result
)) {
1508 *rid
= n
.out
.rids
->ids
[0];
1510 return n
.out
.result
;
1513 init_lsa_String(&sname
[1], "xxNONAMExx");
1515 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1516 if (!NT_STATUS_IS_OK(status
)) {
1519 if (!NT_STATUS_EQUAL(n
.out
.result
, STATUS_SOME_UNMAPPED
)) {
1520 torture_warning(tctx
, "LookupNames[2] failed - %s\n", nt_errstr(n
.out
.result
));
1521 if (NT_STATUS_IS_OK(n
.out
.result
)) {
1522 return NT_STATUS_UNSUCCESSFUL
;
1524 return n
.out
.result
;
1528 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1529 if (!NT_STATUS_IS_OK(status
)) {
1532 if (!NT_STATUS_IS_OK(n
.out
.result
)) {
1533 torture_warning(tctx
, "LookupNames[0] failed - %s\n", nt_errstr(status
));
1534 return n
.out
.result
;
1537 init_lsa_String(&sname
[0], "xxNONAMExx");
1539 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1540 if (!NT_STATUS_IS_OK(status
)) {
1543 if (!NT_STATUS_EQUAL(n
.out
.result
, NT_STATUS_NONE_MAPPED
)) {
1544 torture_warning(tctx
, "LookupNames[1 bad name] failed - %s\n", nt_errstr(n
.out
.result
));
1545 if (NT_STATUS_IS_OK(n
.out
.result
)) {
1546 return NT_STATUS_UNSUCCESSFUL
;
1548 return n
.out
.result
;
1551 init_lsa_String(&sname
[0], "xxNONAMExx");
1552 init_lsa_String(&sname
[1], "xxNONAME2xx");
1554 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1555 if (!NT_STATUS_IS_OK(status
)) {
1558 if (!NT_STATUS_EQUAL(n
.out
.result
, NT_STATUS_NONE_MAPPED
)) {
1559 torture_warning(tctx
, "LookupNames[2 bad names] failed - %s\n", nt_errstr(n
.out
.result
));
1560 if (NT_STATUS_IS_OK(n
.out
.result
)) {
1561 return NT_STATUS_UNSUCCESSFUL
;
1563 return n
.out
.result
;
1566 return NT_STATUS_OK
;
1569 static NTSTATUS
test_OpenUser_byname(struct dcerpc_binding_handle
*b
,
1570 struct torture_context
*tctx
,
1571 struct policy_handle
*domain_handle
,
1572 const char *name
, struct policy_handle
*user_handle
)
1575 struct samr_OpenUser r
;
1578 status
= test_LookupName(b
, tctx
, domain_handle
, name
, &rid
);
1579 if (!NT_STATUS_IS_OK(status
)) {
1583 r
.in
.domain_handle
= domain_handle
;
1584 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1586 r
.out
.user_handle
= user_handle
;
1587 status
= dcerpc_samr_OpenUser_r(b
, tctx
, &r
);
1588 if (!NT_STATUS_IS_OK(status
)) {
1591 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1592 torture_warning(tctx
, "OpenUser_byname(%s -> %d) failed - %s\n", name
, rid
, nt_errstr(r
.out
.result
));
1595 return r
.out
.result
;
1599 static bool test_ChangePasswordNT3(struct dcerpc_pipe
*p
,
1600 struct torture_context
*tctx
,
1601 struct policy_handle
*handle
)
1604 struct samr_ChangePasswordUser r
;
1606 struct samr_Password hash1
, hash2
, hash3
, hash4
, hash5
, hash6
;
1607 struct policy_handle user_handle
;
1608 char *oldpass
= "test";
1609 char *newpass
= "test2";
1610 uint8_t old_nt_hash
[16], new_nt_hash
[16];
1611 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1613 status
= test_OpenUser_byname(p
, tctx
, handle
, "testuser", &user_handle
);
1614 if (!NT_STATUS_IS_OK(status
)) {
1618 torture_comment(tctx
, "Testing ChangePasswordUser for user 'testuser'\n");
1620 torture_comment(tctx
, "old password: %s\n", oldpass
);
1621 torture_comment(tctx
, "new password: %s\n", newpass
);
1623 E_md4hash(oldpass
, old_nt_hash
);
1624 E_md4hash(newpass
, new_nt_hash
);
1625 E_deshash(oldpass
, old_lm_hash
);
1626 E_deshash(newpass
, new_lm_hash
);
1628 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1629 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1630 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1631 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1632 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1633 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1635 r
.in
.handle
= &user_handle
;
1636 r
.in
.lm_present
= 1;
1637 r
.in
.old_lm_crypted
= &hash1
;
1638 r
.in
.new_lm_crypted
= &hash2
;
1639 r
.in
.nt_present
= 1;
1640 r
.in
.old_nt_crypted
= &hash3
;
1641 r
.in
.new_nt_crypted
= &hash4
;
1642 r
.in
.cross1_present
= 1;
1643 r
.in
.nt_cross
= &hash5
;
1644 r
.in
.cross2_present
= 1;
1645 r
.in
.lm_cross
= &hash6
;
1647 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1648 "ChangePasswordUser failed");
1649 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1650 torture_warning(tctx
, "ChangePasswordUser failed - %s\n", nt_errstr(r
.out
.result
));
1654 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
1662 static bool test_ChangePasswordUser(struct dcerpc_binding_handle
*b
,
1663 struct torture_context
*tctx
,
1664 const char *acct_name
,
1665 struct policy_handle
*handle
, char **password
)
1668 struct samr_ChangePasswordUser r
;
1670 struct samr_Password hash1
, hash2
, hash3
, hash4
, hash5
, hash6
;
1671 struct policy_handle user_handle
;
1673 uint8_t old_nt_hash
[16], new_nt_hash
[16];
1674 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1675 bool changed
= true;
1678 struct samr_GetUserPwInfo pwp
;
1679 struct samr_PwInfo info
;
1680 int policy_min_pw_len
= 0;
1682 status
= test_OpenUser_byname(b
, tctx
, handle
, acct_name
, &user_handle
);
1683 if (!NT_STATUS_IS_OK(status
)) {
1686 pwp
.in
.user_handle
= &user_handle
;
1687 pwp
.out
.info
= &info
;
1689 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
1690 "GetUserPwInfo failed");
1691 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
1692 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1694 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1696 torture_comment(tctx
, "Testing ChangePasswordUser\n");
1698 torture_assert(tctx
, *password
!= NULL
,
1699 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1701 oldpass
= *password
;
1703 E_md4hash(oldpass
, old_nt_hash
);
1704 E_md4hash(newpass
, new_nt_hash
);
1705 E_deshash(oldpass
, old_lm_hash
);
1706 E_deshash(newpass
, new_lm_hash
);
1708 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1709 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1710 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1711 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1712 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1713 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1715 r
.in
.user_handle
= &user_handle
;
1716 r
.in
.lm_present
= 1;
1717 /* Break the LM hash */
1719 r
.in
.old_lm_crypted
= &hash1
;
1720 r
.in
.new_lm_crypted
= &hash2
;
1721 r
.in
.nt_present
= 1;
1722 r
.in
.old_nt_crypted
= &hash3
;
1723 r
.in
.new_nt_crypted
= &hash4
;
1724 r
.in
.cross1_present
= 1;
1725 r
.in
.nt_cross
= &hash5
;
1726 r
.in
.cross2_present
= 1;
1727 r
.in
.lm_cross
= &hash6
;
1729 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1730 "ChangePasswordUser failed");
1731 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_WRONG_PASSWORD
,
1732 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1734 /* Unbreak the LM hash */
1737 r
.in
.user_handle
= &user_handle
;
1738 r
.in
.lm_present
= 1;
1739 r
.in
.old_lm_crypted
= &hash1
;
1740 r
.in
.new_lm_crypted
= &hash2
;
1741 /* Break the NT hash */
1743 r
.in
.nt_present
= 1;
1744 r
.in
.old_nt_crypted
= &hash3
;
1745 r
.in
.new_nt_crypted
= &hash4
;
1746 r
.in
.cross1_present
= 1;
1747 r
.in
.nt_cross
= &hash5
;
1748 r
.in
.cross2_present
= 1;
1749 r
.in
.lm_cross
= &hash6
;
1751 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1752 "ChangePasswordUser failed");
1753 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_WRONG_PASSWORD
,
1754 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1756 /* Unbreak the NT hash */
1759 r
.in
.user_handle
= &user_handle
;
1760 r
.in
.lm_present
= 1;
1761 r
.in
.old_lm_crypted
= &hash1
;
1762 r
.in
.new_lm_crypted
= &hash2
;
1763 r
.in
.nt_present
= 1;
1764 r
.in
.old_nt_crypted
= &hash3
;
1765 r
.in
.new_nt_crypted
= &hash4
;
1766 r
.in
.cross1_present
= 1;
1767 r
.in
.nt_cross
= &hash5
;
1768 r
.in
.cross2_present
= 1;
1769 /* Break the LM cross */
1771 r
.in
.lm_cross
= &hash6
;
1773 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1774 "ChangePasswordUser failed");
1775 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
1776 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(r
.out
.result
));
1780 /* Unbreak the LM cross */
1783 r
.in
.user_handle
= &user_handle
;
1784 r
.in
.lm_present
= 1;
1785 r
.in
.old_lm_crypted
= &hash1
;
1786 r
.in
.new_lm_crypted
= &hash2
;
1787 r
.in
.nt_present
= 1;
1788 r
.in
.old_nt_crypted
= &hash3
;
1789 r
.in
.new_nt_crypted
= &hash4
;
1790 r
.in
.cross1_present
= 1;
1791 /* Break the NT cross */
1793 r
.in
.nt_cross
= &hash5
;
1794 r
.in
.cross2_present
= 1;
1795 r
.in
.lm_cross
= &hash6
;
1797 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1798 "ChangePasswordUser failed");
1799 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
1800 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(r
.out
.result
));
1804 /* Unbreak the NT cross */
1808 /* Reset the hashes to not broken values */
1809 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1810 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1811 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1812 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1813 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1814 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1816 r
.in
.user_handle
= &user_handle
;
1817 r
.in
.lm_present
= 1;
1818 r
.in
.old_lm_crypted
= &hash1
;
1819 r
.in
.new_lm_crypted
= &hash2
;
1820 r
.in
.nt_present
= 1;
1821 r
.in
.old_nt_crypted
= &hash3
;
1822 r
.in
.new_nt_crypted
= &hash4
;
1823 r
.in
.cross1_present
= 1;
1824 r
.in
.nt_cross
= &hash5
;
1825 r
.in
.cross2_present
= 0;
1826 r
.in
.lm_cross
= NULL
;
1828 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1829 "ChangePasswordUser failed");
1830 if (NT_STATUS_IS_OK(r
.out
.result
)) {
1832 *password
= newpass
;
1833 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION
, r
.out
.result
)) {
1834 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r
.out
.result
));
1839 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1841 E_md4hash(oldpass
, old_nt_hash
);
1842 E_md4hash(newpass
, new_nt_hash
);
1843 E_deshash(oldpass
, old_lm_hash
);
1844 E_deshash(newpass
, new_lm_hash
);
1847 /* Reset the hashes to not broken values */
1848 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1849 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1850 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1851 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1852 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1853 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1855 r
.in
.user_handle
= &user_handle
;
1856 r
.in
.lm_present
= 1;
1857 r
.in
.old_lm_crypted
= &hash1
;
1858 r
.in
.new_lm_crypted
= &hash2
;
1859 r
.in
.nt_present
= 1;
1860 r
.in
.old_nt_crypted
= &hash3
;
1861 r
.in
.new_nt_crypted
= &hash4
;
1862 r
.in
.cross1_present
= 0;
1863 r
.in
.nt_cross
= NULL
;
1864 r
.in
.cross2_present
= 1;
1865 r
.in
.lm_cross
= &hash6
;
1867 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1868 "ChangePasswordUser failed");
1869 if (NT_STATUS_IS_OK(r
.out
.result
)) {
1871 *password
= newpass
;
1872 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION
, r
.out
.result
)) {
1873 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r
.out
.result
));
1878 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1880 E_md4hash(oldpass
, old_nt_hash
);
1881 E_md4hash(newpass
, new_nt_hash
);
1882 E_deshash(oldpass
, old_lm_hash
);
1883 E_deshash(newpass
, new_lm_hash
);
1886 /* Reset the hashes to not broken values */
1887 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1888 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1889 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1890 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1891 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1892 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1894 r
.in
.user_handle
= &user_handle
;
1895 r
.in
.lm_present
= 1;
1896 r
.in
.old_lm_crypted
= &hash1
;
1897 r
.in
.new_lm_crypted
= &hash2
;
1898 r
.in
.nt_present
= 1;
1899 r
.in
.old_nt_crypted
= &hash3
;
1900 r
.in
.new_nt_crypted
= &hash4
;
1901 r
.in
.cross1_present
= 1;
1902 r
.in
.nt_cross
= &hash5
;
1903 r
.in
.cross2_present
= 1;
1904 r
.in
.lm_cross
= &hash6
;
1906 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1907 "ChangePasswordUser failed");
1908 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1909 torture_comment(tctx
, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r
.out
.result
));
1910 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1911 torture_warning(tctx
, "ChangePasswordUser failed - %s\n", nt_errstr(r
.out
.result
));
1915 *password
= newpass
;
1918 r
.in
.user_handle
= &user_handle
;
1919 r
.in
.lm_present
= 1;
1920 r
.in
.old_lm_crypted
= &hash1
;
1921 r
.in
.new_lm_crypted
= &hash2
;
1922 r
.in
.nt_present
= 1;
1923 r
.in
.old_nt_crypted
= &hash3
;
1924 r
.in
.new_nt_crypted
= &hash4
;
1925 r
.in
.cross1_present
= 1;
1926 r
.in
.nt_cross
= &hash5
;
1927 r
.in
.cross2_present
= 1;
1928 r
.in
.lm_cross
= &hash6
;
1931 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1932 "ChangePasswordUser failed");
1933 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1934 torture_comment(tctx
, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r
.out
.result
));
1935 } else if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
1936 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(r
.out
.result
));
1942 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
1950 static bool test_OemChangePasswordUser2(struct dcerpc_pipe
*p
,
1951 struct torture_context
*tctx
,
1952 const char *acct_name
,
1953 struct policy_handle
*handle
, char **password
)
1955 struct samr_OemChangePasswordUser2 r
;
1957 struct samr_Password lm_verifier
;
1958 struct samr_CryptPassword lm_pass
;
1959 struct lsa_AsciiString server
, account
, account_bad
;
1962 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1963 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1965 struct samr_GetDomPwInfo dom_pw_info
;
1966 struct samr_PwInfo info
;
1967 int policy_min_pw_len
= 0;
1969 struct lsa_String domain_name
;
1971 domain_name
.string
= "";
1972 dom_pw_info
.in
.domain_name
= &domain_name
;
1973 dom_pw_info
.out
.info
= &info
;
1975 torture_comment(tctx
, "Testing OemChangePasswordUser2\n");
1977 torture_assert(tctx
, *password
!= NULL
,
1978 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1980 oldpass
= *password
;
1982 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &dom_pw_info
),
1983 "GetDomPwInfo failed");
1984 if (NT_STATUS_IS_OK(dom_pw_info
.out
.result
)) {
1985 policy_min_pw_len
= dom_pw_info
.out
.info
->min_password_length
;
1988 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1990 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1991 account
.string
= acct_name
;
1993 E_deshash(oldpass
, old_lm_hash
);
1994 E_deshash(newpass
, new_lm_hash
);
1996 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
1997 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
1998 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
2000 r
.in
.server
= &server
;
2001 r
.in
.account
= &account
;
2002 r
.in
.password
= &lm_pass
;
2003 r
.in
.hash
= &lm_verifier
;
2005 /* Break the verification */
2006 lm_verifier
.hash
[0]++;
2008 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2009 "OemChangePasswordUser2 failed");
2011 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)
2012 && !NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
2013 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2014 nt_errstr(r
.out
.result
));
2018 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
2019 /* Break the old password */
2021 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2022 /* unbreak it for the next operation */
2024 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
2026 r
.in
.server
= &server
;
2027 r
.in
.account
= &account
;
2028 r
.in
.password
= &lm_pass
;
2029 r
.in
.hash
= &lm_verifier
;
2031 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2032 "OemChangePasswordUser2 failed");
2034 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)
2035 && !NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
2036 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2037 nt_errstr(r
.out
.result
));
2041 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
2042 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2044 r
.in
.server
= &server
;
2045 r
.in
.account
= &account
;
2046 r
.in
.password
= &lm_pass
;
2049 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2050 "OemChangePasswordUser2 failed");
2052 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)
2053 && !NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
2054 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
2055 nt_errstr(r
.out
.result
));
2059 /* This shouldn't be a valid name */
2060 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
2061 r
.in
.account
= &account_bad
;
2063 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2064 "OemChangePasswordUser2 failed");
2066 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
2067 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
2068 nt_errstr(r
.out
.result
));
2072 /* This shouldn't be a valid name */
2073 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
2074 r
.in
.account
= &account_bad
;
2075 r
.in
.password
= &lm_pass
;
2076 r
.in
.hash
= &lm_verifier
;
2078 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2079 "OemChangePasswordUser2 failed");
2081 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
2082 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2083 nt_errstr(r
.out
.result
));
2087 /* This shouldn't be a valid name */
2088 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
2089 r
.in
.account
= &account_bad
;
2090 r
.in
.password
= NULL
;
2091 r
.in
.hash
= &lm_verifier
;
2093 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2094 "OemChangePasswordUser2 failed");
2096 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
2097 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2098 nt_errstr(r
.out
.result
));
2102 E_deshash(oldpass
, old_lm_hash
);
2103 E_deshash(newpass
, new_lm_hash
);
2105 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
2106 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2107 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
2109 r
.in
.server
= &server
;
2110 r
.in
.account
= &account
;
2111 r
.in
.password
= &lm_pass
;
2112 r
.in
.hash
= &lm_verifier
;
2114 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2115 "OemChangePasswordUser2 failed");
2117 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2118 torture_comment(tctx
, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r
.out
.result
));
2119 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2120 torture_warning(tctx
, "OemChangePasswordUser2 failed - %s\n", nt_errstr(r
.out
.result
));
2123 *password
= newpass
;
2130 static bool test_ChangePasswordUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2131 const char *acct_name
,
2133 char *newpass
, bool allow_password_restriction
)
2135 struct samr_ChangePasswordUser2 r
;
2137 struct lsa_String server
, account
;
2138 struct samr_CryptPassword nt_pass
, lm_pass
;
2139 struct samr_Password nt_verifier
, lm_verifier
;
2141 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2142 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2143 uint8_t old_lm_hash
[16], new_lm_hash
[16];
2145 struct samr_GetDomPwInfo dom_pw_info
;
2146 struct samr_PwInfo info
;
2148 struct lsa_String domain_name
;
2150 domain_name
.string
= "";
2151 dom_pw_info
.in
.domain_name
= &domain_name
;
2152 dom_pw_info
.out
.info
= &info
;
2154 torture_comment(tctx
, "Testing ChangePasswordUser2 on %s\n", acct_name
);
2156 torture_assert(tctx
, *password
!= NULL
,
2157 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2158 oldpass
= *password
;
2161 int policy_min_pw_len
= 0;
2162 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &dom_pw_info
),
2163 "GetDomPwInfo failed");
2164 if (NT_STATUS_IS_OK(dom_pw_info
.out
.result
)) {
2165 policy_min_pw_len
= dom_pw_info
.out
.info
->min_password_length
;
2168 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2171 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2172 init_lsa_String(&account
, acct_name
);
2174 E_md4hash(oldpass
, old_nt_hash
);
2175 E_md4hash(newpass
, new_nt_hash
);
2177 E_deshash(oldpass
, old_lm_hash
);
2178 E_deshash(newpass
, new_lm_hash
);
2180 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
|STR_TERMINATE
);
2181 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2182 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2184 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2185 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2186 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
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
;
2196 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser2_r(b
, tctx
, &r
),
2197 "ChangePasswordUser2 failed");
2199 if (allow_password_restriction
&& NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2200 torture_comment(tctx
, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r
.out
.result
));
2201 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2202 torture_warning(tctx
, "ChangePasswordUser2 failed - %s\n", nt_errstr(r
.out
.result
));
2205 *password
= newpass
;
2212 bool test_ChangePasswordUser3(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2213 const char *account_string
,
2214 int policy_min_pw_len
,
2216 const char *newpass
,
2217 NTTIME last_password_change
,
2218 bool handle_reject_reason
)
2220 struct samr_ChangePasswordUser3 r
;
2222 struct lsa_String server
, account
, account_bad
;
2223 struct samr_CryptPassword nt_pass
, lm_pass
;
2224 struct samr_Password nt_verifier
, lm_verifier
;
2226 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2227 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2228 uint8_t old_lm_hash
[16], new_lm_hash
[16];
2230 struct samr_DomInfo1
*dominfo
= NULL
;
2231 struct userPwdChangeFailureInformation
*reject
= NULL
;
2233 torture_comment(tctx
, "Testing ChangePasswordUser3\n");
2235 if (newpass
== NULL
) {
2237 if (policy_min_pw_len
== 0) {
2238 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2240 newpass
= samr_rand_pass_fixed_len(tctx
, policy_min_pw_len
);
2242 } while (check_password_quality(newpass
) == false);
2244 torture_comment(tctx
, "Using password '%s'\n", newpass
);
2247 torture_assert(tctx
, *password
!= NULL
,
2248 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2250 oldpass
= *password
;
2251 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2252 init_lsa_String(&account
, account_string
);
2254 E_md4hash(oldpass
, old_nt_hash
);
2255 E_md4hash(newpass
, new_nt_hash
);
2257 E_deshash(oldpass
, old_lm_hash
);
2258 E_deshash(newpass
, new_lm_hash
);
2260 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2261 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2262 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2264 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2265 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2266 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2268 /* Break the verification */
2269 nt_verifier
.hash
[0]++;
2271 r
.in
.server
= &server
;
2272 r
.in
.account
= &account
;
2273 r
.in
.nt_password
= &nt_pass
;
2274 r
.in
.nt_verifier
= &nt_verifier
;
2276 r
.in
.lm_password
= &lm_pass
;
2277 r
.in
.lm_verifier
= &lm_verifier
;
2278 r
.in
.password3
= NULL
;
2279 r
.out
.dominfo
= &dominfo
;
2280 r
.out
.reject
= &reject
;
2282 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2283 "ChangePasswordUser3 failed");
2284 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
) &&
2285 (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
))) {
2286 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2287 nt_errstr(r
.out
.result
));
2291 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2292 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2293 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2295 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2296 /* Break the NT hash */
2298 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2299 /* Unbreak it again */
2301 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2303 r
.in
.server
= &server
;
2304 r
.in
.account
= &account
;
2305 r
.in
.nt_password
= &nt_pass
;
2306 r
.in
.nt_verifier
= &nt_verifier
;
2308 r
.in
.lm_password
= &lm_pass
;
2309 r
.in
.lm_verifier
= &lm_verifier
;
2310 r
.in
.password3
= NULL
;
2311 r
.out
.dominfo
= &dominfo
;
2312 r
.out
.reject
= &reject
;
2314 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2315 "ChangePasswordUser3 failed");
2316 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
) &&
2317 (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
))) {
2318 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2319 nt_errstr(r
.out
.result
));
2323 /* This shouldn't be a valid name */
2324 init_lsa_String(&account_bad
, talloc_asprintf(tctx
, "%sXX", account_string
));
2326 r
.in
.account
= &account_bad
;
2327 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2328 "ChangePasswordUser3 failed");
2329 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
2330 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2331 nt_errstr(r
.out
.result
));
2335 E_md4hash(oldpass
, old_nt_hash
);
2336 E_md4hash(newpass
, new_nt_hash
);
2338 E_deshash(oldpass
, old_lm_hash
);
2339 E_deshash(newpass
, new_lm_hash
);
2341 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2342 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2343 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2345 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2346 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2347 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2349 r
.in
.server
= &server
;
2350 r
.in
.account
= &account
;
2351 r
.in
.nt_password
= &nt_pass
;
2352 r
.in
.nt_verifier
= &nt_verifier
;
2354 r
.in
.lm_password
= &lm_pass
;
2355 r
.in
.lm_verifier
= &lm_verifier
;
2356 r
.in
.password3
= NULL
;
2357 r
.out
.dominfo
= &dominfo
;
2358 r
.out
.reject
= &reject
;
2360 unix_to_nt_time(&t
, time(NULL
));
2362 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2363 "ChangePasswordUser3 failed");
2365 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)
2368 && handle_reject_reason
2369 && (!null_nttime(last_password_change
) || !dominfo
->min_password_age
)) {
2370 if (dominfo
->password_properties
& DOMAIN_REFUSE_PASSWORD_CHANGE
) {
2372 if (reject
&& (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
)) {
2373 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2374 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2379 /* We tested the order of precendence which is as follows:
2388 if ((dominfo
->min_password_age
> 0) && !null_nttime(last_password_change
) &&
2389 (last_password_change
+ dominfo
->min_password_age
> t
)) {
2391 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2392 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2393 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2397 } else if ((dominfo
->min_password_length
> 0) &&
2398 (strlen(newpass
) < dominfo
->min_password_length
)) {
2400 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
) {
2401 torture_warning(tctx
, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2402 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
, reject
->extendedFailureReason
);
2406 } else if ((dominfo
->password_history_length
> 0) &&
2407 strequal(oldpass
, newpass
)) {
2409 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_PWD_IN_HISTORY
) {
2410 torture_warning(tctx
, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2411 SAM_PWD_CHANGE_PWD_IN_HISTORY
, reject
->extendedFailureReason
);
2414 } else if (dominfo
->password_properties
& DOMAIN_PASSWORD_COMPLEX
) {
2416 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NOT_COMPLEX
) {
2417 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2418 SAM_PWD_CHANGE_NOT_COMPLEX
, reject
->extendedFailureReason
);
2424 if (reject
->extendedFailureReason
== SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
) {
2425 /* retry with adjusted size */
2426 return test_ChangePasswordUser3(p
, tctx
, account_string
,
2427 dominfo
->min_password_length
,
2428 password
, NULL
, 0, false);
2432 } else if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2433 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2434 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2435 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2438 /* Perhaps the server has a 'min password age' set? */
2441 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ChangePasswordUser3");
2443 *password
= talloc_strdup(tctx
, newpass
);
2449 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2450 const char *account_string
,
2451 struct policy_handle
*handle
,
2455 struct samr_ChangePasswordUser3 r
;
2456 struct samr_SetUserInfo s
;
2457 union samr_UserInfo u
;
2458 DATA_BLOB session_key
;
2459 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
2460 uint8_t confounder
[16];
2461 struct MD5Context ctx
;
2464 struct lsa_String server
, account
;
2465 struct samr_CryptPassword nt_pass
;
2466 struct samr_Password nt_verifier
;
2467 DATA_BLOB new_random_pass
;
2470 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2471 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2473 struct samr_DomInfo1
*dominfo
= NULL
;
2474 struct userPwdChangeFailureInformation
*reject
= NULL
;
2476 new_random_pass
= samr_very_rand_pass(tctx
, 128);
2478 torture_assert(tctx
, *password
!= NULL
,
2479 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2481 oldpass
= *password
;
2482 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2483 init_lsa_String(&account
, account_string
);
2485 s
.in
.user_handle
= handle
;
2491 u
.info25
.info
.fields_present
= SAMR_FIELD_NT_PASSWORD_PRESENT
;
2493 set_pw_in_buffer(u
.info25
.password
.data
, &new_random_pass
);
2495 status
= dcerpc_fetch_session_key(p
, &session_key
);
2496 if (!NT_STATUS_IS_OK(status
)) {
2497 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
2498 s
.in
.level
, nt_errstr(status
));
2502 generate_random_buffer((uint8_t *)confounder
, 16);
2505 MD5Update(&ctx
, confounder
, 16);
2506 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
2507 MD5Final(confounded_session_key
.data
, &ctx
);
2509 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
2510 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
2512 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2514 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
2515 "SetUserInfo failed");
2516 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
2517 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
2518 s
.in
.level
, nt_errstr(s
.out
.result
));
2522 torture_comment(tctx
, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2524 mdfour(old_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2526 new_random_pass
= samr_very_rand_pass(tctx
, 128);
2528 mdfour(new_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2530 set_pw_in_buffer(nt_pass
.data
, &new_random_pass
);
2531 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2532 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2534 r
.in
.server
= &server
;
2535 r
.in
.account
= &account
;
2536 r
.in
.nt_password
= &nt_pass
;
2537 r
.in
.nt_verifier
= &nt_verifier
;
2539 r
.in
.lm_password
= NULL
;
2540 r
.in
.lm_verifier
= NULL
;
2541 r
.in
.password3
= NULL
;
2542 r
.out
.dominfo
= &dominfo
;
2543 r
.out
.reject
= &reject
;
2545 unix_to_nt_time(&t
, time(NULL
));
2547 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2548 "ChangePasswordUser3 failed");
2550 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2551 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2552 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2553 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2556 /* Perhaps the server has a 'min password age' set? */
2558 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2559 torture_warning(tctx
, "ChangePasswordUser3 failed - %s\n", nt_errstr(r
.out
.result
));
2563 newpass
= samr_rand_pass(tctx
, 128);
2565 mdfour(old_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2567 E_md4hash(newpass
, new_nt_hash
);
2569 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2570 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2571 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2573 r
.in
.server
= &server
;
2574 r
.in
.account
= &account
;
2575 r
.in
.nt_password
= &nt_pass
;
2576 r
.in
.nt_verifier
= &nt_verifier
;
2578 r
.in
.lm_password
= NULL
;
2579 r
.in
.lm_verifier
= NULL
;
2580 r
.in
.password3
= NULL
;
2581 r
.out
.dominfo
= &dominfo
;
2582 r
.out
.reject
= &reject
;
2584 unix_to_nt_time(&t
, time(NULL
));
2586 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2587 "ChangePasswordUser3 failed");
2589 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2590 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2591 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2592 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2595 /* Perhaps the server has a 'min password age' set? */
2598 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ChangePasswordUser3 (on second random password)");
2599 *password
= talloc_strdup(tctx
, newpass
);
2606 static bool test_GetMembersInAlias(struct dcerpc_binding_handle
*b
,
2607 struct torture_context
*tctx
,
2608 struct policy_handle
*alias_handle
)
2610 struct samr_GetMembersInAlias r
;
2611 struct lsa_SidArray sids
;
2613 torture_comment(tctx
, "Testing GetMembersInAlias\n");
2615 r
.in
.alias_handle
= alias_handle
;
2618 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetMembersInAlias_r(b
, tctx
, &r
),
2619 "GetMembersInAlias failed");
2620 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetMembersInAlias failed");
2625 static bool test_AddMemberToAlias(struct dcerpc_binding_handle
*b
,
2626 struct torture_context
*tctx
,
2627 struct policy_handle
*alias_handle
,
2628 const struct dom_sid
*domain_sid
)
2630 struct samr_AddAliasMember r
;
2631 struct samr_DeleteAliasMember d
;
2632 struct dom_sid
*sid
;
2634 sid
= dom_sid_add_rid(tctx
, domain_sid
, 512);
2636 torture_comment(tctx
, "Testing AddAliasMember\n");
2637 r
.in
.alias_handle
= alias_handle
;
2640 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddAliasMember_r(b
, tctx
, &r
),
2641 "AddAliasMember failed");
2642 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "AddAliasMember failed");
2644 d
.in
.alias_handle
= alias_handle
;
2647 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteAliasMember_r(b
, tctx
, &d
),
2648 "DeleteAliasMember failed");
2649 torture_assert_ntstatus_ok(tctx
, d
.out
.result
, "DelAliasMember failed");
2654 static bool test_AddMultipleMembersToAlias(struct dcerpc_binding_handle
*b
,
2655 struct torture_context
*tctx
,
2656 struct policy_handle
*alias_handle
)
2658 struct samr_AddMultipleMembersToAlias a
;
2659 struct samr_RemoveMultipleMembersFromAlias r
;
2660 struct lsa_SidArray sids
;
2662 torture_comment(tctx
, "Testing AddMultipleMembersToAlias\n");
2663 a
.in
.alias_handle
= alias_handle
;
2667 sids
.sids
= talloc_array(tctx
, struct lsa_SidPtr
, 3);
2669 sids
.sids
[0].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-1");
2670 sids
.sids
[1].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-2");
2671 sids
.sids
[2].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-3");
2673 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddMultipleMembersToAlias_r(b
, tctx
, &a
),
2674 "AddMultipleMembersToAlias failed");
2675 torture_assert_ntstatus_ok(tctx
, a
.out
.result
, "AddMultipleMembersToAlias");
2678 torture_comment(tctx
, "Testing RemoveMultipleMembersFromAlias\n");
2679 r
.in
.alias_handle
= alias_handle
;
2682 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b
, tctx
, &r
),
2683 "RemoveMultipleMembersFromAlias failed");
2684 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "RemoveMultipleMembersFromAlias failed");
2686 /* strange! removing twice doesn't give any error */
2687 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b
, tctx
, &r
),
2688 "RemoveMultipleMembersFromAlias failed");
2689 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "RemoveMultipleMembersFromAlias failed");
2691 /* but removing an alias that isn't there does */
2692 sids
.sids
[2].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-4");
2694 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b
, tctx
, &r
),
2695 "RemoveMultipleMembersFromAlias failed");
2696 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
, "RemoveMultipleMembersFromAlias");
2701 static bool test_GetAliasMembership(struct dcerpc_binding_handle
*b
,
2702 struct torture_context
*tctx
,
2703 struct policy_handle
*domain_handle
)
2705 struct samr_GetAliasMembership r
;
2706 struct lsa_SidArray sids
;
2707 struct samr_Ids rids
;
2709 torture_comment(tctx
, "Testing GetAliasMembership\n");
2711 r
.in
.domain_handle
= domain_handle
;
2716 sids
.sids
= talloc_zero_array(tctx
, struct lsa_SidPtr
, sids
.num_sids
);
2718 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetAliasMembership_r(b
, tctx
, &r
),
2719 "GetAliasMembership failed");
2720 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
2721 "samr_GetAliasMembership failed");
2723 torture_assert_int_equal(tctx
, sids
.num_sids
, rids
.count
,
2724 "protocol misbehaviour");
2727 sids
.sids
= talloc_zero_array(tctx
, struct lsa_SidPtr
, sids
.num_sids
);
2728 sids
.sids
[0].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-1");
2730 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetAliasMembership_r(b
, tctx
, &r
),
2731 "samr_GetAliasMembership failed");
2732 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
2733 "samr_GetAliasMembership failed");
2736 /* only true for w2k8 it seems
2737 * win7, xp, w2k3 will return a 0 length array pointer */
2739 if (rids
.ids
&& (rids
.count
== 0)) {
2740 torture_fail(tctx
, "samr_GetAliasMembership returned 0 count and a rids array");
2743 if (!rids
.ids
&& rids
.count
) {
2744 torture_fail(tctx
, "samr_GetAliasMembership returned non-0 count but no rids");
2750 static bool test_TestPrivateFunctionsUser(struct dcerpc_binding_handle
*b
,
2751 struct torture_context
*tctx
,
2752 struct policy_handle
*user_handle
)
2754 struct samr_TestPrivateFunctionsUser r
;
2756 torture_comment(tctx
, "Testing TestPrivateFunctionsUser\n");
2758 r
.in
.user_handle
= user_handle
;
2760 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_TestPrivateFunctionsUser_r(b
, tctx
, &r
),
2761 "TestPrivateFunctionsUser failed");
2762 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_NOT_IMPLEMENTED
, "TestPrivateFunctionsUser");
2767 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_binding_handle
*b
,
2768 struct torture_context
*tctx
,
2769 struct policy_handle
*handle
,
2774 uint16_t levels
[] = { /* 3, */ 5, 21 };
2776 NTTIME pwdlastset3
= 0;
2777 NTTIME pwdlastset5
= 0;
2778 NTTIME pwdlastset21
= 0;
2780 torture_comment(tctx
, "Testing QueryUserInfo%s level 5 and 21 call ",
2781 use_info2
? "2":"");
2783 for (i
=0; i
<ARRAY_SIZE(levels
); i
++) {
2785 struct samr_QueryUserInfo r
;
2786 struct samr_QueryUserInfo2 r2
;
2787 union samr_UserInfo
*info
;
2790 r2
.in
.user_handle
= handle
;
2791 r2
.in
.level
= levels
[i
];
2792 r2
.out
.info
= &info
;
2793 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo2_r(b
, tctx
, &r2
),
2794 "QueryUserInfo2 failed");
2795 status
= r2
.out
.result
;
2798 r
.in
.user_handle
= handle
;
2799 r
.in
.level
= levels
[i
];
2801 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
2802 "QueryUserInfo failed");
2803 status
= r
.out
.result
;
2806 if (!NT_STATUS_IS_OK(status
) &&
2807 !NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_INFO_CLASS
)) {
2808 torture_warning(tctx
, "QueryUserInfo%s level %u failed - %s\n",
2809 use_info2
? "2":"", levels
[i
], nt_errstr(status
));
2813 switch (levels
[i
]) {
2815 pwdlastset3
= info
->info3
.last_password_change
;
2818 pwdlastset5
= info
->info5
.last_password_change
;
2821 pwdlastset21
= info
->info21
.last_password_change
;
2827 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2828 "pwdlastset mixup"); */
2829 torture_assert_int_equal(tctx
, pwdlastset5
, pwdlastset21
,
2830 "pwdlastset mixup");
2832 *pwdlastset
= pwdlastset21
;
2834 torture_comment(tctx
, "(pwdlastset: %llu)\n",
2835 (unsigned long long) *pwdlastset
);
2840 static bool test_SamLogon(struct torture_context
*tctx
,
2841 struct dcerpc_pipe
*p
,
2842 struct cli_credentials
*test_credentials
,
2843 NTSTATUS expected_result
,
2847 struct netr_LogonSamLogonEx r
;
2848 union netr_LogonLevel logon
;
2849 union netr_Validation validation
;
2850 uint8_t authoritative
;
2851 struct netr_IdentityInfo identity
;
2852 struct netr_NetworkInfo ninfo
;
2853 struct netr_PasswordInfo pinfo
;
2854 DATA_BLOB names_blob
, chal
, lm_resp
, nt_resp
;
2855 int flags
= CLI_CRED_NTLM_AUTH
;
2856 uint32_t samlogon_flags
= 0;
2857 struct netlogon_creds_CredentialState
*creds
;
2858 struct netr_Authenticator a
;
2859 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2861 torture_assert_ntstatus_ok(tctx
, dcerpc_schannel_creds(p
->conn
->security_state
.generic_state
, tctx
, &creds
), "");
2863 if (lpcfg_client_lanman_auth(tctx
->lp_ctx
)) {
2864 flags
|= CLI_CRED_LANMAN_AUTH
;
2867 if (lpcfg_client_ntlmv2_auth(tctx
->lp_ctx
)) {
2868 flags
|= CLI_CRED_NTLMv2_AUTH
;
2871 cli_credentials_get_ntlm_username_domain(test_credentials
, tctx
,
2872 &identity
.account_name
.string
,
2873 &identity
.domain_name
.string
);
2875 identity
.parameter_control
=
2876 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT
|
2877 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT
;
2878 identity
.logon_id_low
= 0;
2879 identity
.logon_id_high
= 0;
2880 identity
.workstation
.string
= cli_credentials_get_workstation(test_credentials
);
2883 netlogon_creds_client_authenticator(creds
, &a
);
2885 if (!E_deshash(cli_credentials_get_password(test_credentials
), pinfo
.lmpassword
.hash
)) {
2886 ZERO_STRUCT(pinfo
.lmpassword
.hash
);
2888 E_md4hash(cli_credentials_get_password(test_credentials
), pinfo
.ntpassword
.hash
);
2890 if (creds
->negotiate_flags
& NETLOGON_NEG_ARCFOUR
) {
2891 netlogon_creds_arcfour_crypt(creds
, pinfo
.lmpassword
.hash
, 16);
2892 netlogon_creds_arcfour_crypt(creds
, pinfo
.ntpassword
.hash
, 16);
2894 netlogon_creds_des_encrypt(creds
, &pinfo
.lmpassword
);
2895 netlogon_creds_des_encrypt(creds
, &pinfo
.ntpassword
);
2898 pinfo
.identity_info
= identity
;
2899 logon
.password
= &pinfo
;
2901 r
.in
.logon_level
= NetlogonInteractiveInformation
;
2903 generate_random_buffer(ninfo
.challenge
,
2904 sizeof(ninfo
.challenge
));
2905 chal
= data_blob_const(ninfo
.challenge
,
2906 sizeof(ninfo
.challenge
));
2908 names_blob
= NTLMv2_generate_names_blob(tctx
, cli_credentials_get_workstation(test_credentials
),
2909 cli_credentials_get_domain(test_credentials
));
2911 status
= cli_credentials_get_ntlm_response(test_credentials
, tctx
,
2917 torture_assert_ntstatus_ok(tctx
, status
, "cli_credentials_get_ntlm_response failed");
2919 ninfo
.lm
.data
= lm_resp
.data
;
2920 ninfo
.lm
.length
= lm_resp
.length
;
2922 ninfo
.nt
.data
= nt_resp
.data
;
2923 ninfo
.nt
.length
= nt_resp
.length
;
2925 ninfo
.identity_info
= identity
;
2926 logon
.network
= &ninfo
;
2928 r
.in
.logon_level
= NetlogonNetworkInformation
;
2931 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2932 r
.in
.computer_name
= cli_credentials_get_workstation(test_credentials
);
2933 r
.in
.logon
= &logon
;
2934 r
.in
.flags
= &samlogon_flags
;
2935 r
.out
.flags
= &samlogon_flags
;
2936 r
.out
.validation
= &validation
;
2937 r
.out
.authoritative
= &authoritative
;
2939 torture_comment(tctx
, "Testing LogonSamLogon with name %s\n", identity
.account_name
.string
);
2941 r
.in
.validation_level
= 6;
2943 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonSamLogonEx_r(b
, tctx
, &r
),
2944 "netr_LogonSamLogonEx failed");
2945 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_INFO_CLASS
)) {
2946 r
.in
.validation_level
= 3;
2947 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonSamLogonEx_r(b
, tctx
, &r
),
2948 "netr_LogonSamLogonEx failed");
2950 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2951 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, expected_result
, "LogonSamLogonEx failed");
2954 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LogonSamLogonEx failed");
2960 static bool test_SamLogon_with_creds(struct torture_context
*tctx
,
2961 struct dcerpc_pipe
*p
,
2962 struct cli_credentials
*machine_creds
,
2963 const char *acct_name
,
2964 const char *password
,
2965 NTSTATUS expected_samlogon_result
,
2969 struct cli_credentials
*test_credentials
;
2971 test_credentials
= cli_credentials_init(tctx
);
2973 cli_credentials_set_workstation(test_credentials
,
2974 cli_credentials_get_workstation(machine_creds
), CRED_SPECIFIED
);
2975 cli_credentials_set_domain(test_credentials
,
2976 cli_credentials_get_domain(machine_creds
), CRED_SPECIFIED
);
2977 cli_credentials_set_username(test_credentials
,
2978 acct_name
, CRED_SPECIFIED
);
2979 cli_credentials_set_password(test_credentials
,
2980 password
, CRED_SPECIFIED
);
2982 torture_comment(tctx
, "Testing samlogon (%s) as %s password: %s\n",
2983 interactive
? "interactive" : "network", acct_name
, password
);
2985 if (!test_SamLogon(tctx
, p
, test_credentials
,
2986 expected_samlogon_result
, interactive
)) {
2987 torture_warning(tctx
, "new password did not work\n");
2994 static bool test_SetPassword_level(struct dcerpc_pipe
*p
,
2995 struct dcerpc_pipe
*np
,
2996 struct torture_context
*tctx
,
2997 struct policy_handle
*handle
,
2999 uint32_t fields_present
,
3000 uint8_t password_expired
,
3001 bool *matched_expected_error
,
3003 const char *acct_name
,
3005 struct cli_credentials
*machine_creds
,
3006 bool use_queryinfo2
,
3008 NTSTATUS expected_samlogon_result
)
3010 const char *fields
= NULL
;
3012 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3018 fields
= talloc_asprintf(tctx
, "(fields_present: 0x%08x)",
3025 torture_comment(tctx
, "Testing SetUserInfo%s level %d call "
3026 "(password_expired: %d) %s\n",
3027 use_setinfo2
? "2":"", level
, password_expired
,
3028 fields
? fields
: "");
3030 if (!test_SetUserPass_level_ex(p
, tctx
, handle
, level
,
3035 matched_expected_error
)) {
3039 if (!test_QueryUserInfo_pwdlastset(b
, tctx
, handle
,
3045 if (*matched_expected_error
== true) {
3049 if (!test_SamLogon_with_creds(tctx
, np
,
3053 expected_samlogon_result
,
3061 static bool setup_schannel_netlogon_pipe(struct torture_context
*tctx
,
3062 struct cli_credentials
*credentials
,
3063 struct dcerpc_pipe
**p
)
3065 struct dcerpc_binding
*b
;
3067 torture_assert_ntstatus_ok(tctx
, torture_rpc_binding(tctx
, &b
),
3068 "failed to get rpc binding");
3070 /* We have to use schannel, otherwise the SamLogonEx fails
3071 * with INTERNAL_ERROR */
3073 b
->flags
&= ~DCERPC_AUTH_OPTIONS
;
3074 b
->flags
|= DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_128
;
3076 torture_assert_ntstatus_ok(tctx
,
3077 dcerpc_pipe_connect_b(tctx
, p
, b
, &ndr_table_netlogon
,
3078 credentials
, tctx
->ev
, tctx
->lp_ctx
),
3079 "failed to bind to netlogon");
3084 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe
*p
,
3085 struct torture_context
*tctx
,
3086 uint32_t acct_flags
,
3087 const char *acct_name
,
3088 struct policy_handle
*handle
,
3090 struct cli_credentials
*machine_credentials
)
3092 int s
= 0, q
= 0, f
= 0, l
= 0, z
= 0;
3095 bool set_levels
[] = { false, true };
3096 bool query_levels
[] = { false, true };
3097 uint32_t levels
[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
3098 uint32_t nonzeros
[] = { 1, 24 };
3099 uint32_t fields_present
[] = {
3101 SAMR_FIELD_EXPIRED_FLAG
,
3102 SAMR_FIELD_LAST_PWD_CHANGE
,
3103 SAMR_FIELD_EXPIRED_FLAG
| SAMR_FIELD_LAST_PWD_CHANGE
,
3105 SAMR_FIELD_NT_PASSWORD_PRESENT
,
3106 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
,
3107 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
,
3108 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
,
3109 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_EXPIRED_FLAG
,
3110 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_EXPIRED_FLAG
,
3111 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
| SAMR_FIELD_EXPIRED_FLAG
3113 struct dcerpc_pipe
*np
= NULL
;
3115 if (torture_setting_bool(tctx
, "samba3", false) ||
3116 torture_setting_bool(tctx
, "samba4", false)) {
3118 torture_comment(tctx
, "Samba3 has second granularity, setting delay to: %d\n",
3122 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
3124 /* set to 1 to enable testing for all possible opcode
3125 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3128 #define TEST_ALL_LEVELS 1
3129 #define TEST_SET_LEVELS 1
3130 #define TEST_QUERY_LEVELS 1
3132 #ifdef TEST_ALL_LEVELS
3133 for (l
=0; l
<ARRAY_SIZE(levels
); l
++) {
3135 for (l
=0; l
<(ARRAY_SIZE(levels
))/2; l
++) {
3137 for (z
=0; z
<ARRAY_SIZE(nonzeros
); z
++) {
3138 for (f
=0; f
<ARRAY_SIZE(fields_present
); f
++) {
3139 #ifdef TEST_SET_LEVELS
3140 for (s
=0; s
<ARRAY_SIZE(set_levels
); s
++) {
3142 #ifdef TEST_QUERY_LEVELS
3143 for (q
=0; q
<ARRAY_SIZE(query_levels
); q
++) {
3145 NTTIME pwdlastset_old
= 0;
3146 NTTIME pwdlastset_new
= 0;
3147 bool matched_expected_error
= false;
3148 NTSTATUS expected_samlogon_result
= NT_STATUS_ACCOUNT_DISABLED
;
3150 torture_comment(tctx
, "------------------------------\n"
3151 "Testing pwdLastSet attribute for flags: 0x%08x "
3152 "(s: %d (l: %d), q: %d)\n",
3153 acct_flags
, s
, levels
[l
], q
);
3155 switch (levels
[l
]) {
3159 if (!((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3160 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
))) {
3161 expected_samlogon_result
= NT_STATUS_WRONG_PASSWORD
;
3169 /* set a password and force password change (pwdlastset 0) by
3170 * setting the password expired flag to a non-0 value */
3172 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3176 &matched_expected_error
,
3180 machine_credentials
,
3183 expected_samlogon_result
)) {
3187 if (matched_expected_error
== true) {
3188 /* skipping on expected failure */
3192 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3193 * set without the SAMR_FIELD_EXPIRED_FLAG */
3195 switch (levels
[l
]) {
3199 if ((pwdlastset_new
!= 0) &&
3200 !(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
)) {
3201 torture_comment(tctx
, "not considering a non-0 "
3202 "pwdLastSet as a an error as the "
3203 "SAMR_FIELD_EXPIRED_FLAG has not "
3209 if (pwdlastset_new
!= 0) {
3210 torture_warning(tctx
, "pwdLastSet test failed: "
3211 "expected pwdLastSet 0 but got %llu\n",
3212 (unsigned long long) pwdlastset_old
);
3218 switch (levels
[l
]) {
3222 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3223 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3224 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3225 (pwdlastset_old
>= pwdlastset_new
)) {
3226 torture_warning(tctx
, "pwdlastset not increasing\n");
3232 pwdlastset_old
= pwdlastset_new
;
3238 /* set a password, pwdlastset needs to get updated (increased
3239 * value), password_expired value used here is 0 */
3241 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3245 &matched_expected_error
,
3249 machine_credentials
,
3252 expected_samlogon_result
)) {
3256 /* when a password has been changed, pwdlastset must not be 0 afterwards
3257 * and must be larger then the old value */
3259 switch (levels
[l
]) {
3263 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3264 * password has been changed, old and new pwdlastset
3265 * need to be the same value */
3267 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
3268 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3269 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3271 torture_assert_int_equal(tctx
, pwdlastset_old
,
3272 pwdlastset_new
, "pwdlastset must be equal");
3277 if (pwdlastset_old
>= pwdlastset_new
) {
3278 torture_warning(tctx
, "pwdLastSet test failed: "
3279 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3280 (unsigned long long) pwdlastset_old
,
3281 (unsigned long long) pwdlastset_new
);
3284 if (pwdlastset_new
== 0) {
3285 torture_warning(tctx
, "pwdLastSet test failed: "
3286 "expected non-0 pwdlastset, got: %llu\n",
3287 (unsigned long long) pwdlastset_new
);
3293 switch (levels
[l
]) {
3297 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3298 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3299 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3300 (pwdlastset_old
>= pwdlastset_new
)) {
3301 torture_warning(tctx
, "pwdlastset not increasing\n");
3307 pwdlastset_old
= pwdlastset_new
;
3313 /* set a password, pwdlastset needs to get updated (increased
3314 * value), password_expired value used here is 0 */
3316 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3320 &matched_expected_error
,
3324 machine_credentials
,
3327 expected_samlogon_result
)) {
3331 /* when a password has been changed, pwdlastset must not be 0 afterwards
3332 * and must be larger then the old value */
3334 switch (levels
[l
]) {
3339 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3340 * password has been changed, old and new pwdlastset
3341 * need to be the same value */
3343 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
3344 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3345 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3347 torture_assert_int_equal(tctx
, pwdlastset_old
,
3348 pwdlastset_new
, "pwdlastset must be equal");
3353 if (pwdlastset_old
>= pwdlastset_new
) {
3354 torture_warning(tctx
, "pwdLastSet test failed: "
3355 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3356 (unsigned long long) pwdlastset_old
,
3357 (unsigned long long) pwdlastset_new
);
3360 if (pwdlastset_new
== 0) {
3361 torture_warning(tctx
, "pwdLastSet test failed: "
3362 "expected non-0 pwdlastset, got: %llu\n",
3363 (unsigned long long) pwdlastset_new
);
3369 switch (levels
[l
]) {
3373 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3374 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3375 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3376 (pwdlastset_old
>= pwdlastset_new
)) {
3377 torture_warning(tctx
, "pwdlastset not increasing\n");
3383 pwdlastset_old
= pwdlastset_new
;
3389 /* set a password and force password change (pwdlastset 0) by
3390 * setting the password expired flag to a non-0 value */
3392 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3396 &matched_expected_error
,
3400 machine_credentials
,
3403 expected_samlogon_result
)) {
3407 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3408 * set without the SAMR_FIELD_EXPIRED_FLAG */
3410 switch (levels
[l
]) {
3414 if ((pwdlastset_new
!= 0) &&
3415 !(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
)) {
3416 torture_comment(tctx
, "not considering a non-0 "
3417 "pwdLastSet as a an error as the "
3418 "SAMR_FIELD_EXPIRED_FLAG has not "
3423 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3424 * password has been changed, old and new pwdlastset
3425 * need to be the same value */
3427 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
3428 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3429 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3431 torture_assert_int_equal(tctx
, pwdlastset_old
,
3432 pwdlastset_new
, "pwdlastset must be equal");
3437 if (pwdlastset_new
!= 0) {
3438 torture_warning(tctx
, "pwdLastSet test failed: "
3439 "expected pwdLastSet 0, got %llu\n",
3440 (unsigned long long) pwdlastset_old
);
3446 switch (levels
[l
]) {
3450 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3451 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3452 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3453 (pwdlastset_old
>= pwdlastset_new
)) {
3454 torture_warning(tctx
, "pwdlastset not increasing\n");
3460 /* if the level we are testing does not have a fields_present
3461 * field, skip all fields present tests by setting f to to
3463 switch (levels
[l
]) {
3467 f
= ARRAY_SIZE(fields_present
);
3471 #ifdef TEST_QUERY_LEVELS
3474 #ifdef TEST_SET_LEVELS
3477 } /* fields present */
3481 #undef TEST_SET_LEVELS
3482 #undef TEST_QUERY_LEVELS
3489 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_binding_handle
*b
,
3490 struct torture_context
*tctx
,
3491 struct policy_handle
*handle
,
3492 uint32_t *badpwdcount
)
3494 union samr_UserInfo
*info
;
3495 struct samr_QueryUserInfo r
;
3497 r
.in
.user_handle
= handle
;
3501 torture_comment(tctx
, "Testing QueryUserInfo level %d", r
.in
.level
);
3503 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
3504 "failed to query userinfo");
3505 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
3506 "failed to query userinfo");
3508 *badpwdcount
= info
->info3
.bad_password_count
;
3510 torture_comment(tctx
, " (bad password count: %d)\n", *badpwdcount
);
3515 static bool test_SetUserInfo_acct_flags(struct dcerpc_binding_handle
*b
,
3516 struct torture_context
*tctx
,
3517 struct policy_handle
*user_handle
,
3518 uint32_t acct_flags
)
3520 struct samr_SetUserInfo r
;
3521 union samr_UserInfo user_info
;
3523 torture_comment(tctx
, "Testing SetUserInfo level 16\n");
3525 user_info
.info16
.acct_flags
= acct_flags
;
3527 r
.in
.user_handle
= user_handle
;
3529 r
.in
.info
= &user_info
;
3531 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &r
),
3532 "failed to set account flags");
3533 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
3534 "failed to set account flags");
3539 static bool test_reset_badpwdcount(struct dcerpc_pipe
*p
,
3540 struct torture_context
*tctx
,
3541 struct policy_handle
*user_handle
,
3542 uint32_t acct_flags
,
3545 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3547 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
3548 "failed to set password");
3550 torture_comment(tctx
, "Testing SetUserInfo level 16 (enable account)\n");
3552 torture_assert(tctx
,
3553 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
3554 acct_flags
& ~ACB_DISABLED
),
3555 "failed to enable user");
3557 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
3558 "failed to set password");
3563 static bool test_SetDomainInfo(struct dcerpc_binding_handle
*b
,
3564 struct torture_context
*tctx
,
3565 struct policy_handle
*domain_handle
,
3566 enum samr_DomainInfoClass level
,
3567 union samr_DomainInfo
*info
)
3569 struct samr_SetDomainInfo r
;
3571 r
.in
.domain_handle
= domain_handle
;
3575 torture_assert_ntstatus_ok(tctx
,
3576 dcerpc_samr_SetDomainInfo_r(b
, tctx
, &r
),
3577 "failed to set domain info");
3578 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
3579 "failed to set domain info");
3584 static bool test_SetDomainInfo_ntstatus(struct dcerpc_binding_handle
*b
,
3585 struct torture_context
*tctx
,
3586 struct policy_handle
*domain_handle
,
3587 enum samr_DomainInfoClass level
,
3588 union samr_DomainInfo
*info
,
3591 struct samr_SetDomainInfo r
;
3593 r
.in
.domain_handle
= domain_handle
;
3597 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &r
),
3598 "SetDomainInfo failed");
3599 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, expected
, "");
3604 static bool test_QueryDomainInfo2_level(struct dcerpc_binding_handle
*b
,
3605 struct torture_context
*tctx
,
3606 struct policy_handle
*domain_handle
,
3607 enum samr_DomainInfoClass level
,
3608 union samr_DomainInfo
**q_info
)
3610 struct samr_QueryDomainInfo2 r
;
3612 r
.in
.domain_handle
= domain_handle
;
3614 r
.out
.info
= q_info
;
3616 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo2_r(b
, tctx
, &r
),
3617 "failed to query domain info");
3618 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
3619 "failed to query domain info");
3624 static bool test_Password_badpwdcount(struct dcerpc_pipe
*p
,
3625 struct dcerpc_pipe
*np
,
3626 struct torture_context
*tctx
,
3627 uint32_t acct_flags
,
3628 const char *acct_name
,
3629 struct policy_handle
*domain_handle
,
3630 struct policy_handle
*user_handle
,
3632 struct cli_credentials
*machine_credentials
,
3633 const char *comment
,
3636 NTSTATUS expected_success_status
,
3637 struct samr_DomInfo1
*info1
,
3638 struct samr_DomInfo12
*info12
)
3640 union samr_DomainInfo info
;
3643 uint32_t badpwdcount
, tmp
;
3644 uint32_t password_history_length
= 12;
3645 uint32_t lockout_threshold
= 15;
3646 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3648 torture_comment(tctx
, "\nTesting bad pwd count with: %s\n", comment
);
3650 torture_assert(tctx
, password_history_length
< lockout_threshold
,
3651 "password history length needs to be smaller than account lockout threshold for this test");
3656 info
.info1
= *info1
;
3657 info
.info1
.password_history_length
= password_history_length
;
3659 torture_assert(tctx
,
3660 test_SetDomainInfo(b
, tctx
, domain_handle
,
3661 DomainPasswordInformation
, &info
),
3662 "failed to set password history length");
3664 info
.info12
= *info12
;
3665 info
.info12
.lockout_threshold
= lockout_threshold
;
3667 torture_assert(tctx
,
3668 test_SetDomainInfo(b
, tctx
, domain_handle
,
3669 DomainLockoutInformation
, &info
),
3670 "failed to set lockout threshold");
3672 /* reset bad pwd count */
3674 torture_assert(tctx
,
3675 test_reset_badpwdcount(p
, tctx
, user_handle
, acct_flags
, password
), "");
3678 /* enable or disable account */
3680 torture_assert(tctx
,
3681 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
3682 acct_flags
| ACB_DISABLED
),
3683 "failed to disable user");
3685 torture_assert(tctx
,
3686 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
3687 acct_flags
& ~ACB_DISABLED
),
3688 "failed to enable user");
3692 /* setup password history */
3694 passwords
= talloc_array(tctx
, char *, password_history_length
);
3696 for (i
=0; i
< password_history_length
; i
++) {
3698 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
3699 "failed to set password");
3700 passwords
[i
] = talloc_strdup(tctx
, *password
);
3702 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3703 acct_name
, passwords
[i
],
3704 expected_success_status
, interactive
)) {
3705 torture_fail(tctx
, "failed to auth with latest password");
3708 torture_assert(tctx
,
3709 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3711 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3715 /* test with wrong password */
3717 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3718 acct_name
, "random_crap",
3719 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
3720 torture_fail(tctx
, "succeeded to authenticate with wrong password");
3723 torture_assert(tctx
,
3724 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3726 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
3729 /* test with latest good password */
3731 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
3732 passwords
[password_history_length
-1],
3733 expected_success_status
, interactive
)) {
3734 torture_fail(tctx
, "succeeded to authenticate with wrong password");
3737 torture_assert(tctx
,
3738 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3741 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
3743 /* only enabled accounts get the bad pwd count reset upon
3744 * successful logon */
3745 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3751 /* test password history */
3753 for (i
=0; i
< password_history_length
; i
++) {
3755 torture_comment(tctx
, "Testing bad password count behavior with "
3756 "password #%d of #%d\n", i
, password_history_length
);
3758 /* - network samlogon will succeed auth and not
3759 * increase badpwdcount for 2 last entries
3760 * - interactive samlogon only for the last one */
3762 if (i
== password_history_length
- 1 ||
3763 (i
== password_history_length
- 2 && !interactive
)) {
3765 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3766 acct_name
, passwords
[i
],
3767 expected_success_status
, interactive
)) {
3768 torture_fail(tctx
, talloc_asprintf(tctx
, "succeeded to authenticate with old password (#%d of #%d in history)", i
, password_history_length
));
3771 torture_assert(tctx
,
3772 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3775 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
3776 torture_assert_int_equal(tctx
, badpwdcount
, tmp
, "unexpected badpwdcount");
3778 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
3779 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3787 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3788 acct_name
, passwords
[i
],
3789 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
3790 torture_fail(tctx
, talloc_asprintf(tctx
, "succeeded to authenticate with old password (#%d of #%d in history)", i
, password_history_length
));
3793 torture_assert(tctx
,
3794 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3796 /* - network samlogon will fail auth but not increase
3797 * badpwdcount for 3rd last entry
3798 * - interactive samlogon for 3rd and 2nd last entry */
3800 if (i
== password_history_length
- 3 ||
3801 (i
== password_history_length
- 2 && interactive
)) {
3802 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
3803 torture_assert_int_equal(tctx
, badpwdcount
, tmp
, "unexpected badpwdcount");
3805 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
3806 torture_assert_int_equal(tctx
, badpwdcount
, tmp
+ 1, "unexpected badpwdcount");
3815 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe
*p
,
3816 struct torture_context
*tctx
,
3817 uint32_t acct_flags
,
3818 const char *acct_name
,
3819 struct policy_handle
*domain_handle
,
3820 struct policy_handle
*user_handle
,
3822 struct cli_credentials
*machine_credentials
)
3824 union samr_DomainInfo
*q_info
, s_info
;
3825 struct samr_DomInfo1 info1
, _info1
;
3826 struct samr_DomInfo12 info12
, _info12
;
3828 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3829 struct dcerpc_pipe
*np
;
3833 const char *comment
;
3836 NTSTATUS expected_success_status
;
3839 .comment
= "network logon (disabled account)",
3841 .interactive
= false,
3842 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
3845 .comment
= "network logon (enabled account)",
3847 .interactive
= false,
3848 .expected_success_status
= NT_STATUS_OK
3851 .comment
= "interactive logon (disabled account)",
3853 .interactive
= true,
3854 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
3857 .comment
= "interactive logon (enabled account)",
3859 .interactive
= true,
3860 .expected_success_status
= NT_STATUS_OK
3864 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
3866 /* backup old policies */
3868 torture_assert(tctx
,
3869 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
3870 DomainPasswordInformation
, &q_info
),
3871 "failed to query domain info level 1");
3873 info1
= q_info
->info1
;
3876 torture_assert(tctx
,
3877 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
3878 DomainLockoutInformation
, &q_info
),
3879 "failed to query domain info level 12");
3881 info12
= q_info
->info12
;
3886 for (i
=0; i
< ARRAY_SIZE(creds
); i
++) {
3888 /* skip trust tests for now */
3889 if (acct_flags
& ACB_WSTRUST
||
3890 acct_flags
& ACB_SVRTRUST
||
3891 acct_flags
& ACB_DOMTRUST
) {
3895 ret
&= test_Password_badpwdcount(p
, np
, tctx
, acct_flags
, acct_name
,
3896 domain_handle
, user_handle
, password
,
3897 machine_credentials
,
3900 creds
[i
].interactive
,
3901 creds
[i
].expected_success_status
,
3904 torture_warning(tctx
, "TEST #%d (%s) failed\n", i
, creds
[i
].comment
);
3906 torture_comment(tctx
, "TEST #%d (%s) succeeded\n", i
, creds
[i
].comment
);
3910 /* restore policies */
3912 s_info
.info1
= info1
;
3914 torture_assert(tctx
,
3915 test_SetDomainInfo(b
, tctx
, domain_handle
,
3916 DomainPasswordInformation
, &s_info
),
3917 "failed to set password information");
3919 s_info
.info12
= info12
;
3921 torture_assert(tctx
,
3922 test_SetDomainInfo(b
, tctx
, domain_handle
,
3923 DomainLockoutInformation
, &s_info
),
3924 "failed to set lockout information");
3929 static bool test_QueryUserInfo_acct_flags(struct dcerpc_binding_handle
*b
,
3930 struct torture_context
*tctx
,
3931 struct policy_handle
*handle
,
3932 uint32_t *acct_flags
)
3934 union samr_UserInfo
*info
;
3935 struct samr_QueryUserInfo r
;
3937 r
.in
.user_handle
= handle
;
3941 torture_comment(tctx
, "Testing QueryUserInfo level %d", r
.in
.level
);
3943 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
3944 "failed to query userinfo");
3945 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
3946 "failed to query userinfo");
3948 *acct_flags
= info
->info16
.acct_flags
;
3950 torture_comment(tctx
, " (acct_flags: 0x%08x)\n", *acct_flags
);
3955 static bool test_Password_lockout(struct dcerpc_pipe
*p
,
3956 struct dcerpc_pipe
*np
,
3957 struct torture_context
*tctx
,
3958 uint32_t acct_flags
,
3959 const char *acct_name
,
3960 struct policy_handle
*domain_handle
,
3961 struct policy_handle
*user_handle
,
3963 struct cli_credentials
*machine_credentials
,
3964 const char *comment
,
3967 NTSTATUS expected_success_status
,
3968 struct samr_DomInfo1
*info1
,
3969 struct samr_DomInfo12
*info12
)
3971 union samr_DomainInfo info
;
3972 uint32_t badpwdcount
;
3973 uint32_t password_history_length
= 1;
3974 uint64_t lockout_threshold
= 1;
3975 uint32_t lockout_seconds
= 5;
3976 uint64_t delta_time_factor
= 10 * 1000 * 1000;
3977 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3979 torture_comment(tctx
, "\nTesting account lockout: %s\n", comment
);
3983 info
.info1
= *info1
;
3985 torture_comment(tctx
, "setting password history length.\n");
3986 info
.info1
.password_history_length
= password_history_length
;
3988 torture_assert(tctx
,
3989 test_SetDomainInfo(b
, tctx
, domain_handle
,
3990 DomainPasswordInformation
, &info
),
3991 "failed to set password history length");
3993 info
.info12
= *info12
;
3994 info
.info12
.lockout_threshold
= lockout_threshold
;
3996 /* set lockout duration < lockout window: should fail */
3997 info
.info12
.lockout_duration
= ~(lockout_seconds
* delta_time_factor
);
3998 info
.info12
.lockout_window
= ~((lockout_seconds
+ 1) * delta_time_factor
);
4000 torture_assert(tctx
,
4001 test_SetDomainInfo_ntstatus(b
, tctx
, domain_handle
,
4002 DomainLockoutInformation
, &info
,
4003 NT_STATUS_INVALID_PARAMETER
),
4004 "setting lockout duration < lockout window gave unexpected result");
4006 info
.info12
.lockout_duration
= 0;
4007 info
.info12
.lockout_window
= 0;
4009 torture_assert(tctx
,
4010 test_SetDomainInfo(b
, tctx
, domain_handle
,
4011 DomainLockoutInformation
, &info
),
4012 "failed to set lockout window and duration to 0");
4015 /* set lockout duration of 5 seconds */
4016 info
.info12
.lockout_duration
= ~(lockout_seconds
* delta_time_factor
);
4017 info
.info12
.lockout_window
= ~(lockout_seconds
* delta_time_factor
);
4019 torture_assert(tctx
,
4020 test_SetDomainInfo(b
, tctx
, domain_handle
,
4021 DomainLockoutInformation
, &info
),
4022 "failed to set lockout window and duration to 5 seconds");
4024 /* reset bad pwd count */
4026 torture_assert(tctx
,
4027 test_reset_badpwdcount(p
, tctx
, user_handle
, acct_flags
, password
), "");
4030 /* enable or disable account */
4033 torture_assert(tctx
,
4034 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
4035 acct_flags
| ACB_DISABLED
),
4036 "failed to disable user");
4038 torture_assert(tctx
,
4039 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
4040 acct_flags
& ~ACB_DISABLED
),
4041 "failed to enable user");
4045 /* test logon with right password */
4047 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
4048 acct_name
, *password
,
4049 expected_success_status
, interactive
)) {
4050 torture_fail(tctx
, "failed to auth with latest password");
4053 torture_assert(tctx
,
4054 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4055 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
4058 /* test with wrong password ==> lockout */
4060 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
4061 acct_name
, "random_crap",
4062 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
4063 torture_fail(tctx
, "succeeded to authenticate with wrong password");
4066 torture_assert(tctx
,
4067 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4068 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
4070 torture_assert(tctx
,
4071 test_QueryUserInfo_acct_flags(b
, tctx
, user_handle
, &acct_flags
), "");
4072 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
4073 "expected account to be locked");
4076 /* test with good password */
4078 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
4080 NT_STATUS_ACCOUNT_LOCKED_OUT
, interactive
))
4082 torture_fail(tctx
, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4085 /* bad pwd count should not get updated */
4086 torture_assert(tctx
,
4087 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4088 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
4090 /* curiously, windows does _not_ set the autlock flag */
4091 torture_assert(tctx
,
4092 test_QueryUserInfo_acct_flags(b
, tctx
, user_handle
, &acct_flags
), "");
4093 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
4094 "expected account to be locked");
4097 /* with bad password */
4099 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
4100 acct_name
, "random_crap2",
4101 NT_STATUS_ACCOUNT_LOCKED_OUT
, interactive
))
4103 torture_fail(tctx
, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4106 /* bad pwd count should not get updated */
4107 torture_assert(tctx
,
4108 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4109 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
4111 /* curiously, windows does _not_ set the autlock flag */
4112 torture_assert(tctx
,
4113 test_QueryUserInfo_acct_flags(b
, tctx
, user_handle
, &acct_flags
), "");
4114 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
4115 "expected account to be locked");
4118 /* let lockout duration expire ==> unlock */
4120 torture_comment(tctx
, "let lockout duration expire...\n");
4121 sleep(lockout_seconds
+ 1);
4123 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
4125 expected_success_status
, interactive
))
4127 torture_fail(tctx
, "failed to authenticate after lockout expired");
4130 torture_assert(tctx
,
4131 test_QueryUserInfo_acct_flags(b
, tctx
, user_handle
, &acct_flags
), "");
4132 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
4133 "expected account not to be locked");
4138 static bool test_Password_lockout_wrap(struct dcerpc_pipe
*p
,
4139 struct torture_context
*tctx
,
4140 uint32_t acct_flags
,
4141 const char *acct_name
,
4142 struct policy_handle
*domain_handle
,
4143 struct policy_handle
*user_handle
,
4145 struct cli_credentials
*machine_credentials
)
4147 union samr_DomainInfo
*q_info
, s_info
;
4148 struct samr_DomInfo1 info1
, _info1
;
4149 struct samr_DomInfo12 info12
, _info12
;
4151 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4152 struct dcerpc_pipe
*np
;
4156 const char *comment
;
4159 NTSTATUS expected_success_status
;
4162 .comment
= "network logon (disabled account)",
4164 .interactive
= false,
4165 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
4168 .comment
= "network logon (enabled account)",
4170 .interactive
= false,
4171 .expected_success_status
= NT_STATUS_OK
4174 .comment
= "interactive logon (disabled account)",
4176 .interactive
= true,
4177 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
4180 .comment
= "interactive logon (enabled account)",
4182 .interactive
= true,
4183 .expected_success_status
= NT_STATUS_OK
4187 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
4189 /* backup old policies */
4191 torture_assert(tctx
,
4192 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
4193 DomainPasswordInformation
, &q_info
),
4194 "failed to query domain info level 1");
4196 info1
= q_info
->info1
;
4199 torture_assert(tctx
,
4200 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
4201 DomainLockoutInformation
, &q_info
),
4202 "failed to query domain info level 12");
4204 info12
= q_info
->info12
;
4209 for (i
=0; i
< ARRAY_SIZE(creds
); i
++) {
4211 /* skip trust tests for now */
4212 if (acct_flags
& ACB_WSTRUST
||
4213 acct_flags
& ACB_SVRTRUST
||
4214 acct_flags
& ACB_DOMTRUST
) {
4218 ret
&= test_Password_lockout(p
, np
, tctx
, acct_flags
, acct_name
,
4219 domain_handle
, user_handle
, password
,
4220 machine_credentials
,
4223 creds
[i
].interactive
,
4224 creds
[i
].expected_success_status
,
4227 torture_warning(tctx
, "TEST #%d (%s) failed\n", i
, creds
[i
].comment
);
4229 torture_comment(tctx
, "TEST #%d (%s) succeeded\n", i
, creds
[i
].comment
);
4233 /* restore policies */
4235 s_info
.info1
= info1
;
4237 torture_assert(tctx
,
4238 test_SetDomainInfo(b
, tctx
, domain_handle
,
4239 DomainPasswordInformation
, &s_info
),
4240 "failed to set password information");
4242 s_info
.info12
= info12
;
4244 torture_assert(tctx
,
4245 test_SetDomainInfo(b
, tctx
, domain_handle
,
4246 DomainLockoutInformation
, &s_info
),
4247 "failed to set lockout information");
4252 static bool test_DeleteUser_with_privs(struct dcerpc_pipe
*p
,
4253 struct dcerpc_pipe
*lp
,
4254 struct torture_context
*tctx
,
4255 struct policy_handle
*domain_handle
,
4256 struct policy_handle
*lsa_handle
,
4257 struct policy_handle
*user_handle
,
4258 const struct dom_sid
*domain_sid
,
4260 struct cli_credentials
*machine_credentials
)
4263 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4264 struct dcerpc_binding_handle
*lb
= lp
->binding_handle
;
4266 struct policy_handle lsa_acct_handle
;
4267 struct dom_sid
*user_sid
;
4269 user_sid
= dom_sid_add_rid(tctx
, domain_sid
, rid
);
4272 struct lsa_EnumAccountRights r
;
4273 struct lsa_RightSet rights
;
4275 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4277 r
.in
.handle
= lsa_handle
;
4278 r
.in
.sid
= user_sid
;
4279 r
.out
.rights
= &rights
;
4281 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
),
4282 "lsa_EnumAccountRights failed");
4283 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
4284 "Expected enum rights for account to fail");
4288 struct lsa_RightSet rights
;
4289 struct lsa_StringLarge names
[2];
4290 struct lsa_AddAccountRights r
;
4292 torture_comment(tctx
, "Testing LSA AddAccountRights\n");
4294 init_lsa_StringLarge(&names
[0], "SeMachineAccountPrivilege");
4295 init_lsa_StringLarge(&names
[1], NULL
);
4298 rights
.names
= names
;
4300 r
.in
.handle
= lsa_handle
;
4301 r
.in
.sid
= user_sid
;
4302 r
.in
.rights
= &rights
;
4304 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_AddAccountRights_r(lb
, tctx
, &r
),
4305 "lsa_AddAccountRights failed");
4306 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4307 "Failed to add privileges");
4311 struct lsa_EnumAccounts r
;
4312 uint32_t resume_handle
= 0;
4313 struct lsa_SidArray lsa_sid_array
;
4315 bool found_sid
= false;
4317 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
4319 r
.in
.handle
= lsa_handle
;
4320 r
.in
.num_entries
= 0x1000;
4321 r
.in
.resume_handle
= &resume_handle
;
4322 r
.out
.sids
= &lsa_sid_array
;
4323 r
.out
.resume_handle
= &resume_handle
;
4325 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccounts_r(lb
, tctx
, &r
),
4326 "lsa_EnumAccounts failed");
4327 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4328 "Failed to enum accounts");
4330 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
4331 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
4336 torture_assert(tctx
, found_sid
,
4337 "failed to list privileged account");
4341 struct lsa_EnumAccountRights r
;
4342 struct lsa_RightSet user_rights
;
4344 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4346 r
.in
.handle
= lsa_handle
;
4347 r
.in
.sid
= user_sid
;
4348 r
.out
.rights
= &user_rights
;
4350 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
),
4351 "lsa_EnumAccountRights failed");
4352 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4353 "Failed to enum rights for account");
4355 if (user_rights
.count
< 1) {
4356 torture_warning(tctx
, "failed to find newly added rights");
4362 struct lsa_OpenAccount r
;
4364 torture_comment(tctx
, "Testing LSA OpenAccount\n");
4366 r
.in
.handle
= lsa_handle
;
4367 r
.in
.sid
= user_sid
;
4368 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4369 r
.out
.acct_handle
= &lsa_acct_handle
;
4371 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenAccount_r(lb
, tctx
, &r
),
4372 "lsa_OpenAccount failed");
4373 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4374 "Failed to open lsa account");
4378 struct lsa_GetSystemAccessAccount r
;
4379 uint32_t access_mask
;
4381 torture_comment(tctx
, "Testing LSA GetSystemAccessAccount\n");
4383 r
.in
.handle
= &lsa_acct_handle
;
4384 r
.out
.access_mask
= &access_mask
;
4386 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_GetSystemAccessAccount_r(lb
, tctx
, &r
),
4387 "lsa_GetSystemAccessAccount failed");
4388 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4389 "Failed to get lsa system access account");
4395 torture_comment(tctx
, "Testing LSA Close\n");
4397 r
.in
.handle
= &lsa_acct_handle
;
4398 r
.out
.handle
= &lsa_acct_handle
;
4400 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_Close_r(lb
, tctx
, &r
),
4401 "lsa_Close failed");
4402 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4403 "Failed to close lsa");
4407 struct samr_DeleteUser r
;
4409 torture_comment(tctx
, "Testing SAMR DeleteUser\n");
4411 r
.in
.user_handle
= user_handle
;
4412 r
.out
.user_handle
= user_handle
;
4414 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, tctx
, &r
),
4415 "DeleteUser failed");
4416 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4417 "DeleteUser failed");
4421 struct lsa_EnumAccounts r
;
4422 uint32_t resume_handle
= 0;
4423 struct lsa_SidArray lsa_sid_array
;
4425 bool found_sid
= false;
4427 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
4429 r
.in
.handle
= lsa_handle
;
4430 r
.in
.num_entries
= 0x1000;
4431 r
.in
.resume_handle
= &resume_handle
;
4432 r
.out
.sids
= &lsa_sid_array
;
4433 r
.out
.resume_handle
= &resume_handle
;
4435 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccounts_r(lb
, tctx
, &r
),
4436 "lsa_EnumAccounts failed");
4437 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4438 "Failed to enum accounts");
4440 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
4441 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
4446 torture_assert(tctx
, found_sid
,
4447 "failed to list privileged account");
4451 struct lsa_EnumAccountRights r
;
4452 struct lsa_RightSet user_rights
;
4454 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4456 r
.in
.handle
= lsa_handle
;
4457 r
.in
.sid
= user_sid
;
4458 r
.out
.rights
= &user_rights
;
4460 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
),
4461 "lsa_EnumAccountRights failed");
4462 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4463 "Failed to enum rights for account");
4465 if (user_rights
.count
< 1) {
4466 torture_warning(tctx
, "failed to find newly added rights");
4472 struct lsa_OpenAccount r
;
4474 torture_comment(tctx
, "Testing LSA OpenAccount\n");
4476 r
.in
.handle
= lsa_handle
;
4477 r
.in
.sid
= user_sid
;
4478 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4479 r
.out
.acct_handle
= &lsa_acct_handle
;
4481 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenAccount_r(lb
, tctx
, &r
),
4482 "lsa_OpenAccount failed");
4483 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4484 "Failed to open lsa account");
4488 struct lsa_GetSystemAccessAccount r
;
4489 uint32_t access_mask
;
4491 torture_comment(tctx
, "Testing LSA GetSystemAccessAccount\n");
4493 r
.in
.handle
= &lsa_acct_handle
;
4494 r
.out
.access_mask
= &access_mask
;
4496 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_GetSystemAccessAccount_r(lb
, tctx
, &r
),
4497 "lsa_GetSystemAccessAccount failed");
4498 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4499 "Failed to get lsa system access account");
4503 struct lsa_DeleteObject r
;
4505 torture_comment(tctx
, "Testing LSA DeleteObject\n");
4507 r
.in
.handle
= &lsa_acct_handle
;
4508 r
.out
.handle
= &lsa_acct_handle
;
4510 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_DeleteObject_r(lb
, tctx
, &r
),
4511 "lsa_DeleteObject failed");
4512 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4513 "Failed to delete object");
4517 struct lsa_EnumAccounts r
;
4518 uint32_t resume_handle
= 0;
4519 struct lsa_SidArray lsa_sid_array
;
4521 bool found_sid
= false;
4523 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
4525 r
.in
.handle
= lsa_handle
;
4526 r
.in
.num_entries
= 0x1000;
4527 r
.in
.resume_handle
= &resume_handle
;
4528 r
.out
.sids
= &lsa_sid_array
;
4529 r
.out
.resume_handle
= &resume_handle
;
4531 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccounts_r(lb
, tctx
, &r
),
4532 "lsa_EnumAccounts failed");
4533 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4534 "Failed to enum accounts");
4536 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
4537 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
4542 torture_assert(tctx
, !found_sid
,
4543 "should not have listed privileged account");
4547 struct lsa_EnumAccountRights r
;
4548 struct lsa_RightSet user_rights
;
4550 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4552 r
.in
.handle
= lsa_handle
;
4553 r
.in
.sid
= user_sid
;
4554 r
.out
.rights
= &user_rights
;
4556 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
),
4557 "lsa_EnumAccountRights failed");
4558 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
4559 "Failed to enum rights for account");
4565 static bool test_user_ops(struct dcerpc_pipe
*p
,
4566 struct torture_context
*tctx
,
4567 struct policy_handle
*user_handle
,
4568 struct policy_handle
*domain_handle
,
4569 const struct dom_sid
*domain_sid
,
4570 uint32_t base_acct_flags
,
4571 const char *base_acct_name
, enum torture_samr_choice which_ops
,
4572 struct cli_credentials
*machine_credentials
)
4574 char *password
= NULL
;
4575 struct samr_QueryUserInfo q
;
4576 union samr_UserInfo
*info
;
4578 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4583 const uint32_t password_fields
[] = {
4584 SAMR_FIELD_NT_PASSWORD_PRESENT
,
4585 SAMR_FIELD_LM_PASSWORD_PRESENT
,
4586 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
,
4590 status
= test_LookupName(b
, tctx
, domain_handle
, base_acct_name
, &rid
);
4591 if (!NT_STATUS_IS_OK(status
)) {
4595 switch (which_ops
) {
4596 case TORTURE_SAMR_USER_ATTRIBUTES
:
4597 if (!test_QuerySecurity(b
, tctx
, user_handle
)) {
4601 if (!test_QueryUserInfo(b
, tctx
, user_handle
)) {
4605 if (!test_QueryUserInfo2(b
, tctx
, user_handle
)) {
4609 if (!test_SetUserInfo(b
, tctx
, user_handle
, base_acct_flags
,
4614 if (!test_GetUserPwInfo(b
, tctx
, user_handle
)) {
4618 if (!test_TestPrivateFunctionsUser(b
, tctx
, user_handle
)) {
4622 if (!test_SetUserPass(p
, tctx
, user_handle
, &password
)) {
4626 case TORTURE_SAMR_PASSWORDS
:
4627 if (base_acct_flags
& (ACB_WSTRUST
|ACB_DOMTRUST
|ACB_SVRTRUST
)) {
4628 char simple_pass
[9];
4629 char *v
= generate_random_str(tctx
, 1);
4631 ZERO_STRUCT(simple_pass
);
4632 memset(simple_pass
, *v
, sizeof(simple_pass
) - 1);
4634 torture_comment(tctx
, "Testing machine account password policy rules\n");
4636 /* Workstation trust accounts don't seem to need to honour password quality policy */
4637 if (!test_SetUserPassEx(p
, tctx
, user_handle
, true, &password
)) {
4641 if (!test_ChangePasswordUser2(p
, tctx
, base_acct_name
, &password
, simple_pass
, false)) {
4645 /* reset again, to allow another 'user' password change */
4646 if (!test_SetUserPassEx(p
, tctx
, user_handle
, true, &password
)) {
4650 /* Try a 'short' password */
4651 if (!test_ChangePasswordUser2(p
, tctx
, base_acct_name
, &password
, samr_rand_pass(tctx
, 4), false)) {
4655 /* Try a compleatly random password */
4656 if (!test_ChangePasswordRandomBytes(p
, tctx
, base_acct_name
, user_handle
, &password
)) {
4661 for (i
= 0; password_fields
[i
]; i
++) {
4662 if (!test_SetUserPass_23(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
4666 /* check it was set right */
4667 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4672 for (i
= 0; password_fields
[i
]; i
++) {
4673 if (!test_SetUserPass_25(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
4677 /* check it was set right */
4678 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4683 if (!test_SetUserPassEx(p
, tctx
, user_handle
, false, &password
)) {
4687 if (!test_ChangePassword(p
, tctx
, base_acct_name
, domain_handle
, &password
)) {
4691 if (!test_SetUserPass_18(p
, tctx
, user_handle
, &password
)) {
4695 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4699 for (i
= 0; password_fields
[i
]; i
++) {
4701 if (password_fields
[i
] == SAMR_FIELD_LM_PASSWORD_PRESENT
) {
4702 /* we need to skip as that would break
4703 * the ChangePasswordUser3 verify */
4707 if (!test_SetUserPass_21(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
4711 /* check it was set right */
4712 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4717 q
.in
.user_handle
= user_handle
;
4721 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
),
4722 "QueryUserInfo failed");
4723 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
4724 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
4725 q
.in
.level
, nt_errstr(q
.out
.result
));
4728 uint32_t expected_flags
= (base_acct_flags
| ACB_PWNOTREQ
| ACB_DISABLED
);
4729 if ((info
->info5
.acct_flags
) != expected_flags
) {
4730 torture_warning(tctx
, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4731 info
->info5
.acct_flags
,
4734 if (!torture_setting_bool(tctx
, "samba3", false)) {
4738 if (info
->info5
.rid
!= rid
) {
4739 torture_warning(tctx
, "QueryUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
4740 info
->info5
.rid
, rid
);
4747 case TORTURE_SAMR_PASSWORDS_PWDLASTSET
:
4749 /* test last password change timestamp behaviour */
4750 if (!test_SetPassword_pwdlastset(p
, tctx
, base_acct_flags
,
4752 user_handle
, &password
,
4753 machine_credentials
)) {
4758 torture_comment(tctx
, "pwdLastSet test succeeded\n");
4760 torture_warning(tctx
, "pwdLastSet test failed\n");
4765 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
:
4767 /* test bad pwd count change behaviour */
4768 if (!test_Password_badpwdcount_wrap(p
, tctx
, base_acct_flags
,
4771 user_handle
, &password
,
4772 machine_credentials
)) {
4777 torture_comment(tctx
, "badPwdCount test succeeded\n");
4779 torture_warning(tctx
, "badPwdCount test failed\n");
4784 case TORTURE_SAMR_PASSWORDS_LOCKOUT
:
4786 if (!test_Password_lockout_wrap(p
, tctx
, base_acct_flags
,
4789 user_handle
, &password
,
4790 machine_credentials
))
4796 torture_comment(tctx
, "lockout test succeeded\n");
4798 torture_warning(tctx
, "lockout test failed\n");
4804 case TORTURE_SAMR_USER_PRIVILEGES
: {
4806 struct dcerpc_pipe
*lp
;
4807 struct policy_handle
*lsa_handle
;
4808 struct dcerpc_binding_handle
*lb
;
4810 status
= torture_rpc_connection(tctx
, &lp
, &ndr_table_lsarpc
);
4811 torture_assert_ntstatus_ok(tctx
, status
, "Failed to open LSA pipe");
4812 lb
= lp
->binding_handle
;
4814 if (!test_lsa_OpenPolicy2(lb
, tctx
, &lsa_handle
)) {
4818 if (!test_DeleteUser_with_privs(p
, lp
, tctx
,
4819 domain_handle
, lsa_handle
, user_handle
,
4821 machine_credentials
)) {
4825 if (!test_lsa_Close(lb
, tctx
, lsa_handle
)) {
4830 torture_warning(tctx
, "privileged user delete test failed\n");
4835 case TORTURE_SAMR_OTHER
:
4836 case TORTURE_SAMR_MANY_ACCOUNTS
:
4837 case TORTURE_SAMR_MANY_GROUPS
:
4838 case TORTURE_SAMR_MANY_ALIASES
:
4839 /* We just need the account to exist */
4845 static bool test_alias_ops(struct dcerpc_binding_handle
*b
,
4846 struct torture_context
*tctx
,
4847 struct policy_handle
*alias_handle
,
4848 const struct dom_sid
*domain_sid
)
4852 if (!torture_setting_bool(tctx
, "samba3", false)) {
4853 if (!test_QuerySecurity(b
, tctx
, alias_handle
)) {
4858 if (!test_QueryAliasInfo(b
, tctx
, alias_handle
)) {
4862 if (!test_SetAliasInfo(b
, tctx
, alias_handle
)) {
4866 if (!test_AddMemberToAlias(b
, tctx
, alias_handle
, domain_sid
)) {
4870 if (torture_setting_bool(tctx
, "samba3", false) ||
4871 torture_setting_bool(tctx
, "samba4", false)) {
4872 torture_comment(tctx
, "skipping MultipleMembers Alias tests against Samba\n");
4876 if (!test_AddMultipleMembersToAlias(b
, tctx
, alias_handle
)) {
4884 static bool test_DeleteUser(struct dcerpc_binding_handle
*b
,
4885 struct torture_context
*tctx
,
4886 struct policy_handle
*user_handle
)
4888 struct samr_DeleteUser d
;
4889 torture_comment(tctx
, "Testing DeleteUser\n");
4891 d
.in
.user_handle
= user_handle
;
4892 d
.out
.user_handle
= user_handle
;
4894 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, tctx
, &d
),
4895 "DeleteUser failed");
4896 torture_assert_ntstatus_ok(tctx
, d
.out
.result
, "DeleteUser");
4901 bool test_DeleteUser_byname(struct dcerpc_binding_handle
*b
,
4902 struct torture_context
*tctx
,
4903 struct policy_handle
*handle
, const char *name
)
4906 struct samr_DeleteUser d
;
4907 struct policy_handle user_handle
;
4910 status
= test_LookupName(b
, tctx
, handle
, name
, &rid
);
4911 if (!NT_STATUS_IS_OK(status
)) {
4915 status
= test_OpenUser_byname(b
, tctx
, handle
, name
, &user_handle
);
4916 if (!NT_STATUS_IS_OK(status
)) {
4920 d
.in
.user_handle
= &user_handle
;
4921 d
.out
.user_handle
= &user_handle
;
4922 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, tctx
, &d
),
4923 "DeleteUser failed");
4924 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
4925 status
= d
.out
.result
;
4932 torture_warning(tctx
, "DeleteUser_byname(%s) failed - %s\n", name
, nt_errstr(status
));
4937 static bool test_DeleteGroup_byname(struct dcerpc_binding_handle
*b
,
4938 struct torture_context
*tctx
,
4939 struct policy_handle
*handle
, const char *name
)
4942 struct samr_OpenGroup r
;
4943 struct samr_DeleteDomainGroup d
;
4944 struct policy_handle group_handle
;
4947 status
= test_LookupName(b
, tctx
, handle
, name
, &rid
);
4948 if (!NT_STATUS_IS_OK(status
)) {
4952 r
.in
.domain_handle
= handle
;
4953 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4955 r
.out
.group_handle
= &group_handle
;
4956 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenGroup_r(b
, tctx
, &r
),
4957 "OpenGroup failed");
4958 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
4959 status
= r
.out
.result
;
4963 d
.in
.group_handle
= &group_handle
;
4964 d
.out
.group_handle
= &group_handle
;
4965 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteDomainGroup_r(b
, tctx
, &d
),
4966 "DeleteDomainGroup failed");
4967 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
4968 status
= d
.out
.result
;
4975 torture_warning(tctx
, "DeleteGroup_byname(%s) failed - %s\n", name
, nt_errstr(status
));
4980 static bool test_DeleteAlias_byname(struct dcerpc_binding_handle
*b
,
4981 struct torture_context
*tctx
,
4982 struct policy_handle
*domain_handle
,
4986 struct samr_OpenAlias r
;
4987 struct samr_DeleteDomAlias d
;
4988 struct policy_handle alias_handle
;
4991 torture_comment(tctx
, "Testing DeleteAlias_byname\n");
4993 status
= test_LookupName(b
, tctx
, domain_handle
, name
, &rid
);
4994 if (!NT_STATUS_IS_OK(status
)) {
4998 r
.in
.domain_handle
= domain_handle
;
4999 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5001 r
.out
.alias_handle
= &alias_handle
;
5002 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenAlias_r(b
, tctx
, &r
),
5003 "OpenAlias failed");
5004 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5005 status
= r
.out
.result
;
5009 d
.in
.alias_handle
= &alias_handle
;
5010 d
.out
.alias_handle
= &alias_handle
;
5011 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteDomAlias_r(b
, tctx
, &d
),
5012 "DeleteDomAlias failed");
5013 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
5014 status
= d
.out
.result
;
5021 torture_warning(tctx
, "DeleteAlias_byname(%s) failed - %s\n", name
, nt_errstr(status
));
5025 static bool test_DeleteAlias(struct dcerpc_binding_handle
*b
,
5026 struct torture_context
*tctx
,
5027 struct policy_handle
*alias_handle
)
5029 struct samr_DeleteDomAlias d
;
5032 torture_comment(tctx
, "Testing DeleteAlias\n");
5034 d
.in
.alias_handle
= alias_handle
;
5035 d
.out
.alias_handle
= alias_handle
;
5037 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteDomAlias_r(b
, tctx
, &d
),
5038 "DeleteDomAlias failed");
5039 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
5040 torture_warning(tctx
, "DeleteAlias failed - %s\n", nt_errstr(d
.out
.result
));
5047 static bool test_CreateAlias(struct dcerpc_binding_handle
*b
,
5048 struct torture_context
*tctx
,
5049 struct policy_handle
*domain_handle
,
5050 const char *alias_name
,
5051 struct policy_handle
*alias_handle
,
5052 const struct dom_sid
*domain_sid
,
5055 struct samr_CreateDomAlias r
;
5056 struct lsa_String name
;
5060 init_lsa_String(&name
, alias_name
);
5061 r
.in
.domain_handle
= domain_handle
;
5062 r
.in
.alias_name
= &name
;
5063 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5064 r
.out
.alias_handle
= alias_handle
;
5067 torture_comment(tctx
, "Testing CreateAlias (%s)\n", r
.in
.alias_name
->string
);
5069 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomAlias_r(b
, tctx
, &r
),
5070 "CreateDomAlias failed");
5072 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
5073 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
)) {
5074 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.alias_name
->string
);
5077 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.alias_name
->string
,
5078 nt_errstr(r
.out
.result
));
5083 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ALIAS_EXISTS
)) {
5084 if (!test_DeleteAlias_byname(b
, tctx
, domain_handle
, r
.in
.alias_name
->string
)) {
5087 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomAlias_r(b
, tctx
, &r
),
5088 "CreateDomAlias failed");
5091 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5092 torture_warning(tctx
, "CreateAlias failed - %s\n", nt_errstr(r
.out
.result
));
5100 if (!test_alias_ops(b
, tctx
, alias_handle
, domain_sid
)) {
5107 static bool test_ChangePassword(struct dcerpc_pipe
*p
,
5108 struct torture_context
*tctx
,
5109 const char *acct_name
,
5110 struct policy_handle
*domain_handle
, char **password
)
5113 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5119 if (!test_ChangePasswordUser(b
, tctx
, acct_name
, domain_handle
, password
)) {
5123 if (!test_ChangePasswordUser2(p
, tctx
, acct_name
, password
, 0, true)) {
5127 if (!test_OemChangePasswordUser2(p
, tctx
, acct_name
, domain_handle
, password
)) {
5131 /* test what happens when setting the old password again */
5132 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, *password
, 0, true)) {
5137 char simple_pass
[9];
5138 char *v
= generate_random_str(tctx
, 1);
5140 ZERO_STRUCT(simple_pass
);
5141 memset(simple_pass
, *v
, sizeof(simple_pass
) - 1);
5143 /* test what happens when picking a simple password */
5144 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, simple_pass
, 0, true)) {
5149 /* set samr_SetDomainInfo level 1 with min_length 5 */
5151 struct samr_QueryDomainInfo r
;
5152 union samr_DomainInfo
*info
= NULL
;
5153 struct samr_SetDomainInfo s
;
5154 uint16_t len_old
, len
;
5155 uint32_t pwd_prop_old
;
5156 int64_t min_pwd_age_old
;
5160 r
.in
.domain_handle
= domain_handle
;
5164 torture_comment(tctx
, "Testing samr_QueryDomainInfo level 1\n");
5165 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &r
),
5166 "QueryDomainInfo failed");
5167 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5171 s
.in
.domain_handle
= domain_handle
;
5175 /* remember the old min length, so we can reset it */
5176 len_old
= s
.in
.info
->info1
.min_password_length
;
5177 s
.in
.info
->info1
.min_password_length
= len
;
5178 pwd_prop_old
= s
.in
.info
->info1
.password_properties
;
5179 /* turn off password complexity checks for this test */
5180 s
.in
.info
->info1
.password_properties
&= ~DOMAIN_PASSWORD_COMPLEX
;
5182 min_pwd_age_old
= s
.in
.info
->info1
.min_password_age
;
5183 s
.in
.info
->info1
.min_password_age
= 0;
5185 torture_comment(tctx
, "Testing samr_SetDomainInfo level 1\n");
5186 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
),
5187 "SetDomainInfo failed");
5188 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
5192 torture_comment(tctx
, "calling test_ChangePasswordUser3 with too short password\n");
5194 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, len
- 1, password
, NULL
, 0, true)) {
5198 s
.in
.info
->info1
.min_password_length
= len_old
;
5199 s
.in
.info
->info1
.password_properties
= pwd_prop_old
;
5200 s
.in
.info
->info1
.min_password_age
= min_pwd_age_old
;
5202 torture_comment(tctx
, "Testing samr_SetDomainInfo level 1\n");
5203 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
),
5204 "SetDomainInfo failed");
5205 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
5212 struct samr_OpenUser r
;
5213 struct samr_QueryUserInfo q
;
5214 union samr_UserInfo
*info
;
5215 struct samr_LookupNames n
;
5216 struct policy_handle user_handle
;
5217 struct samr_Ids rids
, types
;
5219 n
.in
.domain_handle
= domain_handle
;
5221 n
.in
.names
= talloc_array(tctx
, struct lsa_String
, 1);
5222 n
.in
.names
[0].string
= acct_name
;
5224 n
.out
.types
= &types
;
5226 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupNames_r(b
, tctx
, &n
),
5227 "LookupNames failed");
5228 if (!NT_STATUS_IS_OK(n
.out
.result
)) {
5229 torture_warning(tctx
, "LookupNames failed - %s\n", nt_errstr(n
.out
.result
));
5233 r
.in
.domain_handle
= domain_handle
;
5234 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5235 r
.in
.rid
= n
.out
.rids
->ids
[0];
5236 r
.out
.user_handle
= &user_handle
;
5238 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenUser_r(b
, tctx
, &r
),
5240 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5241 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", n
.out
.rids
->ids
[0], nt_errstr(r
.out
.result
));
5245 q
.in
.user_handle
= &user_handle
;
5249 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
),
5250 "QueryUserInfo failed");
5251 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
5252 torture_warning(tctx
, "QueryUserInfo failed - %s\n", nt_errstr(q
.out
.result
));
5256 torture_comment(tctx
, "calling test_ChangePasswordUser3 with too early password change\n");
5258 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
,
5259 info
->info5
.last_password_change
, true)) {
5264 /* we change passwords twice - this has the effect of verifying
5265 they were changed correctly for the final call */
5266 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
, 0, true)) {
5270 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
, 0, true)) {
5277 static bool test_CreateUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5278 struct policy_handle
*domain_handle
,
5279 const char *user_name
,
5280 struct policy_handle
*user_handle_out
,
5281 struct dom_sid
*domain_sid
,
5282 enum torture_samr_choice which_ops
,
5283 struct cli_credentials
*machine_credentials
,
5287 TALLOC_CTX
*user_ctx
;
5289 struct samr_CreateUser r
;
5290 struct samr_QueryUserInfo q
;
5291 union samr_UserInfo
*info
;
5292 struct samr_DeleteUser d
;
5295 /* This call creates a 'normal' account - check that it really does */
5296 const uint32_t acct_flags
= ACB_NORMAL
;
5297 struct lsa_String name
;
5299 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5301 struct policy_handle user_handle
;
5302 user_ctx
= talloc_named(tctx
, 0, "test_CreateUser2 per-user context");
5303 init_lsa_String(&name
, user_name
);
5305 r
.in
.domain_handle
= domain_handle
;
5306 r
.in
.account_name
= &name
;
5307 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5308 r
.out
.user_handle
= &user_handle
;
5311 torture_comment(tctx
, "Testing CreateUser(%s)\n", r
.in
.account_name
->string
);
5313 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateUser_r(b
, user_ctx
, &r
),
5314 "CreateUser failed");
5316 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
5317 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
) || NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
5318 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.account_name
->string
);
5321 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.account_name
->string
,
5322 nt_errstr(r
.out
.result
));
5327 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_USER_EXISTS
)) {
5328 if (!test_DeleteUser_byname(b
, tctx
, domain_handle
, r
.in
.account_name
->string
)) {
5329 talloc_free(user_ctx
);
5332 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateUser_r(b
, user_ctx
, &r
),
5333 "CreateUser failed");
5336 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5337 talloc_free(user_ctx
);
5338 torture_warning(tctx
, "CreateUser failed - %s\n", nt_errstr(r
.out
.result
));
5343 if (user_handle_out
) {
5344 *user_handle_out
= user_handle
;
5350 q
.in
.user_handle
= &user_handle
;
5354 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, user_ctx
, &q
),
5355 "QueryUserInfo failed");
5356 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
5357 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
5358 q
.in
.level
, nt_errstr(q
.out
.result
));
5361 if ((info
->info16
.acct_flags
& acct_flags
) != acct_flags
) {
5362 torture_warning(tctx
, "QueryUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5363 info
->info16
.acct_flags
,
5369 if (!test_user_ops(p
, tctx
, &user_handle
, domain_handle
,
5370 domain_sid
, acct_flags
, name
.string
, which_ops
,
5371 machine_credentials
)) {
5375 if (user_handle_out
) {
5376 *user_handle_out
= user_handle
;
5378 torture_comment(tctx
, "Testing DeleteUser (createuser test)\n");
5380 d
.in
.user_handle
= &user_handle
;
5381 d
.out
.user_handle
= &user_handle
;
5383 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, user_ctx
, &d
),
5384 "DeleteUser failed");
5385 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
5386 torture_warning(tctx
, "DeleteUser failed - %s\n", nt_errstr(d
.out
.result
));
5393 talloc_free(user_ctx
);
5399 static bool test_CreateUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5400 struct policy_handle
*domain_handle
,
5401 struct dom_sid
*domain_sid
,
5402 enum torture_samr_choice which_ops
,
5403 struct cli_credentials
*machine_credentials
)
5405 struct samr_CreateUser2 r
;
5406 struct samr_QueryUserInfo q
;
5407 union samr_UserInfo
*info
;
5408 struct samr_DeleteUser d
;
5409 struct policy_handle user_handle
;
5411 struct lsa_String name
;
5414 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5417 uint32_t acct_flags
;
5418 const char *account_name
;
5420 } account_types
[] = {
5421 { ACB_NORMAL
, TEST_ACCOUNT_NAME
, NT_STATUS_OK
},
5422 { ACB_NORMAL
| ACB_DISABLED
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5423 { ACB_NORMAL
| ACB_PWNOEXP
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5424 { ACB_WSTRUST
, TEST_MACHINENAME
, NT_STATUS_OK
},
5425 { ACB_WSTRUST
| ACB_DISABLED
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5426 { ACB_WSTRUST
| ACB_PWNOEXP
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5427 { ACB_SVRTRUST
, TEST_MACHINENAME
, NT_STATUS_OK
},
5428 { ACB_SVRTRUST
| ACB_DISABLED
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5429 { ACB_SVRTRUST
| ACB_PWNOEXP
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5430 { ACB_DOMTRUST
, TEST_DOMAINNAME
, NT_STATUS_ACCESS_DENIED
},
5431 { ACB_DOMTRUST
| ACB_DISABLED
, TEST_DOMAINNAME
, NT_STATUS_INVALID_PARAMETER
},
5432 { ACB_DOMTRUST
| ACB_PWNOEXP
, TEST_DOMAINNAME
, NT_STATUS_INVALID_PARAMETER
},
5433 { 0, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5434 { ACB_DISABLED
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5435 { 0, NULL
, NT_STATUS_INVALID_PARAMETER
}
5438 for (i
= 0; account_types
[i
].account_name
; i
++) {
5439 TALLOC_CTX
*user_ctx
;
5440 uint32_t acct_flags
= account_types
[i
].acct_flags
;
5441 uint32_t access_granted
;
5442 user_ctx
= talloc_named(tctx
, 0, "test_CreateUser2 per-user context");
5443 init_lsa_String(&name
, account_types
[i
].account_name
);
5445 r
.in
.domain_handle
= domain_handle
;
5446 r
.in
.account_name
= &name
;
5447 r
.in
.acct_flags
= acct_flags
;
5448 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5449 r
.out
.user_handle
= &user_handle
;
5450 r
.out
.access_granted
= &access_granted
;
5453 torture_comment(tctx
, "Testing CreateUser2(%s, 0x%x)\n", r
.in
.account_name
->string
, acct_flags
);
5455 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateUser2_r(b
, user_ctx
, &r
),
5456 "CreateUser2 failed");
5458 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
5459 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
) || NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
5460 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.account_name
->string
);
5463 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.account_name
->string
,
5464 nt_errstr(r
.out
.result
));
5470 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_USER_EXISTS
)) {
5471 if (!test_DeleteUser_byname(b
, tctx
, domain_handle
, r
.in
.account_name
->string
)) {
5472 talloc_free(user_ctx
);
5476 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateUser2_r(b
, user_ctx
, &r
),
5477 "CreateUser2 failed");
5480 if (!NT_STATUS_EQUAL(r
.out
.result
, account_types
[i
].nt_status
)) {
5481 torture_warning(tctx
, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5482 nt_errstr(r
.out
.result
), nt_errstr(account_types
[i
].nt_status
));
5486 if (NT_STATUS_IS_OK(r
.out
.result
)) {
5487 q
.in
.user_handle
= &user_handle
;
5491 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, user_ctx
, &q
),
5492 "QueryUserInfo failed");
5493 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
5494 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
5495 q
.in
.level
, nt_errstr(q
.out
.result
));
5498 uint32_t expected_flags
= (acct_flags
| ACB_PWNOTREQ
| ACB_DISABLED
);
5499 if (acct_flags
== ACB_NORMAL
) {
5500 expected_flags
|= ACB_PW_EXPIRED
;
5502 if ((info
->info5
.acct_flags
) != expected_flags
) {
5503 torture_warning(tctx
, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5504 info
->info5
.acct_flags
,
5508 switch (acct_flags
) {
5510 if (info
->info5
.primary_gid
!= DOMAIN_RID_DCS
) {
5511 torture_warning(tctx
, "QueryUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5512 DOMAIN_RID_DCS
, info
->info5
.primary_gid
);
5517 if (info
->info5
.primary_gid
!= DOMAIN_RID_DOMAIN_MEMBERS
) {
5518 torture_warning(tctx
, "QueryUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5519 DOMAIN_RID_DOMAIN_MEMBERS
, info
->info5
.primary_gid
);
5524 if (info
->info5
.primary_gid
!= DOMAIN_RID_USERS
) {
5525 torture_warning(tctx
, "QueryUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5526 DOMAIN_RID_USERS
, info
->info5
.primary_gid
);
5533 if (!test_user_ops(p
, tctx
, &user_handle
, domain_handle
,
5534 domain_sid
, acct_flags
, name
.string
, which_ops
,
5535 machine_credentials
)) {
5539 if (!policy_handle_empty(&user_handle
)) {
5540 torture_comment(tctx
, "Testing DeleteUser (createuser2 test)\n");
5542 d
.in
.user_handle
= &user_handle
;
5543 d
.out
.user_handle
= &user_handle
;
5545 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, user_ctx
, &d
),
5546 "DeleteUser failed");
5547 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
5548 torture_warning(tctx
, "DeleteUser failed - %s\n", nt_errstr(d
.out
.result
));
5553 talloc_free(user_ctx
);
5559 static bool test_QueryAliasInfo(struct dcerpc_binding_handle
*b
,
5560 struct torture_context
*tctx
,
5561 struct policy_handle
*handle
)
5563 struct samr_QueryAliasInfo r
;
5564 union samr_AliasInfo
*info
;
5565 uint16_t levels
[] = {1, 2, 3};
5569 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5570 torture_comment(tctx
, "Testing QueryAliasInfo level %u\n", levels
[i
]);
5572 r
.in
.alias_handle
= handle
;
5573 r
.in
.level
= levels
[i
];
5576 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryAliasInfo_r(b
, tctx
, &r
),
5577 "QueryAliasInfo failed");
5578 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5579 torture_warning(tctx
, "QueryAliasInfo level %u failed - %s\n",
5580 levels
[i
], nt_errstr(r
.out
.result
));
5588 static bool test_QueryGroupInfo(struct dcerpc_binding_handle
*b
,
5589 struct torture_context
*tctx
,
5590 struct policy_handle
*handle
)
5592 struct samr_QueryGroupInfo r
;
5593 union samr_GroupInfo
*info
;
5594 uint16_t levels
[] = {1, 2, 3, 4, 5};
5598 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5599 torture_comment(tctx
, "Testing QueryGroupInfo level %u\n", levels
[i
]);
5601 r
.in
.group_handle
= handle
;
5602 r
.in
.level
= levels
[i
];
5605 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupInfo_r(b
, tctx
, &r
),
5606 "QueryGroupInfo failed");
5607 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5608 torture_warning(tctx
, "QueryGroupInfo level %u failed - %s\n",
5609 levels
[i
], nt_errstr(r
.out
.result
));
5617 static bool test_QueryGroupMember(struct dcerpc_binding_handle
*b
,
5618 struct torture_context
*tctx
,
5619 struct policy_handle
*handle
)
5621 struct samr_QueryGroupMember r
;
5622 struct samr_RidAttrArray
*rids
= NULL
;
5625 torture_comment(tctx
, "Testing QueryGroupMember\n");
5627 r
.in
.group_handle
= handle
;
5630 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupMember_r(b
, tctx
, &r
),
5631 "QueryGroupMember failed");
5632 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5633 torture_warning(tctx
, "QueryGroupMember failed - %s\n", nt_errstr(r
.out
.result
));
5641 static bool test_SetGroupInfo(struct dcerpc_binding_handle
*b
,
5642 struct torture_context
*tctx
,
5643 struct policy_handle
*handle
)
5645 struct samr_QueryGroupInfo r
;
5646 union samr_GroupInfo
*info
;
5647 struct samr_SetGroupInfo s
;
5648 uint16_t levels
[] = {1, 2, 3, 4};
5649 uint16_t set_ok
[] = {0, 1, 1, 1};
5653 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5654 torture_comment(tctx
, "Testing QueryGroupInfo level %u\n", levels
[i
]);
5656 r
.in
.group_handle
= handle
;
5657 r
.in
.level
= levels
[i
];
5660 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupInfo_r(b
, tctx
, &r
),
5661 "QueryGroupInfo failed");
5662 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5663 torture_warning(tctx
, "QueryGroupInfo level %u failed - %s\n",
5664 levels
[i
], nt_errstr(r
.out
.result
));
5668 torture_comment(tctx
, "Testing SetGroupInfo level %u\n", levels
[i
]);
5670 s
.in
.group_handle
= handle
;
5671 s
.in
.level
= levels
[i
];
5672 s
.in
.info
= *r
.out
.info
;
5675 /* disabled this, as it changes the name only from the point of view of samr,
5676 but leaves the name from the point of view of w2k3 internals (and ldap). This means
5677 the name is still reserved, so creating the old name fails, but deleting by the old name
5679 if (s
.in
.level
== 2) {
5680 init_lsa_String(&s
.in
.info
->string
, "NewName");
5684 if (s
.in
.level
== 4) {
5685 init_lsa_String(&s
.in
.info
->description
, "test description");
5688 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetGroupInfo_r(b
, tctx
, &s
),
5689 "SetGroupInfo failed");
5691 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
5692 torture_warning(tctx
, "SetGroupInfo level %u failed - %s\n",
5693 r
.in
.level
, nt_errstr(s
.out
.result
));
5698 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, s
.out
.result
)) {
5699 torture_warning(tctx
, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5700 r
.in
.level
, nt_errstr(s
.out
.result
));
5710 static bool test_QueryUserInfo(struct dcerpc_binding_handle
*b
,
5711 struct torture_context
*tctx
,
5712 struct policy_handle
*handle
)
5714 struct samr_QueryUserInfo r
;
5715 union samr_UserInfo
*info
;
5716 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5717 11, 12, 13, 14, 16, 17, 20, 21};
5721 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5722 torture_comment(tctx
, "Testing QueryUserInfo level %u\n", levels
[i
]);
5724 r
.in
.user_handle
= handle
;
5725 r
.in
.level
= levels
[i
];
5728 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
5729 "QueryUserInfo failed");
5730 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5731 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
5732 levels
[i
], nt_errstr(r
.out
.result
));
5740 static bool test_QueryUserInfo2(struct dcerpc_binding_handle
*b
,
5741 struct torture_context
*tctx
,
5742 struct policy_handle
*handle
)
5744 struct samr_QueryUserInfo2 r
;
5745 union samr_UserInfo
*info
;
5746 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5747 11, 12, 13, 14, 16, 17, 20, 21};
5751 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5752 torture_comment(tctx
, "Testing QueryUserInfo2 level %u\n", levels
[i
]);
5754 r
.in
.user_handle
= handle
;
5755 r
.in
.level
= levels
[i
];
5758 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo2_r(b
, tctx
, &r
),
5759 "QueryUserInfo2 failed");
5760 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5761 torture_warning(tctx
, "QueryUserInfo2 level %u failed - %s\n",
5762 levels
[i
], nt_errstr(r
.out
.result
));
5770 static bool test_OpenUser(struct dcerpc_binding_handle
*b
,
5771 struct torture_context
*tctx
,
5772 struct policy_handle
*handle
, uint32_t rid
)
5774 struct samr_OpenUser r
;
5775 struct policy_handle user_handle
;
5778 torture_comment(tctx
, "Testing OpenUser(%u)\n", rid
);
5780 r
.in
.domain_handle
= handle
;
5781 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5783 r
.out
.user_handle
= &user_handle
;
5785 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenUser_r(b
, tctx
, &r
),
5787 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5788 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", rid
, nt_errstr(r
.out
.result
));
5792 if (!test_QuerySecurity(b
, tctx
, &user_handle
)) {
5796 if (!test_QueryUserInfo(b
, tctx
, &user_handle
)) {
5800 if (!test_QueryUserInfo2(b
, tctx
, &user_handle
)) {
5804 if (!test_GetUserPwInfo(b
, tctx
, &user_handle
)) {
5808 if (!test_GetGroupsForUser(b
, tctx
, &user_handle
)) {
5812 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
5819 static bool test_OpenGroup(struct dcerpc_binding_handle
*b
,
5820 struct torture_context
*tctx
,
5821 struct policy_handle
*handle
, uint32_t rid
)
5823 struct samr_OpenGroup r
;
5824 struct policy_handle group_handle
;
5827 torture_comment(tctx
, "Testing OpenGroup(%u)\n", rid
);
5829 r
.in
.domain_handle
= handle
;
5830 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5832 r
.out
.group_handle
= &group_handle
;
5834 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenGroup_r(b
, tctx
, &r
),
5835 "OpenGroup failed");
5836 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5837 torture_warning(tctx
, "OpenGroup(%u) failed - %s\n", rid
, nt_errstr(r
.out
.result
));
5841 if (!torture_setting_bool(tctx
, "samba3", false)) {
5842 if (!test_QuerySecurity(b
, tctx
, &group_handle
)) {
5847 if (!test_QueryGroupInfo(b
, tctx
, &group_handle
)) {
5851 if (!test_QueryGroupMember(b
, tctx
, &group_handle
)) {
5855 if (!test_samr_handle_Close(b
, tctx
, &group_handle
)) {
5862 static bool test_OpenAlias(struct dcerpc_binding_handle
*b
,
5863 struct torture_context
*tctx
,
5864 struct policy_handle
*handle
, uint32_t rid
)
5866 struct samr_OpenAlias r
;
5867 struct policy_handle alias_handle
;
5870 torture_comment(tctx
, "Testing OpenAlias(%u)\n", rid
);
5872 r
.in
.domain_handle
= handle
;
5873 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5875 r
.out
.alias_handle
= &alias_handle
;
5877 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenAlias_r(b
, tctx
, &r
),
5878 "OpenAlias failed");
5879 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5880 torture_warning(tctx
, "OpenAlias(%u) failed - %s\n", rid
, nt_errstr(r
.out
.result
));
5884 if (!torture_setting_bool(tctx
, "samba3", false)) {
5885 if (!test_QuerySecurity(b
, tctx
, &alias_handle
)) {
5890 if (!test_QueryAliasInfo(b
, tctx
, &alias_handle
)) {
5894 if (!test_GetMembersInAlias(b
, tctx
, &alias_handle
)) {
5898 if (!test_samr_handle_Close(b
, tctx
, &alias_handle
)) {
5905 static bool check_mask(struct dcerpc_binding_handle
*b
,
5906 struct torture_context
*tctx
,
5907 struct policy_handle
*handle
, uint32_t rid
,
5908 uint32_t acct_flag_mask
)
5910 struct samr_OpenUser r
;
5911 struct samr_QueryUserInfo q
;
5912 union samr_UserInfo
*info
;
5913 struct policy_handle user_handle
;
5916 torture_comment(tctx
, "Testing OpenUser(%u)\n", rid
);
5918 r
.in
.domain_handle
= handle
;
5919 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5921 r
.out
.user_handle
= &user_handle
;
5923 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenUser_r(b
, tctx
, &r
),
5925 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5926 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", rid
, nt_errstr(r
.out
.result
));
5930 q
.in
.user_handle
= &user_handle
;
5934 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
),
5935 "QueryUserInfo failed");
5936 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
5937 torture_warning(tctx
, "QueryUserInfo level 16 failed - %s\n",
5938 nt_errstr(q
.out
.result
));
5941 if ((acct_flag_mask
& info
->info16
.acct_flags
) == 0) {
5942 torture_warning(tctx
, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
5943 acct_flag_mask
, info
->info16
.acct_flags
, rid
);
5948 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
5955 static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle
*b
,
5956 struct torture_context
*tctx
,
5957 struct policy_handle
*handle
)
5959 struct samr_EnumDomainUsers r
;
5960 uint32_t mask
, resume_handle
=0;
5963 struct samr_LookupNames n
;
5964 struct samr_LookupRids lr
;
5965 struct lsa_Strings names
;
5966 struct samr_Ids rids
, types
;
5967 struct samr_SamArray
*sam
= NULL
;
5968 uint32_t num_entries
= 0;
5970 uint32_t masks
[] = {ACB_NORMAL
, ACB_DOMTRUST
, ACB_WSTRUST
,
5971 ACB_DISABLED
, ACB_NORMAL
| ACB_DISABLED
,
5972 ACB_SVRTRUST
| ACB_DOMTRUST
| ACB_WSTRUST
,
5975 torture_comment(tctx
, "Testing EnumDomainUsers\n");
5977 for (mask_idx
=0;mask_idx
<ARRAY_SIZE(masks
);mask_idx
++) {
5978 r
.in
.domain_handle
= handle
;
5979 r
.in
.resume_handle
= &resume_handle
;
5980 r
.in
.acct_flags
= mask
= masks
[mask_idx
];
5981 r
.in
.max_size
= (uint32_t)-1;
5982 r
.out
.resume_handle
= &resume_handle
;
5983 r
.out
.num_entries
= &num_entries
;
5986 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainUsers_r(b
, tctx
, &r
),
5987 "EnumDomainUsers failed");
5988 if (!NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
) &&
5989 !NT_STATUS_IS_OK(r
.out
.result
)) {
5990 torture_warning(tctx
, "EnumDomainUsers failed - %s\n", nt_errstr(r
.out
.result
));
5994 torture_assert(tctx
, sam
, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
5996 if (sam
->count
== 0) {
6000 for (i
=0;i
<sam
->count
;i
++) {
6002 if (!check_mask(b
, tctx
, handle
, sam
->entries
[i
].idx
, mask
)) {
6005 } else if (!test_OpenUser(b
, tctx
, handle
, sam
->entries
[i
].idx
)) {
6011 torture_comment(tctx
, "Testing LookupNames\n");
6012 n
.in
.domain_handle
= handle
;
6013 n
.in
.num_names
= sam
->count
;
6014 n
.in
.names
= talloc_array(tctx
, struct lsa_String
, sam
->count
);
6016 n
.out
.types
= &types
;
6017 for (i
=0;i
<sam
->count
;i
++) {
6018 n
.in
.names
[i
].string
= sam
->entries
[i
].name
.string
;
6020 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupNames_r(b
, tctx
, &n
),
6021 "LookupNames failed");
6022 if (!NT_STATUS_IS_OK(n
.out
.result
)) {
6023 torture_warning(tctx
, "LookupNames failed - %s\n", nt_errstr(n
.out
.result
));
6028 torture_comment(tctx
, "Testing LookupRids\n");
6029 lr
.in
.domain_handle
= handle
;
6030 lr
.in
.num_rids
= sam
->count
;
6031 lr
.in
.rids
= talloc_array(tctx
, uint32_t, sam
->count
);
6032 lr
.out
.names
= &names
;
6033 lr
.out
.types
= &types
;
6034 for (i
=0;i
<sam
->count
;i
++) {
6035 lr
.in
.rids
[i
] = sam
->entries
[i
].idx
;
6037 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupRids_r(b
, tctx
, &lr
),
6038 "LookupRids failed");
6039 torture_assert_ntstatus_ok(tctx
, lr
.out
.result
, "LookupRids");
6045 try blasting the server with a bunch of sync requests
6047 static bool test_EnumDomainUsers_async(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6048 struct policy_handle
*handle
)
6050 struct samr_EnumDomainUsers r
;
6051 uint32_t resume_handle
=0;
6053 #define ASYNC_COUNT 100
6054 struct tevent_req
*req
[ASYNC_COUNT
];
6056 if (!torture_setting_bool(tctx
, "dangerous", false)) {
6057 torture_skip(tctx
, "samr async test disabled - enable dangerous tests to use\n");
6060 torture_comment(tctx
, "Testing EnumDomainUsers_async\n");
6062 r
.in
.domain_handle
= handle
;
6063 r
.in
.resume_handle
= &resume_handle
;
6064 r
.in
.acct_flags
= 0;
6065 r
.in
.max_size
= (uint32_t)-1;
6066 r
.out
.resume_handle
= &resume_handle
;
6068 for (i
=0;i
<ASYNC_COUNT
;i
++) {
6069 req
[i
] = dcerpc_samr_EnumDomainUsers_r_send(tctx
, tctx
->ev
, p
->binding_handle
, &r
);
6072 for (i
=0;i
<ASYNC_COUNT
;i
++) {
6073 tevent_req_poll(req
[i
], tctx
->ev
);
6074 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainUsers_r_recv(req
[i
], tctx
),
6075 talloc_asprintf(tctx
, "EnumDomainUsers[%d] failed - %s\n",
6076 i
, nt_errstr(r
.out
.result
)));
6079 torture_comment(tctx
, "%d async requests OK\n", i
);
6084 static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle
*b
,
6085 struct torture_context
*tctx
,
6086 struct policy_handle
*handle
)
6088 struct samr_EnumDomainGroups r
;
6089 uint32_t resume_handle
=0;
6090 struct samr_SamArray
*sam
= NULL
;
6091 uint32_t num_entries
= 0;
6094 bool universal_group_found
= false;
6096 torture_comment(tctx
, "Testing EnumDomainGroups\n");
6098 r
.in
.domain_handle
= handle
;
6099 r
.in
.resume_handle
= &resume_handle
;
6100 r
.in
.max_size
= (uint32_t)-1;
6101 r
.out
.resume_handle
= &resume_handle
;
6102 r
.out
.num_entries
= &num_entries
;
6105 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainGroups_r(b
, tctx
, &r
),
6106 "EnumDomainGroups failed");
6107 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6108 torture_warning(tctx
, "EnumDomainGroups failed - %s\n", nt_errstr(r
.out
.result
));
6116 for (i
=0;i
<sam
->count
;i
++) {
6117 if (!test_OpenGroup(b
, tctx
, handle
, sam
->entries
[i
].idx
)) {
6120 if ((ret
== true) && (strcasecmp(sam
->entries
[i
].name
.string
,
6121 "Enterprise Admins") == 0)) {
6122 universal_group_found
= true;
6126 /* when we are running this on s4 we should get back at least the
6127 * "Enterprise Admins" universal group. If we don't get a group entry
6128 * at all we probably are performing the test on the builtin domain.
6129 * So ignore this case. */
6130 if (torture_setting_bool(tctx
, "samba4", false)) {
6131 if ((sam
->count
> 0) && (!universal_group_found
)) {
6139 static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle
*b
,
6140 struct torture_context
*tctx
,
6141 struct policy_handle
*handle
)
6143 struct samr_EnumDomainAliases r
;
6144 uint32_t resume_handle
=0;
6145 struct samr_SamArray
*sam
= NULL
;
6146 uint32_t num_entries
= 0;
6150 torture_comment(tctx
, "Testing EnumDomainAliases\n");
6152 r
.in
.domain_handle
= handle
;
6153 r
.in
.resume_handle
= &resume_handle
;
6154 r
.in
.max_size
= (uint32_t)-1;
6156 r
.out
.num_entries
= &num_entries
;
6157 r
.out
.resume_handle
= &resume_handle
;
6159 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainAliases_r(b
, tctx
, &r
),
6160 "EnumDomainAliases failed");
6161 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6162 torture_warning(tctx
, "EnumDomainAliases failed - %s\n", nt_errstr(r
.out
.result
));
6170 for (i
=0;i
<sam
->count
;i
++) {
6171 if (!test_OpenAlias(b
, tctx
, handle
, sam
->entries
[i
].idx
)) {
6179 static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle
*b
,
6180 struct torture_context
*tctx
,
6181 struct policy_handle
*handle
)
6183 struct samr_GetDisplayEnumerationIndex r
;
6185 uint16_t levels
[] = {1, 2, 3, 4, 5};
6186 uint16_t ok_lvl
[] = {1, 1, 1, 0, 0};
6187 struct lsa_String name
;
6191 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6192 torture_comment(tctx
, "Testing GetDisplayEnumerationIndex level %u\n", levels
[i
]);
6194 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
6196 r
.in
.domain_handle
= handle
;
6197 r
.in
.level
= levels
[i
];
6201 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDisplayEnumerationIndex_r(b
, tctx
, &r
),
6202 "GetDisplayEnumerationIndex failed");
6205 !NT_STATUS_IS_OK(r
.out
.result
) &&
6206 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, r
.out
.result
)) {
6207 torture_warning(tctx
, "GetDisplayEnumerationIndex level %u failed - %s\n",
6208 levels
[i
], nt_errstr(r
.out
.result
));
6212 init_lsa_String(&name
, "zzzzzzzz");
6214 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDisplayEnumerationIndex_r(b
, tctx
, &r
),
6215 "GetDisplayEnumerationIndex failed");
6217 if (ok_lvl
[i
] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, r
.out
.result
)) {
6218 torture_warning(tctx
, "GetDisplayEnumerationIndex level %u failed - %s\n",
6219 levels
[i
], nt_errstr(r
.out
.result
));
6227 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle
*b
,
6228 struct torture_context
*tctx
,
6229 struct policy_handle
*handle
)
6231 struct samr_GetDisplayEnumerationIndex2 r
;
6233 uint16_t levels
[] = {1, 2, 3, 4, 5};
6234 uint16_t ok_lvl
[] = {1, 1, 1, 0, 0};
6235 struct lsa_String name
;
6239 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6240 torture_comment(tctx
, "Testing GetDisplayEnumerationIndex2 level %u\n", levels
[i
]);
6242 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
6244 r
.in
.domain_handle
= handle
;
6245 r
.in
.level
= levels
[i
];
6249 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDisplayEnumerationIndex2_r(b
, tctx
, &r
),
6250 "GetDisplayEnumerationIndex2 failed");
6252 !NT_STATUS_IS_OK(r
.out
.result
) &&
6253 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, r
.out
.result
)) {
6254 torture_warning(tctx
, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6255 levels
[i
], nt_errstr(r
.out
.result
));
6259 init_lsa_String(&name
, "zzzzzzzz");
6261 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDisplayEnumerationIndex2_r(b
, tctx
, &r
),
6262 "GetDisplayEnumerationIndex2 failed");
6263 if (ok_lvl
[i
] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, r
.out
.result
)) {
6264 torture_warning(tctx
, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6265 levels
[i
], nt_errstr(r
.out
.result
));
6273 #define STRING_EQUAL_QUERY(s1, s2, user) \
6274 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6275 /* odd, but valid */ \
6276 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6277 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
6278 #s1, user.string, s1.string, s2.string, __location__); \
6281 #define INT_EQUAL_QUERY(s1, s2, user) \
6283 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6284 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6288 static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle
*b
,
6289 struct torture_context
*tctx
,
6290 struct samr_QueryDisplayInfo
*querydisplayinfo
,
6291 bool *seen_testuser
)
6293 struct samr_OpenUser r
;
6294 struct samr_QueryUserInfo q
;
6295 union samr_UserInfo
*info
;
6296 struct policy_handle user_handle
;
6298 r
.in
.domain_handle
= querydisplayinfo
->in
.domain_handle
;
6299 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6300 for (i
= 0; ; i
++) {
6301 switch (querydisplayinfo
->in
.level
) {
6303 if (i
>= querydisplayinfo
->out
.info
->info1
.count
) {
6306 r
.in
.rid
= querydisplayinfo
->out
.info
->info1
.entries
[i
].rid
;
6309 if (i
>= querydisplayinfo
->out
.info
->info2
.count
) {
6312 r
.in
.rid
= querydisplayinfo
->out
.info
->info2
.entries
[i
].rid
;
6318 /* Not interested in validating just the account name */
6322 r
.out
.user_handle
= &user_handle
;
6324 switch (querydisplayinfo
->in
.level
) {
6327 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenUser_r(b
, tctx
, &r
),
6329 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6330 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", r
.in
.rid
, nt_errstr(r
.out
.result
));
6335 q
.in
.user_handle
= &user_handle
;
6338 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
),
6339 "QueryUserInfo failed");
6340 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6341 torture_warning(tctx
, "QueryUserInfo(%u) failed - %s\n", r
.in
.rid
, nt_errstr(r
.out
.result
));
6345 switch (querydisplayinfo
->in
.level
) {
6347 if (seen_testuser
&& strcmp(info
->info21
.account_name
.string
, TEST_ACCOUNT_NAME
) == 0) {
6348 *seen_testuser
= true;
6350 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].full_name
,
6351 info
->info21
.full_name
, info
->info21
.account_name
);
6352 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].account_name
,
6353 info
->info21
.account_name
, info
->info21
.account_name
);
6354 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].description
,
6355 info
->info21
.description
, info
->info21
.account_name
);
6356 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].rid
,
6357 info
->info21
.rid
, info
->info21
.account_name
);
6358 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].acct_flags
,
6359 info
->info21
.acct_flags
, info
->info21
.account_name
);
6363 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].account_name
,
6364 info
->info21
.account_name
, info
->info21
.account_name
);
6365 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].description
,
6366 info
->info21
.description
, info
->info21
.account_name
);
6367 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].rid
,
6368 info
->info21
.rid
, info
->info21
.account_name
);
6369 INT_EQUAL_QUERY((querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
& ~ACB_NORMAL
),
6370 info
->info21
.acct_flags
, info
->info21
.account_name
);
6372 if (!(querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
& ACB_NORMAL
)) {
6373 torture_warning(tctx
, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6374 info
->info21
.account_name
.string
);
6377 if (!(info
->info21
.acct_flags
& (ACB_WSTRUST
| ACB_SVRTRUST
))) {
6378 torture_warning(tctx
, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6379 info
->info21
.account_name
.string
,
6380 querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
,
6381 info
->info21
.acct_flags
);
6388 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
6395 static bool test_QueryDisplayInfo(struct dcerpc_binding_handle
*b
,
6396 struct torture_context
*tctx
,
6397 struct policy_handle
*handle
)
6399 struct samr_QueryDisplayInfo r
;
6400 struct samr_QueryDomainInfo dom_info
;
6401 union samr_DomainInfo
*info
= NULL
;
6403 uint16_t levels
[] = {1, 2, 3, 4, 5};
6405 bool seen_testuser
= false;
6406 uint32_t total_size
;
6407 uint32_t returned_size
;
6408 union samr_DispInfo disp_info
;
6411 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6412 torture_comment(tctx
, "Testing QueryDisplayInfo level %u\n", levels
[i
]);
6415 r
.out
.result
= STATUS_MORE_ENTRIES
;
6416 while (NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
)) {
6417 r
.in
.domain_handle
= handle
;
6418 r
.in
.level
= levels
[i
];
6419 r
.in
.max_entries
= 2;
6420 r
.in
.buf_size
= (uint32_t)-1;
6421 r
.out
.total_size
= &total_size
;
6422 r
.out
.returned_size
= &returned_size
;
6423 r
.out
.info
= &disp_info
;
6425 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &r
),
6426 "QueryDisplayInfo failed");
6427 if (!NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
) && !NT_STATUS_IS_OK(r
.out
.result
)) {
6428 torture_warning(tctx
, "QueryDisplayInfo level %u failed - %s\n",
6429 levels
[i
], nt_errstr(r
.out
.result
));
6432 switch (r
.in
.level
) {
6434 if (!test_each_DisplayInfo_user(b
, tctx
, &r
, &seen_testuser
)) {
6437 r
.in
.start_idx
+= r
.out
.info
->info1
.count
;
6440 if (!test_each_DisplayInfo_user(b
, tctx
, &r
, NULL
)) {
6443 r
.in
.start_idx
+= r
.out
.info
->info2
.count
;
6446 r
.in
.start_idx
+= r
.out
.info
->info3
.count
;
6449 r
.in
.start_idx
+= r
.out
.info
->info4
.count
;
6452 r
.in
.start_idx
+= r
.out
.info
->info5
.count
;
6456 dom_info
.in
.domain_handle
= handle
;
6457 dom_info
.in
.level
= 2;
6458 dom_info
.out
.info
= &info
;
6460 /* Check number of users returned is correct */
6461 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &dom_info
),
6462 "QueryDomainInfo failed");
6463 if (!NT_STATUS_IS_OK(dom_info
.out
.result
)) {
6464 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
6465 r
.in
.level
, nt_errstr(dom_info
.out
.result
));
6469 switch (r
.in
.level
) {
6472 if (info
->general
.num_users
< r
.in
.start_idx
) {
6473 /* On AD deployments this numbers don't match
6474 * since QueryDisplayInfo returns universal and
6475 * global groups, QueryDomainInfo only global
6477 if (torture_setting_bool(tctx
, "samba3", false)) {
6478 torture_warning(tctx
, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6479 r
.in
.start_idx
, info
->general
.num_groups
,
6480 info
->general
.domain_name
.string
);
6484 if (!seen_testuser
) {
6485 struct policy_handle user_handle
;
6486 if (NT_STATUS_IS_OK(test_OpenUser_byname(b
, tctx
, handle
, TEST_ACCOUNT_NAME
, &user_handle
))) {
6487 torture_warning(tctx
, "Didn't find test user " TEST_ACCOUNT_NAME
" in enumeration of %s\n",
6488 info
->general
.domain_name
.string
);
6490 test_samr_handle_Close(b
, tctx
, &user_handle
);
6496 if (info
->general
.num_groups
!= r
.in
.start_idx
) {
6497 /* On AD deployments this numbers don't match
6498 * since QueryDisplayInfo returns universal and
6499 * global groups, QueryDomainInfo only global
6501 if (torture_setting_bool(tctx
, "samba3", false)) {
6502 torture_warning(tctx
, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6503 r
.in
.start_idx
, info
->general
.num_groups
,
6504 info
->general
.domain_name
.string
);
6517 static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle
*b
,
6518 struct torture_context
*tctx
,
6519 struct policy_handle
*handle
)
6521 struct samr_QueryDisplayInfo2 r
;
6523 uint16_t levels
[] = {1, 2, 3, 4, 5};
6525 uint32_t total_size
;
6526 uint32_t returned_size
;
6527 union samr_DispInfo info
;
6529 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6530 torture_comment(tctx
, "Testing QueryDisplayInfo2 level %u\n", levels
[i
]);
6532 r
.in
.domain_handle
= handle
;
6533 r
.in
.level
= levels
[i
];
6535 r
.in
.max_entries
= 1000;
6536 r
.in
.buf_size
= (uint32_t)-1;
6537 r
.out
.total_size
= &total_size
;
6538 r
.out
.returned_size
= &returned_size
;
6541 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo2_r(b
, tctx
, &r
),
6542 "QueryDisplayInfo2 failed");
6543 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6544 torture_warning(tctx
, "QueryDisplayInfo2 level %u failed - %s\n",
6545 levels
[i
], nt_errstr(r
.out
.result
));
6553 static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle
*b
,
6554 struct torture_context
*tctx
,
6555 struct policy_handle
*handle
)
6557 struct samr_QueryDisplayInfo3 r
;
6559 uint16_t levels
[] = {1, 2, 3, 4, 5};
6561 uint32_t total_size
;
6562 uint32_t returned_size
;
6563 union samr_DispInfo info
;
6565 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6566 torture_comment(tctx
, "Testing QueryDisplayInfo3 level %u\n", levels
[i
]);
6568 r
.in
.domain_handle
= handle
;
6569 r
.in
.level
= levels
[i
];
6571 r
.in
.max_entries
= 1000;
6572 r
.in
.buf_size
= (uint32_t)-1;
6573 r
.out
.total_size
= &total_size
;
6574 r
.out
.returned_size
= &returned_size
;
6577 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo3_r(b
, tctx
, &r
),
6578 "QueryDisplayInfo3 failed");
6579 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6580 torture_warning(tctx
, "QueryDisplayInfo3 level %u failed - %s\n",
6581 levels
[i
], nt_errstr(r
.out
.result
));
6590 static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle
*b
,
6591 struct torture_context
*tctx
,
6592 struct policy_handle
*handle
)
6594 struct samr_QueryDisplayInfo r
;
6596 uint32_t total_size
;
6597 uint32_t returned_size
;
6598 union samr_DispInfo info
;
6600 torture_comment(tctx
, "Testing QueryDisplayInfo continuation\n");
6602 r
.in
.domain_handle
= handle
;
6605 r
.in
.max_entries
= 1;
6606 r
.in
.buf_size
= (uint32_t)-1;
6607 r
.out
.total_size
= &total_size
;
6608 r
.out
.returned_size
= &returned_size
;
6612 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &r
),
6613 "QueryDisplayInfo failed");
6614 if (NT_STATUS_IS_OK(r
.out
.result
) && *r
.out
.returned_size
!= 0) {
6615 if (r
.out
.info
->info1
.entries
[0].idx
!= r
.in
.start_idx
+ 1) {
6616 torture_warning(tctx
, "expected idx %d but got %d\n",
6618 r
.out
.info
->info1
.entries
[0].idx
);
6622 if (!NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
) &&
6623 !NT_STATUS_IS_OK(r
.out
.result
)) {
6624 torture_warning(tctx
, "QueryDisplayInfo level %u failed - %s\n",
6625 r
.in
.level
, nt_errstr(r
.out
.result
));
6630 } while ((NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
) ||
6631 NT_STATUS_IS_OK(r
.out
.result
)) &&
6632 *r
.out
.returned_size
!= 0);
6637 static bool test_QueryDomainInfo(struct dcerpc_pipe
*p
,
6638 struct torture_context
*tctx
,
6639 struct policy_handle
*handle
)
6641 struct samr_QueryDomainInfo r
;
6642 union samr_DomainInfo
*info
= NULL
;
6643 struct samr_SetDomainInfo s
;
6644 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6645 uint16_t set_ok
[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
6648 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
6649 const char *domain_comment
= talloc_asprintf(tctx
,
6650 "Tortured by Samba4 RPC-SAMR: %s",
6651 timestring(tctx
, time(NULL
)));
6653 s
.in
.domain_handle
= handle
;
6655 s
.in
.info
= talloc(tctx
, union samr_DomainInfo
);
6657 s
.in
.info
->oem
.oem_information
.string
= domain_comment
;
6658 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
),
6659 "SetDomainInfo failed");
6660 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
6661 torture_warning(tctx
, "SetDomainInfo level %u (set comment) failed - %s\n",
6662 s
.in
.level
, nt_errstr(s
.out
.result
));
6666 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6667 torture_comment(tctx
, "Testing QueryDomainInfo level %u\n", levels
[i
]);
6669 r
.in
.domain_handle
= handle
;
6670 r
.in
.level
= levels
[i
];
6673 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &r
),
6674 "QueryDomainInfo failed");
6675 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6676 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
6677 r
.in
.level
, nt_errstr(r
.out
.result
));
6682 switch (levels
[i
]) {
6684 if (strcmp(info
->general
.oem_information
.string
, domain_comment
) != 0) {
6685 torture_warning(tctx
, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6686 levels
[i
], info
->general
.oem_information
.string
, domain_comment
);
6687 if (!torture_setting_bool(tctx
, "samba3", false)) {
6691 if (!info
->general
.primary
.string
) {
6692 torture_warning(tctx
, "QueryDomainInfo level %u returned no PDC name\n",
6695 } else if (info
->general
.role
== SAMR_ROLE_DOMAIN_PDC
) {
6696 if (dcerpc_server_name(p
) && strcasecmp_m(dcerpc_server_name(p
), info
->general
.primary
.string
) != 0) {
6697 if (torture_setting_bool(tctx
, "samba3", false)) {
6698 torture_warning(tctx
, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
6699 levels
[i
], info
->general
.primary
.string
, dcerpc_server_name(p
));
6705 if (strcmp(info
->oem
.oem_information
.string
, domain_comment
) != 0) {
6706 torture_warning(tctx
, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6707 levels
[i
], info
->oem
.oem_information
.string
, domain_comment
);
6708 if (!torture_setting_bool(tctx
, "samba3", false)) {
6714 if (!info
->info6
.primary
.string
) {
6715 torture_warning(tctx
, "QueryDomainInfo level %u returned no PDC name\n",
6721 if (strcmp(info
->general2
.general
.oem_information
.string
, domain_comment
) != 0) {
6722 torture_warning(tctx
, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
6723 levels
[i
], info
->general2
.general
.oem_information
.string
, domain_comment
);
6724 if (!torture_setting_bool(tctx
, "samba3", false)) {
6731 torture_comment(tctx
, "Testing SetDomainInfo level %u\n", levels
[i
]);
6733 s
.in
.domain_handle
= handle
;
6734 s
.in
.level
= levels
[i
];
6737 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
),
6738 "SetDomainInfo failed");
6740 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
6741 torture_warning(tctx
, "SetDomainInfo level %u failed - %s\n",
6742 r
.in
.level
, nt_errstr(s
.out
.result
));
6747 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, s
.out
.result
)) {
6748 torture_warning(tctx
, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6749 r
.in
.level
, nt_errstr(s
.out
.result
));
6755 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &r
),
6756 "QueryDomainInfo failed");
6757 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6758 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
6759 r
.in
.level
, nt_errstr(r
.out
.result
));
6769 static bool test_QueryDomainInfo2(struct dcerpc_binding_handle
*b
,
6770 struct torture_context
*tctx
,
6771 struct policy_handle
*handle
)
6773 struct samr_QueryDomainInfo2 r
;
6774 union samr_DomainInfo
*info
= NULL
;
6775 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6779 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6780 torture_comment(tctx
, "Testing QueryDomainInfo2 level %u\n", levels
[i
]);
6782 r
.in
.domain_handle
= handle
;
6783 r
.in
.level
= levels
[i
];
6786 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo2_r(b
, tctx
, &r
),
6787 "QueryDomainInfo2 failed");
6788 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6789 torture_warning(tctx
, "QueryDomainInfo2 level %u failed - %s\n",
6790 r
.in
.level
, nt_errstr(r
.out
.result
));
6799 /* Test whether querydispinfo level 5 and enumdomgroups return the same
6800 set of group names. */
6801 static bool test_GroupList(struct dcerpc_binding_handle
*b
,
6802 struct torture_context
*tctx
,
6803 struct dom_sid
*domain_sid
,
6804 struct policy_handle
*handle
)
6806 struct samr_EnumDomainGroups q1
;
6807 struct samr_QueryDisplayInfo q2
;
6809 uint32_t resume_handle
=0;
6810 struct samr_SamArray
*sam
= NULL
;
6811 uint32_t num_entries
= 0;
6814 uint32_t total_size
;
6815 uint32_t returned_size
;
6816 union samr_DispInfo info
;
6819 const char **names
= NULL
;
6821 bool builtin_domain
= dom_sid_compare(domain_sid
,
6822 &global_sid_Builtin
) == 0;
6824 torture_comment(tctx
, "Testing coherency of querydispinfo vs enumdomgroups\n");
6826 q1
.in
.domain_handle
= handle
;
6827 q1
.in
.resume_handle
= &resume_handle
;
6829 q1
.out
.resume_handle
= &resume_handle
;
6830 q1
.out
.num_entries
= &num_entries
;
6833 status
= STATUS_MORE_ENTRIES
;
6834 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
6835 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainGroups_r(b
, tctx
, &q1
),
6836 "EnumDomainGroups failed");
6837 status
= q1
.out
.result
;
6839 if (!NT_STATUS_IS_OK(status
) &&
6840 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
6843 for (i
=0; i
<*q1
.out
.num_entries
; i
++) {
6844 add_string_to_array(tctx
,
6845 sam
->entries
[i
].name
.string
,
6846 &names
, &num_names
);
6850 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomainGroups");
6852 torture_assert(tctx
, sam
, "EnumDomainGroups failed to return sam");
6854 if (builtin_domain
) {
6855 torture_assert(tctx
, num_names
== 0,
6856 "EnumDomainGroups shouldn't return any group in the builtin domain!");
6859 q2
.in
.domain_handle
= handle
;
6861 q2
.in
.start_idx
= 0;
6862 q2
.in
.max_entries
= 5;
6863 q2
.in
.buf_size
= (uint32_t)-1;
6864 q2
.out
.total_size
= &total_size
;
6865 q2
.out
.returned_size
= &returned_size
;
6866 q2
.out
.info
= &info
;
6868 status
= STATUS_MORE_ENTRIES
;
6869 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
6870 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &q2
),
6871 "QueryDisplayInfo failed");
6872 status
= q2
.out
.result
;
6873 if (!NT_STATUS_IS_OK(status
) &&
6874 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
6877 for (i
=0; i
<q2
.out
.info
->info5
.count
; i
++) {
6879 const char *name
= q2
.out
.info
->info5
.entries
[i
].account_name
.string
;
6881 for (j
=0; j
<num_names
; j
++) {
6882 if (names
[j
] == NULL
)
6884 if (strequal(names
[j
], name
)) {
6891 if ((!found
) && (!builtin_domain
)) {
6892 torture_warning(tctx
, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
6897 q2
.in
.start_idx
+= q2
.out
.info
->info5
.count
;
6900 if (!NT_STATUS_IS_OK(status
)) {
6901 torture_warning(tctx
, "QueryDisplayInfo level 5 failed - %s\n",
6906 if (builtin_domain
) {
6907 torture_assert(tctx
, q2
.in
.start_idx
!= 0,
6908 "QueryDisplayInfo should return all domain groups also on the builtin domain handle!");
6911 for (i
=0; i
<num_names
; i
++) {
6912 if (names
[i
] != NULL
) {
6913 torture_warning(tctx
, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
6922 static bool test_DeleteDomainGroup(struct dcerpc_binding_handle
*b
,
6923 struct torture_context
*tctx
,
6924 struct policy_handle
*group_handle
)
6926 struct samr_DeleteDomainGroup d
;
6928 torture_comment(tctx
, "Testing DeleteDomainGroup\n");
6930 d
.in
.group_handle
= group_handle
;
6931 d
.out
.group_handle
= group_handle
;
6933 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteDomainGroup_r(b
, tctx
, &d
),
6934 "DeleteDomainGroup failed");
6935 torture_assert_ntstatus_ok(tctx
, d
.out
.result
, "DeleteDomainGroup");
6940 static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle
*b
,
6941 struct torture_context
*tctx
,
6942 struct policy_handle
*domain_handle
)
6944 struct samr_TestPrivateFunctionsDomain r
;
6947 torture_comment(tctx
, "Testing TestPrivateFunctionsDomain\n");
6949 r
.in
.domain_handle
= domain_handle
;
6951 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_TestPrivateFunctionsDomain_r(b
, tctx
, &r
),
6952 "TestPrivateFunctionsDomain failed");
6953 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_NOT_IMPLEMENTED
, "TestPrivateFunctionsDomain");
6958 static bool test_RidToSid(struct dcerpc_binding_handle
*b
,
6959 struct torture_context
*tctx
,
6960 struct dom_sid
*domain_sid
,
6961 struct policy_handle
*domain_handle
)
6963 struct samr_RidToSid r
;
6965 struct dom_sid
*calc_sid
, *out_sid
;
6966 int rids
[] = { 0, 42, 512, 10200 };
6969 for (i
=0;i
<ARRAY_SIZE(rids
);i
++) {
6970 torture_comment(tctx
, "Testing RidToSid\n");
6972 calc_sid
= dom_sid_dup(tctx
, domain_sid
);
6973 r
.in
.domain_handle
= domain_handle
;
6975 r
.out
.sid
= &out_sid
;
6977 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RidToSid_r(b
, tctx
, &r
),
6979 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6980 torture_warning(tctx
, "RidToSid for %d failed - %s\n", rids
[i
], nt_errstr(r
.out
.result
));
6983 calc_sid
= dom_sid_add_rid(calc_sid
, calc_sid
, rids
[i
]);
6985 if (!dom_sid_equal(calc_sid
, out_sid
)) {
6986 torture_warning(tctx
, "RidToSid for %d failed - got %s, expected %s\n", rids
[i
],
6987 dom_sid_string(tctx
, out_sid
),
6988 dom_sid_string(tctx
, calc_sid
));
6997 static bool test_GetBootKeyInformation(struct dcerpc_binding_handle
*b
,
6998 struct torture_context
*tctx
,
6999 struct policy_handle
*domain_handle
)
7001 struct samr_GetBootKeyInformation r
;
7003 uint32_t unknown
= 0;
7006 torture_comment(tctx
, "Testing GetBootKeyInformation\n");
7008 r
.in
.domain_handle
= domain_handle
;
7009 r
.out
.unknown
= &unknown
;
7011 status
= dcerpc_samr_GetBootKeyInformation_r(b
, tctx
, &r
);
7012 if (NT_STATUS_IS_OK(status
) && !NT_STATUS_IS_OK(r
.out
.result
)) {
7013 status
= r
.out
.result
;
7015 if (!NT_STATUS_IS_OK(status
)) {
7016 /* w2k3 seems to fail this sometimes and pass it sometimes */
7017 torture_comment(tctx
, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status
));
7023 static bool test_AddGroupMember(struct dcerpc_binding_handle
*b
,
7024 struct torture_context
*tctx
,
7025 struct policy_handle
*domain_handle
,
7026 struct policy_handle
*group_handle
)
7029 struct samr_AddGroupMember r
;
7030 struct samr_DeleteGroupMember d
;
7031 struct samr_QueryGroupMember q
;
7032 struct samr_RidAttrArray
*rids
= NULL
;
7033 struct samr_SetMemberAttributesOfGroup s
;
7035 bool found_member
= false;
7038 status
= test_LookupName(b
, tctx
, domain_handle
, TEST_ACCOUNT_NAME
, &rid
);
7039 torture_assert_ntstatus_ok(tctx
, status
, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME
);
7041 r
.in
.group_handle
= group_handle
;
7043 r
.in
.flags
= 0; /* ??? */
7045 torture_comment(tctx
, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
7047 d
.in
.group_handle
= group_handle
;
7050 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteGroupMember_r(b
, tctx
, &d
),
7051 "DeleteGroupMember failed");
7052 torture_assert_ntstatus_equal(tctx
, NT_STATUS_MEMBER_NOT_IN_GROUP
, d
.out
.result
, "DeleteGroupMember");
7054 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddGroupMember_r(b
, tctx
, &r
),
7055 "AddGroupMember failed");
7056 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "AddGroupMember");
7058 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddGroupMember_r(b
, tctx
, &r
),
7059 "AddGroupMember failed");
7060 torture_assert_ntstatus_equal(tctx
, NT_STATUS_MEMBER_IN_GROUP
, r
.out
.result
, "AddGroupMember");
7062 if (torture_setting_bool(tctx
, "samba4", false) ||
7063 torture_setting_bool(tctx
, "samba3", false)) {
7064 torture_comment(tctx
, "skipping SetMemberAttributesOfGroup test against Samba\n");
7066 /* this one is quite strange. I am using random inputs in the
7067 hope of triggering an error that might give us a clue */
7069 s
.in
.group_handle
= group_handle
;
7070 s
.in
.unknown1
= random();
7071 s
.in
.unknown2
= random();
7073 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetMemberAttributesOfGroup_r(b
, tctx
, &s
),
7074 "SetMemberAttributesOfGroup failed");
7075 torture_assert_ntstatus_ok(tctx
, s
.out
.result
, "SetMemberAttributesOfGroup");
7078 q
.in
.group_handle
= group_handle
;
7081 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupMember_r(b
, tctx
, &q
),
7082 "QueryGroupMember failed");
7083 torture_assert_ntstatus_ok(tctx
, q
.out
.result
, "QueryGroupMember");
7084 torture_assert(tctx
, rids
, "QueryGroupMember did not fill in rids structure");
7086 for (i
=0; i
< rids
->count
; i
++) {
7087 if (rids
->rids
[i
] == rid
) {
7088 found_member
= true;
7092 torture_assert(tctx
, found_member
, "QueryGroupMember did not list newly added member");
7094 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteGroupMember_r(b
, tctx
, &d
),
7095 "DeleteGroupMember failed");
7096 torture_assert_ntstatus_ok(tctx
, d
.out
.result
, "DeleteGroupMember");
7099 found_member
= false;
7101 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupMember_r(b
, tctx
, &q
),
7102 "QueryGroupMember failed");
7103 torture_assert_ntstatus_ok(tctx
, q
.out
.result
, "QueryGroupMember");
7104 torture_assert(tctx
, rids
, "QueryGroupMember did not fill in rids structure");
7106 for (i
=0; i
< rids
->count
; i
++) {
7107 if (rids
->rids
[i
] == rid
) {
7108 found_member
= true;
7112 torture_assert(tctx
, !found_member
, "QueryGroupMember does still list removed member");
7114 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddGroupMember_r(b
, tctx
, &r
),
7115 "AddGroupMember failed");
7116 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "AddGroupMember");
7122 static bool test_CreateDomainGroup(struct dcerpc_binding_handle
*b
,
7123 struct torture_context
*tctx
,
7124 struct policy_handle
*domain_handle
,
7125 const char *group_name
,
7126 struct policy_handle
*group_handle
,
7127 struct dom_sid
*domain_sid
,
7130 struct samr_CreateDomainGroup r
;
7132 struct lsa_String name
;
7135 init_lsa_String(&name
, group_name
);
7137 r
.in
.domain_handle
= domain_handle
;
7139 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7140 r
.out
.group_handle
= group_handle
;
7143 torture_comment(tctx
, "Testing CreateDomainGroup(%s)\n", r
.in
.name
->string
);
7145 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomainGroup_r(b
, tctx
, &r
),
7146 "CreateDomainGroup failed");
7148 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
7149 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
)) {
7150 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.name
->string
);
7153 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.name
->string
,
7154 nt_errstr(r
.out
.result
));
7159 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_GROUP_EXISTS
)) {
7160 if (!test_DeleteGroup_byname(b
, tctx
, domain_handle
, r
.in
.name
->string
)) {
7161 torture_warning(tctx
, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r
.in
.name
->string
,
7162 nt_errstr(r
.out
.result
));
7165 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomainGroup_r(b
, tctx
, &r
),
7166 "CreateDomainGroup failed");
7168 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_USER_EXISTS
)) {
7169 if (!test_DeleteUser_byname(b
, tctx
, domain_handle
, r
.in
.name
->string
)) {
7171 torture_warning(tctx
, "CreateDomainGroup failed: Could not delete user %s - %s\n", r
.in
.name
->string
,
7172 nt_errstr(r
.out
.result
));
7175 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomainGroup_r(b
, tctx
, &r
),
7176 "CreateDomainGroup failed");
7178 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "CreateDomainGroup");
7184 if (!test_AddGroupMember(b
, tctx
, domain_handle
, group_handle
)) {
7185 torture_warning(tctx
, "CreateDomainGroup failed - %s\n", nt_errstr(r
.out
.result
));
7189 if (!test_SetGroupInfo(b
, tctx
, group_handle
)) {
7198 its not totally clear what this does. It seems to accept any sid you like.
7200 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle
*b
,
7201 struct torture_context
*tctx
,
7202 struct policy_handle
*domain_handle
)
7204 struct samr_RemoveMemberFromForeignDomain r
;
7206 r
.in
.domain_handle
= domain_handle
;
7207 r
.in
.sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-12-34-56-78");
7209 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RemoveMemberFromForeignDomain_r(b
, tctx
, &r
),
7210 "RemoveMemberFromForeignDomain failed");
7211 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "RemoveMemberFromForeignDomain");
7216 static bool test_EnumDomainUsers(struct dcerpc_binding_handle
*b
,
7217 struct torture_context
*tctx
,
7218 struct policy_handle
*domain_handle
,
7219 uint32_t *total_num_entries_p
)
7222 struct samr_EnumDomainUsers r
;
7223 uint32_t resume_handle
= 0;
7224 uint32_t num_entries
= 0;
7225 uint32_t total_num_entries
= 0;
7226 struct samr_SamArray
*sam
;
7228 r
.in
.domain_handle
= domain_handle
;
7229 r
.in
.acct_flags
= 0;
7230 r
.in
.max_size
= (uint32_t)-1;
7231 r
.in
.resume_handle
= &resume_handle
;
7234 r
.out
.num_entries
= &num_entries
;
7235 r
.out
.resume_handle
= &resume_handle
;
7237 torture_comment(tctx
, "Testing EnumDomainUsers\n");
7240 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainUsers_r(b
, tctx
, &r
),
7241 "EnumDomainUsers failed");
7242 if (NT_STATUS_IS_ERR(r
.out
.result
)) {
7243 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
7244 "failed to enumerate users");
7246 status
= r
.out
.result
;
7248 total_num_entries
+= num_entries
;
7249 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7251 if (total_num_entries_p
) {
7252 *total_num_entries_p
= total_num_entries
;
7258 static bool test_EnumDomainGroups(struct dcerpc_binding_handle
*b
,
7259 struct torture_context
*tctx
,
7260 struct policy_handle
*domain_handle
,
7261 uint32_t *total_num_entries_p
)
7264 struct samr_EnumDomainGroups r
;
7265 uint32_t resume_handle
= 0;
7266 uint32_t num_entries
= 0;
7267 uint32_t total_num_entries
= 0;
7268 struct samr_SamArray
*sam
;
7270 r
.in
.domain_handle
= domain_handle
;
7271 r
.in
.max_size
= (uint32_t)-1;
7272 r
.in
.resume_handle
= &resume_handle
;
7275 r
.out
.num_entries
= &num_entries
;
7276 r
.out
.resume_handle
= &resume_handle
;
7278 torture_comment(tctx
, "Testing EnumDomainGroups\n");
7281 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainGroups_r(b
, tctx
, &r
),
7282 "EnumDomainGroups failed");
7283 if (NT_STATUS_IS_ERR(r
.out
.result
)) {
7284 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
7285 "failed to enumerate groups");
7287 status
= r
.out
.result
;
7289 total_num_entries
+= num_entries
;
7290 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7292 if (total_num_entries_p
) {
7293 *total_num_entries_p
= total_num_entries
;
7299 static bool test_EnumDomainAliases(struct dcerpc_binding_handle
*b
,
7300 struct torture_context
*tctx
,
7301 struct policy_handle
*domain_handle
,
7302 uint32_t *total_num_entries_p
)
7305 struct samr_EnumDomainAliases r
;
7306 uint32_t resume_handle
= 0;
7307 uint32_t num_entries
= 0;
7308 uint32_t total_num_entries
= 0;
7309 struct samr_SamArray
*sam
;
7311 r
.in
.domain_handle
= domain_handle
;
7312 r
.in
.max_size
= (uint32_t)-1;
7313 r
.in
.resume_handle
= &resume_handle
;
7316 r
.out
.num_entries
= &num_entries
;
7317 r
.out
.resume_handle
= &resume_handle
;
7319 torture_comment(tctx
, "Testing EnumDomainAliases\n");
7322 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainAliases_r(b
, tctx
, &r
),
7323 "EnumDomainAliases failed");
7324 if (NT_STATUS_IS_ERR(r
.out
.result
)) {
7325 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
7326 "failed to enumerate aliases");
7328 status
= r
.out
.result
;
7330 total_num_entries
+= num_entries
;
7331 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7333 if (total_num_entries_p
) {
7334 *total_num_entries_p
= total_num_entries
;
7340 static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle
*b
,
7341 struct torture_context
*tctx
,
7342 struct policy_handle
*handle
,
7344 uint32_t *total_num_entries_p
)
7347 struct samr_QueryDisplayInfo r
;
7348 uint32_t total_num_entries
= 0;
7350 r
.in
.domain_handle
= handle
;
7353 r
.in
.max_entries
= (uint32_t)-1;
7354 r
.in
.buf_size
= (uint32_t)-1;
7356 torture_comment(tctx
, "Testing QueryDisplayInfo\n");
7359 uint32_t total_size
;
7360 uint32_t returned_size
;
7361 union samr_DispInfo info
;
7363 r
.out
.total_size
= &total_size
;
7364 r
.out
.returned_size
= &returned_size
;
7367 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &r
),
7368 "failed to query displayinfo");
7369 if (NT_STATUS_IS_ERR(r
.out
.result
)) {
7370 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
7371 "failed to query displayinfo");
7373 status
= r
.out
.result
;
7375 if (*r
.out
.returned_size
== 0) {
7379 switch (r
.in
.level
) {
7381 total_num_entries
+= info
.info1
.count
;
7382 r
.in
.start_idx
+= info
.info1
.entries
[info
.info1
.count
- 1].idx
+ 1;
7385 total_num_entries
+= info
.info2
.count
;
7386 r
.in
.start_idx
+= info
.info2
.entries
[info
.info2
.count
- 1].idx
+ 1;
7389 total_num_entries
+= info
.info3
.count
;
7390 r
.in
.start_idx
+= info
.info3
.entries
[info
.info3
.count
- 1].idx
+ 1;
7393 total_num_entries
+= info
.info4
.count
;
7394 r
.in
.start_idx
+= info
.info4
.entries
[info
.info4
.count
- 1].idx
+ 1;
7397 total_num_entries
+= info
.info5
.count
;
7398 r
.in
.start_idx
+= info
.info5
.entries
[info
.info5
.count
- 1].idx
+ 1;
7404 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7406 if (total_num_entries_p
) {
7407 *total_num_entries_p
= total_num_entries
;
7413 static bool test_ManyObjects(struct dcerpc_pipe
*p
,
7414 struct torture_context
*tctx
,
7415 struct policy_handle
*domain_handle
,
7416 struct dom_sid
*domain_sid
,
7417 struct torture_samr_context
*ctx
)
7419 uint32_t num_total
= ctx
->num_objects_large_dc
;
7420 uint32_t num_enum
= 0;
7421 uint32_t num_disp
= 0;
7422 uint32_t num_created
= 0;
7423 uint32_t num_anounced
= 0;
7425 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7427 struct policy_handle
*handles
= talloc_zero_array(tctx
, struct policy_handle
, num_total
);
7432 struct samr_QueryDomainInfo2 r
;
7433 union samr_DomainInfo
*info
;
7434 r
.in
.domain_handle
= domain_handle
;
7438 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo2_r(b
, tctx
, &r
),
7439 "QueryDomainInfo2 failed");
7440 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
7441 "failed to query domain info");
7443 switch (ctx
->choice
) {
7444 case TORTURE_SAMR_MANY_ACCOUNTS
:
7445 num_anounced
= info
->general
.num_users
;
7447 case TORTURE_SAMR_MANY_GROUPS
:
7448 num_anounced
= info
->general
.num_groups
;
7450 case TORTURE_SAMR_MANY_ALIASES
:
7451 num_anounced
= info
->general
.num_aliases
;
7460 for (i
=0; i
< num_total
; i
++) {
7462 const char *name
= NULL
;
7464 switch (ctx
->choice
) {
7465 case TORTURE_SAMR_MANY_ACCOUNTS
:
7466 name
= talloc_asprintf(tctx
, "%s%04d", TEST_ACCOUNT_NAME
, i
);
7467 torture_assert(tctx
,
7468 test_CreateUser(p
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, 0, NULL
, false),
7469 "failed to create user");
7471 case TORTURE_SAMR_MANY_GROUPS
:
7472 name
= talloc_asprintf(tctx
, "%s%04d", TEST_GROUPNAME
, i
);
7473 torture_assert(tctx
,
7474 test_CreateDomainGroup(b
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, false),
7475 "failed to create group");
7477 case TORTURE_SAMR_MANY_ALIASES
:
7478 name
= talloc_asprintf(tctx
, "%s%04d", TEST_ALIASNAME
, i
);
7479 torture_assert(tctx
,
7480 test_CreateAlias(b
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, false),
7481 "failed to create alias");
7486 if (!policy_handle_empty(&handles
[i
])) {
7493 switch (ctx
->choice
) {
7494 case TORTURE_SAMR_MANY_ACCOUNTS
:
7495 torture_assert(tctx
,
7496 test_EnumDomainUsers(b
, tctx
, domain_handle
, &num_enum
),
7497 "failed to enum users");
7499 case TORTURE_SAMR_MANY_GROUPS
:
7500 torture_assert(tctx
,
7501 test_EnumDomainGroups(b
, tctx
, domain_handle
, &num_enum
),
7502 "failed to enum groups");
7504 case TORTURE_SAMR_MANY_ALIASES
:
7505 torture_assert(tctx
,
7506 test_EnumDomainAliases(b
, tctx
, domain_handle
, &num_enum
),
7507 "failed to enum aliases");
7515 switch (ctx
->choice
) {
7516 case TORTURE_SAMR_MANY_ACCOUNTS
:
7517 torture_assert(tctx
,
7518 test_QueryDisplayInfo_level(b
, tctx
, domain_handle
, 1, &num_disp
),
7519 "failed to query display info");
7521 case TORTURE_SAMR_MANY_GROUPS
:
7522 torture_assert(tctx
,
7523 test_QueryDisplayInfo_level(b
, tctx
, domain_handle
, 3, &num_disp
),
7524 "failed to query display info");
7526 case TORTURE_SAMR_MANY_ALIASES
:
7527 /* no aliases in dispinfo */
7533 /* close or delete */
7535 for (i
=0; i
< num_total
; i
++) {
7537 if (policy_handle_empty(&handles
[i
])) {
7541 if (torture_setting_bool(tctx
, "samba3", false)) {
7542 torture_assert(tctx
,
7543 test_samr_handle_Close(b
, tctx
, &handles
[i
]),
7544 "failed to close handle");
7546 switch (ctx
->choice
) {
7547 case TORTURE_SAMR_MANY_ACCOUNTS
:
7548 torture_assert(tctx
,
7549 test_DeleteUser(b
, tctx
, &handles
[i
]),
7550 "failed to delete user");
7552 case TORTURE_SAMR_MANY_GROUPS
:
7553 torture_assert(tctx
,
7554 test_DeleteDomainGroup(b
, tctx
, &handles
[i
]),
7555 "failed to delete group");
7557 case TORTURE_SAMR_MANY_ALIASES
:
7558 torture_assert(tctx
,
7559 test_DeleteAlias(b
, tctx
, &handles
[i
]),
7560 "failed to delete alias");
7568 talloc_free(handles
);
7570 if (ctx
->choice
== TORTURE_SAMR_MANY_ACCOUNTS
&& num_enum
!= num_anounced
+ num_created
) {
7571 torture_comment(tctx
,
7572 "unexpected number of results (%u) returned in enum call, expected %u\n",
7573 num_enum
, num_anounced
+ num_created
);
7575 torture_comment(tctx
,
7576 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
7577 num_disp
, num_anounced
+ num_created
);
7583 static bool test_Connect(struct dcerpc_binding_handle
*b
,
7584 struct torture_context
*tctx
,
7585 struct policy_handle
*handle
);
7587 static bool test_OpenDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7588 struct torture_samr_context
*ctx
, struct dom_sid
*sid
)
7590 struct samr_OpenDomain r
;
7591 struct policy_handle domain_handle
;
7592 struct policy_handle alias_handle
;
7593 struct policy_handle user_handle
;
7594 struct policy_handle group_handle
;
7596 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7598 ZERO_STRUCT(alias_handle
);
7599 ZERO_STRUCT(user_handle
);
7600 ZERO_STRUCT(group_handle
);
7601 ZERO_STRUCT(domain_handle
);
7603 torture_comment(tctx
, "Testing OpenDomain of %s\n", dom_sid_string(tctx
, sid
));
7605 r
.in
.connect_handle
= &ctx
->handle
;
7606 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7608 r
.out
.domain_handle
= &domain_handle
;
7610 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenDomain_r(b
, tctx
, &r
),
7611 "OpenDomain failed");
7612 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "OpenDomain failed");
7614 /* run the domain tests with the main handle closed - this tests
7615 the servers reference counting */
7616 torture_assert(tctx
, test_samr_handle_Close(b
, tctx
, &ctx
->handle
), "Failed to close SAMR handle");
7618 switch (ctx
->choice
) {
7619 case TORTURE_SAMR_PASSWORDS
:
7620 case TORTURE_SAMR_USER_PRIVILEGES
:
7621 if (!torture_setting_bool(tctx
, "samba3", false)) {
7622 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, NULL
);
7624 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
7626 torture_warning(tctx
, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7629 case TORTURE_SAMR_USER_ATTRIBUTES
:
7630 if (!torture_setting_bool(tctx
, "samba3", false)) {
7631 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, NULL
);
7633 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
7634 /* This test needs 'complex' users to validate */
7635 ret
&= test_QueryDisplayInfo(b
, tctx
, &domain_handle
);
7637 torture_warning(tctx
, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7640 case TORTURE_SAMR_PASSWORDS_PWDLASTSET
:
7641 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
:
7642 case TORTURE_SAMR_PASSWORDS_LOCKOUT
:
7643 if (!torture_setting_bool(tctx
, "samba3", false)) {
7644 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, ctx
->machine_credentials
);
7646 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, ctx
->machine_credentials
, true);
7648 torture_warning(tctx
, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7651 case TORTURE_SAMR_MANY_ACCOUNTS
:
7652 case TORTURE_SAMR_MANY_GROUPS
:
7653 case TORTURE_SAMR_MANY_ALIASES
:
7654 ret
&= test_ManyObjects(p
, tctx
, &domain_handle
, sid
, ctx
);
7656 torture_warning(tctx
, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7659 case TORTURE_SAMR_OTHER
:
7660 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
7662 torture_warning(tctx
, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx
, sid
));
7664 if (!torture_setting_bool(tctx
, "samba3", false)) {
7665 ret
&= test_QuerySecurity(b
, tctx
, &domain_handle
);
7667 ret
&= test_RemoveMemberFromForeignDomain(b
, tctx
, &domain_handle
);
7668 ret
&= test_CreateAlias(b
, tctx
, &domain_handle
, TEST_ALIASNAME
, &alias_handle
, sid
, true);
7669 ret
&= test_CreateDomainGroup(b
, tctx
, &domain_handle
, TEST_GROUPNAME
, &group_handle
, sid
, true);
7670 ret
&= test_GetAliasMembership(b
, tctx
, &domain_handle
);
7671 ret
&= test_QueryDomainInfo(p
, tctx
, &domain_handle
);
7672 ret
&= test_QueryDomainInfo2(b
, tctx
, &domain_handle
);
7673 ret
&= test_EnumDomainUsers_all(b
, tctx
, &domain_handle
);
7674 ret
&= test_EnumDomainUsers_async(p
, tctx
, &domain_handle
);
7675 ret
&= test_EnumDomainGroups_all(b
, tctx
, &domain_handle
);
7676 ret
&= test_EnumDomainAliases_all(b
, tctx
, &domain_handle
);
7677 ret
&= test_QueryDisplayInfo2(b
, tctx
, &domain_handle
);
7678 ret
&= test_QueryDisplayInfo3(b
, tctx
, &domain_handle
);
7679 ret
&= test_QueryDisplayInfo_continue(b
, tctx
, &domain_handle
);
7681 if (torture_setting_bool(tctx
, "samba4", false)) {
7682 torture_comment(tctx
, "skipping GetDisplayEnumerationIndex test against Samba4\n");
7684 ret
&= test_GetDisplayEnumerationIndex(b
, tctx
, &domain_handle
);
7685 ret
&= test_GetDisplayEnumerationIndex2(b
, tctx
, &domain_handle
);
7687 ret
&= test_GroupList(b
, tctx
, sid
, &domain_handle
);
7688 ret
&= test_TestPrivateFunctionsDomain(b
, tctx
, &domain_handle
);
7689 ret
&= test_RidToSid(b
, tctx
, sid
, &domain_handle
);
7690 ret
&= test_GetBootKeyInformation(b
, tctx
, &domain_handle
);
7692 torture_comment(tctx
, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7697 if (!policy_handle_empty(&user_handle
) &&
7698 !test_DeleteUser(b
, tctx
, &user_handle
)) {
7702 if (!policy_handle_empty(&alias_handle
) &&
7703 !test_DeleteAlias(b
, tctx
, &alias_handle
)) {
7707 if (!policy_handle_empty(&group_handle
) &&
7708 !test_DeleteDomainGroup(b
, tctx
, &group_handle
)) {
7712 torture_assert(tctx
, test_samr_handle_Close(b
, tctx
, &domain_handle
), "Failed to close SAMR domain handle");
7714 torture_assert(tctx
, test_Connect(b
, tctx
, &ctx
->handle
), "Faile to re-connect SAMR handle");
7715 /* reconnect the main handle */
7718 torture_warning(tctx
, "Testing domain %s failed!\n", dom_sid_string(tctx
, sid
));
7724 static bool test_LookupDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7725 struct torture_samr_context
*ctx
, const char *domain
)
7727 struct samr_LookupDomain r
;
7728 struct dom_sid2
*sid
= NULL
;
7729 struct lsa_String n1
;
7730 struct lsa_String n2
;
7732 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7734 torture_comment(tctx
, "Testing LookupDomain(%s)\n", domain
);
7736 /* check for correct error codes */
7737 r
.in
.connect_handle
= &ctx
->handle
;
7738 r
.in
.domain_name
= &n2
;
7742 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupDomain_r(b
, tctx
, &r
),
7743 "LookupDomain failed");
7744 torture_assert_ntstatus_equal(tctx
, NT_STATUS_INVALID_PARAMETER
, r
.out
.result
, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
7746 init_lsa_String(&n2
, "xxNODOMAINxx");
7748 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupDomain_r(b
, tctx
, &r
),
7749 "LookupDomain failed");
7750 torture_assert_ntstatus_equal(tctx
, NT_STATUS_NO_SUCH_DOMAIN
, r
.out
.result
, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
7752 r
.in
.connect_handle
= &ctx
->handle
;
7754 init_lsa_String(&n1
, domain
);
7755 r
.in
.domain_name
= &n1
;
7757 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupDomain_r(b
, tctx
, &r
),
7758 "LookupDomain failed");
7759 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LookupDomain");
7761 if (!test_GetDomPwInfo(p
, tctx
, &n1
)) {
7765 if (!test_OpenDomain(p
, tctx
, ctx
, *r
.out
.sid
)) {
7773 static bool test_EnumDomains(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7774 struct torture_samr_context
*ctx
)
7776 struct samr_EnumDomains r
;
7777 uint32_t resume_handle
= 0;
7778 uint32_t num_entries
= 0;
7779 struct samr_SamArray
*sam
= NULL
;
7782 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7784 r
.in
.connect_handle
= &ctx
->handle
;
7785 r
.in
.resume_handle
= &resume_handle
;
7786 r
.in
.buf_size
= (uint32_t)-1;
7787 r
.out
.resume_handle
= &resume_handle
;
7788 r
.out
.num_entries
= &num_entries
;
7791 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomains_r(b
, tctx
, &r
),
7792 "EnumDomains failed");
7793 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "EnumDomains failed");
7799 for (i
=0;i
<sam
->count
;i
++) {
7800 if (!test_LookupDomain(p
, tctx
, ctx
,
7801 sam
->entries
[i
].name
.string
)) {
7806 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomains_r(b
, tctx
, &r
),
7807 "EnumDomains failed");
7808 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "EnumDomains failed");
7814 static bool test_Connect(struct dcerpc_binding_handle
*b
,
7815 struct torture_context
*tctx
,
7816 struct policy_handle
*handle
)
7818 struct samr_Connect r
;
7819 struct samr_Connect2 r2
;
7820 struct samr_Connect3 r3
;
7821 struct samr_Connect4 r4
;
7822 struct samr_Connect5 r5
;
7823 union samr_ConnectInfo info
;
7824 struct policy_handle h
;
7825 uint32_t level_out
= 0;
7826 bool ret
= true, got_handle
= false;
7828 torture_comment(tctx
, "Testing samr_Connect\n");
7830 r
.in
.system_name
= NULL
;
7831 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7832 r
.out
.connect_handle
= &h
;
7834 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect_r(b
, tctx
, &r
),
7836 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
7837 torture_comment(tctx
, "Connect failed - %s\n", nt_errstr(r
.out
.result
));
7844 torture_comment(tctx
, "Testing samr_Connect2\n");
7846 r2
.in
.system_name
= NULL
;
7847 r2
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7848 r2
.out
.connect_handle
= &h
;
7850 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect2_r(b
, tctx
, &r2
),
7852 if (!NT_STATUS_IS_OK(r2
.out
.result
)) {
7853 torture_comment(tctx
, "Connect2 failed - %s\n", nt_errstr(r2
.out
.result
));
7857 test_samr_handle_Close(b
, tctx
, handle
);
7863 torture_comment(tctx
, "Testing samr_Connect3\n");
7865 r3
.in
.system_name
= NULL
;
7867 r3
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7868 r3
.out
.connect_handle
= &h
;
7870 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect3_r(b
, tctx
, &r3
),
7872 if (!NT_STATUS_IS_OK(r3
.out
.result
)) {
7873 torture_warning(tctx
, "Connect3 failed - %s\n", nt_errstr(r3
.out
.result
));
7877 test_samr_handle_Close(b
, tctx
, handle
);
7883 torture_comment(tctx
, "Testing samr_Connect4\n");
7885 r4
.in
.system_name
= "";
7886 r4
.in
.client_version
= 0;
7887 r4
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7888 r4
.out
.connect_handle
= &h
;
7890 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect4_r(b
, tctx
, &r4
),
7892 if (!NT_STATUS_IS_OK(r4
.out
.result
)) {
7893 torture_warning(tctx
, "Connect4 failed - %s\n", nt_errstr(r4
.out
.result
));
7897 test_samr_handle_Close(b
, tctx
, handle
);
7903 torture_comment(tctx
, "Testing samr_Connect5\n");
7905 info
.info1
.client_version
= 0;
7906 info
.info1
.unknown2
= 0;
7908 r5
.in
.system_name
= "";
7909 r5
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7911 r5
.out
.level_out
= &level_out
;
7912 r5
.in
.info_in
= &info
;
7913 r5
.out
.info_out
= &info
;
7914 r5
.out
.connect_handle
= &h
;
7916 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect5_r(b
, tctx
, &r5
),
7918 if (!NT_STATUS_IS_OK(r5
.out
.result
)) {
7919 torture_warning(tctx
, "Connect5 failed - %s\n", nt_errstr(r5
.out
.result
));
7923 test_samr_handle_Close(b
, tctx
, handle
);
7933 static bool test_samr_ValidatePassword(struct dcerpc_pipe
*p
,
7934 struct torture_context
*tctx
)
7936 struct samr_ValidatePassword r
;
7937 union samr_ValidatePasswordReq req
;
7938 union samr_ValidatePasswordRep
*repp
= NULL
;
7940 const char *passwords
[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL
};
7942 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7944 torture_comment(tctx
, "Testing samr_ValidatePassword\n");
7947 r
.in
.level
= NetValidatePasswordReset
;
7952 req
.req3
.account
.string
= "non-existant-account-aklsdji";
7954 for (i
=0; passwords
[i
]; i
++) {
7955 req
.req3
.password
.string
= passwords
[i
];
7957 status
= dcerpc_samr_ValidatePassword_r(b
, tctx
, &r
);
7958 if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE
)) {
7959 torture_skip(tctx
, "ValidatePassword not supported by server\n");
7961 torture_assert_ntstatus_ok(tctx
, status
,
7962 "samr_ValidatePassword failed");
7963 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
7964 "samr_ValidatePassword failed");
7965 torture_comment(tctx
, "Server %s password '%s' with code %i\n",
7966 repp
->ctr3
.status
==SAMR_VALIDATION_STATUS_SUCCESS
?"allowed":"refused",
7967 req
.req3
.password
.string
, repp
->ctr3
.status
);
7973 bool torture_rpc_samr(struct torture_context
*torture
)
7976 struct dcerpc_pipe
*p
;
7978 struct torture_samr_context
*ctx
;
7979 struct dcerpc_binding_handle
*b
;
7981 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7982 if (!NT_STATUS_IS_OK(status
)) {
7985 b
= p
->binding_handle
;
7987 ctx
= talloc_zero(torture
, struct torture_samr_context
);
7989 ctx
->choice
= TORTURE_SAMR_OTHER
;
7991 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
7993 if (!torture_setting_bool(torture
, "samba3", false)) {
7994 ret
&= test_QuerySecurity(b
, torture
, &ctx
->handle
);
7997 ret
&= test_EnumDomains(p
, torture
, ctx
);
7999 ret
&= test_SetDsrmPassword(b
, torture
, &ctx
->handle
);
8001 ret
&= test_Shutdown(b
, torture
, &ctx
->handle
);
8003 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8009 bool torture_rpc_samr_users(struct torture_context
*torture
)
8012 struct dcerpc_pipe
*p
;
8014 struct torture_samr_context
*ctx
;
8015 struct dcerpc_binding_handle
*b
;
8017 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8018 if (!NT_STATUS_IS_OK(status
)) {
8021 b
= p
->binding_handle
;
8023 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8025 ctx
->choice
= TORTURE_SAMR_USER_ATTRIBUTES
;
8027 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8029 if (!torture_setting_bool(torture
, "samba3", false)) {
8030 ret
&= test_QuerySecurity(b
, torture
, &ctx
->handle
);
8033 ret
&= test_EnumDomains(p
, torture
, ctx
);
8035 ret
&= test_SetDsrmPassword(b
, torture
, &ctx
->handle
);
8037 ret
&= test_Shutdown(b
, torture
, &ctx
->handle
);
8039 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8045 bool torture_rpc_samr_passwords(struct torture_context
*torture
)
8048 struct dcerpc_pipe
*p
;
8050 struct torture_samr_context
*ctx
;
8051 struct dcerpc_binding_handle
*b
;
8053 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8054 if (!NT_STATUS_IS_OK(status
)) {
8057 b
= p
->binding_handle
;
8059 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8061 ctx
->choice
= TORTURE_SAMR_PASSWORDS
;
8063 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8065 ret
&= test_EnumDomains(p
, torture
, ctx
);
8067 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8069 ret
&= test_samr_ValidatePassword(p
, torture
);
8074 static bool torture_rpc_samr_pwdlastset(struct torture_context
*torture
,
8075 struct dcerpc_pipe
*p2
,
8076 struct cli_credentials
*machine_credentials
)
8079 struct dcerpc_pipe
*p
;
8081 struct torture_samr_context
*ctx
;
8082 struct dcerpc_binding_handle
*b
;
8084 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8085 if (!NT_STATUS_IS_OK(status
)) {
8088 b
= p
->binding_handle
;
8090 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8092 ctx
->choice
= TORTURE_SAMR_PASSWORDS_PWDLASTSET
;
8093 ctx
->machine_credentials
= machine_credentials
;
8095 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8097 ret
&= test_EnumDomains(p
, torture
, ctx
);
8099 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8104 struct torture_suite
*torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX
*mem_ctx
)
8106 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.passwords.pwdlastset");
8107 struct torture_rpc_tcase
*tcase
;
8109 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
8111 TEST_ACCOUNT_NAME_PWD
);
8113 torture_rpc_tcase_add_test_creds(tcase
, "pwdLastSet",
8114 torture_rpc_samr_pwdlastset
);
8119 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context
*torture
,
8120 struct dcerpc_pipe
*p2
,
8121 struct cli_credentials
*machine_credentials
)
8124 struct dcerpc_pipe
*p
;
8126 struct torture_samr_context
*ctx
;
8127 struct dcerpc_binding_handle
*b
;
8129 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8130 if (!NT_STATUS_IS_OK(status
)) {
8133 b
= p
->binding_handle
;
8135 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8137 ctx
->choice
= TORTURE_SAMR_USER_PRIVILEGES
;
8138 ctx
->machine_credentials
= machine_credentials
;
8140 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8142 ret
&= test_EnumDomains(p
, torture
, ctx
);
8144 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8149 struct torture_suite
*torture_rpc_samr_user_privileges(TALLOC_CTX
*mem_ctx
)
8151 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.users.privileges");
8152 struct torture_rpc_tcase
*tcase
;
8154 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
8156 TEST_ACCOUNT_NAME_PWD
);
8158 torture_rpc_tcase_add_test_creds(tcase
, "delete_privileged_user",
8159 torture_rpc_samr_users_privileges_delete_user
);
8164 static bool torture_rpc_samr_many_accounts(struct torture_context
*torture
,
8165 struct dcerpc_pipe
*p2
,
8169 struct dcerpc_pipe
*p
;
8171 struct torture_samr_context
*ctx
=
8172 talloc_get_type_abort(data
, struct torture_samr_context
);
8173 struct dcerpc_binding_handle
*b
;
8175 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8176 if (!NT_STATUS_IS_OK(status
)) {
8179 b
= p
->binding_handle
;
8181 ctx
->choice
= TORTURE_SAMR_MANY_ACCOUNTS
;
8182 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
8183 ctx
->num_objects_large_dc
);
8185 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8187 ret
&= test_EnumDomains(p
, torture
, ctx
);
8189 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8194 static bool torture_rpc_samr_many_groups(struct torture_context
*torture
,
8195 struct dcerpc_pipe
*p2
,
8199 struct dcerpc_pipe
*p
;
8201 struct torture_samr_context
*ctx
=
8202 talloc_get_type_abort(data
, struct torture_samr_context
);
8203 struct dcerpc_binding_handle
*b
;
8205 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8206 if (!NT_STATUS_IS_OK(status
)) {
8209 b
= p
->binding_handle
;
8211 ctx
->choice
= TORTURE_SAMR_MANY_GROUPS
;
8212 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
8213 ctx
->num_objects_large_dc
);
8215 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8217 ret
&= test_EnumDomains(p
, torture
, ctx
);
8219 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8224 static bool torture_rpc_samr_many_aliases(struct torture_context
*torture
,
8225 struct dcerpc_pipe
*p2
,
8229 struct dcerpc_pipe
*p
;
8231 struct torture_samr_context
*ctx
=
8232 talloc_get_type_abort(data
, struct torture_samr_context
);
8233 struct dcerpc_binding_handle
*b
;
8235 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8236 if (!NT_STATUS_IS_OK(status
)) {
8239 b
= p
->binding_handle
;
8241 ctx
->choice
= TORTURE_SAMR_MANY_ALIASES
;
8242 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
8243 ctx
->num_objects_large_dc
);
8245 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8247 ret
&= test_EnumDomains(p
, torture
, ctx
);
8249 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8254 struct torture_suite
*torture_rpc_samr_large_dc(TALLOC_CTX
*mem_ctx
)
8256 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.large-dc");
8257 struct torture_rpc_tcase
*tcase
;
8258 struct torture_samr_context
*ctx
;
8260 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "samr", &ndr_table_samr
);
8262 ctx
= talloc_zero(suite
, struct torture_samr_context
);
8263 ctx
->num_objects_large_dc
= 150;
8265 torture_rpc_tcase_add_test_ex(tcase
, "many_aliases",
8266 torture_rpc_samr_many_aliases
, ctx
);
8267 torture_rpc_tcase_add_test_ex(tcase
, "many_groups",
8268 torture_rpc_samr_many_groups
, ctx
);
8269 torture_rpc_tcase_add_test_ex(tcase
, "many_accounts",
8270 torture_rpc_samr_many_accounts
, ctx
);
8275 static bool torture_rpc_samr_badpwdcount(struct torture_context
*torture
,
8276 struct dcerpc_pipe
*p2
,
8277 struct cli_credentials
*machine_credentials
)
8280 struct dcerpc_pipe
*p
;
8282 struct torture_samr_context
*ctx
;
8283 struct dcerpc_binding_handle
*b
;
8285 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8286 if (!NT_STATUS_IS_OK(status
)) {
8289 b
= p
->binding_handle
;
8291 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8293 ctx
->choice
= TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
;
8294 ctx
->machine_credentials
= machine_credentials
;
8296 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8298 ret
&= test_EnumDomains(p
, torture
, ctx
);
8300 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8305 struct torture_suite
*torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX
*mem_ctx
)
8307 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.passwords.badpwdcount");
8308 struct torture_rpc_tcase
*tcase
;
8310 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
8312 TEST_ACCOUNT_NAME_PWD
);
8314 torture_rpc_tcase_add_test_creds(tcase
, "badPwdCount",
8315 torture_rpc_samr_badpwdcount
);
8320 static bool torture_rpc_samr_lockout(struct torture_context
*torture
,
8321 struct dcerpc_pipe
*p2
,
8322 struct cli_credentials
*machine_credentials
)
8325 struct dcerpc_pipe
*p
;
8327 struct torture_samr_context
*ctx
;
8328 struct dcerpc_binding_handle
*b
;
8330 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8331 if (!NT_STATUS_IS_OK(status
)) {
8334 b
= p
->binding_handle
;
8336 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8338 ctx
->choice
= TORTURE_SAMR_PASSWORDS_LOCKOUT
;
8339 ctx
->machine_credentials
= machine_credentials
;
8341 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8343 ret
&= test_EnumDomains(p
, torture
, ctx
);
8345 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8350 struct torture_suite
*torture_rpc_samr_passwords_lockout(TALLOC_CTX
*mem_ctx
)
8352 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.passwords.lockout");
8353 struct torture_rpc_tcase
*tcase
;
8355 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
8357 TEST_ACCOUNT_NAME_PWD
);
8359 torture_rpc_tcase_add_test_creds(tcase
, "lockout",
8360 torture_rpc_samr_lockout
);