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) Jelmer Vernooij 2005-2007
8 Copyright (C) Guenther Deschner 2008-2010
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "torture/torture.h"
27 #include "system/time.h"
28 #include "system/network.h"
29 #include "librpc/gen_ndr/lsa.h"
30 #include "librpc/gen_ndr/ndr_netlogon.h"
31 #include "librpc/gen_ndr/ndr_netlogon_c.h"
32 #include "librpc/gen_ndr/ndr_samr_c.h"
33 #include "librpc/gen_ndr/ndr_lsa_c.h"
34 #include "../lib/crypto/crypto.h"
35 #include "libcli/auth/libcli_auth.h"
36 #include "libcli/security/security.h"
37 #include "torture/rpc/torture_rpc.h"
38 #include "param/param.h"
39 #include "auth/gensec/gensec.h"
40 #include "auth/gensec/schannel.h"
41 #include "auth/gensec/gensec_proto.h"
42 #include "../libcli/auth/schannel.h"
44 #define TEST_ACCOUNT_NAME "samrtorturetest"
45 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
46 #define TEST_ALIASNAME "samrtorturetestalias"
47 #define TEST_GROUPNAME "samrtorturetestgroup"
48 #define TEST_MACHINENAME "samrtestmach$"
49 #define TEST_DOMAINNAME "samrtestdom$"
51 enum torture_samr_choice
{
52 TORTURE_SAMR_PASSWORDS
,
53 TORTURE_SAMR_PASSWORDS_PWDLASTSET
,
54 TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
,
55 TORTURE_SAMR_PASSWORDS_LOCKOUT
,
56 TORTURE_SAMR_USER_ATTRIBUTES
,
57 TORTURE_SAMR_USER_PRIVILEGES
,
59 TORTURE_SAMR_MANY_ACCOUNTS
,
60 TORTURE_SAMR_MANY_GROUPS
,
61 TORTURE_SAMR_MANY_ALIASES
64 struct torture_samr_context
{
65 struct policy_handle handle
;
66 struct cli_credentials
*machine_credentials
;
67 enum torture_samr_choice choice
;
68 uint32_t num_objects_large_dc
;
71 static bool test_QueryUserInfo(struct dcerpc_binding_handle
*b
,
72 struct torture_context
*tctx
,
73 struct policy_handle
*handle
);
75 static bool test_QueryUserInfo2(struct dcerpc_binding_handle
*b
,
76 struct torture_context
*tctx
,
77 struct policy_handle
*handle
);
79 static bool test_QueryAliasInfo(struct dcerpc_binding_handle
*b
,
80 struct torture_context
*tctx
,
81 struct policy_handle
*handle
);
83 static bool test_ChangePassword(struct dcerpc_pipe
*p
,
84 struct torture_context
*tctx
,
85 const char *acct_name
,
86 struct policy_handle
*domain_handle
, char **password
);
88 static void init_lsa_String(struct lsa_String
*string
, const char *s
)
93 static void init_lsa_StringLarge(struct lsa_StringLarge
*string
, const char *s
)
98 static void init_lsa_BinaryString(struct lsa_BinaryString
*string
, const char *s
, uint32_t length
)
100 string
->length
= length
;
101 string
->size
= length
;
102 string
->array
= (uint16_t *)discard_const(s
);
105 bool test_samr_handle_Close(struct dcerpc_binding_handle
*b
,
106 struct torture_context
*tctx
,
107 struct policy_handle
*handle
)
111 r
.in
.handle
= handle
;
112 r
.out
.handle
= handle
;
114 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Close_r(b
, tctx
, &r
),
116 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "Close failed");
121 static bool test_Shutdown(struct dcerpc_binding_handle
*b
,
122 struct torture_context
*tctx
,
123 struct policy_handle
*handle
)
125 struct samr_Shutdown r
;
127 if (!torture_setting_bool(tctx
, "dangerous", false)) {
128 torture_skip(tctx
, "samr_Shutdown disabled - enable dangerous tests to use\n");
132 r
.in
.connect_handle
= handle
;
134 torture_comment(tctx
, "Testing samr_Shutdown\n");
136 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Shutdown_r(b
, tctx
, &r
),
138 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "Shutdown failed");
143 static bool test_SetDsrmPassword(struct dcerpc_binding_handle
*b
,
144 struct torture_context
*tctx
,
145 struct policy_handle
*handle
)
147 struct samr_SetDsrmPassword r
;
148 struct lsa_String string
;
149 struct samr_Password hash
;
151 if (!torture_setting_bool(tctx
, "dangerous", false)) {
152 torture_skip(tctx
, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
155 E_md4hash("TeSTDSRM123", hash
.hash
);
157 init_lsa_String(&string
, "Administrator");
163 torture_comment(tctx
, "Testing samr_SetDsrmPassword\n");
165 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDsrmPassword_r(b
, tctx
, &r
),
166 "SetDsrmPassword failed");
167 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_NOT_SUPPORTED
, "SetDsrmPassword failed");
173 static bool test_QuerySecurity(struct dcerpc_binding_handle
*b
,
174 struct torture_context
*tctx
,
175 struct policy_handle
*handle
)
177 struct samr_QuerySecurity r
;
178 struct samr_SetSecurity s
;
179 struct sec_desc_buf
*sdbuf
= NULL
;
181 r
.in
.handle
= handle
;
183 r
.out
.sdbuf
= &sdbuf
;
185 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QuerySecurity_r(b
, tctx
, &r
),
186 "QuerySecurity failed");
187 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "QuerySecurity failed");
189 torture_assert(tctx
, sdbuf
!= NULL
, "sdbuf is NULL");
191 s
.in
.handle
= handle
;
195 if (torture_setting_bool(tctx
, "samba4", false)) {
196 torture_skip(tctx
, "skipping SetSecurity test against Samba4\n");
199 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetSecurity_r(b
, tctx
, &s
),
200 "SetSecurity failed");
201 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "SetSecurity failed");
203 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QuerySecurity_r(b
, tctx
, &r
),
204 "QuerySecurity failed");
205 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "QuerySecurity failed");
211 static bool test_SetUserInfo(struct dcerpc_binding_handle
*b
, struct torture_context
*tctx
,
212 struct policy_handle
*handle
, uint32_t base_acct_flags
,
213 const char *base_account_name
)
215 struct samr_SetUserInfo s
;
216 struct samr_SetUserInfo2 s2
;
217 struct samr_QueryUserInfo q
;
218 struct samr_QueryUserInfo q0
;
219 union samr_UserInfo u
;
220 union samr_UserInfo
*info
;
222 const char *test_account_name
;
224 uint32_t user_extra_flags
= 0;
226 if (!torture_setting_bool(tctx
, "samba3", false)) {
227 if (base_acct_flags
== ACB_NORMAL
) {
228 /* When created, accounts are expired by default */
229 user_extra_flags
= ACB_PW_EXPIRED
;
233 s
.in
.user_handle
= handle
;
236 s2
.in
.user_handle
= handle
;
239 q
.in
.user_handle
= handle
;
243 #define TESTCALL(call, r) \
244 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ ##call## _r(b, tctx, &r),\
246 if (!NT_STATUS_IS_OK(r.out.result)) { \
247 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
248 r.in.level, nt_errstr(r.out.result), __location__); \
253 #define STRING_EQUAL(s1, s2, field) \
254 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
255 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
256 #field, s2, __location__); \
261 #define MEM_EQUAL(s1, s2, length, field) \
262 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
263 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
264 #field, (const char *)s2, __location__); \
269 #define INT_EQUAL(i1, i2, field) \
271 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
272 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
277 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
278 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
280 TESTCALL(QueryUserInfo, q) \
282 s2.in.level = lvl1; \
285 ZERO_STRUCT(u.info21); \
286 u.info21.fields_present = fpval; \
288 init_lsa_String(&u.info ## lvl1.field1, value); \
289 TESTCALL(SetUserInfo, s) \
290 TESTCALL(SetUserInfo2, s2) \
291 init_lsa_String(&u.info ## lvl1.field1, ""); \
292 TESTCALL(QueryUserInfo, q); \
294 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
296 TESTCALL(QueryUserInfo, q) \
298 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
301 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
302 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
304 TESTCALL(QueryUserInfo, q) \
306 s2.in.level = lvl1; \
309 ZERO_STRUCT(u.info21); \
310 u.info21.fields_present = fpval; \
312 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
313 TESTCALL(SetUserInfo, s) \
314 TESTCALL(SetUserInfo2, s2) \
315 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
316 TESTCALL(QueryUserInfo, q); \
318 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
320 TESTCALL(QueryUserInfo, q) \
322 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
325 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
326 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
328 TESTCALL(QueryUserInfo, q) \
330 s2.in.level = lvl1; \
333 uint8_t *bits = u.info21.logon_hours.bits; \
334 ZERO_STRUCT(u.info21); \
335 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
336 u.info21.logon_hours.units_per_week = 168; \
337 u.info21.logon_hours.bits = bits; \
339 u.info21.fields_present = fpval; \
341 u.info ## lvl1.field1 = value; \
342 TESTCALL(SetUserInfo, s) \
343 TESTCALL(SetUserInfo2, s2) \
344 u.info ## lvl1.field1 = 0; \
345 TESTCALL(QueryUserInfo, q); \
347 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
349 TESTCALL(QueryUserInfo, q) \
351 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
354 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
355 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
359 do { TESTCALL(QueryUserInfo
, q0
) } while (0);
361 TEST_USERINFO_STRING(2, comment
, 1, comment
, "xx2-1 comment", 0);
362 TEST_USERINFO_STRING(2, comment
, 21, comment
, "xx2-21 comment", 0);
363 TEST_USERINFO_STRING(21, comment
, 21, comment
, "xx21-21 comment",
366 test_account_name
= talloc_asprintf(tctx
, "%sxx7-1", base_account_name
);
367 TEST_USERINFO_STRING(7, account_name
, 1, account_name
, base_account_name
, 0);
368 test_account_name
= talloc_asprintf(tctx
, "%sxx7-3", base_account_name
);
369 TEST_USERINFO_STRING(7, account_name
, 3, account_name
, base_account_name
, 0);
370 test_account_name
= talloc_asprintf(tctx
, "%sxx7-5", base_account_name
);
371 TEST_USERINFO_STRING(7, account_name
, 5, account_name
, base_account_name
, 0);
372 test_account_name
= talloc_asprintf(tctx
, "%sxx7-6", base_account_name
);
373 TEST_USERINFO_STRING(7, account_name
, 6, account_name
, base_account_name
, 0);
374 test_account_name
= talloc_asprintf(tctx
, "%sxx7-7", base_account_name
);
375 TEST_USERINFO_STRING(7, account_name
, 7, account_name
, base_account_name
, 0);
376 test_account_name
= talloc_asprintf(tctx
, "%sxx7-21", base_account_name
);
377 TEST_USERINFO_STRING(7, account_name
, 21, account_name
, base_account_name
, 0);
378 test_account_name
= base_account_name
;
379 TEST_USERINFO_STRING(21, account_name
, 21, account_name
, base_account_name
,
380 SAMR_FIELD_ACCOUNT_NAME
);
382 TEST_USERINFO_STRING(6, full_name
, 1, full_name
, "xx6-1 full_name", 0);
383 TEST_USERINFO_STRING(6, full_name
, 3, full_name
, "xx6-3 full_name", 0);
384 TEST_USERINFO_STRING(6, full_name
, 5, full_name
, "xx6-5 full_name", 0);
385 TEST_USERINFO_STRING(6, full_name
, 6, full_name
, "xx6-6 full_name", 0);
386 TEST_USERINFO_STRING(6, full_name
, 8, full_name
, "xx6-8 full_name", 0);
387 TEST_USERINFO_STRING(6, full_name
, 21, full_name
, "xx6-21 full_name", 0);
388 TEST_USERINFO_STRING(8, full_name
, 21, full_name
, "xx8-21 full_name", 0);
389 TEST_USERINFO_STRING(21, full_name
, 21, full_name
, "xx21-21 full_name",
390 SAMR_FIELD_FULL_NAME
);
392 TEST_USERINFO_STRING(6, full_name
, 1, full_name
, "", 0);
393 TEST_USERINFO_STRING(6, full_name
, 3, full_name
, "", 0);
394 TEST_USERINFO_STRING(6, full_name
, 5, full_name
, "", 0);
395 TEST_USERINFO_STRING(6, full_name
, 6, full_name
, "", 0);
396 TEST_USERINFO_STRING(6, full_name
, 8, full_name
, "", 0);
397 TEST_USERINFO_STRING(6, full_name
, 21, full_name
, "", 0);
398 TEST_USERINFO_STRING(8, full_name
, 21, full_name
, "", 0);
399 TEST_USERINFO_STRING(21, full_name
, 21, full_name
, "",
400 SAMR_FIELD_FULL_NAME
);
402 TEST_USERINFO_STRING(11, logon_script
, 3, logon_script
, "xx11-3 logon_script", 0);
403 TEST_USERINFO_STRING(11, logon_script
, 5, logon_script
, "xx11-5 logon_script", 0);
404 TEST_USERINFO_STRING(11, logon_script
, 21, logon_script
, "xx11-21 logon_script", 0);
405 TEST_USERINFO_STRING(21, logon_script
, 21, logon_script
, "xx21-21 logon_script",
406 SAMR_FIELD_LOGON_SCRIPT
);
408 TEST_USERINFO_STRING(12, profile_path
, 3, profile_path
, "xx12-3 profile_path", 0);
409 TEST_USERINFO_STRING(12, profile_path
, 5, profile_path
, "xx12-5 profile_path", 0);
410 TEST_USERINFO_STRING(12, profile_path
, 21, profile_path
, "xx12-21 profile_path", 0);
411 TEST_USERINFO_STRING(21, profile_path
, 21, profile_path
, "xx21-21 profile_path",
412 SAMR_FIELD_PROFILE_PATH
);
414 TEST_USERINFO_STRING(10, home_directory
, 3, home_directory
, "xx10-3 home_directory", 0);
415 TEST_USERINFO_STRING(10, home_directory
, 5, home_directory
, "xx10-5 home_directory", 0);
416 TEST_USERINFO_STRING(10, home_directory
, 21, home_directory
, "xx10-21 home_directory", 0);
417 TEST_USERINFO_STRING(21, home_directory
, 21, home_directory
, "xx21-21 home_directory",
418 SAMR_FIELD_HOME_DIRECTORY
);
419 TEST_USERINFO_STRING(21, home_directory
, 10, home_directory
, "xx21-10 home_directory",
420 SAMR_FIELD_HOME_DIRECTORY
);
422 TEST_USERINFO_STRING(10, home_drive
, 3, home_drive
, "xx10-3 home_drive", 0);
423 TEST_USERINFO_STRING(10, home_drive
, 5, home_drive
, "xx10-5 home_drive", 0);
424 TEST_USERINFO_STRING(10, home_drive
, 21, home_drive
, "xx10-21 home_drive", 0);
425 TEST_USERINFO_STRING(21, home_drive
, 21, home_drive
, "xx21-21 home_drive",
426 SAMR_FIELD_HOME_DRIVE
);
427 TEST_USERINFO_STRING(21, home_drive
, 10, home_drive
, "xx21-10 home_drive",
428 SAMR_FIELD_HOME_DRIVE
);
430 TEST_USERINFO_STRING(13, description
, 1, description
, "xx13-1 description", 0);
431 TEST_USERINFO_STRING(13, description
, 5, description
, "xx13-5 description", 0);
432 TEST_USERINFO_STRING(13, description
, 21, description
, "xx13-21 description", 0);
433 TEST_USERINFO_STRING(21, description
, 21, description
, "xx21-21 description",
434 SAMR_FIELD_DESCRIPTION
);
436 TEST_USERINFO_STRING(14, workstations
, 3, workstations
, "14workstation3", 0);
437 TEST_USERINFO_STRING(14, workstations
, 5, workstations
, "14workstation4", 0);
438 TEST_USERINFO_STRING(14, workstations
, 21, workstations
, "14workstation21", 0);
439 TEST_USERINFO_STRING(21, workstations
, 21, workstations
, "21workstation21",
440 SAMR_FIELD_WORKSTATIONS
);
441 TEST_USERINFO_STRING(21, workstations
, 3, workstations
, "21workstation3",
442 SAMR_FIELD_WORKSTATIONS
);
443 TEST_USERINFO_STRING(21, workstations
, 5, workstations
, "21workstation5",
444 SAMR_FIELD_WORKSTATIONS
);
445 TEST_USERINFO_STRING(21, workstations
, 14, workstations
, "21workstation14",
446 SAMR_FIELD_WORKSTATIONS
);
448 TEST_USERINFO_BINARYSTRING(20, parameters
, 21, parameters
, "xx20-21 parameters", 0);
449 TEST_USERINFO_BINARYSTRING(21, parameters
, 21, parameters
, "xx21-21 parameters",
450 SAMR_FIELD_PARAMETERS
);
451 TEST_USERINFO_BINARYSTRING(21, parameters
, 20, parameters
, "xx21-20 parameters",
452 SAMR_FIELD_PARAMETERS
);
453 /* also empty user parameters are allowed */
454 TEST_USERINFO_BINARYSTRING(20, parameters
, 21, parameters
, "", 0);
455 TEST_USERINFO_BINARYSTRING(21, parameters
, 21, parameters
, "",
456 SAMR_FIELD_PARAMETERS
);
457 TEST_USERINFO_BINARYSTRING(21, parameters
, 20, parameters
, "",
458 SAMR_FIELD_PARAMETERS
);
460 /* Samba 3 cannot store country_code and code_page atm. - gd */
461 if (!torture_setting_bool(tctx
, "samba3", false)) {
462 TEST_USERINFO_INT(2, country_code
, 2, country_code
, __LINE__
, 0);
463 TEST_USERINFO_INT(2, country_code
, 21, country_code
, __LINE__
, 0);
464 TEST_USERINFO_INT(21, country_code
, 21, country_code
, __LINE__
,
465 SAMR_FIELD_COUNTRY_CODE
);
466 TEST_USERINFO_INT(21, country_code
, 2, country_code
, __LINE__
,
467 SAMR_FIELD_COUNTRY_CODE
);
469 TEST_USERINFO_INT(2, code_page
, 21, code_page
, __LINE__
, 0);
470 TEST_USERINFO_INT(21, code_page
, 21, code_page
, __LINE__
,
471 SAMR_FIELD_CODE_PAGE
);
472 TEST_USERINFO_INT(21, code_page
, 2, code_page
, __LINE__
,
473 SAMR_FIELD_CODE_PAGE
);
476 if (!torture_setting_bool(tctx
, "samba3", false)) {
477 TEST_USERINFO_INT(17, acct_expiry
, 21, acct_expiry
, __LINE__
, 0);
478 TEST_USERINFO_INT(17, acct_expiry
, 5, acct_expiry
, __LINE__
, 0);
479 TEST_USERINFO_INT(21, acct_expiry
, 21, acct_expiry
, __LINE__
,
480 SAMR_FIELD_ACCT_EXPIRY
);
481 TEST_USERINFO_INT(21, acct_expiry
, 5, acct_expiry
, __LINE__
,
482 SAMR_FIELD_ACCT_EXPIRY
);
483 TEST_USERINFO_INT(21, acct_expiry
, 17, acct_expiry
, __LINE__
,
484 SAMR_FIELD_ACCT_EXPIRY
);
486 /* Samba 3 can only store seconds / time_t in passdb - gd */
488 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
489 TEST_USERINFO_INT(17, acct_expiry
, 21, acct_expiry
, nt
, 0);
490 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
491 TEST_USERINFO_INT(17, acct_expiry
, 5, acct_expiry
, nt
, 0);
492 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
493 TEST_USERINFO_INT(21, acct_expiry
, 21, acct_expiry
, nt
, SAMR_FIELD_ACCT_EXPIRY
);
494 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
495 TEST_USERINFO_INT(21, acct_expiry
, 5, acct_expiry
, nt
, SAMR_FIELD_ACCT_EXPIRY
);
496 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
497 TEST_USERINFO_INT(21, acct_expiry
, 17, acct_expiry
, nt
, SAMR_FIELD_ACCT_EXPIRY
);
500 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 3, logon_hours
.bits
[3], 1, 0);
501 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 5, logon_hours
.bits
[3], 2, 0);
502 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 21, logon_hours
.bits
[3], 3, 0);
503 TEST_USERINFO_INT(21, logon_hours
.bits
[3], 21, logon_hours
.bits
[3], 4,
504 SAMR_FIELD_LOGON_HOURS
);
506 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
507 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
),
508 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
| user_extra_flags
),
510 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
511 (base_acct_flags
| ACB_DISABLED
),
512 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
515 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
516 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
517 (base_acct_flags
| ACB_DISABLED
| ACB_PWNOEXP
),
518 (base_acct_flags
| ACB_DISABLED
| ACB_PWNOEXP
),
520 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
521 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
),
522 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
| user_extra_flags
),
526 /* The 'autolock' flag doesn't stick - check this */
527 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
528 (base_acct_flags
| ACB_DISABLED
| ACB_AUTOLOCK
),
529 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
532 /* Removing the 'disabled' flag doesn't stick - check this */
533 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
535 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
539 /* Samba3 cannot store these atm */
540 if (!torture_setting_bool(tctx
, "samba3", false)) {
541 /* The 'store plaintext' flag does stick */
542 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
543 (base_acct_flags
| ACB_DISABLED
| ACB_ENC_TXT_PWD_ALLOWED
),
544 (base_acct_flags
| ACB_DISABLED
| ACB_ENC_TXT_PWD_ALLOWED
| user_extra_flags
),
546 /* The 'use DES' flag does stick */
547 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
548 (base_acct_flags
| ACB_DISABLED
| ACB_USE_DES_KEY_ONLY
),
549 (base_acct_flags
| ACB_DISABLED
| ACB_USE_DES_KEY_ONLY
| user_extra_flags
),
551 /* The 'don't require kerberos pre-authentication flag does stick */
552 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
553 (base_acct_flags
| ACB_DISABLED
| ACB_DONT_REQUIRE_PREAUTH
),
554 (base_acct_flags
| ACB_DISABLED
| ACB_DONT_REQUIRE_PREAUTH
| user_extra_flags
),
556 /* The 'no kerberos PAC required' flag sticks */
557 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
558 (base_acct_flags
| ACB_DISABLED
| ACB_NO_AUTH_DATA_REQD
),
559 (base_acct_flags
| ACB_DISABLED
| ACB_NO_AUTH_DATA_REQD
| user_extra_flags
),
562 TEST_USERINFO_INT_EXP(21, acct_flags
, 21, acct_flags
,
563 (base_acct_flags
| ACB_DISABLED
),
564 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
565 SAMR_FIELD_ACCT_FLAGS
);
568 /* these fail with win2003 - it appears you can't set the primary gid?
569 the set succeeds, but the gid isn't changed. Very weird! */
570 TEST_USERINFO_INT(9, primary_gid
, 1, primary_gid
, 513);
571 TEST_USERINFO_INT(9, primary_gid
, 3, primary_gid
, 513);
572 TEST_USERINFO_INT(9, primary_gid
, 5, primary_gid
, 513);
573 TEST_USERINFO_INT(9, primary_gid
, 21, primary_gid
, 513);
580 generate a random password for password change tests
582 static char *samr_rand_pass_silent(TALLOC_CTX
*mem_ctx
, int min_len
)
584 size_t len
= MAX(8, min_len
);
585 char *s
= generate_random_password(mem_ctx
, len
, len
+6);
589 static char *samr_rand_pass(TALLOC_CTX
*mem_ctx
, int min_len
)
591 char *s
= samr_rand_pass_silent(mem_ctx
, min_len
);
592 printf("Generated password '%s'\n", s
);
598 generate a random password for password change tests
600 static DATA_BLOB
samr_very_rand_pass(TALLOC_CTX
*mem_ctx
, int len
)
603 DATA_BLOB password
= data_blob_talloc(mem_ctx
, NULL
, len
* 2 /* number of unicode chars */);
604 generate_random_buffer(password
.data
, password
.length
);
606 for (i
=0; i
< len
; i
++) {
607 if (((uint16_t *)password
.data
)[i
] == 0) {
608 ((uint16_t *)password
.data
)[i
] = 1;
616 generate a random password for password change tests (fixed length)
618 static char *samr_rand_pass_fixed_len(TALLOC_CTX
*mem_ctx
, int len
)
620 char *s
= generate_random_password(mem_ctx
, len
, len
);
621 printf("Generated password '%s'\n", s
);
625 static bool test_SetUserPass(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
626 struct policy_handle
*handle
, char **password
)
629 struct samr_SetUserInfo s
;
630 union samr_UserInfo u
;
632 DATA_BLOB session_key
;
634 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
635 struct samr_GetUserPwInfo pwp
;
636 struct samr_PwInfo info
;
637 int policy_min_pw_len
= 0;
638 pwp
.in
.user_handle
= handle
;
639 pwp
.out
.info
= &info
;
641 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
642 "GetUserPwInfo failed");
643 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
644 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
646 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
648 s
.in
.user_handle
= handle
;
652 encode_pw_buffer(u
.info24
.password
.data
, newpass
, STR_UNICODE
);
653 u
.info24
.password_expired
= 0;
655 status
= dcerpc_fetch_session_key(p
, &session_key
);
656 if (!NT_STATUS_IS_OK(status
)) {
657 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
658 s
.in
.level
, nt_errstr(status
));
662 arcfour_crypt_blob(u
.info24
.password
.data
, 516, &session_key
);
664 torture_comment(tctx
, "Testing SetUserInfo level 24 (set password)\n");
666 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
667 "SetUserInfo failed");
668 torture_comment(tctx
, "(%s:%s) new_password[%s] status[%s]\n",
669 __location__
, __FUNCTION__
,
670 newpass
, nt_errstr(s
.out
.result
));
671 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
672 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
673 s
.in
.level
, nt_errstr(s
.out
.result
));
683 static bool test_SetUserPass_23(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
684 struct policy_handle
*handle
, uint32_t fields_present
,
688 struct samr_SetUserInfo s
;
689 union samr_UserInfo u
;
691 DATA_BLOB session_key
;
692 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
694 struct samr_GetUserPwInfo pwp
;
695 struct samr_PwInfo info
;
696 int policy_min_pw_len
= 0;
697 pwp
.in
.user_handle
= handle
;
698 pwp
.out
.info
= &info
;
700 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
701 "GetUserPwInfo failed");
702 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
703 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
705 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
707 s
.in
.user_handle
= handle
;
713 u
.info23
.info
.fields_present
= fields_present
;
715 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
717 status
= dcerpc_fetch_session_key(p
, &session_key
);
718 if (!NT_STATUS_IS_OK(status
)) {
719 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
720 s
.in
.level
, nt_errstr(status
));
724 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
726 torture_comment(tctx
, "Testing SetUserInfo level 23 (set password)\n");
728 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
729 "SetUserInfo failed");
730 torture_comment(tctx
, "(%s:%s) new_password[%s] status[%s]\n",
731 __location__
, __FUNCTION__
,
732 newpass
, nt_errstr(s
.out
.result
));
733 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
734 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
735 s
.in
.level
, nt_errstr(s
.out
.result
));
741 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
743 status
= dcerpc_fetch_session_key(p
, &session_key
);
744 if (!NT_STATUS_IS_OK(status
)) {
745 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
746 s
.in
.level
, nt_errstr(status
));
750 /* This should break the key nicely */
751 session_key
.length
--;
752 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
754 torture_comment(tctx
, "Testing SetUserInfo level 23 (set password) with wrong password\n");
756 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
757 "SetUserInfo failed");
758 torture_comment(tctx
, "(%s:%s) new_password[%s] status[%s]\n",
759 __location__
, __FUNCTION__
,
760 newpass
, nt_errstr(s
.out
.result
));
761 if (!NT_STATUS_EQUAL(s
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
762 torture_warning(tctx
, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
763 s
.in
.level
, nt_errstr(s
.out
.result
));
771 static bool test_SetUserPassEx(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
772 struct policy_handle
*handle
, bool makeshort
,
776 struct samr_SetUserInfo s
;
777 union samr_UserInfo u
;
779 DATA_BLOB session_key
;
780 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
781 uint8_t confounder
[16];
783 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
784 struct MD5Context ctx
;
785 struct samr_GetUserPwInfo pwp
;
786 struct samr_PwInfo info
;
787 int policy_min_pw_len
= 0;
788 pwp
.in
.user_handle
= handle
;
789 pwp
.out
.info
= &info
;
791 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
792 "GetUserPwInfo failed");
793 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
794 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
796 if (makeshort
&& policy_min_pw_len
) {
797 newpass
= samr_rand_pass_fixed_len(tctx
, policy_min_pw_len
- 1);
799 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
802 s
.in
.user_handle
= handle
;
806 encode_pw_buffer(u
.info26
.password
.data
, newpass
, STR_UNICODE
);
807 u
.info26
.password_expired
= 0;
809 status
= dcerpc_fetch_session_key(p
, &session_key
);
810 if (!NT_STATUS_IS_OK(status
)) {
811 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
812 s
.in
.level
, nt_errstr(status
));
816 generate_random_buffer((uint8_t *)confounder
, 16);
819 MD5Update(&ctx
, confounder
, 16);
820 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
821 MD5Final(confounded_session_key
.data
, &ctx
);
823 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
824 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
826 torture_comment(tctx
, "Testing SetUserInfo level 26 (set password ex)\n");
828 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
829 "SetUserInfo failed");
830 torture_comment(tctx
, "(%s:%s) new_password[%s] status[%s]\n",
831 __location__
, __FUNCTION__
,
832 newpass
, nt_errstr(s
.out
.result
));
833 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
834 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
835 s
.in
.level
, nt_errstr(s
.out
.result
));
841 /* This should break the key nicely */
842 confounded_session_key
.data
[0]++;
844 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
845 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
847 torture_comment(tctx
, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
849 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
850 "SetUserInfo failed");
851 torture_comment(tctx
, "(%s:%s) new_password[%s] status[%s]\n",
852 __location__
, __FUNCTION__
,
853 newpass
, nt_errstr(s
.out
.result
));
854 if (!NT_STATUS_EQUAL(s
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
855 torture_warning(tctx
, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
856 s
.in
.level
, nt_errstr(s
.out
.result
));
865 static bool test_SetUserPass_25(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
866 struct policy_handle
*handle
, uint32_t fields_present
,
870 struct samr_SetUserInfo s
;
871 union samr_UserInfo u
;
873 DATA_BLOB session_key
;
874 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
875 struct MD5Context ctx
;
876 uint8_t confounder
[16];
878 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
879 struct samr_GetUserPwInfo pwp
;
880 struct samr_PwInfo info
;
881 int policy_min_pw_len
= 0;
882 pwp
.in
.user_handle
= handle
;
883 pwp
.out
.info
= &info
;
885 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
886 "GetUserPwInfo failed");
887 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
888 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
890 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
892 s
.in
.user_handle
= handle
;
898 u
.info25
.info
.fields_present
= fields_present
;
900 encode_pw_buffer(u
.info25
.password
.data
, newpass
, STR_UNICODE
);
902 status
= dcerpc_fetch_session_key(p
, &session_key
);
903 if (!NT_STATUS_IS_OK(status
)) {
904 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
905 s
.in
.level
, nt_errstr(status
));
909 generate_random_buffer((uint8_t *)confounder
, 16);
912 MD5Update(&ctx
, confounder
, 16);
913 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
914 MD5Final(confounded_session_key
.data
, &ctx
);
916 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
917 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
919 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex)\n");
921 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
922 "SetUserInfo failed");
923 torture_comment(tctx
, "(%s:%s) new_password[%s] status[%s]\n",
924 __location__
, __FUNCTION__
,
925 newpass
, nt_errstr(s
.out
.result
));
926 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
927 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
928 s
.in
.level
, nt_errstr(s
.out
.result
));
934 /* This should break the key nicely */
935 confounded_session_key
.data
[0]++;
937 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
938 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
940 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
942 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
943 "SetUserInfo failed");
944 torture_comment(tctx
, "(%s:%s) new_password[%s] status[%s]\n",
945 __location__
, __FUNCTION__
,
946 newpass
, nt_errstr(s
.out
.result
));
947 if (!NT_STATUS_EQUAL(s
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
948 torture_warning(tctx
, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
949 s
.in
.level
, nt_errstr(s
.out
.result
));
956 static bool test_SetUserPass_18(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
957 struct policy_handle
*handle
, char **password
)
960 struct samr_SetUserInfo s
;
961 union samr_UserInfo u
;
963 DATA_BLOB session_key
;
965 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
966 struct samr_GetUserPwInfo pwp
;
967 struct samr_PwInfo info
;
968 int policy_min_pw_len
= 0;
969 uint8_t lm_hash
[16], nt_hash
[16];
971 pwp
.in
.user_handle
= handle
;
972 pwp
.out
.info
= &info
;
974 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
975 "GetUserPwInfo failed");
976 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
977 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
979 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
981 s
.in
.user_handle
= handle
;
987 u
.info18
.nt_pwd_active
= true;
988 u
.info18
.lm_pwd_active
= true;
990 E_md4hash(newpass
, nt_hash
);
991 E_deshash(newpass
, lm_hash
);
993 status
= dcerpc_fetch_session_key(p
, &session_key
);
994 if (!NT_STATUS_IS_OK(status
)) {
995 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
996 s
.in
.level
, nt_errstr(status
));
1002 in
= data_blob_const(nt_hash
, 16);
1003 out
= data_blob_talloc_zero(tctx
, 16);
1004 sess_crypt_blob(&out
, &in
, &session_key
, true);
1005 memcpy(u
.info18
.nt_pwd
.hash
, out
.data
, out
.length
);
1009 in
= data_blob_const(lm_hash
, 16);
1010 out
= data_blob_talloc_zero(tctx
, 16);
1011 sess_crypt_blob(&out
, &in
, &session_key
, true);
1012 memcpy(u
.info18
.lm_pwd
.hash
, out
.data
, out
.length
);
1015 torture_comment(tctx
, "Testing SetUserInfo level 18 (set password hash)\n");
1017 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
1018 "SetUserInfo failed");
1019 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
1020 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
1021 s
.in
.level
, nt_errstr(s
.out
.result
));
1024 *password
= newpass
;
1030 static bool test_SetUserPass_21(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1031 struct policy_handle
*handle
, uint32_t fields_present
,
1035 struct samr_SetUserInfo s
;
1036 union samr_UserInfo u
;
1038 DATA_BLOB session_key
;
1040 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1041 struct samr_GetUserPwInfo pwp
;
1042 struct samr_PwInfo info
;
1043 int policy_min_pw_len
= 0;
1044 uint8_t lm_hash
[16], nt_hash
[16];
1046 pwp
.in
.user_handle
= handle
;
1047 pwp
.out
.info
= &info
;
1049 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
1050 "GetUserPwInfo failed");
1051 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
1052 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1054 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1056 s
.in
.user_handle
= handle
;
1060 E_md4hash(newpass
, nt_hash
);
1061 E_deshash(newpass
, lm_hash
);
1065 u
.info21
.fields_present
= fields_present
;
1067 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1068 u
.info21
.lm_owf_password
.length
= 16;
1069 u
.info21
.lm_owf_password
.size
= 16;
1070 u
.info21
.lm_owf_password
.array
= (uint16_t *)lm_hash
;
1071 u
.info21
.lm_password_set
= true;
1074 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1075 u
.info21
.nt_owf_password
.length
= 16;
1076 u
.info21
.nt_owf_password
.size
= 16;
1077 u
.info21
.nt_owf_password
.array
= (uint16_t *)nt_hash
;
1078 u
.info21
.nt_password_set
= true;
1081 status
= dcerpc_fetch_session_key(p
, &session_key
);
1082 if (!NT_STATUS_IS_OK(status
)) {
1083 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
1084 s
.in
.level
, nt_errstr(status
));
1088 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1090 in
= data_blob_const(u
.info21
.lm_owf_password
.array
,
1091 u
.info21
.lm_owf_password
.length
);
1092 out
= data_blob_talloc_zero(tctx
, 16);
1093 sess_crypt_blob(&out
, &in
, &session_key
, true);
1094 u
.info21
.lm_owf_password
.array
= (uint16_t *)out
.data
;
1097 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1099 in
= data_blob_const(u
.info21
.nt_owf_password
.array
,
1100 u
.info21
.nt_owf_password
.length
);
1101 out
= data_blob_talloc_zero(tctx
, 16);
1102 sess_crypt_blob(&out
, &in
, &session_key
, true);
1103 u
.info21
.nt_owf_password
.array
= (uint16_t *)out
.data
;
1106 torture_comment(tctx
, "Testing SetUserInfo level 21 (set password hash)\n");
1108 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
1109 "SetUserInfo failed");
1110 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
1111 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
1112 s
.in
.level
, nt_errstr(s
.out
.result
));
1115 *password
= newpass
;
1118 /* try invalid length */
1119 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1121 u
.info21
.nt_owf_password
.length
++;
1123 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
1124 "SetUserInfo failed");
1125 if (!NT_STATUS_EQUAL(s
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
1126 torture_warning(tctx
, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1127 s
.in
.level
, nt_errstr(s
.out
.result
));
1132 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1134 u
.info21
.lm_owf_password
.length
++;
1136 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
1137 "SetUserInfo failed");
1138 if (!NT_STATUS_EQUAL(s
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
1139 torture_warning(tctx
, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1140 s
.in
.level
, nt_errstr(s
.out
.result
));
1148 static bool test_SetUserPass_level_ex(struct dcerpc_pipe
*p
,
1149 struct torture_context
*tctx
,
1150 struct policy_handle
*handle
,
1152 uint32_t fields_present
,
1153 char **password
, uint8_t password_expired
,
1155 bool *matched_expected_error
)
1158 NTSTATUS expected_error
= NT_STATUS_OK
;
1159 struct samr_SetUserInfo s
;
1160 struct samr_SetUserInfo2 s2
;
1161 union samr_UserInfo u
;
1163 DATA_BLOB session_key
;
1164 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
1165 struct MD5Context ctx
;
1166 uint8_t confounder
[16];
1168 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1169 struct samr_GetUserPwInfo pwp
;
1170 struct samr_PwInfo info
;
1171 int policy_min_pw_len
= 0;
1172 const char *comment
= NULL
;
1173 uint8_t lm_hash
[16], nt_hash
[16];
1175 pwp
.in
.user_handle
= handle
;
1176 pwp
.out
.info
= &info
;
1178 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
1179 "GetUserPwInfo failed");
1180 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
1181 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1183 newpass
= samr_rand_pass_silent(tctx
, policy_min_pw_len
);
1186 s2
.in
.user_handle
= handle
;
1188 s2
.in
.level
= level
;
1190 s
.in
.user_handle
= handle
;
1195 if (fields_present
& SAMR_FIELD_COMMENT
) {
1196 comment
= talloc_asprintf(tctx
, "comment: %ld\n", (long int) time(NULL
));
1203 E_md4hash(newpass
, nt_hash
);
1204 E_deshash(newpass
, lm_hash
);
1206 u
.info18
.nt_pwd_active
= true;
1207 u
.info18
.lm_pwd_active
= true;
1208 u
.info18
.password_expired
= password_expired
;
1210 memcpy(u
.info18
.lm_pwd
.hash
, lm_hash
, 16);
1211 memcpy(u
.info18
.nt_pwd
.hash
, nt_hash
, 16);
1215 E_md4hash(newpass
, nt_hash
);
1216 E_deshash(newpass
, lm_hash
);
1218 u
.info21
.fields_present
= fields_present
;
1219 u
.info21
.password_expired
= password_expired
;
1220 u
.info21
.comment
.string
= comment
;
1222 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1223 u
.info21
.lm_owf_password
.length
= 16;
1224 u
.info21
.lm_owf_password
.size
= 16;
1225 u
.info21
.lm_owf_password
.array
= (uint16_t *)lm_hash
;
1226 u
.info21
.lm_password_set
= true;
1229 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1230 u
.info21
.nt_owf_password
.length
= 16;
1231 u
.info21
.nt_owf_password
.size
= 16;
1232 u
.info21
.nt_owf_password
.array
= (uint16_t *)nt_hash
;
1233 u
.info21
.nt_password_set
= true;
1238 u
.info23
.info
.fields_present
= fields_present
;
1239 u
.info23
.info
.password_expired
= password_expired
;
1240 u
.info23
.info
.comment
.string
= comment
;
1242 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
1246 u
.info24
.password_expired
= password_expired
;
1248 encode_pw_buffer(u
.info24
.password
.data
, newpass
, STR_UNICODE
);
1252 u
.info25
.info
.fields_present
= fields_present
;
1253 u
.info25
.info
.password_expired
= password_expired
;
1254 u
.info25
.info
.comment
.string
= comment
;
1256 encode_pw_buffer(u
.info25
.password
.data
, newpass
, STR_UNICODE
);
1260 u
.info26
.password_expired
= password_expired
;
1262 encode_pw_buffer(u
.info26
.password
.data
, newpass
, STR_UNICODE
);
1267 status
= dcerpc_fetch_session_key(p
, &session_key
);
1268 if (!NT_STATUS_IS_OK(status
)) {
1269 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
1270 s
.in
.level
, nt_errstr(status
));
1274 generate_random_buffer((uint8_t *)confounder
, 16);
1277 MD5Update(&ctx
, confounder
, 16);
1278 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
1279 MD5Final(confounded_session_key
.data
, &ctx
);
1285 in
= data_blob_const(u
.info18
.nt_pwd
.hash
, 16);
1286 out
= data_blob_talloc_zero(tctx
, 16);
1287 sess_crypt_blob(&out
, &in
, &session_key
, true);
1288 memcpy(u
.info18
.nt_pwd
.hash
, out
.data
, out
.length
);
1292 in
= data_blob_const(u
.info18
.lm_pwd
.hash
, 16);
1293 out
= data_blob_talloc_zero(tctx
, 16);
1294 sess_crypt_blob(&out
, &in
, &session_key
, true);
1295 memcpy(u
.info18
.lm_pwd
.hash
, out
.data
, out
.length
);
1300 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1302 in
= data_blob_const(u
.info21
.lm_owf_password
.array
,
1303 u
.info21
.lm_owf_password
.length
);
1304 out
= data_blob_talloc_zero(tctx
, 16);
1305 sess_crypt_blob(&out
, &in
, &session_key
, true);
1306 u
.info21
.lm_owf_password
.array
= (uint16_t *)out
.data
;
1308 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1310 in
= data_blob_const(u
.info21
.nt_owf_password
.array
,
1311 u
.info21
.nt_owf_password
.length
);
1312 out
= data_blob_talloc_zero(tctx
, 16);
1313 sess_crypt_blob(&out
, &in
, &session_key
, true);
1314 u
.info21
.nt_owf_password
.array
= (uint16_t *)out
.data
;
1318 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
1321 arcfour_crypt_blob(u
.info24
.password
.data
, 516, &session_key
);
1324 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
1325 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
1328 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
1329 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
1334 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo2_r(b
, tctx
, &s2
),
1335 "SetUserInfo2 failed");
1336 torture_comment(tctx
, "(%s:%s) new_password[%s] status[%s]\n",
1337 __location__
, __FUNCTION__
,
1338 newpass
, nt_errstr(s2
.out
.result
));
1339 status
= s2
.out
.result
;
1341 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
1342 "SetUserInfo failed");
1343 torture_comment(tctx
, "(%s:%s) new_password[%s] status[%s]\n",
1344 __location__
, __FUNCTION__
,
1345 newpass
, nt_errstr(s
.out
.result
));
1346 status
= s
.out
.result
;
1349 if (!NT_STATUS_IS_OK(status
)) {
1350 if (fields_present
== 0) {
1351 expected_error
= NT_STATUS_INVALID_PARAMETER
;
1353 if (fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
1354 expected_error
= NT_STATUS_ACCESS_DENIED
;
1358 if (!NT_STATUS_IS_OK(expected_error
)) {
1360 torture_assert_ntstatus_equal(tctx
,
1362 expected_error
, "SetUserInfo2 failed");
1364 torture_assert_ntstatus_equal(tctx
,
1366 expected_error
, "SetUserInfo failed");
1368 *matched_expected_error
= true;
1372 if (!NT_STATUS_IS_OK(status
)) {
1373 torture_warning(tctx
, "SetUserInfo%s level %u failed - %s\n",
1374 use_setinfo2
? "2":"", level
, nt_errstr(status
));
1377 *password
= newpass
;
1383 static bool test_SetAliasInfo(struct dcerpc_binding_handle
*b
,
1384 struct torture_context
*tctx
,
1385 struct policy_handle
*handle
)
1387 struct samr_SetAliasInfo r
;
1388 struct samr_QueryAliasInfo q
;
1389 union samr_AliasInfo
*info
;
1390 uint16_t levels
[] = {2, 3};
1394 /* Ignoring switch level 1, as that includes the number of members for the alias
1395 * and setting this to a wrong value might have negative consequences
1398 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
1399 torture_comment(tctx
, "Testing SetAliasInfo level %u\n", levels
[i
]);
1401 r
.in
.alias_handle
= handle
;
1402 r
.in
.level
= levels
[i
];
1403 r
.in
.info
= talloc(tctx
, union samr_AliasInfo
);
1404 switch (r
.in
.level
) {
1405 case ALIASINFONAME
: init_lsa_String(&r
.in
.info
->name
,TEST_ALIASNAME
); break;
1406 case ALIASINFODESCRIPTION
: init_lsa_String(&r
.in
.info
->description
,
1407 "Test Description, should test I18N as well"); break;
1408 case ALIASINFOALL
: torture_comment(tctx
, "ALIASINFOALL ignored\n"); break;
1411 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetAliasInfo_r(b
, tctx
, &r
),
1412 "SetAliasInfo failed");
1413 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1414 torture_warning(tctx
, "SetAliasInfo level %u failed - %s\n",
1415 levels
[i
], nt_errstr(r
.out
.result
));
1419 q
.in
.alias_handle
= handle
;
1420 q
.in
.level
= levels
[i
];
1423 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryAliasInfo_r(b
, tctx
, &q
),
1424 "QueryAliasInfo failed");
1425 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
1426 torture_warning(tctx
, "QueryAliasInfo level %u failed - %s\n",
1427 levels
[i
], nt_errstr(q
.out
.result
));
1435 static bool test_GetGroupsForUser(struct dcerpc_binding_handle
*b
,
1436 struct torture_context
*tctx
,
1437 struct policy_handle
*user_handle
)
1439 struct samr_GetGroupsForUser r
;
1440 struct samr_RidWithAttributeArray
*rids
= NULL
;
1442 torture_comment(tctx
, "Testing GetGroupsForUser\n");
1444 r
.in
.user_handle
= user_handle
;
1447 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetGroupsForUser_r(b
, tctx
, &r
),
1448 "GetGroupsForUser failed");
1449 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetGroupsForUser failed");
1455 static bool test_GetDomPwInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1456 struct lsa_String
*domain_name
)
1458 struct samr_GetDomPwInfo r
;
1459 struct samr_PwInfo info
;
1460 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1462 r
.in
.domain_name
= domain_name
;
1465 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1467 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &r
),
1468 "GetDomPwInfo failed");
1469 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetDomPwInfo failed");
1471 r
.in
.domain_name
->string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1472 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1474 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &r
),
1475 "GetDomPwInfo failed");
1476 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetDomPwInfo failed");
1478 r
.in
.domain_name
->string
= "\\\\__NONAME__";
1479 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1481 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &r
),
1482 "GetDomPwInfo failed");
1483 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetDomPwInfo failed");
1485 r
.in
.domain_name
->string
= "\\\\Builtin";
1486 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1488 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &r
),
1489 "GetDomPwInfo failed");
1490 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetDomPwInfo failed");
1495 static bool test_GetUserPwInfo(struct dcerpc_binding_handle
*b
,
1496 struct torture_context
*tctx
,
1497 struct policy_handle
*handle
)
1499 struct samr_GetUserPwInfo r
;
1500 struct samr_PwInfo info
;
1502 torture_comment(tctx
, "Testing GetUserPwInfo\n");
1504 r
.in
.user_handle
= handle
;
1507 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &r
),
1508 "GetUserPwInfo failed");
1509 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetUserPwInfo");
1514 static NTSTATUS
test_LookupName(struct dcerpc_binding_handle
*b
,
1515 struct torture_context
*tctx
,
1516 struct policy_handle
*domain_handle
, const char *name
,
1520 struct samr_LookupNames n
;
1521 struct lsa_String sname
[2];
1522 struct samr_Ids rids
, types
;
1524 init_lsa_String(&sname
[0], name
);
1526 n
.in
.domain_handle
= domain_handle
;
1530 n
.out
.types
= &types
;
1531 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1532 if (!NT_STATUS_IS_OK(status
)) {
1535 if (NT_STATUS_IS_OK(n
.out
.result
)) {
1536 *rid
= n
.out
.rids
->ids
[0];
1538 return n
.out
.result
;
1541 init_lsa_String(&sname
[1], "xxNONAMExx");
1543 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1544 if (!NT_STATUS_IS_OK(status
)) {
1547 if (!NT_STATUS_EQUAL(n
.out
.result
, STATUS_SOME_UNMAPPED
)) {
1548 torture_warning(tctx
, "LookupNames[2] failed - %s\n", nt_errstr(n
.out
.result
));
1549 if (NT_STATUS_IS_OK(n
.out
.result
)) {
1550 return NT_STATUS_UNSUCCESSFUL
;
1552 return n
.out
.result
;
1556 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1557 if (!NT_STATUS_IS_OK(status
)) {
1560 if (!NT_STATUS_IS_OK(n
.out
.result
)) {
1561 torture_warning(tctx
, "LookupNames[0] failed - %s\n", nt_errstr(status
));
1562 return n
.out
.result
;
1565 init_lsa_String(&sname
[0], "xxNONAMExx");
1567 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1568 if (!NT_STATUS_IS_OK(status
)) {
1571 if (!NT_STATUS_EQUAL(n
.out
.result
, NT_STATUS_NONE_MAPPED
)) {
1572 torture_warning(tctx
, "LookupNames[1 bad name] failed - %s\n", nt_errstr(n
.out
.result
));
1573 if (NT_STATUS_IS_OK(n
.out
.result
)) {
1574 return NT_STATUS_UNSUCCESSFUL
;
1576 return n
.out
.result
;
1579 init_lsa_String(&sname
[0], "xxNONAMExx");
1580 init_lsa_String(&sname
[1], "xxNONAME2xx");
1582 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1583 if (!NT_STATUS_IS_OK(status
)) {
1586 if (!NT_STATUS_EQUAL(n
.out
.result
, NT_STATUS_NONE_MAPPED
)) {
1587 torture_warning(tctx
, "LookupNames[2 bad names] failed - %s\n", nt_errstr(n
.out
.result
));
1588 if (NT_STATUS_IS_OK(n
.out
.result
)) {
1589 return NT_STATUS_UNSUCCESSFUL
;
1591 return n
.out
.result
;
1594 return NT_STATUS_OK
;
1597 static NTSTATUS
test_OpenUser_byname(struct dcerpc_binding_handle
*b
,
1598 struct torture_context
*tctx
,
1599 struct policy_handle
*domain_handle
,
1600 const char *name
, struct policy_handle
*user_handle
)
1603 struct samr_OpenUser r
;
1606 status
= test_LookupName(b
, tctx
, domain_handle
, name
, &rid
);
1607 if (!NT_STATUS_IS_OK(status
)) {
1611 r
.in
.domain_handle
= domain_handle
;
1612 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1614 r
.out
.user_handle
= user_handle
;
1615 status
= dcerpc_samr_OpenUser_r(b
, tctx
, &r
);
1616 if (!NT_STATUS_IS_OK(status
)) {
1619 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1620 torture_warning(tctx
, "OpenUser_byname(%s -> %d) failed - %s\n", name
, rid
, nt_errstr(r
.out
.result
));
1623 return r
.out
.result
;
1627 static bool test_ChangePasswordNT3(struct dcerpc_pipe
*p
,
1628 struct torture_context
*tctx
,
1629 struct policy_handle
*handle
)
1632 struct samr_ChangePasswordUser r
;
1634 struct samr_Password hash1
, hash2
, hash3
, hash4
, hash5
, hash6
;
1635 struct policy_handle user_handle
;
1636 char *oldpass
= "test";
1637 char *newpass
= "test2";
1638 uint8_t old_nt_hash
[16], new_nt_hash
[16];
1639 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1641 status
= test_OpenUser_byname(p
, tctx
, handle
, "testuser", &user_handle
);
1642 if (!NT_STATUS_IS_OK(status
)) {
1646 torture_comment(tctx
, "Testing ChangePasswordUser for user 'testuser'\n");
1648 torture_comment(tctx
, "old password: %s\n", oldpass
);
1649 torture_comment(tctx
, "new password: %s\n", newpass
);
1651 E_md4hash(oldpass
, old_nt_hash
);
1652 E_md4hash(newpass
, new_nt_hash
);
1653 E_deshash(oldpass
, old_lm_hash
);
1654 E_deshash(newpass
, new_lm_hash
);
1656 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1657 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1658 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1659 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1660 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1661 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1663 r
.in
.handle
= &user_handle
;
1664 r
.in
.lm_present
= 1;
1665 r
.in
.old_lm_crypted
= &hash1
;
1666 r
.in
.new_lm_crypted
= &hash2
;
1667 r
.in
.nt_present
= 1;
1668 r
.in
.old_nt_crypted
= &hash3
;
1669 r
.in
.new_nt_crypted
= &hash4
;
1670 r
.in
.cross1_present
= 1;
1671 r
.in
.nt_cross
= &hash5
;
1672 r
.in
.cross2_present
= 1;
1673 r
.in
.lm_cross
= &hash6
;
1675 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1676 "ChangePasswordUser failed");
1677 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1678 torture_warning(tctx
, "ChangePasswordUser failed - %s\n", nt_errstr(r
.out
.result
));
1682 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
1690 static bool test_ChangePasswordUser(struct dcerpc_binding_handle
*b
,
1691 struct torture_context
*tctx
,
1692 const char *acct_name
,
1693 struct policy_handle
*handle
, char **password
)
1696 struct samr_ChangePasswordUser r
;
1698 struct samr_Password hash1
, hash2
, hash3
, hash4
, hash5
, hash6
;
1699 struct policy_handle user_handle
;
1701 uint8_t old_nt_hash
[16], new_nt_hash
[16];
1702 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1703 bool changed
= true;
1706 struct samr_GetUserPwInfo pwp
;
1707 struct samr_PwInfo info
;
1708 int policy_min_pw_len
= 0;
1710 status
= test_OpenUser_byname(b
, tctx
, handle
, acct_name
, &user_handle
);
1711 if (!NT_STATUS_IS_OK(status
)) {
1714 pwp
.in
.user_handle
= &user_handle
;
1715 pwp
.out
.info
= &info
;
1717 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
1718 "GetUserPwInfo failed");
1719 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
1720 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1722 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1724 torture_comment(tctx
, "Testing ChangePasswordUser\n");
1726 torture_assert(tctx
, *password
!= NULL
,
1727 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1729 oldpass
= *password
;
1731 E_md4hash(oldpass
, old_nt_hash
);
1732 E_md4hash(newpass
, new_nt_hash
);
1733 E_deshash(oldpass
, old_lm_hash
);
1734 E_deshash(newpass
, new_lm_hash
);
1736 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1737 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1738 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1739 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1740 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1741 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1743 r
.in
.user_handle
= &user_handle
;
1744 r
.in
.lm_present
= 1;
1745 /* Break the LM hash */
1747 r
.in
.old_lm_crypted
= &hash1
;
1748 r
.in
.new_lm_crypted
= &hash2
;
1749 r
.in
.nt_present
= 1;
1750 r
.in
.old_nt_crypted
= &hash3
;
1751 r
.in
.new_nt_crypted
= &hash4
;
1752 r
.in
.cross1_present
= 1;
1753 r
.in
.nt_cross
= &hash5
;
1754 r
.in
.cross2_present
= 1;
1755 r
.in
.lm_cross
= &hash6
;
1757 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1758 "ChangePasswordUser failed");
1759 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1760 __location__
, __FUNCTION__
,
1761 oldpass
, newpass
, nt_errstr(r
.out
.result
));
1762 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_WRONG_PASSWORD
,
1763 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1765 /* Unbreak the LM hash */
1768 r
.in
.user_handle
= &user_handle
;
1769 r
.in
.lm_present
= 1;
1770 r
.in
.old_lm_crypted
= &hash1
;
1771 r
.in
.new_lm_crypted
= &hash2
;
1772 /* Break the NT hash */
1774 r
.in
.nt_present
= 1;
1775 r
.in
.old_nt_crypted
= &hash3
;
1776 r
.in
.new_nt_crypted
= &hash4
;
1777 r
.in
.cross1_present
= 1;
1778 r
.in
.nt_cross
= &hash5
;
1779 r
.in
.cross2_present
= 1;
1780 r
.in
.lm_cross
= &hash6
;
1782 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1783 "ChangePasswordUser failed");
1784 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1785 __location__
, __FUNCTION__
,
1786 oldpass
, newpass
, nt_errstr(r
.out
.result
));
1787 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_WRONG_PASSWORD
,
1788 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1790 /* Unbreak the NT hash */
1793 r
.in
.user_handle
= &user_handle
;
1794 r
.in
.lm_present
= 1;
1795 r
.in
.old_lm_crypted
= &hash1
;
1796 r
.in
.new_lm_crypted
= &hash2
;
1797 r
.in
.nt_present
= 1;
1798 r
.in
.old_nt_crypted
= &hash3
;
1799 r
.in
.new_nt_crypted
= &hash4
;
1800 r
.in
.cross1_present
= 1;
1801 r
.in
.nt_cross
= &hash5
;
1802 r
.in
.cross2_present
= 1;
1803 /* Break the LM cross */
1805 r
.in
.lm_cross
= &hash6
;
1807 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1808 "ChangePasswordUser failed");
1809 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1810 __location__
, __FUNCTION__
,
1811 oldpass
, newpass
, nt_errstr(r
.out
.result
));
1812 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
1813 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
));
1817 /* Unbreak the LM cross */
1820 r
.in
.user_handle
= &user_handle
;
1821 r
.in
.lm_present
= 1;
1822 r
.in
.old_lm_crypted
= &hash1
;
1823 r
.in
.new_lm_crypted
= &hash2
;
1824 r
.in
.nt_present
= 1;
1825 r
.in
.old_nt_crypted
= &hash3
;
1826 r
.in
.new_nt_crypted
= &hash4
;
1827 r
.in
.cross1_present
= 1;
1828 /* Break the NT cross */
1830 r
.in
.nt_cross
= &hash5
;
1831 r
.in
.cross2_present
= 1;
1832 r
.in
.lm_cross
= &hash6
;
1834 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1835 "ChangePasswordUser failed");
1836 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1837 __location__
, __FUNCTION__
,
1838 oldpass
, newpass
, nt_errstr(r
.out
.result
));
1839 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
1840 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
));
1844 /* Unbreak the NT cross */
1848 /* Reset the hashes to not broken values */
1849 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1850 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1851 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1852 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1853 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1854 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1856 r
.in
.user_handle
= &user_handle
;
1857 r
.in
.lm_present
= 1;
1858 r
.in
.old_lm_crypted
= &hash1
;
1859 r
.in
.new_lm_crypted
= &hash2
;
1860 r
.in
.nt_present
= 1;
1861 r
.in
.old_nt_crypted
= &hash3
;
1862 r
.in
.new_nt_crypted
= &hash4
;
1863 r
.in
.cross1_present
= 1;
1864 r
.in
.nt_cross
= &hash5
;
1865 r
.in
.cross2_present
= 0;
1866 r
.in
.lm_cross
= NULL
;
1868 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1869 "ChangePasswordUser failed");
1870 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1871 __location__
, __FUNCTION__
,
1872 oldpass
, newpass
, nt_errstr(r
.out
.result
));
1873 if (NT_STATUS_IS_OK(r
.out
.result
)) {
1875 *password
= newpass
;
1876 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION
, r
.out
.result
)) {
1877 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r
.out
.result
));
1882 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1884 E_md4hash(oldpass
, old_nt_hash
);
1885 E_md4hash(newpass
, new_nt_hash
);
1886 E_deshash(oldpass
, old_lm_hash
);
1887 E_deshash(newpass
, new_lm_hash
);
1890 /* Reset the hashes to not broken values */
1891 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1892 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1893 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1894 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1895 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1896 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1898 r
.in
.user_handle
= &user_handle
;
1899 r
.in
.lm_present
= 1;
1900 r
.in
.old_lm_crypted
= &hash1
;
1901 r
.in
.new_lm_crypted
= &hash2
;
1902 r
.in
.nt_present
= 1;
1903 r
.in
.old_nt_crypted
= &hash3
;
1904 r
.in
.new_nt_crypted
= &hash4
;
1905 r
.in
.cross1_present
= 0;
1906 r
.in
.nt_cross
= NULL
;
1907 r
.in
.cross2_present
= 1;
1908 r
.in
.lm_cross
= &hash6
;
1910 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1911 "ChangePasswordUser failed");
1912 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1913 __location__
, __FUNCTION__
,
1914 oldpass
, newpass
, nt_errstr(r
.out
.result
));
1915 if (NT_STATUS_IS_OK(r
.out
.result
)) {
1917 *password
= newpass
;
1918 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION
, r
.out
.result
)) {
1919 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r
.out
.result
));
1924 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1926 E_md4hash(oldpass
, old_nt_hash
);
1927 E_md4hash(newpass
, new_nt_hash
);
1928 E_deshash(oldpass
, old_lm_hash
);
1929 E_deshash(newpass
, new_lm_hash
);
1932 /* Reset the hashes to not broken values */
1933 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1934 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1935 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1936 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1937 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1938 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1940 r
.in
.user_handle
= &user_handle
;
1941 r
.in
.lm_present
= 1;
1942 r
.in
.old_lm_crypted
= &hash1
;
1943 r
.in
.new_lm_crypted
= &hash2
;
1944 r
.in
.nt_present
= 1;
1945 r
.in
.old_nt_crypted
= &hash3
;
1946 r
.in
.new_nt_crypted
= &hash4
;
1947 r
.in
.cross1_present
= 1;
1948 r
.in
.nt_cross
= &hash5
;
1949 r
.in
.cross2_present
= 1;
1950 r
.in
.lm_cross
= &hash6
;
1952 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1953 "ChangePasswordUser failed");
1954 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1955 __location__
, __FUNCTION__
,
1956 oldpass
, newpass
, nt_errstr(r
.out
.result
));
1957 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1958 torture_comment(tctx
, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r
.out
.result
));
1959 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1960 torture_warning(tctx
, "ChangePasswordUser failed - %s\n", nt_errstr(r
.out
.result
));
1964 *password
= newpass
;
1967 r
.in
.user_handle
= &user_handle
;
1968 r
.in
.lm_present
= 1;
1969 r
.in
.old_lm_crypted
= &hash1
;
1970 r
.in
.new_lm_crypted
= &hash2
;
1971 r
.in
.nt_present
= 1;
1972 r
.in
.old_nt_crypted
= &hash3
;
1973 r
.in
.new_nt_crypted
= &hash4
;
1974 r
.in
.cross1_present
= 1;
1975 r
.in
.nt_cross
= &hash5
;
1976 r
.in
.cross2_present
= 1;
1977 r
.in
.lm_cross
= &hash6
;
1980 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1981 "ChangePasswordUser failed");
1982 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1983 __location__
, __FUNCTION__
,
1984 oldpass
, newpass
, nt_errstr(r
.out
.result
));
1985 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1986 torture_comment(tctx
, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r
.out
.result
));
1987 } else if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
1988 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(r
.out
.result
));
1994 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
2002 static bool test_OemChangePasswordUser2(struct dcerpc_pipe
*p
,
2003 struct torture_context
*tctx
,
2004 const char *acct_name
,
2005 struct policy_handle
*handle
, char **password
)
2007 struct samr_OemChangePasswordUser2 r
;
2009 struct samr_Password lm_verifier
;
2010 struct samr_CryptPassword lm_pass
;
2011 struct lsa_AsciiString server
, account
, account_bad
;
2014 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2015 uint8_t old_lm_hash
[16], new_lm_hash
[16];
2017 struct samr_GetDomPwInfo dom_pw_info
;
2018 struct samr_PwInfo info
;
2019 int policy_min_pw_len
= 0;
2021 struct lsa_String domain_name
;
2023 domain_name
.string
= "";
2024 dom_pw_info
.in
.domain_name
= &domain_name
;
2025 dom_pw_info
.out
.info
= &info
;
2027 torture_comment(tctx
, "Testing OemChangePasswordUser2\n");
2029 torture_assert(tctx
, *password
!= NULL
,
2030 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
2032 oldpass
= *password
;
2034 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &dom_pw_info
),
2035 "GetDomPwInfo failed");
2036 if (NT_STATUS_IS_OK(dom_pw_info
.out
.result
)) {
2037 policy_min_pw_len
= dom_pw_info
.out
.info
->min_password_length
;
2040 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2042 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2043 account
.string
= acct_name
;
2045 E_deshash(oldpass
, old_lm_hash
);
2046 E_deshash(newpass
, new_lm_hash
);
2048 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
2049 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2050 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
2052 r
.in
.server
= &server
;
2053 r
.in
.account
= &account
;
2054 r
.in
.password
= &lm_pass
;
2055 r
.in
.hash
= &lm_verifier
;
2057 /* Break the verification */
2058 lm_verifier
.hash
[0]++;
2060 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2061 "OemChangePasswordUser2 failed");
2062 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2063 __location__
, __FUNCTION__
,
2064 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2066 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)
2067 && !NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
2068 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2069 nt_errstr(r
.out
.result
));
2073 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
2074 /* Break the old password */
2076 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2077 /* unbreak it for the next operation */
2079 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
2081 r
.in
.server
= &server
;
2082 r
.in
.account
= &account
;
2083 r
.in
.password
= &lm_pass
;
2084 r
.in
.hash
= &lm_verifier
;
2086 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2087 "OemChangePasswordUser2 failed");
2088 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2089 __location__
, __FUNCTION__
,
2090 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2092 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)
2093 && !NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
2094 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2095 nt_errstr(r
.out
.result
));
2099 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
2100 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2102 r
.in
.server
= &server
;
2103 r
.in
.account
= &account
;
2104 r
.in
.password
= &lm_pass
;
2107 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2108 "OemChangePasswordUser2 failed");
2109 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2110 __location__
, __FUNCTION__
,
2111 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2113 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)
2114 && !NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
2115 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
2116 nt_errstr(r
.out
.result
));
2120 /* This shouldn't be a valid name */
2121 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
2122 r
.in
.account
= &account_bad
;
2124 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2125 "OemChangePasswordUser2 failed");
2126 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2127 __location__
, __FUNCTION__
,
2128 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2130 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
2131 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
2132 nt_errstr(r
.out
.result
));
2136 /* This shouldn't be a valid name */
2137 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
2138 r
.in
.account
= &account_bad
;
2139 r
.in
.password
= &lm_pass
;
2140 r
.in
.hash
= &lm_verifier
;
2142 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2143 "OemChangePasswordUser2 failed");
2144 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2145 __location__
, __FUNCTION__
,
2146 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2148 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
2149 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2150 nt_errstr(r
.out
.result
));
2154 /* This shouldn't be a valid name */
2155 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
2156 r
.in
.account
= &account_bad
;
2157 r
.in
.password
= NULL
;
2158 r
.in
.hash
= &lm_verifier
;
2160 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2161 "OemChangePasswordUser2 failed");
2162 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2163 __location__
, __FUNCTION__
,
2164 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2166 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
2167 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2168 nt_errstr(r
.out
.result
));
2172 E_deshash(oldpass
, old_lm_hash
);
2173 E_deshash(newpass
, new_lm_hash
);
2175 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
2176 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2177 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
2179 r
.in
.server
= &server
;
2180 r
.in
.account
= &account
;
2181 r
.in
.password
= &lm_pass
;
2182 r
.in
.hash
= &lm_verifier
;
2184 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2185 "OemChangePasswordUser2 failed");
2186 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2187 __location__
, __FUNCTION__
,
2188 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2190 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2191 torture_comment(tctx
, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r
.out
.result
));
2192 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2193 torture_warning(tctx
, "OemChangePasswordUser2 failed - %s\n", nt_errstr(r
.out
.result
));
2196 *password
= newpass
;
2203 static bool test_ChangePasswordUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2204 const char *acct_name
,
2206 char *newpass
, bool allow_password_restriction
)
2208 struct samr_ChangePasswordUser2 r
;
2210 struct lsa_String server
, account
;
2211 struct samr_CryptPassword nt_pass
, lm_pass
;
2212 struct samr_Password nt_verifier
, lm_verifier
;
2214 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2215 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2216 uint8_t old_lm_hash
[16], new_lm_hash
[16];
2218 struct samr_GetDomPwInfo dom_pw_info
;
2219 struct samr_PwInfo info
;
2221 struct lsa_String domain_name
;
2223 domain_name
.string
= "";
2224 dom_pw_info
.in
.domain_name
= &domain_name
;
2225 dom_pw_info
.out
.info
= &info
;
2227 torture_comment(tctx
, "Testing ChangePasswordUser2 on %s\n", acct_name
);
2229 torture_assert(tctx
, *password
!= NULL
,
2230 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2231 oldpass
= *password
;
2234 int policy_min_pw_len
= 0;
2235 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &dom_pw_info
),
2236 "GetDomPwInfo failed");
2237 if (NT_STATUS_IS_OK(dom_pw_info
.out
.result
)) {
2238 policy_min_pw_len
= dom_pw_info
.out
.info
->min_password_length
;
2241 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2244 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2245 init_lsa_String(&account
, acct_name
);
2247 E_md4hash(oldpass
, old_nt_hash
);
2248 E_md4hash(newpass
, new_nt_hash
);
2250 E_deshash(oldpass
, old_lm_hash
);
2251 E_deshash(newpass
, new_lm_hash
);
2253 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
|STR_TERMINATE
);
2254 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2255 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2257 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2258 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2259 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2261 r
.in
.server
= &server
;
2262 r
.in
.account
= &account
;
2263 r
.in
.nt_password
= &nt_pass
;
2264 r
.in
.nt_verifier
= &nt_verifier
;
2266 r
.in
.lm_password
= &lm_pass
;
2267 r
.in
.lm_verifier
= &lm_verifier
;
2269 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser2_r(b
, tctx
, &r
),
2270 "ChangePasswordUser2 failed");
2271 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2272 __location__
, __FUNCTION__
,
2273 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2275 if (allow_password_restriction
&& NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2276 torture_comment(tctx
, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r
.out
.result
));
2277 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2278 torture_warning(tctx
, "ChangePasswordUser2 failed - %s\n", nt_errstr(r
.out
.result
));
2281 *password
= newpass
;
2288 bool test_ChangePasswordUser3(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2289 const char *account_string
,
2290 int policy_min_pw_len
,
2292 const char *newpass
,
2293 NTTIME last_password_change
,
2294 bool handle_reject_reason
)
2296 struct samr_ChangePasswordUser3 r
;
2298 struct lsa_String server
, account
, account_bad
;
2299 struct samr_CryptPassword nt_pass
, lm_pass
;
2300 struct samr_Password nt_verifier
, lm_verifier
;
2302 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2303 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2304 uint8_t old_lm_hash
[16], new_lm_hash
[16];
2306 struct samr_DomInfo1
*dominfo
= NULL
;
2307 struct userPwdChangeFailureInformation
*reject
= NULL
;
2309 torture_comment(tctx
, "Testing ChangePasswordUser3\n");
2311 if (newpass
== NULL
) {
2313 if (policy_min_pw_len
== 0) {
2314 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2316 newpass
= samr_rand_pass_fixed_len(tctx
, policy_min_pw_len
);
2318 } while (check_password_quality(newpass
) == false);
2320 torture_comment(tctx
, "Using password '%s'\n", newpass
);
2323 torture_assert(tctx
, *password
!= NULL
,
2324 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2326 oldpass
= *password
;
2327 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2328 init_lsa_String(&account
, account_string
);
2330 E_md4hash(oldpass
, old_nt_hash
);
2331 E_md4hash(newpass
, new_nt_hash
);
2333 E_deshash(oldpass
, old_lm_hash
);
2334 E_deshash(newpass
, new_lm_hash
);
2336 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2337 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2338 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2340 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2341 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2342 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2344 /* Break the verification */
2345 nt_verifier
.hash
[0]++;
2347 r
.in
.server
= &server
;
2348 r
.in
.account
= &account
;
2349 r
.in
.nt_password
= &nt_pass
;
2350 r
.in
.nt_verifier
= &nt_verifier
;
2352 r
.in
.lm_password
= &lm_pass
;
2353 r
.in
.lm_verifier
= &lm_verifier
;
2354 r
.in
.password3
= NULL
;
2355 r
.out
.dominfo
= &dominfo
;
2356 r
.out
.reject
= &reject
;
2358 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2359 "ChangePasswordUser3 failed");
2360 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2361 __location__
, __FUNCTION__
,
2362 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2363 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
) &&
2364 (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
))) {
2365 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2366 nt_errstr(r
.out
.result
));
2370 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2371 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2372 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2374 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2375 /* Break the NT hash */
2377 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2378 /* Unbreak it again */
2380 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2382 r
.in
.server
= &server
;
2383 r
.in
.account
= &account
;
2384 r
.in
.nt_password
= &nt_pass
;
2385 r
.in
.nt_verifier
= &nt_verifier
;
2387 r
.in
.lm_password
= &lm_pass
;
2388 r
.in
.lm_verifier
= &lm_verifier
;
2389 r
.in
.password3
= NULL
;
2390 r
.out
.dominfo
= &dominfo
;
2391 r
.out
.reject
= &reject
;
2393 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2394 "ChangePasswordUser3 failed");
2395 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2396 __location__
, __FUNCTION__
,
2397 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2398 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
) &&
2399 (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
))) {
2400 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2401 nt_errstr(r
.out
.result
));
2405 /* This shouldn't be a valid name */
2406 init_lsa_String(&account_bad
, talloc_asprintf(tctx
, "%sXX", account_string
));
2408 r
.in
.account
= &account_bad
;
2409 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2410 "ChangePasswordUser3 failed");
2411 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2412 __location__
, __FUNCTION__
,
2413 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2414 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
2415 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2416 nt_errstr(r
.out
.result
));
2420 E_md4hash(oldpass
, old_nt_hash
);
2421 E_md4hash(newpass
, new_nt_hash
);
2423 E_deshash(oldpass
, old_lm_hash
);
2424 E_deshash(newpass
, new_lm_hash
);
2426 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2427 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2428 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2430 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2431 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2432 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2434 r
.in
.server
= &server
;
2435 r
.in
.account
= &account
;
2436 r
.in
.nt_password
= &nt_pass
;
2437 r
.in
.nt_verifier
= &nt_verifier
;
2439 r
.in
.lm_password
= &lm_pass
;
2440 r
.in
.lm_verifier
= &lm_verifier
;
2441 r
.in
.password3
= NULL
;
2442 r
.out
.dominfo
= &dominfo
;
2443 r
.out
.reject
= &reject
;
2445 unix_to_nt_time(&t
, time(NULL
));
2447 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2448 "ChangePasswordUser3 failed");
2449 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2450 __location__
, __FUNCTION__
,
2451 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2453 torture_comment(tctx
, "(%s): dominfo[%s], reject[%s], handle_reject_reason[%s], "
2454 "last_password_change[%s], dominfo->min_password_age[%lld]\n",
2456 (dominfo
== NULL
)? "NULL" : "present",
2457 reject
? "true" : "false",
2458 handle_reject_reason
? "true" : "false",
2459 null_nttime(last_password_change
) ? "null" : "not null",
2460 dominfo
? (long long)dominfo
->min_password_age
: (long long)0);
2462 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)
2465 && handle_reject_reason
2466 && (!null_nttime(last_password_change
) || !dominfo
->min_password_age
)) {
2467 if (dominfo
->password_properties
& DOMAIN_REFUSE_PASSWORD_CHANGE
) {
2469 if (reject
&& (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
)) {
2470 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2471 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2476 /* We tested the order of precendence which is as follows:
2485 if ((dominfo
->min_password_age
> 0) && !null_nttime(last_password_change
) &&
2486 (last_password_change
+ dominfo
->min_password_age
> t
)) {
2488 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2489 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2490 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2494 } else if ((dominfo
->min_password_length
> 0) &&
2495 (strlen(newpass
) < dominfo
->min_password_length
)) {
2497 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
) {
2498 torture_warning(tctx
, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2499 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
, reject
->extendedFailureReason
);
2503 } else if ((dominfo
->password_history_length
> 0) &&
2504 strequal(oldpass
, newpass
)) {
2506 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_PWD_IN_HISTORY
) {
2507 torture_warning(tctx
, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2508 SAM_PWD_CHANGE_PWD_IN_HISTORY
, reject
->extendedFailureReason
);
2511 } else if (dominfo
->password_properties
& DOMAIN_PASSWORD_COMPLEX
) {
2513 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NOT_COMPLEX
) {
2514 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2515 SAM_PWD_CHANGE_NOT_COMPLEX
, reject
->extendedFailureReason
);
2521 if (reject
->extendedFailureReason
== SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
) {
2522 /* retry with adjusted size */
2523 return test_ChangePasswordUser3(p
, tctx
, account_string
,
2524 dominfo
->min_password_length
,
2525 password
, NULL
, 0, false);
2529 } else if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2530 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2531 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2532 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2535 /* Perhaps the server has a 'min password age' set? */
2538 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ChangePasswordUser3");
2540 *password
= talloc_strdup(tctx
, newpass
);
2546 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2547 const char *account_string
,
2548 struct policy_handle
*handle
,
2552 struct samr_ChangePasswordUser3 r
;
2553 struct samr_SetUserInfo s
;
2554 union samr_UserInfo u
;
2555 DATA_BLOB session_key
;
2556 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
2557 uint8_t confounder
[16];
2558 struct MD5Context ctx
;
2561 struct lsa_String server
, account
;
2562 struct samr_CryptPassword nt_pass
;
2563 struct samr_Password nt_verifier
;
2564 DATA_BLOB new_random_pass
;
2567 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2568 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2570 struct samr_DomInfo1
*dominfo
= NULL
;
2571 struct userPwdChangeFailureInformation
*reject
= NULL
;
2573 new_random_pass
= samr_very_rand_pass(tctx
, 128);
2575 torture_assert(tctx
, *password
!= NULL
,
2576 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2578 oldpass
= *password
;
2579 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2580 init_lsa_String(&account
, account_string
);
2582 s
.in
.user_handle
= handle
;
2588 u
.info25
.info
.fields_present
= SAMR_FIELD_NT_PASSWORD_PRESENT
;
2590 set_pw_in_buffer(u
.info25
.password
.data
, &new_random_pass
);
2592 status
= dcerpc_fetch_session_key(p
, &session_key
);
2593 if (!NT_STATUS_IS_OK(status
)) {
2594 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
2595 s
.in
.level
, nt_errstr(status
));
2599 generate_random_buffer((uint8_t *)confounder
, 16);
2602 MD5Update(&ctx
, confounder
, 16);
2603 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
2604 MD5Final(confounded_session_key
.data
, &ctx
);
2606 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
2607 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
2609 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2611 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
2612 "SetUserInfo failed");
2613 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2614 __location__
, __FUNCTION__
,
2615 oldpass
, "RANDOM", nt_errstr(s
.out
.result
));
2616 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
2617 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
2618 s
.in
.level
, nt_errstr(s
.out
.result
));
2622 torture_comment(tctx
, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2624 mdfour(old_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2626 new_random_pass
= samr_very_rand_pass(tctx
, 128);
2628 mdfour(new_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2630 set_pw_in_buffer(nt_pass
.data
, &new_random_pass
);
2631 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2632 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2634 r
.in
.server
= &server
;
2635 r
.in
.account
= &account
;
2636 r
.in
.nt_password
= &nt_pass
;
2637 r
.in
.nt_verifier
= &nt_verifier
;
2639 r
.in
.lm_password
= NULL
;
2640 r
.in
.lm_verifier
= NULL
;
2641 r
.in
.password3
= NULL
;
2642 r
.out
.dominfo
= &dominfo
;
2643 r
.out
.reject
= &reject
;
2645 unix_to_nt_time(&t
, time(NULL
));
2647 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2648 "ChangePasswordUser3 failed");
2649 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2650 __location__
, __FUNCTION__
,
2651 oldpass
, "RANDOM", nt_errstr(r
.out
.result
));
2653 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2654 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2655 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2656 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2659 /* Perhaps the server has a 'min password age' set? */
2661 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2662 torture_warning(tctx
, "ChangePasswordUser3 failed - %s\n", nt_errstr(r
.out
.result
));
2666 newpass
= samr_rand_pass(tctx
, 128);
2668 mdfour(old_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2670 E_md4hash(newpass
, new_nt_hash
);
2672 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2673 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2674 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2676 r
.in
.server
= &server
;
2677 r
.in
.account
= &account
;
2678 r
.in
.nt_password
= &nt_pass
;
2679 r
.in
.nt_verifier
= &nt_verifier
;
2681 r
.in
.lm_password
= NULL
;
2682 r
.in
.lm_verifier
= NULL
;
2683 r
.in
.password3
= NULL
;
2684 r
.out
.dominfo
= &dominfo
;
2685 r
.out
.reject
= &reject
;
2687 unix_to_nt_time(&t
, time(NULL
));
2689 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2690 "ChangePasswordUser3 failed");
2691 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2692 __location__
, __FUNCTION__
,
2693 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2695 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2696 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2697 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2698 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2701 /* Perhaps the server has a 'min password age' set? */
2704 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ChangePasswordUser3 (on second random password)");
2705 *password
= talloc_strdup(tctx
, newpass
);
2712 static bool test_GetMembersInAlias(struct dcerpc_binding_handle
*b
,
2713 struct torture_context
*tctx
,
2714 struct policy_handle
*alias_handle
)
2716 struct samr_GetMembersInAlias r
;
2717 struct lsa_SidArray sids
;
2719 torture_comment(tctx
, "Testing GetMembersInAlias\n");
2721 r
.in
.alias_handle
= alias_handle
;
2724 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetMembersInAlias_r(b
, tctx
, &r
),
2725 "GetMembersInAlias failed");
2726 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetMembersInAlias failed");
2731 static bool test_AddMemberToAlias(struct dcerpc_binding_handle
*b
,
2732 struct torture_context
*tctx
,
2733 struct policy_handle
*alias_handle
,
2734 const struct dom_sid
*domain_sid
)
2736 struct samr_AddAliasMember r
;
2737 struct samr_DeleteAliasMember d
;
2738 struct dom_sid
*sid
;
2740 sid
= dom_sid_add_rid(tctx
, domain_sid
, 512);
2742 torture_comment(tctx
, "Testing AddAliasMember\n");
2743 r
.in
.alias_handle
= alias_handle
;
2746 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddAliasMember_r(b
, tctx
, &r
),
2747 "AddAliasMember failed");
2748 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "AddAliasMember failed");
2750 d
.in
.alias_handle
= alias_handle
;
2753 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteAliasMember_r(b
, tctx
, &d
),
2754 "DeleteAliasMember failed");
2755 torture_assert_ntstatus_ok(tctx
, d
.out
.result
, "DelAliasMember failed");
2760 static bool test_AddMultipleMembersToAlias(struct dcerpc_binding_handle
*b
,
2761 struct torture_context
*tctx
,
2762 struct policy_handle
*alias_handle
)
2764 struct samr_AddMultipleMembersToAlias a
;
2765 struct samr_RemoveMultipleMembersFromAlias r
;
2766 struct lsa_SidArray sids
;
2768 torture_comment(tctx
, "Testing AddMultipleMembersToAlias\n");
2769 a
.in
.alias_handle
= alias_handle
;
2773 sids
.sids
= talloc_array(tctx
, struct lsa_SidPtr
, 3);
2775 sids
.sids
[0].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-1");
2776 sids
.sids
[1].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-2");
2777 sids
.sids
[2].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-3");
2779 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddMultipleMembersToAlias_r(b
, tctx
, &a
),
2780 "AddMultipleMembersToAlias failed");
2781 torture_assert_ntstatus_ok(tctx
, a
.out
.result
, "AddMultipleMembersToAlias");
2784 torture_comment(tctx
, "Testing RemoveMultipleMembersFromAlias\n");
2785 r
.in
.alias_handle
= alias_handle
;
2788 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b
, tctx
, &r
),
2789 "RemoveMultipleMembersFromAlias failed");
2790 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "RemoveMultipleMembersFromAlias failed");
2792 /* strange! removing twice doesn't give any error */
2793 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b
, tctx
, &r
),
2794 "RemoveMultipleMembersFromAlias failed");
2795 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "RemoveMultipleMembersFromAlias failed");
2797 /* but removing an alias that isn't there does */
2798 sids
.sids
[2].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-4");
2800 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b
, tctx
, &r
),
2801 "RemoveMultipleMembersFromAlias failed");
2802 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
, "RemoveMultipleMembersFromAlias");
2807 static bool test_GetAliasMembership(struct dcerpc_binding_handle
*b
,
2808 struct torture_context
*tctx
,
2809 struct policy_handle
*domain_handle
)
2811 struct samr_GetAliasMembership r
;
2812 struct lsa_SidArray sids
;
2813 struct samr_Ids rids
;
2815 torture_comment(tctx
, "Testing GetAliasMembership\n");
2817 r
.in
.domain_handle
= domain_handle
;
2822 sids
.sids
= talloc_zero_array(tctx
, struct lsa_SidPtr
, sids
.num_sids
);
2824 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetAliasMembership_r(b
, tctx
, &r
),
2825 "GetAliasMembership failed");
2826 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
2827 "samr_GetAliasMembership failed");
2829 torture_assert_int_equal(tctx
, sids
.num_sids
, rids
.count
,
2830 "protocol misbehaviour");
2833 sids
.sids
= talloc_zero_array(tctx
, struct lsa_SidPtr
, sids
.num_sids
);
2834 sids
.sids
[0].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-1");
2836 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetAliasMembership_r(b
, tctx
, &r
),
2837 "samr_GetAliasMembership failed");
2838 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
2839 "samr_GetAliasMembership failed");
2842 /* only true for w2k8 it seems
2843 * win7, xp, w2k3 will return a 0 length array pointer */
2845 if (rids
.ids
&& (rids
.count
== 0)) {
2846 torture_fail(tctx
, "samr_GetAliasMembership returned 0 count and a rids array");
2849 if (!rids
.ids
&& rids
.count
) {
2850 torture_fail(tctx
, "samr_GetAliasMembership returned non-0 count but no rids");
2856 static bool test_TestPrivateFunctionsUser(struct dcerpc_binding_handle
*b
,
2857 struct torture_context
*tctx
,
2858 struct policy_handle
*user_handle
)
2860 struct samr_TestPrivateFunctionsUser r
;
2862 torture_comment(tctx
, "Testing TestPrivateFunctionsUser\n");
2864 r
.in
.user_handle
= user_handle
;
2866 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_TestPrivateFunctionsUser_r(b
, tctx
, &r
),
2867 "TestPrivateFunctionsUser failed");
2868 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_NOT_IMPLEMENTED
, "TestPrivateFunctionsUser");
2873 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_binding_handle
*b
,
2874 struct torture_context
*tctx
,
2875 struct policy_handle
*handle
,
2880 uint16_t levels
[] = { /* 3, */ 5, 21 };
2882 NTTIME pwdlastset3
= 0;
2883 NTTIME pwdlastset5
= 0;
2884 NTTIME pwdlastset21
= 0;
2886 torture_comment(tctx
, "Testing QueryUserInfo%s level 5 and 21 call ",
2887 use_info2
? "2":"");
2889 for (i
=0; i
<ARRAY_SIZE(levels
); i
++) {
2891 struct samr_QueryUserInfo r
;
2892 struct samr_QueryUserInfo2 r2
;
2893 union samr_UserInfo
*info
;
2896 r2
.in
.user_handle
= handle
;
2897 r2
.in
.level
= levels
[i
];
2898 r2
.out
.info
= &info
;
2899 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo2_r(b
, tctx
, &r2
),
2900 "QueryUserInfo2 failed");
2901 status
= r2
.out
.result
;
2904 r
.in
.user_handle
= handle
;
2905 r
.in
.level
= levels
[i
];
2907 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
2908 "QueryUserInfo failed");
2909 status
= r
.out
.result
;
2912 if (!NT_STATUS_IS_OK(status
) &&
2913 !NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_INFO_CLASS
)) {
2914 torture_warning(tctx
, "QueryUserInfo%s level %u failed - %s\n",
2915 use_info2
? "2":"", levels
[i
], nt_errstr(status
));
2919 switch (levels
[i
]) {
2921 pwdlastset3
= info
->info3
.last_password_change
;
2924 pwdlastset5
= info
->info5
.last_password_change
;
2927 pwdlastset21
= info
->info21
.last_password_change
;
2933 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2934 "pwdlastset mixup"); */
2935 torture_assert_int_equal(tctx
, pwdlastset5
, pwdlastset21
,
2936 "pwdlastset mixup");
2938 *pwdlastset
= pwdlastset21
;
2940 torture_comment(tctx
, "(pwdlastset: %llu)\n",
2941 (unsigned long long) *pwdlastset
);
2946 static bool test_SamLogon(struct torture_context
*tctx
,
2947 struct dcerpc_pipe
*p
,
2948 struct cli_credentials
*test_credentials
,
2949 NTSTATUS expected_result
,
2953 struct netr_LogonSamLogonEx r
;
2954 union netr_LogonLevel logon
;
2955 union netr_Validation validation
;
2956 uint8_t authoritative
;
2957 struct netr_IdentityInfo identity
;
2958 struct netr_NetworkInfo ninfo
;
2959 struct netr_PasswordInfo pinfo
;
2960 DATA_BLOB names_blob
, chal
, lm_resp
, nt_resp
;
2961 int flags
= CLI_CRED_NTLM_AUTH
;
2962 uint32_t samlogon_flags
= 0;
2963 struct netlogon_creds_CredentialState
*creds
;
2964 struct netr_Authenticator a
;
2965 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2967 torture_assert_ntstatus_ok(tctx
, dcerpc_schannel_creds(p
->conn
->security_state
.generic_state
, tctx
, &creds
), "");
2969 if (lpcfg_client_lanman_auth(tctx
->lp_ctx
)) {
2970 flags
|= CLI_CRED_LANMAN_AUTH
;
2973 if (lpcfg_client_ntlmv2_auth(tctx
->lp_ctx
)) {
2974 flags
|= CLI_CRED_NTLMv2_AUTH
;
2977 cli_credentials_get_ntlm_username_domain(test_credentials
, tctx
,
2978 &identity
.account_name
.string
,
2979 &identity
.domain_name
.string
);
2981 identity
.parameter_control
=
2982 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT
|
2983 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT
;
2984 identity
.logon_id_low
= 0;
2985 identity
.logon_id_high
= 0;
2986 identity
.workstation
.string
= cli_credentials_get_workstation(test_credentials
);
2989 netlogon_creds_client_authenticator(creds
, &a
);
2991 if (!E_deshash(cli_credentials_get_password(test_credentials
), pinfo
.lmpassword
.hash
)) {
2992 ZERO_STRUCT(pinfo
.lmpassword
.hash
);
2994 E_md4hash(cli_credentials_get_password(test_credentials
), pinfo
.ntpassword
.hash
);
2996 if (creds
->negotiate_flags
& NETLOGON_NEG_SUPPORTS_AES
) {
2997 netlogon_creds_aes_encrypt(creds
, pinfo
.lmpassword
.hash
, 16);
2998 netlogon_creds_aes_encrypt(creds
, pinfo
.ntpassword
.hash
, 16);
2999 } else if (creds
->negotiate_flags
& NETLOGON_NEG_ARCFOUR
) {
3000 netlogon_creds_arcfour_crypt(creds
, pinfo
.lmpassword
.hash
, 16);
3001 netlogon_creds_arcfour_crypt(creds
, pinfo
.ntpassword
.hash
, 16);
3003 netlogon_creds_des_encrypt(creds
, &pinfo
.lmpassword
);
3004 netlogon_creds_des_encrypt(creds
, &pinfo
.ntpassword
);
3007 pinfo
.identity_info
= identity
;
3008 logon
.password
= &pinfo
;
3010 r
.in
.logon_level
= NetlogonInteractiveInformation
;
3012 generate_random_buffer(ninfo
.challenge
,
3013 sizeof(ninfo
.challenge
));
3014 chal
= data_blob_const(ninfo
.challenge
,
3015 sizeof(ninfo
.challenge
));
3017 names_blob
= NTLMv2_generate_names_blob(tctx
, cli_credentials_get_workstation(test_credentials
),
3018 cli_credentials_get_domain(test_credentials
));
3020 status
= cli_credentials_get_ntlm_response(test_credentials
, tctx
,
3026 torture_assert_ntstatus_ok(tctx
, status
, "cli_credentials_get_ntlm_response failed");
3028 ninfo
.lm
.data
= lm_resp
.data
;
3029 ninfo
.lm
.length
= lm_resp
.length
;
3031 ninfo
.nt
.data
= nt_resp
.data
;
3032 ninfo
.nt
.length
= nt_resp
.length
;
3034 ninfo
.identity_info
= identity
;
3035 logon
.network
= &ninfo
;
3037 r
.in
.logon_level
= NetlogonNetworkInformation
;
3040 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
3041 r
.in
.computer_name
= cli_credentials_get_workstation(test_credentials
);
3042 r
.in
.logon
= &logon
;
3043 r
.in
.flags
= &samlogon_flags
;
3044 r
.out
.flags
= &samlogon_flags
;
3045 r
.out
.validation
= &validation
;
3046 r
.out
.authoritative
= &authoritative
;
3048 torture_comment(tctx
, "Testing LogonSamLogon with name %s\n", identity
.account_name
.string
);
3050 r
.in
.validation_level
= 6;
3052 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonSamLogonEx_r(b
, tctx
, &r
),
3053 "netr_LogonSamLogonEx failed");
3054 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_INFO_CLASS
)) {
3055 r
.in
.validation_level
= 3;
3056 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonSamLogonEx_r(b
, tctx
, &r
),
3057 "netr_LogonSamLogonEx failed");
3059 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
3060 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, expected_result
, "LogonSamLogonEx failed");
3063 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LogonSamLogonEx failed");
3069 static bool test_SamLogon_with_creds(struct torture_context
*tctx
,
3070 struct dcerpc_pipe
*p
,
3071 struct cli_credentials
*machine_creds
,
3072 const char *acct_name
,
3073 const char *password
,
3074 NTSTATUS expected_samlogon_result
,
3078 struct cli_credentials
*test_credentials
;
3080 test_credentials
= cli_credentials_init(tctx
);
3082 cli_credentials_set_workstation(test_credentials
,
3083 cli_credentials_get_workstation(machine_creds
), CRED_SPECIFIED
);
3084 cli_credentials_set_domain(test_credentials
,
3085 cli_credentials_get_domain(machine_creds
), CRED_SPECIFIED
);
3086 cli_credentials_set_username(test_credentials
,
3087 acct_name
, CRED_SPECIFIED
);
3088 cli_credentials_set_password(test_credentials
,
3089 password
, CRED_SPECIFIED
);
3091 torture_comment(tctx
, "Testing samlogon (%s) as %s password: %s\n",
3092 interactive
? "interactive" : "network", acct_name
, password
);
3094 if (!test_SamLogon(tctx
, p
, test_credentials
,
3095 expected_samlogon_result
, interactive
)) {
3096 torture_warning(tctx
, "new password did not work\n");
3103 static bool test_SetPassword_level(struct dcerpc_pipe
*p
,
3104 struct dcerpc_pipe
*np
,
3105 struct torture_context
*tctx
,
3106 struct policy_handle
*handle
,
3108 uint32_t fields_present
,
3109 uint8_t password_expired
,
3110 bool *matched_expected_error
,
3112 const char *acct_name
,
3114 struct cli_credentials
*machine_creds
,
3115 bool use_queryinfo2
,
3117 NTSTATUS expected_samlogon_result
)
3119 const char *fields
= NULL
;
3121 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3127 fields
= talloc_asprintf(tctx
, "(fields_present: 0x%08x)",
3134 torture_comment(tctx
, "Testing SetUserInfo%s level %d call "
3135 "(password_expired: %d) %s\n",
3136 use_setinfo2
? "2":"", level
, password_expired
,
3137 fields
? fields
: "");
3139 if (!test_SetUserPass_level_ex(p
, tctx
, handle
, level
,
3144 matched_expected_error
)) {
3148 if (!test_QueryUserInfo_pwdlastset(b
, tctx
, handle
,
3154 if (*matched_expected_error
== true) {
3158 if (!test_SamLogon_with_creds(tctx
, np
,
3162 expected_samlogon_result
,
3170 static bool setup_schannel_netlogon_pipe(struct torture_context
*tctx
,
3171 struct cli_credentials
*credentials
,
3172 struct dcerpc_pipe
**p
)
3174 struct dcerpc_binding
*b
;
3176 torture_assert_ntstatus_ok(tctx
, torture_rpc_binding(tctx
, &b
),
3177 "failed to get rpc binding");
3179 /* We have to use schannel, otherwise the SamLogonEx fails
3180 * with INTERNAL_ERROR */
3182 b
->flags
&= ~DCERPC_AUTH_OPTIONS
;
3183 b
->flags
|= DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_AUTO
;
3185 torture_assert_ntstatus_ok(tctx
,
3186 dcerpc_pipe_connect_b(tctx
, p
, b
, &ndr_table_netlogon
,
3187 credentials
, tctx
->ev
, tctx
->lp_ctx
),
3188 "failed to bind to netlogon");
3193 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe
*p
,
3194 struct torture_context
*tctx
,
3195 uint32_t acct_flags
,
3196 const char *acct_name
,
3197 struct policy_handle
*handle
,
3199 struct cli_credentials
*machine_credentials
)
3201 int s
= 0, q
= 0, f
= 0, l
= 0, z
= 0;
3204 bool set_levels
[] = { false, true };
3205 bool query_levels
[] = { false, true };
3206 uint32_t levels
[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
3207 uint32_t nonzeros
[] = { 1, 24 };
3208 uint32_t fields_present
[] = {
3210 SAMR_FIELD_EXPIRED_FLAG
,
3211 SAMR_FIELD_LAST_PWD_CHANGE
,
3212 SAMR_FIELD_EXPIRED_FLAG
| SAMR_FIELD_LAST_PWD_CHANGE
,
3214 SAMR_FIELD_NT_PASSWORD_PRESENT
,
3215 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
,
3216 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
,
3217 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
,
3218 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_EXPIRED_FLAG
,
3219 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_EXPIRED_FLAG
,
3220 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
| SAMR_FIELD_EXPIRED_FLAG
3222 struct dcerpc_pipe
*np
= NULL
;
3224 if (torture_setting_bool(tctx
, "samba3", false) ||
3225 torture_setting_bool(tctx
, "samba4", false)) {
3227 torture_comment(tctx
, "Samba3 has second granularity, setting delay to: %d\n",
3231 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
3233 /* set to 1 to enable testing for all possible opcode
3234 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3237 #define TEST_ALL_LEVELS 1
3238 #define TEST_SET_LEVELS 1
3239 #define TEST_QUERY_LEVELS 1
3241 #ifdef TEST_ALL_LEVELS
3242 for (l
=0; l
<ARRAY_SIZE(levels
); l
++) {
3244 for (l
=0; l
<(ARRAY_SIZE(levels
))/2; l
++) {
3246 for (z
=0; z
<ARRAY_SIZE(nonzeros
); z
++) {
3247 for (f
=0; f
<ARRAY_SIZE(fields_present
); f
++) {
3248 #ifdef TEST_SET_LEVELS
3249 for (s
=0; s
<ARRAY_SIZE(set_levels
); s
++) {
3251 #ifdef TEST_QUERY_LEVELS
3252 for (q
=0; q
<ARRAY_SIZE(query_levels
); q
++) {
3254 NTTIME pwdlastset_old
= 0;
3255 NTTIME pwdlastset_new
= 0;
3256 bool matched_expected_error
= false;
3257 NTSTATUS expected_samlogon_result
= NT_STATUS_ACCOUNT_DISABLED
;
3259 torture_comment(tctx
, "------------------------------\n"
3260 "Testing pwdLastSet attribute for flags: 0x%08x "
3261 "(s: %d (l: %d), q: %d)\n",
3262 acct_flags
, s
, levels
[l
], q
);
3264 switch (levels
[l
]) {
3268 if (!((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3269 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
))) {
3270 expected_samlogon_result
= NT_STATUS_WRONG_PASSWORD
;
3278 /* set a password and force password change (pwdlastset 0) by
3279 * setting the password expired flag to a non-0 value */
3281 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3285 &matched_expected_error
,
3289 machine_credentials
,
3292 expected_samlogon_result
)) {
3296 if (matched_expected_error
== true) {
3297 /* skipping on expected failure */
3301 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3302 * set without the SAMR_FIELD_EXPIRED_FLAG */
3304 switch (levels
[l
]) {
3308 if ((pwdlastset_new
!= 0) &&
3309 !(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
)) {
3310 torture_comment(tctx
, "not considering a non-0 "
3311 "pwdLastSet as a an error as the "
3312 "SAMR_FIELD_EXPIRED_FLAG has not "
3318 if (pwdlastset_new
!= 0) {
3319 torture_warning(tctx
, "pwdLastSet test failed: "
3320 "expected pwdLastSet 0 but got %llu\n",
3321 (unsigned long long) pwdlastset_old
);
3327 switch (levels
[l
]) {
3331 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3332 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3333 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3334 (pwdlastset_old
>= pwdlastset_new
)) {
3335 torture_warning(tctx
, "pwdlastset not increasing\n");
3341 pwdlastset_old
= pwdlastset_new
;
3347 /* set a password, pwdlastset needs to get updated (increased
3348 * value), password_expired value used here is 0 */
3350 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3354 &matched_expected_error
,
3358 machine_credentials
,
3361 expected_samlogon_result
)) {
3365 /* when a password has been changed, pwdlastset must not be 0 afterwards
3366 * and must be larger then the old value */
3368 switch (levels
[l
]) {
3372 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3373 * password has been changed, old and new pwdlastset
3374 * need to be the same value */
3376 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
3377 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3378 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3380 torture_assert_int_equal(tctx
, pwdlastset_old
,
3381 pwdlastset_new
, "pwdlastset must be equal");
3386 if (pwdlastset_old
>= pwdlastset_new
) {
3387 torture_warning(tctx
, "pwdLastSet test failed: "
3388 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3389 (unsigned long long) pwdlastset_old
,
3390 (unsigned long long) pwdlastset_new
);
3393 if (pwdlastset_new
== 0) {
3394 torture_warning(tctx
, "pwdLastSet test failed: "
3395 "expected non-0 pwdlastset, got: %llu\n",
3396 (unsigned long long) pwdlastset_new
);
3402 switch (levels
[l
]) {
3406 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3407 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3408 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3409 (pwdlastset_old
>= pwdlastset_new
)) {
3410 torture_warning(tctx
, "pwdlastset not increasing\n");
3416 pwdlastset_old
= pwdlastset_new
;
3422 /* set a password, pwdlastset needs to get updated (increased
3423 * value), password_expired value used here is 0 */
3425 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3429 &matched_expected_error
,
3433 machine_credentials
,
3436 expected_samlogon_result
)) {
3440 /* when a password has been changed, pwdlastset must not be 0 afterwards
3441 * and must be larger then the old value */
3443 switch (levels
[l
]) {
3448 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3449 * password has been changed, old and new pwdlastset
3450 * need to be the same value */
3452 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
3453 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3454 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3456 torture_assert_int_equal(tctx
, pwdlastset_old
,
3457 pwdlastset_new
, "pwdlastset must be equal");
3462 if (pwdlastset_old
>= pwdlastset_new
) {
3463 torture_warning(tctx
, "pwdLastSet test failed: "
3464 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3465 (unsigned long long) pwdlastset_old
,
3466 (unsigned long long) pwdlastset_new
);
3469 if (pwdlastset_new
== 0) {
3470 torture_warning(tctx
, "pwdLastSet test failed: "
3471 "expected non-0 pwdlastset, got: %llu\n",
3472 (unsigned long long) pwdlastset_new
);
3478 switch (levels
[l
]) {
3482 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3483 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3484 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3485 (pwdlastset_old
>= pwdlastset_new
)) {
3486 torture_warning(tctx
, "pwdlastset not increasing\n");
3492 pwdlastset_old
= pwdlastset_new
;
3498 /* set a password and force password change (pwdlastset 0) by
3499 * setting the password expired flag to a non-0 value */
3501 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3505 &matched_expected_error
,
3509 machine_credentials
,
3512 expected_samlogon_result
)) {
3516 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3517 * set without the SAMR_FIELD_EXPIRED_FLAG */
3519 switch (levels
[l
]) {
3523 if ((pwdlastset_new
!= 0) &&
3524 !(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
)) {
3525 torture_comment(tctx
, "not considering a non-0 "
3526 "pwdLastSet as a an error as the "
3527 "SAMR_FIELD_EXPIRED_FLAG has not "
3532 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3533 * password has been changed, old and new pwdlastset
3534 * need to be the same value */
3536 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
3537 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3538 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3540 torture_assert_int_equal(tctx
, pwdlastset_old
,
3541 pwdlastset_new
, "pwdlastset must be equal");
3546 if (pwdlastset_new
!= 0) {
3547 torture_warning(tctx
, "pwdLastSet test failed: "
3548 "expected pwdLastSet 0, got %llu\n",
3549 (unsigned long long) pwdlastset_old
);
3555 switch (levels
[l
]) {
3559 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3560 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3561 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3562 (pwdlastset_old
>= pwdlastset_new
)) {
3563 torture_warning(tctx
, "pwdlastset not increasing\n");
3569 /* if the level we are testing does not have a fields_present
3570 * field, skip all fields present tests by setting f to to
3572 switch (levels
[l
]) {
3576 f
= ARRAY_SIZE(fields_present
);
3580 #ifdef TEST_QUERY_LEVELS
3583 #ifdef TEST_SET_LEVELS
3586 } /* fields present */
3590 #undef TEST_SET_LEVELS
3591 #undef TEST_QUERY_LEVELS
3598 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_binding_handle
*b
,
3599 struct torture_context
*tctx
,
3600 struct policy_handle
*handle
,
3601 uint32_t *badpwdcount
)
3603 union samr_UserInfo
*info
;
3604 struct samr_QueryUserInfo r
;
3606 r
.in
.user_handle
= handle
;
3610 torture_comment(tctx
, "Testing QueryUserInfo level %d", r
.in
.level
);
3612 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
3613 "failed to query userinfo");
3614 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
3615 "failed to query userinfo");
3617 *badpwdcount
= info
->info3
.bad_password_count
;
3619 torture_comment(tctx
, " (bad password count: %d)\n", *badpwdcount
);
3624 static bool test_SetUserInfo_acct_flags(struct dcerpc_binding_handle
*b
,
3625 struct torture_context
*tctx
,
3626 struct policy_handle
*user_handle
,
3627 uint32_t acct_flags
)
3629 struct samr_SetUserInfo r
;
3630 union samr_UserInfo user_info
;
3632 torture_comment(tctx
, "Testing SetUserInfo level 16\n");
3634 user_info
.info16
.acct_flags
= acct_flags
;
3636 r
.in
.user_handle
= user_handle
;
3638 r
.in
.info
= &user_info
;
3640 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &r
),
3641 "failed to set account flags");
3642 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
3643 "failed to set account flags");
3648 static bool test_reset_badpwdcount(struct dcerpc_pipe
*p
,
3649 struct torture_context
*tctx
,
3650 struct policy_handle
*user_handle
,
3651 uint32_t acct_flags
,
3654 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3656 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
3657 "failed to set password");
3659 torture_comment(tctx
, "Testing SetUserInfo level 16 (enable account)\n");
3661 torture_assert(tctx
,
3662 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
3663 acct_flags
& ~ACB_DISABLED
),
3664 "failed to enable user");
3666 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
3667 "failed to set password");
3672 static bool test_SetDomainInfo(struct dcerpc_binding_handle
*b
,
3673 struct torture_context
*tctx
,
3674 struct policy_handle
*domain_handle
,
3675 enum samr_DomainInfoClass level
,
3676 union samr_DomainInfo
*info
)
3678 struct samr_SetDomainInfo r
;
3680 r
.in
.domain_handle
= domain_handle
;
3684 torture_assert_ntstatus_ok(tctx
,
3685 dcerpc_samr_SetDomainInfo_r(b
, tctx
, &r
),
3686 "failed to set domain info");
3687 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
3688 "failed to set domain info");
3693 static bool test_SetDomainInfo_ntstatus(struct dcerpc_binding_handle
*b
,
3694 struct torture_context
*tctx
,
3695 struct policy_handle
*domain_handle
,
3696 enum samr_DomainInfoClass level
,
3697 union samr_DomainInfo
*info
,
3700 struct samr_SetDomainInfo r
;
3702 r
.in
.domain_handle
= domain_handle
;
3706 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &r
),
3707 "SetDomainInfo failed");
3708 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, expected
, "");
3713 static bool test_QueryDomainInfo2_level(struct dcerpc_binding_handle
*b
,
3714 struct torture_context
*tctx
,
3715 struct policy_handle
*domain_handle
,
3716 enum samr_DomainInfoClass level
,
3717 union samr_DomainInfo
**q_info
)
3719 struct samr_QueryDomainInfo2 r
;
3721 r
.in
.domain_handle
= domain_handle
;
3723 r
.out
.info
= q_info
;
3725 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo2_r(b
, tctx
, &r
),
3726 "failed to query domain info");
3727 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
3728 "failed to query domain info");
3733 static bool test_Password_badpwdcount(struct dcerpc_pipe
*p
,
3734 struct dcerpc_pipe
*np
,
3735 struct torture_context
*tctx
,
3736 uint32_t acct_flags
,
3737 const char *acct_name
,
3738 struct policy_handle
*domain_handle
,
3739 struct policy_handle
*user_handle
,
3741 struct cli_credentials
*machine_credentials
,
3742 const char *comment
,
3745 NTSTATUS expected_success_status
,
3746 struct samr_DomInfo1
*info1
,
3747 struct samr_DomInfo12
*info12
)
3749 union samr_DomainInfo info
;
3752 uint32_t badpwdcount
, tmp
;
3753 uint32_t password_history_length
= 12;
3754 uint32_t lockout_threshold
= 15;
3755 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3757 torture_comment(tctx
, "\nTesting bad pwd count with: %s\n", comment
);
3759 torture_assert(tctx
, password_history_length
< lockout_threshold
,
3760 "password history length needs to be smaller than account lockout threshold for this test");
3765 info
.info1
= *info1
;
3766 info
.info1
.password_history_length
= password_history_length
;
3768 torture_assert(tctx
,
3769 test_SetDomainInfo(b
, tctx
, domain_handle
,
3770 DomainPasswordInformation
, &info
),
3771 "failed to set password history length");
3773 info
.info12
= *info12
;
3774 info
.info12
.lockout_threshold
= lockout_threshold
;
3776 torture_assert(tctx
,
3777 test_SetDomainInfo(b
, tctx
, domain_handle
,
3778 DomainLockoutInformation
, &info
),
3779 "failed to set lockout threshold");
3781 /* reset bad pwd count */
3783 torture_assert(tctx
,
3784 test_reset_badpwdcount(p
, tctx
, user_handle
, acct_flags
, password
), "");
3787 /* enable or disable account */
3789 torture_assert(tctx
,
3790 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
3791 acct_flags
| ACB_DISABLED
),
3792 "failed to disable user");
3794 torture_assert(tctx
,
3795 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
3796 acct_flags
& ~ACB_DISABLED
),
3797 "failed to enable user");
3801 /* setup password history */
3803 passwords
= talloc_array(tctx
, char *, password_history_length
);
3805 for (i
=0; i
< password_history_length
; i
++) {
3807 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
3808 "failed to set password");
3809 passwords
[i
] = talloc_strdup(tctx
, *password
);
3811 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3812 acct_name
, passwords
[i
],
3813 expected_success_status
, interactive
)) {
3814 torture_fail(tctx
, "failed to auth with latest password");
3817 torture_assert(tctx
,
3818 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3820 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3824 /* test with wrong password */
3826 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3827 acct_name
, "random_crap",
3828 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
3829 torture_fail(tctx
, "succeeded to authenticate with wrong password");
3832 torture_assert(tctx
,
3833 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3835 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
3838 /* test with latest good password */
3840 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
3841 passwords
[password_history_length
-1],
3842 expected_success_status
, interactive
)) {
3843 torture_fail(tctx
, "succeeded to authenticate with wrong password");
3846 torture_assert(tctx
,
3847 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3850 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
3852 /* only enabled accounts get the bad pwd count reset upon
3853 * successful logon */
3854 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3860 /* test password history */
3862 for (i
=0; i
< password_history_length
; i
++) {
3864 torture_comment(tctx
, "Testing bad password count behavior with "
3865 "password #%d of #%d\n", i
, password_history_length
);
3867 /* - network samlogon will succeed auth and not
3868 * increase badpwdcount for 2 last entries
3869 * - interactive samlogon only for the last one */
3871 if (i
== password_history_length
- 1 ||
3872 (i
== password_history_length
- 2 && !interactive
)) {
3874 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3875 acct_name
, passwords
[i
],
3876 expected_success_status
, interactive
)) {
3877 torture_fail(tctx
, talloc_asprintf(tctx
, "succeeded to authenticate with old password (#%d of #%d in history)", i
, password_history_length
));
3880 torture_assert(tctx
,
3881 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3884 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
3885 torture_assert_int_equal(tctx
, badpwdcount
, tmp
, "unexpected badpwdcount");
3887 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
3888 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3896 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3897 acct_name
, passwords
[i
],
3898 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
3899 torture_fail(tctx
, talloc_asprintf(tctx
, "succeeded to authenticate with old password (#%d of #%d in history)", i
, password_history_length
));
3902 torture_assert(tctx
,
3903 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3905 /* - network samlogon will fail auth but not increase
3906 * badpwdcount for 3rd last entry
3907 * - interactive samlogon for 3rd and 2nd last entry */
3909 if (i
== password_history_length
- 3 ||
3910 (i
== password_history_length
- 2 && interactive
)) {
3911 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
3912 torture_assert_int_equal(tctx
, badpwdcount
, tmp
, "unexpected badpwdcount");
3914 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
3915 torture_assert_int_equal(tctx
, badpwdcount
, tmp
+ 1, "unexpected badpwdcount");
3924 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe
*p
,
3925 struct torture_context
*tctx
,
3926 uint32_t acct_flags
,
3927 const char *acct_name
,
3928 struct policy_handle
*domain_handle
,
3929 struct policy_handle
*user_handle
,
3931 struct cli_credentials
*machine_credentials
)
3933 union samr_DomainInfo
*q_info
, s_info
;
3934 struct samr_DomInfo1 info1
, _info1
;
3935 struct samr_DomInfo12 info12
, _info12
;
3937 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3938 struct dcerpc_pipe
*np
;
3942 const char *comment
;
3945 NTSTATUS expected_success_status
;
3948 .comment
= "network logon (disabled account)",
3950 .interactive
= false,
3951 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
3954 .comment
= "network logon (enabled account)",
3956 .interactive
= false,
3957 .expected_success_status
= NT_STATUS_OK
3960 .comment
= "interactive logon (disabled account)",
3962 .interactive
= true,
3963 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
3966 .comment
= "interactive logon (enabled account)",
3968 .interactive
= true,
3969 .expected_success_status
= NT_STATUS_OK
3973 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
3975 /* backup old policies */
3977 torture_assert(tctx
,
3978 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
3979 DomainPasswordInformation
, &q_info
),
3980 "failed to query domain info level 1");
3982 info1
= q_info
->info1
;
3985 torture_assert(tctx
,
3986 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
3987 DomainLockoutInformation
, &q_info
),
3988 "failed to query domain info level 12");
3990 info12
= q_info
->info12
;
3995 for (i
=0; i
< ARRAY_SIZE(creds
); i
++) {
3997 /* skip trust tests for now */
3998 if (acct_flags
& ACB_WSTRUST
||
3999 acct_flags
& ACB_SVRTRUST
||
4000 acct_flags
& ACB_DOMTRUST
) {
4004 ret
&= test_Password_badpwdcount(p
, np
, tctx
, acct_flags
, acct_name
,
4005 domain_handle
, user_handle
, password
,
4006 machine_credentials
,
4009 creds
[i
].interactive
,
4010 creds
[i
].expected_success_status
,
4013 torture_warning(tctx
, "TEST #%d (%s) failed\n", i
, creds
[i
].comment
);
4015 torture_comment(tctx
, "TEST #%d (%s) succeeded\n", i
, creds
[i
].comment
);
4019 /* restore policies */
4021 s_info
.info1
= info1
;
4023 torture_assert(tctx
,
4024 test_SetDomainInfo(b
, tctx
, domain_handle
,
4025 DomainPasswordInformation
, &s_info
),
4026 "failed to set password information");
4028 s_info
.info12
= info12
;
4030 torture_assert(tctx
,
4031 test_SetDomainInfo(b
, tctx
, domain_handle
,
4032 DomainLockoutInformation
, &s_info
),
4033 "failed to set lockout information");
4038 static bool test_QueryUserInfo_acct_flags(struct dcerpc_binding_handle
*b
,
4039 struct torture_context
*tctx
,
4040 struct policy_handle
*handle
,
4041 uint32_t *acct_flags
)
4043 union samr_UserInfo
*info
;
4044 struct samr_QueryUserInfo r
;
4046 r
.in
.user_handle
= handle
;
4050 torture_comment(tctx
, "Testing QueryUserInfo level %d", r
.in
.level
);
4052 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
4053 "failed to query userinfo");
4054 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4055 "failed to query userinfo");
4057 *acct_flags
= info
->info16
.acct_flags
;
4059 torture_comment(tctx
, " (acct_flags: 0x%08x)\n", *acct_flags
);
4064 static bool test_Password_lockout(struct dcerpc_pipe
*p
,
4065 struct dcerpc_pipe
*np
,
4066 struct torture_context
*tctx
,
4067 uint32_t acct_flags
,
4068 const char *acct_name
,
4069 struct policy_handle
*domain_handle
,
4070 struct policy_handle
*user_handle
,
4072 struct cli_credentials
*machine_credentials
,
4073 const char *comment
,
4076 NTSTATUS expected_success_status
,
4077 struct samr_DomInfo1
*info1
,
4078 struct samr_DomInfo12
*info12
)
4080 union samr_DomainInfo info
;
4081 uint32_t badpwdcount
;
4082 uint32_t password_history_length
= 1;
4083 uint64_t lockout_threshold
= 1;
4084 uint32_t lockout_seconds
= 5;
4085 uint64_t delta_time_factor
= 10 * 1000 * 1000;
4086 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4088 torture_comment(tctx
, "\nTesting account lockout: %s\n", comment
);
4092 info
.info1
= *info1
;
4094 torture_comment(tctx
, "setting password history length.\n");
4095 info
.info1
.password_history_length
= password_history_length
;
4097 torture_assert(tctx
,
4098 test_SetDomainInfo(b
, tctx
, domain_handle
,
4099 DomainPasswordInformation
, &info
),
4100 "failed to set password history length");
4102 info
.info12
= *info12
;
4103 info
.info12
.lockout_threshold
= lockout_threshold
;
4105 /* set lockout duration < lockout window: should fail */
4106 info
.info12
.lockout_duration
= ~(lockout_seconds
* delta_time_factor
);
4107 info
.info12
.lockout_window
= ~((lockout_seconds
+ 1) * delta_time_factor
);
4109 torture_assert(tctx
,
4110 test_SetDomainInfo_ntstatus(b
, tctx
, domain_handle
,
4111 DomainLockoutInformation
, &info
,
4112 NT_STATUS_INVALID_PARAMETER
),
4113 "setting lockout duration < lockout window gave unexpected result");
4115 info
.info12
.lockout_duration
= 0;
4116 info
.info12
.lockout_window
= 0;
4118 torture_assert(tctx
,
4119 test_SetDomainInfo(b
, tctx
, domain_handle
,
4120 DomainLockoutInformation
, &info
),
4121 "failed to set lockout window and duration to 0");
4124 /* set lockout duration of 5 seconds */
4125 info
.info12
.lockout_duration
= ~(lockout_seconds
* delta_time_factor
);
4126 info
.info12
.lockout_window
= ~(lockout_seconds
* delta_time_factor
);
4128 torture_assert(tctx
,
4129 test_SetDomainInfo(b
, tctx
, domain_handle
,
4130 DomainLockoutInformation
, &info
),
4131 "failed to set lockout window and duration to 5 seconds");
4133 /* reset bad pwd count */
4135 torture_assert(tctx
,
4136 test_reset_badpwdcount(p
, tctx
, user_handle
, acct_flags
, password
), "");
4139 /* enable or disable account */
4142 torture_assert(tctx
,
4143 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
4144 acct_flags
| ACB_DISABLED
),
4145 "failed to disable user");
4147 torture_assert(tctx
,
4148 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
4149 acct_flags
& ~ACB_DISABLED
),
4150 "failed to enable user");
4154 /* test logon with right password */
4156 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
4157 acct_name
, *password
,
4158 expected_success_status
, interactive
)) {
4159 torture_fail(tctx
, "failed to auth with latest password");
4162 torture_assert(tctx
,
4163 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4164 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
4167 /* test with wrong password ==> lockout */
4169 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
4170 acct_name
, "random_crap",
4171 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
4172 torture_fail(tctx
, "succeeded to authenticate with wrong password");
4175 torture_assert(tctx
,
4176 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4177 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
4179 torture_assert(tctx
,
4180 test_QueryUserInfo_acct_flags(b
, tctx
, user_handle
, &acct_flags
), "");
4181 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
4182 "expected account to be locked");
4185 /* test with good password */
4187 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
4189 NT_STATUS_ACCOUNT_LOCKED_OUT
, interactive
))
4191 torture_fail(tctx
, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4194 /* bad pwd count should not get updated */
4195 torture_assert(tctx
,
4196 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4197 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
4199 /* curiously, windows does _not_ set the autlock flag */
4200 torture_assert(tctx
,
4201 test_QueryUserInfo_acct_flags(b
, tctx
, user_handle
, &acct_flags
), "");
4202 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
4203 "expected account to be locked");
4206 /* with bad password */
4208 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
4209 acct_name
, "random_crap2",
4210 NT_STATUS_ACCOUNT_LOCKED_OUT
, interactive
))
4212 torture_fail(tctx
, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4215 /* bad pwd count should not get updated */
4216 torture_assert(tctx
,
4217 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4218 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
4220 /* curiously, windows does _not_ set the autlock flag */
4221 torture_assert(tctx
,
4222 test_QueryUserInfo_acct_flags(b
, tctx
, user_handle
, &acct_flags
), "");
4223 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
4224 "expected account to be locked");
4227 /* let lockout duration expire ==> unlock */
4229 torture_comment(tctx
, "let lockout duration expire...\n");
4230 sleep(lockout_seconds
+ 1);
4232 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
4234 expected_success_status
, interactive
))
4236 torture_fail(tctx
, "failed to authenticate after lockout expired");
4239 torture_assert(tctx
,
4240 test_QueryUserInfo_acct_flags(b
, tctx
, user_handle
, &acct_flags
), "");
4241 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
4242 "expected account not to be locked");
4247 static bool test_Password_lockout_wrap(struct dcerpc_pipe
*p
,
4248 struct torture_context
*tctx
,
4249 uint32_t acct_flags
,
4250 const char *acct_name
,
4251 struct policy_handle
*domain_handle
,
4252 struct policy_handle
*user_handle
,
4254 struct cli_credentials
*machine_credentials
)
4256 union samr_DomainInfo
*q_info
, s_info
;
4257 struct samr_DomInfo1 info1
, _info1
;
4258 struct samr_DomInfo12 info12
, _info12
;
4260 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4261 struct dcerpc_pipe
*np
;
4265 const char *comment
;
4268 NTSTATUS expected_success_status
;
4271 .comment
= "network logon (disabled account)",
4273 .interactive
= false,
4274 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
4277 .comment
= "network logon (enabled account)",
4279 .interactive
= false,
4280 .expected_success_status
= NT_STATUS_OK
4283 .comment
= "interactive logon (disabled account)",
4285 .interactive
= true,
4286 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
4289 .comment
= "interactive logon (enabled account)",
4291 .interactive
= true,
4292 .expected_success_status
= NT_STATUS_OK
4296 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
4298 /* backup old policies */
4300 torture_assert(tctx
,
4301 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
4302 DomainPasswordInformation
, &q_info
),
4303 "failed to query domain info level 1");
4305 info1
= q_info
->info1
;
4308 torture_assert(tctx
,
4309 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
4310 DomainLockoutInformation
, &q_info
),
4311 "failed to query domain info level 12");
4313 info12
= q_info
->info12
;
4318 for (i
=0; i
< ARRAY_SIZE(creds
); i
++) {
4320 /* skip trust tests for now */
4321 if (acct_flags
& ACB_WSTRUST
||
4322 acct_flags
& ACB_SVRTRUST
||
4323 acct_flags
& ACB_DOMTRUST
) {
4327 ret
&= test_Password_lockout(p
, np
, tctx
, acct_flags
, acct_name
,
4328 domain_handle
, user_handle
, password
,
4329 machine_credentials
,
4332 creds
[i
].interactive
,
4333 creds
[i
].expected_success_status
,
4336 torture_warning(tctx
, "TEST #%d (%s) failed\n", i
, creds
[i
].comment
);
4338 torture_comment(tctx
, "TEST #%d (%s) succeeded\n", i
, creds
[i
].comment
);
4342 /* restore policies */
4344 s_info
.info1
= info1
;
4346 torture_assert(tctx
,
4347 test_SetDomainInfo(b
, tctx
, domain_handle
,
4348 DomainPasswordInformation
, &s_info
),
4349 "failed to set password information");
4351 s_info
.info12
= info12
;
4353 torture_assert(tctx
,
4354 test_SetDomainInfo(b
, tctx
, domain_handle
,
4355 DomainLockoutInformation
, &s_info
),
4356 "failed to set lockout information");
4361 static bool test_DeleteUser_with_privs(struct dcerpc_pipe
*p
,
4362 struct dcerpc_pipe
*lp
,
4363 struct torture_context
*tctx
,
4364 struct policy_handle
*domain_handle
,
4365 struct policy_handle
*lsa_handle
,
4366 struct policy_handle
*user_handle
,
4367 const struct dom_sid
*domain_sid
,
4369 struct cli_credentials
*machine_credentials
)
4372 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4373 struct dcerpc_binding_handle
*lb
= lp
->binding_handle
;
4375 struct policy_handle lsa_acct_handle
;
4376 struct dom_sid
*user_sid
;
4378 user_sid
= dom_sid_add_rid(tctx
, domain_sid
, rid
);
4381 struct lsa_EnumAccountRights r
;
4382 struct lsa_RightSet rights
;
4384 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4386 r
.in
.handle
= lsa_handle
;
4387 r
.in
.sid
= user_sid
;
4388 r
.out
.rights
= &rights
;
4390 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
),
4391 "lsa_EnumAccountRights failed");
4392 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
4393 "Expected enum rights for account to fail");
4397 struct lsa_RightSet rights
;
4398 struct lsa_StringLarge names
[2];
4399 struct lsa_AddAccountRights r
;
4401 torture_comment(tctx
, "Testing LSA AddAccountRights\n");
4403 init_lsa_StringLarge(&names
[0], "SeMachineAccountPrivilege");
4404 init_lsa_StringLarge(&names
[1], NULL
);
4407 rights
.names
= names
;
4409 r
.in
.handle
= lsa_handle
;
4410 r
.in
.sid
= user_sid
;
4411 r
.in
.rights
= &rights
;
4413 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_AddAccountRights_r(lb
, tctx
, &r
),
4414 "lsa_AddAccountRights failed");
4415 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4416 "Failed to add privileges");
4420 struct lsa_EnumAccounts r
;
4421 uint32_t resume_handle
= 0;
4422 struct lsa_SidArray lsa_sid_array
;
4424 bool found_sid
= false;
4426 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
4428 r
.in
.handle
= lsa_handle
;
4429 r
.in
.num_entries
= 0x1000;
4430 r
.in
.resume_handle
= &resume_handle
;
4431 r
.out
.sids
= &lsa_sid_array
;
4432 r
.out
.resume_handle
= &resume_handle
;
4434 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccounts_r(lb
, tctx
, &r
),
4435 "lsa_EnumAccounts failed");
4436 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4437 "Failed to enum accounts");
4439 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
4440 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
4445 torture_assert(tctx
, found_sid
,
4446 "failed to list privileged account");
4450 struct lsa_EnumAccountRights r
;
4451 struct lsa_RightSet user_rights
;
4453 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4455 r
.in
.handle
= lsa_handle
;
4456 r
.in
.sid
= user_sid
;
4457 r
.out
.rights
= &user_rights
;
4459 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
),
4460 "lsa_EnumAccountRights failed");
4461 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4462 "Failed to enum rights for account");
4464 if (user_rights
.count
< 1) {
4465 torture_warning(tctx
, "failed to find newly added rights");
4471 struct lsa_OpenAccount r
;
4473 torture_comment(tctx
, "Testing LSA OpenAccount\n");
4475 r
.in
.handle
= lsa_handle
;
4476 r
.in
.sid
= user_sid
;
4477 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4478 r
.out
.acct_handle
= &lsa_acct_handle
;
4480 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenAccount_r(lb
, tctx
, &r
),
4481 "lsa_OpenAccount failed");
4482 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4483 "Failed to open lsa account");
4487 struct lsa_GetSystemAccessAccount r
;
4488 uint32_t access_mask
;
4490 torture_comment(tctx
, "Testing LSA GetSystemAccessAccount\n");
4492 r
.in
.handle
= &lsa_acct_handle
;
4493 r
.out
.access_mask
= &access_mask
;
4495 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_GetSystemAccessAccount_r(lb
, tctx
, &r
),
4496 "lsa_GetSystemAccessAccount failed");
4497 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4498 "Failed to get lsa system access account");
4504 torture_comment(tctx
, "Testing LSA Close\n");
4506 r
.in
.handle
= &lsa_acct_handle
;
4507 r
.out
.handle
= &lsa_acct_handle
;
4509 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_Close_r(lb
, tctx
, &r
),
4510 "lsa_Close failed");
4511 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4512 "Failed to close lsa");
4516 struct samr_DeleteUser r
;
4518 torture_comment(tctx
, "Testing SAMR DeleteUser\n");
4520 r
.in
.user_handle
= user_handle
;
4521 r
.out
.user_handle
= user_handle
;
4523 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, tctx
, &r
),
4524 "DeleteUser failed");
4525 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4526 "DeleteUser failed");
4530 struct lsa_EnumAccounts r
;
4531 uint32_t resume_handle
= 0;
4532 struct lsa_SidArray lsa_sid_array
;
4534 bool found_sid
= false;
4536 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
4538 r
.in
.handle
= lsa_handle
;
4539 r
.in
.num_entries
= 0x1000;
4540 r
.in
.resume_handle
= &resume_handle
;
4541 r
.out
.sids
= &lsa_sid_array
;
4542 r
.out
.resume_handle
= &resume_handle
;
4544 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccounts_r(lb
, tctx
, &r
),
4545 "lsa_EnumAccounts failed");
4546 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4547 "Failed to enum accounts");
4549 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
4550 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
4555 torture_assert(tctx
, found_sid
,
4556 "failed to list privileged account");
4560 struct lsa_EnumAccountRights r
;
4561 struct lsa_RightSet user_rights
;
4563 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4565 r
.in
.handle
= lsa_handle
;
4566 r
.in
.sid
= user_sid
;
4567 r
.out
.rights
= &user_rights
;
4569 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
),
4570 "lsa_EnumAccountRights failed");
4571 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4572 "Failed to enum rights for account");
4574 if (user_rights
.count
< 1) {
4575 torture_warning(tctx
, "failed to find newly added rights");
4581 struct lsa_OpenAccount r
;
4583 torture_comment(tctx
, "Testing LSA OpenAccount\n");
4585 r
.in
.handle
= lsa_handle
;
4586 r
.in
.sid
= user_sid
;
4587 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4588 r
.out
.acct_handle
= &lsa_acct_handle
;
4590 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenAccount_r(lb
, tctx
, &r
),
4591 "lsa_OpenAccount failed");
4592 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4593 "Failed to open lsa account");
4597 struct lsa_GetSystemAccessAccount r
;
4598 uint32_t access_mask
;
4600 torture_comment(tctx
, "Testing LSA GetSystemAccessAccount\n");
4602 r
.in
.handle
= &lsa_acct_handle
;
4603 r
.out
.access_mask
= &access_mask
;
4605 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_GetSystemAccessAccount_r(lb
, tctx
, &r
),
4606 "lsa_GetSystemAccessAccount failed");
4607 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4608 "Failed to get lsa system access account");
4612 struct lsa_DeleteObject r
;
4614 torture_comment(tctx
, "Testing LSA DeleteObject\n");
4616 r
.in
.handle
= &lsa_acct_handle
;
4617 r
.out
.handle
= &lsa_acct_handle
;
4619 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_DeleteObject_r(lb
, tctx
, &r
),
4620 "lsa_DeleteObject failed");
4621 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4622 "Failed to delete object");
4626 struct lsa_EnumAccounts r
;
4627 uint32_t resume_handle
= 0;
4628 struct lsa_SidArray lsa_sid_array
;
4630 bool found_sid
= false;
4632 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
4634 r
.in
.handle
= lsa_handle
;
4635 r
.in
.num_entries
= 0x1000;
4636 r
.in
.resume_handle
= &resume_handle
;
4637 r
.out
.sids
= &lsa_sid_array
;
4638 r
.out
.resume_handle
= &resume_handle
;
4640 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccounts_r(lb
, tctx
, &r
),
4641 "lsa_EnumAccounts failed");
4642 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4643 "Failed to enum accounts");
4645 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
4646 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
4651 torture_assert(tctx
, !found_sid
,
4652 "should not have listed privileged account");
4656 struct lsa_EnumAccountRights r
;
4657 struct lsa_RightSet user_rights
;
4659 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4661 r
.in
.handle
= lsa_handle
;
4662 r
.in
.sid
= user_sid
;
4663 r
.out
.rights
= &user_rights
;
4665 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
),
4666 "lsa_EnumAccountRights failed");
4667 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
4668 "Failed to enum rights for account");
4674 static bool test_user_ops(struct dcerpc_pipe
*p
,
4675 struct torture_context
*tctx
,
4676 struct policy_handle
*user_handle
,
4677 struct policy_handle
*domain_handle
,
4678 const struct dom_sid
*domain_sid
,
4679 uint32_t base_acct_flags
,
4680 const char *base_acct_name
, enum torture_samr_choice which_ops
,
4681 struct cli_credentials
*machine_credentials
)
4683 char *password
= NULL
;
4684 struct samr_QueryUserInfo q
;
4685 union samr_UserInfo
*info
;
4687 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4692 const uint32_t password_fields
[] = {
4693 SAMR_FIELD_NT_PASSWORD_PRESENT
,
4694 SAMR_FIELD_LM_PASSWORD_PRESENT
,
4695 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
,
4699 status
= test_LookupName(b
, tctx
, domain_handle
, base_acct_name
, &rid
);
4700 if (!NT_STATUS_IS_OK(status
)) {
4704 switch (which_ops
) {
4705 case TORTURE_SAMR_USER_ATTRIBUTES
:
4706 if (!test_QuerySecurity(b
, tctx
, user_handle
)) {
4710 if (!test_QueryUserInfo(b
, tctx
, user_handle
)) {
4714 if (!test_QueryUserInfo2(b
, tctx
, user_handle
)) {
4718 if (!test_SetUserInfo(b
, tctx
, user_handle
, base_acct_flags
,
4723 if (!test_GetUserPwInfo(b
, tctx
, user_handle
)) {
4727 if (!test_TestPrivateFunctionsUser(b
, tctx
, user_handle
)) {
4731 if (!test_SetUserPass(p
, tctx
, user_handle
, &password
)) {
4735 case TORTURE_SAMR_PASSWORDS
:
4736 if (base_acct_flags
& (ACB_WSTRUST
|ACB_DOMTRUST
|ACB_SVRTRUST
)) {
4737 char simple_pass
[9];
4738 char *v
= generate_random_str(tctx
, 1);
4740 ZERO_STRUCT(simple_pass
);
4741 memset(simple_pass
, *v
, sizeof(simple_pass
) - 1);
4743 torture_comment(tctx
, "Testing machine account password policy rules\n");
4745 /* Workstation trust accounts don't seem to need to honour password quality policy */
4746 if (!test_SetUserPassEx(p
, tctx
, user_handle
, true, &password
)) {
4750 if (!test_ChangePasswordUser2(p
, tctx
, base_acct_name
, &password
, simple_pass
, false)) {
4754 /* reset again, to allow another 'user' password change */
4755 if (!test_SetUserPassEx(p
, tctx
, user_handle
, true, &password
)) {
4759 /* Try a 'short' password */
4760 if (!test_ChangePasswordUser2(p
, tctx
, base_acct_name
, &password
, samr_rand_pass(tctx
, 4), false)) {
4764 /* Try a compleatly random password */
4765 if (!test_ChangePasswordRandomBytes(p
, tctx
, base_acct_name
, user_handle
, &password
)) {
4770 for (i
= 0; password_fields
[i
]; i
++) {
4771 if (!test_SetUserPass_23(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
4775 /* check it was set right */
4776 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4781 for (i
= 0; password_fields
[i
]; i
++) {
4782 if (!test_SetUserPass_25(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
4786 /* check it was set right */
4787 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4792 if (!test_SetUserPassEx(p
, tctx
, user_handle
, false, &password
)) {
4796 if (!test_ChangePassword(p
, tctx
, base_acct_name
, domain_handle
, &password
)) {
4800 if (!test_SetUserPass_18(p
, tctx
, user_handle
, &password
)) {
4804 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4808 for (i
= 0; password_fields
[i
]; i
++) {
4810 if (password_fields
[i
] == SAMR_FIELD_LM_PASSWORD_PRESENT
) {
4811 /* we need to skip as that would break
4812 * the ChangePasswordUser3 verify */
4816 if (!test_SetUserPass_21(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
4820 /* check it was set right */
4821 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4826 q
.in
.user_handle
= user_handle
;
4830 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
),
4831 "QueryUserInfo failed");
4832 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
4833 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
4834 q
.in
.level
, nt_errstr(q
.out
.result
));
4837 uint32_t expected_flags
= (base_acct_flags
| ACB_PWNOTREQ
| ACB_DISABLED
);
4838 if ((info
->info5
.acct_flags
) != expected_flags
) {
4839 torture_warning(tctx
, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4840 info
->info5
.acct_flags
,
4843 if (!torture_setting_bool(tctx
, "samba3", false)) {
4847 if (info
->info5
.rid
!= rid
) {
4848 torture_warning(tctx
, "QueryUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
4849 info
->info5
.rid
, rid
);
4856 case TORTURE_SAMR_PASSWORDS_PWDLASTSET
:
4858 /* test last password change timestamp behaviour */
4859 if (!test_SetPassword_pwdlastset(p
, tctx
, base_acct_flags
,
4861 user_handle
, &password
,
4862 machine_credentials
)) {
4867 torture_comment(tctx
, "pwdLastSet test succeeded\n");
4869 torture_warning(tctx
, "pwdLastSet test failed\n");
4874 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
:
4876 /* test bad pwd count change behaviour */
4877 if (!test_Password_badpwdcount_wrap(p
, tctx
, base_acct_flags
,
4880 user_handle
, &password
,
4881 machine_credentials
)) {
4886 torture_comment(tctx
, "badPwdCount test succeeded\n");
4888 torture_warning(tctx
, "badPwdCount test failed\n");
4893 case TORTURE_SAMR_PASSWORDS_LOCKOUT
:
4895 if (!test_Password_lockout_wrap(p
, tctx
, base_acct_flags
,
4898 user_handle
, &password
,
4899 machine_credentials
))
4905 torture_comment(tctx
, "lockout test succeeded\n");
4907 torture_warning(tctx
, "lockout test failed\n");
4913 case TORTURE_SAMR_USER_PRIVILEGES
: {
4915 struct dcerpc_pipe
*lp
;
4916 struct policy_handle
*lsa_handle
;
4917 struct dcerpc_binding_handle
*lb
;
4919 status
= torture_rpc_connection(tctx
, &lp
, &ndr_table_lsarpc
);
4920 torture_assert_ntstatus_ok(tctx
, status
, "Failed to open LSA pipe");
4921 lb
= lp
->binding_handle
;
4923 if (!test_lsa_OpenPolicy2(lb
, tctx
, &lsa_handle
)) {
4927 if (!test_DeleteUser_with_privs(p
, lp
, tctx
,
4928 domain_handle
, lsa_handle
, user_handle
,
4930 machine_credentials
)) {
4934 if (!test_lsa_Close(lb
, tctx
, lsa_handle
)) {
4939 torture_warning(tctx
, "privileged user delete test failed\n");
4944 case TORTURE_SAMR_OTHER
:
4945 case TORTURE_SAMR_MANY_ACCOUNTS
:
4946 case TORTURE_SAMR_MANY_GROUPS
:
4947 case TORTURE_SAMR_MANY_ALIASES
:
4948 /* We just need the account to exist */
4954 static bool test_alias_ops(struct dcerpc_binding_handle
*b
,
4955 struct torture_context
*tctx
,
4956 struct policy_handle
*alias_handle
,
4957 const struct dom_sid
*domain_sid
)
4961 if (!torture_setting_bool(tctx
, "samba3", false)) {
4962 if (!test_QuerySecurity(b
, tctx
, alias_handle
)) {
4967 if (!test_QueryAliasInfo(b
, tctx
, alias_handle
)) {
4971 if (!test_SetAliasInfo(b
, tctx
, alias_handle
)) {
4975 if (!test_AddMemberToAlias(b
, tctx
, alias_handle
, domain_sid
)) {
4979 if (torture_setting_bool(tctx
, "samba3", false) ||
4980 torture_setting_bool(tctx
, "samba4", false)) {
4981 torture_comment(tctx
, "skipping MultipleMembers Alias tests against Samba\n");
4985 if (!test_AddMultipleMembersToAlias(b
, tctx
, alias_handle
)) {
4993 static bool test_DeleteUser(struct dcerpc_binding_handle
*b
,
4994 struct torture_context
*tctx
,
4995 struct policy_handle
*user_handle
)
4997 struct samr_DeleteUser d
;
4998 torture_comment(tctx
, "Testing DeleteUser\n");
5000 d
.in
.user_handle
= user_handle
;
5001 d
.out
.user_handle
= user_handle
;
5003 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, tctx
, &d
),
5004 "DeleteUser failed");
5005 torture_assert_ntstatus_ok(tctx
, d
.out
.result
, "DeleteUser");
5010 bool test_DeleteUser_byname(struct dcerpc_binding_handle
*b
,
5011 struct torture_context
*tctx
,
5012 struct policy_handle
*handle
, const char *name
)
5015 struct samr_DeleteUser d
;
5016 struct policy_handle user_handle
;
5019 status
= test_LookupName(b
, tctx
, handle
, name
, &rid
);
5020 if (!NT_STATUS_IS_OK(status
)) {
5024 status
= test_OpenUser_byname(b
, tctx
, handle
, name
, &user_handle
);
5025 if (!NT_STATUS_IS_OK(status
)) {
5029 d
.in
.user_handle
= &user_handle
;
5030 d
.out
.user_handle
= &user_handle
;
5031 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, tctx
, &d
),
5032 "DeleteUser failed");
5033 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
5034 status
= d
.out
.result
;
5041 torture_warning(tctx
, "DeleteUser_byname(%s) failed - %s\n", name
, nt_errstr(status
));
5046 static bool test_DeleteGroup_byname(struct dcerpc_binding_handle
*b
,
5047 struct torture_context
*tctx
,
5048 struct policy_handle
*handle
, const char *name
)
5051 struct samr_OpenGroup r
;
5052 struct samr_DeleteDomainGroup d
;
5053 struct policy_handle group_handle
;
5056 status
= test_LookupName(b
, tctx
, handle
, name
, &rid
);
5057 if (!NT_STATUS_IS_OK(status
)) {
5061 r
.in
.domain_handle
= handle
;
5062 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5064 r
.out
.group_handle
= &group_handle
;
5065 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenGroup_r(b
, tctx
, &r
),
5066 "OpenGroup failed");
5067 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5068 status
= r
.out
.result
;
5072 d
.in
.group_handle
= &group_handle
;
5073 d
.out
.group_handle
= &group_handle
;
5074 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteDomainGroup_r(b
, tctx
, &d
),
5075 "DeleteDomainGroup failed");
5076 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
5077 status
= d
.out
.result
;
5084 torture_warning(tctx
, "DeleteGroup_byname(%s) failed - %s\n", name
, nt_errstr(status
));
5089 static bool test_DeleteAlias_byname(struct dcerpc_binding_handle
*b
,
5090 struct torture_context
*tctx
,
5091 struct policy_handle
*domain_handle
,
5095 struct samr_OpenAlias r
;
5096 struct samr_DeleteDomAlias d
;
5097 struct policy_handle alias_handle
;
5100 torture_comment(tctx
, "Testing DeleteAlias_byname\n");
5102 status
= test_LookupName(b
, tctx
, domain_handle
, name
, &rid
);
5103 if (!NT_STATUS_IS_OK(status
)) {
5107 r
.in
.domain_handle
= domain_handle
;
5108 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5110 r
.out
.alias_handle
= &alias_handle
;
5111 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenAlias_r(b
, tctx
, &r
),
5112 "OpenAlias failed");
5113 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5114 status
= r
.out
.result
;
5118 d
.in
.alias_handle
= &alias_handle
;
5119 d
.out
.alias_handle
= &alias_handle
;
5120 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteDomAlias_r(b
, tctx
, &d
),
5121 "DeleteDomAlias failed");
5122 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
5123 status
= d
.out
.result
;
5130 torture_warning(tctx
, "DeleteAlias_byname(%s) failed - %s\n", name
, nt_errstr(status
));
5134 static bool test_DeleteAlias(struct dcerpc_binding_handle
*b
,
5135 struct torture_context
*tctx
,
5136 struct policy_handle
*alias_handle
)
5138 struct samr_DeleteDomAlias d
;
5141 torture_comment(tctx
, "Testing DeleteAlias\n");
5143 d
.in
.alias_handle
= alias_handle
;
5144 d
.out
.alias_handle
= alias_handle
;
5146 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteDomAlias_r(b
, tctx
, &d
),
5147 "DeleteDomAlias failed");
5148 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
5149 torture_warning(tctx
, "DeleteAlias failed - %s\n", nt_errstr(d
.out
.result
));
5156 static bool test_CreateAlias(struct dcerpc_binding_handle
*b
,
5157 struct torture_context
*tctx
,
5158 struct policy_handle
*domain_handle
,
5159 const char *alias_name
,
5160 struct policy_handle
*alias_handle
,
5161 const struct dom_sid
*domain_sid
,
5164 struct samr_CreateDomAlias r
;
5165 struct lsa_String name
;
5169 init_lsa_String(&name
, alias_name
);
5170 r
.in
.domain_handle
= domain_handle
;
5171 r
.in
.alias_name
= &name
;
5172 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5173 r
.out
.alias_handle
= alias_handle
;
5176 torture_comment(tctx
, "Testing CreateAlias (%s)\n", r
.in
.alias_name
->string
);
5178 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomAlias_r(b
, tctx
, &r
),
5179 "CreateDomAlias failed");
5181 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
5182 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
)) {
5183 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.alias_name
->string
);
5186 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.alias_name
->string
,
5187 nt_errstr(r
.out
.result
));
5192 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ALIAS_EXISTS
)) {
5193 if (!test_DeleteAlias_byname(b
, tctx
, domain_handle
, r
.in
.alias_name
->string
)) {
5196 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomAlias_r(b
, tctx
, &r
),
5197 "CreateDomAlias failed");
5200 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5201 torture_warning(tctx
, "CreateAlias failed - %s\n", nt_errstr(r
.out
.result
));
5209 if (!test_alias_ops(b
, tctx
, alias_handle
, domain_sid
)) {
5216 static bool test_ChangePassword(struct dcerpc_pipe
*p
,
5217 struct torture_context
*tctx
,
5218 const char *acct_name
,
5219 struct policy_handle
*domain_handle
, char **password
)
5222 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5228 if (!test_ChangePasswordUser(b
, tctx
, acct_name
, domain_handle
, password
)) {
5232 if (!test_ChangePasswordUser2(p
, tctx
, acct_name
, password
, 0, true)) {
5236 if (!test_OemChangePasswordUser2(p
, tctx
, acct_name
, domain_handle
, password
)) {
5240 /* test what happens when setting the old password again */
5241 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, *password
, 0, true)) {
5246 char simple_pass
[9];
5247 char *v
= generate_random_str(tctx
, 1);
5249 ZERO_STRUCT(simple_pass
);
5250 memset(simple_pass
, *v
, sizeof(simple_pass
) - 1);
5252 /* test what happens when picking a simple password */
5253 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, simple_pass
, 0, true)) {
5258 /* set samr_SetDomainInfo level 1 with min_length 5 */
5260 struct samr_QueryDomainInfo r
;
5261 union samr_DomainInfo
*info
= NULL
;
5262 struct samr_SetDomainInfo s
;
5263 uint16_t len_old
, len
;
5264 uint32_t pwd_prop_old
;
5265 int64_t min_pwd_age_old
;
5269 r
.in
.domain_handle
= domain_handle
;
5273 torture_comment(tctx
, "Testing samr_QueryDomainInfo level 1\n");
5274 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &r
),
5275 "QueryDomainInfo failed");
5276 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5280 s
.in
.domain_handle
= domain_handle
;
5284 /* remember the old min length, so we can reset it */
5285 len_old
= s
.in
.info
->info1
.min_password_length
;
5286 s
.in
.info
->info1
.min_password_length
= len
;
5287 pwd_prop_old
= s
.in
.info
->info1
.password_properties
;
5288 /* turn off password complexity checks for this test */
5289 s
.in
.info
->info1
.password_properties
&= ~DOMAIN_PASSWORD_COMPLEX
;
5291 min_pwd_age_old
= s
.in
.info
->info1
.min_password_age
;
5292 s
.in
.info
->info1
.min_password_age
= 0;
5294 torture_comment(tctx
, "Testing samr_SetDomainInfo level 1\n");
5295 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
),
5296 "SetDomainInfo failed");
5297 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
5301 torture_comment(tctx
, "calling test_ChangePasswordUser3 with too short password\n");
5303 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, len
- 1, password
, NULL
, 0, true)) {
5307 s
.in
.info
->info1
.min_password_length
= len_old
;
5308 s
.in
.info
->info1
.password_properties
= pwd_prop_old
;
5309 s
.in
.info
->info1
.min_password_age
= min_pwd_age_old
;
5311 torture_comment(tctx
, "Testing samr_SetDomainInfo level 1\n");
5312 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
),
5313 "SetDomainInfo failed");
5314 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
5321 struct samr_OpenUser r
;
5322 struct samr_QueryUserInfo q
;
5323 union samr_UserInfo
*info
;
5324 struct samr_LookupNames n
;
5325 struct policy_handle user_handle
;
5326 struct samr_Ids rids
, types
;
5328 n
.in
.domain_handle
= domain_handle
;
5330 n
.in
.names
= talloc_array(tctx
, struct lsa_String
, 1);
5331 n
.in
.names
[0].string
= acct_name
;
5333 n
.out
.types
= &types
;
5335 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupNames_r(b
, tctx
, &n
),
5336 "LookupNames failed");
5337 if (!NT_STATUS_IS_OK(n
.out
.result
)) {
5338 torture_warning(tctx
, "LookupNames failed - %s\n", nt_errstr(n
.out
.result
));
5342 r
.in
.domain_handle
= domain_handle
;
5343 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5344 r
.in
.rid
= n
.out
.rids
->ids
[0];
5345 r
.out
.user_handle
= &user_handle
;
5347 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenUser_r(b
, tctx
, &r
),
5349 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5350 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", n
.out
.rids
->ids
[0], nt_errstr(r
.out
.result
));
5354 q
.in
.user_handle
= &user_handle
;
5358 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
),
5359 "QueryUserInfo failed");
5360 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
5361 torture_warning(tctx
, "QueryUserInfo failed - %s\n", nt_errstr(q
.out
.result
));
5365 torture_comment(tctx
, "calling test_ChangePasswordUser3 with too early password change\n");
5367 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
,
5368 info
->info5
.last_password_change
, true)) {
5373 /* we change passwords twice - this has the effect of verifying
5374 they were changed correctly for the final call */
5375 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
, 0, true)) {
5379 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
, 0, true)) {
5386 static bool test_CreateUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5387 struct policy_handle
*domain_handle
,
5388 const char *user_name
,
5389 struct policy_handle
*user_handle_out
,
5390 struct dom_sid
*domain_sid
,
5391 enum torture_samr_choice which_ops
,
5392 struct cli_credentials
*machine_credentials
,
5396 TALLOC_CTX
*user_ctx
;
5398 struct samr_CreateUser r
;
5399 struct samr_QueryUserInfo q
;
5400 union samr_UserInfo
*info
;
5401 struct samr_DeleteUser d
;
5404 /* This call creates a 'normal' account - check that it really does */
5405 const uint32_t acct_flags
= ACB_NORMAL
;
5406 struct lsa_String name
;
5408 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5410 struct policy_handle user_handle
;
5411 user_ctx
= talloc_named(tctx
, 0, "test_CreateUser2 per-user context");
5412 init_lsa_String(&name
, user_name
);
5414 r
.in
.domain_handle
= domain_handle
;
5415 r
.in
.account_name
= &name
;
5416 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5417 r
.out
.user_handle
= &user_handle
;
5420 torture_comment(tctx
, "Testing CreateUser(%s)\n", r
.in
.account_name
->string
);
5422 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateUser_r(b
, user_ctx
, &r
),
5423 "CreateUser failed");
5425 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
5426 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
) || NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
5427 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.account_name
->string
);
5430 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.account_name
->string
,
5431 nt_errstr(r
.out
.result
));
5436 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_USER_EXISTS
)) {
5437 if (!test_DeleteUser_byname(b
, tctx
, domain_handle
, r
.in
.account_name
->string
)) {
5438 talloc_free(user_ctx
);
5441 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateUser_r(b
, user_ctx
, &r
),
5442 "CreateUser failed");
5445 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5446 talloc_free(user_ctx
);
5447 torture_warning(tctx
, "CreateUser failed - %s\n", nt_errstr(r
.out
.result
));
5452 if (user_handle_out
) {
5453 *user_handle_out
= user_handle
;
5459 q
.in
.user_handle
= &user_handle
;
5463 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, user_ctx
, &q
),
5464 "QueryUserInfo failed");
5465 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
5466 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
5467 q
.in
.level
, nt_errstr(q
.out
.result
));
5470 if ((info
->info16
.acct_flags
& acct_flags
) != acct_flags
) {
5471 torture_warning(tctx
, "QueryUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5472 info
->info16
.acct_flags
,
5478 if (!test_user_ops(p
, tctx
, &user_handle
, domain_handle
,
5479 domain_sid
, acct_flags
, name
.string
, which_ops
,
5480 machine_credentials
)) {
5484 if (user_handle_out
) {
5485 *user_handle_out
= user_handle
;
5487 torture_comment(tctx
, "Testing DeleteUser (createuser test)\n");
5489 d
.in
.user_handle
= &user_handle
;
5490 d
.out
.user_handle
= &user_handle
;
5492 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, user_ctx
, &d
),
5493 "DeleteUser failed");
5494 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
5495 torture_warning(tctx
, "DeleteUser failed - %s\n", nt_errstr(d
.out
.result
));
5502 talloc_free(user_ctx
);
5508 static bool test_CreateUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5509 struct policy_handle
*domain_handle
,
5510 struct dom_sid
*domain_sid
,
5511 enum torture_samr_choice which_ops
,
5512 struct cli_credentials
*machine_credentials
)
5514 struct samr_CreateUser2 r
;
5515 struct samr_QueryUserInfo q
;
5516 union samr_UserInfo
*info
;
5517 struct samr_DeleteUser d
;
5518 struct policy_handle user_handle
;
5520 struct lsa_String name
;
5523 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5526 uint32_t acct_flags
;
5527 const char *account_name
;
5529 } account_types
[] = {
5530 { ACB_NORMAL
, TEST_ACCOUNT_NAME
, NT_STATUS_OK
},
5531 { ACB_NORMAL
| ACB_DISABLED
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5532 { ACB_NORMAL
| ACB_PWNOEXP
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5533 { ACB_WSTRUST
, TEST_MACHINENAME
, NT_STATUS_OK
},
5534 { ACB_WSTRUST
| ACB_DISABLED
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5535 { ACB_WSTRUST
| ACB_PWNOEXP
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5536 { ACB_SVRTRUST
, TEST_MACHINENAME
, NT_STATUS_OK
},
5537 { ACB_SVRTRUST
| ACB_DISABLED
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5538 { ACB_SVRTRUST
| ACB_PWNOEXP
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5539 { ACB_DOMTRUST
, TEST_DOMAINNAME
, NT_STATUS_ACCESS_DENIED
},
5540 { ACB_DOMTRUST
| ACB_DISABLED
, TEST_DOMAINNAME
, NT_STATUS_INVALID_PARAMETER
},
5541 { ACB_DOMTRUST
| ACB_PWNOEXP
, TEST_DOMAINNAME
, NT_STATUS_INVALID_PARAMETER
},
5542 { 0, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5543 { ACB_DISABLED
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5544 { 0, NULL
, NT_STATUS_INVALID_PARAMETER
}
5547 for (i
= 0; account_types
[i
].account_name
; i
++) {
5548 TALLOC_CTX
*user_ctx
;
5549 uint32_t acct_flags
= account_types
[i
].acct_flags
;
5550 uint32_t access_granted
;
5551 user_ctx
= talloc_named(tctx
, 0, "test_CreateUser2 per-user context");
5552 init_lsa_String(&name
, account_types
[i
].account_name
);
5554 r
.in
.domain_handle
= domain_handle
;
5555 r
.in
.account_name
= &name
;
5556 r
.in
.acct_flags
= acct_flags
;
5557 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5558 r
.out
.user_handle
= &user_handle
;
5559 r
.out
.access_granted
= &access_granted
;
5562 torture_comment(tctx
, "Testing CreateUser2(%s, 0x%x)\n", r
.in
.account_name
->string
, acct_flags
);
5564 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateUser2_r(b
, user_ctx
, &r
),
5565 "CreateUser2 failed");
5567 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
5568 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
) || NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
5569 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.account_name
->string
);
5572 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.account_name
->string
,
5573 nt_errstr(r
.out
.result
));
5579 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_USER_EXISTS
)) {
5580 if (!test_DeleteUser_byname(b
, tctx
, domain_handle
, r
.in
.account_name
->string
)) {
5581 talloc_free(user_ctx
);
5585 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateUser2_r(b
, user_ctx
, &r
),
5586 "CreateUser2 failed");
5589 if (!NT_STATUS_EQUAL(r
.out
.result
, account_types
[i
].nt_status
)) {
5590 torture_warning(tctx
, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5591 nt_errstr(r
.out
.result
), nt_errstr(account_types
[i
].nt_status
));
5595 if (NT_STATUS_IS_OK(r
.out
.result
)) {
5596 q
.in
.user_handle
= &user_handle
;
5600 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, user_ctx
, &q
),
5601 "QueryUserInfo failed");
5602 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
5603 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
5604 q
.in
.level
, nt_errstr(q
.out
.result
));
5607 uint32_t expected_flags
= (acct_flags
| ACB_PWNOTREQ
| ACB_DISABLED
);
5608 if (acct_flags
== ACB_NORMAL
) {
5609 expected_flags
|= ACB_PW_EXPIRED
;
5611 if ((info
->info5
.acct_flags
) != expected_flags
) {
5612 torture_warning(tctx
, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5613 info
->info5
.acct_flags
,
5617 switch (acct_flags
) {
5619 if (info
->info5
.primary_gid
!= DOMAIN_RID_DCS
) {
5620 torture_warning(tctx
, "QueryUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5621 DOMAIN_RID_DCS
, info
->info5
.primary_gid
);
5626 if (info
->info5
.primary_gid
!= DOMAIN_RID_DOMAIN_MEMBERS
) {
5627 torture_warning(tctx
, "QueryUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5628 DOMAIN_RID_DOMAIN_MEMBERS
, info
->info5
.primary_gid
);
5633 if (info
->info5
.primary_gid
!= DOMAIN_RID_USERS
) {
5634 torture_warning(tctx
, "QueryUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5635 DOMAIN_RID_USERS
, info
->info5
.primary_gid
);
5642 if (!test_user_ops(p
, tctx
, &user_handle
, domain_handle
,
5643 domain_sid
, acct_flags
, name
.string
, which_ops
,
5644 machine_credentials
)) {
5648 if (!ndr_policy_handle_empty(&user_handle
)) {
5649 torture_comment(tctx
, "Testing DeleteUser (createuser2 test)\n");
5651 d
.in
.user_handle
= &user_handle
;
5652 d
.out
.user_handle
= &user_handle
;
5654 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, user_ctx
, &d
),
5655 "DeleteUser failed");
5656 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
5657 torture_warning(tctx
, "DeleteUser failed - %s\n", nt_errstr(d
.out
.result
));
5662 talloc_free(user_ctx
);
5668 static bool test_QueryAliasInfo(struct dcerpc_binding_handle
*b
,
5669 struct torture_context
*tctx
,
5670 struct policy_handle
*handle
)
5672 struct samr_QueryAliasInfo r
;
5673 union samr_AliasInfo
*info
;
5674 uint16_t levels
[] = {1, 2, 3};
5678 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5679 torture_comment(tctx
, "Testing QueryAliasInfo level %u\n", levels
[i
]);
5681 r
.in
.alias_handle
= handle
;
5682 r
.in
.level
= levels
[i
];
5685 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryAliasInfo_r(b
, tctx
, &r
),
5686 "QueryAliasInfo failed");
5687 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5688 torture_warning(tctx
, "QueryAliasInfo level %u failed - %s\n",
5689 levels
[i
], nt_errstr(r
.out
.result
));
5697 static bool test_QueryGroupInfo(struct dcerpc_binding_handle
*b
,
5698 struct torture_context
*tctx
,
5699 struct policy_handle
*handle
)
5701 struct samr_QueryGroupInfo r
;
5702 union samr_GroupInfo
*info
;
5703 uint16_t levels
[] = {1, 2, 3, 4, 5};
5707 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5708 torture_comment(tctx
, "Testing QueryGroupInfo level %u\n", levels
[i
]);
5710 r
.in
.group_handle
= handle
;
5711 r
.in
.level
= levels
[i
];
5714 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupInfo_r(b
, tctx
, &r
),
5715 "QueryGroupInfo failed");
5716 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5717 torture_warning(tctx
, "QueryGroupInfo level %u failed - %s\n",
5718 levels
[i
], nt_errstr(r
.out
.result
));
5726 static bool test_QueryGroupMember(struct dcerpc_binding_handle
*b
,
5727 struct torture_context
*tctx
,
5728 struct policy_handle
*handle
)
5730 struct samr_QueryGroupMember r
;
5731 struct samr_RidAttrArray
*rids
= NULL
;
5734 torture_comment(tctx
, "Testing QueryGroupMember\n");
5736 r
.in
.group_handle
= handle
;
5739 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupMember_r(b
, tctx
, &r
),
5740 "QueryGroupMember failed");
5741 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5742 torture_warning(tctx
, "QueryGroupMember failed - %s\n", nt_errstr(r
.out
.result
));
5750 static bool test_SetGroupInfo(struct dcerpc_binding_handle
*b
,
5751 struct torture_context
*tctx
,
5752 struct policy_handle
*handle
)
5754 struct samr_QueryGroupInfo r
;
5755 union samr_GroupInfo
*info
;
5756 struct samr_SetGroupInfo s
;
5757 uint16_t levels
[] = {1, 2, 3, 4};
5758 uint16_t set_ok
[] = {0, 1, 1, 1};
5762 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5763 torture_comment(tctx
, "Testing QueryGroupInfo level %u\n", levels
[i
]);
5765 r
.in
.group_handle
= handle
;
5766 r
.in
.level
= levels
[i
];
5769 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupInfo_r(b
, tctx
, &r
),
5770 "QueryGroupInfo failed");
5771 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5772 torture_warning(tctx
, "QueryGroupInfo level %u failed - %s\n",
5773 levels
[i
], nt_errstr(r
.out
.result
));
5777 torture_comment(tctx
, "Testing SetGroupInfo level %u\n", levels
[i
]);
5779 s
.in
.group_handle
= handle
;
5780 s
.in
.level
= levels
[i
];
5781 s
.in
.info
= *r
.out
.info
;
5784 /* disabled this, as it changes the name only from the point of view of samr,
5785 but leaves the name from the point of view of w2k3 internals (and ldap). This means
5786 the name is still reserved, so creating the old name fails, but deleting by the old name
5788 if (s
.in
.level
== 2) {
5789 init_lsa_String(&s
.in
.info
->string
, "NewName");
5793 if (s
.in
.level
== 4) {
5794 init_lsa_String(&s
.in
.info
->description
, "test description");
5797 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetGroupInfo_r(b
, tctx
, &s
),
5798 "SetGroupInfo failed");
5800 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
5801 torture_warning(tctx
, "SetGroupInfo level %u failed - %s\n",
5802 r
.in
.level
, nt_errstr(s
.out
.result
));
5807 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, s
.out
.result
)) {
5808 torture_warning(tctx
, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5809 r
.in
.level
, nt_errstr(s
.out
.result
));
5819 static bool test_QueryUserInfo(struct dcerpc_binding_handle
*b
,
5820 struct torture_context
*tctx
,
5821 struct policy_handle
*handle
)
5823 struct samr_QueryUserInfo r
;
5824 union samr_UserInfo
*info
;
5825 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5826 11, 12, 13, 14, 16, 17, 20, 21};
5830 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5831 torture_comment(tctx
, "Testing QueryUserInfo level %u\n", levels
[i
]);
5833 r
.in
.user_handle
= handle
;
5834 r
.in
.level
= levels
[i
];
5837 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
5838 "QueryUserInfo failed");
5839 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5840 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
5841 levels
[i
], nt_errstr(r
.out
.result
));
5849 static bool test_QueryUserInfo2(struct dcerpc_binding_handle
*b
,
5850 struct torture_context
*tctx
,
5851 struct policy_handle
*handle
)
5853 struct samr_QueryUserInfo2 r
;
5854 union samr_UserInfo
*info
;
5855 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5856 11, 12, 13, 14, 16, 17, 20, 21};
5860 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5861 torture_comment(tctx
, "Testing QueryUserInfo2 level %u\n", levels
[i
]);
5863 r
.in
.user_handle
= handle
;
5864 r
.in
.level
= levels
[i
];
5867 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo2_r(b
, tctx
, &r
),
5868 "QueryUserInfo2 failed");
5869 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5870 torture_warning(tctx
, "QueryUserInfo2 level %u failed - %s\n",
5871 levels
[i
], nt_errstr(r
.out
.result
));
5879 static bool test_OpenUser(struct dcerpc_binding_handle
*b
,
5880 struct torture_context
*tctx
,
5881 struct policy_handle
*handle
, uint32_t rid
)
5883 struct samr_OpenUser r
;
5884 struct policy_handle user_handle
;
5887 torture_comment(tctx
, "Testing OpenUser(%u)\n", rid
);
5889 r
.in
.domain_handle
= handle
;
5890 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5892 r
.out
.user_handle
= &user_handle
;
5894 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenUser_r(b
, tctx
, &r
),
5896 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5897 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", rid
, nt_errstr(r
.out
.result
));
5901 if (!test_QuerySecurity(b
, tctx
, &user_handle
)) {
5905 if (!test_QueryUserInfo(b
, tctx
, &user_handle
)) {
5909 if (!test_QueryUserInfo2(b
, tctx
, &user_handle
)) {
5913 if (!test_GetUserPwInfo(b
, tctx
, &user_handle
)) {
5917 if (!test_GetGroupsForUser(b
, tctx
, &user_handle
)) {
5921 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
5928 static bool test_OpenGroup(struct dcerpc_binding_handle
*b
,
5929 struct torture_context
*tctx
,
5930 struct policy_handle
*handle
, uint32_t rid
)
5932 struct samr_OpenGroup r
;
5933 struct policy_handle group_handle
;
5936 torture_comment(tctx
, "Testing OpenGroup(%u)\n", rid
);
5938 r
.in
.domain_handle
= handle
;
5939 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5941 r
.out
.group_handle
= &group_handle
;
5943 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenGroup_r(b
, tctx
, &r
),
5944 "OpenGroup failed");
5945 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5946 torture_warning(tctx
, "OpenGroup(%u) failed - %s\n", rid
, nt_errstr(r
.out
.result
));
5950 if (!torture_setting_bool(tctx
, "samba3", false)) {
5951 if (!test_QuerySecurity(b
, tctx
, &group_handle
)) {
5956 if (!test_QueryGroupInfo(b
, tctx
, &group_handle
)) {
5960 if (!test_QueryGroupMember(b
, tctx
, &group_handle
)) {
5964 if (!test_samr_handle_Close(b
, tctx
, &group_handle
)) {
5971 static bool test_OpenAlias(struct dcerpc_binding_handle
*b
,
5972 struct torture_context
*tctx
,
5973 struct policy_handle
*handle
, uint32_t rid
)
5975 struct samr_OpenAlias r
;
5976 struct policy_handle alias_handle
;
5979 torture_comment(tctx
, "Testing OpenAlias(%u)\n", rid
);
5981 r
.in
.domain_handle
= handle
;
5982 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5984 r
.out
.alias_handle
= &alias_handle
;
5986 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenAlias_r(b
, tctx
, &r
),
5987 "OpenAlias failed");
5988 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5989 torture_warning(tctx
, "OpenAlias(%u) failed - %s\n", rid
, nt_errstr(r
.out
.result
));
5993 if (!torture_setting_bool(tctx
, "samba3", false)) {
5994 if (!test_QuerySecurity(b
, tctx
, &alias_handle
)) {
5999 if (!test_QueryAliasInfo(b
, tctx
, &alias_handle
)) {
6003 if (!test_GetMembersInAlias(b
, tctx
, &alias_handle
)) {
6007 if (!test_samr_handle_Close(b
, tctx
, &alias_handle
)) {
6014 static bool check_mask(struct dcerpc_binding_handle
*b
,
6015 struct torture_context
*tctx
,
6016 struct policy_handle
*handle
, uint32_t rid
,
6017 uint32_t acct_flag_mask
)
6019 struct samr_OpenUser r
;
6020 struct samr_QueryUserInfo q
;
6021 union samr_UserInfo
*info
;
6022 struct policy_handle user_handle
;
6025 torture_comment(tctx
, "Testing OpenUser(%u)\n", rid
);
6027 r
.in
.domain_handle
= handle
;
6028 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6030 r
.out
.user_handle
= &user_handle
;
6032 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenUser_r(b
, tctx
, &r
),
6034 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6035 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", rid
, nt_errstr(r
.out
.result
));
6039 q
.in
.user_handle
= &user_handle
;
6043 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
),
6044 "QueryUserInfo failed");
6045 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
6046 torture_warning(tctx
, "QueryUserInfo level 16 failed - %s\n",
6047 nt_errstr(q
.out
.result
));
6050 if ((acct_flag_mask
& info
->info16
.acct_flags
) == 0) {
6051 torture_warning(tctx
, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
6052 acct_flag_mask
, info
->info16
.acct_flags
, rid
);
6057 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
6064 static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle
*b
,
6065 struct torture_context
*tctx
,
6066 struct policy_handle
*handle
)
6068 struct samr_EnumDomainUsers r
;
6069 uint32_t mask
, resume_handle
=0;
6072 struct samr_LookupNames n
;
6073 struct samr_LookupRids lr
;
6074 struct lsa_Strings names
;
6075 struct samr_Ids rids
, types
;
6076 struct samr_SamArray
*sam
= NULL
;
6077 uint32_t num_entries
= 0;
6079 uint32_t masks
[] = {ACB_NORMAL
, ACB_DOMTRUST
, ACB_WSTRUST
,
6080 ACB_DISABLED
, ACB_NORMAL
| ACB_DISABLED
,
6081 ACB_SVRTRUST
| ACB_DOMTRUST
| ACB_WSTRUST
,
6084 torture_comment(tctx
, "Testing EnumDomainUsers\n");
6086 for (mask_idx
=0;mask_idx
<ARRAY_SIZE(masks
);mask_idx
++) {
6087 r
.in
.domain_handle
= handle
;
6088 r
.in
.resume_handle
= &resume_handle
;
6089 r
.in
.acct_flags
= mask
= masks
[mask_idx
];
6090 r
.in
.max_size
= (uint32_t)-1;
6091 r
.out
.resume_handle
= &resume_handle
;
6092 r
.out
.num_entries
= &num_entries
;
6095 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainUsers_r(b
, tctx
, &r
),
6096 "EnumDomainUsers failed");
6097 if (!NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
) &&
6098 !NT_STATUS_IS_OK(r
.out
.result
)) {
6099 torture_warning(tctx
, "EnumDomainUsers failed - %s\n", nt_errstr(r
.out
.result
));
6103 torture_assert(tctx
, sam
, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
6105 if (sam
->count
== 0) {
6109 for (i
=0;i
<sam
->count
;i
++) {
6111 if (!check_mask(b
, tctx
, handle
, sam
->entries
[i
].idx
, mask
)) {
6114 } else if (!test_OpenUser(b
, tctx
, handle
, sam
->entries
[i
].idx
)) {
6120 torture_comment(tctx
, "Testing LookupNames\n");
6121 n
.in
.domain_handle
= handle
;
6122 n
.in
.num_names
= sam
->count
;
6123 n
.in
.names
= talloc_array(tctx
, struct lsa_String
, sam
->count
);
6125 n
.out
.types
= &types
;
6126 for (i
=0;i
<sam
->count
;i
++) {
6127 n
.in
.names
[i
].string
= sam
->entries
[i
].name
.string
;
6129 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupNames_r(b
, tctx
, &n
),
6130 "LookupNames failed");
6131 if (!NT_STATUS_IS_OK(n
.out
.result
)) {
6132 torture_warning(tctx
, "LookupNames failed - %s\n", nt_errstr(n
.out
.result
));
6137 torture_comment(tctx
, "Testing LookupRids\n");
6138 lr
.in
.domain_handle
= handle
;
6139 lr
.in
.num_rids
= sam
->count
;
6140 lr
.in
.rids
= talloc_array(tctx
, uint32_t, sam
->count
);
6141 lr
.out
.names
= &names
;
6142 lr
.out
.types
= &types
;
6143 for (i
=0;i
<sam
->count
;i
++) {
6144 lr
.in
.rids
[i
] = sam
->entries
[i
].idx
;
6146 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupRids_r(b
, tctx
, &lr
),
6147 "LookupRids failed");
6148 torture_assert_ntstatus_ok(tctx
, lr
.out
.result
, "LookupRids");
6154 try blasting the server with a bunch of sync requests
6156 static bool test_EnumDomainUsers_async(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6157 struct policy_handle
*handle
)
6159 struct samr_EnumDomainUsers r
;
6160 uint32_t resume_handle
=0;
6162 #define ASYNC_COUNT 100
6163 struct tevent_req
*req
[ASYNC_COUNT
];
6165 if (!torture_setting_bool(tctx
, "dangerous", false)) {
6166 torture_skip(tctx
, "samr async test disabled - enable dangerous tests to use\n");
6169 torture_comment(tctx
, "Testing EnumDomainUsers_async\n");
6171 r
.in
.domain_handle
= handle
;
6172 r
.in
.resume_handle
= &resume_handle
;
6173 r
.in
.acct_flags
= 0;
6174 r
.in
.max_size
= (uint32_t)-1;
6175 r
.out
.resume_handle
= &resume_handle
;
6177 for (i
=0;i
<ASYNC_COUNT
;i
++) {
6178 req
[i
] = dcerpc_samr_EnumDomainUsers_r_send(tctx
, tctx
->ev
, p
->binding_handle
, &r
);
6181 for (i
=0;i
<ASYNC_COUNT
;i
++) {
6182 tevent_req_poll(req
[i
], tctx
->ev
);
6183 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainUsers_r_recv(req
[i
], tctx
),
6184 talloc_asprintf(tctx
, "EnumDomainUsers[%d] failed - %s\n",
6185 i
, nt_errstr(r
.out
.result
)));
6188 torture_comment(tctx
, "%d async requests OK\n", i
);
6193 static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle
*b
,
6194 struct torture_context
*tctx
,
6195 struct policy_handle
*handle
)
6197 struct samr_EnumDomainGroups r
;
6198 uint32_t resume_handle
=0;
6199 struct samr_SamArray
*sam
= NULL
;
6200 uint32_t num_entries
= 0;
6203 bool universal_group_found
= false;
6205 torture_comment(tctx
, "Testing EnumDomainGroups\n");
6207 r
.in
.domain_handle
= handle
;
6208 r
.in
.resume_handle
= &resume_handle
;
6209 r
.in
.max_size
= (uint32_t)-1;
6210 r
.out
.resume_handle
= &resume_handle
;
6211 r
.out
.num_entries
= &num_entries
;
6214 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainGroups_r(b
, tctx
, &r
),
6215 "EnumDomainGroups failed");
6216 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6217 torture_warning(tctx
, "EnumDomainGroups failed - %s\n", nt_errstr(r
.out
.result
));
6225 for (i
=0;i
<sam
->count
;i
++) {
6226 if (!test_OpenGroup(b
, tctx
, handle
, sam
->entries
[i
].idx
)) {
6229 if ((ret
== true) && (strcasecmp(sam
->entries
[i
].name
.string
,
6230 "Enterprise Admins") == 0)) {
6231 universal_group_found
= true;
6235 /* when we are running this on s4 we should get back at least the
6236 * "Enterprise Admins" universal group. If we don't get a group entry
6237 * at all we probably are performing the test on the builtin domain.
6238 * So ignore this case. */
6239 if (torture_setting_bool(tctx
, "samba4", false)) {
6240 if ((sam
->count
> 0) && (!universal_group_found
)) {
6248 static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle
*b
,
6249 struct torture_context
*tctx
,
6250 struct policy_handle
*handle
)
6252 struct samr_EnumDomainAliases r
;
6253 uint32_t resume_handle
=0;
6254 struct samr_SamArray
*sam
= NULL
;
6255 uint32_t num_entries
= 0;
6259 torture_comment(tctx
, "Testing EnumDomainAliases\n");
6261 r
.in
.domain_handle
= handle
;
6262 r
.in
.resume_handle
= &resume_handle
;
6263 r
.in
.max_size
= (uint32_t)-1;
6265 r
.out
.num_entries
= &num_entries
;
6266 r
.out
.resume_handle
= &resume_handle
;
6268 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainAliases_r(b
, tctx
, &r
),
6269 "EnumDomainAliases failed");
6270 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6271 torture_warning(tctx
, "EnumDomainAliases failed - %s\n", nt_errstr(r
.out
.result
));
6279 for (i
=0;i
<sam
->count
;i
++) {
6280 if (!test_OpenAlias(b
, tctx
, handle
, sam
->entries
[i
].idx
)) {
6288 static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle
*b
,
6289 struct torture_context
*tctx
,
6290 struct policy_handle
*handle
)
6292 struct samr_GetDisplayEnumerationIndex r
;
6294 uint16_t levels
[] = {1, 2, 3, 4, 5};
6295 uint16_t ok_lvl
[] = {1, 1, 1, 0, 0};
6296 struct lsa_String name
;
6300 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6301 torture_comment(tctx
, "Testing GetDisplayEnumerationIndex level %u\n", levels
[i
]);
6303 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
6305 r
.in
.domain_handle
= handle
;
6306 r
.in
.level
= levels
[i
];
6310 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDisplayEnumerationIndex_r(b
, tctx
, &r
),
6311 "GetDisplayEnumerationIndex failed");
6314 !NT_STATUS_IS_OK(r
.out
.result
) &&
6315 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, r
.out
.result
)) {
6316 torture_warning(tctx
, "GetDisplayEnumerationIndex level %u failed - %s\n",
6317 levels
[i
], nt_errstr(r
.out
.result
));
6321 init_lsa_String(&name
, "zzzzzzzz");
6323 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDisplayEnumerationIndex_r(b
, tctx
, &r
),
6324 "GetDisplayEnumerationIndex failed");
6326 if (ok_lvl
[i
] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, r
.out
.result
)) {
6327 torture_warning(tctx
, "GetDisplayEnumerationIndex level %u failed - %s\n",
6328 levels
[i
], nt_errstr(r
.out
.result
));
6336 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle
*b
,
6337 struct torture_context
*tctx
,
6338 struct policy_handle
*handle
)
6340 struct samr_GetDisplayEnumerationIndex2 r
;
6342 uint16_t levels
[] = {1, 2, 3, 4, 5};
6343 uint16_t ok_lvl
[] = {1, 1, 1, 0, 0};
6344 struct lsa_String name
;
6348 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6349 torture_comment(tctx
, "Testing GetDisplayEnumerationIndex2 level %u\n", levels
[i
]);
6351 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
6353 r
.in
.domain_handle
= handle
;
6354 r
.in
.level
= levels
[i
];
6358 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDisplayEnumerationIndex2_r(b
, tctx
, &r
),
6359 "GetDisplayEnumerationIndex2 failed");
6361 !NT_STATUS_IS_OK(r
.out
.result
) &&
6362 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, r
.out
.result
)) {
6363 torture_warning(tctx
, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6364 levels
[i
], nt_errstr(r
.out
.result
));
6368 init_lsa_String(&name
, "zzzzzzzz");
6370 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDisplayEnumerationIndex2_r(b
, tctx
, &r
),
6371 "GetDisplayEnumerationIndex2 failed");
6372 if (ok_lvl
[i
] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, r
.out
.result
)) {
6373 torture_warning(tctx
, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6374 levels
[i
], nt_errstr(r
.out
.result
));
6382 #define STRING_EQUAL_QUERY(s1, s2, user) \
6383 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6384 /* odd, but valid */ \
6385 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6386 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
6387 #s1, user.string, s1.string, s2.string, __location__); \
6390 #define INT_EQUAL_QUERY(s1, s2, user) \
6392 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6393 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6397 static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle
*b
,
6398 struct torture_context
*tctx
,
6399 struct samr_QueryDisplayInfo
*querydisplayinfo
,
6400 bool *seen_testuser
)
6402 struct samr_OpenUser r
;
6403 struct samr_QueryUserInfo q
;
6404 union samr_UserInfo
*info
;
6405 struct policy_handle user_handle
;
6407 r
.in
.domain_handle
= querydisplayinfo
->in
.domain_handle
;
6408 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6409 for (i
= 0; ; i
++) {
6410 switch (querydisplayinfo
->in
.level
) {
6412 if (i
>= querydisplayinfo
->out
.info
->info1
.count
) {
6415 r
.in
.rid
= querydisplayinfo
->out
.info
->info1
.entries
[i
].rid
;
6418 if (i
>= querydisplayinfo
->out
.info
->info2
.count
) {
6421 r
.in
.rid
= querydisplayinfo
->out
.info
->info2
.entries
[i
].rid
;
6427 /* Not interested in validating just the account name */
6431 r
.out
.user_handle
= &user_handle
;
6433 switch (querydisplayinfo
->in
.level
) {
6436 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenUser_r(b
, tctx
, &r
),
6438 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6439 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", r
.in
.rid
, nt_errstr(r
.out
.result
));
6444 q
.in
.user_handle
= &user_handle
;
6447 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
),
6448 "QueryUserInfo failed");
6449 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6450 torture_warning(tctx
, "QueryUserInfo(%u) failed - %s\n", r
.in
.rid
, nt_errstr(r
.out
.result
));
6454 switch (querydisplayinfo
->in
.level
) {
6456 if (seen_testuser
&& strcmp(info
->info21
.account_name
.string
, TEST_ACCOUNT_NAME
) == 0) {
6457 *seen_testuser
= true;
6459 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].full_name
,
6460 info
->info21
.full_name
, info
->info21
.account_name
);
6461 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].account_name
,
6462 info
->info21
.account_name
, info
->info21
.account_name
);
6463 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].description
,
6464 info
->info21
.description
, info
->info21
.account_name
);
6465 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].rid
,
6466 info
->info21
.rid
, info
->info21
.account_name
);
6467 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].acct_flags
,
6468 info
->info21
.acct_flags
, info
->info21
.account_name
);
6472 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].account_name
,
6473 info
->info21
.account_name
, info
->info21
.account_name
);
6474 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].description
,
6475 info
->info21
.description
, info
->info21
.account_name
);
6476 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].rid
,
6477 info
->info21
.rid
, info
->info21
.account_name
);
6478 INT_EQUAL_QUERY((querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
& ~ACB_NORMAL
),
6479 info
->info21
.acct_flags
, info
->info21
.account_name
);
6481 if (!(querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
& ACB_NORMAL
)) {
6482 torture_warning(tctx
, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6483 info
->info21
.account_name
.string
);
6486 if (!(info
->info21
.acct_flags
& (ACB_WSTRUST
| ACB_SVRTRUST
))) {
6487 torture_warning(tctx
, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6488 info
->info21
.account_name
.string
,
6489 querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
,
6490 info
->info21
.acct_flags
);
6497 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
6504 static bool test_QueryDisplayInfo(struct dcerpc_binding_handle
*b
,
6505 struct torture_context
*tctx
,
6506 struct policy_handle
*handle
)
6508 struct samr_QueryDisplayInfo r
;
6509 struct samr_QueryDomainInfo dom_info
;
6510 union samr_DomainInfo
*info
= NULL
;
6512 uint16_t levels
[] = {1, 2, 3, 4, 5};
6514 bool seen_testuser
= false;
6515 uint32_t total_size
;
6516 uint32_t returned_size
;
6517 union samr_DispInfo disp_info
;
6520 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6521 torture_comment(tctx
, "Testing QueryDisplayInfo level %u\n", levels
[i
]);
6524 r
.out
.result
= STATUS_MORE_ENTRIES
;
6525 while (NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
)) {
6526 r
.in
.domain_handle
= handle
;
6527 r
.in
.level
= levels
[i
];
6528 r
.in
.max_entries
= 2;
6529 r
.in
.buf_size
= (uint32_t)-1;
6530 r
.out
.total_size
= &total_size
;
6531 r
.out
.returned_size
= &returned_size
;
6532 r
.out
.info
= &disp_info
;
6534 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &r
),
6535 "QueryDisplayInfo failed");
6536 if (!NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
) && !NT_STATUS_IS_OK(r
.out
.result
)) {
6537 torture_warning(tctx
, "QueryDisplayInfo level %u failed - %s\n",
6538 levels
[i
], nt_errstr(r
.out
.result
));
6541 switch (r
.in
.level
) {
6543 if (!test_each_DisplayInfo_user(b
, tctx
, &r
, &seen_testuser
)) {
6546 r
.in
.start_idx
+= r
.out
.info
->info1
.count
;
6549 if (!test_each_DisplayInfo_user(b
, tctx
, &r
, NULL
)) {
6552 r
.in
.start_idx
+= r
.out
.info
->info2
.count
;
6555 r
.in
.start_idx
+= r
.out
.info
->info3
.count
;
6558 r
.in
.start_idx
+= r
.out
.info
->info4
.count
;
6561 r
.in
.start_idx
+= r
.out
.info
->info5
.count
;
6565 dom_info
.in
.domain_handle
= handle
;
6566 dom_info
.in
.level
= 2;
6567 dom_info
.out
.info
= &info
;
6569 /* Check number of users returned is correct */
6570 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &dom_info
),
6571 "QueryDomainInfo failed");
6572 if (!NT_STATUS_IS_OK(dom_info
.out
.result
)) {
6573 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
6574 r
.in
.level
, nt_errstr(dom_info
.out
.result
));
6578 switch (r
.in
.level
) {
6581 if (info
->general
.num_users
< r
.in
.start_idx
) {
6582 /* On AD deployments this numbers don't match
6583 * since QueryDisplayInfo returns universal and
6584 * global groups, QueryDomainInfo only global
6586 if (torture_setting_bool(tctx
, "samba3", false)) {
6587 torture_warning(tctx
, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6588 r
.in
.start_idx
, info
->general
.num_groups
,
6589 info
->general
.domain_name
.string
);
6593 if (!seen_testuser
) {
6594 struct policy_handle user_handle
;
6595 if (NT_STATUS_IS_OK(test_OpenUser_byname(b
, tctx
, handle
, TEST_ACCOUNT_NAME
, &user_handle
))) {
6596 torture_warning(tctx
, "Didn't find test user " TEST_ACCOUNT_NAME
" in enumeration of %s\n",
6597 info
->general
.domain_name
.string
);
6599 test_samr_handle_Close(b
, tctx
, &user_handle
);
6605 if (info
->general
.num_groups
!= r
.in
.start_idx
) {
6606 /* On AD deployments this numbers don't match
6607 * since QueryDisplayInfo returns universal and
6608 * global groups, QueryDomainInfo only global
6610 if (torture_setting_bool(tctx
, "samba3", false)) {
6611 torture_warning(tctx
, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6612 r
.in
.start_idx
, info
->general
.num_groups
,
6613 info
->general
.domain_name
.string
);
6626 static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle
*b
,
6627 struct torture_context
*tctx
,
6628 struct policy_handle
*handle
)
6630 struct samr_QueryDisplayInfo2 r
;
6632 uint16_t levels
[] = {1, 2, 3, 4, 5};
6634 uint32_t total_size
;
6635 uint32_t returned_size
;
6636 union samr_DispInfo info
;
6638 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6639 torture_comment(tctx
, "Testing QueryDisplayInfo2 level %u\n", levels
[i
]);
6641 r
.in
.domain_handle
= handle
;
6642 r
.in
.level
= levels
[i
];
6644 r
.in
.max_entries
= 1000;
6645 r
.in
.buf_size
= (uint32_t)-1;
6646 r
.out
.total_size
= &total_size
;
6647 r
.out
.returned_size
= &returned_size
;
6650 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo2_r(b
, tctx
, &r
),
6651 "QueryDisplayInfo2 failed");
6652 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6653 torture_warning(tctx
, "QueryDisplayInfo2 level %u failed - %s\n",
6654 levels
[i
], nt_errstr(r
.out
.result
));
6662 static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle
*b
,
6663 struct torture_context
*tctx
,
6664 struct policy_handle
*handle
)
6666 struct samr_QueryDisplayInfo3 r
;
6668 uint16_t levels
[] = {1, 2, 3, 4, 5};
6670 uint32_t total_size
;
6671 uint32_t returned_size
;
6672 union samr_DispInfo info
;
6674 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6675 torture_comment(tctx
, "Testing QueryDisplayInfo3 level %u\n", levels
[i
]);
6677 r
.in
.domain_handle
= handle
;
6678 r
.in
.level
= levels
[i
];
6680 r
.in
.max_entries
= 1000;
6681 r
.in
.buf_size
= (uint32_t)-1;
6682 r
.out
.total_size
= &total_size
;
6683 r
.out
.returned_size
= &returned_size
;
6686 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo3_r(b
, tctx
, &r
),
6687 "QueryDisplayInfo3 failed");
6688 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6689 torture_warning(tctx
, "QueryDisplayInfo3 level %u failed - %s\n",
6690 levels
[i
], nt_errstr(r
.out
.result
));
6699 static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle
*b
,
6700 struct torture_context
*tctx
,
6701 struct policy_handle
*handle
)
6703 struct samr_QueryDisplayInfo r
;
6705 uint32_t total_size
;
6706 uint32_t returned_size
;
6707 union samr_DispInfo info
;
6709 torture_comment(tctx
, "Testing QueryDisplayInfo continuation\n");
6711 r
.in
.domain_handle
= handle
;
6714 r
.in
.max_entries
= 1;
6715 r
.in
.buf_size
= (uint32_t)-1;
6716 r
.out
.total_size
= &total_size
;
6717 r
.out
.returned_size
= &returned_size
;
6721 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &r
),
6722 "QueryDisplayInfo failed");
6723 if (NT_STATUS_IS_OK(r
.out
.result
) && *r
.out
.returned_size
!= 0) {
6724 if (r
.out
.info
->info1
.entries
[0].idx
!= r
.in
.start_idx
+ 1) {
6725 torture_warning(tctx
, "expected idx %d but got %d\n",
6727 r
.out
.info
->info1
.entries
[0].idx
);
6731 if (!NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
) &&
6732 !NT_STATUS_IS_OK(r
.out
.result
)) {
6733 torture_warning(tctx
, "QueryDisplayInfo level %u failed - %s\n",
6734 r
.in
.level
, nt_errstr(r
.out
.result
));
6739 } while ((NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
) ||
6740 NT_STATUS_IS_OK(r
.out
.result
)) &&
6741 *r
.out
.returned_size
!= 0);
6746 static bool test_QueryDomainInfo(struct dcerpc_pipe
*p
,
6747 struct torture_context
*tctx
,
6748 struct policy_handle
*handle
)
6750 struct samr_QueryDomainInfo r
;
6751 union samr_DomainInfo
*info
= NULL
;
6752 struct samr_SetDomainInfo s
;
6753 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6754 uint16_t set_ok
[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
6757 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
6758 const char *domain_comment
= talloc_asprintf(tctx
,
6759 "Tortured by Samba4 RPC-SAMR: %s",
6760 timestring(tctx
, time(NULL
)));
6762 s
.in
.domain_handle
= handle
;
6764 s
.in
.info
= talloc(tctx
, union samr_DomainInfo
);
6766 s
.in
.info
->oem
.oem_information
.string
= domain_comment
;
6767 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
),
6768 "SetDomainInfo failed");
6769 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
6770 torture_warning(tctx
, "SetDomainInfo level %u (set comment) failed - %s\n",
6771 s
.in
.level
, nt_errstr(s
.out
.result
));
6775 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6776 torture_comment(tctx
, "Testing QueryDomainInfo level %u\n", levels
[i
]);
6778 r
.in
.domain_handle
= handle
;
6779 r
.in
.level
= levels
[i
];
6782 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &r
),
6783 "QueryDomainInfo failed");
6784 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6785 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
6786 r
.in
.level
, nt_errstr(r
.out
.result
));
6791 switch (levels
[i
]) {
6793 if (strcmp(info
->general
.oem_information
.string
, domain_comment
) != 0) {
6794 torture_warning(tctx
, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6795 levels
[i
], info
->general
.oem_information
.string
, domain_comment
);
6796 if (!torture_setting_bool(tctx
, "samba3", false)) {
6800 if (!info
->general
.primary
.string
) {
6801 torture_warning(tctx
, "QueryDomainInfo level %u returned no PDC name\n",
6804 } else if (info
->general
.role
== SAMR_ROLE_DOMAIN_PDC
) {
6805 if (dcerpc_server_name(p
) && strcasecmp_m(dcerpc_server_name(p
), info
->general
.primary
.string
) != 0) {
6806 if (torture_setting_bool(tctx
, "samba3", false)) {
6807 torture_warning(tctx
, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
6808 levels
[i
], info
->general
.primary
.string
, dcerpc_server_name(p
));
6814 if (strcmp(info
->oem
.oem_information
.string
, domain_comment
) != 0) {
6815 torture_warning(tctx
, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6816 levels
[i
], info
->oem
.oem_information
.string
, domain_comment
);
6817 if (!torture_setting_bool(tctx
, "samba3", false)) {
6823 if (!info
->info6
.primary
.string
) {
6824 torture_warning(tctx
, "QueryDomainInfo level %u returned no PDC name\n",
6830 if (strcmp(info
->general2
.general
.oem_information
.string
, domain_comment
) != 0) {
6831 torture_warning(tctx
, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
6832 levels
[i
], info
->general2
.general
.oem_information
.string
, domain_comment
);
6833 if (!torture_setting_bool(tctx
, "samba3", false)) {
6840 torture_comment(tctx
, "Testing SetDomainInfo level %u\n", levels
[i
]);
6842 s
.in
.domain_handle
= handle
;
6843 s
.in
.level
= levels
[i
];
6846 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
),
6847 "SetDomainInfo failed");
6849 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
6850 torture_warning(tctx
, "SetDomainInfo level %u failed - %s\n",
6851 r
.in
.level
, nt_errstr(s
.out
.result
));
6856 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, s
.out
.result
)) {
6857 torture_warning(tctx
, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6858 r
.in
.level
, nt_errstr(s
.out
.result
));
6864 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &r
),
6865 "QueryDomainInfo failed");
6866 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6867 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
6868 r
.in
.level
, nt_errstr(r
.out
.result
));
6878 static bool test_QueryDomainInfo2(struct dcerpc_binding_handle
*b
,
6879 struct torture_context
*tctx
,
6880 struct policy_handle
*handle
)
6882 struct samr_QueryDomainInfo2 r
;
6883 union samr_DomainInfo
*info
= NULL
;
6884 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6888 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6889 torture_comment(tctx
, "Testing QueryDomainInfo2 level %u\n", levels
[i
]);
6891 r
.in
.domain_handle
= handle
;
6892 r
.in
.level
= levels
[i
];
6895 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo2_r(b
, tctx
, &r
),
6896 "QueryDomainInfo2 failed");
6897 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6898 torture_warning(tctx
, "QueryDomainInfo2 level %u failed - %s\n",
6899 r
.in
.level
, nt_errstr(r
.out
.result
));
6908 /* Test whether querydispinfo level 5 and enumdomgroups return the same
6909 set of group names. */
6910 static bool test_GroupList(struct dcerpc_binding_handle
*b
,
6911 struct torture_context
*tctx
,
6912 struct dom_sid
*domain_sid
,
6913 struct policy_handle
*handle
)
6915 struct samr_EnumDomainGroups q1
;
6916 struct samr_QueryDisplayInfo q2
;
6918 uint32_t resume_handle
=0;
6919 struct samr_SamArray
*sam
= NULL
;
6920 uint32_t num_entries
= 0;
6923 uint32_t total_size
;
6924 uint32_t returned_size
;
6925 union samr_DispInfo info
;
6928 const char **names
= NULL
;
6930 bool builtin_domain
= dom_sid_compare(domain_sid
,
6931 &global_sid_Builtin
) == 0;
6933 torture_comment(tctx
, "Testing coherency of querydispinfo vs enumdomgroups\n");
6935 q1
.in
.domain_handle
= handle
;
6936 q1
.in
.resume_handle
= &resume_handle
;
6938 q1
.out
.resume_handle
= &resume_handle
;
6939 q1
.out
.num_entries
= &num_entries
;
6942 status
= STATUS_MORE_ENTRIES
;
6943 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
6944 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainGroups_r(b
, tctx
, &q1
),
6945 "EnumDomainGroups failed");
6946 status
= q1
.out
.result
;
6948 if (!NT_STATUS_IS_OK(status
) &&
6949 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
6952 for (i
=0; i
<*q1
.out
.num_entries
; i
++) {
6953 add_string_to_array(tctx
,
6954 sam
->entries
[i
].name
.string
,
6955 &names
, &num_names
);
6959 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomainGroups");
6961 torture_assert(tctx
, sam
, "EnumDomainGroups failed to return sam");
6963 if (builtin_domain
) {
6964 torture_assert(tctx
, num_names
== 0,
6965 "EnumDomainGroups shouldn't return any group in the builtin domain!");
6968 q2
.in
.domain_handle
= handle
;
6970 q2
.in
.start_idx
= 0;
6971 q2
.in
.max_entries
= 5;
6972 q2
.in
.buf_size
= (uint32_t)-1;
6973 q2
.out
.total_size
= &total_size
;
6974 q2
.out
.returned_size
= &returned_size
;
6975 q2
.out
.info
= &info
;
6977 status
= STATUS_MORE_ENTRIES
;
6978 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
6979 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &q2
),
6980 "QueryDisplayInfo failed");
6981 status
= q2
.out
.result
;
6982 if (!NT_STATUS_IS_OK(status
) &&
6983 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
6986 for (i
=0; i
<q2
.out
.info
->info5
.count
; i
++) {
6988 const char *name
= q2
.out
.info
->info5
.entries
[i
].account_name
.string
;
6990 for (j
=0; j
<num_names
; j
++) {
6991 if (names
[j
] == NULL
)
6993 if (strequal(names
[j
], name
)) {
7000 if ((!found
) && (!builtin_domain
)) {
7001 torture_warning(tctx
, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
7006 q2
.in
.start_idx
+= q2
.out
.info
->info5
.count
;
7009 if (!NT_STATUS_IS_OK(status
)) {
7010 torture_warning(tctx
, "QueryDisplayInfo level 5 failed - %s\n",
7015 if (builtin_domain
) {
7016 torture_assert(tctx
, q2
.in
.start_idx
!= 0,
7017 "QueryDisplayInfo should return all domain groups also on the builtin domain handle!");
7020 for (i
=0; i
<num_names
; i
++) {
7021 if (names
[i
] != NULL
) {
7022 torture_warning(tctx
, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
7031 static bool test_DeleteDomainGroup(struct dcerpc_binding_handle
*b
,
7032 struct torture_context
*tctx
,
7033 struct policy_handle
*group_handle
)
7035 struct samr_DeleteDomainGroup d
;
7037 torture_comment(tctx
, "Testing DeleteDomainGroup\n");
7039 d
.in
.group_handle
= group_handle
;
7040 d
.out
.group_handle
= group_handle
;
7042 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteDomainGroup_r(b
, tctx
, &d
),
7043 "DeleteDomainGroup failed");
7044 torture_assert_ntstatus_ok(tctx
, d
.out
.result
, "DeleteDomainGroup");
7049 static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle
*b
,
7050 struct torture_context
*tctx
,
7051 struct policy_handle
*domain_handle
)
7053 struct samr_TestPrivateFunctionsDomain r
;
7056 torture_comment(tctx
, "Testing TestPrivateFunctionsDomain\n");
7058 r
.in
.domain_handle
= domain_handle
;
7060 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_TestPrivateFunctionsDomain_r(b
, tctx
, &r
),
7061 "TestPrivateFunctionsDomain failed");
7062 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_NOT_IMPLEMENTED
, "TestPrivateFunctionsDomain");
7067 static bool test_RidToSid(struct dcerpc_binding_handle
*b
,
7068 struct torture_context
*tctx
,
7069 struct dom_sid
*domain_sid
,
7070 struct policy_handle
*domain_handle
)
7072 struct samr_RidToSid r
;
7074 struct dom_sid
*calc_sid
, *out_sid
;
7075 int rids
[] = { 0, 42, 512, 10200 };
7078 for (i
=0;i
<ARRAY_SIZE(rids
);i
++) {
7079 torture_comment(tctx
, "Testing RidToSid\n");
7081 calc_sid
= dom_sid_dup(tctx
, domain_sid
);
7082 r
.in
.domain_handle
= domain_handle
;
7084 r
.out
.sid
= &out_sid
;
7086 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RidToSid_r(b
, tctx
, &r
),
7088 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
7089 torture_warning(tctx
, "RidToSid for %d failed - %s\n", rids
[i
], nt_errstr(r
.out
.result
));
7092 calc_sid
= dom_sid_add_rid(calc_sid
, calc_sid
, rids
[i
]);
7094 if (!dom_sid_equal(calc_sid
, out_sid
)) {
7095 torture_warning(tctx
, "RidToSid for %d failed - got %s, expected %s\n", rids
[i
],
7096 dom_sid_string(tctx
, out_sid
),
7097 dom_sid_string(tctx
, calc_sid
));
7106 static bool test_GetBootKeyInformation(struct dcerpc_binding_handle
*b
,
7107 struct torture_context
*tctx
,
7108 struct policy_handle
*domain_handle
)
7110 struct samr_GetBootKeyInformation r
;
7112 uint32_t unknown
= 0;
7115 torture_comment(tctx
, "Testing GetBootKeyInformation\n");
7117 r
.in
.domain_handle
= domain_handle
;
7118 r
.out
.unknown
= &unknown
;
7120 status
= dcerpc_samr_GetBootKeyInformation_r(b
, tctx
, &r
);
7121 if (NT_STATUS_IS_OK(status
) && !NT_STATUS_IS_OK(r
.out
.result
)) {
7122 status
= r
.out
.result
;
7124 if (!NT_STATUS_IS_OK(status
)) {
7125 /* w2k3 seems to fail this sometimes and pass it sometimes */
7126 torture_comment(tctx
, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status
));
7132 static bool test_AddGroupMember(struct dcerpc_binding_handle
*b
,
7133 struct torture_context
*tctx
,
7134 struct policy_handle
*domain_handle
,
7135 struct policy_handle
*group_handle
)
7138 struct samr_AddGroupMember r
;
7139 struct samr_DeleteGroupMember d
;
7140 struct samr_QueryGroupMember q
;
7141 struct samr_RidAttrArray
*rids
= NULL
;
7142 struct samr_SetMemberAttributesOfGroup s
;
7144 bool found_member
= false;
7147 status
= test_LookupName(b
, tctx
, domain_handle
, TEST_ACCOUNT_NAME
, &rid
);
7148 torture_assert_ntstatus_ok(tctx
, status
, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME
);
7150 r
.in
.group_handle
= group_handle
;
7152 r
.in
.flags
= 0; /* ??? */
7154 torture_comment(tctx
, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
7156 d
.in
.group_handle
= group_handle
;
7159 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteGroupMember_r(b
, tctx
, &d
),
7160 "DeleteGroupMember failed");
7161 torture_assert_ntstatus_equal(tctx
, NT_STATUS_MEMBER_NOT_IN_GROUP
, d
.out
.result
, "DeleteGroupMember");
7163 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddGroupMember_r(b
, tctx
, &r
),
7164 "AddGroupMember failed");
7165 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "AddGroupMember");
7167 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddGroupMember_r(b
, tctx
, &r
),
7168 "AddGroupMember failed");
7169 torture_assert_ntstatus_equal(tctx
, NT_STATUS_MEMBER_IN_GROUP
, r
.out
.result
, "AddGroupMember");
7171 if (torture_setting_bool(tctx
, "samba4", false) ||
7172 torture_setting_bool(tctx
, "samba3", false)) {
7173 torture_comment(tctx
, "skipping SetMemberAttributesOfGroup test against Samba\n");
7175 /* this one is quite strange. I am using random inputs in the
7176 hope of triggering an error that might give us a clue */
7178 s
.in
.group_handle
= group_handle
;
7179 s
.in
.unknown1
= random();
7180 s
.in
.unknown2
= random();
7182 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetMemberAttributesOfGroup_r(b
, tctx
, &s
),
7183 "SetMemberAttributesOfGroup failed");
7184 torture_assert_ntstatus_ok(tctx
, s
.out
.result
, "SetMemberAttributesOfGroup");
7187 q
.in
.group_handle
= group_handle
;
7190 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupMember_r(b
, tctx
, &q
),
7191 "QueryGroupMember failed");
7192 torture_assert_ntstatus_ok(tctx
, q
.out
.result
, "QueryGroupMember");
7193 torture_assert(tctx
, rids
, "QueryGroupMember did not fill in rids structure");
7195 for (i
=0; i
< rids
->count
; i
++) {
7196 if (rids
->rids
[i
] == rid
) {
7197 found_member
= true;
7201 torture_assert(tctx
, found_member
, "QueryGroupMember did not list newly added member");
7203 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteGroupMember_r(b
, tctx
, &d
),
7204 "DeleteGroupMember failed");
7205 torture_assert_ntstatus_ok(tctx
, d
.out
.result
, "DeleteGroupMember");
7208 found_member
= false;
7210 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupMember_r(b
, tctx
, &q
),
7211 "QueryGroupMember failed");
7212 torture_assert_ntstatus_ok(tctx
, q
.out
.result
, "QueryGroupMember");
7213 torture_assert(tctx
, rids
, "QueryGroupMember did not fill in rids structure");
7215 for (i
=0; i
< rids
->count
; i
++) {
7216 if (rids
->rids
[i
] == rid
) {
7217 found_member
= true;
7221 torture_assert(tctx
, !found_member
, "QueryGroupMember does still list removed member");
7223 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddGroupMember_r(b
, tctx
, &r
),
7224 "AddGroupMember failed");
7225 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "AddGroupMember");
7231 static bool test_CreateDomainGroup(struct dcerpc_binding_handle
*b
,
7232 struct torture_context
*tctx
,
7233 struct policy_handle
*domain_handle
,
7234 const char *group_name
,
7235 struct policy_handle
*group_handle
,
7236 struct dom_sid
*domain_sid
,
7239 struct samr_CreateDomainGroup r
;
7241 struct lsa_String name
;
7244 init_lsa_String(&name
, group_name
);
7246 r
.in
.domain_handle
= domain_handle
;
7248 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7249 r
.out
.group_handle
= group_handle
;
7252 torture_comment(tctx
, "Testing CreateDomainGroup(%s)\n", r
.in
.name
->string
);
7254 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomainGroup_r(b
, tctx
, &r
),
7255 "CreateDomainGroup failed");
7257 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
7258 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
)) {
7259 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.name
->string
);
7262 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.name
->string
,
7263 nt_errstr(r
.out
.result
));
7268 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_GROUP_EXISTS
)) {
7269 if (!test_DeleteGroup_byname(b
, tctx
, domain_handle
, r
.in
.name
->string
)) {
7270 torture_warning(tctx
, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r
.in
.name
->string
,
7271 nt_errstr(r
.out
.result
));
7274 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomainGroup_r(b
, tctx
, &r
),
7275 "CreateDomainGroup failed");
7277 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_USER_EXISTS
)) {
7278 if (!test_DeleteUser_byname(b
, tctx
, domain_handle
, r
.in
.name
->string
)) {
7280 torture_warning(tctx
, "CreateDomainGroup failed: Could not delete user %s - %s\n", r
.in
.name
->string
,
7281 nt_errstr(r
.out
.result
));
7284 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomainGroup_r(b
, tctx
, &r
),
7285 "CreateDomainGroup failed");
7287 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "CreateDomainGroup");
7293 if (!test_AddGroupMember(b
, tctx
, domain_handle
, group_handle
)) {
7294 torture_warning(tctx
, "CreateDomainGroup failed - %s\n", nt_errstr(r
.out
.result
));
7298 if (!test_SetGroupInfo(b
, tctx
, group_handle
)) {
7307 its not totally clear what this does. It seems to accept any sid you like.
7309 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle
*b
,
7310 struct torture_context
*tctx
,
7311 struct policy_handle
*domain_handle
)
7313 struct samr_RemoveMemberFromForeignDomain r
;
7315 r
.in
.domain_handle
= domain_handle
;
7316 r
.in
.sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-12-34-56-78");
7318 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RemoveMemberFromForeignDomain_r(b
, tctx
, &r
),
7319 "RemoveMemberFromForeignDomain failed");
7320 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "RemoveMemberFromForeignDomain");
7325 static bool test_EnumDomainUsers(struct dcerpc_binding_handle
*b
,
7326 struct torture_context
*tctx
,
7327 struct policy_handle
*domain_handle
,
7328 uint32_t *total_num_entries_p
)
7331 struct samr_EnumDomainUsers r
;
7332 uint32_t resume_handle
= 0;
7333 uint32_t num_entries
= 0;
7334 uint32_t total_num_entries
= 0;
7335 struct samr_SamArray
*sam
;
7337 r
.in
.domain_handle
= domain_handle
;
7338 r
.in
.acct_flags
= 0;
7339 r
.in
.max_size
= (uint32_t)-1;
7340 r
.in
.resume_handle
= &resume_handle
;
7343 r
.out
.num_entries
= &num_entries
;
7344 r
.out
.resume_handle
= &resume_handle
;
7346 torture_comment(tctx
, "Testing EnumDomainUsers\n");
7349 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainUsers_r(b
, tctx
, &r
),
7350 "EnumDomainUsers failed");
7351 if (NT_STATUS_IS_ERR(r
.out
.result
)) {
7352 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
7353 "failed to enumerate users");
7355 status
= r
.out
.result
;
7357 total_num_entries
+= num_entries
;
7358 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7360 if (total_num_entries_p
) {
7361 *total_num_entries_p
= total_num_entries
;
7367 static bool test_EnumDomainGroups(struct dcerpc_binding_handle
*b
,
7368 struct torture_context
*tctx
,
7369 struct policy_handle
*domain_handle
,
7370 uint32_t *total_num_entries_p
)
7373 struct samr_EnumDomainGroups r
;
7374 uint32_t resume_handle
= 0;
7375 uint32_t num_entries
= 0;
7376 uint32_t total_num_entries
= 0;
7377 struct samr_SamArray
*sam
;
7379 r
.in
.domain_handle
= domain_handle
;
7380 r
.in
.max_size
= (uint32_t)-1;
7381 r
.in
.resume_handle
= &resume_handle
;
7384 r
.out
.num_entries
= &num_entries
;
7385 r
.out
.resume_handle
= &resume_handle
;
7387 torture_comment(tctx
, "Testing EnumDomainGroups\n");
7390 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainGroups_r(b
, tctx
, &r
),
7391 "EnumDomainGroups failed");
7392 if (NT_STATUS_IS_ERR(r
.out
.result
)) {
7393 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
7394 "failed to enumerate groups");
7396 status
= r
.out
.result
;
7398 total_num_entries
+= num_entries
;
7399 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7401 if (total_num_entries_p
) {
7402 *total_num_entries_p
= total_num_entries
;
7408 static bool test_EnumDomainAliases(struct dcerpc_binding_handle
*b
,
7409 struct torture_context
*tctx
,
7410 struct policy_handle
*domain_handle
,
7411 uint32_t *total_num_entries_p
)
7414 struct samr_EnumDomainAliases r
;
7415 uint32_t resume_handle
= 0;
7416 uint32_t num_entries
= 0;
7417 uint32_t total_num_entries
= 0;
7418 struct samr_SamArray
*sam
;
7420 r
.in
.domain_handle
= domain_handle
;
7421 r
.in
.max_size
= (uint32_t)-1;
7422 r
.in
.resume_handle
= &resume_handle
;
7425 r
.out
.num_entries
= &num_entries
;
7426 r
.out
.resume_handle
= &resume_handle
;
7428 torture_comment(tctx
, "Testing EnumDomainAliases\n");
7431 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainAliases_r(b
, tctx
, &r
),
7432 "EnumDomainAliases failed");
7433 if (NT_STATUS_IS_ERR(r
.out
.result
)) {
7434 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
7435 "failed to enumerate aliases");
7437 status
= r
.out
.result
;
7439 total_num_entries
+= num_entries
;
7440 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7442 if (total_num_entries_p
) {
7443 *total_num_entries_p
= total_num_entries
;
7449 static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle
*b
,
7450 struct torture_context
*tctx
,
7451 struct policy_handle
*handle
,
7453 uint32_t *total_num_entries_p
)
7456 struct samr_QueryDisplayInfo r
;
7457 uint32_t total_num_entries
= 0;
7459 r
.in
.domain_handle
= handle
;
7462 r
.in
.max_entries
= (uint32_t)-1;
7463 r
.in
.buf_size
= (uint32_t)-1;
7465 torture_comment(tctx
, "Testing QueryDisplayInfo\n");
7468 uint32_t total_size
;
7469 uint32_t returned_size
;
7470 union samr_DispInfo info
;
7472 r
.out
.total_size
= &total_size
;
7473 r
.out
.returned_size
= &returned_size
;
7476 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &r
),
7477 "failed to query displayinfo");
7478 if (NT_STATUS_IS_ERR(r
.out
.result
)) {
7479 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
7480 "failed to query displayinfo");
7482 status
= r
.out
.result
;
7484 if (*r
.out
.returned_size
== 0) {
7488 switch (r
.in
.level
) {
7490 total_num_entries
+= info
.info1
.count
;
7491 r
.in
.start_idx
+= info
.info1
.entries
[info
.info1
.count
- 1].idx
+ 1;
7494 total_num_entries
+= info
.info2
.count
;
7495 r
.in
.start_idx
+= info
.info2
.entries
[info
.info2
.count
- 1].idx
+ 1;
7498 total_num_entries
+= info
.info3
.count
;
7499 r
.in
.start_idx
+= info
.info3
.entries
[info
.info3
.count
- 1].idx
+ 1;
7502 total_num_entries
+= info
.info4
.count
;
7503 r
.in
.start_idx
+= info
.info4
.entries
[info
.info4
.count
- 1].idx
+ 1;
7506 total_num_entries
+= info
.info5
.count
;
7507 r
.in
.start_idx
+= info
.info5
.entries
[info
.info5
.count
- 1].idx
+ 1;
7513 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7515 if (total_num_entries_p
) {
7516 *total_num_entries_p
= total_num_entries
;
7522 static bool test_ManyObjects(struct dcerpc_pipe
*p
,
7523 struct torture_context
*tctx
,
7524 struct policy_handle
*domain_handle
,
7525 struct dom_sid
*domain_sid
,
7526 struct torture_samr_context
*ctx
)
7528 uint32_t num_total
= ctx
->num_objects_large_dc
;
7529 uint32_t num_enum
= 0;
7530 uint32_t num_disp
= 0;
7531 uint32_t num_created
= 0;
7532 uint32_t num_anounced
= 0;
7534 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7536 struct policy_handle
*handles
= talloc_zero_array(tctx
, struct policy_handle
, num_total
);
7541 struct samr_QueryDomainInfo2 r
;
7542 union samr_DomainInfo
*info
;
7543 r
.in
.domain_handle
= domain_handle
;
7547 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo2_r(b
, tctx
, &r
),
7548 "QueryDomainInfo2 failed");
7549 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
7550 "failed to query domain info");
7552 switch (ctx
->choice
) {
7553 case TORTURE_SAMR_MANY_ACCOUNTS
:
7554 num_anounced
= info
->general
.num_users
;
7556 case TORTURE_SAMR_MANY_GROUPS
:
7557 num_anounced
= info
->general
.num_groups
;
7559 case TORTURE_SAMR_MANY_ALIASES
:
7560 num_anounced
= info
->general
.num_aliases
;
7569 for (i
=0; i
< num_total
; i
++) {
7571 const char *name
= NULL
;
7573 switch (ctx
->choice
) {
7574 case TORTURE_SAMR_MANY_ACCOUNTS
:
7575 name
= talloc_asprintf(tctx
, "%s%04d", TEST_ACCOUNT_NAME
, i
);
7576 torture_assert(tctx
,
7577 test_CreateUser(p
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, 0, NULL
, false),
7578 "failed to create user");
7580 case TORTURE_SAMR_MANY_GROUPS
:
7581 name
= talloc_asprintf(tctx
, "%s%04d", TEST_GROUPNAME
, i
);
7582 torture_assert(tctx
,
7583 test_CreateDomainGroup(b
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, false),
7584 "failed to create group");
7586 case TORTURE_SAMR_MANY_ALIASES
:
7587 name
= talloc_asprintf(tctx
, "%s%04d", TEST_ALIASNAME
, i
);
7588 torture_assert(tctx
,
7589 test_CreateAlias(b
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, false),
7590 "failed to create alias");
7595 if (!ndr_policy_handle_empty(&handles
[i
])) {
7602 switch (ctx
->choice
) {
7603 case TORTURE_SAMR_MANY_ACCOUNTS
:
7604 torture_assert(tctx
,
7605 test_EnumDomainUsers(b
, tctx
, domain_handle
, &num_enum
),
7606 "failed to enum users");
7608 case TORTURE_SAMR_MANY_GROUPS
:
7609 torture_assert(tctx
,
7610 test_EnumDomainGroups(b
, tctx
, domain_handle
, &num_enum
),
7611 "failed to enum groups");
7613 case TORTURE_SAMR_MANY_ALIASES
:
7614 torture_assert(tctx
,
7615 test_EnumDomainAliases(b
, tctx
, domain_handle
, &num_enum
),
7616 "failed to enum aliases");
7624 switch (ctx
->choice
) {
7625 case TORTURE_SAMR_MANY_ACCOUNTS
:
7626 torture_assert(tctx
,
7627 test_QueryDisplayInfo_level(b
, tctx
, domain_handle
, 1, &num_disp
),
7628 "failed to query display info");
7630 case TORTURE_SAMR_MANY_GROUPS
:
7631 torture_assert(tctx
,
7632 test_QueryDisplayInfo_level(b
, tctx
, domain_handle
, 3, &num_disp
),
7633 "failed to query display info");
7635 case TORTURE_SAMR_MANY_ALIASES
:
7636 /* no aliases in dispinfo */
7642 /* close or delete */
7644 for (i
=0; i
< num_total
; i
++) {
7646 if (ndr_policy_handle_empty(&handles
[i
])) {
7650 if (torture_setting_bool(tctx
, "samba3", false)) {
7651 torture_assert(tctx
,
7652 test_samr_handle_Close(b
, tctx
, &handles
[i
]),
7653 "failed to close handle");
7655 switch (ctx
->choice
) {
7656 case TORTURE_SAMR_MANY_ACCOUNTS
:
7657 torture_assert(tctx
,
7658 test_DeleteUser(b
, tctx
, &handles
[i
]),
7659 "failed to delete user");
7661 case TORTURE_SAMR_MANY_GROUPS
:
7662 torture_assert(tctx
,
7663 test_DeleteDomainGroup(b
, tctx
, &handles
[i
]),
7664 "failed to delete group");
7666 case TORTURE_SAMR_MANY_ALIASES
:
7667 torture_assert(tctx
,
7668 test_DeleteAlias(b
, tctx
, &handles
[i
]),
7669 "failed to delete alias");
7677 talloc_free(handles
);
7679 if (ctx
->choice
== TORTURE_SAMR_MANY_ACCOUNTS
&& num_enum
!= num_anounced
+ num_created
) {
7680 torture_comment(tctx
,
7681 "unexpected number of results (%u) returned in enum call, expected %u\n",
7682 num_enum
, num_anounced
+ num_created
);
7684 torture_comment(tctx
,
7685 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
7686 num_disp
, num_anounced
+ num_created
);
7692 static bool test_Connect(struct dcerpc_binding_handle
*b
,
7693 struct torture_context
*tctx
,
7694 struct policy_handle
*handle
);
7696 static bool test_OpenDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7697 struct torture_samr_context
*ctx
, struct dom_sid
*sid
)
7699 struct samr_OpenDomain r
;
7700 struct policy_handle domain_handle
;
7701 struct policy_handle alias_handle
;
7702 struct policy_handle user_handle
;
7703 struct policy_handle group_handle
;
7705 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7707 ZERO_STRUCT(alias_handle
);
7708 ZERO_STRUCT(user_handle
);
7709 ZERO_STRUCT(group_handle
);
7710 ZERO_STRUCT(domain_handle
);
7712 torture_comment(tctx
, "Testing OpenDomain of %s\n", dom_sid_string(tctx
, sid
));
7714 r
.in
.connect_handle
= &ctx
->handle
;
7715 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7717 r
.out
.domain_handle
= &domain_handle
;
7719 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenDomain_r(b
, tctx
, &r
),
7720 "OpenDomain failed");
7721 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "OpenDomain failed");
7723 /* run the domain tests with the main handle closed - this tests
7724 the servers reference counting */
7725 torture_assert(tctx
, test_samr_handle_Close(b
, tctx
, &ctx
->handle
), "Failed to close SAMR handle");
7727 switch (ctx
->choice
) {
7728 case TORTURE_SAMR_PASSWORDS
:
7729 case TORTURE_SAMR_USER_PRIVILEGES
:
7730 if (!torture_setting_bool(tctx
, "samba3", false)) {
7731 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, NULL
);
7733 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
7735 torture_warning(tctx
, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7738 case TORTURE_SAMR_USER_ATTRIBUTES
:
7739 if (!torture_setting_bool(tctx
, "samba3", false)) {
7740 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, NULL
);
7742 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
7743 /* This test needs 'complex' users to validate */
7744 ret
&= test_QueryDisplayInfo(b
, tctx
, &domain_handle
);
7746 torture_warning(tctx
, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7749 case TORTURE_SAMR_PASSWORDS_PWDLASTSET
:
7750 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
:
7751 case TORTURE_SAMR_PASSWORDS_LOCKOUT
:
7752 if (!torture_setting_bool(tctx
, "samba3", false)) {
7753 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, ctx
->machine_credentials
);
7755 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, ctx
->machine_credentials
, true);
7757 torture_warning(tctx
, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7760 case TORTURE_SAMR_MANY_ACCOUNTS
:
7761 case TORTURE_SAMR_MANY_GROUPS
:
7762 case TORTURE_SAMR_MANY_ALIASES
:
7763 ret
&= test_ManyObjects(p
, tctx
, &domain_handle
, sid
, ctx
);
7765 torture_warning(tctx
, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7768 case TORTURE_SAMR_OTHER
:
7769 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
7771 torture_warning(tctx
, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx
, sid
));
7773 if (!torture_setting_bool(tctx
, "samba3", false)) {
7774 ret
&= test_QuerySecurity(b
, tctx
, &domain_handle
);
7776 ret
&= test_RemoveMemberFromForeignDomain(b
, tctx
, &domain_handle
);
7777 ret
&= test_CreateAlias(b
, tctx
, &domain_handle
, TEST_ALIASNAME
, &alias_handle
, sid
, true);
7778 ret
&= test_CreateDomainGroup(b
, tctx
, &domain_handle
, TEST_GROUPNAME
, &group_handle
, sid
, true);
7779 ret
&= test_GetAliasMembership(b
, tctx
, &domain_handle
);
7780 ret
&= test_QueryDomainInfo(p
, tctx
, &domain_handle
);
7781 ret
&= test_QueryDomainInfo2(b
, tctx
, &domain_handle
);
7782 ret
&= test_EnumDomainUsers_all(b
, tctx
, &domain_handle
);
7783 ret
&= test_EnumDomainUsers_async(p
, tctx
, &domain_handle
);
7784 ret
&= test_EnumDomainGroups_all(b
, tctx
, &domain_handle
);
7785 ret
&= test_EnumDomainAliases_all(b
, tctx
, &domain_handle
);
7786 ret
&= test_QueryDisplayInfo2(b
, tctx
, &domain_handle
);
7787 ret
&= test_QueryDisplayInfo3(b
, tctx
, &domain_handle
);
7788 ret
&= test_QueryDisplayInfo_continue(b
, tctx
, &domain_handle
);
7790 if (torture_setting_bool(tctx
, "samba4", false)) {
7791 torture_comment(tctx
, "skipping GetDisplayEnumerationIndex test against Samba4\n");
7793 ret
&= test_GetDisplayEnumerationIndex(b
, tctx
, &domain_handle
);
7794 ret
&= test_GetDisplayEnumerationIndex2(b
, tctx
, &domain_handle
);
7796 ret
&= test_GroupList(b
, tctx
, sid
, &domain_handle
);
7797 ret
&= test_TestPrivateFunctionsDomain(b
, tctx
, &domain_handle
);
7798 ret
&= test_RidToSid(b
, tctx
, sid
, &domain_handle
);
7799 ret
&= test_GetBootKeyInformation(b
, tctx
, &domain_handle
);
7801 torture_comment(tctx
, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7806 if (!ndr_policy_handle_empty(&user_handle
) &&
7807 !test_DeleteUser(b
, tctx
, &user_handle
)) {
7811 if (!ndr_policy_handle_empty(&alias_handle
) &&
7812 !test_DeleteAlias(b
, tctx
, &alias_handle
)) {
7816 if (!ndr_policy_handle_empty(&group_handle
) &&
7817 !test_DeleteDomainGroup(b
, tctx
, &group_handle
)) {
7821 torture_assert(tctx
, test_samr_handle_Close(b
, tctx
, &domain_handle
), "Failed to close SAMR domain handle");
7823 torture_assert(tctx
, test_Connect(b
, tctx
, &ctx
->handle
), "Faile to re-connect SAMR handle");
7824 /* reconnect the main handle */
7827 torture_warning(tctx
, "Testing domain %s failed!\n", dom_sid_string(tctx
, sid
));
7833 static bool test_LookupDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7834 struct torture_samr_context
*ctx
, const char *domain
)
7836 struct samr_LookupDomain r
;
7837 struct dom_sid2
*sid
= NULL
;
7838 struct lsa_String n1
;
7839 struct lsa_String n2
;
7841 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7843 torture_comment(tctx
, "Testing LookupDomain(%s)\n", domain
);
7845 /* check for correct error codes */
7846 r
.in
.connect_handle
= &ctx
->handle
;
7847 r
.in
.domain_name
= &n2
;
7851 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupDomain_r(b
, tctx
, &r
),
7852 "LookupDomain failed");
7853 torture_assert_ntstatus_equal(tctx
, NT_STATUS_INVALID_PARAMETER
, r
.out
.result
, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
7855 init_lsa_String(&n2
, "xxNODOMAINxx");
7857 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupDomain_r(b
, tctx
, &r
),
7858 "LookupDomain failed");
7859 torture_assert_ntstatus_equal(tctx
, NT_STATUS_NO_SUCH_DOMAIN
, r
.out
.result
, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
7861 r
.in
.connect_handle
= &ctx
->handle
;
7863 init_lsa_String(&n1
, domain
);
7864 r
.in
.domain_name
= &n1
;
7866 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupDomain_r(b
, tctx
, &r
),
7867 "LookupDomain failed");
7868 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LookupDomain");
7870 if (!test_GetDomPwInfo(p
, tctx
, &n1
)) {
7874 if (!test_OpenDomain(p
, tctx
, ctx
, *r
.out
.sid
)) {
7882 static bool test_EnumDomains(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7883 struct torture_samr_context
*ctx
)
7885 struct samr_EnumDomains r
;
7886 uint32_t resume_handle
= 0;
7887 uint32_t num_entries
= 0;
7888 struct samr_SamArray
*sam
= NULL
;
7891 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7893 r
.in
.connect_handle
= &ctx
->handle
;
7894 r
.in
.resume_handle
= &resume_handle
;
7895 r
.in
.buf_size
= (uint32_t)-1;
7896 r
.out
.resume_handle
= &resume_handle
;
7897 r
.out
.num_entries
= &num_entries
;
7900 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomains_r(b
, tctx
, &r
),
7901 "EnumDomains failed");
7902 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "EnumDomains failed");
7908 for (i
=0;i
<sam
->count
;i
++) {
7909 if (!test_LookupDomain(p
, tctx
, ctx
,
7910 sam
->entries
[i
].name
.string
)) {
7915 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomains_r(b
, tctx
, &r
),
7916 "EnumDomains failed");
7917 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "EnumDomains failed");
7923 static bool test_Connect(struct dcerpc_binding_handle
*b
,
7924 struct torture_context
*tctx
,
7925 struct policy_handle
*handle
)
7927 struct samr_Connect r
;
7928 struct samr_Connect2 r2
;
7929 struct samr_Connect3 r3
;
7930 struct samr_Connect4 r4
;
7931 struct samr_Connect5 r5
;
7932 union samr_ConnectInfo info
;
7933 struct policy_handle h
;
7934 uint32_t level_out
= 0;
7935 bool ret
= true, got_handle
= false;
7937 torture_comment(tctx
, "Testing samr_Connect\n");
7939 r
.in
.system_name
= NULL
;
7940 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7941 r
.out
.connect_handle
= &h
;
7943 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect_r(b
, tctx
, &r
),
7945 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
7946 torture_comment(tctx
, "Connect failed - %s\n", nt_errstr(r
.out
.result
));
7953 torture_comment(tctx
, "Testing samr_Connect2\n");
7955 r2
.in
.system_name
= NULL
;
7956 r2
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7957 r2
.out
.connect_handle
= &h
;
7959 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect2_r(b
, tctx
, &r2
),
7961 if (!NT_STATUS_IS_OK(r2
.out
.result
)) {
7962 torture_comment(tctx
, "Connect2 failed - %s\n", nt_errstr(r2
.out
.result
));
7966 test_samr_handle_Close(b
, tctx
, handle
);
7972 torture_comment(tctx
, "Testing samr_Connect3\n");
7974 r3
.in
.system_name
= NULL
;
7976 r3
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7977 r3
.out
.connect_handle
= &h
;
7979 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect3_r(b
, tctx
, &r3
),
7981 if (!NT_STATUS_IS_OK(r3
.out
.result
)) {
7982 torture_warning(tctx
, "Connect3 failed - %s\n", nt_errstr(r3
.out
.result
));
7986 test_samr_handle_Close(b
, tctx
, handle
);
7992 torture_comment(tctx
, "Testing samr_Connect4\n");
7994 r4
.in
.system_name
= "";
7995 r4
.in
.client_version
= 0;
7996 r4
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7997 r4
.out
.connect_handle
= &h
;
7999 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect4_r(b
, tctx
, &r4
),
8001 if (!NT_STATUS_IS_OK(r4
.out
.result
)) {
8002 torture_warning(tctx
, "Connect4 failed - %s\n", nt_errstr(r4
.out
.result
));
8006 test_samr_handle_Close(b
, tctx
, handle
);
8012 torture_comment(tctx
, "Testing samr_Connect5\n");
8014 info
.info1
.client_version
= 0;
8015 info
.info1
.unknown2
= 0;
8017 r5
.in
.system_name
= "";
8018 r5
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
8020 r5
.out
.level_out
= &level_out
;
8021 r5
.in
.info_in
= &info
;
8022 r5
.out
.info_out
= &info
;
8023 r5
.out
.connect_handle
= &h
;
8025 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect5_r(b
, tctx
, &r5
),
8027 if (!NT_STATUS_IS_OK(r5
.out
.result
)) {
8028 torture_warning(tctx
, "Connect5 failed - %s\n", nt_errstr(r5
.out
.result
));
8032 test_samr_handle_Close(b
, tctx
, handle
);
8042 static bool test_samr_ValidatePassword(struct dcerpc_pipe
*p
,
8043 struct torture_context
*tctx
)
8045 struct samr_ValidatePassword r
;
8046 union samr_ValidatePasswordReq req
;
8047 union samr_ValidatePasswordRep
*repp
= NULL
;
8049 const char *passwords
[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL
};
8051 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
8053 torture_comment(tctx
, "Testing samr_ValidatePassword\n");
8056 r
.in
.level
= NetValidatePasswordReset
;
8061 req
.req3
.account
.string
= "non-existent-account-aklsdji";
8063 for (i
=0; passwords
[i
]; i
++) {
8064 req
.req3
.password
.string
= passwords
[i
];
8066 status
= dcerpc_samr_ValidatePassword_r(b
, tctx
, &r
);
8067 if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE
)) {
8068 torture_skip(tctx
, "ValidatePassword not supported by server\n");
8070 torture_assert_ntstatus_ok(tctx
, status
,
8071 "samr_ValidatePassword failed");
8072 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
8073 "samr_ValidatePassword failed");
8074 torture_comment(tctx
, "Server %s password '%s' with code %i\n",
8075 repp
->ctr3
.status
==SAMR_VALIDATION_STATUS_SUCCESS
?"allowed":"refused",
8076 req
.req3
.password
.string
, repp
->ctr3
.status
);
8082 bool torture_rpc_samr(struct torture_context
*torture
)
8085 struct dcerpc_pipe
*p
;
8087 struct torture_samr_context
*ctx
;
8088 struct dcerpc_binding_handle
*b
;
8090 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8091 if (!NT_STATUS_IS_OK(status
)) {
8094 b
= p
->binding_handle
;
8096 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8098 ctx
->choice
= TORTURE_SAMR_OTHER
;
8100 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8102 if (!torture_setting_bool(torture
, "samba3", false)) {
8103 ret
&= test_QuerySecurity(b
, torture
, &ctx
->handle
);
8106 ret
&= test_EnumDomains(p
, torture
, ctx
);
8108 ret
&= test_SetDsrmPassword(b
, torture
, &ctx
->handle
);
8110 ret
&= test_Shutdown(b
, torture
, &ctx
->handle
);
8112 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8118 bool torture_rpc_samr_users(struct torture_context
*torture
)
8121 struct dcerpc_pipe
*p
;
8123 struct torture_samr_context
*ctx
;
8124 struct dcerpc_binding_handle
*b
;
8126 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8127 if (!NT_STATUS_IS_OK(status
)) {
8130 b
= p
->binding_handle
;
8132 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8134 ctx
->choice
= TORTURE_SAMR_USER_ATTRIBUTES
;
8136 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8138 if (!torture_setting_bool(torture
, "samba3", false)) {
8139 ret
&= test_QuerySecurity(b
, torture
, &ctx
->handle
);
8142 ret
&= test_EnumDomains(p
, torture
, ctx
);
8144 ret
&= test_SetDsrmPassword(b
, torture
, &ctx
->handle
);
8146 ret
&= test_Shutdown(b
, torture
, &ctx
->handle
);
8148 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8154 bool torture_rpc_samr_passwords(struct torture_context
*torture
)
8157 struct dcerpc_pipe
*p
;
8159 struct torture_samr_context
*ctx
;
8160 struct dcerpc_binding_handle
*b
;
8162 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8163 if (!NT_STATUS_IS_OK(status
)) {
8166 b
= p
->binding_handle
;
8168 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8170 ctx
->choice
= TORTURE_SAMR_PASSWORDS
;
8172 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8174 ret
&= test_EnumDomains(p
, torture
, ctx
);
8176 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8178 ret
&= test_samr_ValidatePassword(p
, torture
);
8183 static bool torture_rpc_samr_pwdlastset(struct torture_context
*torture
,
8184 struct dcerpc_pipe
*p2
,
8185 struct cli_credentials
*machine_credentials
)
8188 struct dcerpc_pipe
*p
;
8190 struct torture_samr_context
*ctx
;
8191 struct dcerpc_binding_handle
*b
;
8193 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8194 if (!NT_STATUS_IS_OK(status
)) {
8197 b
= p
->binding_handle
;
8199 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8201 ctx
->choice
= TORTURE_SAMR_PASSWORDS_PWDLASTSET
;
8202 ctx
->machine_credentials
= machine_credentials
;
8204 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8206 ret
&= test_EnumDomains(p
, torture
, ctx
);
8208 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8213 struct torture_suite
*torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX
*mem_ctx
)
8215 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.passwords.pwdlastset");
8216 struct torture_rpc_tcase
*tcase
;
8218 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
8220 TEST_ACCOUNT_NAME_PWD
);
8222 torture_rpc_tcase_add_test_creds(tcase
, "pwdLastSet",
8223 torture_rpc_samr_pwdlastset
);
8228 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context
*torture
,
8229 struct dcerpc_pipe
*p2
,
8230 struct cli_credentials
*machine_credentials
)
8233 struct dcerpc_pipe
*p
;
8235 struct torture_samr_context
*ctx
;
8236 struct dcerpc_binding_handle
*b
;
8238 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8239 if (!NT_STATUS_IS_OK(status
)) {
8242 b
= p
->binding_handle
;
8244 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8246 ctx
->choice
= TORTURE_SAMR_USER_PRIVILEGES
;
8247 ctx
->machine_credentials
= machine_credentials
;
8249 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8251 ret
&= test_EnumDomains(p
, torture
, ctx
);
8253 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8258 struct torture_suite
*torture_rpc_samr_user_privileges(TALLOC_CTX
*mem_ctx
)
8260 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.users.privileges");
8261 struct torture_rpc_tcase
*tcase
;
8263 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
8265 TEST_ACCOUNT_NAME_PWD
);
8267 torture_rpc_tcase_add_test_creds(tcase
, "delete_privileged_user",
8268 torture_rpc_samr_users_privileges_delete_user
);
8273 static bool torture_rpc_samr_many_accounts(struct torture_context
*torture
,
8274 struct dcerpc_pipe
*p2
,
8278 struct dcerpc_pipe
*p
;
8280 struct torture_samr_context
*ctx
=
8281 talloc_get_type_abort(data
, struct torture_samr_context
);
8282 struct dcerpc_binding_handle
*b
;
8284 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8285 if (!NT_STATUS_IS_OK(status
)) {
8288 b
= p
->binding_handle
;
8290 ctx
->choice
= TORTURE_SAMR_MANY_ACCOUNTS
;
8291 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
8292 ctx
->num_objects_large_dc
);
8294 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8296 ret
&= test_EnumDomains(p
, torture
, ctx
);
8298 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8303 static bool torture_rpc_samr_many_groups(struct torture_context
*torture
,
8304 struct dcerpc_pipe
*p2
,
8308 struct dcerpc_pipe
*p
;
8310 struct torture_samr_context
*ctx
=
8311 talloc_get_type_abort(data
, struct torture_samr_context
);
8312 struct dcerpc_binding_handle
*b
;
8314 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8315 if (!NT_STATUS_IS_OK(status
)) {
8318 b
= p
->binding_handle
;
8320 ctx
->choice
= TORTURE_SAMR_MANY_GROUPS
;
8321 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
8322 ctx
->num_objects_large_dc
);
8324 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8326 ret
&= test_EnumDomains(p
, torture
, ctx
);
8328 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8333 static bool torture_rpc_samr_many_aliases(struct torture_context
*torture
,
8334 struct dcerpc_pipe
*p2
,
8338 struct dcerpc_pipe
*p
;
8340 struct torture_samr_context
*ctx
=
8341 talloc_get_type_abort(data
, struct torture_samr_context
);
8342 struct dcerpc_binding_handle
*b
;
8344 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8345 if (!NT_STATUS_IS_OK(status
)) {
8348 b
= p
->binding_handle
;
8350 ctx
->choice
= TORTURE_SAMR_MANY_ALIASES
;
8351 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
8352 ctx
->num_objects_large_dc
);
8354 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8356 ret
&= test_EnumDomains(p
, torture
, ctx
);
8358 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8363 struct torture_suite
*torture_rpc_samr_large_dc(TALLOC_CTX
*mem_ctx
)
8365 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.large-dc");
8366 struct torture_rpc_tcase
*tcase
;
8367 struct torture_samr_context
*ctx
;
8369 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "samr", &ndr_table_samr
);
8371 ctx
= talloc_zero(suite
, struct torture_samr_context
);
8372 ctx
->num_objects_large_dc
= 150;
8374 torture_rpc_tcase_add_test_ex(tcase
, "many_aliases",
8375 torture_rpc_samr_many_aliases
, ctx
);
8376 torture_rpc_tcase_add_test_ex(tcase
, "many_groups",
8377 torture_rpc_samr_many_groups
, ctx
);
8378 torture_rpc_tcase_add_test_ex(tcase
, "many_accounts",
8379 torture_rpc_samr_many_accounts
, ctx
);
8384 static bool torture_rpc_samr_badpwdcount(struct torture_context
*torture
,
8385 struct dcerpc_pipe
*p2
,
8386 struct cli_credentials
*machine_credentials
)
8389 struct dcerpc_pipe
*p
;
8391 struct torture_samr_context
*ctx
;
8392 struct dcerpc_binding_handle
*b
;
8394 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8395 if (!NT_STATUS_IS_OK(status
)) {
8398 b
= p
->binding_handle
;
8400 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8402 ctx
->choice
= TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
;
8403 ctx
->machine_credentials
= machine_credentials
;
8405 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8407 ret
&= test_EnumDomains(p
, torture
, ctx
);
8409 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8414 struct torture_suite
*torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX
*mem_ctx
)
8416 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.passwords.badpwdcount");
8417 struct torture_rpc_tcase
*tcase
;
8419 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
8421 TEST_ACCOUNT_NAME_PWD
);
8423 torture_rpc_tcase_add_test_creds(tcase
, "badPwdCount",
8424 torture_rpc_samr_badpwdcount
);
8429 static bool torture_rpc_samr_lockout(struct torture_context
*torture
,
8430 struct dcerpc_pipe
*p2
,
8431 struct cli_credentials
*machine_credentials
)
8434 struct dcerpc_pipe
*p
;
8436 struct torture_samr_context
*ctx
;
8437 struct dcerpc_binding_handle
*b
;
8439 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8440 if (!NT_STATUS_IS_OK(status
)) {
8443 b
= p
->binding_handle
;
8445 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8447 ctx
->choice
= TORTURE_SAMR_PASSWORDS_LOCKOUT
;
8448 ctx
->machine_credentials
= machine_credentials
;
8450 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8452 ret
&= test_EnumDomains(p
, torture
, ctx
);
8454 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8459 struct torture_suite
*torture_rpc_samr_passwords_lockout(TALLOC_CTX
*mem_ctx
)
8461 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.passwords.lockout");
8462 struct torture_rpc_tcase
*tcase
;
8464 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
8466 TEST_ACCOUNT_NAME_PWD
);
8468 torture_rpc_tcase_add_test_creds(tcase
, "lockout",
8469 torture_rpc_samr_lockout
);