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,2009
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"
25 #include "system/time.h"
26 #include "librpc/gen_ndr/lsa.h"
27 #include "librpc/gen_ndr/ndr_netlogon.h"
28 #include "librpc/gen_ndr/ndr_netlogon_c.h"
29 #include "librpc/gen_ndr/ndr_samr_c.h"
30 #include "librpc/gen_ndr/ndr_lsa_c.h"
31 #include "../lib/crypto/crypto.h"
32 #include "libcli/auth/libcli_auth.h"
33 #include "libcli/security/security.h"
34 #include "torture/rpc/rpc.h"
35 #include "param/param.h"
39 #define TEST_ACCOUNT_NAME "samrtorturetest"
40 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
41 #define TEST_ALIASNAME "samrtorturetestalias"
42 #define TEST_GROUPNAME "samrtorturetestgroup"
43 #define TEST_MACHINENAME "samrtestmach$"
44 #define TEST_DOMAINNAME "samrtestdom$"
46 enum torture_samr_choice
{
47 TORTURE_SAMR_PASSWORDS
,
48 TORTURE_SAMR_PASSWORDS_PWDLASTSET
,
49 TORTURE_SAMR_USER_ATTRIBUTES
,
50 TORTURE_SAMR_USER_PRIVILEGES
,
52 TORTURE_SAMR_MANY_ACCOUNTS
,
53 TORTURE_SAMR_MANY_GROUPS
,
54 TORTURE_SAMR_MANY_ALIASES
57 struct torture_samr_context
{
58 struct policy_handle handle
;
59 struct cli_credentials
*machine_credentials
;
60 enum torture_samr_choice choice
;
61 uint32_t num_objects_large_dc
;
64 static bool test_QueryUserInfo(struct dcerpc_pipe
*p
,
65 struct torture_context
*tctx
,
66 struct policy_handle
*handle
);
68 static bool test_QueryUserInfo2(struct dcerpc_pipe
*p
,
69 struct torture_context
*tctx
,
70 struct policy_handle
*handle
);
72 static bool test_QueryAliasInfo(struct dcerpc_pipe
*p
,
73 struct torture_context
*tctx
,
74 struct policy_handle
*handle
);
76 static bool test_ChangePassword(struct dcerpc_pipe
*p
,
77 struct torture_context
*tctx
,
78 const char *acct_name
,
79 struct policy_handle
*domain_handle
, char **password
);
81 static void init_lsa_String(struct lsa_String
*string
, const char *s
)
86 static void init_lsa_StringLarge(struct lsa_StringLarge
*string
, const char *s
)
91 static void init_lsa_BinaryString(struct lsa_BinaryString
*string
, const char *s
, uint32_t length
)
93 string
->length
= length
;
94 string
->size
= length
;
95 string
->array
= (uint16_t *)discard_const(s
);
98 bool test_samr_handle_Close(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
99 struct policy_handle
*handle
)
104 r
.in
.handle
= handle
;
105 r
.out
.handle
= handle
;
107 status
= dcerpc_samr_Close(p
, tctx
, &r
);
108 torture_assert_ntstatus_ok(tctx
, status
, "Close");
113 static bool test_Shutdown(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
114 struct policy_handle
*handle
)
117 struct samr_Shutdown r
;
119 if (!torture_setting_bool(tctx
, "dangerous", false)) {
120 torture_skip(tctx
, "samr_Shutdown disabled - enable dangerous tests to use\n");
124 r
.in
.connect_handle
= handle
;
126 torture_comment(tctx
, "testing samr_Shutdown\n");
128 status
= dcerpc_samr_Shutdown(p
, tctx
, &r
);
129 torture_assert_ntstatus_ok(tctx
, status
, "samr_Shutdown");
134 static bool test_SetDsrmPassword(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
135 struct policy_handle
*handle
)
138 struct samr_SetDsrmPassword r
;
139 struct lsa_String string
;
140 struct samr_Password hash
;
142 if (!torture_setting_bool(tctx
, "dangerous", false)) {
143 torture_skip(tctx
, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
146 E_md4hash("TeSTDSRM123", hash
.hash
);
148 init_lsa_String(&string
, "Administrator");
154 torture_comment(tctx
, "testing samr_SetDsrmPassword\n");
156 status
= dcerpc_samr_SetDsrmPassword(p
, tctx
, &r
);
157 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_NOT_SUPPORTED
, "samr_SetDsrmPassword");
163 static bool test_QuerySecurity(struct dcerpc_pipe
*p
,
164 struct torture_context
*tctx
,
165 struct policy_handle
*handle
)
168 struct samr_QuerySecurity r
;
169 struct samr_SetSecurity s
;
170 struct sec_desc_buf
*sdbuf
= NULL
;
172 r
.in
.handle
= handle
;
174 r
.out
.sdbuf
= &sdbuf
;
176 status
= dcerpc_samr_QuerySecurity(p
, tctx
, &r
);
177 torture_assert_ntstatus_ok(tctx
, status
, "QuerySecurity");
179 torture_assert(tctx
, sdbuf
!= NULL
, "sdbuf is NULL");
181 s
.in
.handle
= handle
;
185 if (torture_setting_bool(tctx
, "samba4", false)) {
186 torture_skip(tctx
, "skipping SetSecurity test against Samba4\n");
189 status
= dcerpc_samr_SetSecurity(p
, tctx
, &s
);
190 torture_assert_ntstatus_ok(tctx
, status
, "SetSecurity");
192 status
= dcerpc_samr_QuerySecurity(p
, tctx
, &r
);
193 torture_assert_ntstatus_ok(tctx
, status
, "QuerySecurity");
199 static bool test_SetUserInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
200 struct policy_handle
*handle
, uint32_t base_acct_flags
,
201 const char *base_account_name
)
204 struct samr_SetUserInfo s
;
205 struct samr_SetUserInfo2 s2
;
206 struct samr_QueryUserInfo q
;
207 struct samr_QueryUserInfo q0
;
208 union samr_UserInfo u
;
209 union samr_UserInfo
*info
;
211 const char *test_account_name
;
213 uint32_t user_extra_flags
= 0;
215 if (!torture_setting_bool(tctx
, "samba3", false)) {
216 if (base_acct_flags
== ACB_NORMAL
) {
217 /* When created, accounts are expired by default */
218 user_extra_flags
= ACB_PW_EXPIRED
;
222 s
.in
.user_handle
= handle
;
225 s2
.in
.user_handle
= handle
;
228 q
.in
.user_handle
= handle
;
232 #define TESTCALL(call, r) \
233 status = dcerpc_samr_ ##call(p, tctx, &r); \
234 if (!NT_STATUS_IS_OK(status)) { \
235 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
236 r.in.level, nt_errstr(status), __location__); \
241 #define STRING_EQUAL(s1, s2, field) \
242 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
243 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
244 #field, s2, __location__); \
249 #define MEM_EQUAL(s1, s2, length, field) \
250 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
251 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
252 #field, (const char *)s2, __location__); \
257 #define INT_EQUAL(i1, i2, field) \
259 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
260 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
265 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
266 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
268 TESTCALL(QueryUserInfo, q) \
270 s2.in.level = lvl1; \
273 ZERO_STRUCT(u.info21); \
274 u.info21.fields_present = fpval; \
276 init_lsa_String(&u.info ## lvl1.field1, value); \
277 TESTCALL(SetUserInfo, s) \
278 TESTCALL(SetUserInfo2, s2) \
279 init_lsa_String(&u.info ## lvl1.field1, ""); \
280 TESTCALL(QueryUserInfo, q); \
282 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
284 TESTCALL(QueryUserInfo, q) \
286 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
289 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
290 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
292 TESTCALL(QueryUserInfo, q) \
294 s2.in.level = lvl1; \
297 ZERO_STRUCT(u.info21); \
298 u.info21.fields_present = fpval; \
300 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
301 TESTCALL(SetUserInfo, s) \
302 TESTCALL(SetUserInfo2, s2) \
303 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
304 TESTCALL(QueryUserInfo, q); \
306 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
308 TESTCALL(QueryUserInfo, q) \
310 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
313 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
314 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
316 TESTCALL(QueryUserInfo, q) \
318 s2.in.level = lvl1; \
321 uint8_t *bits = u.info21.logon_hours.bits; \
322 ZERO_STRUCT(u.info21); \
323 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
324 u.info21.logon_hours.units_per_week = 168; \
325 u.info21.logon_hours.bits = bits; \
327 u.info21.fields_present = fpval; \
329 u.info ## lvl1.field1 = value; \
330 TESTCALL(SetUserInfo, s) \
331 TESTCALL(SetUserInfo2, s2) \
332 u.info ## lvl1.field1 = 0; \
333 TESTCALL(QueryUserInfo, q); \
335 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
337 TESTCALL(QueryUserInfo, q) \
339 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
342 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
343 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
347 do { TESTCALL(QueryUserInfo
, q0
) } while (0);
349 TEST_USERINFO_STRING(2, comment
, 1, comment
, "xx2-1 comment", 0);
350 TEST_USERINFO_STRING(2, comment
, 21, comment
, "xx2-21 comment", 0);
351 TEST_USERINFO_STRING(21, comment
, 21, comment
, "xx21-21 comment",
354 test_account_name
= talloc_asprintf(tctx
, "%sxx7-1", base_account_name
);
355 TEST_USERINFO_STRING(7, account_name
, 1, account_name
, base_account_name
, 0);
356 test_account_name
= talloc_asprintf(tctx
, "%sxx7-3", base_account_name
);
357 TEST_USERINFO_STRING(7, account_name
, 3, account_name
, base_account_name
, 0);
358 test_account_name
= talloc_asprintf(tctx
, "%sxx7-5", base_account_name
);
359 TEST_USERINFO_STRING(7, account_name
, 5, account_name
, base_account_name
, 0);
360 test_account_name
= talloc_asprintf(tctx
, "%sxx7-6", base_account_name
);
361 TEST_USERINFO_STRING(7, account_name
, 6, account_name
, base_account_name
, 0);
362 test_account_name
= talloc_asprintf(tctx
, "%sxx7-7", base_account_name
);
363 TEST_USERINFO_STRING(7, account_name
, 7, account_name
, base_account_name
, 0);
364 test_account_name
= talloc_asprintf(tctx
, "%sxx7-21", base_account_name
);
365 TEST_USERINFO_STRING(7, account_name
, 21, account_name
, base_account_name
, 0);
366 test_account_name
= base_account_name
;
367 TEST_USERINFO_STRING(21, account_name
, 21, account_name
, base_account_name
,
368 SAMR_FIELD_ACCOUNT_NAME
);
370 TEST_USERINFO_STRING(6, full_name
, 1, full_name
, "xx6-1 full_name", 0);
371 TEST_USERINFO_STRING(6, full_name
, 3, full_name
, "xx6-3 full_name", 0);
372 TEST_USERINFO_STRING(6, full_name
, 5, full_name
, "xx6-5 full_name", 0);
373 TEST_USERINFO_STRING(6, full_name
, 6, full_name
, "xx6-6 full_name", 0);
374 TEST_USERINFO_STRING(6, full_name
, 8, full_name
, "xx6-8 full_name", 0);
375 TEST_USERINFO_STRING(6, full_name
, 21, full_name
, "xx6-21 full_name", 0);
376 TEST_USERINFO_STRING(8, full_name
, 21, full_name
, "xx8-21 full_name", 0);
377 TEST_USERINFO_STRING(21, full_name
, 21, full_name
, "xx21-21 full_name",
378 SAMR_FIELD_FULL_NAME
);
380 TEST_USERINFO_STRING(6, full_name
, 1, full_name
, "", 0);
381 TEST_USERINFO_STRING(6, full_name
, 3, full_name
, "", 0);
382 TEST_USERINFO_STRING(6, full_name
, 5, full_name
, "", 0);
383 TEST_USERINFO_STRING(6, full_name
, 6, full_name
, "", 0);
384 TEST_USERINFO_STRING(6, full_name
, 8, full_name
, "", 0);
385 TEST_USERINFO_STRING(6, full_name
, 21, full_name
, "", 0);
386 TEST_USERINFO_STRING(8, full_name
, 21, full_name
, "", 0);
387 TEST_USERINFO_STRING(21, full_name
, 21, full_name
, "",
388 SAMR_FIELD_FULL_NAME
);
390 TEST_USERINFO_STRING(11, logon_script
, 3, logon_script
, "xx11-3 logon_script", 0);
391 TEST_USERINFO_STRING(11, logon_script
, 5, logon_script
, "xx11-5 logon_script", 0);
392 TEST_USERINFO_STRING(11, logon_script
, 21, logon_script
, "xx11-21 logon_script", 0);
393 TEST_USERINFO_STRING(21, logon_script
, 21, logon_script
, "xx21-21 logon_script",
394 SAMR_FIELD_LOGON_SCRIPT
);
396 TEST_USERINFO_STRING(12, profile_path
, 3, profile_path
, "xx12-3 profile_path", 0);
397 TEST_USERINFO_STRING(12, profile_path
, 5, profile_path
, "xx12-5 profile_path", 0);
398 TEST_USERINFO_STRING(12, profile_path
, 21, profile_path
, "xx12-21 profile_path", 0);
399 TEST_USERINFO_STRING(21, profile_path
, 21, profile_path
, "xx21-21 profile_path",
400 SAMR_FIELD_PROFILE_PATH
);
402 TEST_USERINFO_STRING(10, home_directory
, 3, home_directory
, "xx10-3 home_directory", 0);
403 TEST_USERINFO_STRING(10, home_directory
, 5, home_directory
, "xx10-5 home_directory", 0);
404 TEST_USERINFO_STRING(10, home_directory
, 21, home_directory
, "xx10-21 home_directory", 0);
405 TEST_USERINFO_STRING(21, home_directory
, 21, home_directory
, "xx21-21 home_directory",
406 SAMR_FIELD_HOME_DIRECTORY
);
407 TEST_USERINFO_STRING(21, home_directory
, 10, home_directory
, "xx21-10 home_directory",
408 SAMR_FIELD_HOME_DIRECTORY
);
410 TEST_USERINFO_STRING(10, home_drive
, 3, home_drive
, "xx10-3 home_drive", 0);
411 TEST_USERINFO_STRING(10, home_drive
, 5, home_drive
, "xx10-5 home_drive", 0);
412 TEST_USERINFO_STRING(10, home_drive
, 21, home_drive
, "xx10-21 home_drive", 0);
413 TEST_USERINFO_STRING(21, home_drive
, 21, home_drive
, "xx21-21 home_drive",
414 SAMR_FIELD_HOME_DRIVE
);
415 TEST_USERINFO_STRING(21, home_drive
, 10, home_drive
, "xx21-10 home_drive",
416 SAMR_FIELD_HOME_DRIVE
);
418 TEST_USERINFO_STRING(13, description
, 1, description
, "xx13-1 description", 0);
419 TEST_USERINFO_STRING(13, description
, 5, description
, "xx13-5 description", 0);
420 TEST_USERINFO_STRING(13, description
, 21, description
, "xx13-21 description", 0);
421 TEST_USERINFO_STRING(21, description
, 21, description
, "xx21-21 description",
422 SAMR_FIELD_DESCRIPTION
);
424 TEST_USERINFO_STRING(14, workstations
, 3, workstations
, "14workstation3", 0);
425 TEST_USERINFO_STRING(14, workstations
, 5, workstations
, "14workstation4", 0);
426 TEST_USERINFO_STRING(14, workstations
, 21, workstations
, "14workstation21", 0);
427 TEST_USERINFO_STRING(21, workstations
, 21, workstations
, "21workstation21",
428 SAMR_FIELD_WORKSTATIONS
);
429 TEST_USERINFO_STRING(21, workstations
, 3, workstations
, "21workstation3",
430 SAMR_FIELD_WORKSTATIONS
);
431 TEST_USERINFO_STRING(21, workstations
, 5, workstations
, "21workstation5",
432 SAMR_FIELD_WORKSTATIONS
);
433 TEST_USERINFO_STRING(21, workstations
, 14, workstations
, "21workstation14",
434 SAMR_FIELD_WORKSTATIONS
);
436 TEST_USERINFO_BINARYSTRING(20, parameters
, 21, parameters
, "xx20-21 parameters", 0);
437 TEST_USERINFO_BINARYSTRING(21, parameters
, 21, parameters
, "xx21-21 parameters",
438 SAMR_FIELD_PARAMETERS
);
439 TEST_USERINFO_BINARYSTRING(21, parameters
, 20, parameters
, "xx21-20 parameters",
440 SAMR_FIELD_PARAMETERS
);
441 /* also empty user parameters are allowed */
442 TEST_USERINFO_BINARYSTRING(20, parameters
, 21, parameters
, "", 0);
443 TEST_USERINFO_BINARYSTRING(21, parameters
, 21, parameters
, "",
444 SAMR_FIELD_PARAMETERS
);
445 TEST_USERINFO_BINARYSTRING(21, parameters
, 20, parameters
, "",
446 SAMR_FIELD_PARAMETERS
);
448 /* Samba 3 cannot store country_code and copy_page atm. - gd */
449 if (!torture_setting_bool(tctx
, "samba3", false)) {
450 TEST_USERINFO_INT(2, country_code
, 2, country_code
, __LINE__
, 0);
451 TEST_USERINFO_INT(2, country_code
, 21, country_code
, __LINE__
, 0);
452 TEST_USERINFO_INT(21, country_code
, 21, country_code
, __LINE__
,
453 SAMR_FIELD_COUNTRY_CODE
);
454 TEST_USERINFO_INT(21, country_code
, 2, country_code
, __LINE__
,
455 SAMR_FIELD_COUNTRY_CODE
);
457 TEST_USERINFO_INT(2, code_page
, 21, code_page
, __LINE__
, 0);
458 TEST_USERINFO_INT(21, code_page
, 21, code_page
, __LINE__
,
459 SAMR_FIELD_CODE_PAGE
);
460 TEST_USERINFO_INT(21, code_page
, 2, code_page
, __LINE__
,
461 SAMR_FIELD_CODE_PAGE
);
464 if (!torture_setting_bool(tctx
, "samba3", false)) {
465 TEST_USERINFO_INT(17, acct_expiry
, 21, acct_expiry
, __LINE__
, 0);
466 TEST_USERINFO_INT(17, acct_expiry
, 5, acct_expiry
, __LINE__
, 0);
467 TEST_USERINFO_INT(21, acct_expiry
, 21, acct_expiry
, __LINE__
,
468 SAMR_FIELD_ACCT_EXPIRY
);
469 TEST_USERINFO_INT(21, acct_expiry
, 5, acct_expiry
, __LINE__
,
470 SAMR_FIELD_ACCT_EXPIRY
);
471 TEST_USERINFO_INT(21, acct_expiry
, 17, acct_expiry
, __LINE__
,
472 SAMR_FIELD_ACCT_EXPIRY
);
474 /* Samba 3 can only store seconds / time_t in passdb - gd */
476 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
477 TEST_USERINFO_INT(17, acct_expiry
, 21, acct_expiry
, nt
, 0);
478 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
479 TEST_USERINFO_INT(17, acct_expiry
, 5, acct_expiry
, nt
, 0);
480 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
481 TEST_USERINFO_INT(21, acct_expiry
, 21, acct_expiry
, nt
, SAMR_FIELD_ACCT_EXPIRY
);
482 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
483 TEST_USERINFO_INT(21, acct_expiry
, 5, acct_expiry
, nt
, SAMR_FIELD_ACCT_EXPIRY
);
484 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
485 TEST_USERINFO_INT(21, acct_expiry
, 17, acct_expiry
, nt
, SAMR_FIELD_ACCT_EXPIRY
);
488 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 3, logon_hours
.bits
[3], 1, 0);
489 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 5, logon_hours
.bits
[3], 2, 0);
490 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 21, logon_hours
.bits
[3], 3, 0);
491 TEST_USERINFO_INT(21, logon_hours
.bits
[3], 21, logon_hours
.bits
[3], 4,
492 SAMR_FIELD_LOGON_HOURS
);
494 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
495 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
),
496 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
| user_extra_flags
),
498 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
499 (base_acct_flags
| ACB_DISABLED
),
500 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
503 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
504 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
505 (base_acct_flags
| ACB_DISABLED
| ACB_PWNOEXP
),
506 (base_acct_flags
| ACB_DISABLED
| ACB_PWNOEXP
),
508 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
509 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
),
510 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
| user_extra_flags
),
514 /* The 'autolock' flag doesn't stick - check this */
515 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
516 (base_acct_flags
| ACB_DISABLED
| ACB_AUTOLOCK
),
517 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
520 /* Removing the 'disabled' flag doesn't stick - check this */
521 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
523 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
527 /* Samba3 cannot store these atm */
528 if (!torture_setting_bool(tctx
, "samba3", false)) {
529 /* The 'store plaintext' flag does stick */
530 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
531 (base_acct_flags
| ACB_DISABLED
| ACB_ENC_TXT_PWD_ALLOWED
),
532 (base_acct_flags
| ACB_DISABLED
| ACB_ENC_TXT_PWD_ALLOWED
| user_extra_flags
),
534 /* The 'use DES' flag does stick */
535 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
536 (base_acct_flags
| ACB_DISABLED
| ACB_USE_DES_KEY_ONLY
),
537 (base_acct_flags
| ACB_DISABLED
| ACB_USE_DES_KEY_ONLY
| user_extra_flags
),
539 /* The 'don't require kerberos pre-authentication flag does stick */
540 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
541 (base_acct_flags
| ACB_DISABLED
| ACB_DONT_REQUIRE_PREAUTH
),
542 (base_acct_flags
| ACB_DISABLED
| ACB_DONT_REQUIRE_PREAUTH
| user_extra_flags
),
544 /* The 'no kerberos PAC required' flag sticks */
545 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
546 (base_acct_flags
| ACB_DISABLED
| ACB_NO_AUTH_DATA_REQD
),
547 (base_acct_flags
| ACB_DISABLED
| ACB_NO_AUTH_DATA_REQD
| user_extra_flags
),
550 TEST_USERINFO_INT_EXP(21, acct_flags
, 21, acct_flags
,
551 (base_acct_flags
| ACB_DISABLED
),
552 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
553 SAMR_FIELD_ACCT_FLAGS
);
556 /* these fail with win2003 - it appears you can't set the primary gid?
557 the set succeeds, but the gid isn't changed. Very weird! */
558 TEST_USERINFO_INT(9, primary_gid
, 1, primary_gid
, 513);
559 TEST_USERINFO_INT(9, primary_gid
, 3, primary_gid
, 513);
560 TEST_USERINFO_INT(9, primary_gid
, 5, primary_gid
, 513);
561 TEST_USERINFO_INT(9, primary_gid
, 21, primary_gid
, 513);
568 generate a random password for password change tests
570 static char *samr_rand_pass_silent(TALLOC_CTX
*mem_ctx
, int min_len
)
572 size_t len
= MAX(8, min_len
) + (random() % 6);
573 char *s
= generate_random_str(mem_ctx
, len
);
577 static char *samr_rand_pass(TALLOC_CTX
*mem_ctx
, int min_len
)
579 char *s
= samr_rand_pass_silent(mem_ctx
, min_len
);
580 printf("Generated password '%s'\n", s
);
586 generate a random password for password change tests
588 static DATA_BLOB
samr_very_rand_pass(TALLOC_CTX
*mem_ctx
, int len
)
591 DATA_BLOB password
= data_blob_talloc(mem_ctx
, NULL
, len
* 2 /* number of unicode chars */);
592 generate_random_buffer(password
.data
, password
.length
);
594 for (i
=0; i
< len
; i
++) {
595 if (((uint16_t *)password
.data
)[i
] == 0) {
596 ((uint16_t *)password
.data
)[i
] = 1;
604 generate a random password for password change tests (fixed length)
606 static char *samr_rand_pass_fixed_len(TALLOC_CTX
*mem_ctx
, int len
)
608 char *s
= generate_random_str(mem_ctx
, len
);
609 printf("Generated password '%s'\n", s
);
613 static bool test_SetUserPass(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
614 struct policy_handle
*handle
, char **password
)
617 struct samr_SetUserInfo s
;
618 union samr_UserInfo u
;
620 DATA_BLOB session_key
;
622 struct samr_GetUserPwInfo pwp
;
623 struct samr_PwInfo info
;
624 int policy_min_pw_len
= 0;
625 pwp
.in
.user_handle
= handle
;
626 pwp
.out
.info
= &info
;
628 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
629 if (NT_STATUS_IS_OK(status
)) {
630 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
632 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
634 s
.in
.user_handle
= handle
;
638 encode_pw_buffer(u
.info24
.password
.data
, newpass
, STR_UNICODE
);
639 u
.info24
.password_expired
= 0;
641 status
= dcerpc_fetch_session_key(p
, &session_key
);
642 if (!NT_STATUS_IS_OK(status
)) {
643 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
644 s
.in
.level
, nt_errstr(status
));
648 arcfour_crypt_blob(u
.info24
.password
.data
, 516, &session_key
);
650 torture_comment(tctx
, "Testing SetUserInfo level 24 (set password)\n");
652 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
653 if (!NT_STATUS_IS_OK(status
)) {
654 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
655 s
.in
.level
, nt_errstr(status
));
665 static bool test_SetUserPass_23(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
666 struct policy_handle
*handle
, uint32_t fields_present
,
670 struct samr_SetUserInfo s
;
671 union samr_UserInfo u
;
673 DATA_BLOB session_key
;
675 struct samr_GetUserPwInfo pwp
;
676 struct samr_PwInfo info
;
677 int policy_min_pw_len
= 0;
678 pwp
.in
.user_handle
= handle
;
679 pwp
.out
.info
= &info
;
681 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
682 if (NT_STATUS_IS_OK(status
)) {
683 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
685 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
687 s
.in
.user_handle
= handle
;
693 u
.info23
.info
.fields_present
= fields_present
;
695 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
697 status
= dcerpc_fetch_session_key(p
, &session_key
);
698 if (!NT_STATUS_IS_OK(status
)) {
699 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
700 s
.in
.level
, nt_errstr(status
));
704 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
706 torture_comment(tctx
, "Testing SetUserInfo level 23 (set password)\n");
708 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
709 if (!NT_STATUS_IS_OK(status
)) {
710 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
711 s
.in
.level
, nt_errstr(status
));
717 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
719 status
= dcerpc_fetch_session_key(p
, &session_key
);
720 if (!NT_STATUS_IS_OK(status
)) {
721 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
722 s
.in
.level
, nt_errstr(status
));
726 /* This should break the key nicely */
727 session_key
.length
--;
728 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
730 torture_comment(tctx
, "Testing SetUserInfo level 23 (set password) with wrong password\n");
732 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
733 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
734 torture_warning(tctx
, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
735 s
.in
.level
, nt_errstr(status
));
743 static bool test_SetUserPassEx(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
744 struct policy_handle
*handle
, bool makeshort
,
748 struct samr_SetUserInfo s
;
749 union samr_UserInfo u
;
751 DATA_BLOB session_key
;
752 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
753 uint8_t confounder
[16];
755 struct MD5Context ctx
;
756 struct samr_GetUserPwInfo pwp
;
757 struct samr_PwInfo info
;
758 int policy_min_pw_len
= 0;
759 pwp
.in
.user_handle
= handle
;
760 pwp
.out
.info
= &info
;
762 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
763 if (NT_STATUS_IS_OK(status
)) {
764 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
766 if (makeshort
&& policy_min_pw_len
) {
767 newpass
= samr_rand_pass_fixed_len(tctx
, policy_min_pw_len
- 1);
769 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
772 s
.in
.user_handle
= handle
;
776 encode_pw_buffer(u
.info26
.password
.data
, newpass
, STR_UNICODE
);
777 u
.info26
.password_expired
= 0;
779 status
= dcerpc_fetch_session_key(p
, &session_key
);
780 if (!NT_STATUS_IS_OK(status
)) {
781 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
782 s
.in
.level
, nt_errstr(status
));
786 generate_random_buffer((uint8_t *)confounder
, 16);
789 MD5Update(&ctx
, confounder
, 16);
790 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
791 MD5Final(confounded_session_key
.data
, &ctx
);
793 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
794 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
796 torture_comment(tctx
, "Testing SetUserInfo level 26 (set password ex)\n");
798 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
799 if (!NT_STATUS_IS_OK(status
)) {
800 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
801 s
.in
.level
, nt_errstr(status
));
807 /* This should break the key nicely */
808 confounded_session_key
.data
[0]++;
810 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
811 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
813 torture_comment(tctx
, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
815 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
816 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
817 torture_warning(tctx
, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
818 s
.in
.level
, nt_errstr(status
));
827 static bool test_SetUserPass_25(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
828 struct policy_handle
*handle
, uint32_t fields_present
,
832 struct samr_SetUserInfo s
;
833 union samr_UserInfo u
;
835 DATA_BLOB session_key
;
836 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
837 struct MD5Context ctx
;
838 uint8_t confounder
[16];
840 struct samr_GetUserPwInfo pwp
;
841 struct samr_PwInfo info
;
842 int policy_min_pw_len
= 0;
843 pwp
.in
.user_handle
= handle
;
844 pwp
.out
.info
= &info
;
846 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
847 if (NT_STATUS_IS_OK(status
)) {
848 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
850 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
852 s
.in
.user_handle
= handle
;
858 u
.info25
.info
.fields_present
= fields_present
;
860 encode_pw_buffer(u
.info25
.password
.data
, newpass
, STR_UNICODE
);
862 status
= dcerpc_fetch_session_key(p
, &session_key
);
863 if (!NT_STATUS_IS_OK(status
)) {
864 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
865 s
.in
.level
, nt_errstr(status
));
869 generate_random_buffer((uint8_t *)confounder
, 16);
872 MD5Update(&ctx
, confounder
, 16);
873 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
874 MD5Final(confounded_session_key
.data
, &ctx
);
876 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
877 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
879 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex)\n");
881 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
882 if (!NT_STATUS_IS_OK(status
)) {
883 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
884 s
.in
.level
, nt_errstr(status
));
890 /* This should break the key nicely */
891 confounded_session_key
.data
[0]++;
893 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
894 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
896 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
898 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
899 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
900 torture_warning(tctx
, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
901 s
.in
.level
, nt_errstr(status
));
908 static bool test_SetUserPass_18(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
909 struct policy_handle
*handle
, char **password
)
912 struct samr_SetUserInfo s
;
913 union samr_UserInfo u
;
915 DATA_BLOB session_key
;
917 struct samr_GetUserPwInfo pwp
;
918 struct samr_PwInfo info
;
919 int policy_min_pw_len
= 0;
920 uint8_t lm_hash
[16], nt_hash
[16];
922 pwp
.in
.user_handle
= handle
;
923 pwp
.out
.info
= &info
;
925 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
926 if (NT_STATUS_IS_OK(status
)) {
927 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
929 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
931 s
.in
.user_handle
= handle
;
937 u
.info18
.nt_pwd_active
= true;
938 u
.info18
.lm_pwd_active
= true;
940 E_md4hash(newpass
, nt_hash
);
941 E_deshash(newpass
, lm_hash
);
943 status
= dcerpc_fetch_session_key(p
, &session_key
);
944 if (!NT_STATUS_IS_OK(status
)) {
945 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
946 s
.in
.level
, nt_errstr(status
));
952 in
= data_blob_const(nt_hash
, 16);
953 out
= data_blob_talloc_zero(tctx
, 16);
954 sess_crypt_blob(&out
, &in
, &session_key
, true);
955 memcpy(u
.info18
.nt_pwd
.hash
, out
.data
, out
.length
);
959 in
= data_blob_const(lm_hash
, 16);
960 out
= data_blob_talloc_zero(tctx
, 16);
961 sess_crypt_blob(&out
, &in
, &session_key
, true);
962 memcpy(u
.info18
.lm_pwd
.hash
, out
.data
, out
.length
);
965 torture_comment(tctx
, "Testing SetUserInfo level 18 (set password hash)\n");
967 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
968 if (!NT_STATUS_IS_OK(status
)) {
969 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
970 s
.in
.level
, nt_errstr(status
));
979 static bool test_SetUserPass_21(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
980 struct policy_handle
*handle
, uint32_t fields_present
,
984 struct samr_SetUserInfo s
;
985 union samr_UserInfo u
;
987 DATA_BLOB session_key
;
989 struct samr_GetUserPwInfo pwp
;
990 struct samr_PwInfo info
;
991 int policy_min_pw_len
= 0;
992 uint8_t lm_hash
[16], nt_hash
[16];
994 pwp
.in
.user_handle
= handle
;
995 pwp
.out
.info
= &info
;
997 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
998 if (NT_STATUS_IS_OK(status
)) {
999 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1001 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1003 s
.in
.user_handle
= handle
;
1007 E_md4hash(newpass
, nt_hash
);
1008 E_deshash(newpass
, lm_hash
);
1012 u
.info21
.fields_present
= fields_present
;
1014 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1015 u
.info21
.lm_owf_password
.length
= 16;
1016 u
.info21
.lm_owf_password
.size
= 16;
1017 u
.info21
.lm_owf_password
.array
= (uint16_t *)lm_hash
;
1018 u
.info21
.lm_password_set
= true;
1021 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1022 u
.info21
.nt_owf_password
.length
= 16;
1023 u
.info21
.nt_owf_password
.size
= 16;
1024 u
.info21
.nt_owf_password
.array
= (uint16_t *)nt_hash
;
1025 u
.info21
.nt_password_set
= true;
1028 status
= dcerpc_fetch_session_key(p
, &session_key
);
1029 if (!NT_STATUS_IS_OK(status
)) {
1030 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
1031 s
.in
.level
, nt_errstr(status
));
1035 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1037 in
= data_blob_const(u
.info21
.lm_owf_password
.array
,
1038 u
.info21
.lm_owf_password
.length
);
1039 out
= data_blob_talloc_zero(tctx
, 16);
1040 sess_crypt_blob(&out
, &in
, &session_key
, true);
1041 u
.info21
.lm_owf_password
.array
= (uint16_t *)out
.data
;
1044 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1046 in
= data_blob_const(u
.info21
.nt_owf_password
.array
,
1047 u
.info21
.nt_owf_password
.length
);
1048 out
= data_blob_talloc_zero(tctx
, 16);
1049 sess_crypt_blob(&out
, &in
, &session_key
, true);
1050 u
.info21
.nt_owf_password
.array
= (uint16_t *)out
.data
;
1053 torture_comment(tctx
, "Testing SetUserInfo level 21 (set password hash)\n");
1055 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
1056 if (!NT_STATUS_IS_OK(status
)) {
1057 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
1058 s
.in
.level
, nt_errstr(status
));
1061 *password
= newpass
;
1064 /* try invalid length */
1065 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1067 u
.info21
.nt_owf_password
.length
++;
1069 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
1071 if (!NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
1072 torture_warning(tctx
, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1073 s
.in
.level
, nt_errstr(status
));
1078 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1080 u
.info21
.lm_owf_password
.length
++;
1082 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
1084 if (!NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
1085 torture_warning(tctx
, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1086 s
.in
.level
, nt_errstr(status
));
1094 static bool test_SetUserPass_level_ex(struct dcerpc_pipe
*p
,
1095 struct torture_context
*tctx
,
1096 struct policy_handle
*handle
,
1098 uint32_t fields_present
,
1099 char **password
, uint8_t password_expired
,
1101 bool *matched_expected_error
)
1104 NTSTATUS expected_error
= NT_STATUS_OK
;
1105 struct samr_SetUserInfo s
;
1106 struct samr_SetUserInfo2 s2
;
1107 union samr_UserInfo u
;
1109 DATA_BLOB session_key
;
1110 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
1111 struct MD5Context ctx
;
1112 uint8_t confounder
[16];
1114 struct samr_GetUserPwInfo pwp
;
1115 struct samr_PwInfo info
;
1116 int policy_min_pw_len
= 0;
1117 const char *comment
= NULL
;
1118 uint8_t lm_hash
[16], nt_hash
[16];
1120 pwp
.in
.user_handle
= handle
;
1121 pwp
.out
.info
= &info
;
1123 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
1124 if (NT_STATUS_IS_OK(status
)) {
1125 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1127 newpass
= samr_rand_pass_silent(tctx
, policy_min_pw_len
);
1130 s2
.in
.user_handle
= handle
;
1132 s2
.in
.level
= level
;
1134 s
.in
.user_handle
= handle
;
1139 if (fields_present
& SAMR_FIELD_COMMENT
) {
1140 comment
= talloc_asprintf(tctx
, "comment: %ld\n", time(NULL
));
1147 E_md4hash(newpass
, nt_hash
);
1148 E_deshash(newpass
, lm_hash
);
1150 u
.info18
.nt_pwd_active
= true;
1151 u
.info18
.lm_pwd_active
= true;
1152 u
.info18
.password_expired
= password_expired
;
1154 memcpy(u
.info18
.lm_pwd
.hash
, lm_hash
, 16);
1155 memcpy(u
.info18
.nt_pwd
.hash
, nt_hash
, 16);
1159 E_md4hash(newpass
, nt_hash
);
1160 E_deshash(newpass
, lm_hash
);
1162 u
.info21
.fields_present
= fields_present
;
1163 u
.info21
.password_expired
= password_expired
;
1164 u
.info21
.comment
.string
= comment
;
1166 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1167 u
.info21
.lm_owf_password
.length
= 16;
1168 u
.info21
.lm_owf_password
.size
= 16;
1169 u
.info21
.lm_owf_password
.array
= (uint16_t *)lm_hash
;
1170 u
.info21
.lm_password_set
= true;
1173 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1174 u
.info21
.nt_owf_password
.length
= 16;
1175 u
.info21
.nt_owf_password
.size
= 16;
1176 u
.info21
.nt_owf_password
.array
= (uint16_t *)nt_hash
;
1177 u
.info21
.nt_password_set
= true;
1182 u
.info23
.info
.fields_present
= fields_present
;
1183 u
.info23
.info
.password_expired
= password_expired
;
1184 u
.info23
.info
.comment
.string
= comment
;
1186 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
1190 u
.info24
.password_expired
= password_expired
;
1192 encode_pw_buffer(u
.info24
.password
.data
, newpass
, STR_UNICODE
);
1196 u
.info25
.info
.fields_present
= fields_present
;
1197 u
.info25
.info
.password_expired
= password_expired
;
1198 u
.info25
.info
.comment
.string
= comment
;
1200 encode_pw_buffer(u
.info25
.password
.data
, newpass
, STR_UNICODE
);
1204 u
.info26
.password_expired
= password_expired
;
1206 encode_pw_buffer(u
.info26
.password
.data
, newpass
, STR_UNICODE
);
1211 status
= dcerpc_fetch_session_key(p
, &session_key
);
1212 if (!NT_STATUS_IS_OK(status
)) {
1213 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
1214 s
.in
.level
, nt_errstr(status
));
1218 generate_random_buffer((uint8_t *)confounder
, 16);
1221 MD5Update(&ctx
, confounder
, 16);
1222 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
1223 MD5Final(confounded_session_key
.data
, &ctx
);
1229 in
= data_blob_const(u
.info18
.nt_pwd
.hash
, 16);
1230 out
= data_blob_talloc_zero(tctx
, 16);
1231 sess_crypt_blob(&out
, &in
, &session_key
, true);
1232 memcpy(u
.info18
.nt_pwd
.hash
, out
.data
, out
.length
);
1236 in
= data_blob_const(u
.info18
.lm_pwd
.hash
, 16);
1237 out
= data_blob_talloc_zero(tctx
, 16);
1238 sess_crypt_blob(&out
, &in
, &session_key
, true);
1239 memcpy(u
.info18
.lm_pwd
.hash
, out
.data
, out
.length
);
1244 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1246 in
= data_blob_const(u
.info21
.lm_owf_password
.array
,
1247 u
.info21
.lm_owf_password
.length
);
1248 out
= data_blob_talloc_zero(tctx
, 16);
1249 sess_crypt_blob(&out
, &in
, &session_key
, true);
1250 u
.info21
.lm_owf_password
.array
= (uint16_t *)out
.data
;
1252 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1254 in
= data_blob_const(u
.info21
.nt_owf_password
.array
,
1255 u
.info21
.nt_owf_password
.length
);
1256 out
= data_blob_talloc_zero(tctx
, 16);
1257 sess_crypt_blob(&out
, &in
, &session_key
, true);
1258 u
.info21
.nt_owf_password
.array
= (uint16_t *)out
.data
;
1262 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
1265 arcfour_crypt_blob(u
.info24
.password
.data
, 516, &session_key
);
1268 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
1269 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
1272 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
1273 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
1278 status
= dcerpc_samr_SetUserInfo2(p
, tctx
, &s2
);
1280 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
1283 if (!NT_STATUS_IS_OK(status
)) {
1284 if (fields_present
== 0) {
1285 expected_error
= NT_STATUS_INVALID_PARAMETER
;
1287 if (fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
1288 expected_error
= NT_STATUS_ACCESS_DENIED
;
1292 if (!NT_STATUS_IS_OK(expected_error
)) {
1294 torture_assert_ntstatus_equal(tctx
,
1296 expected_error
, "SetUserInfo2 failed");
1298 torture_assert_ntstatus_equal(tctx
,
1300 expected_error
, "SetUserInfo failed");
1302 *matched_expected_error
= true;
1306 if (!NT_STATUS_IS_OK(status
)) {
1307 torture_warning(tctx
, "SetUserInfo%s level %u failed - %s\n",
1308 use_setinfo2
? "2":"", level
, nt_errstr(status
));
1311 *password
= newpass
;
1317 static bool test_SetAliasInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1318 struct policy_handle
*handle
)
1321 struct samr_SetAliasInfo r
;
1322 struct samr_QueryAliasInfo q
;
1323 union samr_AliasInfo
*info
;
1324 uint16_t levels
[] = {2, 3};
1328 /* Ignoring switch level 1, as that includes the number of members for the alias
1329 * and setting this to a wrong value might have negative consequences
1332 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
1333 torture_comment(tctx
, "Testing SetAliasInfo level %u\n", levels
[i
]);
1335 r
.in
.alias_handle
= handle
;
1336 r
.in
.level
= levels
[i
];
1337 r
.in
.info
= talloc(tctx
, union samr_AliasInfo
);
1338 switch (r
.in
.level
) {
1339 case ALIASINFONAME
: init_lsa_String(&r
.in
.info
->name
,TEST_ALIASNAME
); break;
1340 case ALIASINFODESCRIPTION
: init_lsa_String(&r
.in
.info
->description
,
1341 "Test Description, should test I18N as well"); break;
1342 case ALIASINFOALL
: torture_comment(tctx
, "ALIASINFOALL ignored\n"); break;
1345 status
= dcerpc_samr_SetAliasInfo(p
, tctx
, &r
);
1346 if (!NT_STATUS_IS_OK(status
)) {
1347 torture_warning(tctx
, "SetAliasInfo level %u failed - %s\n",
1348 levels
[i
], nt_errstr(status
));
1352 q
.in
.alias_handle
= handle
;
1353 q
.in
.level
= levels
[i
];
1356 status
= dcerpc_samr_QueryAliasInfo(p
, tctx
, &q
);
1357 if (!NT_STATUS_IS_OK(status
)) {
1358 torture_warning(tctx
, "QueryAliasInfo level %u failed - %s\n",
1359 levels
[i
], nt_errstr(status
));
1367 static bool test_GetGroupsForUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1368 struct policy_handle
*user_handle
)
1370 struct samr_GetGroupsForUser r
;
1371 struct samr_RidWithAttributeArray
*rids
= NULL
;
1374 torture_comment(tctx
, "testing GetGroupsForUser\n");
1376 r
.in
.user_handle
= user_handle
;
1379 status
= dcerpc_samr_GetGroupsForUser(p
, tctx
, &r
);
1380 torture_assert_ntstatus_ok(tctx
, status
, "GetGroupsForUser");
1386 static bool test_GetDomPwInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1387 struct lsa_String
*domain_name
)
1390 struct samr_GetDomPwInfo r
;
1391 struct samr_PwInfo info
;
1393 r
.in
.domain_name
= domain_name
;
1396 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1398 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &r
);
1399 torture_assert_ntstatus_ok(tctx
, status
, "GetDomPwInfo");
1401 r
.in
.domain_name
->string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1402 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1404 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &r
);
1405 torture_assert_ntstatus_ok(tctx
, status
, "GetDomPwInfo");
1407 r
.in
.domain_name
->string
= "\\\\__NONAME__";
1408 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1410 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &r
);
1411 torture_assert_ntstatus_ok(tctx
, status
, "GetDomPwInfo");
1413 r
.in
.domain_name
->string
= "\\\\Builtin";
1414 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1416 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &r
);
1417 torture_assert_ntstatus_ok(tctx
, status
, "GetDomPwInfo");
1422 static bool test_GetUserPwInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1423 struct policy_handle
*handle
)
1426 struct samr_GetUserPwInfo r
;
1427 struct samr_PwInfo info
;
1429 torture_comment(tctx
, "Testing GetUserPwInfo\n");
1431 r
.in
.user_handle
= handle
;
1434 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &r
);
1435 torture_assert_ntstatus_ok(tctx
, status
, "GetUserPwInfo");
1440 static NTSTATUS
test_LookupName(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1441 struct policy_handle
*domain_handle
, const char *name
,
1445 struct samr_LookupNames n
;
1446 struct lsa_String sname
[2];
1447 struct samr_Ids rids
, types
;
1449 init_lsa_String(&sname
[0], name
);
1451 n
.in
.domain_handle
= domain_handle
;
1455 n
.out
.types
= &types
;
1456 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
1457 if (NT_STATUS_IS_OK(status
)) {
1458 *rid
= n
.out
.rids
->ids
[0];
1463 init_lsa_String(&sname
[1], "xxNONAMExx");
1465 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
1466 if (!NT_STATUS_EQUAL(status
, STATUS_SOME_UNMAPPED
)) {
1467 torture_warning(tctx
, "LookupNames[2] failed - %s\n", nt_errstr(status
));
1468 if (NT_STATUS_IS_OK(status
)) {
1469 return NT_STATUS_UNSUCCESSFUL
;
1475 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
1476 if (!NT_STATUS_IS_OK(status
)) {
1477 torture_warning(tctx
, "LookupNames[0] failed - %s\n", nt_errstr(status
));
1481 init_lsa_String(&sname
[0], "xxNONAMExx");
1483 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
1484 if (!NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
)) {
1485 torture_warning(tctx
, "LookupNames[1 bad name] failed - %s\n", nt_errstr(status
));
1486 if (NT_STATUS_IS_OK(status
)) {
1487 return NT_STATUS_UNSUCCESSFUL
;
1492 init_lsa_String(&sname
[0], "xxNONAMExx");
1493 init_lsa_String(&sname
[1], "xxNONAME2xx");
1495 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
1496 if (!NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
)) {
1497 torture_warning(tctx
, "LookupNames[2 bad names] failed - %s\n", nt_errstr(status
));
1498 if (NT_STATUS_IS_OK(status
)) {
1499 return NT_STATUS_UNSUCCESSFUL
;
1504 return NT_STATUS_OK
;
1507 static NTSTATUS
test_OpenUser_byname(struct dcerpc_pipe
*p
,
1508 struct torture_context
*tctx
,
1509 struct policy_handle
*domain_handle
,
1510 const char *name
, struct policy_handle
*user_handle
)
1513 struct samr_OpenUser r
;
1516 status
= test_LookupName(p
, tctx
, domain_handle
, name
, &rid
);
1517 if (!NT_STATUS_IS_OK(status
)) {
1521 r
.in
.domain_handle
= domain_handle
;
1522 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1524 r
.out
.user_handle
= user_handle
;
1525 status
= dcerpc_samr_OpenUser(p
, tctx
, &r
);
1526 if (!NT_STATUS_IS_OK(status
)) {
1527 torture_warning(tctx
, "OpenUser_byname(%s -> %d) failed - %s\n", name
, rid
, nt_errstr(status
));
1534 static bool test_ChangePasswordNT3(struct dcerpc_pipe
*p
,
1535 struct torture_context
*tctx
,
1536 struct policy_handle
*handle
)
1539 struct samr_ChangePasswordUser r
;
1541 struct samr_Password hash1
, hash2
, hash3
, hash4
, hash5
, hash6
;
1542 struct policy_handle user_handle
;
1543 char *oldpass
= "test";
1544 char *newpass
= "test2";
1545 uint8_t old_nt_hash
[16], new_nt_hash
[16];
1546 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1548 status
= test_OpenUser_byname(p
, tctx
, handle
, "testuser", &user_handle
);
1549 if (!NT_STATUS_IS_OK(status
)) {
1553 torture_comment(tctx
, "Testing ChangePasswordUser for user 'testuser'\n");
1555 torture_comment(tctx
, "old password: %s\n", oldpass
);
1556 torture_comment(tctx
, "new password: %s\n", newpass
);
1558 E_md4hash(oldpass
, old_nt_hash
);
1559 E_md4hash(newpass
, new_nt_hash
);
1560 E_deshash(oldpass
, old_lm_hash
);
1561 E_deshash(newpass
, new_lm_hash
);
1563 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1564 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1565 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1566 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1567 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1568 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1570 r
.in
.handle
= &user_handle
;
1571 r
.in
.lm_present
= 1;
1572 r
.in
.old_lm_crypted
= &hash1
;
1573 r
.in
.new_lm_crypted
= &hash2
;
1574 r
.in
.nt_present
= 1;
1575 r
.in
.old_nt_crypted
= &hash3
;
1576 r
.in
.new_nt_crypted
= &hash4
;
1577 r
.in
.cross1_present
= 1;
1578 r
.in
.nt_cross
= &hash5
;
1579 r
.in
.cross2_present
= 1;
1580 r
.in
.lm_cross
= &hash6
;
1582 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1583 if (!NT_STATUS_IS_OK(status
)) {
1584 torture_warning(tctx
, "ChangePasswordUser failed - %s\n", nt_errstr(status
));
1588 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
1596 static bool test_ChangePasswordUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1597 const char *acct_name
,
1598 struct policy_handle
*handle
, char **password
)
1601 struct samr_ChangePasswordUser r
;
1603 struct samr_Password hash1
, hash2
, hash3
, hash4
, hash5
, hash6
;
1604 struct policy_handle user_handle
;
1606 uint8_t old_nt_hash
[16], new_nt_hash
[16];
1607 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1608 bool changed
= true;
1611 struct samr_GetUserPwInfo pwp
;
1612 struct samr_PwInfo info
;
1613 int policy_min_pw_len
= 0;
1615 status
= test_OpenUser_byname(p
, tctx
, handle
, acct_name
, &user_handle
);
1616 if (!NT_STATUS_IS_OK(status
)) {
1619 pwp
.in
.user_handle
= &user_handle
;
1620 pwp
.out
.info
= &info
;
1622 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
1623 if (NT_STATUS_IS_OK(status
)) {
1624 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1626 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1628 torture_comment(tctx
, "Testing ChangePasswordUser\n");
1630 torture_assert(tctx
, *password
!= NULL
,
1631 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1633 oldpass
= *password
;
1635 E_md4hash(oldpass
, old_nt_hash
);
1636 E_md4hash(newpass
, new_nt_hash
);
1637 E_deshash(oldpass
, old_lm_hash
);
1638 E_deshash(newpass
, new_lm_hash
);
1640 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1641 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1642 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1643 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1644 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1645 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1647 r
.in
.user_handle
= &user_handle
;
1648 r
.in
.lm_present
= 1;
1649 /* Break the LM hash */
1651 r
.in
.old_lm_crypted
= &hash1
;
1652 r
.in
.new_lm_crypted
= &hash2
;
1653 r
.in
.nt_present
= 1;
1654 r
.in
.old_nt_crypted
= &hash3
;
1655 r
.in
.new_nt_crypted
= &hash4
;
1656 r
.in
.cross1_present
= 1;
1657 r
.in
.nt_cross
= &hash5
;
1658 r
.in
.cross2_present
= 1;
1659 r
.in
.lm_cross
= &hash6
;
1661 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1662 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_WRONG_PASSWORD
,
1663 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1665 /* Unbreak the LM hash */
1668 r
.in
.user_handle
= &user_handle
;
1669 r
.in
.lm_present
= 1;
1670 r
.in
.old_lm_crypted
= &hash1
;
1671 r
.in
.new_lm_crypted
= &hash2
;
1672 /* Break the NT hash */
1674 r
.in
.nt_present
= 1;
1675 r
.in
.old_nt_crypted
= &hash3
;
1676 r
.in
.new_nt_crypted
= &hash4
;
1677 r
.in
.cross1_present
= 1;
1678 r
.in
.nt_cross
= &hash5
;
1679 r
.in
.cross2_present
= 1;
1680 r
.in
.lm_cross
= &hash6
;
1682 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1683 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_WRONG_PASSWORD
,
1684 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1686 /* Unbreak the NT hash */
1689 r
.in
.user_handle
= &user_handle
;
1690 r
.in
.lm_present
= 1;
1691 r
.in
.old_lm_crypted
= &hash1
;
1692 r
.in
.new_lm_crypted
= &hash2
;
1693 r
.in
.nt_present
= 1;
1694 r
.in
.old_nt_crypted
= &hash3
;
1695 r
.in
.new_nt_crypted
= &hash4
;
1696 r
.in
.cross1_present
= 1;
1697 r
.in
.nt_cross
= &hash5
;
1698 r
.in
.cross2_present
= 1;
1699 /* Break the LM cross */
1701 r
.in
.lm_cross
= &hash6
;
1703 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1704 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1705 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status
));
1709 /* Unbreak the LM cross */
1712 r
.in
.user_handle
= &user_handle
;
1713 r
.in
.lm_present
= 1;
1714 r
.in
.old_lm_crypted
= &hash1
;
1715 r
.in
.new_lm_crypted
= &hash2
;
1716 r
.in
.nt_present
= 1;
1717 r
.in
.old_nt_crypted
= &hash3
;
1718 r
.in
.new_nt_crypted
= &hash4
;
1719 r
.in
.cross1_present
= 1;
1720 /* Break the NT cross */
1722 r
.in
.nt_cross
= &hash5
;
1723 r
.in
.cross2_present
= 1;
1724 r
.in
.lm_cross
= &hash6
;
1726 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1727 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1728 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status
));
1732 /* Unbreak the NT cross */
1736 /* Reset the hashes to not broken values */
1737 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1738 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1739 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1740 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1741 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1742 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1744 r
.in
.user_handle
= &user_handle
;
1745 r
.in
.lm_present
= 1;
1746 r
.in
.old_lm_crypted
= &hash1
;
1747 r
.in
.new_lm_crypted
= &hash2
;
1748 r
.in
.nt_present
= 1;
1749 r
.in
.old_nt_crypted
= &hash3
;
1750 r
.in
.new_nt_crypted
= &hash4
;
1751 r
.in
.cross1_present
= 1;
1752 r
.in
.nt_cross
= &hash5
;
1753 r
.in
.cross2_present
= 0;
1754 r
.in
.lm_cross
= NULL
;
1756 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1757 if (NT_STATUS_IS_OK(status
)) {
1759 *password
= newpass
;
1760 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION
, status
)) {
1761 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status
));
1766 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1768 E_md4hash(oldpass
, old_nt_hash
);
1769 E_md4hash(newpass
, new_nt_hash
);
1770 E_deshash(oldpass
, old_lm_hash
);
1771 E_deshash(newpass
, new_lm_hash
);
1774 /* Reset the hashes to not broken values */
1775 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1776 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1777 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1778 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1779 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1780 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1782 r
.in
.user_handle
= &user_handle
;
1783 r
.in
.lm_present
= 1;
1784 r
.in
.old_lm_crypted
= &hash1
;
1785 r
.in
.new_lm_crypted
= &hash2
;
1786 r
.in
.nt_present
= 1;
1787 r
.in
.old_nt_crypted
= &hash3
;
1788 r
.in
.new_nt_crypted
= &hash4
;
1789 r
.in
.cross1_present
= 0;
1790 r
.in
.nt_cross
= NULL
;
1791 r
.in
.cross2_present
= 1;
1792 r
.in
.lm_cross
= &hash6
;
1794 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1795 if (NT_STATUS_IS_OK(status
)) {
1797 *password
= newpass
;
1798 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION
, status
)) {
1799 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status
));
1804 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1806 E_md4hash(oldpass
, old_nt_hash
);
1807 E_md4hash(newpass
, new_nt_hash
);
1808 E_deshash(oldpass
, old_lm_hash
);
1809 E_deshash(newpass
, new_lm_hash
);
1812 /* Reset the hashes to not broken values */
1813 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1814 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1815 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1816 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1817 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1818 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1820 r
.in
.user_handle
= &user_handle
;
1821 r
.in
.lm_present
= 1;
1822 r
.in
.old_lm_crypted
= &hash1
;
1823 r
.in
.new_lm_crypted
= &hash2
;
1824 r
.in
.nt_present
= 1;
1825 r
.in
.old_nt_crypted
= &hash3
;
1826 r
.in
.new_nt_crypted
= &hash4
;
1827 r
.in
.cross1_present
= 1;
1828 r
.in
.nt_cross
= &hash5
;
1829 r
.in
.cross2_present
= 1;
1830 r
.in
.lm_cross
= &hash6
;
1832 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1833 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1834 torture_comment(tctx
, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status
));
1835 } else if (!NT_STATUS_IS_OK(status
)) {
1836 torture_warning(tctx
, "ChangePasswordUser failed - %s\n", nt_errstr(status
));
1840 *password
= newpass
;
1843 r
.in
.user_handle
= &user_handle
;
1844 r
.in
.lm_present
= 1;
1845 r
.in
.old_lm_crypted
= &hash1
;
1846 r
.in
.new_lm_crypted
= &hash2
;
1847 r
.in
.nt_present
= 1;
1848 r
.in
.old_nt_crypted
= &hash3
;
1849 r
.in
.new_nt_crypted
= &hash4
;
1850 r
.in
.cross1_present
= 1;
1851 r
.in
.nt_cross
= &hash5
;
1852 r
.in
.cross2_present
= 1;
1853 r
.in
.lm_cross
= &hash6
;
1856 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1857 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1858 torture_comment(tctx
, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status
));
1859 } else if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1860 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status
));
1866 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
1874 static bool test_OemChangePasswordUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1875 const char *acct_name
,
1876 struct policy_handle
*handle
, char **password
)
1879 struct samr_OemChangePasswordUser2 r
;
1881 struct samr_Password lm_verifier
;
1882 struct samr_CryptPassword lm_pass
;
1883 struct lsa_AsciiString server
, account
, account_bad
;
1886 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1888 struct samr_GetDomPwInfo dom_pw_info
;
1889 struct samr_PwInfo info
;
1890 int policy_min_pw_len
= 0;
1892 struct lsa_String domain_name
;
1894 domain_name
.string
= "";
1895 dom_pw_info
.in
.domain_name
= &domain_name
;
1896 dom_pw_info
.out
.info
= &info
;
1898 torture_comment(tctx
, "Testing OemChangePasswordUser2\n");
1900 torture_assert(tctx
, *password
!= NULL
,
1901 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1903 oldpass
= *password
;
1905 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &dom_pw_info
);
1906 if (NT_STATUS_IS_OK(status
)) {
1907 policy_min_pw_len
= dom_pw_info
.out
.info
->min_password_length
;
1910 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1912 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1913 account
.string
= acct_name
;
1915 E_deshash(oldpass
, old_lm_hash
);
1916 E_deshash(newpass
, new_lm_hash
);
1918 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
1919 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
1920 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
1922 r
.in
.server
= &server
;
1923 r
.in
.account
= &account
;
1924 r
.in
.password
= &lm_pass
;
1925 r
.in
.hash
= &lm_verifier
;
1927 /* Break the verification */
1928 lm_verifier
.hash
[0]++;
1930 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
1932 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)
1933 && !NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1934 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1939 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
1940 /* Break the old password */
1942 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
1943 /* unbreak it for the next operation */
1945 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
1947 r
.in
.server
= &server
;
1948 r
.in
.account
= &account
;
1949 r
.in
.password
= &lm_pass
;
1950 r
.in
.hash
= &lm_verifier
;
1952 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
1954 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)
1955 && !NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1956 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1961 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
1962 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
1964 r
.in
.server
= &server
;
1965 r
.in
.account
= &account
;
1966 r
.in
.password
= &lm_pass
;
1969 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
1971 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)
1972 && !NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
1973 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1978 /* This shouldn't be a valid name */
1979 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
1980 r
.in
.account
= &account_bad
;
1982 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
1984 if (!NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
1985 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1990 /* This shouldn't be a valid name */
1991 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
1992 r
.in
.account
= &account_bad
;
1993 r
.in
.password
= &lm_pass
;
1994 r
.in
.hash
= &lm_verifier
;
1996 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
1998 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1999 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2004 /* This shouldn't be a valid name */
2005 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
2006 r
.in
.account
= &account_bad
;
2007 r
.in
.password
= NULL
;
2008 r
.in
.hash
= &lm_verifier
;
2010 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
2012 if (!NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
2013 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2018 E_deshash(oldpass
, old_lm_hash
);
2019 E_deshash(newpass
, new_lm_hash
);
2021 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
2022 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2023 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
2025 r
.in
.server
= &server
;
2026 r
.in
.account
= &account
;
2027 r
.in
.password
= &lm_pass
;
2028 r
.in
.hash
= &lm_verifier
;
2030 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
2031 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2032 torture_comment(tctx
, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status
));
2033 } else if (!NT_STATUS_IS_OK(status
)) {
2034 torture_warning(tctx
, "OemChangePasswordUser2 failed - %s\n", nt_errstr(status
));
2037 *password
= newpass
;
2044 static bool test_ChangePasswordUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2045 const char *acct_name
,
2047 char *newpass
, bool allow_password_restriction
)
2050 struct samr_ChangePasswordUser2 r
;
2052 struct lsa_String server
, account
;
2053 struct samr_CryptPassword nt_pass
, lm_pass
;
2054 struct samr_Password nt_verifier
, lm_verifier
;
2056 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2057 uint8_t old_lm_hash
[16], new_lm_hash
[16];
2059 struct samr_GetDomPwInfo dom_pw_info
;
2060 struct samr_PwInfo info
;
2062 struct lsa_String domain_name
;
2064 domain_name
.string
= "";
2065 dom_pw_info
.in
.domain_name
= &domain_name
;
2066 dom_pw_info
.out
.info
= &info
;
2068 torture_comment(tctx
, "Testing ChangePasswordUser2 on %s\n", acct_name
);
2070 torture_assert(tctx
, *password
!= NULL
,
2071 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2072 oldpass
= *password
;
2075 int policy_min_pw_len
= 0;
2076 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &dom_pw_info
);
2077 if (NT_STATUS_IS_OK(status
)) {
2078 policy_min_pw_len
= dom_pw_info
.out
.info
->min_password_length
;
2081 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2084 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2085 init_lsa_String(&account
, acct_name
);
2087 E_md4hash(oldpass
, old_nt_hash
);
2088 E_md4hash(newpass
, new_nt_hash
);
2090 E_deshash(oldpass
, old_lm_hash
);
2091 E_deshash(newpass
, new_lm_hash
);
2093 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
|STR_TERMINATE
);
2094 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2095 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2097 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2098 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2099 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2101 r
.in
.server
= &server
;
2102 r
.in
.account
= &account
;
2103 r
.in
.nt_password
= &nt_pass
;
2104 r
.in
.nt_verifier
= &nt_verifier
;
2106 r
.in
.lm_password
= &lm_pass
;
2107 r
.in
.lm_verifier
= &lm_verifier
;
2109 status
= dcerpc_samr_ChangePasswordUser2(p
, tctx
, &r
);
2110 if (allow_password_restriction
&& NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2111 torture_comment(tctx
, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status
));
2112 } else if (!NT_STATUS_IS_OK(status
)) {
2113 torture_warning(tctx
, "ChangePasswordUser2 failed - %s\n", nt_errstr(status
));
2116 *password
= newpass
;
2123 bool test_ChangePasswordUser3(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2124 const char *account_string
,
2125 int policy_min_pw_len
,
2127 const char *newpass
,
2128 NTTIME last_password_change
,
2129 bool handle_reject_reason
)
2132 struct samr_ChangePasswordUser3 r
;
2134 struct lsa_String server
, account
, account_bad
;
2135 struct samr_CryptPassword nt_pass
, lm_pass
;
2136 struct samr_Password nt_verifier
, lm_verifier
;
2138 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2139 uint8_t old_lm_hash
[16], new_lm_hash
[16];
2141 struct samr_DomInfo1
*dominfo
= NULL
;
2142 struct userPwdChangeFailureInformation
*reject
= NULL
;
2144 torture_comment(tctx
, "Testing ChangePasswordUser3\n");
2146 if (newpass
== NULL
) {
2148 if (policy_min_pw_len
== 0) {
2149 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2151 newpass
= samr_rand_pass_fixed_len(tctx
, policy_min_pw_len
);
2153 } while (check_password_quality(newpass
) == false);
2155 torture_comment(tctx
, "Using password '%s'\n", newpass
);
2158 torture_assert(tctx
, *password
!= NULL
,
2159 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2161 oldpass
= *password
;
2162 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2163 init_lsa_String(&account
, account_string
);
2165 E_md4hash(oldpass
, old_nt_hash
);
2166 E_md4hash(newpass
, new_nt_hash
);
2168 E_deshash(oldpass
, old_lm_hash
);
2169 E_deshash(newpass
, new_lm_hash
);
2171 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2172 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2173 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2175 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2176 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2177 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2179 /* Break the verification */
2180 nt_verifier
.hash
[0]++;
2182 r
.in
.server
= &server
;
2183 r
.in
.account
= &account
;
2184 r
.in
.nt_password
= &nt_pass
;
2185 r
.in
.nt_verifier
= &nt_verifier
;
2187 r
.in
.lm_password
= &lm_pass
;
2188 r
.in
.lm_verifier
= &lm_verifier
;
2189 r
.in
.password3
= NULL
;
2190 r
.out
.dominfo
= &dominfo
;
2191 r
.out
.reject
= &reject
;
2193 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
2194 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
) &&
2195 (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
))) {
2196 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2201 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2202 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2203 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2205 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2206 /* Break the NT hash */
2208 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2209 /* Unbreak it again */
2211 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2213 r
.in
.server
= &server
;
2214 r
.in
.account
= &account
;
2215 r
.in
.nt_password
= &nt_pass
;
2216 r
.in
.nt_verifier
= &nt_verifier
;
2218 r
.in
.lm_password
= &lm_pass
;
2219 r
.in
.lm_verifier
= &lm_verifier
;
2220 r
.in
.password3
= NULL
;
2221 r
.out
.dominfo
= &dominfo
;
2222 r
.out
.reject
= &reject
;
2224 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
2225 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
) &&
2226 (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
))) {
2227 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2232 /* This shouldn't be a valid name */
2233 init_lsa_String(&account_bad
, talloc_asprintf(tctx
, "%sXX", account_string
));
2235 r
.in
.account
= &account_bad
;
2236 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
2237 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
2238 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2243 E_md4hash(oldpass
, old_nt_hash
);
2244 E_md4hash(newpass
, new_nt_hash
);
2246 E_deshash(oldpass
, old_lm_hash
);
2247 E_deshash(newpass
, new_lm_hash
);
2249 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2250 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2251 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2253 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2254 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2255 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2257 r
.in
.server
= &server
;
2258 r
.in
.account
= &account
;
2259 r
.in
.nt_password
= &nt_pass
;
2260 r
.in
.nt_verifier
= &nt_verifier
;
2262 r
.in
.lm_password
= &lm_pass
;
2263 r
.in
.lm_verifier
= &lm_verifier
;
2264 r
.in
.password3
= NULL
;
2265 r
.out
.dominfo
= &dominfo
;
2266 r
.out
.reject
= &reject
;
2268 unix_to_nt_time(&t
, time(NULL
));
2270 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
2272 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)
2275 && handle_reject_reason
2276 && (!null_nttime(last_password_change
) || !dominfo
->min_password_age
)) {
2277 if (dominfo
->password_properties
& DOMAIN_REFUSE_PASSWORD_CHANGE
) {
2279 if (reject
&& (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
)) {
2280 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2281 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2286 /* We tested the order of precendence which is as follows:
2295 if ((dominfo
->min_password_age
> 0) && !null_nttime(last_password_change
) &&
2296 (last_password_change
+ dominfo
->min_password_age
> t
)) {
2298 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2299 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2300 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2304 } else if ((dominfo
->min_password_length
> 0) &&
2305 (strlen(newpass
) < dominfo
->min_password_length
)) {
2307 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
) {
2308 torture_warning(tctx
, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2309 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
, reject
->extendedFailureReason
);
2313 } else if ((dominfo
->password_history_length
> 0) &&
2314 strequal(oldpass
, newpass
)) {
2316 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_PWD_IN_HISTORY
) {
2317 torture_warning(tctx
, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2318 SAM_PWD_CHANGE_PWD_IN_HISTORY
, reject
->extendedFailureReason
);
2321 } else if (dominfo
->password_properties
& DOMAIN_PASSWORD_COMPLEX
) {
2323 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NOT_COMPLEX
) {
2324 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2325 SAM_PWD_CHANGE_NOT_COMPLEX
, reject
->extendedFailureReason
);
2331 if (reject
->extendedFailureReason
== SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
) {
2332 /* retry with adjusted size */
2333 return test_ChangePasswordUser3(p
, tctx
, account_string
,
2334 dominfo
->min_password_length
,
2335 password
, NULL
, 0, false);
2339 } else if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2340 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2341 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2342 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2345 /* Perhaps the server has a 'min password age' set? */
2348 torture_assert_ntstatus_ok(tctx
, status
, "ChangePasswordUser3");
2349 *password
= talloc_strdup(tctx
, newpass
);
2355 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2356 const char *account_string
,
2357 struct policy_handle
*handle
,
2361 struct samr_ChangePasswordUser3 r
;
2362 struct samr_SetUserInfo s
;
2363 union samr_UserInfo u
;
2364 DATA_BLOB session_key
;
2365 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
2366 uint8_t confounder
[16];
2367 struct MD5Context ctx
;
2370 struct lsa_String server
, account
;
2371 struct samr_CryptPassword nt_pass
;
2372 struct samr_Password nt_verifier
;
2373 DATA_BLOB new_random_pass
;
2376 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2378 struct samr_DomInfo1
*dominfo
= NULL
;
2379 struct userPwdChangeFailureInformation
*reject
= NULL
;
2381 new_random_pass
= samr_very_rand_pass(tctx
, 128);
2383 torture_assert(tctx
, *password
!= NULL
,
2384 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2386 oldpass
= *password
;
2387 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2388 init_lsa_String(&account
, account_string
);
2390 s
.in
.user_handle
= handle
;
2396 u
.info25
.info
.fields_present
= SAMR_FIELD_NT_PASSWORD_PRESENT
;
2398 set_pw_in_buffer(u
.info25
.password
.data
, &new_random_pass
);
2400 status
= dcerpc_fetch_session_key(p
, &session_key
);
2401 if (!NT_STATUS_IS_OK(status
)) {
2402 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
2403 s
.in
.level
, nt_errstr(status
));
2407 generate_random_buffer((uint8_t *)confounder
, 16);
2410 MD5Update(&ctx
, confounder
, 16);
2411 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
2412 MD5Final(confounded_session_key
.data
, &ctx
);
2414 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
2415 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
2417 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2419 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
2420 if (!NT_STATUS_IS_OK(status
)) {
2421 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
2422 s
.in
.level
, nt_errstr(status
));
2426 torture_comment(tctx
, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2428 mdfour(old_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2430 new_random_pass
= samr_very_rand_pass(tctx
, 128);
2432 mdfour(new_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2434 set_pw_in_buffer(nt_pass
.data
, &new_random_pass
);
2435 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2436 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2438 r
.in
.server
= &server
;
2439 r
.in
.account
= &account
;
2440 r
.in
.nt_password
= &nt_pass
;
2441 r
.in
.nt_verifier
= &nt_verifier
;
2443 r
.in
.lm_password
= NULL
;
2444 r
.in
.lm_verifier
= NULL
;
2445 r
.in
.password3
= NULL
;
2446 r
.out
.dominfo
= &dominfo
;
2447 r
.out
.reject
= &reject
;
2449 unix_to_nt_time(&t
, time(NULL
));
2451 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
2453 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2454 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2455 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2456 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2459 /* Perhaps the server has a 'min password age' set? */
2461 } else if (!NT_STATUS_IS_OK(status
)) {
2462 torture_warning(tctx
, "ChangePasswordUser3 failed - %s\n", nt_errstr(status
));
2466 newpass
= samr_rand_pass(tctx
, 128);
2468 mdfour(old_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2470 E_md4hash(newpass
, new_nt_hash
);
2472 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2473 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2474 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2476 r
.in
.server
= &server
;
2477 r
.in
.account
= &account
;
2478 r
.in
.nt_password
= &nt_pass
;
2479 r
.in
.nt_verifier
= &nt_verifier
;
2481 r
.in
.lm_password
= NULL
;
2482 r
.in
.lm_verifier
= NULL
;
2483 r
.in
.password3
= NULL
;
2484 r
.out
.dominfo
= &dominfo
;
2485 r
.out
.reject
= &reject
;
2487 unix_to_nt_time(&t
, time(NULL
));
2489 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
2491 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2492 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2493 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2494 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2497 /* Perhaps the server has a 'min password age' set? */
2500 torture_assert_ntstatus_ok(tctx
, status
, "ChangePasswordUser3 (on second random password)");
2501 *password
= talloc_strdup(tctx
, newpass
);
2508 static bool test_GetMembersInAlias(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2509 struct policy_handle
*alias_handle
)
2511 struct samr_GetMembersInAlias r
;
2512 struct lsa_SidArray sids
;
2515 torture_comment(tctx
, "Testing GetMembersInAlias\n");
2517 r
.in
.alias_handle
= alias_handle
;
2520 status
= dcerpc_samr_GetMembersInAlias(p
, tctx
, &r
);
2521 torture_assert_ntstatus_ok(tctx
, status
, "GetMembersInAlias");
2526 static bool test_AddMemberToAlias(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2527 struct policy_handle
*alias_handle
,
2528 const struct dom_sid
*domain_sid
)
2530 struct samr_AddAliasMember r
;
2531 struct samr_DeleteAliasMember d
;
2533 struct dom_sid
*sid
;
2535 sid
= dom_sid_add_rid(tctx
, domain_sid
, 512);
2537 torture_comment(tctx
, "testing AddAliasMember\n");
2538 r
.in
.alias_handle
= alias_handle
;
2541 status
= dcerpc_samr_AddAliasMember(p
, tctx
, &r
);
2542 torture_assert_ntstatus_ok(tctx
, status
, "AddAliasMember");
2544 d
.in
.alias_handle
= alias_handle
;
2547 status
= dcerpc_samr_DeleteAliasMember(p
, tctx
, &d
);
2548 torture_assert_ntstatus_ok(tctx
, status
, "DelAliasMember");
2553 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2554 struct policy_handle
*alias_handle
)
2556 struct samr_AddMultipleMembersToAlias a
;
2557 struct samr_RemoveMultipleMembersFromAlias r
;
2559 struct lsa_SidArray sids
;
2561 torture_comment(tctx
, "testing AddMultipleMembersToAlias\n");
2562 a
.in
.alias_handle
= alias_handle
;
2566 sids
.sids
= talloc_array(tctx
, struct lsa_SidPtr
, 3);
2568 sids
.sids
[0].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-1");
2569 sids
.sids
[1].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-2");
2570 sids
.sids
[2].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-3");
2572 status
= dcerpc_samr_AddMultipleMembersToAlias(p
, tctx
, &a
);
2573 torture_assert_ntstatus_ok(tctx
, status
, "AddMultipleMembersToAlias");
2576 torture_comment(tctx
, "testing RemoveMultipleMembersFromAlias\n");
2577 r
.in
.alias_handle
= alias_handle
;
2580 status
= dcerpc_samr_RemoveMultipleMembersFromAlias(p
, tctx
, &r
);
2581 torture_assert_ntstatus_ok(tctx
, status
, "RemoveMultipleMembersFromAlias");
2583 /* strange! removing twice doesn't give any error */
2584 status
= dcerpc_samr_RemoveMultipleMembersFromAlias(p
, tctx
, &r
);
2585 torture_assert_ntstatus_ok(tctx
, status
, "RemoveMultipleMembersFromAlias");
2587 /* but removing an alias that isn't there does */
2588 sids
.sids
[2].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-4");
2590 status
= dcerpc_samr_RemoveMultipleMembersFromAlias(p
, tctx
, &r
);
2591 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
, "RemoveMultipleMembersFromAlias");
2596 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2597 struct policy_handle
*user_handle
)
2599 struct samr_TestPrivateFunctionsUser r
;
2602 torture_comment(tctx
, "Testing TestPrivateFunctionsUser\n");
2604 r
.in
.user_handle
= user_handle
;
2606 status
= dcerpc_samr_TestPrivateFunctionsUser(p
, tctx
, &r
);
2607 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_NOT_IMPLEMENTED
, "TestPrivateFunctionsUser");
2612 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe
*p
,
2613 struct torture_context
*tctx
,
2614 struct policy_handle
*handle
,
2619 uint16_t levels
[] = { /* 3, */ 5, 21 };
2621 NTTIME pwdlastset3
= 0;
2622 NTTIME pwdlastset5
= 0;
2623 NTTIME pwdlastset21
= 0;
2625 torture_comment(tctx
, "Testing QueryUserInfo%s level 5 and 21 call ",
2626 use_info2
? "2":"");
2628 for (i
=0; i
<ARRAY_SIZE(levels
); i
++) {
2630 struct samr_QueryUserInfo r
;
2631 struct samr_QueryUserInfo2 r2
;
2632 union samr_UserInfo
*info
;
2635 r2
.in
.user_handle
= handle
;
2636 r2
.in
.level
= levels
[i
];
2637 r2
.out
.info
= &info
;
2638 status
= dcerpc_samr_QueryUserInfo2(p
, tctx
, &r2
);
2641 r
.in
.user_handle
= handle
;
2642 r
.in
.level
= levels
[i
];
2644 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &r
);
2647 if (!NT_STATUS_IS_OK(status
) &&
2648 !NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_INFO_CLASS
)) {
2649 torture_warning(tctx
, "QueryUserInfo%s level %u failed - %s\n",
2650 use_info2
? "2":"", levels
[i
], nt_errstr(status
));
2654 switch (levels
[i
]) {
2656 pwdlastset3
= info
->info3
.last_password_change
;
2659 pwdlastset5
= info
->info5
.last_password_change
;
2662 pwdlastset21
= info
->info21
.last_password_change
;
2668 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2669 "pwdlastset mixup"); */
2670 torture_assert_int_equal(tctx
, pwdlastset5
, pwdlastset21
,
2671 "pwdlastset mixup");
2673 *pwdlastset
= pwdlastset21
;
2675 torture_comment(tctx
, "(pwdlastset: %lld)\n", *pwdlastset
);
2680 static bool test_SamLogon(struct torture_context
*tctx
,
2681 struct dcerpc_pipe
*p
,
2682 struct cli_credentials
*test_credentials
,
2683 NTSTATUS expected_result
)
2686 struct netr_LogonSamLogonEx r
;
2687 union netr_LogonLevel logon
;
2688 union netr_Validation validation
;
2689 uint8_t authoritative
;
2690 struct netr_NetworkInfo ninfo
;
2691 DATA_BLOB names_blob
, chal
, lm_resp
, nt_resp
;
2692 int flags
= CLI_CRED_NTLM_AUTH
;
2693 uint32_t samlogon_flags
= 0;
2695 if (lp_client_lanman_auth(tctx
->lp_ctx
)) {
2696 flags
|= CLI_CRED_LANMAN_AUTH
;
2699 if (lp_client_ntlmv2_auth(tctx
->lp_ctx
)) {
2700 flags
|= CLI_CRED_NTLMv2_AUTH
;
2703 cli_credentials_get_ntlm_username_domain(test_credentials
, tctx
,
2704 &ninfo
.identity_info
.account_name
.string
,
2705 &ninfo
.identity_info
.domain_name
.string
);
2707 generate_random_buffer(ninfo
.challenge
,
2708 sizeof(ninfo
.challenge
));
2709 chal
= data_blob_const(ninfo
.challenge
,
2710 sizeof(ninfo
.challenge
));
2712 names_blob
= NTLMv2_generate_names_blob(tctx
, cli_credentials_get_workstation(test_credentials
),
2713 cli_credentials_get_domain(test_credentials
));
2715 status
= cli_credentials_get_ntlm_response(test_credentials
, tctx
,
2721 torture_assert_ntstatus_ok(tctx
, status
, "cli_credentials_get_ntlm_response failed");
2723 ninfo
.lm
.data
= lm_resp
.data
;
2724 ninfo
.lm
.length
= lm_resp
.length
;
2726 ninfo
.nt
.data
= nt_resp
.data
;
2727 ninfo
.nt
.length
= nt_resp
.length
;
2729 ninfo
.identity_info
.parameter_control
=
2730 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT
|
2731 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT
;
2732 ninfo
.identity_info
.logon_id_low
= 0;
2733 ninfo
.identity_info
.logon_id_high
= 0;
2734 ninfo
.identity_info
.workstation
.string
= cli_credentials_get_workstation(test_credentials
);
2736 logon
.network
= &ninfo
;
2738 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2739 r
.in
.computer_name
= cli_credentials_get_workstation(test_credentials
);
2740 r
.in
.logon_level
= NetlogonNetworkInformation
;
2741 r
.in
.logon
= &logon
;
2742 r
.in
.flags
= &samlogon_flags
;
2743 r
.out
.flags
= &samlogon_flags
;
2744 r
.out
.validation
= &validation
;
2745 r
.out
.authoritative
= &authoritative
;
2747 torture_comment(tctx
, "Testing LogonSamLogon with name %s\n", ninfo
.identity_info
.account_name
.string
);
2749 r
.in
.validation_level
= 6;
2751 status
= dcerpc_netr_LogonSamLogonEx(p
, tctx
, &r
);
2752 if (NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_INFO_CLASS
)) {
2753 r
.in
.validation_level
= 3;
2754 status
= dcerpc_netr_LogonSamLogonEx(p
, tctx
, &r
);
2756 if (!NT_STATUS_IS_OK(status
)) {
2757 torture_assert_ntstatus_equal(tctx
, status
, expected_result
, "LogonSamLogonEx failed");
2760 torture_assert_ntstatus_ok(tctx
, status
, "LogonSamLogonEx failed");
2766 static bool test_SamLogon_with_creds(struct torture_context
*tctx
,
2767 struct dcerpc_pipe
*p
,
2768 struct cli_credentials
*machine_creds
,
2769 const char *acct_name
,
2771 NTSTATUS expected_samlogon_result
)
2774 struct cli_credentials
*test_credentials
;
2776 test_credentials
= cli_credentials_init(tctx
);
2778 cli_credentials_set_workstation(test_credentials
,
2779 cli_credentials_get_workstation(machine_creds
), CRED_SPECIFIED
);
2780 cli_credentials_set_domain(test_credentials
,
2781 cli_credentials_get_domain(machine_creds
), CRED_SPECIFIED
);
2782 cli_credentials_set_username(test_credentials
,
2783 acct_name
, CRED_SPECIFIED
);
2784 cli_credentials_set_password(test_credentials
,
2785 password
, CRED_SPECIFIED
);
2787 torture_comment(tctx
, "testing samlogon as %s password: %s\n",
2788 acct_name
, password
);
2790 if (!test_SamLogon(tctx
, p
, test_credentials
,
2791 expected_samlogon_result
)) {
2792 torture_warning(tctx
, "new password did not work\n");
2799 static bool test_SetPassword_level(struct dcerpc_pipe
*p
,
2800 struct dcerpc_pipe
*np
,
2801 struct torture_context
*tctx
,
2802 struct policy_handle
*handle
,
2804 uint32_t fields_present
,
2805 uint8_t password_expired
,
2806 bool *matched_expected_error
,
2808 const char *acct_name
,
2810 struct cli_credentials
*machine_creds
,
2811 bool use_queryinfo2
,
2813 NTSTATUS expected_samlogon_result
)
2815 const char *fields
= NULL
;
2822 fields
= talloc_asprintf(tctx
, "(fields_present: 0x%08x)",
2829 torture_comment(tctx
, "Testing SetUserInfo%s level %d call "
2830 "(password_expired: %d) %s\n",
2831 use_setinfo2
? "2":"", level
, password_expired
,
2832 fields
? fields
: "");
2834 if (!test_SetUserPass_level_ex(p
, tctx
, handle
, level
,
2839 matched_expected_error
)) {
2843 if (!test_QueryUserInfo_pwdlastset(p
, tctx
, handle
,
2849 if (*matched_expected_error
== true) {
2853 if (!test_SamLogon_with_creds(tctx
, np
,
2857 expected_samlogon_result
)) {
2864 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe
*p
,
2865 struct torture_context
*tctx
,
2866 uint32_t acct_flags
,
2867 const char *acct_name
,
2868 struct policy_handle
*handle
,
2870 struct cli_credentials
*machine_credentials
)
2872 int s
= 0, q
= 0, f
= 0, l
= 0, z
= 0;
2873 struct dcerpc_binding
*b
;
2876 bool set_levels
[] = { false, true };
2877 bool query_levels
[] = { false, true };
2878 uint32_t levels
[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
2879 uint32_t nonzeros
[] = { 1, 24 };
2880 uint32_t fields_present
[] = {
2882 SAMR_FIELD_EXPIRED_FLAG
,
2883 SAMR_FIELD_LAST_PWD_CHANGE
,
2884 SAMR_FIELD_EXPIRED_FLAG
| SAMR_FIELD_LAST_PWD_CHANGE
,
2886 SAMR_FIELD_NT_PASSWORD_PRESENT
,
2887 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
,
2888 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
,
2889 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
,
2890 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_EXPIRED_FLAG
,
2891 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_EXPIRED_FLAG
,
2892 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
| SAMR_FIELD_EXPIRED_FLAG
2895 struct dcerpc_pipe
*np
= NULL
;
2897 if (torture_setting_bool(tctx
, "samba3", false)) {
2899 torture_comment(tctx
, "Samba3 has second granularity, setting delay to: %d\n",
2903 status
= torture_rpc_binding(tctx
, &b
);
2904 if (!NT_STATUS_IS_OK(status
)) {
2909 /* We have to use schannel, otherwise the SamLogonEx fails
2910 * with INTERNAL_ERROR */
2912 b
->flags
&= ~DCERPC_AUTH_OPTIONS
;
2913 b
->flags
|= DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_128
;
2915 status
= dcerpc_pipe_connect_b(tctx
, &np
, b
,
2916 &ndr_table_netlogon
,
2917 machine_credentials
, tctx
->ev
, tctx
->lp_ctx
);
2919 if (!NT_STATUS_IS_OK(status
)) {
2920 torture_warning(tctx
, "RPC pipe connect as domain member failed: %s\n", nt_errstr(status
));
2925 /* set to 1 to enable testing for all possible opcode
2926 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2929 #define TEST_ALL_LEVELS 1
2930 #define TEST_SET_LEVELS 1
2931 #define TEST_QUERY_LEVELS 1
2933 #ifdef TEST_ALL_LEVELS
2934 for (l
=0; l
<ARRAY_SIZE(levels
); l
++) {
2936 for (l
=0; l
<(ARRAY_SIZE(levels
))/2; l
++) {
2938 for (z
=0; z
<ARRAY_SIZE(nonzeros
); z
++) {
2939 for (f
=0; f
<ARRAY_SIZE(fields_present
); f
++) {
2940 #ifdef TEST_SET_LEVELS
2941 for (s
=0; s
<ARRAY_SIZE(set_levels
); s
++) {
2943 #ifdef TEST_QUERY_LEVELS
2944 for (q
=0; q
<ARRAY_SIZE(query_levels
); q
++) {
2946 NTTIME pwdlastset_old
= 0;
2947 NTTIME pwdlastset_new
= 0;
2948 bool matched_expected_error
= false;
2949 NTSTATUS expected_samlogon_result
= NT_STATUS_ACCOUNT_DISABLED
;
2951 torture_comment(tctx
, "------------------------------\n"
2952 "Testing pwdLastSet attribute for flags: 0x%08x "
2953 "(s: %d (l: %d), q: %d)\n",
2954 acct_flags
, s
, levels
[l
], q
);
2956 switch (levels
[l
]) {
2960 if (!((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
2961 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
))) {
2962 expected_samlogon_result
= NT_STATUS_WRONG_PASSWORD
;
2970 /* set a password and force password change (pwdlastset 0) by
2971 * setting the password expired flag to a non-0 value */
2973 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
2977 &matched_expected_error
,
2981 machine_credentials
,
2984 expected_samlogon_result
)) {
2988 if (matched_expected_error
== true) {
2989 /* skipping on expected failure */
2993 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2994 * set without the SAMR_FIELD_EXPIRED_FLAG */
2996 switch (levels
[l
]) {
3000 if ((pwdlastset_new
!= 0) &&
3001 !(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
)) {
3002 torture_comment(tctx
, "not considering a non-0 "
3003 "pwdLastSet as a an error as the "
3004 "SAMR_FIELD_EXPIRED_FLAG has not "
3009 if (pwdlastset_new
!= 0) {
3010 torture_warning(tctx
, "pwdLastSet test failed: "
3011 "expected pwdLastSet 0 but got %lld\n",
3018 switch (levels
[l
]) {
3022 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3023 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3024 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3025 (pwdlastset_old
>= pwdlastset_new
)) {
3026 torture_warning(tctx
, "pwdlastset not increasing\n");
3031 if ((pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3032 (pwdlastset_old
>= pwdlastset_new
)) {
3033 torture_warning(tctx
, "pwdlastset not increasing\n");
3043 /* set a password, pwdlastset needs to get updated (increased
3044 * value), password_expired value used here is 0 */
3046 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3050 &matched_expected_error
,
3054 machine_credentials
,
3057 expected_samlogon_result
)) {
3061 /* when a password has been changed, pwdlastset must not be 0 afterwards
3062 * and must be larger then the old value */
3064 switch (levels
[l
]) {
3069 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3070 * password has been changed, old and new pwdlastset
3071 * need to be the same value */
3073 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
3074 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3075 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3077 torture_assert_int_equal(tctx
, pwdlastset_old
,
3078 pwdlastset_new
, "pwdlastset must be equal");
3082 if (pwdlastset_old
>= pwdlastset_new
) {
3083 torture_warning(tctx
, "pwdLastSet test failed: "
3084 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3085 pwdlastset_old
, pwdlastset_new
);
3088 if (pwdlastset_new
== 0) {
3089 torture_warning(tctx
, "pwdLastSet test failed: "
3090 "expected non-0 pwdlastset, got: %lld\n",
3096 switch (levels
[l
]) {
3100 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3101 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3102 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3103 (pwdlastset_old
>= pwdlastset_new
)) {
3104 torture_warning(tctx
, "pwdlastset not increasing\n");
3109 if ((pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3110 (pwdlastset_old
>= pwdlastset_new
)) {
3111 torture_warning(tctx
, "pwdlastset not increasing\n");
3117 pwdlastset_old
= pwdlastset_new
;
3123 /* set a password, pwdlastset needs to get updated (increased
3124 * value), password_expired value used here is 0 */
3126 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3130 &matched_expected_error
,
3134 machine_credentials
,
3137 expected_samlogon_result
)) {
3141 /* when a password has been changed, pwdlastset must not be 0 afterwards
3142 * and must be larger then the old value */
3144 switch (levels
[l
]) {
3149 /* if no password has been changed, old and new pwdlastset
3150 * need to be the same value */
3152 if (!((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3153 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3155 torture_assert_int_equal(tctx
, pwdlastset_old
,
3156 pwdlastset_new
, "pwdlastset must be equal");
3160 if (pwdlastset_old
>= pwdlastset_new
) {
3161 torture_warning(tctx
, "pwdLastSet test failed: "
3162 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3163 pwdlastset_old
, pwdlastset_new
);
3166 if (pwdlastset_new
== 0) {
3167 torture_warning(tctx
, "pwdLastSet test failed: "
3168 "expected non-0 pwdlastset, got: %lld\n",
3176 /* set a password and force password change (pwdlastset 0) by
3177 * setting the password expired flag to a non-0 value */
3179 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3183 &matched_expected_error
,
3187 machine_credentials
,
3190 expected_samlogon_result
)) {
3194 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3195 * set without the SAMR_FIELD_EXPIRED_FLAG */
3197 switch (levels
[l
]) {
3201 if ((pwdlastset_new
!= 0) &&
3202 !(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
)) {
3203 torture_comment(tctx
, "not considering a non-0 "
3204 "pwdLastSet as a an error as the "
3205 "SAMR_FIELD_EXPIRED_FLAG has not "
3210 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3211 * password has been changed, old and new pwdlastset
3212 * need to be the same value */
3214 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
3215 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3216 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3218 torture_assert_int_equal(tctx
, pwdlastset_old
,
3219 pwdlastset_new
, "pwdlastset must be equal");
3224 if (pwdlastset_old
== pwdlastset_new
) {
3225 torture_warning(tctx
, "pwdLastSet test failed: "
3226 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3227 pwdlastset_old
, pwdlastset_new
);
3231 if (pwdlastset_new
!= 0) {
3232 torture_warning(tctx
, "pwdLastSet test failed: "
3233 "expected pwdLastSet 0, got %lld\n",
3240 switch (levels
[l
]) {
3244 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3245 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3246 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3247 (pwdlastset_old
>= pwdlastset_new
)) {
3248 torture_warning(tctx
, "pwdlastset not increasing\n");
3253 if ((pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3254 (pwdlastset_old
>= pwdlastset_new
)) {
3255 torture_warning(tctx
, "pwdlastset not increasing\n");
3261 /* if the level we are testing does not have a fields_present
3262 * field, skip all fields present tests by setting f to to
3264 switch (levels
[l
]) {
3268 f
= ARRAY_SIZE(fields_present
);
3272 #ifdef TEST_QUERY_LEVELS
3275 #ifdef TEST_SET_LEVELS
3278 } /* fields present */
3282 #undef TEST_SET_LEVELS
3283 #undef TEST_QUERY_LEVELS
3290 static bool test_DeleteUser_with_privs(struct dcerpc_pipe
*p
,
3291 struct dcerpc_pipe
*lp
,
3292 struct torture_context
*tctx
,
3293 struct policy_handle
*domain_handle
,
3294 struct policy_handle
*lsa_handle
,
3295 struct policy_handle
*user_handle
,
3296 const struct dom_sid
*domain_sid
,
3298 struct cli_credentials
*machine_credentials
)
3303 struct policy_handle lsa_acct_handle
;
3304 struct dom_sid
*user_sid
;
3306 user_sid
= dom_sid_add_rid(tctx
, domain_sid
, rid
);
3309 struct lsa_EnumAccountRights r
;
3310 struct lsa_RightSet rights
;
3312 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
3314 r
.in
.handle
= lsa_handle
;
3315 r
.in
.sid
= user_sid
;
3316 r
.out
.rights
= &rights
;
3318 status
= dcerpc_lsa_EnumAccountRights(lp
, tctx
, &r
);
3319 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
3320 "Expected enum rights for account to fail");
3324 struct lsa_RightSet rights
;
3325 struct lsa_StringLarge names
[2];
3326 struct lsa_AddAccountRights r
;
3328 torture_comment(tctx
, "Testing LSA AddAccountRights\n");
3330 init_lsa_StringLarge(&names
[0], "SeMachineAccountPrivilege");
3331 init_lsa_StringLarge(&names
[1], NULL
);
3334 rights
.names
= names
;
3336 r
.in
.handle
= lsa_handle
;
3337 r
.in
.sid
= user_sid
;
3338 r
.in
.rights
= &rights
;
3340 status
= dcerpc_lsa_AddAccountRights(lp
, tctx
, &r
);
3341 torture_assert_ntstatus_ok(tctx
, status
,
3342 "Failed to add privileges");
3346 struct lsa_EnumAccounts r
;
3347 uint32_t resume_handle
= 0;
3348 struct lsa_SidArray lsa_sid_array
;
3350 bool found_sid
= false;
3352 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
3354 r
.in
.handle
= lsa_handle
;
3355 r
.in
.num_entries
= 0x1000;
3356 r
.in
.resume_handle
= &resume_handle
;
3357 r
.out
.sids
= &lsa_sid_array
;
3358 r
.out
.resume_handle
= &resume_handle
;
3360 status
= dcerpc_lsa_EnumAccounts(lp
, tctx
, &r
);
3361 torture_assert_ntstatus_ok(tctx
, status
,
3362 "Failed to enum accounts");
3364 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
3365 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
3370 torture_assert(tctx
, found_sid
,
3371 "failed to list privileged account");
3375 struct lsa_EnumAccountRights r
;
3376 struct lsa_RightSet user_rights
;
3378 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
3380 r
.in
.handle
= lsa_handle
;
3381 r
.in
.sid
= user_sid
;
3382 r
.out
.rights
= &user_rights
;
3384 status
= dcerpc_lsa_EnumAccountRights(lp
, tctx
, &r
);
3385 torture_assert_ntstatus_ok(tctx
, status
,
3386 "Failed to enum rights for account");
3388 if (user_rights
.count
< 1) {
3389 torture_warning(tctx
, "failed to find newly added rights");
3395 struct lsa_OpenAccount r
;
3397 torture_comment(tctx
, "Testing LSA OpenAccount\n");
3399 r
.in
.handle
= lsa_handle
;
3400 r
.in
.sid
= user_sid
;
3401 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3402 r
.out
.acct_handle
= &lsa_acct_handle
;
3404 status
= dcerpc_lsa_OpenAccount(lp
, tctx
, &r
);
3405 torture_assert_ntstatus_ok(tctx
, status
,
3406 "Failed to open lsa account");
3410 struct lsa_GetSystemAccessAccount r
;
3411 uint32_t access_mask
;
3413 torture_comment(tctx
, "Testing LSA GetSystemAccessAccount\n");
3415 r
.in
.handle
= &lsa_acct_handle
;
3416 r
.out
.access_mask
= &access_mask
;
3418 status
= dcerpc_lsa_GetSystemAccessAccount(lp
, tctx
, &r
);
3419 torture_assert_ntstatus_ok(tctx
, status
,
3420 "Failed to get lsa system access account");
3426 torture_comment(tctx
, "Testing LSA Close\n");
3428 r
.in
.handle
= &lsa_acct_handle
;
3429 r
.out
.handle
= &lsa_acct_handle
;
3431 status
= dcerpc_lsa_Close(lp
, tctx
, &r
);
3432 torture_assert_ntstatus_ok(tctx
, status
,
3433 "Failed to close lsa");
3437 struct samr_DeleteUser r
;
3439 torture_comment(tctx
, "Testing SAMR DeleteUser\n");
3441 r
.in
.user_handle
= user_handle
;
3442 r
.out
.user_handle
= user_handle
;
3444 status
= dcerpc_samr_DeleteUser(p
, tctx
, &r
);
3445 torture_assert_ntstatus_ok(tctx
, status
, "Delete User failed");
3449 struct lsa_EnumAccounts r
;
3450 uint32_t resume_handle
= 0;
3451 struct lsa_SidArray lsa_sid_array
;
3453 bool found_sid
= false;
3455 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
3457 r
.in
.handle
= lsa_handle
;
3458 r
.in
.num_entries
= 0x1000;
3459 r
.in
.resume_handle
= &resume_handle
;
3460 r
.out
.sids
= &lsa_sid_array
;
3461 r
.out
.resume_handle
= &resume_handle
;
3463 status
= dcerpc_lsa_EnumAccounts(lp
, tctx
, &r
);
3464 torture_assert_ntstatus_ok(tctx
, status
,
3465 "Failed to enum accounts");
3467 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
3468 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
3473 torture_assert(tctx
, found_sid
,
3474 "failed to list privileged account");
3478 struct lsa_EnumAccountRights r
;
3479 struct lsa_RightSet user_rights
;
3481 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
3483 r
.in
.handle
= lsa_handle
;
3484 r
.in
.sid
= user_sid
;
3485 r
.out
.rights
= &user_rights
;
3487 status
= dcerpc_lsa_EnumAccountRights(lp
, tctx
, &r
);
3488 torture_assert_ntstatus_ok(tctx
, status
,
3489 "Failed to enum rights for account");
3491 if (user_rights
.count
< 1) {
3492 torture_warning(tctx
, "failed to find newly added rights");
3498 struct lsa_OpenAccount r
;
3500 torture_comment(tctx
, "Testing LSA OpenAccount\n");
3502 r
.in
.handle
= lsa_handle
;
3503 r
.in
.sid
= user_sid
;
3504 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3505 r
.out
.acct_handle
= &lsa_acct_handle
;
3507 status
= dcerpc_lsa_OpenAccount(lp
, tctx
, &r
);
3508 torture_assert_ntstatus_ok(tctx
, status
,
3509 "Failed to open lsa account");
3513 struct lsa_GetSystemAccessAccount r
;
3514 uint32_t access_mask
;
3516 torture_comment(tctx
, "Testing LSA GetSystemAccessAccount\n");
3518 r
.in
.handle
= &lsa_acct_handle
;
3519 r
.out
.access_mask
= &access_mask
;
3521 status
= dcerpc_lsa_GetSystemAccessAccount(lp
, tctx
, &r
);
3522 torture_assert_ntstatus_ok(tctx
, status
,
3523 "Failed to get lsa system access account");
3527 struct lsa_DeleteObject r
;
3529 torture_comment(tctx
, "Testing LSA DeleteObject\n");
3531 r
.in
.handle
= &lsa_acct_handle
;
3532 r
.out
.handle
= &lsa_acct_handle
;
3534 status
= dcerpc_lsa_DeleteObject(lp
, tctx
, &r
);
3535 torture_assert_ntstatus_ok(tctx
, status
,
3536 "Failed to delete object");
3540 struct lsa_EnumAccounts r
;
3541 uint32_t resume_handle
= 0;
3542 struct lsa_SidArray lsa_sid_array
;
3544 bool found_sid
= false;
3546 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
3548 r
.in
.handle
= lsa_handle
;
3549 r
.in
.num_entries
= 0x1000;
3550 r
.in
.resume_handle
= &resume_handle
;
3551 r
.out
.sids
= &lsa_sid_array
;
3552 r
.out
.resume_handle
= &resume_handle
;
3554 status
= dcerpc_lsa_EnumAccounts(lp
, tctx
, &r
);
3555 torture_assert_ntstatus_ok(tctx
, status
,
3556 "Failed to enum accounts");
3558 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
3559 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
3564 torture_assert(tctx
, !found_sid
,
3565 "should not have listed privileged account");
3569 struct lsa_EnumAccountRights r
;
3570 struct lsa_RightSet user_rights
;
3572 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
3574 r
.in
.handle
= lsa_handle
;
3575 r
.in
.sid
= user_sid
;
3576 r
.out
.rights
= &user_rights
;
3578 status
= dcerpc_lsa_EnumAccountRights(lp
, tctx
, &r
);
3579 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
3580 "Failed to enum rights for account");
3586 static bool test_user_ops(struct dcerpc_pipe
*p
,
3587 struct torture_context
*tctx
,
3588 struct policy_handle
*user_handle
,
3589 struct policy_handle
*domain_handle
,
3590 const struct dom_sid
*domain_sid
,
3591 uint32_t base_acct_flags
,
3592 const char *base_acct_name
, enum torture_samr_choice which_ops
,
3593 struct cli_credentials
*machine_credentials
)
3595 char *password
= NULL
;
3596 struct samr_QueryUserInfo q
;
3597 union samr_UserInfo
*info
;
3603 const uint32_t password_fields
[] = {
3604 SAMR_FIELD_NT_PASSWORD_PRESENT
,
3605 SAMR_FIELD_LM_PASSWORD_PRESENT
,
3606 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
,
3610 status
= test_LookupName(p
, tctx
, domain_handle
, base_acct_name
, &rid
);
3611 if (!NT_STATUS_IS_OK(status
)) {
3615 switch (which_ops
) {
3616 case TORTURE_SAMR_USER_ATTRIBUTES
:
3617 if (!test_QuerySecurity(p
, tctx
, user_handle
)) {
3621 if (!test_QueryUserInfo(p
, tctx
, user_handle
)) {
3625 if (!test_QueryUserInfo2(p
, tctx
, user_handle
)) {
3629 if (!test_SetUserInfo(p
, tctx
, user_handle
, base_acct_flags
,
3634 if (!test_GetUserPwInfo(p
, tctx
, user_handle
)) {
3638 if (!test_TestPrivateFunctionsUser(p
, tctx
, user_handle
)) {
3642 if (!test_SetUserPass(p
, tctx
, user_handle
, &password
)) {
3646 case TORTURE_SAMR_PASSWORDS
:
3647 if (base_acct_flags
& (ACB_WSTRUST
|ACB_DOMTRUST
|ACB_SVRTRUST
)) {
3648 char simple_pass
[9];
3649 char *v
= generate_random_str(tctx
, 1);
3651 ZERO_STRUCT(simple_pass
);
3652 memset(simple_pass
, *v
, sizeof(simple_pass
) - 1);
3654 torture_comment(tctx
, "Testing machine account password policy rules\n");
3656 /* Workstation trust accounts don't seem to need to honour password quality policy */
3657 if (!test_SetUserPassEx(p
, tctx
, user_handle
, true, &password
)) {
3661 if (!test_ChangePasswordUser2(p
, tctx
, base_acct_name
, &password
, simple_pass
, false)) {
3665 /* reset again, to allow another 'user' password change */
3666 if (!test_SetUserPassEx(p
, tctx
, user_handle
, true, &password
)) {
3670 /* Try a 'short' password */
3671 if (!test_ChangePasswordUser2(p
, tctx
, base_acct_name
, &password
, samr_rand_pass(tctx
, 4), false)) {
3675 /* Try a compleatly random password */
3676 if (!test_ChangePasswordRandomBytes(p
, tctx
, base_acct_name
, user_handle
, &password
)) {
3681 for (i
= 0; password_fields
[i
]; i
++) {
3682 if (!test_SetUserPass_23(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
3686 /* check it was set right */
3687 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
3692 for (i
= 0; password_fields
[i
]; i
++) {
3693 if (!test_SetUserPass_25(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
3697 /* check it was set right */
3698 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
3703 if (!test_SetUserPassEx(p
, tctx
, user_handle
, false, &password
)) {
3707 if (!test_ChangePassword(p
, tctx
, base_acct_name
, domain_handle
, &password
)) {
3711 if (torture_setting_bool(tctx
, "samba4", false)) {
3712 torture_comment(tctx
, "skipping Set Password level 18 and 21 against Samba4\n");
3715 if (!test_SetUserPass_18(p
, tctx
, user_handle
, &password
)) {
3719 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
3723 for (i
= 0; password_fields
[i
]; i
++) {
3725 if (password_fields
[i
] == SAMR_FIELD_LM_PASSWORD_PRESENT
) {
3726 /* we need to skip as that would break
3727 * the ChangePasswordUser3 verify */
3731 if (!test_SetUserPass_21(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
3735 /* check it was set right */
3736 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
3742 q
.in
.user_handle
= user_handle
;
3746 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &q
);
3747 if (!NT_STATUS_IS_OK(status
)) {
3748 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
3749 q
.in
.level
, nt_errstr(status
));
3752 uint32_t expected_flags
= (base_acct_flags
| ACB_PWNOTREQ
| ACB_DISABLED
);
3753 if ((info
->info5
.acct_flags
) != expected_flags
) {
3754 torture_warning(tctx
, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3755 info
->info5
.acct_flags
,
3758 if (!torture_setting_bool(tctx
, "samba3", false)) {
3762 if (info
->info5
.rid
!= rid
) {
3763 torture_warning(tctx
, "QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3764 info
->info5
.rid
, rid
);
3771 case TORTURE_SAMR_PASSWORDS_PWDLASTSET
:
3773 /* test last password change timestamp behaviour */
3774 if (!test_SetPassword_pwdlastset(p
, tctx
, base_acct_flags
,
3776 user_handle
, &password
,
3777 machine_credentials
)) {
3782 torture_comment(tctx
, "pwdLastSet test succeeded\n");
3784 torture_warning(tctx
, "pwdLastSet test failed\n");
3789 case TORTURE_SAMR_USER_PRIVILEGES
: {
3791 struct dcerpc_pipe
*lp
;
3792 struct policy_handle
*lsa_handle
;
3794 status
= torture_rpc_connection(tctx
, &lp
, &ndr_table_lsarpc
);
3795 torture_assert_ntstatus_ok(tctx
, status
, "Failed to open LSA pipe");
3797 if (!test_lsa_OpenPolicy2(lp
, tctx
, &lsa_handle
)) {
3801 if (!test_DeleteUser_with_privs(p
, lp
, tctx
,
3802 domain_handle
, lsa_handle
, user_handle
,
3804 machine_credentials
)) {
3808 if (!test_lsa_Close(lp
, tctx
, lsa_handle
)) {
3813 torture_warning(tctx
, "privileged user delete test failed\n");
3818 case TORTURE_SAMR_OTHER
:
3819 /* We just need the account to exist */
3825 static bool test_alias_ops(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
3826 struct policy_handle
*alias_handle
,
3827 const struct dom_sid
*domain_sid
)
3831 if (!torture_setting_bool(tctx
, "samba3", false)) {
3832 if (!test_QuerySecurity(p
, tctx
, alias_handle
)) {
3837 if (!test_QueryAliasInfo(p
, tctx
, alias_handle
)) {
3841 if (!test_SetAliasInfo(p
, tctx
, alias_handle
)) {
3845 if (!test_AddMemberToAlias(p
, tctx
, alias_handle
, domain_sid
)) {
3849 if (torture_setting_bool(tctx
, "samba3", false) ||
3850 torture_setting_bool(tctx
, "samba4", false)) {
3851 torture_comment(tctx
, "skipping MultipleMembers Alias tests against Samba\n");
3855 if (!test_AddMultipleMembersToAlias(p
, tctx
, alias_handle
)) {
3863 static bool test_DeleteUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
3864 struct policy_handle
*user_handle
)
3866 struct samr_DeleteUser d
;
3868 torture_comment(tctx
, "Testing DeleteUser\n");
3870 d
.in
.user_handle
= user_handle
;
3871 d
.out
.user_handle
= user_handle
;
3873 status
= dcerpc_samr_DeleteUser(p
, tctx
, &d
);
3874 torture_assert_ntstatus_ok(tctx
, status
, "DeleteUser");
3879 bool test_DeleteUser_byname(struct dcerpc_pipe
*p
,
3880 struct torture_context
*tctx
,
3881 struct policy_handle
*handle
, const char *name
)
3884 struct samr_DeleteUser d
;
3885 struct policy_handle user_handle
;
3888 status
= test_LookupName(p
, tctx
, handle
, name
, &rid
);
3889 if (!NT_STATUS_IS_OK(status
)) {
3893 status
= test_OpenUser_byname(p
, tctx
, handle
, name
, &user_handle
);
3894 if (!NT_STATUS_IS_OK(status
)) {
3898 d
.in
.user_handle
= &user_handle
;
3899 d
.out
.user_handle
= &user_handle
;
3900 status
= dcerpc_samr_DeleteUser(p
, tctx
, &d
);
3901 if (!NT_STATUS_IS_OK(status
)) {
3908 torture_warning(tctx
, "DeleteUser_byname(%s) failed - %s\n", name
, nt_errstr(status
));
3913 static bool test_DeleteGroup_byname(struct dcerpc_pipe
*p
,
3914 struct torture_context
*tctx
,
3915 struct policy_handle
*handle
, const char *name
)
3918 struct samr_OpenGroup r
;
3919 struct samr_DeleteDomainGroup d
;
3920 struct policy_handle group_handle
;
3923 status
= test_LookupName(p
, tctx
, handle
, name
, &rid
);
3924 if (!NT_STATUS_IS_OK(status
)) {
3928 r
.in
.domain_handle
= handle
;
3929 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3931 r
.out
.group_handle
= &group_handle
;
3932 status
= dcerpc_samr_OpenGroup(p
, tctx
, &r
);
3933 if (!NT_STATUS_IS_OK(status
)) {
3937 d
.in
.group_handle
= &group_handle
;
3938 d
.out
.group_handle
= &group_handle
;
3939 status
= dcerpc_samr_DeleteDomainGroup(p
, tctx
, &d
);
3940 if (!NT_STATUS_IS_OK(status
)) {
3947 torture_warning(tctx
, "DeleteGroup_byname(%s) failed - %s\n", name
, nt_errstr(status
));
3952 static bool test_DeleteAlias_byname(struct dcerpc_pipe
*p
,
3953 struct torture_context
*tctx
,
3954 struct policy_handle
*domain_handle
,
3958 struct samr_OpenAlias r
;
3959 struct samr_DeleteDomAlias d
;
3960 struct policy_handle alias_handle
;
3963 torture_comment(tctx
, "testing DeleteAlias_byname\n");
3965 status
= test_LookupName(p
, tctx
, domain_handle
, name
, &rid
);
3966 if (!NT_STATUS_IS_OK(status
)) {
3970 r
.in
.domain_handle
= domain_handle
;
3971 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3973 r
.out
.alias_handle
= &alias_handle
;
3974 status
= dcerpc_samr_OpenAlias(p
, tctx
, &r
);
3975 if (!NT_STATUS_IS_OK(status
)) {
3979 d
.in
.alias_handle
= &alias_handle
;
3980 d
.out
.alias_handle
= &alias_handle
;
3981 status
= dcerpc_samr_DeleteDomAlias(p
, tctx
, &d
);
3982 if (!NT_STATUS_IS_OK(status
)) {
3989 torture_warning(tctx
, "DeleteAlias_byname(%s) failed - %s\n", name
, nt_errstr(status
));
3993 static bool test_DeleteAlias(struct dcerpc_pipe
*p
,
3994 struct torture_context
*tctx
,
3995 struct policy_handle
*alias_handle
)
3997 struct samr_DeleteDomAlias d
;
4001 torture_comment(tctx
, "Testing DeleteAlias\n");
4003 d
.in
.alias_handle
= alias_handle
;
4004 d
.out
.alias_handle
= alias_handle
;
4006 status
= dcerpc_samr_DeleteDomAlias(p
, tctx
, &d
);
4007 if (!NT_STATUS_IS_OK(status
)) {
4008 torture_warning(tctx
, "DeleteAlias failed - %s\n", nt_errstr(status
));
4015 static bool test_CreateAlias(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4016 struct policy_handle
*domain_handle
,
4017 const char *alias_name
,
4018 struct policy_handle
*alias_handle
,
4019 const struct dom_sid
*domain_sid
,
4023 struct samr_CreateDomAlias r
;
4024 struct lsa_String name
;
4028 init_lsa_String(&name
, alias_name
);
4029 r
.in
.domain_handle
= domain_handle
;
4030 r
.in
.alias_name
= &name
;
4031 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4032 r
.out
.alias_handle
= alias_handle
;
4035 torture_comment(tctx
, "Testing CreateAlias (%s)\n", r
.in
.alias_name
->string
);
4037 status
= dcerpc_samr_CreateDomAlias(p
, tctx
, &r
);
4039 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
4040 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
4041 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.alias_name
->string
);
4044 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.alias_name
->string
,
4050 if (NT_STATUS_EQUAL(status
, NT_STATUS_ALIAS_EXISTS
)) {
4051 if (!test_DeleteAlias_byname(p
, tctx
, domain_handle
, r
.in
.alias_name
->string
)) {
4054 status
= dcerpc_samr_CreateDomAlias(p
, tctx
, &r
);
4057 if (!NT_STATUS_IS_OK(status
)) {
4058 torture_warning(tctx
, "CreateAlias failed - %s\n", nt_errstr(status
));
4066 if (!test_alias_ops(p
, tctx
, alias_handle
, domain_sid
)) {
4073 static bool test_ChangePassword(struct dcerpc_pipe
*p
,
4074 struct torture_context
*tctx
,
4075 const char *acct_name
,
4076 struct policy_handle
*domain_handle
, char **password
)
4084 if (!test_ChangePasswordUser(p
, tctx
, acct_name
, domain_handle
, password
)) {
4088 if (!test_ChangePasswordUser2(p
, tctx
, acct_name
, password
, 0, true)) {
4092 if (!test_OemChangePasswordUser2(p
, tctx
, acct_name
, domain_handle
, password
)) {
4096 /* test what happens when setting the old password again */
4097 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, *password
, 0, true)) {
4102 char simple_pass
[9];
4103 char *v
= generate_random_str(tctx
, 1);
4105 ZERO_STRUCT(simple_pass
);
4106 memset(simple_pass
, *v
, sizeof(simple_pass
) - 1);
4108 /* test what happens when picking a simple password */
4109 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, simple_pass
, 0, true)) {
4114 /* set samr_SetDomainInfo level 1 with min_length 5 */
4116 struct samr_QueryDomainInfo r
;
4117 union samr_DomainInfo
*info
= NULL
;
4118 struct samr_SetDomainInfo s
;
4119 uint16_t len_old
, len
;
4120 uint32_t pwd_prop_old
;
4121 int64_t min_pwd_age_old
;
4126 r
.in
.domain_handle
= domain_handle
;
4130 torture_comment(tctx
, "testing samr_QueryDomainInfo level 1\n");
4131 status
= dcerpc_samr_QueryDomainInfo(p
, tctx
, &r
);
4132 if (!NT_STATUS_IS_OK(status
)) {
4136 s
.in
.domain_handle
= domain_handle
;
4140 /* remember the old min length, so we can reset it */
4141 len_old
= s
.in
.info
->info1
.min_password_length
;
4142 s
.in
.info
->info1
.min_password_length
= len
;
4143 pwd_prop_old
= s
.in
.info
->info1
.password_properties
;
4144 /* turn off password complexity checks for this test */
4145 s
.in
.info
->info1
.password_properties
&= ~DOMAIN_PASSWORD_COMPLEX
;
4147 min_pwd_age_old
= s
.in
.info
->info1
.min_password_age
;
4148 s
.in
.info
->info1
.min_password_age
= 0;
4150 torture_comment(tctx
, "testing samr_SetDomainInfo level 1\n");
4151 status
= dcerpc_samr_SetDomainInfo(p
, tctx
, &s
);
4152 if (!NT_STATUS_IS_OK(status
)) {
4156 torture_comment(tctx
, "calling test_ChangePasswordUser3 with too short password\n");
4158 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, len
- 1, password
, NULL
, 0, true)) {
4162 s
.in
.info
->info1
.min_password_length
= len_old
;
4163 s
.in
.info
->info1
.password_properties
= pwd_prop_old
;
4164 s
.in
.info
->info1
.min_password_age
= min_pwd_age_old
;
4166 torture_comment(tctx
, "testing samr_SetDomainInfo level 1\n");
4167 status
= dcerpc_samr_SetDomainInfo(p
, tctx
, &s
);
4168 if (!NT_STATUS_IS_OK(status
)) {
4176 struct samr_OpenUser r
;
4177 struct samr_QueryUserInfo q
;
4178 union samr_UserInfo
*info
;
4179 struct samr_LookupNames n
;
4180 struct policy_handle user_handle
;
4181 struct samr_Ids rids
, types
;
4183 n
.in
.domain_handle
= domain_handle
;
4185 n
.in
.names
= talloc_array(tctx
, struct lsa_String
, 1);
4186 n
.in
.names
[0].string
= acct_name
;
4188 n
.out
.types
= &types
;
4190 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
4191 if (!NT_STATUS_IS_OK(status
)) {
4192 torture_warning(tctx
, "LookupNames failed - %s\n", nt_errstr(status
));
4196 r
.in
.domain_handle
= domain_handle
;
4197 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4198 r
.in
.rid
= n
.out
.rids
->ids
[0];
4199 r
.out
.user_handle
= &user_handle
;
4201 status
= dcerpc_samr_OpenUser(p
, tctx
, &r
);
4202 if (!NT_STATUS_IS_OK(status
)) {
4203 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", n
.out
.rids
->ids
[0], nt_errstr(status
));
4207 q
.in
.user_handle
= &user_handle
;
4211 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &q
);
4212 if (!NT_STATUS_IS_OK(status
)) {
4213 torture_warning(tctx
, "QueryUserInfo failed - %s\n", nt_errstr(status
));
4217 torture_comment(tctx
, "calling test_ChangePasswordUser3 with too early password change\n");
4219 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
,
4220 info
->info5
.last_password_change
, true)) {
4225 /* we change passwords twice - this has the effect of verifying
4226 they were changed correctly for the final call */
4227 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
, 0, true)) {
4231 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
, 0, true)) {
4238 static bool test_CreateUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4239 struct policy_handle
*domain_handle
,
4240 const char *user_name
,
4241 struct policy_handle
*user_handle_out
,
4242 struct dom_sid
*domain_sid
,
4243 enum torture_samr_choice which_ops
,
4244 struct cli_credentials
*machine_credentials
,
4248 TALLOC_CTX
*user_ctx
;
4251 struct samr_CreateUser r
;
4252 struct samr_QueryUserInfo q
;
4253 union samr_UserInfo
*info
;
4254 struct samr_DeleteUser d
;
4257 /* This call creates a 'normal' account - check that it really does */
4258 const uint32_t acct_flags
= ACB_NORMAL
;
4259 struct lsa_String name
;
4262 struct policy_handle user_handle
;
4263 user_ctx
= talloc_named(tctx
, 0, "test_CreateUser2 per-user context");
4264 init_lsa_String(&name
, user_name
);
4266 r
.in
.domain_handle
= domain_handle
;
4267 r
.in
.account_name
= &name
;
4268 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4269 r
.out
.user_handle
= &user_handle
;
4272 torture_comment(tctx
, "Testing CreateUser(%s)\n", r
.in
.account_name
->string
);
4274 status
= dcerpc_samr_CreateUser(p
, user_ctx
, &r
);
4276 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
4277 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) || NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
4278 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.account_name
->string
);
4281 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.account_name
->string
,
4287 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_EXISTS
)) {
4288 if (!test_DeleteUser_byname(p
, user_ctx
, domain_handle
, r
.in
.account_name
->string
)) {
4289 talloc_free(user_ctx
);
4292 status
= dcerpc_samr_CreateUser(p
, user_ctx
, &r
);
4295 if (!NT_STATUS_IS_OK(status
)) {
4296 talloc_free(user_ctx
);
4297 torture_warning(tctx
, "CreateUser failed - %s\n", nt_errstr(status
));
4302 if (user_handle_out
) {
4303 *user_handle_out
= user_handle
;
4309 q
.in
.user_handle
= &user_handle
;
4313 status
= dcerpc_samr_QueryUserInfo(p
, user_ctx
, &q
);
4314 if (!NT_STATUS_IS_OK(status
)) {
4315 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
4316 q
.in
.level
, nt_errstr(status
));
4319 if ((info
->info16
.acct_flags
& acct_flags
) != acct_flags
) {
4320 torture_warning(tctx
, "QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4321 info
->info16
.acct_flags
,
4327 if (!test_user_ops(p
, tctx
, &user_handle
, domain_handle
,
4328 domain_sid
, acct_flags
, name
.string
, which_ops
,
4329 machine_credentials
)) {
4333 if (user_handle_out
) {
4334 *user_handle_out
= user_handle
;
4336 torture_comment(tctx
, "Testing DeleteUser (createuser test)\n");
4338 d
.in
.user_handle
= &user_handle
;
4339 d
.out
.user_handle
= &user_handle
;
4341 status
= dcerpc_samr_DeleteUser(p
, user_ctx
, &d
);
4342 if (!NT_STATUS_IS_OK(status
)) {
4343 torture_warning(tctx
, "DeleteUser failed - %s\n", nt_errstr(status
));
4350 talloc_free(user_ctx
);
4356 static bool test_CreateUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4357 struct policy_handle
*domain_handle
,
4358 struct dom_sid
*domain_sid
,
4359 enum torture_samr_choice which_ops
,
4360 struct cli_credentials
*machine_credentials
)
4363 struct samr_CreateUser2 r
;
4364 struct samr_QueryUserInfo q
;
4365 union samr_UserInfo
*info
;
4366 struct samr_DeleteUser d
;
4367 struct policy_handle user_handle
;
4369 struct lsa_String name
;
4374 uint32_t acct_flags
;
4375 const char *account_name
;
4377 } account_types
[] = {
4378 { ACB_NORMAL
, TEST_ACCOUNT_NAME
, NT_STATUS_OK
},
4379 { ACB_NORMAL
| ACB_DISABLED
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
4380 { ACB_NORMAL
| ACB_PWNOEXP
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
4381 { ACB_WSTRUST
, TEST_MACHINENAME
, NT_STATUS_OK
},
4382 { ACB_WSTRUST
| ACB_DISABLED
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
4383 { ACB_WSTRUST
| ACB_PWNOEXP
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
4384 { ACB_SVRTRUST
, TEST_MACHINENAME
, NT_STATUS_OK
},
4385 { ACB_SVRTRUST
| ACB_DISABLED
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
4386 { ACB_SVRTRUST
| ACB_PWNOEXP
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
4387 { ACB_DOMTRUST
, TEST_DOMAINNAME
, NT_STATUS_ACCESS_DENIED
},
4388 { ACB_DOMTRUST
| ACB_DISABLED
, TEST_DOMAINNAME
, NT_STATUS_INVALID_PARAMETER
},
4389 { ACB_DOMTRUST
| ACB_PWNOEXP
, TEST_DOMAINNAME
, NT_STATUS_INVALID_PARAMETER
},
4390 { 0, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
4391 { ACB_DISABLED
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
4392 { 0, NULL
, NT_STATUS_INVALID_PARAMETER
}
4395 for (i
= 0; account_types
[i
].account_name
; i
++) {
4396 TALLOC_CTX
*user_ctx
;
4397 uint32_t acct_flags
= account_types
[i
].acct_flags
;
4398 uint32_t access_granted
;
4399 user_ctx
= talloc_named(tctx
, 0, "test_CreateUser2 per-user context");
4400 init_lsa_String(&name
, account_types
[i
].account_name
);
4402 r
.in
.domain_handle
= domain_handle
;
4403 r
.in
.account_name
= &name
;
4404 r
.in
.acct_flags
= acct_flags
;
4405 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4406 r
.out
.user_handle
= &user_handle
;
4407 r
.out
.access_granted
= &access_granted
;
4410 torture_comment(tctx
, "Testing CreateUser2(%s, 0x%x)\n", r
.in
.account_name
->string
, acct_flags
);
4412 status
= dcerpc_samr_CreateUser2(p
, user_ctx
, &r
);
4414 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
4415 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) || NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
4416 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.account_name
->string
);
4419 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.account_name
->string
,
4426 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_EXISTS
)) {
4427 if (!test_DeleteUser_byname(p
, user_ctx
, domain_handle
, r
.in
.account_name
->string
)) {
4428 talloc_free(user_ctx
);
4432 status
= dcerpc_samr_CreateUser2(p
, user_ctx
, &r
);
4435 if (!NT_STATUS_EQUAL(status
, account_types
[i
].nt_status
)) {
4436 torture_warning(tctx
, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
4437 nt_errstr(status
), nt_errstr(account_types
[i
].nt_status
));
4441 if (NT_STATUS_IS_OK(status
)) {
4442 q
.in
.user_handle
= &user_handle
;
4446 status
= dcerpc_samr_QueryUserInfo(p
, user_ctx
, &q
);
4447 if (!NT_STATUS_IS_OK(status
)) {
4448 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
4449 q
.in
.level
, nt_errstr(status
));
4452 uint32_t expected_flags
= (acct_flags
| ACB_PWNOTREQ
| ACB_DISABLED
);
4453 if (acct_flags
== ACB_NORMAL
) {
4454 expected_flags
|= ACB_PW_EXPIRED
;
4456 if ((info
->info5
.acct_flags
) != expected_flags
) {
4457 torture_warning(tctx
, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4458 info
->info5
.acct_flags
,
4462 switch (acct_flags
) {
4464 if (info
->info5
.primary_gid
!= DOMAIN_RID_DCS
) {
4465 torture_warning(tctx
, "QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
4466 DOMAIN_RID_DCS
, info
->info5
.primary_gid
);
4471 if (info
->info5
.primary_gid
!= DOMAIN_RID_DOMAIN_MEMBERS
) {
4472 torture_warning(tctx
, "QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
4473 DOMAIN_RID_DOMAIN_MEMBERS
, info
->info5
.primary_gid
);
4478 if (info
->info5
.primary_gid
!= DOMAIN_RID_USERS
) {
4479 torture_warning(tctx
, "QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
4480 DOMAIN_RID_USERS
, info
->info5
.primary_gid
);
4487 if (!test_user_ops(p
, tctx
, &user_handle
, domain_handle
,
4488 domain_sid
, acct_flags
, name
.string
, which_ops
,
4489 machine_credentials
)) {
4493 if (!policy_handle_empty(&user_handle
)) {
4494 torture_comment(tctx
, "Testing DeleteUser (createuser2 test)\n");
4496 d
.in
.user_handle
= &user_handle
;
4497 d
.out
.user_handle
= &user_handle
;
4499 status
= dcerpc_samr_DeleteUser(p
, user_ctx
, &d
);
4500 if (!NT_STATUS_IS_OK(status
)) {
4501 torture_warning(tctx
, "DeleteUser failed - %s\n", nt_errstr(status
));
4506 talloc_free(user_ctx
);
4512 static bool test_QueryAliasInfo(struct dcerpc_pipe
*p
,
4513 struct torture_context
*tctx
,
4514 struct policy_handle
*handle
)
4517 struct samr_QueryAliasInfo r
;
4518 union samr_AliasInfo
*info
;
4519 uint16_t levels
[] = {1, 2, 3};
4523 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
4524 torture_comment(tctx
, "Testing QueryAliasInfo level %u\n", levels
[i
]);
4526 r
.in
.alias_handle
= handle
;
4527 r
.in
.level
= levels
[i
];
4530 status
= dcerpc_samr_QueryAliasInfo(p
, tctx
, &r
);
4531 if (!NT_STATUS_IS_OK(status
)) {
4532 torture_warning(tctx
, "QueryAliasInfo level %u failed - %s\n",
4533 levels
[i
], nt_errstr(status
));
4541 static bool test_QueryGroupInfo(struct dcerpc_pipe
*p
,
4542 struct torture_context
*tctx
,
4543 struct policy_handle
*handle
)
4546 struct samr_QueryGroupInfo r
;
4547 union samr_GroupInfo
*info
;
4548 uint16_t levels
[] = {1, 2, 3, 4, 5};
4552 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
4553 torture_comment(tctx
, "Testing QueryGroupInfo level %u\n", levels
[i
]);
4555 r
.in
.group_handle
= handle
;
4556 r
.in
.level
= levels
[i
];
4559 status
= dcerpc_samr_QueryGroupInfo(p
, tctx
, &r
);
4560 if (!NT_STATUS_IS_OK(status
)) {
4561 torture_warning(tctx
, "QueryGroupInfo level %u failed - %s\n",
4562 levels
[i
], nt_errstr(status
));
4570 static bool test_QueryGroupMember(struct dcerpc_pipe
*p
,
4571 struct torture_context
*tctx
,
4572 struct policy_handle
*handle
)
4575 struct samr_QueryGroupMember r
;
4576 struct samr_RidTypeArray
*rids
= NULL
;
4579 torture_comment(tctx
, "Testing QueryGroupMember\n");
4581 r
.in
.group_handle
= handle
;
4584 status
= dcerpc_samr_QueryGroupMember(p
, tctx
, &r
);
4585 if (!NT_STATUS_IS_OK(status
)) {
4586 torture_warning(tctx
, "QueryGroupInfo failed - %s\n", nt_errstr(status
));
4594 static bool test_SetGroupInfo(struct dcerpc_pipe
*p
,
4595 struct torture_context
*tctx
,
4596 struct policy_handle
*handle
)
4599 struct samr_QueryGroupInfo r
;
4600 union samr_GroupInfo
*info
;
4601 struct samr_SetGroupInfo s
;
4602 uint16_t levels
[] = {1, 2, 3, 4};
4603 uint16_t set_ok
[] = {0, 1, 1, 1};
4607 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
4608 torture_comment(tctx
, "Testing QueryGroupInfo level %u\n", levels
[i
]);
4610 r
.in
.group_handle
= handle
;
4611 r
.in
.level
= levels
[i
];
4614 status
= dcerpc_samr_QueryGroupInfo(p
, tctx
, &r
);
4615 if (!NT_STATUS_IS_OK(status
)) {
4616 torture_warning(tctx
, "QueryGroupInfo level %u failed - %s\n",
4617 levels
[i
], nt_errstr(status
));
4621 torture_comment(tctx
, "Testing SetGroupInfo level %u\n", levels
[i
]);
4623 s
.in
.group_handle
= handle
;
4624 s
.in
.level
= levels
[i
];
4625 s
.in
.info
= *r
.out
.info
;
4628 /* disabled this, as it changes the name only from the point of view of samr,
4629 but leaves the name from the point of view of w2k3 internals (and ldap). This means
4630 the name is still reserved, so creating the old name fails, but deleting by the old name
4632 if (s
.in
.level
== 2) {
4633 init_lsa_String(&s
.in
.info
->string
, "NewName");
4637 if (s
.in
.level
== 4) {
4638 init_lsa_String(&s
.in
.info
->description
, "test description");
4641 status
= dcerpc_samr_SetGroupInfo(p
, tctx
, &s
);
4643 if (!NT_STATUS_IS_OK(status
)) {
4644 torture_warning(tctx
, "SetGroupInfo level %u failed - %s\n",
4645 r
.in
.level
, nt_errstr(status
));
4650 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, status
)) {
4651 torture_warning(tctx
, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4652 r
.in
.level
, nt_errstr(status
));
4662 static bool test_QueryUserInfo(struct dcerpc_pipe
*p
,
4663 struct torture_context
*tctx
,
4664 struct policy_handle
*handle
)
4667 struct samr_QueryUserInfo r
;
4668 union samr_UserInfo
*info
;
4669 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4670 11, 12, 13, 14, 16, 17, 20, 21};
4674 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
4675 torture_comment(tctx
, "Testing QueryUserInfo level %u\n", levels
[i
]);
4677 r
.in
.user_handle
= handle
;
4678 r
.in
.level
= levels
[i
];
4681 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &r
);
4682 if (!NT_STATUS_IS_OK(status
)) {
4683 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
4684 levels
[i
], nt_errstr(status
));
4692 static bool test_QueryUserInfo2(struct dcerpc_pipe
*p
,
4693 struct torture_context
*tctx
,
4694 struct policy_handle
*handle
)
4697 struct samr_QueryUserInfo2 r
;
4698 union samr_UserInfo
*info
;
4699 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4700 11, 12, 13, 14, 16, 17, 20, 21};
4704 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
4705 torture_comment(tctx
, "Testing QueryUserInfo2 level %u\n", levels
[i
]);
4707 r
.in
.user_handle
= handle
;
4708 r
.in
.level
= levels
[i
];
4711 status
= dcerpc_samr_QueryUserInfo2(p
, tctx
, &r
);
4712 if (!NT_STATUS_IS_OK(status
)) {
4713 torture_warning(tctx
, "QueryUserInfo2 level %u failed - %s\n",
4714 levels
[i
], nt_errstr(status
));
4722 static bool test_OpenUser(struct dcerpc_pipe
*p
,
4723 struct torture_context
*tctx
,
4724 struct policy_handle
*handle
, uint32_t rid
)
4727 struct samr_OpenUser r
;
4728 struct policy_handle user_handle
;
4731 torture_comment(tctx
, "Testing OpenUser(%u)\n", rid
);
4733 r
.in
.domain_handle
= handle
;
4734 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4736 r
.out
.user_handle
= &user_handle
;
4738 status
= dcerpc_samr_OpenUser(p
, tctx
, &r
);
4739 if (!NT_STATUS_IS_OK(status
)) {
4740 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", rid
, nt_errstr(status
));
4744 if (!test_QuerySecurity(p
, tctx
, &user_handle
)) {
4748 if (!test_QueryUserInfo(p
, tctx
, &user_handle
)) {
4752 if (!test_QueryUserInfo2(p
, tctx
, &user_handle
)) {
4756 if (!test_GetUserPwInfo(p
, tctx
, &user_handle
)) {
4760 if (!test_GetGroupsForUser(p
,tctx
, &user_handle
)) {
4764 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
4771 static bool test_OpenGroup(struct dcerpc_pipe
*p
,
4772 struct torture_context
*tctx
,
4773 struct policy_handle
*handle
, uint32_t rid
)
4776 struct samr_OpenGroup r
;
4777 struct policy_handle group_handle
;
4780 torture_comment(tctx
, "Testing OpenGroup(%u)\n", rid
);
4782 r
.in
.domain_handle
= handle
;
4783 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4785 r
.out
.group_handle
= &group_handle
;
4787 status
= dcerpc_samr_OpenGroup(p
, tctx
, &r
);
4788 if (!NT_STATUS_IS_OK(status
)) {
4789 torture_warning(tctx
, "OpenGroup(%u) failed - %s\n", rid
, nt_errstr(status
));
4793 if (!torture_setting_bool(tctx
, "samba3", false)) {
4794 if (!test_QuerySecurity(p
, tctx
, &group_handle
)) {
4799 if (!test_QueryGroupInfo(p
, tctx
, &group_handle
)) {
4803 if (!test_QueryGroupMember(p
, tctx
, &group_handle
)) {
4807 if (!test_samr_handle_Close(p
, tctx
, &group_handle
)) {
4814 static bool test_OpenAlias(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4815 struct policy_handle
*handle
, uint32_t rid
)
4818 struct samr_OpenAlias r
;
4819 struct policy_handle alias_handle
;
4822 torture_comment(tctx
, "Testing OpenAlias(%u)\n", rid
);
4824 r
.in
.domain_handle
= handle
;
4825 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4827 r
.out
.alias_handle
= &alias_handle
;
4829 status
= dcerpc_samr_OpenAlias(p
, tctx
, &r
);
4830 if (!NT_STATUS_IS_OK(status
)) {
4831 torture_warning(tctx
, "OpenAlias(%u) failed - %s\n", rid
, nt_errstr(status
));
4835 if (!torture_setting_bool(tctx
, "samba3", false)) {
4836 if (!test_QuerySecurity(p
, tctx
, &alias_handle
)) {
4841 if (!test_QueryAliasInfo(p
, tctx
, &alias_handle
)) {
4845 if (!test_GetMembersInAlias(p
, tctx
, &alias_handle
)) {
4849 if (!test_samr_handle_Close(p
, tctx
, &alias_handle
)) {
4856 static bool check_mask(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4857 struct policy_handle
*handle
, uint32_t rid
,
4858 uint32_t acct_flag_mask
)
4861 struct samr_OpenUser r
;
4862 struct samr_QueryUserInfo q
;
4863 union samr_UserInfo
*info
;
4864 struct policy_handle user_handle
;
4867 torture_comment(tctx
, "Testing OpenUser(%u)\n", rid
);
4869 r
.in
.domain_handle
= handle
;
4870 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4872 r
.out
.user_handle
= &user_handle
;
4874 status
= dcerpc_samr_OpenUser(p
, tctx
, &r
);
4875 if (!NT_STATUS_IS_OK(status
)) {
4876 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", rid
, nt_errstr(status
));
4880 q
.in
.user_handle
= &user_handle
;
4884 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &q
);
4885 if (!NT_STATUS_IS_OK(status
)) {
4886 torture_warning(tctx
, "QueryUserInfo level 16 failed - %s\n",
4890 if ((acct_flag_mask
& info
->info16
.acct_flags
) == 0) {
4891 torture_warning(tctx
, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4892 acct_flag_mask
, info
->info16
.acct_flags
, rid
);
4897 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
4904 static bool test_EnumDomainUsers_all(struct dcerpc_pipe
*p
,
4905 struct torture_context
*tctx
,
4906 struct policy_handle
*handle
)
4908 NTSTATUS status
= STATUS_MORE_ENTRIES
;
4909 struct samr_EnumDomainUsers r
;
4910 uint32_t mask
, resume_handle
=0;
4913 struct samr_LookupNames n
;
4914 struct samr_LookupRids lr
;
4915 struct lsa_Strings names
;
4916 struct samr_Ids rids
, types
;
4917 struct samr_SamArray
*sam
= NULL
;
4918 uint32_t num_entries
= 0;
4920 uint32_t masks
[] = {ACB_NORMAL
, ACB_DOMTRUST
, ACB_WSTRUST
,
4921 ACB_DISABLED
, ACB_NORMAL
| ACB_DISABLED
,
4922 ACB_SVRTRUST
| ACB_DOMTRUST
| ACB_WSTRUST
,
4925 torture_comment(tctx
, "Testing EnumDomainUsers\n");
4927 for (mask_idx
=0;mask_idx
<ARRAY_SIZE(masks
);mask_idx
++) {
4928 r
.in
.domain_handle
= handle
;
4929 r
.in
.resume_handle
= &resume_handle
;
4930 r
.in
.acct_flags
= mask
= masks
[mask_idx
];
4931 r
.in
.max_size
= (uint32_t)-1;
4932 r
.out
.resume_handle
= &resume_handle
;
4933 r
.out
.num_entries
= &num_entries
;
4936 status
= dcerpc_samr_EnumDomainUsers(p
, tctx
, &r
);
4937 if (!NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) &&
4938 !NT_STATUS_IS_OK(status
)) {
4939 torture_warning(tctx
, "EnumDomainUsers failed - %s\n", nt_errstr(status
));
4943 torture_assert(tctx
, sam
, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4945 if (sam
->count
== 0) {
4949 for (i
=0;i
<sam
->count
;i
++) {
4951 if (!check_mask(p
, tctx
, handle
, sam
->entries
[i
].idx
, mask
)) {
4954 } else if (!test_OpenUser(p
, tctx
, handle
, sam
->entries
[i
].idx
)) {
4960 torture_comment(tctx
, "Testing LookupNames\n");
4961 n
.in
.domain_handle
= handle
;
4962 n
.in
.num_names
= sam
->count
;
4963 n
.in
.names
= talloc_array(tctx
, struct lsa_String
, sam
->count
);
4965 n
.out
.types
= &types
;
4966 for (i
=0;i
<sam
->count
;i
++) {
4967 n
.in
.names
[i
].string
= sam
->entries
[i
].name
.string
;
4969 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
4970 if (!NT_STATUS_IS_OK(status
)) {
4971 torture_warning(tctx
, "LookupNames failed - %s\n", nt_errstr(status
));
4976 torture_comment(tctx
, "Testing LookupRids\n");
4977 lr
.in
.domain_handle
= handle
;
4978 lr
.in
.num_rids
= sam
->count
;
4979 lr
.in
.rids
= talloc_array(tctx
, uint32_t, sam
->count
);
4980 lr
.out
.names
= &names
;
4981 lr
.out
.types
= &types
;
4982 for (i
=0;i
<sam
->count
;i
++) {
4983 lr
.in
.rids
[i
] = sam
->entries
[i
].idx
;
4985 status
= dcerpc_samr_LookupRids(p
, tctx
, &lr
);
4986 torture_assert_ntstatus_ok(tctx
, status
, "LookupRids");
4992 try blasting the server with a bunch of sync requests
4994 static bool test_EnumDomainUsers_async(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4995 struct policy_handle
*handle
)
4998 struct samr_EnumDomainUsers r
;
4999 uint32_t resume_handle
=0;
5001 #define ASYNC_COUNT 100
5002 struct rpc_request
*req
[ASYNC_COUNT
];
5004 if (!torture_setting_bool(tctx
, "dangerous", false)) {
5005 torture_skip(tctx
, "samr async test disabled - enable dangerous tests to use\n");
5008 torture_comment(tctx
, "Testing EnumDomainUsers_async\n");
5010 r
.in
.domain_handle
= handle
;
5011 r
.in
.resume_handle
= &resume_handle
;
5012 r
.in
.acct_flags
= 0;
5013 r
.in
.max_size
= (uint32_t)-1;
5014 r
.out
.resume_handle
= &resume_handle
;
5016 for (i
=0;i
<ASYNC_COUNT
;i
++) {
5017 req
[i
] = dcerpc_samr_EnumDomainUsers_send(p
, tctx
, &r
);
5020 for (i
=0;i
<ASYNC_COUNT
;i
++) {
5021 status
= dcerpc_ndr_request_recv(req
[i
]);
5022 if (!NT_STATUS_IS_OK(status
)) {
5023 torture_warning(tctx
, "EnumDomainUsers[%d] failed - %s\n",
5024 i
, nt_errstr(status
));
5029 torture_comment(tctx
, "%d async requests OK\n", i
);
5034 static bool test_EnumDomainGroups_all(struct dcerpc_pipe
*p
,
5035 struct torture_context
*tctx
,
5036 struct policy_handle
*handle
)
5039 struct samr_EnumDomainGroups r
;
5040 uint32_t resume_handle
=0;
5041 struct samr_SamArray
*sam
= NULL
;
5042 uint32_t num_entries
= 0;
5046 torture_comment(tctx
, "Testing EnumDomainGroups\n");
5048 r
.in
.domain_handle
= handle
;
5049 r
.in
.resume_handle
= &resume_handle
;
5050 r
.in
.max_size
= (uint32_t)-1;
5051 r
.out
.resume_handle
= &resume_handle
;
5052 r
.out
.num_entries
= &num_entries
;
5055 status
= dcerpc_samr_EnumDomainGroups(p
, tctx
, &r
);
5056 if (!NT_STATUS_IS_OK(status
)) {
5057 torture_warning(tctx
, "EnumDomainGroups failed - %s\n", nt_errstr(status
));
5065 for (i
=0;i
<sam
->count
;i
++) {
5066 if (!test_OpenGroup(p
, tctx
, handle
, sam
->entries
[i
].idx
)) {
5074 static bool test_EnumDomainAliases_all(struct dcerpc_pipe
*p
,
5075 struct torture_context
*tctx
,
5076 struct policy_handle
*handle
)
5079 struct samr_EnumDomainAliases r
;
5080 uint32_t resume_handle
=0;
5081 struct samr_SamArray
*sam
= NULL
;
5082 uint32_t num_entries
= 0;
5086 torture_comment(tctx
, "Testing EnumDomainAliases\n");
5088 r
.in
.domain_handle
= handle
;
5089 r
.in
.resume_handle
= &resume_handle
;
5090 r
.in
.max_size
= (uint32_t)-1;
5092 r
.out
.num_entries
= &num_entries
;
5093 r
.out
.resume_handle
= &resume_handle
;
5095 status
= dcerpc_samr_EnumDomainAliases(p
, tctx
, &r
);
5096 if (!NT_STATUS_IS_OK(status
)) {
5097 torture_warning(tctx
, "EnumDomainAliases failed - %s\n", nt_errstr(status
));
5105 for (i
=0;i
<sam
->count
;i
++) {
5106 if (!test_OpenAlias(p
, tctx
, handle
, sam
->entries
[i
].idx
)) {
5114 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe
*p
,
5115 struct torture_context
*tctx
,
5116 struct policy_handle
*handle
)
5119 struct samr_GetDisplayEnumerationIndex r
;
5121 uint16_t levels
[] = {1, 2, 3, 4, 5};
5122 uint16_t ok_lvl
[] = {1, 1, 1, 0, 0};
5123 struct lsa_String name
;
5127 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5128 torture_comment(tctx
, "Testing GetDisplayEnumerationIndex level %u\n", levels
[i
]);
5130 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
5132 r
.in
.domain_handle
= handle
;
5133 r
.in
.level
= levels
[i
];
5137 status
= dcerpc_samr_GetDisplayEnumerationIndex(p
, tctx
, &r
);
5140 !NT_STATUS_IS_OK(status
) &&
5141 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
5142 torture_warning(tctx
, "GetDisplayEnumerationIndex level %u failed - %s\n",
5143 levels
[i
], nt_errstr(status
));
5147 init_lsa_String(&name
, "zzzzzzzz");
5149 status
= dcerpc_samr_GetDisplayEnumerationIndex(p
, tctx
, &r
);
5151 if (ok_lvl
[i
] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
5152 torture_warning(tctx
, "GetDisplayEnumerationIndex level %u failed - %s\n",
5153 levels
[i
], nt_errstr(status
));
5161 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe
*p
,
5162 struct torture_context
*tctx
,
5163 struct policy_handle
*handle
)
5166 struct samr_GetDisplayEnumerationIndex2 r
;
5168 uint16_t levels
[] = {1, 2, 3, 4, 5};
5169 uint16_t ok_lvl
[] = {1, 1, 1, 0, 0};
5170 struct lsa_String name
;
5174 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5175 torture_comment(tctx
, "Testing GetDisplayEnumerationIndex2 level %u\n", levels
[i
]);
5177 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
5179 r
.in
.domain_handle
= handle
;
5180 r
.in
.level
= levels
[i
];
5184 status
= dcerpc_samr_GetDisplayEnumerationIndex2(p
, tctx
, &r
);
5186 !NT_STATUS_IS_OK(status
) &&
5187 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
5188 torture_warning(tctx
, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
5189 levels
[i
], nt_errstr(status
));
5193 init_lsa_String(&name
, "zzzzzzzz");
5195 status
= dcerpc_samr_GetDisplayEnumerationIndex2(p
, tctx
, &r
);
5196 if (ok_lvl
[i
] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
5197 torture_warning(tctx
, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
5198 levels
[i
], nt_errstr(status
));
5206 #define STRING_EQUAL_QUERY(s1, s2, user) \
5207 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
5208 /* odd, but valid */ \
5209 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
5210 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
5211 #s1, user.string, s1.string, s2.string, __location__); \
5214 #define INT_EQUAL_QUERY(s1, s2, user) \
5216 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
5217 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
5221 static bool test_each_DisplayInfo_user(struct dcerpc_pipe
*p
,
5222 struct torture_context
*tctx
,
5223 struct samr_QueryDisplayInfo
*querydisplayinfo
,
5224 bool *seen_testuser
)
5226 struct samr_OpenUser r
;
5227 struct samr_QueryUserInfo q
;
5228 union samr_UserInfo
*info
;
5229 struct policy_handle user_handle
;
5232 r
.in
.domain_handle
= querydisplayinfo
->in
.domain_handle
;
5233 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5234 for (i
= 0; ; i
++) {
5235 switch (querydisplayinfo
->in
.level
) {
5237 if (i
>= querydisplayinfo
->out
.info
->info1
.count
) {
5240 r
.in
.rid
= querydisplayinfo
->out
.info
->info1
.entries
[i
].rid
;
5243 if (i
>= querydisplayinfo
->out
.info
->info2
.count
) {
5246 r
.in
.rid
= querydisplayinfo
->out
.info
->info2
.entries
[i
].rid
;
5252 /* Not interested in validating just the account name */
5256 r
.out
.user_handle
= &user_handle
;
5258 switch (querydisplayinfo
->in
.level
) {
5261 status
= dcerpc_samr_OpenUser(p
, tctx
, &r
);
5262 if (!NT_STATUS_IS_OK(status
)) {
5263 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", r
.in
.rid
, nt_errstr(status
));
5268 q
.in
.user_handle
= &user_handle
;
5271 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &q
);
5272 if (!NT_STATUS_IS_OK(status
)) {
5273 torture_warning(tctx
, "QueryUserInfo(%u) failed - %s\n", r
.in
.rid
, nt_errstr(status
));
5277 switch (querydisplayinfo
->in
.level
) {
5279 if (seen_testuser
&& strcmp(info
->info21
.account_name
.string
, TEST_ACCOUNT_NAME
) == 0) {
5280 *seen_testuser
= true;
5282 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].full_name
,
5283 info
->info21
.full_name
, info
->info21
.account_name
);
5284 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].account_name
,
5285 info
->info21
.account_name
, info
->info21
.account_name
);
5286 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].description
,
5287 info
->info21
.description
, info
->info21
.account_name
);
5288 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].rid
,
5289 info
->info21
.rid
, info
->info21
.account_name
);
5290 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].acct_flags
,
5291 info
->info21
.acct_flags
, info
->info21
.account_name
);
5295 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].account_name
,
5296 info
->info21
.account_name
, info
->info21
.account_name
);
5297 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].description
,
5298 info
->info21
.description
, info
->info21
.account_name
);
5299 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].rid
,
5300 info
->info21
.rid
, info
->info21
.account_name
);
5301 INT_EQUAL_QUERY((querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
& ~ACB_NORMAL
),
5302 info
->info21
.acct_flags
, info
->info21
.account_name
);
5304 if (!(querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
& ACB_NORMAL
)) {
5305 torture_warning(tctx
, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
5306 info
->info21
.account_name
.string
);
5309 if (!(info
->info21
.acct_flags
& (ACB_WSTRUST
| ACB_SVRTRUST
))) {
5310 torture_warning(tctx
, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
5311 info
->info21
.account_name
.string
,
5312 querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
,
5313 info
->info21
.acct_flags
);
5320 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
5327 static bool test_QueryDisplayInfo(struct dcerpc_pipe
*p
,
5328 struct torture_context
*tctx
,
5329 struct policy_handle
*handle
)
5332 struct samr_QueryDisplayInfo r
;
5333 struct samr_QueryDomainInfo dom_info
;
5334 union samr_DomainInfo
*info
= NULL
;
5336 uint16_t levels
[] = {1, 2, 3, 4, 5};
5338 bool seen_testuser
= false;
5339 uint32_t total_size
;
5340 uint32_t returned_size
;
5341 union samr_DispInfo disp_info
;
5344 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5345 torture_comment(tctx
, "Testing QueryDisplayInfo level %u\n", levels
[i
]);
5348 status
= STATUS_MORE_ENTRIES
;
5349 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
5350 r
.in
.domain_handle
= handle
;
5351 r
.in
.level
= levels
[i
];
5352 r
.in
.max_entries
= 2;
5353 r
.in
.buf_size
= (uint32_t)-1;
5354 r
.out
.total_size
= &total_size
;
5355 r
.out
.returned_size
= &returned_size
;
5356 r
.out
.info
= &disp_info
;
5358 status
= dcerpc_samr_QueryDisplayInfo(p
, tctx
, &r
);
5359 if (!NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) && !NT_STATUS_IS_OK(status
)) {
5360 torture_warning(tctx
, "QueryDisplayInfo level %u failed - %s\n",
5361 levels
[i
], nt_errstr(status
));
5364 switch (r
.in
.level
) {
5366 if (!test_each_DisplayInfo_user(p
, tctx
, &r
, &seen_testuser
)) {
5369 r
.in
.start_idx
+= r
.out
.info
->info1
.count
;
5372 if (!test_each_DisplayInfo_user(p
, tctx
, &r
, NULL
)) {
5375 r
.in
.start_idx
+= r
.out
.info
->info2
.count
;
5378 r
.in
.start_idx
+= r
.out
.info
->info3
.count
;
5381 r
.in
.start_idx
+= r
.out
.info
->info4
.count
;
5384 r
.in
.start_idx
+= r
.out
.info
->info5
.count
;
5388 dom_info
.in
.domain_handle
= handle
;
5389 dom_info
.in
.level
= 2;
5390 dom_info
.out
.info
= &info
;
5392 /* Check number of users returned is correct */
5393 status
= dcerpc_samr_QueryDomainInfo(p
, tctx
, &dom_info
);
5394 if (!NT_STATUS_IS_OK(status
)) {
5395 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
5396 r
.in
.level
, nt_errstr(status
));
5400 switch (r
.in
.level
) {
5403 if (info
->general
.num_users
< r
.in
.start_idx
) {
5404 torture_warning(tctx
, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
5405 r
.in
.start_idx
, info
->general
.num_groups
,
5406 info
->general
.domain_name
.string
);
5409 if (!seen_testuser
) {
5410 struct policy_handle user_handle
;
5411 if (NT_STATUS_IS_OK(test_OpenUser_byname(p
, tctx
, handle
, TEST_ACCOUNT_NAME
, &user_handle
))) {
5412 torture_warning(tctx
, "Didn't find test user " TEST_ACCOUNT_NAME
" in enumeration of %s\n",
5413 info
->general
.domain_name
.string
);
5415 test_samr_handle_Close(p
, tctx
, &user_handle
);
5421 if (info
->general
.num_groups
!= r
.in
.start_idx
) {
5422 torture_warning(tctx
, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
5423 r
.in
.start_idx
, info
->general
.num_groups
,
5424 info
->general
.domain_name
.string
);
5436 static bool test_QueryDisplayInfo2(struct dcerpc_pipe
*p
,
5437 struct torture_context
*tctx
,
5438 struct policy_handle
*handle
)
5441 struct samr_QueryDisplayInfo2 r
;
5443 uint16_t levels
[] = {1, 2, 3, 4, 5};
5445 uint32_t total_size
;
5446 uint32_t returned_size
;
5447 union samr_DispInfo info
;
5449 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5450 torture_comment(tctx
, "Testing QueryDisplayInfo2 level %u\n", levels
[i
]);
5452 r
.in
.domain_handle
= handle
;
5453 r
.in
.level
= levels
[i
];
5455 r
.in
.max_entries
= 1000;
5456 r
.in
.buf_size
= (uint32_t)-1;
5457 r
.out
.total_size
= &total_size
;
5458 r
.out
.returned_size
= &returned_size
;
5461 status
= dcerpc_samr_QueryDisplayInfo2(p
, tctx
, &r
);
5462 if (!NT_STATUS_IS_OK(status
)) {
5463 torture_warning(tctx
, "QueryDisplayInfo2 level %u failed - %s\n",
5464 levels
[i
], nt_errstr(status
));
5472 static bool test_QueryDisplayInfo3(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5473 struct policy_handle
*handle
)
5476 struct samr_QueryDisplayInfo3 r
;
5478 uint16_t levels
[] = {1, 2, 3, 4, 5};
5480 uint32_t total_size
;
5481 uint32_t returned_size
;
5482 union samr_DispInfo info
;
5484 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5485 torture_comment(tctx
, "Testing QueryDisplayInfo3 level %u\n", levels
[i
]);
5487 r
.in
.domain_handle
= handle
;
5488 r
.in
.level
= levels
[i
];
5490 r
.in
.max_entries
= 1000;
5491 r
.in
.buf_size
= (uint32_t)-1;
5492 r
.out
.total_size
= &total_size
;
5493 r
.out
.returned_size
= &returned_size
;
5496 status
= dcerpc_samr_QueryDisplayInfo3(p
, tctx
, &r
);
5497 if (!NT_STATUS_IS_OK(status
)) {
5498 torture_warning(tctx
, "QueryDisplayInfo3 level %u failed - %s\n",
5499 levels
[i
], nt_errstr(status
));
5508 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe
*p
,
5509 struct torture_context
*tctx
,
5510 struct policy_handle
*handle
)
5513 struct samr_QueryDisplayInfo r
;
5515 uint32_t total_size
;
5516 uint32_t returned_size
;
5517 union samr_DispInfo info
;
5519 torture_comment(tctx
, "Testing QueryDisplayInfo continuation\n");
5521 r
.in
.domain_handle
= handle
;
5524 r
.in
.max_entries
= 1;
5525 r
.in
.buf_size
= (uint32_t)-1;
5526 r
.out
.total_size
= &total_size
;
5527 r
.out
.returned_size
= &returned_size
;
5531 status
= dcerpc_samr_QueryDisplayInfo(p
, tctx
, &r
);
5532 if (NT_STATUS_IS_OK(status
) && *r
.out
.returned_size
!= 0) {
5533 if (r
.out
.info
->info1
.entries
[0].idx
!= r
.in
.start_idx
+ 1) {
5534 torture_warning(tctx
, "expected idx %d but got %d\n",
5536 r
.out
.info
->info1
.entries
[0].idx
);
5540 if (!NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) &&
5541 !NT_STATUS_IS_OK(status
)) {
5542 torture_warning(tctx
, "QueryDisplayInfo level %u failed - %s\n",
5543 r
.in
.level
, nt_errstr(status
));
5548 } while ((NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) ||
5549 NT_STATUS_IS_OK(status
)) &&
5550 *r
.out
.returned_size
!= 0);
5555 static bool test_QueryDomainInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5556 struct policy_handle
*handle
)
5559 struct samr_QueryDomainInfo r
;
5560 union samr_DomainInfo
*info
= NULL
;
5561 struct samr_SetDomainInfo s
;
5562 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5563 uint16_t set_ok
[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
5566 const char *domain_comment
= talloc_asprintf(tctx
,
5567 "Tortured by Samba4 RPC-SAMR: %s",
5568 timestring(tctx
, time(NULL
)));
5570 s
.in
.domain_handle
= handle
;
5572 s
.in
.info
= talloc(tctx
, union samr_DomainInfo
);
5574 s
.in
.info
->oem
.oem_information
.string
= domain_comment
;
5575 status
= dcerpc_samr_SetDomainInfo(p
, tctx
, &s
);
5576 if (!NT_STATUS_IS_OK(status
)) {
5577 torture_warning(tctx
, "SetDomainInfo level %u (set comment) failed - %s\n",
5578 s
.in
.level
, nt_errstr(status
));
5582 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5583 torture_comment(tctx
, "Testing QueryDomainInfo level %u\n", levels
[i
]);
5585 r
.in
.domain_handle
= handle
;
5586 r
.in
.level
= levels
[i
];
5589 status
= dcerpc_samr_QueryDomainInfo(p
, tctx
, &r
);
5590 if (!NT_STATUS_IS_OK(status
)) {
5591 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
5592 r
.in
.level
, nt_errstr(status
));
5597 switch (levels
[i
]) {
5599 if (strcmp(info
->general
.oem_information
.string
, domain_comment
) != 0) {
5600 torture_warning(tctx
, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5601 levels
[i
], info
->general
.oem_information
.string
, domain_comment
);
5602 if (!torture_setting_bool(tctx
, "samba3", false)) {
5606 if (!info
->general
.primary
.string
) {
5607 torture_warning(tctx
, "QueryDomainInfo level %u returned no PDC name\n",
5610 } else if (info
->general
.role
== SAMR_ROLE_DOMAIN_PDC
) {
5611 if (dcerpc_server_name(p
) && strcasecmp_m(dcerpc_server_name(p
), info
->general
.primary
.string
) != 0) {
5612 torture_warning(tctx
, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5613 levels
[i
], info
->general
.primary
.string
, dcerpc_server_name(p
));
5618 if (strcmp(info
->oem
.oem_information
.string
, domain_comment
) != 0) {
5619 torture_warning(tctx
, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5620 levels
[i
], info
->oem
.oem_information
.string
, domain_comment
);
5621 if (!torture_setting_bool(tctx
, "samba3", false)) {
5627 if (!info
->info6
.primary
.string
) {
5628 torture_warning(tctx
, "QueryDomainInfo level %u returned no PDC name\n",
5634 if (strcmp(info
->general2
.general
.oem_information
.string
, domain_comment
) != 0) {
5635 torture_warning(tctx
, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5636 levels
[i
], info
->general2
.general
.oem_information
.string
, domain_comment
);
5637 if (!torture_setting_bool(tctx
, "samba3", false)) {
5644 torture_comment(tctx
, "Testing SetDomainInfo level %u\n", levels
[i
]);
5646 s
.in
.domain_handle
= handle
;
5647 s
.in
.level
= levels
[i
];
5650 status
= dcerpc_samr_SetDomainInfo(p
, tctx
, &s
);
5652 if (!NT_STATUS_IS_OK(status
)) {
5653 torture_warning(tctx
, "SetDomainInfo level %u failed - %s\n",
5654 r
.in
.level
, nt_errstr(status
));
5659 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, status
)) {
5660 torture_warning(tctx
, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5661 r
.in
.level
, nt_errstr(status
));
5667 status
= dcerpc_samr_QueryDomainInfo(p
, tctx
, &r
);
5668 if (!NT_STATUS_IS_OK(status
)) {
5669 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
5670 r
.in
.level
, nt_errstr(status
));
5680 static bool test_QueryDomainInfo2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5681 struct policy_handle
*handle
)
5684 struct samr_QueryDomainInfo2 r
;
5685 union samr_DomainInfo
*info
= NULL
;
5686 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5690 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5691 torture_comment(tctx
, "Testing QueryDomainInfo2 level %u\n", levels
[i
]);
5693 r
.in
.domain_handle
= handle
;
5694 r
.in
.level
= levels
[i
];
5697 status
= dcerpc_samr_QueryDomainInfo2(p
, tctx
, &r
);
5698 if (!NT_STATUS_IS_OK(status
)) {
5699 torture_warning(tctx
, "QueryDomainInfo2 level %u failed - %s\n",
5700 r
.in
.level
, nt_errstr(status
));
5709 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5710 set of group names. */
5711 static bool test_GroupList(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5712 struct policy_handle
*handle
)
5714 struct samr_EnumDomainGroups q1
;
5715 struct samr_QueryDisplayInfo q2
;
5717 uint32_t resume_handle
=0;
5718 struct samr_SamArray
*sam
= NULL
;
5719 uint32_t num_entries
= 0;
5722 uint32_t total_size
;
5723 uint32_t returned_size
;
5724 union samr_DispInfo info
;
5727 const char **names
= NULL
;
5729 torture_comment(tctx
, "Testing coherency of querydispinfo vs enumdomgroups\n");
5731 q1
.in
.domain_handle
= handle
;
5732 q1
.in
.resume_handle
= &resume_handle
;
5734 q1
.out
.resume_handle
= &resume_handle
;
5735 q1
.out
.num_entries
= &num_entries
;
5738 status
= STATUS_MORE_ENTRIES
;
5739 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
5740 status
= dcerpc_samr_EnumDomainGroups(p
, tctx
, &q1
);
5742 if (!NT_STATUS_IS_OK(status
) &&
5743 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
5746 for (i
=0; i
<*q1
.out
.num_entries
; i
++) {
5747 add_string_to_array(tctx
,
5748 sam
->entries
[i
].name
.string
,
5749 &names
, &num_names
);
5753 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomainGroups");
5755 torture_assert(tctx
, sam
, "EnumDomainGroups failed to return sam");
5757 q2
.in
.domain_handle
= handle
;
5759 q2
.in
.start_idx
= 0;
5760 q2
.in
.max_entries
= 5;
5761 q2
.in
.buf_size
= (uint32_t)-1;
5762 q2
.out
.total_size
= &total_size
;
5763 q2
.out
.returned_size
= &returned_size
;
5764 q2
.out
.info
= &info
;
5766 status
= STATUS_MORE_ENTRIES
;
5767 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
5768 status
= dcerpc_samr_QueryDisplayInfo(p
, tctx
, &q2
);
5770 if (!NT_STATUS_IS_OK(status
) &&
5771 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
5774 for (i
=0; i
<q2
.out
.info
->info5
.count
; i
++) {
5776 const char *name
= q2
.out
.info
->info5
.entries
[i
].account_name
.string
;
5778 for (j
=0; j
<num_names
; j
++) {
5779 if (names
[j
] == NULL
)
5781 if (strequal(names
[j
], name
)) {
5789 torture_warning(tctx
, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5794 q2
.in
.start_idx
+= q2
.out
.info
->info5
.count
;
5797 if (!NT_STATUS_IS_OK(status
)) {
5798 torture_warning(tctx
, "QueryDisplayInfo level 5 failed - %s\n",
5803 for (i
=0; i
<num_names
; i
++) {
5804 if (names
[i
] != NULL
) {
5805 torture_warning(tctx
, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5814 static bool test_DeleteDomainGroup(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5815 struct policy_handle
*group_handle
)
5817 struct samr_DeleteDomainGroup d
;
5820 torture_comment(tctx
, "Testing DeleteDomainGroup\n");
5822 d
.in
.group_handle
= group_handle
;
5823 d
.out
.group_handle
= group_handle
;
5825 status
= dcerpc_samr_DeleteDomainGroup(p
, tctx
, &d
);
5826 torture_assert_ntstatus_ok(tctx
, status
, "DeleteDomainGroup");
5831 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5832 struct policy_handle
*domain_handle
)
5834 struct samr_TestPrivateFunctionsDomain r
;
5838 torture_comment(tctx
, "Testing TestPrivateFunctionsDomain\n");
5840 r
.in
.domain_handle
= domain_handle
;
5842 status
= dcerpc_samr_TestPrivateFunctionsDomain(p
, tctx
, &r
);
5843 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_NOT_IMPLEMENTED
, "TestPrivateFunctionsDomain");
5848 static bool test_RidToSid(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5849 struct dom_sid
*domain_sid
,
5850 struct policy_handle
*domain_handle
)
5852 struct samr_RidToSid r
;
5855 struct dom_sid
*calc_sid
, *out_sid
;
5856 int rids
[] = { 0, 42, 512, 10200 };
5859 for (i
=0;i
<ARRAY_SIZE(rids
);i
++) {
5860 torture_comment(tctx
, "Testing RidToSid\n");
5862 calc_sid
= dom_sid_dup(tctx
, domain_sid
);
5863 r
.in
.domain_handle
= domain_handle
;
5865 r
.out
.sid
= &out_sid
;
5867 status
= dcerpc_samr_RidToSid(p
, tctx
, &r
);
5868 if (!NT_STATUS_IS_OK(status
)) {
5869 torture_warning(tctx
, "RidToSid for %d failed - %s\n", rids
[i
], nt_errstr(status
));
5872 calc_sid
= dom_sid_add_rid(calc_sid
, calc_sid
, rids
[i
]);
5874 if (!dom_sid_equal(calc_sid
, out_sid
)) {
5875 torture_warning(tctx
, "RidToSid for %d failed - got %s, expected %s\n", rids
[i
],
5876 dom_sid_string(tctx
, out_sid
),
5877 dom_sid_string(tctx
, calc_sid
));
5886 static bool test_GetBootKeyInformation(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5887 struct policy_handle
*domain_handle
)
5889 struct samr_GetBootKeyInformation r
;
5892 uint32_t unknown
= 0;
5894 torture_comment(tctx
, "Testing GetBootKeyInformation\n");
5896 r
.in
.domain_handle
= domain_handle
;
5897 r
.out
.unknown
= &unknown
;
5899 status
= dcerpc_samr_GetBootKeyInformation(p
, tctx
, &r
);
5900 if (!NT_STATUS_IS_OK(status
)) {
5901 /* w2k3 seems to fail this sometimes and pass it sometimes */
5902 torture_comment(tctx
, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status
));
5908 static bool test_AddGroupMember(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5909 struct policy_handle
*domain_handle
,
5910 struct policy_handle
*group_handle
)
5913 struct samr_AddGroupMember r
;
5914 struct samr_DeleteGroupMember d
;
5915 struct samr_QueryGroupMember q
;
5916 struct samr_RidTypeArray
*rids
= NULL
;
5917 struct samr_SetMemberAttributesOfGroup s
;
5919 bool found_member
= false;
5922 status
= test_LookupName(p
, tctx
, domain_handle
, TEST_ACCOUNT_NAME
, &rid
);
5923 torture_assert_ntstatus_ok(tctx
, status
, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME
);
5925 r
.in
.group_handle
= group_handle
;
5927 r
.in
.flags
= 0; /* ??? */
5929 torture_comment(tctx
, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
5931 d
.in
.group_handle
= group_handle
;
5934 status
= dcerpc_samr_DeleteGroupMember(p
, tctx
, &d
);
5935 torture_assert_ntstatus_equal(tctx
, NT_STATUS_MEMBER_NOT_IN_GROUP
, status
, "DeleteGroupMember");
5937 status
= dcerpc_samr_AddGroupMember(p
, tctx
, &r
);
5938 torture_assert_ntstatus_ok(tctx
, status
, "AddGroupMember");
5940 status
= dcerpc_samr_AddGroupMember(p
, tctx
, &r
);
5941 torture_assert_ntstatus_equal(tctx
, NT_STATUS_MEMBER_IN_GROUP
, status
, "AddGroupMember");
5943 if (torture_setting_bool(tctx
, "samba4", false) ||
5944 torture_setting_bool(tctx
, "samba3", false)) {
5945 torture_comment(tctx
, "skipping SetMemberAttributesOfGroup test against Samba\n");
5947 /* this one is quite strange. I am using random inputs in the
5948 hope of triggering an error that might give us a clue */
5950 s
.in
.group_handle
= group_handle
;
5951 s
.in
.unknown1
= random();
5952 s
.in
.unknown2
= random();
5954 status
= dcerpc_samr_SetMemberAttributesOfGroup(p
, tctx
, &s
);
5955 torture_assert_ntstatus_ok(tctx
, status
, "SetMemberAttributesOfGroup");
5958 q
.in
.group_handle
= group_handle
;
5961 status
= dcerpc_samr_QueryGroupMember(p
, tctx
, &q
);
5962 torture_assert_ntstatus_ok(tctx
, status
, "QueryGroupMember");
5963 torture_assert(tctx
, rids
, "QueryGroupMember did not fill in rids structure");
5965 for (i
=0; i
< rids
->count
; i
++) {
5966 if (rids
->rids
[i
] == rid
) {
5967 found_member
= true;
5971 torture_assert(tctx
, found_member
, "QueryGroupMember did not list newly added member");
5973 status
= dcerpc_samr_DeleteGroupMember(p
, tctx
, &d
);
5974 torture_assert_ntstatus_ok(tctx
, status
, "DeleteGroupMember");
5977 found_member
= false;
5979 status
= dcerpc_samr_QueryGroupMember(p
, tctx
, &q
);
5980 torture_assert_ntstatus_ok(tctx
, status
, "QueryGroupMember");
5981 torture_assert(tctx
, rids
, "QueryGroupMember did not fill in rids structure");
5983 for (i
=0; i
< rids
->count
; i
++) {
5984 if (rids
->rids
[i
] == rid
) {
5985 found_member
= true;
5989 torture_assert(tctx
, !found_member
, "QueryGroupMember does still list removed member");
5991 status
= dcerpc_samr_AddGroupMember(p
, tctx
, &r
);
5992 torture_assert_ntstatus_ok(tctx
, status
, "AddGroupMember");
5998 static bool test_CreateDomainGroup(struct dcerpc_pipe
*p
,
5999 struct torture_context
*tctx
,
6000 struct policy_handle
*domain_handle
,
6001 const char *group_name
,
6002 struct policy_handle
*group_handle
,
6003 struct dom_sid
*domain_sid
,
6007 struct samr_CreateDomainGroup r
;
6009 struct lsa_String name
;
6012 init_lsa_String(&name
, group_name
);
6014 r
.in
.domain_handle
= domain_handle
;
6016 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6017 r
.out
.group_handle
= group_handle
;
6020 torture_comment(tctx
, "Testing CreateDomainGroup(%s)\n", r
.in
.name
->string
);
6022 status
= dcerpc_samr_CreateDomainGroup(p
, tctx
, &r
);
6024 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
6025 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
6026 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.name
->string
);
6029 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.name
->string
,
6035 if (NT_STATUS_EQUAL(status
, NT_STATUS_GROUP_EXISTS
)) {
6036 if (!test_DeleteGroup_byname(p
, tctx
, domain_handle
, r
.in
.name
->string
)) {
6037 torture_warning(tctx
, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r
.in
.name
->string
,
6041 status
= dcerpc_samr_CreateDomainGroup(p
, tctx
, &r
);
6043 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_EXISTS
)) {
6044 if (!test_DeleteUser_byname(p
, tctx
, domain_handle
, r
.in
.name
->string
)) {
6046 torture_warning(tctx
, "CreateDomainGroup failed: Could not delete user %s - %s\n", r
.in
.name
->string
,
6050 status
= dcerpc_samr_CreateDomainGroup(p
, tctx
, &r
);
6052 torture_assert_ntstatus_ok(tctx
, status
, "CreateDomainGroup");
6058 if (!test_AddGroupMember(p
, tctx
, domain_handle
, group_handle
)) {
6059 torture_warning(tctx
, "CreateDomainGroup failed - %s\n", nt_errstr(status
));
6063 if (!test_SetGroupInfo(p
, tctx
, group_handle
)) {
6072 its not totally clear what this does. It seems to accept any sid you like.
6074 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe
*p
,
6075 struct torture_context
*tctx
,
6076 struct policy_handle
*domain_handle
)
6079 struct samr_RemoveMemberFromForeignDomain r
;
6081 r
.in
.domain_handle
= domain_handle
;
6082 r
.in
.sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-12-34-56-78");
6084 status
= dcerpc_samr_RemoveMemberFromForeignDomain(p
, tctx
, &r
);
6085 torture_assert_ntstatus_ok(tctx
, status
, "RemoveMemberFromForeignDomain");
6090 static bool test_EnumDomainUsers(struct dcerpc_pipe
*p
,
6091 struct torture_context
*tctx
,
6092 struct policy_handle
*domain_handle
,
6093 uint32_t *total_num_entries_p
)
6096 struct samr_EnumDomainUsers r
;
6097 uint32_t resume_handle
= 0;
6098 uint32_t num_entries
= 0;
6099 uint32_t total_num_entries
= 0;
6100 struct samr_SamArray
*sam
;
6102 r
.in
.domain_handle
= domain_handle
;
6103 r
.in
.acct_flags
= 0;
6104 r
.in
.max_size
= (uint32_t)-1;
6105 r
.in
.resume_handle
= &resume_handle
;
6108 r
.out
.num_entries
= &num_entries
;
6109 r
.out
.resume_handle
= &resume_handle
;
6111 torture_comment(tctx
, "Testing EnumDomainUsers\n");
6114 status
= dcerpc_samr_EnumDomainUsers(p
, tctx
, &r
);
6115 if (NT_STATUS_IS_ERR(status
)) {
6116 torture_assert_ntstatus_ok(tctx
, status
,
6117 "failed to enumerate users");
6120 total_num_entries
+= num_entries
;
6121 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
6123 if (total_num_entries_p
) {
6124 *total_num_entries_p
= total_num_entries
;
6130 static bool test_EnumDomainGroups(struct dcerpc_pipe
*p
,
6131 struct torture_context
*tctx
,
6132 struct policy_handle
*domain_handle
,
6133 uint32_t *total_num_entries_p
)
6136 struct samr_EnumDomainGroups r
;
6137 uint32_t resume_handle
= 0;
6138 uint32_t num_entries
= 0;
6139 uint32_t total_num_entries
= 0;
6140 struct samr_SamArray
*sam
;
6142 r
.in
.domain_handle
= domain_handle
;
6143 r
.in
.max_size
= (uint32_t)-1;
6144 r
.in
.resume_handle
= &resume_handle
;
6147 r
.out
.num_entries
= &num_entries
;
6148 r
.out
.resume_handle
= &resume_handle
;
6150 torture_comment(tctx
, "Testing EnumDomainGroups\n");
6153 status
= dcerpc_samr_EnumDomainGroups(p
, tctx
, &r
);
6154 if (NT_STATUS_IS_ERR(status
)) {
6155 torture_assert_ntstatus_ok(tctx
, status
,
6156 "failed to enumerate groups");
6159 total_num_entries
+= num_entries
;
6160 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
6162 if (total_num_entries_p
) {
6163 *total_num_entries_p
= total_num_entries
;
6169 static bool test_EnumDomainAliases(struct dcerpc_pipe
*p
,
6170 struct torture_context
*tctx
,
6171 struct policy_handle
*domain_handle
,
6172 uint32_t *total_num_entries_p
)
6175 struct samr_EnumDomainAliases r
;
6176 uint32_t resume_handle
= 0;
6177 uint32_t num_entries
= 0;
6178 uint32_t total_num_entries
= 0;
6179 struct samr_SamArray
*sam
;
6181 r
.in
.domain_handle
= domain_handle
;
6182 r
.in
.max_size
= (uint32_t)-1;
6183 r
.in
.resume_handle
= &resume_handle
;
6186 r
.out
.num_entries
= &num_entries
;
6187 r
.out
.resume_handle
= &resume_handle
;
6189 torture_comment(tctx
, "Testing EnumDomainAliases\n");
6192 status
= dcerpc_samr_EnumDomainAliases(p
, tctx
, &r
);
6193 if (NT_STATUS_IS_ERR(status
)) {
6194 torture_assert_ntstatus_ok(tctx
, status
,
6195 "failed to enumerate aliases");
6198 total_num_entries
+= num_entries
;
6199 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
6201 if (total_num_entries_p
) {
6202 *total_num_entries_p
= total_num_entries
;
6208 static bool test_QueryDisplayInfo_level(struct dcerpc_pipe
*p
,
6209 struct torture_context
*tctx
,
6210 struct policy_handle
*handle
,
6212 uint32_t *total_num_entries_p
)
6215 struct samr_QueryDisplayInfo r
;
6216 uint32_t total_num_entries
= 0;
6218 r
.in
.domain_handle
= handle
;
6221 r
.in
.max_entries
= (uint32_t)-1;
6222 r
.in
.buf_size
= (uint32_t)-1;
6224 torture_comment(tctx
, "Testing QueryDisplayInfo\n");
6227 uint32_t total_size
;
6228 uint32_t returned_size
;
6229 union samr_DispInfo info
;
6231 r
.out
.total_size
= &total_size
;
6232 r
.out
.returned_size
= &returned_size
;
6235 status
= dcerpc_samr_QueryDisplayInfo(p
, tctx
, &r
);
6236 if (NT_STATUS_IS_ERR(status
)) {
6237 torture_assert_ntstatus_ok(tctx
, status
,
6238 "failed to query displayinfo");
6241 if (*r
.out
.returned_size
== 0) {
6245 switch (r
.in
.level
) {
6247 total_num_entries
+= info
.info1
.count
;
6248 r
.in
.start_idx
+= info
.info1
.entries
[info
.info1
.count
- 1].idx
+ 1;
6251 total_num_entries
+= info
.info2
.count
;
6252 r
.in
.start_idx
+= info
.info2
.entries
[info
.info2
.count
- 1].idx
+ 1;
6255 total_num_entries
+= info
.info3
.count
;
6256 r
.in
.start_idx
+= info
.info3
.entries
[info
.info3
.count
- 1].idx
+ 1;
6259 total_num_entries
+= info
.info4
.count
;
6260 r
.in
.start_idx
+= info
.info4
.entries
[info
.info4
.count
- 1].idx
+ 1;
6263 total_num_entries
+= info
.info5
.count
;
6264 r
.in
.start_idx
+= info
.info5
.entries
[info
.info5
.count
- 1].idx
+ 1;
6270 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
6272 if (total_num_entries_p
) {
6273 *total_num_entries_p
= total_num_entries
;
6279 static bool test_ManyObjects(struct dcerpc_pipe
*p
,
6280 struct torture_context
*tctx
,
6281 struct policy_handle
*domain_handle
,
6282 struct dom_sid
*domain_sid
,
6283 struct torture_samr_context
*ctx
)
6285 uint32_t num_total
= ctx
->num_objects_large_dc
;
6286 uint32_t num_enum
= 0;
6287 uint32_t num_disp
= 0;
6288 uint32_t num_created
= 0;
6289 uint32_t num_anounced
= 0;
6294 struct policy_handle
*handles
= talloc_zero_array(tctx
, struct policy_handle
, num_total
);
6299 struct samr_QueryDomainInfo2 r
;
6300 union samr_DomainInfo
*info
;
6301 r
.in
.domain_handle
= domain_handle
;
6305 status
= dcerpc_samr_QueryDomainInfo2(p
, tctx
, &r
);
6306 torture_assert_ntstatus_ok(tctx
, status
,
6307 "failed to query domain info");
6309 switch (ctx
->choice
) {
6310 case TORTURE_SAMR_MANY_ACCOUNTS
:
6311 num_anounced
= info
->general
.num_users
;
6313 case TORTURE_SAMR_MANY_GROUPS
:
6314 num_anounced
= info
->general
.num_groups
;
6316 case TORTURE_SAMR_MANY_ALIASES
:
6317 num_anounced
= info
->general
.num_aliases
;
6326 for (i
=0; i
< num_total
; i
++) {
6328 const char *name
= NULL
;
6330 switch (ctx
->choice
) {
6331 case TORTURE_SAMR_MANY_ACCOUNTS
:
6332 name
= talloc_asprintf(tctx
, "%s%04d", TEST_ACCOUNT_NAME
, i
);
6333 ret
&= test_CreateUser(p
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, 0, NULL
, false);
6335 case TORTURE_SAMR_MANY_GROUPS
:
6336 name
= talloc_asprintf(tctx
, "%s%04d", TEST_GROUPNAME
, i
);
6337 ret
&= test_CreateDomainGroup(p
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, false);
6339 case TORTURE_SAMR_MANY_ALIASES
:
6340 name
= talloc_asprintf(tctx
, "%s%04d", TEST_ALIASNAME
, i
);
6341 ret
&= test_CreateAlias(p
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, false);
6346 if (!policy_handle_empty(&handles
[i
])) {
6353 switch (ctx
->choice
) {
6354 case TORTURE_SAMR_MANY_ACCOUNTS
:
6355 ret
&= test_EnumDomainUsers(p
, tctx
, domain_handle
, &num_enum
);
6357 case TORTURE_SAMR_MANY_GROUPS
:
6358 ret
&= test_EnumDomainGroups(p
, tctx
, domain_handle
, &num_enum
);
6360 case TORTURE_SAMR_MANY_ALIASES
:
6361 ret
&= test_EnumDomainAliases(p
, tctx
, domain_handle
, &num_enum
);
6369 switch (ctx
->choice
) {
6370 case TORTURE_SAMR_MANY_ACCOUNTS
:
6371 ret
&= test_QueryDisplayInfo_level(p
, tctx
, domain_handle
, 1, &num_disp
);
6373 case TORTURE_SAMR_MANY_GROUPS
:
6374 ret
&= test_QueryDisplayInfo_level(p
, tctx
, domain_handle
, 3, &num_disp
);
6376 case TORTURE_SAMR_MANY_ALIASES
:
6377 /* no aliases in dispinfo */
6383 /* close or delete */
6385 for (i
=0; i
< num_total
; i
++) {
6387 if (policy_handle_empty(&handles
[i
])) {
6391 if (torture_setting_bool(tctx
, "samba3", false)) {
6392 ret
&= test_samr_handle_Close(p
, tctx
, &handles
[i
]);
6394 switch (ctx
->choice
) {
6395 case TORTURE_SAMR_MANY_ACCOUNTS
:
6396 ret
&= test_DeleteUser(p
, tctx
, &handles
[i
]);
6398 case TORTURE_SAMR_MANY_GROUPS
:
6399 ret
&= test_DeleteDomainGroup(p
, tctx
, &handles
[i
]);
6401 case TORTURE_SAMR_MANY_ALIASES
:
6402 ret
&= test_DeleteAlias(p
, tctx
, &handles
[i
]);
6410 talloc_free(handles
);
6412 if (ctx
->choice
== TORTURE_SAMR_MANY_ACCOUNTS
&& num_enum
!= num_anounced
+ num_created
) {
6413 torture_comment(tctx
,
6414 "unexpected number of results (%u) returned in enum call, expected %u\n",
6415 num_enum
, num_anounced
+ num_created
);
6417 torture_comment(tctx
,
6418 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
6419 num_disp
, num_anounced
+ num_created
);
6424 static bool test_Connect(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6425 struct policy_handle
*handle
);
6427 static bool test_OpenDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6428 struct torture_samr_context
*ctx
, struct dom_sid
*sid
)
6431 struct samr_OpenDomain r
;
6432 struct policy_handle domain_handle
;
6433 struct policy_handle alias_handle
;
6434 struct policy_handle user_handle
;
6435 struct policy_handle group_handle
;
6438 ZERO_STRUCT(alias_handle
);
6439 ZERO_STRUCT(user_handle
);
6440 ZERO_STRUCT(group_handle
);
6441 ZERO_STRUCT(domain_handle
);
6443 torture_comment(tctx
, "Testing OpenDomain of %s\n", dom_sid_string(tctx
, sid
));
6445 r
.in
.connect_handle
= &ctx
->handle
;
6446 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6448 r
.out
.domain_handle
= &domain_handle
;
6450 status
= dcerpc_samr_OpenDomain(p
, tctx
, &r
);
6451 torture_assert_ntstatus_ok(tctx
, status
, "OpenDomain");
6453 /* run the domain tests with the main handle closed - this tests
6454 the servers reference counting */
6455 torture_assert(tctx
, test_samr_handle_Close(p
, tctx
, &ctx
->handle
), "Failed to close SAMR handle");
6457 switch (ctx
->choice
) {
6458 case TORTURE_SAMR_PASSWORDS
:
6459 case TORTURE_SAMR_USER_PRIVILEGES
:
6460 if (!torture_setting_bool(tctx
, "samba3", false)) {
6461 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, NULL
);
6463 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
6465 torture_warning(tctx
, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx
, sid
));
6468 case TORTURE_SAMR_USER_ATTRIBUTES
:
6469 if (!torture_setting_bool(tctx
, "samba3", false)) {
6470 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, NULL
);
6472 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
6473 /* This test needs 'complex' users to validate */
6474 ret
&= test_QueryDisplayInfo(p
, tctx
, &domain_handle
);
6476 torture_warning(tctx
, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx
, sid
));
6479 case TORTURE_SAMR_PASSWORDS_PWDLASTSET
:
6480 if (!torture_setting_bool(tctx
, "samba3", false)) {
6481 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, ctx
->machine_credentials
);
6483 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, ctx
->machine_credentials
, true);
6485 torture_warning(tctx
, "Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx
, sid
));
6488 case TORTURE_SAMR_MANY_ACCOUNTS
:
6489 case TORTURE_SAMR_MANY_GROUPS
:
6490 case TORTURE_SAMR_MANY_ALIASES
:
6491 ret
&= test_ManyObjects(p
, tctx
, &domain_handle
, sid
, ctx
);
6493 torture_warning(tctx
, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx
, sid
));
6496 case TORTURE_SAMR_OTHER
:
6497 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
6499 torture_warning(tctx
, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx
, sid
));
6501 if (!torture_setting_bool(tctx
, "samba3", false)) {
6502 ret
&= test_QuerySecurity(p
, tctx
, &domain_handle
);
6504 ret
&= test_RemoveMemberFromForeignDomain(p
, tctx
, &domain_handle
);
6505 ret
&= test_CreateAlias(p
, tctx
, &domain_handle
, TEST_ALIASNAME
, &alias_handle
, sid
, true);
6506 ret
&= test_CreateDomainGroup(p
, tctx
, &domain_handle
, TEST_GROUPNAME
, &group_handle
, sid
, true);
6507 ret
&= test_QueryDomainInfo(p
, tctx
, &domain_handle
);
6508 ret
&= test_QueryDomainInfo2(p
, tctx
, &domain_handle
);
6509 ret
&= test_EnumDomainUsers_all(p
, tctx
, &domain_handle
);
6510 ret
&= test_EnumDomainUsers_async(p
, tctx
, &domain_handle
);
6511 ret
&= test_EnumDomainGroups_all(p
, tctx
, &domain_handle
);
6512 ret
&= test_EnumDomainAliases_all(p
, tctx
, &domain_handle
);
6513 ret
&= test_QueryDisplayInfo2(p
, tctx
, &domain_handle
);
6514 ret
&= test_QueryDisplayInfo3(p
, tctx
, &domain_handle
);
6515 ret
&= test_QueryDisplayInfo_continue(p
, tctx
, &domain_handle
);
6517 if (torture_setting_bool(tctx
, "samba4", false)) {
6518 torture_comment(tctx
, "skipping GetDisplayEnumerationIndex test against Samba4\n");
6520 ret
&= test_GetDisplayEnumerationIndex(p
, tctx
, &domain_handle
);
6521 ret
&= test_GetDisplayEnumerationIndex2(p
, tctx
, &domain_handle
);
6523 ret
&= test_GroupList(p
, tctx
, &domain_handle
);
6524 ret
&= test_TestPrivateFunctionsDomain(p
, tctx
, &domain_handle
);
6525 ret
&= test_RidToSid(p
, tctx
, sid
, &domain_handle
);
6526 ret
&= test_GetBootKeyInformation(p
, tctx
, &domain_handle
);
6528 torture_comment(tctx
, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx
, sid
));
6533 if (!policy_handle_empty(&user_handle
) &&
6534 !test_DeleteUser(p
, tctx
, &user_handle
)) {
6538 if (!policy_handle_empty(&alias_handle
) &&
6539 !test_DeleteAlias(p
, tctx
, &alias_handle
)) {
6543 if (!policy_handle_empty(&group_handle
) &&
6544 !test_DeleteDomainGroup(p
, tctx
, &group_handle
)) {
6548 torture_assert(tctx
, test_samr_handle_Close(p
, tctx
, &domain_handle
), "Failed to close SAMR domain handle");
6550 torture_assert(tctx
, test_Connect(p
, tctx
, &ctx
->handle
), "Faile to re-connect SAMR handle");
6551 /* reconnect the main handle */
6554 torture_warning(tctx
, "Testing domain %s failed!\n", dom_sid_string(tctx
, sid
));
6560 static bool test_LookupDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6561 struct torture_samr_context
*ctx
, const char *domain
)
6564 struct samr_LookupDomain r
;
6565 struct dom_sid2
*sid
= NULL
;
6566 struct lsa_String n1
;
6567 struct lsa_String n2
;
6570 torture_comment(tctx
, "Testing LookupDomain(%s)\n", domain
);
6572 /* check for correct error codes */
6573 r
.in
.connect_handle
= &ctx
->handle
;
6574 r
.in
.domain_name
= &n2
;
6578 status
= dcerpc_samr_LookupDomain(p
, tctx
, &r
);
6579 torture_assert_ntstatus_equal(tctx
, NT_STATUS_INVALID_PARAMETER
, status
, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
6581 init_lsa_String(&n2
, "xxNODOMAINxx");
6583 status
= dcerpc_samr_LookupDomain(p
, tctx
, &r
);
6584 torture_assert_ntstatus_equal(tctx
, NT_STATUS_NO_SUCH_DOMAIN
, status
, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
6586 r
.in
.connect_handle
= &ctx
->handle
;
6588 init_lsa_String(&n1
, domain
);
6589 r
.in
.domain_name
= &n1
;
6591 status
= dcerpc_samr_LookupDomain(p
, tctx
, &r
);
6592 torture_assert_ntstatus_ok(tctx
, status
, "LookupDomain");
6594 if (!test_GetDomPwInfo(p
, tctx
, &n1
)) {
6598 if (!test_OpenDomain(p
, tctx
, ctx
, *r
.out
.sid
)) {
6606 static bool test_EnumDomains(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6607 struct torture_samr_context
*ctx
)
6610 struct samr_EnumDomains r
;
6611 uint32_t resume_handle
= 0;
6612 uint32_t num_entries
= 0;
6613 struct samr_SamArray
*sam
= NULL
;
6617 r
.in
.connect_handle
= &ctx
->handle
;
6618 r
.in
.resume_handle
= &resume_handle
;
6619 r
.in
.buf_size
= (uint32_t)-1;
6620 r
.out
.resume_handle
= &resume_handle
;
6621 r
.out
.num_entries
= &num_entries
;
6624 status
= dcerpc_samr_EnumDomains(p
, tctx
, &r
);
6625 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomains");
6631 for (i
=0;i
<sam
->count
;i
++) {
6632 if (!test_LookupDomain(p
, tctx
, ctx
,
6633 sam
->entries
[i
].name
.string
)) {
6638 status
= dcerpc_samr_EnumDomains(p
, tctx
, &r
);
6639 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomains");
6645 static bool test_Connect(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6646 struct policy_handle
*handle
)
6649 struct samr_Connect r
;
6650 struct samr_Connect2 r2
;
6651 struct samr_Connect3 r3
;
6652 struct samr_Connect4 r4
;
6653 struct samr_Connect5 r5
;
6654 union samr_ConnectInfo info
;
6655 struct policy_handle h
;
6656 uint32_t level_out
= 0;
6657 bool ret
= true, got_handle
= false;
6659 torture_comment(tctx
, "testing samr_Connect\n");
6661 r
.in
.system_name
= 0;
6662 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6663 r
.out
.connect_handle
= &h
;
6665 status
= dcerpc_samr_Connect(p
, tctx
, &r
);
6666 if (!NT_STATUS_IS_OK(status
)) {
6667 torture_comment(tctx
, "Connect failed - %s\n", nt_errstr(status
));
6674 torture_comment(tctx
, "testing samr_Connect2\n");
6676 r2
.in
.system_name
= NULL
;
6677 r2
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6678 r2
.out
.connect_handle
= &h
;
6680 status
= dcerpc_samr_Connect2(p
, tctx
, &r2
);
6681 if (!NT_STATUS_IS_OK(status
)) {
6682 torture_comment(tctx
, "Connect2 failed - %s\n", nt_errstr(status
));
6686 test_samr_handle_Close(p
, tctx
, handle
);
6692 torture_comment(tctx
, "testing samr_Connect3\n");
6694 r3
.in
.system_name
= NULL
;
6696 r3
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6697 r3
.out
.connect_handle
= &h
;
6699 status
= dcerpc_samr_Connect3(p
, tctx
, &r3
);
6700 if (!NT_STATUS_IS_OK(status
)) {
6701 torture_warning(tctx
, "Connect3 failed - %s\n", nt_errstr(status
));
6705 test_samr_handle_Close(p
, tctx
, handle
);
6711 torture_comment(tctx
, "testing samr_Connect4\n");
6713 r4
.in
.system_name
= "";
6714 r4
.in
.client_version
= 0;
6715 r4
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6716 r4
.out
.connect_handle
= &h
;
6718 status
= dcerpc_samr_Connect4(p
, tctx
, &r4
);
6719 if (!NT_STATUS_IS_OK(status
)) {
6720 torture_warning(tctx
, "Connect4 failed - %s\n", nt_errstr(status
));
6724 test_samr_handle_Close(p
, tctx
, handle
);
6730 torture_comment(tctx
, "testing samr_Connect5\n");
6732 info
.info1
.client_version
= 0;
6733 info
.info1
.unknown2
= 0;
6735 r5
.in
.system_name
= "";
6736 r5
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6738 r5
.out
.level_out
= &level_out
;
6739 r5
.in
.info_in
= &info
;
6740 r5
.out
.info_out
= &info
;
6741 r5
.out
.connect_handle
= &h
;
6743 status
= dcerpc_samr_Connect5(p
, tctx
, &r5
);
6744 if (!NT_STATUS_IS_OK(status
)) {
6745 torture_warning(tctx
, "Connect5 failed - %s\n", nt_errstr(status
));
6749 test_samr_handle_Close(p
, tctx
, handle
);
6759 static bool test_samr_ValidatePassword(struct dcerpc_pipe
*p
, struct torture_context
*tctx
)
6761 struct samr_ValidatePassword r
;
6762 union samr_ValidatePasswordReq req
;
6763 union samr_ValidatePasswordRep
*repp
= NULL
;
6765 const char *passwords
[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL
};
6768 torture_comment(tctx
, "testing samr_ValidatePassword\n");
6771 r
.in
.level
= NetValidatePasswordReset
;
6776 req
.req3
.account
.string
= "non-existant-account-aklsdji";
6778 for (i
=0; passwords
[i
]; i
++) {
6779 req
.req3
.password
.string
= passwords
[i
];
6780 status
= dcerpc_samr_ValidatePassword(p
, tctx
, &r
);
6781 torture_assert_ntstatus_ok(tctx
, status
, "samr_ValidatePassword");
6782 torture_comment(tctx
, "Server %s password '%s' with code %i\n",
6783 repp
->ctr3
.status
==SAMR_VALIDATION_STATUS_SUCCESS
?"allowed":"refused",
6784 req
.req3
.password
.string
, repp
->ctr3
.status
);
6790 bool torture_rpc_samr(struct torture_context
*torture
)
6793 struct dcerpc_pipe
*p
;
6795 struct torture_samr_context
*ctx
;
6797 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
6798 if (!NT_STATUS_IS_OK(status
)) {
6802 ctx
= talloc_zero(torture
, struct torture_samr_context
);
6804 ctx
->choice
= TORTURE_SAMR_OTHER
;
6806 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
6808 if (!torture_setting_bool(torture
, "samba3", false)) {
6809 ret
&= test_QuerySecurity(p
, torture
, &ctx
->handle
);
6812 ret
&= test_EnumDomains(p
, torture
, ctx
);
6814 ret
&= test_SetDsrmPassword(p
, torture
, &ctx
->handle
);
6816 ret
&= test_Shutdown(p
, torture
, &ctx
->handle
);
6818 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
6824 bool torture_rpc_samr_users(struct torture_context
*torture
)
6827 struct dcerpc_pipe
*p
;
6829 struct torture_samr_context
*ctx
;
6831 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
6832 if (!NT_STATUS_IS_OK(status
)) {
6836 ctx
= talloc_zero(torture
, struct torture_samr_context
);
6838 ctx
->choice
= TORTURE_SAMR_USER_ATTRIBUTES
;
6840 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
6842 if (!torture_setting_bool(torture
, "samba3", false)) {
6843 ret
&= test_QuerySecurity(p
, torture
, &ctx
->handle
);
6846 ret
&= test_EnumDomains(p
, torture
, ctx
);
6848 ret
&= test_SetDsrmPassword(p
, torture
, &ctx
->handle
);
6850 ret
&= test_Shutdown(p
, torture
, &ctx
->handle
);
6852 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
6858 bool torture_rpc_samr_passwords(struct torture_context
*torture
)
6861 struct dcerpc_pipe
*p
;
6863 struct torture_samr_context
*ctx
;
6865 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
6866 if (!NT_STATUS_IS_OK(status
)) {
6870 ctx
= talloc_zero(torture
, struct torture_samr_context
);
6872 ctx
->choice
= TORTURE_SAMR_PASSWORDS
;
6874 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
6876 ret
&= test_EnumDomains(p
, torture
, ctx
);
6878 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
6880 ret
&= test_samr_ValidatePassword(p
, torture
);
6885 static bool torture_rpc_samr_pwdlastset(struct torture_context
*torture
,
6886 struct dcerpc_pipe
*p2
,
6887 struct cli_credentials
*machine_credentials
)
6890 struct dcerpc_pipe
*p
;
6892 struct torture_samr_context
*ctx
;
6894 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
6895 if (!NT_STATUS_IS_OK(status
)) {
6899 ctx
= talloc_zero(torture
, struct torture_samr_context
);
6901 ctx
->choice
= TORTURE_SAMR_PASSWORDS_PWDLASTSET
;
6902 ctx
->machine_credentials
= machine_credentials
;
6904 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
6906 ret
&= test_EnumDomains(p
, torture
, ctx
);
6908 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
6913 struct torture_suite
*torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX
*mem_ctx
)
6915 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "SAMR-PASSWORDS-PWDLASTSET");
6916 struct torture_rpc_tcase
*tcase
;
6918 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
6920 TEST_ACCOUNT_NAME_PWD
);
6922 torture_rpc_tcase_add_test_creds(tcase
, "pwdLastSet",
6923 torture_rpc_samr_pwdlastset
);
6928 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context
*torture
,
6929 struct dcerpc_pipe
*p2
,
6930 struct cli_credentials
*machine_credentials
)
6933 struct dcerpc_pipe
*p
;
6935 struct torture_samr_context
*ctx
;
6937 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
6938 if (!NT_STATUS_IS_OK(status
)) {
6942 ctx
= talloc_zero(torture
, struct torture_samr_context
);
6944 ctx
->choice
= TORTURE_SAMR_USER_PRIVILEGES
;
6945 ctx
->machine_credentials
= machine_credentials
;
6947 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
6949 ret
&= test_EnumDomains(p
, torture
, ctx
);
6951 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
6956 struct torture_suite
*torture_rpc_samr_user_privileges(TALLOC_CTX
*mem_ctx
)
6958 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "SAMR-USERS-PRIVILEGES");
6959 struct torture_rpc_tcase
*tcase
;
6961 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
6963 TEST_ACCOUNT_NAME_PWD
);
6965 torture_rpc_tcase_add_test_creds(tcase
, "delete_privileged_user",
6966 torture_rpc_samr_users_privileges_delete_user
);
6971 static bool torture_rpc_samr_many_accounts(struct torture_context
*torture
,
6972 struct dcerpc_pipe
*p2
,
6973 struct cli_credentials
*machine_credentials
)
6976 struct dcerpc_pipe
*p
;
6978 struct torture_samr_context
*ctx
;
6980 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
6981 if (!NT_STATUS_IS_OK(status
)) {
6985 ctx
= talloc_zero(torture
, struct torture_samr_context
);
6987 ctx
->choice
= TORTURE_SAMR_MANY_ACCOUNTS
;
6988 ctx
->num_objects_large_dc
= 1500;
6990 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
6992 ret
&= test_EnumDomains(p
, torture
, ctx
);
6994 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
6999 static bool torture_rpc_samr_many_groups(struct torture_context
*torture
,
7000 struct dcerpc_pipe
*p2
,
7001 struct cli_credentials
*machine_credentials
)
7004 struct dcerpc_pipe
*p
;
7006 struct torture_samr_context
*ctx
;
7008 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7009 if (!NT_STATUS_IS_OK(status
)) {
7013 ctx
= talloc_zero(torture
, struct torture_samr_context
);
7015 ctx
->choice
= TORTURE_SAMR_MANY_GROUPS
;
7016 ctx
->num_objects_large_dc
= 1500;
7018 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
7020 ret
&= test_EnumDomains(p
, torture
, ctx
);
7022 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
7027 static bool torture_rpc_samr_many_aliases(struct torture_context
*torture
,
7028 struct dcerpc_pipe
*p2
,
7029 struct cli_credentials
*machine_credentials
)
7032 struct dcerpc_pipe
*p
;
7034 struct torture_samr_context
*ctx
;
7036 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7037 if (!NT_STATUS_IS_OK(status
)) {
7041 ctx
= talloc_zero(torture
, struct torture_samr_context
);
7043 ctx
->choice
= TORTURE_SAMR_MANY_ALIASES
;
7044 ctx
->num_objects_large_dc
= 1500;
7046 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
7048 ret
&= test_EnumDomains(p
, torture
, ctx
);
7050 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
7055 struct torture_suite
*torture_rpc_samr_large_dc(TALLOC_CTX
*mem_ctx
)
7057 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "SAMR-LARGE-DC");
7058 struct torture_rpc_tcase
*tcase
;
7060 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
7064 torture_rpc_tcase_add_test_creds(tcase
, "many_aliases",
7065 torture_rpc_samr_many_aliases
);
7066 torture_rpc_tcase_add_test_creds(tcase
, "many_groups",
7067 torture_rpc_samr_many_groups
);
7068 torture_rpc_tcase_add_test_creds(tcase
, "many_accounts",
7069 torture_rpc_samr_many_accounts
);