2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7 Copyright (C) Jelmer Vernooij 2005-2007
8 Copyright (C) Guenther Deschner 2008-2010
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "torture/torture.h"
27 #include "system/time.h"
28 #include "system/network.h"
29 #include "librpc/gen_ndr/lsa.h"
30 #include "librpc/gen_ndr/ndr_netlogon.h"
31 #include "librpc/gen_ndr/ndr_netlogon_c.h"
32 #include "librpc/gen_ndr/ndr_samr_c.h"
33 #include "librpc/gen_ndr/ndr_lsa_c.h"
34 #include "lib/crypto/crypto.h"
35 #include "libcli/auth/libcli_auth.h"
36 #include "libcli/security/security.h"
37 #include "torture/rpc/torture_rpc.h"
38 #include "param/param.h"
39 #include "auth/gensec/gensec.h"
40 #include "auth/gensec/gensec_proto.h"
41 #include "../libcli/auth/schannel.h"
42 #include "torture/util.h"
43 #include "source4/librpc/rpc/dcerpc.h"
44 #include "librpc/rpc/dcerpc_samr.h"
45 #include "source3/rpc_client/init_samr.h"
46 #include "lib/crypto/gnutls_helpers.h"
50 #define TEST_ACCOUNT_NAME "samrtorturetest"
51 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
52 #define TEST_ALIASNAME "samrtorturetestalias"
53 #define TEST_GROUPNAME "samrtorturetestgroup"
54 #define TEST_MACHINENAME "samrtestmach$"
55 #define TEST_DOMAINNAME "samrtestdom$"
57 #include <gnutls/gnutls.h>
58 #include <gnutls/crypto.h>
60 enum torture_samr_choice
{
61 TORTURE_SAMR_PASSWORDS
,
62 TORTURE_SAMR_PASSWORDS_PWDLASTSET
,
63 TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
,
64 TORTURE_SAMR_PASSWORDS_LOCKOUT
,
65 TORTURE_SAMR_USER_ATTRIBUTES
,
66 TORTURE_SAMR_USER_PRIVILEGES
,
68 TORTURE_SAMR_MANY_ACCOUNTS
,
69 TORTURE_SAMR_MANY_GROUPS
,
70 TORTURE_SAMR_MANY_ALIASES
73 struct torture_samr_context
{
74 struct policy_handle handle
;
75 struct cli_credentials
*machine_credentials
;
76 enum torture_samr_choice choice
;
77 uint32_t num_objects_large_dc
;
80 static bool test_QueryUserInfo(struct dcerpc_binding_handle
*b
,
81 struct torture_context
*tctx
,
82 struct policy_handle
*handle
);
84 static bool test_QueryUserInfo2(struct dcerpc_binding_handle
*b
,
85 struct torture_context
*tctx
,
86 struct policy_handle
*handle
);
88 static bool test_QueryAliasInfo(struct dcerpc_binding_handle
*b
,
89 struct torture_context
*tctx
,
90 struct policy_handle
*handle
);
92 static bool test_ChangePassword(struct dcerpc_pipe
*p
,
93 struct torture_context
*tctx
,
94 const char *acct_name
,
95 struct policy_handle
*domain_handle
, char **password
);
97 static void init_lsa_String(struct lsa_String
*string
, const char *s
)
102 static void init_lsa_StringLarge(struct lsa_StringLarge
*string
, const char *s
)
107 static void init_lsa_BinaryString(struct lsa_BinaryString
*string
, const char *s
, uint32_t length
)
109 string
->length
= length
;
110 string
->size
= length
;
111 string
->array
= (uint16_t *)discard_const(s
);
114 bool test_samr_handle_Close(struct dcerpc_binding_handle
*b
,
115 struct torture_context
*tctx
,
116 struct policy_handle
*handle
)
120 r
.in
.handle
= handle
;
121 r
.out
.handle
= handle
;
123 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Close_r(b
, tctx
, &r
),
125 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "Close failed");
130 static bool test_Shutdown(struct dcerpc_binding_handle
*b
,
131 struct torture_context
*tctx
,
132 struct policy_handle
*handle
)
134 struct samr_Shutdown r
;
136 if (!torture_setting_bool(tctx
, "dangerous", false)) {
137 torture_skip(tctx
, "samr_Shutdown disabled - enable dangerous tests to use\n");
141 r
.in
.connect_handle
= handle
;
143 torture_comment(tctx
, "Testing samr_Shutdown\n");
145 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Shutdown_r(b
, tctx
, &r
),
147 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "Shutdown failed");
152 static bool test_SetDsrmPassword(struct dcerpc_binding_handle
*b
,
153 struct torture_context
*tctx
,
154 struct policy_handle
*handle
)
156 struct samr_SetDsrmPassword r
;
157 struct lsa_String string
;
158 struct samr_Password hash
;
160 if (!torture_setting_bool(tctx
, "dangerous", false)) {
161 torture_skip(tctx
, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
164 E_md4hash("TeSTDSRM123", hash
.hash
);
166 init_lsa_String(&string
, "Administrator");
172 torture_comment(tctx
, "Testing samr_SetDsrmPassword\n");
174 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDsrmPassword_r(b
, tctx
, &r
),
175 "SetDsrmPassword failed");
176 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_NOT_SUPPORTED
, "SetDsrmPassword failed");
182 static bool test_QuerySecurity(struct dcerpc_binding_handle
*b
,
183 struct torture_context
*tctx
,
184 struct policy_handle
*handle
)
186 struct samr_QuerySecurity r
;
187 struct samr_SetSecurity s
;
188 struct sec_desc_buf
*sdbuf
= NULL
;
190 r
.in
.handle
= handle
;
192 r
.out
.sdbuf
= &sdbuf
;
194 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QuerySecurity_r(b
, tctx
, &r
),
195 "QuerySecurity failed");
196 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "QuerySecurity failed");
198 torture_assert(tctx
, sdbuf
!= NULL
, "sdbuf is NULL");
200 s
.in
.handle
= handle
;
204 if (torture_setting_bool(tctx
, "samba4", false)) {
205 torture_skip(tctx
, "skipping SetSecurity test against Samba4\n");
208 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetSecurity_r(b
, tctx
, &s
),
209 "SetSecurity failed");
210 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "SetSecurity failed");
212 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QuerySecurity_r(b
, tctx
, &r
),
213 "QuerySecurity failed");
214 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "QuerySecurity failed");
220 static bool test_SetUserInfo(struct dcerpc_binding_handle
*b
, struct torture_context
*tctx
,
221 struct policy_handle
*handle
, uint32_t base_acct_flags
,
222 const char *base_account_name
)
224 struct samr_SetUserInfo s
;
225 struct samr_SetUserInfo2 s2
;
226 struct samr_QueryUserInfo q
;
227 struct samr_QueryUserInfo q0
;
228 union samr_UserInfo u
;
229 union samr_UserInfo
*info
;
231 const char *test_account_name
;
233 uint32_t user_extra_flags
= 0;
235 if (!torture_setting_bool(tctx
, "samba3", false)) {
236 if (base_acct_flags
== ACB_NORMAL
) {
237 /* When created, accounts are expired by default */
238 user_extra_flags
= ACB_PW_EXPIRED
;
242 s
.in
.user_handle
= handle
;
245 s2
.in
.user_handle
= handle
;
248 q
.in
.user_handle
= handle
;
252 #define TESTCALL(call, r) \
253 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ ##call## _r(b, tctx, &r),\
255 if (!NT_STATUS_IS_OK(r.out.result)) { \
256 torture_result(tctx, TORTURE_FAIL, #call " level %u failed - %s (%s)\n", \
257 r.in.level, nt_errstr(r.out.result), __location__); \
262 #define STRING_EQUAL(s1, s2, field) \
263 torture_assert_str_equal(tctx, s1, s2, "Failed to set " #field)
265 #define MEM_EQUAL(s1, s2, length, field) \
266 torture_assert_mem_equal(tctx, s1, s2, length, "Failed to set " #field)
268 #define INT_EQUAL(i1, i2, field) \
269 torture_assert_int_equal(tctx, i1, i2, "Failed to set " #field)
271 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
272 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
274 TESTCALL(QueryUserInfo, q) \
276 s2.in.level = lvl1; \
279 ZERO_STRUCT(u.info21); \
280 u.info21.fields_present = fpval; \
282 init_lsa_String(&u.info ## lvl1.field1, value); \
283 TESTCALL(SetUserInfo, s) \
284 TESTCALL(SetUserInfo2, s2) \
285 init_lsa_String(&u.info ## lvl1.field1, ""); \
286 TESTCALL(QueryUserInfo, q); \
288 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
290 TESTCALL(QueryUserInfo, q) \
292 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
295 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
296 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
298 TESTCALL(QueryUserInfo, q) \
300 s2.in.level = lvl1; \
303 ZERO_STRUCT(u.info21); \
304 u.info21.fields_present = fpval; \
306 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
307 TESTCALL(SetUserInfo, s) \
308 TESTCALL(SetUserInfo2, s2) \
309 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
310 TESTCALL(QueryUserInfo, q); \
312 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
314 TESTCALL(QueryUserInfo, q) \
316 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
319 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
320 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
322 TESTCALL(QueryUserInfo, q) \
324 s2.in.level = lvl1; \
327 uint8_t *bits = u.info21.logon_hours.bits; \
328 ZERO_STRUCT(u.info21); \
329 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
330 u.info21.logon_hours.units_per_week = 168; \
331 u.info21.logon_hours.bits = bits; \
333 u.info21.fields_present = fpval; \
335 u.info ## lvl1.field1 = value; \
336 TESTCALL(SetUserInfo, s) \
337 TESTCALL(SetUserInfo2, s2) \
338 u.info ## lvl1.field1 = 0; \
339 TESTCALL(QueryUserInfo, q); \
341 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
343 TESTCALL(QueryUserInfo, q) \
345 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
348 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
349 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
353 do { TESTCALL(QueryUserInfo
, q0
) } while (0);
355 TEST_USERINFO_STRING(2, comment
, 1, comment
, "xx2-1 comment", 0);
356 TEST_USERINFO_STRING(2, comment
, 21, comment
, "xx2-21 comment", 0);
357 TEST_USERINFO_STRING(21, comment
, 21, comment
, "xx21-21 comment",
360 test_account_name
= talloc_asprintf(tctx
, "%sxx7-1", base_account_name
);
361 TEST_USERINFO_STRING(7, account_name
, 1, account_name
, test_account_name
, 0);
362 test_account_name
= talloc_asprintf(tctx
, "%sxx7-3", base_account_name
);
363 TEST_USERINFO_STRING(7, account_name
, 3, account_name
, test_account_name
, 0);
364 test_account_name
= talloc_asprintf(tctx
, "%sxx7-5", base_account_name
);
365 TEST_USERINFO_STRING(7, account_name
, 5, account_name
, test_account_name
, 0);
366 test_account_name
= talloc_asprintf(tctx
, "%sxx7-6", base_account_name
);
367 TEST_USERINFO_STRING(7, account_name
, 6, account_name
, test_account_name
, 0);
368 test_account_name
= talloc_asprintf(tctx
, "%sxx7-7", base_account_name
);
369 TEST_USERINFO_STRING(7, account_name
, 7, account_name
, test_account_name
, 0);
370 test_account_name
= talloc_asprintf(tctx
, "%sxx7-21", base_account_name
);
371 TEST_USERINFO_STRING(7, account_name
, 21, account_name
, test_account_name
, 0);
372 test_account_name
= base_account_name
;
373 TEST_USERINFO_STRING(21, account_name
, 21, account_name
, test_account_name
,
374 SAMR_FIELD_ACCOUNT_NAME
);
376 TEST_USERINFO_STRING(6, full_name
, 1, full_name
, "xx6-1 full_name", 0);
377 TEST_USERINFO_STRING(6, full_name
, 3, full_name
, "xx6-3 full_name", 0);
378 TEST_USERINFO_STRING(6, full_name
, 5, full_name
, "xx6-5 full_name", 0);
379 TEST_USERINFO_STRING(6, full_name
, 6, full_name
, "xx6-6 full_name", 0);
380 TEST_USERINFO_STRING(6, full_name
, 8, full_name
, "xx6-8 full_name", 0);
381 TEST_USERINFO_STRING(6, full_name
, 21, full_name
, "xx6-21 full_name", 0);
382 TEST_USERINFO_STRING(8, full_name
, 21, full_name
, "xx8-21 full_name", 0);
383 TEST_USERINFO_STRING(21, full_name
, 21, full_name
, "xx21-21 full_name",
384 SAMR_FIELD_FULL_NAME
);
386 TEST_USERINFO_STRING(6, full_name
, 1, full_name
, "", 0);
387 TEST_USERINFO_STRING(6, full_name
, 3, full_name
, "", 0);
388 TEST_USERINFO_STRING(6, full_name
, 5, full_name
, "", 0);
389 TEST_USERINFO_STRING(6, full_name
, 6, full_name
, "", 0);
390 TEST_USERINFO_STRING(6, full_name
, 8, full_name
, "", 0);
391 TEST_USERINFO_STRING(6, full_name
, 21, full_name
, "", 0);
392 TEST_USERINFO_STRING(8, full_name
, 21, full_name
, "", 0);
393 TEST_USERINFO_STRING(21, full_name
, 21, full_name
, "",
394 SAMR_FIELD_FULL_NAME
);
396 TEST_USERINFO_STRING(11, logon_script
, 3, logon_script
, "xx11-3 logon_script", 0);
397 TEST_USERINFO_STRING(11, logon_script
, 5, logon_script
, "xx11-5 logon_script", 0);
398 TEST_USERINFO_STRING(11, logon_script
, 21, logon_script
, "xx11-21 logon_script", 0);
399 TEST_USERINFO_STRING(21, logon_script
, 21, logon_script
, "xx21-21 logon_script",
400 SAMR_FIELD_LOGON_SCRIPT
);
402 TEST_USERINFO_STRING(12, profile_path
, 3, profile_path
, "xx12-3 profile_path", 0);
403 TEST_USERINFO_STRING(12, profile_path
, 5, profile_path
, "xx12-5 profile_path", 0);
404 TEST_USERINFO_STRING(12, profile_path
, 21, profile_path
, "xx12-21 profile_path", 0);
405 TEST_USERINFO_STRING(21, profile_path
, 21, profile_path
, "xx21-21 profile_path",
406 SAMR_FIELD_PROFILE_PATH
);
408 TEST_USERINFO_STRING(10, home_directory
, 3, home_directory
, "xx10-3 home_directory", 0);
409 TEST_USERINFO_STRING(10, home_directory
, 5, home_directory
, "xx10-5 home_directory", 0);
410 TEST_USERINFO_STRING(10, home_directory
, 21, home_directory
, "xx10-21 home_directory", 0);
411 TEST_USERINFO_STRING(21, home_directory
, 21, home_directory
, "xx21-21 home_directory",
412 SAMR_FIELD_HOME_DIRECTORY
);
413 TEST_USERINFO_STRING(21, home_directory
, 10, home_directory
, "xx21-10 home_directory",
414 SAMR_FIELD_HOME_DIRECTORY
);
416 TEST_USERINFO_STRING(10, home_drive
, 3, home_drive
, "xx10-3 home_drive", 0);
417 TEST_USERINFO_STRING(10, home_drive
, 5, home_drive
, "xx10-5 home_drive", 0);
418 TEST_USERINFO_STRING(10, home_drive
, 21, home_drive
, "xx10-21 home_drive", 0);
419 TEST_USERINFO_STRING(21, home_drive
, 21, home_drive
, "xx21-21 home_drive",
420 SAMR_FIELD_HOME_DRIVE
);
421 TEST_USERINFO_STRING(21, home_drive
, 10, home_drive
, "xx21-10 home_drive",
422 SAMR_FIELD_HOME_DRIVE
);
424 TEST_USERINFO_STRING(13, description
, 1, description
, "xx13-1 description", 0);
425 TEST_USERINFO_STRING(13, description
, 5, description
, "xx13-5 description", 0);
426 TEST_USERINFO_STRING(13, description
, 21, description
, "xx13-21 description", 0);
427 TEST_USERINFO_STRING(21, description
, 21, description
, "xx21-21 description",
428 SAMR_FIELD_DESCRIPTION
);
430 TEST_USERINFO_STRING(14, workstations
, 3, workstations
, "14workstation3", 0);
431 TEST_USERINFO_STRING(14, workstations
, 5, workstations
, "14workstation4", 0);
432 TEST_USERINFO_STRING(14, workstations
, 21, workstations
, "14workstation21", 0);
433 TEST_USERINFO_STRING(21, workstations
, 21, workstations
, "21workstation21",
434 SAMR_FIELD_WORKSTATIONS
);
435 TEST_USERINFO_STRING(21, workstations
, 3, workstations
, "21workstation3",
436 SAMR_FIELD_WORKSTATIONS
);
437 TEST_USERINFO_STRING(21, workstations
, 5, workstations
, "21workstation5",
438 SAMR_FIELD_WORKSTATIONS
);
439 TEST_USERINFO_STRING(21, workstations
, 14, workstations
, "21workstation14",
440 SAMR_FIELD_WORKSTATIONS
);
442 TEST_USERINFO_BINARYSTRING(20, parameters
, 21, parameters
, "xx20-21 parameters", 0);
443 TEST_USERINFO_BINARYSTRING(21, parameters
, 21, parameters
, "xx21-21 parameters",
444 SAMR_FIELD_PARAMETERS
);
445 TEST_USERINFO_BINARYSTRING(21, parameters
, 20, parameters
, "xx21-20 parameters",
446 SAMR_FIELD_PARAMETERS
);
447 /* also empty user parameters are allowed */
448 TEST_USERINFO_BINARYSTRING(20, parameters
, 21, parameters
, "", 0);
449 TEST_USERINFO_BINARYSTRING(21, parameters
, 21, parameters
, "",
450 SAMR_FIELD_PARAMETERS
);
451 TEST_USERINFO_BINARYSTRING(21, parameters
, 20, parameters
, "",
452 SAMR_FIELD_PARAMETERS
);
454 /* Samba 3 cannot store country_code and code_page atm. - gd */
455 if (!torture_setting_bool(tctx
, "samba3", false)) {
456 TEST_USERINFO_INT(2, country_code
, 2, country_code
, __LINE__
, 0);
457 TEST_USERINFO_INT(2, country_code
, 21, country_code
, __LINE__
, 0);
458 TEST_USERINFO_INT(21, country_code
, 21, country_code
, __LINE__
,
459 SAMR_FIELD_COUNTRY_CODE
);
460 TEST_USERINFO_INT(21, country_code
, 2, country_code
, __LINE__
,
461 SAMR_FIELD_COUNTRY_CODE
);
463 TEST_USERINFO_INT(2, code_page
, 21, code_page
, __LINE__
, 0);
464 TEST_USERINFO_INT(21, code_page
, 21, code_page
, __LINE__
,
465 SAMR_FIELD_CODE_PAGE
);
466 TEST_USERINFO_INT(21, code_page
, 2, code_page
, __LINE__
,
467 SAMR_FIELD_CODE_PAGE
);
470 if (!torture_setting_bool(tctx
, "samba3", false)) {
471 TEST_USERINFO_INT(17, acct_expiry
, 21, acct_expiry
, __LINE__
, 0);
472 TEST_USERINFO_INT(17, acct_expiry
, 5, acct_expiry
, __LINE__
, 0);
473 TEST_USERINFO_INT(21, acct_expiry
, 21, acct_expiry
, __LINE__
,
474 SAMR_FIELD_ACCT_EXPIRY
);
475 TEST_USERINFO_INT(21, acct_expiry
, 5, acct_expiry
, __LINE__
,
476 SAMR_FIELD_ACCT_EXPIRY
);
477 TEST_USERINFO_INT(21, acct_expiry
, 17, acct_expiry
, __LINE__
,
478 SAMR_FIELD_ACCT_EXPIRY
);
480 /* Samba 3 can only store seconds / time_t in passdb - gd */
482 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
483 TEST_USERINFO_INT(17, acct_expiry
, 21, acct_expiry
, nt
, 0);
484 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
485 TEST_USERINFO_INT(17, acct_expiry
, 5, acct_expiry
, nt
, 0);
486 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
487 TEST_USERINFO_INT(21, acct_expiry
, 21, acct_expiry
, nt
, SAMR_FIELD_ACCT_EXPIRY
);
488 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
489 TEST_USERINFO_INT(21, acct_expiry
, 5, acct_expiry
, nt
, SAMR_FIELD_ACCT_EXPIRY
);
490 unix_to_nt_time(&nt
, time(NULL
) + __LINE__
);
491 TEST_USERINFO_INT(21, acct_expiry
, 17, acct_expiry
, nt
, SAMR_FIELD_ACCT_EXPIRY
);
494 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 3, logon_hours
.bits
[3], 1, 0);
495 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 5, logon_hours
.bits
[3], 2, 0);
496 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 21, logon_hours
.bits
[3], 3, 0);
497 TEST_USERINFO_INT(21, logon_hours
.bits
[3], 21, logon_hours
.bits
[3], 4,
498 SAMR_FIELD_LOGON_HOURS
);
500 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
501 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
),
502 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
| user_extra_flags
),
504 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
505 (base_acct_flags
| ACB_DISABLED
),
506 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
509 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
510 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
511 (base_acct_flags
| ACB_DISABLED
| ACB_PWNOEXP
),
512 (base_acct_flags
| ACB_DISABLED
| ACB_PWNOEXP
),
514 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
515 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
),
516 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
| user_extra_flags
),
520 /* The 'autolock' flag doesn't stick - check this */
521 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
522 (base_acct_flags
| ACB_DISABLED
| ACB_AUTOLOCK
),
523 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
526 /* Removing the 'disabled' flag doesn't stick - check this */
527 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
529 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
533 /* Samba3 cannot store these atm */
534 if (!torture_setting_bool(tctx
, "samba3", false)) {
535 /* The 'store plaintext' flag does stick */
536 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
537 (base_acct_flags
| ACB_DISABLED
| ACB_ENC_TXT_PWD_ALLOWED
),
538 (base_acct_flags
| ACB_DISABLED
| ACB_ENC_TXT_PWD_ALLOWED
| user_extra_flags
),
540 /* The 'use DES' flag does stick */
541 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
542 (base_acct_flags
| ACB_DISABLED
| ACB_USE_DES_KEY_ONLY
),
543 (base_acct_flags
| ACB_DISABLED
| ACB_USE_DES_KEY_ONLY
| user_extra_flags
),
545 /* The 'don't require kerberos pre-authentication flag does stick */
546 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
547 (base_acct_flags
| ACB_DISABLED
| ACB_DONT_REQUIRE_PREAUTH
),
548 (base_acct_flags
| ACB_DISABLED
| ACB_DONT_REQUIRE_PREAUTH
| user_extra_flags
),
550 /* The 'no kerberos PAC required' flag sticks */
551 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
552 (base_acct_flags
| ACB_DISABLED
| ACB_NO_AUTH_DATA_REQD
),
553 (base_acct_flags
| ACB_DISABLED
| ACB_NO_AUTH_DATA_REQD
| user_extra_flags
),
556 TEST_USERINFO_INT_EXP(21, acct_flags
, 21, acct_flags
,
557 (base_acct_flags
| ACB_DISABLED
),
558 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
559 SAMR_FIELD_ACCT_FLAGS
);
562 /* these fail with win2003 - it appears you can't set the primary gid?
563 the set succeeds, but the gid isn't changed. Very weird! */
564 TEST_USERINFO_INT(9, primary_gid
, 1, primary_gid
, 513);
565 TEST_USERINFO_INT(9, primary_gid
, 3, primary_gid
, 513);
566 TEST_USERINFO_INT(9, primary_gid
, 5, primary_gid
, 513);
567 TEST_USERINFO_INT(9, primary_gid
, 21, primary_gid
, 513);
574 generate a random password for password change tests
576 static char *samr_rand_pass_silent(TALLOC_CTX
*mem_ctx
, int min_len
)
578 size_t len
= MAX(8, min_len
);
579 char *s
= generate_random_password(mem_ctx
, len
, len
+6);
583 static char *samr_rand_pass(TALLOC_CTX
*mem_ctx
, int min_len
)
585 char *s
= samr_rand_pass_silent(mem_ctx
, min_len
);
586 printf("Generated password '%s'\n", s
);
592 generate a random password for password change tests
594 static DATA_BLOB
samr_very_rand_pass(TALLOC_CTX
*mem_ctx
, int len
)
597 DATA_BLOB password
= data_blob_talloc(mem_ctx
, NULL
, len
* 2 /* number of unicode chars */);
598 generate_random_buffer(password
.data
, password
.length
);
600 for (i
=0; i
< len
; i
++) {
601 if (((uint16_t *)password
.data
)[i
] == 0) {
602 ((uint16_t *)password
.data
)[i
] = 1;
610 generate a random password for password change tests (fixed length)
612 static char *samr_rand_pass_fixed_len(TALLOC_CTX
*mem_ctx
, int len
)
614 char *s
= generate_random_password(mem_ctx
, len
, len
);
615 printf("Generated password '%s'\n", s
);
619 static bool test_SetUserPass(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
620 struct policy_handle
*handle
, char **password
)
623 struct samr_SetUserInfo s
;
624 union samr_UserInfo u
;
626 DATA_BLOB session_key
;
628 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
629 struct samr_GetUserPwInfo pwp
;
630 struct samr_PwInfo info
;
631 int policy_min_pw_len
= 0;
632 pwp
.in
.user_handle
= handle
;
633 pwp
.out
.info
= &info
;
635 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
636 "GetUserPwInfo failed");
637 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
638 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
640 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
642 s
.in
.user_handle
= handle
;
646 u
.info24
.password_expired
= 0;
648 status
= dcerpc_binding_handle_transport_session_key(b
, tctx
, &session_key
);
649 if (!NT_STATUS_IS_OK(status
)) {
650 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u - no session key - %s\n",
651 s
.in
.level
, nt_errstr(status
));
655 status
= init_samr_CryptPassword(newpass
,
658 torture_assert_ntstatus_ok(tctx
,
660 "init_samr_CryptPassword failed");
662 torture_comment(tctx
, "Testing SetUserInfo level 24 (set password)\n");
664 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
665 "SetUserInfo failed");
666 torture_comment(tctx
, "(%s:%s) new_password[%s] status[%s]\n",
667 __location__
, __FUNCTION__
,
668 newpass
, nt_errstr(s
.out
.result
));
669 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
670 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u failed - %s\n",
671 s
.in
.level
, nt_errstr(s
.out
.result
));
681 static bool test_SetUserPass_23(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
682 struct policy_handle
*handle
, uint32_t fields_present
,
686 struct samr_SetUserInfo s
;
687 union samr_UserInfo u
;
689 DATA_BLOB session_key
;
690 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
692 struct samr_GetUserPwInfo pwp
;
693 struct samr_PwInfo info
;
694 int policy_min_pw_len
= 0;
695 pwp
.in
.user_handle
= handle
;
696 pwp
.out
.info
= &info
;
698 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
699 "GetUserPwInfo failed");
700 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
701 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
703 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
705 s
.in
.user_handle
= handle
;
711 u
.info23
.info
.fields_present
= fields_present
;
713 status
= dcerpc_binding_handle_transport_session_key(b
, tctx
, &session_key
);
714 if (!NT_STATUS_IS_OK(status
)) {
715 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u - no session key - %s\n",
716 s
.in
.level
, nt_errstr(status
));
720 status
= init_samr_CryptPassword(newpass
,
723 torture_assert_ntstatus_ok(tctx
,
725 "init_samr_CryptPassword failed");
727 torture_comment(tctx
, "Testing SetUserInfo level 23 (set password)\n");
729 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
730 "SetUserInfo failed");
731 torture_comment(tctx
, "(%s:%s) new_password[%s] status[%s]\n",
732 __location__
, __FUNCTION__
,
733 newpass
, nt_errstr(s
.out
.result
));
734 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
735 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u failed - %s\n",
736 s
.in
.level
, nt_errstr(s
.out
.result
));
742 status
= dcerpc_binding_handle_transport_session_key(b
, tctx
, &session_key
);
743 if (!NT_STATUS_IS_OK(status
)) {
744 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u - no session key - %s\n",
745 s
.in
.level
, nt_errstr(status
));
749 /* This should break the key nicely */
750 session_key
.data
[0]++;
752 status
= init_samr_CryptPassword(newpass
,
755 torture_assert_ntstatus_ok(tctx
,
757 "init_samr_CryptPassword failed");
759 /* Reset the session key */
760 session_key
.data
[0]--;
762 torture_comment(tctx
, "Testing SetUserInfo level 23 (set password) with wrong password\n");
764 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
765 "SetUserInfo failed");
766 torture_comment(tctx
, "(%s:%s) new_password[%s] status[%s]\n",
767 __location__
, __FUNCTION__
,
768 newpass
, nt_errstr(s
.out
.result
));
769 if (!NT_STATUS_EQUAL(s
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
770 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
771 s
.in
.level
, nt_errstr(s
.out
.result
));
778 static bool test_SetUserPass_32(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
779 struct policy_handle
*handle
, uint32_t fields_present
,
783 struct samr_SetUserInfo s
;
784 union samr_UserInfo u
;
785 DATA_BLOB session_key
;
786 uint8_t salt_data
[16];
789 .length
= sizeof(salt_data
),
791 char *newpass
= NULL
;
792 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
793 struct samr_GetUserPwInfo pwp
;
794 struct samr_PwInfo info
;
795 int policy_min_pw_len
= 0;
798 pwp
.in
.user_handle
= handle
;
799 pwp
.out
.info
= &info
;
801 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
802 "GetUserPwInfo failed");
803 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
804 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
806 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
808 s
.in
.user_handle
= handle
;
814 u
.info32
.info
.fields_present
= fields_present
;
816 status
= dcerpc_binding_handle_transport_session_key(b
, tctx
, &session_key
);
817 if (!NT_STATUS_IS_OK(status
)) {
820 "SetUserInfo level %u - no session key - %s\n",
826 generate_nonce_buffer(salt
.data
, salt
.length
);
828 status
= init_samr_CryptPasswordAES(tctx
,
833 torture_assert_ntstatus_ok(tctx
,
835 "init_samr_CryptPasswordAES failed");
837 torture_comment(tctx
,
838 "Testing SetUserInfo level 32 (set password aes)\n");
840 status
= dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
);
841 torture_assert_ntstatus_ok(tctx
, status
, "SetUserInfo failed");
842 torture_comment(tctx
, "(%s:%s) new_password[%s] status[%s]\n",
846 nt_errstr(s
.out
.result
));
847 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
850 "SetUserInfo level %u failed - %s\n",
852 nt_errstr(s
.out
.result
));
858 /* This should break the key nicely */
859 session_key
.data
[0]++;
861 status
= init_samr_CryptPasswordAES(tctx
,
866 torture_assert_ntstatus_ok(tctx
,
868 "init_samr_CryptPasswordEx failed");
871 session_key
.data
[0]--;
873 torture_comment(tctx
,
874 "Testing SetUserInfo level 32 (set password aes) with "
875 "wrong session key\n");
877 status
= dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
);
878 torture_assert_ntstatus_ok(tctx
, status
, "SetUserInfo failed");
879 torture_comment(tctx
,
880 "(%s:%s) new_password[%s] status[%s]\n",
884 nt_errstr(s
.out
.result
));
885 if (!NT_STATUS_EQUAL(s
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
888 "SetUserInfo level %u should have failed with "
889 "WRONG_PASSWORD- %s\n",
891 nt_errstr(s
.out
.result
));
899 static bool test_SetUserPass_31(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
900 struct policy_handle
*handle
, bool makeshort
,
904 struct samr_SetUserInfo s
;
905 union samr_UserInfo u
;
907 DATA_BLOB session_key
;
908 uint8_t salt_data
[16];
911 .length
= sizeof(salt_data
),
914 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
915 struct samr_GetUserPwInfo pwp
;
916 struct samr_PwInfo info
;
917 int policy_min_pw_len
= 0;
919 pwp
.in
.user_handle
= handle
;
920 pwp
.out
.info
= &info
;
922 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
923 "GetUserPwInfo failed");
924 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
925 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
927 if (makeshort
&& policy_min_pw_len
) {
928 newpass
= samr_rand_pass_fixed_len(tctx
, policy_min_pw_len
- 1);
930 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
933 s
.in
.user_handle
= handle
;
939 u
.info31
.password_expired
= 0;
941 status
= dcerpc_binding_handle_transport_session_key(b
, tctx
, &session_key
);
942 if (!NT_STATUS_IS_OK(status
)) {
943 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u - no session key - %s\n",
944 s
.in
.level
, nt_errstr(status
));
948 generate_nonce_buffer(salt
.data
, salt
.length
);
950 status
= init_samr_CryptPasswordAES(tctx
,
955 torture_assert_ntstatus_ok(tctx
,
957 "init_samr_CryptPasswordEx failed");
959 torture_comment(tctx
, "Testing SetUserInfo level 31 (set password aes)\n");
961 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
962 "SetUserInfo failed");
963 torture_comment(tctx
, "(%s:%s) new_password[%s] status[%s]\n",
964 __location__
, __FUNCTION__
,
965 newpass
, nt_errstr(s
.out
.result
));
966 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
967 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u failed - %s\n",
968 s
.in
.level
, nt_errstr(s
.out
.result
));
974 /* This should break the key nicely */
975 session_key
.data
[0]++;
977 status
= init_samr_CryptPasswordAES(tctx
,
982 torture_assert_ntstatus_ok(tctx
,
984 "init_samr_CryptPasswordEx failed");
987 session_key
.data
[0]--;
989 torture_comment(tctx
, "Testing SetUserInfo level 31 (set password aes) with wrong session key\n");
991 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
992 "SetUserInfo failed");
993 torture_comment(tctx
, "(%s:%s) new_password[%s] status[%s]\n",
994 __location__
, __FUNCTION__
,
995 newpass
, nt_errstr(s
.out
.result
));
996 if (!NT_STATUS_EQUAL(s
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
997 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
998 s
.in
.level
, nt_errstr(s
.out
.result
));
1001 *password
= newpass
;
1008 static bool test_SetUserPassEx(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1009 struct policy_handle
*handle
, bool makeshort
,
1013 struct samr_SetUserInfo s
;
1014 union samr_UserInfo u
;
1016 DATA_BLOB session_key
;
1018 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1019 struct samr_GetUserPwInfo pwp
;
1020 struct samr_PwInfo info
;
1021 int policy_min_pw_len
= 0;
1023 pwp
.in
.user_handle
= handle
;
1024 pwp
.out
.info
= &info
;
1026 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
1027 "GetUserPwInfo failed");
1028 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
1029 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1031 if (makeshort
&& policy_min_pw_len
) {
1032 newpass
= samr_rand_pass_fixed_len(tctx
, policy_min_pw_len
- 1);
1034 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1037 s
.in
.user_handle
= handle
;
1041 u
.info26
.password_expired
= 0;
1043 status
= dcerpc_binding_handle_transport_session_key(b
, tctx
, &session_key
);
1044 if (!NT_STATUS_IS_OK(status
)) {
1045 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u - no session key - %s\n",
1046 s
.in
.level
, nt_errstr(status
));
1050 status
= init_samr_CryptPasswordEx(newpass
,
1052 &u
.info26
.password
);
1053 torture_assert_ntstatus_ok(tctx
,
1055 "init_samr_CryptPasswordEx failed");
1057 torture_comment(tctx
, "Testing SetUserInfo level 26 (set password ex)\n");
1059 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
1060 "SetUserInfo failed");
1061 torture_comment(tctx
, "(%s:%s) new_password[%s] status[%s]\n",
1062 __location__
, __FUNCTION__
,
1063 newpass
, nt_errstr(s
.out
.result
));
1064 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
1065 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u failed - %s\n",
1066 s
.in
.level
, nt_errstr(s
.out
.result
));
1069 *password
= newpass
;
1072 /* This should break the key nicely */
1073 session_key
.data
[0]++;
1075 status
= init_samr_CryptPasswordEx(newpass
,
1077 &u
.info26
.password
);
1078 torture_assert_ntstatus_ok(tctx
,
1080 "init_samr_CryptPasswordEx failed");
1083 session_key
.data
[0]--;
1085 torture_comment(tctx
, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
1087 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
1088 "SetUserInfo failed");
1089 torture_comment(tctx
, "(%s:%s) new_password[%s] status[%s]\n",
1090 __location__
, __FUNCTION__
,
1091 newpass
, nt_errstr(s
.out
.result
));
1092 if (!NT_STATUS_EQUAL(s
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
1093 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
1094 s
.in
.level
, nt_errstr(s
.out
.result
));
1097 *password
= newpass
;
1103 static bool test_SetUserPass_25(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1104 struct policy_handle
*handle
, uint32_t fields_present
,
1108 struct samr_SetUserInfo s
;
1109 union samr_UserInfo u
;
1111 DATA_BLOB session_key
;
1113 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1114 struct samr_GetUserPwInfo pwp
;
1115 struct samr_PwInfo info
;
1116 int policy_min_pw_len
= 0;
1118 pwp
.in
.user_handle
= handle
;
1119 pwp
.out
.info
= &info
;
1121 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
1122 "GetUserPwInfo failed");
1123 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
1124 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1126 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1128 s
.in
.user_handle
= handle
;
1134 u
.info25
.info
.fields_present
= fields_present
;
1136 status
= dcerpc_binding_handle_transport_session_key(b
, tctx
, &session_key
);
1137 if (!NT_STATUS_IS_OK(status
)) {
1138 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u - no session key - %s\n",
1139 s
.in
.level
, nt_errstr(status
));
1143 status
= init_samr_CryptPasswordEx(newpass
,
1145 &u
.info25
.password
);
1146 torture_assert_ntstatus_ok(tctx
,
1148 "init_samr_CryptPasswordEx failed");
1150 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex)\n");
1152 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
1153 "SetUserInfo failed");
1154 torture_comment(tctx
, "(%s:%s) new_password[%s] status[%s]\n",
1155 __location__
, __FUNCTION__
,
1156 newpass
, nt_errstr(s
.out
.result
));
1157 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
1158 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u failed - %s\n",
1159 s
.in
.level
, nt_errstr(s
.out
.result
));
1162 *password
= newpass
;
1165 /* This should break the key nicely */
1166 session_key
.data
[0]++;
1168 status
= init_samr_CryptPasswordEx(newpass
,
1170 &u
.info25
.password
);
1171 torture_assert_ntstatus_ok(tctx
,
1173 "init_samr_CryptPasswordEx failed");
1176 session_key
.data
[0]--;
1178 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
1180 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
1181 "SetUserInfo failed");
1182 torture_comment(tctx
, "(%s:%s) new_password[%s] status[%s]\n",
1183 __location__
, __FUNCTION__
,
1184 newpass
, nt_errstr(s
.out
.result
));
1185 if (!NT_STATUS_EQUAL(s
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
1186 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
1187 s
.in
.level
, nt_errstr(s
.out
.result
));
1194 static bool test_SetUserPass_18(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1195 struct policy_handle
*handle
, char **password
)
1198 struct samr_SetUserInfo s
;
1199 union samr_UserInfo u
;
1201 DATA_BLOB session_key
;
1203 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1204 struct samr_GetUserPwInfo pwp
;
1205 struct samr_PwInfo info
;
1206 int policy_min_pw_len
= 0;
1207 uint8_t lm_hash
[16], nt_hash
[16];
1209 pwp
.in
.user_handle
= handle
;
1210 pwp
.out
.info
= &info
;
1212 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
1213 "GetUserPwInfo failed");
1214 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
1215 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1217 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1219 s
.in
.user_handle
= handle
;
1225 u
.info18
.nt_pwd_active
= true;
1226 u
.info18
.lm_pwd_active
= true;
1228 E_md4hash(newpass
, nt_hash
);
1229 E_deshash(newpass
, lm_hash
);
1231 status
= dcerpc_binding_handle_transport_session_key(b
, tctx
, &session_key
);
1232 if (!NT_STATUS_IS_OK(status
)) {
1233 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u - no session key - %s\n",
1234 s
.in
.level
, nt_errstr(status
));
1240 in
= data_blob_const(nt_hash
, 16);
1241 out
= data_blob_talloc_zero(tctx
, 16);
1242 sess_crypt_blob(&out
, &in
, &session_key
, SAMBA_GNUTLS_ENCRYPT
);
1243 memcpy(u
.info18
.nt_pwd
.hash
, out
.data
, out
.length
);
1247 in
= data_blob_const(lm_hash
, 16);
1248 out
= data_blob_talloc_zero(tctx
, 16);
1249 sess_crypt_blob(&out
, &in
, &session_key
, SAMBA_GNUTLS_ENCRYPT
);
1250 memcpy(u
.info18
.lm_pwd
.hash
, out
.data
, out
.length
);
1253 torture_comment(tctx
, "Testing SetUserInfo level 18 (set password hash)\n");
1255 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
1256 "SetUserInfo failed");
1257 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
1258 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u failed - %s\n",
1259 s
.in
.level
, nt_errstr(s
.out
.result
));
1262 *password
= newpass
;
1268 static bool test_SetUserPass_21(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1269 struct policy_handle
*handle
, uint32_t fields_present
,
1273 struct samr_SetUserInfo s
;
1274 union samr_UserInfo u
;
1276 DATA_BLOB session_key
;
1278 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1279 struct samr_GetUserPwInfo pwp
;
1280 struct samr_PwInfo info
;
1281 int policy_min_pw_len
= 0;
1282 uint8_t lm_hash
[16], nt_hash
[16];
1284 pwp
.in
.user_handle
= handle
;
1285 pwp
.out
.info
= &info
;
1287 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
1288 "GetUserPwInfo failed");
1289 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
1290 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1292 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1294 s
.in
.user_handle
= handle
;
1298 E_md4hash(newpass
, nt_hash
);
1299 E_deshash(newpass
, lm_hash
);
1303 u
.info21
.fields_present
= fields_present
;
1305 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1306 u
.info21
.lm_owf_password
.length
= 16;
1307 u
.info21
.lm_owf_password
.size
= 16;
1308 u
.info21
.lm_owf_password
.array
= (uint16_t *)lm_hash
;
1309 u
.info21
.lm_password_set
= true;
1312 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1313 u
.info21
.nt_owf_password
.length
= 16;
1314 u
.info21
.nt_owf_password
.size
= 16;
1315 u
.info21
.nt_owf_password
.array
= (uint16_t *)nt_hash
;
1316 u
.info21
.nt_password_set
= true;
1319 status
= dcerpc_binding_handle_transport_session_key(b
, tctx
, &session_key
);
1320 if (!NT_STATUS_IS_OK(status
)) {
1321 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u - no session key - %s\n",
1322 s
.in
.level
, nt_errstr(status
));
1326 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1328 in
= data_blob_const(u
.info21
.lm_owf_password
.array
,
1329 u
.info21
.lm_owf_password
.length
);
1330 out
= data_blob_talloc_zero(tctx
, 16);
1331 sess_crypt_blob(&out
, &in
, &session_key
, SAMBA_GNUTLS_ENCRYPT
);
1332 u
.info21
.lm_owf_password
.array
= (uint16_t *)out
.data
;
1335 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1337 in
= data_blob_const(u
.info21
.nt_owf_password
.array
,
1338 u
.info21
.nt_owf_password
.length
);
1339 out
= data_blob_talloc_zero(tctx
, 16);
1340 sess_crypt_blob(&out
, &in
, &session_key
, SAMBA_GNUTLS_ENCRYPT
);
1341 u
.info21
.nt_owf_password
.array
= (uint16_t *)out
.data
;
1344 torture_comment(tctx
, "Testing SetUserInfo level 21 (set password hash)\n");
1346 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
1347 "SetUserInfo failed");
1348 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
1349 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u failed - %s\n",
1350 s
.in
.level
, nt_errstr(s
.out
.result
));
1353 *password
= newpass
;
1356 /* try invalid length */
1357 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1359 u
.info21
.nt_owf_password
.length
++;
1361 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
1362 "SetUserInfo failed");
1363 if (!NT_STATUS_EQUAL(s
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
1364 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1365 s
.in
.level
, nt_errstr(s
.out
.result
));
1370 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1372 u
.info21
.lm_owf_password
.length
++;
1374 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
1375 "SetUserInfo failed");
1376 if (!NT_STATUS_EQUAL(s
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
1377 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1378 s
.in
.level
, nt_errstr(s
.out
.result
));
1386 static bool test_SetUserPass_level_ex(struct dcerpc_pipe
*p
,
1387 struct torture_context
*tctx
,
1388 struct policy_handle
*handle
,
1390 uint32_t fields_present
,
1391 char **password
, uint8_t password_expired
,
1393 bool *matched_expected_error
)
1396 NTSTATUS expected_error
= NT_STATUS_OK
;
1397 struct samr_SetUserInfo s
;
1398 struct samr_SetUserInfo2 s2
;
1399 union samr_UserInfo u
;
1401 DATA_BLOB session_key
;
1402 uint8_t salt_data
[16];
1405 .length
= sizeof(salt_data
),
1408 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1409 struct samr_GetUserPwInfo pwp
;
1410 struct samr_PwInfo info
;
1411 int policy_min_pw_len
= 0;
1412 const char *comment
= NULL
;
1413 uint8_t lm_hash
[16], nt_hash
[16];
1415 pwp
.in
.user_handle
= handle
;
1416 pwp
.out
.info
= &info
;
1418 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
1419 "GetUserPwInfo failed");
1420 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
1421 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1423 newpass
= samr_rand_pass_silent(tctx
, policy_min_pw_len
);
1426 s2
.in
.user_handle
= handle
;
1428 s2
.in
.level
= level
;
1430 s
.in
.user_handle
= handle
;
1435 if (fields_present
& SAMR_FIELD_COMMENT
) {
1436 comment
= talloc_asprintf(tctx
, "comment: %ld\n", (long int) time(NULL
));
1443 E_md4hash(newpass
, nt_hash
);
1444 E_deshash(newpass
, lm_hash
);
1446 u
.info18
.nt_pwd_active
= true;
1447 u
.info18
.lm_pwd_active
= true;
1448 u
.info18
.password_expired
= password_expired
;
1450 memcpy(u
.info18
.lm_pwd
.hash
, lm_hash
, 16);
1451 memcpy(u
.info18
.nt_pwd
.hash
, nt_hash
, 16);
1455 E_md4hash(newpass
, nt_hash
);
1456 E_deshash(newpass
, lm_hash
);
1458 u
.info21
.fields_present
= fields_present
;
1459 u
.info21
.password_expired
= password_expired
;
1460 u
.info21
.comment
.string
= comment
;
1462 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1463 u
.info21
.lm_owf_password
.length
= 16;
1464 u
.info21
.lm_owf_password
.size
= 16;
1465 u
.info21
.lm_owf_password
.array
= (uint16_t *)lm_hash
;
1466 u
.info21
.lm_password_set
= true;
1469 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1470 u
.info21
.nt_owf_password
.length
= 16;
1471 u
.info21
.nt_owf_password
.size
= 16;
1472 u
.info21
.nt_owf_password
.array
= (uint16_t *)nt_hash
;
1473 u
.info21
.nt_password_set
= true;
1478 u
.info23
.info
.fields_present
= fields_present
;
1479 u
.info23
.info
.password_expired
= password_expired
;
1480 u
.info23
.info
.comment
.string
= comment
;
1484 u
.info24
.password_expired
= password_expired
;
1488 u
.info25
.info
.fields_present
= fields_present
;
1489 u
.info25
.info
.password_expired
= password_expired
;
1490 u
.info25
.info
.comment
.string
= comment
;
1494 u
.info26
.password_expired
= password_expired
;
1498 u
.info31
.password_expired
= password_expired
;
1502 u
.info25
.info
.fields_present
= fields_present
;
1503 u
.info25
.info
.password_expired
= password_expired
;
1504 u
.info25
.info
.comment
.string
= comment
;
1509 status
= dcerpc_binding_handle_transport_session_key(b
, tctx
, &session_key
);
1510 if (!NT_STATUS_IS_OK(status
)) {
1511 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u - no session key - %s\n",
1512 s
.in
.level
, nt_errstr(status
));
1516 generate_nonce_buffer(salt
.data
, salt
.length
);
1522 in
= data_blob_const(u
.info18
.nt_pwd
.hash
, 16);
1523 out
= data_blob_talloc_zero(tctx
, 16);
1524 sess_crypt_blob(&out
, &in
, &session_key
, SAMBA_GNUTLS_ENCRYPT
);
1525 memcpy(u
.info18
.nt_pwd
.hash
, out
.data
, out
.length
);
1529 in
= data_blob_const(u
.info18
.lm_pwd
.hash
, 16);
1530 out
= data_blob_talloc_zero(tctx
, 16);
1531 sess_crypt_blob(&out
, &in
, &session_key
, SAMBA_GNUTLS_ENCRYPT
);
1532 memcpy(u
.info18
.lm_pwd
.hash
, out
.data
, out
.length
);
1537 if (fields_present
& SAMR_FIELD_LM_PASSWORD_PRESENT
) {
1539 in
= data_blob_const(u
.info21
.lm_owf_password
.array
,
1540 u
.info21
.lm_owf_password
.length
);
1541 out
= data_blob_talloc_zero(tctx
, 16);
1542 sess_crypt_blob(&out
, &in
, &session_key
, SAMBA_GNUTLS_ENCRYPT
);
1543 u
.info21
.lm_owf_password
.array
= (uint16_t *)out
.data
;
1545 if (fields_present
& SAMR_FIELD_NT_PASSWORD_PRESENT
) {
1547 in
= data_blob_const(u
.info21
.nt_owf_password
.array
,
1548 u
.info21
.nt_owf_password
.length
);
1549 out
= data_blob_talloc_zero(tctx
, 16);
1550 sess_crypt_blob(&out
, &in
, &session_key
, SAMBA_GNUTLS_ENCRYPT
);
1551 u
.info21
.nt_owf_password
.array
= (uint16_t *)out
.data
;
1555 status
= init_samr_CryptPassword(newpass
,
1557 &u
.info23
.password
);
1558 torture_assert_ntstatus_ok(tctx
,
1560 "init_samr_CryptPassword failed");
1563 status
= init_samr_CryptPassword(newpass
,
1565 &u
.info24
.password
);
1566 torture_assert_ntstatus_ok(tctx
,
1568 "init_samr_CryptPassword failed");
1571 status
= init_samr_CryptPasswordEx(newpass
,
1573 &u
.info25
.password
);
1574 torture_assert_ntstatus_ok(tctx
,
1576 "init_samr_CryptPasswordEx failed");
1579 status
= init_samr_CryptPasswordEx(newpass
,
1581 &u
.info26
.password
);
1582 torture_assert_ntstatus_ok(tctx
,
1584 "init_samr_CryptPasswordEx failed");
1587 status
= init_samr_CryptPasswordAES(tctx
,
1591 &u
.info31
.password
);
1595 status
= init_samr_CryptPasswordAES(tctx
,
1599 &u
.info32
.password
);
1605 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo2_r(b
, tctx
, &s2
),
1606 "SetUserInfo2 failed");
1607 torture_comment(tctx
, "(%s:%s) new_password[%s] status[%s]\n",
1608 __location__
, __FUNCTION__
,
1609 newpass
, nt_errstr(s2
.out
.result
));
1610 status
= s2
.out
.result
;
1612 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
1613 "SetUserInfo failed");
1614 torture_comment(tctx
, "(%s:%s) new_password[%s] status[%s]\n",
1615 __location__
, __FUNCTION__
,
1616 newpass
, nt_errstr(s
.out
.result
));
1617 status
= s
.out
.result
;
1620 if (!NT_STATUS_IS_OK(status
)) {
1621 if (fields_present
== 0) {
1622 expected_error
= NT_STATUS_INVALID_PARAMETER
;
1624 if (fields_present
& SAMR_FIELD_LAST_PWD_CHANGE
) {
1625 expected_error
= NT_STATUS_ACCESS_DENIED
;
1629 if (!NT_STATUS_IS_OK(expected_error
)) {
1631 torture_assert_ntstatus_equal(tctx
,
1633 expected_error
, "SetUserInfo2 failed");
1635 torture_assert_ntstatus_equal(tctx
,
1637 expected_error
, "SetUserInfo failed");
1639 *matched_expected_error
= true;
1643 if (!NT_STATUS_IS_OK(status
)) {
1644 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo%s level %u failed - %s\n",
1645 use_setinfo2
? "2":"", level
, nt_errstr(status
));
1648 *password
= newpass
;
1654 static bool test_SetAliasInfo(struct dcerpc_binding_handle
*b
,
1655 struct torture_context
*tctx
,
1656 struct policy_handle
*handle
)
1658 struct samr_SetAliasInfo r
;
1659 struct samr_QueryAliasInfo q
;
1660 union samr_AliasInfo
*info
;
1661 uint16_t levels
[] = {2, 3};
1665 /* Ignoring switch level 1, as that includes the number of members for the alias
1666 * and setting this to a wrong value might have negative consequences
1669 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
1670 torture_comment(tctx
, "Testing SetAliasInfo level %u\n", levels
[i
]);
1672 r
.in
.alias_handle
= handle
;
1673 r
.in
.level
= levels
[i
];
1674 r
.in
.info
= talloc(tctx
, union samr_AliasInfo
);
1675 switch (r
.in
.level
) {
1676 case ALIASINFONAME
: init_lsa_String(&r
.in
.info
->name
,TEST_ALIASNAME
); break;
1677 case ALIASINFODESCRIPTION
: init_lsa_String(&r
.in
.info
->description
,
1678 "Test Description, should test I18N as well"); break;
1679 case ALIASINFOALL
: torture_comment(tctx
, "ALIASINFOALL ignored\n"); break;
1682 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetAliasInfo_r(b
, tctx
, &r
),
1683 "SetAliasInfo failed");
1684 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1685 torture_result(tctx
, TORTURE_FAIL
, "SetAliasInfo level %u failed - %s\n",
1686 levels
[i
], nt_errstr(r
.out
.result
));
1690 q
.in
.alias_handle
= handle
;
1691 q
.in
.level
= levels
[i
];
1694 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryAliasInfo_r(b
, tctx
, &q
),
1695 "QueryAliasInfo failed");
1696 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
1697 torture_result(tctx
, TORTURE_FAIL
, "QueryAliasInfo level %u failed - %s\n",
1698 levels
[i
], nt_errstr(q
.out
.result
));
1706 static bool test_GetGroupsForUser(struct dcerpc_binding_handle
*b
,
1707 struct torture_context
*tctx
,
1708 struct policy_handle
*user_handle
)
1710 struct samr_GetGroupsForUser r
;
1711 struct samr_RidWithAttributeArray
*rids
= NULL
;
1713 torture_comment(tctx
, "Testing GetGroupsForUser\n");
1715 r
.in
.user_handle
= user_handle
;
1718 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetGroupsForUser_r(b
, tctx
, &r
),
1719 "GetGroupsForUser failed");
1720 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetGroupsForUser failed");
1726 static bool test_GetDomPwInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1727 struct lsa_String
*domain_name
)
1729 struct samr_GetDomPwInfo r
;
1730 struct samr_PwInfo info
;
1731 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1733 r
.in
.domain_name
= domain_name
;
1736 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1738 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &r
),
1739 "GetDomPwInfo failed");
1740 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetDomPwInfo failed");
1742 r
.in
.domain_name
->string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1743 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1745 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &r
),
1746 "GetDomPwInfo failed");
1747 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetDomPwInfo failed");
1749 r
.in
.domain_name
->string
= "\\\\__NONAME__";
1750 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1752 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &r
),
1753 "GetDomPwInfo failed");
1754 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetDomPwInfo failed");
1756 r
.in
.domain_name
->string
= "\\\\Builtin";
1757 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
1759 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &r
),
1760 "GetDomPwInfo failed");
1761 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetDomPwInfo failed");
1766 static bool test_GetUserPwInfo(struct dcerpc_binding_handle
*b
,
1767 struct torture_context
*tctx
,
1768 struct policy_handle
*handle
)
1770 struct samr_GetUserPwInfo r
;
1771 struct samr_PwInfo info
;
1773 torture_comment(tctx
, "Testing GetUserPwInfo\n");
1775 r
.in
.user_handle
= handle
;
1778 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &r
),
1779 "GetUserPwInfo failed");
1780 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetUserPwInfo");
1785 static NTSTATUS
test_LookupName(struct dcerpc_binding_handle
*b
,
1786 struct torture_context
*tctx
,
1787 struct policy_handle
*domain_handle
, const char *name
,
1791 struct samr_LookupNames n
;
1792 struct lsa_String sname
[2];
1793 struct samr_Ids rids
, types
;
1795 init_lsa_String(&sname
[0], name
);
1797 n
.in
.domain_handle
= domain_handle
;
1801 n
.out
.types
= &types
;
1802 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1803 if (!NT_STATUS_IS_OK(status
)) {
1806 if (NT_STATUS_IS_OK(n
.out
.result
)) {
1807 *rid
= n
.out
.rids
->ids
[0];
1809 return n
.out
.result
;
1812 init_lsa_String(&sname
[1], "xxNONAMExx");
1814 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1815 if (!NT_STATUS_IS_OK(status
)) {
1818 if (!NT_STATUS_EQUAL(n
.out
.result
, STATUS_SOME_UNMAPPED
)) {
1819 torture_result(tctx
, TORTURE_FAIL
, "LookupNames[2] failed - %s\n", nt_errstr(n
.out
.result
));
1820 if (NT_STATUS_IS_OK(n
.out
.result
)) {
1821 return NT_STATUS_UNSUCCESSFUL
;
1823 return n
.out
.result
;
1827 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1828 if (!NT_STATUS_IS_OK(status
)) {
1831 if (!NT_STATUS_IS_OK(n
.out
.result
)) {
1832 torture_result(tctx
, TORTURE_FAIL
, "LookupNames[0] failed - %s\n", nt_errstr(status
));
1833 return n
.out
.result
;
1836 init_lsa_String(&sname
[0], "xxNONAMExx");
1838 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1839 if (!NT_STATUS_IS_OK(status
)) {
1842 if (!NT_STATUS_EQUAL(n
.out
.result
, NT_STATUS_NONE_MAPPED
)) {
1843 torture_result(tctx
, TORTURE_FAIL
, "LookupNames[1 bad name] failed - %s\n", nt_errstr(n
.out
.result
));
1844 if (NT_STATUS_IS_OK(n
.out
.result
)) {
1845 return NT_STATUS_UNSUCCESSFUL
;
1847 return n
.out
.result
;
1850 init_lsa_String(&sname
[0], "xxNONAMExx");
1851 init_lsa_String(&sname
[1], "xxNONAME2xx");
1853 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
1854 if (!NT_STATUS_IS_OK(status
)) {
1857 if (!NT_STATUS_EQUAL(n
.out
.result
, NT_STATUS_NONE_MAPPED
)) {
1858 torture_result(tctx
, TORTURE_FAIL
, "LookupNames[2 bad names] failed - %s\n", nt_errstr(n
.out
.result
));
1859 if (NT_STATUS_IS_OK(n
.out
.result
)) {
1860 return NT_STATUS_UNSUCCESSFUL
;
1862 return n
.out
.result
;
1865 return NT_STATUS_OK
;
1868 static NTSTATUS
test_OpenUser_byname(struct dcerpc_binding_handle
*b
,
1869 struct torture_context
*tctx
,
1870 struct policy_handle
*domain_handle
,
1871 const char *name
, struct policy_handle
*user_handle
)
1874 struct samr_OpenUser r
;
1877 status
= test_LookupName(b
, tctx
, domain_handle
, name
, &rid
);
1878 if (!NT_STATUS_IS_OK(status
)) {
1882 r
.in
.domain_handle
= domain_handle
;
1883 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1885 r
.out
.user_handle
= user_handle
;
1886 status
= dcerpc_samr_OpenUser_r(b
, tctx
, &r
);
1887 if (!NT_STATUS_IS_OK(status
)) {
1890 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1891 torture_result(tctx
, TORTURE_FAIL
, "OpenUser_byname(%s -> %d) failed - %s\n", name
, rid
, nt_errstr(r
.out
.result
));
1894 return r
.out
.result
;
1898 static bool test_ChangePasswordNT3(struct dcerpc_pipe
*p
,
1899 struct torture_context
*tctx
,
1900 struct policy_handle
*handle
)
1903 struct samr_ChangePasswordUser r
;
1905 struct samr_Password hash1
, hash2
, hash3
, hash4
, hash5
, hash6
;
1906 struct policy_handle user_handle
;
1907 char *oldpass
= "test";
1908 char *newpass
= "test2";
1909 uint8_t old_nt_hash
[16], new_nt_hash
[16];
1910 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1912 status
= test_OpenUser_byname(p
, tctx
, handle
, "testuser", &user_handle
);
1913 if (!NT_STATUS_IS_OK(status
)) {
1917 torture_comment(tctx
, "Testing ChangePasswordUser for user 'testuser'\n");
1919 torture_comment(tctx
, "old password: %s\n", oldpass
);
1920 torture_comment(tctx
, "new password: %s\n", newpass
);
1922 E_md4hash(oldpass
, old_nt_hash
);
1923 E_md4hash(newpass
, new_nt_hash
);
1924 E_deshash(oldpass
, old_lm_hash
);
1925 E_deshash(newpass
, new_lm_hash
);
1927 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1928 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1929 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1930 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1931 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1932 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1934 r
.in
.handle
= &user_handle
;
1935 r
.in
.lm_present
= 1;
1936 r
.in
.old_lm_crypted
= &hash1
;
1937 r
.in
.new_lm_crypted
= &hash2
;
1938 r
.in
.nt_present
= 1;
1939 r
.in
.old_nt_crypted
= &hash3
;
1940 r
.in
.new_nt_crypted
= &hash4
;
1941 r
.in
.cross1_present
= 1;
1942 r
.in
.nt_cross
= &hash5
;
1943 r
.in
.cross2_present
= 1;
1944 r
.in
.lm_cross
= &hash6
;
1946 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
1947 "ChangePasswordUser failed");
1948 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
1949 torture_result(tctx
, TORTURE_FAIL
, "ChangePasswordUser failed - %s\n", nt_errstr(r
.out
.result
));
1953 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
1961 static bool test_ChangePasswordUser(struct dcerpc_binding_handle
*b
,
1962 struct torture_context
*tctx
,
1963 const char *acct_name
,
1964 struct policy_handle
*handle
, char **password
)
1967 struct samr_ChangePasswordUser r
;
1969 struct samr_Password hash1
, hash2
, hash3
, hash4
, hash5
, hash6
;
1970 struct policy_handle user_handle
;
1972 uint8_t old_nt_hash
[16], new_nt_hash
[16];
1973 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1974 bool changed
= true;
1977 struct samr_GetUserPwInfo pwp
;
1978 struct samr_PwInfo info
;
1979 int policy_min_pw_len
= 0;
1981 status
= test_OpenUser_byname(b
, tctx
, handle
, acct_name
, &user_handle
);
1982 if (!NT_STATUS_IS_OK(status
)) {
1985 pwp
.in
.user_handle
= &user_handle
;
1986 pwp
.out
.info
= &info
;
1988 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetUserPwInfo_r(b
, tctx
, &pwp
),
1989 "GetUserPwInfo failed");
1990 if (NT_STATUS_IS_OK(pwp
.out
.result
)) {
1991 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1993 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1995 torture_comment(tctx
, "Testing ChangePasswordUser\n");
1997 torture_assert(tctx
, *password
!= NULL
,
1998 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
2000 oldpass
= *password
;
2002 E_md4hash(oldpass
, old_nt_hash
);
2003 E_md4hash(newpass
, new_nt_hash
);
2004 E_deshash(oldpass
, old_lm_hash
);
2005 E_deshash(newpass
, new_lm_hash
);
2007 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
2008 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
2009 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
2010 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
2011 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
2012 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
2014 r
.in
.user_handle
= &user_handle
;
2015 r
.in
.lm_present
= 1;
2016 /* Break the NT hash */
2018 r
.in
.old_lm_crypted
= &hash1
;
2019 r
.in
.new_lm_crypted
= &hash2
;
2020 r
.in
.nt_present
= 1;
2021 r
.in
.old_nt_crypted
= &hash3
;
2022 r
.in
.new_nt_crypted
= &hash4
;
2023 r
.in
.cross1_present
= 1;
2024 r
.in
.nt_cross
= &hash5
;
2025 r
.in
.cross2_present
= 1;
2026 r
.in
.lm_cross
= &hash6
;
2028 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
2029 "ChangePasswordUser failed");
2030 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2031 __location__
, __FUNCTION__
,
2032 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2034 /* Do not proceed if this call has been removed */
2035 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_NOT_IMPLEMENTED
)) {
2036 torture_skip(tctx
, "ValidatePassword not supported by server\n");
2039 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2040 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_WRONG_PASSWORD
,
2041 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
2044 /* Unbreak the NT hash */
2047 r
.in
.user_handle
= &user_handle
;
2048 r
.in
.lm_present
= 1;
2049 r
.in
.old_lm_crypted
= &hash1
;
2050 r
.in
.new_lm_crypted
= &hash2
;
2051 /* Break the LM hash */
2053 r
.in
.nt_present
= 1;
2054 r
.in
.old_nt_crypted
= &hash3
;
2055 r
.in
.new_nt_crypted
= &hash4
;
2056 r
.in
.cross1_present
= 1;
2057 r
.in
.nt_cross
= &hash5
;
2058 r
.in
.cross2_present
= 1;
2059 r
.in
.lm_cross
= &hash6
;
2061 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
2062 "ChangePasswordUser failed");
2063 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2064 __location__
, __FUNCTION__
,
2065 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2066 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2067 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_WRONG_PASSWORD
,
2068 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
2071 /* Unbreak the NT hash */
2074 r
.in
.user_handle
= &user_handle
;
2075 r
.in
.lm_present
= 1;
2076 r
.in
.old_lm_crypted
= &hash1
;
2077 r
.in
.new_lm_crypted
= &hash2
;
2078 r
.in
.nt_present
= 1;
2079 r
.in
.old_nt_crypted
= &hash3
;
2080 r
.in
.new_nt_crypted
= &hash4
;
2081 r
.in
.cross1_present
= 1;
2082 r
.in
.nt_cross
= &hash5
;
2083 r
.in
.cross2_present
= 1;
2084 /* Break the LM cross */
2086 r
.in
.lm_cross
= &hash6
;
2088 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
2089 "ChangePasswordUser failed");
2090 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2091 __location__
, __FUNCTION__
,
2092 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2093 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
) &&
2094 !NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
))
2096 torture_result(tctx
, TORTURE_FAIL
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD or NT_STATUS_PASSWORD_RESTRICTION because we broke the LM cross-hash, got %s\n", nt_errstr(r
.out
.result
));
2100 /* Unbreak the LM cross */
2103 r
.in
.user_handle
= &user_handle
;
2104 r
.in
.lm_present
= 1;
2105 r
.in
.old_lm_crypted
= &hash1
;
2106 r
.in
.new_lm_crypted
= &hash2
;
2107 r
.in
.nt_present
= 1;
2108 r
.in
.old_nt_crypted
= &hash3
;
2109 r
.in
.new_nt_crypted
= &hash4
;
2110 r
.in
.cross1_present
= 1;
2111 /* Break the NT cross */
2113 r
.in
.nt_cross
= &hash5
;
2114 r
.in
.cross2_present
= 1;
2115 r
.in
.lm_cross
= &hash6
;
2117 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
2118 "ChangePasswordUser failed");
2119 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2120 __location__
, __FUNCTION__
,
2121 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2122 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
) &&
2123 !NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
))
2125 torture_result(tctx
, TORTURE_FAIL
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD or NT_STATUS_PASSWORD_RESTRICTION because we broke the NT cross-hash, got %s\n", nt_errstr(r
.out
.result
));
2129 /* Unbreak the NT cross */
2133 /* Reset the hashes to not broken values */
2134 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
2135 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
2136 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
2137 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
2138 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
2139 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
2141 r
.in
.user_handle
= &user_handle
;
2142 r
.in
.lm_present
= 1;
2143 r
.in
.old_lm_crypted
= &hash1
;
2144 r
.in
.new_lm_crypted
= &hash2
;
2145 r
.in
.nt_present
= 1;
2146 r
.in
.old_nt_crypted
= &hash3
;
2147 r
.in
.new_nt_crypted
= &hash4
;
2148 r
.in
.cross1_present
= 1;
2149 r
.in
.nt_cross
= &hash5
;
2150 r
.in
.cross2_present
= 0;
2151 r
.in
.lm_cross
= NULL
;
2153 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
2154 "ChangePasswordUser failed");
2155 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2156 __location__
, __FUNCTION__
,
2157 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2158 if (NT_STATUS_IS_OK(r
.out
.result
)) {
2160 *password
= newpass
;
2161 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION
, r
.out
.result
)) {
2162 torture_result(tctx
, TORTURE_FAIL
, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r
.out
.result
));
2167 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2169 E_md4hash(oldpass
, old_nt_hash
);
2170 E_md4hash(newpass
, new_nt_hash
);
2171 E_deshash(oldpass
, old_lm_hash
);
2172 E_deshash(newpass
, new_lm_hash
);
2175 /* Reset the hashes to not broken values */
2176 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
2177 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
2178 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
2179 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
2180 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
2181 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
2183 r
.in
.user_handle
= &user_handle
;
2184 r
.in
.lm_present
= 1;
2185 r
.in
.old_lm_crypted
= &hash1
;
2186 r
.in
.new_lm_crypted
= &hash2
;
2187 r
.in
.nt_present
= 1;
2188 r
.in
.old_nt_crypted
= &hash3
;
2189 r
.in
.new_nt_crypted
= &hash4
;
2190 r
.in
.cross1_present
= 0;
2191 r
.in
.nt_cross
= NULL
;
2192 r
.in
.cross2_present
= 1;
2193 r
.in
.lm_cross
= &hash6
;
2195 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
2196 "ChangePasswordUser failed");
2197 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2198 __location__
, __FUNCTION__
,
2199 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2200 if (NT_STATUS_IS_OK(r
.out
.result
)) {
2202 *password
= newpass
;
2203 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION
, r
.out
.result
)) {
2204 torture_result(tctx
, TORTURE_FAIL
, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r
.out
.result
));
2209 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2211 E_md4hash(oldpass
, old_nt_hash
);
2212 E_md4hash(newpass
, new_nt_hash
);
2213 E_deshash(oldpass
, old_lm_hash
);
2214 E_deshash(newpass
, new_lm_hash
);
2217 /* Reset the hashes to not broken values */
2218 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
2219 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
2220 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
2221 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
2222 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
2223 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
2225 r
.in
.user_handle
= &user_handle
;
2226 r
.in
.lm_present
= 1;
2227 r
.in
.old_lm_crypted
= &hash1
;
2228 r
.in
.new_lm_crypted
= &hash2
;
2229 r
.in
.nt_present
= 1;
2230 r
.in
.old_nt_crypted
= &hash3
;
2231 r
.in
.new_nt_crypted
= &hash4
;
2232 r
.in
.cross1_present
= 1;
2233 r
.in
.nt_cross
= &hash5
;
2234 r
.in
.cross2_present
= 1;
2235 r
.in
.lm_cross
= &hash6
;
2237 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
2238 "ChangePasswordUser failed");
2239 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2240 __location__
, __FUNCTION__
,
2241 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2242 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2243 torture_comment(tctx
, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r
.out
.result
));
2244 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2245 torture_result(tctx
, TORTURE_FAIL
, "ChangePasswordUser failed - %s\n", nt_errstr(r
.out
.result
));
2249 *password
= newpass
;
2252 r
.in
.user_handle
= &user_handle
;
2253 r
.in
.lm_present
= 1;
2254 r
.in
.old_lm_crypted
= &hash1
;
2255 r
.in
.new_lm_crypted
= &hash2
;
2256 r
.in
.nt_present
= 1;
2257 r
.in
.old_nt_crypted
= &hash3
;
2258 r
.in
.new_nt_crypted
= &hash4
;
2259 r
.in
.cross1_present
= 1;
2260 r
.in
.nt_cross
= &hash5
;
2261 r
.in
.cross2_present
= 1;
2262 r
.in
.lm_cross
= &hash6
;
2265 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser_r(b
, tctx
, &r
),
2266 "ChangePasswordUser failed");
2267 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2268 __location__
, __FUNCTION__
,
2269 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2270 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2271 torture_comment(tctx
, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r
.out
.result
));
2272 } else if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
2273 torture_result(tctx
, TORTURE_FAIL
, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(r
.out
.result
));
2279 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
2287 static bool test_OemChangePasswordUser2(struct dcerpc_pipe
*p
,
2288 struct torture_context
*tctx
,
2289 const char *acct_name
,
2290 struct policy_handle
*handle
, char **password
)
2292 struct samr_OemChangePasswordUser2 r
;
2294 struct samr_Password lm_verifier
;
2295 struct samr_CryptPassword lm_pass
;
2296 struct lsa_AsciiString server
, account
, account_bad
;
2299 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2300 uint8_t old_lm_hash
[16], new_lm_hash
[16];
2301 gnutls_cipher_hd_t cipher_hnd
= NULL
;
2302 gnutls_datum_t session_key
= {
2303 .data
= old_lm_hash
,
2307 struct samr_GetDomPwInfo dom_pw_info
;
2308 struct samr_PwInfo info
;
2309 int policy_min_pw_len
= 0;
2311 struct lsa_String domain_name
;
2313 domain_name
.string
= "";
2314 dom_pw_info
.in
.domain_name
= &domain_name
;
2315 dom_pw_info
.out
.info
= &info
;
2317 torture_comment(tctx
, "Testing OemChangePasswordUser2\n");
2319 torture_assert(tctx
, *password
!= NULL
,
2320 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
2322 oldpass
= *password
;
2324 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &dom_pw_info
),
2325 "GetDomPwInfo failed");
2326 if (NT_STATUS_IS_OK(dom_pw_info
.out
.result
)) {
2327 policy_min_pw_len
= dom_pw_info
.out
.info
->min_password_length
;
2330 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2332 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2333 account
.string
= acct_name
;
2335 E_deshash(oldpass
, old_lm_hash
);
2336 E_deshash(newpass
, new_lm_hash
);
2338 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
2340 gnutls_cipher_init(&cipher_hnd
,
2341 GNUTLS_CIPHER_ARCFOUR_128
,
2344 gnutls_cipher_encrypt(cipher_hnd
, lm_pass
.data
, 516);
2345 gnutls_cipher_deinit(cipher_hnd
);
2346 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
2348 r
.in
.server
= &server
;
2349 r
.in
.account
= &account
;
2350 r
.in
.password
= &lm_pass
;
2351 r
.in
.hash
= &lm_verifier
;
2353 /* Break the verification */
2354 lm_verifier
.hash
[0]++;
2356 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2357 "OemChangePasswordUser2 failed");
2358 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2359 __location__
, __FUNCTION__
,
2360 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2362 if (torture_setting_bool(tctx
, "samba4", false)) {
2363 torture_assert_ntstatus_equal(tctx
,
2365 NT_STATUS_NOT_IMPLEMENTED
,
2366 "Samba4 should refuse LM password change");
2368 * No point continuing, once we have checked this is not
2374 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)
2375 && !NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
2376 torture_result(tctx
, TORTURE_FAIL
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2377 nt_errstr(r
.out
.result
));
2381 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
2382 /* Break the old password */
2384 gnutls_cipher_init(&cipher_hnd
,
2385 GNUTLS_CIPHER_ARCFOUR_128
,
2388 gnutls_cipher_encrypt(cipher_hnd
, lm_pass
.data
, 516);
2389 gnutls_cipher_deinit(cipher_hnd
);
2390 /* unbreak it for the next operation */
2392 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
2394 r
.in
.server
= &server
;
2395 r
.in
.account
= &account
;
2396 r
.in
.password
= &lm_pass
;
2397 r
.in
.hash
= &lm_verifier
;
2399 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2400 "OemChangePasswordUser2 failed");
2401 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2402 __location__
, __FUNCTION__
,
2403 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2405 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)
2406 && !NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
2407 torture_result(tctx
, TORTURE_FAIL
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrypted password - %s\n",
2408 nt_errstr(r
.out
.result
));
2412 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
2413 gnutls_cipher_init(&cipher_hnd
,
2414 GNUTLS_CIPHER_ARCFOUR_128
,
2417 gnutls_cipher_encrypt(cipher_hnd
, lm_pass
.data
, 516);
2418 gnutls_cipher_deinit(cipher_hnd
);
2420 r
.in
.server
= &server
;
2421 r
.in
.account
= &account
;
2422 r
.in
.password
= &lm_pass
;
2425 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2426 "OemChangePasswordUser2 failed");
2427 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2428 __location__
, __FUNCTION__
,
2429 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2431 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)
2432 && !NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
2433 torture_result(tctx
, TORTURE_FAIL
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
2434 nt_errstr(r
.out
.result
));
2438 /* This shouldn't be a valid name */
2439 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
2440 r
.in
.account
= &account_bad
;
2442 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2443 "OemChangePasswordUser2 failed");
2444 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2445 __location__
, __FUNCTION__
,
2446 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2448 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
2449 torture_result(tctx
, TORTURE_FAIL
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
2450 nt_errstr(r
.out
.result
));
2454 /* This shouldn't be a valid name */
2455 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
2456 r
.in
.account
= &account_bad
;
2457 r
.in
.password
= &lm_pass
;
2458 r
.in
.hash
= &lm_verifier
;
2460 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2461 "OemChangePasswordUser2 failed");
2462 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2463 __location__
, __FUNCTION__
,
2464 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2466 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
2467 torture_result(tctx
, TORTURE_FAIL
, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2468 nt_errstr(r
.out
.result
));
2472 /* This shouldn't be a valid name */
2473 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
2474 r
.in
.account
= &account_bad
;
2475 r
.in
.password
= NULL
;
2476 r
.in
.hash
= &lm_verifier
;
2478 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2479 "OemChangePasswordUser2 failed");
2480 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2481 __location__
, __FUNCTION__
,
2482 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2484 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
2485 torture_result(tctx
, TORTURE_FAIL
, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2486 nt_errstr(r
.out
.result
));
2490 E_deshash(oldpass
, old_lm_hash
);
2491 E_deshash(newpass
, new_lm_hash
);
2493 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
2494 gnutls_cipher_init(&cipher_hnd
,
2495 GNUTLS_CIPHER_ARCFOUR_128
,
2498 gnutls_cipher_encrypt(cipher_hnd
, lm_pass
.data
, 516);
2499 gnutls_cipher_deinit(cipher_hnd
);
2500 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
2502 r
.in
.server
= &server
;
2503 r
.in
.account
= &account
;
2504 r
.in
.password
= &lm_pass
;
2505 r
.in
.hash
= &lm_verifier
;
2507 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OemChangePasswordUser2_r(b
, tctx
, &r
),
2508 "OemChangePasswordUser2 failed");
2509 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2510 __location__
, __FUNCTION__
,
2511 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2513 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2514 torture_comment(tctx
, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r
.out
.result
));
2515 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2516 torture_result(tctx
, TORTURE_FAIL
, "OemChangePasswordUser2 failed - %s\n", nt_errstr(r
.out
.result
));
2519 *password
= newpass
;
2526 static bool test_ChangePasswordUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2527 const char *acct_name
,
2529 char *newpass
, bool allow_password_restriction
)
2531 struct samr_ChangePasswordUser2 r
;
2533 struct lsa_String server
, account
;
2534 struct samr_CryptPassword nt_pass
, lm_pass
;
2535 struct samr_Password nt_verifier
, lm_verifier
;
2537 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2538 uint8_t old_nt_hash
[16] = { 0 }, new_nt_hash
[16];
2539 uint8_t old_lm_hash
[16], new_lm_hash
[16];
2540 DATA_BLOB old_nt_hash_blob
2541 = data_blob_const(old_nt_hash
, sizeof(old_nt_hash
));
2542 struct samr_GetDomPwInfo dom_pw_info
;
2543 struct samr_PwInfo info
;
2545 struct lsa_String domain_name
;
2548 gnutls_cipher_hd_t cipher_hnd
= NULL
;
2549 gnutls_datum_t old_lm_key
= {
2550 .data
= old_lm_hash
,
2551 .size
= sizeof(old_lm_hash
),
2554 domain_name
.string
= "";
2555 dom_pw_info
.in
.domain_name
= &domain_name
;
2556 dom_pw_info
.out
.info
= &info
;
2558 torture_comment(tctx
, "Testing ChangePasswordUser2 on %s\n", acct_name
);
2560 torture_assert(tctx
, *password
!= NULL
,
2561 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2562 oldpass
= *password
;
2565 int policy_min_pw_len
= 0;
2566 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &dom_pw_info
),
2567 "GetDomPwInfo failed");
2568 if (NT_STATUS_IS_OK(dom_pw_info
.out
.result
)) {
2569 policy_min_pw_len
= dom_pw_info
.out
.info
->min_password_length
;
2572 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2575 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2576 init_lsa_String(&account
, acct_name
);
2578 E_md4hash(oldpass
, old_nt_hash
);
2579 E_md4hash(newpass
, new_nt_hash
);
2581 E_deshash(oldpass
, old_lm_hash
);
2582 E_deshash(newpass
, new_lm_hash
);
2584 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
|STR_TERMINATE
);
2586 gnutls_cipher_init(&cipher_hnd
,
2587 GNUTLS_CIPHER_ARCFOUR_128
,
2590 gnutls_cipher_encrypt(cipher_hnd
,
2593 gnutls_cipher_deinit(cipher_hnd
);
2595 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2597 status
= init_samr_CryptPassword(newpass
,
2600 torture_assert_ntstatus_ok(tctx
,
2602 "init_samr_CryptPassword failed");
2604 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2606 r
.in
.server
= &server
;
2607 r
.in
.account
= &account
;
2608 r
.in
.nt_password
= &nt_pass
;
2609 r
.in
.nt_verifier
= &nt_verifier
;
2611 r
.in
.lm_password
= &lm_pass
;
2612 r
.in
.lm_verifier
= &lm_verifier
;
2614 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser2_r(b
, tctx
, &r
),
2615 "ChangePasswordUser2 failed");
2616 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2617 __location__
, __FUNCTION__
,
2618 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2620 if (allow_password_restriction
&& NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2621 torture_comment(tctx
, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r
.out
.result
));
2622 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
2623 torture_result(tctx
, TORTURE_FAIL
, "ChangePasswordUser2 failed - %s\n", nt_errstr(r
.out
.result
));
2626 *password
= newpass
;
2633 static bool test_ChangePasswordUser2_ntstatus(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2634 const char *acct_name
,
2635 const char *password
, NTSTATUS status
)
2637 struct samr_ChangePasswordUser2 r
;
2638 struct lsa_String server
, account
;
2639 struct samr_CryptPassword nt_pass
, lm_pass
;
2640 struct samr_Password nt_verifier
, lm_verifier
;
2641 const char *oldpass
;
2642 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2643 uint8_t old_nt_hash
[16] = { 0 }, new_nt_hash
[16];
2644 uint8_t old_lm_hash
[16], new_lm_hash
[16];
2645 DATA_BLOB old_nt_hash_blob
2646 = data_blob_const(old_nt_hash
, sizeof(old_nt_hash
));
2647 gnutls_cipher_hd_t cipher_hnd
= NULL
;
2648 gnutls_datum_t old_lm_key
= {
2649 .data
= old_lm_hash
,
2650 .size
= sizeof(old_lm_hash
),
2653 struct samr_GetDomPwInfo dom_pw_info
;
2654 struct samr_PwInfo info
;
2656 struct lsa_String domain_name
;
2657 NTSTATUS crypt_status
;
2660 int policy_min_pw_len
= 0;
2662 domain_name
.string
= "";
2663 dom_pw_info
.in
.domain_name
= &domain_name
;
2664 dom_pw_info
.out
.info
= &info
;
2666 torture_comment(tctx
, "Testing ChangePasswordUser2 on %s\n", acct_name
);
2670 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDomPwInfo_r(b
, tctx
, &dom_pw_info
),
2671 "GetDomPwInfo failed");
2672 if (NT_STATUS_IS_OK(dom_pw_info
.out
.result
)) {
2673 policy_min_pw_len
= dom_pw_info
.out
.info
->min_password_length
;
2676 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2678 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2679 init_lsa_String(&account
, acct_name
);
2681 E_md4hash(oldpass
, old_nt_hash
);
2682 E_md4hash(newpass
, new_nt_hash
);
2684 E_deshash(oldpass
, old_lm_hash
);
2685 E_deshash(newpass
, new_lm_hash
);
2687 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
|STR_TERMINATE
);
2689 gnutls_cipher_init(&cipher_hnd
,
2690 GNUTLS_CIPHER_ARCFOUR_128
,
2693 gnutls_cipher_encrypt(cipher_hnd
,
2696 gnutls_cipher_deinit(cipher_hnd
);
2698 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2700 crypt_status
= init_samr_CryptPassword(newpass
,
2703 torture_assert_ntstatus_ok(tctx
,
2705 "init_samr_CryptPassword failed");
2707 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2709 r
.in
.server
= &server
;
2710 r
.in
.account
= &account
;
2711 r
.in
.nt_password
= &nt_pass
;
2712 r
.in
.nt_verifier
= &nt_verifier
;
2714 r
.in
.lm_password
= &lm_pass
;
2715 r
.in
.lm_verifier
= &lm_verifier
;
2717 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser2_r(b
, tctx
, &r
),
2718 "ChangePasswordUser2 failed");
2719 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2720 __location__
, __FUNCTION__
,
2721 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2723 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2724 torture_comment(tctx
, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r
.out
.result
));
2726 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, status
, "ChangePasswordUser2 returned unexpected value");
2733 bool test_ChangePasswordUser3(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2734 const char *account_string
,
2735 int policy_min_pw_len
,
2737 const char *newpass
,
2738 NTTIME last_password_change
,
2739 bool handle_reject_reason
)
2741 struct samr_ChangePasswordUser3 r
;
2743 struct lsa_String server
, account
, account_bad
;
2744 struct samr_CryptPassword nt_pass
, lm_pass
;
2745 struct samr_Password nt_verifier
, lm_verifier
;
2747 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2748 uint8_t old_nt_hash
[16] = { 0 }, new_nt_hash
[16];
2749 uint8_t old_lm_hash
[16], new_lm_hash
[16];
2751 struct samr_DomInfo1
*dominfo
= NULL
;
2752 struct userPwdChangeFailureInformation
*reject
= NULL
;
2753 DATA_BLOB old_nt_hash_blob
= data_blob_const(old_nt_hash
, 16);
2756 torture_comment(tctx
, "Testing ChangePasswordUser3\n");
2758 if (newpass
== NULL
) {
2760 if (policy_min_pw_len
== 0) {
2761 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
2763 newpass
= samr_rand_pass_fixed_len(tctx
, policy_min_pw_len
);
2765 } while (check_password_quality(newpass
) == false);
2767 torture_comment(tctx
, "Using password '%s'\n", newpass
);
2770 torture_assert(tctx
, *password
!= NULL
,
2771 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2773 oldpass
= *password
;
2774 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2775 init_lsa_String(&account
, account_string
);
2777 E_md4hash(oldpass
, old_nt_hash
);
2778 E_md4hash(newpass
, new_nt_hash
);
2780 E_deshash(oldpass
, old_lm_hash
);
2781 E_deshash(newpass
, new_lm_hash
);
2784 * The new plaintext password is encrypted using RC4 with the
2785 * old NT password hash (directly, with no confounder). The
2786 * password is at the end of the random padded buffer,
2787 * offering a little protection.
2789 * This is almost certainly wrong, it should be the old LM
2790 * hash, it was switched in an unrelated commit
2791 * 579c13da43d5b40ac6d6c1436399fbc1d8dfd054 in 2004.
2793 status
= init_samr_CryptPassword(newpass
,
2796 torture_assert_ntstatus_ok(tctx
,
2798 "init_samr_CryptPassword");
2801 * Now we prepare a DES cross-hash of the old LM and new NT
2802 * passwords to link the two buffers
2804 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2807 * The new plaintext password is also encrypted using RC4 with
2808 * the old NT password hash (directly, with no confounder).
2809 * The password is at the end of the random padded buffer,
2810 * offering a little protection.
2812 status
= init_samr_CryptPassword(newpass
,
2815 torture_assert_ntstatus_ok(tctx
,
2817 "init_samr_CryptPassword");
2820 * Another DES based cross-hash
2822 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2824 /* Break the verification */
2825 nt_verifier
.hash
[0]++;
2827 r
.in
.server
= &server
;
2828 r
.in
.account
= &account
;
2829 r
.in
.nt_password
= &nt_pass
;
2830 r
.in
.nt_verifier
= &nt_verifier
;
2832 r
.in
.lm_password
= &lm_pass
;
2833 r
.in
.lm_verifier
= &lm_verifier
;
2834 r
.in
.password3
= NULL
;
2835 r
.out
.dominfo
= &dominfo
;
2836 r
.out
.reject
= &reject
;
2838 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2839 "ChangePasswordUser3 failed");
2840 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2841 __location__
, __FUNCTION__
,
2842 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2843 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
) &&
2844 (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
))) {
2845 torture_result(tctx
, TORTURE_FAIL
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2846 nt_errstr(r
.out
.result
));
2850 status
= init_samr_CryptPassword(newpass
,
2853 torture_assert_ntstatus_ok(tctx
,
2855 "init_samr_CryptPassword");
2857 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2859 /* Break the NT Hash */
2862 status
= init_samr_CryptPassword(newpass
,
2865 torture_assert_ntstatus_ok(tctx
,
2867 "init_samr_CryptPassword");
2869 /* Unbreak it again */
2872 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2874 r
.in
.server
= &server
;
2875 r
.in
.account
= &account
;
2876 r
.in
.nt_password
= &nt_pass
;
2877 r
.in
.nt_verifier
= &nt_verifier
;
2879 r
.in
.lm_password
= &lm_pass
;
2880 r
.in
.lm_verifier
= &lm_verifier
;
2881 r
.in
.password3
= NULL
;
2882 r
.out
.dominfo
= &dominfo
;
2883 r
.out
.reject
= &reject
;
2885 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2886 "ChangePasswordUser3 failed");
2887 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2888 __location__
, __FUNCTION__
,
2889 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2890 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
) &&
2891 (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
))) {
2892 torture_result(tctx
, TORTURE_FAIL
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrypted password - %s\n",
2893 nt_errstr(r
.out
.result
));
2897 /* This shouldn't be a valid name */
2898 init_lsa_String(&account_bad
, talloc_asprintf(tctx
, "%sXX", account_string
));
2900 r
.in
.account
= &account_bad
;
2901 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2902 "ChangePasswordUser3 failed");
2903 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2904 __location__
, __FUNCTION__
,
2905 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2906 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_WRONG_PASSWORD
)) {
2907 torture_result(tctx
, TORTURE_FAIL
, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2908 nt_errstr(r
.out
.result
));
2912 E_md4hash(oldpass
, old_nt_hash
);
2913 E_md4hash(newpass
, new_nt_hash
);
2915 E_deshash(oldpass
, old_lm_hash
);
2916 E_deshash(newpass
, new_lm_hash
);
2918 status
= init_samr_CryptPassword(newpass
,
2921 torture_assert_ntstatus_ok(tctx
,
2923 "init_samr_CryptPassword");
2925 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
2927 status
= init_samr_CryptPassword(newpass
,
2930 torture_assert_ntstatus_ok(tctx
,
2932 "init_samr_CryptPassword");
2934 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
2936 r
.in
.server
= &server
;
2937 r
.in
.account
= &account
;
2938 r
.in
.nt_password
= &nt_pass
;
2939 r
.in
.nt_verifier
= &nt_verifier
;
2941 r
.in
.lm_password
= &lm_pass
;
2942 r
.in
.lm_verifier
= &lm_verifier
;
2943 r
.in
.password3
= NULL
;
2944 r
.out
.dominfo
= &dominfo
;
2945 r
.out
.reject
= &reject
;
2947 unix_to_nt_time(&t
, time(NULL
));
2949 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
2950 "ChangePasswordUser3 failed");
2951 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2952 __location__
, __FUNCTION__
,
2953 oldpass
, newpass
, nt_errstr(r
.out
.result
));
2955 torture_comment(tctx
, "(%s): dominfo[%s], reject[%s], handle_reject_reason[%s], "
2956 "last_password_change[%s], dominfo->min_password_age[%lld]\n",
2958 (dominfo
== NULL
)? "NULL" : "present",
2959 reject
? "true" : "false",
2960 handle_reject_reason
? "true" : "false",
2961 null_nttime(last_password_change
) ? "null" : "not null",
2962 dominfo
? (long long)dominfo
->min_password_age
: (long long)0);
2964 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)
2967 && handle_reject_reason
2968 && (!null_nttime(last_password_change
) || !dominfo
->min_password_age
)) {
2969 if (dominfo
->password_properties
& DOMAIN_REFUSE_PASSWORD_CHANGE
) {
2971 if (reject
&& (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
)) {
2972 torture_result(tctx
, TORTURE_FAIL
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2973 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2978 /* We tested the order of precedence which is as follows:
2987 if ((dominfo
->min_password_age
< 0) && !null_nttime(last_password_change
) &&
2988 (last_password_change
- dominfo
->min_password_age
> t
)) {
2990 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
2991 torture_result(tctx
, TORTURE_FAIL
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2992 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
2996 } else if ((dominfo
->min_password_length
> 0) &&
2997 (strlen(newpass
) < dominfo
->min_password_length
)) {
2999 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
) {
3000 torture_result(tctx
, TORTURE_FAIL
, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
3001 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
, reject
->extendedFailureReason
);
3005 } else if ((dominfo
->password_history_length
> 0) &&
3006 strequal(oldpass
, newpass
)) {
3008 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_PWD_IN_HISTORY
) {
3009 torture_result(tctx
, TORTURE_FAIL
, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
3010 SAM_PWD_CHANGE_PWD_IN_HISTORY
, reject
->extendedFailureReason
);
3013 } else if (dominfo
->password_properties
& DOMAIN_PASSWORD_COMPLEX
) {
3015 if (reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NOT_COMPLEX
) {
3016 torture_result(tctx
, TORTURE_FAIL
, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
3017 SAM_PWD_CHANGE_NOT_COMPLEX
, reject
->extendedFailureReason
);
3023 if (reject
->extendedFailureReason
== SAM_PWD_CHANGE_PASSWORD_TOO_SHORT
) {
3024 /* retry with adjusted size */
3025 return test_ChangePasswordUser3(p
, tctx
, account_string
,
3026 dominfo
->min_password_length
,
3027 password
, NULL
, 0, false);
3031 } else if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
3032 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
3033 torture_result(tctx
, TORTURE_FAIL
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
3034 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
3037 /* Perhaps the server has a 'min password age' set? */
3040 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ChangePasswordUser3");
3042 *password
= talloc_strdup(tctx
, newpass
);
3048 bool test_ChangePasswordUser4(struct dcerpc_pipe
*p
,
3049 struct torture_context
*tctx
,
3050 const char *account_string
,
3051 int policy_min_pw_len
,
3053 const char *newpassword
)
3055 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3056 struct samr_ChangePasswordUser4 r
;
3057 const char *oldpassword
= *password
;
3058 char *srv_str
= NULL
;
3059 struct lsa_String server
;
3060 struct lsa_String account
;
3061 uint8_t old_nt_key_data
[16] = {0};
3062 gnutls_datum_t old_nt_key
= {
3063 .data
= old_nt_key_data
,
3064 .size
= sizeof(old_nt_key
),
3066 uint8_t cek_data
[16] = {0};
3069 .length
= sizeof(cek_data
),
3071 uint8_t pw_data
[514] = {0};
3072 DATA_BLOB plaintext
= {
3074 .length
= sizeof(pw_data
),
3076 DATA_BLOB ciphertext
= data_blob_null
;
3077 struct samr_EncryptedPasswordAES pwd_buf
= {.cipher_len
= 0};
3079 .data
= pwd_buf
.salt
,
3080 .length
= sizeof(pwd_buf
.salt
),
3082 gnutls_datum_t iv_datum
= {
3086 uint64_t pbkdf2_iterations
= generate_random_u64_range(5000, 1000000);
3091 torture_comment(tctx
, "Testing ChangePasswordUser4\n");
3093 if (newpassword
== NULL
) {
3095 if (policy_min_pw_len
== 0) {
3097 samr_rand_pass(tctx
, policy_min_pw_len
);
3099 newpassword
= samr_rand_pass_fixed_len(
3103 } while (check_password_quality(newpassword
) == false);
3105 torture_comment(tctx
, "Using password '%s'\n", newpassword
);
3108 torture_assert_not_null(tctx
,
3110 "Failing ChangePasswordUser4 as old password "
3111 "was NULL. Previous test failed?");
3113 srv_str
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
3114 torture_assert_not_null(tctx
, srv_str
, "srvstr is NULL");
3115 init_lsa_String(&server
, srv_str
);
3117 init_lsa_String(&account
, account_string
);
3119 E_md4hash(oldpassword
, old_nt_key_data
);
3121 generate_nonce_buffer(iv
.data
, iv
.length
);
3123 rc
= gnutls_pbkdf2(GNUTLS_MAC_SHA512
,
3129 torture_assert_int_equal(tctx
, rc
, 0, "gnutls_pbkdf2 failed");
3131 ok
= encode_pwd_buffer514_from_str(pw_data
, newpassword
, STR_UNICODE
);
3132 torture_assert(tctx
, ok
, "encode_aes_pw_buffer failed");
3134 status
= samba_gnutls_aead_aes_256_cbc_hmac_sha512_encrypt(
3138 &samr_aes256_enc_key_salt
,
3139 &samr_aes256_mac_key_salt
,
3143 torture_assert_ntstatus_ok(
3146 "samba_gnutls_aead_aes_256_cbc_hmac_sha512_encrypt failed");
3148 pwd_buf
.cipher_len
= ciphertext
.length
;
3149 pwd_buf
.cipher
= ciphertext
.data
;
3150 pwd_buf
.PBKDF2Iterations
= pbkdf2_iterations
;
3152 r
.in
.server
= &server
;
3153 r
.in
.account
= &account
;
3154 r
.in
.password
= &pwd_buf
;
3156 status
= dcerpc_samr_ChangePasswordUser4_r(b
, tctx
, &r
);
3157 torture_assert_ntstatus_ok(tctx
, status
, "ChangePasswordUser4 failed");
3159 *password
= talloc_strdup(tctx
, newpassword
);
3163 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
3164 const char *account_string
,
3165 struct policy_handle
*handle
,
3169 struct samr_ChangePasswordUser3 r
;
3170 struct samr_SetUserInfo s
;
3171 union samr_UserInfo u
;
3172 DATA_BLOB session_key
;
3175 struct lsa_String server
, account
;
3176 struct samr_CryptPassword nt_pass
;
3177 struct samr_Password nt_verifier
;
3178 DATA_BLOB new_random_pass
;
3181 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3182 uint8_t old_nt_hash
[16] = { 0 }, new_nt_hash
[16];
3183 DATA_BLOB old_nt_hash_blob
3184 = data_blob_const(old_nt_hash
,
3185 sizeof(old_nt_hash
));
3187 struct samr_DomInfo1
*dominfo
= NULL
;
3188 struct userPwdChangeFailureInformation
*reject
= NULL
;
3189 gnutls_cipher_hd_t cipher_hnd
= NULL
;
3190 uint8_t _confounder
[16] = {0};
3191 DATA_BLOB confounder
3192 = data_blob_const(_confounder
,
3193 sizeof(_confounder
));
3195 gnutls_datum_t old_nt_key
= {
3196 .data
= old_nt_hash
,
3197 .size
= sizeof(old_nt_hash
),
3200 new_random_pass
= samr_very_rand_pass(tctx
, 128);
3202 torture_assert(tctx
, *password
!= NULL
,
3203 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
3205 oldpass
= *password
;
3206 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
3207 init_lsa_String(&account
, account_string
);
3209 s
.in
.user_handle
= handle
;
3215 u
.info25
.info
.fields_present
= SAMR_FIELD_NT_PASSWORD_PRESENT
;
3217 set_pw_in_buffer(u
.info25
.password
.data
, &new_random_pass
);
3219 pw_data
= data_blob_const(u
.info25
.password
.data
, 516);
3221 status
= dcerpc_binding_handle_transport_session_key(b
, tctx
, &session_key
);
3222 if (!NT_STATUS_IS_OK(status
)) {
3223 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u - no session key - %s\n",
3224 s
.in
.level
, nt_errstr(status
));
3228 generate_random_buffer(_confounder
,
3229 sizeof(_confounder
));
3231 samba_gnutls_arcfour_confounded_md5(&confounder
,
3234 SAMBA_GNUTLS_ENCRYPT
);
3236 memcpy(&u
.info25
.password
.data
[516], _confounder
, sizeof(_confounder
));
3238 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
3240 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &s
),
3241 "SetUserInfo failed");
3242 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
3243 __location__
, __FUNCTION__
,
3244 oldpass
, "RANDOM", nt_errstr(s
.out
.result
));
3245 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
3246 torture_result(tctx
, TORTURE_FAIL
, "SetUserInfo level %u failed - %s\n",
3247 s
.in
.level
, nt_errstr(s
.out
.result
));
3251 torture_comment(tctx
, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
3253 mdfour(old_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
3255 new_random_pass
= samr_very_rand_pass(tctx
, 128);
3257 mdfour(new_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
3259 set_pw_in_buffer(nt_pass
.data
, &new_random_pass
);
3261 gnutls_cipher_init(&cipher_hnd
,
3262 GNUTLS_CIPHER_ARCFOUR_128
,
3265 gnutls_cipher_encrypt(cipher_hnd
,
3268 gnutls_cipher_deinit(cipher_hnd
);
3270 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
3272 r
.in
.server
= &server
;
3273 r
.in
.account
= &account
;
3274 r
.in
.nt_password
= &nt_pass
;
3275 r
.in
.nt_verifier
= &nt_verifier
;
3277 r
.in
.lm_password
= NULL
;
3278 r
.in
.lm_verifier
= NULL
;
3279 r
.in
.password3
= NULL
;
3280 r
.out
.dominfo
= &dominfo
;
3281 r
.out
.reject
= &reject
;
3283 unix_to_nt_time(&t
, time(NULL
));
3285 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
3286 "ChangePasswordUser3 failed");
3287 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
3288 __location__
, __FUNCTION__
,
3289 oldpass
, "RANDOM", nt_errstr(r
.out
.result
));
3291 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
3292 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
3293 torture_result(tctx
, TORTURE_FAIL
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
3294 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
3297 /* Perhaps the server has a 'min password age' set? */
3299 } else if (!NT_STATUS_IS_OK(r
.out
.result
)) {
3300 torture_result(tctx
, TORTURE_FAIL
, "ChangePasswordUser3 failed - %s\n", nt_errstr(r
.out
.result
));
3304 newpass
= samr_rand_pass(tctx
, 128);
3306 mdfour(old_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
3308 E_md4hash(newpass
, new_nt_hash
);
3310 status
= init_samr_CryptPassword(newpass
,
3313 torture_assert_ntstatus_ok(tctx
,
3315 "init_samr_CryptPassword failed");
3317 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
3319 r
.in
.server
= &server
;
3320 r
.in
.account
= &account
;
3321 r
.in
.nt_password
= &nt_pass
;
3322 r
.in
.nt_verifier
= &nt_verifier
;
3324 r
.in
.lm_password
= NULL
;
3325 r
.in
.lm_verifier
= NULL
;
3326 r
.in
.password3
= NULL
;
3327 r
.out
.dominfo
= &dominfo
;
3328 r
.out
.reject
= &reject
;
3330 unix_to_nt_time(&t
, time(NULL
));
3332 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_ChangePasswordUser3_r(b
, tctx
, &r
),
3333 "ChangePasswordUser3 failed");
3334 torture_comment(tctx
, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
3335 __location__
, __FUNCTION__
,
3336 oldpass
, newpass
, nt_errstr(r
.out
.result
));
3338 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_PASSWORD_RESTRICTION
)) {
3339 if (reject
&& reject
->extendedFailureReason
!= SAM_PWD_CHANGE_NO_ERROR
) {
3340 torture_result(tctx
, TORTURE_FAIL
, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
3341 SAM_PWD_CHANGE_NO_ERROR
, reject
->extendedFailureReason
);
3344 /* Perhaps the server has a 'min password age' set? */
3347 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ChangePasswordUser3 (on second random password)");
3348 *password
= talloc_strdup(tctx
, newpass
);
3355 static bool test_GetMembersInAlias(struct dcerpc_binding_handle
*b
,
3356 struct torture_context
*tctx
,
3357 struct policy_handle
*alias_handle
)
3359 struct samr_GetMembersInAlias r
;
3360 struct lsa_SidArray sids
;
3362 torture_comment(tctx
, "Testing GetMembersInAlias\n");
3364 r
.in
.alias_handle
= alias_handle
;
3367 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetMembersInAlias_r(b
, tctx
, &r
),
3368 "GetMembersInAlias failed");
3369 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "GetMembersInAlias failed");
3374 static bool test_AddMemberToAlias(struct dcerpc_binding_handle
*b
,
3375 struct torture_context
*tctx
,
3376 struct policy_handle
*alias_handle
,
3377 const struct dom_sid
*domain_sid
)
3379 struct samr_AddAliasMember r
;
3380 struct samr_DeleteAliasMember d
;
3381 struct dom_sid
*sid
;
3383 sid
= dom_sid_add_rid(tctx
, domain_sid
, 512);
3385 torture_comment(tctx
, "Testing AddAliasMember\n");
3386 r
.in
.alias_handle
= alias_handle
;
3389 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddAliasMember_r(b
, tctx
, &r
),
3390 "AddAliasMember failed");
3391 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "AddAliasMember failed");
3393 d
.in
.alias_handle
= alias_handle
;
3396 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteAliasMember_r(b
, tctx
, &d
),
3397 "DeleteAliasMember failed");
3398 torture_assert_ntstatus_ok(tctx
, d
.out
.result
, "DelAliasMember failed");
3403 static bool test_AddMultipleMembersToAlias(struct dcerpc_binding_handle
*b
,
3404 struct torture_context
*tctx
,
3405 struct policy_handle
*alias_handle
)
3407 struct samr_AddMultipleMembersToAlias a
;
3408 struct samr_RemoveMultipleMembersFromAlias r
;
3409 struct lsa_SidArray sids
;
3411 torture_comment(tctx
, "Testing AddMultipleMembersToAlias\n");
3412 a
.in
.alias_handle
= alias_handle
;
3416 sids
.sids
= talloc_array(tctx
, struct lsa_SidPtr
, 3);
3418 sids
.sids
[0].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-1");
3419 sids
.sids
[1].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-2");
3420 sids
.sids
[2].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-3");
3422 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddMultipleMembersToAlias_r(b
, tctx
, &a
),
3423 "AddMultipleMembersToAlias failed");
3424 torture_assert_ntstatus_ok(tctx
, a
.out
.result
, "AddMultipleMembersToAlias");
3427 torture_comment(tctx
, "Testing RemoveMultipleMembersFromAlias\n");
3428 r
.in
.alias_handle
= alias_handle
;
3431 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b
, tctx
, &r
),
3432 "RemoveMultipleMembersFromAlias failed");
3433 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "RemoveMultipleMembersFromAlias failed");
3435 /* strange! removing twice doesn't give any error */
3436 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b
, tctx
, &r
),
3437 "RemoveMultipleMembersFromAlias failed");
3438 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "RemoveMultipleMembersFromAlias failed");
3440 /* but removing an alias that isn't there does */
3441 sids
.sids
[2].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-4");
3443 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b
, tctx
, &r
),
3444 "RemoveMultipleMembersFromAlias failed");
3445 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
, "RemoveMultipleMembersFromAlias");
3450 static bool test_GetAliasMembership(struct dcerpc_binding_handle
*b
,
3451 struct torture_context
*tctx
,
3452 struct policy_handle
*domain_handle
)
3454 struct samr_GetAliasMembership r
;
3455 struct lsa_SidArray sids
;
3456 struct samr_Ids rids
;
3458 torture_comment(tctx
, "Testing GetAliasMembership\n");
3460 r
.in
.domain_handle
= domain_handle
;
3465 sids
.sids
= talloc_zero_array(tctx
, struct lsa_SidPtr
, sids
.num_sids
);
3467 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetAliasMembership_r(b
, tctx
, &r
),
3468 "GetAliasMembership failed");
3469 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
3470 "samr_GetAliasMembership failed");
3472 torture_assert_int_equal(tctx
, sids
.num_sids
, rids
.count
,
3473 "protocol misbehaviour");
3476 sids
.sids
= talloc_zero_array(tctx
, struct lsa_SidPtr
, sids
.num_sids
);
3477 sids
.sids
[0].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-1");
3479 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetAliasMembership_r(b
, tctx
, &r
),
3480 "samr_GetAliasMembership failed");
3481 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
3482 "samr_GetAliasMembership failed");
3485 /* only true for w2k8 it seems
3486 * win7, xp, w2k3 will return a 0 length array pointer */
3488 if (rids
.ids
&& (rids
.count
== 0)) {
3489 torture_fail(tctx
, "samr_GetAliasMembership returned 0 count and a rids array");
3492 if (!rids
.ids
&& rids
.count
) {
3493 torture_fail(tctx
, "samr_GetAliasMembership returned non-0 count but no rids");
3499 static bool test_TestPrivateFunctionsUser(struct dcerpc_binding_handle
*b
,
3500 struct torture_context
*tctx
,
3501 struct policy_handle
*user_handle
)
3503 struct samr_TestPrivateFunctionsUser r
;
3505 torture_comment(tctx
, "Testing TestPrivateFunctionsUser\n");
3507 r
.in
.user_handle
= user_handle
;
3509 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_TestPrivateFunctionsUser_r(b
, tctx
, &r
),
3510 "TestPrivateFunctionsUser failed");
3511 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_NOT_IMPLEMENTED
, "TestPrivateFunctionsUser");
3516 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_binding_handle
*b
,
3517 struct torture_context
*tctx
,
3518 struct policy_handle
*handle
,
3523 uint16_t levels
[] = { /* 3, */ 5, 21 };
3525 /* NTTIME pwdlastset3 = 0; */
3526 NTTIME pwdlastset5
= 0;
3527 NTTIME pwdlastset21
= 0;
3529 torture_comment(tctx
, "Testing QueryUserInfo%s level 5 and 21 call ",
3530 use_info2
? "2":"");
3532 for (i
=0; i
<ARRAY_SIZE(levels
); i
++) {
3534 struct samr_QueryUserInfo r
;
3535 struct samr_QueryUserInfo2 r2
;
3536 union samr_UserInfo
*info
;
3539 r2
.in
.user_handle
= handle
;
3540 r2
.in
.level
= levels
[i
];
3541 r2
.out
.info
= &info
;
3542 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo2_r(b
, tctx
, &r2
),
3543 "QueryUserInfo2 failed");
3544 status
= r2
.out
.result
;
3547 r
.in
.user_handle
= handle
;
3548 r
.in
.level
= levels
[i
];
3550 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
3551 "QueryUserInfo failed");
3552 status
= r
.out
.result
;
3555 if (!NT_STATUS_IS_OK(status
) &&
3556 !NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_INFO_CLASS
)) {
3557 torture_result(tctx
, TORTURE_FAIL
, "QueryUserInfo%s level %u failed - %s\n",
3558 use_info2
? "2":"", levels
[i
], nt_errstr(status
));
3562 switch (levels
[i
]) {
3564 /* pwdlastset3 = info->info3.last_password_change; */
3567 pwdlastset5
= info
->info5
.last_password_change
;
3570 pwdlastset21
= info
->info21
.last_password_change
;
3576 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
3577 "pwdlastset mixup"); */
3578 torture_assert_int_equal(tctx
, pwdlastset5
, pwdlastset21
,
3579 "pwdlastset mixup");
3581 *pwdlastset
= pwdlastset21
;
3583 torture_comment(tctx
, "(pwdlastset: %llu)\n",
3584 (unsigned long long) *pwdlastset
);
3589 static bool test_SamLogon(struct torture_context
*tctx
,
3590 struct dcerpc_pipe
*p
,
3591 struct cli_credentials
*machine_credentials
,
3592 struct cli_credentials
*test_credentials
,
3593 NTSTATUS expected_result
,
3597 struct netr_LogonSamLogonEx r
;
3598 union netr_LogonLevel logon
;
3599 union netr_Validation validation
;
3600 uint8_t authoritative
;
3601 struct netr_IdentityInfo identity
= {};
3602 struct netr_NetworkInfo ninfo
;
3603 struct netr_PasswordInfo pinfo
;
3604 DATA_BLOB names_blob
, chal
, lm_resp
, nt_resp
;
3605 int flags
= CLI_CRED_NTLM_AUTH
;
3606 uint32_t samlogon_flags
= 0;
3607 struct netlogon_creds_CredentialState
*creds
;
3608 struct netr_Authenticator a
;
3609 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3610 enum dcerpc_AuthType auth_type
= DCERPC_AUTH_TYPE_NONE
;
3611 enum dcerpc_AuthLevel auth_level
= DCERPC_AUTH_LEVEL_NONE
;
3613 torture_assert(tctx
, (creds
= cli_credentials_get_netlogon_creds(machine_credentials
)), "");
3615 if (lpcfg_client_lanman_auth(tctx
->lp_ctx
)) {
3616 flags
|= CLI_CRED_LANMAN_AUTH
;
3619 if (lpcfg_client_ntlmv2_auth(tctx
->lp_ctx
)) {
3620 flags
|= CLI_CRED_NTLMv2_AUTH
;
3623 cli_credentials_get_ntlm_username_domain(test_credentials
, tctx
,
3624 &identity
.account_name
.string
,
3625 &identity
.domain_name
.string
);
3627 identity
.parameter_control
=
3628 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT
|
3629 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT
;
3630 identity
.logon_id
= 0;
3631 identity
.workstation
.string
= cli_credentials_get_workstation(test_credentials
);
3634 netlogon_creds_client_authenticator(creds
, &a
);
3636 if (!E_deshash(cli_credentials_get_password(test_credentials
), pinfo
.lmpassword
.hash
)) {
3637 ZERO_STRUCT(pinfo
.lmpassword
.hash
);
3639 E_md4hash(cli_credentials_get_password(test_credentials
), pinfo
.ntpassword
.hash
);
3641 pinfo
.identity_info
= identity
;
3642 logon
.password
= &pinfo
;
3644 r
.in
.logon_level
= NetlogonInteractiveInformation
;
3646 generate_random_buffer(ninfo
.challenge
,
3647 sizeof(ninfo
.challenge
));
3648 chal
= data_blob_const(ninfo
.challenge
,
3649 sizeof(ninfo
.challenge
));
3651 names_blob
= NTLMv2_generate_names_blob(tctx
, cli_credentials_get_workstation(test_credentials
),
3652 cli_credentials_get_domain(test_credentials
));
3654 status
= cli_credentials_get_ntlm_response(test_credentials
, tctx
,
3657 NULL
, /* server_timestamp */
3661 torture_assert_ntstatus_ok(tctx
, status
, "cli_credentials_get_ntlm_response failed");
3663 ninfo
.lm
.data
= lm_resp
.data
;
3664 ninfo
.lm
.length
= lm_resp
.length
;
3666 ninfo
.nt
.data
= nt_resp
.data
;
3667 ninfo
.nt
.length
= nt_resp
.length
;
3669 ninfo
.identity_info
= identity
;
3670 logon
.network
= &ninfo
;
3672 r
.in
.logon_level
= NetlogonNetworkInformation
;
3675 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
3676 r
.in
.computer_name
= cli_credentials_get_workstation(test_credentials
);
3677 r
.in
.logon
= &logon
;
3678 r
.in
.flags
= &samlogon_flags
;
3679 r
.out
.flags
= &samlogon_flags
;
3680 r
.out
.validation
= &validation
;
3681 r
.out
.authoritative
= &authoritative
;
3683 torture_comment(tctx
, "Testing LogonSamLogon with name %s\n", identity
.account_name
.string
);
3685 r
.in
.validation_level
= 6;
3687 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
3688 status
= netlogon_creds_encrypt_samlogon_logon(creds
,
3693 torture_assert_ntstatus_ok(tctx
, status
, "encrypt_samlogon_logon");
3695 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonSamLogonEx_r(b
, tctx
, &r
),
3696 "netr_LogonSamLogonEx failed");
3697 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_INFO_CLASS
)) {
3698 r
.in
.validation_level
= 3;
3699 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_LogonSamLogonEx_r(b
, tctx
, &r
),
3700 "netr_LogonSamLogonEx failed");
3702 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
3703 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, expected_result
, "LogonSamLogonEx failed");
3706 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LogonSamLogonEx failed");
3712 static bool test_SamLogon_with_creds(struct torture_context
*tctx
,
3713 struct dcerpc_pipe
*p
,
3714 struct cli_credentials
*machine_creds
,
3715 const char *acct_name
,
3716 const char *password
,
3717 NTSTATUS expected_samlogon_result
,
3721 struct cli_credentials
*test_credentials
;
3723 test_credentials
= cli_credentials_init(tctx
);
3725 cli_credentials_set_workstation(test_credentials
,
3726 cli_credentials_get_workstation(machine_creds
), CRED_SPECIFIED
);
3727 cli_credentials_set_domain(test_credentials
,
3728 cli_credentials_get_domain(machine_creds
), CRED_SPECIFIED
);
3729 cli_credentials_set_username(test_credentials
,
3730 acct_name
, CRED_SPECIFIED
);
3731 cli_credentials_set_password(test_credentials
,
3732 password
, CRED_SPECIFIED
);
3734 torture_comment(tctx
, "Testing samlogon (%s) as %s password: %s\n",
3735 interactive
? "interactive" : "network", acct_name
, password
);
3737 if (!test_SamLogon(tctx
, p
, machine_creds
, test_credentials
,
3738 expected_samlogon_result
, interactive
)) {
3739 torture_result(tctx
, TORTURE_FAIL
, "new password did not work\n");
3746 static bool test_SetPassword_level(struct dcerpc_pipe
*p
,
3747 struct dcerpc_pipe
*np
,
3748 struct torture_context
*tctx
,
3749 struct policy_handle
*handle
,
3751 uint32_t fields_present
,
3752 uint8_t password_expired
,
3753 bool *matched_expected_error
,
3755 const char *acct_name
,
3757 struct cli_credentials
*machine_creds
,
3758 bool use_queryinfo2
,
3760 NTSTATUS expected_samlogon_result
)
3762 const char *fields
= NULL
;
3764 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
3771 fields
= talloc_asprintf(tctx
, "(fields_present: 0x%08x)",
3778 torture_comment(tctx
, "Testing SetUserInfo%s level %d call "
3779 "(password_expired: %d) %s\n",
3780 use_setinfo2
? "2":"", level
, password_expired
,
3781 fields
? fields
: "");
3783 if (!test_SetUserPass_level_ex(p
, tctx
, handle
, level
,
3788 matched_expected_error
)) {
3792 if (!test_QueryUserInfo_pwdlastset(b
, tctx
, handle
,
3798 if (*matched_expected_error
== true) {
3802 if (!test_SamLogon_with_creds(tctx
, np
,
3806 expected_samlogon_result
,
3814 static bool setup_schannel_netlogon_pipe(struct torture_context
*tctx
,
3815 struct cli_credentials
*credentials
,
3816 struct dcerpc_pipe
**p
)
3818 struct dcerpc_binding
*b
;
3821 torture_assert_ntstatus_ok(tctx
, torture_rpc_binding(tctx
, &b
),
3822 "failed to get rpc binding");
3824 /* We have to use schannel, otherwise the SamLogonEx fails
3825 * with INTERNAL_ERROR */
3827 status
= dcerpc_binding_set_flags(b
,
3829 DCERPC_SIGN
| DCERPC_SEAL
|
3830 DCERPC_SCHANNEL_AUTO
,
3831 DCERPC_AUTH_OPTIONS
);
3832 torture_assert_ntstatus_ok(tctx
, status
, "set flags");
3834 torture_assert_ntstatus_ok(tctx
,
3835 dcerpc_pipe_connect_b(tctx
, p
, b
, &ndr_table_netlogon
,
3836 credentials
, tctx
->ev
, tctx
->lp_ctx
),
3837 "failed to bind to netlogon");
3842 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe
*p
,
3843 struct torture_context
*tctx
,
3844 uint32_t acct_flags
,
3845 const char *acct_name
,
3846 struct policy_handle
*handle
,
3848 struct cli_credentials
*machine_credentials
)
3850 int s
= 0, q
= 0, f
= 0, l
= 0, z
= 0;
3853 bool set_levels
[] = { false, true };
3854 bool query_levels
[] = { false, true };
3855 uint32_t levels
[] = { 18, 21, 26, 23, 24, 25, 31 }; /* Second half only used when TEST_ALL_LEVELS defined */
3856 uint32_t nonzeros
[] = { 1, 24 };
3857 uint32_t fields_present
[] = {
3859 SAMR_FIELD_EXPIRED_FLAG
,
3860 SAMR_FIELD_LAST_PWD_CHANGE
,
3861 SAMR_FIELD_EXPIRED_FLAG
| SAMR_FIELD_LAST_PWD_CHANGE
,
3863 SAMR_FIELD_NT_PASSWORD_PRESENT
,
3864 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
,
3865 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
,
3866 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
,
3867 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_EXPIRED_FLAG
,
3868 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_EXPIRED_FLAG
,
3869 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_LAST_PWD_CHANGE
| SAMR_FIELD_EXPIRED_FLAG
3871 struct dcerpc_pipe
*np
= NULL
;
3873 if (torture_setting_bool(tctx
, "samba3", false) ||
3874 torture_setting_bool(tctx
, "samba4", false)) {
3876 torture_comment(tctx
, "Samba3 has second granularity, setting delay to: %d\n",
3880 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
3882 /* set to 1 to enable testing for all possible opcode
3883 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3886 #define TEST_ALL_LEVELS 1
3887 #define TEST_SET_LEVELS 1
3888 #define TEST_QUERY_LEVELS 1
3890 #ifdef TEST_ALL_LEVELS
3891 for (l
=0; l
<ARRAY_SIZE(levels
); l
++) {
3893 for (l
=0; l
<(ARRAY_SIZE(levels
))/2; l
++) {
3895 for (z
=0; z
<ARRAY_SIZE(nonzeros
); z
++) {
3896 for (f
=0; f
<ARRAY_SIZE(fields_present
); f
++) {
3897 #ifdef TEST_SET_LEVELS
3898 for (s
=0; s
<ARRAY_SIZE(set_levels
); s
++) {
3900 #ifdef TEST_QUERY_LEVELS
3901 for (q
=0; q
<ARRAY_SIZE(query_levels
); q
++) {
3903 NTTIME pwdlastset_old
= 0;
3904 NTTIME pwdlastset_new
= 0;
3905 bool matched_expected_error
= false;
3906 NTSTATUS expected_samlogon_result
= NT_STATUS_ACCOUNT_DISABLED
;
3908 torture_comment(tctx
, "------------------------------\n"
3909 "Testing pwdLastSet attribute for flags: 0x%08x "
3910 "(s: %d (l: %d), q: %d)\n",
3911 acct_flags
, s
, levels
[l
], q
);
3913 switch (levels
[l
]) {
3918 if (!((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3919 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
))) {
3920 expected_samlogon_result
= NT_STATUS_WRONG_PASSWORD
;
3928 /* set a password and force password change (pwdlastset 0) by
3929 * setting the password expired flag to a non-0 value */
3931 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
3935 &matched_expected_error
,
3939 machine_credentials
,
3942 expected_samlogon_result
)) {
3946 if (matched_expected_error
== true) {
3947 /* skipping on expected failure */
3951 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3952 * set without the SAMR_FIELD_EXPIRED_FLAG */
3954 switch (levels
[l
]) {
3959 if ((pwdlastset_new
!= 0) &&
3960 !(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
)) {
3961 torture_comment(tctx
, "not considering a non-0 "
3962 "pwdLastSet as a an error as the "
3963 "SAMR_FIELD_EXPIRED_FLAG has not "
3969 if (pwdlastset_new
!= 0) {
3970 torture_result(tctx
, TORTURE_FAIL
, "pwdLastSet test failed: "
3971 "expected pwdLastSet 0 but got %llu\n",
3972 (unsigned long long) pwdlastset_old
);
3978 switch (levels
[l
]) {
3983 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
3984 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
3985 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
3986 (pwdlastset_old
>= pwdlastset_new
)) {
3987 torture_result(tctx
, TORTURE_FAIL
, "pwdlastset not increasing\n");
3993 pwdlastset_old
= pwdlastset_new
;
3999 /* set a password, pwdlastset needs to get updated (increased
4000 * value), password_expired value used here is 0 */
4002 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
4006 &matched_expected_error
,
4010 machine_credentials
,
4013 expected_samlogon_result
)) {
4017 /* when a password has been changed, pwdlastset must not be 0 afterwards
4018 * and must be larger then the old value */
4020 switch (levels
[l
]) {
4025 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
4026 * password has been changed, old and new pwdlastset
4027 * need to be the same value */
4029 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
4030 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
4031 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
4033 torture_assert_int_equal(tctx
, pwdlastset_old
,
4034 pwdlastset_new
, "pwdlastset must be equal");
4039 if (pwdlastset_old
>= pwdlastset_new
) {
4040 torture_result(tctx
, TORTURE_FAIL
, "pwdLastSet test failed: "
4041 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
4042 (unsigned long long) pwdlastset_old
,
4043 (unsigned long long) pwdlastset_new
);
4046 if (pwdlastset_new
== 0) {
4047 torture_result(tctx
, TORTURE_FAIL
, "pwdLastSet test failed: "
4048 "expected non-0 pwdlastset, got: %llu\n",
4049 (unsigned long long) pwdlastset_new
);
4055 switch (levels
[l
]) {
4060 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
4061 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
4062 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
4063 (pwdlastset_old
>= pwdlastset_new
)) {
4064 torture_result(tctx
, TORTURE_FAIL
, "pwdlastset not increasing\n");
4070 pwdlastset_old
= pwdlastset_new
;
4076 /* set a password, pwdlastset needs to get updated (increased
4077 * value), password_expired value used here is 0 */
4079 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
4083 &matched_expected_error
,
4087 machine_credentials
,
4090 expected_samlogon_result
)) {
4094 /* when a password has been changed, pwdlastset must not be 0 afterwards
4095 * and must be larger then the old value */
4097 switch (levels
[l
]) {
4102 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
4103 * password has been changed, old and new pwdlastset
4104 * need to be the same value */
4106 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
4107 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
4108 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
4110 torture_assert_int_equal(tctx
, pwdlastset_old
,
4111 pwdlastset_new
, "pwdlastset must be equal");
4116 if (pwdlastset_old
>= pwdlastset_new
) {
4117 torture_result(tctx
, TORTURE_FAIL
, "pwdLastSet test failed: "
4118 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
4119 (unsigned long long) pwdlastset_old
,
4120 (unsigned long long) pwdlastset_new
);
4123 if (pwdlastset_new
== 0) {
4124 torture_result(tctx
, TORTURE_FAIL
, "pwdLastSet test failed: "
4125 "expected non-0 pwdlastset, got: %llu\n",
4126 (unsigned long long) pwdlastset_new
);
4132 switch (levels
[l
]) {
4137 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
4138 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
4139 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
4140 (pwdlastset_old
>= pwdlastset_new
)) {
4141 torture_result(tctx
, TORTURE_FAIL
, "pwdlastset not increasing\n");
4147 pwdlastset_old
= pwdlastset_new
;
4153 /* set a password and force password change (pwdlastset 0) by
4154 * setting the password expired flag to a non-0 value */
4156 if (!test_SetPassword_level(p
, np
, tctx
, handle
,
4160 &matched_expected_error
,
4164 machine_credentials
,
4167 expected_samlogon_result
)) {
4171 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
4172 * set without the SAMR_FIELD_EXPIRED_FLAG */
4174 switch (levels
[l
]) {
4179 if ((pwdlastset_new
!= 0) &&
4180 !(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
)) {
4181 torture_comment(tctx
, "not considering a non-0 "
4182 "pwdLastSet as a an error as the "
4183 "SAMR_FIELD_EXPIRED_FLAG has not "
4188 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
4189 * password has been changed, old and new pwdlastset
4190 * need to be the same value */
4192 if (!(fields_present
[f
] & SAMR_FIELD_EXPIRED_FLAG
) &&
4193 !((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
4194 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)))
4196 torture_assert_int_equal(tctx
, pwdlastset_old
,
4197 pwdlastset_new
, "pwdlastset must be equal");
4202 if (pwdlastset_new
!= 0) {
4203 torture_result(tctx
, TORTURE_FAIL
, "pwdLastSet test failed: "
4204 "expected pwdLastSet 0, got %llu\n",
4205 (unsigned long long) pwdlastset_old
);
4211 switch (levels
[l
]) {
4216 if (((fields_present
[f
] & SAMR_FIELD_NT_PASSWORD_PRESENT
) ||
4217 (fields_present
[f
] & SAMR_FIELD_LM_PASSWORD_PRESENT
)) &&
4218 (pwdlastset_old
> 0) && (pwdlastset_new
> 0) &&
4219 (pwdlastset_old
>= pwdlastset_new
)) {
4220 torture_result(tctx
, TORTURE_FAIL
, "pwdlastset not increasing\n");
4226 /* if the level we are testing does not have a fields_present
4227 * field, skip all fields present tests by setting f to to
4229 switch (levels
[l
]) {
4234 f
= ARRAY_SIZE(fields_present
);
4238 #ifdef TEST_QUERY_LEVELS
4241 #ifdef TEST_SET_LEVELS
4244 } /* fields present */
4248 #undef TEST_SET_LEVELS
4249 #undef TEST_QUERY_LEVELS
4256 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_binding_handle
*b
,
4257 struct torture_context
*tctx
,
4258 struct policy_handle
*handle
,
4259 uint32_t *badpwdcount
)
4261 union samr_UserInfo
*info
;
4262 struct samr_QueryUserInfo r
;
4264 r
.in
.user_handle
= handle
;
4268 torture_comment(tctx
, "Testing QueryUserInfo level %d", r
.in
.level
);
4270 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
4271 "failed to query userinfo");
4272 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4273 "failed to query userinfo");
4275 *badpwdcount
= info
->info3
.bad_password_count
;
4277 torture_comment(tctx
, " (bad password count: %d)\n", *badpwdcount
);
4282 static bool test_SetUserInfo_acct_flags(struct dcerpc_binding_handle
*b
,
4283 struct torture_context
*tctx
,
4284 struct policy_handle
*user_handle
,
4285 uint32_t acct_flags
)
4287 struct samr_SetUserInfo r
;
4288 union samr_UserInfo user_info
;
4290 torture_comment(tctx
, "Testing SetUserInfo level 16\n");
4292 user_info
.info16
.acct_flags
= acct_flags
;
4294 r
.in
.user_handle
= user_handle
;
4296 r
.in
.info
= &user_info
;
4298 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetUserInfo_r(b
, tctx
, &r
),
4299 "failed to set account flags");
4300 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4301 "failed to set account flags");
4306 static bool test_reset_badpwdcount(struct dcerpc_pipe
*p
,
4307 struct torture_context
*tctx
,
4308 struct policy_handle
*user_handle
,
4309 uint32_t acct_flags
,
4312 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4314 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
4315 "failed to set password");
4317 torture_comment(tctx
, "Testing SetUserInfo level 16 (enable account)\n");
4319 torture_assert(tctx
,
4320 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
4321 acct_flags
& ~ACB_DISABLED
),
4322 "failed to enable user");
4324 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
4325 "failed to set password");
4330 static bool test_SetDomainInfo(struct dcerpc_binding_handle
*b
,
4331 struct torture_context
*tctx
,
4332 struct policy_handle
*domain_handle
,
4333 enum samr_DomainInfoClass level
,
4334 union samr_DomainInfo
*info
)
4336 struct samr_SetDomainInfo r
;
4338 r
.in
.domain_handle
= domain_handle
;
4342 torture_assert_ntstatus_ok(tctx
,
4343 dcerpc_samr_SetDomainInfo_r(b
, tctx
, &r
),
4344 "failed to set domain info");
4345 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4346 "failed to set domain info");
4351 static bool test_SetDomainInfo_ntstatus(struct dcerpc_binding_handle
*b
,
4352 struct torture_context
*tctx
,
4353 struct policy_handle
*domain_handle
,
4354 enum samr_DomainInfoClass level
,
4355 union samr_DomainInfo
*info
,
4358 struct samr_SetDomainInfo r
;
4360 r
.in
.domain_handle
= domain_handle
;
4364 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &r
),
4365 "SetDomainInfo failed");
4366 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, expected
, "");
4371 static bool test_QueryDomainInfo2_level(struct dcerpc_binding_handle
*b
,
4372 struct torture_context
*tctx
,
4373 struct policy_handle
*domain_handle
,
4374 enum samr_DomainInfoClass level
,
4375 union samr_DomainInfo
**q_info
)
4377 struct samr_QueryDomainInfo2 r
;
4379 r
.in
.domain_handle
= domain_handle
;
4381 r
.out
.info
= q_info
;
4383 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo2_r(b
, tctx
, &r
),
4384 "failed to query domain info");
4385 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4386 "failed to query domain info");
4391 static bool test_Password_badpwdcount(struct dcerpc_pipe
*p
,
4392 struct dcerpc_pipe
*np
,
4393 struct torture_context
*tctx
,
4394 uint32_t acct_flags
,
4395 const char *acct_name
,
4396 struct policy_handle
*domain_handle
,
4397 struct policy_handle
*user_handle
,
4399 struct cli_credentials
*machine_credentials
,
4400 const char *comment
,
4403 NTSTATUS expected_success_status
,
4404 struct samr_DomInfo1
*info1
,
4405 struct samr_DomInfo12
*info12
)
4407 union samr_DomainInfo info
;
4410 uint32_t badpwdcount
, tmp
;
4411 uint32_t password_history_length
= 12;
4412 uint32_t lockout_threshold
= 15;
4413 uint32_t lockout_seconds
= 5;
4414 uint64_t delta_time_factor
= 10 * 1000 * 1000;
4415 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4417 if (torture_setting_bool(tctx
, "samba3", false)) {
4418 lockout_seconds
= 60;
4421 torture_comment(tctx
, "\nTesting bad pwd count with: %s\n", comment
);
4423 torture_assert(tctx
, password_history_length
< lockout_threshold
,
4424 "password history length needs to be smaller than account lockout threshold for this test");
4429 info
.info1
= *info1
;
4430 info
.info1
.password_history_length
= password_history_length
;
4431 info
.info1
.min_password_age
= 0;
4433 torture_assert(tctx
,
4434 test_SetDomainInfo(b
, tctx
, domain_handle
,
4435 DomainPasswordInformation
, &info
),
4436 "failed to set password history length and min passwd age");
4438 info
.info12
= *info12
;
4439 info
.info12
.lockout_threshold
= lockout_threshold
;
4441 /* set lockout duration of 5 seconds */
4442 info
.info12
.lockout_duration
= ~(lockout_seconds
* delta_time_factor
);
4443 info
.info12
.lockout_window
= ~(lockout_seconds
* delta_time_factor
);
4445 torture_assert(tctx
,
4446 test_SetDomainInfo(b
, tctx
, domain_handle
,
4447 DomainLockoutInformation
, &info
),
4448 "failed to set lockout threshold");
4450 /* reset bad pwd count */
4452 torture_assert(tctx
,
4453 test_reset_badpwdcount(p
, tctx
, user_handle
, acct_flags
, password
), "");
4456 /* enable or disable account */
4458 torture_assert(tctx
,
4459 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
4460 acct_flags
| ACB_DISABLED
),
4461 "failed to disable user");
4463 torture_assert(tctx
,
4464 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
4465 acct_flags
& ~ACB_DISABLED
),
4466 "failed to enable user");
4470 /* setup password history */
4472 passwords
= talloc_array(tctx
, char *, password_history_length
);
4474 for (i
=0; i
< password_history_length
; i
++) {
4476 torture_assert(tctx
, test_SetUserPass(p
, tctx
, user_handle
, password
),
4477 "failed to set password");
4478 passwords
[i
] = talloc_strdup(tctx
, *password
);
4480 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
4481 acct_name
, passwords
[i
],
4482 expected_success_status
, interactive
)) {
4483 torture_fail(tctx
, "failed to auth with latest password");
4486 torture_assert(tctx
,
4487 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4489 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
4493 /* test with wrong password */
4495 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
4496 acct_name
, "random_crap",
4497 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
4498 torture_fail(tctx
, "succeeded to authenticate with wrong password");
4501 torture_assert(tctx
,
4502 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4504 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
4507 /* test with latest good password */
4509 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
4510 passwords
[password_history_length
-1],
4511 expected_success_status
, interactive
)) {
4512 torture_fail(tctx
, "succeeded to authenticate with wrong password");
4515 torture_assert(tctx
,
4516 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4519 torture_assert_int_equal(tctx
, badpwdcount
, 1, "expected badpwdcount to be 1");
4521 /* only enabled accounts get the bad pwd count reset upon
4522 * successful logon */
4523 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
4529 /* test password history */
4531 for (i
=0; i
< password_history_length
; i
++) {
4533 torture_comment(tctx
, "Testing bad password count behavior with "
4534 "password #%d of #%d\n", i
, password_history_length
);
4536 /* - network samlogon will succeed auth and not
4537 * increase badpwdcount for 2 last entries
4538 * - interactive samlogon only for the last one */
4540 if (i
== password_history_length
- 1 ||
4541 (i
== password_history_length
- 2 && !interactive
)) {
4543 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
4544 acct_name
, passwords
[i
],
4545 expected_success_status
, interactive
)) {
4546 torture_fail(tctx
, talloc_asprintf(tctx
, "did not successfully to obtain %s for %s login with old password (#%d of #%d in history)",
4547 nt_errstr(expected_success_status
),
4548 interactive
? "interactive" : "network", i
, password_history_length
));
4551 torture_assert(tctx
,
4552 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4555 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
4556 torture_assert_int_equal(tctx
, badpwdcount
, tmp
, "unexpected badpwdcount");
4558 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
4559 torture_assert_int_equal(tctx
, badpwdcount
, 0, "expected badpwdcount to be 0");
4567 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
4568 acct_name
, passwords
[i
],
4569 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
4570 torture_fail(tctx
, talloc_asprintf(tctx
, "succeeded to authenticate with old password (#%d of #%d in history)", i
, password_history_length
));
4573 torture_assert(tctx
,
4574 test_QueryUserInfo_badpwdcount(b
, tctx
, user_handle
, &badpwdcount
), "");
4576 /* - network samlogon will fail auth but not increase
4577 * badpwdcount for 3rd last entry
4578 * - interactive samlogon for 3rd and 2nd last entry */
4580 if (i
== password_history_length
- 3 ||
4581 (i
== password_history_length
- 2 && interactive
)) {
4582 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
4583 torture_assert_int_equal(tctx
, badpwdcount
, tmp
, "unexpected badpwdcount");
4585 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
4586 torture_assert_int_equal(tctx
, badpwdcount
, tmp
+ 1, "unexpected badpwdcount");
4595 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe
*p
,
4596 struct torture_context
*tctx
,
4597 uint32_t acct_flags
,
4598 const char *acct_name
,
4599 struct policy_handle
*domain_handle
,
4600 struct policy_handle
*user_handle
,
4602 struct cli_credentials
*machine_credentials
)
4604 union samr_DomainInfo
*q_info
, s_info
;
4605 struct samr_DomInfo1 info1
, _info1
;
4606 struct samr_DomInfo12 info12
, _info12
;
4608 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4609 struct dcerpc_pipe
*np
;
4613 const char *comment
;
4616 NTSTATUS expected_success_status
;
4619 .comment
= "network logon (disabled account)",
4621 .interactive
= false,
4622 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
4625 .comment
= "network logon (enabled account)",
4627 .interactive
= false,
4628 .expected_success_status
= NT_STATUS_OK
4631 .comment
= "interactive logon (disabled account)",
4633 .interactive
= true,
4634 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
4637 .comment
= "interactive logon (enabled account)",
4639 .interactive
= true,
4640 .expected_success_status
= NT_STATUS_OK
4644 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
4646 /* backup old policies */
4648 torture_assert(tctx
,
4649 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
4650 DomainPasswordInformation
, &q_info
),
4651 "failed to query domain info level 1");
4653 info1
= q_info
->info1
;
4656 torture_assert(tctx
,
4657 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
4658 DomainLockoutInformation
, &q_info
),
4659 "failed to query domain info level 12");
4661 info12
= q_info
->info12
;
4666 for (i
=0; i
< ARRAY_SIZE(creds
); i
++) {
4668 /* skip trust tests for now */
4669 if (acct_flags
& ACB_WSTRUST
||
4670 acct_flags
& ACB_SVRTRUST
||
4671 acct_flags
& ACB_DOMTRUST
) {
4675 if (!test_Password_badpwdcount(p
, np
, tctx
, acct_flags
, acct_name
,
4676 domain_handle
, user_handle
, password
,
4677 machine_credentials
,
4680 creds
[i
].interactive
,
4681 creds
[i
].expected_success_status
,
4682 &_info1
, &_info12
)) {
4683 torture_result(tctx
, TORTURE_FAIL
, "TEST #%d (%s) failed\n", i
, creds
[i
].comment
);
4686 torture_comment(tctx
, "TEST #%d (%s) succeeded\n", i
, creds
[i
].comment
);
4690 /* restore policies */
4692 s_info
.info1
= info1
;
4694 torture_assert(tctx
,
4695 test_SetDomainInfo(b
, tctx
, domain_handle
,
4696 DomainPasswordInformation
, &s_info
),
4697 "failed to set password information");
4699 s_info
.info12
= info12
;
4701 torture_assert(tctx
,
4702 test_SetDomainInfo(b
, tctx
, domain_handle
,
4703 DomainLockoutInformation
, &s_info
),
4704 "failed to set lockout information");
4709 static bool test_QueryUserInfo_lockout(struct dcerpc_binding_handle
*b
,
4710 struct torture_context
*tctx
,
4711 struct policy_handle
*domain_handle
,
4712 const char *acct_name
,
4713 uint16_t raw_bad_password_count
,
4714 uint16_t effective_bad_password_count
,
4715 uint32_t effective_acb_lockout
)
4717 struct policy_handle user_handle
;
4718 union samr_UserInfo
*i
;
4719 struct samr_QueryUserInfo r
;
4721 NTSTATUS status
= test_OpenUser_byname(b
, tctx
, domain_handle
, acct_name
, &user_handle
);
4722 if (!NT_STATUS_IS_OK(status
)) {
4726 r
.in
.user_handle
= &user_handle
;
4729 torture_comment(tctx
, "Testing QueryUserInfo level %d", r
.in
.level
);
4730 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
4731 "failed to query userinfo");
4732 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4733 "failed to query userinfo");
4734 torture_comment(tctx
, " (acct_flags: 0x%08x) (raw_bad_pwd_count: %u)\n",
4735 i
->info3
.acct_flags
, i
->info3
.bad_password_count
);
4736 torture_assert_int_equal(tctx
, i
->info3
.bad_password_count
,
4737 raw_bad_password_count
,
4739 torture_assert_int_equal(tctx
, i
->info3
.acct_flags
& ACB_AUTOLOCK
,
4740 effective_acb_lockout
,
4741 "effective acb_lockout");
4744 r
.in
.user_handle
= &user_handle
;
4747 torture_comment(tctx
, "Testing QueryUserInfo level %d", r
.in
.level
);
4748 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
4749 "failed to query userinfo");
4750 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4751 "failed to query userinfo");
4752 torture_comment(tctx
, " (acct_flags: 0x%08x) (effective_bad_pwd_count: %u)\n",
4753 i
->info5
.acct_flags
, i
->info5
.bad_password_count
);
4754 torture_assert_int_equal(tctx
, i
->info5
.bad_password_count
,
4755 effective_bad_password_count
,
4756 "effective badpwdcount");
4757 torture_assert_int_equal(tctx
, i
->info5
.acct_flags
& ACB_AUTOLOCK
,
4758 effective_acb_lockout
,
4759 "effective acb_lockout");
4762 r
.in
.user_handle
= &user_handle
;
4765 torture_comment(tctx
, "Testing QueryUserInfo level %d", r
.in
.level
);
4766 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
4767 "failed to query userinfo");
4768 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4769 "failed to query userinfo");
4770 torture_comment(tctx
, " (acct_flags: 0x%08x)\n",
4771 i
->info16
.acct_flags
);
4772 torture_assert_int_equal(tctx
, i
->info16
.acct_flags
& ACB_AUTOLOCK
,
4773 effective_acb_lockout
,
4774 "effective acb_lockout");
4777 r
.in
.user_handle
= &user_handle
;
4780 torture_comment(tctx
, "Testing QueryUserInfo level %d", r
.in
.level
);
4781 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
4782 "failed to query userinfo");
4783 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
4784 "failed to query userinfo");
4785 torture_comment(tctx
, " (acct_flags: 0x%08x) (effective_bad_pwd_count: %u)\n",
4786 i
->info21
.acct_flags
, i
->info21
.bad_password_count
);
4787 torture_assert_int_equal(tctx
, i
->info21
.bad_password_count
,
4788 effective_bad_password_count
,
4789 "effective badpwdcount");
4790 torture_assert_int_equal(tctx
, i
->info21
.acct_flags
& ACB_AUTOLOCK
,
4791 effective_acb_lockout
,
4792 "effective acb_lockout");
4795 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
4802 static bool test_Password_lockout(struct dcerpc_pipe
*p
,
4803 struct dcerpc_pipe
*np
,
4804 struct torture_context
*tctx
,
4805 uint32_t acct_flags
,
4806 const char *acct_name
,
4807 struct policy_handle
*domain_handle
,
4808 struct policy_handle
*user_handle
,
4810 struct cli_credentials
*machine_credentials
,
4811 const char *comment
,
4814 uint32_t password_history_length
,
4815 NTSTATUS expected_success_status
,
4816 struct samr_DomInfo1
*info1
,
4817 struct samr_DomInfo12
*info12
)
4819 union samr_DomainInfo info
;
4820 uint64_t lockout_threshold
= 1;
4821 uint32_t lockout_seconds
= 5;
4822 uint64_t delta_time_factor
= 10 * 1000 * 1000;
4823 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
4825 if (torture_setting_bool(tctx
, "samba3", false)) {
4826 lockout_seconds
= 60;
4829 torture_comment(tctx
, "\nTesting account lockout: %s\n", comment
);
4833 info
.info1
= *info1
;
4835 torture_comment(tctx
, "setting password history length to %d.\n", password_history_length
);
4836 info
.info1
.password_history_length
= password_history_length
;
4838 torture_comment(tctx
, "setting min password again.\n");
4839 info
.info1
.min_password_age
= 0;
4841 torture_assert(tctx
,
4842 test_SetDomainInfo(b
, tctx
, domain_handle
,
4843 DomainPasswordInformation
, &info
),
4844 "failed to set password history length");
4846 info
.info12
= *info12
;
4847 info
.info12
.lockout_threshold
= lockout_threshold
;
4849 /* set lockout duration < lockout window: should fail */
4850 info
.info12
.lockout_duration
= ~(lockout_seconds
* delta_time_factor
);
4851 info
.info12
.lockout_window
= ~((lockout_seconds
+ 1) * delta_time_factor
);
4853 torture_assert(tctx
,
4854 test_SetDomainInfo_ntstatus(b
, tctx
, domain_handle
,
4855 DomainLockoutInformation
, &info
,
4856 NT_STATUS_INVALID_PARAMETER
),
4857 "setting lockout duration < lockout window gave unexpected result");
4859 info
.info12
.lockout_duration
= 0;
4860 info
.info12
.lockout_window
= 0;
4862 torture_assert(tctx
,
4863 test_SetDomainInfo(b
, tctx
, domain_handle
,
4864 DomainLockoutInformation
, &info
),
4865 "failed to set lockout window and duration to 0");
4868 /* set lockout duration of 5 seconds */
4869 info
.info12
.lockout_duration
= ~(lockout_seconds
* delta_time_factor
);
4870 info
.info12
.lockout_window
= ~(lockout_seconds
* delta_time_factor
);
4872 torture_assert(tctx
,
4873 test_SetDomainInfo(b
, tctx
, domain_handle
,
4874 DomainLockoutInformation
, &info
),
4875 "failed to set lockout window and duration to 5 seconds");
4877 /* reset bad pwd count */
4879 torture_assert(tctx
,
4880 test_reset_badpwdcount(p
, tctx
, user_handle
, acct_flags
, password
), "");
4883 /* enable or disable account */
4886 torture_assert(tctx
,
4887 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
4888 acct_flags
| ACB_DISABLED
),
4889 "failed to disable user");
4891 torture_assert(tctx
,
4892 test_SetUserInfo_acct_flags(b
, tctx
, user_handle
,
4893 acct_flags
& ~ACB_DISABLED
),
4894 "failed to enable user");
4898 /* test logon with right password */
4900 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
4901 acct_name
, *password
,
4902 expected_success_status
, interactive
)) {
4903 torture_fail(tctx
, "failed to auth with latest password");
4906 torture_assert(tctx
,
4907 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
4909 "expected account to not be locked");
4911 /* test with wrong password ==> lockout */
4913 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
4914 acct_name
, "random_crap",
4915 NT_STATUS_WRONG_PASSWORD
, interactive
)) {
4916 torture_fail(tctx
, "succeeded to authenticate with wrong password");
4920 * curiously, windows does _not_ return fresh values of
4921 * effective bad_password_count and ACB_AUTOLOCK.
4923 torture_assert(tctx
,
4924 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
4925 1, 1, ACB_AUTOLOCK
),
4926 "expected account to not be locked");
4928 /* test with good password */
4930 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
4932 NT_STATUS_ACCOUNT_LOCKED_OUT
, interactive
))
4934 torture_fail(tctx
, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4937 /* bad pwd count should not get updated */
4938 torture_assert(tctx
,
4939 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
4940 1, 1, ACB_AUTOLOCK
),
4941 "expected account to be locked");
4943 torture_assert(tctx
,
4944 test_ChangePasswordUser2_ntstatus(p
, tctx
, acct_name
, *password
,
4945 NT_STATUS_ACCOUNT_LOCKED_OUT
),
4946 "got wrong status from ChangePasswordUser2");
4948 /* bad pwd count should not get updated */
4949 torture_assert(tctx
,
4950 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
4951 1, 1, ACB_AUTOLOCK
),
4952 "expected account to be locked");
4954 torture_assert(tctx
,
4955 test_ChangePasswordUser2_ntstatus(p
, tctx
, acct_name
, "random_crap", NT_STATUS_ACCOUNT_LOCKED_OUT
),
4956 "got wrong status from ChangePasswordUser2");
4958 /* bad pwd count should not get updated */
4959 torture_assert(tctx
,
4960 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
4961 1, 1, ACB_AUTOLOCK
),
4962 "expected account to be locked");
4964 /* with bad password */
4966 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
,
4967 acct_name
, "random_crap2",
4968 NT_STATUS_ACCOUNT_LOCKED_OUT
, interactive
))
4970 torture_fail(tctx
, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4973 /* bad pwd count should not get updated */
4974 torture_assert(tctx
,
4975 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
4976 1, 1, ACB_AUTOLOCK
),
4977 "expected account to be locked");
4979 /* let lockout duration expire ==> unlock */
4981 torture_comment(tctx
, "let lockout duration expire...\n");
4982 sleep(lockout_seconds
+ 1);
4984 torture_assert(tctx
,
4985 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
4987 "expected account to not be locked");
4989 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
4991 expected_success_status
, interactive
))
4993 torture_fail(tctx
, "failed to authenticate after lockout expired");
4996 if (NT_STATUS_IS_OK(expected_success_status
)) {
4997 torture_assert(tctx
,
4998 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
5000 "expected account to not be locked");
5002 torture_assert(tctx
,
5003 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
5005 "expected account to not be locked");
5008 torture_assert(tctx
,
5009 test_ChangePasswordUser2_ntstatus(p
, tctx
, acct_name
, "random_crap", NT_STATUS_WRONG_PASSWORD
),
5010 "got wrong status from ChangePasswordUser2");
5012 torture_assert(tctx
,
5013 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
5014 1, 1, ACB_AUTOLOCK
),
5015 "expected account to be locked");
5017 torture_assert(tctx
,
5018 test_ChangePasswordUser2_ntstatus(p
, tctx
, acct_name
, *password
, NT_STATUS_ACCOUNT_LOCKED_OUT
),
5019 "got wrong status from ChangePasswordUser2");
5021 torture_assert(tctx
,
5022 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
5023 1, 1, ACB_AUTOLOCK
),
5024 "expected account to be locked");
5026 torture_assert(tctx
,
5027 test_ChangePasswordUser2_ntstatus(p
, tctx
, acct_name
, "random_crap", NT_STATUS_ACCOUNT_LOCKED_OUT
),
5028 "got wrong status from ChangePasswordUser2");
5030 torture_assert(tctx
,
5031 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
5032 1, 1, ACB_AUTOLOCK
),
5033 "expected account to be locked");
5035 /* let lockout duration expire ==> unlock */
5037 torture_comment(tctx
, "let lockout duration expire...\n");
5038 sleep(lockout_seconds
+ 1);
5040 torture_assert(tctx
,
5041 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
5043 "expected account to not be locked");
5045 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
5047 expected_success_status
, interactive
))
5049 torture_fail(tctx
, "failed to authenticate after lockout expired");
5052 if (NT_STATUS_IS_OK(expected_success_status
)) {
5053 torture_assert(tctx
,
5054 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
5056 "expected account to not be locked");
5058 torture_assert(tctx
,
5059 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
5061 "expected account to not be locked");
5064 /* Testing ChangePasswordUser behaviour with 3 attempts */
5065 info
.info12
.lockout_threshold
= 3;
5067 torture_assert(tctx
,
5068 test_SetDomainInfo(b
, tctx
, domain_handle
,
5069 DomainLockoutInformation
, &info
),
5070 "failed to set lockout threshold to 3");
5072 if (NT_STATUS_IS_OK(expected_success_status
)) {
5073 torture_assert(tctx
,
5074 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
5076 "expected account to not be locked");
5078 torture_assert(tctx
,
5079 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
5081 "expected account to not be locked");
5084 torture_assert(tctx
,
5085 test_ChangePasswordUser2_ntstatus(p
, tctx
, acct_name
, "random_crap", NT_STATUS_WRONG_PASSWORD
),
5086 "got wrong status from ChangePasswordUser2");
5088 /* bad pwd count will get updated */
5089 torture_assert(tctx
,
5090 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
5092 "expected account to not be locked");
5094 torture_assert(tctx
,
5095 test_ChangePasswordUser2_ntstatus(p
, tctx
, acct_name
, "random_crap", NT_STATUS_WRONG_PASSWORD
),
5096 "got wrong status from ChangePasswordUser2");
5098 /* bad pwd count will get updated */
5099 torture_assert(tctx
,
5100 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
5102 "expected account to not be locked");
5104 torture_assert(tctx
,
5105 test_ChangePasswordUser2_ntstatus(p
, tctx
, acct_name
, "random_crap", NT_STATUS_WRONG_PASSWORD
),
5106 "got wrong status from ChangePasswordUser2");
5108 /* bad pwd count should get updated */
5109 torture_assert(tctx
,
5110 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
5111 3, 3, ACB_AUTOLOCK
),
5112 "expected account to be locked");
5114 torture_assert(tctx
,
5115 test_ChangePasswordUser2_ntstatus(p
, tctx
, acct_name
, *password
, NT_STATUS_ACCOUNT_LOCKED_OUT
),
5116 "got wrong status from ChangePasswordUser2");
5118 /* bad pwd count should not get updated */
5119 torture_assert(tctx
,
5120 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
5121 3, 3, ACB_AUTOLOCK
),
5122 "expected account to be locked");
5124 /* let lockout duration expire ==> unlock */
5126 torture_comment(tctx
, "let lockout duration expire...\n");
5127 sleep(lockout_seconds
+ 1);
5129 torture_assert(tctx
,
5130 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
5132 "expected account to not be locked");
5134 torture_assert(tctx
,
5135 test_ChangePasswordUser2(p
, tctx
, acct_name
, password
, NULL
, false),
5136 "got wrong status from ChangePasswordUser2");
5138 torture_assert(tctx
,
5139 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
5141 "expected account to not be locked");
5143 /* Used to reset the badPwdCount for the other tests */
5144 if (!test_SamLogon_with_creds(tctx
, np
, machine_credentials
, acct_name
,
5146 expected_success_status
, interactive
))
5148 torture_fail(tctx
, "failed to authenticate after lockout expired");
5151 if (NT_STATUS_IS_OK(expected_success_status
)) {
5152 torture_assert(tctx
,
5153 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
5155 "expected account to not be locked");
5157 torture_assert(tctx
,
5158 test_QueryUserInfo_lockout(b
, tctx
, domain_handle
, acct_name
,
5160 "expected account to not be locked");
5166 static bool test_Password_lockout_wrap(struct dcerpc_pipe
*p
,
5167 struct torture_context
*tctx
,
5168 uint32_t acct_flags
,
5169 const char *acct_name
,
5170 struct policy_handle
*domain_handle
,
5171 struct policy_handle
*user_handle
,
5173 struct cli_credentials
*machine_credentials
)
5175 union samr_DomainInfo
*q_info
, s_info
;
5176 struct samr_DomInfo1 info1
, _info1
;
5177 struct samr_DomInfo12 info12
, _info12
;
5179 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5180 struct dcerpc_pipe
*np
;
5184 const char *comment
;
5187 uint32_t password_history_length
;
5188 NTSTATUS expected_success_status
;
5191 .comment
= "network logon (disabled account)",
5193 .interactive
= false,
5194 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
5197 .comment
= "network logon (enabled account)",
5199 .interactive
= false,
5200 .expected_success_status
= NT_STATUS_OK
5203 .comment
= "network logon (enabled account, history len = 1)",
5205 .interactive
= false,
5206 .expected_success_status
= NT_STATUS_OK
,
5207 .password_history_length
= 1
5210 .comment
= "interactive logon (disabled account)",
5212 .interactive
= true,
5213 .expected_success_status
= NT_STATUS_ACCOUNT_DISABLED
5216 .comment
= "interactive logon (enabled account)",
5218 .interactive
= true,
5219 .expected_success_status
= NT_STATUS_OK
5222 .comment
= "interactive logon (enabled account, history len = 1)",
5224 .interactive
= true,
5225 .expected_success_status
= NT_STATUS_OK
,
5226 .password_history_length
= 1
5230 torture_assert(tctx
, setup_schannel_netlogon_pipe(tctx
, machine_credentials
, &np
), "");
5232 /* backup old policies */
5234 torture_assert(tctx
,
5235 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
5236 DomainPasswordInformation
, &q_info
),
5237 "failed to query domain info level 1");
5239 info1
= q_info
->info1
;
5242 torture_assert(tctx
,
5243 test_QueryDomainInfo2_level(b
, tctx
, domain_handle
,
5244 DomainLockoutInformation
, &q_info
),
5245 "failed to query domain info level 12");
5247 info12
= q_info
->info12
;
5252 for (i
=0; i
< ARRAY_SIZE(creds
); i
++) {
5254 /* skip trust tests for now */
5255 if (acct_flags
& ACB_WSTRUST
||
5256 acct_flags
& ACB_SVRTRUST
||
5257 acct_flags
& ACB_DOMTRUST
) {
5261 test_passed
= test_Password_lockout(p
, np
, tctx
, acct_flags
, acct_name
,
5262 domain_handle
, user_handle
, password
,
5263 machine_credentials
,
5266 creds
[i
].interactive
,
5267 creds
[i
].password_history_length
,
5268 creds
[i
].expected_success_status
,
5272 torture_result(tctx
, TORTURE_FAIL
, "TEST #%d (%s) failed\n", i
, creds
[i
].comment
);
5275 torture_comment(tctx
, "TEST #%d (%s) succeeded\n", i
, creds
[i
].comment
);
5279 /* restore policies */
5281 s_info
.info1
= info1
;
5283 torture_assert(tctx
,
5284 test_SetDomainInfo(b
, tctx
, domain_handle
,
5285 DomainPasswordInformation
, &s_info
),
5286 "failed to set password information");
5288 s_info
.info12
= info12
;
5290 torture_assert(tctx
,
5291 test_SetDomainInfo(b
, tctx
, domain_handle
,
5292 DomainLockoutInformation
, &s_info
),
5293 "failed to set lockout information");
5298 static bool test_DeleteUser_with_privs(struct dcerpc_pipe
*p
,
5299 struct dcerpc_pipe
*lp
,
5300 struct torture_context
*tctx
,
5301 struct policy_handle
*domain_handle
,
5302 struct policy_handle
*lsa_handle
,
5303 struct policy_handle
*user_handle
,
5304 const struct dom_sid
*domain_sid
,
5306 struct cli_credentials
*machine_credentials
)
5309 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5310 struct dcerpc_binding_handle
*lb
= lp
->binding_handle
;
5312 struct policy_handle lsa_acct_handle
;
5313 struct dom_sid
*user_sid
;
5315 user_sid
= dom_sid_add_rid(tctx
, domain_sid
, rid
);
5318 struct lsa_EnumAccountRights r
;
5319 struct lsa_RightSet rights
;
5321 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
5323 r
.in
.handle
= lsa_handle
;
5324 r
.in
.sid
= user_sid
;
5325 r
.out
.rights
= &rights
;
5327 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
),
5328 "lsa_EnumAccountRights failed");
5329 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
5330 "Expected enum rights for account to fail");
5334 struct lsa_RightSet rights
;
5335 struct lsa_StringLarge names
[2];
5336 struct lsa_AddAccountRights r
;
5338 torture_comment(tctx
, "Testing LSA AddAccountRights\n");
5340 init_lsa_StringLarge(&names
[0], "SeMachineAccountPrivilege");
5341 init_lsa_StringLarge(&names
[1], NULL
);
5344 rights
.names
= names
;
5346 r
.in
.handle
= lsa_handle
;
5347 r
.in
.sid
= user_sid
;
5348 r
.in
.rights
= &rights
;
5350 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_AddAccountRights_r(lb
, tctx
, &r
),
5351 "lsa_AddAccountRights failed");
5352 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
5353 "Failed to add privileges");
5357 struct lsa_RightSet rights
;
5358 struct lsa_StringLarge names
[2];
5359 struct lsa_AddAccountRights r
;
5361 torture_comment(tctx
, "Testing LSA AddAccountRights 1\n");
5363 init_lsa_StringLarge(&names
[0], "SeInteractiveLogonRight");
5364 init_lsa_StringLarge(&names
[1], NULL
);
5367 rights
.names
= names
;
5369 r
.in
.handle
= lsa_handle
;
5370 r
.in
.sid
= user_sid
;
5371 r
.in
.rights
= &rights
;
5373 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_AddAccountRights_r(lb
, tctx
, &r
),
5374 "lsa_AddAccountRights 1 failed");
5376 if (torture_setting_bool(tctx
, "nt4_dc", false)) {
5378 * The NT4 DC doesn't implement Rights.
5380 torture_assert_ntstatus_equal(tctx
, r
.out
.result
,
5381 NT_STATUS_NO_SUCH_PRIVILEGE
,
5382 "Add rights failed with incorrect error");
5384 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
5385 "Failed to add rights");
5392 struct lsa_EnumAccounts r
;
5393 uint32_t resume_handle
= 0;
5394 struct lsa_SidArray lsa_sid_array
;
5396 bool found_sid
= false;
5398 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
5400 r
.in
.handle
= lsa_handle
;
5401 r
.in
.num_entries
= 0x1000;
5402 r
.in
.resume_handle
= &resume_handle
;
5403 r
.out
.sids
= &lsa_sid_array
;
5404 r
.out
.resume_handle
= &resume_handle
;
5406 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccounts_r(lb
, tctx
, &r
),
5407 "lsa_EnumAccounts failed");
5408 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
5409 "Failed to enum accounts");
5411 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
5412 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
5417 torture_assert(tctx
, found_sid
,
5418 "failed to list privileged account");
5422 struct lsa_EnumAccountRights r
;
5423 struct lsa_RightSet user_rights
;
5424 uint32_t expected_count
= 2;
5426 if (torture_setting_bool(tctx
, "nt4_dc", false)) {
5428 * NT4 DC doesn't store rights.
5433 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
5435 r
.in
.handle
= lsa_handle
;
5436 r
.in
.sid
= user_sid
;
5437 r
.out
.rights
= &user_rights
;
5439 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
),
5440 "lsa_EnumAccountRights failed");
5441 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
5442 "Failed to enum rights for account");
5444 if (user_rights
.count
< expected_count
) {
5445 torture_result(tctx
, TORTURE_FAIL
, "failed to find newly added rights");
5451 struct lsa_OpenAccount r
;
5453 torture_comment(tctx
, "Testing LSA OpenAccount\n");
5455 r
.in
.handle
= lsa_handle
;
5456 r
.in
.sid
= user_sid
;
5457 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5458 r
.out
.acct_handle
= &lsa_acct_handle
;
5460 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenAccount_r(lb
, tctx
, &r
),
5461 "lsa_OpenAccount failed");
5462 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
5463 "Failed to open lsa account");
5467 struct lsa_GetSystemAccessAccount r
;
5468 uint32_t access_mask
;
5470 torture_comment(tctx
, "Testing LSA GetSystemAccessAccount\n");
5472 r
.in
.handle
= &lsa_acct_handle
;
5473 r
.out
.access_mask
= &access_mask
;
5475 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_GetSystemAccessAccount_r(lb
, tctx
, &r
),
5476 "lsa_GetSystemAccessAccount failed");
5477 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
5478 "Failed to get lsa system access account");
5484 torture_comment(tctx
, "Testing LSA Close\n");
5486 r
.in
.handle
= &lsa_acct_handle
;
5487 r
.out
.handle
= &lsa_acct_handle
;
5489 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_Close_r(lb
, tctx
, &r
),
5490 "lsa_Close failed");
5491 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
5492 "Failed to close lsa");
5496 struct samr_DeleteUser r
;
5498 torture_comment(tctx
, "Testing SAMR DeleteUser\n");
5500 r
.in
.user_handle
= user_handle
;
5501 r
.out
.user_handle
= user_handle
;
5503 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, tctx
, &r
),
5504 "DeleteUser failed");
5505 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
5506 "DeleteUser failed");
5510 struct lsa_EnumAccounts r
;
5511 uint32_t resume_handle
= 0;
5512 struct lsa_SidArray lsa_sid_array
;
5514 bool found_sid
= false;
5516 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
5518 r
.in
.handle
= lsa_handle
;
5519 r
.in
.num_entries
= 0x1000;
5520 r
.in
.resume_handle
= &resume_handle
;
5521 r
.out
.sids
= &lsa_sid_array
;
5522 r
.out
.resume_handle
= &resume_handle
;
5524 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccounts_r(lb
, tctx
, &r
),
5525 "lsa_EnumAccounts failed");
5526 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
5527 "Failed to enum accounts");
5529 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
5530 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
5535 torture_assert(tctx
, found_sid
,
5536 "failed to list privileged account");
5540 struct lsa_EnumAccountRights r
;
5541 struct lsa_RightSet user_rights
;
5543 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
5545 r
.in
.handle
= lsa_handle
;
5546 r
.in
.sid
= user_sid
;
5547 r
.out
.rights
= &user_rights
;
5549 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
),
5550 "lsa_EnumAccountRights failed");
5551 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
5552 "Failed to enum rights for account");
5554 if (user_rights
.count
< 1) {
5555 torture_result(tctx
, TORTURE_FAIL
, "failed to find newly added rights");
5561 struct lsa_OpenAccount r
;
5563 torture_comment(tctx
, "Testing LSA OpenAccount\n");
5565 r
.in
.handle
= lsa_handle
;
5566 r
.in
.sid
= user_sid
;
5567 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5568 r
.out
.acct_handle
= &lsa_acct_handle
;
5570 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenAccount_r(lb
, tctx
, &r
),
5571 "lsa_OpenAccount failed");
5572 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
5573 "Failed to open lsa account");
5577 struct lsa_GetSystemAccessAccount r
;
5578 uint32_t access_mask
;
5580 torture_comment(tctx
, "Testing LSA GetSystemAccessAccount\n");
5582 r
.in
.handle
= &lsa_acct_handle
;
5583 r
.out
.access_mask
= &access_mask
;
5585 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_GetSystemAccessAccount_r(lb
, tctx
, &r
),
5586 "lsa_GetSystemAccessAccount failed");
5587 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
5588 "Failed to get lsa system access account");
5592 struct lsa_DeleteObject r
;
5594 torture_comment(tctx
, "Testing LSA DeleteObject\n");
5596 r
.in
.handle
= &lsa_acct_handle
;
5597 r
.out
.handle
= &lsa_acct_handle
;
5599 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_DeleteObject_r(lb
, tctx
, &r
),
5600 "lsa_DeleteObject failed");
5601 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
5602 "Failed to delete object");
5606 struct lsa_EnumAccounts r
;
5607 uint32_t resume_handle
= 0;
5608 struct lsa_SidArray lsa_sid_array
;
5610 bool found_sid
= false;
5612 torture_comment(tctx
, "Testing LSA EnumAccounts\n");
5614 r
.in
.handle
= lsa_handle
;
5615 r
.in
.num_entries
= 0x1000;
5616 r
.in
.resume_handle
= &resume_handle
;
5617 r
.out
.sids
= &lsa_sid_array
;
5618 r
.out
.resume_handle
= &resume_handle
;
5620 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccounts_r(lb
, tctx
, &r
),
5621 "lsa_EnumAccounts failed");
5622 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
5623 "Failed to enum accounts");
5625 for (i
=0; i
< lsa_sid_array
.num_sids
; i
++) {
5626 if (dom_sid_equal(user_sid
, lsa_sid_array
.sids
[i
].sid
)) {
5631 torture_assert(tctx
, !found_sid
,
5632 "should not have listed privileged account");
5636 struct lsa_EnumAccountRights r
;
5637 struct lsa_RightSet user_rights
;
5639 torture_comment(tctx
, "Testing LSA EnumAccountRights\n");
5641 r
.in
.handle
= lsa_handle
;
5642 r
.in
.sid
= user_sid
;
5643 r
.out
.rights
= &user_rights
;
5645 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_EnumAccountRights_r(lb
, tctx
, &r
),
5646 "lsa_EnumAccountRights failed");
5647 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
5648 "Failed to enum rights for account");
5654 static bool test_user_ops(struct dcerpc_pipe
*p
,
5655 struct torture_context
*tctx
,
5656 struct policy_handle
*user_handle
,
5657 struct policy_handle
*domain_handle
,
5658 const struct dom_sid
*domain_sid
,
5659 uint32_t base_acct_flags
,
5660 const char *base_acct_name
, enum torture_samr_choice which_ops
,
5661 struct cli_credentials
*machine_credentials
)
5663 char *password
= NULL
;
5664 struct samr_QueryUserInfo q
;
5665 union samr_UserInfo
*info
;
5667 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
5672 const uint32_t password_fields
[] = {
5673 SAMR_FIELD_NT_PASSWORD_PRESENT
,
5674 SAMR_FIELD_LM_PASSWORD_PRESENT
,
5675 SAMR_FIELD_NT_PASSWORD_PRESENT
| SAMR_FIELD_LM_PASSWORD_PRESENT
,
5679 status
= test_LookupName(b
, tctx
, domain_handle
, base_acct_name
, &rid
);
5680 if (!NT_STATUS_IS_OK(status
)) {
5684 switch (which_ops
) {
5685 case TORTURE_SAMR_USER_ATTRIBUTES
:
5686 if (!test_QuerySecurity(b
, tctx
, user_handle
)) {
5690 if (!test_QueryUserInfo(b
, tctx
, user_handle
)) {
5694 if (!test_QueryUserInfo2(b
, tctx
, user_handle
)) {
5698 if (!test_SetUserInfo(b
, tctx
, user_handle
, base_acct_flags
,
5703 if (!test_GetUserPwInfo(b
, tctx
, user_handle
)) {
5707 if (!test_TestPrivateFunctionsUser(b
, tctx
, user_handle
)) {
5711 if (!test_SetUserPass(p
, tctx
, user_handle
, &password
)) {
5715 case TORTURE_SAMR_PASSWORDS
:
5716 if (base_acct_flags
& (ACB_WSTRUST
|ACB_DOMTRUST
|ACB_SVRTRUST
)) {
5717 char simple_pass
[9];
5718 char *v
= generate_random_str(tctx
, 1);
5720 ZERO_STRUCT(simple_pass
);
5721 memset(simple_pass
, *v
, sizeof(simple_pass
) - 1);
5723 torture_comment(tctx
, "Testing machine account password policy rules\n");
5725 /* Workstation trust accounts don't seem to need to honour password quality policy */
5726 if (!test_SetUserPassEx(p
, tctx
, user_handle
, true, &password
)) {
5730 if (!test_ChangePasswordUser2(p
, tctx
, base_acct_name
, &password
, simple_pass
, false)) {
5734 /* reset again, to allow another 'user' password change */
5735 if (!test_SetUserPassEx(p
, tctx
, user_handle
, true, &password
)) {
5739 /* Try a 'short' password */
5740 if (!test_ChangePasswordUser2(p
, tctx
, base_acct_name
, &password
, samr_rand_pass(tctx
, 4), false)) {
5744 /* Try a completely random password */
5745 if (!test_ChangePasswordRandomBytes(p
, tctx
, base_acct_name
, user_handle
, &password
)) {
5750 for (i
= 0; password_fields
[i
]; i
++) {
5751 if (!test_SetUserPass_23(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
5755 /* check it was set right */
5756 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
5761 for (i
= 0; password_fields
[i
]; i
++) {
5762 if (!test_SetUserPass_25(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
5766 /* check it was set right */
5767 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
5772 if (!test_SetUserPass_31(p
, tctx
, user_handle
, false, &password
)) {
5776 for (i
= 0; password_fields
[i
]; i
++) {
5777 if (!test_SetUserPass_32(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
5781 /* check it was set right */
5782 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
5787 if (!test_ChangePassword(p
, tctx
, base_acct_name
, domain_handle
, &password
)) {
5791 if (!test_SetUserPassEx(p
, tctx
, user_handle
, false, &password
)) {
5795 if (!test_ChangePassword(p
, tctx
, base_acct_name
, domain_handle
, &password
)) {
5799 if (!test_SetUserPass_18(p
, tctx
, user_handle
, &password
)) {
5803 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
5807 for (i
= 0; password_fields
[i
]; i
++) {
5809 if (password_fields
[i
] == SAMR_FIELD_LM_PASSWORD_PRESENT
) {
5810 /* we need to skip as that would break
5811 * the ChangePasswordUser3 verify */
5815 if (!test_SetUserPass_21(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
5819 /* check it was set right */
5820 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
5825 q
.in
.user_handle
= user_handle
;
5829 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
),
5830 "QueryUserInfo failed");
5831 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
5832 torture_result(tctx
, TORTURE_FAIL
, "QueryUserInfo level %u failed - %s\n",
5833 q
.in
.level
, nt_errstr(q
.out
.result
));
5836 uint32_t expected_flags
= (base_acct_flags
| ACB_PWNOTREQ
| ACB_DISABLED
);
5837 if ((info
->info5
.acct_flags
) != expected_flags
) {
5839 if (!torture_setting_bool(tctx
, "samba3", false)) {
5840 torture_result(tctx
, TORTURE_FAIL
, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5841 info
->info5
.acct_flags
,
5846 if (info
->info5
.rid
!= rid
) {
5847 torture_result(tctx
, TORTURE_FAIL
, "QueryUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
5848 info
->info5
.rid
, rid
);
5855 case TORTURE_SAMR_PASSWORDS_PWDLASTSET
:
5857 /* test last password change timestamp behaviour */
5858 torture_assert(tctx
, test_SetPassword_pwdlastset(p
, tctx
, base_acct_flags
,
5860 user_handle
, &password
,
5861 machine_credentials
),
5862 "pwdLastSet test failed\n");
5865 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
:
5867 /* test bad pwd count change behaviour */
5868 torture_assert(tctx
, test_Password_badpwdcount_wrap(p
, tctx
, base_acct_flags
,
5871 user_handle
, &password
,
5872 machine_credentials
),
5873 "badPwdCount test failed\n");
5876 case TORTURE_SAMR_PASSWORDS_LOCKOUT
:
5878 torture_assert(tctx
, test_Password_lockout_wrap(p
, tctx
, base_acct_flags
,
5881 user_handle
, &password
,
5882 machine_credentials
),
5883 "Lockout test failed");
5887 case TORTURE_SAMR_USER_PRIVILEGES
: {
5889 struct dcerpc_pipe
*lp
;
5890 struct policy_handle
*lsa_handle
;
5891 struct dcerpc_binding_handle
*lb
;
5893 status
= torture_rpc_connection(tctx
, &lp
, &ndr_table_lsarpc
);
5894 torture_assert_ntstatus_ok(tctx
, status
, "Failed to open LSA pipe");
5895 lb
= lp
->binding_handle
;
5897 if (!test_lsa_OpenPolicy2(lb
, tctx
, &lsa_handle
)) {
5901 if (!test_DeleteUser_with_privs(p
, lp
, tctx
,
5902 domain_handle
, lsa_handle
, user_handle
,
5904 machine_credentials
)) {
5908 if (!test_lsa_Close(lb
, tctx
, lsa_handle
)) {
5913 torture_result(tctx
, TORTURE_FAIL
, "privileged user delete test failed\n");
5918 case TORTURE_SAMR_OTHER
:
5919 case TORTURE_SAMR_MANY_ACCOUNTS
:
5920 case TORTURE_SAMR_MANY_GROUPS
:
5921 case TORTURE_SAMR_MANY_ALIASES
:
5922 /* We just need the account to exist */
5928 static bool test_alias_ops(struct dcerpc_binding_handle
*b
,
5929 struct torture_context
*tctx
,
5930 struct policy_handle
*alias_handle
,
5931 const struct dom_sid
*domain_sid
)
5935 if (!torture_setting_bool(tctx
, "samba3", false)) {
5936 if (!test_QuerySecurity(b
, tctx
, alias_handle
)) {
5941 if (!test_QueryAliasInfo(b
, tctx
, alias_handle
)) {
5945 if (!test_SetAliasInfo(b
, tctx
, alias_handle
)) {
5949 if (!test_AddMemberToAlias(b
, tctx
, alias_handle
, domain_sid
)) {
5953 if (torture_setting_bool(tctx
, "samba3", false) ||
5954 torture_setting_bool(tctx
, "samba4", false)) {
5955 torture_comment(tctx
, "skipping MultipleMembers Alias tests against Samba\n");
5959 if (!test_AddMultipleMembersToAlias(b
, tctx
, alias_handle
)) {
5967 static bool test_DeleteUser(struct dcerpc_binding_handle
*b
,
5968 struct torture_context
*tctx
,
5969 struct policy_handle
*user_handle
)
5971 struct samr_DeleteUser d
;
5972 torture_comment(tctx
, "Testing DeleteUser\n");
5974 d
.in
.user_handle
= user_handle
;
5975 d
.out
.user_handle
= user_handle
;
5977 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, tctx
, &d
),
5978 "DeleteUser failed");
5979 torture_assert_ntstatus_ok(tctx
, d
.out
.result
, "DeleteUser");
5984 bool test_DeleteUser_byname(struct dcerpc_binding_handle
*b
,
5985 struct torture_context
*tctx
,
5986 struct policy_handle
*handle
, const char *name
)
5989 struct samr_DeleteUser d
;
5990 struct policy_handle user_handle
;
5993 status
= test_LookupName(b
, tctx
, handle
, name
, &rid
);
5994 if (!NT_STATUS_IS_OK(status
)) {
5998 status
= test_OpenUser_byname(b
, tctx
, handle
, name
, &user_handle
);
5999 if (!NT_STATUS_IS_OK(status
)) {
6003 d
.in
.user_handle
= &user_handle
;
6004 d
.out
.user_handle
= &user_handle
;
6005 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, tctx
, &d
),
6006 "DeleteUser failed");
6007 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
6008 status
= d
.out
.result
;
6015 torture_result(tctx
, TORTURE_FAIL
, "DeleteUser_byname(%s) failed - %s\n", name
, nt_errstr(status
));
6020 static bool test_DeleteGroup_byname(struct dcerpc_binding_handle
*b
,
6021 struct torture_context
*tctx
,
6022 struct policy_handle
*handle
, const char *name
)
6025 struct samr_OpenGroup r
;
6026 struct samr_DeleteDomainGroup d
;
6027 struct policy_handle group_handle
;
6030 status
= test_LookupName(b
, tctx
, handle
, name
, &rid
);
6031 if (!NT_STATUS_IS_OK(status
)) {
6035 r
.in
.domain_handle
= handle
;
6036 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6038 r
.out
.group_handle
= &group_handle
;
6039 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenGroup_r(b
, tctx
, &r
),
6040 "OpenGroup failed");
6041 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6042 status
= r
.out
.result
;
6046 d
.in
.group_handle
= &group_handle
;
6047 d
.out
.group_handle
= &group_handle
;
6048 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteDomainGroup_r(b
, tctx
, &d
),
6049 "DeleteDomainGroup failed");
6050 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
6051 status
= d
.out
.result
;
6058 torture_result(tctx
, TORTURE_FAIL
, "DeleteGroup_byname(%s) failed - %s\n", name
, nt_errstr(status
));
6063 static bool test_DeleteAlias_byname(struct dcerpc_binding_handle
*b
,
6064 struct torture_context
*tctx
,
6065 struct policy_handle
*domain_handle
,
6069 struct samr_OpenAlias r
;
6070 struct samr_DeleteDomAlias d
;
6071 struct policy_handle alias_handle
;
6074 torture_comment(tctx
, "Testing DeleteAlias_byname\n");
6076 status
= test_LookupName(b
, tctx
, domain_handle
, name
, &rid
);
6077 if (!NT_STATUS_IS_OK(status
)) {
6081 r
.in
.domain_handle
= domain_handle
;
6082 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6084 r
.out
.alias_handle
= &alias_handle
;
6085 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenAlias_r(b
, tctx
, &r
),
6086 "OpenAlias failed");
6087 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6088 status
= r
.out
.result
;
6092 d
.in
.alias_handle
= &alias_handle
;
6093 d
.out
.alias_handle
= &alias_handle
;
6094 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteDomAlias_r(b
, tctx
, &d
),
6095 "DeleteDomAlias failed");
6096 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
6097 status
= d
.out
.result
;
6104 torture_result(tctx
, TORTURE_FAIL
, "DeleteAlias_byname(%s) failed - %s\n", name
, nt_errstr(status
));
6108 static bool test_DeleteAlias(struct dcerpc_binding_handle
*b
,
6109 struct torture_context
*tctx
,
6110 struct policy_handle
*alias_handle
)
6112 struct samr_DeleteDomAlias d
;
6115 torture_comment(tctx
, "Testing DeleteAlias\n");
6117 d
.in
.alias_handle
= alias_handle
;
6118 d
.out
.alias_handle
= alias_handle
;
6120 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteDomAlias_r(b
, tctx
, &d
),
6121 "DeleteDomAlias failed");
6122 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
6123 torture_result(tctx
, TORTURE_FAIL
, "DeleteAlias failed - %s\n", nt_errstr(d
.out
.result
));
6130 static bool test_CreateAlias(struct dcerpc_binding_handle
*b
,
6131 struct torture_context
*tctx
,
6132 struct policy_handle
*domain_handle
,
6133 const char *alias_name
,
6134 struct policy_handle
*alias_handle
,
6135 const struct dom_sid
*domain_sid
,
6138 struct samr_CreateDomAlias r
;
6139 struct lsa_String name
;
6143 init_lsa_String(&name
, alias_name
);
6144 r
.in
.domain_handle
= domain_handle
;
6145 r
.in
.alias_name
= &name
;
6146 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6147 r
.out
.alias_handle
= alias_handle
;
6150 torture_comment(tctx
, "Testing CreateAlias (%s)\n", r
.in
.alias_name
->string
);
6152 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomAlias_r(b
, tctx
, &r
),
6153 "CreateDomAlias failed");
6155 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
6156 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
)) {
6157 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.alias_name
->string
);
6160 torture_result(tctx
, TORTURE_FAIL
, "Server should have refused create of '%s', got %s instead\n", r
.in
.alias_name
->string
,
6161 nt_errstr(r
.out
.result
));
6166 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ALIAS_EXISTS
)) {
6167 if (!test_DeleteAlias_byname(b
, tctx
, domain_handle
, r
.in
.alias_name
->string
)) {
6170 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomAlias_r(b
, tctx
, &r
),
6171 "CreateDomAlias failed");
6174 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6175 torture_result(tctx
, TORTURE_FAIL
, "CreateAlias failed - %s\n", nt_errstr(r
.out
.result
));
6183 if (!test_alias_ops(b
, tctx
, alias_handle
, domain_sid
)) {
6190 static bool test_ChangePassword(struct dcerpc_pipe
*p
,
6191 struct torture_context
*tctx
,
6192 const char *acct_name
,
6193 struct policy_handle
*domain_handle
, char **password
)
6196 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
6202 if (!test_ChangePasswordUser(b
, tctx
, acct_name
, domain_handle
, password
)) {
6206 if (!test_ChangePasswordUser2(p
, tctx
, acct_name
, password
, 0, true)) {
6210 if (!test_OemChangePasswordUser2(p
, tctx
, acct_name
, domain_handle
, password
)) {
6214 /* test what happens when setting the old password again */
6215 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, *password
, 0, true)) {
6220 char simple_pass
[9];
6221 char *v
= generate_random_str(tctx
, 1);
6223 ZERO_STRUCT(simple_pass
);
6224 memset(simple_pass
, *v
, sizeof(simple_pass
) - 1);
6226 /* test what happens when picking a simple password */
6227 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, simple_pass
, 0, true)) {
6232 /* set samr_SetDomainInfo level 1 with min_length 5 */
6234 struct samr_QueryDomainInfo r
;
6235 union samr_DomainInfo
*info
= NULL
;
6236 struct samr_SetDomainInfo s
;
6237 uint16_t len_old
, len
;
6238 uint32_t pwd_prop_old
;
6239 int64_t min_pwd_age_old
;
6243 r
.in
.domain_handle
= domain_handle
;
6247 torture_comment(tctx
, "Testing samr_QueryDomainInfo level 1\n");
6248 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &r
),
6249 "QueryDomainInfo failed");
6250 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6254 s
.in
.domain_handle
= domain_handle
;
6258 /* remember the old min length, so we can reset it */
6259 len_old
= s
.in
.info
->info1
.min_password_length
;
6260 s
.in
.info
->info1
.min_password_length
= len
;
6261 pwd_prop_old
= s
.in
.info
->info1
.password_properties
;
6262 /* turn off password complexity checks for this test */
6263 s
.in
.info
->info1
.password_properties
&= ~DOMAIN_PASSWORD_COMPLEX
;
6265 min_pwd_age_old
= s
.in
.info
->info1
.min_password_age
;
6266 s
.in
.info
->info1
.min_password_age
= 0;
6268 torture_comment(tctx
, "Testing samr_SetDomainInfo level 1\n");
6269 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
),
6270 "SetDomainInfo failed");
6271 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
6275 torture_comment(tctx
, "calling test_ChangePasswordUser3 with too short password\n");
6277 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, len
- 1, password
, NULL
, 0, true)) {
6281 s
.in
.info
->info1
.min_password_length
= len_old
;
6282 s
.in
.info
->info1
.password_properties
= pwd_prop_old
;
6283 s
.in
.info
->info1
.min_password_age
= min_pwd_age_old
;
6285 torture_comment(tctx
, "Testing samr_SetDomainInfo level 1\n");
6286 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
),
6287 "SetDomainInfo failed");
6288 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
6295 struct samr_OpenUser r
;
6296 struct samr_QueryUserInfo q
;
6297 union samr_UserInfo
*info
;
6298 struct samr_LookupNames n
;
6299 struct policy_handle user_handle
;
6300 struct samr_Ids rids
, types
;
6302 n
.in
.domain_handle
= domain_handle
;
6304 n
.in
.names
= talloc_array(tctx
, struct lsa_String
, 1);
6305 n
.in
.names
[0].string
= acct_name
;
6307 n
.out
.types
= &types
;
6309 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupNames_r(b
, tctx
, &n
),
6310 "LookupNames failed");
6311 if (!NT_STATUS_IS_OK(n
.out
.result
)) {
6312 torture_result(tctx
, TORTURE_FAIL
, "LookupNames failed - %s\n", nt_errstr(n
.out
.result
));
6316 r
.in
.domain_handle
= domain_handle
;
6317 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6318 r
.in
.rid
= n
.out
.rids
->ids
[0];
6319 r
.out
.user_handle
= &user_handle
;
6321 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenUser_r(b
, tctx
, &r
),
6323 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6324 torture_result(tctx
, TORTURE_FAIL
, "OpenUser(%u) failed - %s\n", n
.out
.rids
->ids
[0], nt_errstr(r
.out
.result
));
6328 q
.in
.user_handle
= &user_handle
;
6332 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
),
6333 "QueryUserInfo failed");
6334 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
6335 torture_result(tctx
, TORTURE_FAIL
, "QueryUserInfo failed - %s\n", nt_errstr(q
.out
.result
));
6339 torture_comment(tctx
, "calling test_ChangePasswordUser3 with too early password change\n");
6341 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
,
6342 info
->info5
.last_password_change
, true)) {
6347 /* we change passwords twice - this has the effect of verifying
6348 they were changed correctly for the final call */
6349 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
, 0, true)) {
6353 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
, 0, true)) {
6357 if (!test_ChangePasswordUser4(p
, tctx
, acct_name
, 0, password
, NULL
)) {
6364 static bool test_CreateUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6365 struct policy_handle
*domain_handle
,
6366 const char *user_name
,
6367 struct policy_handle
*user_handle_out
,
6368 struct dom_sid
*domain_sid
,
6369 enum torture_samr_choice which_ops
,
6370 struct cli_credentials
*machine_credentials
,
6374 TALLOC_CTX
*user_ctx
;
6376 struct samr_CreateUser r
;
6377 struct samr_QueryUserInfo q
;
6378 union samr_UserInfo
*info
;
6379 struct samr_DeleteUser d
;
6382 /* This call creates a 'normal' account - check that it really does */
6383 const uint32_t acct_flags
= ACB_NORMAL
;
6384 struct lsa_String name
;
6386 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
6388 struct policy_handle user_handle
;
6389 user_ctx
= talloc_named(tctx
, 0, "test_CreateUser2 per-user context");
6390 init_lsa_String(&name
, user_name
);
6392 r
.in
.domain_handle
= domain_handle
;
6393 r
.in
.account_name
= &name
;
6394 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6395 r
.out
.user_handle
= &user_handle
;
6398 torture_comment(tctx
, "Testing CreateUser(%s)\n", r
.in
.account_name
->string
);
6400 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateUser_r(b
, user_ctx
, &r
),
6401 "CreateUser failed");
6403 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
6404 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
) || NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
6405 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.account_name
->string
);
6408 torture_result(tctx
, TORTURE_FAIL
, "Server should have refused create of '%s', got %s instead\n", r
.in
.account_name
->string
,
6409 nt_errstr(r
.out
.result
));
6414 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_USER_EXISTS
)) {
6415 if (!test_DeleteUser_byname(b
, tctx
, domain_handle
, r
.in
.account_name
->string
)) {
6416 talloc_free(user_ctx
);
6419 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateUser_r(b
, user_ctx
, &r
),
6420 "CreateUser failed");
6423 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6424 talloc_free(user_ctx
);
6425 torture_result(tctx
, TORTURE_FAIL
, "CreateUser failed - %s\n", nt_errstr(r
.out
.result
));
6430 if (user_handle_out
) {
6431 *user_handle_out
= user_handle
;
6437 q
.in
.user_handle
= &user_handle
;
6441 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, user_ctx
, &q
),
6442 "QueryUserInfo failed");
6443 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
6444 torture_result(tctx
, TORTURE_FAIL
, "QueryUserInfo level %u failed - %s\n",
6445 q
.in
.level
, nt_errstr(q
.out
.result
));
6448 if ((info
->info16
.acct_flags
& acct_flags
) != acct_flags
) {
6449 torture_result(tctx
, TORTURE_FAIL
, "QueryUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
6450 info
->info16
.acct_flags
,
6456 if (!test_user_ops(p
, tctx
, &user_handle
, domain_handle
,
6457 domain_sid
, acct_flags
, name
.string
, which_ops
,
6458 machine_credentials
)) {
6462 if (user_handle_out
) {
6463 *user_handle_out
= user_handle
;
6465 torture_comment(tctx
, "Testing DeleteUser (createuser test)\n");
6467 d
.in
.user_handle
= &user_handle
;
6468 d
.out
.user_handle
= &user_handle
;
6470 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, user_ctx
, &d
),
6471 "DeleteUser failed");
6472 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
6473 torture_result(tctx
, TORTURE_FAIL
, "DeleteUser failed - %s\n", nt_errstr(d
.out
.result
));
6480 talloc_free(user_ctx
);
6486 static bool test_CreateUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6487 struct policy_handle
*domain_handle
,
6488 struct dom_sid
*domain_sid
,
6489 enum torture_samr_choice which_ops
,
6490 struct cli_credentials
*machine_credentials
)
6492 struct samr_CreateUser2 r
;
6493 struct samr_QueryUserInfo q
;
6494 union samr_UserInfo
*info
;
6495 struct samr_DeleteUser d
;
6496 struct policy_handle user_handle
;
6498 struct lsa_String name
;
6501 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
6504 uint32_t acct_flags
;
6505 const char *account_name
;
6507 } account_types
[] = {
6508 { ACB_NORMAL
, TEST_ACCOUNT_NAME
, NT_STATUS_OK
},
6509 { ACB_NORMAL
| ACB_DISABLED
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
6510 { ACB_NORMAL
| ACB_PWNOEXP
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
6511 { ACB_WSTRUST
, TEST_MACHINENAME
, NT_STATUS_OK
},
6512 { ACB_WSTRUST
| ACB_DISABLED
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
6513 { ACB_WSTRUST
| ACB_PWNOEXP
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
6514 { ACB_SVRTRUST
, TEST_MACHINENAME
, NT_STATUS_OK
},
6515 { ACB_SVRTRUST
| ACB_DISABLED
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
6516 { ACB_SVRTRUST
| ACB_PWNOEXP
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
6517 { ACB_DOMTRUST
, TEST_DOMAINNAME
, NT_STATUS_ACCESS_DENIED
},
6518 { ACB_DOMTRUST
| ACB_DISABLED
, TEST_DOMAINNAME
, NT_STATUS_INVALID_PARAMETER
},
6519 { ACB_DOMTRUST
| ACB_PWNOEXP
, TEST_DOMAINNAME
, NT_STATUS_INVALID_PARAMETER
},
6520 { 0, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
6521 { ACB_DISABLED
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
6522 { 0, NULL
, NT_STATUS_INVALID_PARAMETER
}
6525 for (i
= 0; account_types
[i
].account_name
; i
++) {
6526 TALLOC_CTX
*user_ctx
;
6527 uint32_t acct_flags
= account_types
[i
].acct_flags
;
6528 uint32_t access_granted
;
6529 user_ctx
= talloc_named(tctx
, 0, "test_CreateUser2 per-user context");
6530 init_lsa_String(&name
, account_types
[i
].account_name
);
6532 r
.in
.domain_handle
= domain_handle
;
6533 r
.in
.account_name
= &name
;
6534 r
.in
.acct_flags
= acct_flags
;
6535 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6536 r
.out
.user_handle
= &user_handle
;
6537 r
.out
.access_granted
= &access_granted
;
6540 torture_comment(tctx
, "Testing CreateUser2(%s, 0x%x)\n", r
.in
.account_name
->string
, acct_flags
);
6542 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateUser2_r(b
, user_ctx
, &r
),
6543 "CreateUser2 failed");
6545 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
6546 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
) || NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
6547 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.account_name
->string
);
6550 torture_result(tctx
, TORTURE_FAIL
, "Server should have refused create of '%s', got %s instead\n", r
.in
.account_name
->string
,
6551 nt_errstr(r
.out
.result
));
6557 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_USER_EXISTS
)) {
6558 if (!test_DeleteUser_byname(b
, tctx
, domain_handle
, r
.in
.account_name
->string
)) {
6559 talloc_free(user_ctx
);
6563 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateUser2_r(b
, user_ctx
, &r
),
6564 "CreateUser2 failed");
6567 if (!NT_STATUS_EQUAL(r
.out
.result
, account_types
[i
].nt_status
)) {
6568 torture_result(tctx
, TORTURE_FAIL
, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
6569 nt_errstr(r
.out
.result
), nt_errstr(account_types
[i
].nt_status
));
6573 if (NT_STATUS_IS_OK(r
.out
.result
)) {
6574 q
.in
.user_handle
= &user_handle
;
6578 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, user_ctx
, &q
),
6579 "QueryUserInfo failed");
6580 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
6581 torture_result(tctx
, TORTURE_FAIL
, "QueryUserInfo level %u failed - %s\n",
6582 q
.in
.level
, nt_errstr(q
.out
.result
));
6585 uint32_t expected_flags
= (acct_flags
| ACB_PWNOTREQ
| ACB_DISABLED
);
6586 if (acct_flags
== ACB_NORMAL
) {
6587 expected_flags
|= ACB_PW_EXPIRED
;
6589 if ((info
->info5
.acct_flags
) != expected_flags
) {
6590 torture_result(tctx
, TORTURE_FAIL
, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
6591 info
->info5
.acct_flags
,
6595 switch (acct_flags
) {
6597 if (info
->info5
.primary_gid
!= DOMAIN_RID_DCS
) {
6598 torture_result(tctx
, TORTURE_FAIL
, "QueryUserInfo level 5: DC should have had Primary Group %d, got %d\n",
6599 DOMAIN_RID_DCS
, info
->info5
.primary_gid
);
6604 if (info
->info5
.primary_gid
!= DOMAIN_RID_DOMAIN_MEMBERS
) {
6605 torture_result(tctx
, TORTURE_FAIL
, "QueryUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
6606 DOMAIN_RID_DOMAIN_MEMBERS
, info
->info5
.primary_gid
);
6611 if (info
->info5
.primary_gid
!= DOMAIN_RID_USERS
) {
6612 torture_result(tctx
, TORTURE_FAIL
, "QueryUserInfo level 5: Users should have had Primary Group %d, got %d\n",
6613 DOMAIN_RID_USERS
, info
->info5
.primary_gid
);
6620 if (!test_user_ops(p
, tctx
, &user_handle
, domain_handle
,
6621 domain_sid
, acct_flags
, name
.string
, which_ops
,
6622 machine_credentials
)) {
6626 if (!ndr_policy_handle_empty(&user_handle
)) {
6627 torture_comment(tctx
, "Testing DeleteUser (createuser2 test)\n");
6629 d
.in
.user_handle
= &user_handle
;
6630 d
.out
.user_handle
= &user_handle
;
6632 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteUser_r(b
, user_ctx
, &d
),
6633 "DeleteUser failed");
6634 if (!NT_STATUS_IS_OK(d
.out
.result
)) {
6635 torture_result(tctx
, TORTURE_FAIL
, "DeleteUser failed - %s\n", nt_errstr(d
.out
.result
));
6640 talloc_free(user_ctx
);
6646 static bool test_QueryAliasInfo(struct dcerpc_binding_handle
*b
,
6647 struct torture_context
*tctx
,
6648 struct policy_handle
*handle
)
6650 struct samr_QueryAliasInfo r
;
6651 union samr_AliasInfo
*info
;
6652 uint16_t levels
[] = {1, 2, 3};
6656 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6657 torture_comment(tctx
, "Testing QueryAliasInfo level %u\n", levels
[i
]);
6659 r
.in
.alias_handle
= handle
;
6660 r
.in
.level
= levels
[i
];
6663 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryAliasInfo_r(b
, tctx
, &r
),
6664 "QueryAliasInfo failed");
6665 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6666 torture_result(tctx
, TORTURE_FAIL
, "QueryAliasInfo level %u failed - %s\n",
6667 levels
[i
], nt_errstr(r
.out
.result
));
6675 static bool test_QueryGroupInfo(struct dcerpc_binding_handle
*b
,
6676 struct torture_context
*tctx
,
6677 struct policy_handle
*handle
)
6679 struct samr_QueryGroupInfo r
;
6680 union samr_GroupInfo
*info
;
6681 uint16_t levels
[] = {1, 2, 3, 4, 5};
6685 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6686 torture_comment(tctx
, "Testing QueryGroupInfo level %u\n", levels
[i
]);
6688 r
.in
.group_handle
= handle
;
6689 r
.in
.level
= levels
[i
];
6692 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupInfo_r(b
, tctx
, &r
),
6693 "QueryGroupInfo failed");
6694 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6695 torture_result(tctx
, TORTURE_FAIL
, "QueryGroupInfo level %u failed - %s\n",
6696 levels
[i
], nt_errstr(r
.out
.result
));
6704 static bool test_QueryGroupMember(struct dcerpc_binding_handle
*b
,
6705 struct torture_context
*tctx
,
6706 struct policy_handle
*handle
)
6708 struct samr_QueryGroupMember r
;
6709 struct samr_RidAttrArray
*rids
= NULL
;
6712 torture_comment(tctx
, "Testing QueryGroupMember\n");
6714 r
.in
.group_handle
= handle
;
6717 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupMember_r(b
, tctx
, &r
),
6718 "QueryGroupMember failed");
6719 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6720 torture_result(tctx
, TORTURE_FAIL
, "QueryGroupMember failed - %s\n", nt_errstr(r
.out
.result
));
6728 static bool test_SetGroupInfo(struct dcerpc_binding_handle
*b
,
6729 struct torture_context
*tctx
,
6730 struct policy_handle
*handle
)
6732 struct samr_QueryGroupInfo r
;
6733 union samr_GroupInfo
*info
;
6734 struct samr_SetGroupInfo s
;
6735 uint16_t levels
[] = {1, 2, 3, 4};
6736 uint16_t set_ok
[] = {0, 1, 1, 1};
6740 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6741 torture_comment(tctx
, "Testing QueryGroupInfo level %u\n", levels
[i
]);
6743 r
.in
.group_handle
= handle
;
6744 r
.in
.level
= levels
[i
];
6747 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupInfo_r(b
, tctx
, &r
),
6748 "QueryGroupInfo failed");
6749 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6750 torture_result(tctx
, TORTURE_FAIL
, "QueryGroupInfo level %u failed - %s\n",
6751 levels
[i
], nt_errstr(r
.out
.result
));
6755 torture_comment(tctx
, "Testing SetGroupInfo level %u\n", levels
[i
]);
6757 s
.in
.group_handle
= handle
;
6758 s
.in
.level
= levels
[i
];
6759 s
.in
.info
= *r
.out
.info
;
6762 /* disabled this, as it changes the name only from the point of view of samr,
6763 but leaves the name from the point of view of w2k3 internals (and ldap). This means
6764 the name is still reserved, so creating the old name fails, but deleting by the old name
6766 if (s
.in
.level
== 2) {
6767 init_lsa_String(&s
.in
.info
->string
, "NewName");
6771 if (s
.in
.level
== 4) {
6772 init_lsa_String(&s
.in
.info
->description
, "test description");
6775 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetGroupInfo_r(b
, tctx
, &s
),
6776 "SetGroupInfo failed");
6778 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
6779 torture_result(tctx
, TORTURE_FAIL
, "SetGroupInfo level %u failed - %s\n",
6780 r
.in
.level
, nt_errstr(s
.out
.result
));
6785 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, s
.out
.result
)) {
6786 torture_result(tctx
, TORTURE_FAIL
, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6787 r
.in
.level
, nt_errstr(s
.out
.result
));
6797 static bool test_QueryUserInfo(struct dcerpc_binding_handle
*b
,
6798 struct torture_context
*tctx
,
6799 struct policy_handle
*handle
)
6801 struct samr_QueryUserInfo r
;
6802 union samr_UserInfo
*info
;
6803 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
6804 11, 12, 13, 14, 16, 17, 20, 21};
6808 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6809 torture_comment(tctx
, "Testing QueryUserInfo level %u\n", levels
[i
]);
6811 r
.in
.user_handle
= handle
;
6812 r
.in
.level
= levels
[i
];
6815 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &r
),
6816 "QueryUserInfo failed");
6817 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6818 torture_result(tctx
, TORTURE_FAIL
, "QueryUserInfo level %u failed - %s\n",
6819 levels
[i
], nt_errstr(r
.out
.result
));
6827 static bool test_QueryUserInfo2(struct dcerpc_binding_handle
*b
,
6828 struct torture_context
*tctx
,
6829 struct policy_handle
*handle
)
6831 struct samr_QueryUserInfo2 r
;
6832 union samr_UserInfo
*info
;
6833 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
6834 11, 12, 13, 14, 16, 17, 20, 21};
6838 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
6839 torture_comment(tctx
, "Testing QueryUserInfo2 level %u\n", levels
[i
]);
6841 r
.in
.user_handle
= handle
;
6842 r
.in
.level
= levels
[i
];
6845 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo2_r(b
, tctx
, &r
),
6846 "QueryUserInfo2 failed");
6847 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6848 torture_result(tctx
, TORTURE_FAIL
, "QueryUserInfo2 level %u failed - %s\n",
6849 levels
[i
], nt_errstr(r
.out
.result
));
6857 static bool test_OpenUser(struct dcerpc_binding_handle
*b
,
6858 struct torture_context
*tctx
,
6859 struct policy_handle
*handle
, uint32_t rid
)
6861 struct samr_OpenUser r
;
6862 struct policy_handle user_handle
;
6865 torture_comment(tctx
, "Testing OpenUser(%u)\n", rid
);
6867 r
.in
.domain_handle
= handle
;
6868 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6870 r
.out
.user_handle
= &user_handle
;
6872 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenUser_r(b
, tctx
, &r
),
6874 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6875 torture_result(tctx
, TORTURE_FAIL
, "OpenUser(%u) failed - %s\n", rid
, nt_errstr(r
.out
.result
));
6879 if (!test_QuerySecurity(b
, tctx
, &user_handle
)) {
6883 if (!test_QueryUserInfo(b
, tctx
, &user_handle
)) {
6887 if (!test_QueryUserInfo2(b
, tctx
, &user_handle
)) {
6891 if (!test_GetUserPwInfo(b
, tctx
, &user_handle
)) {
6895 if (!test_GetGroupsForUser(b
, tctx
, &user_handle
)) {
6899 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
6906 static bool test_OpenGroup(struct dcerpc_binding_handle
*b
,
6907 struct torture_context
*tctx
,
6908 struct policy_handle
*handle
, uint32_t rid
)
6910 struct samr_OpenGroup r
;
6911 struct policy_handle group_handle
;
6914 torture_comment(tctx
, "Testing OpenGroup(%u)\n", rid
);
6916 r
.in
.domain_handle
= handle
;
6917 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6919 r
.out
.group_handle
= &group_handle
;
6921 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenGroup_r(b
, tctx
, &r
),
6922 "OpenGroup failed");
6923 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6924 torture_result(tctx
, TORTURE_FAIL
, "OpenGroup(%u) failed - %s\n", rid
, nt_errstr(r
.out
.result
));
6928 if (!torture_setting_bool(tctx
, "samba3", false)) {
6929 if (!test_QuerySecurity(b
, tctx
, &group_handle
)) {
6934 if (!test_QueryGroupInfo(b
, tctx
, &group_handle
)) {
6938 if (!test_QueryGroupMember(b
, tctx
, &group_handle
)) {
6942 if (!test_samr_handle_Close(b
, tctx
, &group_handle
)) {
6949 static bool test_OpenAlias(struct dcerpc_binding_handle
*b
,
6950 struct torture_context
*tctx
,
6951 struct policy_handle
*handle
, uint32_t rid
)
6953 struct samr_OpenAlias r
;
6954 struct policy_handle alias_handle
;
6957 torture_comment(tctx
, "Testing OpenAlias(%u)\n", rid
);
6959 r
.in
.domain_handle
= handle
;
6960 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6962 r
.out
.alias_handle
= &alias_handle
;
6964 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenAlias_r(b
, tctx
, &r
),
6965 "OpenAlias failed");
6966 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
6967 torture_result(tctx
, TORTURE_FAIL
, "OpenAlias(%u) failed - %s\n", rid
, nt_errstr(r
.out
.result
));
6971 if (!torture_setting_bool(tctx
, "samba3", false)) {
6972 if (!test_QuerySecurity(b
, tctx
, &alias_handle
)) {
6977 if (!test_QueryAliasInfo(b
, tctx
, &alias_handle
)) {
6981 if (!test_GetMembersInAlias(b
, tctx
, &alias_handle
)) {
6985 if (!test_samr_handle_Close(b
, tctx
, &alias_handle
)) {
6992 static bool check_mask(struct dcerpc_binding_handle
*b
,
6993 struct torture_context
*tctx
,
6994 struct policy_handle
*handle
, uint32_t rid
,
6995 uint32_t acct_flag_mask
)
6997 struct samr_OpenUser r
;
6998 struct samr_QueryUserInfo q
;
6999 union samr_UserInfo
*info
;
7000 struct policy_handle user_handle
;
7003 torture_comment(tctx
, "Testing OpenUser(%u)\n", rid
);
7005 r
.in
.domain_handle
= handle
;
7006 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
7008 r
.out
.user_handle
= &user_handle
;
7010 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenUser_r(b
, tctx
, &r
),
7012 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
7013 torture_result(tctx
, TORTURE_FAIL
, "OpenUser(%u) failed - %s\n", rid
, nt_errstr(r
.out
.result
));
7017 q
.in
.user_handle
= &user_handle
;
7021 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
),
7022 "QueryUserInfo failed");
7023 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
7024 torture_result(tctx
, TORTURE_FAIL
, "QueryUserInfo level 16 failed - %s\n",
7025 nt_errstr(q
.out
.result
));
7028 if ((acct_flag_mask
& info
->info16
.acct_flags
) == 0) {
7029 torture_result(tctx
, TORTURE_FAIL
, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
7030 acct_flag_mask
, info
->info16
.acct_flags
, rid
);
7035 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
7042 static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle
*b
,
7043 struct torture_context
*tctx
,
7044 struct policy_handle
*handle
)
7046 struct samr_EnumDomainUsers r
;
7047 uint32_t mask
, resume_handle
=0;
7050 struct samr_LookupNames n
;
7051 struct samr_LookupRids lr
;
7052 struct lsa_Strings names
;
7053 struct samr_Ids rids
, types
;
7054 struct samr_SamArray
*sam
= NULL
;
7055 uint32_t num_entries
= 0;
7057 uint32_t masks
[] = {ACB_NORMAL
, ACB_DOMTRUST
, ACB_WSTRUST
,
7058 ACB_DISABLED
, ACB_NORMAL
| ACB_DISABLED
,
7059 ACB_SVRTRUST
| ACB_DOMTRUST
| ACB_WSTRUST
,
7062 torture_comment(tctx
, "Testing EnumDomainUsers\n");
7064 for (mask_idx
=0;mask_idx
<ARRAY_SIZE(masks
);mask_idx
++) {
7065 r
.in
.domain_handle
= handle
;
7066 r
.in
.resume_handle
= &resume_handle
;
7067 r
.in
.acct_flags
= mask
= masks
[mask_idx
];
7068 r
.in
.max_size
= (uint32_t)-1;
7069 r
.out
.resume_handle
= &resume_handle
;
7070 r
.out
.num_entries
= &num_entries
;
7073 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainUsers_r(b
, tctx
, &r
),
7074 "EnumDomainUsers failed");
7075 if (!NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
) &&
7076 !NT_STATUS_IS_OK(r
.out
.result
)) {
7077 torture_result(tctx
, TORTURE_FAIL
, "EnumDomainUsers failed - %s\n", nt_errstr(r
.out
.result
));
7081 torture_assert(tctx
, sam
, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
7083 if (sam
->count
== 0) {
7087 for (i
=0;i
<sam
->count
;i
++) {
7089 if (!check_mask(b
, tctx
, handle
, sam
->entries
[i
].idx
, mask
)) {
7092 } else if (!test_OpenUser(b
, tctx
, handle
, sam
->entries
[i
].idx
)) {
7098 torture_comment(tctx
, "Testing LookupNames\n");
7099 n
.in
.domain_handle
= handle
;
7100 n
.in
.num_names
= sam
->count
;
7101 n
.in
.names
= talloc_array(tctx
, struct lsa_String
, sam
->count
);
7103 n
.out
.types
= &types
;
7104 for (i
=0;i
<sam
->count
;i
++) {
7105 n
.in
.names
[i
].string
= sam
->entries
[i
].name
.string
;
7107 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupNames_r(b
, tctx
, &n
),
7108 "LookupNames failed");
7109 if (!NT_STATUS_IS_OK(n
.out
.result
)) {
7110 torture_result(tctx
, TORTURE_FAIL
, "LookupNames failed - %s\n", nt_errstr(n
.out
.result
));
7115 torture_comment(tctx
, "Testing LookupRids\n");
7116 lr
.in
.domain_handle
= handle
;
7117 lr
.in
.num_rids
= sam
->count
;
7118 lr
.in
.rids
= talloc_array(tctx
, uint32_t, sam
->count
);
7119 lr
.out
.names
= &names
;
7120 lr
.out
.types
= &types
;
7121 for (i
=0;i
<sam
->count
;i
++) {
7122 lr
.in
.rids
[i
] = sam
->entries
[i
].idx
;
7124 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupRids_r(b
, tctx
, &lr
),
7125 "LookupRids failed");
7126 torture_assert_ntstatus_ok(tctx
, lr
.out
.result
, "LookupRids");
7132 try blasting the server with a bunch of sync requests
7134 static bool test_EnumDomainUsers_async(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
7135 struct policy_handle
*handle
)
7137 struct samr_EnumDomainUsers r
;
7138 uint32_t resume_handle
=0;
7140 #define ASYNC_COUNT 100
7141 struct tevent_req
*req
[ASYNC_COUNT
];
7143 if (!torture_setting_bool(tctx
, "dangerous", false)) {
7144 torture_skip(tctx
, "samr async test disabled - enable dangerous tests to use\n");
7147 torture_comment(tctx
, "Testing EnumDomainUsers_async\n");
7149 r
.in
.domain_handle
= handle
;
7150 r
.in
.resume_handle
= &resume_handle
;
7151 r
.in
.acct_flags
= 0;
7152 r
.in
.max_size
= (uint32_t)-1;
7153 r
.out
.resume_handle
= &resume_handle
;
7155 for (i
=0;i
<ASYNC_COUNT
;i
++) {
7156 req
[i
] = dcerpc_samr_EnumDomainUsers_r_send(tctx
, tctx
->ev
, p
->binding_handle
, &r
);
7159 for (i
=0;i
<ASYNC_COUNT
;i
++) {
7160 tevent_req_poll(req
[i
], tctx
->ev
);
7161 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainUsers_r_recv(req
[i
], tctx
),
7162 talloc_asprintf(tctx
, "EnumDomainUsers[%d] failed - %s\n",
7163 i
, nt_errstr(r
.out
.result
)));
7166 torture_comment(tctx
, "%d async requests OK\n", i
);
7171 static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle
*b
,
7172 struct torture_context
*tctx
,
7173 struct policy_handle
*handle
)
7175 struct samr_EnumDomainGroups r
;
7176 uint32_t resume_handle
=0;
7177 struct samr_SamArray
*sam
= NULL
;
7178 uint32_t num_entries
= 0;
7181 bool universal_group_found
= false;
7183 torture_comment(tctx
, "Testing EnumDomainGroups\n");
7185 r
.in
.domain_handle
= handle
;
7186 r
.in
.resume_handle
= &resume_handle
;
7187 r
.in
.max_size
= (uint32_t)-1;
7188 r
.out
.resume_handle
= &resume_handle
;
7189 r
.out
.num_entries
= &num_entries
;
7192 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainGroups_r(b
, tctx
, &r
),
7193 "EnumDomainGroups failed");
7194 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
7195 torture_result(tctx
, TORTURE_FAIL
, "EnumDomainGroups failed - %s\n", nt_errstr(r
.out
.result
));
7203 for (i
=0;i
<sam
->count
;i
++) {
7204 if (!test_OpenGroup(b
, tctx
, handle
, sam
->entries
[i
].idx
)) {
7207 if ((ret
== true) && (strcasecmp(sam
->entries
[i
].name
.string
,
7208 "Enterprise Admins") == 0)) {
7209 universal_group_found
= true;
7213 /* when we are running this on s4 we should get back at least the
7214 * "Enterprise Admins" universal group. If we don't get a group entry
7215 * at all we probably are performing the test on the builtin domain.
7216 * So ignore this case. */
7217 if (torture_setting_bool(tctx
, "samba4", false)) {
7218 if ((sam
->count
> 0) && (!universal_group_found
)) {
7226 static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle
*b
,
7227 struct torture_context
*tctx
,
7228 struct policy_handle
*handle
)
7230 struct samr_EnumDomainAliases r
;
7231 uint32_t resume_handle
=0;
7232 struct samr_SamArray
*sam
= NULL
;
7233 uint32_t num_entries
= 0;
7237 torture_comment(tctx
, "Testing EnumDomainAliases\n");
7239 r
.in
.domain_handle
= handle
;
7240 r
.in
.resume_handle
= &resume_handle
;
7241 r
.in
.max_size
= (uint32_t)-1;
7243 r
.out
.num_entries
= &num_entries
;
7244 r
.out
.resume_handle
= &resume_handle
;
7246 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainAliases_r(b
, tctx
, &r
),
7247 "EnumDomainAliases failed");
7248 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
7249 torture_result(tctx
, TORTURE_FAIL
, "EnumDomainAliases failed - %s\n", nt_errstr(r
.out
.result
));
7257 for (i
=0;i
<sam
->count
;i
++) {
7258 if (!test_OpenAlias(b
, tctx
, handle
, sam
->entries
[i
].idx
)) {
7266 static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle
*b
,
7267 struct torture_context
*tctx
,
7268 struct policy_handle
*handle
)
7270 struct samr_GetDisplayEnumerationIndex r
;
7272 uint16_t levels
[] = {1, 2, 3, 4, 5};
7273 uint16_t ok_lvl
[] = {1, 1, 1, 0, 0};
7274 struct lsa_String name
;
7278 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
7279 torture_comment(tctx
, "Testing GetDisplayEnumerationIndex level %u\n", levels
[i
]);
7281 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
7283 r
.in
.domain_handle
= handle
;
7284 r
.in
.level
= levels
[i
];
7288 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDisplayEnumerationIndex_r(b
, tctx
, &r
),
7289 "GetDisplayEnumerationIndex failed");
7292 !NT_STATUS_IS_OK(r
.out
.result
) &&
7293 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, r
.out
.result
)) {
7294 torture_result(tctx
, TORTURE_FAIL
, "GetDisplayEnumerationIndex level %u failed - %s\n",
7295 levels
[i
], nt_errstr(r
.out
.result
));
7299 init_lsa_String(&name
, "zzzzzzzz");
7301 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDisplayEnumerationIndex_r(b
, tctx
, &r
),
7302 "GetDisplayEnumerationIndex failed");
7304 if (ok_lvl
[i
] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, r
.out
.result
)) {
7305 torture_result(tctx
, TORTURE_FAIL
, "GetDisplayEnumerationIndex level %u failed - %s\n",
7306 levels
[i
], nt_errstr(r
.out
.result
));
7314 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle
*b
,
7315 struct torture_context
*tctx
,
7316 struct policy_handle
*handle
)
7318 struct samr_GetDisplayEnumerationIndex2 r
;
7320 uint16_t levels
[] = {1, 2, 3, 4, 5};
7321 uint16_t ok_lvl
[] = {1, 1, 1, 0, 0};
7322 struct lsa_String name
;
7326 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
7327 torture_comment(tctx
, "Testing GetDisplayEnumerationIndex2 level %u\n", levels
[i
]);
7329 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
7331 r
.in
.domain_handle
= handle
;
7332 r
.in
.level
= levels
[i
];
7336 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDisplayEnumerationIndex2_r(b
, tctx
, &r
),
7337 "GetDisplayEnumerationIndex2 failed");
7339 !NT_STATUS_IS_OK(r
.out
.result
) &&
7340 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, r
.out
.result
)) {
7341 torture_result(tctx
, TORTURE_FAIL
, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
7342 levels
[i
], nt_errstr(r
.out
.result
));
7346 init_lsa_String(&name
, "zzzzzzzz");
7348 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_GetDisplayEnumerationIndex2_r(b
, tctx
, &r
),
7349 "GetDisplayEnumerationIndex2 failed");
7350 if (ok_lvl
[i
] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, r
.out
.result
)) {
7351 torture_result(tctx
, TORTURE_FAIL
, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
7352 levels
[i
], nt_errstr(r
.out
.result
));
7360 #define STRING_EQUAL_QUERY(s1, s2, user) \
7361 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
7362 /* odd, but valid */ \
7363 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
7364 torture_result(tctx, TORTURE_FAIL, "%s mismatch for %s: %s != %s (%s)\n", \
7365 #s1, user.string, s1.string, s2.string, __location__); \
7368 #define INT_EQUAL_QUERY(s1, s2, user) \
7370 torture_result(tctx, TORTURE_FAIL, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
7371 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
7375 static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle
*b
,
7376 struct torture_context
*tctx
,
7377 struct samr_QueryDisplayInfo
*querydisplayinfo
,
7378 bool *seen_testuser
)
7380 struct samr_OpenUser r
= {
7382 .domain_handle
= querydisplayinfo
->in
.domain_handle
,
7383 .access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
,
7386 struct samr_QueryUserInfo q
;
7387 union samr_UserInfo
*info
;
7388 struct policy_handle user_handle
;
7391 for (i
= 0; ; i
++) {
7392 switch (querydisplayinfo
->in
.level
) {
7394 if (i
>= querydisplayinfo
->out
.info
->info1
.count
) {
7397 r
.in
.rid
= querydisplayinfo
->out
.info
->info1
.entries
[i
].rid
;
7400 if (i
>= querydisplayinfo
->out
.info
->info2
.count
) {
7403 r
.in
.rid
= querydisplayinfo
->out
.info
->info2
.entries
[i
].rid
;
7409 /* Not interested in validating just the account name */
7413 r
.out
.user_handle
= &user_handle
;
7415 switch (querydisplayinfo
->in
.level
) {
7418 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenUser_r(b
, tctx
, &r
),
7420 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
7421 torture_result(tctx
, TORTURE_FAIL
, "OpenUser(%u) failed - %s\n", r
.in
.rid
, nt_errstr(r
.out
.result
));
7426 q
.in
.user_handle
= &user_handle
;
7429 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryUserInfo_r(b
, tctx
, &q
),
7430 "QueryUserInfo failed");
7431 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
7432 torture_result(tctx
, TORTURE_FAIL
, "QueryUserInfo(%u) failed - %s\n", r
.in
.rid
, nt_errstr(r
.out
.result
));
7436 switch (querydisplayinfo
->in
.level
) {
7438 if (seen_testuser
&& strcmp(info
->info21
.account_name
.string
, TEST_ACCOUNT_NAME
) == 0) {
7439 *seen_testuser
= true;
7441 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].full_name
,
7442 info
->info21
.full_name
, info
->info21
.account_name
);
7443 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].account_name
,
7444 info
->info21
.account_name
, info
->info21
.account_name
);
7445 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].description
,
7446 info
->info21
.description
, info
->info21
.account_name
);
7447 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].rid
,
7448 info
->info21
.rid
, info
->info21
.account_name
);
7449 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].acct_flags
,
7450 info
->info21
.acct_flags
, info
->info21
.account_name
);
7454 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].account_name
,
7455 info
->info21
.account_name
, info
->info21
.account_name
);
7456 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].description
,
7457 info
->info21
.description
, info
->info21
.account_name
);
7458 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].rid
,
7459 info
->info21
.rid
, info
->info21
.account_name
);
7460 INT_EQUAL_QUERY((querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
& ~ACB_NORMAL
),
7461 info
->info21
.acct_flags
, info
->info21
.account_name
);
7463 if (!(querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
& ACB_NORMAL
)) {
7464 torture_result(tctx
, TORTURE_FAIL
, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
7465 info
->info21
.account_name
.string
);
7468 if (!(info
->info21
.acct_flags
& (ACB_WSTRUST
| ACB_SVRTRUST
))) {
7469 torture_result(tctx
, TORTURE_FAIL
, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
7470 info
->info21
.account_name
.string
,
7471 querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
,
7472 info
->info21
.acct_flags
);
7479 if (!test_samr_handle_Close(b
, tctx
, &user_handle
)) {
7486 static bool test_QueryDisplayInfo(struct dcerpc_binding_handle
*b
,
7487 struct torture_context
*tctx
,
7488 struct policy_handle
*handle
)
7490 struct samr_QueryDisplayInfo r
;
7491 struct samr_QueryDomainInfo dom_info
;
7492 union samr_DomainInfo
*info
= NULL
;
7494 uint16_t levels
[] = {1, 2, 3, 4, 5};
7496 bool seen_testuser
= false;
7497 uint32_t total_size
;
7498 uint32_t returned_size
;
7499 union samr_DispInfo disp_info
;
7502 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
7503 torture_comment(tctx
, "Testing QueryDisplayInfo level %u\n", levels
[i
]);
7506 r
.out
.result
= STATUS_MORE_ENTRIES
;
7507 while (NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
)) {
7508 r
.in
.domain_handle
= handle
;
7509 r
.in
.level
= levels
[i
];
7510 r
.in
.max_entries
= 2;
7511 r
.in
.buf_size
= (uint32_t)-1;
7512 r
.out
.total_size
= &total_size
;
7513 r
.out
.returned_size
= &returned_size
;
7514 r
.out
.info
= &disp_info
;
7516 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &r
),
7517 "QueryDisplayInfo failed");
7518 if (!NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
) && !NT_STATUS_IS_OK(r
.out
.result
)) {
7519 torture_result(tctx
, TORTURE_FAIL
, "QueryDisplayInfo level %u failed - %s\n",
7520 levels
[i
], nt_errstr(r
.out
.result
));
7523 switch (r
.in
.level
) {
7525 if (!test_each_DisplayInfo_user(b
, tctx
, &r
, &seen_testuser
)) {
7528 r
.in
.start_idx
+= r
.out
.info
->info1
.count
;
7531 if (!test_each_DisplayInfo_user(b
, tctx
, &r
, NULL
)) {
7534 r
.in
.start_idx
+= r
.out
.info
->info2
.count
;
7537 r
.in
.start_idx
+= r
.out
.info
->info3
.count
;
7540 r
.in
.start_idx
+= r
.out
.info
->info4
.count
;
7543 r
.in
.start_idx
+= r
.out
.info
->info5
.count
;
7547 dom_info
.in
.domain_handle
= handle
;
7548 dom_info
.in
.level
= 2;
7549 dom_info
.out
.info
= &info
;
7551 /* Check number of users returned is correct */
7552 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &dom_info
),
7553 "QueryDomainInfo failed");
7554 if (!NT_STATUS_IS_OK(dom_info
.out
.result
)) {
7555 torture_result(tctx
, TORTURE_FAIL
, "QueryDomainInfo level %u failed - %s\n",
7556 r
.in
.level
, nt_errstr(dom_info
.out
.result
));
7560 switch (r
.in
.level
) {
7563 if (info
->general
.num_users
< r
.in
.start_idx
) {
7564 /* On AD deployments this numbers don't match
7565 * since QueryDisplayInfo returns universal and
7566 * global groups, QueryDomainInfo only global
7568 if (torture_setting_bool(tctx
, "samba3", false)) {
7569 torture_result(tctx
, TORTURE_FAIL
, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
7570 r
.in
.start_idx
, info
->general
.num_groups
,
7571 info
->general
.domain_name
.string
);
7575 if (!seen_testuser
) {
7576 struct policy_handle user_handle
;
7577 if (NT_STATUS_IS_OK(test_OpenUser_byname(b
, tctx
, handle
, TEST_ACCOUNT_NAME
, &user_handle
))) {
7578 torture_result(tctx
, TORTURE_FAIL
, "Didn't find test user " TEST_ACCOUNT_NAME
" in enumeration of %s\n",
7579 info
->general
.domain_name
.string
);
7581 test_samr_handle_Close(b
, tctx
, &user_handle
);
7587 if (info
->general
.num_groups
!= r
.in
.start_idx
) {
7588 /* On AD deployments this numbers don't match
7589 * since QueryDisplayInfo returns universal and
7590 * global groups, QueryDomainInfo only global
7592 if (torture_setting_bool(tctx
, "samba3", false)) {
7593 torture_result(tctx
, TORTURE_FAIL
, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
7594 r
.in
.start_idx
, info
->general
.num_groups
,
7595 info
->general
.domain_name
.string
);
7608 static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle
*b
,
7609 struct torture_context
*tctx
,
7610 struct policy_handle
*handle
)
7612 struct samr_QueryDisplayInfo2 r
;
7614 uint16_t levels
[] = {1, 2, 3, 4, 5};
7616 uint32_t total_size
;
7617 uint32_t returned_size
;
7618 union samr_DispInfo info
;
7620 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
7621 torture_comment(tctx
, "Testing QueryDisplayInfo2 level %u\n", levels
[i
]);
7623 r
.in
.domain_handle
= handle
;
7624 r
.in
.level
= levels
[i
];
7626 r
.in
.max_entries
= 1000;
7627 r
.in
.buf_size
= (uint32_t)-1;
7628 r
.out
.total_size
= &total_size
;
7629 r
.out
.returned_size
= &returned_size
;
7632 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo2_r(b
, tctx
, &r
),
7633 "QueryDisplayInfo2 failed");
7634 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
7635 torture_result(tctx
, TORTURE_FAIL
, "QueryDisplayInfo2 level %u failed - %s\n",
7636 levels
[i
], nt_errstr(r
.out
.result
));
7644 static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle
*b
,
7645 struct torture_context
*tctx
,
7646 struct policy_handle
*handle
)
7648 struct samr_QueryDisplayInfo3 r
;
7650 uint16_t levels
[] = {1, 2, 3, 4, 5};
7652 uint32_t total_size
;
7653 uint32_t returned_size
;
7654 union samr_DispInfo info
;
7656 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
7657 torture_comment(tctx
, "Testing QueryDisplayInfo3 level %u\n", levels
[i
]);
7659 r
.in
.domain_handle
= handle
;
7660 r
.in
.level
= levels
[i
];
7662 r
.in
.max_entries
= 1000;
7663 r
.in
.buf_size
= (uint32_t)-1;
7664 r
.out
.total_size
= &total_size
;
7665 r
.out
.returned_size
= &returned_size
;
7668 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo3_r(b
, tctx
, &r
),
7669 "QueryDisplayInfo3 failed");
7670 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
7671 torture_result(tctx
, TORTURE_FAIL
, "QueryDisplayInfo3 level %u failed - %s\n",
7672 levels
[i
], nt_errstr(r
.out
.result
));
7681 static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle
*b
,
7682 struct torture_context
*tctx
,
7683 struct policy_handle
*handle
)
7685 struct samr_QueryDisplayInfo r
;
7687 uint32_t total_size
;
7688 uint32_t returned_size
;
7689 union samr_DispInfo info
;
7691 torture_comment(tctx
, "Testing QueryDisplayInfo continuation\n");
7693 r
.in
.domain_handle
= handle
;
7696 r
.in
.max_entries
= 1;
7697 r
.in
.buf_size
= (uint32_t)-1;
7698 r
.out
.total_size
= &total_size
;
7699 r
.out
.returned_size
= &returned_size
;
7703 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &r
),
7704 "QueryDisplayInfo failed");
7705 if (NT_STATUS_IS_OK(r
.out
.result
) && *r
.out
.returned_size
!= 0) {
7706 if (r
.out
.info
->info1
.entries
[0].idx
!= r
.in
.start_idx
+ 1) {
7707 torture_result(tctx
, TORTURE_FAIL
, "expected idx %d but got %d\n",
7709 r
.out
.info
->info1
.entries
[0].idx
);
7713 if (!NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
) &&
7714 !NT_STATUS_IS_OK(r
.out
.result
)) {
7715 torture_result(tctx
, TORTURE_FAIL
, "QueryDisplayInfo level %u failed - %s\n",
7716 r
.in
.level
, nt_errstr(r
.out
.result
));
7721 } while ((NT_STATUS_EQUAL(r
.out
.result
, STATUS_MORE_ENTRIES
) ||
7722 NT_STATUS_IS_OK(r
.out
.result
)) &&
7723 *r
.out
.returned_size
!= 0);
7728 static bool test_QueryDomainInfo(struct dcerpc_pipe
*p
,
7729 struct torture_context
*tctx
,
7730 struct policy_handle
*handle
)
7732 struct samr_QueryDomainInfo r
;
7733 union samr_DomainInfo
*info
= NULL
;
7734 struct samr_SetDomainInfo s
;
7735 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
7736 uint16_t set_ok
[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
7739 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
7740 const char *domain_comment
= talloc_asprintf(tctx
,
7741 "Tortured by Samba4 RPC-SAMR: %s",
7742 timestring(tctx
, time(NULL
)));
7744 s
.in
.domain_handle
= handle
;
7746 s
.in
.info
= talloc(tctx
, union samr_DomainInfo
);
7748 s
.in
.info
->oem
.oem_information
.string
= domain_comment
;
7749 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
),
7750 "SetDomainInfo failed");
7751 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
7752 torture_result(tctx
, TORTURE_FAIL
, "SetDomainInfo level %u (set comment) failed - %s\n",
7753 s
.in
.level
, nt_errstr(s
.out
.result
));
7757 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
7758 torture_comment(tctx
, "Testing QueryDomainInfo level %u\n", levels
[i
]);
7760 r
.in
.domain_handle
= handle
;
7761 r
.in
.level
= levels
[i
];
7764 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &r
),
7765 "QueryDomainInfo failed");
7766 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
7767 torture_result(tctx
, TORTURE_FAIL
, "QueryDomainInfo level %u failed - %s\n",
7768 r
.in
.level
, nt_errstr(r
.out
.result
));
7773 switch (levels
[i
]) {
7775 if (strcmp(info
->general
.oem_information
.string
, domain_comment
) != 0) {
7776 torture_result(tctx
, TORTURE_FAIL
, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
7777 levels
[i
], info
->general
.oem_information
.string
, domain_comment
);
7778 if (!torture_setting_bool(tctx
, "samba3", false)) {
7782 if (!info
->general
.primary
.string
) {
7783 torture_result(tctx
, TORTURE_FAIL
, "QueryDomainInfo level %u returned no PDC name\n",
7786 } else if (info
->general
.role
== SAMR_ROLE_DOMAIN_PDC
) {
7787 if (dcerpc_server_name(p
) && strcasecmp_m(dcerpc_server_name(p
), info
->general
.primary
.string
) != 0) {
7788 if (torture_setting_bool(tctx
, "samba3", false)) {
7789 torture_result(tctx
, TORTURE_FAIL
, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
7790 levels
[i
], info
->general
.primary
.string
, dcerpc_server_name(p
));
7796 if (strcmp(info
->oem
.oem_information
.string
, domain_comment
) != 0) {
7797 torture_result(tctx
, TORTURE_FAIL
, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
7798 levels
[i
], info
->oem
.oem_information
.string
, domain_comment
);
7799 if (!torture_setting_bool(tctx
, "samba3", false)) {
7805 if (!info
->info6
.primary
.string
) {
7806 torture_result(tctx
, TORTURE_FAIL
, "QueryDomainInfo level %u returned no PDC name\n",
7812 if (strcmp(info
->general2
.general
.oem_information
.string
, domain_comment
) != 0) {
7813 torture_result(tctx
, TORTURE_FAIL
, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
7814 levels
[i
], info
->general2
.general
.oem_information
.string
, domain_comment
);
7815 if (!torture_setting_bool(tctx
, "samba3", false)) {
7822 torture_comment(tctx
, "Testing SetDomainInfo level %u\n", levels
[i
]);
7824 s
.in
.domain_handle
= handle
;
7825 s
.in
.level
= levels
[i
];
7828 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetDomainInfo_r(b
, tctx
, &s
),
7829 "SetDomainInfo failed");
7831 if (!NT_STATUS_IS_OK(s
.out
.result
)) {
7832 torture_result(tctx
, TORTURE_FAIL
, "SetDomainInfo level %u failed - %s\n",
7833 r
.in
.level
, nt_errstr(s
.out
.result
));
7838 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, s
.out
.result
)) {
7839 torture_result(tctx
, TORTURE_FAIL
, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
7840 r
.in
.level
, nt_errstr(s
.out
.result
));
7846 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo_r(b
, tctx
, &r
),
7847 "QueryDomainInfo failed");
7848 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
7849 torture_result(tctx
, TORTURE_FAIL
, "QueryDomainInfo level %u failed - %s\n",
7850 r
.in
.level
, nt_errstr(r
.out
.result
));
7860 static bool test_QueryDomainInfo2(struct dcerpc_binding_handle
*b
,
7861 struct torture_context
*tctx
,
7862 struct policy_handle
*handle
)
7864 struct samr_QueryDomainInfo2 r
;
7865 union samr_DomainInfo
*info
= NULL
;
7866 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
7870 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
7871 torture_comment(tctx
, "Testing QueryDomainInfo2 level %u\n", levels
[i
]);
7873 r
.in
.domain_handle
= handle
;
7874 r
.in
.level
= levels
[i
];
7877 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo2_r(b
, tctx
, &r
),
7878 "QueryDomainInfo2 failed");
7879 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
7880 torture_result(tctx
, TORTURE_FAIL
, "QueryDomainInfo2 level %u failed - %s\n",
7881 r
.in
.level
, nt_errstr(r
.out
.result
));
7890 /* Test whether querydispinfo level 5 and enumdomgroups return the same
7891 set of group names. */
7892 static bool test_GroupList(struct dcerpc_binding_handle
*b
,
7893 struct torture_context
*tctx
,
7894 struct dom_sid
*domain_sid
,
7895 struct policy_handle
*handle
)
7897 struct samr_EnumDomainGroups q1
;
7898 struct samr_QueryDisplayInfo q2
;
7900 uint32_t resume_handle
=0;
7901 struct samr_SamArray
*sam
= NULL
;
7902 uint32_t num_entries
= 0;
7905 uint32_t total_size
;
7906 uint32_t returned_size
;
7907 union samr_DispInfo info
;
7909 size_t num_names
= 0;
7910 const char **names
= NULL
;
7912 bool builtin_domain
= dom_sid_compare(domain_sid
,
7913 &global_sid_Builtin
) == 0;
7915 torture_comment(tctx
, "Testing coherency of querydispinfo vs enumdomgroups\n");
7917 q1
.in
.domain_handle
= handle
;
7918 q1
.in
.resume_handle
= &resume_handle
;
7920 q1
.out
.resume_handle
= &resume_handle
;
7921 q1
.out
.num_entries
= &num_entries
;
7924 status
= STATUS_MORE_ENTRIES
;
7925 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
7926 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainGroups_r(b
, tctx
, &q1
),
7927 "EnumDomainGroups failed");
7928 status
= q1
.out
.result
;
7930 if (!NT_STATUS_IS_OK(status
) &&
7931 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
7934 for (i
=0; i
<*q1
.out
.num_entries
; i
++) {
7935 add_string_to_array(tctx
,
7936 sam
->entries
[i
].name
.string
,
7937 &names
, &num_names
);
7941 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomainGroups");
7943 torture_assert(tctx
, sam
, "EnumDomainGroups failed to return sam");
7945 if (builtin_domain
) {
7946 torture_assert(tctx
, num_names
== 0,
7947 "EnumDomainGroups shouldn't return any group in the builtin domain!");
7950 q2
.in
.domain_handle
= handle
;
7952 q2
.in
.start_idx
= 0;
7953 q2
.in
.max_entries
= 5;
7954 q2
.in
.buf_size
= (uint32_t)-1;
7955 q2
.out
.total_size
= &total_size
;
7956 q2
.out
.returned_size
= &returned_size
;
7957 q2
.out
.info
= &info
;
7959 status
= STATUS_MORE_ENTRIES
;
7960 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
7961 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &q2
),
7962 "QueryDisplayInfo failed");
7963 status
= q2
.out
.result
;
7964 if (!NT_STATUS_IS_OK(status
) &&
7965 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
7968 for (i
=0; i
<q2
.out
.info
->info5
.count
; i
++) {
7970 const char *name
= q2
.out
.info
->info5
.entries
[i
].account_name
.string
;
7972 for (j
=0; j
<num_names
; j
++) {
7973 if (names
[j
] == NULL
)
7975 if (strequal(names
[j
], name
)) {
7982 if ((!found
) && (!builtin_domain
)) {
7983 torture_result(tctx
, TORTURE_FAIL
, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
7988 q2
.in
.start_idx
+= q2
.out
.info
->info5
.count
;
7991 if (!NT_STATUS_IS_OK(status
)) {
7992 torture_result(tctx
, TORTURE_FAIL
, "QueryDisplayInfo level 5 failed - %s\n",
7997 if (builtin_domain
) {
7998 torture_assert(tctx
, q2
.in
.start_idx
!= 0,
7999 "QueryDisplayInfo should return all domain groups also on the builtin domain handle!");
8002 for (i
=0; i
<num_names
; i
++) {
8003 if (names
[i
] != NULL
) {
8004 torture_result(tctx
, TORTURE_FAIL
, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
8013 static bool test_DeleteDomainGroup(struct dcerpc_binding_handle
*b
,
8014 struct torture_context
*tctx
,
8015 struct policy_handle
*group_handle
)
8017 struct samr_DeleteDomainGroup d
;
8019 torture_comment(tctx
, "Testing DeleteDomainGroup\n");
8021 d
.in
.group_handle
= group_handle
;
8022 d
.out
.group_handle
= group_handle
;
8024 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteDomainGroup_r(b
, tctx
, &d
),
8025 "DeleteDomainGroup failed");
8026 torture_assert_ntstatus_ok(tctx
, d
.out
.result
, "DeleteDomainGroup");
8031 static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle
*b
,
8032 struct torture_context
*tctx
,
8033 struct policy_handle
*domain_handle
)
8035 struct samr_TestPrivateFunctionsDomain r
;
8038 torture_comment(tctx
, "Testing TestPrivateFunctionsDomain\n");
8040 r
.in
.domain_handle
= domain_handle
;
8042 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_TestPrivateFunctionsDomain_r(b
, tctx
, &r
),
8043 "TestPrivateFunctionsDomain failed");
8044 torture_assert_ntstatus_equal(tctx
, r
.out
.result
, NT_STATUS_NOT_IMPLEMENTED
, "TestPrivateFunctionsDomain");
8049 static bool test_RidToSid(struct dcerpc_binding_handle
*b
,
8050 struct torture_context
*tctx
,
8051 struct dom_sid
*domain_sid
,
8052 struct policy_handle
*domain_handle
)
8054 struct samr_RidToSid r
;
8056 struct dom_sid
*calc_sid
, *out_sid
;
8057 int rids
[] = { 0, 42, 512, 10200 };
8060 for (i
=0;i
<ARRAY_SIZE(rids
);i
++) {
8061 torture_comment(tctx
, "Testing RidToSid\n");
8063 calc_sid
= dom_sid_dup(tctx
, domain_sid
);
8064 r
.in
.domain_handle
= domain_handle
;
8066 r
.out
.sid
= &out_sid
;
8068 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RidToSid_r(b
, tctx
, &r
),
8070 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
8071 torture_result(tctx
, TORTURE_FAIL
, "RidToSid for %d failed - %s\n", rids
[i
], nt_errstr(r
.out
.result
));
8074 calc_sid
= dom_sid_add_rid(calc_sid
, calc_sid
, rids
[i
]);
8076 if (!dom_sid_equal(calc_sid
, out_sid
)) {
8077 torture_result(tctx
, TORTURE_FAIL
, "RidToSid for %d failed - got %s, expected %s\n", rids
[i
],
8078 dom_sid_string(tctx
, out_sid
),
8079 dom_sid_string(tctx
, calc_sid
));
8088 static bool test_GetBootKeyInformation(struct dcerpc_binding_handle
*b
,
8089 struct torture_context
*tctx
,
8090 struct policy_handle
*domain_handle
)
8092 struct samr_GetBootKeyInformation r
;
8094 uint32_t unknown
= 0;
8097 torture_comment(tctx
, "Testing GetBootKeyInformation\n");
8099 r
.in
.domain_handle
= domain_handle
;
8100 r
.out
.unknown
= &unknown
;
8102 status
= dcerpc_samr_GetBootKeyInformation_r(b
, tctx
, &r
);
8103 if (NT_STATUS_IS_OK(status
) && !NT_STATUS_IS_OK(r
.out
.result
)) {
8104 status
= r
.out
.result
;
8106 if (!NT_STATUS_IS_OK(status
)) {
8107 /* w2k3 seems to fail this sometimes and pass it sometimes */
8108 torture_comment(tctx
, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status
));
8114 static bool test_AddGroupMember(struct dcerpc_binding_handle
*b
,
8115 struct torture_context
*tctx
,
8116 struct policy_handle
*domain_handle
,
8117 struct policy_handle
*group_handle
)
8120 struct samr_AddGroupMember r
;
8121 struct samr_DeleteGroupMember d
;
8122 struct samr_QueryGroupMember q
;
8123 struct samr_RidAttrArray
*rids
= NULL
;
8124 struct samr_SetMemberAttributesOfGroup s
;
8126 bool found_member
= false;
8129 status
= test_LookupName(b
, tctx
, domain_handle
, TEST_ACCOUNT_NAME
, &rid
);
8130 torture_assert_ntstatus_ok(tctx
, status
, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME
);
8132 r
.in
.group_handle
= group_handle
;
8134 r
.in
.flags
= 0; /* ??? */
8136 torture_comment(tctx
, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
8138 d
.in
.group_handle
= group_handle
;
8141 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteGroupMember_r(b
, tctx
, &d
),
8142 "DeleteGroupMember failed");
8143 torture_assert_ntstatus_equal(tctx
, NT_STATUS_MEMBER_NOT_IN_GROUP
, d
.out
.result
, "DeleteGroupMember");
8145 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddGroupMember_r(b
, tctx
, &r
),
8146 "AddGroupMember failed");
8147 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "AddGroupMember");
8149 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddGroupMember_r(b
, tctx
, &r
),
8150 "AddGroupMember failed");
8151 torture_assert_ntstatus_equal(tctx
, NT_STATUS_MEMBER_IN_GROUP
, r
.out
.result
, "AddGroupMember");
8153 if (torture_setting_bool(tctx
, "samba4", false) ||
8154 torture_setting_bool(tctx
, "samba3", false)) {
8155 torture_comment(tctx
, "skipping SetMemberAttributesOfGroup test against Samba\n");
8157 /* this one is quite strange. I am using random inputs in the
8158 hope of triggering an error that might give us a clue */
8160 s
.in
.group_handle
= group_handle
;
8161 s
.in
.unknown1
= random();
8162 s
.in
.unknown2
= random();
8164 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_SetMemberAttributesOfGroup_r(b
, tctx
, &s
),
8165 "SetMemberAttributesOfGroup failed");
8166 torture_assert_ntstatus_ok(tctx
, s
.out
.result
, "SetMemberAttributesOfGroup");
8169 q
.in
.group_handle
= group_handle
;
8172 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupMember_r(b
, tctx
, &q
),
8173 "QueryGroupMember failed");
8174 torture_assert_ntstatus_ok(tctx
, q
.out
.result
, "QueryGroupMember");
8175 torture_assert(tctx
, rids
, "QueryGroupMember did not fill in rids structure");
8177 for (i
=0; i
< rids
->count
; i
++) {
8178 if (rids
->rids
[i
] == rid
) {
8179 found_member
= true;
8183 torture_assert(tctx
, found_member
, "QueryGroupMember did not list newly added member");
8185 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_DeleteGroupMember_r(b
, tctx
, &d
),
8186 "DeleteGroupMember failed");
8187 torture_assert_ntstatus_ok(tctx
, d
.out
.result
, "DeleteGroupMember");
8190 found_member
= false;
8192 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryGroupMember_r(b
, tctx
, &q
),
8193 "QueryGroupMember failed");
8194 torture_assert_ntstatus_ok(tctx
, q
.out
.result
, "QueryGroupMember");
8195 torture_assert(tctx
, rids
, "QueryGroupMember did not fill in rids structure");
8197 for (i
=0; i
< rids
->count
; i
++) {
8198 if (rids
->rids
[i
] == rid
) {
8199 found_member
= true;
8203 torture_assert(tctx
, !found_member
, "QueryGroupMember does still list removed member");
8205 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_AddGroupMember_r(b
, tctx
, &r
),
8206 "AddGroupMember failed");
8207 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "AddGroupMember");
8213 static bool test_CreateDomainGroup(struct dcerpc_binding_handle
*b
,
8214 struct torture_context
*tctx
,
8215 struct policy_handle
*domain_handle
,
8216 const char *group_name
,
8217 struct policy_handle
*group_handle
,
8218 struct dom_sid
*domain_sid
,
8221 struct samr_CreateDomainGroup r
;
8223 struct lsa_String name
;
8226 init_lsa_String(&name
, group_name
);
8228 r
.in
.domain_handle
= domain_handle
;
8230 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
8231 r
.out
.group_handle
= group_handle
;
8234 torture_comment(tctx
, "Testing CreateDomainGroup(%s)\n", r
.in
.name
->string
);
8236 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomainGroup_r(b
, tctx
, &r
),
8237 "CreateDomainGroup failed");
8239 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
8240 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_ACCESS_DENIED
)) {
8241 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.name
->string
);
8244 torture_result(tctx
, TORTURE_FAIL
, "Server should have refused create of '%s', got %s instead\n", r
.in
.name
->string
,
8245 nt_errstr(r
.out
.result
));
8250 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_GROUP_EXISTS
)) {
8251 if (!test_DeleteGroup_byname(b
, tctx
, domain_handle
, r
.in
.name
->string
)) {
8252 torture_result(tctx
, TORTURE_FAIL
, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r
.in
.name
->string
,
8253 nt_errstr(r
.out
.result
));
8256 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomainGroup_r(b
, tctx
, &r
),
8257 "CreateDomainGroup failed");
8259 if (NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_USER_EXISTS
)) {
8260 if (!test_DeleteUser_byname(b
, tctx
, domain_handle
, r
.in
.name
->string
)) {
8262 torture_result(tctx
, TORTURE_FAIL
, "CreateDomainGroup failed: Could not delete user %s - %s\n", r
.in
.name
->string
,
8263 nt_errstr(r
.out
.result
));
8266 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_CreateDomainGroup_r(b
, tctx
, &r
),
8267 "CreateDomainGroup failed");
8269 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "CreateDomainGroup");
8275 if (!test_AddGroupMember(b
, tctx
, domain_handle
, group_handle
)) {
8276 torture_result(tctx
, TORTURE_FAIL
, "CreateDomainGroup failed - %s\n", nt_errstr(r
.out
.result
));
8280 if (!test_SetGroupInfo(b
, tctx
, group_handle
)) {
8289 its not totally clear what this does. It seems to accept any sid you like.
8291 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle
*b
,
8292 struct torture_context
*tctx
,
8293 struct policy_handle
*domain_handle
)
8295 struct samr_RemoveMemberFromForeignDomain r
;
8297 r
.in
.domain_handle
= domain_handle
;
8298 r
.in
.sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-12-34-56-78");
8300 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_RemoveMemberFromForeignDomain_r(b
, tctx
, &r
),
8301 "RemoveMemberFromForeignDomain failed");
8302 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "RemoveMemberFromForeignDomain");
8307 static bool test_EnumDomainUsers(struct dcerpc_binding_handle
*b
,
8308 struct torture_context
*tctx
,
8309 struct policy_handle
*domain_handle
,
8310 uint32_t *total_num_entries_p
)
8313 struct samr_EnumDomainUsers r
;
8314 uint32_t resume_handle
= 0;
8315 uint32_t num_entries
= 0;
8316 uint32_t total_num_entries
= 0;
8317 struct samr_SamArray
*sam
;
8319 r
.in
.domain_handle
= domain_handle
;
8320 r
.in
.acct_flags
= 0;
8321 r
.in
.max_size
= (uint32_t)-1;
8322 r
.in
.resume_handle
= &resume_handle
;
8325 r
.out
.num_entries
= &num_entries
;
8326 r
.out
.resume_handle
= &resume_handle
;
8328 torture_comment(tctx
, "Testing EnumDomainUsers\n");
8331 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainUsers_r(b
, tctx
, &r
),
8332 "EnumDomainUsers failed");
8333 if (NT_STATUS_IS_ERR(r
.out
.result
)) {
8334 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
8335 "failed to enumerate users");
8337 status
= r
.out
.result
;
8339 total_num_entries
+= num_entries
;
8340 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
8342 if (total_num_entries_p
) {
8343 *total_num_entries_p
= total_num_entries
;
8349 static bool test_EnumDomainGroups(struct dcerpc_binding_handle
*b
,
8350 struct torture_context
*tctx
,
8351 struct policy_handle
*domain_handle
,
8352 uint32_t *total_num_entries_p
)
8355 struct samr_EnumDomainGroups r
;
8356 uint32_t resume_handle
= 0;
8357 uint32_t num_entries
= 0;
8358 uint32_t total_num_entries
= 0;
8359 struct samr_SamArray
*sam
;
8361 r
.in
.domain_handle
= domain_handle
;
8362 r
.in
.max_size
= (uint32_t)-1;
8363 r
.in
.resume_handle
= &resume_handle
;
8366 r
.out
.num_entries
= &num_entries
;
8367 r
.out
.resume_handle
= &resume_handle
;
8369 torture_comment(tctx
, "Testing EnumDomainGroups\n");
8372 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainGroups_r(b
, tctx
, &r
),
8373 "EnumDomainGroups failed");
8374 if (NT_STATUS_IS_ERR(r
.out
.result
)) {
8375 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
8376 "failed to enumerate groups");
8378 status
= r
.out
.result
;
8380 total_num_entries
+= num_entries
;
8381 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
8383 if (total_num_entries_p
) {
8384 *total_num_entries_p
= total_num_entries
;
8390 static bool test_EnumDomainAliases(struct dcerpc_binding_handle
*b
,
8391 struct torture_context
*tctx
,
8392 struct policy_handle
*domain_handle
,
8393 uint32_t *total_num_entries_p
)
8396 struct samr_EnumDomainAliases r
;
8397 uint32_t resume_handle
= 0;
8398 uint32_t num_entries
= 0;
8399 uint32_t total_num_entries
= 0;
8400 struct samr_SamArray
*sam
;
8402 r
.in
.domain_handle
= domain_handle
;
8403 r
.in
.max_size
= (uint32_t)-1;
8404 r
.in
.resume_handle
= &resume_handle
;
8407 r
.out
.num_entries
= &num_entries
;
8408 r
.out
.resume_handle
= &resume_handle
;
8410 torture_comment(tctx
, "Testing EnumDomainAliases\n");
8413 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomainAliases_r(b
, tctx
, &r
),
8414 "EnumDomainAliases failed");
8415 if (NT_STATUS_IS_ERR(r
.out
.result
)) {
8416 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
8417 "failed to enumerate aliases");
8419 status
= r
.out
.result
;
8421 total_num_entries
+= num_entries
;
8422 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
8424 if (total_num_entries_p
) {
8425 *total_num_entries_p
= total_num_entries
;
8431 static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle
*b
,
8432 struct torture_context
*tctx
,
8433 struct policy_handle
*handle
,
8435 uint32_t *total_num_entries_p
)
8438 struct samr_QueryDisplayInfo r
;
8439 uint32_t total_num_entries
= 0;
8441 r
.in
.domain_handle
= handle
;
8444 r
.in
.max_entries
= (uint32_t)-1;
8445 r
.in
.buf_size
= (uint32_t)-1;
8447 torture_comment(tctx
, "Testing QueryDisplayInfo\n");
8450 uint32_t total_size
;
8451 uint32_t returned_size
;
8452 union samr_DispInfo info
;
8454 r
.out
.total_size
= &total_size
;
8455 r
.out
.returned_size
= &returned_size
;
8458 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDisplayInfo_r(b
, tctx
, &r
),
8459 "failed to query displayinfo");
8460 if (NT_STATUS_IS_ERR(r
.out
.result
)) {
8461 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
8462 "failed to query displayinfo");
8464 status
= r
.out
.result
;
8466 if (*r
.out
.returned_size
== 0) {
8470 switch (r
.in
.level
) {
8472 total_num_entries
+= info
.info1
.count
;
8473 r
.in
.start_idx
+= info
.info1
.entries
[info
.info1
.count
- 1].idx
+ 1;
8476 total_num_entries
+= info
.info2
.count
;
8477 r
.in
.start_idx
+= info
.info2
.entries
[info
.info2
.count
- 1].idx
+ 1;
8480 total_num_entries
+= info
.info3
.count
;
8481 r
.in
.start_idx
+= info
.info3
.entries
[info
.info3
.count
- 1].idx
+ 1;
8484 total_num_entries
+= info
.info4
.count
;
8485 r
.in
.start_idx
+= info
.info4
.entries
[info
.info4
.count
- 1].idx
+ 1;
8488 total_num_entries
+= info
.info5
.count
;
8489 r
.in
.start_idx
+= info
.info5
.entries
[info
.info5
.count
- 1].idx
+ 1;
8495 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
8497 if (total_num_entries_p
) {
8498 *total_num_entries_p
= total_num_entries
;
8504 static bool test_ManyObjects(struct dcerpc_pipe
*p
,
8505 struct torture_context
*tctx
,
8506 struct policy_handle
*domain_handle
,
8507 struct dom_sid
*domain_sid
,
8508 struct torture_samr_context
*ctx
)
8510 uint32_t num_total
= ctx
->num_objects_large_dc
;
8511 uint32_t num_enum
= 0;
8512 uint32_t num_disp
= 0;
8513 uint32_t num_created
= 0;
8514 uint32_t num_anounced
= 0;
8516 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
8518 struct policy_handle
*handles
= talloc_zero_array(tctx
, struct policy_handle
, num_total
);
8523 struct samr_QueryDomainInfo2 r
;
8524 union samr_DomainInfo
*info
;
8525 r
.in
.domain_handle
= domain_handle
;
8529 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_QueryDomainInfo2_r(b
, tctx
, &r
),
8530 "QueryDomainInfo2 failed");
8531 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
8532 "failed to query domain info");
8534 switch (ctx
->choice
) {
8535 case TORTURE_SAMR_MANY_ACCOUNTS
:
8536 num_anounced
= info
->general
.num_users
;
8538 case TORTURE_SAMR_MANY_GROUPS
:
8539 num_anounced
= info
->general
.num_groups
;
8541 case TORTURE_SAMR_MANY_ALIASES
:
8542 num_anounced
= info
->general
.num_aliases
;
8551 for (i
=0; i
< num_total
; i
++) {
8553 const char *name
= NULL
;
8555 switch (ctx
->choice
) {
8556 case TORTURE_SAMR_MANY_ACCOUNTS
:
8557 name
= talloc_asprintf(tctx
, "%s%04d", TEST_ACCOUNT_NAME
, i
);
8558 torture_assert(tctx
,
8559 test_CreateUser(p
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, 0, NULL
, false),
8560 "failed to create user");
8562 case TORTURE_SAMR_MANY_GROUPS
:
8563 name
= talloc_asprintf(tctx
, "%s%04d", TEST_GROUPNAME
, i
);
8564 torture_assert(tctx
,
8565 test_CreateDomainGroup(b
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, false),
8566 "failed to create group");
8568 case TORTURE_SAMR_MANY_ALIASES
:
8569 name
= talloc_asprintf(tctx
, "%s%04d", TEST_ALIASNAME
, i
);
8570 torture_assert(tctx
,
8571 test_CreateAlias(b
, tctx
, domain_handle
, name
, &handles
[i
], domain_sid
, false),
8572 "failed to create alias");
8577 if (!ndr_policy_handle_empty(&handles
[i
])) {
8584 switch (ctx
->choice
) {
8585 case TORTURE_SAMR_MANY_ACCOUNTS
:
8586 torture_assert(tctx
,
8587 test_EnumDomainUsers(b
, tctx
, domain_handle
, &num_enum
),
8588 "failed to enum users");
8590 case TORTURE_SAMR_MANY_GROUPS
:
8591 torture_assert(tctx
,
8592 test_EnumDomainGroups(b
, tctx
, domain_handle
, &num_enum
),
8593 "failed to enum groups");
8595 case TORTURE_SAMR_MANY_ALIASES
:
8596 torture_assert(tctx
,
8597 test_EnumDomainAliases(b
, tctx
, domain_handle
, &num_enum
),
8598 "failed to enum aliases");
8606 switch (ctx
->choice
) {
8607 case TORTURE_SAMR_MANY_ACCOUNTS
:
8608 torture_assert(tctx
,
8609 test_QueryDisplayInfo_level(b
, tctx
, domain_handle
, 1, &num_disp
),
8610 "failed to query display info");
8612 case TORTURE_SAMR_MANY_GROUPS
:
8613 torture_assert(tctx
,
8614 test_QueryDisplayInfo_level(b
, tctx
, domain_handle
, 3, &num_disp
),
8615 "failed to query display info");
8617 case TORTURE_SAMR_MANY_ALIASES
:
8618 /* no aliases in dispinfo */
8624 /* close or delete */
8626 for (i
=0; i
< num_total
; i
++) {
8628 if (ndr_policy_handle_empty(&handles
[i
])) {
8632 if (torture_setting_bool(tctx
, "samba3", false)) {
8633 torture_assert(tctx
,
8634 test_samr_handle_Close(b
, tctx
, &handles
[i
]),
8635 "failed to close handle");
8637 switch (ctx
->choice
) {
8638 case TORTURE_SAMR_MANY_ACCOUNTS
:
8639 torture_assert(tctx
,
8640 test_DeleteUser(b
, tctx
, &handles
[i
]),
8641 "failed to delete user");
8643 case TORTURE_SAMR_MANY_GROUPS
:
8644 torture_assert(tctx
,
8645 test_DeleteDomainGroup(b
, tctx
, &handles
[i
]),
8646 "failed to delete group");
8648 case TORTURE_SAMR_MANY_ALIASES
:
8649 torture_assert(tctx
,
8650 test_DeleteAlias(b
, tctx
, &handles
[i
]),
8651 "failed to delete alias");
8659 talloc_free(handles
);
8661 if (ctx
->choice
== TORTURE_SAMR_MANY_ACCOUNTS
&& num_enum
!= num_anounced
+ num_created
) {
8662 torture_comment(tctx
,
8663 "unexpected number of results (%u) returned in enum call, expected %u\n",
8664 num_enum
, num_anounced
+ num_created
);
8666 torture_comment(tctx
,
8667 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
8668 num_disp
, num_anounced
+ num_created
);
8674 static bool test_Connect(struct dcerpc_binding_handle
*b
,
8675 struct torture_context
*tctx
,
8676 struct policy_handle
*handle
);
8678 static bool test_OpenDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
8679 struct torture_samr_context
*ctx
, struct dom_sid
*sid
)
8681 struct samr_OpenDomain r
;
8682 struct policy_handle domain_handle
;
8683 struct policy_handle alias_handle
;
8684 struct policy_handle user_handle
;
8685 struct policy_handle group_handle
;
8687 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
8689 ZERO_STRUCT(alias_handle
);
8690 ZERO_STRUCT(user_handle
);
8691 ZERO_STRUCT(group_handle
);
8692 ZERO_STRUCT(domain_handle
);
8694 torture_comment(tctx
, "Testing OpenDomain of %s\n", dom_sid_string(tctx
, sid
));
8696 r
.in
.connect_handle
= &ctx
->handle
;
8697 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
8699 r
.out
.domain_handle
= &domain_handle
;
8701 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_OpenDomain_r(b
, tctx
, &r
),
8702 "OpenDomain failed");
8703 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "OpenDomain failed");
8705 /* run the domain tests with the main handle closed - this tests
8706 the servers reference counting */
8707 torture_assert(tctx
, test_samr_handle_Close(b
, tctx
, &ctx
->handle
), "Failed to close SAMR handle");
8709 switch (ctx
->choice
) {
8710 case TORTURE_SAMR_PASSWORDS
:
8711 case TORTURE_SAMR_USER_PRIVILEGES
:
8712 if (!torture_setting_bool(tctx
, "samba3", false)) {
8713 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, NULL
);
8715 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
8717 torture_result(tctx
, TORTURE_FAIL
, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx
, sid
));
8720 case TORTURE_SAMR_USER_ATTRIBUTES
:
8721 if (!torture_setting_bool(tctx
, "samba3", false)) {
8722 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, NULL
);
8724 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
8725 /* This test needs 'complex' users to validate */
8726 ret
&= test_QueryDisplayInfo(b
, tctx
, &domain_handle
);
8728 torture_result(tctx
, TORTURE_FAIL
, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx
, sid
));
8731 case TORTURE_SAMR_PASSWORDS_PWDLASTSET
:
8732 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
:
8733 case TORTURE_SAMR_PASSWORDS_LOCKOUT
:
8734 if (!torture_setting_bool(tctx
, "samba3", false)) {
8735 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, ctx
->choice
, ctx
->machine_credentials
);
8737 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, ctx
->machine_credentials
, true);
8739 torture_result(tctx
, TORTURE_FAIL
, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx
, sid
));
8742 case TORTURE_SAMR_MANY_ACCOUNTS
:
8743 case TORTURE_SAMR_MANY_GROUPS
:
8744 case TORTURE_SAMR_MANY_ALIASES
:
8745 ret
&= test_ManyObjects(p
, tctx
, &domain_handle
, sid
, ctx
);
8747 torture_result(tctx
, TORTURE_FAIL
, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx
, sid
));
8750 case TORTURE_SAMR_OTHER
:
8751 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, TEST_ACCOUNT_NAME
, &user_handle
, sid
, ctx
->choice
, NULL
, true);
8753 torture_result(tctx
, TORTURE_FAIL
, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx
, sid
));
8755 if (!torture_setting_bool(tctx
, "samba3", false)) {
8756 ret
&= test_QuerySecurity(b
, tctx
, &domain_handle
);
8758 ret
&= test_RemoveMemberFromForeignDomain(b
, tctx
, &domain_handle
);
8759 ret
&= test_CreateAlias(b
, tctx
, &domain_handle
, TEST_ALIASNAME
, &alias_handle
, sid
, true);
8760 ret
&= test_CreateDomainGroup(b
, tctx
, &domain_handle
, TEST_GROUPNAME
, &group_handle
, sid
, true);
8761 ret
&= test_GetAliasMembership(b
, tctx
, &domain_handle
);
8762 ret
&= test_QueryDomainInfo(p
, tctx
, &domain_handle
);
8763 ret
&= test_QueryDomainInfo2(b
, tctx
, &domain_handle
);
8764 ret
&= test_EnumDomainUsers_all(b
, tctx
, &domain_handle
);
8765 ret
&= test_EnumDomainUsers_async(p
, tctx
, &domain_handle
);
8766 ret
&= test_EnumDomainGroups_all(b
, tctx
, &domain_handle
);
8767 ret
&= test_EnumDomainAliases_all(b
, tctx
, &domain_handle
);
8768 ret
&= test_QueryDisplayInfo2(b
, tctx
, &domain_handle
);
8769 ret
&= test_QueryDisplayInfo3(b
, tctx
, &domain_handle
);
8770 ret
&= test_QueryDisplayInfo_continue(b
, tctx
, &domain_handle
);
8772 if (torture_setting_bool(tctx
, "samba4", false)) {
8773 torture_comment(tctx
, "skipping GetDisplayEnumerationIndex test against Samba4\n");
8775 ret
&= test_GetDisplayEnumerationIndex(b
, tctx
, &domain_handle
);
8776 ret
&= test_GetDisplayEnumerationIndex2(b
, tctx
, &domain_handle
);
8778 ret
&= test_GroupList(b
, tctx
, sid
, &domain_handle
);
8779 ret
&= test_TestPrivateFunctionsDomain(b
, tctx
, &domain_handle
);
8780 ret
&= test_RidToSid(b
, tctx
, sid
, &domain_handle
);
8781 ret
&= test_GetBootKeyInformation(b
, tctx
, &domain_handle
);
8783 torture_comment(tctx
, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx
, sid
));
8788 if (!ndr_policy_handle_empty(&user_handle
) &&
8789 !test_DeleteUser(b
, tctx
, &user_handle
)) {
8793 if (!ndr_policy_handle_empty(&alias_handle
) &&
8794 !test_DeleteAlias(b
, tctx
, &alias_handle
)) {
8798 if (!ndr_policy_handle_empty(&group_handle
) &&
8799 !test_DeleteDomainGroup(b
, tctx
, &group_handle
)) {
8803 torture_assert(tctx
, test_samr_handle_Close(b
, tctx
, &domain_handle
), "Failed to close SAMR domain handle");
8805 torture_assert(tctx
, test_Connect(b
, tctx
, &ctx
->handle
), "Failed to re-connect SAMR handle");
8806 /* reconnect the main handle */
8809 torture_result(tctx
, TORTURE_FAIL
, "Testing domain %s failed!\n", dom_sid_string(tctx
, sid
));
8815 static bool test_LookupDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
8816 struct torture_samr_context
*ctx
, const char *domain
)
8818 struct samr_LookupDomain r
;
8819 struct dom_sid2
*sid
= NULL
;
8820 struct lsa_String n1
;
8821 struct lsa_String n2
;
8823 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
8825 torture_comment(tctx
, "Testing LookupDomain(%s)\n", domain
);
8827 /* check for correct error codes */
8828 r
.in
.connect_handle
= &ctx
->handle
;
8829 r
.in
.domain_name
= &n2
;
8833 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupDomain_r(b
, tctx
, &r
),
8834 "LookupDomain failed");
8835 torture_assert_ntstatus_equal(tctx
, NT_STATUS_INVALID_PARAMETER
, r
.out
.result
, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
8837 init_lsa_String(&n2
, "xxNODOMAINxx");
8839 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupDomain_r(b
, tctx
, &r
),
8840 "LookupDomain failed");
8841 torture_assert_ntstatus_equal(tctx
, NT_STATUS_NO_SUCH_DOMAIN
, r
.out
.result
, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
8843 r
.in
.connect_handle
= &ctx
->handle
;
8845 init_lsa_String(&n1
, domain
);
8846 r
.in
.domain_name
= &n1
;
8848 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_LookupDomain_r(b
, tctx
, &r
),
8849 "LookupDomain failed");
8850 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LookupDomain");
8852 if (!test_GetDomPwInfo(p
, tctx
, &n1
)) {
8856 if (!test_OpenDomain(p
, tctx
, ctx
, *r
.out
.sid
)) {
8864 static bool test_EnumDomains(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
8865 struct torture_samr_context
*ctx
)
8867 struct samr_EnumDomains r
;
8868 uint32_t resume_handle
= 0;
8869 uint32_t num_entries
= 0;
8870 struct samr_SamArray
*sam
= NULL
;
8873 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
8875 r
.in
.connect_handle
= &ctx
->handle
;
8876 r
.in
.resume_handle
= &resume_handle
;
8877 r
.in
.buf_size
= (uint32_t)-1;
8878 r
.out
.resume_handle
= &resume_handle
;
8879 r
.out
.num_entries
= &num_entries
;
8882 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomains_r(b
, tctx
, &r
),
8883 "EnumDomains failed");
8884 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "EnumDomains failed");
8890 for (i
=0;i
<sam
->count
;i
++) {
8891 if (!test_LookupDomain(p
, tctx
, ctx
,
8892 sam
->entries
[i
].name
.string
)) {
8897 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_EnumDomains_r(b
, tctx
, &r
),
8898 "EnumDomains failed");
8899 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "EnumDomains failed");
8905 static bool test_Connect(struct dcerpc_binding_handle
*b
,
8906 struct torture_context
*tctx
,
8907 struct policy_handle
*handle
)
8909 struct samr_Connect r
;
8910 struct samr_Connect2 r2
;
8911 struct samr_Connect3 r3
;
8912 struct samr_Connect4 r4
;
8913 struct samr_Connect5 r5
;
8914 union samr_ConnectInfo info
;
8915 struct policy_handle h
;
8916 uint32_t level_out
= 0;
8917 bool ret
= true, got_handle
= false;
8919 torture_comment(tctx
, "Testing samr_Connect\n");
8921 r
.in
.system_name
= NULL
;
8922 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
8923 r
.out
.connect_handle
= &h
;
8925 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect_r(b
, tctx
, &r
),
8927 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
8928 torture_comment(tctx
, "Connect failed - %s\n", nt_errstr(r
.out
.result
));
8935 torture_comment(tctx
, "Testing samr_Connect2\n");
8937 r2
.in
.system_name
= NULL
;
8938 r2
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
8939 r2
.out
.connect_handle
= &h
;
8941 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect2_r(b
, tctx
, &r2
),
8943 if (!NT_STATUS_IS_OK(r2
.out
.result
)) {
8944 torture_comment(tctx
, "Connect2 failed - %s\n", nt_errstr(r2
.out
.result
));
8948 test_samr_handle_Close(b
, tctx
, handle
);
8954 torture_comment(tctx
, "Testing samr_Connect3\n");
8956 r3
.in
.system_name
= NULL
;
8958 r3
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
8959 r3
.out
.connect_handle
= &h
;
8961 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect3_r(b
, tctx
, &r3
),
8963 if (!NT_STATUS_IS_OK(r3
.out
.result
)) {
8964 torture_result(tctx
, TORTURE_FAIL
, "Connect3 failed - %s\n", nt_errstr(r3
.out
.result
));
8968 test_samr_handle_Close(b
, tctx
, handle
);
8974 torture_comment(tctx
, "Testing samr_Connect4\n");
8976 r4
.in
.system_name
= "";
8977 r4
.in
.client_version
= 0;
8978 r4
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
8979 r4
.out
.connect_handle
= &h
;
8981 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect4_r(b
, tctx
, &r4
),
8983 if (!NT_STATUS_IS_OK(r4
.out
.result
)) {
8984 torture_result(tctx
, TORTURE_FAIL
, "Connect4 failed - %s\n", nt_errstr(r4
.out
.result
));
8988 test_samr_handle_Close(b
, tctx
, handle
);
8994 torture_comment(tctx
, "Testing samr_Connect5\n");
8996 info
.info1
.client_version
= 0;
8997 info
.info1
.supported_features
= 0;
8999 r5
.in
.system_name
= "";
9000 r5
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
9002 r5
.out
.level_out
= &level_out
;
9003 r5
.in
.info_in
= &info
;
9004 r5
.out
.info_out
= &info
;
9005 r5
.out
.connect_handle
= &h
;
9007 torture_assert_ntstatus_ok(tctx
, dcerpc_samr_Connect5_r(b
, tctx
, &r5
),
9009 if (!NT_STATUS_IS_OK(r5
.out
.result
)) {
9010 torture_result(tctx
, TORTURE_FAIL
, "Connect5 failed - %s\n", nt_errstr(r5
.out
.result
));
9014 test_samr_handle_Close(b
, tctx
, handle
);
9024 static bool test_samr_ValidatePassword(struct torture_context
*tctx
,
9025 struct dcerpc_pipe
*p
)
9027 struct samr_ValidatePassword r
;
9028 union samr_ValidatePasswordReq req
;
9029 union samr_ValidatePasswordRep
*repp
= NULL
;
9031 const char *passwords
[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL
};
9033 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
9035 torture_comment(tctx
, "Testing samr_ValidatePassword\n");
9037 if (dcerpc_binding_handle_get_transport(b
) != NCACN_IP_TCP
) {
9038 torture_comment(tctx
, "samr_ValidatePassword only should succeed over NCACN_IP_TCP!\n");
9042 r
.in
.level
= NetValidatePasswordReset
;
9047 req
.req3
.account
.string
= "non-existent-account-aklsdji";
9049 for (i
=0; passwords
[i
]; i
++) {
9050 req
.req3
.password
.string
= passwords
[i
];
9052 status
= dcerpc_samr_ValidatePassword_r(b
, tctx
, &r
);
9053 if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE
)) {
9054 torture_skip(tctx
, "ValidatePassword not supported by server\n");
9056 torture_assert_ntstatus_ok(tctx
, status
,
9057 "samr_ValidatePassword failed");
9058 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
9059 "samr_ValidatePassword failed");
9060 torture_comment(tctx
, "Server %s password '%s' with code %i\n",
9061 repp
->ctr3
.status
==SAMR_VALIDATION_STATUS_SUCCESS
?"allowed":"refused",
9062 req
.req3
.password
.string
, repp
->ctr3
.status
);
9068 bool torture_rpc_samr(struct torture_context
*torture
)
9071 struct dcerpc_pipe
*p
;
9073 struct torture_samr_context
*ctx
;
9074 struct dcerpc_binding_handle
*b
;
9076 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
9077 if (!NT_STATUS_IS_OK(status
)) {
9080 b
= p
->binding_handle
;
9082 ctx
= talloc_zero(torture
, struct torture_samr_context
);
9084 ctx
->choice
= TORTURE_SAMR_OTHER
;
9086 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
9088 if (!torture_setting_bool(torture
, "samba3", false)) {
9089 ret
&= test_QuerySecurity(b
, torture
, &ctx
->handle
);
9092 ret
&= test_EnumDomains(p
, torture
, ctx
);
9094 ret
&= test_SetDsrmPassword(b
, torture
, &ctx
->handle
);
9096 ret
&= test_Shutdown(b
, torture
, &ctx
->handle
);
9098 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
9104 bool torture_rpc_samr_users(struct torture_context
*torture
)
9107 struct dcerpc_pipe
*p
;
9109 struct torture_samr_context
*ctx
;
9110 struct dcerpc_binding_handle
*b
;
9112 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
9113 if (!NT_STATUS_IS_OK(status
)) {
9116 b
= p
->binding_handle
;
9118 ctx
= talloc_zero(torture
, struct torture_samr_context
);
9120 ctx
->choice
= TORTURE_SAMR_USER_ATTRIBUTES
;
9122 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
9124 if (!torture_setting_bool(torture
, "samba3", false)) {
9125 ret
&= test_QuerySecurity(b
, torture
, &ctx
->handle
);
9128 ret
&= test_EnumDomains(p
, torture
, ctx
);
9130 ret
&= test_SetDsrmPassword(b
, torture
, &ctx
->handle
);
9132 ret
&= test_Shutdown(b
, torture
, &ctx
->handle
);
9134 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
9140 bool torture_rpc_samr_passwords(struct torture_context
*torture
)
9143 struct dcerpc_pipe
*p
;
9145 struct torture_samr_context
*ctx
;
9146 struct dcerpc_binding_handle
*b
;
9148 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
9149 if (!NT_STATUS_IS_OK(status
)) {
9152 b
= p
->binding_handle
;
9154 ctx
= talloc_zero(torture
, struct torture_samr_context
);
9156 ctx
->choice
= TORTURE_SAMR_PASSWORDS
;
9158 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
9160 ret
&= test_EnumDomains(p
, torture
, ctx
);
9162 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
9167 static bool torture_rpc_samr_pwdlastset(struct torture_context
*torture
,
9168 struct dcerpc_pipe
*p2
,
9169 struct cli_credentials
*machine_credentials
)
9172 struct dcerpc_pipe
*p
;
9174 struct torture_samr_context
*ctx
;
9175 struct dcerpc_binding_handle
*b
;
9177 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
9178 if (!NT_STATUS_IS_OK(status
)) {
9181 b
= p
->binding_handle
;
9183 ctx
= talloc_zero(torture
, struct torture_samr_context
);
9185 ctx
->choice
= TORTURE_SAMR_PASSWORDS_PWDLASTSET
;
9186 ctx
->machine_credentials
= machine_credentials
;
9188 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
9190 ret
&= test_EnumDomains(p
, torture
, ctx
);
9192 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
9197 struct torture_suite
*torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX
*mem_ctx
)
9199 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.passwords.pwdlastset");
9200 struct torture_rpc_tcase
*tcase
;
9202 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
9204 TEST_ACCOUNT_NAME_PWD
);
9206 torture_rpc_tcase_add_test_creds(tcase
, "pwdLastSet",
9207 torture_rpc_samr_pwdlastset
);
9212 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context
*torture
,
9213 struct dcerpc_pipe
*p2
,
9214 struct cli_credentials
*machine_credentials
)
9217 struct dcerpc_pipe
*p
;
9219 struct torture_samr_context
*ctx
;
9220 struct dcerpc_binding_handle
*b
;
9222 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
9223 if (!NT_STATUS_IS_OK(status
)) {
9226 b
= p
->binding_handle
;
9228 ctx
= talloc_zero(torture
, struct torture_samr_context
);
9230 ctx
->choice
= TORTURE_SAMR_USER_PRIVILEGES
;
9231 ctx
->machine_credentials
= machine_credentials
;
9233 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
9235 ret
&= test_EnumDomains(p
, torture
, ctx
);
9237 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
9242 struct torture_suite
*torture_rpc_samr_user_privileges(TALLOC_CTX
*mem_ctx
)
9244 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.users.privileges");
9245 struct torture_rpc_tcase
*tcase
;
9247 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
9249 TEST_ACCOUNT_NAME_PWD
);
9251 torture_rpc_tcase_add_test_creds(tcase
, "delete_privileged_user",
9252 torture_rpc_samr_users_privileges_delete_user
);
9257 static bool torture_rpc_samr_many_accounts(struct torture_context
*torture
,
9258 struct dcerpc_pipe
*p2
,
9262 struct dcerpc_pipe
*p
;
9264 struct torture_samr_context
*ctx
=
9265 talloc_get_type_abort(data
, struct torture_samr_context
);
9266 struct dcerpc_binding_handle
*b
;
9268 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
9269 if (!NT_STATUS_IS_OK(status
)) {
9272 b
= p
->binding_handle
;
9274 ctx
->choice
= TORTURE_SAMR_MANY_ACCOUNTS
;
9275 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
9276 ctx
->num_objects_large_dc
);
9278 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
9280 ret
&= test_EnumDomains(p
, torture
, ctx
);
9282 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
9287 static bool torture_rpc_samr_many_groups(struct torture_context
*torture
,
9288 struct dcerpc_pipe
*p2
,
9292 struct dcerpc_pipe
*p
;
9294 struct torture_samr_context
*ctx
=
9295 talloc_get_type_abort(data
, struct torture_samr_context
);
9296 struct dcerpc_binding_handle
*b
;
9298 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
9299 if (!NT_STATUS_IS_OK(status
)) {
9302 b
= p
->binding_handle
;
9304 ctx
->choice
= TORTURE_SAMR_MANY_GROUPS
;
9305 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
9306 ctx
->num_objects_large_dc
);
9308 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
9310 ret
&= test_EnumDomains(p
, torture
, ctx
);
9312 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
9317 static bool torture_rpc_samr_many_aliases(struct torture_context
*torture
,
9318 struct dcerpc_pipe
*p2
,
9322 struct dcerpc_pipe
*p
;
9324 struct torture_samr_context
*ctx
=
9325 talloc_get_type_abort(data
, struct torture_samr_context
);
9326 struct dcerpc_binding_handle
*b
;
9328 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
9329 if (!NT_STATUS_IS_OK(status
)) {
9332 b
= p
->binding_handle
;
9334 ctx
->choice
= TORTURE_SAMR_MANY_ALIASES
;
9335 ctx
->num_objects_large_dc
= torture_setting_int(torture
, "large_dc",
9336 ctx
->num_objects_large_dc
);
9338 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
9340 ret
&= test_EnumDomains(p
, torture
, ctx
);
9342 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
9347 struct torture_suite
*torture_rpc_samr_large_dc(TALLOC_CTX
*mem_ctx
)
9349 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.large-dc");
9350 struct torture_rpc_tcase
*tcase
;
9351 struct torture_samr_context
*ctx
;
9353 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "samr", &ndr_table_samr
);
9355 ctx
= talloc_zero(suite
, struct torture_samr_context
);
9356 ctx
->num_objects_large_dc
= 150;
9358 torture_rpc_tcase_add_test_ex(tcase
, "many_aliases",
9359 torture_rpc_samr_many_aliases
, ctx
);
9360 torture_rpc_tcase_add_test_ex(tcase
, "many_groups",
9361 torture_rpc_samr_many_groups
, ctx
);
9362 torture_rpc_tcase_add_test_ex(tcase
, "many_accounts",
9363 torture_rpc_samr_many_accounts
, ctx
);
9368 static bool torture_rpc_samr_badpwdcount(struct torture_context
*torture
,
9369 struct dcerpc_pipe
*p2
,
9370 struct cli_credentials
*machine_credentials
)
9373 struct dcerpc_pipe
*p
;
9375 struct torture_samr_context
*ctx
;
9376 struct dcerpc_binding_handle
*b
;
9378 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
9379 if (!NT_STATUS_IS_OK(status
)) {
9382 b
= p
->binding_handle
;
9384 ctx
= talloc_zero(torture
, struct torture_samr_context
);
9386 ctx
->choice
= TORTURE_SAMR_PASSWORDS_BADPWDCOUNT
;
9387 ctx
->machine_credentials
= machine_credentials
;
9389 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
9391 ret
&= test_EnumDomains(p
, torture
, ctx
);
9393 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
9398 struct torture_suite
*torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX
*mem_ctx
)
9400 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.passwords.badpwdcount");
9401 struct torture_rpc_tcase
*tcase
;
9403 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
9405 TEST_ACCOUNT_NAME_PWD
);
9407 torture_rpc_tcase_add_test_creds(tcase
, "badPwdCount",
9408 torture_rpc_samr_badpwdcount
);
9413 static bool torture_rpc_samr_lockout(struct torture_context
*torture
,
9414 struct dcerpc_pipe
*p2
,
9415 struct cli_credentials
*machine_credentials
)
9418 struct dcerpc_pipe
*p
;
9420 struct torture_samr_context
*ctx
;
9421 struct dcerpc_binding_handle
*b
;
9423 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
9424 if (!NT_STATUS_IS_OK(status
)) {
9427 b
= p
->binding_handle
;
9429 ctx
= talloc_zero(torture
, struct torture_samr_context
);
9431 ctx
->choice
= TORTURE_SAMR_PASSWORDS_LOCKOUT
;
9432 ctx
->machine_credentials
= machine_credentials
;
9434 ret
&= test_Connect(b
, torture
, &ctx
->handle
);
9436 ret
&= test_EnumDomains(p
, torture
, ctx
);
9438 ret
&= test_samr_handle_Close(b
, torture
, &ctx
->handle
);
9443 struct torture_suite
*torture_rpc_samr_passwords_lockout(TALLOC_CTX
*mem_ctx
)
9445 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.passwords.lockout");
9446 struct torture_rpc_tcase
*tcase
;
9448 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
, "samr",
9450 TEST_ACCOUNT_NAME_PWD
);
9452 torture_rpc_tcase_add_test_creds(tcase
, "lockout",
9453 torture_rpc_samr_lockout
);
9458 struct torture_suite
*torture_rpc_samr_passwords_validate(TALLOC_CTX
*mem_ctx
)
9460 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "samr.passwords.validate");
9461 struct torture_rpc_tcase
*tcase
;
9463 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "samr",
9465 torture_rpc_tcase_add_test(tcase
, "validate",
9466 test_samr_ValidatePassword
);