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 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
669 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
670 s
.in
.level
, nt_errstr(s
.out
.result
));
680 static bool test_SetUserPass_23(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
681 struct policy_handle
*handle
, uint32_t fields_present
,
685 struct samr_SetUserInfo s
;
686 union samr_UserInfo u
;
688 DATA_BLOB session_key
;
689 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
691 struct samr_GetUserPwInfo pwp
;
692 struct samr_PwInfo info
;
693 int policy_min_pw_len
= 0;
694 pwp
.in
.user_handle
= handle
;
695 pwp
.out
.info
= &info
;
697 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
698 "GetUserPwInfo failed");
699 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
700 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
702 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
704 s
.in
.user_handle
= handle
;
710 u
.info23
.info
.fields_present
= fields_present
;
712 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
714 status
= dcerpc_fetch_session_key(p
, &session_key
);
715 if (!NT_STATUS_IS_OK(status
)) {
716 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
717 s
.in
.level
, nt_errstr(status
));
721 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
723 torture_comment(tctx
, "Testing SetUserInfo level 23 (set password)\n");
725 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
726 "SetUserInfo failed");
727 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
728 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
729 s
.in
.level
, nt_errstr(s
.out
.result
));
735 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
737 status
= dcerpc_fetch_session_key(p
, &session_key
);
738 if (!NT_STATUS_IS_OK(status
)) {
739 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
740 s
.in
.level
, nt_errstr(status
));
744 /* This should break the key nicely */
745 session_key
.length
--;
746 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
748 torture_comment(tctx
, "Testing SetUserInfo level 23 (set password) with wrong password\n");
750 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
751 "SetUserInfo failed");
752 if (!NT_STATUS_EQUAL(s
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
753 torture_warning(tctx
, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
754 s
.in
.level
, nt_errstr(s
.out
.result
));
762 static bool test_SetUserPassEx(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
763 struct policy_handle
*handle
, bool makeshort
,
767 struct samr_SetUserInfo s
;
768 union samr_UserInfo u
;
770 DATA_BLOB session_key
;
771 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
772 uint8_t confounder
[16];
774 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
775 struct MD5Context ctx
;
776 struct samr_GetUserPwInfo pwp
;
777 struct samr_PwInfo info
;
778 int policy_min_pw_len
= 0;
779 pwp
.in
.user_handle
= handle
;
780 pwp
.out
.info
= &info
;
782 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
783 "GetUserPwInfo failed");
784 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
785 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
787 if (makeshort
&& policy_min_pw_len
) {
788 newpass
= samr_rand_pass_fixed_len(tctx
, policy_min_pw_len
- 1);
790 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
793 s
.in
.user_handle
= handle
;
797 encode_pw_buffer(u
.info26
.password
.data
, newpass
, STR_UNICODE
);
798 u
.info26
.password_expired
= 0;
800 status
= dcerpc_fetch_session_key(p
, &session_key
);
801 if (!NT_STATUS_IS_OK(status
)) {
802 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
803 s
.in
.level
, nt_errstr(status
));
807 generate_random_buffer((uint8_t *)confounder
, 16);
810 MD5Update(&ctx
, confounder
, 16);
811 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
812 MD5Final(confounded_session_key
.data
, &ctx
);
814 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
815 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
817 torture_comment(tctx
, "Testing SetUserInfo level 26 (set password ex)\n");
819 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
820 "SetUserInfo failed");
821 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
822 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
823 s
.in
.level
, nt_errstr(s
.out
.result
));
829 /* This should break the key nicely */
830 confounded_session_key
.data
[0]++;
832 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
833 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
835 torture_comment(tctx
, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
837 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
838 "SetUserInfo failed");
839 if (!NT_STATUS_EQUAL(s
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
840 torture_warning(tctx
, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
841 s
.in
.level
, nt_errstr(s
.out
.result
));
850 static bool test_SetUserPass_25(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
851 struct policy_handle
*handle
, uint32_t fields_present
,
855 struct samr_SetUserInfo s
;
856 union samr_UserInfo u
;
858 DATA_BLOB session_key
;
859 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
860 struct MD5Context ctx
;
861 uint8_t confounder
[16];
863 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
864 struct samr_GetUserPwInfo pwp
;
865 struct samr_PwInfo info
;
866 int policy_min_pw_len
= 0;
867 pwp
.in
.user_handle
= handle
;
868 pwp
.out
.info
= &info
;
870 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
871 "GetUserPwInfo failed");
872 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
873 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
875 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
877 s
.in
.user_handle
= handle
;
883 u
.info25
.info
.fields_present
= fields_present
;
885 encode_pw_buffer(u
.info25
.password
.data
, newpass
, STR_UNICODE
);
887 status
= dcerpc_fetch_session_key(p
, &session_key
);
888 if (!NT_STATUS_IS_OK(status
)) {
889 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
890 s
.in
.level
, nt_errstr(status
));
894 generate_random_buffer((uint8_t *)confounder
, 16);
897 MD5Update(&ctx
, confounder
, 16);
898 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
899 MD5Final(confounded_session_key
.data
, &ctx
);
901 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
902 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
904 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex)\n");
906 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
907 "SetUserInfo failed");
908 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
909 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
910 s
.in
.level
, nt_errstr(s
.out
.result
));
916 /* This should break the key nicely */
917 confounded_session_key
.data
[0]++;
919 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
920 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
922 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
924 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
925 "SetUserInfo failed");
926 if (!NT_STATUS_EQUAL(s
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
927 torture_warning(tctx
, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
928 s
.in
.level
, nt_errstr(s
.out
.result
));
935 static bool test_SetUserPass_18(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
936 struct policy_handle
*handle
, char **password
)
939 struct samr_SetUserInfo s
;
940 union samr_UserInfo u
;
942 DATA_BLOB session_key
;
944 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
945 struct samr_GetUserPwInfo pwp
;
946 struct samr_PwInfo info
;
947 int policy_min_pw_len
= 0;
948 uint8_t lm_hash
[16], nt_hash
[16];
950 pwp
.in
.user_handle
= handle
;
951 pwp
.out
.info
= &info
;
953 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
954 "GetUserPwInfo failed");
955 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
956 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
958 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
960 s
.in
.user_handle
= handle
;
966 u
.info18
.nt_pwd_active
= true;
967 u
.info18
.lm_pwd_active
= true;
969 E_md4hash(newpass
, nt_hash
);
970 E_deshash(newpass
, lm_hash
);
972 status
= dcerpc_fetch_session_key(p
, &session_key
);
973 if (!NT_STATUS_IS_OK(status
)) {
974 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
975 s
.in
.level
, nt_errstr(status
));
981 in
= data_blob_const(nt_hash
, 16);
982 out
= data_blob_talloc_zero(tctx
, 16);
983 sess_crypt_blob(&out
, &in
, &session_key
, true);
984 memcpy(u
.info18
.nt_pwd
.hash
, out
.data
, out
.length
);
988 in
= data_blob_const(lm_hash
, 16);
989 out
= data_blob_talloc_zero(tctx
, 16);
990 sess_crypt_blob(&out
, &in
, &session_key
, true);
991 memcpy(u
.info18
.lm_pwd
.hash
, out
.data
, out
.length
);
994 torture_comment(tctx
, "Testing SetUserInfo level 18 (set password hash)\n");
996 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
997 "SetUserInfo failed");
998 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
999 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
1000 s
.in
.level
, nt_errstr(s
.out
.result
));
1003 *password
= newpass
;
1009 static bool test_SetUserPass_21(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1010 struct policy_handle
*handle
, uint32_t fields_present
,
1014 struct samr_SetUserInfo s
;
1015 union samr_UserInfo u
;
1017 DATA_BLOB session_key
;
1019 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1020 struct samr_GetUserPwInfo pwp
;
1021 struct samr_PwInfo info
;
1022 int policy_min_pw_len
= 0;
1023 uint8_t lm_hash
[16], nt_hash
[16];
1025 pwp
.in
.user_handle
= handle
;
1026 pwp
.out
.info
= &info
;
1028 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
1029 "GetUserPwInfo failed");
1030 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
1031 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1033 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1035 s
.in
.user_handle
= handle
;
1039 E_md4hash(newpass
, nt_hash
);
1040 E_deshash(newpass
, lm_hash
);
1044 u
.info21
.fields_present
= fields_present
;
1046 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1047 u
.info21
.lm_owf_password
.length
= 16;
1048 u
.info21
.lm_owf_password
.size
= 16;
1049 u
.info21
.lm_owf_password
.array
= (uint16_t *)lm_hash
;
1050 u
.info21
.lm_password_set
= true;
1053 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1054 u
.info21
.nt_owf_password
.length
= 16;
1055 u
.info21
.nt_owf_password
.size
= 16;
1056 u
.info21
.nt_owf_password
.array
= (uint16_t *)nt_hash
;
1057 u
.info21
.nt_password_set
= true;
1060 status
= dcerpc_fetch_session_key(p
, &session_key
);
1061 if (!NT_STATUS_IS_OK(status
)) {
1062 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
1063 s
.in
.level
, nt_errstr(status
));
1067 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1069 in
= data_blob_const(u
.info21
.lm_owf_password
.array
,
1070 u
.info21
.lm_owf_password
.length
);
1071 out
= data_blob_talloc_zero(tctx
, 16);
1072 sess_crypt_blob(&out
, &in
, &session_key
, true);
1073 u
.info21
.lm_owf_password
.array
= (uint16_t *)out
.data
;
1076 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1078 in
= data_blob_const(u
.info21
.nt_owf_password
.array
,
1079 u
.info21
.nt_owf_password
.length
);
1080 out
= data_blob_talloc_zero(tctx
, 16);
1081 sess_crypt_blob(&out
, &in
, &session_key
, true);
1082 u
.info21
.nt_owf_password
.array
= (uint16_t *)out
.data
;
1085 torture_comment(tctx
, "Testing SetUserInfo level 21 (set password hash)\n");
1087 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
1088 "SetUserInfo failed");
1089 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
1090 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
1091 s
.in
.level
, nt_errstr(s
.out
.result
));
1094 *password
= newpass
;
1097 /* try invalid length */
1098 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1100 u
.info21
.nt_owf_password
.length
++;
1102 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
1103 "SetUserInfo failed");
1104 if (!NT_STATUS_EQUAL(s
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
1105 torture_warning(tctx
, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1106 s
.in
.level
, nt_errstr(s
.out
.result
));
1111 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1113 u
.info21
.lm_owf_password
.length
++;
1115 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
1116 "SetUserInfo failed");
1117 if (!NT_STATUS_EQUAL(s
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
1118 torture_warning(tctx
, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1119 s
.in
.level
, nt_errstr(s
.out
.result
));
1127 static bool test_SetUserPass_level_ex(struct dcerpc_pipe
*p
,
1128 struct torture_context
*tctx
,
1129 struct policy_handle
*handle
,
1131 uint32_t fields_present
,
1132 char **password
, uint8_t password_expired
,
1134 bool *matched_expected_error
)
1137 NTSTATUS expected_error
= NT_STATUS_OK
;
1138 struct samr_SetUserInfo s
;
1139 struct samr_SetUserInfo2 s2
;
1140 union samr_UserInfo u
;
1142 DATA_BLOB session_key
;
1143 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
1144 struct MD5Context ctx
;
1145 uint8_t confounder
[16];
1147 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1148 struct samr_GetUserPwInfo pwp
;
1149 struct samr_PwInfo info
;
1150 int policy_min_pw_len
= 0;
1151 const char *comment
= NULL
;
1152 uint8_t lm_hash
[16], nt_hash
[16];
1154 pwp
.in
.user_handle
= handle
;
1155 pwp
.out
.info
= &info
;
1157 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
1158 "GetUserPwInfo failed");
1159 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
1160 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1162 newpass
= samr_rand_pass_silent(tctx
, policy_min_pw_len
);
1165 s2
.in
.user_handle
= handle
;
1167 s2
.in
.level
= level
;
1169 s
.in
.user_handle
= handle
;
1174 if (fields_present
& SAMR_FIELD_COMMENT
) {
1175 comment
= talloc_asprintf(tctx
, "comment: %ld\n", (long int) time(NULL
));
1182 E_md4hash(newpass
, nt_hash
);
1183 E_deshash(newpass
, lm_hash
);
1185 u
.info18
.nt_pwd_active
= true;
1186 u
.info18
.lm_pwd_active
= true;
1187 u
.info18
.password_expired
= password_expired
;
1189 memcpy(u
.info18
.lm_pwd
.hash
, lm_hash
, 16);
1190 memcpy(u
.info18
.nt_pwd
.hash
, nt_hash
, 16);
1194 E_md4hash(newpass
, nt_hash
);
1195 E_deshash(newpass
, lm_hash
);
1197 u
.info21
.fields_present
= fields_present
;
1198 u
.info21
.password_expired
= password_expired
;
1199 u
.info21
.comment
.string
= comment
;
1201 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1202 u
.info21
.lm_owf_password
.length
= 16;
1203 u
.info21
.lm_owf_password
.size
= 16;
1204 u
.info21
.lm_owf_password
.array
= (uint16_t *)lm_hash
;
1205 u
.info21
.lm_password_set
= true;
1208 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1209 u
.info21
.nt_owf_password
.length
= 16;
1210 u
.info21
.nt_owf_password
.size
= 16;
1211 u
.info21
.nt_owf_password
.array
= (uint16_t *)nt_hash
;
1212 u
.info21
.nt_password_set
= true;
1217 u
.info23
.info
.fields_present
= fields_present
;
1218 u
.info23
.info
.password_expired
= password_expired
;
1219 u
.info23
.info
.comment
.string
= comment
;
1221 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
1225 u
.info24
.password_expired
= password_expired
;
1227 encode_pw_buffer(u
.info24
.password
.data
, newpass
, STR_UNICODE
);
1231 u
.info25
.info
.fields_present
= fields_present
;
1232 u
.info25
.info
.password_expired
= password_expired
;
1233 u
.info25
.info
.comment
.string
= comment
;
1235 encode_pw_buffer(u
.info25
.password
.data
, newpass
, STR_UNICODE
);
1239 u
.info26
.password_expired
= password_expired
;
1241 encode_pw_buffer(u
.info26
.password
.data
, newpass
, STR_UNICODE
);
1246 status
= dcerpc_fetch_session_key(p
, &session_key
);
1247 if (!NT_STATUS_IS_OK(status
)) {
1248 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
1249 s
.in
.level
, nt_errstr(status
));
1253 generate_random_buffer((uint8_t *)confounder
, 16);
1256 MD5Update(&ctx
, confounder
, 16);
1257 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
1258 MD5Final(confounded_session_key
.data
, &ctx
);
1264 in
= data_blob_const(u
.info18
.nt_pwd
.hash
, 16);
1265 out
= data_blob_talloc_zero(tctx
, 16);
1266 sess_crypt_blob(&out
, &in
, &session_key
, true);
1267 memcpy(u
.info18
.nt_pwd
.hash
, out
.data
, out
.length
);
1271 in
= data_blob_const(u
.info18
.lm_pwd
.hash
, 16);
1272 out
= data_blob_talloc_zero(tctx
, 16);
1273 sess_crypt_blob(&out
, &in
, &session_key
, true);
1274 memcpy(u
.info18
.lm_pwd
.hash
, out
.data
, out
.length
);
1279 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1281 in
= data_blob_const(u
.info21
.lm_owf_password
.array
,
1282 u
.info21
.lm_owf_password
.length
);
1283 out
= data_blob_talloc_zero(tctx
, 16);
1284 sess_crypt_blob(&out
, &in
, &session_key
, true);
1285 u
.info21
.lm_owf_password
.array
= (uint16_t *)out
.data
;
1287 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1289 in
= data_blob_const(u
.info21
.nt_owf_password
.array
,
1290 u
.info21
.nt_owf_password
.length
);
1291 out
= data_blob_talloc_zero(tctx
, 16);
1292 sess_crypt_blob(&out
, &in
, &session_key
, true);
1293 u
.info21
.nt_owf_password
.array
= (uint16_t *)out
.data
;
1297 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
1300 arcfour_crypt_blob(u
.info24
.password
.data
, 516, &session_key
);
1303 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
1304 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
1307 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
1308 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
1313 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo2_r(b
, tctx
, &s2
),
1314 "SetUserInfo2 failed");
1315 status
= s2
.out
.result
;
1317 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
1318 "SetUserInfo failed");
1319 status
= s
.out
.result
;
1322 if (!NT_STATUS_IS_OK(status
)) {
1323 if (fields_present
== 0) {
1324 expected_error
= NT_STATUS_INVALID_PARAMETER
;
1326 if (fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
1327 expected_error
= NT_STATUS_ACCESS_DENIED
;
1331 if (!NT_STATUS_IS_OK(expected_error
)) {
1333 torture_assert_ntstatus_equal(tctx
,
1335 expected_error
, "SetUserInfo2 failed");
1337 torture_assert_ntstatus_equal(tctx
,
1339 expected_error
, "SetUserInfo failed");
1341 *matched_expected_error
= true;
1345 if (!NT_STATUS_IS_OK(status
)) {
1346 torture_warning(tctx
, "SetUserInfo%s level %u failed - %s\n",
1347 use_setinfo2
? "2":"", level
, nt_errstr(status
));
1350 *password
= newpass
;
1356 static bool test_SetAliasInfo(struct dcerpc_binding_handle
*b
,
1357 struct torture_context
*tctx
,
1358 struct policy_handle
*handle
)
1360 struct samr_SetAliasInfo r
;
1361 struct samr_QueryAliasInfo q
;
1362 union samr_AliasInfo
*info
;
1363 uint16_t levels
[] = {2, 3};
1367 /* Ignoring switch level 1, as that includes the number of members for the alias
1368 * and setting this to a wrong value might have negative consequences
1371 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
1372 torture_comment(tctx
, "Testing SetAliasInfo level %u\n", levels
[i
]);
1374 r
.in
.alias_handle
= handle
;
1375 r
.in
.level
= levels
[i
];
1376 r
.in
.info
= talloc(tctx
, union samr_AliasInfo
);
1377 switch (r
.in
.level
) {
1378 case ALIASINFONAME
: init_lsa_String(&r
.in
.info
->name
,TEST_ALIASNAME
); break;
1379 case ALIASINFODESCRIPTION
: init_lsa_String(&r
.in
.info
->description
,
1380 "Test Description, should test I18N as well"); break;
1381 case ALIASINFOALL
: torture_comment(tctx
, "ALIASINFOALL ignored\n"); break;
1384 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetAliasInfo_r(b
, tctx
, &r
),
1385 "SetAliasInfo failed");
1386 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1387 torture_warning(tctx
, "SetAliasInfo level %u failed - %s\n",
1388 levels
[i
], nt_errstr(r
.out
.result
));
1392 q
.in
.alias_handle
= handle
;
1393 q
.in
.level
= levels
[i
];
1396 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryAliasInfo_r(b
, tctx
, &q
),
1397 "QueryAliasInfo failed");
1398 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
1399 torture_warning(tctx
, "QueryAliasInfo level %u failed - %s\n",
1400 levels
[i
], nt_errstr(q
.out
.result
));
1408 static bool test_GetGroupsForUser(struct dcerpc_binding_handle
*b
,
1409 struct torture_context
*tctx
,
1410 struct policy_handle
*user_handle
)
1412 struct samr_GetGroupsForUser r
;
1413 struct samr_RidWithAttributeArray
*rids
= NULL
;
1415 torture_comment(tctx
, "Testing GetGroupsForUser\n");
1417 r
.in
.user_handle
= user_handle
;
1420 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetGroupsForUser_r(b
, tctx
, &r
),
1421 "GetGroupsForUser failed");
1422 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetGroupsForUser failed");
1428 static bool test_GetDomPwInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1429 struct lsa_String
*domain_name
)
1431 struct samr_GetDomPwInfo r
;
1432 struct samr_PwInfo info
;
1433 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1435 r
.in
.domain_name
= domain_name
;
1438 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1440 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &r
),
1441 "GetDomPwInfo failed");
1442 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetDomPwInfo failed");
1444 r
.in
.domain_name
->string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1445 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1447 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &r
),
1448 "GetDomPwInfo failed");
1449 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetDomPwInfo failed");
1451 r
.in
.domain_name
->string
= "\\\\__NONAME__";
1452 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1454 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &r
),
1455 "GetDomPwInfo failed");
1456 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetDomPwInfo failed");
1458 r
.in
.domain_name
->string
= "\\\\Builtin";
1459 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1461 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &r
),
1462 "GetDomPwInfo failed");
1463 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetDomPwInfo failed");
1468 static bool test_GetUserPwInfo(struct dcerpc_binding_handle
*b
,
1469 struct torture_context
*tctx
,
1470 struct policy_handle
*handle
)
1472 struct samr_GetUserPwInfo r
;
1473 struct samr_PwInfo info
;
1475 torture_comment(tctx
, "Testing GetUserPwInfo\n");
1477 r
.in
.user_handle
= handle
;
1480 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &r
),
1481 "GetUserPwInfo failed");
1482 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetUserPwInfo");
1487 static NTSTATUS
test_LookupName(struct dcerpc_binding_handle
*b
,
1488 struct torture_context
*tctx
,
1489 struct policy_handle
*domain_handle
, const char *name
,
1493 struct samr_LookupNames n
;
1494 struct lsa_String sname
[2];
1495 struct samr_Ids rids
, types
;
1497 init_lsa_String(&sname
[0], name
);
1499 n
.in
.domain_handle
= domain_handle
;
1503 n
.out
.types
= &types
;
1504 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1505 if (!NT_STATUS_IS_OK(status
)) {
1508 if (NT_STATUS_IS_OK(n
.out
.result
)) {
1509 *rid
= n
.out
.rids
->ids
[0];
1511 return n
.out
.result
;
1514 init_lsa_String(&sname
[1], "xxNONAMExx");
1516 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1517 if (!NT_STATUS_IS_OK(status
)) {
1520 if (!NT_STATUS_EQUAL(n
.out
.result
, STATUS_SOME_UNMAPPED
)) {
1521 torture_warning(tctx
, "LookupNames[2] failed - %s\n", nt_errstr(n
.out
.result
));
1522 if (NT_STATUS_IS_OK(n
.out
.result
)) {
1523 return NT_STATUS_UNSUCCESSFUL
;
1525 return n
.out
.result
;
1529 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1530 if (!NT_STATUS_IS_OK(status
)) {
1533 if (!NT_STATUS_IS_OK(n
.out
.result
)) {
1534 torture_warning(tctx
, "LookupNames[0] failed - %s\n", nt_errstr(status
));
1535 return n
.out
.result
;
1538 init_lsa_String(&sname
[0], "xxNONAMExx");
1540 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1541 if (!NT_STATUS_IS_OK(status
)) {
1544 if (!NT_STATUS_EQUAL(n
.out
.result
, NT_STATUS_NONE_MAPPED
)) {
1545 torture_warning(tctx
, "LookupNames[1 bad name] failed - %s\n", nt_errstr(n
.out
.result
));
1546 if (NT_STATUS_IS_OK(n
.out
.result
)) {
1547 return NT_STATUS_UNSUCCESSFUL
;
1549 return n
.out
.result
;
1552 init_lsa_String(&sname
[0], "xxNONAMExx");
1553 init_lsa_String(&sname
[1], "xxNONAME2xx");
1555 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1556 if (!NT_STATUS_IS_OK(status
)) {
1559 if (!NT_STATUS_EQUAL(n
.out
.result
, NT_STATUS_NONE_MAPPED
)) {
1560 torture_warning(tctx
, "LookupNames[2 bad names] failed - %s\n", nt_errstr(n
.out
.result
));
1561 if (NT_STATUS_IS_OK(n
.out
.result
)) {
1562 return NT_STATUS_UNSUCCESSFUL
;
1564 return n
.out
.result
;
1567 return NT_STATUS_OK
;
1570 static NTSTATUS
test_OpenUser_byname(struct dcerpc_binding_handle
*b
,
1571 struct torture_context
*tctx
,
1572 struct policy_handle
*domain_handle
,
1573 const char *name
, struct policy_handle
*user_handle
)
1576 struct samr_OpenUser r
;
1579 status
= test_LookupName(b
, tctx
, domain_handle
, name
, &rid
);
1580 if (!NT_STATUS_IS_OK(status
)) {
1584 r
.in
.domain_handle
= domain_handle
;
1585 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1587 r
.out
.user_handle
= user_handle
;
1588 status
= dcerpc_samr_OpenUser_r(b
, tctx
, &r
);
1589 if (!NT_STATUS_IS_OK(status
)) {
1592 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1593 torture_warning(tctx
, "OpenUser_byname(%s -> %d) failed - %s\n", name
, rid
, nt_errstr(r
.out
.result
));
1596 return r
.out
.result
;
1600 static bool test_ChangePasswordNT3(struct dcerpc_pipe
*p
,
1601 struct torture_context
*tctx
,
1602 struct policy_handle
*handle
)
1605 struct samr_ChangePasswordUser r
;
1607 struct samr_Password hash1
, hash2
, hash3
, hash4
, hash5
, hash6
;
1608 struct policy_handle user_handle
;
1609 char *oldpass
= "test";
1610 char *newpass
= "test2";
1611 uint8_t old_nt_hash
[16], new_nt_hash
[16];
1612 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1614 status
= test_OpenUser_byname(p
, tctx
, handle
, "testuser", &user_handle
);
1615 if (!NT_STATUS_IS_OK(status
)) {
1619 torture_comment(tctx
, "Testing ChangePasswordUser for user 'testuser'\n");
1621 torture_comment(tctx
, "old password: %s\n", oldpass
);
1622 torture_comment(tctx
, "new password: %s\n", newpass
);
1624 E_md4hash(oldpass
, old_nt_hash
);
1625 E_md4hash(newpass
, new_nt_hash
);
1626 E_deshash(oldpass
, old_lm_hash
);
1627 E_deshash(newpass
, new_lm_hash
);
1629 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1630 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1631 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1632 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1633 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1634 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1636 r
.in
.handle
= &user_handle
;
1637 r
.in
.lm_present
= 1;
1638 r
.in
.old_lm_crypted
= &hash1
;
1639 r
.in
.new_lm_crypted
= &hash2
;
1640 r
.in
.nt_present
= 1;
1641 r
.in
.old_nt_crypted
= &hash3
;
1642 r
.in
.new_nt_crypted
= &hash4
;
1643 r
.in
.cross1_present
= 1;
1644 r
.in
.nt_cross
= &hash5
;
1645 r
.in
.cross2_present
= 1;
1646 r
.in
.lm_cross
= &hash6
;
1648 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1649 "ChangePasswordUser failed");
1650 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1651 torture_warning(tctx
, "ChangePasswordUser failed - %s\n", nt_errstr(r
.out
.result
));
1655 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
1663 static bool test_ChangePasswordUser(struct dcerpc_binding_handle
*b
,
1664 struct torture_context
*tctx
,
1665 const char *acct_name
,
1666 struct policy_handle
*handle
, char **password
)
1669 struct samr_ChangePasswordUser r
;
1671 struct samr_Password hash1
, hash2
, hash3
, hash4
, hash5
, hash6
;
1672 struct policy_handle user_handle
;
1674 uint8_t old_nt_hash
[16], new_nt_hash
[16];
1675 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1676 bool changed
= true;
1679 struct samr_GetUserPwInfo pwp
;
1680 struct samr_PwInfo info
;
1681 int policy_min_pw_len
= 0;
1683 status
= test_OpenUser_byname(b
, tctx
, handle
, acct_name
, &user_handle
);
1684 if (!NT_STATUS_IS_OK(status
)) {
1687 pwp
.in
.user_handle
= &user_handle
;
1688 pwp
.out
.info
= &info
;
1690 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
1691 "GetUserPwInfo failed");
1692 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
1693 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1695 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1697 torture_comment(tctx
, "Testing ChangePasswordUser\n");
1699 torture_assert(tctx
, *password
!= NULL
,
1700 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1702 oldpass
= *password
;
1704 E_md4hash(oldpass
, old_nt_hash
);
1705 E_md4hash(newpass
, new_nt_hash
);
1706 E_deshash(oldpass
, old_lm_hash
);
1707 E_deshash(newpass
, new_lm_hash
);
1709 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1710 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1711 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1712 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1713 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1714 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1716 r
.in
.user_handle
= &user_handle
;
1717 r
.in
.lm_present
= 1;
1718 /* Break the LM hash */
1720 r
.in
.old_lm_crypted
= &hash1
;
1721 r
.in
.new_lm_crypted
= &hash2
;
1722 r
.in
.nt_present
= 1;
1723 r
.in
.old_nt_crypted
= &hash3
;
1724 r
.in
.new_nt_crypted
= &hash4
;
1725 r
.in
.cross1_present
= 1;
1726 r
.in
.nt_cross
= &hash5
;
1727 r
.in
.cross2_present
= 1;
1728 r
.in
.lm_cross
= &hash6
;
1730 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1731 "ChangePasswordUser failed");
1732 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_WRONG_PASSWORD
,
1733 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1735 /* Unbreak the LM hash */
1738 r
.in
.user_handle
= &user_handle
;
1739 r
.in
.lm_present
= 1;
1740 r
.in
.old_lm_crypted
= &hash1
;
1741 r
.in
.new_lm_crypted
= &hash2
;
1742 /* Break the NT hash */
1744 r
.in
.nt_present
= 1;
1745 r
.in
.old_nt_crypted
= &hash3
;
1746 r
.in
.new_nt_crypted
= &hash4
;
1747 r
.in
.cross1_present
= 1;
1748 r
.in
.nt_cross
= &hash5
;
1749 r
.in
.cross2_present
= 1;
1750 r
.in
.lm_cross
= &hash6
;
1752 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1753 "ChangePasswordUser failed");
1754 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_WRONG_PASSWORD
,
1755 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1757 /* Unbreak the NT hash */
1760 r
.in
.user_handle
= &user_handle
;
1761 r
.in
.lm_present
= 1;
1762 r
.in
.old_lm_crypted
= &hash1
;
1763 r
.in
.new_lm_crypted
= &hash2
;
1764 r
.in
.nt_present
= 1;
1765 r
.in
.old_nt_crypted
= &hash3
;
1766 r
.in
.new_nt_crypted
= &hash4
;
1767 r
.in
.cross1_present
= 1;
1768 r
.in
.nt_cross
= &hash5
;
1769 r
.in
.cross2_present
= 1;
1770 /* Break the LM cross */
1772 r
.in
.lm_cross
= &hash6
;
1774 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1775 "ChangePasswordUser failed");
1776 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
1777 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(r
.out
.result
));
1781 /* Unbreak the LM cross */
1784 r
.in
.user_handle
= &user_handle
;
1785 r
.in
.lm_present
= 1;
1786 r
.in
.old_lm_crypted
= &hash1
;
1787 r
.in
.new_lm_crypted
= &hash2
;
1788 r
.in
.nt_present
= 1;
1789 r
.in
.old_nt_crypted
= &hash3
;
1790 r
.in
.new_nt_crypted
= &hash4
;
1791 r
.in
.cross1_present
= 1;
1792 /* Break the NT cross */
1794 r
.in
.nt_cross
= &hash5
;
1795 r
.in
.cross2_present
= 1;
1796 r
.in
.lm_cross
= &hash6
;
1798 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1799 "ChangePasswordUser failed");
1800 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
1801 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(r
.out
.result
));
1805 /* Unbreak the NT cross */
1809 /* Reset the hashes to not broken values */
1810 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1811 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1812 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1813 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1814 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1815 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1817 r
.in
.user_handle
= &user_handle
;
1818 r
.in
.lm_present
= 1;
1819 r
.in
.old_lm_crypted
= &hash1
;
1820 r
.in
.new_lm_crypted
= &hash2
;
1821 r
.in
.nt_present
= 1;
1822 r
.in
.old_nt_crypted
= &hash3
;
1823 r
.in
.new_nt_crypted
= &hash4
;
1824 r
.in
.cross1_present
= 1;
1825 r
.in
.nt_cross
= &hash5
;
1826 r
.in
.cross2_present
= 0;
1827 r
.in
.lm_cross
= NULL
;
1829 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1830 "ChangePasswordUser failed");
1831 if (NT_STATUS_IS_OK(r
.out
.result
)) {
1833 *password
= newpass
;
1834 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION
, r
.out
.result
)) {
1835 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r
.out
.result
));
1840 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1842 E_md4hash(oldpass
, old_nt_hash
);
1843 E_md4hash(newpass
, new_nt_hash
);
1844 E_deshash(oldpass
, old_lm_hash
);
1845 E_deshash(newpass
, new_lm_hash
);
1848 /* Reset the hashes to not broken values */
1849 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1850 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1851 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1852 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1853 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1854 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1856 r
.in
.user_handle
= &user_handle
;
1857 r
.in
.lm_present
= 1;
1858 r
.in
.old_lm_crypted
= &hash1
;
1859 r
.in
.new_lm_crypted
= &hash2
;
1860 r
.in
.nt_present
= 1;
1861 r
.in
.old_nt_crypted
= &hash3
;
1862 r
.in
.new_nt_crypted
= &hash4
;
1863 r
.in
.cross1_present
= 0;
1864 r
.in
.nt_cross
= NULL
;
1865 r
.in
.cross2_present
= 1;
1866 r
.in
.lm_cross
= &hash6
;
1868 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1869 "ChangePasswordUser failed");
1870 if (NT_STATUS_IS_OK(r
.out
.result
)) {
1872 *password
= newpass
;
1873 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION
, r
.out
.result
)) {
1874 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r
.out
.result
));
1879 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1881 E_md4hash(oldpass
, old_nt_hash
);
1882 E_md4hash(newpass
, new_nt_hash
);
1883 E_deshash(oldpass
, old_lm_hash
);
1884 E_deshash(newpass
, new_lm_hash
);
1887 /* Reset the hashes to not broken values */
1888 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1889 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1890 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1891 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1892 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1893 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1895 r
.in
.user_handle
= &user_handle
;
1896 r
.in
.lm_present
= 1;
1897 r
.in
.old_lm_crypted
= &hash1
;
1898 r
.in
.new_lm_crypted
= &hash2
;
1899 r
.in
.nt_present
= 1;
1900 r
.in
.old_nt_crypted
= &hash3
;
1901 r
.in
.new_nt_crypted
= &hash4
;
1902 r
.in
.cross1_present
= 1;
1903 r
.in
.nt_cross
= &hash5
;
1904 r
.in
.cross2_present
= 1;
1905 r
.in
.lm_cross
= &hash6
;
1907 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1908 "ChangePasswordUser failed");
1909 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1910 torture_comment(tctx
, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r
.out
.result
));
1911 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1912 torture_warning(tctx
, "ChangePasswordUser failed - %s\n", nt_errstr(r
.out
.result
));
1916 *password
= newpass
;
1919 r
.in
.user_handle
= &user_handle
;
1920 r
.in
.lm_present
= 1;
1921 r
.in
.old_lm_crypted
= &hash1
;
1922 r
.in
.new_lm_crypted
= &hash2
;
1923 r
.in
.nt_present
= 1;
1924 r
.in
.old_nt_crypted
= &hash3
;
1925 r
.in
.new_nt_crypted
= &hash4
;
1926 r
.in
.cross1_present
= 1;
1927 r
.in
.nt_cross
= &hash5
;
1928 r
.in
.cross2_present
= 1;
1929 r
.in
.lm_cross
= &hash6
;
1932 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1933 "ChangePasswordUser failed");
1934 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1935 torture_comment(tctx
, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r
.out
.result
));
1936 } else if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
1937 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(r
.out
.result
));
1943 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
1951 static bool test_OemChangePasswordUser2(struct dcerpc_pipe
*p
,
1952 struct torture_context
*tctx
,
1953 const char *acct_name
,
1954 struct policy_handle
*handle
, char **password
)
1956 struct samr_OemChangePasswordUser2 r
;
1958 struct samr_Password lm_verifier
;
1959 struct samr_CryptPassword lm_pass
;
1960 struct lsa_AsciiString server
, account
, account_bad
;
1963 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1964 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1966 struct samr_GetDomPwInfo dom_pw_info
;
1967 struct samr_PwInfo info
;
1968 int policy_min_pw_len
= 0;
1970 struct lsa_String domain_name
;
1972 domain_name
.string
= "";
1973 dom_pw_info
.in
.domain_name
= &domain_name
;
1974 dom_pw_info
.out
.info
= &info
;
1976 torture_comment(tctx
, "Testing OemChangePasswordUser2\n");
1978 torture_assert(tctx
, *password
!= NULL
,
1979 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1981 oldpass
= *password
;
1983 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &dom_pw_info
),
1984 "GetDomPwInfo failed");
1985 if (NT_STATUS_IS_OK(dom_pw_info
.out
.result
)) {
1986 policy_min_pw_len
= dom_pw_info
.out
.info
->min_password_length
;
1989 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1991 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1992 account
.string
= acct_name
;
1994 E_deshash(oldpass
, old_lm_hash
);
1995 E_deshash(newpass
, new_lm_hash
);
1997 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
1998 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
1999 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
2001 r
.in
.server
= &server
;
2002 r
.in
.account
= &account
;
2003 r
.in
.password
= &lm_pass
;
2004 r
.in
.hash
= &lm_verifier
;
2006 /* Break the verification */
2007 lm_verifier
.hash
[0]++;
2009 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2010 "OemChangePasswordUser2 failed");
2012 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)
2013 && !NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
2014 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2015 nt_errstr(r
.out
.result
));
2019 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
2020 /* Break the old password */
2022 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2023 /* unbreak it for the next operation */
2025 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
2027 r
.in
.server
= &server
;
2028 r
.in
.account
= &account
;
2029 r
.in
.password
= &lm_pass
;
2030 r
.in
.hash
= &lm_verifier
;
2032 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2033 "OemChangePasswordUser2 failed");
2035 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)
2036 && !NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
2037 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2038 nt_errstr(r
.out
.result
));
2042 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
2043 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2045 r
.in
.server
= &server
;
2046 r
.in
.account
= &account
;
2047 r
.in
.password
= &lm_pass
;
2050 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2051 "OemChangePasswordUser2 failed");
2053 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)
2054 && !NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
2055 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
2056 nt_errstr(r
.out
.result
));
2060 /* This shouldn't be a valid name */
2061 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
2062 r
.in
.account
= &account_bad
;
2064 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2065 "OemChangePasswordUser2 failed");
2067 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
2068 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
2069 nt_errstr(r
.out
.result
));
2073 /* This shouldn't be a valid name */
2074 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
2075 r
.in
.account
= &account_bad
;
2076 r
.in
.password
= &lm_pass
;
2077 r
.in
.hash
= &lm_verifier
;
2079 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2080 "OemChangePasswordUser2 failed");
2082 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
2083 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2084 nt_errstr(r
.out
.result
));
2088 /* This shouldn't be a valid name */
2089 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
2090 r
.in
.account
= &account_bad
;
2091 r
.in
.password
= NULL
;
2092 r
.in
.hash
= &lm_verifier
;
2094 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2095 "OemChangePasswordUser2 failed");
2097 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
2098 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2099 nt_errstr(r
.out
.result
));
2103 E_deshash(oldpass
, old_lm_hash
);
2104 E_deshash(newpass
, new_lm_hash
);
2106 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
2107 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2108 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
2110 r
.in
.server
= &server
;
2111 r
.in
.account
= &account
;
2112 r
.in
.password
= &lm_pass
;
2113 r
.in
.hash
= &lm_verifier
;
2115 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2116 "OemChangePasswordUser2 failed");
2118 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2119 torture_comment(tctx
, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r
.out
.result
));
2120 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2121 torture_warning(tctx
, "OemChangePasswordUser2 failed - %s\n", nt_errstr(r
.out
.result
));
2124 *password
= newpass
;
2131 static bool test_ChangePasswordUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2132 const char *acct_name
,
2134 char *newpass
, bool allow_password_restriction
)
2136 struct samr_ChangePasswordUser2 r
;
2138 struct lsa_String server
, account
;
2139 struct samr_CryptPassword nt_pass
, lm_pass
;
2140 struct samr_Password nt_verifier
, lm_verifier
;
2142 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2143 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2144 uint8_t old_lm_hash
[16], new_lm_hash
[16];
2146 struct samr_GetDomPwInfo dom_pw_info
;
2147 struct samr_PwInfo info
;
2149 struct lsa_String domain_name
;
2151 domain_name
.string
= "";
2152 dom_pw_info
.in
.domain_name
= &domain_name
;
2153 dom_pw_info
.out
.info
= &info
;
2155 torture_comment(tctx
, "Testing ChangePasswordUser2 on %s\n", acct_name
);
2157 torture_assert(tctx
, *password
!= NULL
,
2158 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2159 oldpass
= *password
;
2162 int policy_min_pw_len
= 0;
2163 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &dom_pw_info
),
2164 "GetDomPwInfo failed");
2165 if (NT_STATUS_IS_OK(dom_pw_info
.out
.result
)) {
2166 policy_min_pw_len
= dom_pw_info
.out
.info
->min_password_length
;
2169 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2172 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2173 init_lsa_String(&account
, acct_name
);
2175 E_md4hash(oldpass
, old_nt_hash
);
2176 E_md4hash(newpass
, new_nt_hash
);
2178 E_deshash(oldpass
, old_lm_hash
);
2179 E_deshash(newpass
, new_lm_hash
);
2181 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
|STR_TERMINATE
);
2182 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2183 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2185 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2186 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2187 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2189 r
.in
.server
= &server
;
2190 r
.in
.account
= &account
;
2191 r
.in
.nt_password
= &nt_pass
;
2192 r
.in
.nt_verifier
= &nt_verifier
;
2194 r
.in
.lm_password
= &lm_pass
;
2195 r
.in
.lm_verifier
= &lm_verifier
;
2197 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser2_r(b
, tctx
, &r
),
2198 "ChangePasswordUser2 failed");
2200 if (allow_password_restriction
&& NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2201 torture_comment(tctx
, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r
.out
.result
));
2202 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2203 torture_warning(tctx
, "ChangePasswordUser2 failed - %s\n", nt_errstr(r
.out
.result
));
2206 *password
= newpass
;
2213 bool test_ChangePasswordUser3(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2214 const char *account_string
,
2215 int policy_min_pw_len
,
2217 const char *newpass
,
2218 NTTIME last_password_change
,
2219 bool handle_reject_reason
)
2221 struct samr_ChangePasswordUser3 r
;
2223 struct lsa_String server
, account
, account_bad
;
2224 struct samr_CryptPassword nt_pass
, lm_pass
;
2225 struct samr_Password nt_verifier
, lm_verifier
;
2227 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2228 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2229 uint8_t old_lm_hash
[16], new_lm_hash
[16];
2231 struct samr_DomInfo1
*dominfo
= NULL
;
2232 struct userPwdChangeFailureInformation
*reject
= NULL
;
2234 torture_comment(tctx
, "Testing ChangePasswordUser3\n");
2236 if (newpass
== NULL
) {
2238 if (policy_min_pw_len
== 0) {
2239 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2241 newpass
= samr_rand_pass_fixed_len(tctx
, policy_min_pw_len
);
2243 } while (check_password_quality(newpass
) == false);
2245 torture_comment(tctx
, "Using password '%s'\n", newpass
);
2248 torture_assert(tctx
, *password
!= NULL
,
2249 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2251 oldpass
= *password
;
2252 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2253 init_lsa_String(&account
, account_string
);
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_UNICODE
);
2262 arcfour_crypt(lm_pass
.data
, old_nt_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 /* Break the verification */
2270 nt_verifier
.hash
[0]++;
2272 r
.in
.server
= &server
;
2273 r
.in
.account
= &account
;
2274 r
.in
.nt_password
= &nt_pass
;
2275 r
.in
.nt_verifier
= &nt_verifier
;
2277 r
.in
.lm_password
= &lm_pass
;
2278 r
.in
.lm_verifier
= &lm_verifier
;
2279 r
.in
.password3
= NULL
;
2280 r
.out
.dominfo
= &dominfo
;
2281 r
.out
.reject
= &reject
;
2283 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2284 "ChangePasswordUser3 failed");
2285 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
) &&
2286 (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
))) {
2287 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2288 nt_errstr(r
.out
.result
));
2292 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2293 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2294 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2296 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2297 /* Break the NT hash */
2299 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2300 /* Unbreak it again */
2302 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2304 r
.in
.server
= &server
;
2305 r
.in
.account
= &account
;
2306 r
.in
.nt_password
= &nt_pass
;
2307 r
.in
.nt_verifier
= &nt_verifier
;
2309 r
.in
.lm_password
= &lm_pass
;
2310 r
.in
.lm_verifier
= &lm_verifier
;
2311 r
.in
.password3
= NULL
;
2312 r
.out
.dominfo
= &dominfo
;
2313 r
.out
.reject
= &reject
;
2315 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2316 "ChangePasswordUser3 failed");
2317 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
) &&
2318 (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
))) {
2319 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2320 nt_errstr(r
.out
.result
));
2324 /* This shouldn't be a valid name */
2325 init_lsa_String(&account_bad
, talloc_asprintf(tctx
, "%sXX", account_string
));
2327 r
.in
.account
= &account_bad
;
2328 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2329 "ChangePasswordUser3 failed");
2330 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
2331 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2332 nt_errstr(r
.out
.result
));
2336 E_md4hash(oldpass
, old_nt_hash
);
2337 E_md4hash(newpass
, new_nt_hash
);
2339 E_deshash(oldpass
, old_lm_hash
);
2340 E_deshash(newpass
, new_lm_hash
);
2342 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2343 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2344 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2346 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2347 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2348 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2350 r
.in
.server
= &server
;
2351 r
.in
.account
= &account
;
2352 r
.in
.nt_password
= &nt_pass
;
2353 r
.in
.nt_verifier
= &nt_verifier
;
2355 r
.in
.lm_password
= &lm_pass
;
2356 r
.in
.lm_verifier
= &lm_verifier
;
2357 r
.in
.password3
= NULL
;
2358 r
.out
.dominfo
= &dominfo
;
2359 r
.out
.reject
= &reject
;
2361 unix_to_nt_time(&t
, time(NULL
));
2363 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2364 "ChangePasswordUser3 failed");
2366 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)
2369 && handle_reject_reason
2370 && (!null_nttime(last_password_change
) || !dominfo
->min_password_age
)) {
2371 if (dominfo
->password_properties
& DOMAIN_REFUSE_PASSWORD_CHANGE
) {
2373 if (reject
&& (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
)) {
2374 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2375 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2380 /* We tested the order of precendence which is as follows:
2389 if ((dominfo
->min_password_age
> 0) && !null_nttime(last_password_change
) &&
2390 (last_password_change
+ dominfo
->min_password_age
> t
)) {
2392 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2393 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2394 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2398 } else if ((dominfo
->min_password_length
> 0) &&
2399 (strlen(newpass
) < dominfo
->min_password_length
)) {
2401 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
) {
2402 torture_warning(tctx
, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2403 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
, reject
->extendedFailureReason
);
2407 } else if ((dominfo
->password_history_length
> 0) &&
2408 strequal(oldpass
, newpass
)) {
2410 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_PWD_IN_HISTORY
) {
2411 torture_warning(tctx
, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2412 SAM_PWD_CHANGE_PWD_IN_HISTORY
, reject
->extendedFailureReason
);
2415 } else if (dominfo
->password_properties
& DOMAIN_PASSWORD_COMPLEX
) {
2417 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NOT_COMPLEX
) {
2418 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2419 SAM_PWD_CHANGE_NOT_COMPLEX
, reject
->extendedFailureReason
);
2425 if (reject
->extendedFailureReason
== SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
) {
2426 /* retry with adjusted size */
2427 return test_ChangePasswordUser3(p
, tctx
, account_string
,
2428 dominfo
->min_password_length
,
2429 password
, NULL
, 0, false);
2433 } else if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2434 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2435 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2436 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2439 /* Perhaps the server has a 'min password age' set? */
2442 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ChangePasswordUser3");
2444 *password
= talloc_strdup(tctx
, newpass
);
2450 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2451 const char *account_string
,
2452 struct policy_handle
*handle
,
2456 struct samr_ChangePasswordUser3 r
;
2457 struct samr_SetUserInfo s
;
2458 union samr_UserInfo u
;
2459 DATA_BLOB session_key
;
2460 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
2461 uint8_t confounder
[16];
2462 struct MD5Context ctx
;
2465 struct lsa_String server
, account
;
2466 struct samr_CryptPassword nt_pass
;
2467 struct samr_Password nt_verifier
;
2468 DATA_BLOB new_random_pass
;
2471 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2472 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2474 struct samr_DomInfo1
*dominfo
= NULL
;
2475 struct userPwdChangeFailureInformation
*reject
= NULL
;
2477 new_random_pass
= samr_very_rand_pass(tctx
, 128);
2479 torture_assert(tctx
, *password
!= NULL
,
2480 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2482 oldpass
= *password
;
2483 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2484 init_lsa_String(&account
, account_string
);
2486 s
.in
.user_handle
= handle
;
2492 u
.info25
.info
.fields_present
= SAMR_FIELD_NT_PASSWORD_PRESENT
;
2494 set_pw_in_buffer(u
.info25
.password
.data
, &new_random_pass
);
2496 status
= dcerpc_fetch_session_key(p
, &session_key
);
2497 if (!NT_STATUS_IS_OK(status
)) {
2498 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
2499 s
.in
.level
, nt_errstr(status
));
2503 generate_random_buffer((uint8_t *)confounder
, 16);
2506 MD5Update(&ctx
, confounder
, 16);
2507 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
2508 MD5Final(confounded_session_key
.data
, &ctx
);
2510 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
2511 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
2513 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2515 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
2516 "SetUserInfo failed");
2517 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
2518 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
2519 s
.in
.level
, nt_errstr(s
.out
.result
));
2523 torture_comment(tctx
, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2525 mdfour(old_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2527 new_random_pass
= samr_very_rand_pass(tctx
, 128);
2529 mdfour(new_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2531 set_pw_in_buffer(nt_pass
.data
, &new_random_pass
);
2532 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2533 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2535 r
.in
.server
= &server
;
2536 r
.in
.account
= &account
;
2537 r
.in
.nt_password
= &nt_pass
;
2538 r
.in
.nt_verifier
= &nt_verifier
;
2540 r
.in
.lm_password
= NULL
;
2541 r
.in
.lm_verifier
= NULL
;
2542 r
.in
.password3
= NULL
;
2543 r
.out
.dominfo
= &dominfo
;
2544 r
.out
.reject
= &reject
;
2546 unix_to_nt_time(&t
, time(NULL
));
2548 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2549 "ChangePasswordUser3 failed");
2551 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2552 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2553 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2554 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2557 /* Perhaps the server has a 'min password age' set? */
2559 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2560 torture_warning(tctx
, "ChangePasswordUser3 failed - %s\n", nt_errstr(r
.out
.result
));
2564 newpass
= samr_rand_pass(tctx
, 128);
2566 mdfour(old_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2568 E_md4hash(newpass
, new_nt_hash
);
2570 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2571 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2572 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2574 r
.in
.server
= &server
;
2575 r
.in
.account
= &account
;
2576 r
.in
.nt_password
= &nt_pass
;
2577 r
.in
.nt_verifier
= &nt_verifier
;
2579 r
.in
.lm_password
= NULL
;
2580 r
.in
.lm_verifier
= NULL
;
2581 r
.in
.password3
= NULL
;
2582 r
.out
.dominfo
= &dominfo
;
2583 r
.out
.reject
= &reject
;
2585 unix_to_nt_time(&t
, time(NULL
));
2587 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2588 "ChangePasswordUser3 failed");
2590 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2591 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2592 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2593 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2596 /* Perhaps the server has a 'min password age' set? */
2599 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ChangePasswordUser3 (on second random password)");
2600 *password
= talloc_strdup(tctx
, newpass
);
2607 static bool test_GetMembersInAlias(struct dcerpc_binding_handle
*b
,
2608 struct torture_context
*tctx
,
2609 struct policy_handle
*alias_handle
)
2611 struct samr_GetMembersInAlias r
;
2612 struct lsa_SidArray sids
;
2614 torture_comment(tctx
, "Testing GetMembersInAlias\n");
2616 r
.in
.alias_handle
= alias_handle
;
2619 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetMembersInAlias_r(b
, tctx
, &r
),
2620 "GetMembersInAlias failed");
2621 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetMembersInAlias failed");
2626 static bool test_AddMemberToAlias(struct dcerpc_binding_handle
*b
,
2627 struct torture_context
*tctx
,
2628 struct policy_handle
*alias_handle
,
2629 const struct dom_sid
*domain_sid
)
2631 struct samr_AddAliasMember r
;
2632 struct samr_DeleteAliasMember d
;
2633 struct dom_sid
*sid
;
2635 sid
= dom_sid_add_rid(tctx
, domain_sid
, 512);
2637 torture_comment(tctx
, "Testing AddAliasMember\n");
2638 r
.in
.alias_handle
= alias_handle
;
2641 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddAliasMember_r(b
, tctx
, &r
),
2642 "AddAliasMember failed");
2643 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "AddAliasMember failed");
2645 d
.in
.alias_handle
= alias_handle
;
2648 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteAliasMember_r(b
, tctx
, &d
),
2649 "DeleteAliasMember failed");
2650 torture_assert_ntstatus_ok(tctx
, d
.out
.result
, "DelAliasMember failed");
2655 static bool test_AddMultipleMembersToAlias(struct dcerpc_binding_handle
*b
,
2656 struct torture_context
*tctx
,
2657 struct policy_handle
*alias_handle
)
2659 struct samr_AddMultipleMembersToAlias a
;
2660 struct samr_RemoveMultipleMembersFromAlias r
;
2661 struct lsa_SidArray sids
;
2663 torture_comment(tctx
, "Testing AddMultipleMembersToAlias\n");
2664 a
.in
.alias_handle
= alias_handle
;
2668 sids
.sids
= talloc_array(tctx
, struct lsa_SidPtr
, 3);
2670 sids
.sids
[0].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-1");
2671 sids
.sids
[1].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-2");
2672 sids
.sids
[2].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-3");
2674 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddMultipleMembersToAlias_r(b
, tctx
, &a
),
2675 "AddMultipleMembersToAlias failed");
2676 torture_assert_ntstatus_ok(tctx
, a
.out
.result
, "AddMultipleMembersToAlias");
2679 torture_comment(tctx
, "Testing RemoveMultipleMembersFromAlias\n");
2680 r
.in
.alias_handle
= alias_handle
;
2683 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b
, tctx
, &r
),
2684 "RemoveMultipleMembersFromAlias failed");
2685 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "RemoveMultipleMembersFromAlias failed");
2687 /* strange! removing twice doesn't give any error */
2688 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b
, tctx
, &r
),
2689 "RemoveMultipleMembersFromAlias failed");
2690 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "RemoveMultipleMembersFromAlias failed");
2692 /* but removing an alias that isn't there does */
2693 sids
.sids
[2].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-4");
2695 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b
, tctx
, &r
),
2696 "RemoveMultipleMembersFromAlias failed");
2697 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
, "RemoveMultipleMembersFromAlias");
2702 static bool test_GetAliasMembership(struct dcerpc_binding_handle
*b
,
2703 struct torture_context
*tctx
,
2704 struct policy_handle
*domain_handle
)
2706 struct samr_GetAliasMembership r
;
2707 struct lsa_SidArray sids
;
2708 struct samr_Ids rids
;
2710 torture_comment(tctx
, "Testing GetAliasMembership\n");
2712 r
.in
.domain_handle
= domain_handle
;
2717 sids
.sids
= talloc_zero_array(tctx
, struct lsa_SidPtr
, sids
.num_sids
);
2719 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetAliasMembership_r(b
, tctx
, &r
),
2720 "GetAliasMembership failed");
2721 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
2722 "samr_GetAliasMembership failed");
2724 torture_assert_int_equal(tctx
, sids
.num_sids
, rids
.count
,
2725 "protocol misbehaviour");
2728 sids
.sids
= talloc_zero_array(tctx
, struct lsa_SidPtr
, sids
.num_sids
);
2729 sids
.sids
[0].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-1");
2731 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetAliasMembership_r(b
, tctx
, &r
),
2732 "samr_GetAliasMembership failed");
2733 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
2734 "samr_GetAliasMembership failed");
2737 /* only true for w2k8 it seems
2738 * win7, xp, w2k3 will return a 0 length array pointer */
2740 if (rids
.ids
&& (rids
.count
== 0)) {
2741 torture_fail(tctx
, "samr_GetAliasMembership returned 0 count and a rids array");
2744 if (!rids
.ids
&& rids
.count
) {
2745 torture_fail(tctx
, "samr_GetAliasMembership returned non-0 count but no rids");
2751 static bool test_TestPrivateFunctionsUser(struct dcerpc_binding_handle
*b
,
2752 struct torture_context
*tctx
,
2753 struct policy_handle
*user_handle
)
2755 struct samr_TestPrivateFunctionsUser r
;
2757 torture_comment(tctx
, "Testing TestPrivateFunctionsUser\n");
2759 r
.in
.user_handle
= user_handle
;
2761 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_TestPrivateFunctionsUser_r(b
, tctx
, &r
),
2762 "TestPrivateFunctionsUser failed");
2763 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_NOT_IMPLEMENTED
, "TestPrivateFunctionsUser");
2768 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_binding_handle
*b
,
2769 struct torture_context
*tctx
,
2770 struct policy_handle
*handle
,
2775 uint16_t levels
[] = { /* 3, */ 5, 21 };
2777 NTTIME pwdlastset3
= 0;
2778 NTTIME pwdlastset5
= 0;
2779 NTTIME pwdlastset21
= 0;
2781 torture_comment(tctx
, "Testing QueryUserInfo%s level 5 and 21 call ",
2782 use_info2
? "2":"");
2784 for (i
=0; i
<ARRAY_SIZE(levels
); i
++) {
2786 struct samr_QueryUserInfo r
;
2787 struct samr_QueryUserInfo2 r2
;
2788 union samr_UserInfo
*info
;
2791 r2
.in
.user_handle
= handle
;
2792 r2
.in
.level
= levels
[i
];
2793 r2
.out
.info
= &info
;
2794 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo2_r(b
, tctx
, &r2
),
2795 "QueryUserInfo2 failed");
2796 status
= r2
.out
.result
;
2799 r
.in
.user_handle
= handle
;
2800 r
.in
.level
= levels
[i
];
2802 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
2803 "QueryUserInfo failed");
2804 status
= r
.out
.result
;
2807 if (!NT_STATUS_IS_OK(status
) &&
2808 !NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_INFO_CLASS
)) {
2809 torture_warning(tctx
, "QueryUserInfo%s level %u failed - %s\n",
2810 use_info2
? "2":"", levels
[i
], nt_errstr(status
));
2814 switch (levels
[i
]) {
2816 pwdlastset3
= info
->info3
.last_password_change
;
2819 pwdlastset5
= info
->info5
.last_password_change
;
2822 pwdlastset21
= info
->info21
.last_password_change
;
2828 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2829 "pwdlastset mixup"); */
2830 torture_assert_int_equal(tctx
, pwdlastset5
, pwdlastset21
,
2831 "pwdlastset mixup");
2833 *pwdlastset
= pwdlastset21
;
2835 torture_comment(tctx
, "(pwdlastset: %llu)\n",
2836 (unsigned long long) *pwdlastset
);
2841 static bool test_SamLogon(struct torture_context
*tctx
,
2842 struct dcerpc_pipe
*p
,
2843 struct cli_credentials
*test_credentials
,
2844 NTSTATUS expected_result
,
2848 struct netr_LogonSamLogonEx r
;
2849 union netr_LogonLevel logon
;
2850 union netr_Validation validation
;
2851 uint8_t authoritative
;
2852 struct netr_IdentityInfo identity
;
2853 struct netr_NetworkInfo ninfo
;
2854 struct netr_PasswordInfo pinfo
;
2855 DATA_BLOB names_blob
, chal
, lm_resp
, nt_resp
;
2856 int flags
= CLI_CRED_NTLM_AUTH
;
2857 uint32_t samlogon_flags
= 0;
2858 struct netlogon_creds_CredentialState
*creds
;
2859 struct netr_Authenticator a
;
2860 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2862 torture_assert_ntstatus_ok(tctx
, dcerpc_schannel_creds(p
->conn
->security_state
.generic_state
, tctx
, &creds
), "");
2864 if (lpcfg_client_lanman_auth(tctx
->lp_ctx
)) {
2865 flags
|= CLI_CRED_LANMAN_AUTH
;
2868 if (lpcfg_client_ntlmv2_auth(tctx
->lp_ctx
)) {
2869 flags
|= CLI_CRED_NTLMv2_AUTH
;
2872 cli_credentials_get_ntlm_username_domain(test_credentials
, tctx
,
2873 &identity
.account_name
.string
,
2874 &identity
.domain_name
.string
);
2876 identity
.parameter_control
=
2877 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT
|
2878 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT
;
2879 identity
.logon_id_low
= 0;
2880 identity
.logon_id_high
= 0;
2881 identity
.workstation
.string
= cli_credentials_get_workstation(test_credentials
);
2884 netlogon_creds_client_authenticator(creds
, &a
);
2886 if (!E_deshash(cli_credentials_get_password(test_credentials
), pinfo
.lmpassword
.hash
)) {
2887 ZERO_STRUCT(pinfo
.lmpassword
.hash
);
2889 E_md4hash(cli_credentials_get_password(test_credentials
), pinfo
.ntpassword
.hash
);
2891 if (creds
->negotiate_flags
& NETLOGON_NEG_ARCFOUR
) {
2892 netlogon_creds_arcfour_crypt(creds
, pinfo
.lmpassword
.hash
, 16);
2893 netlogon_creds_arcfour_crypt(creds
, pinfo
.ntpassword
.hash
, 16);
2895 netlogon_creds_des_encrypt(creds
, &pinfo
.lmpassword
);
2896 netlogon_creds_des_encrypt(creds
, &pinfo
.ntpassword
);
2899 pinfo
.identity_info
= identity
;
2900 logon
.password
= &pinfo
;
2902 r
.in
.logon_level
= NetlogonInteractiveInformation
;
2904 generate_random_buffer(ninfo
.challenge
,
2905 sizeof(ninfo
.challenge
));
2906 chal
= data_blob_const(ninfo
.challenge
,
2907 sizeof(ninfo
.challenge
));
2909 names_blob
= NTLMv2_generate_names_blob(tctx
, cli_credentials_get_workstation(test_credentials
),
2910 cli_credentials_get_domain(test_credentials
));
2912 status
= cli_credentials_get_ntlm_response(test_credentials
, tctx
,
2918 torture_assert_ntstatus_ok(tctx
, status
, "cli_credentials_get_ntlm_response failed");
2920 ninfo
.lm
.data
= lm_resp
.data
;
2921 ninfo
.lm
.length
= lm_resp
.length
;
2923 ninfo
.nt
.data
= nt_resp
.data
;
2924 ninfo
.nt
.length
= nt_resp
.length
;
2926 ninfo
.identity_info
= identity
;
2927 logon
.network
= &ninfo
;
2929 r
.in
.logon_level
= NetlogonNetworkInformation
;
2932 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2933 r
.in
.computer_name
= cli_credentials_get_workstation(test_credentials
);
2934 r
.in
.logon
= &logon
;
2935 r
.in
.flags
= &samlogon_flags
;
2936 r
.out
.flags
= &samlogon_flags
;
2937 r
.out
.validation
= &validation
;
2938 r
.out
.authoritative
= &authoritative
;
2940 torture_comment(tctx
, "Testing LogonSamLogon with name %s\n", identity
.account_name
.string
);
2942 r
.in
.validation_level
= 6;
2944 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonSamLogonEx_r(b
, tctx
, &r
),
2945 "netr_LogonSamLogonEx failed");
2946 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_INFO_CLASS
)) {
2947 r
.in
.validation_level
= 3;
2948 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonSamLogonEx_r(b
, tctx
, &r
),
2949 "netr_LogonSamLogonEx failed");
2951 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2952 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, expected_result
, "LogonSamLogonEx failed");
2955 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LogonSamLogonEx failed");
2961 static bool test_SamLogon_with_creds(struct torture_context
*tctx
,
2962 struct dcerpc_pipe
*p
,
2963 struct cli_credentials
*machine_creds
,
2964 const char *acct_name
,
2965 const char *password
,
2966 NTSTATUS expected_samlogon_result
,
2970 struct cli_credentials
*test_credentials
;
2972 test_credentials
= cli_credentials_init(tctx
);
2974 cli_credentials_set_workstation(test_credentials
,
2975 cli_credentials_get_workstation(machine_creds
), CRED_SPECIFIED
);
2976 cli_credentials_set_domain(test_credentials
,
2977 cli_credentials_get_domain(machine_creds
), CRED_SPECIFIED
);
2978 cli_credentials_set_username(test_credentials
,
2979 acct_name
, CRED_SPECIFIED
);
2980 cli_credentials_set_password(test_credentials
,
2981 password
, CRED_SPECIFIED
);
2983 torture_comment(tctx
, "Testing samlogon (%s) as %s password: %s\n",
2984 interactive
? "interactive" : "network", acct_name
, password
);
2986 if (!test_SamLogon(tctx
, p
, test_credentials
,
2987 expected_samlogon_result
, interactive
)) {
2988 torture_warning(tctx
, "new password did not work\n");
2995 static bool test_SetPassword_level(struct dcerpc_pipe
*p
,
2996 struct dcerpc_pipe
*np
,
2997 struct torture_context
*tctx
,
2998 struct policy_handle
*handle
,
3000 uint32_t fields_present
,
3001 uint8_t password_expired
,
3002 bool *matched_expected_error
,
3004 const char *acct_name
,
3006 struct cli_credentials
*machine_creds
,
3007 bool use_queryinfo2
,
3009 NTSTATUS expected_samlogon_result
)
3011 const char *fields
= NULL
;
3013 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3019 fields
= talloc_asprintf(tctx
, "(fields_present: 0x%08x)",
3026 torture_comment(tctx
, "Testing SetUserInfo%s level %d call "
3027 "(password_expired: %d) %s\n",
3028 use_setinfo2
? "2":"", level
, password_expired
,
3029 fields
? fields
: "");
3031 if (!test_SetUserPass_level_ex(p
, tctx
, handle
, level
,
3036 matched_expected_error
)) {
3040 if (!test_QueryUserInfo_pwdlastset(b
, tctx
, handle
,
3046 if (*matched_expected_error
== true) {
3050 if (!test_SamLogon_with_creds(tctx
, np
,
3054 expected_samlogon_result
,
3062 static bool setup_schannel_netlogon_pipe(struct torture_context
*tctx
,
3063 struct cli_credentials
*credentials
,
3064 struct dcerpc_pipe
**p
)
3066 struct dcerpc_binding
*b
;
3068 torture_assert_ntstatus_ok(tctx
, torture_rpc_binding(tctx
, &b
),
3069 "failed to get rpc binding");
3071 /* We have to use schannel, otherwise the SamLogonEx fails
3072 * with INTERNAL_ERROR */
3074 b
->flags
&= ~DCERPC_AUTH_OPTIONS
;
3075 b
->flags
|= DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_128
;
3077 torture_assert_ntstatus_ok(tctx
,
3078 dcerpc_pipe_connect_b(tctx
, p
, b
, &ndr_table_netlogon
,
3079 credentials
, tctx
->ev
, tctx
->lp_ctx
),
3080 "failed to bind to netlogon");
3085 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe
*p
,
3086 struct torture_context
*tctx
,
3087 uint32_t acct_flags
,
3088 const char *acct_name
,
3089 struct policy_handle
*handle
,
3091 struct cli_credentials
*machine_credentials
)
3093 int s
= 0, q
= 0, f
= 0, l
= 0, z
= 0;
3096 bool set_levels
[] = { false, true };
3097 bool query_levels
[] = { false, true };
3098 uint32_t levels
[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
3099 uint32_t nonzeros
[] = { 1, 24 };
3100 uint32_t fields_present
[] = {
3102 SAMR_FIELD_EXPIRED_FLAG
,
3103 SAMR_FIELD_LAST_PWD_CHANGE
,
3104 SAMR_FIELD_EXPIRED_FLAG
| SAMR_FIELD_LAST_PWD_CHANGE
,
3106 SAMR_FIELD_NT_PASSWORD_PRESENT
,
3107 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
,
3108 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
,
3109 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
,
3110 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_EXPIRED_FLAG
,
3111 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_EXPIRED_FLAG
,
3112 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
| SAMR_FIELD_EXPIRED_FLAG
3114 struct dcerpc_pipe
*np
= NULL
;
3116 if (torture_setting_bool(tctx
, "samba3", false) ||
3117 torture_setting_bool(tctx
, "samba4", false)) {
3119 torture_comment(tctx
, "Samba3 has second granularity, setting delay to: %d\n",
3123 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
3125 /* set to 1 to enable testing for all possible opcode
3126 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3129 #define TEST_ALL_LEVELS 1
3130 #define TEST_SET_LEVELS 1
3131 #define TEST_QUERY_LEVELS 1
3133 #ifdef TEST_ALL_LEVELS
3134 for (l
=0; l
<ARRAY_SIZE(levels
); l
++) {
3136 for (l
=0; l
<(ARRAY_SIZE(levels
))/2; l
++) {
3138 for (z
=0; z
<ARRAY_SIZE(nonzeros
); z
++) {
3139 for (f
=0; f
<ARRAY_SIZE(fields_present
); f
++) {
3140 #ifdef TEST_SET_LEVELS
3141 for (s
=0; s
<ARRAY_SIZE(set_levels
); s
++) {
3143 #ifdef TEST_QUERY_LEVELS
3144 for (q
=0; q
<ARRAY_SIZE(query_levels
); q
++) {
3146 NTTIME pwdlastset_old
= 0;
3147 NTTIME pwdlastset_new
= 0;
3148 bool matched_expected_error
= false;
3149 NTSTATUS expected_samlogon_result
= NT_STATUS_ACCOUNT_DISABLED
;
3151 torture_comment(tctx
, "------------------------------\n"
3152 "Testing pwdLastSet attribute for flags: 0x%08x "
3153 "(s: %d (l: %d), q: %d)\n",
3154 acct_flags
, s
, levels
[l
], q
);
3156 switch (levels
[l
]) {
3160 if (!((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3161 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
))) {
3162 expected_samlogon_result
= NT_STATUS_WRONG_PASSWORD
;
3170 /* set a password and force password change (pwdlastset 0) by
3171 * setting the password expired flag to a non-0 value */
3173 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3177 &matched_expected_error
,
3181 machine_credentials
,
3184 expected_samlogon_result
)) {
3188 if (matched_expected_error
== true) {
3189 /* skipping on expected failure */
3193 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3194 * set without the SAMR_FIELD_EXPIRED_FLAG */
3196 switch (levels
[l
]) {
3200 if ((pwdlastset_new
!= 0) &&
3201 !(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
)) {
3202 torture_comment(tctx
, "not considering a non-0 "
3203 "pwdLastSet as a an error as the "
3204 "SAMR_FIELD_EXPIRED_FLAG has not "
3210 if (pwdlastset_new
!= 0) {
3211 torture_warning(tctx
, "pwdLastSet test failed: "
3212 "expected pwdLastSet 0 but got %llu\n",
3213 (unsigned long long) pwdlastset_old
);
3219 switch (levels
[l
]) {
3223 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3224 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3225 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3226 (pwdlastset_old
>= pwdlastset_new
)) {
3227 torture_warning(tctx
, "pwdlastset not increasing\n");
3233 pwdlastset_old
= pwdlastset_new
;
3239 /* set a password, pwdlastset needs to get updated (increased
3240 * value), password_expired value used here is 0 */
3242 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3246 &matched_expected_error
,
3250 machine_credentials
,
3253 expected_samlogon_result
)) {
3257 /* when a password has been changed, pwdlastset must not be 0 afterwards
3258 * and must be larger then the old value */
3260 switch (levels
[l
]) {
3264 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3265 * password has been changed, old and new pwdlastset
3266 * need to be the same value */
3268 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
3269 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3270 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3272 torture_assert_int_equal(tctx
, pwdlastset_old
,
3273 pwdlastset_new
, "pwdlastset must be equal");
3278 if (pwdlastset_old
>= pwdlastset_new
) {
3279 torture_warning(tctx
, "pwdLastSet test failed: "
3280 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3281 (unsigned long long) pwdlastset_old
,
3282 (unsigned long long) pwdlastset_new
);
3285 if (pwdlastset_new
== 0) {
3286 torture_warning(tctx
, "pwdLastSet test failed: "
3287 "expected non-0 pwdlastset, got: %llu\n",
3288 (unsigned long long) pwdlastset_new
);
3294 switch (levels
[l
]) {
3298 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3299 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3300 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3301 (pwdlastset_old
>= pwdlastset_new
)) {
3302 torture_warning(tctx
, "pwdlastset not increasing\n");
3308 pwdlastset_old
= pwdlastset_new
;
3314 /* set a password, pwdlastset needs to get updated (increased
3315 * value), password_expired value used here is 0 */
3317 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3321 &matched_expected_error
,
3325 machine_credentials
,
3328 expected_samlogon_result
)) {
3332 /* when a password has been changed, pwdlastset must not be 0 afterwards
3333 * and must be larger then the old value */
3335 switch (levels
[l
]) {
3340 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3341 * password has been changed, old and new pwdlastset
3342 * need to be the same value */
3344 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
3345 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3346 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3348 torture_assert_int_equal(tctx
, pwdlastset_old
,
3349 pwdlastset_new
, "pwdlastset must be equal");
3354 if (pwdlastset_old
>= pwdlastset_new
) {
3355 torture_warning(tctx
, "pwdLastSet test failed: "
3356 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3357 (unsigned long long) pwdlastset_old
,
3358 (unsigned long long) pwdlastset_new
);
3361 if (pwdlastset_new
== 0) {
3362 torture_warning(tctx
, "pwdLastSet test failed: "
3363 "expected non-0 pwdlastset, got: %llu\n",
3364 (unsigned long long) pwdlastset_new
);
3370 switch (levels
[l
]) {
3374 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3375 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3376 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3377 (pwdlastset_old
>= pwdlastset_new
)) {
3378 torture_warning(tctx
, "pwdlastset not increasing\n");
3384 pwdlastset_old
= pwdlastset_new
;
3390 /* set a password and force password change (pwdlastset 0) by
3391 * setting the password expired flag to a non-0 value */
3393 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3397 &matched_expected_error
,
3401 machine_credentials
,
3404 expected_samlogon_result
)) {
3408 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3409 * set without the SAMR_FIELD_EXPIRED_FLAG */
3411 switch (levels
[l
]) {
3415 if ((pwdlastset_new
!= 0) &&
3416 !(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
)) {
3417 torture_comment(tctx
, "not considering a non-0 "
3418 "pwdLastSet as a an error as the "
3419 "SAMR_FIELD_EXPIRED_FLAG has not "
3424 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3425 * password has been changed, old and new pwdlastset
3426 * need to be the same value */
3428 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
3429 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3430 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3432 torture_assert_int_equal(tctx
, pwdlastset_old
,
3433 pwdlastset_new
, "pwdlastset must be equal");
3438 if (pwdlastset_new
!= 0) {
3439 torture_warning(tctx
, "pwdLastSet test failed: "
3440 "expected pwdLastSet 0, got %llu\n",
3441 (unsigned long long) pwdlastset_old
);
3447 switch (levels
[l
]) {
3451 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3452 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3453 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3454 (pwdlastset_old
>= pwdlastset_new
)) {
3455 torture_warning(tctx
, "pwdlastset not increasing\n");
3461 /* if the level we are testing does not have a fields_present
3462 * field, skip all fields present tests by setting f to to
3464 switch (levels
[l
]) {
3468 f
= ARRAY_SIZE(fields_present
);
3472 #ifdef TEST_QUERY_LEVELS
3475 #ifdef TEST_SET_LEVELS
3478 } /* fields present */
3482 #undef TEST_SET_LEVELS
3483 #undef TEST_QUERY_LEVELS
3490 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_binding_handle
*b
,
3491 struct torture_context
*tctx
,
3492 struct policy_handle
*handle
,
3493 uint32_t *badpwdcount
)
3495 union samr_UserInfo
*info
;
3496 struct samr_QueryUserInfo r
;
3498 r
.in
.user_handle
= handle
;
3502 torture_comment(tctx
, "Testing QueryUserInfo level %d", r
.in
.level
);
3504 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
3505 "failed to query userinfo");
3506 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
3507 "failed to query userinfo");
3509 *badpwdcount
= info
->info3
.bad_password_count
;
3511 torture_comment(tctx
, " (bad password count: %d)\n", *badpwdcount
);
3516 static bool test_SetUserInfo_acct_flags(struct dcerpc_binding_handle
*b
,
3517 struct torture_context
*tctx
,
3518 struct policy_handle
*user_handle
,
3519 uint32_t acct_flags
)
3521 struct samr_SetUserInfo r
;
3522 union samr_UserInfo user_info
;
3524 torture_comment(tctx
, "Testing SetUserInfo level 16\n");
3526 user_info
.info16
.acct_flags
= acct_flags
;
3528 r
.in
.user_handle
= user_handle
;
3530 r
.in
.info
= &user_info
;
3532 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &r
),
3533 "failed to set account flags");
3534 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
3535 "failed to set account flags");
3540 static bool test_reset_badpwdcount(struct dcerpc_pipe
*p
,
3541 struct torture_context
*tctx
,
3542 struct policy_handle
*user_handle
,
3543 uint32_t acct_flags
,
3546 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3548 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
3549 "failed to set password");
3551 torture_comment(tctx
, "Testing SetUserInfo level 16 (enable account)\n");
3553 torture_assert(tctx
,
3554 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
3555 acct_flags
& ~ACB_DISABLED
),
3556 "failed to enable user");
3558 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
3559 "failed to set password");
3564 static bool test_SetDomainInfo(struct dcerpc_binding_handle
*b
,
3565 struct torture_context
*tctx
,
3566 struct policy_handle
*domain_handle
,
3567 enum samr_DomainInfoClass level
,
3568 union samr_DomainInfo
*info
)
3570 struct samr_SetDomainInfo r
;
3572 r
.in
.domain_handle
= domain_handle
;
3576 torture_assert_ntstatus_ok(tctx
,
3577 dcerpc_samr_SetDomainInfo_r(b
, tctx
, &r
),
3578 "failed to set domain info");
3579 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
3580 "failed to set domain info");
3585 static bool test_SetDomainInfo_ntstatus(struct dcerpc_binding_handle
*b
,
3586 struct torture_context
*tctx
,
3587 struct policy_handle
*domain_handle
,
3588 enum samr_DomainInfoClass level
,
3589 union samr_DomainInfo
*info
,
3592 struct samr_SetDomainInfo r
;
3594 r
.in
.domain_handle
= domain_handle
;
3598 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &r
),
3599 "SetDomainInfo failed");
3600 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, expected
, "");
3605 static bool test_QueryDomainInfo2_level(struct dcerpc_binding_handle
*b
,
3606 struct torture_context
*tctx
,
3607 struct policy_handle
*domain_handle
,
3608 enum samr_DomainInfoClass level
,
3609 union samr_DomainInfo
**q_info
)
3611 struct samr_QueryDomainInfo2 r
;
3613 r
.in
.domain_handle
= domain_handle
;
3615 r
.out
.info
= q_info
;
3617 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo2_r(b
, tctx
, &r
),
3618 "failed to query domain info");
3619 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
3620 "failed to query domain info");
3625 static bool test_Password_badpwdcount(struct dcerpc_pipe
*p
,
3626 struct dcerpc_pipe
*np
,
3627 struct torture_context
*tctx
,
3628 uint32_t acct_flags
,
3629 const char *acct_name
,
3630 struct policy_handle
*domain_handle
,
3631 struct policy_handle
*user_handle
,
3633 struct cli_credentials
*machine_credentials
,
3634 const char *comment
,
3637 NTSTATUS expected_success_status
,
3638 struct samr_DomInfo1
*info1
,
3639 struct samr_DomInfo12
*info12
)
3641 union samr_DomainInfo info
;
3644 uint32_t badpwdcount
, tmp
;
3645 uint32_t password_history_length
= 12;
3646 uint32_t lockout_threshold
= 15;
3647 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3649 torture_comment(tctx
, "\nTesting bad pwd count with: %s\n", comment
);
3651 torture_assert(tctx
, password_history_length
< lockout_threshold
,
3652 "password history length needs to be smaller than account lockout threshold for this test");
3657 info
.info1
= *info1
;
3658 info
.info1
.password_history_length
= password_history_length
;
3660 torture_assert(tctx
,
3661 test_SetDomainInfo(b
, tctx
, domain_handle
,
3662 DomainPasswordInformation
, &info
),
3663 "failed to set password history length");
3665 info
.info12
= *info12
;
3666 info
.info12
.lockout_threshold
= lockout_threshold
;
3668 torture_assert(tctx
,
3669 test_SetDomainInfo(b
, tctx
, domain_handle
,
3670 DomainLockoutInformation
, &info
),
3671 "failed to set lockout threshold");
3673 /* reset bad pwd count */
3675 torture_assert(tctx
,
3676 test_reset_badpwdcount(p
, tctx
, user_handle
, acct_flags
, password
), "");
3679 /* enable or disable account */
3681 torture_assert(tctx
,
3682 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
3683 acct_flags
| ACB_DISABLED
),
3684 "failed to disable user");
3686 torture_assert(tctx
,
3687 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
3688 acct_flags
& ~ACB_DISABLED
),
3689 "failed to enable user");
3693 /* setup password history */
3695 passwords
= talloc_array(tctx
, char *, password_history_length
);
3697 for (i
=0; i
< password_history_length
; i
++) {
3699 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
3700 "failed to set password");
3701 passwords
[i
] = talloc_strdup(tctx
, *password
);
3703 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3704 acct_name
, passwords
[i
],
3705 expected_success_status
, interactive
)) {
3706 torture_fail(tctx
, "failed to auth with latest password");
3709 torture_assert(tctx
,
3710 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3712 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3716 /* test with wrong password */
3718 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3719 acct_name
, "random_crap",
3720 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
3721 torture_fail(tctx
, "succeeded to authenticate with wrong password");
3724 torture_assert(tctx
,
3725 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3727 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
3730 /* test with latest good password */
3732 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
3733 passwords
[password_history_length
-1],
3734 expected_success_status
, interactive
)) {
3735 torture_fail(tctx
, "succeeded to authenticate with wrong password");
3738 torture_assert(tctx
,
3739 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3742 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
3744 /* only enabled accounts get the bad pwd count reset upon
3745 * successful logon */
3746 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3752 /* test password history */
3754 for (i
=0; i
< password_history_length
; i
++) {
3756 torture_comment(tctx
, "Testing bad password count behavior with "
3757 "password #%d of #%d\n", i
, password_history_length
);
3759 /* - network samlogon will succeed auth and not
3760 * increase badpwdcount for 2 last entries
3761 * - interactive samlogon only for the last one */
3763 if (i
== password_history_length
- 1 ||
3764 (i
== password_history_length
- 2 && !interactive
)) {
3766 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3767 acct_name
, passwords
[i
],
3768 expected_success_status
, interactive
)) {
3769 torture_fail(tctx
, talloc_asprintf(tctx
, "succeeded to authenticate with old password (#%d of #%d in history)", i
, password_history_length
));
3772 torture_assert(tctx
,
3773 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3776 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
3777 torture_assert_int_equal(tctx
, badpwdcount
, tmp
, "unexpected badpwdcount");
3779 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
3780 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3788 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3789 acct_name
, passwords
[i
],
3790 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
3791 torture_fail(tctx
, talloc_asprintf(tctx
, "succeeded to authenticate with old password (#%d of #%d in history)", i
, password_history_length
));
3794 torture_assert(tctx
,
3795 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3797 /* - network samlogon will fail auth but not increase
3798 * badpwdcount for 3rd last entry
3799 * - interactive samlogon for 3rd and 2nd last entry */
3801 if (i
== password_history_length
- 3 ||
3802 (i
== password_history_length
- 2 && interactive
)) {
3803 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
3804 torture_assert_int_equal(tctx
, badpwdcount
, tmp
, "unexpected badpwdcount");
3806 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
3807 torture_assert_int_equal(tctx
, badpwdcount
, tmp
+ 1, "unexpected badpwdcount");
3816 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe
*p
,
3817 struct torture_context
*tctx
,
3818 uint32_t acct_flags
,
3819 const char *acct_name
,
3820 struct policy_handle
*domain_handle
,
3821 struct policy_handle
*user_handle
,
3823 struct cli_credentials
*machine_credentials
)
3825 union samr_DomainInfo
*q_info
, s_info
;
3826 struct samr_DomInfo1 info1
, _info1
;
3827 struct samr_DomInfo12 info12
, _info12
;
3829 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3830 struct dcerpc_pipe
*np
;
3834 const char *comment
;
3837 NTSTATUS expected_success_status
;
3840 .comment
= "network logon (disabled account)",
3842 .interactive
= false,
3843 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
3846 .comment
= "network logon (enabled account)",
3848 .interactive
= false,
3849 .expected_success_status
= NT_STATUS_OK
3852 .comment
= "interactive logon (disabled account)",
3854 .interactive
= true,
3855 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
3858 .comment
= "interactive logon (enabled account)",
3860 .interactive
= true,
3861 .expected_success_status
= NT_STATUS_OK
3865 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
3867 /* backup old policies */
3869 torture_assert(tctx
,
3870 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
3871 DomainPasswordInformation
, &q_info
),
3872 "failed to query domain info level 1");
3874 info1
= q_info
->info1
;
3877 torture_assert(tctx
,
3878 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
3879 DomainLockoutInformation
, &q_info
),
3880 "failed to query domain info level 12");
3882 info12
= q_info
->info12
;
3887 for (i
=0; i
< ARRAY_SIZE(creds
); i
++) {
3889 /* skip trust tests for now */
3890 if (acct_flags
& ACB_WSTRUST
||
3891 acct_flags
& ACB_SVRTRUST
||
3892 acct_flags
& ACB_DOMTRUST
) {
3896 ret
&= test_Password_badpwdcount(p
, np
, tctx
, acct_flags
, acct_name
,
3897 domain_handle
, user_handle
, password
,
3898 machine_credentials
,
3901 creds
[i
].interactive
,
3902 creds
[i
].expected_success_status
,
3905 torture_warning(tctx
, "TEST #%d (%s) failed\n", i
, creds
[i
].comment
);
3907 torture_comment(tctx
, "TEST #%d (%s) succeeded\n", i
, creds
[i
].comment
);
3911 /* restore policies */
3913 s_info
.info1
= info1
;
3915 torture_assert(tctx
,
3916 test_SetDomainInfo(b
, tctx
, domain_handle
,
3917 DomainPasswordInformation
, &s_info
),
3918 "failed to set password information");
3920 s_info
.info12
= info12
;
3922 torture_assert(tctx
,
3923 test_SetDomainInfo(b
, tctx
, domain_handle
,
3924 DomainLockoutInformation
, &s_info
),
3925 "failed to set lockout information");
3930 static bool test_QueryUserInfo_acct_flags(struct dcerpc_binding_handle
*b
,
3931 struct torture_context
*tctx
,
3932 struct policy_handle
*handle
,
3933 uint32_t *acct_flags
)
3935 union samr_UserInfo
*info
;
3936 struct samr_QueryUserInfo r
;
3938 r
.in
.user_handle
= handle
;
3942 torture_comment(tctx
, "Testing QueryUserInfo level %d", r
.in
.level
);
3944 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
3945 "failed to query userinfo");
3946 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
3947 "failed to query userinfo");
3949 *acct_flags
= info
->info16
.acct_flags
;
3951 torture_comment(tctx
, " (acct_flags: 0x%08x)\n", *acct_flags
);
3956 static bool test_Password_lockout(struct dcerpc_pipe
*p
,
3957 struct dcerpc_pipe
*np
,
3958 struct torture_context
*tctx
,
3959 uint32_t acct_flags
,
3960 const char *acct_name
,
3961 struct policy_handle
*domain_handle
,
3962 struct policy_handle
*user_handle
,
3964 struct cli_credentials
*machine_credentials
,
3965 const char *comment
,
3968 NTSTATUS expected_success_status
,
3969 struct samr_DomInfo1
*info1
,
3970 struct samr_DomInfo12
*info12
)
3972 union samr_DomainInfo info
;
3973 uint32_t badpwdcount
;
3974 uint32_t password_history_length
= 1;
3975 uint64_t lockout_threshold
= 1;
3976 uint32_t lockout_seconds
= 5;
3977 uint64_t delta_time_factor
= 10 * 1000 * 1000;
3978 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3980 torture_comment(tctx
, "\nTesting account lockout: %s\n", comment
);
3984 info
.info1
= *info1
;
3986 torture_comment(tctx
, "setting password history length.\n");
3987 info
.info1
.password_history_length
= password_history_length
;
3989 torture_assert(tctx
,
3990 test_SetDomainInfo(b
, tctx
, domain_handle
,
3991 DomainPasswordInformation
, &info
),
3992 "failed to set password history length");
3994 info
.info12
= *info12
;
3995 info
.info12
.lockout_threshold
= lockout_threshold
;
3997 /* set lockout duration < lockout window: should fail */
3998 info
.info12
.lockout_duration
= ~(lockout_seconds
* delta_time_factor
);
3999 info
.info12
.lockout_window
= ~((lockout_seconds
+ 1) * delta_time_factor
);
4001 torture_assert(tctx
,
4002 test_SetDomainInfo_ntstatus(b
, tctx
, domain_handle
,
4003 DomainLockoutInformation
, &info
,
4004 NT_STATUS_INVALID_PARAMETER
),
4005 "setting lockout duration < lockout window gave unexpected result");
4007 info
.info12
.lockout_duration
= 0;
4008 info
.info12
.lockout_window
= 0;
4010 torture_assert(tctx
,
4011 test_SetDomainInfo(b
, tctx
, domain_handle
,
4012 DomainLockoutInformation
, &info
),
4013 "failed to set lockout window and duration to 0");
4016 /* set lockout duration of 5 seconds */
4017 info
.info12
.lockout_duration
= ~(lockout_seconds
* delta_time_factor
);
4018 info
.info12
.lockout_window
= ~(lockout_seconds
* delta_time_factor
);
4020 torture_assert(tctx
,
4021 test_SetDomainInfo(b
, tctx
, domain_handle
,
4022 DomainLockoutInformation
, &info
),
4023 "failed to set lockout window and duration to 5 seconds");
4025 /* reset bad pwd count */
4027 torture_assert(tctx
,
4028 test_reset_badpwdcount(p
, tctx
, user_handle
, acct_flags
, password
), "");
4031 /* enable or disable account */
4034 torture_assert(tctx
,
4035 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
4036 acct_flags
| ACB_DISABLED
),
4037 "failed to disable user");
4039 torture_assert(tctx
,
4040 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
4041 acct_flags
& ~ACB_DISABLED
),
4042 "failed to enable user");
4046 /* test logon with right password */
4048 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
4049 acct_name
, *password
,
4050 expected_success_status
, interactive
)) {
4051 torture_fail(tctx
, "failed to auth with latest password");
4054 torture_assert(tctx
,
4055 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4056 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
4059 /* test with wrong password ==> lockout */
4061 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
4062 acct_name
, "random_crap",
4063 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
4064 torture_fail(tctx
, "succeeded to authenticate with wrong password");
4067 torture_assert(tctx
,
4068 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4069 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
4071 torture_assert(tctx
,
4072 test_QueryUserInfo_acct_flags(b
, tctx
, user_handle
, &acct_flags
), "");
4073 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
4074 "expected account to be locked");
4077 /* test with good password */
4079 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
4081 NT_STATUS_ACCOUNT_LOCKED_OUT
, interactive
))
4083 torture_fail(tctx
, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4086 /* bad pwd count should not get updated */
4087 torture_assert(tctx
,
4088 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4089 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
4091 /* curiously, windows does _not_ set the autlock flag */
4092 torture_assert(tctx
,
4093 test_QueryUserInfo_acct_flags(b
, tctx
, user_handle
, &acct_flags
), "");
4094 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
4095 "expected account to be locked");
4098 /* with bad password */
4100 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
4101 acct_name
, "random_crap2",
4102 NT_STATUS_ACCOUNT_LOCKED_OUT
, interactive
))
4104 torture_fail(tctx
, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4107 /* bad pwd count should not get updated */
4108 torture_assert(tctx
,
4109 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4110 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
4112 /* curiously, windows does _not_ set the autlock flag */
4113 torture_assert(tctx
,
4114 test_QueryUserInfo_acct_flags(b
, tctx
, user_handle
, &acct_flags
), "");
4115 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
4116 "expected account to be locked");
4119 /* let lockout duration expire ==> unlock */
4121 torture_comment(tctx
, "let lockout duration expire...\n");
4122 sleep(lockout_seconds
+ 1);
4124 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
4126 expected_success_status
, interactive
))
4128 torture_fail(tctx
, "failed to authenticate after lockout expired");
4131 torture_assert(tctx
,
4132 test_QueryUserInfo_acct_flags(b
, tctx
, user_handle
, &acct_flags
), "");
4133 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
4134 "expected account not to be locked");
4139 static bool test_Password_lockout_wrap(struct dcerpc_pipe
*p
,
4140 struct torture_context
*tctx
,
4141 uint32_t acct_flags
,
4142 const char *acct_name
,
4143 struct policy_handle
*domain_handle
,
4144 struct policy_handle
*user_handle
,
4146 struct cli_credentials
*machine_credentials
)
4148 union samr_DomainInfo
*q_info
, s_info
;
4149 struct samr_DomInfo1 info1
, _info1
;
4150 struct samr_DomInfo12 info12
, _info12
;
4152 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4153 struct dcerpc_pipe
*np
;
4157 const char *comment
;
4160 NTSTATUS expected_success_status
;
4163 .comment
= "network logon (disabled account)",
4165 .interactive
= false,
4166 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
4169 .comment
= "network logon (enabled account)",
4171 .interactive
= false,
4172 .expected_success_status
= NT_STATUS_OK
4175 .comment
= "interactive logon (disabled account)",
4177 .interactive
= true,
4178 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
4181 .comment
= "interactive logon (enabled account)",
4183 .interactive
= true,
4184 .expected_success_status
= NT_STATUS_OK
4188 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
4190 /* backup old policies */
4192 torture_assert(tctx
,
4193 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
4194 DomainPasswordInformation
, &q_info
),
4195 "failed to query domain info level 1");
4197 info1
= q_info
->info1
;
4200 torture_assert(tctx
,
4201 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
4202 DomainLockoutInformation
, &q_info
),
4203 "failed to query domain info level 12");
4205 info12
= q_info
->info12
;
4210 for (i
=0; i
< ARRAY_SIZE(creds
); i
++) {
4212 /* skip trust tests for now */
4213 if (acct_flags
& ACB_WSTRUST
||
4214 acct_flags
& ACB_SVRTRUST
||
4215 acct_flags
& ACB_DOMTRUST
) {
4219 ret
&= test_Password_lockout(p
, np
, tctx
, acct_flags
, acct_name
,
4220 domain_handle
, user_handle
, password
,
4221 machine_credentials
,
4224 creds
[i
].interactive
,
4225 creds
[i
].expected_success_status
,
4228 torture_warning(tctx
, "TEST #%d (%s) failed\n", i
, creds
[i
].comment
);
4230 torture_comment(tctx
, "TEST #%d (%s) succeeded\n", i
, creds
[i
].comment
);
4234 /* restore policies */
4236 s_info
.info1
= info1
;
4238 torture_assert(tctx
,
4239 test_SetDomainInfo(b
, tctx
, domain_handle
,
4240 DomainPasswordInformation
, &s_info
),
4241 "failed to set password information");
4243 s_info
.info12
= info12
;
4245 torture_assert(tctx
,
4246 test_SetDomainInfo(b
, tctx
, domain_handle
,
4247 DomainLockoutInformation
, &s_info
),
4248 "failed to set lockout information");
4253 static bool test_DeleteUser_with_privs(struct dcerpc_pipe
*p
,
4254 struct dcerpc_pipe
*lp
,
4255 struct torture_context
*tctx
,
4256 struct policy_handle
*domain_handle
,
4257 struct policy_handle
*lsa_handle
,
4258 struct policy_handle
*user_handle
,
4259 const struct dom_sid
*domain_sid
,
4261 struct cli_credentials
*machine_credentials
)
4264 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4265 struct dcerpc_binding_handle
*lb
= lp
->binding_handle
;
4267 struct policy_handle lsa_acct_handle
;
4268 struct dom_sid
*user_sid
;
4270 user_sid
= dom_sid_add_rid(tctx
, domain_sid
, rid
);
4273 struct lsa_EnumAccountRights r
;
4274 struct lsa_RightSet rights
;
4276 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4278 r
.in
.handle
= lsa_handle
;
4279 r
.in
.sid
= user_sid
;
4280 r
.out
.rights
= &rights
;
4282 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
),
4283 "lsa_EnumAccountRights failed");
4284 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
4285 "Expected enum rights for account to fail");
4289 struct lsa_RightSet rights
;
4290 struct lsa_StringLarge names
[2];
4291 struct lsa_AddAccountRights r
;
4293 torture_comment(tctx
, "Testing LSA AddAccountRights\n");
4295 init_lsa_StringLarge(&names
[0], "SeMachineAccountPrivilege");
4296 init_lsa_StringLarge(&names
[1], NULL
);
4299 rights
.names
= names
;
4301 r
.in
.handle
= lsa_handle
;
4302 r
.in
.sid
= user_sid
;
4303 r
.in
.rights
= &rights
;
4305 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_AddAccountRights_r(lb
, tctx
, &r
),
4306 "lsa_AddAccountRights failed");
4307 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4308 "Failed to add privileges");
4312 struct lsa_EnumAccounts r
;
4313 uint32_t resume_handle
= 0;
4314 struct lsa_SidArray lsa_sid_array
;
4316 bool found_sid
= false;
4318 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
4320 r
.in
.handle
= lsa_handle
;
4321 r
.in
.num_entries
= 0x1000;
4322 r
.in
.resume_handle
= &resume_handle
;
4323 r
.out
.sids
= &lsa_sid_array
;
4324 r
.out
.resume_handle
= &resume_handle
;
4326 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccounts_r(lb
, tctx
, &r
),
4327 "lsa_EnumAccounts failed");
4328 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4329 "Failed to enum accounts");
4331 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
4332 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
4337 torture_assert(tctx
, found_sid
,
4338 "failed to list privileged account");
4342 struct lsa_EnumAccountRights r
;
4343 struct lsa_RightSet user_rights
;
4345 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4347 r
.in
.handle
= lsa_handle
;
4348 r
.in
.sid
= user_sid
;
4349 r
.out
.rights
= &user_rights
;
4351 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
),
4352 "lsa_EnumAccountRights failed");
4353 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4354 "Failed to enum rights for account");
4356 if (user_rights
.count
< 1) {
4357 torture_warning(tctx
, "failed to find newly added rights");
4363 struct lsa_OpenAccount r
;
4365 torture_comment(tctx
, "Testing LSA OpenAccount\n");
4367 r
.in
.handle
= lsa_handle
;
4368 r
.in
.sid
= user_sid
;
4369 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4370 r
.out
.acct_handle
= &lsa_acct_handle
;
4372 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenAccount_r(lb
, tctx
, &r
),
4373 "lsa_OpenAccount failed");
4374 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4375 "Failed to open lsa account");
4379 struct lsa_GetSystemAccessAccount r
;
4380 uint32_t access_mask
;
4382 torture_comment(tctx
, "Testing LSA GetSystemAccessAccount\n");
4384 r
.in
.handle
= &lsa_acct_handle
;
4385 r
.out
.access_mask
= &access_mask
;
4387 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_GetSystemAccessAccount_r(lb
, tctx
, &r
),
4388 "lsa_GetSystemAccessAccount failed");
4389 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4390 "Failed to get lsa system access account");
4396 torture_comment(tctx
, "Testing LSA Close\n");
4398 r
.in
.handle
= &lsa_acct_handle
;
4399 r
.out
.handle
= &lsa_acct_handle
;
4401 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_Close_r(lb
, tctx
, &r
),
4402 "lsa_Close failed");
4403 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4404 "Failed to close lsa");
4408 struct samr_DeleteUser r
;
4410 torture_comment(tctx
, "Testing SAMR DeleteUser\n");
4412 r
.in
.user_handle
= user_handle
;
4413 r
.out
.user_handle
= user_handle
;
4415 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, tctx
, &r
),
4416 "DeleteUser failed");
4417 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4418 "DeleteUser failed");
4422 struct lsa_EnumAccounts r
;
4423 uint32_t resume_handle
= 0;
4424 struct lsa_SidArray lsa_sid_array
;
4426 bool found_sid
= false;
4428 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
4430 r
.in
.handle
= lsa_handle
;
4431 r
.in
.num_entries
= 0x1000;
4432 r
.in
.resume_handle
= &resume_handle
;
4433 r
.out
.sids
= &lsa_sid_array
;
4434 r
.out
.resume_handle
= &resume_handle
;
4436 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccounts_r(lb
, tctx
, &r
),
4437 "lsa_EnumAccounts failed");
4438 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4439 "Failed to enum accounts");
4441 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
4442 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
4447 torture_assert(tctx
, found_sid
,
4448 "failed to list privileged account");
4452 struct lsa_EnumAccountRights r
;
4453 struct lsa_RightSet user_rights
;
4455 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4457 r
.in
.handle
= lsa_handle
;
4458 r
.in
.sid
= user_sid
;
4459 r
.out
.rights
= &user_rights
;
4461 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
),
4462 "lsa_EnumAccountRights failed");
4463 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4464 "Failed to enum rights for account");
4466 if (user_rights
.count
< 1) {
4467 torture_warning(tctx
, "failed to find newly added rights");
4473 struct lsa_OpenAccount r
;
4475 torture_comment(tctx
, "Testing LSA OpenAccount\n");
4477 r
.in
.handle
= lsa_handle
;
4478 r
.in
.sid
= user_sid
;
4479 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4480 r
.out
.acct_handle
= &lsa_acct_handle
;
4482 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenAccount_r(lb
, tctx
, &r
),
4483 "lsa_OpenAccount failed");
4484 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4485 "Failed to open lsa account");
4489 struct lsa_GetSystemAccessAccount r
;
4490 uint32_t access_mask
;
4492 torture_comment(tctx
, "Testing LSA GetSystemAccessAccount\n");
4494 r
.in
.handle
= &lsa_acct_handle
;
4495 r
.out
.access_mask
= &access_mask
;
4497 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_GetSystemAccessAccount_r(lb
, tctx
, &r
),
4498 "lsa_GetSystemAccessAccount failed");
4499 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4500 "Failed to get lsa system access account");
4504 struct lsa_DeleteObject r
;
4506 torture_comment(tctx
, "Testing LSA DeleteObject\n");
4508 r
.in
.handle
= &lsa_acct_handle
;
4509 r
.out
.handle
= &lsa_acct_handle
;
4511 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_DeleteObject_r(lb
, tctx
, &r
),
4512 "lsa_DeleteObject failed");
4513 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4514 "Failed to delete object");
4518 struct lsa_EnumAccounts r
;
4519 uint32_t resume_handle
= 0;
4520 struct lsa_SidArray lsa_sid_array
;
4522 bool found_sid
= false;
4524 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
4526 r
.in
.handle
= lsa_handle
;
4527 r
.in
.num_entries
= 0x1000;
4528 r
.in
.resume_handle
= &resume_handle
;
4529 r
.out
.sids
= &lsa_sid_array
;
4530 r
.out
.resume_handle
= &resume_handle
;
4532 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccounts_r(lb
, tctx
, &r
),
4533 "lsa_EnumAccounts failed");
4534 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4535 "Failed to enum accounts");
4537 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
4538 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
4543 torture_assert(tctx
, !found_sid
,
4544 "should not have listed privileged account");
4548 struct lsa_EnumAccountRights r
;
4549 struct lsa_RightSet user_rights
;
4551 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4553 r
.in
.handle
= lsa_handle
;
4554 r
.in
.sid
= user_sid
;
4555 r
.out
.rights
= &user_rights
;
4557 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
),
4558 "lsa_EnumAccountRights failed");
4559 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
4560 "Failed to enum rights for account");
4566 static bool test_user_ops(struct dcerpc_pipe
*p
,
4567 struct torture_context
*tctx
,
4568 struct policy_handle
*user_handle
,
4569 struct policy_handle
*domain_handle
,
4570 const struct dom_sid
*domain_sid
,
4571 uint32_t base_acct_flags
,
4572 const char *base_acct_name
, enum torture_samr_choice which_ops
,
4573 struct cli_credentials
*machine_credentials
)
4575 char *password
= NULL
;
4576 struct samr_QueryUserInfo q
;
4577 union samr_UserInfo
*info
;
4579 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4584 const uint32_t password_fields
[] = {
4585 SAMR_FIELD_NT_PASSWORD_PRESENT
,
4586 SAMR_FIELD_LM_PASSWORD_PRESENT
,
4587 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
,
4591 status
= test_LookupName(b
, tctx
, domain_handle
, base_acct_name
, &rid
);
4592 if (!NT_STATUS_IS_OK(status
)) {
4596 switch (which_ops
) {
4597 case TORTURE_SAMR_USER_ATTRIBUTES
:
4598 if (!test_QuerySecurity(b
, tctx
, user_handle
)) {
4602 if (!test_QueryUserInfo(b
, tctx
, user_handle
)) {
4606 if (!test_QueryUserInfo2(b
, tctx
, user_handle
)) {
4610 if (!test_SetUserInfo(b
, tctx
, user_handle
, base_acct_flags
,
4615 if (!test_GetUserPwInfo(b
, tctx
, user_handle
)) {
4619 if (!test_TestPrivateFunctionsUser(b
, tctx
, user_handle
)) {
4623 if (!test_SetUserPass(p
, tctx
, user_handle
, &password
)) {
4627 case TORTURE_SAMR_PASSWORDS
:
4628 if (base_acct_flags
& (ACB_WSTRUST
|ACB_DOMTRUST
|ACB_SVRTRUST
)) {
4629 char simple_pass
[9];
4630 char *v
= generate_random_str(tctx
, 1);
4632 ZERO_STRUCT(simple_pass
);
4633 memset(simple_pass
, *v
, sizeof(simple_pass
) - 1);
4635 torture_comment(tctx
, "Testing machine account password policy rules\n");
4637 /* Workstation trust accounts don't seem to need to honour password quality policy */
4638 if (!test_SetUserPassEx(p
, tctx
, user_handle
, true, &password
)) {
4642 if (!test_ChangePasswordUser2(p
, tctx
, base_acct_name
, &password
, simple_pass
, false)) {
4646 /* reset again, to allow another 'user' password change */
4647 if (!test_SetUserPassEx(p
, tctx
, user_handle
, true, &password
)) {
4651 /* Try a 'short' password */
4652 if (!test_ChangePasswordUser2(p
, tctx
, base_acct_name
, &password
, samr_rand_pass(tctx
, 4), false)) {
4656 /* Try a compleatly random password */
4657 if (!test_ChangePasswordRandomBytes(p
, tctx
, base_acct_name
, user_handle
, &password
)) {
4662 for (i
= 0; password_fields
[i
]; i
++) {
4663 if (!test_SetUserPass_23(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
4667 /* check it was set right */
4668 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4673 for (i
= 0; password_fields
[i
]; i
++) {
4674 if (!test_SetUserPass_25(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
4678 /* check it was set right */
4679 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4684 if (!test_SetUserPassEx(p
, tctx
, user_handle
, false, &password
)) {
4688 if (!test_ChangePassword(p
, tctx
, base_acct_name
, domain_handle
, &password
)) {
4692 if (!test_SetUserPass_18(p
, tctx
, user_handle
, &password
)) {
4696 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4700 for (i
= 0; password_fields
[i
]; i
++) {
4702 if (password_fields
[i
] == SAMR_FIELD_LM_PASSWORD_PRESENT
) {
4703 /* we need to skip as that would break
4704 * the ChangePasswordUser3 verify */
4708 if (!test_SetUserPass_21(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
4712 /* check it was set right */
4713 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4718 q
.in
.user_handle
= user_handle
;
4722 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
),
4723 "QueryUserInfo failed");
4724 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
4725 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
4726 q
.in
.level
, nt_errstr(q
.out
.result
));
4729 uint32_t expected_flags
= (base_acct_flags
| ACB_PWNOTREQ
| ACB_DISABLED
);
4730 if ((info
->info5
.acct_flags
) != expected_flags
) {
4731 torture_warning(tctx
, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4732 info
->info5
.acct_flags
,
4735 if (!torture_setting_bool(tctx
, "samba3", false)) {
4739 if (info
->info5
.rid
!= rid
) {
4740 torture_warning(tctx
, "QueryUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
4741 info
->info5
.rid
, rid
);
4748 case TORTURE_SAMR_PASSWORDS_PWDLASTSET
:
4750 /* test last password change timestamp behaviour */
4751 if (!test_SetPassword_pwdlastset(p
, tctx
, base_acct_flags
,
4753 user_handle
, &password
,
4754 machine_credentials
)) {
4759 torture_comment(tctx
, "pwdLastSet test succeeded\n");
4761 torture_warning(tctx
, "pwdLastSet test failed\n");
4766 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
:
4768 /* test bad pwd count change behaviour */
4769 if (!test_Password_badpwdcount_wrap(p
, tctx
, base_acct_flags
,
4772 user_handle
, &password
,
4773 machine_credentials
)) {
4778 torture_comment(tctx
, "badPwdCount test succeeded\n");
4780 torture_warning(tctx
, "badPwdCount test failed\n");
4785 case TORTURE_SAMR_PASSWORDS_LOCKOUT
:
4787 if (!test_Password_lockout_wrap(p
, tctx
, base_acct_flags
,
4790 user_handle
, &password
,
4791 machine_credentials
))
4797 torture_comment(tctx
, "lockout test succeeded\n");
4799 torture_warning(tctx
, "lockout test failed\n");
4805 case TORTURE_SAMR_USER_PRIVILEGES
: {
4807 struct dcerpc_pipe
*lp
;
4808 struct policy_handle
*lsa_handle
;
4809 struct dcerpc_binding_handle
*lb
;
4811 status
= torture_rpc_connection(tctx
, &lp
, &ndr_table_lsarpc
);
4812 torture_assert_ntstatus_ok(tctx
, status
, "Failed to open LSA pipe");
4813 lb
= lp
->binding_handle
;
4815 if (!test_lsa_OpenPolicy2(lb
, tctx
, &lsa_handle
)) {
4819 if (!test_DeleteUser_with_privs(p
, lp
, tctx
,
4820 domain_handle
, lsa_handle
, user_handle
,
4822 machine_credentials
)) {
4826 if (!test_lsa_Close(lb
, tctx
, lsa_handle
)) {
4831 torture_warning(tctx
, "privileged user delete test failed\n");
4836 case TORTURE_SAMR_OTHER
:
4837 case TORTURE_SAMR_MANY_ACCOUNTS
:
4838 case TORTURE_SAMR_MANY_GROUPS
:
4839 case TORTURE_SAMR_MANY_ALIASES
:
4840 /* We just need the account to exist */
4846 static bool test_alias_ops(struct dcerpc_binding_handle
*b
,
4847 struct torture_context
*tctx
,
4848 struct policy_handle
*alias_handle
,
4849 const struct dom_sid
*domain_sid
)
4853 if (!torture_setting_bool(tctx
, "samba3", false)) {
4854 if (!test_QuerySecurity(b
, tctx
, alias_handle
)) {
4859 if (!test_QueryAliasInfo(b
, tctx
, alias_handle
)) {
4863 if (!test_SetAliasInfo(b
, tctx
, alias_handle
)) {
4867 if (!test_AddMemberToAlias(b
, tctx
, alias_handle
, domain_sid
)) {
4871 if (torture_setting_bool(tctx
, "samba3", false) ||
4872 torture_setting_bool(tctx
, "samba4", false)) {
4873 torture_comment(tctx
, "skipping MultipleMembers Alias tests against Samba\n");
4877 if (!test_AddMultipleMembersToAlias(b
, tctx
, alias_handle
)) {
4885 static bool test_DeleteUser(struct dcerpc_binding_handle
*b
,
4886 struct torture_context
*tctx
,
4887 struct policy_handle
*user_handle
)
4889 struct samr_DeleteUser d
;
4890 torture_comment(tctx
, "Testing DeleteUser\n");
4892 d
.in
.user_handle
= user_handle
;
4893 d
.out
.user_handle
= user_handle
;
4895 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, tctx
, &d
),
4896 "DeleteUser failed");
4897 torture_assert_ntstatus_ok(tctx
, d
.out
.result
, "DeleteUser");
4902 bool test_DeleteUser_byname(struct dcerpc_binding_handle
*b
,
4903 struct torture_context
*tctx
,
4904 struct policy_handle
*handle
, const char *name
)
4907 struct samr_DeleteUser d
;
4908 struct policy_handle user_handle
;
4911 status
= test_LookupName(b
, tctx
, handle
, name
, &rid
);
4912 if (!NT_STATUS_IS_OK(status
)) {
4916 status
= test_OpenUser_byname(b
, tctx
, handle
, name
, &user_handle
);
4917 if (!NT_STATUS_IS_OK(status
)) {
4921 d
.in
.user_handle
= &user_handle
;
4922 d
.out
.user_handle
= &user_handle
;
4923 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, tctx
, &d
),
4924 "DeleteUser failed");
4925 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
4926 status
= d
.out
.result
;
4933 torture_warning(tctx
, "DeleteUser_byname(%s) failed - %s\n", name
, nt_errstr(status
));
4938 static bool test_DeleteGroup_byname(struct dcerpc_binding_handle
*b
,
4939 struct torture_context
*tctx
,
4940 struct policy_handle
*handle
, const char *name
)
4943 struct samr_OpenGroup r
;
4944 struct samr_DeleteDomainGroup d
;
4945 struct policy_handle group_handle
;
4948 status
= test_LookupName(b
, tctx
, handle
, name
, &rid
);
4949 if (!NT_STATUS_IS_OK(status
)) {
4953 r
.in
.domain_handle
= handle
;
4954 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4956 r
.out
.group_handle
= &group_handle
;
4957 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenGroup_r(b
, tctx
, &r
),
4958 "OpenGroup failed");
4959 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
4960 status
= r
.out
.result
;
4964 d
.in
.group_handle
= &group_handle
;
4965 d
.out
.group_handle
= &group_handle
;
4966 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteDomainGroup_r(b
, tctx
, &d
),
4967 "DeleteDomainGroup failed");
4968 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
4969 status
= d
.out
.result
;
4976 torture_warning(tctx
, "DeleteGroup_byname(%s) failed - %s\n", name
, nt_errstr(status
));
4981 static bool test_DeleteAlias_byname(struct dcerpc_binding_handle
*b
,
4982 struct torture_context
*tctx
,
4983 struct policy_handle
*domain_handle
,
4987 struct samr_OpenAlias r
;
4988 struct samr_DeleteDomAlias d
;
4989 struct policy_handle alias_handle
;
4992 torture_comment(tctx
, "Testing DeleteAlias_byname\n");
4994 status
= test_LookupName(b
, tctx
, domain_handle
, name
, &rid
);
4995 if (!NT_STATUS_IS_OK(status
)) {
4999 r
.in
.domain_handle
= domain_handle
;
5000 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5002 r
.out
.alias_handle
= &alias_handle
;
5003 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenAlias_r(b
, tctx
, &r
),
5004 "OpenAlias failed");
5005 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5006 status
= r
.out
.result
;
5010 d
.in
.alias_handle
= &alias_handle
;
5011 d
.out
.alias_handle
= &alias_handle
;
5012 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteDomAlias_r(b
, tctx
, &d
),
5013 "DeleteDomAlias failed");
5014 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
5015 status
= d
.out
.result
;
5022 torture_warning(tctx
, "DeleteAlias_byname(%s) failed - %s\n", name
, nt_errstr(status
));
5026 static bool test_DeleteAlias(struct dcerpc_binding_handle
*b
,
5027 struct torture_context
*tctx
,
5028 struct policy_handle
*alias_handle
)
5030 struct samr_DeleteDomAlias d
;
5033 torture_comment(tctx
, "Testing DeleteAlias\n");
5035 d
.in
.alias_handle
= alias_handle
;
5036 d
.out
.alias_handle
= alias_handle
;
5038 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteDomAlias_r(b
, tctx
, &d
),
5039 "DeleteDomAlias failed");
5040 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
5041 torture_warning(tctx
, "DeleteAlias failed - %s\n", nt_errstr(d
.out
.result
));
5048 static bool test_CreateAlias(struct dcerpc_binding_handle
*b
,
5049 struct torture_context
*tctx
,
5050 struct policy_handle
*domain_handle
,
5051 const char *alias_name
,
5052 struct policy_handle
*alias_handle
,
5053 const struct dom_sid
*domain_sid
,
5056 struct samr_CreateDomAlias r
;
5057 struct lsa_String name
;
5061 init_lsa_String(&name
, alias_name
);
5062 r
.in
.domain_handle
= domain_handle
;
5063 r
.in
.alias_name
= &name
;
5064 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5065 r
.out
.alias_handle
= alias_handle
;
5068 torture_comment(tctx
, "Testing CreateAlias (%s)\n", r
.in
.alias_name
->string
);
5070 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomAlias_r(b
, tctx
, &r
),
5071 "CreateDomAlias failed");
5073 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
5074 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
)) {
5075 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.alias_name
->string
);
5078 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.alias_name
->string
,
5079 nt_errstr(r
.out
.result
));
5084 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ALIAS_EXISTS
)) {
5085 if (!test_DeleteAlias_byname(b
, tctx
, domain_handle
, r
.in
.alias_name
->string
)) {
5088 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomAlias_r(b
, tctx
, &r
),
5089 "CreateDomAlias failed");
5092 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5093 torture_warning(tctx
, "CreateAlias failed - %s\n", nt_errstr(r
.out
.result
));
5101 if (!test_alias_ops(b
, tctx
, alias_handle
, domain_sid
)) {
5108 static bool test_ChangePassword(struct dcerpc_pipe
*p
,
5109 struct torture_context
*tctx
,
5110 const char *acct_name
,
5111 struct policy_handle
*domain_handle
, char **password
)
5114 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5120 if (!test_ChangePasswordUser(b
, tctx
, acct_name
, domain_handle
, password
)) {
5124 if (!test_ChangePasswordUser2(p
, tctx
, acct_name
, password
, 0, true)) {
5128 if (!test_OemChangePasswordUser2(p
, tctx
, acct_name
, domain_handle
, password
)) {
5132 /* test what happens when setting the old password again */
5133 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, *password
, 0, true)) {
5138 char simple_pass
[9];
5139 char *v
= generate_random_str(tctx
, 1);
5141 ZERO_STRUCT(simple_pass
);
5142 memset(simple_pass
, *v
, sizeof(simple_pass
) - 1);
5144 /* test what happens when picking a simple password */
5145 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, simple_pass
, 0, true)) {
5150 /* set samr_SetDomainInfo level 1 with min_length 5 */
5152 struct samr_QueryDomainInfo r
;
5153 union samr_DomainInfo
*info
= NULL
;
5154 struct samr_SetDomainInfo s
;
5155 uint16_t len_old
, len
;
5156 uint32_t pwd_prop_old
;
5157 int64_t min_pwd_age_old
;
5161 r
.in
.domain_handle
= domain_handle
;
5165 torture_comment(tctx
, "Testing samr_QueryDomainInfo level 1\n");
5166 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &r
),
5167 "QueryDomainInfo failed");
5168 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5172 s
.in
.domain_handle
= domain_handle
;
5176 /* remember the old min length, so we can reset it */
5177 len_old
= s
.in
.info
->info1
.min_password_length
;
5178 s
.in
.info
->info1
.min_password_length
= len
;
5179 pwd_prop_old
= s
.in
.info
->info1
.password_properties
;
5180 /* turn off password complexity checks for this test */
5181 s
.in
.info
->info1
.password_properties
&= ~DOMAIN_PASSWORD_COMPLEX
;
5183 min_pwd_age_old
= s
.in
.info
->info1
.min_password_age
;
5184 s
.in
.info
->info1
.min_password_age
= 0;
5186 torture_comment(tctx
, "Testing samr_SetDomainInfo level 1\n");
5187 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
),
5188 "SetDomainInfo failed");
5189 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
5193 torture_comment(tctx
, "calling test_ChangePasswordUser3 with too short password\n");
5195 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, len
- 1, password
, NULL
, 0, true)) {
5199 s
.in
.info
->info1
.min_password_length
= len_old
;
5200 s
.in
.info
->info1
.password_properties
= pwd_prop_old
;
5201 s
.in
.info
->info1
.min_password_age
= min_pwd_age_old
;
5203 torture_comment(tctx
, "Testing samr_SetDomainInfo level 1\n");
5204 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
),
5205 "SetDomainInfo failed");
5206 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
5213 struct samr_OpenUser r
;
5214 struct samr_QueryUserInfo q
;
5215 union samr_UserInfo
*info
;
5216 struct samr_LookupNames n
;
5217 struct policy_handle user_handle
;
5218 struct samr_Ids rids
, types
;
5220 n
.in
.domain_handle
= domain_handle
;
5222 n
.in
.names
= talloc_array(tctx
, struct lsa_String
, 1);
5223 n
.in
.names
[0].string
= acct_name
;
5225 n
.out
.types
= &types
;
5227 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupNames_r(b
, tctx
, &n
),
5228 "LookupNames failed");
5229 if (!NT_STATUS_IS_OK(n
.out
.result
)) {
5230 torture_warning(tctx
, "LookupNames failed - %s\n", nt_errstr(n
.out
.result
));
5234 r
.in
.domain_handle
= domain_handle
;
5235 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5236 r
.in
.rid
= n
.out
.rids
->ids
[0];
5237 r
.out
.user_handle
= &user_handle
;
5239 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenUser_r(b
, tctx
, &r
),
5241 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5242 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", n
.out
.rids
->ids
[0], nt_errstr(r
.out
.result
));
5246 q
.in
.user_handle
= &user_handle
;
5250 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
),
5251 "QueryUserInfo failed");
5252 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
5253 torture_warning(tctx
, "QueryUserInfo failed - %s\n", nt_errstr(q
.out
.result
));
5257 torture_comment(tctx
, "calling test_ChangePasswordUser3 with too early password change\n");
5259 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
,
5260 info
->info5
.last_password_change
, true)) {
5265 /* we change passwords twice - this has the effect of verifying
5266 they were changed correctly for the final call */
5267 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
, 0, true)) {
5271 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
, 0, true)) {
5278 static bool test_CreateUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5279 struct policy_handle
*domain_handle
,
5280 const char *user_name
,
5281 struct policy_handle
*user_handle_out
,
5282 struct dom_sid
*domain_sid
,
5283 enum torture_samr_choice which_ops
,
5284 struct cli_credentials
*machine_credentials
,
5288 TALLOC_CTX
*user_ctx
;
5290 struct samr_CreateUser r
;
5291 struct samr_QueryUserInfo q
;
5292 union samr_UserInfo
*info
;
5293 struct samr_DeleteUser d
;
5296 /* This call creates a 'normal' account - check that it really does */
5297 const uint32_t acct_flags
= ACB_NORMAL
;
5298 struct lsa_String name
;
5300 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5302 struct policy_handle user_handle
;
5303 user_ctx
= talloc_named(tctx
, 0, "test_CreateUser2 per-user context");
5304 init_lsa_String(&name
, user_name
);
5306 r
.in
.domain_handle
= domain_handle
;
5307 r
.in
.account_name
= &name
;
5308 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5309 r
.out
.user_handle
= &user_handle
;
5312 torture_comment(tctx
, "Testing CreateUser(%s)\n", r
.in
.account_name
->string
);
5314 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateUser_r(b
, user_ctx
, &r
),
5315 "CreateUser failed");
5317 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
5318 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
) || NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
5319 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.account_name
->string
);
5322 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.account_name
->string
,
5323 nt_errstr(r
.out
.result
));
5328 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_USER_EXISTS
)) {
5329 if (!test_DeleteUser_byname(b
, tctx
, domain_handle
, r
.in
.account_name
->string
)) {
5330 talloc_free(user_ctx
);
5333 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateUser_r(b
, user_ctx
, &r
),
5334 "CreateUser failed");
5337 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5338 talloc_free(user_ctx
);
5339 torture_warning(tctx
, "CreateUser failed - %s\n", nt_errstr(r
.out
.result
));
5344 if (user_handle_out
) {
5345 *user_handle_out
= user_handle
;
5351 q
.in
.user_handle
= &user_handle
;
5355 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, user_ctx
, &q
),
5356 "QueryUserInfo failed");
5357 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
5358 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
5359 q
.in
.level
, nt_errstr(q
.out
.result
));
5362 if ((info
->info16
.acct_flags
& acct_flags
) != acct_flags
) {
5363 torture_warning(tctx
, "QueryUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5364 info
->info16
.acct_flags
,
5370 if (!test_user_ops(p
, tctx
, &user_handle
, domain_handle
,
5371 domain_sid
, acct_flags
, name
.string
, which_ops
,
5372 machine_credentials
)) {
5376 if (user_handle_out
) {
5377 *user_handle_out
= user_handle
;
5379 torture_comment(tctx
, "Testing DeleteUser (createuser test)\n");
5381 d
.in
.user_handle
= &user_handle
;
5382 d
.out
.user_handle
= &user_handle
;
5384 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, user_ctx
, &d
),
5385 "DeleteUser failed");
5386 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
5387 torture_warning(tctx
, "DeleteUser failed - %s\n", nt_errstr(d
.out
.result
));
5394 talloc_free(user_ctx
);
5400 static bool test_CreateUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5401 struct policy_handle
*domain_handle
,
5402 struct dom_sid
*domain_sid
,
5403 enum torture_samr_choice which_ops
,
5404 struct cli_credentials
*machine_credentials
)
5406 struct samr_CreateUser2 r
;
5407 struct samr_QueryUserInfo q
;
5408 union samr_UserInfo
*info
;
5409 struct samr_DeleteUser d
;
5410 struct policy_handle user_handle
;
5412 struct lsa_String name
;
5415 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5418 uint32_t acct_flags
;
5419 const char *account_name
;
5421 } account_types
[] = {
5422 { ACB_NORMAL
, TEST_ACCOUNT_NAME
, NT_STATUS_OK
},
5423 { ACB_NORMAL
| ACB_DISABLED
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5424 { ACB_NORMAL
| ACB_PWNOEXP
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5425 { ACB_WSTRUST
, TEST_MACHINENAME
, NT_STATUS_OK
},
5426 { ACB_WSTRUST
| ACB_DISABLED
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5427 { ACB_WSTRUST
| ACB_PWNOEXP
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5428 { ACB_SVRTRUST
, TEST_MACHINENAME
, NT_STATUS_OK
},
5429 { ACB_SVRTRUST
| ACB_DISABLED
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5430 { ACB_SVRTRUST
| ACB_PWNOEXP
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5431 { ACB_DOMTRUST
, TEST_DOMAINNAME
, NT_STATUS_ACCESS_DENIED
},
5432 { ACB_DOMTRUST
| ACB_DISABLED
, TEST_DOMAINNAME
, NT_STATUS_INVALID_PARAMETER
},
5433 { ACB_DOMTRUST
| ACB_PWNOEXP
, TEST_DOMAINNAME
, NT_STATUS_INVALID_PARAMETER
},
5434 { 0, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5435 { ACB_DISABLED
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5436 { 0, NULL
, NT_STATUS_INVALID_PARAMETER
}
5439 for (i
= 0; account_types
[i
].account_name
; i
++) {
5440 TALLOC_CTX
*user_ctx
;
5441 uint32_t acct_flags
= account_types
[i
].acct_flags
;
5442 uint32_t access_granted
;
5443 user_ctx
= talloc_named(tctx
, 0, "test_CreateUser2 per-user context");
5444 init_lsa_String(&name
, account_types
[i
].account_name
);
5446 r
.in
.domain_handle
= domain_handle
;
5447 r
.in
.account_name
= &name
;
5448 r
.in
.acct_flags
= acct_flags
;
5449 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5450 r
.out
.user_handle
= &user_handle
;
5451 r
.out
.access_granted
= &access_granted
;
5454 torture_comment(tctx
, "Testing CreateUser2(%s, 0x%x)\n", r
.in
.account_name
->string
, acct_flags
);
5456 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateUser2_r(b
, user_ctx
, &r
),
5457 "CreateUser2 failed");
5459 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
5460 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
) || NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
5461 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.account_name
->string
);
5464 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.account_name
->string
,
5465 nt_errstr(r
.out
.result
));
5471 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_USER_EXISTS
)) {
5472 if (!test_DeleteUser_byname(b
, tctx
, domain_handle
, r
.in
.account_name
->string
)) {
5473 talloc_free(user_ctx
);
5477 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateUser2_r(b
, user_ctx
, &r
),
5478 "CreateUser2 failed");
5481 if (!NT_STATUS_EQUAL(r
.out
.result
, account_types
[i
].nt_status
)) {
5482 torture_warning(tctx
, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5483 nt_errstr(r
.out
.result
), nt_errstr(account_types
[i
].nt_status
));
5487 if (NT_STATUS_IS_OK(r
.out
.result
)) {
5488 q
.in
.user_handle
= &user_handle
;
5492 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, user_ctx
, &q
),
5493 "QueryUserInfo failed");
5494 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
5495 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
5496 q
.in
.level
, nt_errstr(q
.out
.result
));
5499 uint32_t expected_flags
= (acct_flags
| ACB_PWNOTREQ
| ACB_DISABLED
);
5500 if (acct_flags
== ACB_NORMAL
) {
5501 expected_flags
|= ACB_PW_EXPIRED
;
5503 if ((info
->info5
.acct_flags
) != expected_flags
) {
5504 torture_warning(tctx
, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5505 info
->info5
.acct_flags
,
5509 switch (acct_flags
) {
5511 if (info
->info5
.primary_gid
!= DOMAIN_RID_DCS
) {
5512 torture_warning(tctx
, "QueryUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5513 DOMAIN_RID_DCS
, info
->info5
.primary_gid
);
5518 if (info
->info5
.primary_gid
!= DOMAIN_RID_DOMAIN_MEMBERS
) {
5519 torture_warning(tctx
, "QueryUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5520 DOMAIN_RID_DOMAIN_MEMBERS
, info
->info5
.primary_gid
);
5525 if (info
->info5
.primary_gid
!= DOMAIN_RID_USERS
) {
5526 torture_warning(tctx
, "QueryUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5527 DOMAIN_RID_USERS
, info
->info5
.primary_gid
);
5534 if (!test_user_ops(p
, tctx
, &user_handle
, domain_handle
,
5535 domain_sid
, acct_flags
, name
.string
, which_ops
,
5536 machine_credentials
)) {
5540 if (!ndr_policy_handle_empty(&user_handle
)) {
5541 torture_comment(tctx
, "Testing DeleteUser (createuser2 test)\n");
5543 d
.in
.user_handle
= &user_handle
;
5544 d
.out
.user_handle
= &user_handle
;
5546 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, user_ctx
, &d
),
5547 "DeleteUser failed");
5548 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
5549 torture_warning(tctx
, "DeleteUser failed - %s\n", nt_errstr(d
.out
.result
));
5554 talloc_free(user_ctx
);
5560 static bool test_QueryAliasInfo(struct dcerpc_binding_handle
*b
,
5561 struct torture_context
*tctx
,
5562 struct policy_handle
*handle
)
5564 struct samr_QueryAliasInfo r
;
5565 union samr_AliasInfo
*info
;
5566 uint16_t levels
[] = {1, 2, 3};
5570 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5571 torture_comment(tctx
, "Testing QueryAliasInfo level %u\n", levels
[i
]);
5573 r
.in
.alias_handle
= handle
;
5574 r
.in
.level
= levels
[i
];
5577 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryAliasInfo_r(b
, tctx
, &r
),
5578 "QueryAliasInfo failed");
5579 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5580 torture_warning(tctx
, "QueryAliasInfo level %u failed - %s\n",
5581 levels
[i
], nt_errstr(r
.out
.result
));
5589 static bool test_QueryGroupInfo(struct dcerpc_binding_handle
*b
,
5590 struct torture_context
*tctx
,
5591 struct policy_handle
*handle
)
5593 struct samr_QueryGroupInfo r
;
5594 union samr_GroupInfo
*info
;
5595 uint16_t levels
[] = {1, 2, 3, 4, 5};
5599 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5600 torture_comment(tctx
, "Testing QueryGroupInfo level %u\n", levels
[i
]);
5602 r
.in
.group_handle
= handle
;
5603 r
.in
.level
= levels
[i
];
5606 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupInfo_r(b
, tctx
, &r
),
5607 "QueryGroupInfo failed");
5608 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5609 torture_warning(tctx
, "QueryGroupInfo level %u failed - %s\n",
5610 levels
[i
], nt_errstr(r
.out
.result
));
5618 static bool test_QueryGroupMember(struct dcerpc_binding_handle
*b
,
5619 struct torture_context
*tctx
,
5620 struct policy_handle
*handle
)
5622 struct samr_QueryGroupMember r
;
5623 struct samr_RidAttrArray
*rids
= NULL
;
5626 torture_comment(tctx
, "Testing QueryGroupMember\n");
5628 r
.in
.group_handle
= handle
;
5631 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupMember_r(b
, tctx
, &r
),
5632 "QueryGroupMember failed");
5633 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5634 torture_warning(tctx
, "QueryGroupMember failed - %s\n", nt_errstr(r
.out
.result
));
5642 static bool test_SetGroupInfo(struct dcerpc_binding_handle
*b
,
5643 struct torture_context
*tctx
,
5644 struct policy_handle
*handle
)
5646 struct samr_QueryGroupInfo r
;
5647 union samr_GroupInfo
*info
;
5648 struct samr_SetGroupInfo s
;
5649 uint16_t levels
[] = {1, 2, 3, 4};
5650 uint16_t set_ok
[] = {0, 1, 1, 1};
5654 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5655 torture_comment(tctx
, "Testing QueryGroupInfo level %u\n", levels
[i
]);
5657 r
.in
.group_handle
= handle
;
5658 r
.in
.level
= levels
[i
];
5661 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupInfo_r(b
, tctx
, &r
),
5662 "QueryGroupInfo failed");
5663 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5664 torture_warning(tctx
, "QueryGroupInfo level %u failed - %s\n",
5665 levels
[i
], nt_errstr(r
.out
.result
));
5669 torture_comment(tctx
, "Testing SetGroupInfo level %u\n", levels
[i
]);
5671 s
.in
.group_handle
= handle
;
5672 s
.in
.level
= levels
[i
];
5673 s
.in
.info
= *r
.out
.info
;
5676 /* disabled this, as it changes the name only from the point of view of samr,
5677 but leaves the name from the point of view of w2k3 internals (and ldap). This means
5678 the name is still reserved, so creating the old name fails, but deleting by the old name
5680 if (s
.in
.level
== 2) {
5681 init_lsa_String(&s
.in
.info
->string
, "NewName");
5685 if (s
.in
.level
== 4) {
5686 init_lsa_String(&s
.in
.info
->description
, "test description");
5689 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetGroupInfo_r(b
, tctx
, &s
),
5690 "SetGroupInfo failed");
5692 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
5693 torture_warning(tctx
, "SetGroupInfo level %u failed - %s\n",
5694 r
.in
.level
, nt_errstr(s
.out
.result
));
5699 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, s
.out
.result
)) {
5700 torture_warning(tctx
, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5701 r
.in
.level
, nt_errstr(s
.out
.result
));
5711 static bool test_QueryUserInfo(struct dcerpc_binding_handle
*b
,
5712 struct torture_context
*tctx
,
5713 struct policy_handle
*handle
)
5715 struct samr_QueryUserInfo r
;
5716 union samr_UserInfo
*info
;
5717 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5718 11, 12, 13, 14, 16, 17, 20, 21};
5722 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5723 torture_comment(tctx
, "Testing QueryUserInfo level %u\n", levels
[i
]);
5725 r
.in
.user_handle
= handle
;
5726 r
.in
.level
= levels
[i
];
5729 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
5730 "QueryUserInfo failed");
5731 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5732 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
5733 levels
[i
], nt_errstr(r
.out
.result
));
5741 static bool test_QueryUserInfo2(struct dcerpc_binding_handle
*b
,
5742 struct torture_context
*tctx
,
5743 struct policy_handle
*handle
)
5745 struct samr_QueryUserInfo2 r
;
5746 union samr_UserInfo
*info
;
5747 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5748 11, 12, 13, 14, 16, 17, 20, 21};
5752 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5753 torture_comment(tctx
, "Testing QueryUserInfo2 level %u\n", levels
[i
]);
5755 r
.in
.user_handle
= handle
;
5756 r
.in
.level
= levels
[i
];
5759 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo2_r(b
, tctx
, &r
),
5760 "QueryUserInfo2 failed");
5761 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5762 torture_warning(tctx
, "QueryUserInfo2 level %u failed - %s\n",
5763 levels
[i
], nt_errstr(r
.out
.result
));
5771 static bool test_OpenUser(struct dcerpc_binding_handle
*b
,
5772 struct torture_context
*tctx
,
5773 struct policy_handle
*handle
, uint32_t rid
)
5775 struct samr_OpenUser r
;
5776 struct policy_handle user_handle
;
5779 torture_comment(tctx
, "Testing OpenUser(%u)\n", rid
);
5781 r
.in
.domain_handle
= handle
;
5782 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5784 r
.out
.user_handle
= &user_handle
;
5786 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenUser_r(b
, tctx
, &r
),
5788 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5789 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", rid
, nt_errstr(r
.out
.result
));
5793 if (!test_QuerySecurity(b
, tctx
, &user_handle
)) {
5797 if (!test_QueryUserInfo(b
, tctx
, &user_handle
)) {
5801 if (!test_QueryUserInfo2(b
, tctx
, &user_handle
)) {
5805 if (!test_GetUserPwInfo(b
, tctx
, &user_handle
)) {
5809 if (!test_GetGroupsForUser(b
, tctx
, &user_handle
)) {
5813 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
5820 static bool test_OpenGroup(struct dcerpc_binding_handle
*b
,
5821 struct torture_context
*tctx
,
5822 struct policy_handle
*handle
, uint32_t rid
)
5824 struct samr_OpenGroup r
;
5825 struct policy_handle group_handle
;
5828 torture_comment(tctx
, "Testing OpenGroup(%u)\n", rid
);
5830 r
.in
.domain_handle
= handle
;
5831 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5833 r
.out
.group_handle
= &group_handle
;
5835 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenGroup_r(b
, tctx
, &r
),
5836 "OpenGroup failed");
5837 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5838 torture_warning(tctx
, "OpenGroup(%u) failed - %s\n", rid
, nt_errstr(r
.out
.result
));
5842 if (!torture_setting_bool(tctx
, "samba3", false)) {
5843 if (!test_QuerySecurity(b
, tctx
, &group_handle
)) {
5848 if (!test_QueryGroupInfo(b
, tctx
, &group_handle
)) {
5852 if (!test_QueryGroupMember(b
, tctx
, &group_handle
)) {
5856 if (!test_samr_handle_Close(b
, tctx
, &group_handle
)) {
5863 static bool test_OpenAlias(struct dcerpc_binding_handle
*b
,
5864 struct torture_context
*tctx
,
5865 struct policy_handle
*handle
, uint32_t rid
)
5867 struct samr_OpenAlias r
;
5868 struct policy_handle alias_handle
;
5871 torture_comment(tctx
, "Testing OpenAlias(%u)\n", rid
);
5873 r
.in
.domain_handle
= handle
;
5874 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5876 r
.out
.alias_handle
= &alias_handle
;
5878 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenAlias_r(b
, tctx
, &r
),
5879 "OpenAlias failed");
5880 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5881 torture_warning(tctx
, "OpenAlias(%u) failed - %s\n", rid
, nt_errstr(r
.out
.result
));
5885 if (!torture_setting_bool(tctx
, "samba3", false)) {
5886 if (!test_QuerySecurity(b
, tctx
, &alias_handle
)) {
5891 if (!test_QueryAliasInfo(b
, tctx
, &alias_handle
)) {
5895 if (!test_GetMembersInAlias(b
, tctx
, &alias_handle
)) {
5899 if (!test_samr_handle_Close(b
, tctx
, &alias_handle
)) {
5906 static bool check_mask(struct dcerpc_binding_handle
*b
,
5907 struct torture_context
*tctx
,
5908 struct policy_handle
*handle
, uint32_t rid
,
5909 uint32_t acct_flag_mask
)
5911 struct samr_OpenUser r
;
5912 struct samr_QueryUserInfo q
;
5913 union samr_UserInfo
*info
;
5914 struct policy_handle user_handle
;
5917 torture_comment(tctx
, "Testing OpenUser(%u)\n", rid
);
5919 r
.in
.domain_handle
= handle
;
5920 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5922 r
.out
.user_handle
= &user_handle
;
5924 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenUser_r(b
, tctx
, &r
),
5926 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
5927 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", rid
, nt_errstr(r
.out
.result
));
5931 q
.in
.user_handle
= &user_handle
;
5935 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
),
5936 "QueryUserInfo failed");
5937 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
5938 torture_warning(tctx
, "QueryUserInfo level 16 failed - %s\n",
5939 nt_errstr(q
.out
.result
));
5942 if ((acct_flag_mask
& info
->info16
.acct_flags
) == 0) {
5943 torture_warning(tctx
, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
5944 acct_flag_mask
, info
->info16
.acct_flags
, rid
);
5949 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
5956 static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle
*b
,
5957 struct torture_context
*tctx
,
5958 struct policy_handle
*handle
)
5960 struct samr_EnumDomainUsers r
;
5961 uint32_t mask
, resume_handle
=0;
5964 struct samr_LookupNames n
;
5965 struct samr_LookupRids lr
;
5966 struct lsa_Strings names
;
5967 struct samr_Ids rids
, types
;
5968 struct samr_SamArray
*sam
= NULL
;
5969 uint32_t num_entries
= 0;
5971 uint32_t masks
[] = {ACB_NORMAL
, ACB_DOMTRUST
, ACB_WSTRUST
,
5972 ACB_DISABLED
, ACB_NORMAL
| ACB_DISABLED
,
5973 ACB_SVRTRUST
| ACB_DOMTRUST
| ACB_WSTRUST
,
5976 torture_comment(tctx
, "Testing EnumDomainUsers\n");
5978 for (mask_idx
=0;mask_idx
<ARRAY_SIZE(masks
);mask_idx
++) {
5979 r
.in
.domain_handle
= handle
;
5980 r
.in
.resume_handle
= &resume_handle
;
5981 r
.in
.acct_flags
= mask
= masks
[mask_idx
];
5982 r
.in
.max_size
= (uint32_t)-1;
5983 r
.out
.resume_handle
= &resume_handle
;
5984 r
.out
.num_entries
= &num_entries
;
5987 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainUsers_r(b
, tctx
, &r
),
5988 "EnumDomainUsers failed");
5989 if (!NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
) &&
5990 !NT_STATUS_IS_OK(r
.out
.result
)) {
5991 torture_warning(tctx
, "EnumDomainUsers failed - %s\n", nt_errstr(r
.out
.result
));
5995 torture_assert(tctx
, sam
, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
5997 if (sam
->count
== 0) {
6001 for (i
=0;i
<sam
->count
;i
++) {
6003 if (!check_mask(b
, tctx
, handle
, sam
->entries
[i
].idx
, mask
)) {
6006 } else if (!test_OpenUser(b
, tctx
, handle
, sam
->entries
[i
].idx
)) {
6012 torture_comment(tctx
, "Testing LookupNames\n");
6013 n
.in
.domain_handle
= handle
;
6014 n
.in
.num_names
= sam
->count
;
6015 n
.in
.names
= talloc_array(tctx
, struct lsa_String
, sam
->count
);
6017 n
.out
.types
= &types
;
6018 for (i
=0;i
<sam
->count
;i
++) {
6019 n
.in
.names
[i
].string
= sam
->entries
[i
].name
.string
;
6021 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupNames_r(b
, tctx
, &n
),
6022 "LookupNames failed");
6023 if (!NT_STATUS_IS_OK(n
.out
.result
)) {
6024 torture_warning(tctx
, "LookupNames failed - %s\n", nt_errstr(n
.out
.result
));
6029 torture_comment(tctx
, "Testing LookupRids\n");
6030 lr
.in
.domain_handle
= handle
;
6031 lr
.in
.num_rids
= sam
->count
;
6032 lr
.in
.rids
= talloc_array(tctx
, uint32_t, sam
->count
);
6033 lr
.out
.names
= &names
;
6034 lr
.out
.types
= &types
;
6035 for (i
=0;i
<sam
->count
;i
++) {
6036 lr
.in
.rids
[i
] = sam
->entries
[i
].idx
;
6038 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupRids_r(b
, tctx
, &lr
),
6039 "LookupRids failed");
6040 torture_assert_ntstatus_ok(tctx
, lr
.out
.result
, "LookupRids");
6046 try blasting the server with a bunch of sync requests
6048 static bool test_EnumDomainUsers_async(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6049 struct policy_handle
*handle
)
6051 struct samr_EnumDomainUsers r
;
6052 uint32_t resume_handle
=0;
6054 #define ASYNC_COUNT 100
6055 struct tevent_req
*req
[ASYNC_COUNT
];
6057 if (!torture_setting_bool(tctx
, "dangerous", false)) {
6058 torture_skip(tctx
, "samr async test disabled - enable dangerous tests to use\n");
6061 torture_comment(tctx
, "Testing EnumDomainUsers_async\n");
6063 r
.in
.domain_handle
= handle
;
6064 r
.in
.resume_handle
= &resume_handle
;
6065 r
.in
.acct_flags
= 0;
6066 r
.in
.max_size
= (uint32_t)-1;
6067 r
.out
.resume_handle
= &resume_handle
;
6069 for (i
=0;i
<ASYNC_COUNT
;i
++) {
6070 req
[i
] = dcerpc_samr_EnumDomainUsers_r_send(tctx
, tctx
->ev
, p
->binding_handle
, &r
);
6073 for (i
=0;i
<ASYNC_COUNT
;i
++) {
6074 tevent_req_poll(req
[i
], tctx
->ev
);
6075 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainUsers_r_recv(req
[i
], tctx
),
6076 talloc_asprintf(tctx
, "EnumDomainUsers[%d] failed - %s\n",
6077 i
, nt_errstr(r
.out
.result
)));
6080 torture_comment(tctx
, "%d async requests OK\n", i
);
6085 static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle
*b
,
6086 struct torture_context
*tctx
,
6087 struct policy_handle
*handle
)
6089 struct samr_EnumDomainGroups r
;
6090 uint32_t resume_handle
=0;
6091 struct samr_SamArray
*sam
= NULL
;
6092 uint32_t num_entries
= 0;
6095 bool universal_group_found
= false;
6097 torture_comment(tctx
, "Testing EnumDomainGroups\n");
6099 r
.in
.domain_handle
= handle
;
6100 r
.in
.resume_handle
= &resume_handle
;
6101 r
.in
.max_size
= (uint32_t)-1;
6102 r
.out
.resume_handle
= &resume_handle
;
6103 r
.out
.num_entries
= &num_entries
;
6106 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainGroups_r(b
, tctx
, &r
),
6107 "EnumDomainGroups failed");
6108 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6109 torture_warning(tctx
, "EnumDomainGroups failed - %s\n", nt_errstr(r
.out
.result
));
6117 for (i
=0;i
<sam
->count
;i
++) {
6118 if (!test_OpenGroup(b
, tctx
, handle
, sam
->entries
[i
].idx
)) {
6121 if ((ret
== true) && (strcasecmp(sam
->entries
[i
].name
.string
,
6122 "Enterprise Admins") == 0)) {
6123 universal_group_found
= true;
6127 /* when we are running this on s4 we should get back at least the
6128 * "Enterprise Admins" universal group. If we don't get a group entry
6129 * at all we probably are performing the test on the builtin domain.
6130 * So ignore this case. */
6131 if (torture_setting_bool(tctx
, "samba4", false)) {
6132 if ((sam
->count
> 0) && (!universal_group_found
)) {
6140 static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle
*b
,
6141 struct torture_context
*tctx
,
6142 struct policy_handle
*handle
)
6144 struct samr_EnumDomainAliases r
;
6145 uint32_t resume_handle
=0;
6146 struct samr_SamArray
*sam
= NULL
;
6147 uint32_t num_entries
= 0;
6151 torture_comment(tctx
, "Testing EnumDomainAliases\n");
6153 r
.in
.domain_handle
= handle
;
6154 r
.in
.resume_handle
= &resume_handle
;
6155 r
.in
.max_size
= (uint32_t)-1;
6157 r
.out
.num_entries
= &num_entries
;
6158 r
.out
.resume_handle
= &resume_handle
;
6160 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainAliases_r(b
, tctx
, &r
),
6161 "EnumDomainAliases failed");
6162 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6163 torture_warning(tctx
, "EnumDomainAliases failed - %s\n", nt_errstr(r
.out
.result
));
6171 for (i
=0;i
<sam
->count
;i
++) {
6172 if (!test_OpenAlias(b
, tctx
, handle
, sam
->entries
[i
].idx
)) {
6180 static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle
*b
,
6181 struct torture_context
*tctx
,
6182 struct policy_handle
*handle
)
6184 struct samr_GetDisplayEnumerationIndex r
;
6186 uint16_t levels
[] = {1, 2, 3, 4, 5};
6187 uint16_t ok_lvl
[] = {1, 1, 1, 0, 0};
6188 struct lsa_String name
;
6192 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6193 torture_comment(tctx
, "Testing GetDisplayEnumerationIndex level %u\n", levels
[i
]);
6195 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
6197 r
.in
.domain_handle
= handle
;
6198 r
.in
.level
= levels
[i
];
6202 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDisplayEnumerationIndex_r(b
, tctx
, &r
),
6203 "GetDisplayEnumerationIndex failed");
6206 !NT_STATUS_IS_OK(r
.out
.result
) &&
6207 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, r
.out
.result
)) {
6208 torture_warning(tctx
, "GetDisplayEnumerationIndex level %u failed - %s\n",
6209 levels
[i
], nt_errstr(r
.out
.result
));
6213 init_lsa_String(&name
, "zzzzzzzz");
6215 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDisplayEnumerationIndex_r(b
, tctx
, &r
),
6216 "GetDisplayEnumerationIndex failed");
6218 if (ok_lvl
[i
] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, r
.out
.result
)) {
6219 torture_warning(tctx
, "GetDisplayEnumerationIndex level %u failed - %s\n",
6220 levels
[i
], nt_errstr(r
.out
.result
));
6228 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle
*b
,
6229 struct torture_context
*tctx
,
6230 struct policy_handle
*handle
)
6232 struct samr_GetDisplayEnumerationIndex2 r
;
6234 uint16_t levels
[] = {1, 2, 3, 4, 5};
6235 uint16_t ok_lvl
[] = {1, 1, 1, 0, 0};
6236 struct lsa_String name
;
6240 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6241 torture_comment(tctx
, "Testing GetDisplayEnumerationIndex2 level %u\n", levels
[i
]);
6243 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
6245 r
.in
.domain_handle
= handle
;
6246 r
.in
.level
= levels
[i
];
6250 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDisplayEnumerationIndex2_r(b
, tctx
, &r
),
6251 "GetDisplayEnumerationIndex2 failed");
6253 !NT_STATUS_IS_OK(r
.out
.result
) &&
6254 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, r
.out
.result
)) {
6255 torture_warning(tctx
, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6256 levels
[i
], nt_errstr(r
.out
.result
));
6260 init_lsa_String(&name
, "zzzzzzzz");
6262 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDisplayEnumerationIndex2_r(b
, tctx
, &r
),
6263 "GetDisplayEnumerationIndex2 failed");
6264 if (ok_lvl
[i
] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, r
.out
.result
)) {
6265 torture_warning(tctx
, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6266 levels
[i
], nt_errstr(r
.out
.result
));
6274 #define STRING_EQUAL_QUERY(s1, s2, user) \
6275 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6276 /* odd, but valid */ \
6277 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6278 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
6279 #s1, user.string, s1.string, s2.string, __location__); \
6282 #define INT_EQUAL_QUERY(s1, s2, user) \
6284 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6285 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6289 static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle
*b
,
6290 struct torture_context
*tctx
,
6291 struct samr_QueryDisplayInfo
*querydisplayinfo
,
6292 bool *seen_testuser
)
6294 struct samr_OpenUser r
;
6295 struct samr_QueryUserInfo q
;
6296 union samr_UserInfo
*info
;
6297 struct policy_handle user_handle
;
6299 r
.in
.domain_handle
= querydisplayinfo
->in
.domain_handle
;
6300 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6301 for (i
= 0; ; i
++) {
6302 switch (querydisplayinfo
->in
.level
) {
6304 if (i
>= querydisplayinfo
->out
.info
->info1
.count
) {
6307 r
.in
.rid
= querydisplayinfo
->out
.info
->info1
.entries
[i
].rid
;
6310 if (i
>= querydisplayinfo
->out
.info
->info2
.count
) {
6313 r
.in
.rid
= querydisplayinfo
->out
.info
->info2
.entries
[i
].rid
;
6319 /* Not interested in validating just the account name */
6323 r
.out
.user_handle
= &user_handle
;
6325 switch (querydisplayinfo
->in
.level
) {
6328 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenUser_r(b
, tctx
, &r
),
6330 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6331 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", r
.in
.rid
, nt_errstr(r
.out
.result
));
6336 q
.in
.user_handle
= &user_handle
;
6339 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
),
6340 "QueryUserInfo failed");
6341 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6342 torture_warning(tctx
, "QueryUserInfo(%u) failed - %s\n", r
.in
.rid
, nt_errstr(r
.out
.result
));
6346 switch (querydisplayinfo
->in
.level
) {
6348 if (seen_testuser
&& strcmp(info
->info21
.account_name
.string
, TEST_ACCOUNT_NAME
) == 0) {
6349 *seen_testuser
= true;
6351 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].full_name
,
6352 info
->info21
.full_name
, info
->info21
.account_name
);
6353 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].account_name
,
6354 info
->info21
.account_name
, info
->info21
.account_name
);
6355 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].description
,
6356 info
->info21
.description
, info
->info21
.account_name
);
6357 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].rid
,
6358 info
->info21
.rid
, info
->info21
.account_name
);
6359 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].acct_flags
,
6360 info
->info21
.acct_flags
, info
->info21
.account_name
);
6364 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].account_name
,
6365 info
->info21
.account_name
, info
->info21
.account_name
);
6366 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].description
,
6367 info
->info21
.description
, info
->info21
.account_name
);
6368 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].rid
,
6369 info
->info21
.rid
, info
->info21
.account_name
);
6370 INT_EQUAL_QUERY((querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
& ~ACB_NORMAL
),
6371 info
->info21
.acct_flags
, info
->info21
.account_name
);
6373 if (!(querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
& ACB_NORMAL
)) {
6374 torture_warning(tctx
, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6375 info
->info21
.account_name
.string
);
6378 if (!(info
->info21
.acct_flags
& (ACB_WSTRUST
| ACB_SVRTRUST
))) {
6379 torture_warning(tctx
, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6380 info
->info21
.account_name
.string
,
6381 querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
,
6382 info
->info21
.acct_flags
);
6389 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
6396 static bool test_QueryDisplayInfo(struct dcerpc_binding_handle
*b
,
6397 struct torture_context
*tctx
,
6398 struct policy_handle
*handle
)
6400 struct samr_QueryDisplayInfo r
;
6401 struct samr_QueryDomainInfo dom_info
;
6402 union samr_DomainInfo
*info
= NULL
;
6404 uint16_t levels
[] = {1, 2, 3, 4, 5};
6406 bool seen_testuser
= false;
6407 uint32_t total_size
;
6408 uint32_t returned_size
;
6409 union samr_DispInfo disp_info
;
6412 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6413 torture_comment(tctx
, "Testing QueryDisplayInfo level %u\n", levels
[i
]);
6416 r
.out
.result
= STATUS_MORE_ENTRIES
;
6417 while (NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
)) {
6418 r
.in
.domain_handle
= handle
;
6419 r
.in
.level
= levels
[i
];
6420 r
.in
.max_entries
= 2;
6421 r
.in
.buf_size
= (uint32_t)-1;
6422 r
.out
.total_size
= &total_size
;
6423 r
.out
.returned_size
= &returned_size
;
6424 r
.out
.info
= &disp_info
;
6426 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &r
),
6427 "QueryDisplayInfo failed");
6428 if (!NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
) && !NT_STATUS_IS_OK(r
.out
.result
)) {
6429 torture_warning(tctx
, "QueryDisplayInfo level %u failed - %s\n",
6430 levels
[i
], nt_errstr(r
.out
.result
));
6433 switch (r
.in
.level
) {
6435 if (!test_each_DisplayInfo_user(b
, tctx
, &r
, &seen_testuser
)) {
6438 r
.in
.start_idx
+= r
.out
.info
->info1
.count
;
6441 if (!test_each_DisplayInfo_user(b
, tctx
, &r
, NULL
)) {
6444 r
.in
.start_idx
+= r
.out
.info
->info2
.count
;
6447 r
.in
.start_idx
+= r
.out
.info
->info3
.count
;
6450 r
.in
.start_idx
+= r
.out
.info
->info4
.count
;
6453 r
.in
.start_idx
+= r
.out
.info
->info5
.count
;
6457 dom_info
.in
.domain_handle
= handle
;
6458 dom_info
.in
.level
= 2;
6459 dom_info
.out
.info
= &info
;
6461 /* Check number of users returned is correct */
6462 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &dom_info
),
6463 "QueryDomainInfo failed");
6464 if (!NT_STATUS_IS_OK(dom_info
.out
.result
)) {
6465 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
6466 r
.in
.level
, nt_errstr(dom_info
.out
.result
));
6470 switch (r
.in
.level
) {
6473 if (info
->general
.num_users
< r
.in
.start_idx
) {
6474 /* On AD deployments this numbers don't match
6475 * since QueryDisplayInfo returns universal and
6476 * global groups, QueryDomainInfo only global
6478 if (torture_setting_bool(tctx
, "samba3", false)) {
6479 torture_warning(tctx
, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6480 r
.in
.start_idx
, info
->general
.num_groups
,
6481 info
->general
.domain_name
.string
);
6485 if (!seen_testuser
) {
6486 struct policy_handle user_handle
;
6487 if (NT_STATUS_IS_OK(test_OpenUser_byname(b
, tctx
, handle
, TEST_ACCOUNT_NAME
, &user_handle
))) {
6488 torture_warning(tctx
, "Didn't find test user " TEST_ACCOUNT_NAME
" in enumeration of %s\n",
6489 info
->general
.domain_name
.string
);
6491 test_samr_handle_Close(b
, tctx
, &user_handle
);
6497 if (info
->general
.num_groups
!= r
.in
.start_idx
) {
6498 /* On AD deployments this numbers don't match
6499 * since QueryDisplayInfo returns universal and
6500 * global groups, QueryDomainInfo only global
6502 if (torture_setting_bool(tctx
, "samba3", false)) {
6503 torture_warning(tctx
, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6504 r
.in
.start_idx
, info
->general
.num_groups
,
6505 info
->general
.domain_name
.string
);
6518 static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle
*b
,
6519 struct torture_context
*tctx
,
6520 struct policy_handle
*handle
)
6522 struct samr_QueryDisplayInfo2 r
;
6524 uint16_t levels
[] = {1, 2, 3, 4, 5};
6526 uint32_t total_size
;
6527 uint32_t returned_size
;
6528 union samr_DispInfo info
;
6530 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6531 torture_comment(tctx
, "Testing QueryDisplayInfo2 level %u\n", levels
[i
]);
6533 r
.in
.domain_handle
= handle
;
6534 r
.in
.level
= levels
[i
];
6536 r
.in
.max_entries
= 1000;
6537 r
.in
.buf_size
= (uint32_t)-1;
6538 r
.out
.total_size
= &total_size
;
6539 r
.out
.returned_size
= &returned_size
;
6542 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo2_r(b
, tctx
, &r
),
6543 "QueryDisplayInfo2 failed");
6544 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6545 torture_warning(tctx
, "QueryDisplayInfo2 level %u failed - %s\n",
6546 levels
[i
], nt_errstr(r
.out
.result
));
6554 static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle
*b
,
6555 struct torture_context
*tctx
,
6556 struct policy_handle
*handle
)
6558 struct samr_QueryDisplayInfo3 r
;
6560 uint16_t levels
[] = {1, 2, 3, 4, 5};
6562 uint32_t total_size
;
6563 uint32_t returned_size
;
6564 union samr_DispInfo info
;
6566 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6567 torture_comment(tctx
, "Testing QueryDisplayInfo3 level %u\n", levels
[i
]);
6569 r
.in
.domain_handle
= handle
;
6570 r
.in
.level
= levels
[i
];
6572 r
.in
.max_entries
= 1000;
6573 r
.in
.buf_size
= (uint32_t)-1;
6574 r
.out
.total_size
= &total_size
;
6575 r
.out
.returned_size
= &returned_size
;
6578 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo3_r(b
, tctx
, &r
),
6579 "QueryDisplayInfo3 failed");
6580 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6581 torture_warning(tctx
, "QueryDisplayInfo3 level %u failed - %s\n",
6582 levels
[i
], nt_errstr(r
.out
.result
));
6591 static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle
*b
,
6592 struct torture_context
*tctx
,
6593 struct policy_handle
*handle
)
6595 struct samr_QueryDisplayInfo r
;
6597 uint32_t total_size
;
6598 uint32_t returned_size
;
6599 union samr_DispInfo info
;
6601 torture_comment(tctx
, "Testing QueryDisplayInfo continuation\n");
6603 r
.in
.domain_handle
= handle
;
6606 r
.in
.max_entries
= 1;
6607 r
.in
.buf_size
= (uint32_t)-1;
6608 r
.out
.total_size
= &total_size
;
6609 r
.out
.returned_size
= &returned_size
;
6613 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &r
),
6614 "QueryDisplayInfo failed");
6615 if (NT_STATUS_IS_OK(r
.out
.result
) && *r
.out
.returned_size
!= 0) {
6616 if (r
.out
.info
->info1
.entries
[0].idx
!= r
.in
.start_idx
+ 1) {
6617 torture_warning(tctx
, "expected idx %d but got %d\n",
6619 r
.out
.info
->info1
.entries
[0].idx
);
6623 if (!NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
) &&
6624 !NT_STATUS_IS_OK(r
.out
.result
)) {
6625 torture_warning(tctx
, "QueryDisplayInfo level %u failed - %s\n",
6626 r
.in
.level
, nt_errstr(r
.out
.result
));
6631 } while ((NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
) ||
6632 NT_STATUS_IS_OK(r
.out
.result
)) &&
6633 *r
.out
.returned_size
!= 0);
6638 static bool test_QueryDomainInfo(struct dcerpc_pipe
*p
,
6639 struct torture_context
*tctx
,
6640 struct policy_handle
*handle
)
6642 struct samr_QueryDomainInfo r
;
6643 union samr_DomainInfo
*info
= NULL
;
6644 struct samr_SetDomainInfo s
;
6645 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6646 uint16_t set_ok
[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
6649 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
6650 const char *domain_comment
= talloc_asprintf(tctx
,
6651 "Tortured by Samba4 RPC-SAMR: %s",
6652 timestring(tctx
, time(NULL
)));
6654 s
.in
.domain_handle
= handle
;
6656 s
.in
.info
= talloc(tctx
, union samr_DomainInfo
);
6658 s
.in
.info
->oem
.oem_information
.string
= domain_comment
;
6659 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
),
6660 "SetDomainInfo failed");
6661 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
6662 torture_warning(tctx
, "SetDomainInfo level %u (set comment) failed - %s\n",
6663 s
.in
.level
, nt_errstr(s
.out
.result
));
6667 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6668 torture_comment(tctx
, "Testing QueryDomainInfo level %u\n", levels
[i
]);
6670 r
.in
.domain_handle
= handle
;
6671 r
.in
.level
= levels
[i
];
6674 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &r
),
6675 "QueryDomainInfo failed");
6676 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6677 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
6678 r
.in
.level
, nt_errstr(r
.out
.result
));
6683 switch (levels
[i
]) {
6685 if (strcmp(info
->general
.oem_information
.string
, domain_comment
) != 0) {
6686 torture_warning(tctx
, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6687 levels
[i
], info
->general
.oem_information
.string
, domain_comment
);
6688 if (!torture_setting_bool(tctx
, "samba3", false)) {
6692 if (!info
->general
.primary
.string
) {
6693 torture_warning(tctx
, "QueryDomainInfo level %u returned no PDC name\n",
6696 } else if (info
->general
.role
== SAMR_ROLE_DOMAIN_PDC
) {
6697 if (dcerpc_server_name(p
) && strcasecmp_m(dcerpc_server_name(p
), info
->general
.primary
.string
) != 0) {
6698 if (torture_setting_bool(tctx
, "samba3", false)) {
6699 torture_warning(tctx
, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
6700 levels
[i
], info
->general
.primary
.string
, dcerpc_server_name(p
));
6706 if (strcmp(info
->oem
.oem_information
.string
, domain_comment
) != 0) {
6707 torture_warning(tctx
, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6708 levels
[i
], info
->oem
.oem_information
.string
, domain_comment
);
6709 if (!torture_setting_bool(tctx
, "samba3", false)) {
6715 if (!info
->info6
.primary
.string
) {
6716 torture_warning(tctx
, "QueryDomainInfo level %u returned no PDC name\n",
6722 if (strcmp(info
->general2
.general
.oem_information
.string
, domain_comment
) != 0) {
6723 torture_warning(tctx
, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
6724 levels
[i
], info
->general2
.general
.oem_information
.string
, domain_comment
);
6725 if (!torture_setting_bool(tctx
, "samba3", false)) {
6732 torture_comment(tctx
, "Testing SetDomainInfo level %u\n", levels
[i
]);
6734 s
.in
.domain_handle
= handle
;
6735 s
.in
.level
= levels
[i
];
6738 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
),
6739 "SetDomainInfo failed");
6741 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
6742 torture_warning(tctx
, "SetDomainInfo level %u failed - %s\n",
6743 r
.in
.level
, nt_errstr(s
.out
.result
));
6748 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, s
.out
.result
)) {
6749 torture_warning(tctx
, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6750 r
.in
.level
, nt_errstr(s
.out
.result
));
6756 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &r
),
6757 "QueryDomainInfo failed");
6758 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6759 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
6760 r
.in
.level
, nt_errstr(r
.out
.result
));
6770 static bool test_QueryDomainInfo2(struct dcerpc_binding_handle
*b
,
6771 struct torture_context
*tctx
,
6772 struct policy_handle
*handle
)
6774 struct samr_QueryDomainInfo2 r
;
6775 union samr_DomainInfo
*info
= NULL
;
6776 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6780 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6781 torture_comment(tctx
, "Testing QueryDomainInfo2 level %u\n", levels
[i
]);
6783 r
.in
.domain_handle
= handle
;
6784 r
.in
.level
= levels
[i
];
6787 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo2_r(b
, tctx
, &r
),
6788 "QueryDomainInfo2 failed");
6789 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6790 torture_warning(tctx
, "QueryDomainInfo2 level %u failed - %s\n",
6791 r
.in
.level
, nt_errstr(r
.out
.result
));
6800 /* Test whether querydispinfo level 5 and enumdomgroups return the same
6801 set of group names. */
6802 static bool test_GroupList(struct dcerpc_binding_handle
*b
,
6803 struct torture_context
*tctx
,
6804 struct dom_sid
*domain_sid
,
6805 struct policy_handle
*handle
)
6807 struct samr_EnumDomainGroups q1
;
6808 struct samr_QueryDisplayInfo q2
;
6810 uint32_t resume_handle
=0;
6811 struct samr_SamArray
*sam
= NULL
;
6812 uint32_t num_entries
= 0;
6815 uint32_t total_size
;
6816 uint32_t returned_size
;
6817 union samr_DispInfo info
;
6820 const char **names
= NULL
;
6822 bool builtin_domain
= dom_sid_compare(domain_sid
,
6823 &global_sid_Builtin
) == 0;
6825 torture_comment(tctx
, "Testing coherency of querydispinfo vs enumdomgroups\n");
6827 q1
.in
.domain_handle
= handle
;
6828 q1
.in
.resume_handle
= &resume_handle
;
6830 q1
.out
.resume_handle
= &resume_handle
;
6831 q1
.out
.num_entries
= &num_entries
;
6834 status
= STATUS_MORE_ENTRIES
;
6835 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
6836 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainGroups_r(b
, tctx
, &q1
),
6837 "EnumDomainGroups failed");
6838 status
= q1
.out
.result
;
6840 if (!NT_STATUS_IS_OK(status
) &&
6841 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
6844 for (i
=0; i
<*q1
.out
.num_entries
; i
++) {
6845 add_string_to_array(tctx
,
6846 sam
->entries
[i
].name
.string
,
6847 &names
, &num_names
);
6851 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomainGroups");
6853 torture_assert(tctx
, sam
, "EnumDomainGroups failed to return sam");
6855 if (builtin_domain
) {
6856 torture_assert(tctx
, num_names
== 0,
6857 "EnumDomainGroups shouldn't return any group in the builtin domain!");
6860 q2
.in
.domain_handle
= handle
;
6862 q2
.in
.start_idx
= 0;
6863 q2
.in
.max_entries
= 5;
6864 q2
.in
.buf_size
= (uint32_t)-1;
6865 q2
.out
.total_size
= &total_size
;
6866 q2
.out
.returned_size
= &returned_size
;
6867 q2
.out
.info
= &info
;
6869 status
= STATUS_MORE_ENTRIES
;
6870 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
6871 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &q2
),
6872 "QueryDisplayInfo failed");
6873 status
= q2
.out
.result
;
6874 if (!NT_STATUS_IS_OK(status
) &&
6875 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
6878 for (i
=0; i
<q2
.out
.info
->info5
.count
; i
++) {
6880 const char *name
= q2
.out
.info
->info5
.entries
[i
].account_name
.string
;
6882 for (j
=0; j
<num_names
; j
++) {
6883 if (names
[j
] == NULL
)
6885 if (strequal(names
[j
], name
)) {
6892 if ((!found
) && (!builtin_domain
)) {
6893 torture_warning(tctx
, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
6898 q2
.in
.start_idx
+= q2
.out
.info
->info5
.count
;
6901 if (!NT_STATUS_IS_OK(status
)) {
6902 torture_warning(tctx
, "QueryDisplayInfo level 5 failed - %s\n",
6907 if (builtin_domain
) {
6908 torture_assert(tctx
, q2
.in
.start_idx
!= 0,
6909 "QueryDisplayInfo should return all domain groups also on the builtin domain handle!");
6912 for (i
=0; i
<num_names
; i
++) {
6913 if (names
[i
] != NULL
) {
6914 torture_warning(tctx
, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
6923 static bool test_DeleteDomainGroup(struct dcerpc_binding_handle
*b
,
6924 struct torture_context
*tctx
,
6925 struct policy_handle
*group_handle
)
6927 struct samr_DeleteDomainGroup d
;
6929 torture_comment(tctx
, "Testing DeleteDomainGroup\n");
6931 d
.in
.group_handle
= group_handle
;
6932 d
.out
.group_handle
= group_handle
;
6934 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteDomainGroup_r(b
, tctx
, &d
),
6935 "DeleteDomainGroup failed");
6936 torture_assert_ntstatus_ok(tctx
, d
.out
.result
, "DeleteDomainGroup");
6941 static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle
*b
,
6942 struct torture_context
*tctx
,
6943 struct policy_handle
*domain_handle
)
6945 struct samr_TestPrivateFunctionsDomain r
;
6948 torture_comment(tctx
, "Testing TestPrivateFunctionsDomain\n");
6950 r
.in
.domain_handle
= domain_handle
;
6952 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_TestPrivateFunctionsDomain_r(b
, tctx
, &r
),
6953 "TestPrivateFunctionsDomain failed");
6954 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_NOT_IMPLEMENTED
, "TestPrivateFunctionsDomain");
6959 static bool test_RidToSid(struct dcerpc_binding_handle
*b
,
6960 struct torture_context
*tctx
,
6961 struct dom_sid
*domain_sid
,
6962 struct policy_handle
*domain_handle
)
6964 struct samr_RidToSid r
;
6966 struct dom_sid
*calc_sid
, *out_sid
;
6967 int rids
[] = { 0, 42, 512, 10200 };
6970 for (i
=0;i
<ARRAY_SIZE(rids
);i
++) {
6971 torture_comment(tctx
, "Testing RidToSid\n");
6973 calc_sid
= dom_sid_dup(tctx
, domain_sid
);
6974 r
.in
.domain_handle
= domain_handle
;
6976 r
.out
.sid
= &out_sid
;
6978 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RidToSid_r(b
, tctx
, &r
),
6980 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6981 torture_warning(tctx
, "RidToSid for %d failed - %s\n", rids
[i
], nt_errstr(r
.out
.result
));
6984 calc_sid
= dom_sid_add_rid(calc_sid
, calc_sid
, rids
[i
]);
6986 if (!dom_sid_equal(calc_sid
, out_sid
)) {
6987 torture_warning(tctx
, "RidToSid for %d failed - got %s, expected %s\n", rids
[i
],
6988 dom_sid_string(tctx
, out_sid
),
6989 dom_sid_string(tctx
, calc_sid
));
6998 static bool test_GetBootKeyInformation(struct dcerpc_binding_handle
*b
,
6999 struct torture_context
*tctx
,
7000 struct policy_handle
*domain_handle
)
7002 struct samr_GetBootKeyInformation r
;
7004 uint32_t unknown
= 0;
7007 torture_comment(tctx
, "Testing GetBootKeyInformation\n");
7009 r
.in
.domain_handle
= domain_handle
;
7010 r
.out
.unknown
= &unknown
;
7012 status
= dcerpc_samr_GetBootKeyInformation_r(b
, tctx
, &r
);
7013 if (NT_STATUS_IS_OK(status
) && !NT_STATUS_IS_OK(r
.out
.result
)) {
7014 status
= r
.out
.result
;
7016 if (!NT_STATUS_IS_OK(status
)) {
7017 /* w2k3 seems to fail this sometimes and pass it sometimes */
7018 torture_comment(tctx
, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status
));
7024 static bool test_AddGroupMember(struct dcerpc_binding_handle
*b
,
7025 struct torture_context
*tctx
,
7026 struct policy_handle
*domain_handle
,
7027 struct policy_handle
*group_handle
)
7030 struct samr_AddGroupMember r
;
7031 struct samr_DeleteGroupMember d
;
7032 struct samr_QueryGroupMember q
;
7033 struct samr_RidAttrArray
*rids
= NULL
;
7034 struct samr_SetMemberAttributesOfGroup s
;
7036 bool found_member
= false;
7039 status
= test_LookupName(b
, tctx
, domain_handle
, TEST_ACCOUNT_NAME
, &rid
);
7040 torture_assert_ntstatus_ok(tctx
, status
, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME
);
7042 r
.in
.group_handle
= group_handle
;
7044 r
.in
.flags
= 0; /* ??? */
7046 torture_comment(tctx
, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
7048 d
.in
.group_handle
= group_handle
;
7051 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteGroupMember_r(b
, tctx
, &d
),
7052 "DeleteGroupMember failed");
7053 torture_assert_ntstatus_equal(tctx
, NT_STATUS_MEMBER_NOT_IN_GROUP
, d
.out
.result
, "DeleteGroupMember");
7055 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddGroupMember_r(b
, tctx
, &r
),
7056 "AddGroupMember failed");
7057 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "AddGroupMember");
7059 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddGroupMember_r(b
, tctx
, &r
),
7060 "AddGroupMember failed");
7061 torture_assert_ntstatus_equal(tctx
, NT_STATUS_MEMBER_IN_GROUP
, r
.out
.result
, "AddGroupMember");
7063 if (torture_setting_bool(tctx
, "samba4", false) ||
7064 torture_setting_bool(tctx
, "samba3", false)) {
7065 torture_comment(tctx
, "skipping SetMemberAttributesOfGroup test against Samba\n");
7067 /* this one is quite strange. I am using random inputs in the
7068 hope of triggering an error that might give us a clue */
7070 s
.in
.group_handle
= group_handle
;
7071 s
.in
.unknown1
= random();
7072 s
.in
.unknown2
= random();
7074 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetMemberAttributesOfGroup_r(b
, tctx
, &s
),
7075 "SetMemberAttributesOfGroup failed");
7076 torture_assert_ntstatus_ok(tctx
, s
.out
.result
, "SetMemberAttributesOfGroup");
7079 q
.in
.group_handle
= group_handle
;
7082 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupMember_r(b
, tctx
, &q
),
7083 "QueryGroupMember failed");
7084 torture_assert_ntstatus_ok(tctx
, q
.out
.result
, "QueryGroupMember");
7085 torture_assert(tctx
, rids
, "QueryGroupMember did not fill in rids structure");
7087 for (i
=0; i
< rids
->count
; i
++) {
7088 if (rids
->rids
[i
] == rid
) {
7089 found_member
= true;
7093 torture_assert(tctx
, found_member
, "QueryGroupMember did not list newly added member");
7095 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteGroupMember_r(b
, tctx
, &d
),
7096 "DeleteGroupMember failed");
7097 torture_assert_ntstatus_ok(tctx
, d
.out
.result
, "DeleteGroupMember");
7100 found_member
= false;
7102 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupMember_r(b
, tctx
, &q
),
7103 "QueryGroupMember failed");
7104 torture_assert_ntstatus_ok(tctx
, q
.out
.result
, "QueryGroupMember");
7105 torture_assert(tctx
, rids
, "QueryGroupMember did not fill in rids structure");
7107 for (i
=0; i
< rids
->count
; i
++) {
7108 if (rids
->rids
[i
] == rid
) {
7109 found_member
= true;
7113 torture_assert(tctx
, !found_member
, "QueryGroupMember does still list removed member");
7115 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddGroupMember_r(b
, tctx
, &r
),
7116 "AddGroupMember failed");
7117 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "AddGroupMember");
7123 static bool test_CreateDomainGroup(struct dcerpc_binding_handle
*b
,
7124 struct torture_context
*tctx
,
7125 struct policy_handle
*domain_handle
,
7126 const char *group_name
,
7127 struct policy_handle
*group_handle
,
7128 struct dom_sid
*domain_sid
,
7131 struct samr_CreateDomainGroup r
;
7133 struct lsa_String name
;
7136 init_lsa_String(&name
, group_name
);
7138 r
.in
.domain_handle
= domain_handle
;
7140 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7141 r
.out
.group_handle
= group_handle
;
7144 torture_comment(tctx
, "Testing CreateDomainGroup(%s)\n", r
.in
.name
->string
);
7146 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomainGroup_r(b
, tctx
, &r
),
7147 "CreateDomainGroup failed");
7149 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
7150 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
)) {
7151 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.name
->string
);
7154 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.name
->string
,
7155 nt_errstr(r
.out
.result
));
7160 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_GROUP_EXISTS
)) {
7161 if (!test_DeleteGroup_byname(b
, tctx
, domain_handle
, r
.in
.name
->string
)) {
7162 torture_warning(tctx
, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r
.in
.name
->string
,
7163 nt_errstr(r
.out
.result
));
7166 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomainGroup_r(b
, tctx
, &r
),
7167 "CreateDomainGroup failed");
7169 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_USER_EXISTS
)) {
7170 if (!test_DeleteUser_byname(b
, tctx
, domain_handle
, r
.in
.name
->string
)) {
7172 torture_warning(tctx
, "CreateDomainGroup failed: Could not delete user %s - %s\n", r
.in
.name
->string
,
7173 nt_errstr(r
.out
.result
));
7176 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomainGroup_r(b
, tctx
, &r
),
7177 "CreateDomainGroup failed");
7179 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "CreateDomainGroup");
7185 if (!test_AddGroupMember(b
, tctx
, domain_handle
, group_handle
)) {
7186 torture_warning(tctx
, "CreateDomainGroup failed - %s\n", nt_errstr(r
.out
.result
));
7190 if (!test_SetGroupInfo(b
, tctx
, group_handle
)) {
7199 its not totally clear what this does. It seems to accept any sid you like.
7201 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle
*b
,
7202 struct torture_context
*tctx
,
7203 struct policy_handle
*domain_handle
)
7205 struct samr_RemoveMemberFromForeignDomain r
;
7207 r
.in
.domain_handle
= domain_handle
;
7208 r
.in
.sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-12-34-56-78");
7210 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RemoveMemberFromForeignDomain_r(b
, tctx
, &r
),
7211 "RemoveMemberFromForeignDomain failed");
7212 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "RemoveMemberFromForeignDomain");
7217 static bool test_EnumDomainUsers(struct dcerpc_binding_handle
*b
,
7218 struct torture_context
*tctx
,
7219 struct policy_handle
*domain_handle
,
7220 uint32_t *total_num_entries_p
)
7223 struct samr_EnumDomainUsers r
;
7224 uint32_t resume_handle
= 0;
7225 uint32_t num_entries
= 0;
7226 uint32_t total_num_entries
= 0;
7227 struct samr_SamArray
*sam
;
7229 r
.in
.domain_handle
= domain_handle
;
7230 r
.in
.acct_flags
= 0;
7231 r
.in
.max_size
= (uint32_t)-1;
7232 r
.in
.resume_handle
= &resume_handle
;
7235 r
.out
.num_entries
= &num_entries
;
7236 r
.out
.resume_handle
= &resume_handle
;
7238 torture_comment(tctx
, "Testing EnumDomainUsers\n");
7241 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainUsers_r(b
, tctx
, &r
),
7242 "EnumDomainUsers failed");
7243 if (NT_STATUS_IS_ERR(r
.out
.result
)) {
7244 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
7245 "failed to enumerate users");
7247 status
= r
.out
.result
;
7249 total_num_entries
+= num_entries
;
7250 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7252 if (total_num_entries_p
) {
7253 *total_num_entries_p
= total_num_entries
;
7259 static bool test_EnumDomainGroups(struct dcerpc_binding_handle
*b
,
7260 struct torture_context
*tctx
,
7261 struct policy_handle
*domain_handle
,
7262 uint32_t *total_num_entries_p
)
7265 struct samr_EnumDomainGroups r
;
7266 uint32_t resume_handle
= 0;
7267 uint32_t num_entries
= 0;
7268 uint32_t total_num_entries
= 0;
7269 struct samr_SamArray
*sam
;
7271 r
.in
.domain_handle
= domain_handle
;
7272 r
.in
.max_size
= (uint32_t)-1;
7273 r
.in
.resume_handle
= &resume_handle
;
7276 r
.out
.num_entries
= &num_entries
;
7277 r
.out
.resume_handle
= &resume_handle
;
7279 torture_comment(tctx
, "Testing EnumDomainGroups\n");
7282 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainGroups_r(b
, tctx
, &r
),
7283 "EnumDomainGroups failed");
7284 if (NT_STATUS_IS_ERR(r
.out
.result
)) {
7285 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
7286 "failed to enumerate groups");
7288 status
= r
.out
.result
;
7290 total_num_entries
+= num_entries
;
7291 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7293 if (total_num_entries_p
) {
7294 *total_num_entries_p
= total_num_entries
;
7300 static bool test_EnumDomainAliases(struct dcerpc_binding_handle
*b
,
7301 struct torture_context
*tctx
,
7302 struct policy_handle
*domain_handle
,
7303 uint32_t *total_num_entries_p
)
7306 struct samr_EnumDomainAliases r
;
7307 uint32_t resume_handle
= 0;
7308 uint32_t num_entries
= 0;
7309 uint32_t total_num_entries
= 0;
7310 struct samr_SamArray
*sam
;
7312 r
.in
.domain_handle
= domain_handle
;
7313 r
.in
.max_size
= (uint32_t)-1;
7314 r
.in
.resume_handle
= &resume_handle
;
7317 r
.out
.num_entries
= &num_entries
;
7318 r
.out
.resume_handle
= &resume_handle
;
7320 torture_comment(tctx
, "Testing EnumDomainAliases\n");
7323 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainAliases_r(b
, tctx
, &r
),
7324 "EnumDomainAliases failed");
7325 if (NT_STATUS_IS_ERR(r
.out
.result
)) {
7326 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
7327 "failed to enumerate aliases");
7329 status
= r
.out
.result
;
7331 total_num_entries
+= num_entries
;
7332 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7334 if (total_num_entries_p
) {
7335 *total_num_entries_p
= total_num_entries
;
7341 static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle
*b
,
7342 struct torture_context
*tctx
,
7343 struct policy_handle
*handle
,
7345 uint32_t *total_num_entries_p
)
7348 struct samr_QueryDisplayInfo r
;
7349 uint32_t total_num_entries
= 0;
7351 r
.in
.domain_handle
= handle
;
7354 r
.in
.max_entries
= (uint32_t)-1;
7355 r
.in
.buf_size
= (uint32_t)-1;
7357 torture_comment(tctx
, "Testing QueryDisplayInfo\n");
7360 uint32_t total_size
;
7361 uint32_t returned_size
;
7362 union samr_DispInfo info
;
7364 r
.out
.total_size
= &total_size
;
7365 r
.out
.returned_size
= &returned_size
;
7368 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &r
),
7369 "failed to query displayinfo");
7370 if (NT_STATUS_IS_ERR(r
.out
.result
)) {
7371 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
7372 "failed to query displayinfo");
7374 status
= r
.out
.result
;
7376 if (*r
.out
.returned_size
== 0) {
7380 switch (r
.in
.level
) {
7382 total_num_entries
+= info
.info1
.count
;
7383 r
.in
.start_idx
+= info
.info1
.entries
[info
.info1
.count
- 1].idx
+ 1;
7386 total_num_entries
+= info
.info2
.count
;
7387 r
.in
.start_idx
+= info
.info2
.entries
[info
.info2
.count
- 1].idx
+ 1;
7390 total_num_entries
+= info
.info3
.count
;
7391 r
.in
.start_idx
+= info
.info3
.entries
[info
.info3
.count
- 1].idx
+ 1;
7394 total_num_entries
+= info
.info4
.count
;
7395 r
.in
.start_idx
+= info
.info4
.entries
[info
.info4
.count
- 1].idx
+ 1;
7398 total_num_entries
+= info
.info5
.count
;
7399 r
.in
.start_idx
+= info
.info5
.entries
[info
.info5
.count
- 1].idx
+ 1;
7405 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7407 if (total_num_entries_p
) {
7408 *total_num_entries_p
= total_num_entries
;
7414 static bool test_ManyObjects(struct dcerpc_pipe
*p
,
7415 struct torture_context
*tctx
,
7416 struct policy_handle
*domain_handle
,
7417 struct dom_sid
*domain_sid
,
7418 struct torture_samr_context
*ctx
)
7420 uint32_t num_total
= ctx
->num_objects_large_dc
;
7421 uint32_t num_enum
= 0;
7422 uint32_t num_disp
= 0;
7423 uint32_t num_created
= 0;
7424 uint32_t num_anounced
= 0;
7426 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7428 struct policy_handle
*handles
= talloc_zero_array(tctx
, struct policy_handle
, num_total
);
7433 struct samr_QueryDomainInfo2 r
;
7434 union samr_DomainInfo
*info
;
7435 r
.in
.domain_handle
= domain_handle
;
7439 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo2_r(b
, tctx
, &r
),
7440 "QueryDomainInfo2 failed");
7441 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
7442 "failed to query domain info");
7444 switch (ctx
->choice
) {
7445 case TORTURE_SAMR_MANY_ACCOUNTS
:
7446 num_anounced
= info
->general
.num_users
;
7448 case TORTURE_SAMR_MANY_GROUPS
:
7449 num_anounced
= info
->general
.num_groups
;
7451 case TORTURE_SAMR_MANY_ALIASES
:
7452 num_anounced
= info
->general
.num_aliases
;
7461 for (i
=0; i
< num_total
; i
++) {
7463 const char *name
= NULL
;
7465 switch (ctx
->choice
) {
7466 case TORTURE_SAMR_MANY_ACCOUNTS
:
7467 name
= talloc_asprintf(tctx
, "%s%04d", TEST_ACCOUNT_NAME
, i
);
7468 torture_assert(tctx
,
7469 test_CreateUser(p
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, 0, NULL
, false),
7470 "failed to create user");
7472 case TORTURE_SAMR_MANY_GROUPS
:
7473 name
= talloc_asprintf(tctx
, "%s%04d", TEST_GROUPNAME
, i
);
7474 torture_assert(tctx
,
7475 test_CreateDomainGroup(b
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, false),
7476 "failed to create group");
7478 case TORTURE_SAMR_MANY_ALIASES
:
7479 name
= talloc_asprintf(tctx
, "%s%04d", TEST_ALIASNAME
, i
);
7480 torture_assert(tctx
,
7481 test_CreateAlias(b
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, false),
7482 "failed to create alias");
7487 if (!ndr_policy_handle_empty(&handles
[i
])) {
7494 switch (ctx
->choice
) {
7495 case TORTURE_SAMR_MANY_ACCOUNTS
:
7496 torture_assert(tctx
,
7497 test_EnumDomainUsers(b
, tctx
, domain_handle
, &num_enum
),
7498 "failed to enum users");
7500 case TORTURE_SAMR_MANY_GROUPS
:
7501 torture_assert(tctx
,
7502 test_EnumDomainGroups(b
, tctx
, domain_handle
, &num_enum
),
7503 "failed to enum groups");
7505 case TORTURE_SAMR_MANY_ALIASES
:
7506 torture_assert(tctx
,
7507 test_EnumDomainAliases(b
, tctx
, domain_handle
, &num_enum
),
7508 "failed to enum aliases");
7516 switch (ctx
->choice
) {
7517 case TORTURE_SAMR_MANY_ACCOUNTS
:
7518 torture_assert(tctx
,
7519 test_QueryDisplayInfo_level(b
, tctx
, domain_handle
, 1, &num_disp
),
7520 "failed to query display info");
7522 case TORTURE_SAMR_MANY_GROUPS
:
7523 torture_assert(tctx
,
7524 test_QueryDisplayInfo_level(b
, tctx
, domain_handle
, 3, &num_disp
),
7525 "failed to query display info");
7527 case TORTURE_SAMR_MANY_ALIASES
:
7528 /* no aliases in dispinfo */
7534 /* close or delete */
7536 for (i
=0; i
< num_total
; i
++) {
7538 if (ndr_policy_handle_empty(&handles
[i
])) {
7542 if (torture_setting_bool(tctx
, "samba3", false)) {
7543 torture_assert(tctx
,
7544 test_samr_handle_Close(b
, tctx
, &handles
[i
]),
7545 "failed to close handle");
7547 switch (ctx
->choice
) {
7548 case TORTURE_SAMR_MANY_ACCOUNTS
:
7549 torture_assert(tctx
,
7550 test_DeleteUser(b
, tctx
, &handles
[i
]),
7551 "failed to delete user");
7553 case TORTURE_SAMR_MANY_GROUPS
:
7554 torture_assert(tctx
,
7555 test_DeleteDomainGroup(b
, tctx
, &handles
[i
]),
7556 "failed to delete group");
7558 case TORTURE_SAMR_MANY_ALIASES
:
7559 torture_assert(tctx
,
7560 test_DeleteAlias(b
, tctx
, &handles
[i
]),
7561 "failed to delete alias");
7569 talloc_free(handles
);
7571 if (ctx
->choice
== TORTURE_SAMR_MANY_ACCOUNTS
&& num_enum
!= num_anounced
+ num_created
) {
7572 torture_comment(tctx
,
7573 "unexpected number of results (%u) returned in enum call, expected %u\n",
7574 num_enum
, num_anounced
+ num_created
);
7576 torture_comment(tctx
,
7577 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
7578 num_disp
, num_anounced
+ num_created
);
7584 static bool test_Connect(struct dcerpc_binding_handle
*b
,
7585 struct torture_context
*tctx
,
7586 struct policy_handle
*handle
);
7588 static bool test_OpenDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7589 struct torture_samr_context
*ctx
, struct dom_sid
*sid
)
7591 struct samr_OpenDomain r
;
7592 struct policy_handle domain_handle
;
7593 struct policy_handle alias_handle
;
7594 struct policy_handle user_handle
;
7595 struct policy_handle group_handle
;
7597 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7599 ZERO_STRUCT(alias_handle
);
7600 ZERO_STRUCT(user_handle
);
7601 ZERO_STRUCT(group_handle
);
7602 ZERO_STRUCT(domain_handle
);
7604 torture_comment(tctx
, "Testing OpenDomain of %s\n", dom_sid_string(tctx
, sid
));
7606 r
.in
.connect_handle
= &ctx
->handle
;
7607 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7609 r
.out
.domain_handle
= &domain_handle
;
7611 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenDomain_r(b
, tctx
, &r
),
7612 "OpenDomain failed");
7613 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "OpenDomain failed");
7615 /* run the domain tests with the main handle closed - this tests
7616 the servers reference counting */
7617 torture_assert(tctx
, test_samr_handle_Close(b
, tctx
, &ctx
->handle
), "Failed to close SAMR handle");
7619 switch (ctx
->choice
) {
7620 case TORTURE_SAMR_PASSWORDS
:
7621 case TORTURE_SAMR_USER_PRIVILEGES
:
7622 if (!torture_setting_bool(tctx
, "samba3", false)) {
7623 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, NULL
);
7625 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
7627 torture_warning(tctx
, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7630 case TORTURE_SAMR_USER_ATTRIBUTES
:
7631 if (!torture_setting_bool(tctx
, "samba3", false)) {
7632 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, NULL
);
7634 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
7635 /* This test needs 'complex' users to validate */
7636 ret
&= test_QueryDisplayInfo(b
, tctx
, &domain_handle
);
7638 torture_warning(tctx
, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7641 case TORTURE_SAMR_PASSWORDS_PWDLASTSET
:
7642 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
:
7643 case TORTURE_SAMR_PASSWORDS_LOCKOUT
:
7644 if (!torture_setting_bool(tctx
, "samba3", false)) {
7645 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, ctx
->machine_credentials
);
7647 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, ctx
->machine_credentials
, true);
7649 torture_warning(tctx
, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7652 case TORTURE_SAMR_MANY_ACCOUNTS
:
7653 case TORTURE_SAMR_MANY_GROUPS
:
7654 case TORTURE_SAMR_MANY_ALIASES
:
7655 ret
&= test_ManyObjects(p
, tctx
, &domain_handle
, sid
, ctx
);
7657 torture_warning(tctx
, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7660 case TORTURE_SAMR_OTHER
:
7661 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
7663 torture_warning(tctx
, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx
, sid
));
7665 if (!torture_setting_bool(tctx
, "samba3", false)) {
7666 ret
&= test_QuerySecurity(b
, tctx
, &domain_handle
);
7668 ret
&= test_RemoveMemberFromForeignDomain(b
, tctx
, &domain_handle
);
7669 ret
&= test_CreateAlias(b
, tctx
, &domain_handle
, TEST_ALIASNAME
, &alias_handle
, sid
, true);
7670 ret
&= test_CreateDomainGroup(b
, tctx
, &domain_handle
, TEST_GROUPNAME
, &group_handle
, sid
, true);
7671 ret
&= test_GetAliasMembership(b
, tctx
, &domain_handle
);
7672 ret
&= test_QueryDomainInfo(p
, tctx
, &domain_handle
);
7673 ret
&= test_QueryDomainInfo2(b
, tctx
, &domain_handle
);
7674 ret
&= test_EnumDomainUsers_all(b
, tctx
, &domain_handle
);
7675 ret
&= test_EnumDomainUsers_async(p
, tctx
, &domain_handle
);
7676 ret
&= test_EnumDomainGroups_all(b
, tctx
, &domain_handle
);
7677 ret
&= test_EnumDomainAliases_all(b
, tctx
, &domain_handle
);
7678 ret
&= test_QueryDisplayInfo2(b
, tctx
, &domain_handle
);
7679 ret
&= test_QueryDisplayInfo3(b
, tctx
, &domain_handle
);
7680 ret
&= test_QueryDisplayInfo_continue(b
, tctx
, &domain_handle
);
7682 if (torture_setting_bool(tctx
, "samba4", false)) {
7683 torture_comment(tctx
, "skipping GetDisplayEnumerationIndex test against Samba4\n");
7685 ret
&= test_GetDisplayEnumerationIndex(b
, tctx
, &domain_handle
);
7686 ret
&= test_GetDisplayEnumerationIndex2(b
, tctx
, &domain_handle
);
7688 ret
&= test_GroupList(b
, tctx
, sid
, &domain_handle
);
7689 ret
&= test_TestPrivateFunctionsDomain(b
, tctx
, &domain_handle
);
7690 ret
&= test_RidToSid(b
, tctx
, sid
, &domain_handle
);
7691 ret
&= test_GetBootKeyInformation(b
, tctx
, &domain_handle
);
7693 torture_comment(tctx
, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7698 if (!ndr_policy_handle_empty(&user_handle
) &&
7699 !test_DeleteUser(b
, tctx
, &user_handle
)) {
7703 if (!ndr_policy_handle_empty(&alias_handle
) &&
7704 !test_DeleteAlias(b
, tctx
, &alias_handle
)) {
7708 if (!ndr_policy_handle_empty(&group_handle
) &&
7709 !test_DeleteDomainGroup(b
, tctx
, &group_handle
)) {
7713 torture_assert(tctx
, test_samr_handle_Close(b
, tctx
, &domain_handle
), "Failed to close SAMR domain handle");
7715 torture_assert(tctx
, test_Connect(b
, tctx
, &ctx
->handle
), "Faile to re-connect SAMR handle");
7716 /* reconnect the main handle */
7719 torture_warning(tctx
, "Testing domain %s failed!\n", dom_sid_string(tctx
, sid
));
7725 static bool test_LookupDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7726 struct torture_samr_context
*ctx
, const char *domain
)
7728 struct samr_LookupDomain r
;
7729 struct dom_sid2
*sid
= NULL
;
7730 struct lsa_String n1
;
7731 struct lsa_String n2
;
7733 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7735 torture_comment(tctx
, "Testing LookupDomain(%s)\n", domain
);
7737 /* check for correct error codes */
7738 r
.in
.connect_handle
= &ctx
->handle
;
7739 r
.in
.domain_name
= &n2
;
7743 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupDomain_r(b
, tctx
, &r
),
7744 "LookupDomain failed");
7745 torture_assert_ntstatus_equal(tctx
, NT_STATUS_INVALID_PARAMETER
, r
.out
.result
, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
7747 init_lsa_String(&n2
, "xxNODOMAINxx");
7749 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupDomain_r(b
, tctx
, &r
),
7750 "LookupDomain failed");
7751 torture_assert_ntstatus_equal(tctx
, NT_STATUS_NO_SUCH_DOMAIN
, r
.out
.result
, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
7753 r
.in
.connect_handle
= &ctx
->handle
;
7755 init_lsa_String(&n1
, domain
);
7756 r
.in
.domain_name
= &n1
;
7758 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupDomain_r(b
, tctx
, &r
),
7759 "LookupDomain failed");
7760 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LookupDomain");
7762 if (!test_GetDomPwInfo(p
, tctx
, &n1
)) {
7766 if (!test_OpenDomain(p
, tctx
, ctx
, *r
.out
.sid
)) {
7774 static bool test_EnumDomains(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7775 struct torture_samr_context
*ctx
)
7777 struct samr_EnumDomains r
;
7778 uint32_t resume_handle
= 0;
7779 uint32_t num_entries
= 0;
7780 struct samr_SamArray
*sam
= NULL
;
7783 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7785 r
.in
.connect_handle
= &ctx
->handle
;
7786 r
.in
.resume_handle
= &resume_handle
;
7787 r
.in
.buf_size
= (uint32_t)-1;
7788 r
.out
.resume_handle
= &resume_handle
;
7789 r
.out
.num_entries
= &num_entries
;
7792 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomains_r(b
, tctx
, &r
),
7793 "EnumDomains failed");
7794 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "EnumDomains failed");
7800 for (i
=0;i
<sam
->count
;i
++) {
7801 if (!test_LookupDomain(p
, tctx
, ctx
,
7802 sam
->entries
[i
].name
.string
)) {
7807 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomains_r(b
, tctx
, &r
),
7808 "EnumDomains failed");
7809 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "EnumDomains failed");
7815 static bool test_Connect(struct dcerpc_binding_handle
*b
,
7816 struct torture_context
*tctx
,
7817 struct policy_handle
*handle
)
7819 struct samr_Connect r
;
7820 struct samr_Connect2 r2
;
7821 struct samr_Connect3 r3
;
7822 struct samr_Connect4 r4
;
7823 struct samr_Connect5 r5
;
7824 union samr_ConnectInfo info
;
7825 struct policy_handle h
;
7826 uint32_t level_out
= 0;
7827 bool ret
= true, got_handle
= false;
7829 torture_comment(tctx
, "Testing samr_Connect\n");
7831 r
.in
.system_name
= NULL
;
7832 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7833 r
.out
.connect_handle
= &h
;
7835 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect_r(b
, tctx
, &r
),
7837 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
7838 torture_comment(tctx
, "Connect failed - %s\n", nt_errstr(r
.out
.result
));
7845 torture_comment(tctx
, "Testing samr_Connect2\n");
7847 r2
.in
.system_name
= NULL
;
7848 r2
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7849 r2
.out
.connect_handle
= &h
;
7851 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect2_r(b
, tctx
, &r2
),
7853 if (!NT_STATUS_IS_OK(r2
.out
.result
)) {
7854 torture_comment(tctx
, "Connect2 failed - %s\n", nt_errstr(r2
.out
.result
));
7858 test_samr_handle_Close(b
, tctx
, handle
);
7864 torture_comment(tctx
, "Testing samr_Connect3\n");
7866 r3
.in
.system_name
= NULL
;
7868 r3
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7869 r3
.out
.connect_handle
= &h
;
7871 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect3_r(b
, tctx
, &r3
),
7873 if (!NT_STATUS_IS_OK(r3
.out
.result
)) {
7874 torture_warning(tctx
, "Connect3 failed - %s\n", nt_errstr(r3
.out
.result
));
7878 test_samr_handle_Close(b
, tctx
, handle
);
7884 torture_comment(tctx
, "Testing samr_Connect4\n");
7886 r4
.in
.system_name
= "";
7887 r4
.in
.client_version
= 0;
7888 r4
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7889 r4
.out
.connect_handle
= &h
;
7891 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect4_r(b
, tctx
, &r4
),
7893 if (!NT_STATUS_IS_OK(r4
.out
.result
)) {
7894 torture_warning(tctx
, "Connect4 failed - %s\n", nt_errstr(r4
.out
.result
));
7898 test_samr_handle_Close(b
, tctx
, handle
);
7904 torture_comment(tctx
, "Testing samr_Connect5\n");
7906 info
.info1
.client_version
= 0;
7907 info
.info1
.unknown2
= 0;
7909 r5
.in
.system_name
= "";
7910 r5
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7912 r5
.out
.level_out
= &level_out
;
7913 r5
.in
.info_in
= &info
;
7914 r5
.out
.info_out
= &info
;
7915 r5
.out
.connect_handle
= &h
;
7917 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect5_r(b
, tctx
, &r5
),
7919 if (!NT_STATUS_IS_OK(r5
.out
.result
)) {
7920 torture_warning(tctx
, "Connect5 failed - %s\n", nt_errstr(r5
.out
.result
));
7924 test_samr_handle_Close(b
, tctx
, handle
);
7934 static bool test_samr_ValidatePassword(struct dcerpc_pipe
*p
,
7935 struct torture_context
*tctx
)
7937 struct samr_ValidatePassword r
;
7938 union samr_ValidatePasswordReq req
;
7939 union samr_ValidatePasswordRep
*repp
= NULL
;
7941 const char *passwords
[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL
};
7943 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7945 torture_comment(tctx
, "Testing samr_ValidatePassword\n");
7948 r
.in
.level
= NetValidatePasswordReset
;
7953 req
.req3
.account
.string
= "non-existent-account-aklsdji";
7955 for (i
=0; passwords
[i
]; i
++) {
7956 req
.req3
.password
.string
= passwords
[i
];
7958 status
= dcerpc_samr_ValidatePassword_r(b
, tctx
, &r
);
7959 if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE
)) {
7960 torture_skip(tctx
, "ValidatePassword not supported by server\n");
7962 torture_assert_ntstatus_ok(tctx
, status
,
7963 "samr_ValidatePassword failed");
7964 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
7965 "samr_ValidatePassword failed");
7966 torture_comment(tctx
, "Server %s password '%s' with code %i\n",
7967 repp
->ctr3
.status
==SAMR_VALIDATION_STATUS_SUCCESS
?"allowed":"refused",
7968 req
.req3
.password
.string
, repp
->ctr3
.status
);
7974 bool torture_rpc_samr(struct torture_context
*torture
)
7977 struct dcerpc_pipe
*p
;
7979 struct torture_samr_context
*ctx
;
7980 struct dcerpc_binding_handle
*b
;
7982 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7983 if (!NT_STATUS_IS_OK(status
)) {
7986 b
= p
->binding_handle
;
7988 ctx
= talloc_zero(torture
, struct torture_samr_context
);
7990 ctx
->choice
= TORTURE_SAMR_OTHER
;
7992 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
7994 if (!torture_setting_bool(torture
, "samba3", false)) {
7995 ret
&= test_QuerySecurity(b
, torture
, &ctx
->handle
);
7998 ret
&= test_EnumDomains(p
, torture
, ctx
);
8000 ret
&= test_SetDsrmPassword(b
, torture
, &ctx
->handle
);
8002 ret
&= test_Shutdown(b
, torture
, &ctx
->handle
);
8004 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8010 bool torture_rpc_samr_users(struct torture_context
*torture
)
8013 struct dcerpc_pipe
*p
;
8015 struct torture_samr_context
*ctx
;
8016 struct dcerpc_binding_handle
*b
;
8018 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8019 if (!NT_STATUS_IS_OK(status
)) {
8022 b
= p
->binding_handle
;
8024 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8026 ctx
->choice
= TORTURE_SAMR_USER_ATTRIBUTES
;
8028 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8030 if (!torture_setting_bool(torture
, "samba3", false)) {
8031 ret
&= test_QuerySecurity(b
, torture
, &ctx
->handle
);
8034 ret
&= test_EnumDomains(p
, torture
, ctx
);
8036 ret
&= test_SetDsrmPassword(b
, torture
, &ctx
->handle
);
8038 ret
&= test_Shutdown(b
, torture
, &ctx
->handle
);
8040 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8046 bool torture_rpc_samr_passwords(struct torture_context
*torture
)
8049 struct dcerpc_pipe
*p
;
8051 struct torture_samr_context
*ctx
;
8052 struct dcerpc_binding_handle
*b
;
8054 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8055 if (!NT_STATUS_IS_OK(status
)) {
8058 b
= p
->binding_handle
;
8060 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8062 ctx
->choice
= TORTURE_SAMR_PASSWORDS
;
8064 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8066 ret
&= test_EnumDomains(p
, torture
, ctx
);
8068 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8070 ret
&= test_samr_ValidatePassword(p
, torture
);
8075 static bool torture_rpc_samr_pwdlastset(struct torture_context
*torture
,
8076 struct dcerpc_pipe
*p2
,
8077 struct cli_credentials
*machine_credentials
)
8080 struct dcerpc_pipe
*p
;
8082 struct torture_samr_context
*ctx
;
8083 struct dcerpc_binding_handle
*b
;
8085 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8086 if (!NT_STATUS_IS_OK(status
)) {
8089 b
= p
->binding_handle
;
8091 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8093 ctx
->choice
= TORTURE_SAMR_PASSWORDS_PWDLASTSET
;
8094 ctx
->machine_credentials
= machine_credentials
;
8096 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8098 ret
&= test_EnumDomains(p
, torture
, ctx
);
8100 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8105 struct torture_suite
*torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX
*mem_ctx
)
8107 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.passwords.pwdlastset");
8108 struct torture_rpc_tcase
*tcase
;
8110 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
8112 TEST_ACCOUNT_NAME_PWD
);
8114 torture_rpc_tcase_add_test_creds(tcase
, "pwdLastSet",
8115 torture_rpc_samr_pwdlastset
);
8120 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context
*torture
,
8121 struct dcerpc_pipe
*p2
,
8122 struct cli_credentials
*machine_credentials
)
8125 struct dcerpc_pipe
*p
;
8127 struct torture_samr_context
*ctx
;
8128 struct dcerpc_binding_handle
*b
;
8130 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8131 if (!NT_STATUS_IS_OK(status
)) {
8134 b
= p
->binding_handle
;
8136 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8138 ctx
->choice
= TORTURE_SAMR_USER_PRIVILEGES
;
8139 ctx
->machine_credentials
= machine_credentials
;
8141 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8143 ret
&= test_EnumDomains(p
, torture
, ctx
);
8145 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8150 struct torture_suite
*torture_rpc_samr_user_privileges(TALLOC_CTX
*mem_ctx
)
8152 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.users.privileges");
8153 struct torture_rpc_tcase
*tcase
;
8155 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
8157 TEST_ACCOUNT_NAME_PWD
);
8159 torture_rpc_tcase_add_test_creds(tcase
, "delete_privileged_user",
8160 torture_rpc_samr_users_privileges_delete_user
);
8165 static bool torture_rpc_samr_many_accounts(struct torture_context
*torture
,
8166 struct dcerpc_pipe
*p2
,
8170 struct dcerpc_pipe
*p
;
8172 struct torture_samr_context
*ctx
=
8173 talloc_get_type_abort(data
, struct torture_samr_context
);
8174 struct dcerpc_binding_handle
*b
;
8176 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8177 if (!NT_STATUS_IS_OK(status
)) {
8180 b
= p
->binding_handle
;
8182 ctx
->choice
= TORTURE_SAMR_MANY_ACCOUNTS
;
8183 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
8184 ctx
->num_objects_large_dc
);
8186 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8188 ret
&= test_EnumDomains(p
, torture
, ctx
);
8190 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8195 static bool torture_rpc_samr_many_groups(struct torture_context
*torture
,
8196 struct dcerpc_pipe
*p2
,
8200 struct dcerpc_pipe
*p
;
8202 struct torture_samr_context
*ctx
=
8203 talloc_get_type_abort(data
, struct torture_samr_context
);
8204 struct dcerpc_binding_handle
*b
;
8206 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8207 if (!NT_STATUS_IS_OK(status
)) {
8210 b
= p
->binding_handle
;
8212 ctx
->choice
= TORTURE_SAMR_MANY_GROUPS
;
8213 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
8214 ctx
->num_objects_large_dc
);
8216 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8218 ret
&= test_EnumDomains(p
, torture
, ctx
);
8220 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8225 static bool torture_rpc_samr_many_aliases(struct torture_context
*torture
,
8226 struct dcerpc_pipe
*p2
,
8230 struct dcerpc_pipe
*p
;
8232 struct torture_samr_context
*ctx
=
8233 talloc_get_type_abort(data
, struct torture_samr_context
);
8234 struct dcerpc_binding_handle
*b
;
8236 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8237 if (!NT_STATUS_IS_OK(status
)) {
8240 b
= p
->binding_handle
;
8242 ctx
->choice
= TORTURE_SAMR_MANY_ALIASES
;
8243 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
8244 ctx
->num_objects_large_dc
);
8246 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8248 ret
&= test_EnumDomains(p
, torture
, ctx
);
8250 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8255 struct torture_suite
*torture_rpc_samr_large_dc(TALLOC_CTX
*mem_ctx
)
8257 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.large-dc");
8258 struct torture_rpc_tcase
*tcase
;
8259 struct torture_samr_context
*ctx
;
8261 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "samr", &ndr_table_samr
);
8263 ctx
= talloc_zero(suite
, struct torture_samr_context
);
8264 ctx
->num_objects_large_dc
= 150;
8266 torture_rpc_tcase_add_test_ex(tcase
, "many_aliases",
8267 torture_rpc_samr_many_aliases
, ctx
);
8268 torture_rpc_tcase_add_test_ex(tcase
, "many_groups",
8269 torture_rpc_samr_many_groups
, ctx
);
8270 torture_rpc_tcase_add_test_ex(tcase
, "many_accounts",
8271 torture_rpc_samr_many_accounts
, ctx
);
8276 static bool torture_rpc_samr_badpwdcount(struct torture_context
*torture
,
8277 struct dcerpc_pipe
*p2
,
8278 struct cli_credentials
*machine_credentials
)
8281 struct dcerpc_pipe
*p
;
8283 struct torture_samr_context
*ctx
;
8284 struct dcerpc_binding_handle
*b
;
8286 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8287 if (!NT_STATUS_IS_OK(status
)) {
8290 b
= p
->binding_handle
;
8292 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8294 ctx
->choice
= TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
;
8295 ctx
->machine_credentials
= machine_credentials
;
8297 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8299 ret
&= test_EnumDomains(p
, torture
, ctx
);
8301 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8306 struct torture_suite
*torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX
*mem_ctx
)
8308 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.passwords.badpwdcount");
8309 struct torture_rpc_tcase
*tcase
;
8311 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
8313 TEST_ACCOUNT_NAME_PWD
);
8315 torture_rpc_tcase_add_test_creds(tcase
, "badPwdCount",
8316 torture_rpc_samr_badpwdcount
);
8321 static bool torture_rpc_samr_lockout(struct torture_context
*torture
,
8322 struct dcerpc_pipe
*p2
,
8323 struct cli_credentials
*machine_credentials
)
8326 struct dcerpc_pipe
*p
;
8328 struct torture_samr_context
*ctx
;
8329 struct dcerpc_binding_handle
*b
;
8331 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8332 if (!NT_STATUS_IS_OK(status
)) {
8335 b
= p
->binding_handle
;
8337 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8339 ctx
->choice
= TORTURE_SAMR_PASSWORDS_LOCKOUT
;
8340 ctx
->machine_credentials
= machine_credentials
;
8342 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8344 ret
&= test_EnumDomains(p
, torture
, ctx
);
8346 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8351 struct torture_suite
*torture_rpc_samr_passwords_lockout(TALLOC_CTX
*mem_ctx
)
8353 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.passwords.lockout");
8354 struct torture_rpc_tcase
*tcase
;
8356 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
8358 TEST_ACCOUNT_NAME_PWD
);
8360 torture_rpc_tcase_add_test_creds(tcase
, "lockout",
8361 torture_rpc_samr_lockout
);