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
;
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);
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);
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 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1763 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_WRONG_PASSWORD
,
1764 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1767 /* Unbreak the LM hash */
1770 r
.in
.user_handle
= &user_handle
;
1771 r
.in
.lm_present
= 1;
1772 r
.in
.old_lm_crypted
= &hash1
;
1773 r
.in
.new_lm_crypted
= &hash2
;
1774 /* Break the NT hash */
1776 r
.in
.nt_present
= 1;
1777 r
.in
.old_nt_crypted
= &hash3
;
1778 r
.in
.new_nt_crypted
= &hash4
;
1779 r
.in
.cross1_present
= 1;
1780 r
.in
.nt_cross
= &hash5
;
1781 r
.in
.cross2_present
= 1;
1782 r
.in
.lm_cross
= &hash6
;
1784 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1785 "ChangePasswordUser failed");
1786 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1787 __location__
, __FUNCTION__
,
1788 oldpass
, newpass
, nt_errstr(r
.out
.result
));
1789 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1790 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_WRONG_PASSWORD
,
1791 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1794 /* Unbreak the NT hash */
1797 r
.in
.user_handle
= &user_handle
;
1798 r
.in
.lm_present
= 1;
1799 r
.in
.old_lm_crypted
= &hash1
;
1800 r
.in
.new_lm_crypted
= &hash2
;
1801 r
.in
.nt_present
= 1;
1802 r
.in
.old_nt_crypted
= &hash3
;
1803 r
.in
.new_nt_crypted
= &hash4
;
1804 r
.in
.cross1_present
= 1;
1805 r
.in
.nt_cross
= &hash5
;
1806 r
.in
.cross2_present
= 1;
1807 /* Break the LM cross */
1809 r
.in
.lm_cross
= &hash6
;
1811 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1812 "ChangePasswordUser failed");
1813 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1814 __location__
, __FUNCTION__
,
1815 oldpass
, newpass
, nt_errstr(r
.out
.result
));
1816 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
) &&
1817 !NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
))
1819 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD or NT_STATUS_PASSWORD_RESTRICTION because we broke the LM cross-hash, got %s\n", nt_errstr(r
.out
.result
));
1823 /* Unbreak the LM cross */
1826 r
.in
.user_handle
= &user_handle
;
1827 r
.in
.lm_present
= 1;
1828 r
.in
.old_lm_crypted
= &hash1
;
1829 r
.in
.new_lm_crypted
= &hash2
;
1830 r
.in
.nt_present
= 1;
1831 r
.in
.old_nt_crypted
= &hash3
;
1832 r
.in
.new_nt_crypted
= &hash4
;
1833 r
.in
.cross1_present
= 1;
1834 /* Break the NT cross */
1836 r
.in
.nt_cross
= &hash5
;
1837 r
.in
.cross2_present
= 1;
1838 r
.in
.lm_cross
= &hash6
;
1840 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1841 "ChangePasswordUser failed");
1842 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1843 __location__
, __FUNCTION__
,
1844 oldpass
, newpass
, nt_errstr(r
.out
.result
));
1845 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
) &&
1846 !NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
))
1848 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD or NT_STATUS_PASSWORD_RESTRICTION because we broke the NT cross-hash, got %s\n", nt_errstr(r
.out
.result
));
1852 /* Unbreak the NT cross */
1856 /* Reset the hashes to not broken values */
1857 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1858 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1859 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1860 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1861 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1862 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1864 r
.in
.user_handle
= &user_handle
;
1865 r
.in
.lm_present
= 1;
1866 r
.in
.old_lm_crypted
= &hash1
;
1867 r
.in
.new_lm_crypted
= &hash2
;
1868 r
.in
.nt_present
= 1;
1869 r
.in
.old_nt_crypted
= &hash3
;
1870 r
.in
.new_nt_crypted
= &hash4
;
1871 r
.in
.cross1_present
= 1;
1872 r
.in
.nt_cross
= &hash5
;
1873 r
.in
.cross2_present
= 0;
1874 r
.in
.lm_cross
= NULL
;
1876 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1877 "ChangePasswordUser failed");
1878 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1879 __location__
, __FUNCTION__
,
1880 oldpass
, newpass
, nt_errstr(r
.out
.result
));
1881 if (NT_STATUS_IS_OK(r
.out
.result
)) {
1883 *password
= newpass
;
1884 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION
, r
.out
.result
)) {
1885 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r
.out
.result
));
1890 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1892 E_md4hash(oldpass
, old_nt_hash
);
1893 E_md4hash(newpass
, new_nt_hash
);
1894 E_deshash(oldpass
, old_lm_hash
);
1895 E_deshash(newpass
, new_lm_hash
);
1898 /* Reset the hashes to not broken values */
1899 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1900 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1901 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1902 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1903 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1904 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1906 r
.in
.user_handle
= &user_handle
;
1907 r
.in
.lm_present
= 1;
1908 r
.in
.old_lm_crypted
= &hash1
;
1909 r
.in
.new_lm_crypted
= &hash2
;
1910 r
.in
.nt_present
= 1;
1911 r
.in
.old_nt_crypted
= &hash3
;
1912 r
.in
.new_nt_crypted
= &hash4
;
1913 r
.in
.cross1_present
= 0;
1914 r
.in
.nt_cross
= NULL
;
1915 r
.in
.cross2_present
= 1;
1916 r
.in
.lm_cross
= &hash6
;
1918 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1919 "ChangePasswordUser failed");
1920 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1921 __location__
, __FUNCTION__
,
1922 oldpass
, newpass
, nt_errstr(r
.out
.result
));
1923 if (NT_STATUS_IS_OK(r
.out
.result
)) {
1925 *password
= newpass
;
1926 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION
, r
.out
.result
)) {
1927 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r
.out
.result
));
1932 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1934 E_md4hash(oldpass
, old_nt_hash
);
1935 E_md4hash(newpass
, new_nt_hash
);
1936 E_deshash(oldpass
, old_lm_hash
);
1937 E_deshash(newpass
, new_lm_hash
);
1940 /* Reset the hashes to not broken values */
1941 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1942 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1943 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1944 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1945 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1946 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1948 r
.in
.user_handle
= &user_handle
;
1949 r
.in
.lm_present
= 1;
1950 r
.in
.old_lm_crypted
= &hash1
;
1951 r
.in
.new_lm_crypted
= &hash2
;
1952 r
.in
.nt_present
= 1;
1953 r
.in
.old_nt_crypted
= &hash3
;
1954 r
.in
.new_nt_crypted
= &hash4
;
1955 r
.in
.cross1_present
= 1;
1956 r
.in
.nt_cross
= &hash5
;
1957 r
.in
.cross2_present
= 1;
1958 r
.in
.lm_cross
= &hash6
;
1960 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1961 "ChangePasswordUser failed");
1962 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1963 __location__
, __FUNCTION__
,
1964 oldpass
, newpass
, nt_errstr(r
.out
.result
));
1965 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1966 torture_comment(tctx
, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r
.out
.result
));
1967 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1968 torture_warning(tctx
, "ChangePasswordUser failed - %s\n", nt_errstr(r
.out
.result
));
1972 *password
= newpass
;
1975 r
.in
.user_handle
= &user_handle
;
1976 r
.in
.lm_present
= 1;
1977 r
.in
.old_lm_crypted
= &hash1
;
1978 r
.in
.new_lm_crypted
= &hash2
;
1979 r
.in
.nt_present
= 1;
1980 r
.in
.old_nt_crypted
= &hash3
;
1981 r
.in
.new_nt_crypted
= &hash4
;
1982 r
.in
.cross1_present
= 1;
1983 r
.in
.nt_cross
= &hash5
;
1984 r
.in
.cross2_present
= 1;
1985 r
.in
.lm_cross
= &hash6
;
1988 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1989 "ChangePasswordUser failed");
1990 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
1991 __location__
, __FUNCTION__
,
1992 oldpass
, newpass
, nt_errstr(r
.out
.result
));
1993 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1994 torture_comment(tctx
, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r
.out
.result
));
1995 } else if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
1996 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(r
.out
.result
));
2002 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
2010 static bool test_OemChangePasswordUser2(struct dcerpc_pipe
*p
,
2011 struct torture_context
*tctx
,
2012 const char *acct_name
,
2013 struct policy_handle
*handle
, char **password
)
2015 struct samr_OemChangePasswordUser2 r
;
2017 struct samr_Password lm_verifier
;
2018 struct samr_CryptPassword lm_pass
;
2019 struct lsa_AsciiString server
, account
, account_bad
;
2022 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2023 uint8_t old_lm_hash
[16], new_lm_hash
[16];
2025 struct samr_GetDomPwInfo dom_pw_info
;
2026 struct samr_PwInfo info
;
2027 int policy_min_pw_len
= 0;
2029 struct lsa_String domain_name
;
2031 domain_name
.string
= "";
2032 dom_pw_info
.in
.domain_name
= &domain_name
;
2033 dom_pw_info
.out
.info
= &info
;
2035 torture_comment(tctx
, "Testing OemChangePasswordUser2\n");
2037 torture_assert(tctx
, *password
!= NULL
,
2038 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
2040 oldpass
= *password
;
2042 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &dom_pw_info
),
2043 "GetDomPwInfo failed");
2044 if (NT_STATUS_IS_OK(dom_pw_info
.out
.result
)) {
2045 policy_min_pw_len
= dom_pw_info
.out
.info
->min_password_length
;
2048 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2050 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2051 account
.string
= acct_name
;
2053 E_deshash(oldpass
, old_lm_hash
);
2054 E_deshash(newpass
, new_lm_hash
);
2056 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
2057 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2058 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
2060 r
.in
.server
= &server
;
2061 r
.in
.account
= &account
;
2062 r
.in
.password
= &lm_pass
;
2063 r
.in
.hash
= &lm_verifier
;
2065 /* Break the verification */
2066 lm_verifier
.hash
[0]++;
2068 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2069 "OemChangePasswordUser2 failed");
2070 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2071 __location__
, __FUNCTION__
,
2072 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2074 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)
2075 && !NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
2076 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2077 nt_errstr(r
.out
.result
));
2081 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
2082 /* Break the old password */
2084 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2085 /* unbreak it for the next operation */
2087 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
2089 r
.in
.server
= &server
;
2090 r
.in
.account
= &account
;
2091 r
.in
.password
= &lm_pass
;
2092 r
.in
.hash
= &lm_verifier
;
2094 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2095 "OemChangePasswordUser2 failed");
2096 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2097 __location__
, __FUNCTION__
,
2098 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2100 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)
2101 && !NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
2102 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2103 nt_errstr(r
.out
.result
));
2107 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
2108 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2110 r
.in
.server
= &server
;
2111 r
.in
.account
= &account
;
2112 r
.in
.password
= &lm_pass
;
2115 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2116 "OemChangePasswordUser2 failed");
2117 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2118 __location__
, __FUNCTION__
,
2119 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2121 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)
2122 && !NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
2123 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
2124 nt_errstr(r
.out
.result
));
2128 /* This shouldn't be a valid name */
2129 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
2130 r
.in
.account
= &account_bad
;
2132 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2133 "OemChangePasswordUser2 failed");
2134 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2135 __location__
, __FUNCTION__
,
2136 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2138 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
2139 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
2140 nt_errstr(r
.out
.result
));
2144 /* This shouldn't be a valid name */
2145 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
2146 r
.in
.account
= &account_bad
;
2147 r
.in
.password
= &lm_pass
;
2148 r
.in
.hash
= &lm_verifier
;
2150 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2151 "OemChangePasswordUser2 failed");
2152 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2153 __location__
, __FUNCTION__
,
2154 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2156 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
2157 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2158 nt_errstr(r
.out
.result
));
2162 /* This shouldn't be a valid name */
2163 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
2164 r
.in
.account
= &account_bad
;
2165 r
.in
.password
= NULL
;
2166 r
.in
.hash
= &lm_verifier
;
2168 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2169 "OemChangePasswordUser2 failed");
2170 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2171 __location__
, __FUNCTION__
,
2172 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2174 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
2175 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2176 nt_errstr(r
.out
.result
));
2180 E_deshash(oldpass
, old_lm_hash
);
2181 E_deshash(newpass
, new_lm_hash
);
2183 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
2184 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2185 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
2187 r
.in
.server
= &server
;
2188 r
.in
.account
= &account
;
2189 r
.in
.password
= &lm_pass
;
2190 r
.in
.hash
= &lm_verifier
;
2192 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2193 "OemChangePasswordUser2 failed");
2194 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2195 __location__
, __FUNCTION__
,
2196 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2198 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2199 torture_comment(tctx
, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r
.out
.result
));
2200 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2201 torture_warning(tctx
, "OemChangePasswordUser2 failed - %s\n", nt_errstr(r
.out
.result
));
2204 *password
= newpass
;
2211 static bool test_ChangePasswordUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2212 const char *acct_name
,
2214 char *newpass
, bool allow_password_restriction
)
2216 struct samr_ChangePasswordUser2 r
;
2218 struct lsa_String server
, account
;
2219 struct samr_CryptPassword nt_pass
, lm_pass
;
2220 struct samr_Password nt_verifier
, lm_verifier
;
2222 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2223 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2224 uint8_t old_lm_hash
[16], new_lm_hash
[16];
2226 struct samr_GetDomPwInfo dom_pw_info
;
2227 struct samr_PwInfo info
;
2229 struct lsa_String domain_name
;
2231 domain_name
.string
= "";
2232 dom_pw_info
.in
.domain_name
= &domain_name
;
2233 dom_pw_info
.out
.info
= &info
;
2235 torture_comment(tctx
, "Testing ChangePasswordUser2 on %s\n", acct_name
);
2237 torture_assert(tctx
, *password
!= NULL
,
2238 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2239 oldpass
= *password
;
2242 int policy_min_pw_len
= 0;
2243 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &dom_pw_info
),
2244 "GetDomPwInfo failed");
2245 if (NT_STATUS_IS_OK(dom_pw_info
.out
.result
)) {
2246 policy_min_pw_len
= dom_pw_info
.out
.info
->min_password_length
;
2249 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2252 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2253 init_lsa_String(&account
, acct_name
);
2255 E_md4hash(oldpass
, old_nt_hash
);
2256 E_md4hash(newpass
, new_nt_hash
);
2258 E_deshash(oldpass
, old_lm_hash
);
2259 E_deshash(newpass
, new_lm_hash
);
2261 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
|STR_TERMINATE
);
2262 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2263 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2265 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2266 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2267 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2269 r
.in
.server
= &server
;
2270 r
.in
.account
= &account
;
2271 r
.in
.nt_password
= &nt_pass
;
2272 r
.in
.nt_verifier
= &nt_verifier
;
2274 r
.in
.lm_password
= &lm_pass
;
2275 r
.in
.lm_verifier
= &lm_verifier
;
2277 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser2_r(b
, tctx
, &r
),
2278 "ChangePasswordUser2 failed");
2279 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2280 __location__
, __FUNCTION__
,
2281 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2283 if (allow_password_restriction
&& NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2284 torture_comment(tctx
, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r
.out
.result
));
2285 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2286 torture_warning(tctx
, "ChangePasswordUser2 failed - %s\n", nt_errstr(r
.out
.result
));
2289 *password
= newpass
;
2296 bool test_ChangePasswordUser3(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2297 const char *account_string
,
2298 int policy_min_pw_len
,
2300 const char *newpass
,
2301 NTTIME last_password_change
,
2302 bool handle_reject_reason
)
2304 struct samr_ChangePasswordUser3 r
;
2306 struct lsa_String server
, account
, account_bad
;
2307 struct samr_CryptPassword nt_pass
, lm_pass
;
2308 struct samr_Password nt_verifier
, lm_verifier
;
2310 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2311 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2312 uint8_t old_lm_hash
[16], new_lm_hash
[16];
2314 struct samr_DomInfo1
*dominfo
= NULL
;
2315 struct userPwdChangeFailureInformation
*reject
= NULL
;
2317 torture_comment(tctx
, "Testing ChangePasswordUser3\n");
2319 if (newpass
== NULL
) {
2321 if (policy_min_pw_len
== 0) {
2322 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2324 newpass
= samr_rand_pass_fixed_len(tctx
, policy_min_pw_len
);
2326 } while (check_password_quality(newpass
) == false);
2328 torture_comment(tctx
, "Using password '%s'\n", newpass
);
2331 torture_assert(tctx
, *password
!= NULL
,
2332 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2334 oldpass
= *password
;
2335 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2336 init_lsa_String(&account
, account_string
);
2338 E_md4hash(oldpass
, old_nt_hash
);
2339 E_md4hash(newpass
, new_nt_hash
);
2341 E_deshash(oldpass
, old_lm_hash
);
2342 E_deshash(newpass
, new_lm_hash
);
2344 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2345 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2346 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2348 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2349 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2350 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2352 /* Break the verification */
2353 nt_verifier
.hash
[0]++;
2355 r
.in
.server
= &server
;
2356 r
.in
.account
= &account
;
2357 r
.in
.nt_password
= &nt_pass
;
2358 r
.in
.nt_verifier
= &nt_verifier
;
2360 r
.in
.lm_password
= &lm_pass
;
2361 r
.in
.lm_verifier
= &lm_verifier
;
2362 r
.in
.password3
= NULL
;
2363 r
.out
.dominfo
= &dominfo
;
2364 r
.out
.reject
= &reject
;
2366 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2367 "ChangePasswordUser3 failed");
2368 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2369 __location__
, __FUNCTION__
,
2370 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2371 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
) &&
2372 (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
))) {
2373 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2374 nt_errstr(r
.out
.result
));
2378 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2379 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2380 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2382 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2383 /* Break the NT hash */
2385 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2386 /* Unbreak it again */
2388 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2390 r
.in
.server
= &server
;
2391 r
.in
.account
= &account
;
2392 r
.in
.nt_password
= &nt_pass
;
2393 r
.in
.nt_verifier
= &nt_verifier
;
2395 r
.in
.lm_password
= &lm_pass
;
2396 r
.in
.lm_verifier
= &lm_verifier
;
2397 r
.in
.password3
= NULL
;
2398 r
.out
.dominfo
= &dominfo
;
2399 r
.out
.reject
= &reject
;
2401 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2402 "ChangePasswordUser3 failed");
2403 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2404 __location__
, __FUNCTION__
,
2405 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2406 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
) &&
2407 (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
))) {
2408 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2409 nt_errstr(r
.out
.result
));
2413 /* This shouldn't be a valid name */
2414 init_lsa_String(&account_bad
, talloc_asprintf(tctx
, "%sXX", account_string
));
2416 r
.in
.account
= &account_bad
;
2417 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2418 "ChangePasswordUser3 failed");
2419 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2420 __location__
, __FUNCTION__
,
2421 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2422 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
2423 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2424 nt_errstr(r
.out
.result
));
2428 E_md4hash(oldpass
, old_nt_hash
);
2429 E_md4hash(newpass
, new_nt_hash
);
2431 E_deshash(oldpass
, old_lm_hash
);
2432 E_deshash(newpass
, new_lm_hash
);
2434 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2435 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2436 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2438 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2439 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2440 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2442 r
.in
.server
= &server
;
2443 r
.in
.account
= &account
;
2444 r
.in
.nt_password
= &nt_pass
;
2445 r
.in
.nt_verifier
= &nt_verifier
;
2447 r
.in
.lm_password
= &lm_pass
;
2448 r
.in
.lm_verifier
= &lm_verifier
;
2449 r
.in
.password3
= NULL
;
2450 r
.out
.dominfo
= &dominfo
;
2451 r
.out
.reject
= &reject
;
2453 unix_to_nt_time(&t
, time(NULL
));
2455 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2456 "ChangePasswordUser3 failed");
2457 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2458 __location__
, __FUNCTION__
,
2459 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2461 torture_comment(tctx
, "(%s): dominfo[%s], reject[%s], handle_reject_reason[%s], "
2462 "last_password_change[%s], dominfo->min_password_age[%lld]\n",
2464 (dominfo
== NULL
)? "NULL" : "present",
2465 reject
? "true" : "false",
2466 handle_reject_reason
? "true" : "false",
2467 null_nttime(last_password_change
) ? "null" : "not null",
2468 dominfo
? (long long)dominfo
->min_password_age
: (long long)0);
2470 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)
2473 && handle_reject_reason
2474 && (!null_nttime(last_password_change
) || !dominfo
->min_password_age
)) {
2475 if (dominfo
->password_properties
& DOMAIN_REFUSE_PASSWORD_CHANGE
) {
2477 if (reject
&& (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
)) {
2478 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2479 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2484 /* We tested the order of precendence which is as follows:
2493 if ((dominfo
->min_password_age
< 0) && !null_nttime(last_password_change
) &&
2494 (last_password_change
- dominfo
->min_password_age
> t
)) {
2496 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2497 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2498 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2502 } else if ((dominfo
->min_password_length
> 0) &&
2503 (strlen(newpass
) < dominfo
->min_password_length
)) {
2505 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
) {
2506 torture_warning(tctx
, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2507 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
, reject
->extendedFailureReason
);
2511 } else if ((dominfo
->password_history_length
> 0) &&
2512 strequal(oldpass
, newpass
)) {
2514 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_PWD_IN_HISTORY
) {
2515 torture_warning(tctx
, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2516 SAM_PWD_CHANGE_PWD_IN_HISTORY
, reject
->extendedFailureReason
);
2519 } else if (dominfo
->password_properties
& DOMAIN_PASSWORD_COMPLEX
) {
2521 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NOT_COMPLEX
) {
2522 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2523 SAM_PWD_CHANGE_NOT_COMPLEX
, reject
->extendedFailureReason
);
2529 if (reject
->extendedFailureReason
== SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
) {
2530 /* retry with adjusted size */
2531 return test_ChangePasswordUser3(p
, tctx
, account_string
,
2532 dominfo
->min_password_length
,
2533 password
, NULL
, 0, false);
2537 } else if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2538 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2539 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2540 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2543 /* Perhaps the server has a 'min password age' set? */
2546 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ChangePasswordUser3");
2548 *password
= talloc_strdup(tctx
, newpass
);
2554 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2555 const char *account_string
,
2556 struct policy_handle
*handle
,
2560 struct samr_ChangePasswordUser3 r
;
2561 struct samr_SetUserInfo s
;
2562 union samr_UserInfo u
;
2563 DATA_BLOB session_key
;
2564 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
2565 uint8_t confounder
[16];
2569 struct lsa_String server
, account
;
2570 struct samr_CryptPassword nt_pass
;
2571 struct samr_Password nt_verifier
;
2572 DATA_BLOB new_random_pass
;
2575 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2576 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2578 struct samr_DomInfo1
*dominfo
= NULL
;
2579 struct userPwdChangeFailureInformation
*reject
= NULL
;
2581 new_random_pass
= samr_very_rand_pass(tctx
, 128);
2583 torture_assert(tctx
, *password
!= NULL
,
2584 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2586 oldpass
= *password
;
2587 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2588 init_lsa_String(&account
, account_string
);
2590 s
.in
.user_handle
= handle
;
2596 u
.info25
.info
.fields_present
= SAMR_FIELD_NT_PASSWORD_PRESENT
;
2598 set_pw_in_buffer(u
.info25
.password
.data
, &new_random_pass
);
2600 status
= dcerpc_fetch_session_key(p
, &session_key
);
2601 if (!NT_STATUS_IS_OK(status
)) {
2602 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
2603 s
.in
.level
, nt_errstr(status
));
2607 generate_random_buffer((uint8_t *)confounder
, 16);
2610 MD5Update(&ctx
, confounder
, 16);
2611 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
2612 MD5Final(confounded_session_key
.data
, &ctx
);
2614 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
2615 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
2617 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2619 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
2620 "SetUserInfo failed");
2621 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2622 __location__
, __FUNCTION__
,
2623 oldpass
, "RANDOM", nt_errstr(s
.out
.result
));
2624 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
2625 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
2626 s
.in
.level
, nt_errstr(s
.out
.result
));
2630 torture_comment(tctx
, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2632 mdfour(old_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2634 new_random_pass
= samr_very_rand_pass(tctx
, 128);
2636 mdfour(new_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2638 set_pw_in_buffer(nt_pass
.data
, &new_random_pass
);
2639 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2640 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2642 r
.in
.server
= &server
;
2643 r
.in
.account
= &account
;
2644 r
.in
.nt_password
= &nt_pass
;
2645 r
.in
.nt_verifier
= &nt_verifier
;
2647 r
.in
.lm_password
= NULL
;
2648 r
.in
.lm_verifier
= NULL
;
2649 r
.in
.password3
= NULL
;
2650 r
.out
.dominfo
= &dominfo
;
2651 r
.out
.reject
= &reject
;
2653 unix_to_nt_time(&t
, time(NULL
));
2655 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2656 "ChangePasswordUser3 failed");
2657 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2658 __location__
, __FUNCTION__
,
2659 oldpass
, "RANDOM", nt_errstr(r
.out
.result
));
2661 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2662 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2663 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2664 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2667 /* Perhaps the server has a 'min password age' set? */
2669 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2670 torture_warning(tctx
, "ChangePasswordUser3 failed - %s\n", nt_errstr(r
.out
.result
));
2674 newpass
= samr_rand_pass(tctx
, 128);
2676 mdfour(old_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2678 E_md4hash(newpass
, new_nt_hash
);
2680 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2681 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2682 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2684 r
.in
.server
= &server
;
2685 r
.in
.account
= &account
;
2686 r
.in
.nt_password
= &nt_pass
;
2687 r
.in
.nt_verifier
= &nt_verifier
;
2689 r
.in
.lm_password
= NULL
;
2690 r
.in
.lm_verifier
= NULL
;
2691 r
.in
.password3
= NULL
;
2692 r
.out
.dominfo
= &dominfo
;
2693 r
.out
.reject
= &reject
;
2695 unix_to_nt_time(&t
, time(NULL
));
2697 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2698 "ChangePasswordUser3 failed");
2699 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2700 __location__
, __FUNCTION__
,
2701 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2703 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2704 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2705 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2706 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2709 /* Perhaps the server has a 'min password age' set? */
2712 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ChangePasswordUser3 (on second random password)");
2713 *password
= talloc_strdup(tctx
, newpass
);
2720 static bool test_GetMembersInAlias(struct dcerpc_binding_handle
*b
,
2721 struct torture_context
*tctx
,
2722 struct policy_handle
*alias_handle
)
2724 struct samr_GetMembersInAlias r
;
2725 struct lsa_SidArray sids
;
2727 torture_comment(tctx
, "Testing GetMembersInAlias\n");
2729 r
.in
.alias_handle
= alias_handle
;
2732 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetMembersInAlias_r(b
, tctx
, &r
),
2733 "GetMembersInAlias failed");
2734 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetMembersInAlias failed");
2739 static bool test_AddMemberToAlias(struct dcerpc_binding_handle
*b
,
2740 struct torture_context
*tctx
,
2741 struct policy_handle
*alias_handle
,
2742 const struct dom_sid
*domain_sid
)
2744 struct samr_AddAliasMember r
;
2745 struct samr_DeleteAliasMember d
;
2746 struct dom_sid
*sid
;
2748 sid
= dom_sid_add_rid(tctx
, domain_sid
, 512);
2750 torture_comment(tctx
, "Testing AddAliasMember\n");
2751 r
.in
.alias_handle
= alias_handle
;
2754 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddAliasMember_r(b
, tctx
, &r
),
2755 "AddAliasMember failed");
2756 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "AddAliasMember failed");
2758 d
.in
.alias_handle
= alias_handle
;
2761 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteAliasMember_r(b
, tctx
, &d
),
2762 "DeleteAliasMember failed");
2763 torture_assert_ntstatus_ok(tctx
, d
.out
.result
, "DelAliasMember failed");
2768 static bool test_AddMultipleMembersToAlias(struct dcerpc_binding_handle
*b
,
2769 struct torture_context
*tctx
,
2770 struct policy_handle
*alias_handle
)
2772 struct samr_AddMultipleMembersToAlias a
;
2773 struct samr_RemoveMultipleMembersFromAlias r
;
2774 struct lsa_SidArray sids
;
2776 torture_comment(tctx
, "Testing AddMultipleMembersToAlias\n");
2777 a
.in
.alias_handle
= alias_handle
;
2781 sids
.sids
= talloc_array(tctx
, struct lsa_SidPtr
, 3);
2783 sids
.sids
[0].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-1");
2784 sids
.sids
[1].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-2");
2785 sids
.sids
[2].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-3");
2787 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddMultipleMembersToAlias_r(b
, tctx
, &a
),
2788 "AddMultipleMembersToAlias failed");
2789 torture_assert_ntstatus_ok(tctx
, a
.out
.result
, "AddMultipleMembersToAlias");
2792 torture_comment(tctx
, "Testing RemoveMultipleMembersFromAlias\n");
2793 r
.in
.alias_handle
= alias_handle
;
2796 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b
, tctx
, &r
),
2797 "RemoveMultipleMembersFromAlias failed");
2798 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "RemoveMultipleMembersFromAlias failed");
2800 /* strange! removing twice doesn't give any error */
2801 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b
, tctx
, &r
),
2802 "RemoveMultipleMembersFromAlias failed");
2803 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "RemoveMultipleMembersFromAlias failed");
2805 /* but removing an alias that isn't there does */
2806 sids
.sids
[2].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-4");
2808 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b
, tctx
, &r
),
2809 "RemoveMultipleMembersFromAlias failed");
2810 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
, "RemoveMultipleMembersFromAlias");
2815 static bool test_GetAliasMembership(struct dcerpc_binding_handle
*b
,
2816 struct torture_context
*tctx
,
2817 struct policy_handle
*domain_handle
)
2819 struct samr_GetAliasMembership r
;
2820 struct lsa_SidArray sids
;
2821 struct samr_Ids rids
;
2823 torture_comment(tctx
, "Testing GetAliasMembership\n");
2825 r
.in
.domain_handle
= domain_handle
;
2830 sids
.sids
= talloc_zero_array(tctx
, struct lsa_SidPtr
, sids
.num_sids
);
2832 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetAliasMembership_r(b
, tctx
, &r
),
2833 "GetAliasMembership failed");
2834 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
2835 "samr_GetAliasMembership failed");
2837 torture_assert_int_equal(tctx
, sids
.num_sids
, rids
.count
,
2838 "protocol misbehaviour");
2841 sids
.sids
= talloc_zero_array(tctx
, struct lsa_SidPtr
, sids
.num_sids
);
2842 sids
.sids
[0].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-1");
2844 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetAliasMembership_r(b
, tctx
, &r
),
2845 "samr_GetAliasMembership failed");
2846 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
2847 "samr_GetAliasMembership failed");
2850 /* only true for w2k8 it seems
2851 * win7, xp, w2k3 will return a 0 length array pointer */
2853 if (rids
.ids
&& (rids
.count
== 0)) {
2854 torture_fail(tctx
, "samr_GetAliasMembership returned 0 count and a rids array");
2857 if (!rids
.ids
&& rids
.count
) {
2858 torture_fail(tctx
, "samr_GetAliasMembership returned non-0 count but no rids");
2864 static bool test_TestPrivateFunctionsUser(struct dcerpc_binding_handle
*b
,
2865 struct torture_context
*tctx
,
2866 struct policy_handle
*user_handle
)
2868 struct samr_TestPrivateFunctionsUser r
;
2870 torture_comment(tctx
, "Testing TestPrivateFunctionsUser\n");
2872 r
.in
.user_handle
= user_handle
;
2874 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_TestPrivateFunctionsUser_r(b
, tctx
, &r
),
2875 "TestPrivateFunctionsUser failed");
2876 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_NOT_IMPLEMENTED
, "TestPrivateFunctionsUser");
2881 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_binding_handle
*b
,
2882 struct torture_context
*tctx
,
2883 struct policy_handle
*handle
,
2888 uint16_t levels
[] = { /* 3, */ 5, 21 };
2890 NTTIME pwdlastset3
= 0;
2891 NTTIME pwdlastset5
= 0;
2892 NTTIME pwdlastset21
= 0;
2894 torture_comment(tctx
, "Testing QueryUserInfo%s level 5 and 21 call ",
2895 use_info2
? "2":"");
2897 for (i
=0; i
<ARRAY_SIZE(levels
); i
++) {
2899 struct samr_QueryUserInfo r
;
2900 struct samr_QueryUserInfo2 r2
;
2901 union samr_UserInfo
*info
;
2904 r2
.in
.user_handle
= handle
;
2905 r2
.in
.level
= levels
[i
];
2906 r2
.out
.info
= &info
;
2907 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo2_r(b
, tctx
, &r2
),
2908 "QueryUserInfo2 failed");
2909 status
= r2
.out
.result
;
2912 r
.in
.user_handle
= handle
;
2913 r
.in
.level
= levels
[i
];
2915 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
2916 "QueryUserInfo failed");
2917 status
= r
.out
.result
;
2920 if (!NT_STATUS_IS_OK(status
) &&
2921 !NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_INFO_CLASS
)) {
2922 torture_warning(tctx
, "QueryUserInfo%s level %u failed - %s\n",
2923 use_info2
? "2":"", levels
[i
], nt_errstr(status
));
2927 switch (levels
[i
]) {
2929 pwdlastset3
= info
->info3
.last_password_change
;
2932 pwdlastset5
= info
->info5
.last_password_change
;
2935 pwdlastset21
= info
->info21
.last_password_change
;
2941 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2942 "pwdlastset mixup"); */
2943 torture_assert_int_equal(tctx
, pwdlastset5
, pwdlastset21
,
2944 "pwdlastset mixup");
2946 *pwdlastset
= pwdlastset21
;
2948 torture_comment(tctx
, "(pwdlastset: %llu)\n",
2949 (unsigned long long) *pwdlastset
);
2954 static bool test_SamLogon(struct torture_context
*tctx
,
2955 struct dcerpc_pipe
*p
,
2956 struct cli_credentials
*test_credentials
,
2957 NTSTATUS expected_result
,
2961 struct netr_LogonSamLogonEx r
;
2962 union netr_LogonLevel logon
;
2963 union netr_Validation validation
;
2964 uint8_t authoritative
;
2965 struct netr_IdentityInfo identity
;
2966 struct netr_NetworkInfo ninfo
;
2967 struct netr_PasswordInfo pinfo
;
2968 DATA_BLOB names_blob
, chal
, lm_resp
, nt_resp
;
2969 int flags
= CLI_CRED_NTLM_AUTH
;
2970 uint32_t samlogon_flags
= 0;
2971 struct netlogon_creds_CredentialState
*creds
;
2972 struct netr_Authenticator a
;
2973 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2975 torture_assert_ntstatus_ok(tctx
, dcerpc_schannel_creds(p
->conn
->security_state
.generic_state
, tctx
, &creds
), "");
2977 if (lpcfg_client_lanman_auth(tctx
->lp_ctx
)) {
2978 flags
|= CLI_CRED_LANMAN_AUTH
;
2981 if (lpcfg_client_ntlmv2_auth(tctx
->lp_ctx
)) {
2982 flags
|= CLI_CRED_NTLMv2_AUTH
;
2985 cli_credentials_get_ntlm_username_domain(test_credentials
, tctx
,
2986 &identity
.account_name
.string
,
2987 &identity
.domain_name
.string
);
2989 identity
.parameter_control
=
2990 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT
|
2991 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT
;
2992 identity
.logon_id_low
= 0;
2993 identity
.logon_id_high
= 0;
2994 identity
.workstation
.string
= cli_credentials_get_workstation(test_credentials
);
2997 netlogon_creds_client_authenticator(creds
, &a
);
2999 if (!E_deshash(cli_credentials_get_password(test_credentials
), pinfo
.lmpassword
.hash
)) {
3000 ZERO_STRUCT(pinfo
.lmpassword
.hash
);
3002 E_md4hash(cli_credentials_get_password(test_credentials
), pinfo
.ntpassword
.hash
);
3004 if (creds
->negotiate_flags
& NETLOGON_NEG_SUPPORTS_AES
) {
3005 netlogon_creds_aes_encrypt(creds
, pinfo
.lmpassword
.hash
, 16);
3006 netlogon_creds_aes_encrypt(creds
, pinfo
.ntpassword
.hash
, 16);
3007 } else if (creds
->negotiate_flags
& NETLOGON_NEG_ARCFOUR
) {
3008 netlogon_creds_arcfour_crypt(creds
, pinfo
.lmpassword
.hash
, 16);
3009 netlogon_creds_arcfour_crypt(creds
, pinfo
.ntpassword
.hash
, 16);
3011 netlogon_creds_des_encrypt(creds
, &pinfo
.lmpassword
);
3012 netlogon_creds_des_encrypt(creds
, &pinfo
.ntpassword
);
3015 pinfo
.identity_info
= identity
;
3016 logon
.password
= &pinfo
;
3018 r
.in
.logon_level
= NetlogonInteractiveInformation
;
3020 generate_random_buffer(ninfo
.challenge
,
3021 sizeof(ninfo
.challenge
));
3022 chal
= data_blob_const(ninfo
.challenge
,
3023 sizeof(ninfo
.challenge
));
3025 names_blob
= NTLMv2_generate_names_blob(tctx
, cli_credentials_get_workstation(test_credentials
),
3026 cli_credentials_get_domain(test_credentials
));
3028 status
= cli_credentials_get_ntlm_response(test_credentials
, tctx
,
3034 torture_assert_ntstatus_ok(tctx
, status
, "cli_credentials_get_ntlm_response failed");
3036 ninfo
.lm
.data
= lm_resp
.data
;
3037 ninfo
.lm
.length
= lm_resp
.length
;
3039 ninfo
.nt
.data
= nt_resp
.data
;
3040 ninfo
.nt
.length
= nt_resp
.length
;
3042 ninfo
.identity_info
= identity
;
3043 logon
.network
= &ninfo
;
3045 r
.in
.logon_level
= NetlogonNetworkInformation
;
3048 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
3049 r
.in
.computer_name
= cli_credentials_get_workstation(test_credentials
);
3050 r
.in
.logon
= &logon
;
3051 r
.in
.flags
= &samlogon_flags
;
3052 r
.out
.flags
= &samlogon_flags
;
3053 r
.out
.validation
= &validation
;
3054 r
.out
.authoritative
= &authoritative
;
3056 torture_comment(tctx
, "Testing LogonSamLogon with name %s\n", identity
.account_name
.string
);
3058 r
.in
.validation_level
= 6;
3060 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonSamLogonEx_r(b
, tctx
, &r
),
3061 "netr_LogonSamLogonEx failed");
3062 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_INFO_CLASS
)) {
3063 r
.in
.validation_level
= 3;
3064 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonSamLogonEx_r(b
, tctx
, &r
),
3065 "netr_LogonSamLogonEx failed");
3067 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
3068 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, expected_result
, "LogonSamLogonEx failed");
3071 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LogonSamLogonEx failed");
3077 static bool test_SamLogon_with_creds(struct torture_context
*tctx
,
3078 struct dcerpc_pipe
*p
,
3079 struct cli_credentials
*machine_creds
,
3080 const char *acct_name
,
3081 const char *password
,
3082 NTSTATUS expected_samlogon_result
,
3086 struct cli_credentials
*test_credentials
;
3088 test_credentials
= cli_credentials_init(tctx
);
3090 cli_credentials_set_workstation(test_credentials
,
3091 cli_credentials_get_workstation(machine_creds
), CRED_SPECIFIED
);
3092 cli_credentials_set_domain(test_credentials
,
3093 cli_credentials_get_domain(machine_creds
), CRED_SPECIFIED
);
3094 cli_credentials_set_username(test_credentials
,
3095 acct_name
, CRED_SPECIFIED
);
3096 cli_credentials_set_password(test_credentials
,
3097 password
, CRED_SPECIFIED
);
3099 torture_comment(tctx
, "Testing samlogon (%s) as %s password: %s\n",
3100 interactive
? "interactive" : "network", acct_name
, password
);
3102 if (!test_SamLogon(tctx
, p
, test_credentials
,
3103 expected_samlogon_result
, interactive
)) {
3104 torture_warning(tctx
, "new password did not work\n");
3111 static bool test_SetPassword_level(struct dcerpc_pipe
*p
,
3112 struct dcerpc_pipe
*np
,
3113 struct torture_context
*tctx
,
3114 struct policy_handle
*handle
,
3116 uint32_t fields_present
,
3117 uint8_t password_expired
,
3118 bool *matched_expected_error
,
3120 const char *acct_name
,
3122 struct cli_credentials
*machine_creds
,
3123 bool use_queryinfo2
,
3125 NTSTATUS expected_samlogon_result
)
3127 const char *fields
= NULL
;
3129 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3135 fields
= talloc_asprintf(tctx
, "(fields_present: 0x%08x)",
3142 torture_comment(tctx
, "Testing SetUserInfo%s level %d call "
3143 "(password_expired: %d) %s\n",
3144 use_setinfo2
? "2":"", level
, password_expired
,
3145 fields
? fields
: "");
3147 if (!test_SetUserPass_level_ex(p
, tctx
, handle
, level
,
3152 matched_expected_error
)) {
3156 if (!test_QueryUserInfo_pwdlastset(b
, tctx
, handle
,
3162 if (*matched_expected_error
== true) {
3166 if (!test_SamLogon_with_creds(tctx
, np
,
3170 expected_samlogon_result
,
3178 static bool setup_schannel_netlogon_pipe(struct torture_context
*tctx
,
3179 struct cli_credentials
*credentials
,
3180 struct dcerpc_pipe
**p
)
3182 struct dcerpc_binding
*b
;
3184 torture_assert_ntstatus_ok(tctx
, torture_rpc_binding(tctx
, &b
),
3185 "failed to get rpc binding");
3187 /* We have to use schannel, otherwise the SamLogonEx fails
3188 * with INTERNAL_ERROR */
3190 b
->flags
&= ~DCERPC_AUTH_OPTIONS
;
3191 b
->flags
|= DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_AUTO
;
3193 torture_assert_ntstatus_ok(tctx
,
3194 dcerpc_pipe_connect_b(tctx
, p
, b
, &ndr_table_netlogon
,
3195 credentials
, tctx
->ev
, tctx
->lp_ctx
),
3196 "failed to bind to netlogon");
3201 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe
*p
,
3202 struct torture_context
*tctx
,
3203 uint32_t acct_flags
,
3204 const char *acct_name
,
3205 struct policy_handle
*handle
,
3207 struct cli_credentials
*machine_credentials
)
3209 int s
= 0, q
= 0, f
= 0, l
= 0, z
= 0;
3212 bool set_levels
[] = { false, true };
3213 bool query_levels
[] = { false, true };
3214 uint32_t levels
[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
3215 uint32_t nonzeros
[] = { 1, 24 };
3216 uint32_t fields_present
[] = {
3218 SAMR_FIELD_EXPIRED_FLAG
,
3219 SAMR_FIELD_LAST_PWD_CHANGE
,
3220 SAMR_FIELD_EXPIRED_FLAG
| SAMR_FIELD_LAST_PWD_CHANGE
,
3222 SAMR_FIELD_NT_PASSWORD_PRESENT
,
3223 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
,
3224 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
,
3225 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
,
3226 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_EXPIRED_FLAG
,
3227 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_EXPIRED_FLAG
,
3228 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
| SAMR_FIELD_EXPIRED_FLAG
3230 struct dcerpc_pipe
*np
= NULL
;
3232 if (torture_setting_bool(tctx
, "samba3", false) ||
3233 torture_setting_bool(tctx
, "samba4", false)) {
3235 torture_comment(tctx
, "Samba3 has second granularity, setting delay to: %d\n",
3239 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
3241 /* set to 1 to enable testing for all possible opcode
3242 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3245 #define TEST_ALL_LEVELS 1
3246 #define TEST_SET_LEVELS 1
3247 #define TEST_QUERY_LEVELS 1
3249 #ifdef TEST_ALL_LEVELS
3250 for (l
=0; l
<ARRAY_SIZE(levels
); l
++) {
3252 for (l
=0; l
<(ARRAY_SIZE(levels
))/2; l
++) {
3254 for (z
=0; z
<ARRAY_SIZE(nonzeros
); z
++) {
3255 for (f
=0; f
<ARRAY_SIZE(fields_present
); f
++) {
3256 #ifdef TEST_SET_LEVELS
3257 for (s
=0; s
<ARRAY_SIZE(set_levels
); s
++) {
3259 #ifdef TEST_QUERY_LEVELS
3260 for (q
=0; q
<ARRAY_SIZE(query_levels
); q
++) {
3262 NTTIME pwdlastset_old
= 0;
3263 NTTIME pwdlastset_new
= 0;
3264 bool matched_expected_error
= false;
3265 NTSTATUS expected_samlogon_result
= NT_STATUS_ACCOUNT_DISABLED
;
3267 torture_comment(tctx
, "------------------------------\n"
3268 "Testing pwdLastSet attribute for flags: 0x%08x "
3269 "(s: %d (l: %d), q: %d)\n",
3270 acct_flags
, s
, levels
[l
], q
);
3272 switch (levels
[l
]) {
3276 if (!((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3277 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
))) {
3278 expected_samlogon_result
= NT_STATUS_WRONG_PASSWORD
;
3286 /* set a password and force password change (pwdlastset 0) by
3287 * setting the password expired flag to a non-0 value */
3289 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3293 &matched_expected_error
,
3297 machine_credentials
,
3300 expected_samlogon_result
)) {
3304 if (matched_expected_error
== true) {
3305 /* skipping on expected failure */
3309 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3310 * set without the SAMR_FIELD_EXPIRED_FLAG */
3312 switch (levels
[l
]) {
3316 if ((pwdlastset_new
!= 0) &&
3317 !(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
)) {
3318 torture_comment(tctx
, "not considering a non-0 "
3319 "pwdLastSet as a an error as the "
3320 "SAMR_FIELD_EXPIRED_FLAG has not "
3326 if (pwdlastset_new
!= 0) {
3327 torture_warning(tctx
, "pwdLastSet test failed: "
3328 "expected pwdLastSet 0 but got %llu\n",
3329 (unsigned long long) pwdlastset_old
);
3335 switch (levels
[l
]) {
3339 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3340 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3341 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3342 (pwdlastset_old
>= pwdlastset_new
)) {
3343 torture_warning(tctx
, "pwdlastset not increasing\n");
3349 pwdlastset_old
= pwdlastset_new
;
3355 /* set a password, pwdlastset needs to get updated (increased
3356 * value), password_expired value used here is 0 */
3358 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3362 &matched_expected_error
,
3366 machine_credentials
,
3369 expected_samlogon_result
)) {
3373 /* when a password has been changed, pwdlastset must not be 0 afterwards
3374 * and must be larger then the old value */
3376 switch (levels
[l
]) {
3380 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3381 * password has been changed, old and new pwdlastset
3382 * need to be the same value */
3384 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
3385 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3386 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3388 torture_assert_int_equal(tctx
, pwdlastset_old
,
3389 pwdlastset_new
, "pwdlastset must be equal");
3394 if (pwdlastset_old
>= pwdlastset_new
) {
3395 torture_warning(tctx
, "pwdLastSet test failed: "
3396 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3397 (unsigned long long) pwdlastset_old
,
3398 (unsigned long long) pwdlastset_new
);
3401 if (pwdlastset_new
== 0) {
3402 torture_warning(tctx
, "pwdLastSet test failed: "
3403 "expected non-0 pwdlastset, got: %llu\n",
3404 (unsigned long long) pwdlastset_new
);
3410 switch (levels
[l
]) {
3414 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3415 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3416 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3417 (pwdlastset_old
>= pwdlastset_new
)) {
3418 torture_warning(tctx
, "pwdlastset not increasing\n");
3424 pwdlastset_old
= pwdlastset_new
;
3430 /* set a password, pwdlastset needs to get updated (increased
3431 * value), password_expired value used here is 0 */
3433 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3437 &matched_expected_error
,
3441 machine_credentials
,
3444 expected_samlogon_result
)) {
3448 /* when a password has been changed, pwdlastset must not be 0 afterwards
3449 * and must be larger then the old value */
3451 switch (levels
[l
]) {
3456 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3457 * password has been changed, old and new pwdlastset
3458 * need to be the same value */
3460 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
3461 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3462 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3464 torture_assert_int_equal(tctx
, pwdlastset_old
,
3465 pwdlastset_new
, "pwdlastset must be equal");
3470 if (pwdlastset_old
>= pwdlastset_new
) {
3471 torture_warning(tctx
, "pwdLastSet test failed: "
3472 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3473 (unsigned long long) pwdlastset_old
,
3474 (unsigned long long) pwdlastset_new
);
3477 if (pwdlastset_new
== 0) {
3478 torture_warning(tctx
, "pwdLastSet test failed: "
3479 "expected non-0 pwdlastset, got: %llu\n",
3480 (unsigned long long) pwdlastset_new
);
3486 switch (levels
[l
]) {
3490 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3491 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3492 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3493 (pwdlastset_old
>= pwdlastset_new
)) {
3494 torture_warning(tctx
, "pwdlastset not increasing\n");
3500 pwdlastset_old
= pwdlastset_new
;
3506 /* set a password and force password change (pwdlastset 0) by
3507 * setting the password expired flag to a non-0 value */
3509 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3513 &matched_expected_error
,
3517 machine_credentials
,
3520 expected_samlogon_result
)) {
3524 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3525 * set without the SAMR_FIELD_EXPIRED_FLAG */
3527 switch (levels
[l
]) {
3531 if ((pwdlastset_new
!= 0) &&
3532 !(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
)) {
3533 torture_comment(tctx
, "not considering a non-0 "
3534 "pwdLastSet as a an error as the "
3535 "SAMR_FIELD_EXPIRED_FLAG has not "
3540 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3541 * password has been changed, old and new pwdlastset
3542 * need to be the same value */
3544 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
3545 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3546 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3548 torture_assert_int_equal(tctx
, pwdlastset_old
,
3549 pwdlastset_new
, "pwdlastset must be equal");
3554 if (pwdlastset_new
!= 0) {
3555 torture_warning(tctx
, "pwdLastSet test failed: "
3556 "expected pwdLastSet 0, got %llu\n",
3557 (unsigned long long) pwdlastset_old
);
3563 switch (levels
[l
]) {
3567 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3568 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3569 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3570 (pwdlastset_old
>= pwdlastset_new
)) {
3571 torture_warning(tctx
, "pwdlastset not increasing\n");
3577 /* if the level we are testing does not have a fields_present
3578 * field, skip all fields present tests by setting f to to
3580 switch (levels
[l
]) {
3584 f
= ARRAY_SIZE(fields_present
);
3588 #ifdef TEST_QUERY_LEVELS
3591 #ifdef TEST_SET_LEVELS
3594 } /* fields present */
3598 #undef TEST_SET_LEVELS
3599 #undef TEST_QUERY_LEVELS
3606 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_binding_handle
*b
,
3607 struct torture_context
*tctx
,
3608 struct policy_handle
*handle
,
3609 uint32_t *badpwdcount
)
3611 union samr_UserInfo
*info
;
3612 struct samr_QueryUserInfo r
;
3614 r
.in
.user_handle
= handle
;
3618 torture_comment(tctx
, "Testing QueryUserInfo level %d", r
.in
.level
);
3620 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
3621 "failed to query userinfo");
3622 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
3623 "failed to query userinfo");
3625 *badpwdcount
= info
->info3
.bad_password_count
;
3627 torture_comment(tctx
, " (bad password count: %d)\n", *badpwdcount
);
3632 static bool test_SetUserInfo_acct_flags(struct dcerpc_binding_handle
*b
,
3633 struct torture_context
*tctx
,
3634 struct policy_handle
*user_handle
,
3635 uint32_t acct_flags
)
3637 struct samr_SetUserInfo r
;
3638 union samr_UserInfo user_info
;
3640 torture_comment(tctx
, "Testing SetUserInfo level 16\n");
3642 user_info
.info16
.acct_flags
= acct_flags
;
3644 r
.in
.user_handle
= user_handle
;
3646 r
.in
.info
= &user_info
;
3648 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &r
),
3649 "failed to set account flags");
3650 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
3651 "failed to set account flags");
3656 static bool test_reset_badpwdcount(struct dcerpc_pipe
*p
,
3657 struct torture_context
*tctx
,
3658 struct policy_handle
*user_handle
,
3659 uint32_t acct_flags
,
3662 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3664 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
3665 "failed to set password");
3667 torture_comment(tctx
, "Testing SetUserInfo level 16 (enable account)\n");
3669 torture_assert(tctx
,
3670 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
3671 acct_flags
& ~ACB_DISABLED
),
3672 "failed to enable user");
3674 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
3675 "failed to set password");
3680 static bool test_SetDomainInfo(struct dcerpc_binding_handle
*b
,
3681 struct torture_context
*tctx
,
3682 struct policy_handle
*domain_handle
,
3683 enum samr_DomainInfoClass level
,
3684 union samr_DomainInfo
*info
)
3686 struct samr_SetDomainInfo r
;
3688 r
.in
.domain_handle
= domain_handle
;
3692 torture_assert_ntstatus_ok(tctx
,
3693 dcerpc_samr_SetDomainInfo_r(b
, tctx
, &r
),
3694 "failed to set domain info");
3695 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
3696 "failed to set domain info");
3701 static bool test_SetDomainInfo_ntstatus(struct dcerpc_binding_handle
*b
,
3702 struct torture_context
*tctx
,
3703 struct policy_handle
*domain_handle
,
3704 enum samr_DomainInfoClass level
,
3705 union samr_DomainInfo
*info
,
3708 struct samr_SetDomainInfo r
;
3710 r
.in
.domain_handle
= domain_handle
;
3714 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &r
),
3715 "SetDomainInfo failed");
3716 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, expected
, "");
3721 static bool test_QueryDomainInfo2_level(struct dcerpc_binding_handle
*b
,
3722 struct torture_context
*tctx
,
3723 struct policy_handle
*domain_handle
,
3724 enum samr_DomainInfoClass level
,
3725 union samr_DomainInfo
**q_info
)
3727 struct samr_QueryDomainInfo2 r
;
3729 r
.in
.domain_handle
= domain_handle
;
3731 r
.out
.info
= q_info
;
3733 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo2_r(b
, tctx
, &r
),
3734 "failed to query domain info");
3735 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
3736 "failed to query domain info");
3741 static bool test_Password_badpwdcount(struct dcerpc_pipe
*p
,
3742 struct dcerpc_pipe
*np
,
3743 struct torture_context
*tctx
,
3744 uint32_t acct_flags
,
3745 const char *acct_name
,
3746 struct policy_handle
*domain_handle
,
3747 struct policy_handle
*user_handle
,
3749 struct cli_credentials
*machine_credentials
,
3750 const char *comment
,
3753 NTSTATUS expected_success_status
,
3754 struct samr_DomInfo1
*info1
,
3755 struct samr_DomInfo12
*info12
)
3757 union samr_DomainInfo info
;
3760 uint32_t badpwdcount
, tmp
;
3761 uint32_t password_history_length
= 12;
3762 uint32_t lockout_threshold
= 15;
3763 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3765 torture_comment(tctx
, "\nTesting bad pwd count with: %s\n", comment
);
3767 torture_assert(tctx
, password_history_length
< lockout_threshold
,
3768 "password history length needs to be smaller than account lockout threshold for this test");
3773 info
.info1
= *info1
;
3774 info
.info1
.password_history_length
= password_history_length
;
3776 torture_assert(tctx
,
3777 test_SetDomainInfo(b
, tctx
, domain_handle
,
3778 DomainPasswordInformation
, &info
),
3779 "failed to set password history length");
3781 info
.info12
= *info12
;
3782 info
.info12
.lockout_threshold
= lockout_threshold
;
3784 torture_assert(tctx
,
3785 test_SetDomainInfo(b
, tctx
, domain_handle
,
3786 DomainLockoutInformation
, &info
),
3787 "failed to set lockout threshold");
3789 /* reset bad pwd count */
3791 torture_assert(tctx
,
3792 test_reset_badpwdcount(p
, tctx
, user_handle
, acct_flags
, password
), "");
3795 /* enable or disable account */
3797 torture_assert(tctx
,
3798 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
3799 acct_flags
| ACB_DISABLED
),
3800 "failed to disable user");
3802 torture_assert(tctx
,
3803 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
3804 acct_flags
& ~ACB_DISABLED
),
3805 "failed to enable user");
3809 /* setup password history */
3811 passwords
= talloc_array(tctx
, char *, password_history_length
);
3813 for (i
=0; i
< password_history_length
; i
++) {
3815 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
3816 "failed to set password");
3817 passwords
[i
] = talloc_strdup(tctx
, *password
);
3819 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3820 acct_name
, passwords
[i
],
3821 expected_success_status
, interactive
)) {
3822 torture_fail(tctx
, "failed to auth with latest password");
3825 torture_assert(tctx
,
3826 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3828 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3832 /* test with wrong password */
3834 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3835 acct_name
, "random_crap",
3836 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
3837 torture_fail(tctx
, "succeeded to authenticate with wrong password");
3840 torture_assert(tctx
,
3841 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3843 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
3846 /* test with latest good password */
3848 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
3849 passwords
[password_history_length
-1],
3850 expected_success_status
, interactive
)) {
3851 torture_fail(tctx
, "succeeded to authenticate with wrong password");
3854 torture_assert(tctx
,
3855 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3858 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
3860 /* only enabled accounts get the bad pwd count reset upon
3861 * successful logon */
3862 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3868 /* test password history */
3870 for (i
=0; i
< password_history_length
; i
++) {
3872 torture_comment(tctx
, "Testing bad password count behavior with "
3873 "password #%d of #%d\n", i
, password_history_length
);
3875 /* - network samlogon will succeed auth and not
3876 * increase badpwdcount for 2 last entries
3877 * - interactive samlogon only for the last one */
3879 if (i
== password_history_length
- 1 ||
3880 (i
== password_history_length
- 2 && !interactive
)) {
3882 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3883 acct_name
, passwords
[i
],
3884 expected_success_status
, interactive
)) {
3885 torture_fail(tctx
, talloc_asprintf(tctx
, "succeeded to authenticate with old password (#%d of #%d in history)", i
, password_history_length
));
3888 torture_assert(tctx
,
3889 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3892 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
3893 torture_assert_int_equal(tctx
, badpwdcount
, tmp
, "unexpected badpwdcount");
3895 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
3896 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3904 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3905 acct_name
, passwords
[i
],
3906 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
3907 torture_fail(tctx
, talloc_asprintf(tctx
, "succeeded to authenticate with old password (#%d of #%d in history)", i
, password_history_length
));
3910 torture_assert(tctx
,
3911 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3913 /* - network samlogon will fail auth but not increase
3914 * badpwdcount for 3rd last entry
3915 * - interactive samlogon for 3rd and 2nd last entry */
3917 if (i
== password_history_length
- 3 ||
3918 (i
== password_history_length
- 2 && interactive
)) {
3919 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
3920 torture_assert_int_equal(tctx
, badpwdcount
, tmp
, "unexpected badpwdcount");
3922 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
3923 torture_assert_int_equal(tctx
, badpwdcount
, tmp
+ 1, "unexpected badpwdcount");
3932 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe
*p
,
3933 struct torture_context
*tctx
,
3934 uint32_t acct_flags
,
3935 const char *acct_name
,
3936 struct policy_handle
*domain_handle
,
3937 struct policy_handle
*user_handle
,
3939 struct cli_credentials
*machine_credentials
)
3941 union samr_DomainInfo
*q_info
, s_info
;
3942 struct samr_DomInfo1 info1
, _info1
;
3943 struct samr_DomInfo12 info12
, _info12
;
3945 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3946 struct dcerpc_pipe
*np
;
3950 const char *comment
;
3953 NTSTATUS expected_success_status
;
3956 .comment
= "network logon (disabled account)",
3958 .interactive
= false,
3959 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
3962 .comment
= "network logon (enabled account)",
3964 .interactive
= false,
3965 .expected_success_status
= NT_STATUS_OK
3968 .comment
= "interactive logon (disabled account)",
3970 .interactive
= true,
3971 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
3974 .comment
= "interactive logon (enabled account)",
3976 .interactive
= true,
3977 .expected_success_status
= NT_STATUS_OK
3981 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
3983 /* backup old policies */
3985 torture_assert(tctx
,
3986 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
3987 DomainPasswordInformation
, &q_info
),
3988 "failed to query domain info level 1");
3990 info1
= q_info
->info1
;
3993 torture_assert(tctx
,
3994 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
3995 DomainLockoutInformation
, &q_info
),
3996 "failed to query domain info level 12");
3998 info12
= q_info
->info12
;
4003 for (i
=0; i
< ARRAY_SIZE(creds
); i
++) {
4005 /* skip trust tests for now */
4006 if (acct_flags
& ACB_WSTRUST
||
4007 acct_flags
& ACB_SVRTRUST
||
4008 acct_flags
& ACB_DOMTRUST
) {
4012 ret
&= test_Password_badpwdcount(p
, np
, tctx
, acct_flags
, acct_name
,
4013 domain_handle
, user_handle
, password
,
4014 machine_credentials
,
4017 creds
[i
].interactive
,
4018 creds
[i
].expected_success_status
,
4021 torture_warning(tctx
, "TEST #%d (%s) failed\n", i
, creds
[i
].comment
);
4023 torture_comment(tctx
, "TEST #%d (%s) succeeded\n", i
, creds
[i
].comment
);
4027 /* restore policies */
4029 s_info
.info1
= info1
;
4031 torture_assert(tctx
,
4032 test_SetDomainInfo(b
, tctx
, domain_handle
,
4033 DomainPasswordInformation
, &s_info
),
4034 "failed to set password information");
4036 s_info
.info12
= info12
;
4038 torture_assert(tctx
,
4039 test_SetDomainInfo(b
, tctx
, domain_handle
,
4040 DomainLockoutInformation
, &s_info
),
4041 "failed to set lockout information");
4046 static bool test_QueryUserInfo_acct_flags(struct dcerpc_binding_handle
*b
,
4047 struct torture_context
*tctx
,
4048 struct policy_handle
*handle
,
4049 uint32_t *acct_flags
)
4051 union samr_UserInfo
*info
;
4052 struct samr_QueryUserInfo r
;
4054 r
.in
.user_handle
= handle
;
4058 torture_comment(tctx
, "Testing QueryUserInfo level %d", r
.in
.level
);
4060 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
4061 "failed to query userinfo");
4062 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4063 "failed to query userinfo");
4065 *acct_flags
= info
->info16
.acct_flags
;
4067 torture_comment(tctx
, " (acct_flags: 0x%08x)\n", *acct_flags
);
4072 static bool test_Password_lockout(struct dcerpc_pipe
*p
,
4073 struct dcerpc_pipe
*np
,
4074 struct torture_context
*tctx
,
4075 uint32_t acct_flags
,
4076 const char *acct_name
,
4077 struct policy_handle
*domain_handle
,
4078 struct policy_handle
*user_handle
,
4080 struct cli_credentials
*machine_credentials
,
4081 const char *comment
,
4084 NTSTATUS expected_success_status
,
4085 struct samr_DomInfo1
*info1
,
4086 struct samr_DomInfo12
*info12
)
4088 union samr_DomainInfo info
;
4089 uint32_t badpwdcount
;
4090 uint32_t password_history_length
= 1;
4091 uint64_t lockout_threshold
= 1;
4092 uint32_t lockout_seconds
= 5;
4093 uint64_t delta_time_factor
= 10 * 1000 * 1000;
4094 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4096 torture_comment(tctx
, "\nTesting account lockout: %s\n", comment
);
4100 info
.info1
= *info1
;
4102 torture_comment(tctx
, "setting password history length.\n");
4103 info
.info1
.password_history_length
= password_history_length
;
4105 torture_assert(tctx
,
4106 test_SetDomainInfo(b
, tctx
, domain_handle
,
4107 DomainPasswordInformation
, &info
),
4108 "failed to set password history length");
4110 info
.info12
= *info12
;
4111 info
.info12
.lockout_threshold
= lockout_threshold
;
4113 /* set lockout duration < lockout window: should fail */
4114 info
.info12
.lockout_duration
= ~(lockout_seconds
* delta_time_factor
);
4115 info
.info12
.lockout_window
= ~((lockout_seconds
+ 1) * delta_time_factor
);
4117 torture_assert(tctx
,
4118 test_SetDomainInfo_ntstatus(b
, tctx
, domain_handle
,
4119 DomainLockoutInformation
, &info
,
4120 NT_STATUS_INVALID_PARAMETER
),
4121 "setting lockout duration < lockout window gave unexpected result");
4123 info
.info12
.lockout_duration
= 0;
4124 info
.info12
.lockout_window
= 0;
4126 torture_assert(tctx
,
4127 test_SetDomainInfo(b
, tctx
, domain_handle
,
4128 DomainLockoutInformation
, &info
),
4129 "failed to set lockout window and duration to 0");
4132 /* set lockout duration of 5 seconds */
4133 info
.info12
.lockout_duration
= ~(lockout_seconds
* delta_time_factor
);
4134 info
.info12
.lockout_window
= ~(lockout_seconds
* delta_time_factor
);
4136 torture_assert(tctx
,
4137 test_SetDomainInfo(b
, tctx
, domain_handle
,
4138 DomainLockoutInformation
, &info
),
4139 "failed to set lockout window and duration to 5 seconds");
4141 /* reset bad pwd count */
4143 torture_assert(tctx
,
4144 test_reset_badpwdcount(p
, tctx
, user_handle
, acct_flags
, password
), "");
4147 /* enable or disable account */
4150 torture_assert(tctx
,
4151 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
4152 acct_flags
| ACB_DISABLED
),
4153 "failed to disable user");
4155 torture_assert(tctx
,
4156 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
4157 acct_flags
& ~ACB_DISABLED
),
4158 "failed to enable user");
4162 /* test logon with right password */
4164 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
4165 acct_name
, *password
,
4166 expected_success_status
, interactive
)) {
4167 torture_fail(tctx
, "failed to auth with latest password");
4170 torture_assert(tctx
,
4171 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4172 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
4175 /* test with wrong password ==> lockout */
4177 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
4178 acct_name
, "random_crap",
4179 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
4180 torture_fail(tctx
, "succeeded to authenticate with wrong password");
4183 torture_assert(tctx
,
4184 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4185 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
4187 torture_assert(tctx
,
4188 test_QueryUserInfo_acct_flags(b
, tctx
, user_handle
, &acct_flags
), "");
4189 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
4190 "expected account to be locked");
4193 /* test with good password */
4195 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
4197 NT_STATUS_ACCOUNT_LOCKED_OUT
, interactive
))
4199 torture_fail(tctx
, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4202 /* bad pwd count should not get updated */
4203 torture_assert(tctx
,
4204 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4205 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
4207 /* curiously, windows does _not_ set the autlock flag */
4208 torture_assert(tctx
,
4209 test_QueryUserInfo_acct_flags(b
, tctx
, user_handle
, &acct_flags
), "");
4210 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
4211 "expected account to be locked");
4214 /* with bad password */
4216 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
4217 acct_name
, "random_crap2",
4218 NT_STATUS_ACCOUNT_LOCKED_OUT
, interactive
))
4220 torture_fail(tctx
, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4223 /* bad pwd count should not get updated */
4224 torture_assert(tctx
,
4225 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4226 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
4228 /* curiously, windows does _not_ set the autlock flag */
4229 torture_assert(tctx
,
4230 test_QueryUserInfo_acct_flags(b
, tctx
, user_handle
, &acct_flags
), "");
4231 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
4232 "expected account to be locked");
4235 /* let lockout duration expire ==> unlock */
4237 torture_comment(tctx
, "let lockout duration expire...\n");
4238 sleep(lockout_seconds
+ 1);
4240 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
4242 expected_success_status
, interactive
))
4244 torture_fail(tctx
, "failed to authenticate after lockout expired");
4247 torture_assert(tctx
,
4248 test_QueryUserInfo_acct_flags(b
, tctx
, user_handle
, &acct_flags
), "");
4249 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
4250 "expected account not to be locked");
4255 static bool test_Password_lockout_wrap(struct dcerpc_pipe
*p
,
4256 struct torture_context
*tctx
,
4257 uint32_t acct_flags
,
4258 const char *acct_name
,
4259 struct policy_handle
*domain_handle
,
4260 struct policy_handle
*user_handle
,
4262 struct cli_credentials
*machine_credentials
)
4264 union samr_DomainInfo
*q_info
, s_info
;
4265 struct samr_DomInfo1 info1
, _info1
;
4266 struct samr_DomInfo12 info12
, _info12
;
4268 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4269 struct dcerpc_pipe
*np
;
4273 const char *comment
;
4276 NTSTATUS expected_success_status
;
4279 .comment
= "network logon (disabled account)",
4281 .interactive
= false,
4282 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
4285 .comment
= "network logon (enabled account)",
4287 .interactive
= false,
4288 .expected_success_status
= NT_STATUS_OK
4291 .comment
= "interactive logon (disabled account)",
4293 .interactive
= true,
4294 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
4297 .comment
= "interactive logon (enabled account)",
4299 .interactive
= true,
4300 .expected_success_status
= NT_STATUS_OK
4304 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
4306 /* backup old policies */
4308 torture_assert(tctx
,
4309 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
4310 DomainPasswordInformation
, &q_info
),
4311 "failed to query domain info level 1");
4313 info1
= q_info
->info1
;
4316 torture_assert(tctx
,
4317 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
4318 DomainLockoutInformation
, &q_info
),
4319 "failed to query domain info level 12");
4321 info12
= q_info
->info12
;
4326 for (i
=0; i
< ARRAY_SIZE(creds
); i
++) {
4328 /* skip trust tests for now */
4329 if (acct_flags
& ACB_WSTRUST
||
4330 acct_flags
& ACB_SVRTRUST
||
4331 acct_flags
& ACB_DOMTRUST
) {
4335 ret
&= test_Password_lockout(p
, np
, tctx
, acct_flags
, acct_name
,
4336 domain_handle
, user_handle
, password
,
4337 machine_credentials
,
4340 creds
[i
].interactive
,
4341 creds
[i
].expected_success_status
,
4344 torture_warning(tctx
, "TEST #%d (%s) failed\n", i
, creds
[i
].comment
);
4346 torture_comment(tctx
, "TEST #%d (%s) succeeded\n", i
, creds
[i
].comment
);
4350 /* restore policies */
4352 s_info
.info1
= info1
;
4354 torture_assert(tctx
,
4355 test_SetDomainInfo(b
, tctx
, domain_handle
,
4356 DomainPasswordInformation
, &s_info
),
4357 "failed to set password information");
4359 s_info
.info12
= info12
;
4361 torture_assert(tctx
,
4362 test_SetDomainInfo(b
, tctx
, domain_handle
,
4363 DomainLockoutInformation
, &s_info
),
4364 "failed to set lockout information");
4369 static bool test_DeleteUser_with_privs(struct dcerpc_pipe
*p
,
4370 struct dcerpc_pipe
*lp
,
4371 struct torture_context
*tctx
,
4372 struct policy_handle
*domain_handle
,
4373 struct policy_handle
*lsa_handle
,
4374 struct policy_handle
*user_handle
,
4375 const struct dom_sid
*domain_sid
,
4377 struct cli_credentials
*machine_credentials
)
4380 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4381 struct dcerpc_binding_handle
*lb
= lp
->binding_handle
;
4383 struct policy_handle lsa_acct_handle
;
4384 struct dom_sid
*user_sid
;
4386 user_sid
= dom_sid_add_rid(tctx
, domain_sid
, rid
);
4389 struct lsa_EnumAccountRights r
;
4390 struct lsa_RightSet rights
;
4392 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4394 r
.in
.handle
= lsa_handle
;
4395 r
.in
.sid
= user_sid
;
4396 r
.out
.rights
= &rights
;
4398 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
),
4399 "lsa_EnumAccountRights failed");
4400 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
4401 "Expected enum rights for account to fail");
4405 struct lsa_RightSet rights
;
4406 struct lsa_StringLarge names
[2];
4407 struct lsa_AddAccountRights r
;
4409 torture_comment(tctx
, "Testing LSA AddAccountRights\n");
4411 init_lsa_StringLarge(&names
[0], "SeMachineAccountPrivilege");
4412 init_lsa_StringLarge(&names
[1], NULL
);
4415 rights
.names
= names
;
4417 r
.in
.handle
= lsa_handle
;
4418 r
.in
.sid
= user_sid
;
4419 r
.in
.rights
= &rights
;
4421 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_AddAccountRights_r(lb
, tctx
, &r
),
4422 "lsa_AddAccountRights failed");
4423 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4424 "Failed to add privileges");
4428 struct lsa_EnumAccounts r
;
4429 uint32_t resume_handle
= 0;
4430 struct lsa_SidArray lsa_sid_array
;
4432 bool found_sid
= false;
4434 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
4436 r
.in
.handle
= lsa_handle
;
4437 r
.in
.num_entries
= 0x1000;
4438 r
.in
.resume_handle
= &resume_handle
;
4439 r
.out
.sids
= &lsa_sid_array
;
4440 r
.out
.resume_handle
= &resume_handle
;
4442 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccounts_r(lb
, tctx
, &r
),
4443 "lsa_EnumAccounts failed");
4444 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4445 "Failed to enum accounts");
4447 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
4448 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
4453 torture_assert(tctx
, found_sid
,
4454 "failed to list privileged account");
4458 struct lsa_EnumAccountRights r
;
4459 struct lsa_RightSet user_rights
;
4461 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4463 r
.in
.handle
= lsa_handle
;
4464 r
.in
.sid
= user_sid
;
4465 r
.out
.rights
= &user_rights
;
4467 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
),
4468 "lsa_EnumAccountRights failed");
4469 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4470 "Failed to enum rights for account");
4472 if (user_rights
.count
< 1) {
4473 torture_warning(tctx
, "failed to find newly added rights");
4479 struct lsa_OpenAccount r
;
4481 torture_comment(tctx
, "Testing LSA OpenAccount\n");
4483 r
.in
.handle
= lsa_handle
;
4484 r
.in
.sid
= user_sid
;
4485 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4486 r
.out
.acct_handle
= &lsa_acct_handle
;
4488 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenAccount_r(lb
, tctx
, &r
),
4489 "lsa_OpenAccount failed");
4490 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4491 "Failed to open lsa account");
4495 struct lsa_GetSystemAccessAccount r
;
4496 uint32_t access_mask
;
4498 torture_comment(tctx
, "Testing LSA GetSystemAccessAccount\n");
4500 r
.in
.handle
= &lsa_acct_handle
;
4501 r
.out
.access_mask
= &access_mask
;
4503 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_GetSystemAccessAccount_r(lb
, tctx
, &r
),
4504 "lsa_GetSystemAccessAccount failed");
4505 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4506 "Failed to get lsa system access account");
4512 torture_comment(tctx
, "Testing LSA Close\n");
4514 r
.in
.handle
= &lsa_acct_handle
;
4515 r
.out
.handle
= &lsa_acct_handle
;
4517 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_Close_r(lb
, tctx
, &r
),
4518 "lsa_Close failed");
4519 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4520 "Failed to close lsa");
4524 struct samr_DeleteUser r
;
4526 torture_comment(tctx
, "Testing SAMR DeleteUser\n");
4528 r
.in
.user_handle
= user_handle
;
4529 r
.out
.user_handle
= user_handle
;
4531 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, tctx
, &r
),
4532 "DeleteUser failed");
4533 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4534 "DeleteUser failed");
4538 struct lsa_EnumAccounts r
;
4539 uint32_t resume_handle
= 0;
4540 struct lsa_SidArray lsa_sid_array
;
4542 bool found_sid
= false;
4544 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
4546 r
.in
.handle
= lsa_handle
;
4547 r
.in
.num_entries
= 0x1000;
4548 r
.in
.resume_handle
= &resume_handle
;
4549 r
.out
.sids
= &lsa_sid_array
;
4550 r
.out
.resume_handle
= &resume_handle
;
4552 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccounts_r(lb
, tctx
, &r
),
4553 "lsa_EnumAccounts failed");
4554 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4555 "Failed to enum accounts");
4557 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
4558 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
4563 torture_assert(tctx
, found_sid
,
4564 "failed to list privileged account");
4568 struct lsa_EnumAccountRights r
;
4569 struct lsa_RightSet user_rights
;
4571 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4573 r
.in
.handle
= lsa_handle
;
4574 r
.in
.sid
= user_sid
;
4575 r
.out
.rights
= &user_rights
;
4577 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
),
4578 "lsa_EnumAccountRights failed");
4579 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4580 "Failed to enum rights for account");
4582 if (user_rights
.count
< 1) {
4583 torture_warning(tctx
, "failed to find newly added rights");
4589 struct lsa_OpenAccount r
;
4591 torture_comment(tctx
, "Testing LSA OpenAccount\n");
4593 r
.in
.handle
= lsa_handle
;
4594 r
.in
.sid
= user_sid
;
4595 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4596 r
.out
.acct_handle
= &lsa_acct_handle
;
4598 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenAccount_r(lb
, tctx
, &r
),
4599 "lsa_OpenAccount failed");
4600 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4601 "Failed to open lsa account");
4605 struct lsa_GetSystemAccessAccount r
;
4606 uint32_t access_mask
;
4608 torture_comment(tctx
, "Testing LSA GetSystemAccessAccount\n");
4610 r
.in
.handle
= &lsa_acct_handle
;
4611 r
.out
.access_mask
= &access_mask
;
4613 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_GetSystemAccessAccount_r(lb
, tctx
, &r
),
4614 "lsa_GetSystemAccessAccount failed");
4615 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4616 "Failed to get lsa system access account");
4620 struct lsa_DeleteObject r
;
4622 torture_comment(tctx
, "Testing LSA DeleteObject\n");
4624 r
.in
.handle
= &lsa_acct_handle
;
4625 r
.out
.handle
= &lsa_acct_handle
;
4627 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_DeleteObject_r(lb
, tctx
, &r
),
4628 "lsa_DeleteObject failed");
4629 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4630 "Failed to delete object");
4634 struct lsa_EnumAccounts r
;
4635 uint32_t resume_handle
= 0;
4636 struct lsa_SidArray lsa_sid_array
;
4638 bool found_sid
= false;
4640 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
4642 r
.in
.handle
= lsa_handle
;
4643 r
.in
.num_entries
= 0x1000;
4644 r
.in
.resume_handle
= &resume_handle
;
4645 r
.out
.sids
= &lsa_sid_array
;
4646 r
.out
.resume_handle
= &resume_handle
;
4648 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccounts_r(lb
, tctx
, &r
),
4649 "lsa_EnumAccounts failed");
4650 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4651 "Failed to enum accounts");
4653 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
4654 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
4659 torture_assert(tctx
, !found_sid
,
4660 "should not have listed privileged account");
4664 struct lsa_EnumAccountRights r
;
4665 struct lsa_RightSet user_rights
;
4667 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4669 r
.in
.handle
= lsa_handle
;
4670 r
.in
.sid
= user_sid
;
4671 r
.out
.rights
= &user_rights
;
4673 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
),
4674 "lsa_EnumAccountRights failed");
4675 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
4676 "Failed to enum rights for account");
4682 static bool test_user_ops(struct dcerpc_pipe
*p
,
4683 struct torture_context
*tctx
,
4684 struct policy_handle
*user_handle
,
4685 struct policy_handle
*domain_handle
,
4686 const struct dom_sid
*domain_sid
,
4687 uint32_t base_acct_flags
,
4688 const char *base_acct_name
, enum torture_samr_choice which_ops
,
4689 struct cli_credentials
*machine_credentials
)
4691 char *password
= NULL
;
4692 struct samr_QueryUserInfo q
;
4693 union samr_UserInfo
*info
;
4695 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4700 const uint32_t password_fields
[] = {
4701 SAMR_FIELD_NT_PASSWORD_PRESENT
,
4702 SAMR_FIELD_LM_PASSWORD_PRESENT
,
4703 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
,
4707 status
= test_LookupName(b
, tctx
, domain_handle
, base_acct_name
, &rid
);
4708 if (!NT_STATUS_IS_OK(status
)) {
4712 switch (which_ops
) {
4713 case TORTURE_SAMR_USER_ATTRIBUTES
:
4714 if (!test_QuerySecurity(b
, tctx
, user_handle
)) {
4718 if (!test_QueryUserInfo(b
, tctx
, user_handle
)) {
4722 if (!test_QueryUserInfo2(b
, tctx
, user_handle
)) {
4726 if (!test_SetUserInfo(b
, tctx
, user_handle
, base_acct_flags
,
4731 if (!test_GetUserPwInfo(b
, tctx
, user_handle
)) {
4735 if (!test_TestPrivateFunctionsUser(b
, tctx
, user_handle
)) {
4739 if (!test_SetUserPass(p
, tctx
, user_handle
, &password
)) {
4743 case TORTURE_SAMR_PASSWORDS
:
4744 if (base_acct_flags
& (ACB_WSTRUST
|ACB_DOMTRUST
|ACB_SVRTRUST
)) {
4745 char simple_pass
[9];
4746 char *v
= generate_random_str(tctx
, 1);
4748 ZERO_STRUCT(simple_pass
);
4749 memset(simple_pass
, *v
, sizeof(simple_pass
) - 1);
4751 torture_comment(tctx
, "Testing machine account password policy rules\n");
4753 /* Workstation trust accounts don't seem to need to honour password quality policy */
4754 if (!test_SetUserPassEx(p
, tctx
, user_handle
, true, &password
)) {
4758 if (!test_ChangePasswordUser2(p
, tctx
, base_acct_name
, &password
, simple_pass
, false)) {
4762 /* reset again, to allow another 'user' password change */
4763 if (!test_SetUserPassEx(p
, tctx
, user_handle
, true, &password
)) {
4767 /* Try a 'short' password */
4768 if (!test_ChangePasswordUser2(p
, tctx
, base_acct_name
, &password
, samr_rand_pass(tctx
, 4), false)) {
4772 /* Try a compleatly random password */
4773 if (!test_ChangePasswordRandomBytes(p
, tctx
, base_acct_name
, user_handle
, &password
)) {
4778 for (i
= 0; password_fields
[i
]; i
++) {
4779 if (!test_SetUserPass_23(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
4783 /* check it was set right */
4784 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4789 for (i
= 0; password_fields
[i
]; i
++) {
4790 if (!test_SetUserPass_25(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
4794 /* check it was set right */
4795 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4800 if (!test_SetUserPassEx(p
, tctx
, user_handle
, false, &password
)) {
4804 if (!test_ChangePassword(p
, tctx
, base_acct_name
, domain_handle
, &password
)) {
4808 if (!test_SetUserPass_18(p
, tctx
, user_handle
, &password
)) {
4812 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4816 for (i
= 0; password_fields
[i
]; i
++) {
4818 if (password_fields
[i
] == SAMR_FIELD_LM_PASSWORD_PRESENT
) {
4819 /* we need to skip as that would break
4820 * the ChangePasswordUser3 verify */
4824 if (!test_SetUserPass_21(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
4828 /* check it was set right */
4829 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4834 q
.in
.user_handle
= user_handle
;
4838 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
),
4839 "QueryUserInfo failed");
4840 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
4841 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
4842 q
.in
.level
, nt_errstr(q
.out
.result
));
4845 uint32_t expected_flags
= (base_acct_flags
| ACB_PWNOTREQ
| ACB_DISABLED
);
4846 if ((info
->info5
.acct_flags
) != expected_flags
) {
4847 torture_warning(tctx
, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4848 info
->info5
.acct_flags
,
4851 if (!torture_setting_bool(tctx
, "samba3", false)) {
4855 if (info
->info5
.rid
!= rid
) {
4856 torture_warning(tctx
, "QueryUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
4857 info
->info5
.rid
, rid
);
4864 case TORTURE_SAMR_PASSWORDS_PWDLASTSET
:
4866 /* test last password change timestamp behaviour */
4867 if (!test_SetPassword_pwdlastset(p
, tctx
, base_acct_flags
,
4869 user_handle
, &password
,
4870 machine_credentials
)) {
4875 torture_comment(tctx
, "pwdLastSet test succeeded\n");
4877 torture_warning(tctx
, "pwdLastSet test failed\n");
4882 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
:
4884 /* test bad pwd count change behaviour */
4885 if (!test_Password_badpwdcount_wrap(p
, tctx
, base_acct_flags
,
4888 user_handle
, &password
,
4889 machine_credentials
)) {
4894 torture_comment(tctx
, "badPwdCount test succeeded\n");
4896 torture_warning(tctx
, "badPwdCount test failed\n");
4901 case TORTURE_SAMR_PASSWORDS_LOCKOUT
:
4903 if (!test_Password_lockout_wrap(p
, tctx
, base_acct_flags
,
4906 user_handle
, &password
,
4907 machine_credentials
))
4913 torture_comment(tctx
, "lockout test succeeded\n");
4915 torture_warning(tctx
, "lockout test failed\n");
4921 case TORTURE_SAMR_USER_PRIVILEGES
: {
4923 struct dcerpc_pipe
*lp
;
4924 struct policy_handle
*lsa_handle
;
4925 struct dcerpc_binding_handle
*lb
;
4927 status
= torture_rpc_connection(tctx
, &lp
, &ndr_table_lsarpc
);
4928 torture_assert_ntstatus_ok(tctx
, status
, "Failed to open LSA pipe");
4929 lb
= lp
->binding_handle
;
4931 if (!test_lsa_OpenPolicy2(lb
, tctx
, &lsa_handle
)) {
4935 if (!test_DeleteUser_with_privs(p
, lp
, tctx
,
4936 domain_handle
, lsa_handle
, user_handle
,
4938 machine_credentials
)) {
4942 if (!test_lsa_Close(lb
, tctx
, lsa_handle
)) {
4947 torture_warning(tctx
, "privileged user delete test failed\n");
4952 case TORTURE_SAMR_OTHER
:
4953 case TORTURE_SAMR_MANY_ACCOUNTS
:
4954 case TORTURE_SAMR_MANY_GROUPS
:
4955 case TORTURE_SAMR_MANY_ALIASES
:
4956 /* We just need the account to exist */
4962 static bool test_alias_ops(struct dcerpc_binding_handle
*b
,
4963 struct torture_context
*tctx
,
4964 struct policy_handle
*alias_handle
,
4965 const struct dom_sid
*domain_sid
)
4969 if (!torture_setting_bool(tctx
, "samba3", false)) {
4970 if (!test_QuerySecurity(b
, tctx
, alias_handle
)) {
4975 if (!test_QueryAliasInfo(b
, tctx
, alias_handle
)) {
4979 if (!test_SetAliasInfo(b
, tctx
, alias_handle
)) {
4983 if (!test_AddMemberToAlias(b
, tctx
, alias_handle
, domain_sid
)) {
4987 if (torture_setting_bool(tctx
, "samba3", false) ||
4988 torture_setting_bool(tctx
, "samba4", false)) {
4989 torture_comment(tctx
, "skipping MultipleMembers Alias tests against Samba\n");
4993 if (!test_AddMultipleMembersToAlias(b
, tctx
, alias_handle
)) {
5001 static bool test_DeleteUser(struct dcerpc_binding_handle
*b
,
5002 struct torture_context
*tctx
,
5003 struct policy_handle
*user_handle
)
5005 struct samr_DeleteUser d
;
5006 torture_comment(tctx
, "Testing DeleteUser\n");
5008 d
.in
.user_handle
= user_handle
;
5009 d
.out
.user_handle
= user_handle
;
5011 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, tctx
, &d
),
5012 "DeleteUser failed");
5013 torture_assert_ntstatus_ok(tctx
, d
.out
.result
, "DeleteUser");
5018 bool test_DeleteUser_byname(struct dcerpc_binding_handle
*b
,
5019 struct torture_context
*tctx
,
5020 struct policy_handle
*handle
, const char *name
)
5023 struct samr_DeleteUser d
;
5024 struct policy_handle user_handle
;
5027 status
= test_LookupName(b
, tctx
, handle
, name
, &rid
);
5028 if (!NT_STATUS_IS_OK(status
)) {
5032 status
= test_OpenUser_byname(b
, tctx
, handle
, name
, &user_handle
);
5033 if (!NT_STATUS_IS_OK(status
)) {
5037 d
.in
.user_handle
= &user_handle
;
5038 d
.out
.user_handle
= &user_handle
;
5039 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, tctx
, &d
),
5040 "DeleteUser failed");
5041 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
5042 status
= d
.out
.result
;
5049 torture_warning(tctx
, "DeleteUser_byname(%s) failed - %s\n", name
, nt_errstr(status
));
5054 static bool test_DeleteGroup_byname(struct dcerpc_binding_handle
*b
,
5055 struct torture_context
*tctx
,
5056 struct policy_handle
*handle
, const char *name
)
5059 struct samr_OpenGroup r
;
5060 struct samr_DeleteDomainGroup d
;
5061 struct policy_handle group_handle
;
5064 status
= test_LookupName(b
, tctx
, handle
, name
, &rid
);
5065 if (!NT_STATUS_IS_OK(status
)) {
5069 r
.in
.domain_handle
= handle
;
5070 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5072 r
.out
.group_handle
= &group_handle
;
5073 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenGroup_r(b
, tctx
, &r
),
5074 "OpenGroup failed");
5075 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5076 status
= r
.out
.result
;
5080 d
.in
.group_handle
= &group_handle
;
5081 d
.out
.group_handle
= &group_handle
;
5082 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteDomainGroup_r(b
, tctx
, &d
),
5083 "DeleteDomainGroup failed");
5084 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
5085 status
= d
.out
.result
;
5092 torture_warning(tctx
, "DeleteGroup_byname(%s) failed - %s\n", name
, nt_errstr(status
));
5097 static bool test_DeleteAlias_byname(struct dcerpc_binding_handle
*b
,
5098 struct torture_context
*tctx
,
5099 struct policy_handle
*domain_handle
,
5103 struct samr_OpenAlias r
;
5104 struct samr_DeleteDomAlias d
;
5105 struct policy_handle alias_handle
;
5108 torture_comment(tctx
, "Testing DeleteAlias_byname\n");
5110 status
= test_LookupName(b
, tctx
, domain_handle
, name
, &rid
);
5111 if (!NT_STATUS_IS_OK(status
)) {
5115 r
.in
.domain_handle
= domain_handle
;
5116 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5118 r
.out
.alias_handle
= &alias_handle
;
5119 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenAlias_r(b
, tctx
, &r
),
5120 "OpenAlias failed");
5121 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5122 status
= r
.out
.result
;
5126 d
.in
.alias_handle
= &alias_handle
;
5127 d
.out
.alias_handle
= &alias_handle
;
5128 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteDomAlias_r(b
, tctx
, &d
),
5129 "DeleteDomAlias failed");
5130 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
5131 status
= d
.out
.result
;
5138 torture_warning(tctx
, "DeleteAlias_byname(%s) failed - %s\n", name
, nt_errstr(status
));
5142 static bool test_DeleteAlias(struct dcerpc_binding_handle
*b
,
5143 struct torture_context
*tctx
,
5144 struct policy_handle
*alias_handle
)
5146 struct samr_DeleteDomAlias d
;
5149 torture_comment(tctx
, "Testing DeleteAlias\n");
5151 d
.in
.alias_handle
= alias_handle
;
5152 d
.out
.alias_handle
= alias_handle
;
5154 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteDomAlias_r(b
, tctx
, &d
),
5155 "DeleteDomAlias failed");
5156 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
5157 torture_warning(tctx
, "DeleteAlias failed - %s\n", nt_errstr(d
.out
.result
));
5164 static bool test_CreateAlias(struct dcerpc_binding_handle
*b
,
5165 struct torture_context
*tctx
,
5166 struct policy_handle
*domain_handle
,
5167 const char *alias_name
,
5168 struct policy_handle
*alias_handle
,
5169 const struct dom_sid
*domain_sid
,
5172 struct samr_CreateDomAlias r
;
5173 struct lsa_String name
;
5177 init_lsa_String(&name
, alias_name
);
5178 r
.in
.domain_handle
= domain_handle
;
5179 r
.in
.alias_name
= &name
;
5180 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5181 r
.out
.alias_handle
= alias_handle
;
5184 torture_comment(tctx
, "Testing CreateAlias (%s)\n", r
.in
.alias_name
->string
);
5186 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomAlias_r(b
, tctx
, &r
),
5187 "CreateDomAlias failed");
5189 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
5190 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
)) {
5191 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.alias_name
->string
);
5194 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.alias_name
->string
,
5195 nt_errstr(r
.out
.result
));
5200 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ALIAS_EXISTS
)) {
5201 if (!test_DeleteAlias_byname(b
, tctx
, domain_handle
, r
.in
.alias_name
->string
)) {
5204 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomAlias_r(b
, tctx
, &r
),
5205 "CreateDomAlias failed");
5208 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5209 torture_warning(tctx
, "CreateAlias failed - %s\n", nt_errstr(r
.out
.result
));
5217 if (!test_alias_ops(b
, tctx
, alias_handle
, domain_sid
)) {
5224 static bool test_ChangePassword(struct dcerpc_pipe
*p
,
5225 struct torture_context
*tctx
,
5226 const char *acct_name
,
5227 struct policy_handle
*domain_handle
, char **password
)
5230 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5236 if (!test_ChangePasswordUser(b
, tctx
, acct_name
, domain_handle
, password
)) {
5240 if (!test_ChangePasswordUser2(p
, tctx
, acct_name
, password
, 0, true)) {
5244 if (!test_OemChangePasswordUser2(p
, tctx
, acct_name
, domain_handle
, password
)) {
5248 /* test what happens when setting the old password again */
5249 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, *password
, 0, true)) {
5254 char simple_pass
[9];
5255 char *v
= generate_random_str(tctx
, 1);
5257 ZERO_STRUCT(simple_pass
);
5258 memset(simple_pass
, *v
, sizeof(simple_pass
) - 1);
5260 /* test what happens when picking a simple password */
5261 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, simple_pass
, 0, true)) {
5266 /* set samr_SetDomainInfo level 1 with min_length 5 */
5268 struct samr_QueryDomainInfo r
;
5269 union samr_DomainInfo
*info
= NULL
;
5270 struct samr_SetDomainInfo s
;
5271 uint16_t len_old
, len
;
5272 uint32_t pwd_prop_old
;
5273 int64_t min_pwd_age_old
;
5277 r
.in
.domain_handle
= domain_handle
;
5281 torture_comment(tctx
, "Testing samr_QueryDomainInfo level 1\n");
5282 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &r
),
5283 "QueryDomainInfo failed");
5284 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5288 s
.in
.domain_handle
= domain_handle
;
5292 /* remember the old min length, so we can reset it */
5293 len_old
= s
.in
.info
->info1
.min_password_length
;
5294 s
.in
.info
->info1
.min_password_length
= len
;
5295 pwd_prop_old
= s
.in
.info
->info1
.password_properties
;
5296 /* turn off password complexity checks for this test */
5297 s
.in
.info
->info1
.password_properties
&= ~DOMAIN_PASSWORD_COMPLEX
;
5299 min_pwd_age_old
= s
.in
.info
->info1
.min_password_age
;
5300 s
.in
.info
->info1
.min_password_age
= 0;
5302 torture_comment(tctx
, "Testing samr_SetDomainInfo level 1\n");
5303 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
),
5304 "SetDomainInfo failed");
5305 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
5309 torture_comment(tctx
, "calling test_ChangePasswordUser3 with too short password\n");
5311 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, len
- 1, password
, NULL
, 0, true)) {
5315 s
.in
.info
->info1
.min_password_length
= len_old
;
5316 s
.in
.info
->info1
.password_properties
= pwd_prop_old
;
5317 s
.in
.info
->info1
.min_password_age
= min_pwd_age_old
;
5319 torture_comment(tctx
, "Testing samr_SetDomainInfo level 1\n");
5320 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
),
5321 "SetDomainInfo failed");
5322 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
5329 struct samr_OpenUser r
;
5330 struct samr_QueryUserInfo q
;
5331 union samr_UserInfo
*info
;
5332 struct samr_LookupNames n
;
5333 struct policy_handle user_handle
;
5334 struct samr_Ids rids
, types
;
5336 n
.in
.domain_handle
= domain_handle
;
5338 n
.in
.names
= talloc_array(tctx
, struct lsa_String
, 1);
5339 n
.in
.names
[0].string
= acct_name
;
5341 n
.out
.types
= &types
;
5343 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupNames_r(b
, tctx
, &n
),
5344 "LookupNames failed");
5345 if (!NT_STATUS_IS_OK(n
.out
.result
)) {
5346 torture_warning(tctx
, "LookupNames failed - %s\n", nt_errstr(n
.out
.result
));
5350 r
.in
.domain_handle
= domain_handle
;
5351 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5352 r
.in
.rid
= n
.out
.rids
->ids
[0];
5353 r
.out
.user_handle
= &user_handle
;
5355 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenUser_r(b
, tctx
, &r
),
5357 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5358 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", n
.out
.rids
->ids
[0], nt_errstr(r
.out
.result
));
5362 q
.in
.user_handle
= &user_handle
;
5366 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
),
5367 "QueryUserInfo failed");
5368 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
5369 torture_warning(tctx
, "QueryUserInfo failed - %s\n", nt_errstr(q
.out
.result
));
5373 torture_comment(tctx
, "calling test_ChangePasswordUser3 with too early password change\n");
5375 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
,
5376 info
->info5
.last_password_change
, true)) {
5381 /* we change passwords twice - this has the effect of verifying
5382 they were changed correctly for the final call */
5383 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
, 0, true)) {
5387 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
, 0, true)) {
5394 static bool test_CreateUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5395 struct policy_handle
*domain_handle
,
5396 const char *user_name
,
5397 struct policy_handle
*user_handle_out
,
5398 struct dom_sid
*domain_sid
,
5399 enum torture_samr_choice which_ops
,
5400 struct cli_credentials
*machine_credentials
,
5404 TALLOC_CTX
*user_ctx
;
5406 struct samr_CreateUser r
;
5407 struct samr_QueryUserInfo q
;
5408 union samr_UserInfo
*info
;
5409 struct samr_DeleteUser d
;
5412 /* This call creates a 'normal' account - check that it really does */
5413 const uint32_t acct_flags
= ACB_NORMAL
;
5414 struct lsa_String name
;
5416 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5418 struct policy_handle user_handle
;
5419 user_ctx
= talloc_named(tctx
, 0, "test_CreateUser2 per-user context");
5420 init_lsa_String(&name
, user_name
);
5422 r
.in
.domain_handle
= domain_handle
;
5423 r
.in
.account_name
= &name
;
5424 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5425 r
.out
.user_handle
= &user_handle
;
5428 torture_comment(tctx
, "Testing CreateUser(%s)\n", r
.in
.account_name
->string
);
5430 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateUser_r(b
, user_ctx
, &r
),
5431 "CreateUser failed");
5433 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
5434 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
) || NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
5435 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.account_name
->string
);
5438 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.account_name
->string
,
5439 nt_errstr(r
.out
.result
));
5444 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_USER_EXISTS
)) {
5445 if (!test_DeleteUser_byname(b
, tctx
, domain_handle
, r
.in
.account_name
->string
)) {
5446 talloc_free(user_ctx
);
5449 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateUser_r(b
, user_ctx
, &r
),
5450 "CreateUser failed");
5453 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5454 talloc_free(user_ctx
);
5455 torture_warning(tctx
, "CreateUser failed - %s\n", nt_errstr(r
.out
.result
));
5460 if (user_handle_out
) {
5461 *user_handle_out
= user_handle
;
5467 q
.in
.user_handle
= &user_handle
;
5471 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, user_ctx
, &q
),
5472 "QueryUserInfo failed");
5473 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
5474 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
5475 q
.in
.level
, nt_errstr(q
.out
.result
));
5478 if ((info
->info16
.acct_flags
& acct_flags
) != acct_flags
) {
5479 torture_warning(tctx
, "QueryUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5480 info
->info16
.acct_flags
,
5486 if (!test_user_ops(p
, tctx
, &user_handle
, domain_handle
,
5487 domain_sid
, acct_flags
, name
.string
, which_ops
,
5488 machine_credentials
)) {
5492 if (user_handle_out
) {
5493 *user_handle_out
= user_handle
;
5495 torture_comment(tctx
, "Testing DeleteUser (createuser test)\n");
5497 d
.in
.user_handle
= &user_handle
;
5498 d
.out
.user_handle
= &user_handle
;
5500 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, user_ctx
, &d
),
5501 "DeleteUser failed");
5502 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
5503 torture_warning(tctx
, "DeleteUser failed - %s\n", nt_errstr(d
.out
.result
));
5510 talloc_free(user_ctx
);
5516 static bool test_CreateUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5517 struct policy_handle
*domain_handle
,
5518 struct dom_sid
*domain_sid
,
5519 enum torture_samr_choice which_ops
,
5520 struct cli_credentials
*machine_credentials
)
5522 struct samr_CreateUser2 r
;
5523 struct samr_QueryUserInfo q
;
5524 union samr_UserInfo
*info
;
5525 struct samr_DeleteUser d
;
5526 struct policy_handle user_handle
;
5528 struct lsa_String name
;
5531 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5534 uint32_t acct_flags
;
5535 const char *account_name
;
5537 } account_types
[] = {
5538 { ACB_NORMAL
, TEST_ACCOUNT_NAME
, NT_STATUS_OK
},
5539 { ACB_NORMAL
| ACB_DISABLED
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5540 { ACB_NORMAL
| ACB_PWNOEXP
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5541 { ACB_WSTRUST
, TEST_MACHINENAME
, NT_STATUS_OK
},
5542 { ACB_WSTRUST
| ACB_DISABLED
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5543 { ACB_WSTRUST
| ACB_PWNOEXP
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5544 { ACB_SVRTRUST
, TEST_MACHINENAME
, NT_STATUS_OK
},
5545 { ACB_SVRTRUST
| ACB_DISABLED
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5546 { ACB_SVRTRUST
| ACB_PWNOEXP
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5547 { ACB_DOMTRUST
, TEST_DOMAINNAME
, NT_STATUS_ACCESS_DENIED
},
5548 { ACB_DOMTRUST
| ACB_DISABLED
, TEST_DOMAINNAME
, NT_STATUS_INVALID_PARAMETER
},
5549 { ACB_DOMTRUST
| ACB_PWNOEXP
, TEST_DOMAINNAME
, NT_STATUS_INVALID_PARAMETER
},
5550 { 0, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5551 { ACB_DISABLED
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5552 { 0, NULL
, NT_STATUS_INVALID_PARAMETER
}
5555 for (i
= 0; account_types
[i
].account_name
; i
++) {
5556 TALLOC_CTX
*user_ctx
;
5557 uint32_t acct_flags
= account_types
[i
].acct_flags
;
5558 uint32_t access_granted
;
5559 user_ctx
= talloc_named(tctx
, 0, "test_CreateUser2 per-user context");
5560 init_lsa_String(&name
, account_types
[i
].account_name
);
5562 r
.in
.domain_handle
= domain_handle
;
5563 r
.in
.account_name
= &name
;
5564 r
.in
.acct_flags
= acct_flags
;
5565 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5566 r
.out
.user_handle
= &user_handle
;
5567 r
.out
.access_granted
= &access_granted
;
5570 torture_comment(tctx
, "Testing CreateUser2(%s, 0x%x)\n", r
.in
.account_name
->string
, acct_flags
);
5572 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateUser2_r(b
, user_ctx
, &r
),
5573 "CreateUser2 failed");
5575 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
5576 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
) || NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
5577 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.account_name
->string
);
5580 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.account_name
->string
,
5581 nt_errstr(r
.out
.result
));
5587 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_USER_EXISTS
)) {
5588 if (!test_DeleteUser_byname(b
, tctx
, domain_handle
, r
.in
.account_name
->string
)) {
5589 talloc_free(user_ctx
);
5593 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateUser2_r(b
, user_ctx
, &r
),
5594 "CreateUser2 failed");
5597 if (!NT_STATUS_EQUAL(r
.out
.result
, account_types
[i
].nt_status
)) {
5598 torture_warning(tctx
, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5599 nt_errstr(r
.out
.result
), nt_errstr(account_types
[i
].nt_status
));
5603 if (NT_STATUS_IS_OK(r
.out
.result
)) {
5604 q
.in
.user_handle
= &user_handle
;
5608 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, user_ctx
, &q
),
5609 "QueryUserInfo failed");
5610 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
5611 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
5612 q
.in
.level
, nt_errstr(q
.out
.result
));
5615 uint32_t expected_flags
= (acct_flags
| ACB_PWNOTREQ
| ACB_DISABLED
);
5616 if (acct_flags
== ACB_NORMAL
) {
5617 expected_flags
|= ACB_PW_EXPIRED
;
5619 if ((info
->info5
.acct_flags
) != expected_flags
) {
5620 torture_warning(tctx
, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5621 info
->info5
.acct_flags
,
5625 switch (acct_flags
) {
5627 if (info
->info5
.primary_gid
!= DOMAIN_RID_DCS
) {
5628 torture_warning(tctx
, "QueryUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5629 DOMAIN_RID_DCS
, info
->info5
.primary_gid
);
5634 if (info
->info5
.primary_gid
!= DOMAIN_RID_DOMAIN_MEMBERS
) {
5635 torture_warning(tctx
, "QueryUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5636 DOMAIN_RID_DOMAIN_MEMBERS
, info
->info5
.primary_gid
);
5641 if (info
->info5
.primary_gid
!= DOMAIN_RID_USERS
) {
5642 torture_warning(tctx
, "QueryUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5643 DOMAIN_RID_USERS
, info
->info5
.primary_gid
);
5650 if (!test_user_ops(p
, tctx
, &user_handle
, domain_handle
,
5651 domain_sid
, acct_flags
, name
.string
, which_ops
,
5652 machine_credentials
)) {
5656 if (!ndr_policy_handle_empty(&user_handle
)) {
5657 torture_comment(tctx
, "Testing DeleteUser (createuser2 test)\n");
5659 d
.in
.user_handle
= &user_handle
;
5660 d
.out
.user_handle
= &user_handle
;
5662 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, user_ctx
, &d
),
5663 "DeleteUser failed");
5664 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
5665 torture_warning(tctx
, "DeleteUser failed - %s\n", nt_errstr(d
.out
.result
));
5670 talloc_free(user_ctx
);
5676 static bool test_QueryAliasInfo(struct dcerpc_binding_handle
*b
,
5677 struct torture_context
*tctx
,
5678 struct policy_handle
*handle
)
5680 struct samr_QueryAliasInfo r
;
5681 union samr_AliasInfo
*info
;
5682 uint16_t levels
[] = {1, 2, 3};
5686 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5687 torture_comment(tctx
, "Testing QueryAliasInfo level %u\n", levels
[i
]);
5689 r
.in
.alias_handle
= handle
;
5690 r
.in
.level
= levels
[i
];
5693 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryAliasInfo_r(b
, tctx
, &r
),
5694 "QueryAliasInfo failed");
5695 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5696 torture_warning(tctx
, "QueryAliasInfo level %u failed - %s\n",
5697 levels
[i
], nt_errstr(r
.out
.result
));
5705 static bool test_QueryGroupInfo(struct dcerpc_binding_handle
*b
,
5706 struct torture_context
*tctx
,
5707 struct policy_handle
*handle
)
5709 struct samr_QueryGroupInfo r
;
5710 union samr_GroupInfo
*info
;
5711 uint16_t levels
[] = {1, 2, 3, 4, 5};
5715 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5716 torture_comment(tctx
, "Testing QueryGroupInfo level %u\n", levels
[i
]);
5718 r
.in
.group_handle
= handle
;
5719 r
.in
.level
= levels
[i
];
5722 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupInfo_r(b
, tctx
, &r
),
5723 "QueryGroupInfo failed");
5724 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5725 torture_warning(tctx
, "QueryGroupInfo level %u failed - %s\n",
5726 levels
[i
], nt_errstr(r
.out
.result
));
5734 static bool test_QueryGroupMember(struct dcerpc_binding_handle
*b
,
5735 struct torture_context
*tctx
,
5736 struct policy_handle
*handle
)
5738 struct samr_QueryGroupMember r
;
5739 struct samr_RidAttrArray
*rids
= NULL
;
5742 torture_comment(tctx
, "Testing QueryGroupMember\n");
5744 r
.in
.group_handle
= handle
;
5747 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupMember_r(b
, tctx
, &r
),
5748 "QueryGroupMember failed");
5749 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5750 torture_warning(tctx
, "QueryGroupMember failed - %s\n", nt_errstr(r
.out
.result
));
5758 static bool test_SetGroupInfo(struct dcerpc_binding_handle
*b
,
5759 struct torture_context
*tctx
,
5760 struct policy_handle
*handle
)
5762 struct samr_QueryGroupInfo r
;
5763 union samr_GroupInfo
*info
;
5764 struct samr_SetGroupInfo s
;
5765 uint16_t levels
[] = {1, 2, 3, 4};
5766 uint16_t set_ok
[] = {0, 1, 1, 1};
5770 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5771 torture_comment(tctx
, "Testing QueryGroupInfo level %u\n", levels
[i
]);
5773 r
.in
.group_handle
= handle
;
5774 r
.in
.level
= levels
[i
];
5777 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupInfo_r(b
, tctx
, &r
),
5778 "QueryGroupInfo failed");
5779 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5780 torture_warning(tctx
, "QueryGroupInfo level %u failed - %s\n",
5781 levels
[i
], nt_errstr(r
.out
.result
));
5785 torture_comment(tctx
, "Testing SetGroupInfo level %u\n", levels
[i
]);
5787 s
.in
.group_handle
= handle
;
5788 s
.in
.level
= levels
[i
];
5789 s
.in
.info
= *r
.out
.info
;
5792 /* disabled this, as it changes the name only from the point of view of samr,
5793 but leaves the name from the point of view of w2k3 internals (and ldap). This means
5794 the name is still reserved, so creating the old name fails, but deleting by the old name
5796 if (s
.in
.level
== 2) {
5797 init_lsa_String(&s
.in
.info
->string
, "NewName");
5801 if (s
.in
.level
== 4) {
5802 init_lsa_String(&s
.in
.info
->description
, "test description");
5805 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetGroupInfo_r(b
, tctx
, &s
),
5806 "SetGroupInfo failed");
5808 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
5809 torture_warning(tctx
, "SetGroupInfo level %u failed - %s\n",
5810 r
.in
.level
, nt_errstr(s
.out
.result
));
5815 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, s
.out
.result
)) {
5816 torture_warning(tctx
, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5817 r
.in
.level
, nt_errstr(s
.out
.result
));
5827 static bool test_QueryUserInfo(struct dcerpc_binding_handle
*b
,
5828 struct torture_context
*tctx
,
5829 struct policy_handle
*handle
)
5831 struct samr_QueryUserInfo r
;
5832 union samr_UserInfo
*info
;
5833 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5834 11, 12, 13, 14, 16, 17, 20, 21};
5838 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5839 torture_comment(tctx
, "Testing QueryUserInfo level %u\n", levels
[i
]);
5841 r
.in
.user_handle
= handle
;
5842 r
.in
.level
= levels
[i
];
5845 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
5846 "QueryUserInfo failed");
5847 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5848 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
5849 levels
[i
], nt_errstr(r
.out
.result
));
5857 static bool test_QueryUserInfo2(struct dcerpc_binding_handle
*b
,
5858 struct torture_context
*tctx
,
5859 struct policy_handle
*handle
)
5861 struct samr_QueryUserInfo2 r
;
5862 union samr_UserInfo
*info
;
5863 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5864 11, 12, 13, 14, 16, 17, 20, 21};
5868 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5869 torture_comment(tctx
, "Testing QueryUserInfo2 level %u\n", levels
[i
]);
5871 r
.in
.user_handle
= handle
;
5872 r
.in
.level
= levels
[i
];
5875 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo2_r(b
, tctx
, &r
),
5876 "QueryUserInfo2 failed");
5877 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5878 torture_warning(tctx
, "QueryUserInfo2 level %u failed - %s\n",
5879 levels
[i
], nt_errstr(r
.out
.result
));
5887 static bool test_OpenUser(struct dcerpc_binding_handle
*b
,
5888 struct torture_context
*tctx
,
5889 struct policy_handle
*handle
, uint32_t rid
)
5891 struct samr_OpenUser r
;
5892 struct policy_handle user_handle
;
5895 torture_comment(tctx
, "Testing OpenUser(%u)\n", rid
);
5897 r
.in
.domain_handle
= handle
;
5898 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5900 r
.out
.user_handle
= &user_handle
;
5902 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenUser_r(b
, tctx
, &r
),
5904 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5905 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", rid
, nt_errstr(r
.out
.result
));
5909 if (!test_QuerySecurity(b
, tctx
, &user_handle
)) {
5913 if (!test_QueryUserInfo(b
, tctx
, &user_handle
)) {
5917 if (!test_QueryUserInfo2(b
, tctx
, &user_handle
)) {
5921 if (!test_GetUserPwInfo(b
, tctx
, &user_handle
)) {
5925 if (!test_GetGroupsForUser(b
, tctx
, &user_handle
)) {
5929 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
5936 static bool test_OpenGroup(struct dcerpc_binding_handle
*b
,
5937 struct torture_context
*tctx
,
5938 struct policy_handle
*handle
, uint32_t rid
)
5940 struct samr_OpenGroup r
;
5941 struct policy_handle group_handle
;
5944 torture_comment(tctx
, "Testing OpenGroup(%u)\n", rid
);
5946 r
.in
.domain_handle
= handle
;
5947 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5949 r
.out
.group_handle
= &group_handle
;
5951 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenGroup_r(b
, tctx
, &r
),
5952 "OpenGroup failed");
5953 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5954 torture_warning(tctx
, "OpenGroup(%u) failed - %s\n", rid
, nt_errstr(r
.out
.result
));
5958 if (!torture_setting_bool(tctx
, "samba3", false)) {
5959 if (!test_QuerySecurity(b
, tctx
, &group_handle
)) {
5964 if (!test_QueryGroupInfo(b
, tctx
, &group_handle
)) {
5968 if (!test_QueryGroupMember(b
, tctx
, &group_handle
)) {
5972 if (!test_samr_handle_Close(b
, tctx
, &group_handle
)) {
5979 static bool test_OpenAlias(struct dcerpc_binding_handle
*b
,
5980 struct torture_context
*tctx
,
5981 struct policy_handle
*handle
, uint32_t rid
)
5983 struct samr_OpenAlias r
;
5984 struct policy_handle alias_handle
;
5987 torture_comment(tctx
, "Testing OpenAlias(%u)\n", rid
);
5989 r
.in
.domain_handle
= handle
;
5990 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5992 r
.out
.alias_handle
= &alias_handle
;
5994 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenAlias_r(b
, tctx
, &r
),
5995 "OpenAlias failed");
5996 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5997 torture_warning(tctx
, "OpenAlias(%u) failed - %s\n", rid
, nt_errstr(r
.out
.result
));
6001 if (!torture_setting_bool(tctx
, "samba3", false)) {
6002 if (!test_QuerySecurity(b
, tctx
, &alias_handle
)) {
6007 if (!test_QueryAliasInfo(b
, tctx
, &alias_handle
)) {
6011 if (!test_GetMembersInAlias(b
, tctx
, &alias_handle
)) {
6015 if (!test_samr_handle_Close(b
, tctx
, &alias_handle
)) {
6022 static bool check_mask(struct dcerpc_binding_handle
*b
,
6023 struct torture_context
*tctx
,
6024 struct policy_handle
*handle
, uint32_t rid
,
6025 uint32_t acct_flag_mask
)
6027 struct samr_OpenUser r
;
6028 struct samr_QueryUserInfo q
;
6029 union samr_UserInfo
*info
;
6030 struct policy_handle user_handle
;
6033 torture_comment(tctx
, "Testing OpenUser(%u)\n", rid
);
6035 r
.in
.domain_handle
= handle
;
6036 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6038 r
.out
.user_handle
= &user_handle
;
6040 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenUser_r(b
, tctx
, &r
),
6042 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6043 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", rid
, nt_errstr(r
.out
.result
));
6047 q
.in
.user_handle
= &user_handle
;
6051 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
),
6052 "QueryUserInfo failed");
6053 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
6054 torture_warning(tctx
, "QueryUserInfo level 16 failed - %s\n",
6055 nt_errstr(q
.out
.result
));
6058 if ((acct_flag_mask
& info
->info16
.acct_flags
) == 0) {
6059 torture_warning(tctx
, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
6060 acct_flag_mask
, info
->info16
.acct_flags
, rid
);
6065 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
6072 static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle
*b
,
6073 struct torture_context
*tctx
,
6074 struct policy_handle
*handle
)
6076 struct samr_EnumDomainUsers r
;
6077 uint32_t mask
, resume_handle
=0;
6080 struct samr_LookupNames n
;
6081 struct samr_LookupRids lr
;
6082 struct lsa_Strings names
;
6083 struct samr_Ids rids
, types
;
6084 struct samr_SamArray
*sam
= NULL
;
6085 uint32_t num_entries
= 0;
6087 uint32_t masks
[] = {ACB_NORMAL
, ACB_DOMTRUST
, ACB_WSTRUST
,
6088 ACB_DISABLED
, ACB_NORMAL
| ACB_DISABLED
,
6089 ACB_SVRTRUST
| ACB_DOMTRUST
| ACB_WSTRUST
,
6092 torture_comment(tctx
, "Testing EnumDomainUsers\n");
6094 for (mask_idx
=0;mask_idx
<ARRAY_SIZE(masks
);mask_idx
++) {
6095 r
.in
.domain_handle
= handle
;
6096 r
.in
.resume_handle
= &resume_handle
;
6097 r
.in
.acct_flags
= mask
= masks
[mask_idx
];
6098 r
.in
.max_size
= (uint32_t)-1;
6099 r
.out
.resume_handle
= &resume_handle
;
6100 r
.out
.num_entries
= &num_entries
;
6103 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainUsers_r(b
, tctx
, &r
),
6104 "EnumDomainUsers failed");
6105 if (!NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
) &&
6106 !NT_STATUS_IS_OK(r
.out
.result
)) {
6107 torture_warning(tctx
, "EnumDomainUsers failed - %s\n", nt_errstr(r
.out
.result
));
6111 torture_assert(tctx
, sam
, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
6113 if (sam
->count
== 0) {
6117 for (i
=0;i
<sam
->count
;i
++) {
6119 if (!check_mask(b
, tctx
, handle
, sam
->entries
[i
].idx
, mask
)) {
6122 } else if (!test_OpenUser(b
, tctx
, handle
, sam
->entries
[i
].idx
)) {
6128 torture_comment(tctx
, "Testing LookupNames\n");
6129 n
.in
.domain_handle
= handle
;
6130 n
.in
.num_names
= sam
->count
;
6131 n
.in
.names
= talloc_array(tctx
, struct lsa_String
, sam
->count
);
6133 n
.out
.types
= &types
;
6134 for (i
=0;i
<sam
->count
;i
++) {
6135 n
.in
.names
[i
].string
= sam
->entries
[i
].name
.string
;
6137 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupNames_r(b
, tctx
, &n
),
6138 "LookupNames failed");
6139 if (!NT_STATUS_IS_OK(n
.out
.result
)) {
6140 torture_warning(tctx
, "LookupNames failed - %s\n", nt_errstr(n
.out
.result
));
6145 torture_comment(tctx
, "Testing LookupRids\n");
6146 lr
.in
.domain_handle
= handle
;
6147 lr
.in
.num_rids
= sam
->count
;
6148 lr
.in
.rids
= talloc_array(tctx
, uint32_t, sam
->count
);
6149 lr
.out
.names
= &names
;
6150 lr
.out
.types
= &types
;
6151 for (i
=0;i
<sam
->count
;i
++) {
6152 lr
.in
.rids
[i
] = sam
->entries
[i
].idx
;
6154 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupRids_r(b
, tctx
, &lr
),
6155 "LookupRids failed");
6156 torture_assert_ntstatus_ok(tctx
, lr
.out
.result
, "LookupRids");
6162 try blasting the server with a bunch of sync requests
6164 static bool test_EnumDomainUsers_async(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6165 struct policy_handle
*handle
)
6167 struct samr_EnumDomainUsers r
;
6168 uint32_t resume_handle
=0;
6170 #define ASYNC_COUNT 100
6171 struct tevent_req
*req
[ASYNC_COUNT
];
6173 if (!torture_setting_bool(tctx
, "dangerous", false)) {
6174 torture_skip(tctx
, "samr async test disabled - enable dangerous tests to use\n");
6177 torture_comment(tctx
, "Testing EnumDomainUsers_async\n");
6179 r
.in
.domain_handle
= handle
;
6180 r
.in
.resume_handle
= &resume_handle
;
6181 r
.in
.acct_flags
= 0;
6182 r
.in
.max_size
= (uint32_t)-1;
6183 r
.out
.resume_handle
= &resume_handle
;
6185 for (i
=0;i
<ASYNC_COUNT
;i
++) {
6186 req
[i
] = dcerpc_samr_EnumDomainUsers_r_send(tctx
, tctx
->ev
, p
->binding_handle
, &r
);
6189 for (i
=0;i
<ASYNC_COUNT
;i
++) {
6190 tevent_req_poll(req
[i
], tctx
->ev
);
6191 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainUsers_r_recv(req
[i
], tctx
),
6192 talloc_asprintf(tctx
, "EnumDomainUsers[%d] failed - %s\n",
6193 i
, nt_errstr(r
.out
.result
)));
6196 torture_comment(tctx
, "%d async requests OK\n", i
);
6201 static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle
*b
,
6202 struct torture_context
*tctx
,
6203 struct policy_handle
*handle
)
6205 struct samr_EnumDomainGroups r
;
6206 uint32_t resume_handle
=0;
6207 struct samr_SamArray
*sam
= NULL
;
6208 uint32_t num_entries
= 0;
6211 bool universal_group_found
= false;
6213 torture_comment(tctx
, "Testing EnumDomainGroups\n");
6215 r
.in
.domain_handle
= handle
;
6216 r
.in
.resume_handle
= &resume_handle
;
6217 r
.in
.max_size
= (uint32_t)-1;
6218 r
.out
.resume_handle
= &resume_handle
;
6219 r
.out
.num_entries
= &num_entries
;
6222 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainGroups_r(b
, tctx
, &r
),
6223 "EnumDomainGroups failed");
6224 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6225 torture_warning(tctx
, "EnumDomainGroups failed - %s\n", nt_errstr(r
.out
.result
));
6233 for (i
=0;i
<sam
->count
;i
++) {
6234 if (!test_OpenGroup(b
, tctx
, handle
, sam
->entries
[i
].idx
)) {
6237 if ((ret
== true) && (strcasecmp(sam
->entries
[i
].name
.string
,
6238 "Enterprise Admins") == 0)) {
6239 universal_group_found
= true;
6243 /* when we are running this on s4 we should get back at least the
6244 * "Enterprise Admins" universal group. If we don't get a group entry
6245 * at all we probably are performing the test on the builtin domain.
6246 * So ignore this case. */
6247 if (torture_setting_bool(tctx
, "samba4", false)) {
6248 if ((sam
->count
> 0) && (!universal_group_found
)) {
6256 static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle
*b
,
6257 struct torture_context
*tctx
,
6258 struct policy_handle
*handle
)
6260 struct samr_EnumDomainAliases r
;
6261 uint32_t resume_handle
=0;
6262 struct samr_SamArray
*sam
= NULL
;
6263 uint32_t num_entries
= 0;
6267 torture_comment(tctx
, "Testing EnumDomainAliases\n");
6269 r
.in
.domain_handle
= handle
;
6270 r
.in
.resume_handle
= &resume_handle
;
6271 r
.in
.max_size
= (uint32_t)-1;
6273 r
.out
.num_entries
= &num_entries
;
6274 r
.out
.resume_handle
= &resume_handle
;
6276 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainAliases_r(b
, tctx
, &r
),
6277 "EnumDomainAliases failed");
6278 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6279 torture_warning(tctx
, "EnumDomainAliases failed - %s\n", nt_errstr(r
.out
.result
));
6287 for (i
=0;i
<sam
->count
;i
++) {
6288 if (!test_OpenAlias(b
, tctx
, handle
, sam
->entries
[i
].idx
)) {
6296 static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle
*b
,
6297 struct torture_context
*tctx
,
6298 struct policy_handle
*handle
)
6300 struct samr_GetDisplayEnumerationIndex r
;
6302 uint16_t levels
[] = {1, 2, 3, 4, 5};
6303 uint16_t ok_lvl
[] = {1, 1, 1, 0, 0};
6304 struct lsa_String name
;
6308 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6309 torture_comment(tctx
, "Testing GetDisplayEnumerationIndex level %u\n", levels
[i
]);
6311 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
6313 r
.in
.domain_handle
= handle
;
6314 r
.in
.level
= levels
[i
];
6318 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDisplayEnumerationIndex_r(b
, tctx
, &r
),
6319 "GetDisplayEnumerationIndex failed");
6322 !NT_STATUS_IS_OK(r
.out
.result
) &&
6323 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, r
.out
.result
)) {
6324 torture_warning(tctx
, "GetDisplayEnumerationIndex level %u failed - %s\n",
6325 levels
[i
], nt_errstr(r
.out
.result
));
6329 init_lsa_String(&name
, "zzzzzzzz");
6331 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDisplayEnumerationIndex_r(b
, tctx
, &r
),
6332 "GetDisplayEnumerationIndex failed");
6334 if (ok_lvl
[i
] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, r
.out
.result
)) {
6335 torture_warning(tctx
, "GetDisplayEnumerationIndex level %u failed - %s\n",
6336 levels
[i
], nt_errstr(r
.out
.result
));
6344 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle
*b
,
6345 struct torture_context
*tctx
,
6346 struct policy_handle
*handle
)
6348 struct samr_GetDisplayEnumerationIndex2 r
;
6350 uint16_t levels
[] = {1, 2, 3, 4, 5};
6351 uint16_t ok_lvl
[] = {1, 1, 1, 0, 0};
6352 struct lsa_String name
;
6356 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6357 torture_comment(tctx
, "Testing GetDisplayEnumerationIndex2 level %u\n", levels
[i
]);
6359 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
6361 r
.in
.domain_handle
= handle
;
6362 r
.in
.level
= levels
[i
];
6366 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDisplayEnumerationIndex2_r(b
, tctx
, &r
),
6367 "GetDisplayEnumerationIndex2 failed");
6369 !NT_STATUS_IS_OK(r
.out
.result
) &&
6370 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, r
.out
.result
)) {
6371 torture_warning(tctx
, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6372 levels
[i
], nt_errstr(r
.out
.result
));
6376 init_lsa_String(&name
, "zzzzzzzz");
6378 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDisplayEnumerationIndex2_r(b
, tctx
, &r
),
6379 "GetDisplayEnumerationIndex2 failed");
6380 if (ok_lvl
[i
] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, r
.out
.result
)) {
6381 torture_warning(tctx
, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6382 levels
[i
], nt_errstr(r
.out
.result
));
6390 #define STRING_EQUAL_QUERY(s1, s2, user) \
6391 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6392 /* odd, but valid */ \
6393 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6394 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
6395 #s1, user.string, s1.string, s2.string, __location__); \
6398 #define INT_EQUAL_QUERY(s1, s2, user) \
6400 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6401 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6405 static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle
*b
,
6406 struct torture_context
*tctx
,
6407 struct samr_QueryDisplayInfo
*querydisplayinfo
,
6408 bool *seen_testuser
)
6410 struct samr_OpenUser r
;
6411 struct samr_QueryUserInfo q
;
6412 union samr_UserInfo
*info
;
6413 struct policy_handle user_handle
;
6415 r
.in
.domain_handle
= querydisplayinfo
->in
.domain_handle
;
6416 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6417 for (i
= 0; ; i
++) {
6418 switch (querydisplayinfo
->in
.level
) {
6420 if (i
>= querydisplayinfo
->out
.info
->info1
.count
) {
6423 r
.in
.rid
= querydisplayinfo
->out
.info
->info1
.entries
[i
].rid
;
6426 if (i
>= querydisplayinfo
->out
.info
->info2
.count
) {
6429 r
.in
.rid
= querydisplayinfo
->out
.info
->info2
.entries
[i
].rid
;
6435 /* Not interested in validating just the account name */
6439 r
.out
.user_handle
= &user_handle
;
6441 switch (querydisplayinfo
->in
.level
) {
6444 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenUser_r(b
, tctx
, &r
),
6446 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6447 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", r
.in
.rid
, nt_errstr(r
.out
.result
));
6452 q
.in
.user_handle
= &user_handle
;
6455 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
),
6456 "QueryUserInfo failed");
6457 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6458 torture_warning(tctx
, "QueryUserInfo(%u) failed - %s\n", r
.in
.rid
, nt_errstr(r
.out
.result
));
6462 switch (querydisplayinfo
->in
.level
) {
6464 if (seen_testuser
&& strcmp(info
->info21
.account_name
.string
, TEST_ACCOUNT_NAME
) == 0) {
6465 *seen_testuser
= true;
6467 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].full_name
,
6468 info
->info21
.full_name
, info
->info21
.account_name
);
6469 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].account_name
,
6470 info
->info21
.account_name
, info
->info21
.account_name
);
6471 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].description
,
6472 info
->info21
.description
, info
->info21
.account_name
);
6473 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].rid
,
6474 info
->info21
.rid
, info
->info21
.account_name
);
6475 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].acct_flags
,
6476 info
->info21
.acct_flags
, info
->info21
.account_name
);
6480 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].account_name
,
6481 info
->info21
.account_name
, info
->info21
.account_name
);
6482 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].description
,
6483 info
->info21
.description
, info
->info21
.account_name
);
6484 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].rid
,
6485 info
->info21
.rid
, info
->info21
.account_name
);
6486 INT_EQUAL_QUERY((querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
& ~ACB_NORMAL
),
6487 info
->info21
.acct_flags
, info
->info21
.account_name
);
6489 if (!(querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
& ACB_NORMAL
)) {
6490 torture_warning(tctx
, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6491 info
->info21
.account_name
.string
);
6494 if (!(info
->info21
.acct_flags
& (ACB_WSTRUST
| ACB_SVRTRUST
))) {
6495 torture_warning(tctx
, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6496 info
->info21
.account_name
.string
,
6497 querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
,
6498 info
->info21
.acct_flags
);
6505 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
6512 static bool test_QueryDisplayInfo(struct dcerpc_binding_handle
*b
,
6513 struct torture_context
*tctx
,
6514 struct policy_handle
*handle
)
6516 struct samr_QueryDisplayInfo r
;
6517 struct samr_QueryDomainInfo dom_info
;
6518 union samr_DomainInfo
*info
= NULL
;
6520 uint16_t levels
[] = {1, 2, 3, 4, 5};
6522 bool seen_testuser
= false;
6523 uint32_t total_size
;
6524 uint32_t returned_size
;
6525 union samr_DispInfo disp_info
;
6528 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6529 torture_comment(tctx
, "Testing QueryDisplayInfo level %u\n", levels
[i
]);
6532 r
.out
.result
= STATUS_MORE_ENTRIES
;
6533 while (NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
)) {
6534 r
.in
.domain_handle
= handle
;
6535 r
.in
.level
= levels
[i
];
6536 r
.in
.max_entries
= 2;
6537 r
.in
.buf_size
= (uint32_t)-1;
6538 r
.out
.total_size
= &total_size
;
6539 r
.out
.returned_size
= &returned_size
;
6540 r
.out
.info
= &disp_info
;
6542 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &r
),
6543 "QueryDisplayInfo failed");
6544 if (!NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
) && !NT_STATUS_IS_OK(r
.out
.result
)) {
6545 torture_warning(tctx
, "QueryDisplayInfo level %u failed - %s\n",
6546 levels
[i
], nt_errstr(r
.out
.result
));
6549 switch (r
.in
.level
) {
6551 if (!test_each_DisplayInfo_user(b
, tctx
, &r
, &seen_testuser
)) {
6554 r
.in
.start_idx
+= r
.out
.info
->info1
.count
;
6557 if (!test_each_DisplayInfo_user(b
, tctx
, &r
, NULL
)) {
6560 r
.in
.start_idx
+= r
.out
.info
->info2
.count
;
6563 r
.in
.start_idx
+= r
.out
.info
->info3
.count
;
6566 r
.in
.start_idx
+= r
.out
.info
->info4
.count
;
6569 r
.in
.start_idx
+= r
.out
.info
->info5
.count
;
6573 dom_info
.in
.domain_handle
= handle
;
6574 dom_info
.in
.level
= 2;
6575 dom_info
.out
.info
= &info
;
6577 /* Check number of users returned is correct */
6578 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &dom_info
),
6579 "QueryDomainInfo failed");
6580 if (!NT_STATUS_IS_OK(dom_info
.out
.result
)) {
6581 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
6582 r
.in
.level
, nt_errstr(dom_info
.out
.result
));
6586 switch (r
.in
.level
) {
6589 if (info
->general
.num_users
< r
.in
.start_idx
) {
6590 /* On AD deployments this numbers don't match
6591 * since QueryDisplayInfo returns universal and
6592 * global groups, QueryDomainInfo only global
6594 if (torture_setting_bool(tctx
, "samba3", false)) {
6595 torture_warning(tctx
, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6596 r
.in
.start_idx
, info
->general
.num_groups
,
6597 info
->general
.domain_name
.string
);
6601 if (!seen_testuser
) {
6602 struct policy_handle user_handle
;
6603 if (NT_STATUS_IS_OK(test_OpenUser_byname(b
, tctx
, handle
, TEST_ACCOUNT_NAME
, &user_handle
))) {
6604 torture_warning(tctx
, "Didn't find test user " TEST_ACCOUNT_NAME
" in enumeration of %s\n",
6605 info
->general
.domain_name
.string
);
6607 test_samr_handle_Close(b
, tctx
, &user_handle
);
6613 if (info
->general
.num_groups
!= r
.in
.start_idx
) {
6614 /* On AD deployments this numbers don't match
6615 * since QueryDisplayInfo returns universal and
6616 * global groups, QueryDomainInfo only global
6618 if (torture_setting_bool(tctx
, "samba3", false)) {
6619 torture_warning(tctx
, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6620 r
.in
.start_idx
, info
->general
.num_groups
,
6621 info
->general
.domain_name
.string
);
6634 static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle
*b
,
6635 struct torture_context
*tctx
,
6636 struct policy_handle
*handle
)
6638 struct samr_QueryDisplayInfo2 r
;
6640 uint16_t levels
[] = {1, 2, 3, 4, 5};
6642 uint32_t total_size
;
6643 uint32_t returned_size
;
6644 union samr_DispInfo info
;
6646 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6647 torture_comment(tctx
, "Testing QueryDisplayInfo2 level %u\n", levels
[i
]);
6649 r
.in
.domain_handle
= handle
;
6650 r
.in
.level
= levels
[i
];
6652 r
.in
.max_entries
= 1000;
6653 r
.in
.buf_size
= (uint32_t)-1;
6654 r
.out
.total_size
= &total_size
;
6655 r
.out
.returned_size
= &returned_size
;
6658 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo2_r(b
, tctx
, &r
),
6659 "QueryDisplayInfo2 failed");
6660 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6661 torture_warning(tctx
, "QueryDisplayInfo2 level %u failed - %s\n",
6662 levels
[i
], nt_errstr(r
.out
.result
));
6670 static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle
*b
,
6671 struct torture_context
*tctx
,
6672 struct policy_handle
*handle
)
6674 struct samr_QueryDisplayInfo3 r
;
6676 uint16_t levels
[] = {1, 2, 3, 4, 5};
6678 uint32_t total_size
;
6679 uint32_t returned_size
;
6680 union samr_DispInfo info
;
6682 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6683 torture_comment(tctx
, "Testing QueryDisplayInfo3 level %u\n", levels
[i
]);
6685 r
.in
.domain_handle
= handle
;
6686 r
.in
.level
= levels
[i
];
6688 r
.in
.max_entries
= 1000;
6689 r
.in
.buf_size
= (uint32_t)-1;
6690 r
.out
.total_size
= &total_size
;
6691 r
.out
.returned_size
= &returned_size
;
6694 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo3_r(b
, tctx
, &r
),
6695 "QueryDisplayInfo3 failed");
6696 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6697 torture_warning(tctx
, "QueryDisplayInfo3 level %u failed - %s\n",
6698 levels
[i
], nt_errstr(r
.out
.result
));
6707 static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle
*b
,
6708 struct torture_context
*tctx
,
6709 struct policy_handle
*handle
)
6711 struct samr_QueryDisplayInfo r
;
6713 uint32_t total_size
;
6714 uint32_t returned_size
;
6715 union samr_DispInfo info
;
6717 torture_comment(tctx
, "Testing QueryDisplayInfo continuation\n");
6719 r
.in
.domain_handle
= handle
;
6722 r
.in
.max_entries
= 1;
6723 r
.in
.buf_size
= (uint32_t)-1;
6724 r
.out
.total_size
= &total_size
;
6725 r
.out
.returned_size
= &returned_size
;
6729 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &r
),
6730 "QueryDisplayInfo failed");
6731 if (NT_STATUS_IS_OK(r
.out
.result
) && *r
.out
.returned_size
!= 0) {
6732 if (r
.out
.info
->info1
.entries
[0].idx
!= r
.in
.start_idx
+ 1) {
6733 torture_warning(tctx
, "expected idx %d but got %d\n",
6735 r
.out
.info
->info1
.entries
[0].idx
);
6739 if (!NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
) &&
6740 !NT_STATUS_IS_OK(r
.out
.result
)) {
6741 torture_warning(tctx
, "QueryDisplayInfo level %u failed - %s\n",
6742 r
.in
.level
, nt_errstr(r
.out
.result
));
6747 } while ((NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
) ||
6748 NT_STATUS_IS_OK(r
.out
.result
)) &&
6749 *r
.out
.returned_size
!= 0);
6754 static bool test_QueryDomainInfo(struct dcerpc_pipe
*p
,
6755 struct torture_context
*tctx
,
6756 struct policy_handle
*handle
)
6758 struct samr_QueryDomainInfo r
;
6759 union samr_DomainInfo
*info
= NULL
;
6760 struct samr_SetDomainInfo s
;
6761 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6762 uint16_t set_ok
[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
6765 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
6766 const char *domain_comment
= talloc_asprintf(tctx
,
6767 "Tortured by Samba4 RPC-SAMR: %s",
6768 timestring(tctx
, time(NULL
)));
6770 s
.in
.domain_handle
= handle
;
6772 s
.in
.info
= talloc(tctx
, union samr_DomainInfo
);
6774 s
.in
.info
->oem
.oem_information
.string
= domain_comment
;
6775 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
),
6776 "SetDomainInfo failed");
6777 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
6778 torture_warning(tctx
, "SetDomainInfo level %u (set comment) failed - %s\n",
6779 s
.in
.level
, nt_errstr(s
.out
.result
));
6783 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6784 torture_comment(tctx
, "Testing QueryDomainInfo level %u\n", levels
[i
]);
6786 r
.in
.domain_handle
= handle
;
6787 r
.in
.level
= levels
[i
];
6790 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &r
),
6791 "QueryDomainInfo failed");
6792 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6793 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
6794 r
.in
.level
, nt_errstr(r
.out
.result
));
6799 switch (levels
[i
]) {
6801 if (strcmp(info
->general
.oem_information
.string
, domain_comment
) != 0) {
6802 torture_warning(tctx
, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6803 levels
[i
], info
->general
.oem_information
.string
, domain_comment
);
6804 if (!torture_setting_bool(tctx
, "samba3", false)) {
6808 if (!info
->general
.primary
.string
) {
6809 torture_warning(tctx
, "QueryDomainInfo level %u returned no PDC name\n",
6812 } else if (info
->general
.role
== SAMR_ROLE_DOMAIN_PDC
) {
6813 if (dcerpc_server_name(p
) && strcasecmp_m(dcerpc_server_name(p
), info
->general
.primary
.string
) != 0) {
6814 if (torture_setting_bool(tctx
, "samba3", false)) {
6815 torture_warning(tctx
, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
6816 levels
[i
], info
->general
.primary
.string
, dcerpc_server_name(p
));
6822 if (strcmp(info
->oem
.oem_information
.string
, domain_comment
) != 0) {
6823 torture_warning(tctx
, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6824 levels
[i
], info
->oem
.oem_information
.string
, domain_comment
);
6825 if (!torture_setting_bool(tctx
, "samba3", false)) {
6831 if (!info
->info6
.primary
.string
) {
6832 torture_warning(tctx
, "QueryDomainInfo level %u returned no PDC name\n",
6838 if (strcmp(info
->general2
.general
.oem_information
.string
, domain_comment
) != 0) {
6839 torture_warning(tctx
, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
6840 levels
[i
], info
->general2
.general
.oem_information
.string
, domain_comment
);
6841 if (!torture_setting_bool(tctx
, "samba3", false)) {
6848 torture_comment(tctx
, "Testing SetDomainInfo level %u\n", levels
[i
]);
6850 s
.in
.domain_handle
= handle
;
6851 s
.in
.level
= levels
[i
];
6854 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
),
6855 "SetDomainInfo failed");
6857 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
6858 torture_warning(tctx
, "SetDomainInfo level %u failed - %s\n",
6859 r
.in
.level
, nt_errstr(s
.out
.result
));
6864 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, s
.out
.result
)) {
6865 torture_warning(tctx
, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6866 r
.in
.level
, nt_errstr(s
.out
.result
));
6872 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &r
),
6873 "QueryDomainInfo failed");
6874 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6875 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
6876 r
.in
.level
, nt_errstr(r
.out
.result
));
6886 static bool test_QueryDomainInfo2(struct dcerpc_binding_handle
*b
,
6887 struct torture_context
*tctx
,
6888 struct policy_handle
*handle
)
6890 struct samr_QueryDomainInfo2 r
;
6891 union samr_DomainInfo
*info
= NULL
;
6892 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6896 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6897 torture_comment(tctx
, "Testing QueryDomainInfo2 level %u\n", levels
[i
]);
6899 r
.in
.domain_handle
= handle
;
6900 r
.in
.level
= levels
[i
];
6903 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo2_r(b
, tctx
, &r
),
6904 "QueryDomainInfo2 failed");
6905 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6906 torture_warning(tctx
, "QueryDomainInfo2 level %u failed - %s\n",
6907 r
.in
.level
, nt_errstr(r
.out
.result
));
6916 /* Test whether querydispinfo level 5 and enumdomgroups return the same
6917 set of group names. */
6918 static bool test_GroupList(struct dcerpc_binding_handle
*b
,
6919 struct torture_context
*tctx
,
6920 struct dom_sid
*domain_sid
,
6921 struct policy_handle
*handle
)
6923 struct samr_EnumDomainGroups q1
;
6924 struct samr_QueryDisplayInfo q2
;
6926 uint32_t resume_handle
=0;
6927 struct samr_SamArray
*sam
= NULL
;
6928 uint32_t num_entries
= 0;
6931 uint32_t total_size
;
6932 uint32_t returned_size
;
6933 union samr_DispInfo info
;
6936 const char **names
= NULL
;
6938 bool builtin_domain
= dom_sid_compare(domain_sid
,
6939 &global_sid_Builtin
) == 0;
6941 torture_comment(tctx
, "Testing coherency of querydispinfo vs enumdomgroups\n");
6943 q1
.in
.domain_handle
= handle
;
6944 q1
.in
.resume_handle
= &resume_handle
;
6946 q1
.out
.resume_handle
= &resume_handle
;
6947 q1
.out
.num_entries
= &num_entries
;
6950 status
= STATUS_MORE_ENTRIES
;
6951 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
6952 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainGroups_r(b
, tctx
, &q1
),
6953 "EnumDomainGroups failed");
6954 status
= q1
.out
.result
;
6956 if (!NT_STATUS_IS_OK(status
) &&
6957 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
6960 for (i
=0; i
<*q1
.out
.num_entries
; i
++) {
6961 add_string_to_array(tctx
,
6962 sam
->entries
[i
].name
.string
,
6963 &names
, &num_names
);
6967 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomainGroups");
6969 torture_assert(tctx
, sam
, "EnumDomainGroups failed to return sam");
6971 if (builtin_domain
) {
6972 torture_assert(tctx
, num_names
== 0,
6973 "EnumDomainGroups shouldn't return any group in the builtin domain!");
6976 q2
.in
.domain_handle
= handle
;
6978 q2
.in
.start_idx
= 0;
6979 q2
.in
.max_entries
= 5;
6980 q2
.in
.buf_size
= (uint32_t)-1;
6981 q2
.out
.total_size
= &total_size
;
6982 q2
.out
.returned_size
= &returned_size
;
6983 q2
.out
.info
= &info
;
6985 status
= STATUS_MORE_ENTRIES
;
6986 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
6987 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &q2
),
6988 "QueryDisplayInfo failed");
6989 status
= q2
.out
.result
;
6990 if (!NT_STATUS_IS_OK(status
) &&
6991 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
6994 for (i
=0; i
<q2
.out
.info
->info5
.count
; i
++) {
6996 const char *name
= q2
.out
.info
->info5
.entries
[i
].account_name
.string
;
6998 for (j
=0; j
<num_names
; j
++) {
6999 if (names
[j
] == NULL
)
7001 if (strequal(names
[j
], name
)) {
7008 if ((!found
) && (!builtin_domain
)) {
7009 torture_warning(tctx
, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
7014 q2
.in
.start_idx
+= q2
.out
.info
->info5
.count
;
7017 if (!NT_STATUS_IS_OK(status
)) {
7018 torture_warning(tctx
, "QueryDisplayInfo level 5 failed - %s\n",
7023 if (builtin_domain
) {
7024 torture_assert(tctx
, q2
.in
.start_idx
!= 0,
7025 "QueryDisplayInfo should return all domain groups also on the builtin domain handle!");
7028 for (i
=0; i
<num_names
; i
++) {
7029 if (names
[i
] != NULL
) {
7030 torture_warning(tctx
, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
7039 static bool test_DeleteDomainGroup(struct dcerpc_binding_handle
*b
,
7040 struct torture_context
*tctx
,
7041 struct policy_handle
*group_handle
)
7043 struct samr_DeleteDomainGroup d
;
7045 torture_comment(tctx
, "Testing DeleteDomainGroup\n");
7047 d
.in
.group_handle
= group_handle
;
7048 d
.out
.group_handle
= group_handle
;
7050 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteDomainGroup_r(b
, tctx
, &d
),
7051 "DeleteDomainGroup failed");
7052 torture_assert_ntstatus_ok(tctx
, d
.out
.result
, "DeleteDomainGroup");
7057 static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle
*b
,
7058 struct torture_context
*tctx
,
7059 struct policy_handle
*domain_handle
)
7061 struct samr_TestPrivateFunctionsDomain r
;
7064 torture_comment(tctx
, "Testing TestPrivateFunctionsDomain\n");
7066 r
.in
.domain_handle
= domain_handle
;
7068 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_TestPrivateFunctionsDomain_r(b
, tctx
, &r
),
7069 "TestPrivateFunctionsDomain failed");
7070 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_NOT_IMPLEMENTED
, "TestPrivateFunctionsDomain");
7075 static bool test_RidToSid(struct dcerpc_binding_handle
*b
,
7076 struct torture_context
*tctx
,
7077 struct dom_sid
*domain_sid
,
7078 struct policy_handle
*domain_handle
)
7080 struct samr_RidToSid r
;
7082 struct dom_sid
*calc_sid
, *out_sid
;
7083 int rids
[] = { 0, 42, 512, 10200 };
7086 for (i
=0;i
<ARRAY_SIZE(rids
);i
++) {
7087 torture_comment(tctx
, "Testing RidToSid\n");
7089 calc_sid
= dom_sid_dup(tctx
, domain_sid
);
7090 r
.in
.domain_handle
= domain_handle
;
7092 r
.out
.sid
= &out_sid
;
7094 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RidToSid_r(b
, tctx
, &r
),
7096 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
7097 torture_warning(tctx
, "RidToSid for %d failed - %s\n", rids
[i
], nt_errstr(r
.out
.result
));
7100 calc_sid
= dom_sid_add_rid(calc_sid
, calc_sid
, rids
[i
]);
7102 if (!dom_sid_equal(calc_sid
, out_sid
)) {
7103 torture_warning(tctx
, "RidToSid for %d failed - got %s, expected %s\n", rids
[i
],
7104 dom_sid_string(tctx
, out_sid
),
7105 dom_sid_string(tctx
, calc_sid
));
7114 static bool test_GetBootKeyInformation(struct dcerpc_binding_handle
*b
,
7115 struct torture_context
*tctx
,
7116 struct policy_handle
*domain_handle
)
7118 struct samr_GetBootKeyInformation r
;
7120 uint32_t unknown
= 0;
7123 torture_comment(tctx
, "Testing GetBootKeyInformation\n");
7125 r
.in
.domain_handle
= domain_handle
;
7126 r
.out
.unknown
= &unknown
;
7128 status
= dcerpc_samr_GetBootKeyInformation_r(b
, tctx
, &r
);
7129 if (NT_STATUS_IS_OK(status
) && !NT_STATUS_IS_OK(r
.out
.result
)) {
7130 status
= r
.out
.result
;
7132 if (!NT_STATUS_IS_OK(status
)) {
7133 /* w2k3 seems to fail this sometimes and pass it sometimes */
7134 torture_comment(tctx
, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status
));
7140 static bool test_AddGroupMember(struct dcerpc_binding_handle
*b
,
7141 struct torture_context
*tctx
,
7142 struct policy_handle
*domain_handle
,
7143 struct policy_handle
*group_handle
)
7146 struct samr_AddGroupMember r
;
7147 struct samr_DeleteGroupMember d
;
7148 struct samr_QueryGroupMember q
;
7149 struct samr_RidAttrArray
*rids
= NULL
;
7150 struct samr_SetMemberAttributesOfGroup s
;
7152 bool found_member
= false;
7155 status
= test_LookupName(b
, tctx
, domain_handle
, TEST_ACCOUNT_NAME
, &rid
);
7156 torture_assert_ntstatus_ok(tctx
, status
, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME
);
7158 r
.in
.group_handle
= group_handle
;
7160 r
.in
.flags
= 0; /* ??? */
7162 torture_comment(tctx
, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
7164 d
.in
.group_handle
= group_handle
;
7167 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteGroupMember_r(b
, tctx
, &d
),
7168 "DeleteGroupMember failed");
7169 torture_assert_ntstatus_equal(tctx
, NT_STATUS_MEMBER_NOT_IN_GROUP
, d
.out
.result
, "DeleteGroupMember");
7171 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddGroupMember_r(b
, tctx
, &r
),
7172 "AddGroupMember failed");
7173 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "AddGroupMember");
7175 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddGroupMember_r(b
, tctx
, &r
),
7176 "AddGroupMember failed");
7177 torture_assert_ntstatus_equal(tctx
, NT_STATUS_MEMBER_IN_GROUP
, r
.out
.result
, "AddGroupMember");
7179 if (torture_setting_bool(tctx
, "samba4", false) ||
7180 torture_setting_bool(tctx
, "samba3", false)) {
7181 torture_comment(tctx
, "skipping SetMemberAttributesOfGroup test against Samba\n");
7183 /* this one is quite strange. I am using random inputs in the
7184 hope of triggering an error that might give us a clue */
7186 s
.in
.group_handle
= group_handle
;
7187 s
.in
.unknown1
= random();
7188 s
.in
.unknown2
= random();
7190 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetMemberAttributesOfGroup_r(b
, tctx
, &s
),
7191 "SetMemberAttributesOfGroup failed");
7192 torture_assert_ntstatus_ok(tctx
, s
.out
.result
, "SetMemberAttributesOfGroup");
7195 q
.in
.group_handle
= group_handle
;
7198 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupMember_r(b
, tctx
, &q
),
7199 "QueryGroupMember failed");
7200 torture_assert_ntstatus_ok(tctx
, q
.out
.result
, "QueryGroupMember");
7201 torture_assert(tctx
, rids
, "QueryGroupMember did not fill in rids structure");
7203 for (i
=0; i
< rids
->count
; i
++) {
7204 if (rids
->rids
[i
] == rid
) {
7205 found_member
= true;
7209 torture_assert(tctx
, found_member
, "QueryGroupMember did not list newly added member");
7211 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteGroupMember_r(b
, tctx
, &d
),
7212 "DeleteGroupMember failed");
7213 torture_assert_ntstatus_ok(tctx
, d
.out
.result
, "DeleteGroupMember");
7216 found_member
= false;
7218 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupMember_r(b
, tctx
, &q
),
7219 "QueryGroupMember failed");
7220 torture_assert_ntstatus_ok(tctx
, q
.out
.result
, "QueryGroupMember");
7221 torture_assert(tctx
, rids
, "QueryGroupMember did not fill in rids structure");
7223 for (i
=0; i
< rids
->count
; i
++) {
7224 if (rids
->rids
[i
] == rid
) {
7225 found_member
= true;
7229 torture_assert(tctx
, !found_member
, "QueryGroupMember does still list removed member");
7231 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddGroupMember_r(b
, tctx
, &r
),
7232 "AddGroupMember failed");
7233 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "AddGroupMember");
7239 static bool test_CreateDomainGroup(struct dcerpc_binding_handle
*b
,
7240 struct torture_context
*tctx
,
7241 struct policy_handle
*domain_handle
,
7242 const char *group_name
,
7243 struct policy_handle
*group_handle
,
7244 struct dom_sid
*domain_sid
,
7247 struct samr_CreateDomainGroup r
;
7249 struct lsa_String name
;
7252 init_lsa_String(&name
, group_name
);
7254 r
.in
.domain_handle
= domain_handle
;
7256 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7257 r
.out
.group_handle
= group_handle
;
7260 torture_comment(tctx
, "Testing CreateDomainGroup(%s)\n", r
.in
.name
->string
);
7262 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomainGroup_r(b
, tctx
, &r
),
7263 "CreateDomainGroup failed");
7265 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
7266 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
)) {
7267 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.name
->string
);
7270 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.name
->string
,
7271 nt_errstr(r
.out
.result
));
7276 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_GROUP_EXISTS
)) {
7277 if (!test_DeleteGroup_byname(b
, tctx
, domain_handle
, r
.in
.name
->string
)) {
7278 torture_warning(tctx
, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r
.in
.name
->string
,
7279 nt_errstr(r
.out
.result
));
7282 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomainGroup_r(b
, tctx
, &r
),
7283 "CreateDomainGroup failed");
7285 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_USER_EXISTS
)) {
7286 if (!test_DeleteUser_byname(b
, tctx
, domain_handle
, r
.in
.name
->string
)) {
7288 torture_warning(tctx
, "CreateDomainGroup failed: Could not delete user %s - %s\n", r
.in
.name
->string
,
7289 nt_errstr(r
.out
.result
));
7292 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomainGroup_r(b
, tctx
, &r
),
7293 "CreateDomainGroup failed");
7295 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "CreateDomainGroup");
7301 if (!test_AddGroupMember(b
, tctx
, domain_handle
, group_handle
)) {
7302 torture_warning(tctx
, "CreateDomainGroup failed - %s\n", nt_errstr(r
.out
.result
));
7306 if (!test_SetGroupInfo(b
, tctx
, group_handle
)) {
7315 its not totally clear what this does. It seems to accept any sid you like.
7317 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle
*b
,
7318 struct torture_context
*tctx
,
7319 struct policy_handle
*domain_handle
)
7321 struct samr_RemoveMemberFromForeignDomain r
;
7323 r
.in
.domain_handle
= domain_handle
;
7324 r
.in
.sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-12-34-56-78");
7326 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RemoveMemberFromForeignDomain_r(b
, tctx
, &r
),
7327 "RemoveMemberFromForeignDomain failed");
7328 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "RemoveMemberFromForeignDomain");
7333 static bool test_EnumDomainUsers(struct dcerpc_binding_handle
*b
,
7334 struct torture_context
*tctx
,
7335 struct policy_handle
*domain_handle
,
7336 uint32_t *total_num_entries_p
)
7339 struct samr_EnumDomainUsers r
;
7340 uint32_t resume_handle
= 0;
7341 uint32_t num_entries
= 0;
7342 uint32_t total_num_entries
= 0;
7343 struct samr_SamArray
*sam
;
7345 r
.in
.domain_handle
= domain_handle
;
7346 r
.in
.acct_flags
= 0;
7347 r
.in
.max_size
= (uint32_t)-1;
7348 r
.in
.resume_handle
= &resume_handle
;
7351 r
.out
.num_entries
= &num_entries
;
7352 r
.out
.resume_handle
= &resume_handle
;
7354 torture_comment(tctx
, "Testing EnumDomainUsers\n");
7357 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainUsers_r(b
, tctx
, &r
),
7358 "EnumDomainUsers failed");
7359 if (NT_STATUS_IS_ERR(r
.out
.result
)) {
7360 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
7361 "failed to enumerate users");
7363 status
= r
.out
.result
;
7365 total_num_entries
+= num_entries
;
7366 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7368 if (total_num_entries_p
) {
7369 *total_num_entries_p
= total_num_entries
;
7375 static bool test_EnumDomainGroups(struct dcerpc_binding_handle
*b
,
7376 struct torture_context
*tctx
,
7377 struct policy_handle
*domain_handle
,
7378 uint32_t *total_num_entries_p
)
7381 struct samr_EnumDomainGroups r
;
7382 uint32_t resume_handle
= 0;
7383 uint32_t num_entries
= 0;
7384 uint32_t total_num_entries
= 0;
7385 struct samr_SamArray
*sam
;
7387 r
.in
.domain_handle
= domain_handle
;
7388 r
.in
.max_size
= (uint32_t)-1;
7389 r
.in
.resume_handle
= &resume_handle
;
7392 r
.out
.num_entries
= &num_entries
;
7393 r
.out
.resume_handle
= &resume_handle
;
7395 torture_comment(tctx
, "Testing EnumDomainGroups\n");
7398 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainGroups_r(b
, tctx
, &r
),
7399 "EnumDomainGroups failed");
7400 if (NT_STATUS_IS_ERR(r
.out
.result
)) {
7401 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
7402 "failed to enumerate groups");
7404 status
= r
.out
.result
;
7406 total_num_entries
+= num_entries
;
7407 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7409 if (total_num_entries_p
) {
7410 *total_num_entries_p
= total_num_entries
;
7416 static bool test_EnumDomainAliases(struct dcerpc_binding_handle
*b
,
7417 struct torture_context
*tctx
,
7418 struct policy_handle
*domain_handle
,
7419 uint32_t *total_num_entries_p
)
7422 struct samr_EnumDomainAliases r
;
7423 uint32_t resume_handle
= 0;
7424 uint32_t num_entries
= 0;
7425 uint32_t total_num_entries
= 0;
7426 struct samr_SamArray
*sam
;
7428 r
.in
.domain_handle
= domain_handle
;
7429 r
.in
.max_size
= (uint32_t)-1;
7430 r
.in
.resume_handle
= &resume_handle
;
7433 r
.out
.num_entries
= &num_entries
;
7434 r
.out
.resume_handle
= &resume_handle
;
7436 torture_comment(tctx
, "Testing EnumDomainAliases\n");
7439 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainAliases_r(b
, tctx
, &r
),
7440 "EnumDomainAliases failed");
7441 if (NT_STATUS_IS_ERR(r
.out
.result
)) {
7442 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
7443 "failed to enumerate aliases");
7445 status
= r
.out
.result
;
7447 total_num_entries
+= num_entries
;
7448 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7450 if (total_num_entries_p
) {
7451 *total_num_entries_p
= total_num_entries
;
7457 static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle
*b
,
7458 struct torture_context
*tctx
,
7459 struct policy_handle
*handle
,
7461 uint32_t *total_num_entries_p
)
7464 struct samr_QueryDisplayInfo r
;
7465 uint32_t total_num_entries
= 0;
7467 r
.in
.domain_handle
= handle
;
7470 r
.in
.max_entries
= (uint32_t)-1;
7471 r
.in
.buf_size
= (uint32_t)-1;
7473 torture_comment(tctx
, "Testing QueryDisplayInfo\n");
7476 uint32_t total_size
;
7477 uint32_t returned_size
;
7478 union samr_DispInfo info
;
7480 r
.out
.total_size
= &total_size
;
7481 r
.out
.returned_size
= &returned_size
;
7484 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &r
),
7485 "failed to query displayinfo");
7486 if (NT_STATUS_IS_ERR(r
.out
.result
)) {
7487 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
7488 "failed to query displayinfo");
7490 status
= r
.out
.result
;
7492 if (*r
.out
.returned_size
== 0) {
7496 switch (r
.in
.level
) {
7498 total_num_entries
+= info
.info1
.count
;
7499 r
.in
.start_idx
+= info
.info1
.entries
[info
.info1
.count
- 1].idx
+ 1;
7502 total_num_entries
+= info
.info2
.count
;
7503 r
.in
.start_idx
+= info
.info2
.entries
[info
.info2
.count
- 1].idx
+ 1;
7506 total_num_entries
+= info
.info3
.count
;
7507 r
.in
.start_idx
+= info
.info3
.entries
[info
.info3
.count
- 1].idx
+ 1;
7510 total_num_entries
+= info
.info4
.count
;
7511 r
.in
.start_idx
+= info
.info4
.entries
[info
.info4
.count
- 1].idx
+ 1;
7514 total_num_entries
+= info
.info5
.count
;
7515 r
.in
.start_idx
+= info
.info5
.entries
[info
.info5
.count
- 1].idx
+ 1;
7521 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7523 if (total_num_entries_p
) {
7524 *total_num_entries_p
= total_num_entries
;
7530 static bool test_ManyObjects(struct dcerpc_pipe
*p
,
7531 struct torture_context
*tctx
,
7532 struct policy_handle
*domain_handle
,
7533 struct dom_sid
*domain_sid
,
7534 struct torture_samr_context
*ctx
)
7536 uint32_t num_total
= ctx
->num_objects_large_dc
;
7537 uint32_t num_enum
= 0;
7538 uint32_t num_disp
= 0;
7539 uint32_t num_created
= 0;
7540 uint32_t num_anounced
= 0;
7542 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7544 struct policy_handle
*handles
= talloc_zero_array(tctx
, struct policy_handle
, num_total
);
7549 struct samr_QueryDomainInfo2 r
;
7550 union samr_DomainInfo
*info
;
7551 r
.in
.domain_handle
= domain_handle
;
7555 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo2_r(b
, tctx
, &r
),
7556 "QueryDomainInfo2 failed");
7557 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
7558 "failed to query domain info");
7560 switch (ctx
->choice
) {
7561 case TORTURE_SAMR_MANY_ACCOUNTS
:
7562 num_anounced
= info
->general
.num_users
;
7564 case TORTURE_SAMR_MANY_GROUPS
:
7565 num_anounced
= info
->general
.num_groups
;
7567 case TORTURE_SAMR_MANY_ALIASES
:
7568 num_anounced
= info
->general
.num_aliases
;
7577 for (i
=0; i
< num_total
; i
++) {
7579 const char *name
= NULL
;
7581 switch (ctx
->choice
) {
7582 case TORTURE_SAMR_MANY_ACCOUNTS
:
7583 name
= talloc_asprintf(tctx
, "%s%04d", TEST_ACCOUNT_NAME
, i
);
7584 torture_assert(tctx
,
7585 test_CreateUser(p
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, 0, NULL
, false),
7586 "failed to create user");
7588 case TORTURE_SAMR_MANY_GROUPS
:
7589 name
= talloc_asprintf(tctx
, "%s%04d", TEST_GROUPNAME
, i
);
7590 torture_assert(tctx
,
7591 test_CreateDomainGroup(b
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, false),
7592 "failed to create group");
7594 case TORTURE_SAMR_MANY_ALIASES
:
7595 name
= talloc_asprintf(tctx
, "%s%04d", TEST_ALIASNAME
, i
);
7596 torture_assert(tctx
,
7597 test_CreateAlias(b
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, false),
7598 "failed to create alias");
7603 if (!ndr_policy_handle_empty(&handles
[i
])) {
7610 switch (ctx
->choice
) {
7611 case TORTURE_SAMR_MANY_ACCOUNTS
:
7612 torture_assert(tctx
,
7613 test_EnumDomainUsers(b
, tctx
, domain_handle
, &num_enum
),
7614 "failed to enum users");
7616 case TORTURE_SAMR_MANY_GROUPS
:
7617 torture_assert(tctx
,
7618 test_EnumDomainGroups(b
, tctx
, domain_handle
, &num_enum
),
7619 "failed to enum groups");
7621 case TORTURE_SAMR_MANY_ALIASES
:
7622 torture_assert(tctx
,
7623 test_EnumDomainAliases(b
, tctx
, domain_handle
, &num_enum
),
7624 "failed to enum aliases");
7632 switch (ctx
->choice
) {
7633 case TORTURE_SAMR_MANY_ACCOUNTS
:
7634 torture_assert(tctx
,
7635 test_QueryDisplayInfo_level(b
, tctx
, domain_handle
, 1, &num_disp
),
7636 "failed to query display info");
7638 case TORTURE_SAMR_MANY_GROUPS
:
7639 torture_assert(tctx
,
7640 test_QueryDisplayInfo_level(b
, tctx
, domain_handle
, 3, &num_disp
),
7641 "failed to query display info");
7643 case TORTURE_SAMR_MANY_ALIASES
:
7644 /* no aliases in dispinfo */
7650 /* close or delete */
7652 for (i
=0; i
< num_total
; i
++) {
7654 if (ndr_policy_handle_empty(&handles
[i
])) {
7658 if (torture_setting_bool(tctx
, "samba3", false)) {
7659 torture_assert(tctx
,
7660 test_samr_handle_Close(b
, tctx
, &handles
[i
]),
7661 "failed to close handle");
7663 switch (ctx
->choice
) {
7664 case TORTURE_SAMR_MANY_ACCOUNTS
:
7665 torture_assert(tctx
,
7666 test_DeleteUser(b
, tctx
, &handles
[i
]),
7667 "failed to delete user");
7669 case TORTURE_SAMR_MANY_GROUPS
:
7670 torture_assert(tctx
,
7671 test_DeleteDomainGroup(b
, tctx
, &handles
[i
]),
7672 "failed to delete group");
7674 case TORTURE_SAMR_MANY_ALIASES
:
7675 torture_assert(tctx
,
7676 test_DeleteAlias(b
, tctx
, &handles
[i
]),
7677 "failed to delete alias");
7685 talloc_free(handles
);
7687 if (ctx
->choice
== TORTURE_SAMR_MANY_ACCOUNTS
&& num_enum
!= num_anounced
+ num_created
) {
7688 torture_comment(tctx
,
7689 "unexpected number of results (%u) returned in enum call, expected %u\n",
7690 num_enum
, num_anounced
+ num_created
);
7692 torture_comment(tctx
,
7693 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
7694 num_disp
, num_anounced
+ num_created
);
7700 static bool test_Connect(struct dcerpc_binding_handle
*b
,
7701 struct torture_context
*tctx
,
7702 struct policy_handle
*handle
);
7704 static bool test_OpenDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7705 struct torture_samr_context
*ctx
, struct dom_sid
*sid
)
7707 struct samr_OpenDomain r
;
7708 struct policy_handle domain_handle
;
7709 struct policy_handle alias_handle
;
7710 struct policy_handle user_handle
;
7711 struct policy_handle group_handle
;
7713 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7715 ZERO_STRUCT(alias_handle
);
7716 ZERO_STRUCT(user_handle
);
7717 ZERO_STRUCT(group_handle
);
7718 ZERO_STRUCT(domain_handle
);
7720 torture_comment(tctx
, "Testing OpenDomain of %s\n", dom_sid_string(tctx
, sid
));
7722 r
.in
.connect_handle
= &ctx
->handle
;
7723 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7725 r
.out
.domain_handle
= &domain_handle
;
7727 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenDomain_r(b
, tctx
, &r
),
7728 "OpenDomain failed");
7729 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "OpenDomain failed");
7731 /* run the domain tests with the main handle closed - this tests
7732 the servers reference counting */
7733 torture_assert(tctx
, test_samr_handle_Close(b
, tctx
, &ctx
->handle
), "Failed to close SAMR handle");
7735 switch (ctx
->choice
) {
7736 case TORTURE_SAMR_PASSWORDS
:
7737 case TORTURE_SAMR_USER_PRIVILEGES
:
7738 if (!torture_setting_bool(tctx
, "samba3", false)) {
7739 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, NULL
);
7741 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
7743 torture_warning(tctx
, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7746 case TORTURE_SAMR_USER_ATTRIBUTES
:
7747 if (!torture_setting_bool(tctx
, "samba3", false)) {
7748 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, NULL
);
7750 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
7751 /* This test needs 'complex' users to validate */
7752 ret
&= test_QueryDisplayInfo(b
, tctx
, &domain_handle
);
7754 torture_warning(tctx
, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7757 case TORTURE_SAMR_PASSWORDS_PWDLASTSET
:
7758 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
:
7759 case TORTURE_SAMR_PASSWORDS_LOCKOUT
:
7760 if (!torture_setting_bool(tctx
, "samba3", false)) {
7761 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, ctx
->machine_credentials
);
7763 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, ctx
->machine_credentials
, true);
7765 torture_warning(tctx
, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7768 case TORTURE_SAMR_MANY_ACCOUNTS
:
7769 case TORTURE_SAMR_MANY_GROUPS
:
7770 case TORTURE_SAMR_MANY_ALIASES
:
7771 ret
&= test_ManyObjects(p
, tctx
, &domain_handle
, sid
, ctx
);
7773 torture_warning(tctx
, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7776 case TORTURE_SAMR_OTHER
:
7777 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
7779 torture_warning(tctx
, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx
, sid
));
7781 if (!torture_setting_bool(tctx
, "samba3", false)) {
7782 ret
&= test_QuerySecurity(b
, tctx
, &domain_handle
);
7784 ret
&= test_RemoveMemberFromForeignDomain(b
, tctx
, &domain_handle
);
7785 ret
&= test_CreateAlias(b
, tctx
, &domain_handle
, TEST_ALIASNAME
, &alias_handle
, sid
, true);
7786 ret
&= test_CreateDomainGroup(b
, tctx
, &domain_handle
, TEST_GROUPNAME
, &group_handle
, sid
, true);
7787 ret
&= test_GetAliasMembership(b
, tctx
, &domain_handle
);
7788 ret
&= test_QueryDomainInfo(p
, tctx
, &domain_handle
);
7789 ret
&= test_QueryDomainInfo2(b
, tctx
, &domain_handle
);
7790 ret
&= test_EnumDomainUsers_all(b
, tctx
, &domain_handle
);
7791 ret
&= test_EnumDomainUsers_async(p
, tctx
, &domain_handle
);
7792 ret
&= test_EnumDomainGroups_all(b
, tctx
, &domain_handle
);
7793 ret
&= test_EnumDomainAliases_all(b
, tctx
, &domain_handle
);
7794 ret
&= test_QueryDisplayInfo2(b
, tctx
, &domain_handle
);
7795 ret
&= test_QueryDisplayInfo3(b
, tctx
, &domain_handle
);
7796 ret
&= test_QueryDisplayInfo_continue(b
, tctx
, &domain_handle
);
7798 if (torture_setting_bool(tctx
, "samba4", false)) {
7799 torture_comment(tctx
, "skipping GetDisplayEnumerationIndex test against Samba4\n");
7801 ret
&= test_GetDisplayEnumerationIndex(b
, tctx
, &domain_handle
);
7802 ret
&= test_GetDisplayEnumerationIndex2(b
, tctx
, &domain_handle
);
7804 ret
&= test_GroupList(b
, tctx
, sid
, &domain_handle
);
7805 ret
&= test_TestPrivateFunctionsDomain(b
, tctx
, &domain_handle
);
7806 ret
&= test_RidToSid(b
, tctx
, sid
, &domain_handle
);
7807 ret
&= test_GetBootKeyInformation(b
, tctx
, &domain_handle
);
7809 torture_comment(tctx
, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7814 if (!ndr_policy_handle_empty(&user_handle
) &&
7815 !test_DeleteUser(b
, tctx
, &user_handle
)) {
7819 if (!ndr_policy_handle_empty(&alias_handle
) &&
7820 !test_DeleteAlias(b
, tctx
, &alias_handle
)) {
7824 if (!ndr_policy_handle_empty(&group_handle
) &&
7825 !test_DeleteDomainGroup(b
, tctx
, &group_handle
)) {
7829 torture_assert(tctx
, test_samr_handle_Close(b
, tctx
, &domain_handle
), "Failed to close SAMR domain handle");
7831 torture_assert(tctx
, test_Connect(b
, tctx
, &ctx
->handle
), "Faile to re-connect SAMR handle");
7832 /* reconnect the main handle */
7835 torture_warning(tctx
, "Testing domain %s failed!\n", dom_sid_string(tctx
, sid
));
7841 static bool test_LookupDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7842 struct torture_samr_context
*ctx
, const char *domain
)
7844 struct samr_LookupDomain r
;
7845 struct dom_sid2
*sid
= NULL
;
7846 struct lsa_String n1
;
7847 struct lsa_String n2
;
7849 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7851 torture_comment(tctx
, "Testing LookupDomain(%s)\n", domain
);
7853 /* check for correct error codes */
7854 r
.in
.connect_handle
= &ctx
->handle
;
7855 r
.in
.domain_name
= &n2
;
7859 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupDomain_r(b
, tctx
, &r
),
7860 "LookupDomain failed");
7861 torture_assert_ntstatus_equal(tctx
, NT_STATUS_INVALID_PARAMETER
, r
.out
.result
, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
7863 init_lsa_String(&n2
, "xxNODOMAINxx");
7865 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupDomain_r(b
, tctx
, &r
),
7866 "LookupDomain failed");
7867 torture_assert_ntstatus_equal(tctx
, NT_STATUS_NO_SUCH_DOMAIN
, r
.out
.result
, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
7869 r
.in
.connect_handle
= &ctx
->handle
;
7871 init_lsa_String(&n1
, domain
);
7872 r
.in
.domain_name
= &n1
;
7874 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupDomain_r(b
, tctx
, &r
),
7875 "LookupDomain failed");
7876 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LookupDomain");
7878 if (!test_GetDomPwInfo(p
, tctx
, &n1
)) {
7882 if (!test_OpenDomain(p
, tctx
, ctx
, *r
.out
.sid
)) {
7890 static bool test_EnumDomains(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7891 struct torture_samr_context
*ctx
)
7893 struct samr_EnumDomains r
;
7894 uint32_t resume_handle
= 0;
7895 uint32_t num_entries
= 0;
7896 struct samr_SamArray
*sam
= NULL
;
7899 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7901 r
.in
.connect_handle
= &ctx
->handle
;
7902 r
.in
.resume_handle
= &resume_handle
;
7903 r
.in
.buf_size
= (uint32_t)-1;
7904 r
.out
.resume_handle
= &resume_handle
;
7905 r
.out
.num_entries
= &num_entries
;
7908 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomains_r(b
, tctx
, &r
),
7909 "EnumDomains failed");
7910 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "EnumDomains failed");
7916 for (i
=0;i
<sam
->count
;i
++) {
7917 if (!test_LookupDomain(p
, tctx
, ctx
,
7918 sam
->entries
[i
].name
.string
)) {
7923 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomains_r(b
, tctx
, &r
),
7924 "EnumDomains failed");
7925 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "EnumDomains failed");
7931 static bool test_Connect(struct dcerpc_binding_handle
*b
,
7932 struct torture_context
*tctx
,
7933 struct policy_handle
*handle
)
7935 struct samr_Connect r
;
7936 struct samr_Connect2 r2
;
7937 struct samr_Connect3 r3
;
7938 struct samr_Connect4 r4
;
7939 struct samr_Connect5 r5
;
7940 union samr_ConnectInfo info
;
7941 struct policy_handle h
;
7942 uint32_t level_out
= 0;
7943 bool ret
= true, got_handle
= false;
7945 torture_comment(tctx
, "Testing samr_Connect\n");
7947 r
.in
.system_name
= NULL
;
7948 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7949 r
.out
.connect_handle
= &h
;
7951 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect_r(b
, tctx
, &r
),
7953 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
7954 torture_comment(tctx
, "Connect failed - %s\n", nt_errstr(r
.out
.result
));
7961 torture_comment(tctx
, "Testing samr_Connect2\n");
7963 r2
.in
.system_name
= NULL
;
7964 r2
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7965 r2
.out
.connect_handle
= &h
;
7967 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect2_r(b
, tctx
, &r2
),
7969 if (!NT_STATUS_IS_OK(r2
.out
.result
)) {
7970 torture_comment(tctx
, "Connect2 failed - %s\n", nt_errstr(r2
.out
.result
));
7974 test_samr_handle_Close(b
, tctx
, handle
);
7980 torture_comment(tctx
, "Testing samr_Connect3\n");
7982 r3
.in
.system_name
= NULL
;
7984 r3
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7985 r3
.out
.connect_handle
= &h
;
7987 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect3_r(b
, tctx
, &r3
),
7989 if (!NT_STATUS_IS_OK(r3
.out
.result
)) {
7990 torture_warning(tctx
, "Connect3 failed - %s\n", nt_errstr(r3
.out
.result
));
7994 test_samr_handle_Close(b
, tctx
, handle
);
8000 torture_comment(tctx
, "Testing samr_Connect4\n");
8002 r4
.in
.system_name
= "";
8003 r4
.in
.client_version
= 0;
8004 r4
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
8005 r4
.out
.connect_handle
= &h
;
8007 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect4_r(b
, tctx
, &r4
),
8009 if (!NT_STATUS_IS_OK(r4
.out
.result
)) {
8010 torture_warning(tctx
, "Connect4 failed - %s\n", nt_errstr(r4
.out
.result
));
8014 test_samr_handle_Close(b
, tctx
, handle
);
8020 torture_comment(tctx
, "Testing samr_Connect5\n");
8022 info
.info1
.client_version
= 0;
8023 info
.info1
.unknown2
= 0;
8025 r5
.in
.system_name
= "";
8026 r5
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
8028 r5
.out
.level_out
= &level_out
;
8029 r5
.in
.info_in
= &info
;
8030 r5
.out
.info_out
= &info
;
8031 r5
.out
.connect_handle
= &h
;
8033 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect5_r(b
, tctx
, &r5
),
8035 if (!NT_STATUS_IS_OK(r5
.out
.result
)) {
8036 torture_warning(tctx
, "Connect5 failed - %s\n", nt_errstr(r5
.out
.result
));
8040 test_samr_handle_Close(b
, tctx
, handle
);
8050 static bool test_samr_ValidatePassword(struct torture_context
*tctx
,
8051 struct dcerpc_pipe
*p
)
8053 struct samr_ValidatePassword r
;
8054 union samr_ValidatePasswordReq req
;
8055 union samr_ValidatePasswordRep
*repp
= NULL
;
8057 const char *passwords
[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL
};
8059 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
8061 torture_comment(tctx
, "Testing samr_ValidatePassword\n");
8063 if (p
->conn
->transport
.transport
!= NCACN_IP_TCP
) {
8064 torture_comment(tctx
, "samr_ValidatePassword only should succeed over NCACN_IP_TCP!\n");
8068 r
.in
.level
= NetValidatePasswordReset
;
8073 req
.req3
.account
.string
= "non-existent-account-aklsdji";
8075 for (i
=0; passwords
[i
]; i
++) {
8076 req
.req3
.password
.string
= passwords
[i
];
8078 status
= dcerpc_samr_ValidatePassword_r(b
, tctx
, &r
);
8079 if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE
)) {
8080 torture_skip(tctx
, "ValidatePassword not supported by server\n");
8082 torture_assert_ntstatus_ok(tctx
, status
,
8083 "samr_ValidatePassword failed");
8084 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
8085 "samr_ValidatePassword failed");
8086 torture_comment(tctx
, "Server %s password '%s' with code %i\n",
8087 repp
->ctr3
.status
==SAMR_VALIDATION_STATUS_SUCCESS
?"allowed":"refused",
8088 req
.req3
.password
.string
, repp
->ctr3
.status
);
8094 bool torture_rpc_samr(struct torture_context
*torture
)
8097 struct dcerpc_pipe
*p
;
8099 struct torture_samr_context
*ctx
;
8100 struct dcerpc_binding_handle
*b
;
8102 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8103 if (!NT_STATUS_IS_OK(status
)) {
8106 b
= p
->binding_handle
;
8108 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8110 ctx
->choice
= TORTURE_SAMR_OTHER
;
8112 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8114 if (!torture_setting_bool(torture
, "samba3", false)) {
8115 ret
&= test_QuerySecurity(b
, torture
, &ctx
->handle
);
8118 ret
&= test_EnumDomains(p
, torture
, ctx
);
8120 ret
&= test_SetDsrmPassword(b
, torture
, &ctx
->handle
);
8122 ret
&= test_Shutdown(b
, torture
, &ctx
->handle
);
8124 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8130 bool torture_rpc_samr_users(struct torture_context
*torture
)
8133 struct dcerpc_pipe
*p
;
8135 struct torture_samr_context
*ctx
;
8136 struct dcerpc_binding_handle
*b
;
8138 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8139 if (!NT_STATUS_IS_OK(status
)) {
8142 b
= p
->binding_handle
;
8144 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8146 ctx
->choice
= TORTURE_SAMR_USER_ATTRIBUTES
;
8148 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8150 if (!torture_setting_bool(torture
, "samba3", false)) {
8151 ret
&= test_QuerySecurity(b
, torture
, &ctx
->handle
);
8154 ret
&= test_EnumDomains(p
, torture
, ctx
);
8156 ret
&= test_SetDsrmPassword(b
, torture
, &ctx
->handle
);
8158 ret
&= test_Shutdown(b
, torture
, &ctx
->handle
);
8160 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8166 bool torture_rpc_samr_passwords(struct torture_context
*torture
)
8169 struct dcerpc_pipe
*p
;
8171 struct torture_samr_context
*ctx
;
8172 struct dcerpc_binding_handle
*b
;
8174 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8175 if (!NT_STATUS_IS_OK(status
)) {
8178 b
= p
->binding_handle
;
8180 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8182 ctx
->choice
= TORTURE_SAMR_PASSWORDS
;
8184 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8186 ret
&= test_EnumDomains(p
, torture
, ctx
);
8188 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8193 static bool torture_rpc_samr_pwdlastset(struct torture_context
*torture
,
8194 struct dcerpc_pipe
*p2
,
8195 struct cli_credentials
*machine_credentials
)
8198 struct dcerpc_pipe
*p
;
8200 struct torture_samr_context
*ctx
;
8201 struct dcerpc_binding_handle
*b
;
8203 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8204 if (!NT_STATUS_IS_OK(status
)) {
8207 b
= p
->binding_handle
;
8209 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8211 ctx
->choice
= TORTURE_SAMR_PASSWORDS_PWDLASTSET
;
8212 ctx
->machine_credentials
= machine_credentials
;
8214 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8216 ret
&= test_EnumDomains(p
, torture
, ctx
);
8218 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8223 struct torture_suite
*torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX
*mem_ctx
)
8225 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.passwords.pwdlastset");
8226 struct torture_rpc_tcase
*tcase
;
8228 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
8230 TEST_ACCOUNT_NAME_PWD
);
8232 torture_rpc_tcase_add_test_creds(tcase
, "pwdLastSet",
8233 torture_rpc_samr_pwdlastset
);
8238 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context
*torture
,
8239 struct dcerpc_pipe
*p2
,
8240 struct cli_credentials
*machine_credentials
)
8243 struct dcerpc_pipe
*p
;
8245 struct torture_samr_context
*ctx
;
8246 struct dcerpc_binding_handle
*b
;
8248 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8249 if (!NT_STATUS_IS_OK(status
)) {
8252 b
= p
->binding_handle
;
8254 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8256 ctx
->choice
= TORTURE_SAMR_USER_PRIVILEGES
;
8257 ctx
->machine_credentials
= machine_credentials
;
8259 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8261 ret
&= test_EnumDomains(p
, torture
, ctx
);
8263 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8268 struct torture_suite
*torture_rpc_samr_user_privileges(TALLOC_CTX
*mem_ctx
)
8270 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.users.privileges");
8271 struct torture_rpc_tcase
*tcase
;
8273 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
8275 TEST_ACCOUNT_NAME_PWD
);
8277 torture_rpc_tcase_add_test_creds(tcase
, "delete_privileged_user",
8278 torture_rpc_samr_users_privileges_delete_user
);
8283 static bool torture_rpc_samr_many_accounts(struct torture_context
*torture
,
8284 struct dcerpc_pipe
*p2
,
8288 struct dcerpc_pipe
*p
;
8290 struct torture_samr_context
*ctx
=
8291 talloc_get_type_abort(data
, struct torture_samr_context
);
8292 struct dcerpc_binding_handle
*b
;
8294 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8295 if (!NT_STATUS_IS_OK(status
)) {
8298 b
= p
->binding_handle
;
8300 ctx
->choice
= TORTURE_SAMR_MANY_ACCOUNTS
;
8301 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
8302 ctx
->num_objects_large_dc
);
8304 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8306 ret
&= test_EnumDomains(p
, torture
, ctx
);
8308 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8313 static bool torture_rpc_samr_many_groups(struct torture_context
*torture
,
8314 struct dcerpc_pipe
*p2
,
8318 struct dcerpc_pipe
*p
;
8320 struct torture_samr_context
*ctx
=
8321 talloc_get_type_abort(data
, struct torture_samr_context
);
8322 struct dcerpc_binding_handle
*b
;
8324 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8325 if (!NT_STATUS_IS_OK(status
)) {
8328 b
= p
->binding_handle
;
8330 ctx
->choice
= TORTURE_SAMR_MANY_GROUPS
;
8331 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
8332 ctx
->num_objects_large_dc
);
8334 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8336 ret
&= test_EnumDomains(p
, torture
, ctx
);
8338 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8343 static bool torture_rpc_samr_many_aliases(struct torture_context
*torture
,
8344 struct dcerpc_pipe
*p2
,
8348 struct dcerpc_pipe
*p
;
8350 struct torture_samr_context
*ctx
=
8351 talloc_get_type_abort(data
, struct torture_samr_context
);
8352 struct dcerpc_binding_handle
*b
;
8354 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8355 if (!NT_STATUS_IS_OK(status
)) {
8358 b
= p
->binding_handle
;
8360 ctx
->choice
= TORTURE_SAMR_MANY_ALIASES
;
8361 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
8362 ctx
->num_objects_large_dc
);
8364 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8366 ret
&= test_EnumDomains(p
, torture
, ctx
);
8368 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8373 struct torture_suite
*torture_rpc_samr_large_dc(TALLOC_CTX
*mem_ctx
)
8375 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.large-dc");
8376 struct torture_rpc_tcase
*tcase
;
8377 struct torture_samr_context
*ctx
;
8379 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "samr", &ndr_table_samr
);
8381 ctx
= talloc_zero(suite
, struct torture_samr_context
);
8382 ctx
->num_objects_large_dc
= 150;
8384 torture_rpc_tcase_add_test_ex(tcase
, "many_aliases",
8385 torture_rpc_samr_many_aliases
, ctx
);
8386 torture_rpc_tcase_add_test_ex(tcase
, "many_groups",
8387 torture_rpc_samr_many_groups
, ctx
);
8388 torture_rpc_tcase_add_test_ex(tcase
, "many_accounts",
8389 torture_rpc_samr_many_accounts
, ctx
);
8394 static bool torture_rpc_samr_badpwdcount(struct torture_context
*torture
,
8395 struct dcerpc_pipe
*p2
,
8396 struct cli_credentials
*machine_credentials
)
8399 struct dcerpc_pipe
*p
;
8401 struct torture_samr_context
*ctx
;
8402 struct dcerpc_binding_handle
*b
;
8404 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8405 if (!NT_STATUS_IS_OK(status
)) {
8408 b
= p
->binding_handle
;
8410 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8412 ctx
->choice
= TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
;
8413 ctx
->machine_credentials
= machine_credentials
;
8415 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8417 ret
&= test_EnumDomains(p
, torture
, ctx
);
8419 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8424 struct torture_suite
*torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX
*mem_ctx
)
8426 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.passwords.badpwdcount");
8427 struct torture_rpc_tcase
*tcase
;
8429 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
8431 TEST_ACCOUNT_NAME_PWD
);
8433 torture_rpc_tcase_add_test_creds(tcase
, "badPwdCount",
8434 torture_rpc_samr_badpwdcount
);
8439 static bool torture_rpc_samr_lockout(struct torture_context
*torture
,
8440 struct dcerpc_pipe
*p2
,
8441 struct cli_credentials
*machine_credentials
)
8444 struct dcerpc_pipe
*p
;
8446 struct torture_samr_context
*ctx
;
8447 struct dcerpc_binding_handle
*b
;
8449 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8450 if (!NT_STATUS_IS_OK(status
)) {
8453 b
= p
->binding_handle
;
8455 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8457 ctx
->choice
= TORTURE_SAMR_PASSWORDS_LOCKOUT
;
8458 ctx
->machine_credentials
= machine_credentials
;
8460 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8462 ret
&= test_EnumDomains(p
, torture
, ctx
);
8464 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8469 struct torture_suite
*torture_rpc_samr_passwords_lockout(TALLOC_CTX
*mem_ctx
)
8471 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.passwords.lockout");
8472 struct torture_rpc_tcase
*tcase
;
8474 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
8476 TEST_ACCOUNT_NAME_PWD
);
8478 torture_rpc_tcase_add_test_creds(tcase
, "lockout",
8479 torture_rpc_samr_lockout
);
8484 struct torture_suite
*torture_rpc_samr_passwords_validate(TALLOC_CTX
*mem_ctx
)
8486 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.passwords.validate");
8487 struct torture_rpc_tcase
*tcase
;
8489 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "samr",
8491 torture_rpc_tcase_add_test(tcase
, "validate",
8492 test_samr_ValidatePassword
);