2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7 Copyright (C) Guenther Deschner 2008-2010
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "torture/torture.h"
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"
36 #include "auth/gensec/gensec.h"
37 #include "auth/gensec/gensec_proto.h"
38 #include "../libcli/auth/schannel.h"
42 #define TEST_ACCOUNT_NAME "samrtorturetest"
43 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
44 #define TEST_ALIASNAME "samrtorturetestalias"
45 #define TEST_GROUPNAME "samrtorturetestgroup"
46 #define TEST_MACHINENAME "samrtestmach$"
47 #define TEST_DOMAINNAME "samrtestdom$"
49 enum torture_samr_choice
{
50 TORTURE_SAMR_PASSWORDS
,
51 TORTURE_SAMR_PASSWORDS_PWDLASTSET
,
52 TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
,
53 TORTURE_SAMR_PASSWORDS_LOCKOUT
,
54 TORTURE_SAMR_USER_ATTRIBUTES
,
55 TORTURE_SAMR_USER_PRIVILEGES
,
57 TORTURE_SAMR_MANY_ACCOUNTS
,
58 TORTURE_SAMR_MANY_GROUPS
,
59 TORTURE_SAMR_MANY_ALIASES
62 struct torture_samr_context
{
63 struct policy_handle handle
;
64 struct cli_credentials
*machine_credentials
;
65 enum torture_samr_choice choice
;
66 uint32_t num_objects_large_dc
;
69 static bool test_QueryUserInfo(struct dcerpc_pipe
*p
,
70 struct torture_context
*tctx
,
71 struct policy_handle
*handle
);
73 static bool test_QueryUserInfo2(struct dcerpc_pipe
*p
,
74 struct torture_context
*tctx
,
75 struct policy_handle
*handle
);
77 static bool test_QueryAliasInfo(struct dcerpc_pipe
*p
,
78 struct torture_context
*tctx
,
79 struct policy_handle
*handle
);
81 static bool test_ChangePassword(struct dcerpc_pipe
*p
,
82 struct torture_context
*tctx
,
83 const char *acct_name
,
84 struct policy_handle
*domain_handle
, char **password
);
86 static void init_lsa_String(struct lsa_String
*string
, const char *s
)
91 static void init_lsa_StringLarge(struct lsa_StringLarge
*string
, const char *s
)
96 static void init_lsa_BinaryString(struct lsa_BinaryString
*string
, const char *s
, uint32_t length
)
98 string
->length
= length
;
99 string
->size
= length
;
100 string
->array
= (uint16_t *)discard_const(s
);
103 bool test_samr_handle_Close(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
104 struct policy_handle
*handle
)
109 r
.in
.handle
= handle
;
110 r
.out
.handle
= handle
;
112 status
= dcerpc_samr_Close(p
, tctx
, &r
);
113 torture_assert_ntstatus_ok(tctx
, status
, "Close");
118 static bool test_Shutdown(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
119 struct policy_handle
*handle
)
122 struct samr_Shutdown r
;
124 if (!torture_setting_bool(tctx
, "dangerous", false)) {
125 torture_skip(tctx
, "samr_Shutdown disabled - enable dangerous tests to use\n");
129 r
.in
.connect_handle
= handle
;
131 torture_comment(tctx
, "testing samr_Shutdown\n");
133 status
= dcerpc_samr_Shutdown(p
, tctx
, &r
);
134 torture_assert_ntstatus_ok(tctx
, status
, "samr_Shutdown");
139 static bool test_SetDsrmPassword(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
140 struct policy_handle
*handle
)
143 struct samr_SetDsrmPassword r
;
144 struct lsa_String string
;
145 struct samr_Password hash
;
147 if (!torture_setting_bool(tctx
, "dangerous", false)) {
148 torture_skip(tctx
, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
151 E_md4hash("TeSTDSRM123", hash
.hash
);
153 init_lsa_String(&string
, "Administrator");
159 torture_comment(tctx
, "testing samr_SetDsrmPassword\n");
161 status
= dcerpc_samr_SetDsrmPassword(p
, tctx
, &r
);
162 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_NOT_SUPPORTED
, "samr_SetDsrmPassword");
168 static bool test_QuerySecurity(struct dcerpc_pipe
*p
,
169 struct torture_context
*tctx
,
170 struct policy_handle
*handle
)
173 struct samr_QuerySecurity r
;
174 struct samr_SetSecurity s
;
175 struct sec_desc_buf
*sdbuf
= NULL
;
177 r
.in
.handle
= handle
;
179 r
.out
.sdbuf
= &sdbuf
;
181 status
= dcerpc_samr_QuerySecurity(p
, tctx
, &r
);
182 torture_assert_ntstatus_ok(tctx
, status
, "QuerySecurity");
184 torture_assert(tctx
, sdbuf
!= NULL
, "sdbuf is NULL");
186 s
.in
.handle
= handle
;
190 if (torture_setting_bool(tctx
, "samba4", false)) {
191 torture_skip(tctx
, "skipping SetSecurity test against Samba4\n");
194 status
= dcerpc_samr_SetSecurity(p
, tctx
, &s
);
195 torture_assert_ntstatus_ok(tctx
, status
, "SetSecurity");
197 status
= dcerpc_samr_QuerySecurity(p
, tctx
, &r
);
198 torture_assert_ntstatus_ok(tctx
, status
, "QuerySecurity");
204 static bool test_SetUserInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
205 struct policy_handle
*handle
, uint32_t base_acct_flags
,
206 const char *base_account_name
)
209 struct samr_SetUserInfo s
;
210 struct samr_SetUserInfo2 s2
;
211 struct samr_QueryUserInfo q
;
212 struct samr_QueryUserInfo q0
;
213 union samr_UserInfo u
;
214 union samr_UserInfo
*info
;
216 const char *test_account_name
;
218 uint32_t user_extra_flags
= 0;
220 if (!torture_setting_bool(tctx
, "samba3", false)) {
221 if (base_acct_flags
== ACB_NORMAL
) {
222 /* When created, accounts are expired by default */
223 user_extra_flags
= ACB_PW_EXPIRED
;
227 s
.in
.user_handle
= handle
;
230 s2
.in
.user_handle
= handle
;
233 q
.in
.user_handle
= handle
;
237 #define TESTCALL(call, r) \
238 status = dcerpc_samr_ ##call(p, tctx, &r); \
239 if (!NT_STATUS_IS_OK(status)) { \
240 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
241 r.in.level, nt_errstr(status), __location__); \
246 #define STRING_EQUAL(s1, s2, field) \
247 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
248 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
249 #field, s2, __location__); \
254 #define MEM_EQUAL(s1, s2, length, field) \
255 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
256 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
257 #field, (const char *)s2, __location__); \
262 #define INT_EQUAL(i1, i2, field) \
264 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
265 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
270 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
271 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
273 TESTCALL(QueryUserInfo, q) \
275 s2.in.level = lvl1; \
278 ZERO_STRUCT(u.info21); \
279 u.info21.fields_present = fpval; \
281 init_lsa_String(&u.info ## lvl1.field1, value); \
282 TESTCALL(SetUserInfo, s) \
283 TESTCALL(SetUserInfo2, s2) \
284 init_lsa_String(&u.info ## lvl1.field1, ""); \
285 TESTCALL(QueryUserInfo, q); \
287 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
289 TESTCALL(QueryUserInfo, q) \
291 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
294 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
295 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
297 TESTCALL(QueryUserInfo, q) \
299 s2.in.level = lvl1; \
302 ZERO_STRUCT(u.info21); \
303 u.info21.fields_present = fpval; \
305 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
306 TESTCALL(SetUserInfo, s) \
307 TESTCALL(SetUserInfo2, s2) \
308 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
309 TESTCALL(QueryUserInfo, q); \
311 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
313 TESTCALL(QueryUserInfo, q) \
315 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
318 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
319 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
321 TESTCALL(QueryUserInfo, q) \
323 s2.in.level = lvl1; \
326 uint8_t *bits = u.info21.logon_hours.bits; \
327 ZERO_STRUCT(u.info21); \
328 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
329 u.info21.logon_hours.units_per_week = 168; \
330 u.info21.logon_hours.bits = bits; \
332 u.info21.fields_present = fpval; \
334 u.info ## lvl1.field1 = value; \
335 TESTCALL(SetUserInfo, s) \
336 TESTCALL(SetUserInfo2, s2) \
337 u.info ## lvl1.field1 = 0; \
338 TESTCALL(QueryUserInfo, q); \
340 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
342 TESTCALL(QueryUserInfo, q) \
344 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
347 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
348 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
352 do { TESTCALL(QueryUserInfo
, q0
) } while (0);
354 TEST_USERINFO_STRING(2, comment
, 1, comment
, "xx2-1 comment", 0);
355 TEST_USERINFO_STRING(2, comment
, 21, comment
, "xx2-21 comment", 0);
356 TEST_USERINFO_STRING(21, comment
, 21, comment
, "xx21-21 comment",
359 test_account_name
= talloc_asprintf(tctx
, "%sxx7-1", base_account_name
);
360 TEST_USERINFO_STRING(7, account_name
, 1, account_name
, base_account_name
, 0);
361 test_account_name
= talloc_asprintf(tctx
, "%sxx7-3", base_account_name
);
362 TEST_USERINFO_STRING(7, account_name
, 3, account_name
, base_account_name
, 0);
363 test_account_name
= talloc_asprintf(tctx
, "%sxx7-5", base_account_name
);
364 TEST_USERINFO_STRING(7, account_name
, 5, account_name
, base_account_name
, 0);
365 test_account_name
= talloc_asprintf(tctx
, "%sxx7-6", base_account_name
);
366 TEST_USERINFO_STRING(7, account_name
, 6, account_name
, base_account_name
, 0);
367 test_account_name
= talloc_asprintf(tctx
, "%sxx7-7", base_account_name
);
368 TEST_USERINFO_STRING(7, account_name
, 7, account_name
, base_account_name
, 0);
369 test_account_name
= talloc_asprintf(tctx
, "%sxx7-21", base_account_name
);
370 TEST_USERINFO_STRING(7, account_name
, 21, account_name
, base_account_name
, 0);
371 test_account_name
= base_account_name
;
372 TEST_USERINFO_STRING(21, account_name
, 21, account_name
, base_account_name
,
373 SAMR_FIELD_ACCOUNT_NAME
);
375 TEST_USERINFO_STRING(6, full_name
, 1, full_name
, "xx6-1 full_name", 0);
376 TEST_USERINFO_STRING(6, full_name
, 3, full_name
, "xx6-3 full_name", 0);
377 TEST_USERINFO_STRING(6, full_name
, 5, full_name
, "xx6-5 full_name", 0);
378 TEST_USERINFO_STRING(6, full_name
, 6, full_name
, "xx6-6 full_name", 0);
379 TEST_USERINFO_STRING(6, full_name
, 8, full_name
, "xx6-8 full_name", 0);
380 TEST_USERINFO_STRING(6, full_name
, 21, full_name
, "xx6-21 full_name", 0);
381 TEST_USERINFO_STRING(8, full_name
, 21, full_name
, "xx8-21 full_name", 0);
382 TEST_USERINFO_STRING(21, full_name
, 21, full_name
, "xx21-21 full_name",
383 SAMR_FIELD_FULL_NAME
);
385 TEST_USERINFO_STRING(6, full_name
, 1, full_name
, "", 0);
386 TEST_USERINFO_STRING(6, full_name
, 3, full_name
, "", 0);
387 TEST_USERINFO_STRING(6, full_name
, 5, full_name
, "", 0);
388 TEST_USERINFO_STRING(6, full_name
, 6, full_name
, "", 0);
389 TEST_USERINFO_STRING(6, full_name
, 8, full_name
, "", 0);
390 TEST_USERINFO_STRING(6, full_name
, 21, full_name
, "", 0);
391 TEST_USERINFO_STRING(8, full_name
, 21, full_name
, "", 0);
392 TEST_USERINFO_STRING(21, full_name
, 21, full_name
, "",
393 SAMR_FIELD_FULL_NAME
);
395 TEST_USERINFO_STRING(11, logon_script
, 3, logon_script
, "xx11-3 logon_script", 0);
396 TEST_USERINFO_STRING(11, logon_script
, 5, logon_script
, "xx11-5 logon_script", 0);
397 TEST_USERINFO_STRING(11, logon_script
, 21, logon_script
, "xx11-21 logon_script", 0);
398 TEST_USERINFO_STRING(21, logon_script
, 21, logon_script
, "xx21-21 logon_script",
399 SAMR_FIELD_LOGON_SCRIPT
);
401 TEST_USERINFO_STRING(12, profile_path
, 3, profile_path
, "xx12-3 profile_path", 0);
402 TEST_USERINFO_STRING(12, profile_path
, 5, profile_path
, "xx12-5 profile_path", 0);
403 TEST_USERINFO_STRING(12, profile_path
, 21, profile_path
, "xx12-21 profile_path", 0);
404 TEST_USERINFO_STRING(21, profile_path
, 21, profile_path
, "xx21-21 profile_path",
405 SAMR_FIELD_PROFILE_PATH
);
407 TEST_USERINFO_STRING(10, home_directory
, 3, home_directory
, "xx10-3 home_directory", 0);
408 TEST_USERINFO_STRING(10, home_directory
, 5, home_directory
, "xx10-5 home_directory", 0);
409 TEST_USERINFO_STRING(10, home_directory
, 21, home_directory
, "xx10-21 home_directory", 0);
410 TEST_USERINFO_STRING(21, home_directory
, 21, home_directory
, "xx21-21 home_directory",
411 SAMR_FIELD_HOME_DIRECTORY
);
412 TEST_USERINFO_STRING(21, home_directory
, 10, home_directory
, "xx21-10 home_directory",
413 SAMR_FIELD_HOME_DIRECTORY
);
415 TEST_USERINFO_STRING(10, home_drive
, 3, home_drive
, "xx10-3 home_drive", 0);
416 TEST_USERINFO_STRING(10, home_drive
, 5, home_drive
, "xx10-5 home_drive", 0);
417 TEST_USERINFO_STRING(10, home_drive
, 21, home_drive
, "xx10-21 home_drive", 0);
418 TEST_USERINFO_STRING(21, home_drive
, 21, home_drive
, "xx21-21 home_drive",
419 SAMR_FIELD_HOME_DRIVE
);
420 TEST_USERINFO_STRING(21, home_drive
, 10, home_drive
, "xx21-10 home_drive",
421 SAMR_FIELD_HOME_DRIVE
);
423 TEST_USERINFO_STRING(13, description
, 1, description
, "xx13-1 description", 0);
424 TEST_USERINFO_STRING(13, description
, 5, description
, "xx13-5 description", 0);
425 TEST_USERINFO_STRING(13, description
, 21, description
, "xx13-21 description", 0);
426 TEST_USERINFO_STRING(21, description
, 21, description
, "xx21-21 description",
427 SAMR_FIELD_DESCRIPTION
);
429 TEST_USERINFO_STRING(14, workstations
, 3, workstations
, "14workstation3", 0);
430 TEST_USERINFO_STRING(14, workstations
, 5, workstations
, "14workstation4", 0);
431 TEST_USERINFO_STRING(14, workstations
, 21, workstations
, "14workstation21", 0);
432 TEST_USERINFO_STRING(21, workstations
, 21, workstations
, "21workstation21",
433 SAMR_FIELD_WORKSTATIONS
);
434 TEST_USERINFO_STRING(21, workstations
, 3, workstations
, "21workstation3",
435 SAMR_FIELD_WORKSTATIONS
);
436 TEST_USERINFO_STRING(21, workstations
, 5, workstations
, "21workstation5",
437 SAMR_FIELD_WORKSTATIONS
);
438 TEST_USERINFO_STRING(21, workstations
, 14, workstations
, "21workstation14",
439 SAMR_FIELD_WORKSTATIONS
);
441 TEST_USERINFO_BINARYSTRING(20, parameters
, 21, parameters
, "xx20-21 parameters", 0);
442 TEST_USERINFO_BINARYSTRING(21, parameters
, 21, parameters
, "xx21-21 parameters",
443 SAMR_FIELD_PARAMETERS
);
444 TEST_USERINFO_BINARYSTRING(21, parameters
, 20, parameters
, "xx21-20 parameters",
445 SAMR_FIELD_PARAMETERS
);
446 /* also empty user parameters are allowed */
447 TEST_USERINFO_BINARYSTRING(20, parameters
, 21, parameters
, "", 0);
448 TEST_USERINFO_BINARYSTRING(21, parameters
, 21, parameters
, "",
449 SAMR_FIELD_PARAMETERS
);
450 TEST_USERINFO_BINARYSTRING(21, parameters
, 20, parameters
, "",
451 SAMR_FIELD_PARAMETERS
);
453 /* Samba 3 cannot store country_code and copy_page atm. - gd */
454 if (!torture_setting_bool(tctx
, "samba3", false)) {
455 TEST_USERINFO_INT(2, country_code
, 2, country_code
, __LINE__
, 0);
456 TEST_USERINFO_INT(2, country_code
, 21, country_code
, __LINE__
, 0);
457 TEST_USERINFO_INT(21, country_code
, 21, country_code
, __LINE__
,
458 SAMR_FIELD_COUNTRY_CODE
);
459 TEST_USERINFO_INT(21, country_code
, 2, country_code
, __LINE__
,
460 SAMR_FIELD_COUNTRY_CODE
);
462 TEST_USERINFO_INT(2, code_page
, 21, code_page
, __LINE__
, 0);
463 TEST_USERINFO_INT(21, code_page
, 21, code_page
, __LINE__
,
464 SAMR_FIELD_CODE_PAGE
);
465 TEST_USERINFO_INT(21, code_page
, 2, code_page
, __LINE__
,
466 SAMR_FIELD_CODE_PAGE
);
469 if (!torture_setting_bool(tctx
, "samba3", false)) {
470 TEST_USERINFO_INT(17, acct_expiry
, 21, acct_expiry
, __LINE__
, 0);
471 TEST_USERINFO_INT(17, acct_expiry
, 5, acct_expiry
, __LINE__
, 0);
472 TEST_USERINFO_INT(21, acct_expiry
, 21, acct_expiry
, __LINE__
,
473 SAMR_FIELD_ACCT_EXPIRY
);
474 TEST_USERINFO_INT(21, acct_expiry
, 5, acct_expiry
, __LINE__
,
475 SAMR_FIELD_ACCT_EXPIRY
);
476 TEST_USERINFO_INT(21, acct_expiry
, 17, acct_expiry
, __LINE__
,
477 SAMR_FIELD_ACCT_EXPIRY
);
479 /* Samba 3 can only store seconds / time_t in passdb - gd */
481 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
482 TEST_USERINFO_INT(17, acct_expiry
, 21, acct_expiry
, nt
, 0);
483 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
484 TEST_USERINFO_INT(17, acct_expiry
, 5, acct_expiry
, nt
, 0);
485 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
486 TEST_USERINFO_INT(21, acct_expiry
, 21, acct_expiry
, nt
, SAMR_FIELD_ACCT_EXPIRY
);
487 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
488 TEST_USERINFO_INT(21, acct_expiry
, 5, acct_expiry
, nt
, SAMR_FIELD_ACCT_EXPIRY
);
489 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
490 TEST_USERINFO_INT(21, acct_expiry
, 17, acct_expiry
, nt
, SAMR_FIELD_ACCT_EXPIRY
);
493 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 3, logon_hours
.bits
[3], 1, 0);
494 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 5, logon_hours
.bits
[3], 2, 0);
495 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 21, logon_hours
.bits
[3], 3, 0);
496 TEST_USERINFO_INT(21, logon_hours
.bits
[3], 21, logon_hours
.bits
[3], 4,
497 SAMR_FIELD_LOGON_HOURS
);
499 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
500 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
),
501 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
| user_extra_flags
),
503 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
504 (base_acct_flags
| ACB_DISABLED
),
505 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
508 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
509 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
510 (base_acct_flags
| ACB_DISABLED
| ACB_PWNOEXP
),
511 (base_acct_flags
| ACB_DISABLED
| ACB_PWNOEXP
),
513 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
514 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
),
515 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
| user_extra_flags
),
519 /* The 'autolock' flag doesn't stick - check this */
520 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
521 (base_acct_flags
| ACB_DISABLED
| ACB_AUTOLOCK
),
522 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
525 /* Removing the 'disabled' flag doesn't stick - check this */
526 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
528 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
532 /* Samba3 cannot store these atm */
533 if (!torture_setting_bool(tctx
, "samba3", false)) {
534 /* The 'store plaintext' flag does stick */
535 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
536 (base_acct_flags
| ACB_DISABLED
| ACB_ENC_TXT_PWD_ALLOWED
),
537 (base_acct_flags
| ACB_DISABLED
| ACB_ENC_TXT_PWD_ALLOWED
| user_extra_flags
),
539 /* The 'use DES' flag does stick */
540 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
541 (base_acct_flags
| ACB_DISABLED
| ACB_USE_DES_KEY_ONLY
),
542 (base_acct_flags
| ACB_DISABLED
| ACB_USE_DES_KEY_ONLY
| user_extra_flags
),
544 /* The 'don't require kerberos pre-authentication flag does stick */
545 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
546 (base_acct_flags
| ACB_DISABLED
| ACB_DONT_REQUIRE_PREAUTH
),
547 (base_acct_flags
| ACB_DISABLED
| ACB_DONT_REQUIRE_PREAUTH
| user_extra_flags
),
549 /* The 'no kerberos PAC required' flag sticks */
550 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
551 (base_acct_flags
| ACB_DISABLED
| ACB_NO_AUTH_DATA_REQD
),
552 (base_acct_flags
| ACB_DISABLED
| ACB_NO_AUTH_DATA_REQD
| user_extra_flags
),
555 TEST_USERINFO_INT_EXP(21, acct_flags
, 21, acct_flags
,
556 (base_acct_flags
| ACB_DISABLED
),
557 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
558 SAMR_FIELD_ACCT_FLAGS
);
561 /* these fail with win2003 - it appears you can't set the primary gid?
562 the set succeeds, but the gid isn't changed. Very weird! */
563 TEST_USERINFO_INT(9, primary_gid
, 1, primary_gid
, 513);
564 TEST_USERINFO_INT(9, primary_gid
, 3, primary_gid
, 513);
565 TEST_USERINFO_INT(9, primary_gid
, 5, primary_gid
, 513);
566 TEST_USERINFO_INT(9, primary_gid
, 21, primary_gid
, 513);
573 generate a random password for password change tests
575 static char *samr_rand_pass_silent(TALLOC_CTX
*mem_ctx
, int min_len
)
577 size_t len
= MAX(8, min_len
);
578 char *s
= generate_random_password(mem_ctx
, len
, len
+6);
582 static char *samr_rand_pass(TALLOC_CTX
*mem_ctx
, int min_len
)
584 char *s
= samr_rand_pass_silent(mem_ctx
, min_len
);
585 printf("Generated password '%s'\n", s
);
591 generate a random password for password change tests
593 static DATA_BLOB
samr_very_rand_pass(TALLOC_CTX
*mem_ctx
, int len
)
596 DATA_BLOB password
= data_blob_talloc(mem_ctx
, NULL
, len
* 2 /* number of unicode chars */);
597 generate_random_buffer(password
.data
, password
.length
);
599 for (i
=0; i
< len
; i
++) {
600 if (((uint16_t *)password
.data
)[i
] == 0) {
601 ((uint16_t *)password
.data
)[i
] = 1;
609 generate a random password for password change tests (fixed length)
611 static char *samr_rand_pass_fixed_len(TALLOC_CTX
*mem_ctx
, int len
)
613 char *s
= generate_random_password(mem_ctx
, len
, len
);
614 printf("Generated password '%s'\n", s
);
618 static bool test_SetUserPass(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
619 struct policy_handle
*handle
, char **password
)
622 struct samr_SetUserInfo s
;
623 union samr_UserInfo u
;
625 DATA_BLOB session_key
;
627 struct samr_GetUserPwInfo pwp
;
628 struct samr_PwInfo info
;
629 int policy_min_pw_len
= 0;
630 pwp
.in
.user_handle
= handle
;
631 pwp
.out
.info
= &info
;
633 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
634 if (NT_STATUS_IS_OK(status
)) {
635 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
637 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
639 s
.in
.user_handle
= handle
;
643 encode_pw_buffer(u
.info24
.password
.data
, newpass
, STR_UNICODE
);
644 u
.info24
.password_expired
= 0;
646 status
= dcerpc_fetch_session_key(p
, &session_key
);
647 if (!NT_STATUS_IS_OK(status
)) {
648 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
649 s
.in
.level
, nt_errstr(status
));
653 arcfour_crypt_blob(u
.info24
.password
.data
, 516, &session_key
);
655 torture_comment(tctx
, "Testing SetUserInfo level 24 (set password)\n");
657 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
658 if (!NT_STATUS_IS_OK(status
)) {
659 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
660 s
.in
.level
, nt_errstr(status
));
670 static bool test_SetUserPass_23(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
671 struct policy_handle
*handle
, uint32_t fields_present
,
675 struct samr_SetUserInfo s
;
676 union samr_UserInfo u
;
678 DATA_BLOB session_key
;
680 struct samr_GetUserPwInfo pwp
;
681 struct samr_PwInfo info
;
682 int policy_min_pw_len
= 0;
683 pwp
.in
.user_handle
= handle
;
684 pwp
.out
.info
= &info
;
686 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
687 if (NT_STATUS_IS_OK(status
)) {
688 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
690 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
692 s
.in
.user_handle
= handle
;
698 u
.info23
.info
.fields_present
= fields_present
;
700 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
702 status
= dcerpc_fetch_session_key(p
, &session_key
);
703 if (!NT_STATUS_IS_OK(status
)) {
704 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
705 s
.in
.level
, nt_errstr(status
));
709 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
711 torture_comment(tctx
, "Testing SetUserInfo level 23 (set password)\n");
713 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
714 if (!NT_STATUS_IS_OK(status
)) {
715 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
716 s
.in
.level
, nt_errstr(status
));
722 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
724 status
= dcerpc_fetch_session_key(p
, &session_key
);
725 if (!NT_STATUS_IS_OK(status
)) {
726 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
727 s
.in
.level
, nt_errstr(status
));
731 /* This should break the key nicely */
732 session_key
.length
--;
733 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
735 torture_comment(tctx
, "Testing SetUserInfo level 23 (set password) with wrong password\n");
737 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
738 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
739 torture_warning(tctx
, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
740 s
.in
.level
, nt_errstr(status
));
748 static bool test_SetUserPassEx(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
749 struct policy_handle
*handle
, bool makeshort
,
753 struct samr_SetUserInfo s
;
754 union samr_UserInfo u
;
756 DATA_BLOB session_key
;
757 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
758 uint8_t confounder
[16];
760 struct MD5Context ctx
;
761 struct samr_GetUserPwInfo pwp
;
762 struct samr_PwInfo info
;
763 int policy_min_pw_len
= 0;
764 pwp
.in
.user_handle
= handle
;
765 pwp
.out
.info
= &info
;
767 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
768 if (NT_STATUS_IS_OK(status
)) {
769 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
771 if (makeshort
&& policy_min_pw_len
) {
772 newpass
= samr_rand_pass_fixed_len(tctx
, policy_min_pw_len
- 1);
774 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
777 s
.in
.user_handle
= handle
;
781 encode_pw_buffer(u
.info26
.password
.data
, newpass
, STR_UNICODE
);
782 u
.info26
.password_expired
= 0;
784 status
= dcerpc_fetch_session_key(p
, &session_key
);
785 if (!NT_STATUS_IS_OK(status
)) {
786 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
787 s
.in
.level
, nt_errstr(status
));
791 generate_random_buffer((uint8_t *)confounder
, 16);
794 MD5Update(&ctx
, confounder
, 16);
795 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
796 MD5Final(confounded_session_key
.data
, &ctx
);
798 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
799 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
801 torture_comment(tctx
, "Testing SetUserInfo level 26 (set password ex)\n");
803 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
804 if (!NT_STATUS_IS_OK(status
)) {
805 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
806 s
.in
.level
, nt_errstr(status
));
812 /* This should break the key nicely */
813 confounded_session_key
.data
[0]++;
815 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
816 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
818 torture_comment(tctx
, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
820 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
821 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
822 torture_warning(tctx
, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
823 s
.in
.level
, nt_errstr(status
));
832 static bool test_SetUserPass_25(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
833 struct policy_handle
*handle
, uint32_t fields_present
,
837 struct samr_SetUserInfo s
;
838 union samr_UserInfo u
;
840 DATA_BLOB session_key
;
841 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
842 struct MD5Context ctx
;
843 uint8_t confounder
[16];
845 struct samr_GetUserPwInfo pwp
;
846 struct samr_PwInfo info
;
847 int policy_min_pw_len
= 0;
848 pwp
.in
.user_handle
= handle
;
849 pwp
.out
.info
= &info
;
851 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
852 if (NT_STATUS_IS_OK(status
)) {
853 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
855 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
857 s
.in
.user_handle
= handle
;
863 u
.info25
.info
.fields_present
= fields_present
;
865 encode_pw_buffer(u
.info25
.password
.data
, newpass
, STR_UNICODE
);
867 status
= dcerpc_fetch_session_key(p
, &session_key
);
868 if (!NT_STATUS_IS_OK(status
)) {
869 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
870 s
.in
.level
, nt_errstr(status
));
874 generate_random_buffer((uint8_t *)confounder
, 16);
877 MD5Update(&ctx
, confounder
, 16);
878 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
879 MD5Final(confounded_session_key
.data
, &ctx
);
881 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
882 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
884 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex)\n");
886 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
887 if (!NT_STATUS_IS_OK(status
)) {
888 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
889 s
.in
.level
, nt_errstr(status
));
895 /* This should break the key nicely */
896 confounded_session_key
.data
[0]++;
898 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
899 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
901 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
903 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
904 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
905 torture_warning(tctx
, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
906 s
.in
.level
, nt_errstr(status
));
913 static bool test_SetUserPass_18(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
914 struct policy_handle
*handle
, char **password
)
917 struct samr_SetUserInfo s
;
918 union samr_UserInfo u
;
920 DATA_BLOB session_key
;
922 struct samr_GetUserPwInfo pwp
;
923 struct samr_PwInfo info
;
924 int policy_min_pw_len
= 0;
925 uint8_t lm_hash
[16], nt_hash
[16];
927 pwp
.in
.user_handle
= handle
;
928 pwp
.out
.info
= &info
;
930 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
931 if (NT_STATUS_IS_OK(status
)) {
932 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
934 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
936 s
.in
.user_handle
= handle
;
942 u
.info18
.nt_pwd_active
= true;
943 u
.info18
.lm_pwd_active
= true;
945 E_md4hash(newpass
, nt_hash
);
946 E_deshash(newpass
, lm_hash
);
948 status
= dcerpc_fetch_session_key(p
, &session_key
);
949 if (!NT_STATUS_IS_OK(status
)) {
950 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
951 s
.in
.level
, nt_errstr(status
));
957 in
= data_blob_const(nt_hash
, 16);
958 out
= data_blob_talloc_zero(tctx
, 16);
959 sess_crypt_blob(&out
, &in
, &session_key
, true);
960 memcpy(u
.info18
.nt_pwd
.hash
, out
.data
, out
.length
);
964 in
= data_blob_const(lm_hash
, 16);
965 out
= data_blob_talloc_zero(tctx
, 16);
966 sess_crypt_blob(&out
, &in
, &session_key
, true);
967 memcpy(u
.info18
.lm_pwd
.hash
, out
.data
, out
.length
);
970 torture_comment(tctx
, "Testing SetUserInfo level 18 (set password hash)\n");
972 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
973 if (!NT_STATUS_IS_OK(status
)) {
974 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
975 s
.in
.level
, nt_errstr(status
));
984 static bool test_SetUserPass_21(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
985 struct policy_handle
*handle
, uint32_t fields_present
,
989 struct samr_SetUserInfo s
;
990 union samr_UserInfo u
;
992 DATA_BLOB session_key
;
994 struct samr_GetUserPwInfo pwp
;
995 struct samr_PwInfo info
;
996 int policy_min_pw_len
= 0;
997 uint8_t lm_hash
[16], nt_hash
[16];
999 pwp
.in
.user_handle
= handle
;
1000 pwp
.out
.info
= &info
;
1002 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
1003 if (NT_STATUS_IS_OK(status
)) {
1004 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1006 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1008 s
.in
.user_handle
= handle
;
1012 E_md4hash(newpass
, nt_hash
);
1013 E_deshash(newpass
, lm_hash
);
1017 u
.info21
.fields_present
= fields_present
;
1019 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1020 u
.info21
.lm_owf_password
.length
= 16;
1021 u
.info21
.lm_owf_password
.size
= 16;
1022 u
.info21
.lm_owf_password
.array
= (uint16_t *)lm_hash
;
1023 u
.info21
.lm_password_set
= true;
1026 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1027 u
.info21
.nt_owf_password
.length
= 16;
1028 u
.info21
.nt_owf_password
.size
= 16;
1029 u
.info21
.nt_owf_password
.array
= (uint16_t *)nt_hash
;
1030 u
.info21
.nt_password_set
= true;
1033 status
= dcerpc_fetch_session_key(p
, &session_key
);
1034 if (!NT_STATUS_IS_OK(status
)) {
1035 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
1036 s
.in
.level
, nt_errstr(status
));
1040 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1042 in
= data_blob_const(u
.info21
.lm_owf_password
.array
,
1043 u
.info21
.lm_owf_password
.length
);
1044 out
= data_blob_talloc_zero(tctx
, 16);
1045 sess_crypt_blob(&out
, &in
, &session_key
, true);
1046 u
.info21
.lm_owf_password
.array
= (uint16_t *)out
.data
;
1049 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1051 in
= data_blob_const(u
.info21
.nt_owf_password
.array
,
1052 u
.info21
.nt_owf_password
.length
);
1053 out
= data_blob_talloc_zero(tctx
, 16);
1054 sess_crypt_blob(&out
, &in
, &session_key
, true);
1055 u
.info21
.nt_owf_password
.array
= (uint16_t *)out
.data
;
1058 torture_comment(tctx
, "Testing SetUserInfo level 21 (set password hash)\n");
1060 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
1061 if (!NT_STATUS_IS_OK(status
)) {
1062 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
1063 s
.in
.level
, nt_errstr(status
));
1066 *password
= newpass
;
1069 /* try invalid length */
1070 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1072 u
.info21
.nt_owf_password
.length
++;
1074 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
1076 if (!NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
1077 torture_warning(tctx
, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1078 s
.in
.level
, nt_errstr(status
));
1083 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1085 u
.info21
.lm_owf_password
.length
++;
1087 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
1089 if (!NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
1090 torture_warning(tctx
, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1091 s
.in
.level
, nt_errstr(status
));
1099 static bool test_SetUserPass_level_ex(struct dcerpc_pipe
*p
,
1100 struct torture_context
*tctx
,
1101 struct policy_handle
*handle
,
1103 uint32_t fields_present
,
1104 char **password
, uint8_t password_expired
,
1106 bool *matched_expected_error
)
1109 NTSTATUS expected_error
= NT_STATUS_OK
;
1110 struct samr_SetUserInfo s
;
1111 struct samr_SetUserInfo2 s2
;
1112 union samr_UserInfo u
;
1114 DATA_BLOB session_key
;
1115 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
1116 struct MD5Context ctx
;
1117 uint8_t confounder
[16];
1119 struct samr_GetUserPwInfo pwp
;
1120 struct samr_PwInfo info
;
1121 int policy_min_pw_len
= 0;
1122 const char *comment
= NULL
;
1123 uint8_t lm_hash
[16], nt_hash
[16];
1125 pwp
.in
.user_handle
= handle
;
1126 pwp
.out
.info
= &info
;
1128 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
1129 if (NT_STATUS_IS_OK(status
)) {
1130 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1132 newpass
= samr_rand_pass_silent(tctx
, policy_min_pw_len
);
1135 s2
.in
.user_handle
= handle
;
1137 s2
.in
.level
= level
;
1139 s
.in
.user_handle
= handle
;
1144 if (fields_present
& SAMR_FIELD_COMMENT
) {
1145 comment
= talloc_asprintf(tctx
, "comment: %ld\n", time(NULL
));
1152 E_md4hash(newpass
, nt_hash
);
1153 E_deshash(newpass
, lm_hash
);
1155 u
.info18
.nt_pwd_active
= true;
1156 u
.info18
.lm_pwd_active
= true;
1157 u
.info18
.password_expired
= password_expired
;
1159 memcpy(u
.info18
.lm_pwd
.hash
, lm_hash
, 16);
1160 memcpy(u
.info18
.nt_pwd
.hash
, nt_hash
, 16);
1164 E_md4hash(newpass
, nt_hash
);
1165 E_deshash(newpass
, lm_hash
);
1167 u
.info21
.fields_present
= fields_present
;
1168 u
.info21
.password_expired
= password_expired
;
1169 u
.info21
.comment
.string
= comment
;
1171 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1172 u
.info21
.lm_owf_password
.length
= 16;
1173 u
.info21
.lm_owf_password
.size
= 16;
1174 u
.info21
.lm_owf_password
.array
= (uint16_t *)lm_hash
;
1175 u
.info21
.lm_password_set
= true;
1178 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1179 u
.info21
.nt_owf_password
.length
= 16;
1180 u
.info21
.nt_owf_password
.size
= 16;
1181 u
.info21
.nt_owf_password
.array
= (uint16_t *)nt_hash
;
1182 u
.info21
.nt_password_set
= true;
1187 u
.info23
.info
.fields_present
= fields_present
;
1188 u
.info23
.info
.password_expired
= password_expired
;
1189 u
.info23
.info
.comment
.string
= comment
;
1191 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
1195 u
.info24
.password_expired
= password_expired
;
1197 encode_pw_buffer(u
.info24
.password
.data
, newpass
, STR_UNICODE
);
1201 u
.info25
.info
.fields_present
= fields_present
;
1202 u
.info25
.info
.password_expired
= password_expired
;
1203 u
.info25
.info
.comment
.string
= comment
;
1205 encode_pw_buffer(u
.info25
.password
.data
, newpass
, STR_UNICODE
);
1209 u
.info26
.password_expired
= password_expired
;
1211 encode_pw_buffer(u
.info26
.password
.data
, newpass
, STR_UNICODE
);
1216 status
= dcerpc_fetch_session_key(p
, &session_key
);
1217 if (!NT_STATUS_IS_OK(status
)) {
1218 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
1219 s
.in
.level
, nt_errstr(status
));
1223 generate_random_buffer((uint8_t *)confounder
, 16);
1226 MD5Update(&ctx
, confounder
, 16);
1227 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
1228 MD5Final(confounded_session_key
.data
, &ctx
);
1234 in
= data_blob_const(u
.info18
.nt_pwd
.hash
, 16);
1235 out
= data_blob_talloc_zero(tctx
, 16);
1236 sess_crypt_blob(&out
, &in
, &session_key
, true);
1237 memcpy(u
.info18
.nt_pwd
.hash
, out
.data
, out
.length
);
1241 in
= data_blob_const(u
.info18
.lm_pwd
.hash
, 16);
1242 out
= data_blob_talloc_zero(tctx
, 16);
1243 sess_crypt_blob(&out
, &in
, &session_key
, true);
1244 memcpy(u
.info18
.lm_pwd
.hash
, out
.data
, out
.length
);
1249 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1251 in
= data_blob_const(u
.info21
.lm_owf_password
.array
,
1252 u
.info21
.lm_owf_password
.length
);
1253 out
= data_blob_talloc_zero(tctx
, 16);
1254 sess_crypt_blob(&out
, &in
, &session_key
, true);
1255 u
.info21
.lm_owf_password
.array
= (uint16_t *)out
.data
;
1257 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1259 in
= data_blob_const(u
.info21
.nt_owf_password
.array
,
1260 u
.info21
.nt_owf_password
.length
);
1261 out
= data_blob_talloc_zero(tctx
, 16);
1262 sess_crypt_blob(&out
, &in
, &session_key
, true);
1263 u
.info21
.nt_owf_password
.array
= (uint16_t *)out
.data
;
1267 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
1270 arcfour_crypt_blob(u
.info24
.password
.data
, 516, &session_key
);
1273 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
1274 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
1277 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
1278 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
1283 status
= dcerpc_samr_SetUserInfo2(p
, tctx
, &s2
);
1285 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
1288 if (!NT_STATUS_IS_OK(status
)) {
1289 if (fields_present
== 0) {
1290 expected_error
= NT_STATUS_INVALID_PARAMETER
;
1292 if (fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
1293 expected_error
= NT_STATUS_ACCESS_DENIED
;
1297 if (!NT_STATUS_IS_OK(expected_error
)) {
1299 torture_assert_ntstatus_equal(tctx
,
1301 expected_error
, "SetUserInfo2 failed");
1303 torture_assert_ntstatus_equal(tctx
,
1305 expected_error
, "SetUserInfo failed");
1307 *matched_expected_error
= true;
1311 if (!NT_STATUS_IS_OK(status
)) {
1312 torture_warning(tctx
, "SetUserInfo%s level %u failed - %s\n",
1313 use_setinfo2
? "2":"", level
, nt_errstr(status
));
1316 *password
= newpass
;
1322 static bool test_SetAliasInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1323 struct policy_handle
*handle
)
1326 struct samr_SetAliasInfo r
;
1327 struct samr_QueryAliasInfo q
;
1328 union samr_AliasInfo
*info
;
1329 uint16_t levels
[] = {2, 3};
1333 /* Ignoring switch level 1, as that includes the number of members for the alias
1334 * and setting this to a wrong value might have negative consequences
1337 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
1338 torture_comment(tctx
, "Testing SetAliasInfo level %u\n", levels
[i
]);
1340 r
.in
.alias_handle
= handle
;
1341 r
.in
.level
= levels
[i
];
1342 r
.in
.info
= talloc(tctx
, union samr_AliasInfo
);
1343 switch (r
.in
.level
) {
1344 case ALIASINFONAME
: init_lsa_String(&r
.in
.info
->name
,TEST_ALIASNAME
); break;
1345 case ALIASINFODESCRIPTION
: init_lsa_String(&r
.in
.info
->description
,
1346 "Test Description, should test I18N as well"); break;
1347 case ALIASINFOALL
: torture_comment(tctx
, "ALIASINFOALL ignored\n"); break;
1350 status
= dcerpc_samr_SetAliasInfo(p
, tctx
, &r
);
1351 if (!NT_STATUS_IS_OK(status
)) {
1352 torture_warning(tctx
, "SetAliasInfo level %u failed - %s\n",
1353 levels
[i
], nt_errstr(status
));
1357 q
.in
.alias_handle
= handle
;
1358 q
.in
.level
= levels
[i
];
1361 status
= dcerpc_samr_QueryAliasInfo(p
, tctx
, &q
);
1362 if (!NT_STATUS_IS_OK(status
)) {
1363 torture_warning(tctx
, "QueryAliasInfo level %u failed - %s\n",
1364 levels
[i
], nt_errstr(status
));
1372 static bool test_GetGroupsForUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1373 struct policy_handle
*user_handle
)
1375 struct samr_GetGroupsForUser r
;
1376 struct samr_RidWithAttributeArray
*rids
= NULL
;
1379 torture_comment(tctx
, "testing GetGroupsForUser\n");
1381 r
.in
.user_handle
= user_handle
;
1384 status
= dcerpc_samr_GetGroupsForUser(p
, tctx
, &r
);
1385 torture_assert_ntstatus_ok(tctx
, status
, "GetGroupsForUser");
1391 static bool test_GetDomPwInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1392 struct lsa_String
*domain_name
)
1395 struct samr_GetDomPwInfo r
;
1396 struct samr_PwInfo info
;
1398 r
.in
.domain_name
= domain_name
;
1401 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1403 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &r
);
1404 torture_assert_ntstatus_ok(tctx
, status
, "GetDomPwInfo");
1406 r
.in
.domain_name
->string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1407 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1409 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &r
);
1410 torture_assert_ntstatus_ok(tctx
, status
, "GetDomPwInfo");
1412 r
.in
.domain_name
->string
= "\\\\__NONAME__";
1413 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1415 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &r
);
1416 torture_assert_ntstatus_ok(tctx
, status
, "GetDomPwInfo");
1418 r
.in
.domain_name
->string
= "\\\\Builtin";
1419 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1421 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &r
);
1422 torture_assert_ntstatus_ok(tctx
, status
, "GetDomPwInfo");
1427 static bool test_GetUserPwInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1428 struct policy_handle
*handle
)
1431 struct samr_GetUserPwInfo r
;
1432 struct samr_PwInfo info
;
1434 torture_comment(tctx
, "Testing GetUserPwInfo\n");
1436 r
.in
.user_handle
= handle
;
1439 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &r
);
1440 torture_assert_ntstatus_ok(tctx
, status
, "GetUserPwInfo");
1445 static NTSTATUS
test_LookupName(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1446 struct policy_handle
*domain_handle
, const char *name
,
1450 struct samr_LookupNames n
;
1451 struct lsa_String sname
[2];
1452 struct samr_Ids rids
, types
;
1454 init_lsa_String(&sname
[0], name
);
1456 n
.in
.domain_handle
= domain_handle
;
1460 n
.out
.types
= &types
;
1461 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
1462 if (NT_STATUS_IS_OK(status
)) {
1463 *rid
= n
.out
.rids
->ids
[0];
1468 init_lsa_String(&sname
[1], "xxNONAMExx");
1470 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
1471 if (!NT_STATUS_EQUAL(status
, STATUS_SOME_UNMAPPED
)) {
1472 torture_warning(tctx
, "LookupNames[2] failed - %s\n", nt_errstr(status
));
1473 if (NT_STATUS_IS_OK(status
)) {
1474 return NT_STATUS_UNSUCCESSFUL
;
1480 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
1481 if (!NT_STATUS_IS_OK(status
)) {
1482 torture_warning(tctx
, "LookupNames[0] failed - %s\n", nt_errstr(status
));
1486 init_lsa_String(&sname
[0], "xxNONAMExx");
1488 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
1489 if (!NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
)) {
1490 torture_warning(tctx
, "LookupNames[1 bad name] failed - %s\n", nt_errstr(status
));
1491 if (NT_STATUS_IS_OK(status
)) {
1492 return NT_STATUS_UNSUCCESSFUL
;
1497 init_lsa_String(&sname
[0], "xxNONAMExx");
1498 init_lsa_String(&sname
[1], "xxNONAME2xx");
1500 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
1501 if (!NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
)) {
1502 torture_warning(tctx
, "LookupNames[2 bad names] failed - %s\n", nt_errstr(status
));
1503 if (NT_STATUS_IS_OK(status
)) {
1504 return NT_STATUS_UNSUCCESSFUL
;
1509 return NT_STATUS_OK
;
1512 static NTSTATUS
test_OpenUser_byname(struct dcerpc_pipe
*p
,
1513 struct torture_context
*tctx
,
1514 struct policy_handle
*domain_handle
,
1515 const char *name
, struct policy_handle
*user_handle
)
1518 struct samr_OpenUser r
;
1521 status
= test_LookupName(p
, tctx
, domain_handle
, name
, &rid
);
1522 if (!NT_STATUS_IS_OK(status
)) {
1526 r
.in
.domain_handle
= domain_handle
;
1527 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1529 r
.out
.user_handle
= user_handle
;
1530 status
= dcerpc_samr_OpenUser(p
, tctx
, &r
);
1531 if (!NT_STATUS_IS_OK(status
)) {
1532 torture_warning(tctx
, "OpenUser_byname(%s -> %d) failed - %s\n", name
, rid
, nt_errstr(status
));
1539 static bool test_ChangePasswordNT3(struct dcerpc_pipe
*p
,
1540 struct torture_context
*tctx
,
1541 struct policy_handle
*handle
)
1544 struct samr_ChangePasswordUser r
;
1546 struct samr_Password hash1
, hash2
, hash3
, hash4
, hash5
, hash6
;
1547 struct policy_handle user_handle
;
1548 char *oldpass
= "test";
1549 char *newpass
= "test2";
1550 uint8_t old_nt_hash
[16], new_nt_hash
[16];
1551 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1553 status
= test_OpenUser_byname(p
, tctx
, handle
, "testuser", &user_handle
);
1554 if (!NT_STATUS_IS_OK(status
)) {
1558 torture_comment(tctx
, "Testing ChangePasswordUser for user 'testuser'\n");
1560 torture_comment(tctx
, "old password: %s\n", oldpass
);
1561 torture_comment(tctx
, "new password: %s\n", newpass
);
1563 E_md4hash(oldpass
, old_nt_hash
);
1564 E_md4hash(newpass
, new_nt_hash
);
1565 E_deshash(oldpass
, old_lm_hash
);
1566 E_deshash(newpass
, new_lm_hash
);
1568 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1569 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1570 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1571 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1572 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1573 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1575 r
.in
.handle
= &user_handle
;
1576 r
.in
.lm_present
= 1;
1577 r
.in
.old_lm_crypted
= &hash1
;
1578 r
.in
.new_lm_crypted
= &hash2
;
1579 r
.in
.nt_present
= 1;
1580 r
.in
.old_nt_crypted
= &hash3
;
1581 r
.in
.new_nt_crypted
= &hash4
;
1582 r
.in
.cross1_present
= 1;
1583 r
.in
.nt_cross
= &hash5
;
1584 r
.in
.cross2_present
= 1;
1585 r
.in
.lm_cross
= &hash6
;
1587 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1588 if (!NT_STATUS_IS_OK(status
)) {
1589 torture_warning(tctx
, "ChangePasswordUser failed - %s\n", nt_errstr(status
));
1593 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
1601 static bool test_ChangePasswordUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1602 const char *acct_name
,
1603 struct policy_handle
*handle
, char **password
)
1606 struct samr_ChangePasswordUser r
;
1608 struct samr_Password hash1
, hash2
, hash3
, hash4
, hash5
, hash6
;
1609 struct policy_handle user_handle
;
1611 uint8_t old_nt_hash
[16], new_nt_hash
[16];
1612 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1613 bool changed
= true;
1616 struct samr_GetUserPwInfo pwp
;
1617 struct samr_PwInfo info
;
1618 int policy_min_pw_len
= 0;
1620 status
= test_OpenUser_byname(p
, tctx
, handle
, acct_name
, &user_handle
);
1621 if (!NT_STATUS_IS_OK(status
)) {
1624 pwp
.in
.user_handle
= &user_handle
;
1625 pwp
.out
.info
= &info
;
1627 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
1628 if (NT_STATUS_IS_OK(status
)) {
1629 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1631 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1633 torture_comment(tctx
, "Testing ChangePasswordUser\n");
1635 torture_assert(tctx
, *password
!= NULL
,
1636 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1638 oldpass
= *password
;
1640 E_md4hash(oldpass
, old_nt_hash
);
1641 E_md4hash(newpass
, new_nt_hash
);
1642 E_deshash(oldpass
, old_lm_hash
);
1643 E_deshash(newpass
, new_lm_hash
);
1645 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1646 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1647 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1648 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1649 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1650 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1652 r
.in
.user_handle
= &user_handle
;
1653 r
.in
.lm_present
= 1;
1654 /* Break the LM hash */
1656 r
.in
.old_lm_crypted
= &hash1
;
1657 r
.in
.new_lm_crypted
= &hash2
;
1658 r
.in
.nt_present
= 1;
1659 r
.in
.old_nt_crypted
= &hash3
;
1660 r
.in
.new_nt_crypted
= &hash4
;
1661 r
.in
.cross1_present
= 1;
1662 r
.in
.nt_cross
= &hash5
;
1663 r
.in
.cross2_present
= 1;
1664 r
.in
.lm_cross
= &hash6
;
1666 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1667 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_WRONG_PASSWORD
,
1668 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1670 /* Unbreak the LM hash */
1673 r
.in
.user_handle
= &user_handle
;
1674 r
.in
.lm_present
= 1;
1675 r
.in
.old_lm_crypted
= &hash1
;
1676 r
.in
.new_lm_crypted
= &hash2
;
1677 /* Break the NT hash */
1679 r
.in
.nt_present
= 1;
1680 r
.in
.old_nt_crypted
= &hash3
;
1681 r
.in
.new_nt_crypted
= &hash4
;
1682 r
.in
.cross1_present
= 1;
1683 r
.in
.nt_cross
= &hash5
;
1684 r
.in
.cross2_present
= 1;
1685 r
.in
.lm_cross
= &hash6
;
1687 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1688 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_WRONG_PASSWORD
,
1689 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1691 /* Unbreak the NT hash */
1694 r
.in
.user_handle
= &user_handle
;
1695 r
.in
.lm_present
= 1;
1696 r
.in
.old_lm_crypted
= &hash1
;
1697 r
.in
.new_lm_crypted
= &hash2
;
1698 r
.in
.nt_present
= 1;
1699 r
.in
.old_nt_crypted
= &hash3
;
1700 r
.in
.new_nt_crypted
= &hash4
;
1701 r
.in
.cross1_present
= 1;
1702 r
.in
.nt_cross
= &hash5
;
1703 r
.in
.cross2_present
= 1;
1704 /* Break the LM cross */
1706 r
.in
.lm_cross
= &hash6
;
1708 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1709 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1710 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status
));
1714 /* Unbreak the LM cross */
1717 r
.in
.user_handle
= &user_handle
;
1718 r
.in
.lm_present
= 1;
1719 r
.in
.old_lm_crypted
= &hash1
;
1720 r
.in
.new_lm_crypted
= &hash2
;
1721 r
.in
.nt_present
= 1;
1722 r
.in
.old_nt_crypted
= &hash3
;
1723 r
.in
.new_nt_crypted
= &hash4
;
1724 r
.in
.cross1_present
= 1;
1725 /* Break the NT cross */
1727 r
.in
.nt_cross
= &hash5
;
1728 r
.in
.cross2_present
= 1;
1729 r
.in
.lm_cross
= &hash6
;
1731 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1732 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1733 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status
));
1737 /* Unbreak the NT cross */
1741 /* Reset the hashes to not broken values */
1742 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1743 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1744 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1745 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1746 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1747 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1749 r
.in
.user_handle
= &user_handle
;
1750 r
.in
.lm_present
= 1;
1751 r
.in
.old_lm_crypted
= &hash1
;
1752 r
.in
.new_lm_crypted
= &hash2
;
1753 r
.in
.nt_present
= 1;
1754 r
.in
.old_nt_crypted
= &hash3
;
1755 r
.in
.new_nt_crypted
= &hash4
;
1756 r
.in
.cross1_present
= 1;
1757 r
.in
.nt_cross
= &hash5
;
1758 r
.in
.cross2_present
= 0;
1759 r
.in
.lm_cross
= NULL
;
1761 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1762 if (NT_STATUS_IS_OK(status
)) {
1764 *password
= newpass
;
1765 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION
, status
)) {
1766 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status
));
1771 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1773 E_md4hash(oldpass
, old_nt_hash
);
1774 E_md4hash(newpass
, new_nt_hash
);
1775 E_deshash(oldpass
, old_lm_hash
);
1776 E_deshash(newpass
, new_lm_hash
);
1779 /* Reset the hashes to not broken values */
1780 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1781 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1782 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1783 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1784 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1785 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1787 r
.in
.user_handle
= &user_handle
;
1788 r
.in
.lm_present
= 1;
1789 r
.in
.old_lm_crypted
= &hash1
;
1790 r
.in
.new_lm_crypted
= &hash2
;
1791 r
.in
.nt_present
= 1;
1792 r
.in
.old_nt_crypted
= &hash3
;
1793 r
.in
.new_nt_crypted
= &hash4
;
1794 r
.in
.cross1_present
= 0;
1795 r
.in
.nt_cross
= NULL
;
1796 r
.in
.cross2_present
= 1;
1797 r
.in
.lm_cross
= &hash6
;
1799 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1800 if (NT_STATUS_IS_OK(status
)) {
1802 *password
= newpass
;
1803 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION
, status
)) {
1804 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status
));
1809 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1811 E_md4hash(oldpass
, old_nt_hash
);
1812 E_md4hash(newpass
, new_nt_hash
);
1813 E_deshash(oldpass
, old_lm_hash
);
1814 E_deshash(newpass
, new_lm_hash
);
1817 /* Reset the hashes to not broken values */
1818 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1819 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1820 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1821 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1822 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1823 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1825 r
.in
.user_handle
= &user_handle
;
1826 r
.in
.lm_present
= 1;
1827 r
.in
.old_lm_crypted
= &hash1
;
1828 r
.in
.new_lm_crypted
= &hash2
;
1829 r
.in
.nt_present
= 1;
1830 r
.in
.old_nt_crypted
= &hash3
;
1831 r
.in
.new_nt_crypted
= &hash4
;
1832 r
.in
.cross1_present
= 1;
1833 r
.in
.nt_cross
= &hash5
;
1834 r
.in
.cross2_present
= 1;
1835 r
.in
.lm_cross
= &hash6
;
1837 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1838 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1839 torture_comment(tctx
, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status
));
1840 } else if (!NT_STATUS_IS_OK(status
)) {
1841 torture_warning(tctx
, "ChangePasswordUser failed - %s\n", nt_errstr(status
));
1845 *password
= newpass
;
1848 r
.in
.user_handle
= &user_handle
;
1849 r
.in
.lm_present
= 1;
1850 r
.in
.old_lm_crypted
= &hash1
;
1851 r
.in
.new_lm_crypted
= &hash2
;
1852 r
.in
.nt_present
= 1;
1853 r
.in
.old_nt_crypted
= &hash3
;
1854 r
.in
.new_nt_crypted
= &hash4
;
1855 r
.in
.cross1_present
= 1;
1856 r
.in
.nt_cross
= &hash5
;
1857 r
.in
.cross2_present
= 1;
1858 r
.in
.lm_cross
= &hash6
;
1861 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1862 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1863 torture_comment(tctx
, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status
));
1864 } else if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1865 torture_warning(tctx
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status
));
1871 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
1879 static bool test_OemChangePasswordUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1880 const char *acct_name
,
1881 struct policy_handle
*handle
, char **password
)
1884 struct samr_OemChangePasswordUser2 r
;
1886 struct samr_Password lm_verifier
;
1887 struct samr_CryptPassword lm_pass
;
1888 struct lsa_AsciiString server
, account
, account_bad
;
1891 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1893 struct samr_GetDomPwInfo dom_pw_info
;
1894 struct samr_PwInfo info
;
1895 int policy_min_pw_len
= 0;
1897 struct lsa_String domain_name
;
1899 domain_name
.string
= "";
1900 dom_pw_info
.in
.domain_name
= &domain_name
;
1901 dom_pw_info
.out
.info
= &info
;
1903 torture_comment(tctx
, "Testing OemChangePasswordUser2\n");
1905 torture_assert(tctx
, *password
!= NULL
,
1906 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1908 oldpass
= *password
;
1910 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &dom_pw_info
);
1911 if (NT_STATUS_IS_OK(status
)) {
1912 policy_min_pw_len
= dom_pw_info
.out
.info
->min_password_length
;
1915 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1917 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1918 account
.string
= acct_name
;
1920 E_deshash(oldpass
, old_lm_hash
);
1921 E_deshash(newpass
, new_lm_hash
);
1923 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
1924 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
1925 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
1927 r
.in
.server
= &server
;
1928 r
.in
.account
= &account
;
1929 r
.in
.password
= &lm_pass
;
1930 r
.in
.hash
= &lm_verifier
;
1932 /* Break the verification */
1933 lm_verifier
.hash
[0]++;
1935 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
1937 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)
1938 && !NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1939 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1944 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
1945 /* Break the old password */
1947 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
1948 /* unbreak it for the next operation */
1950 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
1952 r
.in
.server
= &server
;
1953 r
.in
.account
= &account
;
1954 r
.in
.password
= &lm_pass
;
1955 r
.in
.hash
= &lm_verifier
;
1957 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
1959 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)
1960 && !NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1961 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1966 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
1967 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
1969 r
.in
.server
= &server
;
1970 r
.in
.account
= &account
;
1971 r
.in
.password
= &lm_pass
;
1974 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
1976 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)
1977 && !NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
1978 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1983 /* This shouldn't be a valid name */
1984 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
1985 r
.in
.account
= &account_bad
;
1987 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
1989 if (!NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
1990 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1995 /* This shouldn't be a valid name */
1996 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
1997 r
.in
.account
= &account_bad
;
1998 r
.in
.password
= &lm_pass
;
1999 r
.in
.hash
= &lm_verifier
;
2001 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
2003 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
2004 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2009 /* This shouldn't be a valid name */
2010 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
2011 r
.in
.account
= &account_bad
;
2012 r
.in
.password
= NULL
;
2013 r
.in
.hash
= &lm_verifier
;
2015 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
2017 if (!NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
2018 torture_warning(tctx
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2023 E_deshash(oldpass
, old_lm_hash
);
2024 E_deshash(newpass
, new_lm_hash
);
2026 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
2027 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2028 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
2030 r
.in
.server
= &server
;
2031 r
.in
.account
= &account
;
2032 r
.in
.password
= &lm_pass
;
2033 r
.in
.hash
= &lm_verifier
;
2035 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
2036 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2037 torture_comment(tctx
, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status
));
2038 } else if (!NT_STATUS_IS_OK(status
)) {
2039 torture_warning(tctx
, "OemChangePasswordUser2 failed - %s\n", nt_errstr(status
));
2042 *password
= newpass
;
2049 static bool test_ChangePasswordUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2050 const char *acct_name
,
2052 char *newpass
, bool allow_password_restriction
)
2055 struct samr_ChangePasswordUser2 r
;
2057 struct lsa_String server
, account
;
2058 struct samr_CryptPassword nt_pass
, lm_pass
;
2059 struct samr_Password nt_verifier
, lm_verifier
;
2061 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2062 uint8_t old_lm_hash
[16], new_lm_hash
[16];
2064 struct samr_GetDomPwInfo dom_pw_info
;
2065 struct samr_PwInfo info
;
2067 struct lsa_String domain_name
;
2069 domain_name
.string
= "";
2070 dom_pw_info
.in
.domain_name
= &domain_name
;
2071 dom_pw_info
.out
.info
= &info
;
2073 torture_comment(tctx
, "Testing ChangePasswordUser2 on %s\n", acct_name
);
2075 torture_assert(tctx
, *password
!= NULL
,
2076 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2077 oldpass
= *password
;
2080 int policy_min_pw_len
= 0;
2081 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &dom_pw_info
);
2082 if (NT_STATUS_IS_OK(status
)) {
2083 policy_min_pw_len
= dom_pw_info
.out
.info
->min_password_length
;
2086 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2089 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2090 init_lsa_String(&account
, acct_name
);
2092 E_md4hash(oldpass
, old_nt_hash
);
2093 E_md4hash(newpass
, new_nt_hash
);
2095 E_deshash(oldpass
, old_lm_hash
);
2096 E_deshash(newpass
, new_lm_hash
);
2098 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
|STR_TERMINATE
);
2099 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
2100 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2102 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2103 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2104 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2106 r
.in
.server
= &server
;
2107 r
.in
.account
= &account
;
2108 r
.in
.nt_password
= &nt_pass
;
2109 r
.in
.nt_verifier
= &nt_verifier
;
2111 r
.in
.lm_password
= &lm_pass
;
2112 r
.in
.lm_verifier
= &lm_verifier
;
2114 status
= dcerpc_samr_ChangePasswordUser2(p
, tctx
, &r
);
2115 if (allow_password_restriction
&& NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2116 torture_comment(tctx
, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status
));
2117 } else if (!NT_STATUS_IS_OK(status
)) {
2118 torture_warning(tctx
, "ChangePasswordUser2 failed - %s\n", nt_errstr(status
));
2121 *password
= newpass
;
2128 bool test_ChangePasswordUser3(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2129 const char *account_string
,
2130 int policy_min_pw_len
,
2132 const char *newpass
,
2133 NTTIME last_password_change
,
2134 bool handle_reject_reason
)
2137 struct samr_ChangePasswordUser3 r
;
2139 struct lsa_String server
, account
, account_bad
;
2140 struct samr_CryptPassword nt_pass
, lm_pass
;
2141 struct samr_Password nt_verifier
, lm_verifier
;
2143 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2144 uint8_t old_lm_hash
[16], new_lm_hash
[16];
2146 struct samr_DomInfo1
*dominfo
= NULL
;
2147 struct userPwdChangeFailureInformation
*reject
= NULL
;
2149 torture_comment(tctx
, "Testing ChangePasswordUser3\n");
2151 if (newpass
== NULL
) {
2153 if (policy_min_pw_len
== 0) {
2154 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2156 newpass
= samr_rand_pass_fixed_len(tctx
, policy_min_pw_len
);
2158 } while (check_password_quality(newpass
) == false);
2160 torture_comment(tctx
, "Using password '%s'\n", newpass
);
2163 torture_assert(tctx
, *password
!= NULL
,
2164 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2166 oldpass
= *password
;
2167 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2168 init_lsa_String(&account
, account_string
);
2170 E_md4hash(oldpass
, old_nt_hash
);
2171 E_md4hash(newpass
, new_nt_hash
);
2173 E_deshash(oldpass
, old_lm_hash
);
2174 E_deshash(newpass
, new_lm_hash
);
2176 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2177 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2178 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2180 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2181 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2182 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2184 /* Break the verification */
2185 nt_verifier
.hash
[0]++;
2187 r
.in
.server
= &server
;
2188 r
.in
.account
= &account
;
2189 r
.in
.nt_password
= &nt_pass
;
2190 r
.in
.nt_verifier
= &nt_verifier
;
2192 r
.in
.lm_password
= &lm_pass
;
2193 r
.in
.lm_verifier
= &lm_verifier
;
2194 r
.in
.password3
= NULL
;
2195 r
.out
.dominfo
= &dominfo
;
2196 r
.out
.reject
= &reject
;
2198 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
2199 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
) &&
2200 (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
))) {
2201 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2206 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2207 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2208 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2210 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2211 /* Break the NT hash */
2213 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2214 /* Unbreak it again */
2216 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2218 r
.in
.server
= &server
;
2219 r
.in
.account
= &account
;
2220 r
.in
.nt_password
= &nt_pass
;
2221 r
.in
.nt_verifier
= &nt_verifier
;
2223 r
.in
.lm_password
= &lm_pass
;
2224 r
.in
.lm_verifier
= &lm_verifier
;
2225 r
.in
.password3
= NULL
;
2226 r
.out
.dominfo
= &dominfo
;
2227 r
.out
.reject
= &reject
;
2229 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
2230 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
) &&
2231 (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
))) {
2232 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2237 /* This shouldn't be a valid name */
2238 init_lsa_String(&account_bad
, talloc_asprintf(tctx
, "%sXX", account_string
));
2240 r
.in
.account
= &account_bad
;
2241 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
2242 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
2243 torture_warning(tctx
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2248 E_md4hash(oldpass
, old_nt_hash
);
2249 E_md4hash(newpass
, new_nt_hash
);
2251 E_deshash(oldpass
, old_lm_hash
);
2252 E_deshash(newpass
, new_lm_hash
);
2254 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
2255 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
2256 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2258 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2259 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2260 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2262 r
.in
.server
= &server
;
2263 r
.in
.account
= &account
;
2264 r
.in
.nt_password
= &nt_pass
;
2265 r
.in
.nt_verifier
= &nt_verifier
;
2267 r
.in
.lm_password
= &lm_pass
;
2268 r
.in
.lm_verifier
= &lm_verifier
;
2269 r
.in
.password3
= NULL
;
2270 r
.out
.dominfo
= &dominfo
;
2271 r
.out
.reject
= &reject
;
2273 unix_to_nt_time(&t
, time(NULL
));
2275 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
2277 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)
2280 && handle_reject_reason
2281 && (!null_nttime(last_password_change
) || !dominfo
->min_password_age
)) {
2282 if (dominfo
->password_properties
& DOMAIN_REFUSE_PASSWORD_CHANGE
) {
2284 if (reject
&& (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
)) {
2285 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2286 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2291 /* We tested the order of precendence which is as follows:
2300 if ((dominfo
->min_password_age
> 0) && !null_nttime(last_password_change
) &&
2301 (last_password_change
+ dominfo
->min_password_age
> t
)) {
2303 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2304 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2305 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2309 } else if ((dominfo
->min_password_length
> 0) &&
2310 (strlen(newpass
) < dominfo
->min_password_length
)) {
2312 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
) {
2313 torture_warning(tctx
, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2314 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
, reject
->extendedFailureReason
);
2318 } else if ((dominfo
->password_history_length
> 0) &&
2319 strequal(oldpass
, newpass
)) {
2321 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_PWD_IN_HISTORY
) {
2322 torture_warning(tctx
, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2323 SAM_PWD_CHANGE_PWD_IN_HISTORY
, reject
->extendedFailureReason
);
2326 } else if (dominfo
->password_properties
& DOMAIN_PASSWORD_COMPLEX
) {
2328 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NOT_COMPLEX
) {
2329 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2330 SAM_PWD_CHANGE_NOT_COMPLEX
, reject
->extendedFailureReason
);
2336 if (reject
->extendedFailureReason
== SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
) {
2337 /* retry with adjusted size */
2338 return test_ChangePasswordUser3(p
, tctx
, account_string
,
2339 dominfo
->min_password_length
,
2340 password
, NULL
, 0, false);
2344 } else if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2345 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2346 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2347 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2350 /* Perhaps the server has a 'min password age' set? */
2353 torture_assert_ntstatus_ok(tctx
, status
, "ChangePasswordUser3");
2354 *password
= talloc_strdup(tctx
, newpass
);
2360 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2361 const char *account_string
,
2362 struct policy_handle
*handle
,
2366 struct samr_ChangePasswordUser3 r
;
2367 struct samr_SetUserInfo s
;
2368 union samr_UserInfo u
;
2369 DATA_BLOB session_key
;
2370 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
2371 uint8_t confounder
[16];
2372 struct MD5Context ctx
;
2375 struct lsa_String server
, account
;
2376 struct samr_CryptPassword nt_pass
;
2377 struct samr_Password nt_verifier
;
2378 DATA_BLOB new_random_pass
;
2381 uint8_t old_nt_hash
[16], new_nt_hash
[16];
2383 struct samr_DomInfo1
*dominfo
= NULL
;
2384 struct userPwdChangeFailureInformation
*reject
= NULL
;
2386 new_random_pass
= samr_very_rand_pass(tctx
, 128);
2388 torture_assert(tctx
, *password
!= NULL
,
2389 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2391 oldpass
= *password
;
2392 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2393 init_lsa_String(&account
, account_string
);
2395 s
.in
.user_handle
= handle
;
2401 u
.info25
.info
.fields_present
= SAMR_FIELD_NT_PASSWORD_PRESENT
;
2403 set_pw_in_buffer(u
.info25
.password
.data
, &new_random_pass
);
2405 status
= dcerpc_fetch_session_key(p
, &session_key
);
2406 if (!NT_STATUS_IS_OK(status
)) {
2407 torture_warning(tctx
, "SetUserInfo level %u - no session key - %s\n",
2408 s
.in
.level
, nt_errstr(status
));
2412 generate_random_buffer((uint8_t *)confounder
, 16);
2415 MD5Update(&ctx
, confounder
, 16);
2416 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
2417 MD5Final(confounded_session_key
.data
, &ctx
);
2419 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
2420 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
2422 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2424 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
2425 if (!NT_STATUS_IS_OK(status
)) {
2426 torture_warning(tctx
, "SetUserInfo level %u failed - %s\n",
2427 s
.in
.level
, nt_errstr(status
));
2431 torture_comment(tctx
, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2433 mdfour(old_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2435 new_random_pass
= samr_very_rand_pass(tctx
, 128);
2437 mdfour(new_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2439 set_pw_in_buffer(nt_pass
.data
, &new_random_pass
);
2440 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2441 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2443 r
.in
.server
= &server
;
2444 r
.in
.account
= &account
;
2445 r
.in
.nt_password
= &nt_pass
;
2446 r
.in
.nt_verifier
= &nt_verifier
;
2448 r
.in
.lm_password
= NULL
;
2449 r
.in
.lm_verifier
= NULL
;
2450 r
.in
.password3
= NULL
;
2451 r
.out
.dominfo
= &dominfo
;
2452 r
.out
.reject
= &reject
;
2454 unix_to_nt_time(&t
, time(NULL
));
2456 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
2458 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2459 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2460 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2461 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2464 /* Perhaps the server has a 'min password age' set? */
2466 } else if (!NT_STATUS_IS_OK(status
)) {
2467 torture_warning(tctx
, "ChangePasswordUser3 failed - %s\n", nt_errstr(status
));
2471 newpass
= samr_rand_pass(tctx
, 128);
2473 mdfour(old_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
2475 E_md4hash(newpass
, new_nt_hash
);
2477 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
2478 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
2479 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2481 r
.in
.server
= &server
;
2482 r
.in
.account
= &account
;
2483 r
.in
.nt_password
= &nt_pass
;
2484 r
.in
.nt_verifier
= &nt_verifier
;
2486 r
.in
.lm_password
= NULL
;
2487 r
.in
.lm_verifier
= NULL
;
2488 r
.in
.password3
= NULL
;
2489 r
.out
.dominfo
= &dominfo
;
2490 r
.out
.reject
= &reject
;
2492 unix_to_nt_time(&t
, time(NULL
));
2494 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
2496 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2497 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2498 torture_warning(tctx
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2499 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2502 /* Perhaps the server has a 'min password age' set? */
2505 torture_assert_ntstatus_ok(tctx
, status
, "ChangePasswordUser3 (on second random password)");
2506 *password
= talloc_strdup(tctx
, newpass
);
2513 static bool test_GetMembersInAlias(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2514 struct policy_handle
*alias_handle
)
2516 struct samr_GetMembersInAlias r
;
2517 struct lsa_SidArray sids
;
2520 torture_comment(tctx
, "Testing GetMembersInAlias\n");
2522 r
.in
.alias_handle
= alias_handle
;
2525 status
= dcerpc_samr_GetMembersInAlias(p
, tctx
, &r
);
2526 torture_assert_ntstatus_ok(tctx
, status
, "GetMembersInAlias");
2531 static bool test_AddMemberToAlias(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2532 struct policy_handle
*alias_handle
,
2533 const struct dom_sid
*domain_sid
)
2535 struct samr_AddAliasMember r
;
2536 struct samr_DeleteAliasMember d
;
2538 struct dom_sid
*sid
;
2540 sid
= dom_sid_add_rid(tctx
, domain_sid
, 512);
2542 torture_comment(tctx
, "testing AddAliasMember\n");
2543 r
.in
.alias_handle
= alias_handle
;
2546 status
= dcerpc_samr_AddAliasMember(p
, tctx
, &r
);
2547 torture_assert_ntstatus_ok(tctx
, status
, "AddAliasMember");
2549 d
.in
.alias_handle
= alias_handle
;
2552 status
= dcerpc_samr_DeleteAliasMember(p
, tctx
, &d
);
2553 torture_assert_ntstatus_ok(tctx
, status
, "DelAliasMember");
2558 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2559 struct policy_handle
*alias_handle
)
2561 struct samr_AddMultipleMembersToAlias a
;
2562 struct samr_RemoveMultipleMembersFromAlias r
;
2564 struct lsa_SidArray sids
;
2566 torture_comment(tctx
, "testing AddMultipleMembersToAlias\n");
2567 a
.in
.alias_handle
= alias_handle
;
2571 sids
.sids
= talloc_array(tctx
, struct lsa_SidPtr
, 3);
2573 sids
.sids
[0].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-1");
2574 sids
.sids
[1].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-2");
2575 sids
.sids
[2].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-3");
2577 status
= dcerpc_samr_AddMultipleMembersToAlias(p
, tctx
, &a
);
2578 torture_assert_ntstatus_ok(tctx
, status
, "AddMultipleMembersToAlias");
2581 torture_comment(tctx
, "testing RemoveMultipleMembersFromAlias\n");
2582 r
.in
.alias_handle
= alias_handle
;
2585 status
= dcerpc_samr_RemoveMultipleMembersFromAlias(p
, tctx
, &r
);
2586 torture_assert_ntstatus_ok(tctx
, status
, "RemoveMultipleMembersFromAlias");
2588 /* strange! removing twice doesn't give any error */
2589 status
= dcerpc_samr_RemoveMultipleMembersFromAlias(p
, tctx
, &r
);
2590 torture_assert_ntstatus_ok(tctx
, status
, "RemoveMultipleMembersFromAlias");
2592 /* but removing an alias that isn't there does */
2593 sids
.sids
[2].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-4");
2595 status
= dcerpc_samr_RemoveMultipleMembersFromAlias(p
, tctx
, &r
);
2596 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
, "RemoveMultipleMembersFromAlias");
2601 static bool test_GetAliasMembership(struct dcerpc_pipe
*p
,
2602 struct torture_context
*tctx
,
2603 struct policy_handle
*domain_handle
)
2605 struct samr_GetAliasMembership r
;
2606 struct lsa_SidArray sids
;
2607 struct samr_Ids rids
;
2610 torture_comment(tctx
, "Testing GetAliasMembership\n");
2612 if (torture_setting_bool(tctx
, "samba4", false)) {
2613 torture_skip(tctx
, "skipping GetAliasMembership against s4");
2616 r
.in
.domain_handle
= domain_handle
;
2621 sids
.sids
= talloc_zero_array(tctx
, struct lsa_SidPtr
, sids
.num_sids
);
2623 status
= dcerpc_samr_GetAliasMembership(p
, tctx
, &r
);
2624 torture_assert_ntstatus_ok(tctx
, status
,
2625 "samr_GetAliasMembership failed");
2627 torture_assert_int_equal(tctx
, sids
.num_sids
, rids
.count
,
2628 "protocol misbehaviour");
2631 sids
.sids
= talloc_zero_array(tctx
, struct lsa_SidPtr
, sids
.num_sids
);
2632 sids
.sids
[0].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-1");
2634 status
= dcerpc_samr_GetAliasMembership(p
, tctx
, &r
);
2635 torture_assert_ntstatus_ok(tctx
, status
,
2636 "samr_GetAliasMembership failed");
2639 /* only true for w2k8 it seems
2640 * win7, xp, w2k3 will return a 0 length array pointer */
2642 if (rids
.ids
&& (rids
.count
== 0)) {
2643 torture_fail(tctx
, "samr_GetAliasMembership returned 0 count and a rids array");
2646 if (!rids
.ids
&& rids
.count
) {
2647 torture_fail(tctx
, "samr_GetAliasMembership returned non-0 count but no rids");
2653 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2654 struct policy_handle
*user_handle
)
2656 struct samr_TestPrivateFunctionsUser r
;
2659 torture_comment(tctx
, "Testing TestPrivateFunctionsUser\n");
2661 r
.in
.user_handle
= user_handle
;
2663 status
= dcerpc_samr_TestPrivateFunctionsUser(p
, tctx
, &r
);
2664 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_NOT_IMPLEMENTED
, "TestPrivateFunctionsUser");
2669 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe
*p
,
2670 struct torture_context
*tctx
,
2671 struct policy_handle
*handle
,
2676 uint16_t levels
[] = { /* 3, */ 5, 21 };
2678 NTTIME pwdlastset3
= 0;
2679 NTTIME pwdlastset5
= 0;
2680 NTTIME pwdlastset21
= 0;
2682 torture_comment(tctx
, "Testing QueryUserInfo%s level 5 and 21 call ",
2683 use_info2
? "2":"");
2685 for (i
=0; i
<ARRAY_SIZE(levels
); i
++) {
2687 struct samr_QueryUserInfo r
;
2688 struct samr_QueryUserInfo2 r2
;
2689 union samr_UserInfo
*info
;
2692 r2
.in
.user_handle
= handle
;
2693 r2
.in
.level
= levels
[i
];
2694 r2
.out
.info
= &info
;
2695 status
= dcerpc_samr_QueryUserInfo2(p
, tctx
, &r2
);
2698 r
.in
.user_handle
= handle
;
2699 r
.in
.level
= levels
[i
];
2701 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &r
);
2704 if (!NT_STATUS_IS_OK(status
) &&
2705 !NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_INFO_CLASS
)) {
2706 torture_warning(tctx
, "QueryUserInfo%s level %u failed - %s\n",
2707 use_info2
? "2":"", levels
[i
], nt_errstr(status
));
2711 switch (levels
[i
]) {
2713 pwdlastset3
= info
->info3
.last_password_change
;
2716 pwdlastset5
= info
->info5
.last_password_change
;
2719 pwdlastset21
= info
->info21
.last_password_change
;
2725 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2726 "pwdlastset mixup"); */
2727 torture_assert_int_equal(tctx
, pwdlastset5
, pwdlastset21
,
2728 "pwdlastset mixup");
2730 *pwdlastset
= pwdlastset21
;
2732 torture_comment(tctx
, "(pwdlastset: %lld)\n", *pwdlastset
);
2737 static bool test_SamLogon(struct torture_context
*tctx
,
2738 struct dcerpc_pipe
*p
,
2739 struct cli_credentials
*test_credentials
,
2740 NTSTATUS expected_result
,
2744 struct netr_LogonSamLogonEx r
;
2745 union netr_LogonLevel logon
;
2746 union netr_Validation validation
;
2747 uint8_t authoritative
;
2748 struct netr_IdentityInfo identity
;
2749 struct netr_NetworkInfo ninfo
;
2750 struct netr_PasswordInfo pinfo
;
2751 DATA_BLOB names_blob
, chal
, lm_resp
, nt_resp
;
2752 int flags
= CLI_CRED_NTLM_AUTH
;
2753 uint32_t samlogon_flags
= 0;
2754 struct netlogon_creds_CredentialState
*creds
;
2755 struct netr_Authenticator a
;
2757 torture_assert_ntstatus_ok(tctx
, dcerpc_schannel_creds(p
->conn
->security_state
.generic_state
, tctx
, &creds
), "");
2759 if (lp_client_lanman_auth(tctx
->lp_ctx
)) {
2760 flags
|= CLI_CRED_LANMAN_AUTH
;
2763 if (lp_client_ntlmv2_auth(tctx
->lp_ctx
)) {
2764 flags
|= CLI_CRED_NTLMv2_AUTH
;
2767 cli_credentials_get_ntlm_username_domain(test_credentials
, tctx
,
2768 &identity
.account_name
.string
,
2769 &identity
.domain_name
.string
);
2771 identity
.parameter_control
=
2772 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT
|
2773 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT
;
2774 identity
.logon_id_low
= 0;
2775 identity
.logon_id_high
= 0;
2776 identity
.workstation
.string
= cli_credentials_get_workstation(test_credentials
);
2779 netlogon_creds_client_authenticator(creds
, &a
);
2781 if (!E_deshash(cli_credentials_get_password(test_credentials
), pinfo
.lmpassword
.hash
)) {
2782 ZERO_STRUCT(pinfo
.lmpassword
.hash
);
2784 E_md4hash(cli_credentials_get_password(test_credentials
), pinfo
.ntpassword
.hash
);
2786 if (creds
->negotiate_flags
& NETLOGON_NEG_ARCFOUR
) {
2787 netlogon_creds_arcfour_crypt(creds
, pinfo
.lmpassword
.hash
, 16);
2788 netlogon_creds_arcfour_crypt(creds
, pinfo
.ntpassword
.hash
, 16);
2790 netlogon_creds_des_encrypt(creds
, &pinfo
.lmpassword
);
2791 netlogon_creds_des_encrypt(creds
, &pinfo
.ntpassword
);
2794 pinfo
.identity_info
= identity
;
2795 logon
.password
= &pinfo
;
2797 r
.in
.logon_level
= NetlogonInteractiveInformation
;
2799 generate_random_buffer(ninfo
.challenge
,
2800 sizeof(ninfo
.challenge
));
2801 chal
= data_blob_const(ninfo
.challenge
,
2802 sizeof(ninfo
.challenge
));
2804 names_blob
= NTLMv2_generate_names_blob(tctx
, cli_credentials_get_workstation(test_credentials
),
2805 cli_credentials_get_domain(test_credentials
));
2807 status
= cli_credentials_get_ntlm_response(test_credentials
, tctx
,
2813 torture_assert_ntstatus_ok(tctx
, status
, "cli_credentials_get_ntlm_response failed");
2815 ninfo
.lm
.data
= lm_resp
.data
;
2816 ninfo
.lm
.length
= lm_resp
.length
;
2818 ninfo
.nt
.data
= nt_resp
.data
;
2819 ninfo
.nt
.length
= nt_resp
.length
;
2821 ninfo
.identity_info
= identity
;
2822 logon
.network
= &ninfo
;
2824 r
.in
.logon_level
= NetlogonNetworkInformation
;
2827 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2828 r
.in
.computer_name
= cli_credentials_get_workstation(test_credentials
);
2829 r
.in
.logon
= &logon
;
2830 r
.in
.flags
= &samlogon_flags
;
2831 r
.out
.flags
= &samlogon_flags
;
2832 r
.out
.validation
= &validation
;
2833 r
.out
.authoritative
= &authoritative
;
2835 torture_comment(tctx
, "Testing LogonSamLogon with name %s\n", identity
.account_name
.string
);
2837 r
.in
.validation_level
= 6;
2839 status
= dcerpc_netr_LogonSamLogonEx(p
, tctx
, &r
);
2840 if (NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_INFO_CLASS
)) {
2841 r
.in
.validation_level
= 3;
2842 status
= dcerpc_netr_LogonSamLogonEx(p
, tctx
, &r
);
2844 if (!NT_STATUS_IS_OK(status
)) {
2845 torture_assert_ntstatus_equal(tctx
, status
, expected_result
, "LogonSamLogonEx failed");
2848 torture_assert_ntstatus_ok(tctx
, status
, "LogonSamLogonEx failed");
2854 static bool test_SamLogon_with_creds(struct torture_context
*tctx
,
2855 struct dcerpc_pipe
*p
,
2856 struct cli_credentials
*machine_creds
,
2857 const char *acct_name
,
2859 NTSTATUS expected_samlogon_result
,
2863 struct cli_credentials
*test_credentials
;
2865 test_credentials
= cli_credentials_init(tctx
);
2867 cli_credentials_set_workstation(test_credentials
,
2868 cli_credentials_get_workstation(machine_creds
), CRED_SPECIFIED
);
2869 cli_credentials_set_domain(test_credentials
,
2870 cli_credentials_get_domain(machine_creds
), CRED_SPECIFIED
);
2871 cli_credentials_set_username(test_credentials
,
2872 acct_name
, CRED_SPECIFIED
);
2873 cli_credentials_set_password(test_credentials
,
2874 password
, CRED_SPECIFIED
);
2876 torture_comment(tctx
, "testing samlogon (%s) as %s password: %s\n",
2877 interactive
? "interactive" : "network", acct_name
, password
);
2879 if (!test_SamLogon(tctx
, p
, test_credentials
,
2880 expected_samlogon_result
, interactive
)) {
2881 torture_warning(tctx
, "new password did not work\n");
2888 static bool test_SetPassword_level(struct dcerpc_pipe
*p
,
2889 struct dcerpc_pipe
*np
,
2890 struct torture_context
*tctx
,
2891 struct policy_handle
*handle
,
2893 uint32_t fields_present
,
2894 uint8_t password_expired
,
2895 bool *matched_expected_error
,
2897 const char *acct_name
,
2899 struct cli_credentials
*machine_creds
,
2900 bool use_queryinfo2
,
2902 NTSTATUS expected_samlogon_result
)
2904 const char *fields
= NULL
;
2911 fields
= talloc_asprintf(tctx
, "(fields_present: 0x%08x)",
2918 torture_comment(tctx
, "Testing SetUserInfo%s level %d call "
2919 "(password_expired: %d) %s\n",
2920 use_setinfo2
? "2":"", level
, password_expired
,
2921 fields
? fields
: "");
2923 if (!test_SetUserPass_level_ex(p
, tctx
, handle
, level
,
2928 matched_expected_error
)) {
2932 if (!test_QueryUserInfo_pwdlastset(p
, tctx
, handle
,
2938 if (*matched_expected_error
== true) {
2942 if (!test_SamLogon_with_creds(tctx
, np
,
2946 expected_samlogon_result
,
2954 static bool setup_schannel_netlogon_pipe(struct torture_context
*tctx
,
2955 struct cli_credentials
*credentials
,
2956 struct dcerpc_pipe
**p
)
2958 struct dcerpc_binding
*b
;
2960 torture_assert_ntstatus_ok(tctx
, torture_rpc_binding(tctx
, &b
),
2961 "failed to get rpc binding");
2963 /* We have to use schannel, otherwise the SamLogonEx fails
2964 * with INTERNAL_ERROR */
2966 b
->flags
&= ~DCERPC_AUTH_OPTIONS
;
2967 b
->flags
|= DCERPC_SCHANNEL
| DCERPC_SIGN
| DCERPC_SCHANNEL_128
;
2969 torture_assert_ntstatus_ok(tctx
,
2970 dcerpc_pipe_connect_b(tctx
, p
, b
, &ndr_table_netlogon
,
2971 credentials
, tctx
->ev
, tctx
->lp_ctx
),
2972 "failed to bind to netlogon");
2977 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe
*p
,
2978 struct torture_context
*tctx
,
2979 uint32_t acct_flags
,
2980 const char *acct_name
,
2981 struct policy_handle
*handle
,
2983 struct cli_credentials
*machine_credentials
)
2985 int s
= 0, q
= 0, f
= 0, l
= 0, z
= 0;
2988 bool set_levels
[] = { false, true };
2989 bool query_levels
[] = { false, true };
2990 uint32_t levels
[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
2991 uint32_t nonzeros
[] = { 1, 24 };
2992 uint32_t fields_present
[] = {
2994 SAMR_FIELD_EXPIRED_FLAG
,
2995 SAMR_FIELD_LAST_PWD_CHANGE
,
2996 SAMR_FIELD_EXPIRED_FLAG
| SAMR_FIELD_LAST_PWD_CHANGE
,
2998 SAMR_FIELD_NT_PASSWORD_PRESENT
,
2999 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
,
3000 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
,
3001 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
,
3002 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_EXPIRED_FLAG
,
3003 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_EXPIRED_FLAG
,
3004 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
| SAMR_FIELD_EXPIRED_FLAG
3006 struct dcerpc_pipe
*np
= NULL
;
3008 if (torture_setting_bool(tctx
, "samba3", false)) {
3010 torture_comment(tctx
, "Samba3 has second granularity, setting delay to: %d\n",
3014 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
3016 /* set to 1 to enable testing for all possible opcode
3017 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3020 #define TEST_ALL_LEVELS 1
3021 #define TEST_SET_LEVELS 1
3022 #define TEST_QUERY_LEVELS 1
3024 #ifdef TEST_ALL_LEVELS
3025 for (l
=0; l
<ARRAY_SIZE(levels
); l
++) {
3027 for (l
=0; l
<(ARRAY_SIZE(levels
))/2; l
++) {
3029 for (z
=0; z
<ARRAY_SIZE(nonzeros
); z
++) {
3030 for (f
=0; f
<ARRAY_SIZE(fields_present
); f
++) {
3031 #ifdef TEST_SET_LEVELS
3032 for (s
=0; s
<ARRAY_SIZE(set_levels
); s
++) {
3034 #ifdef TEST_QUERY_LEVELS
3035 for (q
=0; q
<ARRAY_SIZE(query_levels
); q
++) {
3037 NTTIME pwdlastset_old
= 0;
3038 NTTIME pwdlastset_new
= 0;
3039 bool matched_expected_error
= false;
3040 NTSTATUS expected_samlogon_result
= NT_STATUS_ACCOUNT_DISABLED
;
3042 torture_comment(tctx
, "------------------------------\n"
3043 "Testing pwdLastSet attribute for flags: 0x%08x "
3044 "(s: %d (l: %d), q: %d)\n",
3045 acct_flags
, s
, levels
[l
], q
);
3047 switch (levels
[l
]) {
3051 if (!((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3052 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
))) {
3053 expected_samlogon_result
= NT_STATUS_WRONG_PASSWORD
;
3061 /* set a password and force password change (pwdlastset 0) by
3062 * setting the password expired flag to a non-0 value */
3064 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3068 &matched_expected_error
,
3072 machine_credentials
,
3075 expected_samlogon_result
)) {
3079 if (matched_expected_error
== true) {
3080 /* skipping on expected failure */
3084 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3085 * set without the SAMR_FIELD_EXPIRED_FLAG */
3087 switch (levels
[l
]) {
3091 if ((pwdlastset_new
!= 0) &&
3092 !(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
)) {
3093 torture_comment(tctx
, "not considering a non-0 "
3094 "pwdLastSet as a an error as the "
3095 "SAMR_FIELD_EXPIRED_FLAG has not "
3100 if (pwdlastset_new
!= 0) {
3101 torture_warning(tctx
, "pwdLastSet test failed: "
3102 "expected pwdLastSet 0 but got %lld\n",
3109 switch (levels
[l
]) {
3113 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3114 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3115 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3116 (pwdlastset_old
>= pwdlastset_new
)) {
3117 torture_warning(tctx
, "pwdlastset not increasing\n");
3122 if ((pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3123 (pwdlastset_old
>= pwdlastset_new
)) {
3124 torture_warning(tctx
, "pwdlastset not increasing\n");
3134 /* set a password, pwdlastset needs to get updated (increased
3135 * value), password_expired value used here is 0 */
3137 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3141 &matched_expected_error
,
3145 machine_credentials
,
3148 expected_samlogon_result
)) {
3152 /* when a password has been changed, pwdlastset must not be 0 afterwards
3153 * and must be larger then the old value */
3155 switch (levels
[l
]) {
3160 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3161 * password has been changed, old and new pwdlastset
3162 * need to be the same value */
3164 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
3165 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3166 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3168 torture_assert_int_equal(tctx
, pwdlastset_old
,
3169 pwdlastset_new
, "pwdlastset must be equal");
3173 if (pwdlastset_old
>= pwdlastset_new
) {
3174 torture_warning(tctx
, "pwdLastSet test failed: "
3175 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3176 pwdlastset_old
, pwdlastset_new
);
3179 if (pwdlastset_new
== 0) {
3180 torture_warning(tctx
, "pwdLastSet test failed: "
3181 "expected non-0 pwdlastset, got: %lld\n",
3187 switch (levels
[l
]) {
3191 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3192 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3193 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3194 (pwdlastset_old
>= pwdlastset_new
)) {
3195 torture_warning(tctx
, "pwdlastset not increasing\n");
3200 if ((pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3201 (pwdlastset_old
>= pwdlastset_new
)) {
3202 torture_warning(tctx
, "pwdlastset not increasing\n");
3208 pwdlastset_old
= pwdlastset_new
;
3214 /* set a password, pwdlastset needs to get updated (increased
3215 * value), password_expired value used here is 0 */
3217 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3221 &matched_expected_error
,
3225 machine_credentials
,
3228 expected_samlogon_result
)) {
3232 /* when a password has been changed, pwdlastset must not be 0 afterwards
3233 * and must be larger then the old value */
3235 switch (levels
[l
]) {
3240 /* if no password has been changed, old and new pwdlastset
3241 * need to be the same value */
3243 if (!((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3244 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3246 torture_assert_int_equal(tctx
, pwdlastset_old
,
3247 pwdlastset_new
, "pwdlastset must be equal");
3251 if (pwdlastset_old
>= pwdlastset_new
) {
3252 torture_warning(tctx
, "pwdLastSet test failed: "
3253 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3254 pwdlastset_old
, pwdlastset_new
);
3257 if (pwdlastset_new
== 0) {
3258 torture_warning(tctx
, "pwdLastSet test failed: "
3259 "expected non-0 pwdlastset, got: %lld\n",
3267 /* set a password and force password change (pwdlastset 0) by
3268 * setting the password expired flag to a non-0 value */
3270 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3274 &matched_expected_error
,
3278 machine_credentials
,
3281 expected_samlogon_result
)) {
3285 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3286 * set without the SAMR_FIELD_EXPIRED_FLAG */
3288 switch (levels
[l
]) {
3292 if ((pwdlastset_new
!= 0) &&
3293 !(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
)) {
3294 torture_comment(tctx
, "not considering a non-0 "
3295 "pwdLastSet as a an error as the "
3296 "SAMR_FIELD_EXPIRED_FLAG has not "
3301 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3302 * password has been changed, old and new pwdlastset
3303 * need to be the same value */
3305 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
3306 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3307 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
3309 torture_assert_int_equal(tctx
, pwdlastset_old
,
3310 pwdlastset_new
, "pwdlastset must be equal");
3315 if (pwdlastset_old
== pwdlastset_new
) {
3316 torture_warning(tctx
, "pwdLastSet test failed: "
3317 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3318 pwdlastset_old
, pwdlastset_new
);
3322 if (pwdlastset_new
!= 0) {
3323 torture_warning(tctx
, "pwdLastSet test failed: "
3324 "expected pwdLastSet 0, got %lld\n",
3331 switch (levels
[l
]) {
3335 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3336 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3337 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3338 (pwdlastset_old
>= pwdlastset_new
)) {
3339 torture_warning(tctx
, "pwdlastset not increasing\n");
3344 if ((pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3345 (pwdlastset_old
>= pwdlastset_new
)) {
3346 torture_warning(tctx
, "pwdlastset not increasing\n");
3352 /* if the level we are testing does not have a fields_present
3353 * field, skip all fields present tests by setting f to to
3355 switch (levels
[l
]) {
3359 f
= ARRAY_SIZE(fields_present
);
3363 #ifdef TEST_QUERY_LEVELS
3366 #ifdef TEST_SET_LEVELS
3369 } /* fields present */
3373 #undef TEST_SET_LEVELS
3374 #undef TEST_QUERY_LEVELS
3381 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_pipe
*p
,
3382 struct torture_context
*tctx
,
3383 struct policy_handle
*handle
,
3384 uint32_t *badpwdcount
)
3386 union samr_UserInfo
*info
;
3387 struct samr_QueryUserInfo r
;
3389 r
.in
.user_handle
= handle
;
3393 torture_comment(tctx
, "Testing QueryUserInfo level %d", r
.in
.level
);
3395 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo(p
, tctx
, &r
),
3396 "failed to query userinfo");
3398 *badpwdcount
= info
->info3
.bad_password_count
;
3400 torture_comment(tctx
, " (bad password count: %d)\n", *badpwdcount
);
3405 static bool test_SetUserInfo_acct_flags(struct dcerpc_pipe
*p
,
3406 struct torture_context
*tctx
,
3407 struct policy_handle
*user_handle
,
3408 uint32_t acct_flags
)
3410 struct samr_SetUserInfo r
;
3411 union samr_UserInfo user_info
;
3413 torture_comment(tctx
, "Testing SetUserInfo level 16\n");
3415 user_info
.info16
.acct_flags
= acct_flags
;
3417 r
.in
.user_handle
= user_handle
;
3419 r
.in
.info
= &user_info
;
3421 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo(p
, tctx
, &r
),
3422 "failed to set account flags");
3427 static bool test_reset_badpwdcount(struct dcerpc_pipe
*p
,
3428 struct torture_context
*tctx
,
3429 struct policy_handle
*user_handle
,
3430 uint32_t acct_flags
,
3433 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
3434 "failed to set password");
3436 torture_comment(tctx
, "Testing SetUserInfo level 16 (enable account)\n");
3438 torture_assert(tctx
,
3439 test_SetUserInfo_acct_flags(p
, tctx
, user_handle
,
3440 acct_flags
& ~ACB_DISABLED
),
3441 "failed to enable user");
3443 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
3444 "failed to set password");
3449 static bool test_SetDomainInfo(struct dcerpc_pipe
*p
,
3450 struct torture_context
*tctx
,
3451 struct policy_handle
*domain_handle
,
3452 enum samr_DomainInfoClass level
,
3453 union samr_DomainInfo
*info
)
3455 struct samr_SetDomainInfo r
;
3457 r
.in
.domain_handle
= domain_handle
;
3461 torture_assert_ntstatus_ok(tctx
,
3462 dcerpc_samr_SetDomainInfo(p
, tctx
, &r
),
3463 "failed to set domain info");
3468 static bool test_SetDomainInfo_ntstatus(struct dcerpc_pipe
*p
,
3469 struct torture_context
*tctx
,
3470 struct policy_handle
*domain_handle
,
3471 enum samr_DomainInfoClass level
,
3472 union samr_DomainInfo
*info
,
3475 struct samr_SetDomainInfo r
;
3477 r
.in
.domain_handle
= domain_handle
;
3481 torture_assert_ntstatus_equal(tctx
,
3482 dcerpc_samr_SetDomainInfo(p
, tctx
, &r
),
3489 static bool test_QueryDomainInfo2_level(struct dcerpc_pipe
*p
,
3490 struct torture_context
*tctx
,
3491 struct policy_handle
*domain_handle
,
3492 enum samr_DomainInfoClass level
,
3493 union samr_DomainInfo
**q_info
)
3495 struct samr_QueryDomainInfo2 r
;
3497 r
.in
.domain_handle
= domain_handle
;
3499 r
.out
.info
= q_info
;
3501 torture_assert_ntstatus_ok(tctx
,
3502 dcerpc_samr_QueryDomainInfo2(p
, tctx
, &r
),
3503 "failed to query domain info");
3508 static bool test_Password_badpwdcount(struct dcerpc_pipe
*p
,
3509 struct dcerpc_pipe
*np
,
3510 struct torture_context
*tctx
,
3511 uint32_t acct_flags
,
3512 const char *acct_name
,
3513 struct policy_handle
*domain_handle
,
3514 struct policy_handle
*user_handle
,
3516 struct cli_credentials
*machine_credentials
,
3517 const char *comment
,
3520 NTSTATUS expected_success_status
,
3521 struct samr_DomInfo1
*info1
,
3522 struct samr_DomInfo12
*info12
)
3524 union samr_DomainInfo info
;
3527 uint32_t badpwdcount
, tmp
;
3528 uint32_t password_history_length
= 12;
3529 uint32_t lockout_threshold
= 15;
3531 torture_comment(tctx
, "\nTesting bad pwd count with: %s\n", comment
);
3533 torture_assert(tctx
, password_history_length
< lockout_threshold
,
3534 "password history length needs to be smaller than account lockout threshold for this test");
3539 info
.info1
= *info1
;
3540 info
.info1
.password_history_length
= password_history_length
;
3542 torture_assert(tctx
,
3543 test_SetDomainInfo(p
, tctx
, domain_handle
,
3544 DomainPasswordInformation
, &info
),
3545 "failed to set password history length");
3547 info
.info12
= *info12
;
3548 info
.info12
.lockout_threshold
= lockout_threshold
;
3550 torture_assert(tctx
,
3551 test_SetDomainInfo(p
, tctx
, domain_handle
,
3552 DomainLockoutInformation
, &info
),
3553 "failed to set lockout threshold");
3555 /* reset bad pwd count */
3557 torture_assert(tctx
,
3558 test_reset_badpwdcount(p
, tctx
, user_handle
, acct_flags
, password
), "");
3561 /* enable or disable account */
3563 torture_assert(tctx
,
3564 test_SetUserInfo_acct_flags(p
, tctx
, user_handle
,
3565 acct_flags
| ACB_DISABLED
),
3566 "failed to disable user");
3568 torture_assert(tctx
,
3569 test_SetUserInfo_acct_flags(p
, tctx
, user_handle
,
3570 acct_flags
& ~ACB_DISABLED
),
3571 "failed to enable user");
3575 /* setup password history */
3577 passwords
= talloc_array(tctx
, char *, password_history_length
);
3579 for (i
=0; i
< password_history_length
; i
++) {
3581 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
3582 "failed to set password");
3583 passwords
[i
] = talloc_strdup(tctx
, *password
);
3585 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3586 acct_name
, passwords
[i
],
3587 expected_success_status
, interactive
)) {
3588 torture_fail(tctx
, "failed to auth with latest password");
3591 torture_assert(tctx
,
3592 test_QueryUserInfo_badpwdcount(p
, tctx
, user_handle
, &badpwdcount
), "");
3594 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3598 /* test with wrong password */
3600 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3601 acct_name
, "random_crap",
3602 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
3603 torture_fail(tctx
, "succeeded to authenticate with wrong password");
3606 torture_assert(tctx
,
3607 test_QueryUserInfo_badpwdcount(p
, tctx
, user_handle
, &badpwdcount
), "");
3609 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
3612 /* test with latest good password */
3614 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
3615 passwords
[password_history_length
-1],
3616 expected_success_status
, interactive
)) {
3617 torture_fail(tctx
, "succeeded to authenticate with wrong password");
3620 torture_assert(tctx
,
3621 test_QueryUserInfo_badpwdcount(p
, tctx
, user_handle
, &badpwdcount
), "");
3624 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
3626 /* only enabled accounts get the bad pwd count reset upon
3627 * successful logon */
3628 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3634 /* test password history */
3636 for (i
=0; i
< password_history_length
; i
++) {
3638 torture_comment(tctx
, "Testing bad password count behavior with "
3639 "password #%d of #%d\n", i
, password_history_length
);
3641 /* - network samlogon will succeed auth and not
3642 * increase badpwdcount for 2 last entries
3643 * - interactive samlogon only for the last one */
3645 if (i
== password_history_length
- 1 ||
3646 (i
== password_history_length
- 2 && !interactive
)) {
3648 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3649 acct_name
, passwords
[i
],
3650 expected_success_status
, interactive
)) {
3651 torture_fail(tctx
, talloc_asprintf(tctx
, "succeeded to authenticate with old password (#%d of #%d in history)", i
, password_history_length
));
3654 torture_assert(tctx
,
3655 test_QueryUserInfo_badpwdcount(p
, tctx
, user_handle
, &badpwdcount
), "");
3658 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
3659 torture_assert_int_equal(tctx
, badpwdcount
, tmp
, "unexpected badpwdcount");
3661 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
3662 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3670 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3671 acct_name
, passwords
[i
],
3672 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
3673 torture_fail(tctx
, talloc_asprintf(tctx
, "succeeded to authenticate with old password (#%d of #%d in history)", i
, password_history_length
));
3676 torture_assert(tctx
,
3677 test_QueryUserInfo_badpwdcount(p
, tctx
, user_handle
, &badpwdcount
), "");
3679 /* - network samlogon will fail auth but not increase
3680 * badpwdcount for 3rd last entry
3681 * - interactive samlogon for 3rd and 2nd last entry */
3683 if (i
== password_history_length
- 3 ||
3684 (i
== password_history_length
- 2 && interactive
)) {
3685 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
3686 torture_assert_int_equal(tctx
, badpwdcount
, tmp
, "unexpected badpwdcount");
3688 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
3689 torture_assert_int_equal(tctx
, badpwdcount
, tmp
+ 1, "unexpected badpwdcount");
3698 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe
*p
,
3699 struct torture_context
*tctx
,
3700 uint32_t acct_flags
,
3701 const char *acct_name
,
3702 struct policy_handle
*domain_handle
,
3703 struct policy_handle
*user_handle
,
3705 struct cli_credentials
*machine_credentials
)
3707 union samr_DomainInfo
*q_info
, s_info
;
3708 struct samr_DomInfo1 info1
, _info1
;
3709 struct samr_DomInfo12 info12
, _info12
;
3711 struct dcerpc_pipe
*np
;
3715 const char *comment
;
3718 NTSTATUS expected_success_status
;
3721 .comment
= "network logon (disabled account)",
3723 .interactive
= false,
3724 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
3727 .comment
= "network logon (enabled account)",
3729 .interactive
= false,
3730 .expected_success_status
= NT_STATUS_OK
3733 .comment
= "interactive logon (disabled account)",
3735 .interactive
= true,
3736 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
3739 .comment
= "interactive logon (enabled account)",
3741 .interactive
= true,
3742 .expected_success_status
= NT_STATUS_OK
3746 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
3748 /* backup old policies */
3750 torture_assert(tctx
,
3751 test_QueryDomainInfo2_level(p
, tctx
, domain_handle
,
3752 DomainPasswordInformation
, &q_info
),
3753 "failed to query domain info level 1");
3755 info1
= q_info
->info1
;
3758 torture_assert(tctx
,
3759 test_QueryDomainInfo2_level(p
, tctx
, domain_handle
,
3760 DomainLockoutInformation
, &q_info
),
3761 "failed to query domain info level 12");
3763 info12
= q_info
->info12
;
3768 for (i
=0; i
< ARRAY_SIZE(creds
); i
++) {
3770 /* skip trust tests for now */
3771 if (acct_flags
& ACB_WSTRUST
||
3772 acct_flags
& ACB_SVRTRUST
||
3773 acct_flags
& ACB_DOMTRUST
) {
3777 ret
&= test_Password_badpwdcount(p
, np
, tctx
, acct_flags
, acct_name
,
3778 domain_handle
, user_handle
, password
,
3779 machine_credentials
,
3782 creds
[i
].interactive
,
3783 creds
[i
].expected_success_status
,
3786 torture_warning(tctx
, "TEST #%d (%s) failed\n", i
, creds
[i
].comment
);
3788 torture_comment(tctx
, "TEST #%d (%s) succeeded\n", i
, creds
[i
].comment
);
3792 /* restore policies */
3794 s_info
.info1
= info1
;
3796 torture_assert(tctx
,
3797 test_SetDomainInfo(p
, tctx
, domain_handle
,
3798 DomainPasswordInformation
, &s_info
),
3799 "failed to set password information");
3801 s_info
.info12
= info12
;
3803 torture_assert(tctx
,
3804 test_SetDomainInfo(p
, tctx
, domain_handle
,
3805 DomainLockoutInformation
, &s_info
),
3806 "failed to set lockout information");
3811 static bool test_QueryUserInfo_acct_flags(struct dcerpc_pipe
*p
,
3812 struct torture_context
*tctx
,
3813 struct policy_handle
*handle
,
3814 uint32_t *acct_flags
)
3816 union samr_UserInfo
*info
;
3817 struct samr_QueryUserInfo r
;
3819 r
.in
.user_handle
= handle
;
3823 torture_comment(tctx
, "Testing QueryUserInfo level %d", r
.in
.level
);
3825 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo(p
, tctx
, &r
),
3826 "failed to query userinfo");
3828 *acct_flags
= info
->info16
.acct_flags
;
3830 torture_comment(tctx
, " (acct_flags: 0x%08x)\n", *acct_flags
);
3835 static bool test_Password_lockout(struct dcerpc_pipe
*p
,
3836 struct dcerpc_pipe
*np
,
3837 struct torture_context
*tctx
,
3838 uint32_t acct_flags
,
3839 const char *acct_name
,
3840 struct policy_handle
*domain_handle
,
3841 struct policy_handle
*user_handle
,
3843 struct cli_credentials
*machine_credentials
,
3844 const char *comment
,
3847 NTSTATUS expected_success_status
,
3848 struct samr_DomInfo1
*info1
,
3849 struct samr_DomInfo12
*info12
)
3851 union samr_DomainInfo info
;
3852 uint32_t badpwdcount
;
3853 uint32_t password_history_length
= 1;
3854 uint64_t lockout_threshold
= 1;
3855 uint32_t lockout_seconds
= 5;
3856 uint64_t delta_time_factor
= 10 * 1000 * 1000;
3858 torture_comment(tctx
, "\nTesting account lockout: %s\n", comment
);
3862 info
.info1
= *info1
;
3864 torture_comment(tctx
, "setting password history lenght.\n");
3865 info
.info1
.password_history_length
= password_history_length
;
3867 torture_assert(tctx
,
3868 test_SetDomainInfo(p
, tctx
, domain_handle
,
3869 DomainPasswordInformation
, &info
),
3870 "failed to set password history length");
3872 info
.info12
= *info12
;
3873 info
.info12
.lockout_threshold
= lockout_threshold
;
3875 /* set lockout duration < lockout window: should fail */
3876 info
.info12
.lockout_duration
= ~(lockout_seconds
* delta_time_factor
);
3877 info
.info12
.lockout_window
= ~((lockout_seconds
+ 1) * delta_time_factor
);
3879 torture_assert(tctx
,
3880 test_SetDomainInfo_ntstatus(p
, tctx
, domain_handle
,
3881 DomainLockoutInformation
, &info
,
3882 NT_STATUS_INVALID_PARAMETER
),
3883 "setting lockout duration < lockout window gave unexpected result");
3885 info
.info12
.lockout_duration
= 0;
3886 info
.info12
.lockout_window
= 0;
3888 torture_assert(tctx
,
3889 test_SetDomainInfo(p
, tctx
, domain_handle
,
3890 DomainLockoutInformation
, &info
),
3891 "failed to set lockout window and duration to 0");
3894 /* set lockout duration of 5 seconds */
3895 info
.info12
.lockout_duration
= ~(lockout_seconds
* delta_time_factor
);
3896 info
.info12
.lockout_window
= ~(lockout_seconds
* delta_time_factor
);
3898 torture_assert(tctx
,
3899 test_SetDomainInfo(p
, tctx
, domain_handle
,
3900 DomainLockoutInformation
, &info
),
3901 "failed to set lockout window and duration to 5 seconds");
3903 /* reset bad pwd count */
3905 torture_assert(tctx
,
3906 test_reset_badpwdcount(p
, tctx
, user_handle
, acct_flags
, password
), "");
3909 /* enable or disable account */
3912 torture_assert(tctx
,
3913 test_SetUserInfo_acct_flags(p
, tctx
, user_handle
,
3914 acct_flags
| ACB_DISABLED
),
3915 "failed to disable user");
3917 torture_assert(tctx
,
3918 test_SetUserInfo_acct_flags(p
, tctx
, user_handle
,
3919 acct_flags
& ~ACB_DISABLED
),
3920 "failed to enable user");
3924 /* test logon with right password */
3926 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3927 acct_name
, *password
,
3928 expected_success_status
, interactive
)) {
3929 torture_fail(tctx
, "failed to auth with latest password");
3932 torture_assert(tctx
,
3933 test_QueryUserInfo_badpwdcount(p
, tctx
, user_handle
, &badpwdcount
), "");
3934 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
3937 /* test with wrong password ==> lockout */
3939 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3940 acct_name
, "random_crap",
3941 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
3942 torture_fail(tctx
, "succeeded to authenticate with wrong password");
3945 torture_assert(tctx
,
3946 test_QueryUserInfo_badpwdcount(p
, tctx
, user_handle
, &badpwdcount
), "");
3947 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
3949 torture_assert(tctx
,
3950 test_QueryUserInfo_acct_flags(p
, tctx
, user_handle
, &acct_flags
), "");
3951 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
3952 "expected account to be locked");
3955 /* test with good password */
3957 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
3959 NT_STATUS_ACCOUNT_LOCKED_OUT
, interactive
))
3961 torture_fail(tctx
, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
3964 /* bad pwd count should not get updated */
3965 torture_assert(tctx
,
3966 test_QueryUserInfo_badpwdcount(p
, tctx
, user_handle
, &badpwdcount
), "");
3967 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
3969 /* curiously, windows does _not_ set the autlock flag */
3970 torture_assert(tctx
,
3971 test_QueryUserInfo_acct_flags(p
, tctx
, user_handle
, &acct_flags
), "");
3972 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
3973 "expected account to be locked");
3976 /* with bad password */
3978 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
3979 acct_name
, "random_crap2",
3980 NT_STATUS_ACCOUNT_LOCKED_OUT
, interactive
))
3982 torture_fail(tctx
, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
3985 /* bad pwd count should not get updated */
3986 torture_assert(tctx
,
3987 test_QueryUserInfo_badpwdcount(p
, tctx
, user_handle
, &badpwdcount
), "");
3988 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
3990 /* curiously, windows does _not_ set the autlock flag */
3991 torture_assert(tctx
,
3992 test_QueryUserInfo_acct_flags(p
, tctx
, user_handle
, &acct_flags
), "");
3993 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
3994 "expected account to be locked");
3997 /* let lockout duration expire ==> unlock */
3999 torture_comment(tctx
, "let lockout duration expire...\n");
4000 sleep(lockout_seconds
+ 1);
4002 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
4004 expected_success_status
, interactive
))
4006 torture_fail(tctx
, "failed to authenticate after lockout expired");
4009 torture_assert(tctx
,
4010 test_QueryUserInfo_acct_flags(p
, tctx
, user_handle
, &acct_flags
), "");
4011 torture_assert_int_equal(tctx
, acct_flags
& ACB_AUTOLOCK
, 0,
4012 "expected account not to be locked");
4017 static bool test_Password_lockout_wrap(struct dcerpc_pipe
*p
,
4018 struct torture_context
*tctx
,
4019 uint32_t acct_flags
,
4020 const char *acct_name
,
4021 struct policy_handle
*domain_handle
,
4022 struct policy_handle
*user_handle
,
4024 struct cli_credentials
*machine_credentials
)
4026 union samr_DomainInfo
*q_info
, s_info
;
4027 struct samr_DomInfo1 info1
, _info1
;
4028 struct samr_DomInfo12 info12
, _info12
;
4030 struct dcerpc_pipe
*np
;
4034 const char *comment
;
4037 NTSTATUS expected_success_status
;
4040 .comment
= "network logon (disabled account)",
4042 .interactive
= false,
4043 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
4046 .comment
= "network logon (enabled account)",
4048 .interactive
= false,
4049 .expected_success_status
= NT_STATUS_OK
4052 .comment
= "interactive logon (disabled account)",
4054 .interactive
= true,
4055 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
4058 .comment
= "interactive logon (enabled account)",
4060 .interactive
= true,
4061 .expected_success_status
= NT_STATUS_OK
4065 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
4067 /* backup old policies */
4069 torture_assert(tctx
,
4070 test_QueryDomainInfo2_level(p
, tctx
, domain_handle
,
4071 DomainPasswordInformation
, &q_info
),
4072 "failed to query domain info level 1");
4074 info1
= q_info
->info1
;
4077 torture_assert(tctx
,
4078 test_QueryDomainInfo2_level(p
, tctx
, domain_handle
,
4079 DomainLockoutInformation
, &q_info
),
4080 "failed to query domain info level 12");
4082 info12
= q_info
->info12
;
4087 for (i
=0; i
< ARRAY_SIZE(creds
); i
++) {
4089 /* skip trust tests for now */
4090 if (acct_flags
& ACB_WSTRUST
||
4091 acct_flags
& ACB_SVRTRUST
||
4092 acct_flags
& ACB_DOMTRUST
) {
4096 ret
&= test_Password_lockout(p
, np
, tctx
, acct_flags
, acct_name
,
4097 domain_handle
, user_handle
, password
,
4098 machine_credentials
,
4101 creds
[i
].interactive
,
4102 creds
[i
].expected_success_status
,
4105 torture_warning(tctx
, "TEST #%d (%s) failed\n", i
, creds
[i
].comment
);
4107 torture_comment(tctx
, "TEST #%d (%s) succeeded\n", i
, creds
[i
].comment
);
4111 /* restore policies */
4113 s_info
.info1
= info1
;
4115 torture_assert(tctx
,
4116 test_SetDomainInfo(p
, tctx
, domain_handle
,
4117 DomainPasswordInformation
, &s_info
),
4118 "failed to set password information");
4120 s_info
.info12
= info12
;
4122 torture_assert(tctx
,
4123 test_SetDomainInfo(p
, tctx
, domain_handle
,
4124 DomainLockoutInformation
, &s_info
),
4125 "failed to set lockout information");
4130 static bool test_DeleteUser_with_privs(struct dcerpc_pipe
*p
,
4131 struct dcerpc_pipe
*lp
,
4132 struct torture_context
*tctx
,
4133 struct policy_handle
*domain_handle
,
4134 struct policy_handle
*lsa_handle
,
4135 struct policy_handle
*user_handle
,
4136 const struct dom_sid
*domain_sid
,
4138 struct cli_credentials
*machine_credentials
)
4143 struct policy_handle lsa_acct_handle
;
4144 struct dom_sid
*user_sid
;
4146 user_sid
= dom_sid_add_rid(tctx
, domain_sid
, rid
);
4149 struct lsa_EnumAccountRights r
;
4150 struct lsa_RightSet rights
;
4152 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4154 r
.in
.handle
= lsa_handle
;
4155 r
.in
.sid
= user_sid
;
4156 r
.out
.rights
= &rights
;
4158 status
= dcerpc_lsa_EnumAccountRights(lp
, tctx
, &r
);
4159 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
4160 "Expected enum rights for account to fail");
4164 struct lsa_RightSet rights
;
4165 struct lsa_StringLarge names
[2];
4166 struct lsa_AddAccountRights r
;
4168 torture_comment(tctx
, "Testing LSA AddAccountRights\n");
4170 init_lsa_StringLarge(&names
[0], "SeMachineAccountPrivilege");
4171 init_lsa_StringLarge(&names
[1], NULL
);
4174 rights
.names
= names
;
4176 r
.in
.handle
= lsa_handle
;
4177 r
.in
.sid
= user_sid
;
4178 r
.in
.rights
= &rights
;
4180 status
= dcerpc_lsa_AddAccountRights(lp
, tctx
, &r
);
4181 torture_assert_ntstatus_ok(tctx
, status
,
4182 "Failed to add privileges");
4186 struct lsa_EnumAccounts r
;
4187 uint32_t resume_handle
= 0;
4188 struct lsa_SidArray lsa_sid_array
;
4190 bool found_sid
= false;
4192 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
4194 r
.in
.handle
= lsa_handle
;
4195 r
.in
.num_entries
= 0x1000;
4196 r
.in
.resume_handle
= &resume_handle
;
4197 r
.out
.sids
= &lsa_sid_array
;
4198 r
.out
.resume_handle
= &resume_handle
;
4200 status
= dcerpc_lsa_EnumAccounts(lp
, tctx
, &r
);
4201 torture_assert_ntstatus_ok(tctx
, status
,
4202 "Failed to enum accounts");
4204 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
4205 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
4210 torture_assert(tctx
, found_sid
,
4211 "failed to list privileged account");
4215 struct lsa_EnumAccountRights r
;
4216 struct lsa_RightSet user_rights
;
4218 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4220 r
.in
.handle
= lsa_handle
;
4221 r
.in
.sid
= user_sid
;
4222 r
.out
.rights
= &user_rights
;
4224 status
= dcerpc_lsa_EnumAccountRights(lp
, tctx
, &r
);
4225 torture_assert_ntstatus_ok(tctx
, status
,
4226 "Failed to enum rights for account");
4228 if (user_rights
.count
< 1) {
4229 torture_warning(tctx
, "failed to find newly added rights");
4235 struct lsa_OpenAccount r
;
4237 torture_comment(tctx
, "Testing LSA OpenAccount\n");
4239 r
.in
.handle
= lsa_handle
;
4240 r
.in
.sid
= user_sid
;
4241 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4242 r
.out
.acct_handle
= &lsa_acct_handle
;
4244 status
= dcerpc_lsa_OpenAccount(lp
, tctx
, &r
);
4245 torture_assert_ntstatus_ok(tctx
, status
,
4246 "Failed to open lsa account");
4250 struct lsa_GetSystemAccessAccount r
;
4251 uint32_t access_mask
;
4253 torture_comment(tctx
, "Testing LSA GetSystemAccessAccount\n");
4255 r
.in
.handle
= &lsa_acct_handle
;
4256 r
.out
.access_mask
= &access_mask
;
4258 status
= dcerpc_lsa_GetSystemAccessAccount(lp
, tctx
, &r
);
4259 torture_assert_ntstatus_ok(tctx
, status
,
4260 "Failed to get lsa system access account");
4266 torture_comment(tctx
, "Testing LSA Close\n");
4268 r
.in
.handle
= &lsa_acct_handle
;
4269 r
.out
.handle
= &lsa_acct_handle
;
4271 status
= dcerpc_lsa_Close(lp
, tctx
, &r
);
4272 torture_assert_ntstatus_ok(tctx
, status
,
4273 "Failed to close lsa");
4277 struct samr_DeleteUser r
;
4279 torture_comment(tctx
, "Testing SAMR DeleteUser\n");
4281 r
.in
.user_handle
= user_handle
;
4282 r
.out
.user_handle
= user_handle
;
4284 status
= dcerpc_samr_DeleteUser(p
, tctx
, &r
);
4285 torture_assert_ntstatus_ok(tctx
, status
, "Delete User failed");
4289 struct lsa_EnumAccounts r
;
4290 uint32_t resume_handle
= 0;
4291 struct lsa_SidArray lsa_sid_array
;
4293 bool found_sid
= false;
4295 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
4297 r
.in
.handle
= lsa_handle
;
4298 r
.in
.num_entries
= 0x1000;
4299 r
.in
.resume_handle
= &resume_handle
;
4300 r
.out
.sids
= &lsa_sid_array
;
4301 r
.out
.resume_handle
= &resume_handle
;
4303 status
= dcerpc_lsa_EnumAccounts(lp
, tctx
, &r
);
4304 torture_assert_ntstatus_ok(tctx
, status
,
4305 "Failed to enum accounts");
4307 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
4308 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
4313 torture_assert(tctx
, found_sid
,
4314 "failed to list privileged account");
4318 struct lsa_EnumAccountRights r
;
4319 struct lsa_RightSet user_rights
;
4321 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4323 r
.in
.handle
= lsa_handle
;
4324 r
.in
.sid
= user_sid
;
4325 r
.out
.rights
= &user_rights
;
4327 status
= dcerpc_lsa_EnumAccountRights(lp
, tctx
, &r
);
4328 torture_assert_ntstatus_ok(tctx
, status
,
4329 "Failed to enum rights for account");
4331 if (user_rights
.count
< 1) {
4332 torture_warning(tctx
, "failed to find newly added rights");
4338 struct lsa_OpenAccount r
;
4340 torture_comment(tctx
, "Testing LSA OpenAccount\n");
4342 r
.in
.handle
= lsa_handle
;
4343 r
.in
.sid
= user_sid
;
4344 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4345 r
.out
.acct_handle
= &lsa_acct_handle
;
4347 status
= dcerpc_lsa_OpenAccount(lp
, tctx
, &r
);
4348 torture_assert_ntstatus_ok(tctx
, status
,
4349 "Failed to open lsa account");
4353 struct lsa_GetSystemAccessAccount r
;
4354 uint32_t access_mask
;
4356 torture_comment(tctx
, "Testing LSA GetSystemAccessAccount\n");
4358 r
.in
.handle
= &lsa_acct_handle
;
4359 r
.out
.access_mask
= &access_mask
;
4361 status
= dcerpc_lsa_GetSystemAccessAccount(lp
, tctx
, &r
);
4362 torture_assert_ntstatus_ok(tctx
, status
,
4363 "Failed to get lsa system access account");
4367 struct lsa_DeleteObject r
;
4369 torture_comment(tctx
, "Testing LSA DeleteObject\n");
4371 r
.in
.handle
= &lsa_acct_handle
;
4372 r
.out
.handle
= &lsa_acct_handle
;
4374 status
= dcerpc_lsa_DeleteObject(lp
, tctx
, &r
);
4375 torture_assert_ntstatus_ok(tctx
, status
,
4376 "Failed to delete object");
4380 struct lsa_EnumAccounts r
;
4381 uint32_t resume_handle
= 0;
4382 struct lsa_SidArray lsa_sid_array
;
4384 bool found_sid
= false;
4386 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
4388 r
.in
.handle
= lsa_handle
;
4389 r
.in
.num_entries
= 0x1000;
4390 r
.in
.resume_handle
= &resume_handle
;
4391 r
.out
.sids
= &lsa_sid_array
;
4392 r
.out
.resume_handle
= &resume_handle
;
4394 status
= dcerpc_lsa_EnumAccounts(lp
, tctx
, &r
);
4395 torture_assert_ntstatus_ok(tctx
, status
,
4396 "Failed to enum accounts");
4398 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
4399 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
4404 torture_assert(tctx
, !found_sid
,
4405 "should not have listed privileged account");
4409 struct lsa_EnumAccountRights r
;
4410 struct lsa_RightSet user_rights
;
4412 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
4414 r
.in
.handle
= lsa_handle
;
4415 r
.in
.sid
= user_sid
;
4416 r
.out
.rights
= &user_rights
;
4418 status
= dcerpc_lsa_EnumAccountRights(lp
, tctx
, &r
);
4419 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
4420 "Failed to enum rights for account");
4426 static bool test_user_ops(struct dcerpc_pipe
*p
,
4427 struct torture_context
*tctx
,
4428 struct policy_handle
*user_handle
,
4429 struct policy_handle
*domain_handle
,
4430 const struct dom_sid
*domain_sid
,
4431 uint32_t base_acct_flags
,
4432 const char *base_acct_name
, enum torture_samr_choice which_ops
,
4433 struct cli_credentials
*machine_credentials
)
4435 char *password
= NULL
;
4436 struct samr_QueryUserInfo q
;
4437 union samr_UserInfo
*info
;
4443 const uint32_t password_fields
[] = {
4444 SAMR_FIELD_NT_PASSWORD_PRESENT
,
4445 SAMR_FIELD_LM_PASSWORD_PRESENT
,
4446 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
,
4450 status
= test_LookupName(p
, tctx
, domain_handle
, base_acct_name
, &rid
);
4451 if (!NT_STATUS_IS_OK(status
)) {
4455 switch (which_ops
) {
4456 case TORTURE_SAMR_USER_ATTRIBUTES
:
4457 if (!test_QuerySecurity(p
, tctx
, user_handle
)) {
4461 if (!test_QueryUserInfo(p
, tctx
, user_handle
)) {
4465 if (!test_QueryUserInfo2(p
, tctx
, user_handle
)) {
4469 if (!test_SetUserInfo(p
, tctx
, user_handle
, base_acct_flags
,
4474 if (!test_GetUserPwInfo(p
, tctx
, user_handle
)) {
4478 if (!test_TestPrivateFunctionsUser(p
, tctx
, user_handle
)) {
4482 if (!test_SetUserPass(p
, tctx
, user_handle
, &password
)) {
4486 case TORTURE_SAMR_PASSWORDS
:
4487 if (base_acct_flags
& (ACB_WSTRUST
|ACB_DOMTRUST
|ACB_SVRTRUST
)) {
4488 char simple_pass
[9];
4489 char *v
= generate_random_str(tctx
, 1);
4491 ZERO_STRUCT(simple_pass
);
4492 memset(simple_pass
, *v
, sizeof(simple_pass
) - 1);
4494 torture_comment(tctx
, "Testing machine account password policy rules\n");
4496 /* Workstation trust accounts don't seem to need to honour password quality policy */
4497 if (!test_SetUserPassEx(p
, tctx
, user_handle
, true, &password
)) {
4501 if (!test_ChangePasswordUser2(p
, tctx
, base_acct_name
, &password
, simple_pass
, false)) {
4505 /* reset again, to allow another 'user' password change */
4506 if (!test_SetUserPassEx(p
, tctx
, user_handle
, true, &password
)) {
4510 /* Try a 'short' password */
4511 if (!test_ChangePasswordUser2(p
, tctx
, base_acct_name
, &password
, samr_rand_pass(tctx
, 4), false)) {
4515 /* Try a compleatly random password */
4516 if (!test_ChangePasswordRandomBytes(p
, tctx
, base_acct_name
, user_handle
, &password
)) {
4521 for (i
= 0; password_fields
[i
]; i
++) {
4522 if (!test_SetUserPass_23(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
4526 /* check it was set right */
4527 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4532 for (i
= 0; password_fields
[i
]; i
++) {
4533 if (!test_SetUserPass_25(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
4537 /* check it was set right */
4538 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4543 if (!test_SetUserPassEx(p
, tctx
, user_handle
, false, &password
)) {
4547 if (!test_ChangePassword(p
, tctx
, base_acct_name
, domain_handle
, &password
)) {
4551 if (torture_setting_bool(tctx
, "samba4", false)) {
4552 torture_comment(tctx
, "skipping Set Password level 18 and 21 against Samba4\n");
4555 if (!test_SetUserPass_18(p
, tctx
, user_handle
, &password
)) {
4559 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4563 for (i
= 0; password_fields
[i
]; i
++) {
4565 if (password_fields
[i
] == SAMR_FIELD_LM_PASSWORD_PRESENT
) {
4566 /* we need to skip as that would break
4567 * the ChangePasswordUser3 verify */
4571 if (!test_SetUserPass_21(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
4575 /* check it was set right */
4576 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
4582 q
.in
.user_handle
= user_handle
;
4586 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &q
);
4587 if (!NT_STATUS_IS_OK(status
)) {
4588 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
4589 q
.in
.level
, nt_errstr(status
));
4592 uint32_t expected_flags
= (base_acct_flags
| ACB_PWNOTREQ
| ACB_DISABLED
);
4593 if ((info
->info5
.acct_flags
) != expected_flags
) {
4594 torture_warning(tctx
, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4595 info
->info5
.acct_flags
,
4598 if (!torture_setting_bool(tctx
, "samba3", false)) {
4602 if (info
->info5
.rid
!= rid
) {
4603 torture_warning(tctx
, "QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
4604 info
->info5
.rid
, rid
);
4611 case TORTURE_SAMR_PASSWORDS_PWDLASTSET
:
4613 /* test last password change timestamp behaviour */
4614 if (!test_SetPassword_pwdlastset(p
, tctx
, base_acct_flags
,
4616 user_handle
, &password
,
4617 machine_credentials
)) {
4622 torture_comment(tctx
, "pwdLastSet test succeeded\n");
4624 torture_warning(tctx
, "pwdLastSet test failed\n");
4629 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
:
4631 /* test bad pwd count change behaviour */
4632 if (!test_Password_badpwdcount_wrap(p
, tctx
, base_acct_flags
,
4635 user_handle
, &password
,
4636 machine_credentials
)) {
4641 torture_comment(tctx
, "badPwdCount test succeeded\n");
4643 torture_warning(tctx
, "badPwdCount test failed\n");
4648 case TORTURE_SAMR_PASSWORDS_LOCKOUT
:
4650 if (!test_Password_lockout_wrap(p
, tctx
, base_acct_flags
,
4653 user_handle
, &password
,
4654 machine_credentials
))
4660 torture_comment(tctx
, "lockout test succeeded\n");
4662 torture_warning(tctx
, "lockout test failed\n");
4668 case TORTURE_SAMR_USER_PRIVILEGES
: {
4670 struct dcerpc_pipe
*lp
;
4671 struct policy_handle
*lsa_handle
;
4673 status
= torture_rpc_connection(tctx
, &lp
, &ndr_table_lsarpc
);
4674 torture_assert_ntstatus_ok(tctx
, status
, "Failed to open LSA pipe");
4676 if (!test_lsa_OpenPolicy2(lp
, tctx
, &lsa_handle
)) {
4680 if (!test_DeleteUser_with_privs(p
, lp
, tctx
,
4681 domain_handle
, lsa_handle
, user_handle
,
4683 machine_credentials
)) {
4687 if (!test_lsa_Close(lp
, tctx
, lsa_handle
)) {
4692 torture_warning(tctx
, "privileged user delete test failed\n");
4697 case TORTURE_SAMR_OTHER
:
4698 /* We just need the account to exist */
4704 static bool test_alias_ops(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4705 struct policy_handle
*alias_handle
,
4706 const struct dom_sid
*domain_sid
)
4710 if (!torture_setting_bool(tctx
, "samba3", false)) {
4711 if (!test_QuerySecurity(p
, tctx
, alias_handle
)) {
4716 if (!test_QueryAliasInfo(p
, tctx
, alias_handle
)) {
4720 if (!test_SetAliasInfo(p
, tctx
, alias_handle
)) {
4724 if (!test_AddMemberToAlias(p
, tctx
, alias_handle
, domain_sid
)) {
4728 if (torture_setting_bool(tctx
, "samba3", false) ||
4729 torture_setting_bool(tctx
, "samba4", false)) {
4730 torture_comment(tctx
, "skipping MultipleMembers Alias tests against Samba\n");
4734 if (!test_AddMultipleMembersToAlias(p
, tctx
, alias_handle
)) {
4742 static bool test_DeleteUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4743 struct policy_handle
*user_handle
)
4745 struct samr_DeleteUser d
;
4747 torture_comment(tctx
, "Testing DeleteUser\n");
4749 d
.in
.user_handle
= user_handle
;
4750 d
.out
.user_handle
= user_handle
;
4752 status
= dcerpc_samr_DeleteUser(p
, tctx
, &d
);
4753 torture_assert_ntstatus_ok(tctx
, status
, "DeleteUser");
4758 bool test_DeleteUser_byname(struct dcerpc_pipe
*p
,
4759 struct torture_context
*tctx
,
4760 struct policy_handle
*handle
, const char *name
)
4763 struct samr_DeleteUser d
;
4764 struct policy_handle user_handle
;
4767 status
= test_LookupName(p
, tctx
, handle
, name
, &rid
);
4768 if (!NT_STATUS_IS_OK(status
)) {
4772 status
= test_OpenUser_byname(p
, tctx
, handle
, name
, &user_handle
);
4773 if (!NT_STATUS_IS_OK(status
)) {
4777 d
.in
.user_handle
= &user_handle
;
4778 d
.out
.user_handle
= &user_handle
;
4779 status
= dcerpc_samr_DeleteUser(p
, tctx
, &d
);
4780 if (!NT_STATUS_IS_OK(status
)) {
4787 torture_warning(tctx
, "DeleteUser_byname(%s) failed - %s\n", name
, nt_errstr(status
));
4792 static bool test_DeleteGroup_byname(struct dcerpc_pipe
*p
,
4793 struct torture_context
*tctx
,
4794 struct policy_handle
*handle
, const char *name
)
4797 struct samr_OpenGroup r
;
4798 struct samr_DeleteDomainGroup d
;
4799 struct policy_handle group_handle
;
4802 status
= test_LookupName(p
, tctx
, handle
, name
, &rid
);
4803 if (!NT_STATUS_IS_OK(status
)) {
4807 r
.in
.domain_handle
= handle
;
4808 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4810 r
.out
.group_handle
= &group_handle
;
4811 status
= dcerpc_samr_OpenGroup(p
, tctx
, &r
);
4812 if (!NT_STATUS_IS_OK(status
)) {
4816 d
.in
.group_handle
= &group_handle
;
4817 d
.out
.group_handle
= &group_handle
;
4818 status
= dcerpc_samr_DeleteDomainGroup(p
, tctx
, &d
);
4819 if (!NT_STATUS_IS_OK(status
)) {
4826 torture_warning(tctx
, "DeleteGroup_byname(%s) failed - %s\n", name
, nt_errstr(status
));
4831 static bool test_DeleteAlias_byname(struct dcerpc_pipe
*p
,
4832 struct torture_context
*tctx
,
4833 struct policy_handle
*domain_handle
,
4837 struct samr_OpenAlias r
;
4838 struct samr_DeleteDomAlias d
;
4839 struct policy_handle alias_handle
;
4842 torture_comment(tctx
, "testing DeleteAlias_byname\n");
4844 status
= test_LookupName(p
, tctx
, domain_handle
, name
, &rid
);
4845 if (!NT_STATUS_IS_OK(status
)) {
4849 r
.in
.domain_handle
= domain_handle
;
4850 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4852 r
.out
.alias_handle
= &alias_handle
;
4853 status
= dcerpc_samr_OpenAlias(p
, tctx
, &r
);
4854 if (!NT_STATUS_IS_OK(status
)) {
4858 d
.in
.alias_handle
= &alias_handle
;
4859 d
.out
.alias_handle
= &alias_handle
;
4860 status
= dcerpc_samr_DeleteDomAlias(p
, tctx
, &d
);
4861 if (!NT_STATUS_IS_OK(status
)) {
4868 torture_warning(tctx
, "DeleteAlias_byname(%s) failed - %s\n", name
, nt_errstr(status
));
4872 static bool test_DeleteAlias(struct dcerpc_pipe
*p
,
4873 struct torture_context
*tctx
,
4874 struct policy_handle
*alias_handle
)
4876 struct samr_DeleteDomAlias d
;
4880 torture_comment(tctx
, "Testing DeleteAlias\n");
4882 d
.in
.alias_handle
= alias_handle
;
4883 d
.out
.alias_handle
= alias_handle
;
4885 status
= dcerpc_samr_DeleteDomAlias(p
, tctx
, &d
);
4886 if (!NT_STATUS_IS_OK(status
)) {
4887 torture_warning(tctx
, "DeleteAlias failed - %s\n", nt_errstr(status
));
4894 static bool test_CreateAlias(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4895 struct policy_handle
*domain_handle
,
4896 const char *alias_name
,
4897 struct policy_handle
*alias_handle
,
4898 const struct dom_sid
*domain_sid
,
4902 struct samr_CreateDomAlias r
;
4903 struct lsa_String name
;
4907 init_lsa_String(&name
, alias_name
);
4908 r
.in
.domain_handle
= domain_handle
;
4909 r
.in
.alias_name
= &name
;
4910 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4911 r
.out
.alias_handle
= alias_handle
;
4914 torture_comment(tctx
, "Testing CreateAlias (%s)\n", r
.in
.alias_name
->string
);
4916 status
= dcerpc_samr_CreateDomAlias(p
, tctx
, &r
);
4918 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
4919 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
4920 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.alias_name
->string
);
4923 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.alias_name
->string
,
4929 if (NT_STATUS_EQUAL(status
, NT_STATUS_ALIAS_EXISTS
)) {
4930 if (!test_DeleteAlias_byname(p
, tctx
, domain_handle
, r
.in
.alias_name
->string
)) {
4933 status
= dcerpc_samr_CreateDomAlias(p
, tctx
, &r
);
4936 if (!NT_STATUS_IS_OK(status
)) {
4937 torture_warning(tctx
, "CreateAlias failed - %s\n", nt_errstr(status
));
4945 if (!test_alias_ops(p
, tctx
, alias_handle
, domain_sid
)) {
4952 static bool test_ChangePassword(struct dcerpc_pipe
*p
,
4953 struct torture_context
*tctx
,
4954 const char *acct_name
,
4955 struct policy_handle
*domain_handle
, char **password
)
4963 if (!test_ChangePasswordUser(p
, tctx
, acct_name
, domain_handle
, password
)) {
4967 if (!test_ChangePasswordUser2(p
, tctx
, acct_name
, password
, 0, true)) {
4971 if (!test_OemChangePasswordUser2(p
, tctx
, acct_name
, domain_handle
, password
)) {
4975 /* test what happens when setting the old password again */
4976 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, *password
, 0, true)) {
4981 char simple_pass
[9];
4982 char *v
= generate_random_str(tctx
, 1);
4984 ZERO_STRUCT(simple_pass
);
4985 memset(simple_pass
, *v
, sizeof(simple_pass
) - 1);
4987 /* test what happens when picking a simple password */
4988 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, simple_pass
, 0, true)) {
4993 /* set samr_SetDomainInfo level 1 with min_length 5 */
4995 struct samr_QueryDomainInfo r
;
4996 union samr_DomainInfo
*info
= NULL
;
4997 struct samr_SetDomainInfo s
;
4998 uint16_t len_old
, len
;
4999 uint32_t pwd_prop_old
;
5000 int64_t min_pwd_age_old
;
5005 r
.in
.domain_handle
= domain_handle
;
5009 torture_comment(tctx
, "testing samr_QueryDomainInfo level 1\n");
5010 status
= dcerpc_samr_QueryDomainInfo(p
, tctx
, &r
);
5011 if (!NT_STATUS_IS_OK(status
)) {
5015 s
.in
.domain_handle
= domain_handle
;
5019 /* remember the old min length, so we can reset it */
5020 len_old
= s
.in
.info
->info1
.min_password_length
;
5021 s
.in
.info
->info1
.min_password_length
= len
;
5022 pwd_prop_old
= s
.in
.info
->info1
.password_properties
;
5023 /* turn off password complexity checks for this test */
5024 s
.in
.info
->info1
.password_properties
&= ~DOMAIN_PASSWORD_COMPLEX
;
5026 min_pwd_age_old
= s
.in
.info
->info1
.min_password_age
;
5027 s
.in
.info
->info1
.min_password_age
= 0;
5029 torture_comment(tctx
, "testing samr_SetDomainInfo level 1\n");
5030 status
= dcerpc_samr_SetDomainInfo(p
, tctx
, &s
);
5031 if (!NT_STATUS_IS_OK(status
)) {
5035 torture_comment(tctx
, "calling test_ChangePasswordUser3 with too short password\n");
5037 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, len
- 1, password
, NULL
, 0, true)) {
5041 s
.in
.info
->info1
.min_password_length
= len_old
;
5042 s
.in
.info
->info1
.password_properties
= pwd_prop_old
;
5043 s
.in
.info
->info1
.min_password_age
= min_pwd_age_old
;
5045 torture_comment(tctx
, "testing samr_SetDomainInfo level 1\n");
5046 status
= dcerpc_samr_SetDomainInfo(p
, tctx
, &s
);
5047 if (!NT_STATUS_IS_OK(status
)) {
5055 struct samr_OpenUser r
;
5056 struct samr_QueryUserInfo q
;
5057 union samr_UserInfo
*info
;
5058 struct samr_LookupNames n
;
5059 struct policy_handle user_handle
;
5060 struct samr_Ids rids
, types
;
5062 n
.in
.domain_handle
= domain_handle
;
5064 n
.in
.names
= talloc_array(tctx
, struct lsa_String
, 1);
5065 n
.in
.names
[0].string
= acct_name
;
5067 n
.out
.types
= &types
;
5069 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
5070 if (!NT_STATUS_IS_OK(status
)) {
5071 torture_warning(tctx
, "LookupNames failed - %s\n", nt_errstr(status
));
5075 r
.in
.domain_handle
= domain_handle
;
5076 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5077 r
.in
.rid
= n
.out
.rids
->ids
[0];
5078 r
.out
.user_handle
= &user_handle
;
5080 status
= dcerpc_samr_OpenUser(p
, tctx
, &r
);
5081 if (!NT_STATUS_IS_OK(status
)) {
5082 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", n
.out
.rids
->ids
[0], nt_errstr(status
));
5086 q
.in
.user_handle
= &user_handle
;
5090 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &q
);
5091 if (!NT_STATUS_IS_OK(status
)) {
5092 torture_warning(tctx
, "QueryUserInfo failed - %s\n", nt_errstr(status
));
5096 torture_comment(tctx
, "calling test_ChangePasswordUser3 with too early password change\n");
5098 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
,
5099 info
->info5
.last_password_change
, true)) {
5104 /* we change passwords twice - this has the effect of verifying
5105 they were changed correctly for the final call */
5106 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
, 0, true)) {
5110 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
, 0, true)) {
5117 static bool test_CreateUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5118 struct policy_handle
*domain_handle
,
5119 const char *user_name
,
5120 struct policy_handle
*user_handle_out
,
5121 struct dom_sid
*domain_sid
,
5122 enum torture_samr_choice which_ops
,
5123 struct cli_credentials
*machine_credentials
,
5127 TALLOC_CTX
*user_ctx
;
5130 struct samr_CreateUser r
;
5131 struct samr_QueryUserInfo q
;
5132 union samr_UserInfo
*info
;
5133 struct samr_DeleteUser d
;
5136 /* This call creates a 'normal' account - check that it really does */
5137 const uint32_t acct_flags
= ACB_NORMAL
;
5138 struct lsa_String name
;
5141 struct policy_handle user_handle
;
5142 user_ctx
= talloc_named(tctx
, 0, "test_CreateUser2 per-user context");
5143 init_lsa_String(&name
, user_name
);
5145 r
.in
.domain_handle
= domain_handle
;
5146 r
.in
.account_name
= &name
;
5147 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5148 r
.out
.user_handle
= &user_handle
;
5151 torture_comment(tctx
, "Testing CreateUser(%s)\n", r
.in
.account_name
->string
);
5153 status
= dcerpc_samr_CreateUser(p
, user_ctx
, &r
);
5155 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
5156 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) || NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
5157 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.account_name
->string
);
5160 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.account_name
->string
,
5166 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_EXISTS
)) {
5167 if (!test_DeleteUser_byname(p
, user_ctx
, domain_handle
, r
.in
.account_name
->string
)) {
5168 talloc_free(user_ctx
);
5171 status
= dcerpc_samr_CreateUser(p
, user_ctx
, &r
);
5174 if (!NT_STATUS_IS_OK(status
)) {
5175 talloc_free(user_ctx
);
5176 torture_warning(tctx
, "CreateUser failed - %s\n", nt_errstr(status
));
5181 if (user_handle_out
) {
5182 *user_handle_out
= user_handle
;
5188 q
.in
.user_handle
= &user_handle
;
5192 status
= dcerpc_samr_QueryUserInfo(p
, user_ctx
, &q
);
5193 if (!NT_STATUS_IS_OK(status
)) {
5194 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
5195 q
.in
.level
, nt_errstr(status
));
5198 if ((info
->info16
.acct_flags
& acct_flags
) != acct_flags
) {
5199 torture_warning(tctx
, "QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5200 info
->info16
.acct_flags
,
5206 if (!test_user_ops(p
, tctx
, &user_handle
, domain_handle
,
5207 domain_sid
, acct_flags
, name
.string
, which_ops
,
5208 machine_credentials
)) {
5212 if (user_handle_out
) {
5213 *user_handle_out
= user_handle
;
5215 torture_comment(tctx
, "Testing DeleteUser (createuser test)\n");
5217 d
.in
.user_handle
= &user_handle
;
5218 d
.out
.user_handle
= &user_handle
;
5220 status
= dcerpc_samr_DeleteUser(p
, user_ctx
, &d
);
5221 if (!NT_STATUS_IS_OK(status
)) {
5222 torture_warning(tctx
, "DeleteUser failed - %s\n", nt_errstr(status
));
5229 talloc_free(user_ctx
);
5235 static bool test_CreateUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5236 struct policy_handle
*domain_handle
,
5237 struct dom_sid
*domain_sid
,
5238 enum torture_samr_choice which_ops
,
5239 struct cli_credentials
*machine_credentials
)
5242 struct samr_CreateUser2 r
;
5243 struct samr_QueryUserInfo q
;
5244 union samr_UserInfo
*info
;
5245 struct samr_DeleteUser d
;
5246 struct policy_handle user_handle
;
5248 struct lsa_String name
;
5253 uint32_t acct_flags
;
5254 const char *account_name
;
5256 } account_types
[] = {
5257 { ACB_NORMAL
, TEST_ACCOUNT_NAME
, NT_STATUS_OK
},
5258 { ACB_NORMAL
| ACB_DISABLED
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5259 { ACB_NORMAL
| ACB_PWNOEXP
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5260 { ACB_WSTRUST
, TEST_MACHINENAME
, NT_STATUS_OK
},
5261 { ACB_WSTRUST
| ACB_DISABLED
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5262 { ACB_WSTRUST
| ACB_PWNOEXP
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5263 { ACB_SVRTRUST
, TEST_MACHINENAME
, NT_STATUS_OK
},
5264 { ACB_SVRTRUST
| ACB_DISABLED
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5265 { ACB_SVRTRUST
| ACB_PWNOEXP
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
5266 { ACB_DOMTRUST
, TEST_DOMAINNAME
, NT_STATUS_ACCESS_DENIED
},
5267 { ACB_DOMTRUST
| ACB_DISABLED
, TEST_DOMAINNAME
, NT_STATUS_INVALID_PARAMETER
},
5268 { ACB_DOMTRUST
| ACB_PWNOEXP
, TEST_DOMAINNAME
, NT_STATUS_INVALID_PARAMETER
},
5269 { 0, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5270 { ACB_DISABLED
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
5271 { 0, NULL
, NT_STATUS_INVALID_PARAMETER
}
5274 for (i
= 0; account_types
[i
].account_name
; i
++) {
5275 TALLOC_CTX
*user_ctx
;
5276 uint32_t acct_flags
= account_types
[i
].acct_flags
;
5277 uint32_t access_granted
;
5278 user_ctx
= talloc_named(tctx
, 0, "test_CreateUser2 per-user context");
5279 init_lsa_String(&name
, account_types
[i
].account_name
);
5281 r
.in
.domain_handle
= domain_handle
;
5282 r
.in
.account_name
= &name
;
5283 r
.in
.acct_flags
= acct_flags
;
5284 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5285 r
.out
.user_handle
= &user_handle
;
5286 r
.out
.access_granted
= &access_granted
;
5289 torture_comment(tctx
, "Testing CreateUser2(%s, 0x%x)\n", r
.in
.account_name
->string
, acct_flags
);
5291 status
= dcerpc_samr_CreateUser2(p
, user_ctx
, &r
);
5293 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
5294 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) || NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
5295 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.account_name
->string
);
5298 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.account_name
->string
,
5305 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_EXISTS
)) {
5306 if (!test_DeleteUser_byname(p
, user_ctx
, domain_handle
, r
.in
.account_name
->string
)) {
5307 talloc_free(user_ctx
);
5311 status
= dcerpc_samr_CreateUser2(p
, user_ctx
, &r
);
5314 if (!NT_STATUS_EQUAL(status
, account_types
[i
].nt_status
)) {
5315 torture_warning(tctx
, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5316 nt_errstr(status
), nt_errstr(account_types
[i
].nt_status
));
5320 if (NT_STATUS_IS_OK(status
)) {
5321 q
.in
.user_handle
= &user_handle
;
5325 status
= dcerpc_samr_QueryUserInfo(p
, user_ctx
, &q
);
5326 if (!NT_STATUS_IS_OK(status
)) {
5327 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
5328 q
.in
.level
, nt_errstr(status
));
5331 uint32_t expected_flags
= (acct_flags
| ACB_PWNOTREQ
| ACB_DISABLED
);
5332 if (acct_flags
== ACB_NORMAL
) {
5333 expected_flags
|= ACB_PW_EXPIRED
;
5335 if ((info
->info5
.acct_flags
) != expected_flags
) {
5336 torture_warning(tctx
, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5337 info
->info5
.acct_flags
,
5341 switch (acct_flags
) {
5343 if (info
->info5
.primary_gid
!= DOMAIN_RID_DCS
) {
5344 torture_warning(tctx
, "QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5345 DOMAIN_RID_DCS
, info
->info5
.primary_gid
);
5350 if (info
->info5
.primary_gid
!= DOMAIN_RID_DOMAIN_MEMBERS
) {
5351 torture_warning(tctx
, "QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5352 DOMAIN_RID_DOMAIN_MEMBERS
, info
->info5
.primary_gid
);
5357 if (info
->info5
.primary_gid
!= DOMAIN_RID_USERS
) {
5358 torture_warning(tctx
, "QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5359 DOMAIN_RID_USERS
, info
->info5
.primary_gid
);
5366 if (!test_user_ops(p
, tctx
, &user_handle
, domain_handle
,
5367 domain_sid
, acct_flags
, name
.string
, which_ops
,
5368 machine_credentials
)) {
5372 if (!policy_handle_empty(&user_handle
)) {
5373 torture_comment(tctx
, "Testing DeleteUser (createuser2 test)\n");
5375 d
.in
.user_handle
= &user_handle
;
5376 d
.out
.user_handle
= &user_handle
;
5378 status
= dcerpc_samr_DeleteUser(p
, user_ctx
, &d
);
5379 if (!NT_STATUS_IS_OK(status
)) {
5380 torture_warning(tctx
, "DeleteUser failed - %s\n", nt_errstr(status
));
5385 talloc_free(user_ctx
);
5391 static bool test_QueryAliasInfo(struct dcerpc_pipe
*p
,
5392 struct torture_context
*tctx
,
5393 struct policy_handle
*handle
)
5396 struct samr_QueryAliasInfo r
;
5397 union samr_AliasInfo
*info
;
5398 uint16_t levels
[] = {1, 2, 3};
5402 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5403 torture_comment(tctx
, "Testing QueryAliasInfo level %u\n", levels
[i
]);
5405 r
.in
.alias_handle
= handle
;
5406 r
.in
.level
= levels
[i
];
5409 status
= dcerpc_samr_QueryAliasInfo(p
, tctx
, &r
);
5410 if (!NT_STATUS_IS_OK(status
)) {
5411 torture_warning(tctx
, "QueryAliasInfo level %u failed - %s\n",
5412 levels
[i
], nt_errstr(status
));
5420 static bool test_QueryGroupInfo(struct dcerpc_pipe
*p
,
5421 struct torture_context
*tctx
,
5422 struct policy_handle
*handle
)
5425 struct samr_QueryGroupInfo r
;
5426 union samr_GroupInfo
*info
;
5427 uint16_t levels
[] = {1, 2, 3, 4, 5};
5431 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5432 torture_comment(tctx
, "Testing QueryGroupInfo level %u\n", levels
[i
]);
5434 r
.in
.group_handle
= handle
;
5435 r
.in
.level
= levels
[i
];
5438 status
= dcerpc_samr_QueryGroupInfo(p
, tctx
, &r
);
5439 if (!NT_STATUS_IS_OK(status
)) {
5440 torture_warning(tctx
, "QueryGroupInfo level %u failed - %s\n",
5441 levels
[i
], nt_errstr(status
));
5449 static bool test_QueryGroupMember(struct dcerpc_pipe
*p
,
5450 struct torture_context
*tctx
,
5451 struct policy_handle
*handle
)
5454 struct samr_QueryGroupMember r
;
5455 struct samr_RidTypeArray
*rids
= NULL
;
5458 torture_comment(tctx
, "Testing QueryGroupMember\n");
5460 r
.in
.group_handle
= handle
;
5463 status
= dcerpc_samr_QueryGroupMember(p
, tctx
, &r
);
5464 if (!NT_STATUS_IS_OK(status
)) {
5465 torture_warning(tctx
, "QueryGroupInfo failed - %s\n", nt_errstr(status
));
5473 static bool test_SetGroupInfo(struct dcerpc_pipe
*p
,
5474 struct torture_context
*tctx
,
5475 struct policy_handle
*handle
)
5478 struct samr_QueryGroupInfo r
;
5479 union samr_GroupInfo
*info
;
5480 struct samr_SetGroupInfo s
;
5481 uint16_t levels
[] = {1, 2, 3, 4};
5482 uint16_t set_ok
[] = {0, 1, 1, 1};
5486 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5487 torture_comment(tctx
, "Testing QueryGroupInfo level %u\n", levels
[i
]);
5489 r
.in
.group_handle
= handle
;
5490 r
.in
.level
= levels
[i
];
5493 status
= dcerpc_samr_QueryGroupInfo(p
, tctx
, &r
);
5494 if (!NT_STATUS_IS_OK(status
)) {
5495 torture_warning(tctx
, "QueryGroupInfo level %u failed - %s\n",
5496 levels
[i
], nt_errstr(status
));
5500 torture_comment(tctx
, "Testing SetGroupInfo level %u\n", levels
[i
]);
5502 s
.in
.group_handle
= handle
;
5503 s
.in
.level
= levels
[i
];
5504 s
.in
.info
= *r
.out
.info
;
5507 /* disabled this, as it changes the name only from the point of view of samr,
5508 but leaves the name from the point of view of w2k3 internals (and ldap). This means
5509 the name is still reserved, so creating the old name fails, but deleting by the old name
5511 if (s
.in
.level
== 2) {
5512 init_lsa_String(&s
.in
.info
->string
, "NewName");
5516 if (s
.in
.level
== 4) {
5517 init_lsa_String(&s
.in
.info
->description
, "test description");
5520 status
= dcerpc_samr_SetGroupInfo(p
, tctx
, &s
);
5522 if (!NT_STATUS_IS_OK(status
)) {
5523 torture_warning(tctx
, "SetGroupInfo level %u failed - %s\n",
5524 r
.in
.level
, nt_errstr(status
));
5529 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, status
)) {
5530 torture_warning(tctx
, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5531 r
.in
.level
, nt_errstr(status
));
5541 static bool test_QueryUserInfo(struct dcerpc_pipe
*p
,
5542 struct torture_context
*tctx
,
5543 struct policy_handle
*handle
)
5546 struct samr_QueryUserInfo r
;
5547 union samr_UserInfo
*info
;
5548 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5549 11, 12, 13, 14, 16, 17, 20, 21};
5553 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5554 torture_comment(tctx
, "Testing QueryUserInfo level %u\n", levels
[i
]);
5556 r
.in
.user_handle
= handle
;
5557 r
.in
.level
= levels
[i
];
5560 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &r
);
5561 if (!NT_STATUS_IS_OK(status
)) {
5562 torture_warning(tctx
, "QueryUserInfo level %u failed - %s\n",
5563 levels
[i
], nt_errstr(status
));
5571 static bool test_QueryUserInfo2(struct dcerpc_pipe
*p
,
5572 struct torture_context
*tctx
,
5573 struct policy_handle
*handle
)
5576 struct samr_QueryUserInfo2 r
;
5577 union samr_UserInfo
*info
;
5578 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5579 11, 12, 13, 14, 16, 17, 20, 21};
5583 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5584 torture_comment(tctx
, "Testing QueryUserInfo2 level %u\n", levels
[i
]);
5586 r
.in
.user_handle
= handle
;
5587 r
.in
.level
= levels
[i
];
5590 status
= dcerpc_samr_QueryUserInfo2(p
, tctx
, &r
);
5591 if (!NT_STATUS_IS_OK(status
)) {
5592 torture_warning(tctx
, "QueryUserInfo2 level %u failed - %s\n",
5593 levels
[i
], nt_errstr(status
));
5601 static bool test_OpenUser(struct dcerpc_pipe
*p
,
5602 struct torture_context
*tctx
,
5603 struct policy_handle
*handle
, uint32_t rid
)
5606 struct samr_OpenUser r
;
5607 struct policy_handle user_handle
;
5610 torture_comment(tctx
, "Testing OpenUser(%u)\n", rid
);
5612 r
.in
.domain_handle
= handle
;
5613 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5615 r
.out
.user_handle
= &user_handle
;
5617 status
= dcerpc_samr_OpenUser(p
, tctx
, &r
);
5618 if (!NT_STATUS_IS_OK(status
)) {
5619 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", rid
, nt_errstr(status
));
5623 if (!test_QuerySecurity(p
, tctx
, &user_handle
)) {
5627 if (!test_QueryUserInfo(p
, tctx
, &user_handle
)) {
5631 if (!test_QueryUserInfo2(p
, tctx
, &user_handle
)) {
5635 if (!test_GetUserPwInfo(p
, tctx
, &user_handle
)) {
5639 if (!test_GetGroupsForUser(p
,tctx
, &user_handle
)) {
5643 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
5650 static bool test_OpenGroup(struct dcerpc_pipe
*p
,
5651 struct torture_context
*tctx
,
5652 struct policy_handle
*handle
, uint32_t rid
)
5655 struct samr_OpenGroup r
;
5656 struct policy_handle group_handle
;
5659 torture_comment(tctx
, "Testing OpenGroup(%u)\n", rid
);
5661 r
.in
.domain_handle
= handle
;
5662 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5664 r
.out
.group_handle
= &group_handle
;
5666 status
= dcerpc_samr_OpenGroup(p
, tctx
, &r
);
5667 if (!NT_STATUS_IS_OK(status
)) {
5668 torture_warning(tctx
, "OpenGroup(%u) failed - %s\n", rid
, nt_errstr(status
));
5672 if (!torture_setting_bool(tctx
, "samba3", false)) {
5673 if (!test_QuerySecurity(p
, tctx
, &group_handle
)) {
5678 if (!test_QueryGroupInfo(p
, tctx
, &group_handle
)) {
5682 if (!test_QueryGroupMember(p
, tctx
, &group_handle
)) {
5686 if (!test_samr_handle_Close(p
, tctx
, &group_handle
)) {
5693 static bool test_OpenAlias(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5694 struct policy_handle
*handle
, uint32_t rid
)
5697 struct samr_OpenAlias r
;
5698 struct policy_handle alias_handle
;
5701 torture_comment(tctx
, "Testing OpenAlias(%u)\n", rid
);
5703 r
.in
.domain_handle
= handle
;
5704 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5706 r
.out
.alias_handle
= &alias_handle
;
5708 status
= dcerpc_samr_OpenAlias(p
, tctx
, &r
);
5709 if (!NT_STATUS_IS_OK(status
)) {
5710 torture_warning(tctx
, "OpenAlias(%u) failed - %s\n", rid
, nt_errstr(status
));
5714 if (!torture_setting_bool(tctx
, "samba3", false)) {
5715 if (!test_QuerySecurity(p
, tctx
, &alias_handle
)) {
5720 if (!test_QueryAliasInfo(p
, tctx
, &alias_handle
)) {
5724 if (!test_GetMembersInAlias(p
, tctx
, &alias_handle
)) {
5728 if (!test_samr_handle_Close(p
, tctx
, &alias_handle
)) {
5735 static bool check_mask(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5736 struct policy_handle
*handle
, uint32_t rid
,
5737 uint32_t acct_flag_mask
)
5740 struct samr_OpenUser r
;
5741 struct samr_QueryUserInfo q
;
5742 union samr_UserInfo
*info
;
5743 struct policy_handle user_handle
;
5746 torture_comment(tctx
, "Testing OpenUser(%u)\n", rid
);
5748 r
.in
.domain_handle
= handle
;
5749 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5751 r
.out
.user_handle
= &user_handle
;
5753 status
= dcerpc_samr_OpenUser(p
, tctx
, &r
);
5754 if (!NT_STATUS_IS_OK(status
)) {
5755 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", rid
, nt_errstr(status
));
5759 q
.in
.user_handle
= &user_handle
;
5763 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &q
);
5764 if (!NT_STATUS_IS_OK(status
)) {
5765 torture_warning(tctx
, "QueryUserInfo level 16 failed - %s\n",
5769 if ((acct_flag_mask
& info
->info16
.acct_flags
) == 0) {
5770 torture_warning(tctx
, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
5771 acct_flag_mask
, info
->info16
.acct_flags
, rid
);
5776 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
5783 static bool test_EnumDomainUsers_all(struct dcerpc_pipe
*p
,
5784 struct torture_context
*tctx
,
5785 struct policy_handle
*handle
)
5787 NTSTATUS status
= STATUS_MORE_ENTRIES
;
5788 struct samr_EnumDomainUsers r
;
5789 uint32_t mask
, resume_handle
=0;
5792 struct samr_LookupNames n
;
5793 struct samr_LookupRids lr
;
5794 struct lsa_Strings names
;
5795 struct samr_Ids rids
, types
;
5796 struct samr_SamArray
*sam
= NULL
;
5797 uint32_t num_entries
= 0;
5799 uint32_t masks
[] = {ACB_NORMAL
, ACB_DOMTRUST
, ACB_WSTRUST
,
5800 ACB_DISABLED
, ACB_NORMAL
| ACB_DISABLED
,
5801 ACB_SVRTRUST
| ACB_DOMTRUST
| ACB_WSTRUST
,
5804 torture_comment(tctx
, "Testing EnumDomainUsers\n");
5806 for (mask_idx
=0;mask_idx
<ARRAY_SIZE(masks
);mask_idx
++) {
5807 r
.in
.domain_handle
= handle
;
5808 r
.in
.resume_handle
= &resume_handle
;
5809 r
.in
.acct_flags
= mask
= masks
[mask_idx
];
5810 r
.in
.max_size
= (uint32_t)-1;
5811 r
.out
.resume_handle
= &resume_handle
;
5812 r
.out
.num_entries
= &num_entries
;
5815 status
= dcerpc_samr_EnumDomainUsers(p
, tctx
, &r
);
5816 if (!NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) &&
5817 !NT_STATUS_IS_OK(status
)) {
5818 torture_warning(tctx
, "EnumDomainUsers failed - %s\n", nt_errstr(status
));
5822 torture_assert(tctx
, sam
, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
5824 if (sam
->count
== 0) {
5828 for (i
=0;i
<sam
->count
;i
++) {
5830 if (!check_mask(p
, tctx
, handle
, sam
->entries
[i
].idx
, mask
)) {
5833 } else if (!test_OpenUser(p
, tctx
, handle
, sam
->entries
[i
].idx
)) {
5839 torture_comment(tctx
, "Testing LookupNames\n");
5840 n
.in
.domain_handle
= handle
;
5841 n
.in
.num_names
= sam
->count
;
5842 n
.in
.names
= talloc_array(tctx
, struct lsa_String
, sam
->count
);
5844 n
.out
.types
= &types
;
5845 for (i
=0;i
<sam
->count
;i
++) {
5846 n
.in
.names
[i
].string
= sam
->entries
[i
].name
.string
;
5848 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
5849 if (!NT_STATUS_IS_OK(status
)) {
5850 torture_warning(tctx
, "LookupNames failed - %s\n", nt_errstr(status
));
5855 torture_comment(tctx
, "Testing LookupRids\n");
5856 lr
.in
.domain_handle
= handle
;
5857 lr
.in
.num_rids
= sam
->count
;
5858 lr
.in
.rids
= talloc_array(tctx
, uint32_t, sam
->count
);
5859 lr
.out
.names
= &names
;
5860 lr
.out
.types
= &types
;
5861 for (i
=0;i
<sam
->count
;i
++) {
5862 lr
.in
.rids
[i
] = sam
->entries
[i
].idx
;
5864 status
= dcerpc_samr_LookupRids(p
, tctx
, &lr
);
5865 torture_assert_ntstatus_ok(tctx
, status
, "LookupRids");
5871 try blasting the server with a bunch of sync requests
5873 static bool test_EnumDomainUsers_async(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5874 struct policy_handle
*handle
)
5877 struct samr_EnumDomainUsers r
;
5878 uint32_t resume_handle
=0;
5880 #define ASYNC_COUNT 100
5881 struct rpc_request
*req
[ASYNC_COUNT
];
5883 if (!torture_setting_bool(tctx
, "dangerous", false)) {
5884 torture_skip(tctx
, "samr async test disabled - enable dangerous tests to use\n");
5887 torture_comment(tctx
, "Testing EnumDomainUsers_async\n");
5889 r
.in
.domain_handle
= handle
;
5890 r
.in
.resume_handle
= &resume_handle
;
5891 r
.in
.acct_flags
= 0;
5892 r
.in
.max_size
= (uint32_t)-1;
5893 r
.out
.resume_handle
= &resume_handle
;
5895 for (i
=0;i
<ASYNC_COUNT
;i
++) {
5896 req
[i
] = dcerpc_samr_EnumDomainUsers_send(p
, tctx
, &r
);
5899 for (i
=0;i
<ASYNC_COUNT
;i
++) {
5900 status
= dcerpc_ndr_request_recv(req
[i
]);
5901 if (!NT_STATUS_IS_OK(status
)) {
5902 torture_warning(tctx
, "EnumDomainUsers[%d] failed - %s\n",
5903 i
, nt_errstr(status
));
5908 torture_comment(tctx
, "%d async requests OK\n", i
);
5913 static bool test_EnumDomainGroups_all(struct dcerpc_pipe
*p
,
5914 struct torture_context
*tctx
,
5915 struct policy_handle
*handle
)
5918 struct samr_EnumDomainGroups r
;
5919 uint32_t resume_handle
=0;
5920 struct samr_SamArray
*sam
= NULL
;
5921 uint32_t num_entries
= 0;
5925 torture_comment(tctx
, "Testing EnumDomainGroups\n");
5927 r
.in
.domain_handle
= handle
;
5928 r
.in
.resume_handle
= &resume_handle
;
5929 r
.in
.max_size
= (uint32_t)-1;
5930 r
.out
.resume_handle
= &resume_handle
;
5931 r
.out
.num_entries
= &num_entries
;
5934 status
= dcerpc_samr_EnumDomainGroups(p
, tctx
, &r
);
5935 if (!NT_STATUS_IS_OK(status
)) {
5936 torture_warning(tctx
, "EnumDomainGroups failed - %s\n", nt_errstr(status
));
5944 for (i
=0;i
<sam
->count
;i
++) {
5945 if (!test_OpenGroup(p
, tctx
, handle
, sam
->entries
[i
].idx
)) {
5953 static bool test_EnumDomainAliases_all(struct dcerpc_pipe
*p
,
5954 struct torture_context
*tctx
,
5955 struct policy_handle
*handle
)
5958 struct samr_EnumDomainAliases r
;
5959 uint32_t resume_handle
=0;
5960 struct samr_SamArray
*sam
= NULL
;
5961 uint32_t num_entries
= 0;
5965 torture_comment(tctx
, "Testing EnumDomainAliases\n");
5967 r
.in
.domain_handle
= handle
;
5968 r
.in
.resume_handle
= &resume_handle
;
5969 r
.in
.max_size
= (uint32_t)-1;
5971 r
.out
.num_entries
= &num_entries
;
5972 r
.out
.resume_handle
= &resume_handle
;
5974 status
= dcerpc_samr_EnumDomainAliases(p
, tctx
, &r
);
5975 if (!NT_STATUS_IS_OK(status
)) {
5976 torture_warning(tctx
, "EnumDomainAliases failed - %s\n", nt_errstr(status
));
5984 for (i
=0;i
<sam
->count
;i
++) {
5985 if (!test_OpenAlias(p
, tctx
, handle
, sam
->entries
[i
].idx
)) {
5993 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe
*p
,
5994 struct torture_context
*tctx
,
5995 struct policy_handle
*handle
)
5998 struct samr_GetDisplayEnumerationIndex r
;
6000 uint16_t levels
[] = {1, 2, 3, 4, 5};
6001 uint16_t ok_lvl
[] = {1, 1, 1, 0, 0};
6002 struct lsa_String name
;
6006 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6007 torture_comment(tctx
, "Testing GetDisplayEnumerationIndex level %u\n", levels
[i
]);
6009 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
6011 r
.in
.domain_handle
= handle
;
6012 r
.in
.level
= levels
[i
];
6016 status
= dcerpc_samr_GetDisplayEnumerationIndex(p
, tctx
, &r
);
6019 !NT_STATUS_IS_OK(status
) &&
6020 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
6021 torture_warning(tctx
, "GetDisplayEnumerationIndex level %u failed - %s\n",
6022 levels
[i
], nt_errstr(status
));
6026 init_lsa_String(&name
, "zzzzzzzz");
6028 status
= dcerpc_samr_GetDisplayEnumerationIndex(p
, tctx
, &r
);
6030 if (ok_lvl
[i
] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
6031 torture_warning(tctx
, "GetDisplayEnumerationIndex level %u failed - %s\n",
6032 levels
[i
], nt_errstr(status
));
6040 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe
*p
,
6041 struct torture_context
*tctx
,
6042 struct policy_handle
*handle
)
6045 struct samr_GetDisplayEnumerationIndex2 r
;
6047 uint16_t levels
[] = {1, 2, 3, 4, 5};
6048 uint16_t ok_lvl
[] = {1, 1, 1, 0, 0};
6049 struct lsa_String name
;
6053 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6054 torture_comment(tctx
, "Testing GetDisplayEnumerationIndex2 level %u\n", levels
[i
]);
6056 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
6058 r
.in
.domain_handle
= handle
;
6059 r
.in
.level
= levels
[i
];
6063 status
= dcerpc_samr_GetDisplayEnumerationIndex2(p
, tctx
, &r
);
6065 !NT_STATUS_IS_OK(status
) &&
6066 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
6067 torture_warning(tctx
, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6068 levels
[i
], nt_errstr(status
));
6072 init_lsa_String(&name
, "zzzzzzzz");
6074 status
= dcerpc_samr_GetDisplayEnumerationIndex2(p
, tctx
, &r
);
6075 if (ok_lvl
[i
] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
6076 torture_warning(tctx
, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6077 levels
[i
], nt_errstr(status
));
6085 #define STRING_EQUAL_QUERY(s1, s2, user) \
6086 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6087 /* odd, but valid */ \
6088 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6089 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
6090 #s1, user.string, s1.string, s2.string, __location__); \
6093 #define INT_EQUAL_QUERY(s1, s2, user) \
6095 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6096 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6100 static bool test_each_DisplayInfo_user(struct dcerpc_pipe
*p
,
6101 struct torture_context
*tctx
,
6102 struct samr_QueryDisplayInfo
*querydisplayinfo
,
6103 bool *seen_testuser
)
6105 struct samr_OpenUser r
;
6106 struct samr_QueryUserInfo q
;
6107 union samr_UserInfo
*info
;
6108 struct policy_handle user_handle
;
6111 r
.in
.domain_handle
= querydisplayinfo
->in
.domain_handle
;
6112 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6113 for (i
= 0; ; i
++) {
6114 switch (querydisplayinfo
->in
.level
) {
6116 if (i
>= querydisplayinfo
->out
.info
->info1
.count
) {
6119 r
.in
.rid
= querydisplayinfo
->out
.info
->info1
.entries
[i
].rid
;
6122 if (i
>= querydisplayinfo
->out
.info
->info2
.count
) {
6125 r
.in
.rid
= querydisplayinfo
->out
.info
->info2
.entries
[i
].rid
;
6131 /* Not interested in validating just the account name */
6135 r
.out
.user_handle
= &user_handle
;
6137 switch (querydisplayinfo
->in
.level
) {
6140 status
= dcerpc_samr_OpenUser(p
, tctx
, &r
);
6141 if (!NT_STATUS_IS_OK(status
)) {
6142 torture_warning(tctx
, "OpenUser(%u) failed - %s\n", r
.in
.rid
, nt_errstr(status
));
6147 q
.in
.user_handle
= &user_handle
;
6150 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &q
);
6151 if (!NT_STATUS_IS_OK(status
)) {
6152 torture_warning(tctx
, "QueryUserInfo(%u) failed - %s\n", r
.in
.rid
, nt_errstr(status
));
6156 switch (querydisplayinfo
->in
.level
) {
6158 if (seen_testuser
&& strcmp(info
->info21
.account_name
.string
, TEST_ACCOUNT_NAME
) == 0) {
6159 *seen_testuser
= true;
6161 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].full_name
,
6162 info
->info21
.full_name
, info
->info21
.account_name
);
6163 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].account_name
,
6164 info
->info21
.account_name
, info
->info21
.account_name
);
6165 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].description
,
6166 info
->info21
.description
, info
->info21
.account_name
);
6167 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].rid
,
6168 info
->info21
.rid
, info
->info21
.account_name
);
6169 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].acct_flags
,
6170 info
->info21
.acct_flags
, info
->info21
.account_name
);
6174 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].account_name
,
6175 info
->info21
.account_name
, info
->info21
.account_name
);
6176 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].description
,
6177 info
->info21
.description
, info
->info21
.account_name
);
6178 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].rid
,
6179 info
->info21
.rid
, info
->info21
.account_name
);
6180 INT_EQUAL_QUERY((querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
& ~ACB_NORMAL
),
6181 info
->info21
.acct_flags
, info
->info21
.account_name
);
6183 if (!(querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
& ACB_NORMAL
)) {
6184 torture_warning(tctx
, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6185 info
->info21
.account_name
.string
);
6188 if (!(info
->info21
.acct_flags
& (ACB_WSTRUST
| ACB_SVRTRUST
))) {
6189 torture_warning(tctx
, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6190 info
->info21
.account_name
.string
,
6191 querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
,
6192 info
->info21
.acct_flags
);
6199 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
6206 static bool test_QueryDisplayInfo(struct dcerpc_pipe
*p
,
6207 struct torture_context
*tctx
,
6208 struct policy_handle
*handle
)
6211 struct samr_QueryDisplayInfo r
;
6212 struct samr_QueryDomainInfo dom_info
;
6213 union samr_DomainInfo
*info
= NULL
;
6215 uint16_t levels
[] = {1, 2, 3, 4, 5};
6217 bool seen_testuser
= false;
6218 uint32_t total_size
;
6219 uint32_t returned_size
;
6220 union samr_DispInfo disp_info
;
6223 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6224 torture_comment(tctx
, "Testing QueryDisplayInfo level %u\n", levels
[i
]);
6227 status
= STATUS_MORE_ENTRIES
;
6228 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
6229 r
.in
.domain_handle
= handle
;
6230 r
.in
.level
= levels
[i
];
6231 r
.in
.max_entries
= 2;
6232 r
.in
.buf_size
= (uint32_t)-1;
6233 r
.out
.total_size
= &total_size
;
6234 r
.out
.returned_size
= &returned_size
;
6235 r
.out
.info
= &disp_info
;
6237 status
= dcerpc_samr_QueryDisplayInfo(p
, tctx
, &r
);
6238 if (!NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) && !NT_STATUS_IS_OK(status
)) {
6239 torture_warning(tctx
, "QueryDisplayInfo level %u failed - %s\n",
6240 levels
[i
], nt_errstr(status
));
6243 switch (r
.in
.level
) {
6245 if (!test_each_DisplayInfo_user(p
, tctx
, &r
, &seen_testuser
)) {
6248 r
.in
.start_idx
+= r
.out
.info
->info1
.count
;
6251 if (!test_each_DisplayInfo_user(p
, tctx
, &r
, NULL
)) {
6254 r
.in
.start_idx
+= r
.out
.info
->info2
.count
;
6257 r
.in
.start_idx
+= r
.out
.info
->info3
.count
;
6260 r
.in
.start_idx
+= r
.out
.info
->info4
.count
;
6263 r
.in
.start_idx
+= r
.out
.info
->info5
.count
;
6267 dom_info
.in
.domain_handle
= handle
;
6268 dom_info
.in
.level
= 2;
6269 dom_info
.out
.info
= &info
;
6271 /* Check number of users returned is correct */
6272 status
= dcerpc_samr_QueryDomainInfo(p
, tctx
, &dom_info
);
6273 if (!NT_STATUS_IS_OK(status
)) {
6274 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
6275 r
.in
.level
, nt_errstr(status
));
6279 switch (r
.in
.level
) {
6282 if (info
->general
.num_users
< r
.in
.start_idx
) {
6283 torture_warning(tctx
, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6284 r
.in
.start_idx
, info
->general
.num_groups
,
6285 info
->general
.domain_name
.string
);
6288 if (!seen_testuser
) {
6289 struct policy_handle user_handle
;
6290 if (NT_STATUS_IS_OK(test_OpenUser_byname(p
, tctx
, handle
, TEST_ACCOUNT_NAME
, &user_handle
))) {
6291 torture_warning(tctx
, "Didn't find test user " TEST_ACCOUNT_NAME
" in enumeration of %s\n",
6292 info
->general
.domain_name
.string
);
6294 test_samr_handle_Close(p
, tctx
, &user_handle
);
6300 if (info
->general
.num_groups
!= r
.in
.start_idx
) {
6301 torture_warning(tctx
, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6302 r
.in
.start_idx
, info
->general
.num_groups
,
6303 info
->general
.domain_name
.string
);
6315 static bool test_QueryDisplayInfo2(struct dcerpc_pipe
*p
,
6316 struct torture_context
*tctx
,
6317 struct policy_handle
*handle
)
6320 struct samr_QueryDisplayInfo2 r
;
6322 uint16_t levels
[] = {1, 2, 3, 4, 5};
6324 uint32_t total_size
;
6325 uint32_t returned_size
;
6326 union samr_DispInfo info
;
6328 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6329 torture_comment(tctx
, "Testing QueryDisplayInfo2 level %u\n", levels
[i
]);
6331 r
.in
.domain_handle
= handle
;
6332 r
.in
.level
= levels
[i
];
6334 r
.in
.max_entries
= 1000;
6335 r
.in
.buf_size
= (uint32_t)-1;
6336 r
.out
.total_size
= &total_size
;
6337 r
.out
.returned_size
= &returned_size
;
6340 status
= dcerpc_samr_QueryDisplayInfo2(p
, tctx
, &r
);
6341 if (!NT_STATUS_IS_OK(status
)) {
6342 torture_warning(tctx
, "QueryDisplayInfo2 level %u failed - %s\n",
6343 levels
[i
], nt_errstr(status
));
6351 static bool test_QueryDisplayInfo3(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6352 struct policy_handle
*handle
)
6355 struct samr_QueryDisplayInfo3 r
;
6357 uint16_t levels
[] = {1, 2, 3, 4, 5};
6359 uint32_t total_size
;
6360 uint32_t returned_size
;
6361 union samr_DispInfo info
;
6363 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6364 torture_comment(tctx
, "Testing QueryDisplayInfo3 level %u\n", levels
[i
]);
6366 r
.in
.domain_handle
= handle
;
6367 r
.in
.level
= levels
[i
];
6369 r
.in
.max_entries
= 1000;
6370 r
.in
.buf_size
= (uint32_t)-1;
6371 r
.out
.total_size
= &total_size
;
6372 r
.out
.returned_size
= &returned_size
;
6375 status
= dcerpc_samr_QueryDisplayInfo3(p
, tctx
, &r
);
6376 if (!NT_STATUS_IS_OK(status
)) {
6377 torture_warning(tctx
, "QueryDisplayInfo3 level %u failed - %s\n",
6378 levels
[i
], nt_errstr(status
));
6387 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe
*p
,
6388 struct torture_context
*tctx
,
6389 struct policy_handle
*handle
)
6392 struct samr_QueryDisplayInfo r
;
6394 uint32_t total_size
;
6395 uint32_t returned_size
;
6396 union samr_DispInfo info
;
6398 torture_comment(tctx
, "Testing QueryDisplayInfo continuation\n");
6400 r
.in
.domain_handle
= handle
;
6403 r
.in
.max_entries
= 1;
6404 r
.in
.buf_size
= (uint32_t)-1;
6405 r
.out
.total_size
= &total_size
;
6406 r
.out
.returned_size
= &returned_size
;
6410 status
= dcerpc_samr_QueryDisplayInfo(p
, tctx
, &r
);
6411 if (NT_STATUS_IS_OK(status
) && *r
.out
.returned_size
!= 0) {
6412 if (r
.out
.info
->info1
.entries
[0].idx
!= r
.in
.start_idx
+ 1) {
6413 torture_warning(tctx
, "expected idx %d but got %d\n",
6415 r
.out
.info
->info1
.entries
[0].idx
);
6419 if (!NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) &&
6420 !NT_STATUS_IS_OK(status
)) {
6421 torture_warning(tctx
, "QueryDisplayInfo level %u failed - %s\n",
6422 r
.in
.level
, nt_errstr(status
));
6427 } while ((NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) ||
6428 NT_STATUS_IS_OK(status
)) &&
6429 *r
.out
.returned_size
!= 0);
6434 static bool test_QueryDomainInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6435 struct policy_handle
*handle
)
6438 struct samr_QueryDomainInfo r
;
6439 union samr_DomainInfo
*info
= NULL
;
6440 struct samr_SetDomainInfo s
;
6441 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6442 uint16_t set_ok
[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
6445 const char *domain_comment
= talloc_asprintf(tctx
,
6446 "Tortured by Samba4 RPC-SAMR: %s",
6447 timestring(tctx
, time(NULL
)));
6449 s
.in
.domain_handle
= handle
;
6451 s
.in
.info
= talloc(tctx
, union samr_DomainInfo
);
6453 s
.in
.info
->oem
.oem_information
.string
= domain_comment
;
6454 status
= dcerpc_samr_SetDomainInfo(p
, tctx
, &s
);
6455 if (!NT_STATUS_IS_OK(status
)) {
6456 torture_warning(tctx
, "SetDomainInfo level %u (set comment) failed - %s\n",
6457 s
.in
.level
, nt_errstr(status
));
6461 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6462 torture_comment(tctx
, "Testing QueryDomainInfo level %u\n", levels
[i
]);
6464 r
.in
.domain_handle
= handle
;
6465 r
.in
.level
= levels
[i
];
6468 status
= dcerpc_samr_QueryDomainInfo(p
, tctx
, &r
);
6469 if (!NT_STATUS_IS_OK(status
)) {
6470 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
6471 r
.in
.level
, nt_errstr(status
));
6476 switch (levels
[i
]) {
6478 if (strcmp(info
->general
.oem_information
.string
, domain_comment
) != 0) {
6479 torture_warning(tctx
, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6480 levels
[i
], info
->general
.oem_information
.string
, domain_comment
);
6481 if (!torture_setting_bool(tctx
, "samba3", false)) {
6485 if (!info
->general
.primary
.string
) {
6486 torture_warning(tctx
, "QueryDomainInfo level %u returned no PDC name\n",
6489 } else if (info
->general
.role
== SAMR_ROLE_DOMAIN_PDC
) {
6490 if (dcerpc_server_name(p
) && strcasecmp_m(dcerpc_server_name(p
), info
->general
.primary
.string
) != 0) {
6491 torture_warning(tctx
, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
6492 levels
[i
], info
->general
.primary
.string
, dcerpc_server_name(p
));
6497 if (strcmp(info
->oem
.oem_information
.string
, domain_comment
) != 0) {
6498 torture_warning(tctx
, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6499 levels
[i
], info
->oem
.oem_information
.string
, domain_comment
);
6500 if (!torture_setting_bool(tctx
, "samba3", false)) {
6506 if (!info
->info6
.primary
.string
) {
6507 torture_warning(tctx
, "QueryDomainInfo level %u returned no PDC name\n",
6513 if (strcmp(info
->general2
.general
.oem_information
.string
, domain_comment
) != 0) {
6514 torture_warning(tctx
, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
6515 levels
[i
], info
->general2
.general
.oem_information
.string
, domain_comment
);
6516 if (!torture_setting_bool(tctx
, "samba3", false)) {
6523 torture_comment(tctx
, "Testing SetDomainInfo level %u\n", levels
[i
]);
6525 s
.in
.domain_handle
= handle
;
6526 s
.in
.level
= levels
[i
];
6529 status
= dcerpc_samr_SetDomainInfo(p
, tctx
, &s
);
6531 if (!NT_STATUS_IS_OK(status
)) {
6532 torture_warning(tctx
, "SetDomainInfo level %u failed - %s\n",
6533 r
.in
.level
, nt_errstr(status
));
6538 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, status
)) {
6539 torture_warning(tctx
, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6540 r
.in
.level
, nt_errstr(status
));
6546 status
= dcerpc_samr_QueryDomainInfo(p
, tctx
, &r
);
6547 if (!NT_STATUS_IS_OK(status
)) {
6548 torture_warning(tctx
, "QueryDomainInfo level %u failed - %s\n",
6549 r
.in
.level
, nt_errstr(status
));
6559 static bool test_QueryDomainInfo2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6560 struct policy_handle
*handle
)
6563 struct samr_QueryDomainInfo2 r
;
6564 union samr_DomainInfo
*info
= NULL
;
6565 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6569 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6570 torture_comment(tctx
, "Testing QueryDomainInfo2 level %u\n", levels
[i
]);
6572 r
.in
.domain_handle
= handle
;
6573 r
.in
.level
= levels
[i
];
6576 status
= dcerpc_samr_QueryDomainInfo2(p
, tctx
, &r
);
6577 if (!NT_STATUS_IS_OK(status
)) {
6578 torture_warning(tctx
, "QueryDomainInfo2 level %u failed - %s\n",
6579 r
.in
.level
, nt_errstr(status
));
6588 /* Test whether querydispinfo level 5 and enumdomgroups return the same
6589 set of group names. */
6590 static bool test_GroupList(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6591 struct policy_handle
*handle
)
6593 struct samr_EnumDomainGroups q1
;
6594 struct samr_QueryDisplayInfo q2
;
6596 uint32_t resume_handle
=0;
6597 struct samr_SamArray
*sam
= NULL
;
6598 uint32_t num_entries
= 0;
6601 uint32_t total_size
;
6602 uint32_t returned_size
;
6603 union samr_DispInfo info
;
6606 const char **names
= NULL
;
6608 torture_comment(tctx
, "Testing coherency of querydispinfo vs enumdomgroups\n");
6610 q1
.in
.domain_handle
= handle
;
6611 q1
.in
.resume_handle
= &resume_handle
;
6613 q1
.out
.resume_handle
= &resume_handle
;
6614 q1
.out
.num_entries
= &num_entries
;
6617 status
= STATUS_MORE_ENTRIES
;
6618 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
6619 status
= dcerpc_samr_EnumDomainGroups(p
, tctx
, &q1
);
6621 if (!NT_STATUS_IS_OK(status
) &&
6622 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
6625 for (i
=0; i
<*q1
.out
.num_entries
; i
++) {
6626 add_string_to_array(tctx
,
6627 sam
->entries
[i
].name
.string
,
6628 &names
, &num_names
);
6632 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomainGroups");
6634 torture_assert(tctx
, sam
, "EnumDomainGroups failed to return sam");
6636 q2
.in
.domain_handle
= handle
;
6638 q2
.in
.start_idx
= 0;
6639 q2
.in
.max_entries
= 5;
6640 q2
.in
.buf_size
= (uint32_t)-1;
6641 q2
.out
.total_size
= &total_size
;
6642 q2
.out
.returned_size
= &returned_size
;
6643 q2
.out
.info
= &info
;
6645 status
= STATUS_MORE_ENTRIES
;
6646 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
6647 status
= dcerpc_samr_QueryDisplayInfo(p
, tctx
, &q2
);
6649 if (!NT_STATUS_IS_OK(status
) &&
6650 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
6653 for (i
=0; i
<q2
.out
.info
->info5
.count
; i
++) {
6655 const char *name
= q2
.out
.info
->info5
.entries
[i
].account_name
.string
;
6657 for (j
=0; j
<num_names
; j
++) {
6658 if (names
[j
] == NULL
)
6660 if (strequal(names
[j
], name
)) {
6668 torture_warning(tctx
, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
6673 q2
.in
.start_idx
+= q2
.out
.info
->info5
.count
;
6676 if (!NT_STATUS_IS_OK(status
)) {
6677 torture_warning(tctx
, "QueryDisplayInfo level 5 failed - %s\n",
6682 for (i
=0; i
<num_names
; i
++) {
6683 if (names
[i
] != NULL
) {
6684 torture_warning(tctx
, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
6693 static bool test_DeleteDomainGroup(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6694 struct policy_handle
*group_handle
)
6696 struct samr_DeleteDomainGroup d
;
6699 torture_comment(tctx
, "Testing DeleteDomainGroup\n");
6701 d
.in
.group_handle
= group_handle
;
6702 d
.out
.group_handle
= group_handle
;
6704 status
= dcerpc_samr_DeleteDomainGroup(p
, tctx
, &d
);
6705 torture_assert_ntstatus_ok(tctx
, status
, "DeleteDomainGroup");
6710 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6711 struct policy_handle
*domain_handle
)
6713 struct samr_TestPrivateFunctionsDomain r
;
6717 torture_comment(tctx
, "Testing TestPrivateFunctionsDomain\n");
6719 r
.in
.domain_handle
= domain_handle
;
6721 status
= dcerpc_samr_TestPrivateFunctionsDomain(p
, tctx
, &r
);
6722 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_NOT_IMPLEMENTED
, "TestPrivateFunctionsDomain");
6727 static bool test_RidToSid(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6728 struct dom_sid
*domain_sid
,
6729 struct policy_handle
*domain_handle
)
6731 struct samr_RidToSid r
;
6734 struct dom_sid
*calc_sid
, *out_sid
;
6735 int rids
[] = { 0, 42, 512, 10200 };
6738 for (i
=0;i
<ARRAY_SIZE(rids
);i
++) {
6739 torture_comment(tctx
, "Testing RidToSid\n");
6741 calc_sid
= dom_sid_dup(tctx
, domain_sid
);
6742 r
.in
.domain_handle
= domain_handle
;
6744 r
.out
.sid
= &out_sid
;
6746 status
= dcerpc_samr_RidToSid(p
, tctx
, &r
);
6747 if (!NT_STATUS_IS_OK(status
)) {
6748 torture_warning(tctx
, "RidToSid for %d failed - %s\n", rids
[i
], nt_errstr(status
));
6751 calc_sid
= dom_sid_add_rid(calc_sid
, calc_sid
, rids
[i
]);
6753 if (!dom_sid_equal(calc_sid
, out_sid
)) {
6754 torture_warning(tctx
, "RidToSid for %d failed - got %s, expected %s\n", rids
[i
],
6755 dom_sid_string(tctx
, out_sid
),
6756 dom_sid_string(tctx
, calc_sid
));
6765 static bool test_GetBootKeyInformation(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6766 struct policy_handle
*domain_handle
)
6768 struct samr_GetBootKeyInformation r
;
6771 uint32_t unknown
= 0;
6773 torture_comment(tctx
, "Testing GetBootKeyInformation\n");
6775 r
.in
.domain_handle
= domain_handle
;
6776 r
.out
.unknown
= &unknown
;
6778 status
= dcerpc_samr_GetBootKeyInformation(p
, tctx
, &r
);
6779 if (!NT_STATUS_IS_OK(status
)) {
6780 /* w2k3 seems to fail this sometimes and pass it sometimes */
6781 torture_comment(tctx
, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status
));
6787 static bool test_AddGroupMember(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6788 struct policy_handle
*domain_handle
,
6789 struct policy_handle
*group_handle
)
6792 struct samr_AddGroupMember r
;
6793 struct samr_DeleteGroupMember d
;
6794 struct samr_QueryGroupMember q
;
6795 struct samr_RidTypeArray
*rids
= NULL
;
6796 struct samr_SetMemberAttributesOfGroup s
;
6798 bool found_member
= false;
6801 status
= test_LookupName(p
, tctx
, domain_handle
, TEST_ACCOUNT_NAME
, &rid
);
6802 torture_assert_ntstatus_ok(tctx
, status
, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME
);
6804 r
.in
.group_handle
= group_handle
;
6806 r
.in
.flags
= 0; /* ??? */
6808 torture_comment(tctx
, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
6810 d
.in
.group_handle
= group_handle
;
6813 status
= dcerpc_samr_DeleteGroupMember(p
, tctx
, &d
);
6814 torture_assert_ntstatus_equal(tctx
, NT_STATUS_MEMBER_NOT_IN_GROUP
, status
, "DeleteGroupMember");
6816 status
= dcerpc_samr_AddGroupMember(p
, tctx
, &r
);
6817 torture_assert_ntstatus_ok(tctx
, status
, "AddGroupMember");
6819 status
= dcerpc_samr_AddGroupMember(p
, tctx
, &r
);
6820 torture_assert_ntstatus_equal(tctx
, NT_STATUS_MEMBER_IN_GROUP
, status
, "AddGroupMember");
6822 if (torture_setting_bool(tctx
, "samba4", false) ||
6823 torture_setting_bool(tctx
, "samba3", false)) {
6824 torture_comment(tctx
, "skipping SetMemberAttributesOfGroup test against Samba\n");
6826 /* this one is quite strange. I am using random inputs in the
6827 hope of triggering an error that might give us a clue */
6829 s
.in
.group_handle
= group_handle
;
6830 s
.in
.unknown1
= random();
6831 s
.in
.unknown2
= random();
6833 status
= dcerpc_samr_SetMemberAttributesOfGroup(p
, tctx
, &s
);
6834 torture_assert_ntstatus_ok(tctx
, status
, "SetMemberAttributesOfGroup");
6837 q
.in
.group_handle
= group_handle
;
6840 status
= dcerpc_samr_QueryGroupMember(p
, tctx
, &q
);
6841 torture_assert_ntstatus_ok(tctx
, status
, "QueryGroupMember");
6842 torture_assert(tctx
, rids
, "QueryGroupMember did not fill in rids structure");
6844 for (i
=0; i
< rids
->count
; i
++) {
6845 if (rids
->rids
[i
] == rid
) {
6846 found_member
= true;
6850 torture_assert(tctx
, found_member
, "QueryGroupMember did not list newly added member");
6852 status
= dcerpc_samr_DeleteGroupMember(p
, tctx
, &d
);
6853 torture_assert_ntstatus_ok(tctx
, status
, "DeleteGroupMember");
6856 found_member
= false;
6858 status
= dcerpc_samr_QueryGroupMember(p
, tctx
, &q
);
6859 torture_assert_ntstatus_ok(tctx
, status
, "QueryGroupMember");
6860 torture_assert(tctx
, rids
, "QueryGroupMember did not fill in rids structure");
6862 for (i
=0; i
< rids
->count
; i
++) {
6863 if (rids
->rids
[i
] == rid
) {
6864 found_member
= true;
6868 torture_assert(tctx
, !found_member
, "QueryGroupMember does still list removed member");
6870 status
= dcerpc_samr_AddGroupMember(p
, tctx
, &r
);
6871 torture_assert_ntstatus_ok(tctx
, status
, "AddGroupMember");
6877 static bool test_CreateDomainGroup(struct dcerpc_pipe
*p
,
6878 struct torture_context
*tctx
,
6879 struct policy_handle
*domain_handle
,
6880 const char *group_name
,
6881 struct policy_handle
*group_handle
,
6882 struct dom_sid
*domain_sid
,
6886 struct samr_CreateDomainGroup r
;
6888 struct lsa_String name
;
6891 init_lsa_String(&name
, group_name
);
6893 r
.in
.domain_handle
= domain_handle
;
6895 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6896 r
.out
.group_handle
= group_handle
;
6899 torture_comment(tctx
, "Testing CreateDomainGroup(%s)\n", r
.in
.name
->string
);
6901 status
= dcerpc_samr_CreateDomainGroup(p
, tctx
, &r
);
6903 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
6904 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
6905 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.name
->string
);
6908 torture_warning(tctx
, "Server should have refused create of '%s', got %s instead\n", r
.in
.name
->string
,
6914 if (NT_STATUS_EQUAL(status
, NT_STATUS_GROUP_EXISTS
)) {
6915 if (!test_DeleteGroup_byname(p
, tctx
, domain_handle
, r
.in
.name
->string
)) {
6916 torture_warning(tctx
, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r
.in
.name
->string
,
6920 status
= dcerpc_samr_CreateDomainGroup(p
, tctx
, &r
);
6922 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_EXISTS
)) {
6923 if (!test_DeleteUser_byname(p
, tctx
, domain_handle
, r
.in
.name
->string
)) {
6925 torture_warning(tctx
, "CreateDomainGroup failed: Could not delete user %s - %s\n", r
.in
.name
->string
,
6929 status
= dcerpc_samr_CreateDomainGroup(p
, tctx
, &r
);
6931 torture_assert_ntstatus_ok(tctx
, status
, "CreateDomainGroup");
6937 if (!test_AddGroupMember(p
, tctx
, domain_handle
, group_handle
)) {
6938 torture_warning(tctx
, "CreateDomainGroup failed - %s\n", nt_errstr(status
));
6942 if (!test_SetGroupInfo(p
, tctx
, group_handle
)) {
6951 its not totally clear what this does. It seems to accept any sid you like.
6953 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe
*p
,
6954 struct torture_context
*tctx
,
6955 struct policy_handle
*domain_handle
)
6958 struct samr_RemoveMemberFromForeignDomain r
;
6960 r
.in
.domain_handle
= domain_handle
;
6961 r
.in
.sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-12-34-56-78");
6963 status
= dcerpc_samr_RemoveMemberFromForeignDomain(p
, tctx
, &r
);
6964 torture_assert_ntstatus_ok(tctx
, status
, "RemoveMemberFromForeignDomain");
6969 static bool test_EnumDomainUsers(struct dcerpc_pipe
*p
,
6970 struct torture_context
*tctx
,
6971 struct policy_handle
*domain_handle
,
6972 uint32_t *total_num_entries_p
)
6975 struct samr_EnumDomainUsers r
;
6976 uint32_t resume_handle
= 0;
6977 uint32_t num_entries
= 0;
6978 uint32_t total_num_entries
= 0;
6979 struct samr_SamArray
*sam
;
6981 r
.in
.domain_handle
= domain_handle
;
6982 r
.in
.acct_flags
= 0;
6983 r
.in
.max_size
= (uint32_t)-1;
6984 r
.in
.resume_handle
= &resume_handle
;
6987 r
.out
.num_entries
= &num_entries
;
6988 r
.out
.resume_handle
= &resume_handle
;
6990 torture_comment(tctx
, "Testing EnumDomainUsers\n");
6993 status
= dcerpc_samr_EnumDomainUsers(p
, tctx
, &r
);
6994 if (NT_STATUS_IS_ERR(status
)) {
6995 torture_assert_ntstatus_ok(tctx
, status
,
6996 "failed to enumerate users");
6999 total_num_entries
+= num_entries
;
7000 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7002 if (total_num_entries_p
) {
7003 *total_num_entries_p
= total_num_entries
;
7009 static bool test_EnumDomainGroups(struct dcerpc_pipe
*p
,
7010 struct torture_context
*tctx
,
7011 struct policy_handle
*domain_handle
,
7012 uint32_t *total_num_entries_p
)
7015 struct samr_EnumDomainGroups r
;
7016 uint32_t resume_handle
= 0;
7017 uint32_t num_entries
= 0;
7018 uint32_t total_num_entries
= 0;
7019 struct samr_SamArray
*sam
;
7021 r
.in
.domain_handle
= domain_handle
;
7022 r
.in
.max_size
= (uint32_t)-1;
7023 r
.in
.resume_handle
= &resume_handle
;
7026 r
.out
.num_entries
= &num_entries
;
7027 r
.out
.resume_handle
= &resume_handle
;
7029 torture_comment(tctx
, "Testing EnumDomainGroups\n");
7032 status
= dcerpc_samr_EnumDomainGroups(p
, tctx
, &r
);
7033 if (NT_STATUS_IS_ERR(status
)) {
7034 torture_assert_ntstatus_ok(tctx
, status
,
7035 "failed to enumerate groups");
7038 total_num_entries
+= num_entries
;
7039 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7041 if (total_num_entries_p
) {
7042 *total_num_entries_p
= total_num_entries
;
7048 static bool test_EnumDomainAliases(struct dcerpc_pipe
*p
,
7049 struct torture_context
*tctx
,
7050 struct policy_handle
*domain_handle
,
7051 uint32_t *total_num_entries_p
)
7054 struct samr_EnumDomainAliases r
;
7055 uint32_t resume_handle
= 0;
7056 uint32_t num_entries
= 0;
7057 uint32_t total_num_entries
= 0;
7058 struct samr_SamArray
*sam
;
7060 r
.in
.domain_handle
= domain_handle
;
7061 r
.in
.max_size
= (uint32_t)-1;
7062 r
.in
.resume_handle
= &resume_handle
;
7065 r
.out
.num_entries
= &num_entries
;
7066 r
.out
.resume_handle
= &resume_handle
;
7068 torture_comment(tctx
, "Testing EnumDomainAliases\n");
7071 status
= dcerpc_samr_EnumDomainAliases(p
, tctx
, &r
);
7072 if (NT_STATUS_IS_ERR(status
)) {
7073 torture_assert_ntstatus_ok(tctx
, status
,
7074 "failed to enumerate aliases");
7077 total_num_entries
+= num_entries
;
7078 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7080 if (total_num_entries_p
) {
7081 *total_num_entries_p
= total_num_entries
;
7087 static bool test_QueryDisplayInfo_level(struct dcerpc_pipe
*p
,
7088 struct torture_context
*tctx
,
7089 struct policy_handle
*handle
,
7091 uint32_t *total_num_entries_p
)
7094 struct samr_QueryDisplayInfo r
;
7095 uint32_t total_num_entries
= 0;
7097 r
.in
.domain_handle
= handle
;
7100 r
.in
.max_entries
= (uint32_t)-1;
7101 r
.in
.buf_size
= (uint32_t)-1;
7103 torture_comment(tctx
, "Testing QueryDisplayInfo\n");
7106 uint32_t total_size
;
7107 uint32_t returned_size
;
7108 union samr_DispInfo info
;
7110 r
.out
.total_size
= &total_size
;
7111 r
.out
.returned_size
= &returned_size
;
7114 status
= dcerpc_samr_QueryDisplayInfo(p
, tctx
, &r
);
7115 if (NT_STATUS_IS_ERR(status
)) {
7116 torture_assert_ntstatus_ok(tctx
, status
,
7117 "failed to query displayinfo");
7120 if (*r
.out
.returned_size
== 0) {
7124 switch (r
.in
.level
) {
7126 total_num_entries
+= info
.info1
.count
;
7127 r
.in
.start_idx
+= info
.info1
.entries
[info
.info1
.count
- 1].idx
+ 1;
7130 total_num_entries
+= info
.info2
.count
;
7131 r
.in
.start_idx
+= info
.info2
.entries
[info
.info2
.count
- 1].idx
+ 1;
7134 total_num_entries
+= info
.info3
.count
;
7135 r
.in
.start_idx
+= info
.info3
.entries
[info
.info3
.count
- 1].idx
+ 1;
7138 total_num_entries
+= info
.info4
.count
;
7139 r
.in
.start_idx
+= info
.info4
.entries
[info
.info4
.count
- 1].idx
+ 1;
7142 total_num_entries
+= info
.info5
.count
;
7143 r
.in
.start_idx
+= info
.info5
.entries
[info
.info5
.count
- 1].idx
+ 1;
7149 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
7151 if (total_num_entries_p
) {
7152 *total_num_entries_p
= total_num_entries
;
7158 static bool test_ManyObjects(struct dcerpc_pipe
*p
,
7159 struct torture_context
*tctx
,
7160 struct policy_handle
*domain_handle
,
7161 struct dom_sid
*domain_sid
,
7162 struct torture_samr_context
*ctx
)
7164 uint32_t num_total
= ctx
->num_objects_large_dc
;
7165 uint32_t num_enum
= 0;
7166 uint32_t num_disp
= 0;
7167 uint32_t num_created
= 0;
7168 uint32_t num_anounced
= 0;
7173 struct policy_handle
*handles
= talloc_zero_array(tctx
, struct policy_handle
, num_total
);
7178 struct samr_QueryDomainInfo2 r
;
7179 union samr_DomainInfo
*info
;
7180 r
.in
.domain_handle
= domain_handle
;
7184 status
= dcerpc_samr_QueryDomainInfo2(p
, tctx
, &r
);
7185 torture_assert_ntstatus_ok(tctx
, status
,
7186 "failed to query domain info");
7188 switch (ctx
->choice
) {
7189 case TORTURE_SAMR_MANY_ACCOUNTS
:
7190 num_anounced
= info
->general
.num_users
;
7192 case TORTURE_SAMR_MANY_GROUPS
:
7193 num_anounced
= info
->general
.num_groups
;
7195 case TORTURE_SAMR_MANY_ALIASES
:
7196 num_anounced
= info
->general
.num_aliases
;
7205 for (i
=0; i
< num_total
; i
++) {
7207 const char *name
= NULL
;
7209 switch (ctx
->choice
) {
7210 case TORTURE_SAMR_MANY_ACCOUNTS
:
7211 name
= talloc_asprintf(tctx
, "%s%04d", TEST_ACCOUNT_NAME
, i
);
7212 ret
&= test_CreateUser(p
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, 0, NULL
, false);
7214 case TORTURE_SAMR_MANY_GROUPS
:
7215 name
= talloc_asprintf(tctx
, "%s%04d", TEST_GROUPNAME
, i
);
7216 ret
&= test_CreateDomainGroup(p
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, false);
7218 case TORTURE_SAMR_MANY_ALIASES
:
7219 name
= talloc_asprintf(tctx
, "%s%04d", TEST_ALIASNAME
, i
);
7220 ret
&= test_CreateAlias(p
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, false);
7225 if (!policy_handle_empty(&handles
[i
])) {
7232 switch (ctx
->choice
) {
7233 case TORTURE_SAMR_MANY_ACCOUNTS
:
7234 ret
&= test_EnumDomainUsers(p
, tctx
, domain_handle
, &num_enum
);
7236 case TORTURE_SAMR_MANY_GROUPS
:
7237 ret
&= test_EnumDomainGroups(p
, tctx
, domain_handle
, &num_enum
);
7239 case TORTURE_SAMR_MANY_ALIASES
:
7240 ret
&= test_EnumDomainAliases(p
, tctx
, domain_handle
, &num_enum
);
7248 switch (ctx
->choice
) {
7249 case TORTURE_SAMR_MANY_ACCOUNTS
:
7250 ret
&= test_QueryDisplayInfo_level(p
, tctx
, domain_handle
, 1, &num_disp
);
7252 case TORTURE_SAMR_MANY_GROUPS
:
7253 ret
&= test_QueryDisplayInfo_level(p
, tctx
, domain_handle
, 3, &num_disp
);
7255 case TORTURE_SAMR_MANY_ALIASES
:
7256 /* no aliases in dispinfo */
7262 /* close or delete */
7264 for (i
=0; i
< num_total
; i
++) {
7266 if (policy_handle_empty(&handles
[i
])) {
7270 if (torture_setting_bool(tctx
, "samba3", false)) {
7271 ret
&= test_samr_handle_Close(p
, tctx
, &handles
[i
]);
7273 switch (ctx
->choice
) {
7274 case TORTURE_SAMR_MANY_ACCOUNTS
:
7275 ret
&= test_DeleteUser(p
, tctx
, &handles
[i
]);
7277 case TORTURE_SAMR_MANY_GROUPS
:
7278 ret
&= test_DeleteDomainGroup(p
, tctx
, &handles
[i
]);
7280 case TORTURE_SAMR_MANY_ALIASES
:
7281 ret
&= test_DeleteAlias(p
, tctx
, &handles
[i
]);
7289 talloc_free(handles
);
7291 if (ctx
->choice
== TORTURE_SAMR_MANY_ACCOUNTS
&& num_enum
!= num_anounced
+ num_created
) {
7292 torture_comment(tctx
,
7293 "unexpected number of results (%u) returned in enum call, expected %u\n",
7294 num_enum
, num_anounced
+ num_created
);
7296 torture_comment(tctx
,
7297 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
7298 num_disp
, num_anounced
+ num_created
);
7303 static bool test_Connect(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7304 struct policy_handle
*handle
);
7306 static bool test_OpenDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7307 struct torture_samr_context
*ctx
, struct dom_sid
*sid
)
7310 struct samr_OpenDomain r
;
7311 struct policy_handle domain_handle
;
7312 struct policy_handle alias_handle
;
7313 struct policy_handle user_handle
;
7314 struct policy_handle group_handle
;
7317 ZERO_STRUCT(alias_handle
);
7318 ZERO_STRUCT(user_handle
);
7319 ZERO_STRUCT(group_handle
);
7320 ZERO_STRUCT(domain_handle
);
7322 torture_comment(tctx
, "Testing OpenDomain of %s\n", dom_sid_string(tctx
, sid
));
7324 r
.in
.connect_handle
= &ctx
->handle
;
7325 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7327 r
.out
.domain_handle
= &domain_handle
;
7329 status
= dcerpc_samr_OpenDomain(p
, tctx
, &r
);
7330 torture_assert_ntstatus_ok(tctx
, status
, "OpenDomain");
7332 /* run the domain tests with the main handle closed - this tests
7333 the servers reference counting */
7334 torture_assert(tctx
, test_samr_handle_Close(p
, tctx
, &ctx
->handle
), "Failed to close SAMR handle");
7336 switch (ctx
->choice
) {
7337 case TORTURE_SAMR_PASSWORDS
:
7338 case TORTURE_SAMR_USER_PRIVILEGES
:
7339 if (!torture_setting_bool(tctx
, "samba3", false)) {
7340 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, NULL
);
7342 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
7344 torture_warning(tctx
, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7347 case TORTURE_SAMR_USER_ATTRIBUTES
:
7348 if (!torture_setting_bool(tctx
, "samba3", false)) {
7349 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, NULL
);
7351 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
7352 /* This test needs 'complex' users to validate */
7353 ret
&= test_QueryDisplayInfo(p
, tctx
, &domain_handle
);
7355 torture_warning(tctx
, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7358 case TORTURE_SAMR_PASSWORDS_PWDLASTSET
:
7359 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
:
7360 case TORTURE_SAMR_PASSWORDS_LOCKOUT
:
7361 if (!torture_setting_bool(tctx
, "samba3", false)) {
7362 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, ctx
->machine_credentials
);
7364 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, ctx
->machine_credentials
, true);
7366 torture_warning(tctx
, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7369 case TORTURE_SAMR_MANY_ACCOUNTS
:
7370 case TORTURE_SAMR_MANY_GROUPS
:
7371 case TORTURE_SAMR_MANY_ALIASES
:
7372 ret
&= test_ManyObjects(p
, tctx
, &domain_handle
, sid
, ctx
);
7374 torture_warning(tctx
, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7377 case TORTURE_SAMR_OTHER
:
7378 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
7380 torture_warning(tctx
, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx
, sid
));
7382 if (!torture_setting_bool(tctx
, "samba3", false)) {
7383 ret
&= test_QuerySecurity(p
, tctx
, &domain_handle
);
7385 ret
&= test_RemoveMemberFromForeignDomain(p
, tctx
, &domain_handle
);
7386 ret
&= test_CreateAlias(p
, tctx
, &domain_handle
, TEST_ALIASNAME
, &alias_handle
, sid
, true);
7387 ret
&= test_CreateDomainGroup(p
, tctx
, &domain_handle
, TEST_GROUPNAME
, &group_handle
, sid
, true);
7388 ret
&= test_GetAliasMembership(p
, tctx
, &domain_handle
);
7389 ret
&= test_QueryDomainInfo(p
, tctx
, &domain_handle
);
7390 ret
&= test_QueryDomainInfo2(p
, tctx
, &domain_handle
);
7391 ret
&= test_EnumDomainUsers_all(p
, tctx
, &domain_handle
);
7392 ret
&= test_EnumDomainUsers_async(p
, tctx
, &domain_handle
);
7393 ret
&= test_EnumDomainGroups_all(p
, tctx
, &domain_handle
);
7394 ret
&= test_EnumDomainAliases_all(p
, tctx
, &domain_handle
);
7395 ret
&= test_QueryDisplayInfo2(p
, tctx
, &domain_handle
);
7396 ret
&= test_QueryDisplayInfo3(p
, tctx
, &domain_handle
);
7397 ret
&= test_QueryDisplayInfo_continue(p
, tctx
, &domain_handle
);
7399 if (torture_setting_bool(tctx
, "samba4", false)) {
7400 torture_comment(tctx
, "skipping GetDisplayEnumerationIndex test against Samba4\n");
7402 ret
&= test_GetDisplayEnumerationIndex(p
, tctx
, &domain_handle
);
7403 ret
&= test_GetDisplayEnumerationIndex2(p
, tctx
, &domain_handle
);
7405 ret
&= test_GroupList(p
, tctx
, &domain_handle
);
7406 ret
&= test_TestPrivateFunctionsDomain(p
, tctx
, &domain_handle
);
7407 ret
&= test_RidToSid(p
, tctx
, sid
, &domain_handle
);
7408 ret
&= test_GetBootKeyInformation(p
, tctx
, &domain_handle
);
7410 torture_comment(tctx
, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx
, sid
));
7415 if (!policy_handle_empty(&user_handle
) &&
7416 !test_DeleteUser(p
, tctx
, &user_handle
)) {
7420 if (!policy_handle_empty(&alias_handle
) &&
7421 !test_DeleteAlias(p
, tctx
, &alias_handle
)) {
7425 if (!policy_handle_empty(&group_handle
) &&
7426 !test_DeleteDomainGroup(p
, tctx
, &group_handle
)) {
7430 torture_assert(tctx
, test_samr_handle_Close(p
, tctx
, &domain_handle
), "Failed to close SAMR domain handle");
7432 torture_assert(tctx
, test_Connect(p
, tctx
, &ctx
->handle
), "Faile to re-connect SAMR handle");
7433 /* reconnect the main handle */
7436 torture_warning(tctx
, "Testing domain %s failed!\n", dom_sid_string(tctx
, sid
));
7442 static bool test_LookupDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7443 struct torture_samr_context
*ctx
, const char *domain
)
7446 struct samr_LookupDomain r
;
7447 struct dom_sid2
*sid
= NULL
;
7448 struct lsa_String n1
;
7449 struct lsa_String n2
;
7452 torture_comment(tctx
, "Testing LookupDomain(%s)\n", domain
);
7454 /* check for correct error codes */
7455 r
.in
.connect_handle
= &ctx
->handle
;
7456 r
.in
.domain_name
= &n2
;
7460 status
= dcerpc_samr_LookupDomain(p
, tctx
, &r
);
7461 torture_assert_ntstatus_equal(tctx
, NT_STATUS_INVALID_PARAMETER
, status
, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
7463 init_lsa_String(&n2
, "xxNODOMAINxx");
7465 status
= dcerpc_samr_LookupDomain(p
, tctx
, &r
);
7466 torture_assert_ntstatus_equal(tctx
, NT_STATUS_NO_SUCH_DOMAIN
, status
, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
7468 r
.in
.connect_handle
= &ctx
->handle
;
7470 init_lsa_String(&n1
, domain
);
7471 r
.in
.domain_name
= &n1
;
7473 status
= dcerpc_samr_LookupDomain(p
, tctx
, &r
);
7474 torture_assert_ntstatus_ok(tctx
, status
, "LookupDomain");
7476 if (!test_GetDomPwInfo(p
, tctx
, &n1
)) {
7480 if (!test_OpenDomain(p
, tctx
, ctx
, *r
.out
.sid
)) {
7488 static bool test_EnumDomains(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7489 struct torture_samr_context
*ctx
)
7492 struct samr_EnumDomains r
;
7493 uint32_t resume_handle
= 0;
7494 uint32_t num_entries
= 0;
7495 struct samr_SamArray
*sam
= NULL
;
7499 r
.in
.connect_handle
= &ctx
->handle
;
7500 r
.in
.resume_handle
= &resume_handle
;
7501 r
.in
.buf_size
= (uint32_t)-1;
7502 r
.out
.resume_handle
= &resume_handle
;
7503 r
.out
.num_entries
= &num_entries
;
7506 status
= dcerpc_samr_EnumDomains(p
, tctx
, &r
);
7507 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomains");
7513 for (i
=0;i
<sam
->count
;i
++) {
7514 if (!test_LookupDomain(p
, tctx
, ctx
,
7515 sam
->entries
[i
].name
.string
)) {
7520 status
= dcerpc_samr_EnumDomains(p
, tctx
, &r
);
7521 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomains");
7527 static bool test_Connect(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7528 struct policy_handle
*handle
)
7531 struct samr_Connect r
;
7532 struct samr_Connect2 r2
;
7533 struct samr_Connect3 r3
;
7534 struct samr_Connect4 r4
;
7535 struct samr_Connect5 r5
;
7536 union samr_ConnectInfo info
;
7537 struct policy_handle h
;
7538 uint32_t level_out
= 0;
7539 bool ret
= true, got_handle
= false;
7541 torture_comment(tctx
, "testing samr_Connect\n");
7543 r
.in
.system_name
= 0;
7544 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7545 r
.out
.connect_handle
= &h
;
7547 status
= dcerpc_samr_Connect(p
, tctx
, &r
);
7548 if (!NT_STATUS_IS_OK(status
)) {
7549 torture_comment(tctx
, "Connect failed - %s\n", nt_errstr(status
));
7556 torture_comment(tctx
, "testing samr_Connect2\n");
7558 r2
.in
.system_name
= NULL
;
7559 r2
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7560 r2
.out
.connect_handle
= &h
;
7562 status
= dcerpc_samr_Connect2(p
, tctx
, &r2
);
7563 if (!NT_STATUS_IS_OK(status
)) {
7564 torture_comment(tctx
, "Connect2 failed - %s\n", nt_errstr(status
));
7568 test_samr_handle_Close(p
, tctx
, handle
);
7574 torture_comment(tctx
, "testing samr_Connect3\n");
7576 r3
.in
.system_name
= NULL
;
7578 r3
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7579 r3
.out
.connect_handle
= &h
;
7581 status
= dcerpc_samr_Connect3(p
, tctx
, &r3
);
7582 if (!NT_STATUS_IS_OK(status
)) {
7583 torture_warning(tctx
, "Connect3 failed - %s\n", nt_errstr(status
));
7587 test_samr_handle_Close(p
, tctx
, handle
);
7593 torture_comment(tctx
, "testing samr_Connect4\n");
7595 r4
.in
.system_name
= "";
7596 r4
.in
.client_version
= 0;
7597 r4
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7598 r4
.out
.connect_handle
= &h
;
7600 status
= dcerpc_samr_Connect4(p
, tctx
, &r4
);
7601 if (!NT_STATUS_IS_OK(status
)) {
7602 torture_warning(tctx
, "Connect4 failed - %s\n", nt_errstr(status
));
7606 test_samr_handle_Close(p
, tctx
, handle
);
7612 torture_comment(tctx
, "testing samr_Connect5\n");
7614 info
.info1
.client_version
= 0;
7615 info
.info1
.unknown2
= 0;
7617 r5
.in
.system_name
= "";
7618 r5
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7620 r5
.out
.level_out
= &level_out
;
7621 r5
.in
.info_in
= &info
;
7622 r5
.out
.info_out
= &info
;
7623 r5
.out
.connect_handle
= &h
;
7625 status
= dcerpc_samr_Connect5(p
, tctx
, &r5
);
7626 if (!NT_STATUS_IS_OK(status
)) {
7627 torture_warning(tctx
, "Connect5 failed - %s\n", nt_errstr(status
));
7631 test_samr_handle_Close(p
, tctx
, handle
);
7641 static bool test_samr_ValidatePassword(struct dcerpc_pipe
*p
, struct torture_context
*tctx
)
7643 struct samr_ValidatePassword r
;
7644 union samr_ValidatePasswordReq req
;
7645 union samr_ValidatePasswordRep
*repp
= NULL
;
7647 const char *passwords
[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL
};
7650 torture_comment(tctx
, "testing samr_ValidatePassword\n");
7653 r
.in
.level
= NetValidatePasswordReset
;
7658 req
.req3
.account
.string
= "non-existant-account-aklsdji";
7660 for (i
=0; passwords
[i
]; i
++) {
7661 req
.req3
.password
.string
= passwords
[i
];
7662 status
= dcerpc_samr_ValidatePassword(p
, tctx
, &r
);
7663 if (NT_STATUS_EQUAL(status
, NT_STATUS_NET_WRITE_FAULT
) &&
7664 p
->last_fault_code
== DCERPC_FAULT_OP_RNG_ERROR
) {
7665 torture_skip(tctx
, "ValidatePassword not supported by server\n");
7667 torture_assert_ntstatus_ok(tctx
, status
, "samr_ValidatePassword");
7668 torture_comment(tctx
, "Server %s password '%s' with code %i\n",
7669 repp
->ctr3
.status
==SAMR_VALIDATION_STATUS_SUCCESS
?"allowed":"refused",
7670 req
.req3
.password
.string
, repp
->ctr3
.status
);
7676 bool torture_rpc_samr(struct torture_context
*torture
)
7679 struct dcerpc_pipe
*p
;
7681 struct torture_samr_context
*ctx
;
7683 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7684 if (!NT_STATUS_IS_OK(status
)) {
7688 ctx
= talloc_zero(torture
, struct torture_samr_context
);
7690 ctx
->choice
= TORTURE_SAMR_OTHER
;
7692 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
7694 if (!torture_setting_bool(torture
, "samba3", false)) {
7695 ret
&= test_QuerySecurity(p
, torture
, &ctx
->handle
);
7698 ret
&= test_EnumDomains(p
, torture
, ctx
);
7700 ret
&= test_SetDsrmPassword(p
, torture
, &ctx
->handle
);
7702 ret
&= test_Shutdown(p
, torture
, &ctx
->handle
);
7704 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
7710 bool torture_rpc_samr_users(struct torture_context
*torture
)
7713 struct dcerpc_pipe
*p
;
7715 struct torture_samr_context
*ctx
;
7717 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7718 if (!NT_STATUS_IS_OK(status
)) {
7722 ctx
= talloc_zero(torture
, struct torture_samr_context
);
7724 ctx
->choice
= TORTURE_SAMR_USER_ATTRIBUTES
;
7726 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
7728 if (!torture_setting_bool(torture
, "samba3", false)) {
7729 ret
&= test_QuerySecurity(p
, torture
, &ctx
->handle
);
7732 ret
&= test_EnumDomains(p
, torture
, ctx
);
7734 ret
&= test_SetDsrmPassword(p
, torture
, &ctx
->handle
);
7736 ret
&= test_Shutdown(p
, torture
, &ctx
->handle
);
7738 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
7744 bool torture_rpc_samr_passwords(struct torture_context
*torture
)
7747 struct dcerpc_pipe
*p
;
7749 struct torture_samr_context
*ctx
;
7751 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7752 if (!NT_STATUS_IS_OK(status
)) {
7756 ctx
= talloc_zero(torture
, struct torture_samr_context
);
7758 ctx
->choice
= TORTURE_SAMR_PASSWORDS
;
7760 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
7762 ret
&= test_EnumDomains(p
, torture
, ctx
);
7764 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
7766 ret
&= test_samr_ValidatePassword(p
, torture
);
7771 static bool torture_rpc_samr_pwdlastset(struct torture_context
*torture
,
7772 struct dcerpc_pipe
*p2
,
7773 struct cli_credentials
*machine_credentials
)
7776 struct dcerpc_pipe
*p
;
7778 struct torture_samr_context
*ctx
;
7780 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7781 if (!NT_STATUS_IS_OK(status
)) {
7785 ctx
= talloc_zero(torture
, struct torture_samr_context
);
7787 ctx
->choice
= TORTURE_SAMR_PASSWORDS_PWDLASTSET
;
7788 ctx
->machine_credentials
= machine_credentials
;
7790 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
7792 ret
&= test_EnumDomains(p
, torture
, ctx
);
7794 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
7799 struct torture_suite
*torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX
*mem_ctx
)
7801 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "SAMR-PASSWORDS-PWDLASTSET");
7802 struct torture_rpc_tcase
*tcase
;
7804 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
7806 TEST_ACCOUNT_NAME_PWD
);
7808 torture_rpc_tcase_add_test_creds(tcase
, "pwdLastSet",
7809 torture_rpc_samr_pwdlastset
);
7814 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context
*torture
,
7815 struct dcerpc_pipe
*p2
,
7816 struct cli_credentials
*machine_credentials
)
7819 struct dcerpc_pipe
*p
;
7821 struct torture_samr_context
*ctx
;
7823 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7824 if (!NT_STATUS_IS_OK(status
)) {
7828 ctx
= talloc_zero(torture
, struct torture_samr_context
);
7830 ctx
->choice
= TORTURE_SAMR_USER_PRIVILEGES
;
7831 ctx
->machine_credentials
= machine_credentials
;
7833 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
7835 ret
&= test_EnumDomains(p
, torture
, ctx
);
7837 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
7842 struct torture_suite
*torture_rpc_samr_user_privileges(TALLOC_CTX
*mem_ctx
)
7844 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "SAMR-USERS-PRIVILEGES");
7845 struct torture_rpc_tcase
*tcase
;
7847 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
7849 TEST_ACCOUNT_NAME_PWD
);
7851 torture_rpc_tcase_add_test_creds(tcase
, "delete_privileged_user",
7852 torture_rpc_samr_users_privileges_delete_user
);
7857 static bool torture_rpc_samr_many_accounts(struct torture_context
*torture
,
7858 struct dcerpc_pipe
*p2
,
7862 struct dcerpc_pipe
*p
;
7864 struct torture_samr_context
*ctx
=
7865 talloc_get_type_abort(data
, struct torture_samr_context
);
7867 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7868 if (!NT_STATUS_IS_OK(status
)) {
7872 ctx
->choice
= TORTURE_SAMR_MANY_ACCOUNTS
;
7873 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
7874 ctx
->num_objects_large_dc
);
7876 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
7878 ret
&= test_EnumDomains(p
, torture
, ctx
);
7880 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
7885 static bool torture_rpc_samr_many_groups(struct torture_context
*torture
,
7886 struct dcerpc_pipe
*p2
,
7890 struct dcerpc_pipe
*p
;
7892 struct torture_samr_context
*ctx
=
7893 talloc_get_type_abort(data
, struct torture_samr_context
);
7895 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7896 if (!NT_STATUS_IS_OK(status
)) {
7900 ctx
->choice
= TORTURE_SAMR_MANY_GROUPS
;
7901 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
7902 ctx
->num_objects_large_dc
);
7904 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
7906 ret
&= test_EnumDomains(p
, torture
, ctx
);
7908 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
7913 static bool torture_rpc_samr_many_aliases(struct torture_context
*torture
,
7914 struct dcerpc_pipe
*p2
,
7918 struct dcerpc_pipe
*p
;
7920 struct torture_samr_context
*ctx
=
7921 talloc_get_type_abort(data
, struct torture_samr_context
);
7923 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7924 if (!NT_STATUS_IS_OK(status
)) {
7928 ctx
->choice
= TORTURE_SAMR_MANY_ALIASES
;
7929 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
7930 ctx
->num_objects_large_dc
);
7932 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
7934 ret
&= test_EnumDomains(p
, torture
, ctx
);
7936 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
7941 struct torture_suite
*torture_rpc_samr_large_dc(TALLOC_CTX
*mem_ctx
)
7943 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "SAMR-LARGE-DC");
7944 struct torture_rpc_tcase
*tcase
;
7945 struct torture_samr_context
*ctx
;
7947 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "samr", &ndr_table_samr
);
7949 ctx
= talloc_zero(suite
, struct torture_samr_context
);
7950 ctx
->num_objects_large_dc
= 150;
7952 torture_rpc_tcase_add_test_ex(tcase
, "many_aliases",
7953 torture_rpc_samr_many_aliases
, ctx
);
7954 torture_rpc_tcase_add_test_ex(tcase
, "many_groups",
7955 torture_rpc_samr_many_groups
, ctx
);
7956 torture_rpc_tcase_add_test_ex(tcase
, "many_accounts",
7957 torture_rpc_samr_many_accounts
, ctx
);
7962 static bool torture_rpc_samr_badpwdcount(struct torture_context
*torture
,
7963 struct dcerpc_pipe
*p2
,
7964 struct cli_credentials
*machine_credentials
)
7967 struct dcerpc_pipe
*p
;
7969 struct torture_samr_context
*ctx
;
7971 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
7972 if (!NT_STATUS_IS_OK(status
)) {
7976 ctx
= talloc_zero(torture
, struct torture_samr_context
);
7978 ctx
->choice
= TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
;
7979 ctx
->machine_credentials
= machine_credentials
;
7981 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
7983 ret
&= test_EnumDomains(p
, torture
, ctx
);
7985 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
7990 struct torture_suite
*torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX
*mem_ctx
)
7992 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "SAMR-PASSWORDS-BADPWDCOUNT");
7993 struct torture_rpc_tcase
*tcase
;
7995 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
7997 TEST_ACCOUNT_NAME_PWD
);
7999 torture_rpc_tcase_add_test_creds(tcase
, "badPwdCount",
8000 torture_rpc_samr_badpwdcount
);
8005 static bool torture_rpc_samr_lockout(struct torture_context
*torture
,
8006 struct dcerpc_pipe
*p2
,
8007 struct cli_credentials
*machine_credentials
)
8010 struct dcerpc_pipe
*p
;
8012 struct torture_samr_context
*ctx
;
8014 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
8015 if (!NT_STATUS_IS_OK(status
)) {
8019 ctx
= talloc_zero(torture
, struct torture_samr_context
);
8021 ctx
->choice
= TORTURE_SAMR_PASSWORDS_LOCKOUT
;
8022 ctx
->machine_credentials
= machine_credentials
;
8024 ret
&= test_Connect(p
, torture
, &ctx
->handle
);
8026 ret
&= test_EnumDomains(p
, torture
, ctx
);
8028 ret
&= test_samr_handle_Close(p
, torture
, &ctx
->handle
);
8033 struct torture_suite
*torture_rpc_samr_passwords_lockout(TALLOC_CTX
*mem_ctx
)
8035 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "SAMR-PASSWORDS-LOCKOUT");
8036 struct torture_rpc_tcase
*tcase
;
8038 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
8040 TEST_ACCOUNT_NAME_PWD
);
8042 torture_rpc_tcase_add_test_creds(tcase
, "lockout",
8043 torture_rpc_samr_lockout
);