2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7 Copyright (C) Guenther Deschner 2008-2010
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "torture/torture.h"
26 #include "system/time.h"
27 #include "librpc/gen_ndr/lsa.h"
28 #include "librpc/gen_ndr/ndr_netlogon.h"
29 #include "librpc/gen_ndr/ndr_netlogon_c.h"
30 #include "librpc/gen_ndr/ndr_samr_c.h"
31 #include "librpc/gen_ndr/ndr_lsa_c.h"
32 #include "../lib/crypto/crypto.h"
33 #include "libcli/auth/libcli_auth.h"
34 #include "libcli/security/security.h"
35 #include "torture/rpc/rpc.h"
36 #include "param/param.h"
37 #include "auth/gensec/gensec.h"
38 #include "auth/gensec/gensec_proto.h"
39 #include "../libcli/auth/schannel.h"
43 #define TEST_ACCOUNT_NAME "samrtorturetest"
44 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
45 #define TEST_ALIASNAME "samrtorturetestalias"
46 #define TEST_GROUPNAME "samrtorturetestgroup"
47 #define TEST_MACHINENAME "samrtestmach$"
48 #define TEST_DOMAINNAME "samrtestdom$"
50 enum torture_samr_choice
{
51 TORTURE_SAMR_PASSWORDS
,
52 TORTURE_SAMR_PASSWORDS_PWDLASTSET
,
53 TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
,
54 TORTURE_SAMR_PASSWORDS_LOCKOUT
,
55 TORTURE_SAMR_USER_ATTRIBUTES
,
56 TORTURE_SAMR_USER_PRIVILEGES
,
58 TORTURE_SAMR_MANY_ACCOUNTS
,
59 TORTURE_SAMR_MANY_GROUPS
,
60 TORTURE_SAMR_MANY_ALIASES
63 struct torture_samr_context
{
64 struct policy_handle handle
;
65 struct cli_credentials
*machine_credentials
;
66 enum torture_samr_choice choice
;
67 uint32_t num_objects_large_dc
;
70 static bool test_QueryUserInfo(struct dcerpc_binding_handle
*b
,
71 struct torture_context
*tctx
,
72 struct policy_handle
*handle
);
74 static bool test_QueryUserInfo2(struct dcerpc_binding_handle
*b
,
75 struct torture_context
*tctx
,
76 struct policy_handle
*handle
);
78 static bool test_QueryAliasInfo(struct dcerpc_binding_handle
*b
,
79 struct torture_context
*tctx
,
80 struct policy_handle
*handle
);
82 static bool test_ChangePassword(struct dcerpc_pipe
*p
,
83 struct torture_context
*tctx
,
84 const char *acct_name
,
85 struct policy_handle
*domain_handle
, char **password
);
87 static void init_lsa_String(struct lsa_String
*string
, const char *s
)
92 static void init_lsa_StringLarge(struct lsa_StringLarge
*string
, const char *s
)
97 static void init_lsa_BinaryString(struct lsa_BinaryString
*string
, const char *s
, uint32_t length
)
99 string
->length
= length
;
100 string
->size
= length
;
101 string
->array
= (uint16_t *)discard_const(s
);
104 bool test_samr_handle_Close(struct dcerpc_binding_handle
*b
,
105 struct torture_context
*tctx
,
106 struct policy_handle
*handle
)
111 r
.in
.handle
= handle
;
112 r
.out
.handle
= handle
;
114 status
= dcerpc_samr_Close_r(b
, tctx
, &r
);
115 torture_assert_ntstatus_ok(tctx
, status
, "Close");
120 static bool test_Shutdown(struct dcerpc_binding_handle
*b
,
121 struct torture_context
*tctx
,
122 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 status
= dcerpc_samr_Shutdown_r(b
, tctx
, &r
);
137 torture_assert_ntstatus_ok(tctx
, status
, "samr_Shutdown");
142 static bool test_SetDsrmPassword(struct dcerpc_binding_handle
*b
,
143 struct torture_context
*tctx
,
144 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 status
= dcerpc_samr_SetDsrmPassword_r(b
, tctx
, &r
);
166 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_NOT_SUPPORTED
, "samr_SetDsrmPassword");
172 static bool test_QuerySecurity(struct dcerpc_binding_handle
*b
,
173 struct torture_context
*tctx
,
174 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 status
= dcerpc_samr_QuerySecurity_r(b
, tctx
, &r
);
186 torture_assert_ntstatus_ok(tctx
, status
, "QuerySecurity");
188 torture_assert(tctx
, sdbuf
!= NULL
, "sdbuf is NULL");
190 s
.in
.handle
= handle
;
194 if (torture_setting_bool(tctx
, "samba4", false)) {
195 torture_skip(tctx
, "skipping SetSecurity test against Samba4\n");
198 status
= dcerpc_samr_SetSecurity_r(b
, tctx
, &s
);
199 torture_assert_ntstatus_ok(tctx
, status
, "SetSecurity");
201 status
= dcerpc_samr_QuerySecurity_r(b
, tctx
, &r
);
202 torture_assert_ntstatus_ok(tctx
, status
, "QuerySecurity");
208 static bool test_SetUserInfo(struct dcerpc_binding_handle
*b
, struct torture_context
*tctx
,
209 struct policy_handle
*handle
, uint32_t base_acct_flags
,
210 const char *base_account_name
)
213 struct samr_SetUserInfo s
;
214 struct samr_SetUserInfo2 s2
;
215 struct samr_QueryUserInfo q
;
216 struct samr_QueryUserInfo q0
;
217 union samr_UserInfo u
;
218 union samr_UserInfo
*info
;
220 const char *test_account_name
;
222 uint32_t user_extra_flags
= 0;
224 if (!torture_setting_bool(tctx
, "samba3", false)) {
225 if (base_acct_flags
== ACB_NORMAL
) {
226 /* When created, accounts are expired by default */
227 user_extra_flags
= ACB_PW_EXPIRED
;
231 s
.in
.user_handle
= handle
;
234 s2
.in
.user_handle
= handle
;
237 q
.in
.user_handle
= handle
;
241 #define TESTCALL(call, r) \
242 status = dcerpc_samr_ ##call## _r(b, tctx, &r); \
243 if (!NT_STATUS_IS_OK(status)) { \
244 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
245 r.in.level, nt_errstr(status), __location__); \
250 #define STRING_EQUAL(s1, s2, field) \
251 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
252 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
253 #field, s2, __location__); \
258 #define MEM_EQUAL(s1, s2, length, field) \
259 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
260 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
261 #field, (const char *)s2, __location__); \
266 #define INT_EQUAL(i1, i2, field) \
268 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
269 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
274 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
275 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
277 TESTCALL(QueryUserInfo, q) \
279 s2.in.level = lvl1; \
282 ZERO_STRUCT(u.info21); \
283 u.info21.fields_present = fpval; \
285 init_lsa_String(&u.info ## lvl1.field1, value); \
286 TESTCALL(SetUserInfo, s) \
287 TESTCALL(SetUserInfo2, s2) \
288 init_lsa_String(&u.info ## lvl1.field1, ""); \
289 TESTCALL(QueryUserInfo, q); \
291 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
293 TESTCALL(QueryUserInfo, q) \
295 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
298 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
299 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
301 TESTCALL(QueryUserInfo, q) \
303 s2.in.level = lvl1; \
306 ZERO_STRUCT(u.info21); \
307 u.info21.fields_present = fpval; \
309 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
310 TESTCALL(SetUserInfo, s) \
311 TESTCALL(SetUserInfo2, s2) \
312 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
313 TESTCALL(QueryUserInfo, q); \
315 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
317 TESTCALL(QueryUserInfo, q) \
319 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
322 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
323 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
325 TESTCALL(QueryUserInfo, q) \
327 s2.in.level = lvl1; \
330 uint8_t *bits = u.info21.logon_hours.bits; \
331 ZERO_STRUCT(u.info21); \
332 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
333 u.info21.logon_hours.units_per_week = 168; \
334 u.info21.logon_hours.bits = bits; \
336 u.info21.fields_present = fpval; \
338 u.info ## lvl1.field1 = value; \
339 TESTCALL(SetUserInfo, s) \
340 TESTCALL(SetUserInfo2, s2) \
341 u.info ## lvl1.field1 = 0; \
342 TESTCALL(QueryUserInfo, q); \
344 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
346 TESTCALL(QueryUserInfo, q) \
348 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
351 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
352 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
356 do { TESTCALL(QueryUserInfo
, q0
) } while (0);
358 TEST_USERINFO_STRING(2, comment
, 1, comment
, "xx2-1 comment", 0);
359 TEST_USERINFO_STRING(2, comment
, 21, comment
, "xx2-21 comment", 0);
360 TEST_USERINFO_STRING(21, comment
, 21, comment
, "xx21-21 comment",
363 test_account_name
= talloc_asprintf(tctx
, "%sxx7-1", base_account_name
);
364 TEST_USERINFO_STRING(7, account_name
, 1, account_name
, base_account_name
, 0);
365 test_account_name
= talloc_asprintf(tctx
, "%sxx7-3", base_account_name
);
366 TEST_USERINFO_STRING(7, account_name
, 3, account_name
, base_account_name
, 0);
367 test_account_name
= talloc_asprintf(tctx
, "%sxx7-5", base_account_name
);
368 TEST_USERINFO_STRING(7, account_name
, 5, account_name
, base_account_name
, 0);
369 test_account_name
= talloc_asprintf(tctx
, "%sxx7-6", base_account_name
);
370 TEST_USERINFO_STRING(7, account_name
, 6, account_name
, base_account_name
, 0);
371 test_account_name
= talloc_asprintf(tctx
, "%sxx7-7", base_account_name
);
372 TEST_USERINFO_STRING(7, account_name
, 7, account_name
, base_account_name
, 0);
373 test_account_name
= talloc_asprintf(tctx
, "%sxx7-21", base_account_name
);
374 TEST_USERINFO_STRING(7, account_name
, 21, account_name
, base_account_name
, 0);
375 test_account_name
= base_account_name
;
376 TEST_USERINFO_STRING(21, account_name
, 21, account_name
, base_account_name
,
377 SAMR_FIELD_ACCOUNT_NAME
);
379 TEST_USERINFO_STRING(6, full_name
, 1, full_name
, "xx6-1 full_name", 0);
380 TEST_USERINFO_STRING(6, full_name
, 3, full_name
, "xx6-3 full_name", 0);
381 TEST_USERINFO_STRING(6, full_name
, 5, full_name
, "xx6-5 full_name", 0);
382 TEST_USERINFO_STRING(6, full_name
, 6, full_name
, "xx6-6 full_name", 0);
383 TEST_USERINFO_STRING(6, full_name
, 8, full_name
, "xx6-8 full_name", 0);
384 TEST_USERINFO_STRING(6, full_name
, 21, full_name
, "xx6-21 full_name", 0);
385 TEST_USERINFO_STRING(8, full_name
, 21, full_name
, "xx8-21 full_name", 0);
386 TEST_USERINFO_STRING(21, full_name
, 21, full_name
, "xx21-21 full_name",
387 SAMR_FIELD_FULL_NAME
);
389 TEST_USERINFO_STRING(6, full_name
, 1, full_name
, "", 0);
390 TEST_USERINFO_STRING(6, full_name
, 3, full_name
, "", 0);
391 TEST_USERINFO_STRING(6, full_name
, 5, full_name
, "", 0);
392 TEST_USERINFO_STRING(6, full_name
, 6, full_name
, "", 0);
393 TEST_USERINFO_STRING(6, full_name
, 8, full_name
, "", 0);
394 TEST_USERINFO_STRING(6, full_name
, 21, full_name
, "", 0);
395 TEST_USERINFO_STRING(8, full_name
, 21, full_name
, "", 0);
396 TEST_USERINFO_STRING(21, full_name
, 21, full_name
, "",
397 SAMR_FIELD_FULL_NAME
);
399 TEST_USERINFO_STRING(11, logon_script
, 3, logon_script
, "xx11-3 logon_script", 0);
400 TEST_USERINFO_STRING(11, logon_script
, 5, logon_script
, "xx11-5 logon_script", 0);
401 TEST_USERINFO_STRING(11, logon_script
, 21, logon_script
, "xx11-21 logon_script", 0);
402 TEST_USERINFO_STRING(21, logon_script
, 21, logon_script
, "xx21-21 logon_script",
403 SAMR_FIELD_LOGON_SCRIPT
);
405 TEST_USERINFO_STRING(12, profile_path
, 3, profile_path
, "xx12-3 profile_path", 0);
406 TEST_USERINFO_STRING(12, profile_path
, 5, profile_path
, "xx12-5 profile_path", 0);
407 TEST_USERINFO_STRING(12, profile_path
, 21, profile_path
, "xx12-21 profile_path", 0);
408 TEST_USERINFO_STRING(21, profile_path
, 21, profile_path
, "xx21-21 profile_path",
409 SAMR_FIELD_PROFILE_PATH
);
411 TEST_USERINFO_STRING(10, home_directory
, 3, home_directory
, "xx10-3 home_directory", 0);
412 TEST_USERINFO_STRING(10, home_directory
, 5, home_directory
, "xx10-5 home_directory", 0);
413 TEST_USERINFO_STRING(10, home_directory
, 21, home_directory
, "xx10-21 home_directory", 0);
414 TEST_USERINFO_STRING(21, home_directory
, 21, home_directory
, "xx21-21 home_directory",
415 SAMR_FIELD_HOME_DIRECTORY
);
416 TEST_USERINFO_STRING(21, home_directory
, 10, home_directory
, "xx21-10 home_directory",
417 SAMR_FIELD_HOME_DIRECTORY
);
419 TEST_USERINFO_STRING(10, home_drive
, 3, home_drive
, "xx10-3 home_drive", 0);
420 TEST_USERINFO_STRING(10, home_drive
, 5, home_drive
, "xx10-5 home_drive", 0);
421 TEST_USERINFO_STRING(10, home_drive
, 21, home_drive
, "xx10-21 home_drive", 0);
422 TEST_USERINFO_STRING(21, home_drive
, 21, home_drive
, "xx21-21 home_drive",
423 SAMR_FIELD_HOME_DRIVE
);
424 TEST_USERINFO_STRING(21, home_drive
, 10, home_drive
, "xx21-10 home_drive",
425 SAMR_FIELD_HOME_DRIVE
);
427 TEST_USERINFO_STRING(13, description
, 1, description
, "xx13-1 description", 0);
428 TEST_USERINFO_STRING(13, description
, 5, description
, "xx13-5 description", 0);
429 TEST_USERINFO_STRING(13, description
, 21, description
, "xx13-21 description", 0);
430 TEST_USERINFO_STRING(21, description
, 21, description
, "xx21-21 description",
431 SAMR_FIELD_DESCRIPTION
);
433 TEST_USERINFO_STRING(14, workstations
, 3, workstations
, "14workstation3", 0);
434 TEST_USERINFO_STRING(14, workstations
, 5, workstations
, "14workstation4", 0);
435 TEST_USERINFO_STRING(14, workstations
, 21, workstations
, "14workstation21", 0);
436 TEST_USERINFO_STRING(21, workstations
, 21, workstations
, "21workstation21",
437 SAMR_FIELD_WORKSTATIONS
);
438 TEST_USERINFO_STRING(21, workstations
, 3, workstations
, "21workstation3",
439 SAMR_FIELD_WORKSTATIONS
);
440 TEST_USERINFO_STRING(21, workstations
, 5, workstations
, "21workstation5",
441 SAMR_FIELD_WORKSTATIONS
);
442 TEST_USERINFO_STRING(21, workstations
, 14, workstations
, "21workstation14",
443 SAMR_FIELD_WORKSTATIONS
);
445 TEST_USERINFO_BINARYSTRING(20, parameters
, 21, parameters
, "xx20-21 parameters", 0);
446 TEST_USERINFO_BINARYSTRING(21, parameters
, 21, parameters
, "xx21-21 parameters",
447 SAMR_FIELD_PARAMETERS
);
448 TEST_USERINFO_BINARYSTRING(21, parameters
, 20, parameters
, "xx21-20 parameters",
449 SAMR_FIELD_PARAMETERS
);
450 /* also empty user parameters are allowed */
451 TEST_USERINFO_BINARYSTRING(20, parameters
, 21, parameters
, "", 0);
452 TEST_USERINFO_BINARYSTRING(21, parameters
, 21, parameters
, "",
453 SAMR_FIELD_PARAMETERS
);
454 TEST_USERINFO_BINARYSTRING(21, parameters
, 20, parameters
, "",
455 SAMR_FIELD_PARAMETERS
);
457 /* Samba 3 cannot store country_code and copy_page atm. - gd */
458 if (!torture_setting_bool(tctx
, "samba3", false)) {
459 TEST_USERINFO_INT(2, country_code
, 2, country_code
, __LINE__
, 0);
460 TEST_USERINFO_INT(2, country_code
, 21, country_code
, __LINE__
, 0);
461 TEST_USERINFO_INT(21, country_code
, 21, country_code
, __LINE__
,
462 SAMR_FIELD_COUNTRY_CODE
);
463 TEST_USERINFO_INT(21, country_code
, 2, country_code
, __LINE__
,
464 SAMR_FIELD_COUNTRY_CODE
);
466 TEST_USERINFO_INT(2, code_page
, 21, code_page
, __LINE__
, 0);
467 TEST_USERINFO_INT(21, code_page
, 21, code_page
, __LINE__
,
468 SAMR_FIELD_CODE_PAGE
);
469 TEST_USERINFO_INT(21, code_page
, 2, code_page
, __LINE__
,
470 SAMR_FIELD_CODE_PAGE
);
473 if (!torture_setting_bool(tctx
, "samba3", false)) {
474 TEST_USERINFO_INT(17, acct_expiry
, 21, acct_expiry
, __LINE__
, 0);
475 TEST_USERINFO_INT(17, acct_expiry
, 5, acct_expiry
, __LINE__
, 0);
476 TEST_USERINFO_INT(21, acct_expiry
, 21, acct_expiry
, __LINE__
,
477 SAMR_FIELD_ACCT_EXPIRY
);
478 TEST_USERINFO_INT(21, acct_expiry
, 5, acct_expiry
, __LINE__
,
479 SAMR_FIELD_ACCT_EXPIRY
);
480 TEST_USERINFO_INT(21, acct_expiry
, 17, acct_expiry
, __LINE__
,
481 SAMR_FIELD_ACCT_EXPIRY
);
483 /* Samba 3 can only store seconds / time_t in passdb - gd */
485 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
486 TEST_USERINFO_INT(17, acct_expiry
, 21, acct_expiry
, nt
, 0);
487 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
488 TEST_USERINFO_INT(17, acct_expiry
, 5, acct_expiry
, nt
, 0);
489 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
490 TEST_USERINFO_INT(21, acct_expiry
, 21, acct_expiry
, nt
, SAMR_FIELD_ACCT_EXPIRY
);
491 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
492 TEST_USERINFO_INT(21, acct_expiry
, 5, acct_expiry
, nt
, SAMR_FIELD_ACCT_EXPIRY
);
493 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
494 TEST_USERINFO_INT(21, acct_expiry
, 17, acct_expiry
, nt
, SAMR_FIELD_ACCT_EXPIRY
);
497 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 3, logon_hours
.bits
[3], 1, 0);
498 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 5, logon_hours
.bits
[3], 2, 0);
499 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 21, logon_hours
.bits
[3], 3, 0);
500 TEST_USERINFO_INT(21, logon_hours
.bits
[3], 21, logon_hours
.bits
[3], 4,
501 SAMR_FIELD_LOGON_HOURS
);
503 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
504 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
),
505 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
| user_extra_flags
),
507 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
508 (base_acct_flags
| ACB_DISABLED
),
509 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
512 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
513 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
514 (base_acct_flags
| ACB_DISABLED
| ACB_PWNOEXP
),
515 (base_acct_flags
| ACB_DISABLED
| ACB_PWNOEXP
),
517 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
518 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
),
519 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
| user_extra_flags
),
523 /* The 'autolock' flag doesn't stick - check this */
524 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
525 (base_acct_flags
| ACB_DISABLED
| ACB_AUTOLOCK
),
526 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
529 /* Removing the 'disabled' flag doesn't stick - check this */
530 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
532 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
536 /* Samba3 cannot store these atm */
537 if (!torture_setting_bool(tctx
, "samba3", false)) {
538 /* The 'store plaintext' flag does stick */
539 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
540 (base_acct_flags
| ACB_DISABLED
| ACB_ENC_TXT_PWD_ALLOWED
),
541 (base_acct_flags
| ACB_DISABLED
| ACB_ENC_TXT_PWD_ALLOWED
| user_extra_flags
),
543 /* The 'use DES' flag does stick */
544 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
545 (base_acct_flags
| ACB_DISABLED
| ACB_USE_DES_KEY_ONLY
),
546 (base_acct_flags
| ACB_DISABLED
| ACB_USE_DES_KEY_ONLY
| user_extra_flags
),
548 /* The 'don't require kerberos pre-authentication flag does stick */
549 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
550 (base_acct_flags
| ACB_DISABLED
| ACB_DONT_REQUIRE_PREAUTH
),
551 (base_acct_flags
| ACB_DISABLED
| ACB_DONT_REQUIRE_PREAUTH
| user_extra_flags
),
553 /* The 'no kerberos PAC required' flag sticks */
554 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
555 (base_acct_flags
| ACB_DISABLED
| ACB_NO_AUTH_DATA_REQD
),
556 (base_acct_flags
| ACB_DISABLED
| ACB_NO_AUTH_DATA_REQD
| user_extra_flags
),
559 TEST_USERINFO_INT_EXP(21, acct_flags
, 21, acct_flags
,
560 (base_acct_flags
| ACB_DISABLED
),
561 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
562 SAMR_FIELD_ACCT_FLAGS
);
565 /* these fail with win2003 - it appears you can't set the primary gid?
566 the set succeeds, but the gid isn't changed. Very weird! */
567 TEST_USERINFO_INT(9, primary_gid
, 1, primary_gid
, 513);
568 TEST_USERINFO_INT(9, primary_gid
, 3, primary_gid
, 513);
569 TEST_USERINFO_INT(9, primary_gid
, 5, primary_gid
, 513);
570 TEST_USERINFO_INT(9, primary_gid
, 21, primary_gid
, 513);
577 generate a random password for password change tests
579 static char *samr_rand_pass_silent(TALLOC_CTX
*mem_ctx
, int min_len
)
581 size_t len
= MAX(8, min_len
);
582 char *s
= generate_random_password(mem_ctx
, len
, len
+6);
586 static char *samr_rand_pass(TALLOC_CTX
*mem_ctx
, int min_len
)
588 char *s
= samr_rand_pass_silent(mem_ctx
, min_len
);
589 printf("Generated password '%s'\n", s
);
595 generate a random password for password change tests
597 static DATA_BLOB
samr_very_rand_pass(TALLOC_CTX
*mem_ctx
, int len
)
600 DATA_BLOB password
= data_blob_talloc(mem_ctx
, NULL
, len
* 2 /* number of unicode chars */);
601 generate_random_buffer(password
.data
, password
.length
);
603 for (i
=0; i
< len
; i
++) {
604 if (((uint16_t *)password
.data
)[i
] == 0) {
605 ((uint16_t *)password
.data
)[i
] = 1;
613 generate a random password for password change tests (fixed length)
615 static char *samr_rand_pass_fixed_len(TALLOC_CTX
*mem_ctx
, int len
)
617 char *s
= generate_random_password(mem_ctx
, len
, len
);
618 printf("Generated password '%s'\n", s
);
622 static bool test_SetUserPass(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
623 struct policy_handle
*handle
, char **password
)
626 struct samr_SetUserInfo s
;
627 union samr_UserInfo u
;
629 DATA_BLOB session_key
;
631 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
632 struct samr_GetUserPwInfo pwp
;
633 struct samr_PwInfo info
;
634 int policy_min_pw_len
= 0;
635 pwp
.in
.user_handle
= handle
;
636 pwp
.out
.info
= &info
;
638 status
= dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
);
639 if (NT_STATUS_IS_OK(status
)) {
640 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
642 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
644 s
.in
.user_handle
= handle
;
648 encode_pw_buffer(u
.info24
.password
.data
, newpass
, STR_UNICODE
);
649 u
.info24
.password_expired
= 0;
651 status
= dcerpc_fetch_session_key(p
, &session_key
);
652 if (!NT_STATUS_IS_OK(status
)) {
653 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
654 s
.in
.level
, nt_errstr(status
));
658 arcfour_crypt_blob(u
.info24
.password
.data
, 516, &session_key
);
660 torture_comment(tctx
, "Testing SetUserInfo level 24 (set password)\n");
662 status
= dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
);
663 if (!NT_STATUS_IS_OK(status
)) {
664 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
665 s
.in
.level
, nt_errstr(status
));
675 static bool test_SetUserPass_23(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
676 struct policy_handle
*handle
, uint32_t fields_present
,
680 struct samr_SetUserInfo s
;
681 union samr_UserInfo u
;
683 DATA_BLOB session_key
;
684 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
686 struct samr_GetUserPwInfo pwp
;
687 struct samr_PwInfo info
;
688 int policy_min_pw_len
= 0;
689 pwp
.in
.user_handle
= handle
;
690 pwp
.out
.info
= &info
;
692 status
= dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
);
693 if (NT_STATUS_IS_OK(status
)) {
694 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
696 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
698 s
.in
.user_handle
= handle
;
704 u
.info23
.info
.fields_present
= fields_present
;
706 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
708 status
= dcerpc_fetch_session_key(p
, &session_key
);
709 if (!NT_STATUS_IS_OK(status
)) {
710 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
711 s
.in
.level
, nt_errstr(status
));
715 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
717 torture_comment(tctx
, "Testing SetUserInfo level 23 (set password)\n");
719 status
= dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
);
720 if (!NT_STATUS_IS_OK(status
)) {
721 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
722 s
.in
.level
, nt_errstr(status
));
728 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
730 status
= dcerpc_fetch_session_key(p
, &session_key
);
731 if (!NT_STATUS_IS_OK(status
)) {
732 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
733 s
.in
.level
, nt_errstr(status
));
737 /* This should break the key nicely */
738 session_key
.length
--;
739 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
741 torture_comment(tctx
, "Testing SetUserInfo level 23 (set password) with wrong password\n");
743 status
= dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
);
744 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
745 torture_warning(tctx
, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
746 s
.in
.level
, nt_errstr(status
));
754 static bool test_SetUserPassEx(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
755 struct policy_handle
*handle
, bool makeshort
,
759 struct samr_SetUserInfo s
;
760 union samr_UserInfo u
;
762 DATA_BLOB session_key
;
763 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
764 uint8_t confounder
[16];
766 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
767 struct MD5Context ctx
;
768 struct samr_GetUserPwInfo pwp
;
769 struct samr_PwInfo info
;
770 int policy_min_pw_len
= 0;
771 pwp
.in
.user_handle
= handle
;
772 pwp
.out
.info
= &info
;
774 status
= dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
);
775 if (NT_STATUS_IS_OK(status
)) {
776 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
778 if (makeshort
&& policy_min_pw_len
) {
779 newpass
= samr_rand_pass_fixed_len(tctx
, policy_min_pw_len
- 1);
781 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
784 s
.in
.user_handle
= handle
;
788 encode_pw_buffer(u
.info26
.password
.data
, newpass
, STR_UNICODE
);
789 u
.info26
.password_expired
= 0;
791 status
= dcerpc_fetch_session_key(p
, &session_key
);
792 if (!NT_STATUS_IS_OK(status
)) {
793 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
794 s
.in
.level
, nt_errstr(status
));
798 generate_random_buffer((uint8_t *)confounder
, 16);
801 MD5Update(&ctx
, confounder
, 16);
802 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
803 MD5Final(confounded_session_key
.data
, &ctx
);
805 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
806 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
808 torture_comment(tctx
, "Testing SetUserInfo level 26 (set password ex)\n");
810 status
= dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
);
811 if (!NT_STATUS_IS_OK(status
)) {
812 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
813 s
.in
.level
, nt_errstr(status
));
819 /* This should break the key nicely */
820 confounded_session_key
.data
[0]++;
822 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
823 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
825 torture_comment(tctx
, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
827 status
= dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
);
828 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
829 torture_warning(tctx
, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
830 s
.in
.level
, nt_errstr(status
));
839 static bool test_SetUserPass_25(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
840 struct policy_handle
*handle
, uint32_t fields_present
,
844 struct samr_SetUserInfo s
;
845 union samr_UserInfo u
;
847 DATA_BLOB session_key
;
848 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
849 struct MD5Context ctx
;
850 uint8_t confounder
[16];
852 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
853 struct samr_GetUserPwInfo pwp
;
854 struct samr_PwInfo info
;
855 int policy_min_pw_len
= 0;
856 pwp
.in
.user_handle
= handle
;
857 pwp
.out
.info
= &info
;
859 status
= dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
);
860 if (NT_STATUS_IS_OK(status
)) {
861 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
863 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
865 s
.in
.user_handle
= handle
;
871 u
.info25
.info
.fields_present
= fields_present
;
873 encode_pw_buffer(u
.info25
.password
.data
, newpass
, STR_UNICODE
);
875 status
= dcerpc_fetch_session_key(p
, &session_key
);
876 if (!NT_STATUS_IS_OK(status
)) {
877 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
878 s
.in
.level
, nt_errstr(status
));
882 generate_random_buffer((uint8_t *)confounder
, 16);
885 MD5Update(&ctx
, confounder
, 16);
886 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
887 MD5Final(confounded_session_key
.data
, &ctx
);
889 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
890 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
892 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex)\n");
894 status
= dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
);
895 if (!NT_STATUS_IS_OK(status
)) {
896 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
897 s
.in
.level
, nt_errstr(status
));
903 /* This should break the key nicely */
904 confounded_session_key
.data
[0]++;
906 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
907 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
909 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
911 status
= dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
);
912 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
913 torture_warning(tctx
, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
914 s
.in
.level
, nt_errstr(status
));
921 static bool test_SetUserPass_18(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
922 struct policy_handle
*handle
, char **password
)
925 struct samr_SetUserInfo s
;
926 union samr_UserInfo u
;
928 DATA_BLOB session_key
;
930 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
931 struct samr_GetUserPwInfo pwp
;
932 struct samr_PwInfo info
;
933 int policy_min_pw_len
= 0;
934 uint8_t lm_hash
[16], nt_hash
[16];
936 pwp
.in
.user_handle
= handle
;
937 pwp
.out
.info
= &info
;
939 status
= dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
);
940 if (NT_STATUS_IS_OK(status
)) {
941 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
943 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
945 s
.in
.user_handle
= handle
;
951 u
.info18
.nt_pwd_active
= true;
952 u
.info18
.lm_pwd_active
= true;
954 E_md4hash(newpass
, nt_hash
);
955 E_deshash(newpass
, lm_hash
);
957 status
= dcerpc_fetch_session_key(p
, &session_key
);
958 if (!NT_STATUS_IS_OK(status
)) {
959 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
960 s
.in
.level
, nt_errstr(status
));
966 in
= data_blob_const(nt_hash
, 16);
967 out
= data_blob_talloc_zero(tctx
, 16);
968 sess_crypt_blob(&out
, &in
, &session_key
, true);
969 memcpy(u
.info18
.nt_pwd
.hash
, out
.data
, out
.length
);
973 in
= data_blob_const(lm_hash
, 16);
974 out
= data_blob_talloc_zero(tctx
, 16);
975 sess_crypt_blob(&out
, &in
, &session_key
, true);
976 memcpy(u
.info18
.lm_pwd
.hash
, out
.data
, out
.length
);
979 torture_comment(tctx
, "Testing SetUserInfo level 18 (set password hash)\n");
981 status
= dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
);
982 if (!NT_STATUS_IS_OK(status
)) {
983 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
984 s
.in
.level
, nt_errstr(status
));
993 static bool test_SetUserPass_21(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
994 struct policy_handle
*handle
, uint32_t fields_present
,
998 struct samr_SetUserInfo s
;
999 union samr_UserInfo u
;
1001 DATA_BLOB session_key
;
1003 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1004 struct samr_GetUserPwInfo pwp
;
1005 struct samr_PwInfo info
;
1006 int policy_min_pw_len
= 0;
1007 uint8_t lm_hash
[16], nt_hash
[16];
1009 pwp
.in
.user_handle
= handle
;
1010 pwp
.out
.info
= &info
;
1012 status
= dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
);
1013 if (NT_STATUS_IS_OK(status
)) {
1014 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1016 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1018 s
.in
.user_handle
= handle
;
1022 E_md4hash(newpass
, nt_hash
);
1023 E_deshash(newpass
, lm_hash
);
1027 u
.info21
.fields_present
= fields_present
;
1029 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1030 u
.info21
.lm_owf_password
.length
= 16;
1031 u
.info21
.lm_owf_password
.size
= 16;
1032 u
.info21
.lm_owf_password
.array
= (uint16_t *)lm_hash
;
1033 u
.info21
.lm_password_set
= true;
1036 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1037 u
.info21
.nt_owf_password
.length
= 16;
1038 u
.info21
.nt_owf_password
.size
= 16;
1039 u
.info21
.nt_owf_password
.array
= (uint16_t *)nt_hash
;
1040 u
.info21
.nt_password_set
= true;
1043 status
= dcerpc_fetch_session_key(p
, &session_key
);
1044 if (!NT_STATUS_IS_OK(status
)) {
1045 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
1046 s
.in
.level
, nt_errstr(status
));
1050 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1052 in
= data_blob_const(u
.info21
.lm_owf_password
.array
,
1053 u
.info21
.lm_owf_password
.length
);
1054 out
= data_blob_talloc_zero(tctx
, 16);
1055 sess_crypt_blob(&out
, &in
, &session_key
, true);
1056 u
.info21
.lm_owf_password
.array
= (uint16_t *)out
.data
;
1059 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1061 in
= data_blob_const(u
.info21
.nt_owf_password
.array
,
1062 u
.info21
.nt_owf_password
.length
);
1063 out
= data_blob_talloc_zero(tctx
, 16);
1064 sess_crypt_blob(&out
, &in
, &session_key
, true);
1065 u
.info21
.nt_owf_password
.array
= (uint16_t *)out
.data
;
1068 torture_comment(tctx
, "Testing SetUserInfo level 21 (set password hash)\n");
1070 status
= dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
);
1071 if (!NT_STATUS_IS_OK(status
)) {
1072 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
1073 s
.in
.level
, nt_errstr(status
));
1076 *password
= newpass
;
1079 /* try invalid length */
1080 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1082 u
.info21
.nt_owf_password
.length
++;
1084 status
= dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
);
1086 if (!NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
1087 torture_warning(tctx
, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1088 s
.in
.level
, nt_errstr(status
));
1093 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1095 u
.info21
.lm_owf_password
.length
++;
1097 status
= dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
);
1099 if (!NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
1100 torture_warning(tctx
, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1101 s
.in
.level
, nt_errstr(status
));
1109 static bool test_SetUserPass_level_ex(struct dcerpc_pipe
*p
,
1110 struct torture_context
*tctx
,
1111 struct policy_handle
*handle
,
1113 uint32_t fields_present
,
1114 char **password
, uint8_t password_expired
,
1116 bool *matched_expected_error
)
1119 NTSTATUS expected_error
= NT_STATUS_OK
;
1120 struct samr_SetUserInfo s
;
1121 struct samr_SetUserInfo2 s2
;
1122 union samr_UserInfo u
;
1124 DATA_BLOB session_key
;
1125 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
1126 struct MD5Context ctx
;
1127 uint8_t confounder
[16];
1129 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1130 struct samr_GetUserPwInfo pwp
;
1131 struct samr_PwInfo info
;
1132 int policy_min_pw_len
= 0;
1133 const char *comment
= NULL
;
1134 uint8_t lm_hash
[16], nt_hash
[16];
1136 pwp
.in
.user_handle
= handle
;
1137 pwp
.out
.info
= &info
;
1139 status
= dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
);
1140 if (NT_STATUS_IS_OK(status
)) {
1141 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1143 newpass
= samr_rand_pass_silent(tctx
, policy_min_pw_len
);
1146 s2
.in
.user_handle
= handle
;
1148 s2
.in
.level
= level
;
1150 s
.in
.user_handle
= handle
;
1155 if (fields_present
& SAMR_FIELD_COMMENT
) {
1156 comment
= talloc_asprintf(tctx
, "comment: %ld\n", time(NULL
));
1163 E_md4hash(newpass
, nt_hash
);
1164 E_deshash(newpass
, lm_hash
);
1166 u
.info18
.nt_pwd_active
= true;
1167 u
.info18
.lm_pwd_active
= true;
1168 u
.info18
.password_expired
= password_expired
;
1170 memcpy(u
.info18
.lm_pwd
.hash
, lm_hash
, 16);
1171 memcpy(u
.info18
.nt_pwd
.hash
, nt_hash
, 16);
1175 E_md4hash(newpass
, nt_hash
);
1176 E_deshash(newpass
, lm_hash
);
1178 u
.info21
.fields_present
= fields_present
;
1179 u
.info21
.password_expired
= password_expired
;
1180 u
.info21
.comment
.string
= comment
;
1182 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1183 u
.info21
.lm_owf_password
.length
= 16;
1184 u
.info21
.lm_owf_password
.size
= 16;
1185 u
.info21
.lm_owf_password
.array
= (uint16_t *)lm_hash
;
1186 u
.info21
.lm_password_set
= true;
1189 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1190 u
.info21
.nt_owf_password
.length
= 16;
1191 u
.info21
.nt_owf_password
.size
= 16;
1192 u
.info21
.nt_owf_password
.array
= (uint16_t *)nt_hash
;
1193 u
.info21
.nt_password_set
= true;
1198 u
.info23
.info
.fields_present
= fields_present
;
1199 u
.info23
.info
.password_expired
= password_expired
;
1200 u
.info23
.info
.comment
.string
= comment
;
1202 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
1206 u
.info24
.password_expired
= password_expired
;
1208 encode_pw_buffer(u
.info24
.password
.data
, newpass
, STR_UNICODE
);
1212 u
.info25
.info
.fields_present
= fields_present
;
1213 u
.info25
.info
.password_expired
= password_expired
;
1214 u
.info25
.info
.comment
.string
= comment
;
1216 encode_pw_buffer(u
.info25
.password
.data
, newpass
, STR_UNICODE
);
1220 u
.info26
.password_expired
= password_expired
;
1222 encode_pw_buffer(u
.info26
.password
.data
, newpass
, STR_UNICODE
);
1227 status
= dcerpc_fetch_session_key(p
, &session_key
);
1228 if (!NT_STATUS_IS_OK(status
)) {
1229 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
1230 s
.in
.level
, nt_errstr(status
));
1234 generate_random_buffer((uint8_t *)confounder
, 16);
1237 MD5Update(&ctx
, confounder
, 16);
1238 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
1239 MD5Final(confounded_session_key
.data
, &ctx
);
1245 in
= data_blob_const(u
.info18
.nt_pwd
.hash
, 16);
1246 out
= data_blob_talloc_zero(tctx
, 16);
1247 sess_crypt_blob(&out
, &in
, &session_key
, true);
1248 memcpy(u
.info18
.nt_pwd
.hash
, out
.data
, out
.length
);
1252 in
= data_blob_const(u
.info18
.lm_pwd
.hash
, 16);
1253 out
= data_blob_talloc_zero(tctx
, 16);
1254 sess_crypt_blob(&out
, &in
, &session_key
, true);
1255 memcpy(u
.info18
.lm_pwd
.hash
, out
.data
, out
.length
);
1260 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1262 in
= data_blob_const(u
.info21
.lm_owf_password
.array
,
1263 u
.info21
.lm_owf_password
.length
);
1264 out
= data_blob_talloc_zero(tctx
, 16);
1265 sess_crypt_blob(&out
, &in
, &session_key
, true);
1266 u
.info21
.lm_owf_password
.array
= (uint16_t *)out
.data
;
1268 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1270 in
= data_blob_const(u
.info21
.nt_owf_password
.array
,
1271 u
.info21
.nt_owf_password
.length
);
1272 out
= data_blob_talloc_zero(tctx
, 16);
1273 sess_crypt_blob(&out
, &in
, &session_key
, true);
1274 u
.info21
.nt_owf_password
.array
= (uint16_t *)out
.data
;
1278 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
1281 arcfour_crypt_blob(u
.info24
.password
.data
, 516, &session_key
);
1284 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
1285 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
1288 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
1289 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
1294 status
= dcerpc_samr_SetUserInfo2_r(b
, tctx
, &s2
);
1296 status
= dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
);
1299 if (!NT_STATUS_IS_OK(status
)) {
1300 if (fields_present
== 0) {
1301 expected_error
= NT_STATUS_INVALID_PARAMETER
;
1303 if (fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
1304 expected_error
= NT_STATUS_ACCESS_DENIED
;
1308 if (!NT_STATUS_IS_OK(expected_error
)) {
1310 torture_assert_ntstatus_equal(tctx
,
1312 expected_error
, "SetUserInfo2 failed");
1314 torture_assert_ntstatus_equal(tctx
,
1316 expected_error
, "SetUserInfo failed");
1318 *matched_expected_error
= true;
1322 if (!NT_STATUS_IS_OK(status
)) {
1323 torture_warning(tctx
, "SetUserInfo%s level %u failed - %s\n",
1324 use_setinfo2
? "2":"", level
, nt_errstr(status
));
1327 *password
= newpass
;
1333 static bool test_SetAliasInfo(struct dcerpc_binding_handle
*b
,
1334 struct torture_context
*tctx
,
1335 struct policy_handle
*handle
)
1338 struct samr_SetAliasInfo r
;
1339 struct samr_QueryAliasInfo q
;
1340 union samr_AliasInfo
*info
;
1341 uint16_t levels
[] = {2, 3};
1345 /* Ignoring switch level 1, as that includes the number of members for the alias
1346 * and setting this to a wrong value might have negative consequences
1349 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
1350 torture_comment(tctx
, "Testing SetAliasInfo level %u\n", levels
[i
]);
1352 r
.in
.alias_handle
= handle
;
1353 r
.in
.level
= levels
[i
];
1354 r
.in
.info
= talloc(tctx
, union samr_AliasInfo
);
1355 switch (r
.in
.level
) {
1356 case ALIASINFONAME
: init_lsa_String(&r
.in
.info
->name
,TEST_ALIASNAME
); break;
1357 case ALIASINFODESCRIPTION
: init_lsa_String(&r
.in
.info
->description
,
1358 "Test Description, should test I18N as well"); break;
1359 case ALIASINFOALL
: torture_comment(tctx
, "ALIASINFOALL ignored\n"); break;
1362 status
= dcerpc_samr_SetAliasInfo_r(b
, tctx
, &r
);
1363 if (!NT_STATUS_IS_OK(status
)) {
1364 torture_warning(tctx
, "SetAliasInfo level %u failed - %s\n",
1365 levels
[i
], nt_errstr(status
));
1369 q
.in
.alias_handle
= handle
;
1370 q
.in
.level
= levels
[i
];
1373 status
= dcerpc_samr_QueryAliasInfo_r(b
, tctx
, &q
);
1374 if (!NT_STATUS_IS_OK(status
)) {
1375 torture_warning(tctx
, "QueryAliasInfo level %u failed - %s\n",
1376 levels
[i
], nt_errstr(status
));
1384 static bool test_GetGroupsForUser(struct dcerpc_binding_handle
*b
,
1385 struct torture_context
*tctx
,
1386 struct policy_handle
*user_handle
)
1388 struct samr_GetGroupsForUser r
;
1389 struct samr_RidWithAttributeArray
*rids
= NULL
;
1392 torture_comment(tctx
, "testing GetGroupsForUser\n");
1394 r
.in
.user_handle
= user_handle
;
1397 status
= dcerpc_samr_GetGroupsForUser_r(b
, tctx
, &r
);
1398 torture_assert_ntstatus_ok(tctx
, status
, "GetGroupsForUser");
1404 static bool test_GetDomPwInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1405 struct lsa_String
*domain_name
)
1408 struct samr_GetDomPwInfo r
;
1409 struct samr_PwInfo info
;
1410 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1412 r
.in
.domain_name
= domain_name
;
1415 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1417 status
= dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &r
);
1418 torture_assert_ntstatus_ok(tctx
, status
, "GetDomPwInfo");
1420 r
.in
.domain_name
->string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1421 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1423 status
= dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &r
);
1424 torture_assert_ntstatus_ok(tctx
, status
, "GetDomPwInfo");
1426 r
.in
.domain_name
->string
= "\\\\__NONAME__";
1427 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1429 status
= dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &r
);
1430 torture_assert_ntstatus_ok(tctx
, status
, "GetDomPwInfo");
1432 r
.in
.domain_name
->string
= "\\\\Builtin";
1433 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1435 status
= dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &r
);
1436 torture_assert_ntstatus_ok(tctx
, status
, "GetDomPwInfo");
1441 static bool test_GetUserPwInfo(struct dcerpc_binding_handle
*b
,
1442 struct torture_context
*tctx
,
1443 struct policy_handle
*handle
)
1446 struct samr_GetUserPwInfo r
;
1447 struct samr_PwInfo info
;
1449 torture_comment(tctx
, "Testing GetUserPwInfo\n");
1451 r
.in
.user_handle
= handle
;
1454 status
= dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &r
);
1455 torture_assert_ntstatus_ok(tctx
, status
, "GetUserPwInfo");
1460 static NTSTATUS
test_LookupName(struct dcerpc_binding_handle
*b
,
1461 struct torture_context
*tctx
,
1462 struct policy_handle
*domain_handle
, const char *name
,
1466 struct samr_LookupNames n
;
1467 struct lsa_String sname
[2];
1468 struct samr_Ids rids
, types
;
1470 init_lsa_String(&sname
[0], name
);
1472 n
.in
.domain_handle
= domain_handle
;
1476 n
.out
.types
= &types
;
1477 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1478 if (NT_STATUS_IS_OK(status
)) {
1479 *rid
= n
.out
.rids
->ids
[0];
1484 init_lsa_String(&sname
[1], "xxNONAMExx");
1486 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1487 if (!NT_STATUS_EQUAL(status
, STATUS_SOME_UNMAPPED
)) {
1488 torture_warning(tctx
, "LookupNames[2] failed - %s\n", nt_errstr(status
));
1489 if (NT_STATUS_IS_OK(status
)) {
1490 return NT_STATUS_UNSUCCESSFUL
;
1496 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1497 if (!NT_STATUS_IS_OK(status
)) {
1498 torture_warning(tctx
, "LookupNames[0] failed - %s\n", nt_errstr(status
));
1502 init_lsa_String(&sname
[0], "xxNONAMExx");
1504 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1505 if (!NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
)) {
1506 torture_warning(tctx
, "LookupNames[1 bad name] failed - %s\n", nt_errstr(status
));
1507 if (NT_STATUS_IS_OK(status
)) {
1508 return NT_STATUS_UNSUCCESSFUL
;
1513 init_lsa_String(&sname
[0], "xxNONAMExx");
1514 init_lsa_String(&sname
[1], "xxNONAME2xx");
1516 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1517 if (!NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
)) {
1518 torture_warning(tctx
, "LookupNames[2 bad names] failed - %s\n", nt_errstr(status
));
1519 if (NT_STATUS_IS_OK(status
)) {
1520 return NT_STATUS_UNSUCCESSFUL
;
1525 return NT_STATUS_OK
;
1528 static NTSTATUS
test_OpenUser_byname(struct dcerpc_binding_handle
*b
,
1529 struct torture_context
*tctx
,
1530 struct policy_handle
*domain_handle
,
1531 const char *name
, struct policy_handle
*user_handle
)
1534 struct samr_OpenUser r
;
1537 status
= test_LookupName(b
, tctx
, domain_handle
, name
, &rid
);
1538 if (!NT_STATUS_IS_OK(status
)) {
1542 r
.in
.domain_handle
= domain_handle
;
1543 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1545 r
.out
.user_handle
= user_handle
;
1546 status
= dcerpc_samr_OpenUser_r(b
, tctx
, &r
);
1547 if (!NT_STATUS_IS_OK(status
)) {
1548 torture_warning(tctx
, "OpenUser_byname(%s -> %d) failed - %s\n", name
, rid
, nt_errstr(status
));
1555 static bool test_ChangePasswordNT3(struct dcerpc_pipe
*p
,
1556 struct torture_context
*tctx
,
1557 struct policy_handle
*handle
)
1560 struct samr_ChangePasswordUser r
;
1562 struct samr_Password hash1
, hash2
, hash3
, hash4
, hash5
, hash6
;
1563 struct policy_handle user_handle
;
1564 char *oldpass
= "test";
1565 char *newpass
= "test2";
1566 uint8_t old_nt_hash
[16], new_nt_hash
[16];
1567 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1569 status
= test_OpenUser_byname(p
, tctx
, handle
, "testuser", &user_handle
);
1570 if (!NT_STATUS_IS_OK(status
)) {
1574 torture_comment(tctx
, "Testing ChangePasswordUser for user 'testuser'\n");
1576 torture_comment(tctx
, "old password: %s\n", oldpass
);
1577 torture_comment(tctx
, "new password: %s\n", newpass
);
1579 E_md4hash(oldpass
, old_nt_hash
);
1580 E_md4hash(newpass
, new_nt_hash
);
1581 E_deshash(oldpass
, old_lm_hash
);
1582 E_deshash(newpass
, new_lm_hash
);
1584 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1585 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1586 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1587 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1588 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1589 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1591 r
.in
.handle
= &user_handle
;
1592 r
.in
.lm_present
= 1;
1593 r
.in
.old_lm_crypted
= &hash1
;
1594 r
.in
.new_lm_crypted
= &hash2
;
1595 r
.in
.nt_present
= 1;
1596 r
.in
.old_nt_crypted
= &hash3
;
1597 r
.in
.new_nt_crypted
= &hash4
;
1598 r
.in
.cross1_present
= 1;
1599 r
.in
.nt_cross
= &hash5
;
1600 r
.in
.cross2_present
= 1;
1601 r
.in
.lm_cross
= &hash6
;
1603 status
= dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
);
1604 if (!NT_STATUS_IS_OK(status
)) {
1605 torture_warning(tctx
, "ChangePasswordUser failed - %s\n", nt_errstr(status
));
1609 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
1617 static bool test_ChangePasswordUser(struct dcerpc_binding_handle
*b
,
1618 struct torture_context
*tctx
,
1619 const char *acct_name
,
1620 struct policy_handle
*handle
, char **password
)
1623 struct samr_ChangePasswordUser r
;
1625 struct samr_Password hash1
, hash2
, hash3
, hash4
, hash5
, hash6
;
1626 struct policy_handle user_handle
;
1628 uint8_t old_nt_hash
[16], new_nt_hash
[16];
1629 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1630 bool changed
= true;
1633 struct samr_GetUserPwInfo pwp
;
1634 struct samr_PwInfo info
;
1635 int policy_min_pw_len
= 0;
1637 status
= test_OpenUser_byname(b
, tctx
, handle
, acct_name
, &user_handle
);
1638 if (!NT_STATUS_IS_OK(status
)) {
1641 pwp
.in
.user_handle
= &user_handle
;
1642 pwp
.out
.info
= &info
;
1644 status
= dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
);
1645 if (NT_STATUS_IS_OK(status
)) {
1646 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1648 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1650 torture_comment(tctx
, "Testing ChangePasswordUser\n");
1652 torture_assert(tctx
, *password
!= NULL
,
1653 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1655 oldpass
= *password
;
1657 E_md4hash(oldpass
, old_nt_hash
);
1658 E_md4hash(newpass
, new_nt_hash
);
1659 E_deshash(oldpass
, old_lm_hash
);
1660 E_deshash(newpass
, new_lm_hash
);
1662 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1663 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1664 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1665 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1666 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1667 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1669 r
.in
.user_handle
= &user_handle
;
1670 r
.in
.lm_present
= 1;
1671 /* Break the LM hash */
1673 r
.in
.old_lm_crypted
= &hash1
;
1674 r
.in
.new_lm_crypted
= &hash2
;
1675 r
.in
.nt_present
= 1;
1676 r
.in
.old_nt_crypted
= &hash3
;
1677 r
.in
.new_nt_crypted
= &hash4
;
1678 r
.in
.cross1_present
= 1;
1679 r
.in
.nt_cross
= &hash5
;
1680 r
.in
.cross2_present
= 1;
1681 r
.in
.lm_cross
= &hash6
;
1683 status
= dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
);
1684 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_WRONG_PASSWORD
,
1685 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1687 /* Unbreak the LM hash */
1690 r
.in
.user_handle
= &user_handle
;
1691 r
.in
.lm_present
= 1;
1692 r
.in
.old_lm_crypted
= &hash1
;
1693 r
.in
.new_lm_crypted
= &hash2
;
1694 /* Break the NT hash */
1696 r
.in
.nt_present
= 1;
1697 r
.in
.old_nt_crypted
= &hash3
;
1698 r
.in
.new_nt_crypted
= &hash4
;
1699 r
.in
.cross1_present
= 1;
1700 r
.in
.nt_cross
= &hash5
;
1701 r
.in
.cross2_present
= 1;
1702 r
.in
.lm_cross
= &hash6
;
1704 status
= dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
);
1705 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_WRONG_PASSWORD
,
1706 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1708 /* Unbreak the NT hash */
1711 r
.in
.user_handle
= &user_handle
;
1712 r
.in
.lm_present
= 1;
1713 r
.in
.old_lm_crypted
= &hash1
;
1714 r
.in
.new_lm_crypted
= &hash2
;
1715 r
.in
.nt_present
= 1;
1716 r
.in
.old_nt_crypted
= &hash3
;
1717 r
.in
.new_nt_crypted
= &hash4
;
1718 r
.in
.cross1_present
= 1;
1719 r
.in
.nt_cross
= &hash5
;
1720 r
.in
.cross2_present
= 1;
1721 /* Break the LM cross */
1723 r
.in
.lm_cross
= &hash6
;
1725 status
= dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
);
1726 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1727 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status
));
1731 /* Unbreak the LM cross */
1734 r
.in
.user_handle
= &user_handle
;
1735 r
.in
.lm_present
= 1;
1736 r
.in
.old_lm_crypted
= &hash1
;
1737 r
.in
.new_lm_crypted
= &hash2
;
1738 r
.in
.nt_present
= 1;
1739 r
.in
.old_nt_crypted
= &hash3
;
1740 r
.in
.new_nt_crypted
= &hash4
;
1741 r
.in
.cross1_present
= 1;
1742 /* Break the NT cross */
1744 r
.in
.nt_cross
= &hash5
;
1745 r
.in
.cross2_present
= 1;
1746 r
.in
.lm_cross
= &hash6
;
1748 status
= dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
);
1749 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1750 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status
));
1754 /* Unbreak the NT cross */
1758 /* Reset the hashes to not broken values */
1759 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1760 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1761 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1762 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1763 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1764 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1766 r
.in
.user_handle
= &user_handle
;
1767 r
.in
.lm_present
= 1;
1768 r
.in
.old_lm_crypted
= &hash1
;
1769 r
.in
.new_lm_crypted
= &hash2
;
1770 r
.in
.nt_present
= 1;
1771 r
.in
.old_nt_crypted
= &hash3
;
1772 r
.in
.new_nt_crypted
= &hash4
;
1773 r
.in
.cross1_present
= 1;
1774 r
.in
.nt_cross
= &hash5
;
1775 r
.in
.cross2_present
= 0;
1776 r
.in
.lm_cross
= NULL
;
1778 status
= dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
);
1779 if (NT_STATUS_IS_OK(status
)) {
1781 *password
= newpass
;
1782 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION
, status
)) {
1783 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status
));
1788 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1790 E_md4hash(oldpass
, old_nt_hash
);
1791 E_md4hash(newpass
, new_nt_hash
);
1792 E_deshash(oldpass
, old_lm_hash
);
1793 E_deshash(newpass
, new_lm_hash
);
1796 /* Reset the hashes to not broken values */
1797 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1798 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1799 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1800 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1801 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1802 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1804 r
.in
.user_handle
= &user_handle
;
1805 r
.in
.lm_present
= 1;
1806 r
.in
.old_lm_crypted
= &hash1
;
1807 r
.in
.new_lm_crypted
= &hash2
;
1808 r
.in
.nt_present
= 1;
1809 r
.in
.old_nt_crypted
= &hash3
;
1810 r
.in
.new_nt_crypted
= &hash4
;
1811 r
.in
.cross1_present
= 0;
1812 r
.in
.nt_cross
= NULL
;
1813 r
.in
.cross2_present
= 1;
1814 r
.in
.lm_cross
= &hash6
;
1816 status
= dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
);
1817 if (NT_STATUS_IS_OK(status
)) {
1819 *password
= newpass
;
1820 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION
, status
)) {
1821 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status
));
1826 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1828 E_md4hash(oldpass
, old_nt_hash
);
1829 E_md4hash(newpass
, new_nt_hash
);
1830 E_deshash(oldpass
, old_lm_hash
);
1831 E_deshash(newpass
, new_lm_hash
);
1834 /* Reset the hashes to not broken values */
1835 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1836 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1837 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1838 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1839 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1840 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1842 r
.in
.user_handle
= &user_handle
;
1843 r
.in
.lm_present
= 1;
1844 r
.in
.old_lm_crypted
= &hash1
;
1845 r
.in
.new_lm_crypted
= &hash2
;
1846 r
.in
.nt_present
= 1;
1847 r
.in
.old_nt_crypted
= &hash3
;
1848 r
.in
.new_nt_crypted
= &hash4
;
1849 r
.in
.cross1_present
= 1;
1850 r
.in
.nt_cross
= &hash5
;
1851 r
.in
.cross2_present
= 1;
1852 r
.in
.lm_cross
= &hash6
;
1854 status
= dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
);
1855 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1856 torture_comment(tctx
, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status
));
1857 } else if (!NT_STATUS_IS_OK(status
)) {
1858 torture_warning(tctx
, "ChangePasswordUser failed - %s\n", nt_errstr(status
));
1862 *password
= newpass
;
1865 r
.in
.user_handle
= &user_handle
;
1866 r
.in
.lm_present
= 1;
1867 r
.in
.old_lm_crypted
= &hash1
;
1868 r
.in
.new_lm_crypted
= &hash2
;
1869 r
.in
.nt_present
= 1;
1870 r
.in
.old_nt_crypted
= &hash3
;
1871 r
.in
.new_nt_crypted
= &hash4
;
1872 r
.in
.cross1_present
= 1;
1873 r
.in
.nt_cross
= &hash5
;
1874 r
.in
.cross2_present
= 1;
1875 r
.in
.lm_cross
= &hash6
;
1878 status
= dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
);
1879 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1880 torture_comment(tctx
, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status
));
1881 } else if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1882 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status
));
1888 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
1896 static bool test_OemChangePasswordUser2(struct dcerpc_pipe
*p
,
1897 struct torture_context
*tctx
,
1898 const char *acct_name
,
1899 struct policy_handle
*handle
, char **password
)
1902 struct samr_OemChangePasswordUser2 r
;
1904 struct samr_Password lm_verifier
;
1905 struct samr_CryptPassword lm_pass
;
1906 struct lsa_AsciiString server
, account
, account_bad
;
1909 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1910 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1912 struct samr_GetDomPwInfo dom_pw_info
;
1913 struct samr_PwInfo info
;
1914 int policy_min_pw_len
= 0;
1916 struct lsa_String domain_name
;
1918 domain_name
.string
= "";
1919 dom_pw_info
.in
.domain_name
= &domain_name
;
1920 dom_pw_info
.out
.info
= &info
;
1922 torture_comment(tctx
, "Testing OemChangePasswordUser2\n");
1924 torture_assert(tctx
, *password
!= NULL
,
1925 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1927 oldpass
= *password
;
1929 status
= dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &dom_pw_info
);
1930 if (NT_STATUS_IS_OK(status
)) {
1931 policy_min_pw_len
= dom_pw_info
.out
.info
->min_password_length
;
1934 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1936 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1937 account
.string
= acct_name
;
1939 E_deshash(oldpass
, old_lm_hash
);
1940 E_deshash(newpass
, new_lm_hash
);
1942 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
1943 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
1944 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
1946 r
.in
.server
= &server
;
1947 r
.in
.account
= &account
;
1948 r
.in
.password
= &lm_pass
;
1949 r
.in
.hash
= &lm_verifier
;
1951 /* Break the verification */
1952 lm_verifier
.hash
[0]++;
1954 status
= dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
);
1956 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)
1957 && !NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1958 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1963 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
1964 /* Break the old password */
1966 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
1967 /* unbreak it for the next operation */
1969 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
1971 r
.in
.server
= &server
;
1972 r
.in
.account
= &account
;
1973 r
.in
.password
= &lm_pass
;
1974 r
.in
.hash
= &lm_verifier
;
1976 status
= dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
);
1978 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)
1979 && !NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1980 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1985 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
1986 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
1988 r
.in
.server
= &server
;
1989 r
.in
.account
= &account
;
1990 r
.in
.password
= &lm_pass
;
1993 status
= dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
);
1995 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)
1996 && !NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
1997 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
2002 /* This shouldn't be a valid name */
2003 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
2004 r
.in
.account
= &account_bad
;
2006 status
= dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
);
2008 if (!NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
2009 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
2014 /* This shouldn't be a valid name */
2015 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
2016 r
.in
.account
= &account_bad
;
2017 r
.in
.password
= &lm_pass
;
2018 r
.in
.hash
= &lm_verifier
;
2020 status
= dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
);
2022 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
2023 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2028 /* This shouldn't be a valid name */
2029 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
2030 r
.in
.account
= &account_bad
;
2031 r
.in
.password
= NULL
;
2032 r
.in
.hash
= &lm_verifier
;
2034 status
= dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
);
2036 if (!NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
2037 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2042 E_deshash(oldpass
, old_lm_hash
);
2043 E_deshash(newpass
, new_lm_hash
);
2045 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
2046 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2047 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
2049 r
.in
.server
= &server
;
2050 r
.in
.account
= &account
;
2051 r
.in
.password
= &lm_pass
;
2052 r
.in
.hash
= &lm_verifier
;
2054 status
= dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
);
2055 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2056 torture_comment(tctx
, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status
));
2057 } else if (!NT_STATUS_IS_OK(status
)) {
2058 torture_warning(tctx
, "OemChangePasswordUser2 failed - %s\n", nt_errstr(status
));
2061 *password
= newpass
;
2068 static bool test_ChangePasswordUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2069 const char *acct_name
,
2071 char *newpass
, bool allow_password_restriction
)
2074 struct samr_ChangePasswordUser2 r
;
2076 struct lsa_String server
, account
;
2077 struct samr_CryptPassword nt_pass
, lm_pass
;
2078 struct samr_Password nt_verifier
, lm_verifier
;
2080 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2081 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2082 uint8_t old_lm_hash
[16], new_lm_hash
[16];
2084 struct samr_GetDomPwInfo dom_pw_info
;
2085 struct samr_PwInfo info
;
2087 struct lsa_String domain_name
;
2089 domain_name
.string
= "";
2090 dom_pw_info
.in
.domain_name
= &domain_name
;
2091 dom_pw_info
.out
.info
= &info
;
2093 torture_comment(tctx
, "Testing ChangePasswordUser2 on %s\n", acct_name
);
2095 torture_assert(tctx
, *password
!= NULL
,
2096 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2097 oldpass
= *password
;
2100 int policy_min_pw_len
= 0;
2101 status
= dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &dom_pw_info
);
2102 if (NT_STATUS_IS_OK(status
)) {
2103 policy_min_pw_len
= dom_pw_info
.out
.info
->min_password_length
;
2106 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2109 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2110 init_lsa_String(&account
, acct_name
);
2112 E_md4hash(oldpass
, old_nt_hash
);
2113 E_md4hash(newpass
, new_nt_hash
);
2115 E_deshash(oldpass
, old_lm_hash
);
2116 E_deshash(newpass
, new_lm_hash
);
2118 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
|STR_TERMINATE
);
2119 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2120 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2122 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2123 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2124 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2126 r
.in
.server
= &server
;
2127 r
.in
.account
= &account
;
2128 r
.in
.nt_password
= &nt_pass
;
2129 r
.in
.nt_verifier
= &nt_verifier
;
2131 r
.in
.lm_password
= &lm_pass
;
2132 r
.in
.lm_verifier
= &lm_verifier
;
2134 status
= dcerpc_samr_ChangePasswordUser2_r(b
, tctx
, &r
);
2135 if (allow_password_restriction
&& NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2136 torture_comment(tctx
, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status
));
2137 } else if (!NT_STATUS_IS_OK(status
)) {
2138 torture_warning(tctx
, "ChangePasswordUser2 failed - %s\n", nt_errstr(status
));
2141 *password
= newpass
;
2148 bool test_ChangePasswordUser3(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2149 const char *account_string
,
2150 int policy_min_pw_len
,
2152 const char *newpass
,
2153 NTTIME last_password_change
,
2154 bool handle_reject_reason
)
2157 struct samr_ChangePasswordUser3 r
;
2159 struct lsa_String server
, account
, account_bad
;
2160 struct samr_CryptPassword nt_pass
, lm_pass
;
2161 struct samr_Password nt_verifier
, lm_verifier
;
2163 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2164 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2165 uint8_t old_lm_hash
[16], new_lm_hash
[16];
2167 struct samr_DomInfo1
*dominfo
= NULL
;
2168 struct userPwdChangeFailureInformation
*reject
= NULL
;
2170 torture_comment(tctx
, "Testing ChangePasswordUser3\n");
2172 if (newpass
== NULL
) {
2174 if (policy_min_pw_len
== 0) {
2175 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2177 newpass
= samr_rand_pass_fixed_len(tctx
, policy_min_pw_len
);
2179 } while (check_password_quality(newpass
) == false);
2181 torture_comment(tctx
, "Using password '%s'\n", newpass
);
2184 torture_assert(tctx
, *password
!= NULL
,
2185 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2187 oldpass
= *password
;
2188 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2189 init_lsa_String(&account
, account_string
);
2191 E_md4hash(oldpass
, old_nt_hash
);
2192 E_md4hash(newpass
, new_nt_hash
);
2194 E_deshash(oldpass
, old_lm_hash
);
2195 E_deshash(newpass
, new_lm_hash
);
2197 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2198 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2199 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2201 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2202 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2203 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2205 /* Break the verification */
2206 nt_verifier
.hash
[0]++;
2208 r
.in
.server
= &server
;
2209 r
.in
.account
= &account
;
2210 r
.in
.nt_password
= &nt_pass
;
2211 r
.in
.nt_verifier
= &nt_verifier
;
2213 r
.in
.lm_password
= &lm_pass
;
2214 r
.in
.lm_verifier
= &lm_verifier
;
2215 r
.in
.password3
= NULL
;
2216 r
.out
.dominfo
= &dominfo
;
2217 r
.out
.reject
= &reject
;
2219 status
= dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
);
2220 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
) &&
2221 (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
))) {
2222 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2227 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2228 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2229 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2231 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2232 /* Break the NT hash */
2234 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2235 /* Unbreak it again */
2237 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2239 r
.in
.server
= &server
;
2240 r
.in
.account
= &account
;
2241 r
.in
.nt_password
= &nt_pass
;
2242 r
.in
.nt_verifier
= &nt_verifier
;
2244 r
.in
.lm_password
= &lm_pass
;
2245 r
.in
.lm_verifier
= &lm_verifier
;
2246 r
.in
.password3
= NULL
;
2247 r
.out
.dominfo
= &dominfo
;
2248 r
.out
.reject
= &reject
;
2250 status
= dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
);
2251 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
) &&
2252 (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
))) {
2253 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2258 /* This shouldn't be a valid name */
2259 init_lsa_String(&account_bad
, talloc_asprintf(tctx
, "%sXX", account_string
));
2261 r
.in
.account
= &account_bad
;
2262 status
= dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
);
2263 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
2264 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2269 E_md4hash(oldpass
, old_nt_hash
);
2270 E_md4hash(newpass
, new_nt_hash
);
2272 E_deshash(oldpass
, old_lm_hash
);
2273 E_deshash(newpass
, new_lm_hash
);
2275 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2276 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2277 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2279 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2280 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2281 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2283 r
.in
.server
= &server
;
2284 r
.in
.account
= &account
;
2285 r
.in
.nt_password
= &nt_pass
;
2286 r
.in
.nt_verifier
= &nt_verifier
;
2288 r
.in
.lm_password
= &lm_pass
;
2289 r
.in
.lm_verifier
= &lm_verifier
;
2290 r
.in
.password3
= NULL
;
2291 r
.out
.dominfo
= &dominfo
;
2292 r
.out
.reject
= &reject
;
2294 unix_to_nt_time(&t
, time(NULL
));
2296 status
= dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
);
2298 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)
2301 && handle_reject_reason
2302 && (!null_nttime(last_password_change
) || !dominfo
->min_password_age
)) {
2303 if (dominfo
->password_properties
& DOMAIN_REFUSE_PASSWORD_CHANGE
) {
2305 if (reject
&& (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
)) {
2306 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2307 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2312 /* We tested the order of precendence which is as follows:
2321 if ((dominfo
->min_password_age
> 0) && !null_nttime(last_password_change
) &&
2322 (last_password_change
+ dominfo
->min_password_age
> t
)) {
2324 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2325 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2326 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2330 } else if ((dominfo
->min_password_length
> 0) &&
2331 (strlen(newpass
) < dominfo
->min_password_length
)) {
2333 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
) {
2334 torture_warning(tctx
, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2335 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
, reject
->extendedFailureReason
);
2339 } else if ((dominfo
->password_history_length
> 0) &&
2340 strequal(oldpass
, newpass
)) {
2342 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_PWD_IN_HISTORY
) {
2343 torture_warning(tctx
, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2344 SAM_PWD_CHANGE_PWD_IN_HISTORY
, reject
->extendedFailureReason
);
2347 } else if (dominfo
->password_properties
& DOMAIN_PASSWORD_COMPLEX
) {
2349 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NOT_COMPLEX
) {
2350 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2351 SAM_PWD_CHANGE_NOT_COMPLEX
, reject
->extendedFailureReason
);
2357 if (reject
->extendedFailureReason
== SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
) {
2358 /* retry with adjusted size */
2359 return test_ChangePasswordUser3(p
, tctx
, account_string
,
2360 dominfo
->min_password_length
,
2361 password
, NULL
, 0, false);
2365 } else if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2366 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2367 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2368 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2371 /* Perhaps the server has a 'min password age' set? */
2374 torture_assert_ntstatus_ok(tctx
, status
, "ChangePasswordUser3");
2375 *password
= talloc_strdup(tctx
, newpass
);
2381 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2382 const char *account_string
,
2383 struct policy_handle
*handle
,
2387 struct samr_ChangePasswordUser3 r
;
2388 struct samr_SetUserInfo s
;
2389 union samr_UserInfo u
;
2390 DATA_BLOB session_key
;
2391 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
2392 uint8_t confounder
[16];
2393 struct MD5Context ctx
;
2396 struct lsa_String server
, account
;
2397 struct samr_CryptPassword nt_pass
;
2398 struct samr_Password nt_verifier
;
2399 DATA_BLOB new_random_pass
;
2402 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2403 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2405 struct samr_DomInfo1
*dominfo
= NULL
;
2406 struct userPwdChangeFailureInformation
*reject
= NULL
;
2408 new_random_pass
= samr_very_rand_pass(tctx
, 128);
2410 torture_assert(tctx
, *password
!= NULL
,
2411 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2413 oldpass
= *password
;
2414 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2415 init_lsa_String(&account
, account_string
);
2417 s
.in
.user_handle
= handle
;
2423 u
.info25
.info
.fields_present
= SAMR_FIELD_NT_PASSWORD_PRESENT
;
2425 set_pw_in_buffer(u
.info25
.password
.data
, &new_random_pass
);
2427 status
= dcerpc_fetch_session_key(p
, &session_key
);
2428 if (!NT_STATUS_IS_OK(status
)) {
2429 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
2430 s
.in
.level
, nt_errstr(status
));
2434 generate_random_buffer((uint8_t *)confounder
, 16);
2437 MD5Update(&ctx
, confounder
, 16);
2438 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
2439 MD5Final(confounded_session_key
.data
, &ctx
);
2441 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
2442 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
2444 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2446 status
= dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
);
2447 if (!NT_STATUS_IS_OK(status
)) {
2448 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
2449 s
.in
.level
, nt_errstr(status
));
2453 torture_comment(tctx
, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2455 mdfour(old_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2457 new_random_pass
= samr_very_rand_pass(tctx
, 128);
2459 mdfour(new_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2461 set_pw_in_buffer(nt_pass
.data
, &new_random_pass
);
2462 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2463 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2465 r
.in
.server
= &server
;
2466 r
.in
.account
= &account
;
2467 r
.in
.nt_password
= &nt_pass
;
2468 r
.in
.nt_verifier
= &nt_verifier
;
2470 r
.in
.lm_password
= NULL
;
2471 r
.in
.lm_verifier
= NULL
;
2472 r
.in
.password3
= NULL
;
2473 r
.out
.dominfo
= &dominfo
;
2474 r
.out
.reject
= &reject
;
2476 unix_to_nt_time(&t
, time(NULL
));
2478 status
= dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
);
2480 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2481 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2482 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2483 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2486 /* Perhaps the server has a 'min password age' set? */
2488 } else if (!NT_STATUS_IS_OK(status
)) {
2489 torture_warning(tctx
, "ChangePasswordUser3 failed - %s\n", nt_errstr(status
));
2493 newpass
= samr_rand_pass(tctx
, 128);
2495 mdfour(old_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2497 E_md4hash(newpass
, new_nt_hash
);
2499 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2500 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2501 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2503 r
.in
.server
= &server
;
2504 r
.in
.account
= &account
;
2505 r
.in
.nt_password
= &nt_pass
;
2506 r
.in
.nt_verifier
= &nt_verifier
;
2508 r
.in
.lm_password
= NULL
;
2509 r
.in
.lm_verifier
= NULL
;
2510 r
.in
.password3
= NULL
;
2511 r
.out
.dominfo
= &dominfo
;
2512 r
.out
.reject
= &reject
;
2514 unix_to_nt_time(&t
, time(NULL
));
2516 status
= dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
);
2518 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2519 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2520 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2521 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2524 /* Perhaps the server has a 'min password age' set? */
2527 torture_assert_ntstatus_ok(tctx
, status
, "ChangePasswordUser3 (on second random password)");
2528 *password
= talloc_strdup(tctx
, newpass
);
2535 static bool test_GetMembersInAlias(struct dcerpc_binding_handle
*b
,
2536 struct torture_context
*tctx
,
2537 struct policy_handle
*alias_handle
)
2539 struct samr_GetMembersInAlias r
;
2540 struct lsa_SidArray sids
;
2543 torture_comment(tctx
, "Testing GetMembersInAlias\n");
2545 r
.in
.alias_handle
= alias_handle
;
2548 status
= dcerpc_samr_GetMembersInAlias_r(b
, tctx
, &r
);
2549 torture_assert_ntstatus_ok(tctx
, status
, "GetMembersInAlias");
2554 static bool test_AddMemberToAlias(struct dcerpc_binding_handle
*b
,
2555 struct torture_context
*tctx
,
2556 struct policy_handle
*alias_handle
,
2557 const struct dom_sid
*domain_sid
)
2559 struct samr_AddAliasMember r
;
2560 struct samr_DeleteAliasMember d
;
2562 struct dom_sid
*sid
;
2564 sid
= dom_sid_add_rid(tctx
, domain_sid
, 512);
2566 torture_comment(tctx
, "testing AddAliasMember\n");
2567 r
.in
.alias_handle
= alias_handle
;
2570 status
= dcerpc_samr_AddAliasMember_r(b
, tctx
, &r
);
2571 torture_assert_ntstatus_ok(tctx
, status
, "AddAliasMember");
2573 d
.in
.alias_handle
= alias_handle
;
2576 status
= dcerpc_samr_DeleteAliasMember_r(b
, tctx
, &d
);
2577 torture_assert_ntstatus_ok(tctx
, status
, "DelAliasMember");
2582 static bool test_AddMultipleMembersToAlias(struct dcerpc_binding_handle
*b
,
2583 struct torture_context
*tctx
,
2584 struct policy_handle
*alias_handle
)
2586 struct samr_AddMultipleMembersToAlias a
;
2587 struct samr_RemoveMultipleMembersFromAlias r
;
2589 struct lsa_SidArray sids
;
2591 torture_comment(tctx
, "testing AddMultipleMembersToAlias\n");
2592 a
.in
.alias_handle
= alias_handle
;
2596 sids
.sids
= talloc_array(tctx
, struct lsa_SidPtr
, 3);
2598 sids
.sids
[0].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-1");
2599 sids
.sids
[1].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-2");
2600 sids
.sids
[2].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-3");
2602 status
= dcerpc_samr_AddMultipleMembersToAlias_r(b
, tctx
, &a
);
2603 torture_assert_ntstatus_ok(tctx
, status
, "AddMultipleMembersToAlias");
2606 torture_comment(tctx
, "testing RemoveMultipleMembersFromAlias\n");
2607 r
.in
.alias_handle
= alias_handle
;
2610 status
= dcerpc_samr_RemoveMultipleMembersFromAlias_r(b
, tctx
, &r
);
2611 torture_assert_ntstatus_ok(tctx
, status
, "RemoveMultipleMembersFromAlias");
2613 /* strange! removing twice doesn't give any error */
2614 status
= dcerpc_samr_RemoveMultipleMembersFromAlias_r(b
, tctx
, &r
);
2615 torture_assert_ntstatus_ok(tctx
, status
, "RemoveMultipleMembersFromAlias");
2617 /* but removing an alias that isn't there does */
2618 sids
.sids
[2].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-4");
2620 status
= dcerpc_samr_RemoveMultipleMembersFromAlias_r(b
, tctx
, &r
);
2621 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
, "RemoveMultipleMembersFromAlias");
2626 static bool test_GetAliasMembership(struct dcerpc_binding_handle
*b
,
2627 struct torture_context
*tctx
,
2628 struct policy_handle
*domain_handle
)
2630 struct samr_GetAliasMembership r
;
2631 struct lsa_SidArray sids
;
2632 struct samr_Ids rids
;
2635 torture_comment(tctx
, "Testing GetAliasMembership\n");
2637 if (torture_setting_bool(tctx
, "samba4", false)) {
2638 torture_skip(tctx
, "skipping GetAliasMembership against s4");
2641 r
.in
.domain_handle
= domain_handle
;
2646 sids
.sids
= talloc_zero_array(tctx
, struct lsa_SidPtr
, sids
.num_sids
);
2648 status
= dcerpc_samr_GetAliasMembership_r(b
, tctx
, &r
);
2649 torture_assert_ntstatus_ok(tctx
, status
,
2650 "samr_GetAliasMembership failed");
2652 torture_assert_int_equal(tctx
, sids
.num_sids
, rids
.count
,
2653 "protocol misbehaviour");
2656 sids
.sids
= talloc_zero_array(tctx
, struct lsa_SidPtr
, sids
.num_sids
);
2657 sids
.sids
[0].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-1");
2659 status
= dcerpc_samr_GetAliasMembership_r(b
, tctx
, &r
);
2660 torture_assert_ntstatus_ok(tctx
, status
,
2661 "samr_GetAliasMembership failed");
2664 /* only true for w2k8 it seems
2665 * win7, xp, w2k3 will return a 0 length array pointer */
2667 if (rids
.ids
&& (rids
.count
== 0)) {
2668 torture_fail(tctx
, "samr_GetAliasMembership returned 0 count and a rids array");
2671 if (!rids
.ids
&& rids
.count
) {
2672 torture_fail(tctx
, "samr_GetAliasMembership returned non-0 count but no rids");
2678 static bool test_TestPrivateFunctionsUser(struct dcerpc_binding_handle
*b
,
2679 struct torture_context
*tctx
,
2680 struct policy_handle
*user_handle
)
2682 struct samr_TestPrivateFunctionsUser r
;
2685 torture_comment(tctx
, "Testing TestPrivateFunctionsUser\n");
2687 r
.in
.user_handle
= user_handle
;
2689 status
= dcerpc_samr_TestPrivateFunctionsUser_r(b
, tctx
, &r
);
2690 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_NOT_IMPLEMENTED
, "TestPrivateFunctionsUser");
2695 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_binding_handle
*b
,
2696 struct torture_context
*tctx
,
2697 struct policy_handle
*handle
,
2702 uint16_t levels
[] = { /* 3, */ 5, 21 };
2704 NTTIME pwdlastset3
= 0;
2705 NTTIME pwdlastset5
= 0;
2706 NTTIME pwdlastset21
= 0;
2708 torture_comment(tctx
, "Testing QueryUserInfo%s level 5 and 21 call ",
2709 use_info2
? "2":"");
2711 for (i
=0; i
<ARRAY_SIZE(levels
); i
++) {
2713 struct samr_QueryUserInfo r
;
2714 struct samr_QueryUserInfo2 r2
;
2715 union samr_UserInfo
*info
;
2718 r2
.in
.user_handle
= handle
;
2719 r2
.in
.level
= levels
[i
];
2720 r2
.out
.info
= &info
;
2721 status
= dcerpc_samr_QueryUserInfo2_r(b
, tctx
, &r2
);
2724 r
.in
.user_handle
= handle
;
2725 r
.in
.level
= levels
[i
];
2727 status
= dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
);
2730 if (!NT_STATUS_IS_OK(status
) &&
2731 !NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_INFO_CLASS
)) {
2732 torture_warning(tctx
, "QueryUserInfo%s level %u failed - %s\n",
2733 use_info2
? "2":"", levels
[i
], nt_errstr(status
));
2737 switch (levels
[i
]) {
2739 pwdlastset3
= info
->info3
.last_password_change
;
2742 pwdlastset5
= info
->info5
.last_password_change
;
2745 pwdlastset21
= info
->info21
.last_password_change
;
2751 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2752 "pwdlastset mixup"); */
2753 torture_assert_int_equal(tctx
, pwdlastset5
, pwdlastset21
,
2754 "pwdlastset mixup");
2756 *pwdlastset
= pwdlastset21
;
2758 torture_comment(tctx
, "(pwdlastset: %lld)\n", *pwdlastset
);
2763 static bool test_SamLogon(struct torture_context
*tctx
,
2764 struct dcerpc_pipe
*p
,
2765 struct cli_credentials
*test_credentials
,
2766 NTSTATUS expected_result
,
2770 struct netr_LogonSamLogonEx r
;
2771 union netr_LogonLevel logon
;
2772 union netr_Validation validation
;
2773 uint8_t authoritative
;
2774 struct netr_IdentityInfo identity
;
2775 struct netr_NetworkInfo ninfo
;
2776 struct netr_PasswordInfo pinfo
;
2777 DATA_BLOB names_blob
, chal
, lm_resp
, nt_resp
;
2778 int flags
= CLI_CRED_NTLM_AUTH
;
2779 uint32_t samlogon_flags
= 0;
2780 struct netlogon_creds_CredentialState
*creds
;
2781 struct netr_Authenticator a
;
2782 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2784 torture_assert_ntstatus_ok(tctx
, dcerpc_schannel_creds(p
->conn
->security_state
.generic_state
, tctx
, &creds
), "");
2786 if (lp_client_lanman_auth(tctx
->lp_ctx
)) {
2787 flags
|= CLI_CRED_LANMAN_AUTH
;
2790 if (lp_client_ntlmv2_auth(tctx
->lp_ctx
)) {
2791 flags
|= CLI_CRED_NTLMv2_AUTH
;
2794 cli_credentials_get_ntlm_username_domain(test_credentials
, tctx
,
2795 &identity
.account_name
.string
,
2796 &identity
.domain_name
.string
);
2798 identity
.parameter_control
=
2799 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT
|
2800 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT
;
2801 identity
.logon_id_low
= 0;
2802 identity
.logon_id_high
= 0;
2803 identity
.workstation
.string
= cli_credentials_get_workstation(test_credentials
);
2806 netlogon_creds_client_authenticator(creds
, &a
);
2808 if (!E_deshash(cli_credentials_get_password(test_credentials
), pinfo
.lmpassword
.hash
)) {
2809 ZERO_STRUCT(pinfo
.lmpassword
.hash
);
2811 E_md4hash(cli_credentials_get_password(test_credentials
), pinfo
.ntpassword
.hash
);
2813 if (creds
->negotiate_flags
& NETLOGON_NEG_ARCFOUR
) {
2814 netlogon_creds_arcfour_crypt(creds
, pinfo
.lmpassword
.hash
, 16);
2815 netlogon_creds_arcfour_crypt(creds
, pinfo
.ntpassword
.hash
, 16);
2817 netlogon_creds_des_encrypt(creds
, &pinfo
.lmpassword
);
2818 netlogon_creds_des_encrypt(creds
, &pinfo
.ntpassword
);
2821 pinfo
.identity_info
= identity
;
2822 logon
.password
= &pinfo
;
2824 r
.in
.logon_level
= NetlogonInteractiveInformation
;
2826 generate_random_buffer(ninfo
.challenge
,
2827 sizeof(ninfo
.challenge
));
2828 chal
= data_blob_const(ninfo
.challenge
,
2829 sizeof(ninfo
.challenge
));
2831 names_blob
= NTLMv2_generate_names_blob(tctx
, cli_credentials_get_workstation(test_credentials
),
2832 cli_credentials_get_domain(test_credentials
));
2834 status
= cli_credentials_get_ntlm_response(test_credentials
, tctx
,
2840 torture_assert_ntstatus_ok(tctx
, status
, "cli_credentials_get_ntlm_response failed");
2842 ninfo
.lm
.data
= lm_resp
.data
;
2843 ninfo
.lm
.length
= lm_resp
.length
;
2845 ninfo
.nt
.data
= nt_resp
.data
;
2846 ninfo
.nt
.length
= nt_resp
.length
;
2848 ninfo
.identity_info
= identity
;
2849 logon
.network
= &ninfo
;
2851 r
.in
.logon_level
= NetlogonNetworkInformation
;
2854 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2855 r
.in
.computer_name
= cli_credentials_get_workstation(test_credentials
);
2856 r
.in
.logon
= &logon
;
2857 r
.in
.flags
= &samlogon_flags
;
2858 r
.out
.flags
= &samlogon_flags
;
2859 r
.out
.validation
= &validation
;
2860 r
.out
.authoritative
= &authoritative
;
2862 torture_comment(tctx
, "Testing LogonSamLogon with name %s\n", identity
.account_name
.string
);
2864 r
.in
.validation_level
= 6;
2866 status
= dcerpc_netr_LogonSamLogonEx_r(b
, tctx
, &r
);
2867 if (NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_INFO_CLASS
)) {
2868 r
.in
.validation_level
= 3;
2869 status
= dcerpc_netr_LogonSamLogonEx_r(b
, tctx
, &r
);
2871 if (!NT_STATUS_IS_OK(status
)) {
2872 torture_assert_ntstatus_equal(tctx
, status
, expected_result
, "LogonSamLogonEx failed");
2875 torture_assert_ntstatus_ok(tctx
, status
, "LogonSamLogonEx failed");
2881 static bool test_SamLogon_with_creds(struct torture_context
*tctx
,
2882 struct dcerpc_pipe
*p
,
2883 struct cli_credentials
*machine_creds
,
2884 const char *acct_name
,
2885 const char *password
,
2886 NTSTATUS expected_samlogon_result
,
2890 struct cli_credentials
*test_credentials
;
2892 test_credentials
= cli_credentials_init(tctx
);
2894 cli_credentials_set_workstation(test_credentials
,
2895 cli_credentials_get_workstation(machine_creds
), CRED_SPECIFIED
);
2896 cli_credentials_set_domain(test_credentials
,
2897 cli_credentials_get_domain(machine_creds
), CRED_SPECIFIED
);
2898 cli_credentials_set_username(test_credentials
,
2899 acct_name
, CRED_SPECIFIED
);
2900 cli_credentials_set_password(test_credentials
,
2901 password
, CRED_SPECIFIED
);
2903 torture_comment(tctx
, "testing samlogon (%s) as %s password: %s\n",
2904 interactive
? "interactive" : "network", acct_name
, password
);
2906 if (!test_SamLogon(tctx
, p
, test_credentials
,
2907 expected_samlogon_result
, interactive
)) {
2908 torture_warning(tctx
, "new password did not work\n");
2915 static bool test_SetPassword_level(struct dcerpc_pipe
*p
,
2916 struct dcerpc_pipe
*np
,
2917 struct torture_context
*tctx
,
2918 struct policy_handle
*handle
,
2920 uint32_t fields_present
,
2921 uint8_t password_expired
,
2922 bool *matched_expected_error
,
2924 const char *acct_name
,
2926 struct cli_credentials
*machine_creds
,
2927 bool use_queryinfo2
,
2929 NTSTATUS expected_samlogon_result
)
2931 const char *fields
= NULL
;
2933 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2939 fields
= talloc_asprintf(tctx
, "(fields_present: 0x%08x)",
2946 torture_comment(tctx
, "Testing SetUserInfo%s level %d call "
2947 "(password_expired: %d) %s\n",
2948 use_setinfo2
? "2":"", level
, password_expired
,
2949 fields
? fields
: "");
2951 if (!test_SetUserPass_level_ex(p
, tctx
, handle
, level
,
2956 matched_expected_error
)) {
2960 if (!test_QueryUserInfo_pwdlastset(b
, tctx
, handle
,
2966 if (*matched_expected_error
== true) {
2970 if (!test_SamLogon_with_creds(tctx
, np
,
2974 expected_samlogon_result
,
2982 static bool setup_schannel_netlogon_pipe(struct torture_context
*tctx
,
2983 struct cli_credentials
*credentials
,
2984 struct dcerpc_pipe
**p
)
2986 struct dcerpc_binding
*b
;
2988 torture_assert_ntstatus_ok(tctx
, torture_rpc_binding(tctx
, &b
),
2989 "failed to get rpc binding");
2991 /* We have to use schannel, otherwise the SamLogonEx fails
2992 * with INTERNAL_ERROR */
2994 b
->flags
&= ~DCERPC_AUTH_OPTIONS
;
2995 b
->flags
|= DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_128
;
2997 torture_assert_ntstatus_ok(tctx
,
2998 dcerpc_pipe_connect_b(tctx
, p
, b
, &ndr_table_netlogon
,
2999 credentials
, tctx
->ev
, tctx
->lp_ctx
),
3000 "failed to bind to netlogon");
3005 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe
*p
,
3006 struct torture_context
*tctx
,
3007 uint32_t acct_flags
,
3008 const char *acct_name
,
3009 struct policy_handle
*handle
,
3011 struct cli_credentials
*machine_credentials
)
3013 int s
= 0, q
= 0, f
= 0, l
= 0, z
= 0;
3016 bool set_levels
[] = { false, true };
3017 bool query_levels
[] = { false, true };
3018 uint32_t levels
[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
3019 uint32_t nonzeros
[] = { 1, 24 };
3020 uint32_t fields_present
[] = {
3022 SAMR_FIELD_EXPIRED_FLAG
,
3023 SAMR_FIELD_LAST_PWD_CHANGE
,
3024 SAMR_FIELD_EXPIRED_FLAG
| SAMR_FIELD_LAST_PWD_CHANGE
,
3026 SAMR_FIELD_NT_PASSWORD_PRESENT
,
3027 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
,
3028 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
,
3029 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
,
3030 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_EXPIRED_FLAG
,
3031 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_EXPIRED_FLAG
,
3032 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
| SAMR_FIELD_EXPIRED_FLAG
3034 struct dcerpc_pipe
*np
= NULL
;
3036 if (torture_setting_bool(tctx
, "samba3", false)) {
3038 torture_comment(tctx
, "Samba3 has second granularity, setting delay to: %d\n",
3042 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
3044 /* set to 1 to enable testing for all possible opcode
3045 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3048 #define TEST_ALL_LEVELS 1
3049 #define TEST_SET_LEVELS 1
3050 #define TEST_QUERY_LEVELS 1
3052 #ifdef TEST_ALL_LEVELS
3053 for (l
=0; l
<ARRAY_SIZE(levels
); l
++) {
3055 for (l
=0; l
<(ARRAY_SIZE(levels
))/2; l
++) {
3057 for (z
=0; z
<ARRAY_SIZE(nonzeros
); z
++) {
3058 for (f
=0; f
<ARRAY_SIZE(fields_present
); f
++) {
3059 #ifdef TEST_SET_LEVELS
3060 for (s
=0; s
<ARRAY_SIZE(set_levels
); s
++) {
3062 #ifdef TEST_QUERY_LEVELS
3063 for (q
=0; q
<ARRAY_SIZE(query_levels
); q
++) {
3065 NTTIME pwdlastset_old
= 0;
3066 NTTIME pwdlastset_new
= 0;
3067 bool matched_expected_error
= false;
3068 NTSTATUS expected_samlogon_result
= NT_STATUS_ACCOUNT_DISABLED
;
3070 torture_comment(tctx
, "------------------------------\n"
3071 "Testing pwdLastSet attribute for flags: 0x%08x "
3072 "(s: %d (l: %d), q: %d)\n",
3073 acct_flags
, s
, levels
[l
], q
);
3075 switch (levels
[l
]) {
3079 if (!((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3080 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
))) {
3081 expected_samlogon_result
= NT_STATUS_WRONG_PASSWORD
;
3089 /* set a password and force password change (pwdlastset 0) by
3090 * setting the password expired flag to a non-0 value */
3092 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3096 &matched_expected_error
,
3100 machine_credentials
,
3103 expected_samlogon_result
)) {
3107 if (matched_expected_error
== true) {
3108 /* skipping on expected failure */
3112 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3113 * set without the SAMR_FIELD_EXPIRED_FLAG */
3115 switch (levels
[l
]) {
3119 if ((pwdlastset_new
!= 0) &&
3120 !(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
)) {
3121 torture_comment(tctx
, "not considering a non-0 "
3122 "pwdLastSet as a an error as the "
3123 "SAMR_FIELD_EXPIRED_FLAG has not "
3128 if (pwdlastset_new
!= 0) {
3129 torture_warning(tctx
, "pwdLastSet test failed: "
3130 "expected pwdLastSet 0 but got %lld\n",
3137 switch (levels
[l
]) {
3141 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3142 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3143 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3144 (pwdlastset_old
>= pwdlastset_new
)) {
3145 torture_warning(tctx
, "pwdlastset not increasing\n");
3150 if ((pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3151 (pwdlastset_old
>= pwdlastset_new
)) {
3152 torture_warning(tctx
, "pwdlastset not increasing\n");
3162 /* set a password, pwdlastset needs to get updated (increased
3163 * value), password_expired value used here is 0 */
3165 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3169 &matched_expected_error
,
3173 machine_credentials
,
3176 expected_samlogon_result
)) {
3180 /* when a password has been changed, pwdlastset must not be 0 afterwards
3181 * and must be larger then the old value */
3183 switch (levels
[l
]) {
3188 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3189 * password has been changed, old and new pwdlastset
3190 * need to be the same value */
3192 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
3193 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3194 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3196 torture_assert_int_equal(tctx
, pwdlastset_old
,
3197 pwdlastset_new
, "pwdlastset must be equal");
3201 if (pwdlastset_old
>= pwdlastset_new
) {
3202 torture_warning(tctx
, "pwdLastSet test failed: "
3203 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3204 pwdlastset_old
, pwdlastset_new
);
3207 if (pwdlastset_new
== 0) {
3208 torture_warning(tctx
, "pwdLastSet test failed: "
3209 "expected non-0 pwdlastset, got: %lld\n",
3215 switch (levels
[l
]) {
3219 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3220 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3221 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3222 (pwdlastset_old
>= pwdlastset_new
)) {
3223 torture_warning(tctx
, "pwdlastset not increasing\n");
3228 if ((pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3229 (pwdlastset_old
>= pwdlastset_new
)) {
3230 torture_warning(tctx
, "pwdlastset not increasing\n");
3236 pwdlastset_old
= pwdlastset_new
;
3242 /* set a password, pwdlastset needs to get updated (increased
3243 * value), password_expired value used here is 0 */
3245 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3249 &matched_expected_error
,
3253 machine_credentials
,
3256 expected_samlogon_result
)) {
3260 /* when a password has been changed, pwdlastset must not be 0 afterwards
3261 * and must be larger then the old value */
3263 switch (levels
[l
]) {
3268 /* if no password has been changed, old and new pwdlastset
3269 * need to be the same value */
3271 if (!((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3272 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3274 torture_assert_int_equal(tctx
, pwdlastset_old
,
3275 pwdlastset_new
, "pwdlastset must be equal");
3279 if (pwdlastset_old
>= pwdlastset_new
) {
3280 torture_warning(tctx
, "pwdLastSet test failed: "
3281 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3282 pwdlastset_old
, pwdlastset_new
);
3285 if (pwdlastset_new
== 0) {
3286 torture_warning(tctx
, "pwdLastSet test failed: "
3287 "expected non-0 pwdlastset, got: %lld\n",
3295 /* set a password and force password change (pwdlastset 0) by
3296 * setting the password expired flag to a non-0 value */
3298 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3302 &matched_expected_error
,
3306 machine_credentials
,
3309 expected_samlogon_result
)) {
3313 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3314 * set without the SAMR_FIELD_EXPIRED_FLAG */
3316 switch (levels
[l
]) {
3320 if ((pwdlastset_new
!= 0) &&
3321 !(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
)) {
3322 torture_comment(tctx
, "not considering a non-0 "
3323 "pwdLastSet as a an error as the "
3324 "SAMR_FIELD_EXPIRED_FLAG has not "
3329 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3330 * password has been changed, old and new pwdlastset
3331 * need to be the same value */
3333 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
3334 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3335 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3337 torture_assert_int_equal(tctx
, pwdlastset_old
,
3338 pwdlastset_new
, "pwdlastset must be equal");
3343 if (pwdlastset_old
== pwdlastset_new
) {
3344 torture_warning(tctx
, "pwdLastSet test failed: "
3345 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3346 pwdlastset_old
, pwdlastset_new
);
3350 if (pwdlastset_new
!= 0) {
3351 torture_warning(tctx
, "pwdLastSet test failed: "
3352 "expected pwdLastSet 0, got %lld\n",
3359 switch (levels
[l
]) {
3363 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3364 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3365 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3366 (pwdlastset_old
>= pwdlastset_new
)) {
3367 torture_warning(tctx
, "pwdlastset not increasing\n");
3372 if ((pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3373 (pwdlastset_old
>= pwdlastset_new
)) {
3374 torture_warning(tctx
, "pwdlastset not increasing\n");
3380 /* if the level we are testing does not have a fields_present
3381 * field, skip all fields present tests by setting f to to
3383 switch (levels
[l
]) {
3387 f
= ARRAY_SIZE(fields_present
);
3391 #ifdef TEST_QUERY_LEVELS
3394 #ifdef TEST_SET_LEVELS
3397 } /* fields present */
3401 #undef TEST_SET_LEVELS
3402 #undef TEST_QUERY_LEVELS
3409 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_binding_handle
*b
,
3410 struct torture_context
*tctx
,
3411 struct policy_handle
*handle
,
3412 uint32_t *badpwdcount
)
3414 union samr_UserInfo
*info
;
3415 struct samr_QueryUserInfo r
;
3417 r
.in
.user_handle
= handle
;
3421 torture_comment(tctx
, "Testing QueryUserInfo level %d", r
.in
.level
);
3423 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
3424 "failed to query userinfo");
3426 *badpwdcount
= info
->info3
.bad_password_count
;
3428 torture_comment(tctx
, " (bad password count: %d)\n", *badpwdcount
);
3433 static bool test_SetUserInfo_acct_flags(struct dcerpc_binding_handle
*b
,
3434 struct torture_context
*tctx
,
3435 struct policy_handle
*user_handle
,
3436 uint32_t acct_flags
)
3438 struct samr_SetUserInfo r
;
3439 union samr_UserInfo user_info
;
3441 torture_comment(tctx
, "Testing SetUserInfo level 16\n");
3443 user_info
.info16
.acct_flags
= acct_flags
;
3445 r
.in
.user_handle
= user_handle
;
3447 r
.in
.info
= &user_info
;
3449 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &r
),
3450 "failed to set account flags");
3455 static bool test_reset_badpwdcount(struct dcerpc_pipe
*p
,
3456 struct torture_context
*tctx
,
3457 struct policy_handle
*user_handle
,
3458 uint32_t acct_flags
,
3461 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3463 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
3464 "failed to set password");
3466 torture_comment(tctx
, "Testing SetUserInfo level 16 (enable account)\n");
3468 torture_assert(tctx
,
3469 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
3470 acct_flags
& ~ACB_DISABLED
),
3471 "failed to enable user");
3473 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
3474 "failed to set password");
3479 static bool test_SetDomainInfo(struct dcerpc_binding_handle
*b
,
3480 struct torture_context
*tctx
,
3481 struct policy_handle
*domain_handle
,
3482 enum samr_DomainInfoClass level
,
3483 union samr_DomainInfo
*info
)
3485 struct samr_SetDomainInfo r
;
3487 r
.in
.domain_handle
= domain_handle
;
3491 torture_assert_ntstatus_ok(tctx
,
3492 dcerpc_samr_SetDomainInfo_r(b
, tctx
, &r
),
3493 "failed to set domain info");
3498 static bool test_SetDomainInfo_ntstatus(struct dcerpc_binding_handle
*b
,
3499 struct torture_context
*tctx
,
3500 struct policy_handle
*domain_handle
,
3501 enum samr_DomainInfoClass level
,
3502 union samr_DomainInfo
*info
,
3505 struct samr_SetDomainInfo r
;
3507 r
.in
.domain_handle
= domain_handle
;
3511 torture_assert_ntstatus_equal(tctx
,
3512 dcerpc_samr_SetDomainInfo_r(b
, tctx
, &r
),
3519 static bool test_QueryDomainInfo2_level(struct dcerpc_binding_handle
*b
,
3520 struct torture_context
*tctx
,
3521 struct policy_handle
*domain_handle
,
3522 enum samr_DomainInfoClass level
,
3523 union samr_DomainInfo
**q_info
)
3525 struct samr_QueryDomainInfo2 r
;
3527 r
.in
.domain_handle
= domain_handle
;
3529 r
.out
.info
= q_info
;
3531 torture_assert_ntstatus_ok(tctx
,
3532 dcerpc_samr_QueryDomainInfo2_r(b
, tctx
, &r
),
3533 "failed to query domain info");
3538 static bool test_Password_badpwdcount(struct dcerpc_pipe
*p
,
3539 struct dcerpc_pipe
*np
,
3540 struct torture_context
*tctx
,
3541 uint32_t acct_flags
,
3542 const char *acct_name
,
3543 struct policy_handle
*domain_handle
,
3544 struct policy_handle
*user_handle
,
3546 struct cli_credentials
*machine_credentials
,
3547 const char *comment
,
3550 NTSTATUS expected_success_status
,
3551 struct samr_DomInfo1
*info1
,
3552 struct samr_DomInfo12
*info12
)
3554 union samr_DomainInfo info
;
3557 uint32_t badpwdcount
, tmp
;
3558 uint32_t password_history_length
= 12;
3559 uint32_t lockout_threshold
= 15;
3560 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3562 torture_comment(tctx
, "\nTesting bad pwd count with: %s\n", comment
);
3564 torture_assert(tctx
, password_history_length
< lockout_threshold
,
3565 "password history length needs to be smaller than account lockout threshold for this test");
3570 info
.info1
= *info1
;
3571 info
.info1
.password_history_length
= password_history_length
;
3573 torture_assert(tctx
,
3574 test_SetDomainInfo(b
, tctx
, domain_handle
,
3575 DomainPasswordInformation
, &info
),
3576 "failed to set password history length");
3578 info
.info12
= *info12
;
3579 info
.info12
.lockout_threshold
= lockout_threshold
;
3581 torture_assert(tctx
,
3582 test_SetDomainInfo(b
, tctx
, domain_handle
,
3583 DomainLockoutInformation
, &info
),
3584 "failed to set lockout threshold");
3586 /* reset bad pwd count */
3588 torture_assert(tctx
,
3589 test_reset_badpwdcount(p
, tctx
, user_handle
, acct_flags
, password
), "");
3592 /* enable or disable account */
3594 torture_assert(tctx
,
3595 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
3596 acct_flags
| ACB_DISABLED
),
3597 "failed to disable user");
3599 torture_assert(tctx
,
3600 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
3601 acct_flags
& ~ACB_DISABLED
),
3602 "failed to enable user");
3606 /* setup password history */
3608 passwords
= talloc_array(tctx
, char *, password_history_length
);
3610 for (i
=0; i
< password_history_length
; i
++) {
3612 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
3613 "failed to set password");
3614 passwords
[i
] = talloc_strdup(tctx
, *password
);
3616 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3617 acct_name
, passwords
[i
],
3618 expected_success_status
, interactive
)) {
3619 torture_fail(tctx
, "failed to auth with latest password");
3622 torture_assert(tctx
,
3623 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3625 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3629 /* test with wrong password */
3631 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3632 acct_name
, "random_crap",
3633 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
3634 torture_fail(tctx
, "succeeded to authenticate with wrong password");
3637 torture_assert(tctx
,
3638 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3640 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
3643 /* test with latest good password */
3645 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
3646 passwords
[password_history_length
-1],
3647 expected_success_status
, interactive
)) {
3648 torture_fail(tctx
, "succeeded to authenticate with wrong password");
3651 torture_assert(tctx
,
3652 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3655 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
3657 /* only enabled accounts get the bad pwd count reset upon
3658 * successful logon */
3659 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3665 /* test password history */
3667 for (i
=0; i
< password_history_length
; i
++) {
3669 torture_comment(tctx
, "Testing bad password count behavior with "
3670 "password #%d of #%d\n", i
, password_history_length
);
3672 /* - network samlogon will succeed auth and not
3673 * increase badpwdcount for 2 last entries
3674 * - interactive samlogon only for the last one */
3676 if (i
== password_history_length
- 1 ||
3677 (i
== password_history_length
- 2 && !interactive
)) {
3679 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3680 acct_name
, passwords
[i
],
3681 expected_success_status
, interactive
)) {
3682 torture_fail(tctx
, talloc_asprintf(tctx
, "succeeded to authenticate with old password (#%d of #%d in history)", i
, password_history_length
));
3685 torture_assert(tctx
,
3686 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3689 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
3690 torture_assert_int_equal(tctx
, badpwdcount
, tmp
, "unexpected badpwdcount");
3692 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
3693 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3701 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3702 acct_name
, passwords
[i
],
3703 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
3704 torture_fail(tctx
, talloc_asprintf(tctx
, "succeeded to authenticate with old password (#%d of #%d in history)", i
, password_history_length
));
3707 torture_assert(tctx
,
3708 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3710 /* - network samlogon will fail auth but not increase
3711 * badpwdcount for 3rd last entry
3712 * - interactive samlogon for 3rd and 2nd last entry */
3714 if (i
== password_history_length
- 3 ||
3715 (i
== password_history_length
- 2 && interactive
)) {
3716 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
3717 torture_assert_int_equal(tctx
, badpwdcount
, tmp
, "unexpected badpwdcount");
3719 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
3720 torture_assert_int_equal(tctx
, badpwdcount
, tmp
+ 1, "unexpected badpwdcount");
3729 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe
*p
,
3730 struct torture_context
*tctx
,
3731 uint32_t acct_flags
,
3732 const char *acct_name
,
3733 struct policy_handle
*domain_handle
,
3734 struct policy_handle
*user_handle
,
3736 struct cli_credentials
*machine_credentials
)
3738 union samr_DomainInfo
*q_info
, s_info
;
3739 struct samr_DomInfo1 info1
, _info1
;
3740 struct samr_DomInfo12 info12
, _info12
;
3742 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3743 struct dcerpc_pipe
*np
;
3747 const char *comment
;
3750 NTSTATUS expected_success_status
;
3753 .comment
= "network logon (disabled account)",
3755 .interactive
= false,
3756 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
3759 .comment
= "network logon (enabled account)",
3761 .interactive
= false,
3762 .expected_success_status
= NT_STATUS_OK
3765 .comment
= "interactive logon (disabled account)",
3767 .interactive
= true,
3768 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
3771 .comment
= "interactive logon (enabled account)",
3773 .interactive
= true,
3774 .expected_success_status
= NT_STATUS_OK
3778 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
3780 /* backup old policies */
3782 torture_assert(tctx
,
3783 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
3784 DomainPasswordInformation
, &q_info
),
3785 "failed to query domain info level 1");
3787 info1
= q_info
->info1
;
3790 torture_assert(tctx
,
3791 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
3792 DomainLockoutInformation
, &q_info
),
3793 "failed to query domain info level 12");
3795 info12
= q_info
->info12
;
3800 for (i
=0; i
< ARRAY_SIZE(creds
); i
++) {
3802 /* skip trust tests for now */
3803 if (acct_flags
& ACB_WSTRUST
||
3804 acct_flags
& ACB_SVRTRUST
||
3805 acct_flags
& ACB_DOMTRUST
) {
3809 ret
&= test_Password_badpwdcount(p
, np
, tctx
, acct_flags
, acct_name
,
3810 domain_handle
, user_handle
, password
,
3811 machine_credentials
,
3814 creds
[i
].interactive
,
3815 creds
[i
].expected_success_status
,
3818 torture_warning(tctx
, "TEST #%d (%s) failed\n", i
, creds
[i
].comment
);
3820 torture_comment(tctx
, "TEST #%d (%s) succeeded\n", i
, creds
[i
].comment
);
3824 /* restore policies */
3826 s_info
.info1
= info1
;
3828 torture_assert(tctx
,
3829 test_SetDomainInfo(b
, tctx
, domain_handle
,
3830 DomainPasswordInformation
, &s_info
),
3831 "failed to set password information");
3833 s_info
.info12
= info12
;
3835 torture_assert(tctx
,
3836 test_SetDomainInfo(b
, tctx
, domain_handle
,
3837 DomainLockoutInformation
, &s_info
),
3838 "failed to set lockout information");
3843 static bool test_QueryUserInfo_acct_flags(struct dcerpc_binding_handle
*b
,
3844 struct torture_context
*tctx
,
3845 struct policy_handle
*handle
,
3846 uint32_t *acct_flags
)
3848 union samr_UserInfo
*info
;
3849 struct samr_QueryUserInfo r
;
3851 r
.in
.user_handle
= handle
;
3855 torture_comment(tctx
, "Testing QueryUserInfo level %d", r
.in
.level
);
3857 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
3858 "failed to query userinfo");
3860 *acct_flags
= info
->info16
.acct_flags
;
3862 torture_comment(tctx
, " (acct_flags: 0x%08x)\n", *acct_flags
);
3867 static bool test_Password_lockout(struct dcerpc_pipe
*p
,
3868 struct dcerpc_pipe
*np
,
3869 struct torture_context
*tctx
,
3870 uint32_t acct_flags
,
3871 const char *acct_name
,
3872 struct policy_handle
*domain_handle
,
3873 struct policy_handle
*user_handle
,
3875 struct cli_credentials
*machine_credentials
,
3876 const char *comment
,
3879 NTSTATUS expected_success_status
,
3880 struct samr_DomInfo1
*info1
,
3881 struct samr_DomInfo12
*info12
)
3883 union samr_DomainInfo info
;
3884 uint32_t badpwdcount
;
3885 uint32_t password_history_length
= 1;
3886 uint64_t lockout_threshold
= 1;
3887 uint32_t lockout_seconds
= 5;
3888 uint64_t delta_time_factor
= 10 * 1000 * 1000;
3889 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3891 torture_comment(tctx
, "\nTesting account lockout: %s\n", comment
);
3895 info
.info1
= *info1
;
3897 torture_comment(tctx
, "setting password history lenght.\n");
3898 info
.info1
.password_history_length
= password_history_length
;
3900 torture_assert(tctx
,
3901 test_SetDomainInfo(b
, tctx
, domain_handle
,
3902 DomainPasswordInformation
, &info
),
3903 "failed to set password history length");
3905 info
.info12
= *info12
;
3906 info
.info12
.lockout_threshold
= lockout_threshold
;
3908 /* set lockout duration < lockout window: should fail */
3909 info
.info12
.lockout_duration
= ~(lockout_seconds
* delta_time_factor
);
3910 info
.info12
.lockout_window
= ~((lockout_seconds
+ 1) * delta_time_factor
);
3912 torture_assert(tctx
,
3913 test_SetDomainInfo_ntstatus(b
, tctx
, domain_handle
,
3914 DomainLockoutInformation
, &info
,
3915 NT_STATUS_INVALID_PARAMETER
),
3916 "setting lockout duration < lockout window gave unexpected result");
3918 info
.info12
.lockout_duration
= 0;
3919 info
.info12
.lockout_window
= 0;
3921 torture_assert(tctx
,
3922 test_SetDomainInfo(b
, tctx
, domain_handle
,
3923 DomainLockoutInformation
, &info
),
3924 "failed to set lockout window and duration to 0");
3927 /* set lockout duration of 5 seconds */
3928 info
.info12
.lockout_duration
= ~(lockout_seconds
* delta_time_factor
);
3929 info
.info12
.lockout_window
= ~(lockout_seconds
* delta_time_factor
);
3931 torture_assert(tctx
,
3932 test_SetDomainInfo(b
, tctx
, domain_handle
,
3933 DomainLockoutInformation
, &info
),
3934 "failed to set lockout window and duration to 5 seconds");
3936 /* reset bad pwd count */
3938 torture_assert(tctx
,
3939 test_reset_badpwdcount(p
, tctx
, user_handle
, acct_flags
, password
), "");
3942 /* enable or disable account */
3945 torture_assert(tctx
,
3946 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
3947 acct_flags
| ACB_DISABLED
),
3948 "failed to disable user");
3950 torture_assert(tctx
,
3951 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
3952 acct_flags
& ~ACB_DISABLED
),
3953 "failed to enable user");
3957 /* test logon with right password */
3959 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3960 acct_name
, *password
,
3961 expected_success_status
, interactive
)) {
3962 torture_fail(tctx
, "failed to auth with latest password");
3965 torture_assert(tctx
,
3966 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3967 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3970 /* test with wrong password ==> lockout */
3972 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3973 acct_name
, "random_crap",
3974 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
3975 torture_fail(tctx
, "succeeded to authenticate with wrong password");
3978 torture_assert(tctx
,
3979 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
3980 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
3982 torture_assert(tctx
,
3983 test_QueryUserInfo_acct_flags(b
, tctx
, user_handle
, &acct_flags
), "");
3984 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
3985 "expected account to be locked");
3988 /* test with good password */
3990 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
3992 NT_STATUS_ACCOUNT_LOCKED_OUT
, interactive
))
3994 torture_fail(tctx
, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
3997 /* bad pwd count should not get updated */
3998 torture_assert(tctx
,
3999 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4000 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
4002 /* curiously, windows does _not_ set the autlock flag */
4003 torture_assert(tctx
,
4004 test_QueryUserInfo_acct_flags(b
, tctx
, user_handle
, &acct_flags
), "");
4005 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
4006 "expected account to be locked");
4009 /* with bad password */
4011 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
4012 acct_name
, "random_crap2",
4013 NT_STATUS_ACCOUNT_LOCKED_OUT
, interactive
))
4015 torture_fail(tctx
, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4018 /* bad pwd count should not get updated */
4019 torture_assert(tctx
,
4020 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4021 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
4023 /* curiously, windows does _not_ set the autlock flag */
4024 torture_assert(tctx
,
4025 test_QueryUserInfo_acct_flags(b
, tctx
, user_handle
, &acct_flags
), "");
4026 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
4027 "expected account to be locked");
4030 /* let lockout duration expire ==> unlock */
4032 torture_comment(tctx
, "let lockout duration expire...\n");
4033 sleep(lockout_seconds
+ 1);
4035 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
4037 expected_success_status
, interactive
))
4039 torture_fail(tctx
, "failed to authenticate after lockout expired");
4042 torture_assert(tctx
,
4043 test_QueryUserInfo_acct_flags(b
, tctx
, user_handle
, &acct_flags
), "");
4044 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
4045 "expected account not to be locked");
4050 static bool test_Password_lockout_wrap(struct dcerpc_pipe
*p
,
4051 struct torture_context
*tctx
,
4052 uint32_t acct_flags
,
4053 const char *acct_name
,
4054 struct policy_handle
*domain_handle
,
4055 struct policy_handle
*user_handle
,
4057 struct cli_credentials
*machine_credentials
)
4059 union samr_DomainInfo
*q_info
, s_info
;
4060 struct samr_DomInfo1 info1
, _info1
;
4061 struct samr_DomInfo12 info12
, _info12
;
4063 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4064 struct dcerpc_pipe
*np
;
4068 const char *comment
;
4071 NTSTATUS expected_success_status
;
4074 .comment
= "network logon (disabled account)",
4076 .interactive
= false,
4077 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
4080 .comment
= "network logon (enabled account)",
4082 .interactive
= false,
4083 .expected_success_status
= NT_STATUS_OK
4086 .comment
= "interactive logon (disabled account)",
4088 .interactive
= true,
4089 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
4092 .comment
= "interactive logon (enabled account)",
4094 .interactive
= true,
4095 .expected_success_status
= NT_STATUS_OK
4099 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
4101 /* backup old policies */
4103 torture_assert(tctx
,
4104 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
4105 DomainPasswordInformation
, &q_info
),
4106 "failed to query domain info level 1");
4108 info1
= q_info
->info1
;
4111 torture_assert(tctx
,
4112 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
4113 DomainLockoutInformation
, &q_info
),
4114 "failed to query domain info level 12");
4116 info12
= q_info
->info12
;
4121 for (i
=0; i
< ARRAY_SIZE(creds
); i
++) {
4123 /* skip trust tests for now */
4124 if (acct_flags
& ACB_WSTRUST
||
4125 acct_flags
& ACB_SVRTRUST
||
4126 acct_flags
& ACB_DOMTRUST
) {
4130 ret
&= test_Password_lockout(p
, np
, tctx
, acct_flags
, acct_name
,
4131 domain_handle
, user_handle
, password
,
4132 machine_credentials
,
4135 creds
[i
].interactive
,
4136 creds
[i
].expected_success_status
,
4139 torture_warning(tctx
, "TEST #%d (%s) failed\n", i
, creds
[i
].comment
);
4141 torture_comment(tctx
, "TEST #%d (%s) succeeded\n", i
, creds
[i
].comment
);
4145 /* restore policies */
4147 s_info
.info1
= info1
;
4149 torture_assert(tctx
,
4150 test_SetDomainInfo(b
, tctx
, domain_handle
,
4151 DomainPasswordInformation
, &s_info
),
4152 "failed to set password information");
4154 s_info
.info12
= info12
;
4156 torture_assert(tctx
,
4157 test_SetDomainInfo(b
, tctx
, domain_handle
,
4158 DomainLockoutInformation
, &s_info
),
4159 "failed to set lockout information");
4164 static bool test_DeleteUser_with_privs(struct dcerpc_pipe
*p
,
4165 struct dcerpc_pipe
*lp
,
4166 struct torture_context
*tctx
,
4167 struct policy_handle
*domain_handle
,
4168 struct policy_handle
*lsa_handle
,
4169 struct policy_handle
*user_handle
,
4170 const struct dom_sid
*domain_sid
,
4172 struct cli_credentials
*machine_credentials
)
4176 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4177 struct dcerpc_binding_handle
*lb
= lp
->binding_handle
;
4179 struct policy_handle lsa_acct_handle
;
4180 struct dom_sid
*user_sid
;
4182 user_sid
= dom_sid_add_rid(tctx
, domain_sid
, rid
);
4185 struct lsa_EnumAccountRights r
;
4186 struct lsa_RightSet rights
;
4188 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4190 r
.in
.handle
= lsa_handle
;
4191 r
.in
.sid
= user_sid
;
4192 r
.out
.rights
= &rights
;
4194 status
= dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
);
4195 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
4196 "Expected enum rights for account to fail");
4200 struct lsa_RightSet rights
;
4201 struct lsa_StringLarge names
[2];
4202 struct lsa_AddAccountRights r
;
4204 torture_comment(tctx
, "Testing LSA AddAccountRights\n");
4206 init_lsa_StringLarge(&names
[0], "SeMachineAccountPrivilege");
4207 init_lsa_StringLarge(&names
[1], NULL
);
4210 rights
.names
= names
;
4212 r
.in
.handle
= lsa_handle
;
4213 r
.in
.sid
= user_sid
;
4214 r
.in
.rights
= &rights
;
4216 status
= dcerpc_lsa_AddAccountRights_r(lb
, tctx
, &r
);
4217 torture_assert_ntstatus_ok(tctx
, status
,
4218 "Failed to add privileges");
4222 struct lsa_EnumAccounts r
;
4223 uint32_t resume_handle
= 0;
4224 struct lsa_SidArray lsa_sid_array
;
4226 bool found_sid
= false;
4228 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
4230 r
.in
.handle
= lsa_handle
;
4231 r
.in
.num_entries
= 0x1000;
4232 r
.in
.resume_handle
= &resume_handle
;
4233 r
.out
.sids
= &lsa_sid_array
;
4234 r
.out
.resume_handle
= &resume_handle
;
4236 status
= dcerpc_lsa_EnumAccounts_r(lb
, tctx
, &r
);
4237 torture_assert_ntstatus_ok(tctx
, status
,
4238 "Failed to enum accounts");
4240 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
4241 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
4246 torture_assert(tctx
, found_sid
,
4247 "failed to list privileged account");
4251 struct lsa_EnumAccountRights r
;
4252 struct lsa_RightSet user_rights
;
4254 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4256 r
.in
.handle
= lsa_handle
;
4257 r
.in
.sid
= user_sid
;
4258 r
.out
.rights
= &user_rights
;
4260 status
= dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
);
4261 torture_assert_ntstatus_ok(tctx
, status
,
4262 "Failed to enum rights for account");
4264 if (user_rights
.count
< 1) {
4265 torture_warning(tctx
, "failed to find newly added rights");
4271 struct lsa_OpenAccount r
;
4273 torture_comment(tctx
, "Testing LSA OpenAccount\n");
4275 r
.in
.handle
= lsa_handle
;
4276 r
.in
.sid
= user_sid
;
4277 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4278 r
.out
.acct_handle
= &lsa_acct_handle
;
4280 status
= dcerpc_lsa_OpenAccount_r(lb
, tctx
, &r
);
4281 torture_assert_ntstatus_ok(tctx
, status
,
4282 "Failed to open lsa account");
4286 struct lsa_GetSystemAccessAccount r
;
4287 uint32_t access_mask
;
4289 torture_comment(tctx
, "Testing LSA GetSystemAccessAccount\n");
4291 r
.in
.handle
= &lsa_acct_handle
;
4292 r
.out
.access_mask
= &access_mask
;
4294 status
= dcerpc_lsa_GetSystemAccessAccount_r(lb
, tctx
, &r
);
4295 torture_assert_ntstatus_ok(tctx
, status
,
4296 "Failed to get lsa system access account");
4302 torture_comment(tctx
, "Testing LSA Close\n");
4304 r
.in
.handle
= &lsa_acct_handle
;
4305 r
.out
.handle
= &lsa_acct_handle
;
4307 status
= dcerpc_lsa_Close_r(lb
, tctx
, &r
);
4308 torture_assert_ntstatus_ok(tctx
, status
,
4309 "Failed to close lsa");
4313 struct samr_DeleteUser r
;
4315 torture_comment(tctx
, "Testing SAMR DeleteUser\n");
4317 r
.in
.user_handle
= user_handle
;
4318 r
.out
.user_handle
= user_handle
;
4320 status
= dcerpc_samr_DeleteUser_r(b
, tctx
, &r
);
4321 torture_assert_ntstatus_ok(tctx
, status
, "Delete User failed");
4325 struct lsa_EnumAccounts r
;
4326 uint32_t resume_handle
= 0;
4327 struct lsa_SidArray lsa_sid_array
;
4329 bool found_sid
= false;
4331 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
4333 r
.in
.handle
= lsa_handle
;
4334 r
.in
.num_entries
= 0x1000;
4335 r
.in
.resume_handle
= &resume_handle
;
4336 r
.out
.sids
= &lsa_sid_array
;
4337 r
.out
.resume_handle
= &resume_handle
;
4339 status
= dcerpc_lsa_EnumAccounts_r(lb
, tctx
, &r
);
4340 torture_assert_ntstatus_ok(tctx
, status
,
4341 "Failed to enum accounts");
4343 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
4344 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
4349 torture_assert(tctx
, found_sid
,
4350 "failed to list privileged account");
4354 struct lsa_EnumAccountRights r
;
4355 struct lsa_RightSet user_rights
;
4357 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4359 r
.in
.handle
= lsa_handle
;
4360 r
.in
.sid
= user_sid
;
4361 r
.out
.rights
= &user_rights
;
4363 status
= dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
);
4364 torture_assert_ntstatus_ok(tctx
, status
,
4365 "Failed to enum rights for account");
4367 if (user_rights
.count
< 1) {
4368 torture_warning(tctx
, "failed to find newly added rights");
4374 struct lsa_OpenAccount r
;
4376 torture_comment(tctx
, "Testing LSA OpenAccount\n");
4378 r
.in
.handle
= lsa_handle
;
4379 r
.in
.sid
= user_sid
;
4380 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4381 r
.out
.acct_handle
= &lsa_acct_handle
;
4383 status
= dcerpc_lsa_OpenAccount_r(lb
, tctx
, &r
);
4384 torture_assert_ntstatus_ok(tctx
, status
,
4385 "Failed to open lsa account");
4389 struct lsa_GetSystemAccessAccount r
;
4390 uint32_t access_mask
;
4392 torture_comment(tctx
, "Testing LSA GetSystemAccessAccount\n");
4394 r
.in
.handle
= &lsa_acct_handle
;
4395 r
.out
.access_mask
= &access_mask
;
4397 status
= dcerpc_lsa_GetSystemAccessAccount_r(lb
, tctx
, &r
);
4398 torture_assert_ntstatus_ok(tctx
, status
,
4399 "Failed to get lsa system access account");
4403 struct lsa_DeleteObject r
;
4405 torture_comment(tctx
, "Testing LSA DeleteObject\n");
4407 r
.in
.handle
= &lsa_acct_handle
;
4408 r
.out
.handle
= &lsa_acct_handle
;
4410 status
= dcerpc_lsa_DeleteObject_r(lb
, tctx
, &r
);
4411 torture_assert_ntstatus_ok(tctx
, status
,
4412 "Failed to delete object");
4416 struct lsa_EnumAccounts r
;
4417 uint32_t resume_handle
= 0;
4418 struct lsa_SidArray lsa_sid_array
;
4420 bool found_sid
= false;
4422 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
4424 r
.in
.handle
= lsa_handle
;
4425 r
.in
.num_entries
= 0x1000;
4426 r
.in
.resume_handle
= &resume_handle
;
4427 r
.out
.sids
= &lsa_sid_array
;
4428 r
.out
.resume_handle
= &resume_handle
;
4430 status
= dcerpc_lsa_EnumAccounts_r(lb
, tctx
, &r
);
4431 torture_assert_ntstatus_ok(tctx
, status
,
4432 "Failed to enum accounts");
4434 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
4435 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
4440 torture_assert(tctx
, !found_sid
,
4441 "should not have listed privileged account");
4445 struct lsa_EnumAccountRights r
;
4446 struct lsa_RightSet user_rights
;
4448 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4450 r
.in
.handle
= lsa_handle
;
4451 r
.in
.sid
= user_sid
;
4452 r
.out
.rights
= &user_rights
;
4454 status
= dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
);
4455 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
4456 "Failed to enum rights for account");
4462 static bool test_user_ops(struct dcerpc_pipe
*p
,
4463 struct torture_context
*tctx
,
4464 struct policy_handle
*user_handle
,
4465 struct policy_handle
*domain_handle
,
4466 const struct dom_sid
*domain_sid
,
4467 uint32_t base_acct_flags
,
4468 const char *base_acct_name
, enum torture_samr_choice which_ops
,
4469 struct cli_credentials
*machine_credentials
)
4471 char *password
= NULL
;
4472 struct samr_QueryUserInfo q
;
4473 union samr_UserInfo
*info
;
4475 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4480 const uint32_t password_fields
[] = {
4481 SAMR_FIELD_NT_PASSWORD_PRESENT
,
4482 SAMR_FIELD_LM_PASSWORD_PRESENT
,
4483 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
,
4487 status
= test_LookupName(b
, tctx
, domain_handle
, base_acct_name
, &rid
);
4488 if (!NT_STATUS_IS_OK(status
)) {
4492 switch (which_ops
) {
4493 case TORTURE_SAMR_USER_ATTRIBUTES
:
4494 if (!test_QuerySecurity(b
, tctx
, user_handle
)) {
4498 if (!test_QueryUserInfo(b
, tctx
, user_handle
)) {
4502 if (!test_QueryUserInfo2(b
, tctx
, user_handle
)) {
4506 if (!test_SetUserInfo(b
, tctx
, user_handle
, base_acct_flags
,
4511 if (!test_GetUserPwInfo(b
, tctx
, user_handle
)) {
4515 if (!test_TestPrivateFunctionsUser(b
, tctx
, user_handle
)) {
4519 if (!test_SetUserPass(p
, tctx
, user_handle
, &password
)) {
4523 case TORTURE_SAMR_PASSWORDS
:
4524 if (base_acct_flags
& (ACB_WSTRUST
|ACB_DOMTRUST
|ACB_SVRTRUST
)) {
4525 char simple_pass
[9];
4526 char *v
= generate_random_str(tctx
, 1);
4528 ZERO_STRUCT(simple_pass
);
4529 memset(simple_pass
, *v
, sizeof(simple_pass
) - 1);
4531 torture_comment(tctx
, "Testing machine account password policy rules\n");
4533 /* Workstation trust accounts don't seem to need to honour password quality policy */
4534 if (!test_SetUserPassEx(p
, tctx
, user_handle
, true, &password
)) {
4538 if (!test_ChangePasswordUser2(p
, tctx
, base_acct_name
, &password
, simple_pass
, false)) {
4542 /* reset again, to allow another 'user' password change */
4543 if (!test_SetUserPassEx(p
, tctx
, user_handle
, true, &password
)) {
4547 /* Try a 'short' password */
4548 if (!test_ChangePasswordUser2(p
, tctx
, base_acct_name
, &password
, samr_rand_pass(tctx
, 4), false)) {
4552 /* Try a compleatly random password */
4553 if (!test_ChangePasswordRandomBytes(p
, tctx
, base_acct_name
, user_handle
, &password
)) {
4558 for (i
= 0; password_fields
[i
]; i
++) {
4559 if (!test_SetUserPass_23(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
4563 /* check it was set right */
4564 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4569 for (i
= 0; password_fields
[i
]; i
++) {
4570 if (!test_SetUserPass_25(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
4574 /* check it was set right */
4575 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4580 if (!test_SetUserPassEx(p
, tctx
, user_handle
, false, &password
)) {
4584 if (!test_ChangePassword(p
, tctx
, base_acct_name
, domain_handle
, &password
)) {
4588 if (torture_setting_bool(tctx
, "samba4", false)) {
4589 torture_comment(tctx
, "skipping Set Password level 18 and 21 against Samba4\n");
4592 if (!test_SetUserPass_18(p
, tctx
, user_handle
, &password
)) {
4596 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4600 for (i
= 0; password_fields
[i
]; i
++) {
4602 if (password_fields
[i
] == SAMR_FIELD_LM_PASSWORD_PRESENT
) {
4603 /* we need to skip as that would break
4604 * the ChangePasswordUser3 verify */
4608 if (!test_SetUserPass_21(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
4612 /* check it was set right */
4613 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4619 q
.in
.user_handle
= user_handle
;
4623 status
= dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
);
4624 if (!NT_STATUS_IS_OK(status
)) {
4625 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
4626 q
.in
.level
, nt_errstr(status
));
4629 uint32_t expected_flags
= (base_acct_flags
| ACB_PWNOTREQ
| ACB_DISABLED
);
4630 if ((info
->info5
.acct_flags
) != expected_flags
) {
4631 torture_warning(tctx
, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4632 info
->info5
.acct_flags
,
4635 if (!torture_setting_bool(tctx
, "samba3", false)) {
4639 if (info
->info5
.rid
!= rid
) {
4640 torture_warning(tctx
, "QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
4641 info
->info5
.rid
, rid
);
4648 case TORTURE_SAMR_PASSWORDS_PWDLASTSET
:
4650 /* test last password change timestamp behaviour */
4651 if (!test_SetPassword_pwdlastset(p
, tctx
, base_acct_flags
,
4653 user_handle
, &password
,
4654 machine_credentials
)) {
4659 torture_comment(tctx
, "pwdLastSet test succeeded\n");
4661 torture_warning(tctx
, "pwdLastSet test failed\n");
4666 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
:
4668 /* test bad pwd count change behaviour */
4669 if (!test_Password_badpwdcount_wrap(p
, tctx
, base_acct_flags
,
4672 user_handle
, &password
,
4673 machine_credentials
)) {
4678 torture_comment(tctx
, "badPwdCount test succeeded\n");
4680 torture_warning(tctx
, "badPwdCount test failed\n");
4685 case TORTURE_SAMR_PASSWORDS_LOCKOUT
:
4687 if (!test_Password_lockout_wrap(p
, tctx
, base_acct_flags
,
4690 user_handle
, &password
,
4691 machine_credentials
))
4697 torture_comment(tctx
, "lockout test succeeded\n");
4699 torture_warning(tctx
, "lockout test failed\n");
4705 case TORTURE_SAMR_USER_PRIVILEGES
: {
4707 struct dcerpc_pipe
*lp
;
4708 struct policy_handle
*lsa_handle
;
4709 struct dcerpc_binding_handle
*lb
;
4711 status
= torture_rpc_connection(tctx
, &lp
, &ndr_table_lsarpc
);
4712 torture_assert_ntstatus_ok(tctx
, status
, "Failed to open LSA pipe");
4713 lb
= lp
->binding_handle
;
4715 if (!test_lsa_OpenPolicy2(lb
, tctx
, &lsa_handle
)) {
4719 if (!test_DeleteUser_with_privs(p
, lp
, tctx
,
4720 domain_handle
, lsa_handle
, user_handle
,
4722 machine_credentials
)) {
4726 if (!test_lsa_Close(lb
, tctx
, lsa_handle
)) {
4731 torture_warning(tctx
, "privileged user delete test failed\n");
4736 case TORTURE_SAMR_OTHER
:
4737 case TORTURE_SAMR_MANY_ACCOUNTS
:
4738 case TORTURE_SAMR_MANY_GROUPS
:
4739 case TORTURE_SAMR_MANY_ALIASES
:
4740 /* We just need the account to exist */
4746 static bool test_alias_ops(struct dcerpc_binding_handle
*b
,
4747 struct torture_context
*tctx
,
4748 struct policy_handle
*alias_handle
,
4749 const struct dom_sid
*domain_sid
)
4753 if (!torture_setting_bool(tctx
, "samba3", false)) {
4754 if (!test_QuerySecurity(b
, tctx
, alias_handle
)) {
4759 if (!test_QueryAliasInfo(b
, tctx
, alias_handle
)) {
4763 if (!test_SetAliasInfo(b
, tctx
, alias_handle
)) {
4767 if (!test_AddMemberToAlias(b
, tctx
, alias_handle
, domain_sid
)) {
4771 if (torture_setting_bool(tctx
, "samba3", false) ||
4772 torture_setting_bool(tctx
, "samba4", false)) {
4773 torture_comment(tctx
, "skipping MultipleMembers Alias tests against Samba\n");
4777 if (!test_AddMultipleMembersToAlias(b
, tctx
, alias_handle
)) {
4785 static bool test_DeleteUser(struct dcerpc_binding_handle
*b
,
4786 struct torture_context
*tctx
,
4787 struct policy_handle
*user_handle
)
4789 struct samr_DeleteUser d
;
4791 torture_comment(tctx
, "Testing DeleteUser\n");
4793 d
.in
.user_handle
= user_handle
;
4794 d
.out
.user_handle
= user_handle
;
4796 status
= dcerpc_samr_DeleteUser_r(b
, tctx
, &d
);
4797 torture_assert_ntstatus_ok(tctx
, status
, "DeleteUser");
4802 bool test_DeleteUser_byname(struct dcerpc_binding_handle
*b
,
4803 struct torture_context
*tctx
,
4804 struct policy_handle
*handle
, const char *name
)
4807 struct samr_DeleteUser d
;
4808 struct policy_handle user_handle
;
4811 status
= test_LookupName(b
, tctx
, handle
, name
, &rid
);
4812 if (!NT_STATUS_IS_OK(status
)) {
4816 status
= test_OpenUser_byname(b
, tctx
, handle
, name
, &user_handle
);
4817 if (!NT_STATUS_IS_OK(status
)) {
4821 d
.in
.user_handle
= &user_handle
;
4822 d
.out
.user_handle
= &user_handle
;
4823 status
= dcerpc_samr_DeleteUser_r(b
, tctx
, &d
);
4824 if (!NT_STATUS_IS_OK(status
)) {
4831 torture_warning(tctx
, "DeleteUser_byname(%s) failed - %s\n", name
, nt_errstr(status
));
4836 static bool test_DeleteGroup_byname(struct dcerpc_binding_handle
*b
,
4837 struct torture_context
*tctx
,
4838 struct policy_handle
*handle
, const char *name
)
4841 struct samr_OpenGroup r
;
4842 struct samr_DeleteDomainGroup d
;
4843 struct policy_handle group_handle
;
4846 status
= test_LookupName(b
, tctx
, handle
, name
, &rid
);
4847 if (!NT_STATUS_IS_OK(status
)) {
4851 r
.in
.domain_handle
= handle
;
4852 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4854 r
.out
.group_handle
= &group_handle
;
4855 status
= dcerpc_samr_OpenGroup_r(b
, tctx
, &r
);
4856 if (!NT_STATUS_IS_OK(status
)) {
4860 d
.in
.group_handle
= &group_handle
;
4861 d
.out
.group_handle
= &group_handle
;
4862 status
= dcerpc_samr_DeleteDomainGroup_r(b
, tctx
, &d
);
4863 if (!NT_STATUS_IS_OK(status
)) {
4870 torture_warning(tctx
, "DeleteGroup_byname(%s) failed - %s\n", name
, nt_errstr(status
));
4875 static bool test_DeleteAlias_byname(struct dcerpc_binding_handle
*b
,
4876 struct torture_context
*tctx
,
4877 struct policy_handle
*domain_handle
,
4881 struct samr_OpenAlias r
;
4882 struct samr_DeleteDomAlias d
;
4883 struct policy_handle alias_handle
;
4886 torture_comment(tctx
, "testing DeleteAlias_byname\n");
4888 status
= test_LookupName(b
, tctx
, domain_handle
, name
, &rid
);
4889 if (!NT_STATUS_IS_OK(status
)) {
4893 r
.in
.domain_handle
= domain_handle
;
4894 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4896 r
.out
.alias_handle
= &alias_handle
;
4897 status
= dcerpc_samr_OpenAlias_r(b
, tctx
, &r
);
4898 if (!NT_STATUS_IS_OK(status
)) {
4902 d
.in
.alias_handle
= &alias_handle
;
4903 d
.out
.alias_handle
= &alias_handle
;
4904 status
= dcerpc_samr_DeleteDomAlias_r(b
, tctx
, &d
);
4905 if (!NT_STATUS_IS_OK(status
)) {
4912 torture_warning(tctx
, "DeleteAlias_byname(%s) failed - %s\n", name
, nt_errstr(status
));
4916 static bool test_DeleteAlias(struct dcerpc_binding_handle
*b
,
4917 struct torture_context
*tctx
,
4918 struct policy_handle
*alias_handle
)
4920 struct samr_DeleteDomAlias d
;
4924 torture_comment(tctx
, "Testing DeleteAlias\n");
4926 d
.in
.alias_handle
= alias_handle
;
4927 d
.out
.alias_handle
= alias_handle
;
4929 status
= dcerpc_samr_DeleteDomAlias_r(b
, tctx
, &d
);
4930 if (!NT_STATUS_IS_OK(status
)) {
4931 torture_warning(tctx
, "DeleteAlias failed - %s\n", nt_errstr(status
));
4938 static bool test_CreateAlias(struct dcerpc_binding_handle
*b
,
4939 struct torture_context
*tctx
,
4940 struct policy_handle
*domain_handle
,
4941 const char *alias_name
,
4942 struct policy_handle
*alias_handle
,
4943 const struct dom_sid
*domain_sid
,
4947 struct samr_CreateDomAlias r
;
4948 struct lsa_String name
;
4952 init_lsa_String(&name
, alias_name
);
4953 r
.in
.domain_handle
= domain_handle
;
4954 r
.in
.alias_name
= &name
;
4955 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4956 r
.out
.alias_handle
= alias_handle
;
4959 torture_comment(tctx
, "Testing CreateAlias (%s)\n", r
.in
.alias_name
->string
);
4961 status
= dcerpc_samr_CreateDomAlias_r(b
, tctx
, &r
);
4963 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
4964 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
4965 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.alias_name
->string
);
4968 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.alias_name
->string
,
4974 if (NT_STATUS_EQUAL(status
, NT_STATUS_ALIAS_EXISTS
)) {
4975 if (!test_DeleteAlias_byname(b
, tctx
, domain_handle
, r
.in
.alias_name
->string
)) {
4978 status
= dcerpc_samr_CreateDomAlias_r(b
, tctx
, &r
);
4981 if (!NT_STATUS_IS_OK(status
)) {
4982 torture_warning(tctx
, "CreateAlias failed - %s\n", nt_errstr(status
));
4990 if (!test_alias_ops(b
, tctx
, alias_handle
, domain_sid
)) {
4997 static bool test_ChangePassword(struct dcerpc_pipe
*p
,
4998 struct torture_context
*tctx
,
4999 const char *acct_name
,
5000 struct policy_handle
*domain_handle
, char **password
)
5003 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5009 if (!test_ChangePasswordUser(b
, tctx
, acct_name
, domain_handle
, password
)) {
5013 if (!test_ChangePasswordUser2(p
, tctx
, acct_name
, password
, 0, true)) {
5017 if (!test_OemChangePasswordUser2(p
, tctx
, acct_name
, domain_handle
, password
)) {
5021 /* test what happens when setting the old password again */
5022 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, *password
, 0, true)) {
5027 char simple_pass
[9];
5028 char *v
= generate_random_str(tctx
, 1);
5030 ZERO_STRUCT(simple_pass
);
5031 memset(simple_pass
, *v
, sizeof(simple_pass
) - 1);
5033 /* test what happens when picking a simple password */
5034 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, simple_pass
, 0, true)) {
5039 /* set samr_SetDomainInfo level 1 with min_length 5 */
5041 struct samr_QueryDomainInfo r
;
5042 union samr_DomainInfo
*info
= NULL
;
5043 struct samr_SetDomainInfo s
;
5044 uint16_t len_old
, len
;
5045 uint32_t pwd_prop_old
;
5046 int64_t min_pwd_age_old
;
5051 r
.in
.domain_handle
= domain_handle
;
5055 torture_comment(tctx
, "testing samr_QueryDomainInfo level 1\n");
5056 status
= dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &r
);
5057 if (!NT_STATUS_IS_OK(status
)) {
5061 s
.in
.domain_handle
= domain_handle
;
5065 /* remember the old min length, so we can reset it */
5066 len_old
= s
.in
.info
->info1
.min_password_length
;
5067 s
.in
.info
->info1
.min_password_length
= len
;
5068 pwd_prop_old
= s
.in
.info
->info1
.password_properties
;
5069 /* turn off password complexity checks for this test */
5070 s
.in
.info
->info1
.password_properties
&= ~DOMAIN_PASSWORD_COMPLEX
;
5072 min_pwd_age_old
= s
.in
.info
->info1
.min_password_age
;
5073 s
.in
.info
->info1
.min_password_age
= 0;
5075 torture_comment(tctx
, "testing samr_SetDomainInfo level 1\n");
5076 status
= dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
);
5077 if (!NT_STATUS_IS_OK(status
)) {
5081 torture_comment(tctx
, "calling test_ChangePasswordUser3 with too short password\n");
5083 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, len
- 1, password
, NULL
, 0, true)) {
5087 s
.in
.info
->info1
.min_password_length
= len_old
;
5088 s
.in
.info
->info1
.password_properties
= pwd_prop_old
;
5089 s
.in
.info
->info1
.min_password_age
= min_pwd_age_old
;
5091 torture_comment(tctx
, "testing samr_SetDomainInfo level 1\n");
5092 status
= dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
);
5093 if (!NT_STATUS_IS_OK(status
)) {
5101 struct samr_OpenUser r
;
5102 struct samr_QueryUserInfo q
;
5103 union samr_UserInfo
*info
;
5104 struct samr_LookupNames n
;
5105 struct policy_handle user_handle
;
5106 struct samr_Ids rids
, types
;
5108 n
.in
.domain_handle
= domain_handle
;
5110 n
.in
.names
= talloc_array(tctx
, struct lsa_String
, 1);
5111 n
.in
.names
[0].string
= acct_name
;
5113 n
.out
.types
= &types
;
5115 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
5116 if (!NT_STATUS_IS_OK(status
)) {
5117 torture_warning(tctx
, "LookupNames failed - %s\n", nt_errstr(status
));
5121 r
.in
.domain_handle
= domain_handle
;
5122 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5123 r
.in
.rid
= n
.out
.rids
->ids
[0];
5124 r
.out
.user_handle
= &user_handle
;
5126 status
= dcerpc_samr_OpenUser_r(b
, tctx
, &r
);
5127 if (!NT_STATUS_IS_OK(status
)) {
5128 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", n
.out
.rids
->ids
[0], nt_errstr(status
));
5132 q
.in
.user_handle
= &user_handle
;
5136 status
= dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
);
5137 if (!NT_STATUS_IS_OK(status
)) {
5138 torture_warning(tctx
, "QueryUserInfo failed - %s\n", nt_errstr(status
));
5142 torture_comment(tctx
, "calling test_ChangePasswordUser3 with too early password change\n");
5144 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
,
5145 info
->info5
.last_password_change
, true)) {
5150 /* we change passwords twice - this has the effect of verifying
5151 they were changed correctly for the final call */
5152 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
, 0, true)) {
5156 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
, 0, true)) {
5163 static bool test_CreateUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5164 struct policy_handle
*domain_handle
,
5165 const char *user_name
,
5166 struct policy_handle
*user_handle_out
,
5167 struct dom_sid
*domain_sid
,
5168 enum torture_samr_choice which_ops
,
5169 struct cli_credentials
*machine_credentials
,
5173 TALLOC_CTX
*user_ctx
;
5176 struct samr_CreateUser r
;
5177 struct samr_QueryUserInfo q
;
5178 union samr_UserInfo
*info
;
5179 struct samr_DeleteUser d
;
5182 /* This call creates a 'normal' account - check that it really does */
5183 const uint32_t acct_flags
= ACB_NORMAL
;
5184 struct lsa_String name
;
5186 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5188 struct policy_handle user_handle
;
5189 user_ctx
= talloc_named(tctx
, 0, "test_CreateUser2 per-user context");
5190 init_lsa_String(&name
, user_name
);
5192 r
.in
.domain_handle
= domain_handle
;
5193 r
.in
.account_name
= &name
;
5194 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5195 r
.out
.user_handle
= &user_handle
;
5198 torture_comment(tctx
, "Testing CreateUser(%s)\n", r
.in
.account_name
->string
);
5200 status
= dcerpc_samr_CreateUser_r(b
, user_ctx
, &r
);
5202 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
5203 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) || NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
5204 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.account_name
->string
);
5207 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.account_name
->string
,
5213 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_EXISTS
)) {
5214 if (!test_DeleteUser_byname(b
, tctx
, domain_handle
, r
.in
.account_name
->string
)) {
5215 talloc_free(user_ctx
);
5218 status
= dcerpc_samr_CreateUser_r(b
, user_ctx
, &r
);
5221 if (!NT_STATUS_IS_OK(status
)) {
5222 talloc_free(user_ctx
);
5223 torture_warning(tctx
, "CreateUser failed - %s\n", nt_errstr(status
));
5228 if (user_handle_out
) {
5229 *user_handle_out
= user_handle
;
5235 q
.in
.user_handle
= &user_handle
;
5239 status
= dcerpc_samr_QueryUserInfo_r(b
, user_ctx
, &q
);
5240 if (!NT_STATUS_IS_OK(status
)) {
5241 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
5242 q
.in
.level
, nt_errstr(status
));
5245 if ((info
->info16
.acct_flags
& acct_flags
) != acct_flags
) {
5246 torture_warning(tctx
, "QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5247 info
->info16
.acct_flags
,
5253 if (!test_user_ops(p
, tctx
, &user_handle
, domain_handle
,
5254 domain_sid
, acct_flags
, name
.string
, which_ops
,
5255 machine_credentials
)) {
5259 if (user_handle_out
) {
5260 *user_handle_out
= user_handle
;
5262 torture_comment(tctx
, "Testing DeleteUser (createuser test)\n");
5264 d
.in
.user_handle
= &user_handle
;
5265 d
.out
.user_handle
= &user_handle
;
5267 status
= dcerpc_samr_DeleteUser_r(b
, user_ctx
, &d
);
5268 if (!NT_STATUS_IS_OK(status
)) {
5269 torture_warning(tctx
, "DeleteUser failed - %s\n", nt_errstr(status
));
5276 talloc_free(user_ctx
);
5282 static bool test_CreateUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5283 struct policy_handle
*domain_handle
,
5284 struct dom_sid
*domain_sid
,
5285 enum torture_samr_choice which_ops
,
5286 struct cli_credentials
*machine_credentials
)
5289 struct samr_CreateUser2 r
;
5290 struct samr_QueryUserInfo q
;
5291 union samr_UserInfo
*info
;
5292 struct samr_DeleteUser d
;
5293 struct policy_handle user_handle
;
5295 struct lsa_String name
;
5298 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5301 uint32_t acct_flags
;
5302 const char *account_name
;
5304 } account_types
[] = {
5305 { ACB_NORMAL
, TEST_ACCOUNT_NAME
, NT_STATUS_OK
},
5306 { ACB_NORMAL
| ACB_DISABLED
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5307 { ACB_NORMAL
| ACB_PWNOEXP
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5308 { ACB_WSTRUST
, TEST_MACHINENAME
, NT_STATUS_OK
},
5309 { ACB_WSTRUST
| ACB_DISABLED
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5310 { ACB_WSTRUST
| ACB_PWNOEXP
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5311 { ACB_SVRTRUST
, TEST_MACHINENAME
, NT_STATUS_OK
},
5312 { ACB_SVRTRUST
| ACB_DISABLED
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5313 { ACB_SVRTRUST
| ACB_PWNOEXP
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5314 { ACB_DOMTRUST
, TEST_DOMAINNAME
, NT_STATUS_ACCESS_DENIED
},
5315 { ACB_DOMTRUST
| ACB_DISABLED
, TEST_DOMAINNAME
, NT_STATUS_INVALID_PARAMETER
},
5316 { ACB_DOMTRUST
| ACB_PWNOEXP
, TEST_DOMAINNAME
, NT_STATUS_INVALID_PARAMETER
},
5317 { 0, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5318 { ACB_DISABLED
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5319 { 0, NULL
, NT_STATUS_INVALID_PARAMETER
}
5322 for (i
= 0; account_types
[i
].account_name
; i
++) {
5323 TALLOC_CTX
*user_ctx
;
5324 uint32_t acct_flags
= account_types
[i
].acct_flags
;
5325 uint32_t access_granted
;
5326 user_ctx
= talloc_named(tctx
, 0, "test_CreateUser2 per-user context");
5327 init_lsa_String(&name
, account_types
[i
].account_name
);
5329 r
.in
.domain_handle
= domain_handle
;
5330 r
.in
.account_name
= &name
;
5331 r
.in
.acct_flags
= acct_flags
;
5332 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5333 r
.out
.user_handle
= &user_handle
;
5334 r
.out
.access_granted
= &access_granted
;
5337 torture_comment(tctx
, "Testing CreateUser2(%s, 0x%x)\n", r
.in
.account_name
->string
, acct_flags
);
5339 status
= dcerpc_samr_CreateUser2_r(b
, user_ctx
, &r
);
5341 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
5342 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) || NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
5343 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.account_name
->string
);
5346 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.account_name
->string
,
5353 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_EXISTS
)) {
5354 if (!test_DeleteUser_byname(b
, tctx
, domain_handle
, r
.in
.account_name
->string
)) {
5355 talloc_free(user_ctx
);
5359 status
= dcerpc_samr_CreateUser2_r(b
, user_ctx
, &r
);
5362 if (!NT_STATUS_EQUAL(status
, account_types
[i
].nt_status
)) {
5363 torture_warning(tctx
, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5364 nt_errstr(status
), nt_errstr(account_types
[i
].nt_status
));
5368 if (NT_STATUS_IS_OK(status
)) {
5369 q
.in
.user_handle
= &user_handle
;
5373 status
= dcerpc_samr_QueryUserInfo_r(b
, user_ctx
, &q
);
5374 if (!NT_STATUS_IS_OK(status
)) {
5375 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
5376 q
.in
.level
, nt_errstr(status
));
5379 uint32_t expected_flags
= (acct_flags
| ACB_PWNOTREQ
| ACB_DISABLED
);
5380 if (acct_flags
== ACB_NORMAL
) {
5381 expected_flags
|= ACB_PW_EXPIRED
;
5383 if ((info
->info5
.acct_flags
) != expected_flags
) {
5384 torture_warning(tctx
, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5385 info
->info5
.acct_flags
,
5389 switch (acct_flags
) {
5391 if (info
->info5
.primary_gid
!= DOMAIN_RID_DCS
) {
5392 torture_warning(tctx
, "QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5393 DOMAIN_RID_DCS
, info
->info5
.primary_gid
);
5398 if (info
->info5
.primary_gid
!= DOMAIN_RID_DOMAIN_MEMBERS
) {
5399 torture_warning(tctx
, "QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5400 DOMAIN_RID_DOMAIN_MEMBERS
, info
->info5
.primary_gid
);
5405 if (info
->info5
.primary_gid
!= DOMAIN_RID_USERS
) {
5406 torture_warning(tctx
, "QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5407 DOMAIN_RID_USERS
, info
->info5
.primary_gid
);
5414 if (!test_user_ops(p
, tctx
, &user_handle
, domain_handle
,
5415 domain_sid
, acct_flags
, name
.string
, which_ops
,
5416 machine_credentials
)) {
5420 if (!policy_handle_empty(&user_handle
)) {
5421 torture_comment(tctx
, "Testing DeleteUser (createuser2 test)\n");
5423 d
.in
.user_handle
= &user_handle
;
5424 d
.out
.user_handle
= &user_handle
;
5426 status
= dcerpc_samr_DeleteUser_r(b
, user_ctx
, &d
);
5427 if (!NT_STATUS_IS_OK(status
)) {
5428 torture_warning(tctx
, "DeleteUser failed - %s\n", nt_errstr(status
));
5433 talloc_free(user_ctx
);
5439 static bool test_QueryAliasInfo(struct dcerpc_binding_handle
*b
,
5440 struct torture_context
*tctx
,
5441 struct policy_handle
*handle
)
5444 struct samr_QueryAliasInfo r
;
5445 union samr_AliasInfo
*info
;
5446 uint16_t levels
[] = {1, 2, 3};
5450 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5451 torture_comment(tctx
, "Testing QueryAliasInfo level %u\n", levels
[i
]);
5453 r
.in
.alias_handle
= handle
;
5454 r
.in
.level
= levels
[i
];
5457 status
= dcerpc_samr_QueryAliasInfo_r(b
, tctx
, &r
);
5458 if (!NT_STATUS_IS_OK(status
)) {
5459 torture_warning(tctx
, "QueryAliasInfo level %u failed - %s\n",
5460 levels
[i
], nt_errstr(status
));
5468 static bool test_QueryGroupInfo(struct dcerpc_binding_handle
*b
,
5469 struct torture_context
*tctx
,
5470 struct policy_handle
*handle
)
5473 struct samr_QueryGroupInfo r
;
5474 union samr_GroupInfo
*info
;
5475 uint16_t levels
[] = {1, 2, 3, 4, 5};
5479 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5480 torture_comment(tctx
, "Testing QueryGroupInfo level %u\n", levels
[i
]);
5482 r
.in
.group_handle
= handle
;
5483 r
.in
.level
= levels
[i
];
5486 status
= dcerpc_samr_QueryGroupInfo_r(b
, tctx
, &r
);
5487 if (!NT_STATUS_IS_OK(status
)) {
5488 torture_warning(tctx
, "QueryGroupInfo level %u failed - %s\n",
5489 levels
[i
], nt_errstr(status
));
5497 static bool test_QueryGroupMember(struct dcerpc_binding_handle
*b
,
5498 struct torture_context
*tctx
,
5499 struct policy_handle
*handle
)
5502 struct samr_QueryGroupMember r
;
5503 struct samr_RidTypeArray
*rids
= NULL
;
5506 torture_comment(tctx
, "Testing QueryGroupMember\n");
5508 r
.in
.group_handle
= handle
;
5511 status
= dcerpc_samr_QueryGroupMember_r(b
, tctx
, &r
);
5512 if (!NT_STATUS_IS_OK(status
)) {
5513 torture_warning(tctx
, "QueryGroupInfo failed - %s\n", nt_errstr(status
));
5521 static bool test_SetGroupInfo(struct dcerpc_binding_handle
*b
,
5522 struct torture_context
*tctx
,
5523 struct policy_handle
*handle
)
5526 struct samr_QueryGroupInfo r
;
5527 union samr_GroupInfo
*info
;
5528 struct samr_SetGroupInfo s
;
5529 uint16_t levels
[] = {1, 2, 3, 4};
5530 uint16_t set_ok
[] = {0, 1, 1, 1};
5534 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5535 torture_comment(tctx
, "Testing QueryGroupInfo level %u\n", levels
[i
]);
5537 r
.in
.group_handle
= handle
;
5538 r
.in
.level
= levels
[i
];
5541 status
= dcerpc_samr_QueryGroupInfo_r(b
, tctx
, &r
);
5542 if (!NT_STATUS_IS_OK(status
)) {
5543 torture_warning(tctx
, "QueryGroupInfo level %u failed - %s\n",
5544 levels
[i
], nt_errstr(status
));
5548 torture_comment(tctx
, "Testing SetGroupInfo level %u\n", levels
[i
]);
5550 s
.in
.group_handle
= handle
;
5551 s
.in
.level
= levels
[i
];
5552 s
.in
.info
= *r
.out
.info
;
5555 /* disabled this, as it changes the name only from the point of view of samr,
5556 but leaves the name from the point of view of w2k3 internals (and ldap). This means
5557 the name is still reserved, so creating the old name fails, but deleting by the old name
5559 if (s
.in
.level
== 2) {
5560 init_lsa_String(&s
.in
.info
->string
, "NewName");
5564 if (s
.in
.level
== 4) {
5565 init_lsa_String(&s
.in
.info
->description
, "test description");
5568 status
= dcerpc_samr_SetGroupInfo_r(b
, tctx
, &s
);
5570 if (!NT_STATUS_IS_OK(status
)) {
5571 torture_warning(tctx
, "SetGroupInfo level %u failed - %s\n",
5572 r
.in
.level
, nt_errstr(status
));
5577 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, status
)) {
5578 torture_warning(tctx
, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5579 r
.in
.level
, nt_errstr(status
));
5589 static bool test_QueryUserInfo(struct dcerpc_binding_handle
*b
,
5590 struct torture_context
*tctx
,
5591 struct policy_handle
*handle
)
5594 struct samr_QueryUserInfo r
;
5595 union samr_UserInfo
*info
;
5596 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5597 11, 12, 13, 14, 16, 17, 20, 21};
5601 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5602 torture_comment(tctx
, "Testing QueryUserInfo level %u\n", levels
[i
]);
5604 r
.in
.user_handle
= handle
;
5605 r
.in
.level
= levels
[i
];
5608 status
= dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
);
5609 if (!NT_STATUS_IS_OK(status
)) {
5610 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
5611 levels
[i
], nt_errstr(status
));
5619 static bool test_QueryUserInfo2(struct dcerpc_binding_handle
*b
,
5620 struct torture_context
*tctx
,
5621 struct policy_handle
*handle
)
5624 struct samr_QueryUserInfo2 r
;
5625 union samr_UserInfo
*info
;
5626 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5627 11, 12, 13, 14, 16, 17, 20, 21};
5631 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5632 torture_comment(tctx
, "Testing QueryUserInfo2 level %u\n", levels
[i
]);
5634 r
.in
.user_handle
= handle
;
5635 r
.in
.level
= levels
[i
];
5638 status
= dcerpc_samr_QueryUserInfo2_r(b
, tctx
, &r
);
5639 if (!NT_STATUS_IS_OK(status
)) {
5640 torture_warning(tctx
, "QueryUserInfo2 level %u failed - %s\n",
5641 levels
[i
], nt_errstr(status
));
5649 static bool test_OpenUser(struct dcerpc_binding_handle
*b
,
5650 struct torture_context
*tctx
,
5651 struct policy_handle
*handle
, uint32_t rid
)
5654 struct samr_OpenUser r
;
5655 struct policy_handle user_handle
;
5658 torture_comment(tctx
, "Testing OpenUser(%u)\n", rid
);
5660 r
.in
.domain_handle
= handle
;
5661 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5663 r
.out
.user_handle
= &user_handle
;
5665 status
= dcerpc_samr_OpenUser_r(b
, tctx
, &r
);
5666 if (!NT_STATUS_IS_OK(status
)) {
5667 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", rid
, nt_errstr(status
));
5671 if (!test_QuerySecurity(b
, tctx
, &user_handle
)) {
5675 if (!test_QueryUserInfo(b
, tctx
, &user_handle
)) {
5679 if (!test_QueryUserInfo2(b
, tctx
, &user_handle
)) {
5683 if (!test_GetUserPwInfo(b
, tctx
, &user_handle
)) {
5687 if (!test_GetGroupsForUser(b
, tctx
, &user_handle
)) {
5691 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
5698 static bool test_OpenGroup(struct dcerpc_binding_handle
*b
,
5699 struct torture_context
*tctx
,
5700 struct policy_handle
*handle
, uint32_t rid
)
5703 struct samr_OpenGroup r
;
5704 struct policy_handle group_handle
;
5707 torture_comment(tctx
, "Testing OpenGroup(%u)\n", rid
);
5709 r
.in
.domain_handle
= handle
;
5710 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5712 r
.out
.group_handle
= &group_handle
;
5714 status
= dcerpc_samr_OpenGroup_r(b
, tctx
, &r
);
5715 if (!NT_STATUS_IS_OK(status
)) {
5716 torture_warning(tctx
, "OpenGroup(%u) failed - %s\n", rid
, nt_errstr(status
));
5720 if (!torture_setting_bool(tctx
, "samba3", false)) {
5721 if (!test_QuerySecurity(b
, tctx
, &group_handle
)) {
5726 if (!test_QueryGroupInfo(b
, tctx
, &group_handle
)) {
5730 if (!test_QueryGroupMember(b
, tctx
, &group_handle
)) {
5734 if (!test_samr_handle_Close(b
, tctx
, &group_handle
)) {
5741 static bool test_OpenAlias(struct dcerpc_binding_handle
*b
,
5742 struct torture_context
*tctx
,
5743 struct policy_handle
*handle
, uint32_t rid
)
5746 struct samr_OpenAlias r
;
5747 struct policy_handle alias_handle
;
5750 torture_comment(tctx
, "Testing OpenAlias(%u)\n", rid
);
5752 r
.in
.domain_handle
= handle
;
5753 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5755 r
.out
.alias_handle
= &alias_handle
;
5757 status
= dcerpc_samr_OpenAlias_r(b
, tctx
, &r
);
5758 if (!NT_STATUS_IS_OK(status
)) {
5759 torture_warning(tctx
, "OpenAlias(%u) failed - %s\n", rid
, nt_errstr(status
));
5763 if (!torture_setting_bool(tctx
, "samba3", false)) {
5764 if (!test_QuerySecurity(b
, tctx
, &alias_handle
)) {
5769 if (!test_QueryAliasInfo(b
, tctx
, &alias_handle
)) {
5773 if (!test_GetMembersInAlias(b
, tctx
, &alias_handle
)) {
5777 if (!test_samr_handle_Close(b
, tctx
, &alias_handle
)) {
5784 static bool check_mask(struct dcerpc_binding_handle
*b
,
5785 struct torture_context
*tctx
,
5786 struct policy_handle
*handle
, uint32_t rid
,
5787 uint32_t acct_flag_mask
)
5790 struct samr_OpenUser r
;
5791 struct samr_QueryUserInfo q
;
5792 union samr_UserInfo
*info
;
5793 struct policy_handle user_handle
;
5796 torture_comment(tctx
, "Testing OpenUser(%u)\n", rid
);
5798 r
.in
.domain_handle
= handle
;
5799 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5801 r
.out
.user_handle
= &user_handle
;
5803 status
= dcerpc_samr_OpenUser_r(b
, tctx
, &r
);
5804 if (!NT_STATUS_IS_OK(status
)) {
5805 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", rid
, nt_errstr(status
));
5809 q
.in
.user_handle
= &user_handle
;
5813 status
= dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
);
5814 if (!NT_STATUS_IS_OK(status
)) {
5815 torture_warning(tctx
, "QueryUserInfo level 16 failed - %s\n",
5819 if ((acct_flag_mask
& info
->info16
.acct_flags
) == 0) {
5820 torture_warning(tctx
, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
5821 acct_flag_mask
, info
->info16
.acct_flags
, rid
);
5826 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
5833 static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle
*b
,
5834 struct torture_context
*tctx
,
5835 struct policy_handle
*handle
)
5837 NTSTATUS status
= STATUS_MORE_ENTRIES
;
5838 struct samr_EnumDomainUsers r
;
5839 uint32_t mask
, resume_handle
=0;
5842 struct samr_LookupNames n
;
5843 struct samr_LookupRids lr
;
5844 struct lsa_Strings names
;
5845 struct samr_Ids rids
, types
;
5846 struct samr_SamArray
*sam
= NULL
;
5847 uint32_t num_entries
= 0;
5849 uint32_t masks
[] = {ACB_NORMAL
, ACB_DOMTRUST
, ACB_WSTRUST
,
5850 ACB_DISABLED
, ACB_NORMAL
| ACB_DISABLED
,
5851 ACB_SVRTRUST
| ACB_DOMTRUST
| ACB_WSTRUST
,
5854 torture_comment(tctx
, "Testing EnumDomainUsers\n");
5856 for (mask_idx
=0;mask_idx
<ARRAY_SIZE(masks
);mask_idx
++) {
5857 r
.in
.domain_handle
= handle
;
5858 r
.in
.resume_handle
= &resume_handle
;
5859 r
.in
.acct_flags
= mask
= masks
[mask_idx
];
5860 r
.in
.max_size
= (uint32_t)-1;
5861 r
.out
.resume_handle
= &resume_handle
;
5862 r
.out
.num_entries
= &num_entries
;
5865 status
= dcerpc_samr_EnumDomainUsers_r(b
, tctx
, &r
);
5866 if (!NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) &&
5867 !NT_STATUS_IS_OK(status
)) {
5868 torture_warning(tctx
, "EnumDomainUsers failed - %s\n", nt_errstr(status
));
5872 torture_assert(tctx
, sam
, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
5874 if (sam
->count
== 0) {
5878 for (i
=0;i
<sam
->count
;i
++) {
5880 if (!check_mask(b
, tctx
, handle
, sam
->entries
[i
].idx
, mask
)) {
5883 } else if (!test_OpenUser(b
, tctx
, handle
, sam
->entries
[i
].idx
)) {
5889 torture_comment(tctx
, "Testing LookupNames\n");
5890 n
.in
.domain_handle
= handle
;
5891 n
.in
.num_names
= sam
->count
;
5892 n
.in
.names
= talloc_array(tctx
, struct lsa_String
, sam
->count
);
5894 n
.out
.types
= &types
;
5895 for (i
=0;i
<sam
->count
;i
++) {
5896 n
.in
.names
[i
].string
= sam
->entries
[i
].name
.string
;
5898 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
5899 if (!NT_STATUS_IS_OK(status
)) {
5900 torture_warning(tctx
, "LookupNames failed - %s\n", nt_errstr(status
));
5905 torture_comment(tctx
, "Testing LookupRids\n");
5906 lr
.in
.domain_handle
= handle
;
5907 lr
.in
.num_rids
= sam
->count
;
5908 lr
.in
.rids
= talloc_array(tctx
, uint32_t, sam
->count
);
5909 lr
.out
.names
= &names
;
5910 lr
.out
.types
= &types
;
5911 for (i
=0;i
<sam
->count
;i
++) {
5912 lr
.in
.rids
[i
] = sam
->entries
[i
].idx
;
5914 status
= dcerpc_samr_LookupRids_r(b
, tctx
, &lr
);
5915 torture_assert_ntstatus_ok(tctx
, status
, "LookupRids");
5921 try blasting the server with a bunch of sync requests
5923 static bool test_EnumDomainUsers_async(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5924 struct policy_handle
*handle
)
5927 struct samr_EnumDomainUsers r
;
5928 uint32_t resume_handle
=0;
5930 #define ASYNC_COUNT 100
5931 struct tevent_req
*req
[ASYNC_COUNT
];
5933 if (!torture_setting_bool(tctx
, "dangerous", false)) {
5934 torture_skip(tctx
, "samr async test disabled - enable dangerous tests to use\n");
5937 torture_comment(tctx
, "Testing EnumDomainUsers_async\n");
5939 r
.in
.domain_handle
= handle
;
5940 r
.in
.resume_handle
= &resume_handle
;
5941 r
.in
.acct_flags
= 0;
5942 r
.in
.max_size
= (uint32_t)-1;
5943 r
.out
.resume_handle
= &resume_handle
;
5945 for (i
=0;i
<ASYNC_COUNT
;i
++) {
5946 req
[i
] = dcerpc_samr_EnumDomainUsers_r_send(tctx
, tctx
->ev
, p
->binding_handle
, &r
);
5949 for (i
=0;i
<ASYNC_COUNT
;i
++) {
5950 tevent_req_poll(req
[i
], tctx
->ev
);
5951 status
= dcerpc_samr_EnumDomainUsers_r_recv(req
[i
], tctx
);
5952 if (!NT_STATUS_IS_OK(status
)) {
5953 torture_warning(tctx
, "EnumDomainUsers[%d] failed - %s\n",
5954 i
, nt_errstr(status
));
5959 torture_comment(tctx
, "%d async requests OK\n", i
);
5964 static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle
*b
,
5965 struct torture_context
*tctx
,
5966 struct policy_handle
*handle
)
5969 struct samr_EnumDomainGroups r
;
5970 uint32_t resume_handle
=0;
5971 struct samr_SamArray
*sam
= NULL
;
5972 uint32_t num_entries
= 0;
5975 bool universal_group_found
= false;
5977 torture_comment(tctx
, "Testing EnumDomainGroups\n");
5979 r
.in
.domain_handle
= handle
;
5980 r
.in
.resume_handle
= &resume_handle
;
5981 r
.in
.max_size
= (uint32_t)-1;
5982 r
.out
.resume_handle
= &resume_handle
;
5983 r
.out
.num_entries
= &num_entries
;
5986 status
= dcerpc_samr_EnumDomainGroups_r(b
, tctx
, &r
);
5987 if (!NT_STATUS_IS_OK(status
)) {
5988 torture_warning(tctx
, "EnumDomainGroups failed - %s\n", nt_errstr(status
));
5996 for (i
=0;i
<sam
->count
;i
++) {
5997 if (!test_OpenGroup(b
, tctx
, handle
, sam
->entries
[i
].idx
)) {
6000 if ((ret
== true) && (strcasecmp(sam
->entries
[i
].name
.string
,
6001 "Enterprise Admins") == 0)) {
6002 universal_group_found
= true;
6006 /* when we are running this on s4 we should get back at least the
6007 * "Enterprise Admins" universal group. If we don't get a group entry
6008 * at all we probably are performing the test on the builtin domain.
6009 * So ignore this case. */
6010 if (torture_setting_bool(tctx
, "samba4", false)) {
6011 if ((sam
->count
> 0) && (!universal_group_found
)) {
6019 static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle
*b
,
6020 struct torture_context
*tctx
,
6021 struct policy_handle
*handle
)
6024 struct samr_EnumDomainAliases r
;
6025 uint32_t resume_handle
=0;
6026 struct samr_SamArray
*sam
= NULL
;
6027 uint32_t num_entries
= 0;
6031 torture_comment(tctx
, "Testing EnumDomainAliases\n");
6033 r
.in
.domain_handle
= handle
;
6034 r
.in
.resume_handle
= &resume_handle
;
6035 r
.in
.max_size
= (uint32_t)-1;
6037 r
.out
.num_entries
= &num_entries
;
6038 r
.out
.resume_handle
= &resume_handle
;
6040 status
= dcerpc_samr_EnumDomainAliases_r(b
, tctx
, &r
);
6041 if (!NT_STATUS_IS_OK(status
)) {
6042 torture_warning(tctx
, "EnumDomainAliases failed - %s\n", nt_errstr(status
));
6050 for (i
=0;i
<sam
->count
;i
++) {
6051 if (!test_OpenAlias(b
, tctx
, handle
, sam
->entries
[i
].idx
)) {
6059 static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle
*b
,
6060 struct torture_context
*tctx
,
6061 struct policy_handle
*handle
)
6064 struct samr_GetDisplayEnumerationIndex r
;
6066 uint16_t levels
[] = {1, 2, 3, 4, 5};
6067 uint16_t ok_lvl
[] = {1, 1, 1, 0, 0};
6068 struct lsa_String name
;
6072 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6073 torture_comment(tctx
, "Testing GetDisplayEnumerationIndex level %u\n", levels
[i
]);
6075 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
6077 r
.in
.domain_handle
= handle
;
6078 r
.in
.level
= levels
[i
];
6082 status
= dcerpc_samr_GetDisplayEnumerationIndex_r(b
, tctx
, &r
);
6085 !NT_STATUS_IS_OK(status
) &&
6086 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
6087 torture_warning(tctx
, "GetDisplayEnumerationIndex level %u failed - %s\n",
6088 levels
[i
], nt_errstr(status
));
6092 init_lsa_String(&name
, "zzzzzzzz");
6094 status
= dcerpc_samr_GetDisplayEnumerationIndex_r(b
, tctx
, &r
);
6096 if (ok_lvl
[i
] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
6097 torture_warning(tctx
, "GetDisplayEnumerationIndex level %u failed - %s\n",
6098 levels
[i
], nt_errstr(status
));
6106 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle
*b
,
6107 struct torture_context
*tctx
,
6108 struct policy_handle
*handle
)
6111 struct samr_GetDisplayEnumerationIndex2 r
;
6113 uint16_t levels
[] = {1, 2, 3, 4, 5};
6114 uint16_t ok_lvl
[] = {1, 1, 1, 0, 0};
6115 struct lsa_String name
;
6119 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6120 torture_comment(tctx
, "Testing GetDisplayEnumerationIndex2 level %u\n", levels
[i
]);
6122 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
6124 r
.in
.domain_handle
= handle
;
6125 r
.in
.level
= levels
[i
];
6129 status
= dcerpc_samr_GetDisplayEnumerationIndex2_r(b
, tctx
, &r
);
6131 !NT_STATUS_IS_OK(status
) &&
6132 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
6133 torture_warning(tctx
, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6134 levels
[i
], nt_errstr(status
));
6138 init_lsa_String(&name
, "zzzzzzzz");
6140 status
= dcerpc_samr_GetDisplayEnumerationIndex2_r(b
, tctx
, &r
);
6141 if (ok_lvl
[i
] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
6142 torture_warning(tctx
, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6143 levels
[i
], nt_errstr(status
));
6151 #define STRING_EQUAL_QUERY(s1, s2, user) \
6152 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6153 /* odd, but valid */ \
6154 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6155 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
6156 #s1, user.string, s1.string, s2.string, __location__); \
6159 #define INT_EQUAL_QUERY(s1, s2, user) \
6161 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6162 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6166 static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle
*b
,
6167 struct torture_context
*tctx
,
6168 struct samr_QueryDisplayInfo
*querydisplayinfo
,
6169 bool *seen_testuser
)
6171 struct samr_OpenUser r
;
6172 struct samr_QueryUserInfo q
;
6173 union samr_UserInfo
*info
;
6174 struct policy_handle user_handle
;
6177 r
.in
.domain_handle
= querydisplayinfo
->in
.domain_handle
;
6178 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6179 for (i
= 0; ; i
++) {
6180 switch (querydisplayinfo
->in
.level
) {
6182 if (i
>= querydisplayinfo
->out
.info
->info1
.count
) {
6185 r
.in
.rid
= querydisplayinfo
->out
.info
->info1
.entries
[i
].rid
;
6188 if (i
>= querydisplayinfo
->out
.info
->info2
.count
) {
6191 r
.in
.rid
= querydisplayinfo
->out
.info
->info2
.entries
[i
].rid
;
6197 /* Not interested in validating just the account name */
6201 r
.out
.user_handle
= &user_handle
;
6203 switch (querydisplayinfo
->in
.level
) {
6206 status
= dcerpc_samr_OpenUser_r(b
, tctx
, &r
);
6207 if (!NT_STATUS_IS_OK(status
)) {
6208 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", r
.in
.rid
, nt_errstr(status
));
6213 q
.in
.user_handle
= &user_handle
;
6216 status
= dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
);
6217 if (!NT_STATUS_IS_OK(status
)) {
6218 torture_warning(tctx
, "QueryUserInfo(%u) failed - %s\n", r
.in
.rid
, nt_errstr(status
));
6222 switch (querydisplayinfo
->in
.level
) {
6224 if (seen_testuser
&& strcmp(info
->info21
.account_name
.string
, TEST_ACCOUNT_NAME
) == 0) {
6225 *seen_testuser
= true;
6227 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].full_name
,
6228 info
->info21
.full_name
, info
->info21
.account_name
);
6229 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].account_name
,
6230 info
->info21
.account_name
, info
->info21
.account_name
);
6231 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].description
,
6232 info
->info21
.description
, info
->info21
.account_name
);
6233 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].rid
,
6234 info
->info21
.rid
, info
->info21
.account_name
);
6235 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].acct_flags
,
6236 info
->info21
.acct_flags
, info
->info21
.account_name
);
6240 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].account_name
,
6241 info
->info21
.account_name
, info
->info21
.account_name
);
6242 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].description
,
6243 info
->info21
.description
, info
->info21
.account_name
);
6244 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].rid
,
6245 info
->info21
.rid
, info
->info21
.account_name
);
6246 INT_EQUAL_QUERY((querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
& ~ACB_NORMAL
),
6247 info
->info21
.acct_flags
, info
->info21
.account_name
);
6249 if (!(querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
& ACB_NORMAL
)) {
6250 torture_warning(tctx
, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6251 info
->info21
.account_name
.string
);
6254 if (!(info
->info21
.acct_flags
& (ACB_WSTRUST
| ACB_SVRTRUST
))) {
6255 torture_warning(tctx
, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6256 info
->info21
.account_name
.string
,
6257 querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
,
6258 info
->info21
.acct_flags
);
6265 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
6272 static bool test_QueryDisplayInfo(struct dcerpc_binding_handle
*b
,
6273 struct torture_context
*tctx
,
6274 struct policy_handle
*handle
)
6277 struct samr_QueryDisplayInfo r
;
6278 struct samr_QueryDomainInfo dom_info
;
6279 union samr_DomainInfo
*info
= NULL
;
6281 uint16_t levels
[] = {1, 2, 3, 4, 5};
6283 bool seen_testuser
= false;
6284 uint32_t total_size
;
6285 uint32_t returned_size
;
6286 union samr_DispInfo disp_info
;
6289 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6290 torture_comment(tctx
, "Testing QueryDisplayInfo level %u\n", levels
[i
]);
6293 status
= STATUS_MORE_ENTRIES
;
6294 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
6295 r
.in
.domain_handle
= handle
;
6296 r
.in
.level
= levels
[i
];
6297 r
.in
.max_entries
= 2;
6298 r
.in
.buf_size
= (uint32_t)-1;
6299 r
.out
.total_size
= &total_size
;
6300 r
.out
.returned_size
= &returned_size
;
6301 r
.out
.info
= &disp_info
;
6303 status
= dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &r
);
6304 if (!NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) && !NT_STATUS_IS_OK(status
)) {
6305 torture_warning(tctx
, "QueryDisplayInfo level %u failed - %s\n",
6306 levels
[i
], nt_errstr(status
));
6309 switch (r
.in
.level
) {
6311 if (!test_each_DisplayInfo_user(b
, tctx
, &r
, &seen_testuser
)) {
6314 r
.in
.start_idx
+= r
.out
.info
->info1
.count
;
6317 if (!test_each_DisplayInfo_user(b
, tctx
, &r
, NULL
)) {
6320 r
.in
.start_idx
+= r
.out
.info
->info2
.count
;
6323 r
.in
.start_idx
+= r
.out
.info
->info3
.count
;
6326 r
.in
.start_idx
+= r
.out
.info
->info4
.count
;
6329 r
.in
.start_idx
+= r
.out
.info
->info5
.count
;
6333 dom_info
.in
.domain_handle
= handle
;
6334 dom_info
.in
.level
= 2;
6335 dom_info
.out
.info
= &info
;
6337 /* Check number of users returned is correct */
6338 status
= dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &dom_info
);
6339 if (!NT_STATUS_IS_OK(status
)) {
6340 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
6341 r
.in
.level
, nt_errstr(status
));
6345 switch (r
.in
.level
) {
6348 if (info
->general
.num_users
< r
.in
.start_idx
) {
6349 /* On AD deployments this numbers don't match
6350 * since QueryDisplayInfo returns universal and
6351 * global groups, QueryDomainInfo only global
6353 if (torture_setting_bool(tctx
, "samba3", false)) {
6354 torture_warning(tctx
, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6355 r
.in
.start_idx
, info
->general
.num_groups
,
6356 info
->general
.domain_name
.string
);
6360 if (!seen_testuser
) {
6361 struct policy_handle user_handle
;
6362 if (NT_STATUS_IS_OK(test_OpenUser_byname(b
, tctx
, handle
, TEST_ACCOUNT_NAME
, &user_handle
))) {
6363 torture_warning(tctx
, "Didn't find test user " TEST_ACCOUNT_NAME
" in enumeration of %s\n",
6364 info
->general
.domain_name
.string
);
6366 test_samr_handle_Close(b
, tctx
, &user_handle
);
6372 if (info
->general
.num_groups
!= r
.in
.start_idx
) {
6373 /* On AD deployments this numbers don't match
6374 * since QueryDisplayInfo returns universal and
6375 * global groups, QueryDomainInfo only global
6377 if (torture_setting_bool(tctx
, "samba3", false)) {
6378 torture_warning(tctx
, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6379 r
.in
.start_idx
, info
->general
.num_groups
,
6380 info
->general
.domain_name
.string
);
6393 static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle
*b
,
6394 struct torture_context
*tctx
,
6395 struct policy_handle
*handle
)
6398 struct samr_QueryDisplayInfo2 r
;
6400 uint16_t levels
[] = {1, 2, 3, 4, 5};
6402 uint32_t total_size
;
6403 uint32_t returned_size
;
6404 union samr_DispInfo info
;
6406 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6407 torture_comment(tctx
, "Testing QueryDisplayInfo2 level %u\n", levels
[i
]);
6409 r
.in
.domain_handle
= handle
;
6410 r
.in
.level
= levels
[i
];
6412 r
.in
.max_entries
= 1000;
6413 r
.in
.buf_size
= (uint32_t)-1;
6414 r
.out
.total_size
= &total_size
;
6415 r
.out
.returned_size
= &returned_size
;
6418 status
= dcerpc_samr_QueryDisplayInfo2_r(b
, tctx
, &r
);
6419 if (!NT_STATUS_IS_OK(status
)) {
6420 torture_warning(tctx
, "QueryDisplayInfo2 level %u failed - %s\n",
6421 levels
[i
], nt_errstr(status
));
6429 static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle
*b
,
6430 struct torture_context
*tctx
,
6431 struct policy_handle
*handle
)
6434 struct samr_QueryDisplayInfo3 r
;
6436 uint16_t levels
[] = {1, 2, 3, 4, 5};
6438 uint32_t total_size
;
6439 uint32_t returned_size
;
6440 union samr_DispInfo info
;
6442 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6443 torture_comment(tctx
, "Testing QueryDisplayInfo3 level %u\n", levels
[i
]);
6445 r
.in
.domain_handle
= handle
;
6446 r
.in
.level
= levels
[i
];
6448 r
.in
.max_entries
= 1000;
6449 r
.in
.buf_size
= (uint32_t)-1;
6450 r
.out
.total_size
= &total_size
;
6451 r
.out
.returned_size
= &returned_size
;
6454 status
= dcerpc_samr_QueryDisplayInfo3_r(b
, tctx
, &r
);
6455 if (!NT_STATUS_IS_OK(status
)) {
6456 torture_warning(tctx
, "QueryDisplayInfo3 level %u failed - %s\n",
6457 levels
[i
], nt_errstr(status
));
6466 static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle
*b
,
6467 struct torture_context
*tctx
,
6468 struct policy_handle
*handle
)
6471 struct samr_QueryDisplayInfo r
;
6473 uint32_t total_size
;
6474 uint32_t returned_size
;
6475 union samr_DispInfo info
;
6477 torture_comment(tctx
, "Testing QueryDisplayInfo continuation\n");
6479 r
.in
.domain_handle
= handle
;
6482 r
.in
.max_entries
= 1;
6483 r
.in
.buf_size
= (uint32_t)-1;
6484 r
.out
.total_size
= &total_size
;
6485 r
.out
.returned_size
= &returned_size
;
6489 status
= dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &r
);
6490 if (NT_STATUS_IS_OK(status
) && *r
.out
.returned_size
!= 0) {
6491 if (r
.out
.info
->info1
.entries
[0].idx
!= r
.in
.start_idx
+ 1) {
6492 torture_warning(tctx
, "expected idx %d but got %d\n",
6494 r
.out
.info
->info1
.entries
[0].idx
);
6498 if (!NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) &&
6499 !NT_STATUS_IS_OK(status
)) {
6500 torture_warning(tctx
, "QueryDisplayInfo level %u failed - %s\n",
6501 r
.in
.level
, nt_errstr(status
));
6506 } while ((NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) ||
6507 NT_STATUS_IS_OK(status
)) &&
6508 *r
.out
.returned_size
!= 0);
6513 static bool test_QueryDomainInfo(struct dcerpc_pipe
*p
,
6514 struct torture_context
*tctx
,
6515 struct policy_handle
*handle
)
6518 struct samr_QueryDomainInfo r
;
6519 union samr_DomainInfo
*info
= NULL
;
6520 struct samr_SetDomainInfo s
;
6521 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6522 uint16_t set_ok
[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
6525 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
6526 const char *domain_comment
= talloc_asprintf(tctx
,
6527 "Tortured by Samba4 RPC-SAMR: %s",
6528 timestring(tctx
, time(NULL
)));
6530 s
.in
.domain_handle
= handle
;
6532 s
.in
.info
= talloc(tctx
, union samr_DomainInfo
);
6534 s
.in
.info
->oem
.oem_information
.string
= domain_comment
;
6535 status
= dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
);
6536 if (!NT_STATUS_IS_OK(status
)) {
6537 torture_warning(tctx
, "SetDomainInfo level %u (set comment) failed - %s\n",
6538 s
.in
.level
, nt_errstr(status
));
6542 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6543 torture_comment(tctx
, "Testing QueryDomainInfo level %u\n", levels
[i
]);
6545 r
.in
.domain_handle
= handle
;
6546 r
.in
.level
= levels
[i
];
6549 status
= dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &r
);
6550 if (!NT_STATUS_IS_OK(status
)) {
6551 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
6552 r
.in
.level
, nt_errstr(status
));
6557 switch (levels
[i
]) {
6559 if (strcmp(info
->general
.oem_information
.string
, domain_comment
) != 0) {
6560 torture_warning(tctx
, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6561 levels
[i
], info
->general
.oem_information
.string
, domain_comment
);
6562 if (!torture_setting_bool(tctx
, "samba3", false)) {
6566 if (!info
->general
.primary
.string
) {
6567 torture_warning(tctx
, "QueryDomainInfo level %u returned no PDC name\n",
6570 } else if (info
->general
.role
== SAMR_ROLE_DOMAIN_PDC
) {
6571 if (dcerpc_server_name(p
) && strcasecmp_m(dcerpc_server_name(p
), info
->general
.primary
.string
) != 0) {
6572 torture_warning(tctx
, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
6573 levels
[i
], info
->general
.primary
.string
, dcerpc_server_name(p
));
6578 if (strcmp(info
->oem
.oem_information
.string
, domain_comment
) != 0) {
6579 torture_warning(tctx
, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6580 levels
[i
], info
->oem
.oem_information
.string
, domain_comment
);
6581 if (!torture_setting_bool(tctx
, "samba3", false)) {
6587 if (!info
->info6
.primary
.string
) {
6588 torture_warning(tctx
, "QueryDomainInfo level %u returned no PDC name\n",
6594 if (strcmp(info
->general2
.general
.oem_information
.string
, domain_comment
) != 0) {
6595 torture_warning(tctx
, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
6596 levels
[i
], info
->general2
.general
.oem_information
.string
, domain_comment
);
6597 if (!torture_setting_bool(tctx
, "samba3", false)) {
6604 torture_comment(tctx
, "Testing SetDomainInfo level %u\n", levels
[i
]);
6606 s
.in
.domain_handle
= handle
;
6607 s
.in
.level
= levels
[i
];
6610 status
= dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
);
6612 if (!NT_STATUS_IS_OK(status
)) {
6613 torture_warning(tctx
, "SetDomainInfo level %u failed - %s\n",
6614 r
.in
.level
, nt_errstr(status
));
6619 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, status
)) {
6620 torture_warning(tctx
, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6621 r
.in
.level
, nt_errstr(status
));
6627 status
= dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &r
);
6628 if (!NT_STATUS_IS_OK(status
)) {
6629 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
6630 r
.in
.level
, nt_errstr(status
));
6640 static bool test_QueryDomainInfo2(struct dcerpc_binding_handle
*b
,
6641 struct torture_context
*tctx
,
6642 struct policy_handle
*handle
)
6645 struct samr_QueryDomainInfo2 r
;
6646 union samr_DomainInfo
*info
= NULL
;
6647 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6651 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6652 torture_comment(tctx
, "Testing QueryDomainInfo2 level %u\n", levels
[i
]);
6654 r
.in
.domain_handle
= handle
;
6655 r
.in
.level
= levels
[i
];
6658 status
= dcerpc_samr_QueryDomainInfo2_r(b
, tctx
, &r
);
6659 if (!NT_STATUS_IS_OK(status
)) {
6660 torture_warning(tctx
, "QueryDomainInfo2 level %u failed - %s\n",
6661 r
.in
.level
, nt_errstr(status
));
6670 /* Test whether querydispinfo level 5 and enumdomgroups return the same
6671 set of group names. */
6672 static bool test_GroupList(struct dcerpc_binding_handle
*b
,
6673 struct torture_context
*tctx
,
6674 struct policy_handle
*handle
)
6676 struct samr_EnumDomainGroups q1
;
6677 struct samr_QueryDisplayInfo q2
;
6679 uint32_t resume_handle
=0;
6680 struct samr_SamArray
*sam
= NULL
;
6681 uint32_t num_entries
= 0;
6684 uint32_t total_size
;
6685 uint32_t returned_size
;
6686 union samr_DispInfo info
;
6689 const char **names
= NULL
;
6691 torture_comment(tctx
, "Testing coherency of querydispinfo vs enumdomgroups\n");
6693 q1
.in
.domain_handle
= handle
;
6694 q1
.in
.resume_handle
= &resume_handle
;
6696 q1
.out
.resume_handle
= &resume_handle
;
6697 q1
.out
.num_entries
= &num_entries
;
6700 status
= STATUS_MORE_ENTRIES
;
6701 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
6702 status
= dcerpc_samr_EnumDomainGroups_r(b
, tctx
, &q1
);
6704 if (!NT_STATUS_IS_OK(status
) &&
6705 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
6708 for (i
=0; i
<*q1
.out
.num_entries
; i
++) {
6709 add_string_to_array(tctx
,
6710 sam
->entries
[i
].name
.string
,
6711 &names
, &num_names
);
6715 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomainGroups");
6717 torture_assert(tctx
, sam
, "EnumDomainGroups failed to return sam");
6719 q2
.in
.domain_handle
= handle
;
6721 q2
.in
.start_idx
= 0;
6722 q2
.in
.max_entries
= 5;
6723 q2
.in
.buf_size
= (uint32_t)-1;
6724 q2
.out
.total_size
= &total_size
;
6725 q2
.out
.returned_size
= &returned_size
;
6726 q2
.out
.info
= &info
;
6728 status
= STATUS_MORE_ENTRIES
;
6729 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
6730 status
= dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &q2
);
6732 if (!NT_STATUS_IS_OK(status
) &&
6733 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
6736 for (i
=0; i
<q2
.out
.info
->info5
.count
; i
++) {
6738 const char *name
= q2
.out
.info
->info5
.entries
[i
].account_name
.string
;
6740 for (j
=0; j
<num_names
; j
++) {
6741 if (names
[j
] == NULL
)
6743 if (strequal(names
[j
], name
)) {
6751 torture_warning(tctx
, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
6756 q2
.in
.start_idx
+= q2
.out
.info
->info5
.count
;
6759 if (!NT_STATUS_IS_OK(status
)) {
6760 torture_warning(tctx
, "QueryDisplayInfo level 5 failed - %s\n",
6765 for (i
=0; i
<num_names
; i
++) {
6766 if (names
[i
] != NULL
) {
6767 torture_warning(tctx
, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
6776 static bool test_DeleteDomainGroup(struct dcerpc_binding_handle
*b
,
6777 struct torture_context
*tctx
,
6778 struct policy_handle
*group_handle
)
6780 struct samr_DeleteDomainGroup d
;
6783 torture_comment(tctx
, "Testing DeleteDomainGroup\n");
6785 d
.in
.group_handle
= group_handle
;
6786 d
.out
.group_handle
= group_handle
;
6788 status
= dcerpc_samr_DeleteDomainGroup_r(b
, tctx
, &d
);
6789 torture_assert_ntstatus_ok(tctx
, status
, "DeleteDomainGroup");
6794 static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle
*b
,
6795 struct torture_context
*tctx
,
6796 struct policy_handle
*domain_handle
)
6798 struct samr_TestPrivateFunctionsDomain r
;
6802 torture_comment(tctx
, "Testing TestPrivateFunctionsDomain\n");
6804 r
.in
.domain_handle
= domain_handle
;
6806 status
= dcerpc_samr_TestPrivateFunctionsDomain_r(b
, tctx
, &r
);
6807 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_NOT_IMPLEMENTED
, "TestPrivateFunctionsDomain");
6812 static bool test_RidToSid(struct dcerpc_binding_handle
*b
,
6813 struct torture_context
*tctx
,
6814 struct dom_sid
*domain_sid
,
6815 struct policy_handle
*domain_handle
)
6817 struct samr_RidToSid r
;
6820 struct dom_sid
*calc_sid
, *out_sid
;
6821 int rids
[] = { 0, 42, 512, 10200 };
6824 for (i
=0;i
<ARRAY_SIZE(rids
);i
++) {
6825 torture_comment(tctx
, "Testing RidToSid\n");
6827 calc_sid
= dom_sid_dup(tctx
, domain_sid
);
6828 r
.in
.domain_handle
= domain_handle
;
6830 r
.out
.sid
= &out_sid
;
6832 status
= dcerpc_samr_RidToSid_r(b
, tctx
, &r
);
6833 if (!NT_STATUS_IS_OK(status
)) {
6834 torture_warning(tctx
, "RidToSid for %d failed - %s\n", rids
[i
], nt_errstr(status
));
6837 calc_sid
= dom_sid_add_rid(calc_sid
, calc_sid
, rids
[i
]);
6839 if (!dom_sid_equal(calc_sid
, out_sid
)) {
6840 torture_warning(tctx
, "RidToSid for %d failed - got %s, expected %s\n", rids
[i
],
6841 dom_sid_string(tctx
, out_sid
),
6842 dom_sid_string(tctx
, calc_sid
));
6851 static bool test_GetBootKeyInformation(struct dcerpc_binding_handle
*b
,
6852 struct torture_context
*tctx
,
6853 struct policy_handle
*domain_handle
)
6855 struct samr_GetBootKeyInformation r
;
6858 uint32_t unknown
= 0;
6860 torture_comment(tctx
, "Testing GetBootKeyInformation\n");
6862 r
.in
.domain_handle
= domain_handle
;
6863 r
.out
.unknown
= &unknown
;
6865 status
= dcerpc_samr_GetBootKeyInformation_r(b
, tctx
, &r
);
6866 if (!NT_STATUS_IS_OK(status
)) {
6867 /* w2k3 seems to fail this sometimes and pass it sometimes */
6868 torture_comment(tctx
, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status
));
6874 static bool test_AddGroupMember(struct dcerpc_binding_handle
*b
,
6875 struct torture_context
*tctx
,
6876 struct policy_handle
*domain_handle
,
6877 struct policy_handle
*group_handle
)
6880 struct samr_AddGroupMember r
;
6881 struct samr_DeleteGroupMember d
;
6882 struct samr_QueryGroupMember q
;
6883 struct samr_RidTypeArray
*rids
= NULL
;
6884 struct samr_SetMemberAttributesOfGroup s
;
6886 bool found_member
= false;
6889 status
= test_LookupName(b
, tctx
, domain_handle
, TEST_ACCOUNT_NAME
, &rid
);
6890 torture_assert_ntstatus_ok(tctx
, status
, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME
);
6892 r
.in
.group_handle
= group_handle
;
6894 r
.in
.flags
= 0; /* ??? */
6896 torture_comment(tctx
, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
6898 d
.in
.group_handle
= group_handle
;
6901 status
= dcerpc_samr_DeleteGroupMember_r(b
, tctx
, &d
);
6902 torture_assert_ntstatus_equal(tctx
, NT_STATUS_MEMBER_NOT_IN_GROUP
, status
, "DeleteGroupMember");
6904 status
= dcerpc_samr_AddGroupMember_r(b
, tctx
, &r
);
6905 torture_assert_ntstatus_ok(tctx
, status
, "AddGroupMember");
6907 status
= dcerpc_samr_AddGroupMember_r(b
, tctx
, &r
);
6908 torture_assert_ntstatus_equal(tctx
, NT_STATUS_MEMBER_IN_GROUP
, status
, "AddGroupMember");
6910 if (torture_setting_bool(tctx
, "samba4", false) ||
6911 torture_setting_bool(tctx
, "samba3", false)) {
6912 torture_comment(tctx
, "skipping SetMemberAttributesOfGroup test against Samba\n");
6914 /* this one is quite strange. I am using random inputs in the
6915 hope of triggering an error that might give us a clue */
6917 s
.in
.group_handle
= group_handle
;
6918 s
.in
.unknown1
= random();
6919 s
.in
.unknown2
= random();
6921 status
= dcerpc_samr_SetMemberAttributesOfGroup_r(b
, tctx
, &s
);
6922 torture_assert_ntstatus_ok(tctx
, status
, "SetMemberAttributesOfGroup");
6925 q
.in
.group_handle
= group_handle
;
6928 status
= dcerpc_samr_QueryGroupMember_r(b
, tctx
, &q
);
6929 torture_assert_ntstatus_ok(tctx
, status
, "QueryGroupMember");
6930 torture_assert(tctx
, rids
, "QueryGroupMember did not fill in rids structure");
6932 for (i
=0; i
< rids
->count
; i
++) {
6933 if (rids
->rids
[i
] == rid
) {
6934 found_member
= true;
6938 torture_assert(tctx
, found_member
, "QueryGroupMember did not list newly added member");
6940 status
= dcerpc_samr_DeleteGroupMember_r(b
, tctx
, &d
);
6941 torture_assert_ntstatus_ok(tctx
, status
, "DeleteGroupMember");
6944 found_member
= false;
6946 status
= dcerpc_samr_QueryGroupMember_r(b
, tctx
, &q
);
6947 torture_assert_ntstatus_ok(tctx
, status
, "QueryGroupMember");
6948 torture_assert(tctx
, rids
, "QueryGroupMember did not fill in rids structure");
6950 for (i
=0; i
< rids
->count
; i
++) {
6951 if (rids
->rids
[i
] == rid
) {
6952 found_member
= true;
6956 torture_assert(tctx
, !found_member
, "QueryGroupMember does still list removed member");
6958 status
= dcerpc_samr_AddGroupMember_r(b
, tctx
, &r
);
6959 torture_assert_ntstatus_ok(tctx
, status
, "AddGroupMember");
6965 static bool test_CreateDomainGroup(struct dcerpc_binding_handle
*b
,
6966 struct torture_context
*tctx
,
6967 struct policy_handle
*domain_handle
,
6968 const char *group_name
,
6969 struct policy_handle
*group_handle
,
6970 struct dom_sid
*domain_sid
,
6974 struct samr_CreateDomainGroup r
;
6976 struct lsa_String name
;
6979 init_lsa_String(&name
, group_name
);
6981 r
.in
.domain_handle
= domain_handle
;
6983 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6984 r
.out
.group_handle
= group_handle
;
6987 torture_comment(tctx
, "Testing CreateDomainGroup(%s)\n", r
.in
.name
->string
);
6989 status
= dcerpc_samr_CreateDomainGroup_r(b
, tctx
, &r
);
6991 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
6992 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
6993 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.name
->string
);
6996 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.name
->string
,
7002 if (NT_STATUS_EQUAL(status
, NT_STATUS_GROUP_EXISTS
)) {
7003 if (!test_DeleteGroup_byname(b
, tctx
, domain_handle
, r
.in
.name
->string
)) {
7004 torture_warning(tctx
, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r
.in
.name
->string
,
7008 status
= dcerpc_samr_CreateDomainGroup_r(b
, tctx
, &r
);
7010 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_EXISTS
)) {
7011 if (!test_DeleteUser_byname(b
, tctx
, domain_handle
, r
.in
.name
->string
)) {
7013 torture_warning(tctx
, "CreateDomainGroup failed: Could not delete user %s - %s\n", r
.in
.name
->string
,
7017 status
= dcerpc_samr_CreateDomainGroup_r(b
, tctx
, &r
);
7019 torture_assert_ntstatus_ok(tctx
, status
, "CreateDomainGroup");
7025 if (!test_AddGroupMember(b
, tctx
, domain_handle
, group_handle
)) {
7026 torture_warning(tctx
, "CreateDomainGroup failed - %s\n", nt_errstr(status
));
7030 if (!test_SetGroupInfo(b
, tctx
, group_handle
)) {
7039 its not totally clear what this does. It seems to accept any sid you like.
7041 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle
*b
,
7042 struct torture_context
*tctx
,
7043 struct policy_handle
*domain_handle
)
7046 struct samr_RemoveMemberFromForeignDomain r
;
7048 r
.in
.domain_handle
= domain_handle
;
7049 r
.in
.sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-12-34-56-78");
7051 status
= dcerpc_samr_RemoveMemberFromForeignDomain_r(b
, tctx
, &r
);
7052 torture_assert_ntstatus_ok(tctx
, status
, "RemoveMemberFromForeignDomain");
7057 static bool test_EnumDomainUsers(struct dcerpc_binding_handle
*b
,
7058 struct torture_context
*tctx
,
7059 struct policy_handle
*domain_handle
,
7060 uint32_t *total_num_entries_p
)
7063 struct samr_EnumDomainUsers r
;
7064 uint32_t resume_handle
= 0;
7065 uint32_t num_entries
= 0;
7066 uint32_t total_num_entries
= 0;
7067 struct samr_SamArray
*sam
;
7069 r
.in
.domain_handle
= domain_handle
;
7070 r
.in
.acct_flags
= 0;
7071 r
.in
.max_size
= (uint32_t)-1;
7072 r
.in
.resume_handle
= &resume_handle
;
7075 r
.out
.num_entries
= &num_entries
;
7076 r
.out
.resume_handle
= &resume_handle
;
7078 torture_comment(tctx
, "Testing EnumDomainUsers\n");
7081 status
= dcerpc_samr_EnumDomainUsers_r(b
, tctx
, &r
);
7082 if (NT_STATUS_IS_ERR(status
)) {
7083 torture_assert_ntstatus_ok(tctx
, status
,
7084 "failed to enumerate users");
7087 total_num_entries
+= num_entries
;
7088 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7090 if (total_num_entries_p
) {
7091 *total_num_entries_p
= total_num_entries
;
7097 static bool test_EnumDomainGroups(struct dcerpc_binding_handle
*b
,
7098 struct torture_context
*tctx
,
7099 struct policy_handle
*domain_handle
,
7100 uint32_t *total_num_entries_p
)
7103 struct samr_EnumDomainGroups r
;
7104 uint32_t resume_handle
= 0;
7105 uint32_t num_entries
= 0;
7106 uint32_t total_num_entries
= 0;
7107 struct samr_SamArray
*sam
;
7109 r
.in
.domain_handle
= domain_handle
;
7110 r
.in
.max_size
= (uint32_t)-1;
7111 r
.in
.resume_handle
= &resume_handle
;
7114 r
.out
.num_entries
= &num_entries
;
7115 r
.out
.resume_handle
= &resume_handle
;
7117 torture_comment(tctx
, "Testing EnumDomainGroups\n");
7120 status
= dcerpc_samr_EnumDomainGroups_r(b
, tctx
, &r
);
7121 if (NT_STATUS_IS_ERR(status
)) {
7122 torture_assert_ntstatus_ok(tctx
, status
,
7123 "failed to enumerate groups");
7126 total_num_entries
+= num_entries
;
7127 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7129 if (total_num_entries_p
) {
7130 *total_num_entries_p
= total_num_entries
;
7136 static bool test_EnumDomainAliases(struct dcerpc_binding_handle
*b
,
7137 struct torture_context
*tctx
,
7138 struct policy_handle
*domain_handle
,
7139 uint32_t *total_num_entries_p
)
7142 struct samr_EnumDomainAliases r
;
7143 uint32_t resume_handle
= 0;
7144 uint32_t num_entries
= 0;
7145 uint32_t total_num_entries
= 0;
7146 struct samr_SamArray
*sam
;
7148 r
.in
.domain_handle
= domain_handle
;
7149 r
.in
.max_size
= (uint32_t)-1;
7150 r
.in
.resume_handle
= &resume_handle
;
7153 r
.out
.num_entries
= &num_entries
;
7154 r
.out
.resume_handle
= &resume_handle
;
7156 torture_comment(tctx
, "Testing EnumDomainAliases\n");
7159 status
= dcerpc_samr_EnumDomainAliases_r(b
, tctx
, &r
);
7160 if (NT_STATUS_IS_ERR(status
)) {
7161 torture_assert_ntstatus_ok(tctx
, status
,
7162 "failed to enumerate aliases");
7165 total_num_entries
+= num_entries
;
7166 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7168 if (total_num_entries_p
) {
7169 *total_num_entries_p
= total_num_entries
;
7175 static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle
*b
,
7176 struct torture_context
*tctx
,
7177 struct policy_handle
*handle
,
7179 uint32_t *total_num_entries_p
)
7182 struct samr_QueryDisplayInfo r
;
7183 uint32_t total_num_entries
= 0;
7185 r
.in
.domain_handle
= handle
;
7188 r
.in
.max_entries
= (uint32_t)-1;
7189 r
.in
.buf_size
= (uint32_t)-1;
7191 torture_comment(tctx
, "Testing QueryDisplayInfo\n");
7194 uint32_t total_size
;
7195 uint32_t returned_size
;
7196 union samr_DispInfo info
;
7198 r
.out
.total_size
= &total_size
;
7199 r
.out
.returned_size
= &returned_size
;
7202 status
= dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &r
);
7203 if (NT_STATUS_IS_ERR(status
)) {
7204 torture_assert_ntstatus_ok(tctx
, status
,
7205 "failed to query displayinfo");
7208 if (*r
.out
.returned_size
== 0) {
7212 switch (r
.in
.level
) {
7214 total_num_entries
+= info
.info1
.count
;
7215 r
.in
.start_idx
+= info
.info1
.entries
[info
.info1
.count
- 1].idx
+ 1;
7218 total_num_entries
+= info
.info2
.count
;
7219 r
.in
.start_idx
+= info
.info2
.entries
[info
.info2
.count
- 1].idx
+ 1;
7222 total_num_entries
+= info
.info3
.count
;
7223 r
.in
.start_idx
+= info
.info3
.entries
[info
.info3
.count
- 1].idx
+ 1;
7226 total_num_entries
+= info
.info4
.count
;
7227 r
.in
.start_idx
+= info
.info4
.entries
[info
.info4
.count
- 1].idx
+ 1;
7230 total_num_entries
+= info
.info5
.count
;
7231 r
.in
.start_idx
+= info
.info5
.entries
[info
.info5
.count
- 1].idx
+ 1;
7237 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7239 if (total_num_entries_p
) {
7240 *total_num_entries_p
= total_num_entries
;
7246 static bool test_ManyObjects(struct dcerpc_pipe
*p
,
7247 struct torture_context
*tctx
,
7248 struct policy_handle
*domain_handle
,
7249 struct dom_sid
*domain_sid
,
7250 struct torture_samr_context
*ctx
)
7252 uint32_t num_total
= ctx
->num_objects_large_dc
;
7253 uint32_t num_enum
= 0;
7254 uint32_t num_disp
= 0;
7255 uint32_t num_created
= 0;
7256 uint32_t num_anounced
= 0;
7260 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7262 struct policy_handle
*handles
= talloc_zero_array(tctx
, struct policy_handle
, num_total
);
7267 struct samr_QueryDomainInfo2 r
;
7268 union samr_DomainInfo
*info
;
7269 r
.in
.domain_handle
= domain_handle
;
7273 status
= dcerpc_samr_QueryDomainInfo2_r(b
, tctx
, &r
);
7274 torture_assert_ntstatus_ok(tctx
, status
,
7275 "failed to query domain info");
7277 switch (ctx
->choice
) {
7278 case TORTURE_SAMR_MANY_ACCOUNTS
:
7279 num_anounced
= info
->general
.num_users
;
7281 case TORTURE_SAMR_MANY_GROUPS
:
7282 num_anounced
= info
->general
.num_groups
;
7284 case TORTURE_SAMR_MANY_ALIASES
:
7285 num_anounced
= info
->general
.num_aliases
;
7294 for (i
=0; i
< num_total
; i
++) {
7296 const char *name
= NULL
;
7298 switch (ctx
->choice
) {
7299 case TORTURE_SAMR_MANY_ACCOUNTS
:
7300 name
= talloc_asprintf(tctx
, "%s%04d", TEST_ACCOUNT_NAME
, i
);
7301 ret
&= test_CreateUser(p
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, 0, NULL
, false);
7303 case TORTURE_SAMR_MANY_GROUPS
:
7304 name
= talloc_asprintf(tctx
, "%s%04d", TEST_GROUPNAME
, i
);
7305 ret
&= test_CreateDomainGroup(b
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, false);
7307 case TORTURE_SAMR_MANY_ALIASES
:
7308 name
= talloc_asprintf(tctx
, "%s%04d", TEST_ALIASNAME
, i
);
7309 ret
&= test_CreateAlias(b
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, false);
7314 if (!policy_handle_empty(&handles
[i
])) {
7321 switch (ctx
->choice
) {
7322 case TORTURE_SAMR_MANY_ACCOUNTS
:
7323 ret
&= test_EnumDomainUsers(b
, tctx
, domain_handle
, &num_enum
);
7325 case TORTURE_SAMR_MANY_GROUPS
:
7326 ret
&= test_EnumDomainGroups(b
, tctx
, domain_handle
, &num_enum
);
7328 case TORTURE_SAMR_MANY_ALIASES
:
7329 ret
&= test_EnumDomainAliases(b
, tctx
, domain_handle
, &num_enum
);
7337 switch (ctx
->choice
) {
7338 case TORTURE_SAMR_MANY_ACCOUNTS
:
7339 ret
&= test_QueryDisplayInfo_level(b
, tctx
, domain_handle
, 1, &num_disp
);
7341 case TORTURE_SAMR_MANY_GROUPS
:
7342 ret
&= test_QueryDisplayInfo_level(b
, tctx
, domain_handle
, 3, &num_disp
);
7344 case TORTURE_SAMR_MANY_ALIASES
:
7345 /* no aliases in dispinfo */
7351 /* close or delete */
7353 for (i
=0; i
< num_total
; i
++) {
7355 if (policy_handle_empty(&handles
[i
])) {
7359 if (torture_setting_bool(tctx
, "samba3", false)) {
7360 ret
&= test_samr_handle_Close(b
, tctx
, &handles
[i
]);
7362 switch (ctx
->choice
) {
7363 case TORTURE_SAMR_MANY_ACCOUNTS
:
7364 ret
&= test_DeleteUser(b
, tctx
, &handles
[i
]);
7366 case TORTURE_SAMR_MANY_GROUPS
:
7367 ret
&= test_DeleteDomainGroup(b
, tctx
, &handles
[i
]);
7369 case TORTURE_SAMR_MANY_ALIASES
:
7370 ret
&= test_DeleteAlias(b
, tctx
, &handles
[i
]);
7378 talloc_free(handles
);
7380 if (ctx
->choice
== TORTURE_SAMR_MANY_ACCOUNTS
&& num_enum
!= num_anounced
+ num_created
) {
7381 torture_comment(tctx
,
7382 "unexpected number of results (%u) returned in enum call, expected %u\n",
7383 num_enum
, num_anounced
+ num_created
);
7385 torture_comment(tctx
,
7386 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
7387 num_disp
, num_anounced
+ num_created
);
7392 static bool test_Connect(struct dcerpc_binding_handle
*b
,
7393 struct torture_context
*tctx
,
7394 struct policy_handle
*handle
);
7396 static bool test_OpenDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7397 struct torture_samr_context
*ctx
, struct dom_sid
*sid
)
7400 struct samr_OpenDomain r
;
7401 struct policy_handle domain_handle
;
7402 struct policy_handle alias_handle
;
7403 struct policy_handle user_handle
;
7404 struct policy_handle group_handle
;
7406 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7408 ZERO_STRUCT(alias_handle
);
7409 ZERO_STRUCT(user_handle
);
7410 ZERO_STRUCT(group_handle
);
7411 ZERO_STRUCT(domain_handle
);
7413 torture_comment(tctx
, "Testing OpenDomain of %s\n", dom_sid_string(tctx
, sid
));
7415 r
.in
.connect_handle
= &ctx
->handle
;
7416 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7418 r
.out
.domain_handle
= &domain_handle
;
7420 status
= dcerpc_samr_OpenDomain_r(b
, tctx
, &r
);
7421 torture_assert_ntstatus_ok(tctx
, status
, "OpenDomain");
7423 /* run the domain tests with the main handle closed - this tests
7424 the servers reference counting */
7425 torture_assert(tctx
, test_samr_handle_Close(b
, tctx
, &ctx
->handle
), "Failed to close SAMR handle");
7427 switch (ctx
->choice
) {
7428 case TORTURE_SAMR_PASSWORDS
:
7429 case TORTURE_SAMR_USER_PRIVILEGES
:
7430 if (!torture_setting_bool(tctx
, "samba3", false)) {
7431 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, NULL
);
7433 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
7435 torture_warning(tctx
, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7438 case TORTURE_SAMR_USER_ATTRIBUTES
:
7439 if (!torture_setting_bool(tctx
, "samba3", false)) {
7440 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, NULL
);
7442 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
7443 /* This test needs 'complex' users to validate */
7444 ret
&= test_QueryDisplayInfo(b
, tctx
, &domain_handle
);
7446 torture_warning(tctx
, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7449 case TORTURE_SAMR_PASSWORDS_PWDLASTSET
:
7450 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
:
7451 case TORTURE_SAMR_PASSWORDS_LOCKOUT
:
7452 if (!torture_setting_bool(tctx
, "samba3", false)) {
7453 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, ctx
->machine_credentials
);
7455 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, ctx
->machine_credentials
, true);
7457 torture_warning(tctx
, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7460 case TORTURE_SAMR_MANY_ACCOUNTS
:
7461 case TORTURE_SAMR_MANY_GROUPS
:
7462 case TORTURE_SAMR_MANY_ALIASES
:
7463 ret
&= test_ManyObjects(p
, tctx
, &domain_handle
, sid
, ctx
);
7465 torture_warning(tctx
, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7468 case TORTURE_SAMR_OTHER
:
7469 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
7471 torture_warning(tctx
, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx
, sid
));
7473 if (!torture_setting_bool(tctx
, "samba3", false)) {
7474 ret
&= test_QuerySecurity(b
, tctx
, &domain_handle
);
7476 ret
&= test_RemoveMemberFromForeignDomain(b
, tctx
, &domain_handle
);
7477 ret
&= test_CreateAlias(b
, tctx
, &domain_handle
, TEST_ALIASNAME
, &alias_handle
, sid
, true);
7478 ret
&= test_CreateDomainGroup(b
, tctx
, &domain_handle
, TEST_GROUPNAME
, &group_handle
, sid
, true);
7479 ret
&= test_GetAliasMembership(b
, tctx
, &domain_handle
);
7480 ret
&= test_QueryDomainInfo(p
, tctx
, &domain_handle
);
7481 ret
&= test_QueryDomainInfo2(b
, tctx
, &domain_handle
);
7482 ret
&= test_EnumDomainUsers_all(b
, tctx
, &domain_handle
);
7483 ret
&= test_EnumDomainUsers_async(p
, tctx
, &domain_handle
);
7484 ret
&= test_EnumDomainGroups_all(b
, tctx
, &domain_handle
);
7485 ret
&= test_EnumDomainAliases_all(b
, tctx
, &domain_handle
);
7486 ret
&= test_QueryDisplayInfo2(b
, tctx
, &domain_handle
);
7487 ret
&= test_QueryDisplayInfo3(b
, tctx
, &domain_handle
);
7488 ret
&= test_QueryDisplayInfo_continue(b
, tctx
, &domain_handle
);
7490 if (torture_setting_bool(tctx
, "samba4", false)) {
7491 torture_comment(tctx
, "skipping GetDisplayEnumerationIndex test against Samba4\n");
7493 ret
&= test_GetDisplayEnumerationIndex(b
, tctx
, &domain_handle
);
7494 ret
&= test_GetDisplayEnumerationIndex2(b
, tctx
, &domain_handle
);
7496 ret
&= test_GroupList(b
, tctx
, &domain_handle
);
7497 ret
&= test_TestPrivateFunctionsDomain(b
, tctx
, &domain_handle
);
7498 ret
&= test_RidToSid(b
, tctx
, sid
, &domain_handle
);
7499 ret
&= test_GetBootKeyInformation(b
, tctx
, &domain_handle
);
7501 torture_comment(tctx
, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7506 if (!policy_handle_empty(&user_handle
) &&
7507 !test_DeleteUser(b
, tctx
, &user_handle
)) {
7511 if (!policy_handle_empty(&alias_handle
) &&
7512 !test_DeleteAlias(b
, tctx
, &alias_handle
)) {
7516 if (!policy_handle_empty(&group_handle
) &&
7517 !test_DeleteDomainGroup(b
, tctx
, &group_handle
)) {
7521 torture_assert(tctx
, test_samr_handle_Close(b
, tctx
, &domain_handle
), "Failed to close SAMR domain handle");
7523 torture_assert(tctx
, test_Connect(b
, tctx
, &ctx
->handle
), "Faile to re-connect SAMR handle");
7524 /* reconnect the main handle */
7527 torture_warning(tctx
, "Testing domain %s failed!\n", dom_sid_string(tctx
, sid
));
7533 static bool test_LookupDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7534 struct torture_samr_context
*ctx
, const char *domain
)
7537 struct samr_LookupDomain r
;
7538 struct dom_sid2
*sid
= NULL
;
7539 struct lsa_String n1
;
7540 struct lsa_String n2
;
7542 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7544 torture_comment(tctx
, "Testing LookupDomain(%s)\n", domain
);
7546 /* check for correct error codes */
7547 r
.in
.connect_handle
= &ctx
->handle
;
7548 r
.in
.domain_name
= &n2
;
7552 status
= dcerpc_samr_LookupDomain_r(b
, tctx
, &r
);
7553 torture_assert_ntstatus_equal(tctx
, NT_STATUS_INVALID_PARAMETER
, status
, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
7555 init_lsa_String(&n2
, "xxNODOMAINxx");
7557 status
= dcerpc_samr_LookupDomain_r(b
, tctx
, &r
);
7558 torture_assert_ntstatus_equal(tctx
, NT_STATUS_NO_SUCH_DOMAIN
, status
, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
7560 r
.in
.connect_handle
= &ctx
->handle
;
7562 init_lsa_String(&n1
, domain
);
7563 r
.in
.domain_name
= &n1
;
7565 status
= dcerpc_samr_LookupDomain_r(b
, tctx
, &r
);
7566 torture_assert_ntstatus_ok(tctx
, status
, "LookupDomain");
7568 if (!test_GetDomPwInfo(p
, tctx
, &n1
)) {
7572 if (!test_OpenDomain(p
, tctx
, ctx
, *r
.out
.sid
)) {
7580 static bool test_EnumDomains(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7581 struct torture_samr_context
*ctx
)
7584 struct samr_EnumDomains r
;
7585 uint32_t resume_handle
= 0;
7586 uint32_t num_entries
= 0;
7587 struct samr_SamArray
*sam
= NULL
;
7590 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7592 r
.in
.connect_handle
= &ctx
->handle
;
7593 r
.in
.resume_handle
= &resume_handle
;
7594 r
.in
.buf_size
= (uint32_t)-1;
7595 r
.out
.resume_handle
= &resume_handle
;
7596 r
.out
.num_entries
= &num_entries
;
7599 status
= dcerpc_samr_EnumDomains_r(b
, tctx
, &r
);
7600 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomains");
7606 for (i
=0;i
<sam
->count
;i
++) {
7607 if (!test_LookupDomain(p
, tctx
, ctx
,
7608 sam
->entries
[i
].name
.string
)) {
7613 status
= dcerpc_samr_EnumDomains_r(b
, tctx
, &r
);
7614 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomains");
7620 static bool test_Connect(struct dcerpc_binding_handle
*b
,
7621 struct torture_context
*tctx
,
7622 struct policy_handle
*handle
)
7625 struct samr_Connect r
;
7626 struct samr_Connect2 r2
;
7627 struct samr_Connect3 r3
;
7628 struct samr_Connect4 r4
;
7629 struct samr_Connect5 r5
;
7630 union samr_ConnectInfo info
;
7631 struct policy_handle h
;
7632 uint32_t level_out
= 0;
7633 bool ret
= true, got_handle
= false;
7635 torture_comment(tctx
, "testing samr_Connect\n");
7637 r
.in
.system_name
= 0;
7638 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7639 r
.out
.connect_handle
= &h
;
7641 status
= dcerpc_samr_Connect_r(b
, tctx
, &r
);
7642 if (!NT_STATUS_IS_OK(status
)) {
7643 torture_comment(tctx
, "Connect failed - %s\n", nt_errstr(status
));
7650 torture_comment(tctx
, "testing samr_Connect2\n");
7652 r2
.in
.system_name
= NULL
;
7653 r2
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7654 r2
.out
.connect_handle
= &h
;
7656 status
= dcerpc_samr_Connect2_r(b
, tctx
, &r2
);
7657 if (!NT_STATUS_IS_OK(status
)) {
7658 torture_comment(tctx
, "Connect2 failed - %s\n", nt_errstr(status
));
7662 test_samr_handle_Close(b
, tctx
, handle
);
7668 torture_comment(tctx
, "testing samr_Connect3\n");
7670 r3
.in
.system_name
= NULL
;
7672 r3
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7673 r3
.out
.connect_handle
= &h
;
7675 status
= dcerpc_samr_Connect3_r(b
, tctx
, &r3
);
7676 if (!NT_STATUS_IS_OK(status
)) {
7677 torture_warning(tctx
, "Connect3 failed - %s\n", nt_errstr(status
));
7681 test_samr_handle_Close(b
, tctx
, handle
);
7687 torture_comment(tctx
, "testing samr_Connect4\n");
7689 r4
.in
.system_name
= "";
7690 r4
.in
.client_version
= 0;
7691 r4
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7692 r4
.out
.connect_handle
= &h
;
7694 status
= dcerpc_samr_Connect4_r(b
, tctx
, &r4
);
7695 if (!NT_STATUS_IS_OK(status
)) {
7696 torture_warning(tctx
, "Connect4 failed - %s\n", nt_errstr(status
));
7700 test_samr_handle_Close(b
, tctx
, handle
);
7706 torture_comment(tctx
, "testing samr_Connect5\n");
7708 info
.info1
.client_version
= 0;
7709 info
.info1
.unknown2
= 0;
7711 r5
.in
.system_name
= "";
7712 r5
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7714 r5
.out
.level_out
= &level_out
;
7715 r5
.in
.info_in
= &info
;
7716 r5
.out
.info_out
= &info
;
7717 r5
.out
.connect_handle
= &h
;
7719 status
= dcerpc_samr_Connect5_r(b
, tctx
, &r5
);
7720 if (!NT_STATUS_IS_OK(status
)) {
7721 torture_warning(tctx
, "Connect5 failed - %s\n", nt_errstr(status
));
7725 test_samr_handle_Close(b
, tctx
, handle
);
7735 static bool test_samr_ValidatePassword(struct dcerpc_pipe
*p
,
7736 struct torture_context
*tctx
)
7738 struct samr_ValidatePassword r
;
7739 union samr_ValidatePasswordReq req
;
7740 union samr_ValidatePasswordRep
*repp
= NULL
;
7742 const char *passwords
[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL
};
7744 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7746 torture_comment(tctx
, "testing samr_ValidatePassword\n");
7749 r
.in
.level
= NetValidatePasswordReset
;
7754 req
.req3
.account
.string
= "non-existant-account-aklsdji";
7756 for (i
=0; passwords
[i
]; i
++) {
7757 req
.req3
.password
.string
= passwords
[i
];
7758 status
= dcerpc_samr_ValidatePassword_r(b
, tctx
, &r
);
7759 if (NT_STATUS_EQUAL(status
, NT_STATUS_NET_WRITE_FAULT
) &&
7760 p
->last_fault_code
== DCERPC_FAULT_OP_RNG_ERROR
) {
7761 torture_skip(tctx
, "ValidatePassword not supported by server\n");
7763 torture_assert_ntstatus_ok(tctx
, status
, "samr_ValidatePassword");
7764 torture_comment(tctx
, "Server %s password '%s' with code %i\n",
7765 repp
->ctr3
.status
==SAMR_VALIDATION_STATUS_SUCCESS
?"allowed":"refused",
7766 req
.req3
.password
.string
, repp
->ctr3
.status
);
7772 bool torture_rpc_samr(struct torture_context
*torture
)
7775 struct dcerpc_pipe
*p
;
7777 struct torture_samr_context
*ctx
;
7778 struct dcerpc_binding_handle
*b
;
7780 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7781 if (!NT_STATUS_IS_OK(status
)) {
7784 b
= p
->binding_handle
;
7786 ctx
= talloc_zero(torture
, struct torture_samr_context
);
7788 ctx
->choice
= TORTURE_SAMR_OTHER
;
7790 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
7792 if (!torture_setting_bool(torture
, "samba3", false)) {
7793 ret
&= test_QuerySecurity(b
, torture
, &ctx
->handle
);
7796 ret
&= test_EnumDomains(p
, torture
, ctx
);
7798 ret
&= test_SetDsrmPassword(b
, torture
, &ctx
->handle
);
7800 ret
&= test_Shutdown(b
, torture
, &ctx
->handle
);
7802 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
7808 bool torture_rpc_samr_users(struct torture_context
*torture
)
7811 struct dcerpc_pipe
*p
;
7813 struct torture_samr_context
*ctx
;
7814 struct dcerpc_binding_handle
*b
;
7816 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7817 if (!NT_STATUS_IS_OK(status
)) {
7820 b
= p
->binding_handle
;
7822 ctx
= talloc_zero(torture
, struct torture_samr_context
);
7824 ctx
->choice
= TORTURE_SAMR_USER_ATTRIBUTES
;
7826 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
7828 if (!torture_setting_bool(torture
, "samba3", false)) {
7829 ret
&= test_QuerySecurity(b
, torture
, &ctx
->handle
);
7832 ret
&= test_EnumDomains(p
, torture
, ctx
);
7834 ret
&= test_SetDsrmPassword(b
, torture
, &ctx
->handle
);
7836 ret
&= test_Shutdown(b
, torture
, &ctx
->handle
);
7838 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
7844 bool torture_rpc_samr_passwords(struct torture_context
*torture
)
7847 struct dcerpc_pipe
*p
;
7849 struct torture_samr_context
*ctx
;
7850 struct dcerpc_binding_handle
*b
;
7852 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7853 if (!NT_STATUS_IS_OK(status
)) {
7856 b
= p
->binding_handle
;
7858 ctx
= talloc_zero(torture
, struct torture_samr_context
);
7860 ctx
->choice
= TORTURE_SAMR_PASSWORDS
;
7862 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
7864 ret
&= test_EnumDomains(p
, torture
, ctx
);
7866 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
7868 ret
&= test_samr_ValidatePassword(p
, torture
);
7873 static bool torture_rpc_samr_pwdlastset(struct torture_context
*torture
,
7874 struct dcerpc_pipe
*p2
,
7875 struct cli_credentials
*machine_credentials
)
7878 struct dcerpc_pipe
*p
;
7880 struct torture_samr_context
*ctx
;
7881 struct dcerpc_binding_handle
*b
;
7883 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7884 if (!NT_STATUS_IS_OK(status
)) {
7887 b
= p
->binding_handle
;
7889 ctx
= talloc_zero(torture
, struct torture_samr_context
);
7891 ctx
->choice
= TORTURE_SAMR_PASSWORDS_PWDLASTSET
;
7892 ctx
->machine_credentials
= machine_credentials
;
7894 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
7896 ret
&= test_EnumDomains(p
, torture
, ctx
);
7898 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
7903 struct torture_suite
*torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX
*mem_ctx
)
7905 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "SAMR-PASSWORDS-PWDLASTSET");
7906 struct torture_rpc_tcase
*tcase
;
7908 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
7910 TEST_ACCOUNT_NAME_PWD
);
7912 torture_rpc_tcase_add_test_creds(tcase
, "pwdLastSet",
7913 torture_rpc_samr_pwdlastset
);
7918 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context
*torture
,
7919 struct dcerpc_pipe
*p2
,
7920 struct cli_credentials
*machine_credentials
)
7923 struct dcerpc_pipe
*p
;
7925 struct torture_samr_context
*ctx
;
7926 struct dcerpc_binding_handle
*b
;
7928 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7929 if (!NT_STATUS_IS_OK(status
)) {
7932 b
= p
->binding_handle
;
7934 ctx
= talloc_zero(torture
, struct torture_samr_context
);
7936 ctx
->choice
= TORTURE_SAMR_USER_PRIVILEGES
;
7937 ctx
->machine_credentials
= machine_credentials
;
7939 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
7941 ret
&= test_EnumDomains(p
, torture
, ctx
);
7943 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
7948 struct torture_suite
*torture_rpc_samr_user_privileges(TALLOC_CTX
*mem_ctx
)
7950 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "SAMR-USERS-PRIVILEGES");
7951 struct torture_rpc_tcase
*tcase
;
7953 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
7955 TEST_ACCOUNT_NAME_PWD
);
7957 torture_rpc_tcase_add_test_creds(tcase
, "delete_privileged_user",
7958 torture_rpc_samr_users_privileges_delete_user
);
7963 static bool torture_rpc_samr_many_accounts(struct torture_context
*torture
,
7964 struct dcerpc_pipe
*p2
,
7968 struct dcerpc_pipe
*p
;
7970 struct torture_samr_context
*ctx
=
7971 talloc_get_type_abort(data
, struct torture_samr_context
);
7972 struct dcerpc_binding_handle
*b
;
7974 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7975 if (!NT_STATUS_IS_OK(status
)) {
7978 b
= p
->binding_handle
;
7980 ctx
->choice
= TORTURE_SAMR_MANY_ACCOUNTS
;
7981 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
7982 ctx
->num_objects_large_dc
);
7984 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
7986 ret
&= test_EnumDomains(p
, torture
, ctx
);
7988 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
7993 static bool torture_rpc_samr_many_groups(struct torture_context
*torture
,
7994 struct dcerpc_pipe
*p2
,
7998 struct dcerpc_pipe
*p
;
8000 struct torture_samr_context
*ctx
=
8001 talloc_get_type_abort(data
, struct torture_samr_context
);
8002 struct dcerpc_binding_handle
*b
;
8004 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8005 if (!NT_STATUS_IS_OK(status
)) {
8008 b
= p
->binding_handle
;
8010 ctx
->choice
= TORTURE_SAMR_MANY_GROUPS
;
8011 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
8012 ctx
->num_objects_large_dc
);
8014 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8016 ret
&= test_EnumDomains(p
, torture
, ctx
);
8018 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8023 static bool torture_rpc_samr_many_aliases(struct torture_context
*torture
,
8024 struct dcerpc_pipe
*p2
,
8028 struct dcerpc_pipe
*p
;
8030 struct torture_samr_context
*ctx
=
8031 talloc_get_type_abort(data
, struct torture_samr_context
);
8032 struct dcerpc_binding_handle
*b
;
8034 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8035 if (!NT_STATUS_IS_OK(status
)) {
8038 b
= p
->binding_handle
;
8040 ctx
->choice
= TORTURE_SAMR_MANY_ALIASES
;
8041 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
8042 ctx
->num_objects_large_dc
);
8044 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8046 ret
&= test_EnumDomains(p
, torture
, ctx
);
8048 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8053 struct torture_suite
*torture_rpc_samr_large_dc(TALLOC_CTX
*mem_ctx
)
8055 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "SAMR-LARGE-DC");
8056 struct torture_rpc_tcase
*tcase
;
8057 struct torture_samr_context
*ctx
;
8059 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "samr", &ndr_table_samr
);
8061 ctx
= talloc_zero(suite
, struct torture_samr_context
);
8062 ctx
->num_objects_large_dc
= 150;
8064 torture_rpc_tcase_add_test_ex(tcase
, "many_aliases",
8065 torture_rpc_samr_many_aliases
, ctx
);
8066 torture_rpc_tcase_add_test_ex(tcase
, "many_groups",
8067 torture_rpc_samr_many_groups
, ctx
);
8068 torture_rpc_tcase_add_test_ex(tcase
, "many_accounts",
8069 torture_rpc_samr_many_accounts
, ctx
);
8074 static bool torture_rpc_samr_badpwdcount(struct torture_context
*torture
,
8075 struct dcerpc_pipe
*p2
,
8076 struct cli_credentials
*machine_credentials
)
8079 struct dcerpc_pipe
*p
;
8081 struct torture_samr_context
*ctx
;
8082 struct dcerpc_binding_handle
*b
;
8084 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8085 if (!NT_STATUS_IS_OK(status
)) {
8088 b
= p
->binding_handle
;
8090 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8092 ctx
->choice
= TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
;
8093 ctx
->machine_credentials
= machine_credentials
;
8095 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8097 ret
&= test_EnumDomains(p
, torture
, ctx
);
8099 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8104 struct torture_suite
*torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX
*mem_ctx
)
8106 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "SAMR-PASSWORDS-BADPWDCOUNT");
8107 struct torture_rpc_tcase
*tcase
;
8109 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
8111 TEST_ACCOUNT_NAME_PWD
);
8113 torture_rpc_tcase_add_test_creds(tcase
, "badPwdCount",
8114 torture_rpc_samr_badpwdcount
);
8119 static bool torture_rpc_samr_lockout(struct torture_context
*torture
,
8120 struct dcerpc_pipe
*p2
,
8121 struct cli_credentials
*machine_credentials
)
8124 struct dcerpc_pipe
*p
;
8126 struct torture_samr_context
*ctx
;
8127 struct dcerpc_binding_handle
*b
;
8129 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8130 if (!NT_STATUS_IS_OK(status
)) {
8133 b
= p
->binding_handle
;
8135 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8137 ctx
->choice
= TORTURE_SAMR_PASSWORDS_LOCKOUT
;
8138 ctx
->machine_credentials
= machine_credentials
;
8140 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
8142 ret
&= test_EnumDomains(p
, torture
, ctx
);
8144 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
8149 struct torture_suite
*torture_rpc_samr_passwords_lockout(TALLOC_CTX
*mem_ctx
)
8151 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "SAMR-PASSWORDS-LOCKOUT");
8152 struct torture_rpc_tcase
*tcase
;
8154 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
8156 TEST_ACCOUNT_NAME_PWD
);
8158 torture_rpc_tcase_add_test_creds(tcase
, "lockout",
8159 torture_rpc_samr_lockout
);