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
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "torture/torture.h"
24 #include "system/time.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_samr_c.h"
27 #include "../lib/crypto/crypto.h"
28 #include "libcli/auth/libcli_auth.h"
29 #include "libcli/security/security.h"
30 #include "torture/rpc/rpc.h"
32 #define TEST_ACCOUNT_NAME "samrtorturetest"
33 #define TEST_ALIASNAME "samrtorturetestalias"
34 #define TEST_GROUPNAME "samrtorturetestgroup"
35 #define TEST_MACHINENAME "samrtestmach$"
36 #define TEST_DOMAINNAME "samrtestdom$"
38 enum torture_samr_choice
{
39 TORTURE_SAMR_PASSWORDS
,
40 TORTURE_SAMR_USER_ATTRIBUTES
,
44 static bool test_QueryUserInfo(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
45 struct policy_handle
*handle
);
47 static bool test_QueryUserInfo2(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
48 struct policy_handle
*handle
);
50 static bool test_QueryAliasInfo(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
51 struct policy_handle
*handle
);
53 static bool test_ChangePassword(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
54 const char *acct_name
,
55 struct policy_handle
*domain_handle
, char **password
);
57 static void init_lsa_String(struct lsa_String
*string
, const char *s
)
62 static void init_lsa_BinaryString(struct lsa_BinaryString
*string
, const char *s
, uint32_t length
)
64 string
->length
= length
;
65 string
->size
= length
;
66 string
->array
= (uint16_t *)discard_const(s
);
69 bool test_samr_handle_Close(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
70 struct policy_handle
*handle
)
76 r
.out
.handle
= handle
;
78 status
= dcerpc_samr_Close(p
, tctx
, &r
);
79 torture_assert_ntstatus_ok(tctx
, status
, "Close");
84 static bool test_Shutdown(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
85 struct policy_handle
*handle
)
88 struct samr_Shutdown r
;
90 if (!torture_setting_bool(tctx
, "dangerous", false)) {
91 torture_skip(tctx
, "samr_Shutdown disabled - enable dangerous tests to use\n");
95 r
.in
.connect_handle
= handle
;
97 torture_comment(tctx
, "testing samr_Shutdown\n");
99 status
= dcerpc_samr_Shutdown(p
, tctx
, &r
);
100 torture_assert_ntstatus_ok(tctx
, status
, "samr_Shutdown");
105 static bool test_SetDsrmPassword(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
106 struct policy_handle
*handle
)
109 struct samr_SetDsrmPassword r
;
110 struct lsa_String string
;
111 struct samr_Password hash
;
113 if (!torture_setting_bool(tctx
, "dangerous", false)) {
114 torture_skip(tctx
, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
117 E_md4hash("TeSTDSRM123", hash
.hash
);
119 init_lsa_String(&string
, "Administrator");
125 torture_comment(tctx
, "testing samr_SetDsrmPassword\n");
127 status
= dcerpc_samr_SetDsrmPassword(p
, tctx
, &r
);
128 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_NOT_SUPPORTED
, "samr_SetDsrmPassword");
134 static bool test_QuerySecurity(struct dcerpc_pipe
*p
,
135 struct torture_context
*tctx
,
136 struct policy_handle
*handle
)
139 struct samr_QuerySecurity r
;
140 struct samr_SetSecurity s
;
141 struct sec_desc_buf
*sdbuf
= NULL
;
143 r
.in
.handle
= handle
;
145 r
.out
.sdbuf
= &sdbuf
;
147 status
= dcerpc_samr_QuerySecurity(p
, tctx
, &r
);
148 torture_assert_ntstatus_ok(tctx
, status
, "QuerySecurity");
150 torture_assert(tctx
, sdbuf
!= NULL
, "sdbuf is NULL");
152 s
.in
.handle
= handle
;
156 if (torture_setting_bool(tctx
, "samba4", false)) {
157 torture_skip(tctx
, "skipping SetSecurity test against Samba4\n");
160 status
= dcerpc_samr_SetSecurity(p
, tctx
, &s
);
161 torture_assert_ntstatus_ok(tctx
, status
, "SetSecurity");
163 status
= dcerpc_samr_QuerySecurity(p
, tctx
, &r
);
164 torture_assert_ntstatus_ok(tctx
, status
, "QuerySecurity");
170 static bool test_SetUserInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
171 struct policy_handle
*handle
, uint32_t base_acct_flags
,
172 const char *base_account_name
)
175 struct samr_SetUserInfo s
;
176 struct samr_SetUserInfo2 s2
;
177 struct samr_QueryUserInfo q
;
178 struct samr_QueryUserInfo q0
;
179 union samr_UserInfo u
;
181 const char *test_account_name
;
183 uint32_t user_extra_flags
= 0;
184 if (base_acct_flags
== ACB_NORMAL
) {
185 /* When created, accounts are expired by default */
186 user_extra_flags
= ACB_PW_EXPIRED
;
189 s
.in
.user_handle
= handle
;
192 s2
.in
.user_handle
= handle
;
195 q
.in
.user_handle
= handle
;
199 #define TESTCALL(call, r) \
200 status = dcerpc_samr_ ##call(p, tctx, &r); \
201 if (!NT_STATUS_IS_OK(status)) { \
202 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
203 r.in.level, nt_errstr(status), __location__); \
208 #define STRING_EQUAL(s1, s2, field) \
209 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
210 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
211 #field, s2, __location__); \
216 #define MEM_EQUAL(s1, s2, length, field) \
217 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
218 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
219 #field, (const char *)s2, __location__); \
224 #define INT_EQUAL(i1, i2, field) \
226 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
227 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
232 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
233 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
235 TESTCALL(QueryUserInfo, q) \
237 s2.in.level = lvl1; \
240 ZERO_STRUCT(u.info21); \
241 u.info21.fields_present = fpval; \
243 init_lsa_String(&u.info ## lvl1.field1, value); \
244 TESTCALL(SetUserInfo, s) \
245 TESTCALL(SetUserInfo2, s2) \
246 init_lsa_String(&u.info ## lvl1.field1, ""); \
247 TESTCALL(QueryUserInfo, q); \
249 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
251 TESTCALL(QueryUserInfo, q) \
253 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
256 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
257 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
259 TESTCALL(QueryUserInfo, q) \
261 s2.in.level = lvl1; \
264 ZERO_STRUCT(u.info21); \
265 u.info21.fields_present = fpval; \
267 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
268 TESTCALL(SetUserInfo, s) \
269 TESTCALL(SetUserInfo2, s2) \
270 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
271 TESTCALL(QueryUserInfo, q); \
273 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
275 TESTCALL(QueryUserInfo, q) \
277 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
280 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
281 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
283 TESTCALL(QueryUserInfo, q) \
285 s2.in.level = lvl1; \
288 uint8_t *bits = u.info21.logon_hours.bits; \
289 ZERO_STRUCT(u.info21); \
290 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
291 u.info21.logon_hours.units_per_week = 168; \
292 u.info21.logon_hours.bits = bits; \
294 u.info21.fields_present = fpval; \
296 u.info ## lvl1.field1 = value; \
297 TESTCALL(SetUserInfo, s) \
298 TESTCALL(SetUserInfo2, s2) \
299 u.info ## lvl1.field1 = 0; \
300 TESTCALL(QueryUserInfo, q); \
302 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
304 TESTCALL(QueryUserInfo, q) \
306 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
309 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
310 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
314 do { TESTCALL(QueryUserInfo
, q0
) } while (0);
316 TEST_USERINFO_STRING(2, comment
, 1, comment
, "xx2-1 comment", 0);
317 TEST_USERINFO_STRING(2, comment
, 21, comment
, "xx2-21 comment", 0);
318 TEST_USERINFO_STRING(21, comment
, 21, comment
, "xx21-21 comment",
321 test_account_name
= talloc_asprintf(tctx
, "%sxx7-1", base_account_name
);
322 TEST_USERINFO_STRING(7, account_name
, 1, account_name
, base_account_name
, 0);
323 test_account_name
= talloc_asprintf(tctx
, "%sxx7-3", base_account_name
);
324 TEST_USERINFO_STRING(7, account_name
, 3, account_name
, base_account_name
, 0);
325 test_account_name
= talloc_asprintf(tctx
, "%sxx7-5", base_account_name
);
326 TEST_USERINFO_STRING(7, account_name
, 5, account_name
, base_account_name
, 0);
327 test_account_name
= talloc_asprintf(tctx
, "%sxx7-6", base_account_name
);
328 TEST_USERINFO_STRING(7, account_name
, 6, account_name
, base_account_name
, 0);
329 test_account_name
= talloc_asprintf(tctx
, "%sxx7-7", base_account_name
);
330 TEST_USERINFO_STRING(7, account_name
, 7, account_name
, base_account_name
, 0);
331 test_account_name
= talloc_asprintf(tctx
, "%sxx7-21", base_account_name
);
332 TEST_USERINFO_STRING(7, account_name
, 21, account_name
, base_account_name
, 0);
333 test_account_name
= base_account_name
;
334 TEST_USERINFO_STRING(21, account_name
, 21, account_name
, base_account_name
,
335 SAMR_FIELD_ACCOUNT_NAME
);
337 TEST_USERINFO_STRING(6, full_name
, 1, full_name
, "xx6-1 full_name", 0);
338 TEST_USERINFO_STRING(6, full_name
, 3, full_name
, "xx6-3 full_name", 0);
339 TEST_USERINFO_STRING(6, full_name
, 5, full_name
, "xx6-5 full_name", 0);
340 TEST_USERINFO_STRING(6, full_name
, 6, full_name
, "xx6-6 full_name", 0);
341 TEST_USERINFO_STRING(6, full_name
, 8, full_name
, "xx6-8 full_name", 0);
342 TEST_USERINFO_STRING(6, full_name
, 21, full_name
, "xx6-21 full_name", 0);
343 TEST_USERINFO_STRING(8, full_name
, 21, full_name
, "xx8-21 full_name", 0);
344 TEST_USERINFO_STRING(21, full_name
, 21, full_name
, "xx21-21 full_name",
345 SAMR_FIELD_FULL_NAME
);
347 TEST_USERINFO_STRING(6, full_name
, 1, full_name
, "", 0);
348 TEST_USERINFO_STRING(6, full_name
, 3, full_name
, "", 0);
349 TEST_USERINFO_STRING(6, full_name
, 5, full_name
, "", 0);
350 TEST_USERINFO_STRING(6, full_name
, 6, full_name
, "", 0);
351 TEST_USERINFO_STRING(6, full_name
, 8, full_name
, "", 0);
352 TEST_USERINFO_STRING(6, full_name
, 21, full_name
, "", 0);
353 TEST_USERINFO_STRING(8, full_name
, 21, full_name
, "", 0);
354 TEST_USERINFO_STRING(21, full_name
, 21, full_name
, "",
355 SAMR_FIELD_FULL_NAME
);
357 TEST_USERINFO_STRING(11, logon_script
, 3, logon_script
, "xx11-3 logon_script", 0);
358 TEST_USERINFO_STRING(11, logon_script
, 5, logon_script
, "xx11-5 logon_script", 0);
359 TEST_USERINFO_STRING(11, logon_script
, 21, logon_script
, "xx11-21 logon_script", 0);
360 TEST_USERINFO_STRING(21, logon_script
, 21, logon_script
, "xx21-21 logon_script",
361 SAMR_FIELD_LOGON_SCRIPT
);
363 TEST_USERINFO_STRING(12, profile_path
, 3, profile_path
, "xx12-3 profile_path", 0);
364 TEST_USERINFO_STRING(12, profile_path
, 5, profile_path
, "xx12-5 profile_path", 0);
365 TEST_USERINFO_STRING(12, profile_path
, 21, profile_path
, "xx12-21 profile_path", 0);
366 TEST_USERINFO_STRING(21, profile_path
, 21, profile_path
, "xx21-21 profile_path",
367 SAMR_FIELD_PROFILE_PATH
);
369 TEST_USERINFO_STRING(10, home_directory
, 3, home_directory
, "xx10-3 home_directory", 0);
370 TEST_USERINFO_STRING(10, home_directory
, 5, home_directory
, "xx10-5 home_directory", 0);
371 TEST_USERINFO_STRING(10, home_directory
, 21, home_directory
, "xx10-21 home_directory", 0);
372 TEST_USERINFO_STRING(21, home_directory
, 21, home_directory
, "xx21-21 home_directory",
373 SAMR_FIELD_HOME_DIRECTORY
);
374 TEST_USERINFO_STRING(21, home_directory
, 10, home_directory
, "xx21-10 home_directory",
375 SAMR_FIELD_HOME_DIRECTORY
);
377 TEST_USERINFO_STRING(10, home_drive
, 3, home_drive
, "xx10-3 home_drive", 0);
378 TEST_USERINFO_STRING(10, home_drive
, 5, home_drive
, "xx10-5 home_drive", 0);
379 TEST_USERINFO_STRING(10, home_drive
, 21, home_drive
, "xx10-21 home_drive", 0);
380 TEST_USERINFO_STRING(21, home_drive
, 21, home_drive
, "xx21-21 home_drive",
381 SAMR_FIELD_HOME_DRIVE
);
382 TEST_USERINFO_STRING(21, home_drive
, 10, home_drive
, "xx21-10 home_drive",
383 SAMR_FIELD_HOME_DRIVE
);
385 TEST_USERINFO_STRING(13, description
, 1, description
, "xx13-1 description", 0);
386 TEST_USERINFO_STRING(13, description
, 5, description
, "xx13-5 description", 0);
387 TEST_USERINFO_STRING(13, description
, 21, description
, "xx13-21 description", 0);
388 TEST_USERINFO_STRING(21, description
, 21, description
, "xx21-21 description",
389 SAMR_FIELD_DESCRIPTION
);
391 TEST_USERINFO_STRING(14, workstations
, 3, workstations
, "14workstation3", 0);
392 TEST_USERINFO_STRING(14, workstations
, 5, workstations
, "14workstation4", 0);
393 TEST_USERINFO_STRING(14, workstations
, 21, workstations
, "14workstation21", 0);
394 TEST_USERINFO_STRING(21, workstations
, 21, workstations
, "21workstation21",
395 SAMR_FIELD_WORKSTATIONS
);
396 TEST_USERINFO_STRING(21, workstations
, 3, workstations
, "21workstation3",
397 SAMR_FIELD_WORKSTATIONS
);
398 TEST_USERINFO_STRING(21, workstations
, 5, workstations
, "21workstation5",
399 SAMR_FIELD_WORKSTATIONS
);
400 TEST_USERINFO_STRING(21, workstations
, 14, workstations
, "21workstation14",
401 SAMR_FIELD_WORKSTATIONS
);
403 TEST_USERINFO_BINARYSTRING(20, parameters
, 21, parameters
, "xx20-21 parameters", 0);
404 TEST_USERINFO_BINARYSTRING(21, parameters
, 21, parameters
, "xx21-21 parameters",
405 SAMR_FIELD_PARAMETERS
);
406 TEST_USERINFO_BINARYSTRING(21, parameters
, 20, parameters
, "xx21-20 parameters",
407 SAMR_FIELD_PARAMETERS
);
409 TEST_USERINFO_INT(2, country_code
, 2, country_code
, __LINE__
, 0);
410 TEST_USERINFO_INT(2, country_code
, 21, country_code
, __LINE__
, 0);
411 TEST_USERINFO_INT(21, country_code
, 21, country_code
, __LINE__
,
412 SAMR_FIELD_COUNTRY_CODE
);
413 TEST_USERINFO_INT(21, country_code
, 2, country_code
, __LINE__
,
414 SAMR_FIELD_COUNTRY_CODE
);
416 TEST_USERINFO_INT(2, code_page
, 21, code_page
, __LINE__
, 0);
417 TEST_USERINFO_INT(21, code_page
, 21, code_page
, __LINE__
,
418 SAMR_FIELD_CODE_PAGE
);
419 TEST_USERINFO_INT(21, code_page
, 2, code_page
, __LINE__
,
420 SAMR_FIELD_CODE_PAGE
);
422 TEST_USERINFO_INT(17, acct_expiry
, 21, acct_expiry
, __LINE__
, 0);
423 TEST_USERINFO_INT(17, acct_expiry
, 5, acct_expiry
, __LINE__
, 0);
424 TEST_USERINFO_INT(21, acct_expiry
, 21, acct_expiry
, __LINE__
,
425 SAMR_FIELD_ACCT_EXPIRY
);
426 TEST_USERINFO_INT(21, acct_expiry
, 5, acct_expiry
, __LINE__
,
427 SAMR_FIELD_ACCT_EXPIRY
);
428 TEST_USERINFO_INT(21, acct_expiry
, 17, acct_expiry
, __LINE__
,
429 SAMR_FIELD_ACCT_EXPIRY
);
431 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 3, logon_hours
.bits
[3], 1, 0);
432 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 5, logon_hours
.bits
[3], 2, 0);
433 TEST_USERINFO_INT(4, logon_hours
.bits
[3], 21, logon_hours
.bits
[3], 3, 0);
434 TEST_USERINFO_INT(21, logon_hours
.bits
[3], 21, logon_hours
.bits
[3], 4,
435 SAMR_FIELD_LOGON_HOURS
);
437 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
438 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
),
439 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
| user_extra_flags
),
441 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
442 (base_acct_flags
| ACB_DISABLED
),
443 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
446 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
447 TEST_USERINFO_INT_EXP(16, acct_flags
, 5, acct_flags
,
448 (base_acct_flags
| ACB_DISABLED
| ACB_PWNOEXP
),
449 (base_acct_flags
| ACB_DISABLED
| ACB_PWNOEXP
),
451 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
452 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
),
453 (base_acct_flags
| ACB_DISABLED
| ACB_HOMDIRREQ
| user_extra_flags
),
457 /* The 'autolock' flag doesn't stick - check this */
458 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
459 (base_acct_flags
| ACB_DISABLED
| ACB_AUTOLOCK
),
460 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
463 /* Removing the 'disabled' flag doesn't stick - check this */
464 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
466 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
469 /* The 'store plaintext' flag does stick */
470 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
471 (base_acct_flags
| ACB_DISABLED
| ACB_ENC_TXT_PWD_ALLOWED
),
472 (base_acct_flags
| ACB_DISABLED
| ACB_ENC_TXT_PWD_ALLOWED
| user_extra_flags
),
474 /* The 'use DES' flag does stick */
475 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
476 (base_acct_flags
| ACB_DISABLED
| ACB_USE_DES_KEY_ONLY
),
477 (base_acct_flags
| ACB_DISABLED
| ACB_USE_DES_KEY_ONLY
| user_extra_flags
),
479 /* The 'don't require kerberos pre-authentication flag does stick */
480 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
481 (base_acct_flags
| ACB_DISABLED
| ACB_DONT_REQUIRE_PREAUTH
),
482 (base_acct_flags
| ACB_DISABLED
| ACB_DONT_REQUIRE_PREAUTH
| user_extra_flags
),
484 /* The 'no kerberos PAC required' flag sticks */
485 TEST_USERINFO_INT_EXP(16, acct_flags
, 21, acct_flags
,
486 (base_acct_flags
| ACB_DISABLED
| ACB_NO_AUTH_DATA_REQD
),
487 (base_acct_flags
| ACB_DISABLED
| ACB_NO_AUTH_DATA_REQD
| user_extra_flags
),
490 TEST_USERINFO_INT_EXP(21, acct_flags
, 21, acct_flags
,
491 (base_acct_flags
| ACB_DISABLED
),
492 (base_acct_flags
| ACB_DISABLED
| user_extra_flags
),
493 SAMR_FIELD_ACCT_FLAGS
);
496 /* these fail with win2003 - it appears you can't set the primary gid?
497 the set succeeds, but the gid isn't changed. Very weird! */
498 TEST_USERINFO_INT(9, primary_gid
, 1, primary_gid
, 513);
499 TEST_USERINFO_INT(9, primary_gid
, 3, primary_gid
, 513);
500 TEST_USERINFO_INT(9, primary_gid
, 5, primary_gid
, 513);
501 TEST_USERINFO_INT(9, primary_gid
, 21, primary_gid
, 513);
508 generate a random password for password change tests
510 static char *samr_rand_pass(TALLOC_CTX
*mem_ctx
, int min_len
)
512 size_t len
= MAX(8, min_len
) + (random() % 6);
513 char *s
= generate_random_str(mem_ctx
, len
);
514 printf("Generated password '%s'\n", s
);
519 generate a random password for password change tests
521 static DATA_BLOB
samr_very_rand_pass(TALLOC_CTX
*mem_ctx
, int len
)
524 DATA_BLOB password
= data_blob_talloc(mem_ctx
, NULL
, len
* 2 /* number of unicode chars */);
525 generate_random_buffer(password
.data
, password
.length
);
527 for (i
=0; i
< len
; i
++) {
528 if (((uint16_t *)password
.data
)[i
] == 0) {
529 ((uint16_t *)password
.data
)[i
] = 1;
537 generate a random password for password change tests (fixed length)
539 static char *samr_rand_pass_fixed_len(TALLOC_CTX
*mem_ctx
, int len
)
541 char *s
= generate_random_str(mem_ctx
, len
);
542 printf("Generated password '%s'\n", s
);
546 static bool test_SetUserPass(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
547 struct policy_handle
*handle
, char **password
)
550 struct samr_SetUserInfo s
;
551 union samr_UserInfo u
;
553 DATA_BLOB session_key
;
555 struct samr_GetUserPwInfo pwp
;
556 struct samr_PwInfo info
;
557 int policy_min_pw_len
= 0;
558 pwp
.in
.user_handle
= handle
;
559 pwp
.out
.info
= &info
;
561 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
562 if (NT_STATUS_IS_OK(status
)) {
563 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
565 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
567 s
.in
.user_handle
= handle
;
571 encode_pw_buffer(u
.info24
.password
.data
, newpass
, STR_UNICODE
);
572 /* w2k3 ignores this length */
573 u
.info24
.pw_len
= strlen_m(newpass
) * 2;
575 status
= dcerpc_fetch_session_key(p
, &session_key
);
576 if (!NT_STATUS_IS_OK(status
)) {
577 printf("SetUserInfo level %u - no session key - %s\n",
578 s
.in
.level
, nt_errstr(status
));
582 arcfour_crypt_blob(u
.info24
.password
.data
, 516, &session_key
);
584 torture_comment(tctx
, "Testing SetUserInfo level 24 (set password)\n");
586 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
587 if (!NT_STATUS_IS_OK(status
)) {
588 printf("SetUserInfo level %u failed - %s\n",
589 s
.in
.level
, nt_errstr(status
));
599 static bool test_SetUserPass_23(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
600 struct policy_handle
*handle
, uint32_t fields_present
,
604 struct samr_SetUserInfo s
;
605 union samr_UserInfo u
;
607 DATA_BLOB session_key
;
609 struct samr_GetUserPwInfo pwp
;
610 struct samr_PwInfo info
;
611 int policy_min_pw_len
= 0;
612 pwp
.in
.user_handle
= handle
;
613 pwp
.out
.info
= &info
;
615 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
616 if (NT_STATUS_IS_OK(status
)) {
617 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
619 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
621 s
.in
.user_handle
= handle
;
627 u
.info23
.info
.fields_present
= fields_present
;
629 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
631 status
= dcerpc_fetch_session_key(p
, &session_key
);
632 if (!NT_STATUS_IS_OK(status
)) {
633 printf("SetUserInfo level %u - no session key - %s\n",
634 s
.in
.level
, nt_errstr(status
));
638 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
640 torture_comment(tctx
, "Testing SetUserInfo level 23 (set password)\n");
642 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
643 if (!NT_STATUS_IS_OK(status
)) {
644 printf("SetUserInfo level %u failed - %s\n",
645 s
.in
.level
, nt_errstr(status
));
651 encode_pw_buffer(u
.info23
.password
.data
, newpass
, STR_UNICODE
);
653 status
= dcerpc_fetch_session_key(p
, &session_key
);
654 if (!NT_STATUS_IS_OK(status
)) {
655 printf("SetUserInfo level %u - no session key - %s\n",
656 s
.in
.level
, nt_errstr(status
));
660 /* This should break the key nicely */
661 session_key
.length
--;
662 arcfour_crypt_blob(u
.info23
.password
.data
, 516, &session_key
);
664 torture_comment(tctx
, "Testing SetUserInfo level 23 (set password) with wrong password\n");
666 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
667 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
668 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
669 s
.in
.level
, nt_errstr(status
));
677 static bool test_SetUserPassEx(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
678 struct policy_handle
*handle
, bool makeshort
,
682 struct samr_SetUserInfo s
;
683 union samr_UserInfo u
;
685 DATA_BLOB session_key
;
686 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
687 uint8_t confounder
[16];
689 struct MD5Context ctx
;
690 struct samr_GetUserPwInfo pwp
;
691 struct samr_PwInfo info
;
692 int policy_min_pw_len
= 0;
693 pwp
.in
.user_handle
= handle
;
694 pwp
.out
.info
= &info
;
696 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
697 if (NT_STATUS_IS_OK(status
)) {
698 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
700 if (makeshort
&& policy_min_pw_len
) {
701 newpass
= samr_rand_pass_fixed_len(tctx
, policy_min_pw_len
- 1);
703 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
706 s
.in
.user_handle
= handle
;
710 encode_pw_buffer(u
.info26
.password
.data
, newpass
, STR_UNICODE
);
711 u
.info26
.pw_len
= strlen(newpass
);
713 status
= dcerpc_fetch_session_key(p
, &session_key
);
714 if (!NT_STATUS_IS_OK(status
)) {
715 printf("SetUserInfo level %u - no session key - %s\n",
716 s
.in
.level
, nt_errstr(status
));
720 generate_random_buffer((uint8_t *)confounder
, 16);
723 MD5Update(&ctx
, confounder
, 16);
724 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
725 MD5Final(confounded_session_key
.data
, &ctx
);
727 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
728 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
730 torture_comment(tctx
, "Testing SetUserInfo level 26 (set password ex)\n");
732 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
733 if (!NT_STATUS_IS_OK(status
)) {
734 printf("SetUserInfo level %u failed - %s\n",
735 s
.in
.level
, nt_errstr(status
));
741 /* This should break the key nicely */
742 confounded_session_key
.data
[0]++;
744 arcfour_crypt_blob(u
.info26
.password
.data
, 516, &confounded_session_key
);
745 memcpy(&u
.info26
.password
.data
[516], confounder
, 16);
747 torture_comment(tctx
, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
749 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
750 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
751 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
752 s
.in
.level
, nt_errstr(status
));
761 static bool test_SetUserPass_25(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
762 struct policy_handle
*handle
, uint32_t fields_present
,
766 struct samr_SetUserInfo s
;
767 union samr_UserInfo u
;
769 DATA_BLOB session_key
;
770 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
771 struct MD5Context ctx
;
772 uint8_t confounder
[16];
774 struct samr_GetUserPwInfo pwp
;
775 struct samr_PwInfo info
;
776 int policy_min_pw_len
= 0;
777 pwp
.in
.user_handle
= handle
;
778 pwp
.out
.info
= &info
;
780 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
781 if (NT_STATUS_IS_OK(status
)) {
782 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
784 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
786 s
.in
.user_handle
= handle
;
792 u
.info25
.info
.fields_present
= fields_present
;
794 encode_pw_buffer(u
.info25
.password
.data
, newpass
, STR_UNICODE
);
796 status
= dcerpc_fetch_session_key(p
, &session_key
);
797 if (!NT_STATUS_IS_OK(status
)) {
798 printf("SetUserInfo level %u - no session key - %s\n",
799 s
.in
.level
, nt_errstr(status
));
803 generate_random_buffer((uint8_t *)confounder
, 16);
806 MD5Update(&ctx
, confounder
, 16);
807 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
808 MD5Final(confounded_session_key
.data
, &ctx
);
810 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
811 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
813 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex)\n");
815 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
816 if (!NT_STATUS_IS_OK(status
)) {
817 printf("SetUserInfo level %u failed - %s\n",
818 s
.in
.level
, nt_errstr(status
));
824 /* This should break the key nicely */
825 confounded_session_key
.data
[0]++;
827 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
828 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
830 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
832 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
833 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
834 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
835 s
.in
.level
, nt_errstr(status
));
842 static bool test_SetAliasInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
843 struct policy_handle
*handle
)
846 struct samr_SetAliasInfo r
;
847 struct samr_QueryAliasInfo q
;
848 uint16_t levels
[] = {2, 3};
852 /* Ignoring switch level 1, as that includes the number of members for the alias
853 * and setting this to a wrong value might have negative consequences
856 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
857 torture_comment(tctx
, "Testing SetAliasInfo level %u\n", levels
[i
]);
859 r
.in
.alias_handle
= handle
;
860 r
.in
.level
= levels
[i
];
861 r
.in
.info
= talloc(tctx
, union samr_AliasInfo
);
862 switch (r
.in
.level
) {
863 case ALIASINFONAME
: init_lsa_String(&r
.in
.info
->name
,TEST_ALIASNAME
); break;
864 case ALIASINFODESCRIPTION
: init_lsa_String(&r
.in
.info
->description
,
865 "Test Description, should test I18N as well"); break;
866 case ALIASINFOALL
: printf("ALIASINFOALL ignored\n"); break;
869 status
= dcerpc_samr_SetAliasInfo(p
, tctx
, &r
);
870 if (!NT_STATUS_IS_OK(status
)) {
871 printf("SetAliasInfo level %u failed - %s\n",
872 levels
[i
], nt_errstr(status
));
876 q
.in
.alias_handle
= handle
;
877 q
.in
.level
= levels
[i
];
879 status
= dcerpc_samr_QueryAliasInfo(p
, tctx
, &q
);
880 if (!NT_STATUS_IS_OK(status
)) {
881 printf("QueryAliasInfo level %u failed - %s\n",
882 levels
[i
], nt_errstr(status
));
890 static bool test_GetGroupsForUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
891 struct policy_handle
*user_handle
)
893 struct samr_GetGroupsForUser r
;
894 struct samr_RidWithAttributeArray
*rids
= NULL
;
897 torture_comment(tctx
, "testing GetGroupsForUser\n");
899 r
.in
.user_handle
= user_handle
;
902 status
= dcerpc_samr_GetGroupsForUser(p
, tctx
, &r
);
903 torture_assert_ntstatus_ok(tctx
, status
, "GetGroupsForUser");
909 static bool test_GetDomPwInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
910 struct lsa_String
*domain_name
)
913 struct samr_GetDomPwInfo r
;
914 struct samr_PwInfo info
;
916 r
.in
.domain_name
= domain_name
;
919 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
921 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &r
);
922 torture_assert_ntstatus_ok(tctx
, status
, "GetDomPwInfo");
924 r
.in
.domain_name
->string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
925 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
927 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &r
);
928 torture_assert_ntstatus_ok(tctx
, status
, "GetDomPwInfo");
930 r
.in
.domain_name
->string
= "\\\\__NONAME__";
931 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
933 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &r
);
934 torture_assert_ntstatus_ok(tctx
, status
, "GetDomPwInfo");
936 r
.in
.domain_name
->string
= "\\\\Builtin";
937 torture_comment(tctx
, "Testing GetDomPwInfo with name %s\n", r
.in
.domain_name
->string
);
939 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &r
);
940 torture_assert_ntstatus_ok(tctx
, status
, "GetDomPwInfo");
945 static bool test_GetUserPwInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
946 struct policy_handle
*handle
)
949 struct samr_GetUserPwInfo r
;
950 struct samr_PwInfo info
;
952 torture_comment(tctx
, "Testing GetUserPwInfo\n");
954 r
.in
.user_handle
= handle
;
957 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &r
);
958 torture_assert_ntstatus_ok(tctx
, status
, "GetUserPwInfo");
963 static NTSTATUS
test_LookupName(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
964 struct policy_handle
*domain_handle
, const char *name
,
968 struct samr_LookupNames n
;
969 struct lsa_String sname
[2];
971 init_lsa_String(&sname
[0], name
);
973 n
.in
.domain_handle
= domain_handle
;
976 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
977 if (NT_STATUS_IS_OK(status
)) {
978 *rid
= n
.out
.rids
.ids
[0];
983 init_lsa_String(&sname
[1], "xxNONAMExx");
985 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
986 if (!NT_STATUS_EQUAL(status
, STATUS_SOME_UNMAPPED
)) {
987 printf("LookupNames[2] failed - %s\n", nt_errstr(status
));
988 if (NT_STATUS_IS_OK(status
)) {
989 return NT_STATUS_UNSUCCESSFUL
;
995 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
996 if (!NT_STATUS_IS_OK(status
)) {
997 printf("LookupNames[0] failed - %s\n", nt_errstr(status
));
1001 init_lsa_String(&sname
[0], "xxNONAMExx");
1003 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
1004 if (!NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
)) {
1005 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status
));
1006 if (NT_STATUS_IS_OK(status
)) {
1007 return NT_STATUS_UNSUCCESSFUL
;
1012 init_lsa_String(&sname
[0], "xxNONAMExx");
1013 init_lsa_String(&sname
[1], "xxNONAME2xx");
1015 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
1016 if (!NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
)) {
1017 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status
));
1018 if (NT_STATUS_IS_OK(status
)) {
1019 return NT_STATUS_UNSUCCESSFUL
;
1024 return NT_STATUS_OK
;
1027 static NTSTATUS
test_OpenUser_byname(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
1028 struct policy_handle
*domain_handle
,
1029 const char *name
, struct policy_handle
*user_handle
)
1032 struct samr_OpenUser r
;
1035 status
= test_LookupName(p
, mem_ctx
, domain_handle
, name
, &rid
);
1036 if (!NT_STATUS_IS_OK(status
)) {
1040 r
.in
.domain_handle
= domain_handle
;
1041 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1043 r
.out
.user_handle
= user_handle
;
1044 status
= dcerpc_samr_OpenUser(p
, mem_ctx
, &r
);
1045 if (!NT_STATUS_IS_OK(status
)) {
1046 printf("OpenUser_byname(%s -> %d) failed - %s\n", name
, rid
, nt_errstr(status
));
1053 static bool test_ChangePasswordNT3(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
1054 struct policy_handle
*handle
)
1057 struct samr_ChangePasswordUser r
;
1059 struct samr_Password hash1
, hash2
, hash3
, hash4
, hash5
, hash6
;
1060 struct policy_handle user_handle
;
1061 char *oldpass
= "test";
1062 char *newpass
= "test2";
1063 uint8_t old_nt_hash
[16], new_nt_hash
[16];
1064 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1066 status
= test_OpenUser_byname(p
, mem_ctx
, handle
, "testuser", &user_handle
);
1067 if (!NT_STATUS_IS_OK(status
)) {
1071 printf("Testing ChangePasswordUser for user 'testuser'\n");
1073 printf("old password: %s\n", oldpass
);
1074 printf("new password: %s\n", newpass
);
1076 E_md4hash(oldpass
, old_nt_hash
);
1077 E_md4hash(newpass
, new_nt_hash
);
1078 E_deshash(oldpass
, old_lm_hash
);
1079 E_deshash(newpass
, new_lm_hash
);
1081 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1082 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1083 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1084 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1085 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1086 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1088 r
.in
.handle
= &user_handle
;
1089 r
.in
.lm_present
= 1;
1090 r
.in
.old_lm_crypted
= &hash1
;
1091 r
.in
.new_lm_crypted
= &hash2
;
1092 r
.in
.nt_present
= 1;
1093 r
.in
.old_nt_crypted
= &hash3
;
1094 r
.in
.new_nt_crypted
= &hash4
;
1095 r
.in
.cross1_present
= 1;
1096 r
.in
.nt_cross
= &hash5
;
1097 r
.in
.cross2_present
= 1;
1098 r
.in
.lm_cross
= &hash6
;
1100 status
= dcerpc_samr_ChangePasswordUser(p
, mem_ctx
, &r
);
1101 if (!NT_STATUS_IS_OK(status
)) {
1102 printf("ChangePasswordUser failed - %s\n", nt_errstr(status
));
1106 if (!test_samr_handle_Close(p
, mem_ctx
, &user_handle
)) {
1114 static bool test_ChangePasswordUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1115 const char *acct_name
,
1116 struct policy_handle
*handle
, char **password
)
1119 struct samr_ChangePasswordUser r
;
1121 struct samr_Password hash1
, hash2
, hash3
, hash4
, hash5
, hash6
;
1122 struct policy_handle user_handle
;
1124 uint8_t old_nt_hash
[16], new_nt_hash
[16];
1125 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1126 bool changed
= true;
1129 struct samr_GetUserPwInfo pwp
;
1130 struct samr_PwInfo info
;
1131 int policy_min_pw_len
= 0;
1133 status
= test_OpenUser_byname(p
, tctx
, handle
, acct_name
, &user_handle
);
1134 if (!NT_STATUS_IS_OK(status
)) {
1137 pwp
.in
.user_handle
= &user_handle
;
1138 pwp
.out
.info
= &info
;
1140 status
= dcerpc_samr_GetUserPwInfo(p
, tctx
, &pwp
);
1141 if (NT_STATUS_IS_OK(status
)) {
1142 policy_min_pw_len
= pwp
.out
.info
->min_password_length
;
1144 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1146 torture_comment(tctx
, "Testing ChangePasswordUser\n");
1148 torture_assert(tctx
, *password
!= NULL
,
1149 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1151 oldpass
= *password
;
1153 E_md4hash(oldpass
, old_nt_hash
);
1154 E_md4hash(newpass
, new_nt_hash
);
1155 E_deshash(oldpass
, old_lm_hash
);
1156 E_deshash(newpass
, new_lm_hash
);
1158 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1159 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1160 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1161 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1162 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1163 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1165 r
.in
.user_handle
= &user_handle
;
1166 r
.in
.lm_present
= 1;
1167 /* Break the LM hash */
1169 r
.in
.old_lm_crypted
= &hash1
;
1170 r
.in
.new_lm_crypted
= &hash2
;
1171 r
.in
.nt_present
= 1;
1172 r
.in
.old_nt_crypted
= &hash3
;
1173 r
.in
.new_nt_crypted
= &hash4
;
1174 r
.in
.cross1_present
= 1;
1175 r
.in
.nt_cross
= &hash5
;
1176 r
.in
.cross2_present
= 1;
1177 r
.in
.lm_cross
= &hash6
;
1179 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1180 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_WRONG_PASSWORD
,
1181 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1183 /* Unbreak the LM hash */
1186 r
.in
.user_handle
= &user_handle
;
1187 r
.in
.lm_present
= 1;
1188 r
.in
.old_lm_crypted
= &hash1
;
1189 r
.in
.new_lm_crypted
= &hash2
;
1190 /* Break the NT hash */
1192 r
.in
.nt_present
= 1;
1193 r
.in
.old_nt_crypted
= &hash3
;
1194 r
.in
.new_nt_crypted
= &hash4
;
1195 r
.in
.cross1_present
= 1;
1196 r
.in
.nt_cross
= &hash5
;
1197 r
.in
.cross2_present
= 1;
1198 r
.in
.lm_cross
= &hash6
;
1200 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1201 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_WRONG_PASSWORD
,
1202 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1204 /* Unbreak the NT hash */
1207 r
.in
.user_handle
= &user_handle
;
1208 r
.in
.lm_present
= 1;
1209 r
.in
.old_lm_crypted
= &hash1
;
1210 r
.in
.new_lm_crypted
= &hash2
;
1211 r
.in
.nt_present
= 1;
1212 r
.in
.old_nt_crypted
= &hash3
;
1213 r
.in
.new_nt_crypted
= &hash4
;
1214 r
.in
.cross1_present
= 1;
1215 r
.in
.nt_cross
= &hash5
;
1216 r
.in
.cross2_present
= 1;
1217 /* Break the LM cross */
1219 r
.in
.lm_cross
= &hash6
;
1221 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1222 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1223 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status
));
1227 /* Unbreak the LM cross */
1230 r
.in
.user_handle
= &user_handle
;
1231 r
.in
.lm_present
= 1;
1232 r
.in
.old_lm_crypted
= &hash1
;
1233 r
.in
.new_lm_crypted
= &hash2
;
1234 r
.in
.nt_present
= 1;
1235 r
.in
.old_nt_crypted
= &hash3
;
1236 r
.in
.new_nt_crypted
= &hash4
;
1237 r
.in
.cross1_present
= 1;
1238 /* Break the NT cross */
1240 r
.in
.nt_cross
= &hash5
;
1241 r
.in
.cross2_present
= 1;
1242 r
.in
.lm_cross
= &hash6
;
1244 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1245 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1246 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status
));
1250 /* Unbreak the NT cross */
1254 /* Reset the hashes to not broken values */
1255 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1256 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1257 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1258 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1259 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1260 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1262 r
.in
.user_handle
= &user_handle
;
1263 r
.in
.lm_present
= 1;
1264 r
.in
.old_lm_crypted
= &hash1
;
1265 r
.in
.new_lm_crypted
= &hash2
;
1266 r
.in
.nt_present
= 1;
1267 r
.in
.old_nt_crypted
= &hash3
;
1268 r
.in
.new_nt_crypted
= &hash4
;
1269 r
.in
.cross1_present
= 1;
1270 r
.in
.nt_cross
= &hash5
;
1271 r
.in
.cross2_present
= 0;
1272 r
.in
.lm_cross
= NULL
;
1274 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1275 if (NT_STATUS_IS_OK(status
)) {
1277 *password
= newpass
;
1278 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION
, status
)) {
1279 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status
));
1284 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1286 E_md4hash(oldpass
, old_nt_hash
);
1287 E_md4hash(newpass
, new_nt_hash
);
1288 E_deshash(oldpass
, old_lm_hash
);
1289 E_deshash(newpass
, new_lm_hash
);
1292 /* Reset the hashes to not broken values */
1293 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1294 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1295 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1296 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1297 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1298 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1300 r
.in
.user_handle
= &user_handle
;
1301 r
.in
.lm_present
= 1;
1302 r
.in
.old_lm_crypted
= &hash1
;
1303 r
.in
.new_lm_crypted
= &hash2
;
1304 r
.in
.nt_present
= 1;
1305 r
.in
.old_nt_crypted
= &hash3
;
1306 r
.in
.new_nt_crypted
= &hash4
;
1307 r
.in
.cross1_present
= 0;
1308 r
.in
.nt_cross
= NULL
;
1309 r
.in
.cross2_present
= 1;
1310 r
.in
.lm_cross
= &hash6
;
1312 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1313 if (NT_STATUS_IS_OK(status
)) {
1315 *password
= newpass
;
1316 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION
, status
)) {
1317 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status
));
1322 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1324 E_md4hash(oldpass
, old_nt_hash
);
1325 E_md4hash(newpass
, new_nt_hash
);
1326 E_deshash(oldpass
, old_lm_hash
);
1327 E_deshash(newpass
, new_lm_hash
);
1330 /* Reset the hashes to not broken values */
1331 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
1332 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
1333 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
1334 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
1335 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
1336 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
1338 r
.in
.user_handle
= &user_handle
;
1339 r
.in
.lm_present
= 1;
1340 r
.in
.old_lm_crypted
= &hash1
;
1341 r
.in
.new_lm_crypted
= &hash2
;
1342 r
.in
.nt_present
= 1;
1343 r
.in
.old_nt_crypted
= &hash3
;
1344 r
.in
.new_nt_crypted
= &hash4
;
1345 r
.in
.cross1_present
= 1;
1346 r
.in
.nt_cross
= &hash5
;
1347 r
.in
.cross2_present
= 1;
1348 r
.in
.lm_cross
= &hash6
;
1350 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1351 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1352 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status
));
1353 } else if (!NT_STATUS_IS_OK(status
)) {
1354 printf("ChangePasswordUser failed - %s\n", nt_errstr(status
));
1358 *password
= newpass
;
1361 r
.in
.user_handle
= &user_handle
;
1362 r
.in
.lm_present
= 1;
1363 r
.in
.old_lm_crypted
= &hash1
;
1364 r
.in
.new_lm_crypted
= &hash2
;
1365 r
.in
.nt_present
= 1;
1366 r
.in
.old_nt_crypted
= &hash3
;
1367 r
.in
.new_nt_crypted
= &hash4
;
1368 r
.in
.cross1_present
= 1;
1369 r
.in
.nt_cross
= &hash5
;
1370 r
.in
.cross2_present
= 1;
1371 r
.in
.lm_cross
= &hash6
;
1374 status
= dcerpc_samr_ChangePasswordUser(p
, tctx
, &r
);
1375 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1376 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status
));
1377 } else if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1378 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status
));
1384 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
1392 static bool test_OemChangePasswordUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1393 const char *acct_name
,
1394 struct policy_handle
*handle
, char **password
)
1397 struct samr_OemChangePasswordUser2 r
;
1399 struct samr_Password lm_verifier
;
1400 struct samr_CryptPassword lm_pass
;
1401 struct lsa_AsciiString server
, account
, account_bad
;
1404 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1406 struct samr_GetDomPwInfo dom_pw_info
;
1407 struct samr_PwInfo info
;
1408 int policy_min_pw_len
= 0;
1410 struct lsa_String domain_name
;
1412 domain_name
.string
= "";
1413 dom_pw_info
.in
.domain_name
= &domain_name
;
1414 dom_pw_info
.out
.info
= &info
;
1416 torture_comment(tctx
, "Testing OemChangePasswordUser2\n");
1418 torture_assert(tctx
, *password
!= NULL
,
1419 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1421 oldpass
= *password
;
1423 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &dom_pw_info
);
1424 if (NT_STATUS_IS_OK(status
)) {
1425 policy_min_pw_len
= dom_pw_info
.out
.info
->min_password_length
;
1428 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1430 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1431 account
.string
= acct_name
;
1433 E_deshash(oldpass
, old_lm_hash
);
1434 E_deshash(newpass
, new_lm_hash
);
1436 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
1437 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
1438 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
1440 r
.in
.server
= &server
;
1441 r
.in
.account
= &account
;
1442 r
.in
.password
= &lm_pass
;
1443 r
.in
.hash
= &lm_verifier
;
1445 /* Break the verification */
1446 lm_verifier
.hash
[0]++;
1448 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
1450 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)
1451 && !NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1452 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1457 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
1458 /* Break the old password */
1460 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
1461 /* unbreak it for the next operation */
1463 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
1465 r
.in
.server
= &server
;
1466 r
.in
.account
= &account
;
1467 r
.in
.password
= &lm_pass
;
1468 r
.in
.hash
= &lm_verifier
;
1470 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
1472 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)
1473 && !NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1474 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1479 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
1480 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
1482 r
.in
.server
= &server
;
1483 r
.in
.account
= &account
;
1484 r
.in
.password
= &lm_pass
;
1487 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
1489 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)
1490 && !NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
1491 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1496 /* This shouldn't be a valid name */
1497 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
1498 r
.in
.account
= &account_bad
;
1500 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
1502 if (!NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
1503 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1508 /* This shouldn't be a valid name */
1509 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
1510 r
.in
.account
= &account_bad
;
1511 r
.in
.password
= &lm_pass
;
1512 r
.in
.hash
= &lm_verifier
;
1514 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
1516 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1517 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1522 /* This shouldn't be a valid name */
1523 account_bad
.string
= TEST_ACCOUNT_NAME
"XX";
1524 r
.in
.account
= &account_bad
;
1525 r
.in
.password
= NULL
;
1526 r
.in
.hash
= &lm_verifier
;
1528 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
1530 if (!NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
1531 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1536 E_deshash(oldpass
, old_lm_hash
);
1537 E_deshash(newpass
, new_lm_hash
);
1539 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
);
1540 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
1541 E_old_pw_hash(new_lm_hash
, old_lm_hash
, lm_verifier
.hash
);
1543 r
.in
.server
= &server
;
1544 r
.in
.account
= &account
;
1545 r
.in
.password
= &lm_pass
;
1546 r
.in
.hash
= &lm_verifier
;
1548 status
= dcerpc_samr_OemChangePasswordUser2(p
, tctx
, &r
);
1549 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1550 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status
));
1551 } else if (!NT_STATUS_IS_OK(status
)) {
1552 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status
));
1555 *password
= newpass
;
1562 static bool test_ChangePasswordUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1563 const char *acct_name
,
1565 char *newpass
, bool allow_password_restriction
)
1568 struct samr_ChangePasswordUser2 r
;
1570 struct lsa_String server
, account
;
1571 struct samr_CryptPassword nt_pass
, lm_pass
;
1572 struct samr_Password nt_verifier
, lm_verifier
;
1574 uint8_t old_nt_hash
[16], new_nt_hash
[16];
1575 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1577 struct samr_GetDomPwInfo dom_pw_info
;
1578 struct samr_PwInfo info
;
1580 struct lsa_String domain_name
;
1582 domain_name
.string
= "";
1583 dom_pw_info
.in
.domain_name
= &domain_name
;
1584 dom_pw_info
.out
.info
= &info
;
1586 torture_comment(tctx
, "Testing ChangePasswordUser2 on %s\n", acct_name
);
1588 torture_assert(tctx
, *password
!= NULL
,
1589 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
1590 oldpass
= *password
;
1593 int policy_min_pw_len
= 0;
1594 status
= dcerpc_samr_GetDomPwInfo(p
, tctx
, &dom_pw_info
);
1595 if (NT_STATUS_IS_OK(status
)) {
1596 policy_min_pw_len
= dom_pw_info
.out
.info
->min_password_length
;
1599 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1602 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1603 init_lsa_String(&account
, acct_name
);
1605 E_md4hash(oldpass
, old_nt_hash
);
1606 E_md4hash(newpass
, new_nt_hash
);
1608 E_deshash(oldpass
, old_lm_hash
);
1609 E_deshash(newpass
, new_lm_hash
);
1611 encode_pw_buffer(lm_pass
.data
, newpass
, STR_ASCII
|STR_TERMINATE
);
1612 arcfour_crypt(lm_pass
.data
, old_lm_hash
, 516);
1613 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
1615 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
1616 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
1617 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
1619 r
.in
.server
= &server
;
1620 r
.in
.account
= &account
;
1621 r
.in
.nt_password
= &nt_pass
;
1622 r
.in
.nt_verifier
= &nt_verifier
;
1624 r
.in
.lm_password
= &lm_pass
;
1625 r
.in
.lm_verifier
= &lm_verifier
;
1627 status
= dcerpc_samr_ChangePasswordUser2(p
, tctx
, &r
);
1628 if (allow_password_restriction
&& NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1629 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status
));
1630 } else if (!NT_STATUS_IS_OK(status
)) {
1631 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status
));
1634 *password
= newpass
;
1641 bool test_ChangePasswordUser3(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1642 const char *account_string
,
1643 int policy_min_pw_len
,
1645 const char *newpass
,
1646 NTTIME last_password_change
,
1647 bool handle_reject_reason
)
1650 struct samr_ChangePasswordUser3 r
;
1652 struct lsa_String server
, account
, account_bad
;
1653 struct samr_CryptPassword nt_pass
, lm_pass
;
1654 struct samr_Password nt_verifier
, lm_verifier
;
1656 uint8_t old_nt_hash
[16], new_nt_hash
[16];
1657 uint8_t old_lm_hash
[16], new_lm_hash
[16];
1659 struct samr_DomInfo1
*dominfo
= NULL
;
1660 struct samr_ChangeReject
*reject
= NULL
;
1662 torture_comment(tctx
, "Testing ChangePasswordUser3\n");
1664 if (newpass
== NULL
) {
1666 if (policy_min_pw_len
== 0) {
1667 newpass
= samr_rand_pass(tctx
, policy_min_pw_len
);
1669 newpass
= samr_rand_pass_fixed_len(tctx
, policy_min_pw_len
);
1671 } while (check_password_quality(newpass
) == false);
1673 torture_comment(tctx
, "Using password '%s'\n", newpass
);
1676 torture_assert(tctx
, *password
!= NULL
,
1677 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1679 oldpass
= *password
;
1680 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1681 init_lsa_String(&account
, account_string
);
1683 E_md4hash(oldpass
, old_nt_hash
);
1684 E_md4hash(newpass
, new_nt_hash
);
1686 E_deshash(oldpass
, old_lm_hash
);
1687 E_deshash(newpass
, new_lm_hash
);
1689 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
1690 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
1691 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
1693 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
1694 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
1695 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
1697 /* Break the verification */
1698 nt_verifier
.hash
[0]++;
1700 r
.in
.server
= &server
;
1701 r
.in
.account
= &account
;
1702 r
.in
.nt_password
= &nt_pass
;
1703 r
.in
.nt_verifier
= &nt_verifier
;
1705 r
.in
.lm_password
= &lm_pass
;
1706 r
.in
.lm_verifier
= &lm_verifier
;
1707 r
.in
.password3
= NULL
;
1708 r
.out
.dominfo
= &dominfo
;
1709 r
.out
.reject
= &reject
;
1711 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
1712 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
) &&
1713 (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
))) {
1714 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1719 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
1720 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
1721 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
1723 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
1724 /* Break the NT hash */
1726 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
1727 /* Unbreak it again */
1729 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
1731 r
.in
.server
= &server
;
1732 r
.in
.account
= &account
;
1733 r
.in
.nt_password
= &nt_pass
;
1734 r
.in
.nt_verifier
= &nt_verifier
;
1736 r
.in
.lm_password
= &lm_pass
;
1737 r
.in
.lm_verifier
= &lm_verifier
;
1738 r
.in
.password3
= NULL
;
1739 r
.out
.dominfo
= &dominfo
;
1740 r
.out
.reject
= &reject
;
1742 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
1743 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
) &&
1744 (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
))) {
1745 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1750 /* This shouldn't be a valid name */
1751 init_lsa_String(&account_bad
, talloc_asprintf(tctx
, "%sXX", account_string
));
1753 r
.in
.account
= &account_bad
;
1754 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
1755 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1756 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1761 E_md4hash(oldpass
, old_nt_hash
);
1762 E_md4hash(newpass
, new_nt_hash
);
1764 E_deshash(oldpass
, old_lm_hash
);
1765 E_deshash(newpass
, new_lm_hash
);
1767 encode_pw_buffer(lm_pass
.data
, newpass
, STR_UNICODE
);
1768 arcfour_crypt(lm_pass
.data
, old_nt_hash
, 516);
1769 E_old_pw_hash(new_nt_hash
, old_lm_hash
, lm_verifier
.hash
);
1771 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
1772 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
1773 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
1775 r
.in
.server
= &server
;
1776 r
.in
.account
= &account
;
1777 r
.in
.nt_password
= &nt_pass
;
1778 r
.in
.nt_verifier
= &nt_verifier
;
1780 r
.in
.lm_password
= &lm_pass
;
1781 r
.in
.lm_verifier
= &lm_verifier
;
1782 r
.in
.password3
= NULL
;
1783 r
.out
.dominfo
= &dominfo
;
1784 r
.out
.reject
= &reject
;
1786 unix_to_nt_time(&t
, time(NULL
));
1788 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
1790 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)
1793 && handle_reject_reason
1794 && (!null_nttime(last_password_change
) || !dominfo
->min_password_age
)) {
1795 if (dominfo
->password_properties
& DOMAIN_REFUSE_PASSWORD_CHANGE
) {
1797 if (reject
&& (reject
->reason
!= SAMR_REJECT_OTHER
)) {
1798 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1799 SAMR_REJECT_OTHER
, reject
->reason
);
1804 /* We tested the order of precendence which is as follows:
1813 if ((dominfo
->min_password_age
> 0) && !null_nttime(last_password_change
) &&
1814 (last_password_change
+ dominfo
->min_password_age
> t
)) {
1816 if (reject
->reason
!= SAMR_REJECT_OTHER
) {
1817 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1818 SAMR_REJECT_OTHER
, reject
->reason
);
1822 } else if ((dominfo
->min_password_length
> 0) &&
1823 (strlen(newpass
) < dominfo
->min_password_length
)) {
1825 if (reject
->reason
!= SAMR_REJECT_TOO_SHORT
) {
1826 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1827 SAMR_REJECT_TOO_SHORT
, reject
->reason
);
1831 } else if ((dominfo
->password_history_length
> 0) &&
1832 strequal(oldpass
, newpass
)) {
1834 if (reject
->reason
!= SAMR_REJECT_IN_HISTORY
) {
1835 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1836 SAMR_REJECT_IN_HISTORY
, reject
->reason
);
1839 } else if (dominfo
->password_properties
& DOMAIN_PASSWORD_COMPLEX
) {
1841 if (reject
->reason
!= SAMR_REJECT_COMPLEXITY
) {
1842 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1843 SAMR_REJECT_COMPLEXITY
, reject
->reason
);
1849 if (reject
->reason
== SAMR_REJECT_TOO_SHORT
) {
1850 /* retry with adjusted size */
1851 return test_ChangePasswordUser3(p
, tctx
, account_string
,
1852 dominfo
->min_password_length
,
1853 password
, NULL
, 0, false);
1857 } else if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1858 if (reject
&& reject
->reason
!= SAMR_REJECT_OTHER
) {
1859 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1860 SAMR_REJECT_OTHER
, reject
->reason
);
1863 /* Perhaps the server has a 'min password age' set? */
1866 torture_assert_ntstatus_ok(tctx
, status
, "ChangePasswordUser3");
1867 *password
= talloc_strdup(tctx
, newpass
);
1873 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1874 const char *account_string
,
1875 struct policy_handle
*handle
,
1879 struct samr_ChangePasswordUser3 r
;
1880 struct samr_SetUserInfo s
;
1881 union samr_UserInfo u
;
1882 DATA_BLOB session_key
;
1883 DATA_BLOB confounded_session_key
= data_blob_talloc(tctx
, NULL
, 16);
1884 uint8_t confounder
[16];
1885 struct MD5Context ctx
;
1888 struct lsa_String server
, account
;
1889 struct samr_CryptPassword nt_pass
;
1890 struct samr_Password nt_verifier
;
1891 DATA_BLOB new_random_pass
;
1894 uint8_t old_nt_hash
[16], new_nt_hash
[16];
1896 struct samr_DomInfo1
*dominfo
= NULL
;
1897 struct samr_ChangeReject
*reject
= NULL
;
1899 new_random_pass
= samr_very_rand_pass(tctx
, 128);
1901 torture_assert(tctx
, *password
!= NULL
,
1902 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1904 oldpass
= *password
;
1905 server
.string
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1906 init_lsa_String(&account
, account_string
);
1908 s
.in
.user_handle
= handle
;
1914 u
.info25
.info
.fields_present
= SAMR_FIELD_PASSWORD
;
1916 set_pw_in_buffer(u
.info25
.password
.data
, &new_random_pass
);
1918 status
= dcerpc_fetch_session_key(p
, &session_key
);
1919 if (!NT_STATUS_IS_OK(status
)) {
1920 printf("SetUserInfo level %u - no session key - %s\n",
1921 s
.in
.level
, nt_errstr(status
));
1925 generate_random_buffer((uint8_t *)confounder
, 16);
1928 MD5Update(&ctx
, confounder
, 16);
1929 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
1930 MD5Final(confounded_session_key
.data
, &ctx
);
1932 arcfour_crypt_blob(u
.info25
.password
.data
, 516, &confounded_session_key
);
1933 memcpy(&u
.info25
.password
.data
[516], confounder
, 16);
1935 torture_comment(tctx
, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
1937 status
= dcerpc_samr_SetUserInfo(p
, tctx
, &s
);
1938 if (!NT_STATUS_IS_OK(status
)) {
1939 printf("SetUserInfo level %u failed - %s\n",
1940 s
.in
.level
, nt_errstr(status
));
1944 torture_comment(tctx
, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
1946 mdfour(old_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
1948 new_random_pass
= samr_very_rand_pass(tctx
, 128);
1950 mdfour(new_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
1952 set_pw_in_buffer(nt_pass
.data
, &new_random_pass
);
1953 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
1954 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
1956 r
.in
.server
= &server
;
1957 r
.in
.account
= &account
;
1958 r
.in
.nt_password
= &nt_pass
;
1959 r
.in
.nt_verifier
= &nt_verifier
;
1961 r
.in
.lm_password
= NULL
;
1962 r
.in
.lm_verifier
= NULL
;
1963 r
.in
.password3
= NULL
;
1964 r
.out
.dominfo
= &dominfo
;
1965 r
.out
.reject
= &reject
;
1967 unix_to_nt_time(&t
, time(NULL
));
1969 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
1971 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
1972 if (reject
&& reject
->reason
!= SAMR_REJECT_OTHER
) {
1973 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1974 SAMR_REJECT_OTHER
, reject
->reason
);
1977 /* Perhaps the server has a 'min password age' set? */
1979 } else if (!NT_STATUS_IS_OK(status
)) {
1980 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status
));
1984 newpass
= samr_rand_pass(tctx
, 128);
1986 mdfour(old_nt_hash
, new_random_pass
.data
, new_random_pass
.length
);
1988 E_md4hash(newpass
, new_nt_hash
);
1990 encode_pw_buffer(nt_pass
.data
, newpass
, STR_UNICODE
);
1991 arcfour_crypt(nt_pass
.data
, old_nt_hash
, 516);
1992 E_old_pw_hash(new_nt_hash
, old_nt_hash
, nt_verifier
.hash
);
1994 r
.in
.server
= &server
;
1995 r
.in
.account
= &account
;
1996 r
.in
.nt_password
= &nt_pass
;
1997 r
.in
.nt_verifier
= &nt_verifier
;
1999 r
.in
.lm_password
= NULL
;
2000 r
.in
.lm_verifier
= NULL
;
2001 r
.in
.password3
= NULL
;
2002 r
.out
.dominfo
= &dominfo
;
2003 r
.out
.reject
= &reject
;
2005 unix_to_nt_time(&t
, time(NULL
));
2007 status
= dcerpc_samr_ChangePasswordUser3(p
, tctx
, &r
);
2009 if (NT_STATUS_EQUAL(status
, NT_STATUS_PASSWORD_RESTRICTION
)) {
2010 if (reject
&& reject
->reason
!= SAMR_REJECT_OTHER
) {
2011 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2012 SAMR_REJECT_OTHER
, reject
->reason
);
2015 /* Perhaps the server has a 'min password age' set? */
2018 torture_assert_ntstatus_ok(tctx
, status
, "ChangePasswordUser3 (on second random password)");
2019 *password
= talloc_strdup(tctx
, newpass
);
2026 static bool test_GetMembersInAlias(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2027 struct policy_handle
*alias_handle
)
2029 struct samr_GetMembersInAlias r
;
2030 struct lsa_SidArray sids
;
2033 torture_comment(tctx
, "Testing GetMembersInAlias\n");
2035 r
.in
.alias_handle
= alias_handle
;
2038 status
= dcerpc_samr_GetMembersInAlias(p
, tctx
, &r
);
2039 torture_assert_ntstatus_ok(tctx
, status
, "GetMembersInAlias");
2044 static bool test_AddMemberToAlias(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2045 struct policy_handle
*alias_handle
,
2046 const struct dom_sid
*domain_sid
)
2048 struct samr_AddAliasMember r
;
2049 struct samr_DeleteAliasMember d
;
2051 struct dom_sid
*sid
;
2053 sid
= dom_sid_add_rid(tctx
, domain_sid
, 512);
2055 torture_comment(tctx
, "testing AddAliasMember\n");
2056 r
.in
.alias_handle
= alias_handle
;
2059 status
= dcerpc_samr_AddAliasMember(p
, tctx
, &r
);
2060 torture_assert_ntstatus_ok(tctx
, status
, "AddAliasMember");
2062 d
.in
.alias_handle
= alias_handle
;
2065 status
= dcerpc_samr_DeleteAliasMember(p
, tctx
, &d
);
2066 torture_assert_ntstatus_ok(tctx
, status
, "DelAliasMember");
2071 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2072 struct policy_handle
*alias_handle
)
2074 struct samr_AddMultipleMembersToAlias a
;
2075 struct samr_RemoveMultipleMembersFromAlias r
;
2077 struct lsa_SidArray sids
;
2079 torture_comment(tctx
, "testing AddMultipleMembersToAlias\n");
2080 a
.in
.alias_handle
= alias_handle
;
2084 sids
.sids
= talloc_array(tctx
, struct lsa_SidPtr
, 3);
2086 sids
.sids
[0].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-1");
2087 sids
.sids
[1].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-2");
2088 sids
.sids
[2].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-3");
2090 status
= dcerpc_samr_AddMultipleMembersToAlias(p
, tctx
, &a
);
2091 torture_assert_ntstatus_ok(tctx
, status
, "AddMultipleMembersToAlias");
2094 torture_comment(tctx
, "testing RemoveMultipleMembersFromAlias\n");
2095 r
.in
.alias_handle
= alias_handle
;
2098 status
= dcerpc_samr_RemoveMultipleMembersFromAlias(p
, tctx
, &r
);
2099 torture_assert_ntstatus_ok(tctx
, status
, "RemoveMultipleMembersFromAlias");
2101 /* strange! removing twice doesn't give any error */
2102 status
= dcerpc_samr_RemoveMultipleMembersFromAlias(p
, tctx
, &r
);
2103 torture_assert_ntstatus_ok(tctx
, status
, "RemoveMultipleMembersFromAlias");
2105 /* but removing an alias that isn't there does */
2106 sids
.sids
[2].sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-1-2-3-4");
2108 status
= dcerpc_samr_RemoveMultipleMembersFromAlias(p
, tctx
, &r
);
2109 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
, "RemoveMultipleMembersFromAlias");
2114 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2115 struct policy_handle
*user_handle
)
2117 struct samr_TestPrivateFunctionsUser r
;
2120 torture_comment(tctx
, "Testing TestPrivateFunctionsUser\n");
2122 r
.in
.user_handle
= user_handle
;
2124 status
= dcerpc_samr_TestPrivateFunctionsUser(p
, tctx
, &r
);
2125 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_NOT_IMPLEMENTED
, "TestPrivateFunctionsUser");
2131 static bool test_user_ops(struct dcerpc_pipe
*p
,
2132 struct torture_context
*tctx
,
2133 struct policy_handle
*user_handle
,
2134 struct policy_handle
*domain_handle
,
2135 uint32_t base_acct_flags
,
2136 const char *base_acct_name
, enum torture_samr_choice which_ops
)
2138 char *password
= NULL
;
2139 struct samr_QueryUserInfo q
;
2145 const uint32_t password_fields
[] = {
2146 SAMR_FIELD_PASSWORD
,
2147 SAMR_FIELD_PASSWORD2
,
2148 SAMR_FIELD_PASSWORD
| SAMR_FIELD_PASSWORD2
,
2152 status
= test_LookupName(p
, tctx
, domain_handle
, base_acct_name
, &rid
);
2153 if (!NT_STATUS_IS_OK(status
)) {
2157 switch (which_ops
) {
2158 case TORTURE_SAMR_USER_ATTRIBUTES
:
2159 if (!test_QuerySecurity(p
, tctx
, user_handle
)) {
2163 if (!test_QueryUserInfo(p
, tctx
, user_handle
)) {
2167 if (!test_QueryUserInfo2(p
, tctx
, user_handle
)) {
2171 if (!test_SetUserInfo(p
, tctx
, user_handle
, base_acct_flags
,
2176 if (!test_GetUserPwInfo(p
, tctx
, user_handle
)) {
2180 if (!test_TestPrivateFunctionsUser(p
, tctx
, user_handle
)) {
2184 if (!test_SetUserPass(p
, tctx
, user_handle
, &password
)) {
2188 case TORTURE_SAMR_PASSWORDS
:
2189 if (base_acct_flags
& (ACB_WSTRUST
|ACB_DOMTRUST
|ACB_SVRTRUST
)) {
2190 char simple_pass
[9];
2191 char *v
= generate_random_str(tctx
, 1);
2193 ZERO_STRUCT(simple_pass
);
2194 memset(simple_pass
, *v
, sizeof(simple_pass
) - 1);
2196 printf("Testing machine account password policy rules\n");
2198 /* Workstation trust accounts don't seem to need to honour password quality policy */
2199 if (!test_SetUserPassEx(p
, tctx
, user_handle
, true, &password
)) {
2203 if (!test_ChangePasswordUser2(p
, tctx
, base_acct_name
, &password
, simple_pass
, false)) {
2207 /* reset again, to allow another 'user' password change */
2208 if (!test_SetUserPassEx(p
, tctx
, user_handle
, true, &password
)) {
2212 /* Try a 'short' password */
2213 if (!test_ChangePasswordUser2(p
, tctx
, base_acct_name
, &password
, samr_rand_pass(tctx
, 4), false)) {
2217 /* Try a compleatly random password */
2218 if (!test_ChangePasswordRandomBytes(p
, tctx
, base_acct_name
, user_handle
, &password
)) {
2223 for (i
= 0; password_fields
[i
]; i
++) {
2224 if (!test_SetUserPass_23(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
2228 /* check it was set right */
2229 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
2234 for (i
= 0; password_fields
[i
]; i
++) {
2235 if (!test_SetUserPass_25(p
, tctx
, user_handle
, password_fields
[i
], &password
)) {
2239 /* check it was set right */
2240 if (!test_ChangePasswordUser3(p
, tctx
, base_acct_name
, 0, &password
, NULL
, 0, false)) {
2245 if (!test_SetUserPassEx(p
, tctx
, user_handle
, false, &password
)) {
2249 if (!test_ChangePassword(p
, tctx
, base_acct_name
, domain_handle
, &password
)) {
2253 q
.in
.user_handle
= user_handle
;
2256 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &q
);
2257 if (!NT_STATUS_IS_OK(status
)) {
2258 printf("QueryUserInfo level %u failed - %s\n",
2259 q
.in
.level
, nt_errstr(status
));
2262 uint32_t expected_flags
= (base_acct_flags
| ACB_PWNOTREQ
| ACB_DISABLED
);
2263 if ((q
.out
.info
->info5
.acct_flags
) != expected_flags
) {
2264 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2265 q
.out
.info
->info5
.acct_flags
,
2269 if (q
.out
.info
->info5
.rid
!= rid
) {
2270 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2271 q
.out
.info
->info5
.rid
, rid
);
2277 case TORTURE_SAMR_OTHER
:
2278 /* We just need the account to exist */
2284 static bool test_alias_ops(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2285 struct policy_handle
*alias_handle
,
2286 const struct dom_sid
*domain_sid
)
2290 if (!test_QuerySecurity(p
, tctx
, alias_handle
)) {
2294 if (!test_QueryAliasInfo(p
, tctx
, alias_handle
)) {
2298 if (!test_SetAliasInfo(p
, tctx
, alias_handle
)) {
2302 if (!test_AddMemberToAlias(p
, tctx
, alias_handle
, domain_sid
)) {
2306 if (torture_setting_bool(tctx
, "samba4", false)) {
2307 printf("skipping MultipleMembers Alias tests against Samba4\n");
2311 if (!test_AddMultipleMembersToAlias(p
, tctx
, alias_handle
)) {
2319 static bool test_DeleteUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2320 struct policy_handle
*user_handle
)
2322 struct samr_DeleteUser d
;
2324 torture_comment(tctx
, "Testing DeleteUser\n");
2326 d
.in
.user_handle
= user_handle
;
2327 d
.out
.user_handle
= user_handle
;
2329 status
= dcerpc_samr_DeleteUser(p
, tctx
, &d
);
2330 torture_assert_ntstatus_ok(tctx
, status
, "DeleteUser");
2335 bool test_DeleteUser_byname(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
2336 struct policy_handle
*handle
, const char *name
)
2339 struct samr_DeleteUser d
;
2340 struct policy_handle user_handle
;
2343 status
= test_LookupName(p
, mem_ctx
, handle
, name
, &rid
);
2344 if (!NT_STATUS_IS_OK(status
)) {
2348 status
= test_OpenUser_byname(p
, mem_ctx
, handle
, name
, &user_handle
);
2349 if (!NT_STATUS_IS_OK(status
)) {
2353 d
.in
.user_handle
= &user_handle
;
2354 d
.out
.user_handle
= &user_handle
;
2355 status
= dcerpc_samr_DeleteUser(p
, mem_ctx
, &d
);
2356 if (!NT_STATUS_IS_OK(status
)) {
2363 printf("DeleteUser_byname(%s) failed - %s\n", name
, nt_errstr(status
));
2368 static bool test_DeleteGroup_byname(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
2369 struct policy_handle
*handle
, const char *name
)
2372 struct samr_OpenGroup r
;
2373 struct samr_DeleteDomainGroup d
;
2374 struct policy_handle group_handle
;
2377 status
= test_LookupName(p
, mem_ctx
, handle
, name
, &rid
);
2378 if (!NT_STATUS_IS_OK(status
)) {
2382 r
.in
.domain_handle
= handle
;
2383 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2385 r
.out
.group_handle
= &group_handle
;
2386 status
= dcerpc_samr_OpenGroup(p
, mem_ctx
, &r
);
2387 if (!NT_STATUS_IS_OK(status
)) {
2391 d
.in
.group_handle
= &group_handle
;
2392 d
.out
.group_handle
= &group_handle
;
2393 status
= dcerpc_samr_DeleteDomainGroup(p
, mem_ctx
, &d
);
2394 if (!NT_STATUS_IS_OK(status
)) {
2401 printf("DeleteGroup_byname(%s) failed - %s\n", name
, nt_errstr(status
));
2406 static bool test_DeleteAlias_byname(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
2407 struct policy_handle
*domain_handle
, const char *name
)
2410 struct samr_OpenAlias r
;
2411 struct samr_DeleteDomAlias d
;
2412 struct policy_handle alias_handle
;
2415 printf("testing DeleteAlias_byname\n");
2417 status
= test_LookupName(p
, mem_ctx
, domain_handle
, name
, &rid
);
2418 if (!NT_STATUS_IS_OK(status
)) {
2422 r
.in
.domain_handle
= domain_handle
;
2423 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2425 r
.out
.alias_handle
= &alias_handle
;
2426 status
= dcerpc_samr_OpenAlias(p
, mem_ctx
, &r
);
2427 if (!NT_STATUS_IS_OK(status
)) {
2431 d
.in
.alias_handle
= &alias_handle
;
2432 d
.out
.alias_handle
= &alias_handle
;
2433 status
= dcerpc_samr_DeleteDomAlias(p
, mem_ctx
, &d
);
2434 if (!NT_STATUS_IS_OK(status
)) {
2441 printf("DeleteAlias_byname(%s) failed - %s\n", name
, nt_errstr(status
));
2445 static bool test_DeleteAlias(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
2446 struct policy_handle
*alias_handle
)
2448 struct samr_DeleteDomAlias d
;
2451 printf("Testing DeleteAlias\n");
2453 d
.in
.alias_handle
= alias_handle
;
2454 d
.out
.alias_handle
= alias_handle
;
2456 status
= dcerpc_samr_DeleteDomAlias(p
, mem_ctx
, &d
);
2457 if (!NT_STATUS_IS_OK(status
)) {
2458 printf("DeleteAlias failed - %s\n", nt_errstr(status
));
2465 static bool test_CreateAlias(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2466 struct policy_handle
*domain_handle
,
2467 struct policy_handle
*alias_handle
,
2468 const struct dom_sid
*domain_sid
)
2471 struct samr_CreateDomAlias r
;
2472 struct lsa_String name
;
2476 init_lsa_String(&name
, TEST_ALIASNAME
);
2477 r
.in
.domain_handle
= domain_handle
;
2478 r
.in
.alias_name
= &name
;
2479 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2480 r
.out
.alias_handle
= alias_handle
;
2483 printf("Testing CreateAlias (%s)\n", r
.in
.alias_name
->string
);
2485 status
= dcerpc_samr_CreateDomAlias(p
, tctx
, &r
);
2487 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
2488 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
2489 printf("Server correctly refused create of '%s'\n", r
.in
.alias_name
->string
);
2492 printf("Server should have refused create of '%s', got %s instead\n", r
.in
.alias_name
->string
,
2498 if (NT_STATUS_EQUAL(status
, NT_STATUS_ALIAS_EXISTS
)) {
2499 if (!test_DeleteAlias_byname(p
, tctx
, domain_handle
, r
.in
.alias_name
->string
)) {
2502 status
= dcerpc_samr_CreateDomAlias(p
, tctx
, &r
);
2505 if (!NT_STATUS_IS_OK(status
)) {
2506 printf("CreateAlias failed - %s\n", nt_errstr(status
));
2510 if (!test_alias_ops(p
, tctx
, alias_handle
, domain_sid
)) {
2517 static bool test_ChangePassword(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
2518 const char *acct_name
,
2519 struct policy_handle
*domain_handle
, char **password
)
2527 if (!test_ChangePasswordUser(p
, mem_ctx
, acct_name
, domain_handle
, password
)) {
2531 if (!test_ChangePasswordUser2(p
, mem_ctx
, acct_name
, password
, 0, true)) {
2535 if (!test_OemChangePasswordUser2(p
, mem_ctx
, acct_name
, domain_handle
, password
)) {
2539 /* test what happens when setting the old password again */
2540 if (!test_ChangePasswordUser3(p
, mem_ctx
, acct_name
, 0, password
, *password
, 0, true)) {
2545 char simple_pass
[9];
2546 char *v
= generate_random_str(mem_ctx
, 1);
2548 ZERO_STRUCT(simple_pass
);
2549 memset(simple_pass
, *v
, sizeof(simple_pass
) - 1);
2551 /* test what happens when picking a simple password */
2552 if (!test_ChangePasswordUser3(p
, mem_ctx
, acct_name
, 0, password
, simple_pass
, 0, true)) {
2557 /* set samr_SetDomainInfo level 1 with min_length 5 */
2559 struct samr_QueryDomainInfo r
;
2560 union samr_DomainInfo
*info
= NULL
;
2561 struct samr_SetDomainInfo s
;
2562 uint16_t len_old
, len
;
2563 uint32_t pwd_prop_old
;
2564 int64_t min_pwd_age_old
;
2569 r
.in
.domain_handle
= domain_handle
;
2573 printf("testing samr_QueryDomainInfo level 1\n");
2574 status
= dcerpc_samr_QueryDomainInfo(p
, mem_ctx
, &r
);
2575 if (!NT_STATUS_IS_OK(status
)) {
2579 s
.in
.domain_handle
= domain_handle
;
2583 /* remember the old min length, so we can reset it */
2584 len_old
= s
.in
.info
->info1
.min_password_length
;
2585 s
.in
.info
->info1
.min_password_length
= len
;
2586 pwd_prop_old
= s
.in
.info
->info1
.password_properties
;
2587 /* turn off password complexity checks for this test */
2588 s
.in
.info
->info1
.password_properties
&= ~DOMAIN_PASSWORD_COMPLEX
;
2590 min_pwd_age_old
= s
.in
.info
->info1
.min_password_age
;
2591 s
.in
.info
->info1
.min_password_age
= 0;
2593 printf("testing samr_SetDomainInfo level 1\n");
2594 status
= dcerpc_samr_SetDomainInfo(p
, mem_ctx
, &s
);
2595 if (!NT_STATUS_IS_OK(status
)) {
2599 printf("calling test_ChangePasswordUser3 with too short password\n");
2601 if (!test_ChangePasswordUser3(p
, mem_ctx
, acct_name
, len
- 1, password
, NULL
, 0, true)) {
2605 s
.in
.info
->info1
.min_password_length
= len_old
;
2606 s
.in
.info
->info1
.password_properties
= pwd_prop_old
;
2607 s
.in
.info
->info1
.min_password_age
= min_pwd_age_old
;
2609 printf("testing samr_SetDomainInfo level 1\n");
2610 status
= dcerpc_samr_SetDomainInfo(p
, mem_ctx
, &s
);
2611 if (!NT_STATUS_IS_OK(status
)) {
2619 struct samr_OpenUser r
;
2620 struct samr_QueryUserInfo q
;
2621 struct samr_LookupNames n
;
2622 struct policy_handle user_handle
;
2624 n
.in
.domain_handle
= domain_handle
;
2626 n
.in
.names
= talloc_array(mem_ctx
, struct lsa_String
, 1);
2627 n
.in
.names
[0].string
= acct_name
;
2629 status
= dcerpc_samr_LookupNames(p
, mem_ctx
, &n
);
2630 if (!NT_STATUS_IS_OK(status
)) {
2631 printf("LookupNames failed - %s\n", nt_errstr(status
));
2635 r
.in
.domain_handle
= domain_handle
;
2636 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2637 r
.in
.rid
= n
.out
.rids
.ids
[0];
2638 r
.out
.user_handle
= &user_handle
;
2640 status
= dcerpc_samr_OpenUser(p
, mem_ctx
, &r
);
2641 if (!NT_STATUS_IS_OK(status
)) {
2642 printf("OpenUser(%u) failed - %s\n", n
.out
.rids
.ids
[0], nt_errstr(status
));
2646 q
.in
.user_handle
= &user_handle
;
2649 status
= dcerpc_samr_QueryUserInfo(p
, mem_ctx
, &q
);
2650 if (!NT_STATUS_IS_OK(status
)) {
2651 printf("QueryUserInfo failed - %s\n", nt_errstr(status
));
2655 printf("calling test_ChangePasswordUser3 with too early password change\n");
2657 if (!test_ChangePasswordUser3(p
, mem_ctx
, acct_name
, 0, password
, NULL
,
2658 q
.out
.info
->info5
.last_password_change
, true)) {
2663 /* we change passwords twice - this has the effect of verifying
2664 they were changed correctly for the final call */
2665 if (!test_ChangePasswordUser3(p
, mem_ctx
, acct_name
, 0, password
, NULL
, 0, true)) {
2669 if (!test_ChangePasswordUser3(p
, mem_ctx
, acct_name
, 0, password
, NULL
, 0, true)) {
2676 static bool test_CreateUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2677 struct policy_handle
*domain_handle
,
2678 struct policy_handle
*user_handle_out
,
2679 struct dom_sid
*domain_sid
,
2680 enum torture_samr_choice which_ops
)
2683 TALLOC_CTX
*user_ctx
;
2686 struct samr_CreateUser r
;
2687 struct samr_QueryUserInfo q
;
2688 struct samr_DeleteUser d
;
2691 /* This call creates a 'normal' account - check that it really does */
2692 const uint32_t acct_flags
= ACB_NORMAL
;
2693 struct lsa_String name
;
2696 struct policy_handle user_handle
;
2697 user_ctx
= talloc_named(tctx
, 0, "test_CreateUser2 per-user context");
2698 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
2700 r
.in
.domain_handle
= domain_handle
;
2701 r
.in
.account_name
= &name
;
2702 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2703 r
.out
.user_handle
= &user_handle
;
2706 printf("Testing CreateUser(%s)\n", r
.in
.account_name
->string
);
2708 status
= dcerpc_samr_CreateUser(p
, user_ctx
, &r
);
2710 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
2711 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) || NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
2712 printf("Server correctly refused create of '%s'\n", r
.in
.account_name
->string
);
2715 printf("Server should have refused create of '%s', got %s instead\n", r
.in
.account_name
->string
,
2721 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_EXISTS
)) {
2722 if (!test_DeleteUser_byname(p
, user_ctx
, domain_handle
, r
.in
.account_name
->string
)) {
2723 talloc_free(user_ctx
);
2726 status
= dcerpc_samr_CreateUser(p
, user_ctx
, &r
);
2728 if (!NT_STATUS_IS_OK(status
)) {
2729 talloc_free(user_ctx
);
2730 printf("CreateUser failed - %s\n", nt_errstr(status
));
2733 q
.in
.user_handle
= &user_handle
;
2736 status
= dcerpc_samr_QueryUserInfo(p
, user_ctx
, &q
);
2737 if (!NT_STATUS_IS_OK(status
)) {
2738 printf("QueryUserInfo level %u failed - %s\n",
2739 q
.in
.level
, nt_errstr(status
));
2742 if ((q
.out
.info
->info16
.acct_flags
& acct_flags
) != acct_flags
) {
2743 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2744 q
.out
.info
->info16
.acct_flags
,
2750 if (!test_user_ops(p
, tctx
, &user_handle
, domain_handle
,
2751 acct_flags
, name
.string
, which_ops
)) {
2755 if (user_handle_out
) {
2756 *user_handle_out
= user_handle
;
2758 printf("Testing DeleteUser (createuser test)\n");
2760 d
.in
.user_handle
= &user_handle
;
2761 d
.out
.user_handle
= &user_handle
;
2763 status
= dcerpc_samr_DeleteUser(p
, user_ctx
, &d
);
2764 if (!NT_STATUS_IS_OK(status
)) {
2765 printf("DeleteUser failed - %s\n", nt_errstr(status
));
2772 talloc_free(user_ctx
);
2778 static bool test_CreateUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
2779 struct policy_handle
*domain_handle
,
2780 struct dom_sid
*domain_sid
,
2781 enum torture_samr_choice which_ops
)
2784 struct samr_CreateUser2 r
;
2785 struct samr_QueryUserInfo q
;
2786 struct samr_DeleteUser d
;
2787 struct policy_handle user_handle
;
2789 struct lsa_String name
;
2794 uint32_t acct_flags
;
2795 const char *account_name
;
2797 } account_types
[] = {
2798 { ACB_NORMAL
, TEST_ACCOUNT_NAME
, NT_STATUS_OK
},
2799 { ACB_NORMAL
| ACB_DISABLED
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
2800 { ACB_NORMAL
| ACB_PWNOEXP
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
2801 { ACB_WSTRUST
, TEST_MACHINENAME
, NT_STATUS_OK
},
2802 { ACB_WSTRUST
| ACB_DISABLED
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
2803 { ACB_WSTRUST
| ACB_PWNOEXP
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
2804 { ACB_SVRTRUST
, TEST_MACHINENAME
, NT_STATUS_OK
},
2805 { ACB_SVRTRUST
| ACB_DISABLED
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
2806 { ACB_SVRTRUST
| ACB_PWNOEXP
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
2807 { ACB_DOMTRUST
, TEST_DOMAINNAME
, NT_STATUS_OK
},
2808 { ACB_DOMTRUST
| ACB_DISABLED
, TEST_DOMAINNAME
, NT_STATUS_INVALID_PARAMETER
},
2809 { ACB_DOMTRUST
| ACB_PWNOEXP
, TEST_DOMAINNAME
, NT_STATUS_INVALID_PARAMETER
},
2810 { 0, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
2811 { ACB_DISABLED
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
2812 { 0, NULL
, NT_STATUS_INVALID_PARAMETER
}
2815 for (i
= 0; account_types
[i
].account_name
; i
++) {
2816 TALLOC_CTX
*user_ctx
;
2817 uint32_t acct_flags
= account_types
[i
].acct_flags
;
2818 uint32_t access_granted
;
2819 user_ctx
= talloc_named(tctx
, 0, "test_CreateUser2 per-user context");
2820 init_lsa_String(&name
, account_types
[i
].account_name
);
2822 r
.in
.domain_handle
= domain_handle
;
2823 r
.in
.account_name
= &name
;
2824 r
.in
.acct_flags
= acct_flags
;
2825 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2826 r
.out
.user_handle
= &user_handle
;
2827 r
.out
.access_granted
= &access_granted
;
2830 printf("Testing CreateUser2(%s, 0x%x)\n", r
.in
.account_name
->string
, acct_flags
);
2832 status
= dcerpc_samr_CreateUser2(p
, user_ctx
, &r
);
2834 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
2835 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) || NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
2836 printf("Server correctly refused create of '%s'\n", r
.in
.account_name
->string
);
2839 printf("Server should have refused create of '%s', got %s instead\n", r
.in
.account_name
->string
,
2846 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_EXISTS
)) {
2847 if (!test_DeleteUser_byname(p
, user_ctx
, domain_handle
, r
.in
.account_name
->string
)) {
2848 talloc_free(user_ctx
);
2852 status
= dcerpc_samr_CreateUser2(p
, user_ctx
, &r
);
2855 if (!NT_STATUS_EQUAL(status
, account_types
[i
].nt_status
)) {
2856 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2857 nt_errstr(status
), nt_errstr(account_types
[i
].nt_status
));
2861 if (NT_STATUS_IS_OK(status
)) {
2862 q
.in
.user_handle
= &user_handle
;
2865 status
= dcerpc_samr_QueryUserInfo(p
, user_ctx
, &q
);
2866 if (!NT_STATUS_IS_OK(status
)) {
2867 printf("QueryUserInfo level %u failed - %s\n",
2868 q
.in
.level
, nt_errstr(status
));
2871 uint32_t expected_flags
= (acct_flags
| ACB_PWNOTREQ
| ACB_DISABLED
);
2872 if (acct_flags
== ACB_NORMAL
) {
2873 expected_flags
|= ACB_PW_EXPIRED
;
2875 if ((q
.out
.info
->info5
.acct_flags
) != expected_flags
) {
2876 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2877 q
.out
.info
->info5
.acct_flags
,
2881 switch (acct_flags
) {
2883 if (q
.out
.info
->info5
.primary_gid
!= DOMAIN_RID_DCS
) {
2884 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2885 DOMAIN_RID_DCS
, q
.out
.info
->info5
.primary_gid
);
2890 if (q
.out
.info
->info5
.primary_gid
!= DOMAIN_RID_DOMAIN_MEMBERS
) {
2891 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2892 DOMAIN_RID_DOMAIN_MEMBERS
, q
.out
.info
->info5
.primary_gid
);
2897 if (q
.out
.info
->info5
.primary_gid
!= DOMAIN_RID_USERS
) {
2898 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2899 DOMAIN_RID_USERS
, q
.out
.info
->info5
.primary_gid
);
2906 if (!test_user_ops(p
, tctx
, &user_handle
, domain_handle
,
2907 acct_flags
, name
.string
, which_ops
)) {
2911 printf("Testing DeleteUser (createuser2 test)\n");
2913 d
.in
.user_handle
= &user_handle
;
2914 d
.out
.user_handle
= &user_handle
;
2916 status
= dcerpc_samr_DeleteUser(p
, user_ctx
, &d
);
2917 if (!NT_STATUS_IS_OK(status
)) {
2918 printf("DeleteUser failed - %s\n", nt_errstr(status
));
2922 talloc_free(user_ctx
);
2928 static bool test_QueryAliasInfo(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
2929 struct policy_handle
*handle
)
2932 struct samr_QueryAliasInfo r
;
2933 uint16_t levels
[] = {1, 2, 3};
2937 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
2938 printf("Testing QueryAliasInfo level %u\n", levels
[i
]);
2940 r
.in
.alias_handle
= handle
;
2941 r
.in
.level
= levels
[i
];
2943 status
= dcerpc_samr_QueryAliasInfo(p
, mem_ctx
, &r
);
2944 if (!NT_STATUS_IS_OK(status
)) {
2945 printf("QueryAliasInfo level %u failed - %s\n",
2946 levels
[i
], nt_errstr(status
));
2954 static bool test_QueryGroupInfo(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
2955 struct policy_handle
*handle
)
2958 struct samr_QueryGroupInfo r
;
2959 uint16_t levels
[] = {1, 2, 3, 4, 5};
2963 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
2964 printf("Testing QueryGroupInfo level %u\n", levels
[i
]);
2966 r
.in
.group_handle
= handle
;
2967 r
.in
.level
= levels
[i
];
2969 status
= dcerpc_samr_QueryGroupInfo(p
, mem_ctx
, &r
);
2970 if (!NT_STATUS_IS_OK(status
)) {
2971 printf("QueryGroupInfo level %u failed - %s\n",
2972 levels
[i
], nt_errstr(status
));
2980 static bool test_QueryGroupMember(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
2981 struct policy_handle
*handle
)
2984 struct samr_QueryGroupMember r
;
2985 struct samr_RidTypeArray
*rids
= NULL
;
2988 printf("Testing QueryGroupMember\n");
2990 r
.in
.group_handle
= handle
;
2993 status
= dcerpc_samr_QueryGroupMember(p
, mem_ctx
, &r
);
2994 if (!NT_STATUS_IS_OK(status
)) {
2995 printf("QueryGroupInfo failed - %s\n", nt_errstr(status
));
3003 static bool test_SetGroupInfo(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
3004 struct policy_handle
*handle
)
3007 struct samr_QueryGroupInfo r
;
3008 struct samr_SetGroupInfo s
;
3009 uint16_t levels
[] = {1, 2, 3, 4};
3010 uint16_t set_ok
[] = {0, 1, 1, 1};
3014 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
3015 printf("Testing QueryGroupInfo level %u\n", levels
[i
]);
3017 r
.in
.group_handle
= handle
;
3018 r
.in
.level
= levels
[i
];
3020 status
= dcerpc_samr_QueryGroupInfo(p
, mem_ctx
, &r
);
3021 if (!NT_STATUS_IS_OK(status
)) {
3022 printf("QueryGroupInfo level %u failed - %s\n",
3023 levels
[i
], nt_errstr(status
));
3027 printf("Testing SetGroupInfo level %u\n", levels
[i
]);
3029 s
.in
.group_handle
= handle
;
3030 s
.in
.level
= levels
[i
];
3031 s
.in
.info
= r
.out
.info
;
3034 /* disabled this, as it changes the name only from the point of view of samr,
3035 but leaves the name from the point of view of w2k3 internals (and ldap). This means
3036 the name is still reserved, so creating the old name fails, but deleting by the old name
3038 if (s
.in
.level
== 2) {
3039 init_lsa_String(&s
.in
.info
->string
, "NewName");
3043 if (s
.in
.level
== 4) {
3044 init_lsa_String(&s
.in
.info
->description
, "test description");
3047 status
= dcerpc_samr_SetGroupInfo(p
, mem_ctx
, &s
);
3049 if (!NT_STATUS_IS_OK(status
)) {
3050 printf("SetGroupInfo level %u failed - %s\n",
3051 r
.in
.level
, nt_errstr(status
));
3056 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, status
)) {
3057 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3058 r
.in
.level
, nt_errstr(status
));
3068 static bool test_QueryUserInfo(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
3069 struct policy_handle
*handle
)
3072 struct samr_QueryUserInfo r
;
3073 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3074 11, 12, 13, 14, 16, 17, 20, 21};
3078 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
3079 printf("Testing QueryUserInfo level %u\n", levels
[i
]);
3081 r
.in
.user_handle
= handle
;
3082 r
.in
.level
= levels
[i
];
3084 status
= dcerpc_samr_QueryUserInfo(p
, mem_ctx
, &r
);
3085 if (!NT_STATUS_IS_OK(status
)) {
3086 printf("QueryUserInfo level %u failed - %s\n",
3087 levels
[i
], nt_errstr(status
));
3095 static bool test_QueryUserInfo2(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
3096 struct policy_handle
*handle
)
3099 struct samr_QueryUserInfo2 r
;
3100 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3101 11, 12, 13, 14, 16, 17, 20, 21};
3105 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
3106 printf("Testing QueryUserInfo2 level %u\n", levels
[i
]);
3108 r
.in
.user_handle
= handle
;
3109 r
.in
.level
= levels
[i
];
3111 status
= dcerpc_samr_QueryUserInfo2(p
, mem_ctx
, &r
);
3112 if (!NT_STATUS_IS_OK(status
)) {
3113 printf("QueryUserInfo2 level %u failed - %s\n",
3114 levels
[i
], nt_errstr(status
));
3122 static bool test_OpenUser(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
3123 struct policy_handle
*handle
, uint32_t rid
)
3126 struct samr_OpenUser r
;
3127 struct policy_handle user_handle
;
3130 printf("Testing OpenUser(%u)\n", rid
);
3132 r
.in
.domain_handle
= handle
;
3133 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3135 r
.out
.user_handle
= &user_handle
;
3137 status
= dcerpc_samr_OpenUser(p
, mem_ctx
, &r
);
3138 if (!NT_STATUS_IS_OK(status
)) {
3139 printf("OpenUser(%u) failed - %s\n", rid
, nt_errstr(status
));
3143 if (!test_QuerySecurity(p
, mem_ctx
, &user_handle
)) {
3147 if (!test_QueryUserInfo(p
, mem_ctx
, &user_handle
)) {
3151 if (!test_QueryUserInfo2(p
, mem_ctx
, &user_handle
)) {
3155 if (!test_GetUserPwInfo(p
, mem_ctx
, &user_handle
)) {
3159 if (!test_GetGroupsForUser(p
,mem_ctx
, &user_handle
)) {
3163 if (!test_samr_handle_Close(p
, mem_ctx
, &user_handle
)) {
3170 static bool test_OpenGroup(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
3171 struct policy_handle
*handle
, uint32_t rid
)
3174 struct samr_OpenGroup r
;
3175 struct policy_handle group_handle
;
3178 printf("Testing OpenGroup(%u)\n", rid
);
3180 r
.in
.domain_handle
= handle
;
3181 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3183 r
.out
.group_handle
= &group_handle
;
3185 status
= dcerpc_samr_OpenGroup(p
, mem_ctx
, &r
);
3186 if (!NT_STATUS_IS_OK(status
)) {
3187 printf("OpenGroup(%u) failed - %s\n", rid
, nt_errstr(status
));
3191 if (!test_QuerySecurity(p
, mem_ctx
, &group_handle
)) {
3195 if (!test_QueryGroupInfo(p
, mem_ctx
, &group_handle
)) {
3199 if (!test_QueryGroupMember(p
, mem_ctx
, &group_handle
)) {
3203 if (!test_samr_handle_Close(p
, mem_ctx
, &group_handle
)) {
3210 static bool test_OpenAlias(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
3211 struct policy_handle
*handle
, uint32_t rid
)
3214 struct samr_OpenAlias r
;
3215 struct policy_handle alias_handle
;
3218 torture_comment(tctx
, "Testing OpenAlias(%u)\n", rid
);
3220 r
.in
.domain_handle
= handle
;
3221 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3223 r
.out
.alias_handle
= &alias_handle
;
3225 status
= dcerpc_samr_OpenAlias(p
, tctx
, &r
);
3226 if (!NT_STATUS_IS_OK(status
)) {
3227 printf("OpenAlias(%u) failed - %s\n", rid
, nt_errstr(status
));
3231 if (!test_QuerySecurity(p
, tctx
, &alias_handle
)) {
3235 if (!test_QueryAliasInfo(p
, tctx
, &alias_handle
)) {
3239 if (!test_GetMembersInAlias(p
, tctx
, &alias_handle
)) {
3243 if (!test_samr_handle_Close(p
, tctx
, &alias_handle
)) {
3250 static bool check_mask(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
3251 struct policy_handle
*handle
, uint32_t rid
,
3252 uint32_t acct_flag_mask
)
3255 struct samr_OpenUser r
;
3256 struct samr_QueryUserInfo q
;
3257 struct policy_handle user_handle
;
3260 torture_comment(tctx
, "Testing OpenUser(%u)\n", rid
);
3262 r
.in
.domain_handle
= handle
;
3263 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3265 r
.out
.user_handle
= &user_handle
;
3267 status
= dcerpc_samr_OpenUser(p
, tctx
, &r
);
3268 if (!NT_STATUS_IS_OK(status
)) {
3269 printf("OpenUser(%u) failed - %s\n", rid
, nt_errstr(status
));
3273 q
.in
.user_handle
= &user_handle
;
3276 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &q
);
3277 if (!NT_STATUS_IS_OK(status
)) {
3278 printf("QueryUserInfo level 16 failed - %s\n",
3282 if ((acct_flag_mask
& q
.out
.info
->info16
.acct_flags
) == 0) {
3283 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3284 acct_flag_mask
, q
.out
.info
->info16
.acct_flags
, rid
);
3289 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
3296 static bool test_EnumDomainUsers(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
3297 struct policy_handle
*handle
)
3299 NTSTATUS status
= STATUS_MORE_ENTRIES
;
3300 struct samr_EnumDomainUsers r
;
3301 uint32_t mask
, resume_handle
=0;
3304 struct samr_LookupNames n
;
3305 struct samr_LookupRids lr
;
3306 struct lsa_Strings names
;
3307 struct samr_Ids types
;
3309 uint32_t masks
[] = {ACB_NORMAL
, ACB_DOMTRUST
, ACB_WSTRUST
,
3310 ACB_DISABLED
, ACB_NORMAL
| ACB_DISABLED
,
3311 ACB_SVRTRUST
| ACB_DOMTRUST
| ACB_WSTRUST
,
3314 printf("Testing EnumDomainUsers\n");
3316 for (mask_idx
=0;mask_idx
<ARRAY_SIZE(masks
);mask_idx
++) {
3317 r
.in
.domain_handle
= handle
;
3318 r
.in
.resume_handle
= &resume_handle
;
3319 r
.in
.acct_flags
= mask
= masks
[mask_idx
];
3320 r
.in
.max_size
= (uint32_t)-1;
3321 r
.out
.resume_handle
= &resume_handle
;
3323 status
= dcerpc_samr_EnumDomainUsers(p
, tctx
, &r
);
3324 if (!NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) &&
3325 !NT_STATUS_IS_OK(status
)) {
3326 printf("EnumDomainUsers failed - %s\n", nt_errstr(status
));
3330 torture_assert(tctx
, r
.out
.sam
, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
3332 if (r
.out
.sam
->count
== 0) {
3336 for (i
=0;i
<r
.out
.sam
->count
;i
++) {
3338 if (!check_mask(p
, tctx
, handle
, r
.out
.sam
->entries
[i
].idx
, mask
)) {
3341 } else if (!test_OpenUser(p
, tctx
, handle
, r
.out
.sam
->entries
[i
].idx
)) {
3347 printf("Testing LookupNames\n");
3348 n
.in
.domain_handle
= handle
;
3349 n
.in
.num_names
= r
.out
.sam
->count
;
3350 n
.in
.names
= talloc_array(tctx
, struct lsa_String
, r
.out
.sam
->count
);
3351 for (i
=0;i
<r
.out
.sam
->count
;i
++) {
3352 n
.in
.names
[i
].string
= r
.out
.sam
->entries
[i
].name
.string
;
3354 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
3355 if (!NT_STATUS_IS_OK(status
)) {
3356 printf("LookupNames failed - %s\n", nt_errstr(status
));
3361 printf("Testing LookupRids\n");
3362 lr
.in
.domain_handle
= handle
;
3363 lr
.in
.num_rids
= r
.out
.sam
->count
;
3364 lr
.in
.rids
= talloc_array(tctx
, uint32_t, r
.out
.sam
->count
);
3365 lr
.out
.names
= &names
;
3366 lr
.out
.types
= &types
;
3367 for (i
=0;i
<r
.out
.sam
->count
;i
++) {
3368 lr
.in
.rids
[i
] = r
.out
.sam
->entries
[i
].idx
;
3370 status
= dcerpc_samr_LookupRids(p
, tctx
, &lr
);
3371 torture_assert_ntstatus_ok(tctx
, status
, "LookupRids");
3377 try blasting the server with a bunch of sync requests
3379 static bool test_EnumDomainUsers_async(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
3380 struct policy_handle
*handle
)
3383 struct samr_EnumDomainUsers r
;
3384 uint32_t resume_handle
=0;
3386 #define ASYNC_COUNT 100
3387 struct rpc_request
*req
[ASYNC_COUNT
];
3389 if (!torture_setting_bool(tctx
, "dangerous", false)) {
3390 torture_skip(tctx
, "samr async test disabled - enable dangerous tests to use\n");
3393 torture_comment(tctx
, "Testing EnumDomainUsers_async\n");
3395 r
.in
.domain_handle
= handle
;
3396 r
.in
.resume_handle
= &resume_handle
;
3397 r
.in
.acct_flags
= 0;
3398 r
.in
.max_size
= (uint32_t)-1;
3399 r
.out
.resume_handle
= &resume_handle
;
3401 for (i
=0;i
<ASYNC_COUNT
;i
++) {
3402 req
[i
] = dcerpc_samr_EnumDomainUsers_send(p
, tctx
, &r
);
3405 for (i
=0;i
<ASYNC_COUNT
;i
++) {
3406 status
= dcerpc_ndr_request_recv(req
[i
]);
3407 if (!NT_STATUS_IS_OK(status
)) {
3408 printf("EnumDomainUsers[%d] failed - %s\n",
3409 i
, nt_errstr(status
));
3414 torture_comment(tctx
, "%d async requests OK\n", i
);
3419 static bool test_EnumDomainGroups(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
3420 struct policy_handle
*handle
)
3423 struct samr_EnumDomainGroups r
;
3424 uint32_t resume_handle
=0;
3428 printf("Testing EnumDomainGroups\n");
3430 r
.in
.domain_handle
= handle
;
3431 r
.in
.resume_handle
= &resume_handle
;
3432 r
.in
.max_size
= (uint32_t)-1;
3433 r
.out
.resume_handle
= &resume_handle
;
3435 status
= dcerpc_samr_EnumDomainGroups(p
, mem_ctx
, &r
);
3436 if (!NT_STATUS_IS_OK(status
)) {
3437 printf("EnumDomainGroups failed - %s\n", nt_errstr(status
));
3445 for (i
=0;i
<r
.out
.sam
->count
;i
++) {
3446 if (!test_OpenGroup(p
, mem_ctx
, handle
, r
.out
.sam
->entries
[i
].idx
)) {
3454 static bool test_EnumDomainAliases(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
3455 struct policy_handle
*handle
)
3458 struct samr_EnumDomainAliases r
;
3459 uint32_t resume_handle
=0;
3463 printf("Testing EnumDomainAliases\n");
3465 r
.in
.domain_handle
= handle
;
3466 r
.in
.resume_handle
= &resume_handle
;
3467 r
.in
.acct_flags
= (uint32_t)-1;
3468 r
.out
.resume_handle
= &resume_handle
;
3470 status
= dcerpc_samr_EnumDomainAliases(p
, mem_ctx
, &r
);
3471 if (!NT_STATUS_IS_OK(status
)) {
3472 printf("EnumDomainAliases failed - %s\n", nt_errstr(status
));
3480 for (i
=0;i
<r
.out
.sam
->count
;i
++) {
3481 if (!test_OpenAlias(p
, mem_ctx
, handle
, r
.out
.sam
->entries
[i
].idx
)) {
3489 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
3490 struct policy_handle
*handle
)
3493 struct samr_GetDisplayEnumerationIndex r
;
3495 uint16_t levels
[] = {1, 2, 3, 4, 5};
3496 uint16_t ok_lvl
[] = {1, 1, 1, 0, 0};
3497 struct lsa_String name
;
3501 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
3502 printf("Testing GetDisplayEnumerationIndex level %u\n", levels
[i
]);
3504 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
3506 r
.in
.domain_handle
= handle
;
3507 r
.in
.level
= levels
[i
];
3511 status
= dcerpc_samr_GetDisplayEnumerationIndex(p
, mem_ctx
, &r
);
3514 !NT_STATUS_IS_OK(status
) &&
3515 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
3516 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3517 levels
[i
], nt_errstr(status
));
3521 init_lsa_String(&name
, "zzzzzzzz");
3523 status
= dcerpc_samr_GetDisplayEnumerationIndex(p
, mem_ctx
, &r
);
3525 if (ok_lvl
[i
] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
3526 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3527 levels
[i
], nt_errstr(status
));
3535 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
3536 struct policy_handle
*handle
)
3539 struct samr_GetDisplayEnumerationIndex2 r
;
3541 uint16_t levels
[] = {1, 2, 3, 4, 5};
3542 uint16_t ok_lvl
[] = {1, 1, 1, 0, 0};
3543 struct lsa_String name
;
3547 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
3548 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels
[i
]);
3550 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
3552 r
.in
.domain_handle
= handle
;
3553 r
.in
.level
= levels
[i
];
3557 status
= dcerpc_samr_GetDisplayEnumerationIndex2(p
, mem_ctx
, &r
);
3559 !NT_STATUS_IS_OK(status
) &&
3560 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
3561 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3562 levels
[i
], nt_errstr(status
));
3566 init_lsa_String(&name
, "zzzzzzzz");
3568 status
= dcerpc_samr_GetDisplayEnumerationIndex2(p
, mem_ctx
, &r
);
3569 if (ok_lvl
[i
] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
3570 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3571 levels
[i
], nt_errstr(status
));
3579 #define STRING_EQUAL_QUERY(s1, s2, user) \
3580 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3581 /* odd, but valid */ \
3582 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3583 printf("%s mismatch for %s: %s != %s (%s)\n", \
3584 #s1, user.string, s1.string, s2.string, __location__); \
3587 #define INT_EQUAL_QUERY(s1, s2, user) \
3589 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3590 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3594 static bool test_each_DisplayInfo_user(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
3595 struct samr_QueryDisplayInfo
*querydisplayinfo
,
3596 bool *seen_testuser
)
3598 struct samr_OpenUser r
;
3599 struct samr_QueryUserInfo q
;
3600 struct policy_handle user_handle
;
3603 r
.in
.domain_handle
= querydisplayinfo
->in
.domain_handle
;
3604 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3605 for (i
= 0; ; i
++) {
3606 switch (querydisplayinfo
->in
.level
) {
3608 if (i
>= querydisplayinfo
->out
.info
->info1
.count
) {
3611 r
.in
.rid
= querydisplayinfo
->out
.info
->info1
.entries
[i
].rid
;
3614 if (i
>= querydisplayinfo
->out
.info
->info2
.count
) {
3617 r
.in
.rid
= querydisplayinfo
->out
.info
->info2
.entries
[i
].rid
;
3623 /* Not interested in validating just the account name */
3627 r
.out
.user_handle
= &user_handle
;
3629 switch (querydisplayinfo
->in
.level
) {
3632 status
= dcerpc_samr_OpenUser(p
, mem_ctx
, &r
);
3633 if (!NT_STATUS_IS_OK(status
)) {
3634 printf("OpenUser(%u) failed - %s\n", r
.in
.rid
, nt_errstr(status
));
3639 q
.in
.user_handle
= &user_handle
;
3641 status
= dcerpc_samr_QueryUserInfo(p
, mem_ctx
, &q
);
3642 if (!NT_STATUS_IS_OK(status
)) {
3643 printf("QueryUserInfo(%u) failed - %s\n", r
.in
.rid
, nt_errstr(status
));
3647 switch (querydisplayinfo
->in
.level
) {
3649 if (seen_testuser
&& strcmp(q
.out
.info
->info21
.account_name
.string
, TEST_ACCOUNT_NAME
) == 0) {
3650 *seen_testuser
= true;
3652 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].full_name
,
3653 q
.out
.info
->info21
.full_name
, q
.out
.info
->info21
.account_name
);
3654 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].account_name
,
3655 q
.out
.info
->info21
.account_name
, q
.out
.info
->info21
.account_name
);
3656 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].description
,
3657 q
.out
.info
->info21
.description
, q
.out
.info
->info21
.account_name
);
3658 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].rid
,
3659 q
.out
.info
->info21
.rid
, q
.out
.info
->info21
.account_name
);
3660 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].acct_flags
,
3661 q
.out
.info
->info21
.acct_flags
, q
.out
.info
->info21
.account_name
);
3665 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].account_name
,
3666 q
.out
.info
->info21
.account_name
, q
.out
.info
->info21
.account_name
);
3667 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].description
,
3668 q
.out
.info
->info21
.description
, q
.out
.info
->info21
.account_name
);
3669 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].rid
,
3670 q
.out
.info
->info21
.rid
, q
.out
.info
->info21
.account_name
);
3671 INT_EQUAL_QUERY((querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
& ~ACB_NORMAL
),
3672 q
.out
.info
->info21
.acct_flags
, q
.out
.info
->info21
.account_name
);
3674 if (!(querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
& ACB_NORMAL
)) {
3675 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
3676 q
.out
.info
->info21
.account_name
.string
);
3679 if (!(q
.out
.info
->info21
.acct_flags
& (ACB_WSTRUST
| ACB_SVRTRUST
))) {
3680 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3681 q
.out
.info
->info21
.account_name
.string
,
3682 querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
,
3683 q
.out
.info
->info21
.acct_flags
);
3690 if (!test_samr_handle_Close(p
, mem_ctx
, &user_handle
)) {
3697 static bool test_QueryDisplayInfo(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
3698 struct policy_handle
*handle
)
3701 struct samr_QueryDisplayInfo r
;
3702 struct samr_QueryDomainInfo dom_info
;
3703 union samr_DomainInfo
*info
= NULL
;
3705 uint16_t levels
[] = {1, 2, 3, 4, 5};
3707 bool seen_testuser
= false;
3708 uint32_t total_size
;
3709 uint32_t returned_size
;
3710 union samr_DispInfo disp_info
;
3713 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
3714 printf("Testing QueryDisplayInfo level %u\n", levels
[i
]);
3717 status
= STATUS_MORE_ENTRIES
;
3718 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
3719 r
.in
.domain_handle
= handle
;
3720 r
.in
.level
= levels
[i
];
3721 r
.in
.max_entries
= 2;
3722 r
.in
.buf_size
= (uint32_t)-1;
3723 r
.out
.total_size
= &total_size
;
3724 r
.out
.returned_size
= &returned_size
;
3725 r
.out
.info
= &disp_info
;
3727 status
= dcerpc_samr_QueryDisplayInfo(p
, mem_ctx
, &r
);
3728 if (!NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) && !NT_STATUS_IS_OK(status
)) {
3729 printf("QueryDisplayInfo level %u failed - %s\n",
3730 levels
[i
], nt_errstr(status
));
3733 switch (r
.in
.level
) {
3735 if (!test_each_DisplayInfo_user(p
, mem_ctx
, &r
, &seen_testuser
)) {
3738 r
.in
.start_idx
+= r
.out
.info
->info1
.count
;
3741 if (!test_each_DisplayInfo_user(p
, mem_ctx
, &r
, NULL
)) {
3744 r
.in
.start_idx
+= r
.out
.info
->info2
.count
;
3747 r
.in
.start_idx
+= r
.out
.info
->info3
.count
;
3750 r
.in
.start_idx
+= r
.out
.info
->info4
.count
;
3753 r
.in
.start_idx
+= r
.out
.info
->info5
.count
;
3757 dom_info
.in
.domain_handle
= handle
;
3758 dom_info
.in
.level
= 2;
3759 dom_info
.out
.info
= &info
;
3761 /* Check number of users returned is correct */
3762 status
= dcerpc_samr_QueryDomainInfo(p
, mem_ctx
, &dom_info
);
3763 if (!NT_STATUS_IS_OK(status
)) {
3764 printf("QueryDomainInfo level %u failed - %s\n",
3765 r
.in
.level
, nt_errstr(status
));
3769 switch (r
.in
.level
) {
3772 if (info
->general
.num_users
< r
.in
.start_idx
) {
3773 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3774 r
.in
.start_idx
, info
->general
.num_groups
,
3775 info
->general
.domain_name
.string
);
3778 if (!seen_testuser
) {
3779 struct policy_handle user_handle
;
3780 if (NT_STATUS_IS_OK(test_OpenUser_byname(p
, mem_ctx
, handle
, TEST_ACCOUNT_NAME
, &user_handle
))) {
3781 printf("Didn't find test user " TEST_ACCOUNT_NAME
" in enumeration of %s\n",
3782 info
->general
.domain_name
.string
);
3784 test_samr_handle_Close(p
, mem_ctx
, &user_handle
);
3790 if (info
->general
.num_groups
!= r
.in
.start_idx
) {
3791 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3792 r
.in
.start_idx
, info
->general
.num_groups
,
3793 info
->general
.domain_name
.string
);
3805 static bool test_QueryDisplayInfo2(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
3806 struct policy_handle
*handle
)
3809 struct samr_QueryDisplayInfo2 r
;
3811 uint16_t levels
[] = {1, 2, 3, 4, 5};
3813 uint32_t total_size
;
3814 uint32_t returned_size
;
3815 union samr_DispInfo info
;
3817 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
3818 printf("Testing QueryDisplayInfo2 level %u\n", levels
[i
]);
3820 r
.in
.domain_handle
= handle
;
3821 r
.in
.level
= levels
[i
];
3823 r
.in
.max_entries
= 1000;
3824 r
.in
.buf_size
= (uint32_t)-1;
3825 r
.out
.total_size
= &total_size
;
3826 r
.out
.returned_size
= &returned_size
;
3829 status
= dcerpc_samr_QueryDisplayInfo2(p
, mem_ctx
, &r
);
3830 if (!NT_STATUS_IS_OK(status
)) {
3831 printf("QueryDisplayInfo2 level %u failed - %s\n",
3832 levels
[i
], nt_errstr(status
));
3840 static bool test_QueryDisplayInfo3(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
3841 struct policy_handle
*handle
)
3844 struct samr_QueryDisplayInfo3 r
;
3846 uint16_t levels
[] = {1, 2, 3, 4, 5};
3848 uint32_t total_size
;
3849 uint32_t returned_size
;
3850 union samr_DispInfo info
;
3852 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
3853 torture_comment(tctx
, "Testing QueryDisplayInfo3 level %u\n", levels
[i
]);
3855 r
.in
.domain_handle
= handle
;
3856 r
.in
.level
= levels
[i
];
3858 r
.in
.max_entries
= 1000;
3859 r
.in
.buf_size
= (uint32_t)-1;
3860 r
.out
.total_size
= &total_size
;
3861 r
.out
.returned_size
= &returned_size
;
3864 status
= dcerpc_samr_QueryDisplayInfo3(p
, tctx
, &r
);
3865 if (!NT_STATUS_IS_OK(status
)) {
3866 printf("QueryDisplayInfo3 level %u failed - %s\n",
3867 levels
[i
], nt_errstr(status
));
3876 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
3877 struct policy_handle
*handle
)
3880 struct samr_QueryDisplayInfo r
;
3882 uint32_t total_size
;
3883 uint32_t returned_size
;
3884 union samr_DispInfo info
;
3886 printf("Testing QueryDisplayInfo continuation\n");
3888 r
.in
.domain_handle
= handle
;
3891 r
.in
.max_entries
= 1;
3892 r
.in
.buf_size
= (uint32_t)-1;
3893 r
.out
.total_size
= &total_size
;
3894 r
.out
.returned_size
= &returned_size
;
3898 status
= dcerpc_samr_QueryDisplayInfo(p
, mem_ctx
, &r
);
3899 if (NT_STATUS_IS_OK(status
) && *r
.out
.returned_size
!= 0) {
3900 if (r
.out
.info
->info1
.entries
[0].idx
!= r
.in
.start_idx
+ 1) {
3901 printf("expected idx %d but got %d\n",
3903 r
.out
.info
->info1
.entries
[0].idx
);
3907 if (!NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) &&
3908 !NT_STATUS_IS_OK(status
)) {
3909 printf("QueryDisplayInfo level %u failed - %s\n",
3910 r
.in
.level
, nt_errstr(status
));
3915 } while ((NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) ||
3916 NT_STATUS_IS_OK(status
)) &&
3917 *r
.out
.returned_size
!= 0);
3922 static bool test_QueryDomainInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
3923 struct policy_handle
*handle
)
3926 struct samr_QueryDomainInfo r
;
3927 union samr_DomainInfo
*info
= NULL
;
3928 struct samr_SetDomainInfo s
;
3929 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3930 uint16_t set_ok
[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3933 const char *domain_comment
= talloc_asprintf(tctx
,
3934 "Tortured by Samba4 RPC-SAMR: %s",
3935 timestring(tctx
, time(NULL
)));
3937 s
.in
.domain_handle
= handle
;
3939 s
.in
.info
= talloc(tctx
, union samr_DomainInfo
);
3941 s
.in
.info
->oem
.oem_information
.string
= domain_comment
;
3942 status
= dcerpc_samr_SetDomainInfo(p
, tctx
, &s
);
3943 if (!NT_STATUS_IS_OK(status
)) {
3944 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3945 r
.in
.level
, nt_errstr(status
));
3949 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
3950 torture_comment(tctx
, "Testing QueryDomainInfo level %u\n", levels
[i
]);
3952 r
.in
.domain_handle
= handle
;
3953 r
.in
.level
= levels
[i
];
3956 status
= dcerpc_samr_QueryDomainInfo(p
, tctx
, &r
);
3957 if (!NT_STATUS_IS_OK(status
)) {
3958 printf("QueryDomainInfo level %u failed - %s\n",
3959 r
.in
.level
, nt_errstr(status
));
3964 switch (levels
[i
]) {
3966 if (strcmp(info
->general
.oem_information
.string
, domain_comment
) != 0) {
3967 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3968 levels
[i
], info
->general
.oem_information
.string
, domain_comment
);
3971 if (!info
->general
.primary
.string
) {
3972 printf("QueryDomainInfo level %u returned no PDC name\n",
3975 } else if (info
->general
.role
== SAMR_ROLE_DOMAIN_PDC
) {
3976 if (dcerpc_server_name(p
) && strcasecmp_m(dcerpc_server_name(p
), info
->general
.primary
.string
) != 0) {
3977 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3978 levels
[i
], info
->general
.primary
.string
, dcerpc_server_name(p
));
3983 if (strcmp(info
->oem
.oem_information
.string
, domain_comment
) != 0) {
3984 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3985 levels
[i
], info
->oem
.oem_information
.string
, domain_comment
);
3990 if (!info
->info6
.primary
.string
) {
3991 printf("QueryDomainInfo level %u returned no PDC name\n",
3997 if (strcmp(info
->general2
.general
.oem_information
.string
, domain_comment
) != 0) {
3998 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3999 levels
[i
], info
->general2
.general
.oem_information
.string
, domain_comment
);
4005 torture_comment(tctx
, "Testing SetDomainInfo level %u\n", levels
[i
]);
4007 s
.in
.domain_handle
= handle
;
4008 s
.in
.level
= levels
[i
];
4011 status
= dcerpc_samr_SetDomainInfo(p
, tctx
, &s
);
4013 if (!NT_STATUS_IS_OK(status
)) {
4014 printf("SetDomainInfo level %u failed - %s\n",
4015 r
.in
.level
, nt_errstr(status
));
4020 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, status
)) {
4021 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4022 r
.in
.level
, nt_errstr(status
));
4028 status
= dcerpc_samr_QueryDomainInfo(p
, tctx
, &r
);
4029 if (!NT_STATUS_IS_OK(status
)) {
4030 printf("QueryDomainInfo level %u failed - %s\n",
4031 r
.in
.level
, nt_errstr(status
));
4041 static bool test_QueryDomainInfo2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4042 struct policy_handle
*handle
)
4045 struct samr_QueryDomainInfo2 r
;
4046 union samr_DomainInfo
*info
= NULL
;
4047 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4051 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
4052 printf("Testing QueryDomainInfo2 level %u\n", levels
[i
]);
4054 r
.in
.domain_handle
= handle
;
4055 r
.in
.level
= levels
[i
];
4058 status
= dcerpc_samr_QueryDomainInfo2(p
, tctx
, &r
);
4059 if (!NT_STATUS_IS_OK(status
)) {
4060 printf("QueryDomainInfo2 level %u failed - %s\n",
4061 r
.in
.level
, nt_errstr(status
));
4070 /* Test whether querydispinfo level 5 and enumdomgroups return the same
4071 set of group names. */
4072 static bool test_GroupList(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4073 struct policy_handle
*handle
)
4075 struct samr_EnumDomainGroups q1
;
4076 struct samr_QueryDisplayInfo q2
;
4078 uint32_t resume_handle
=0;
4081 uint32_t total_size
;
4082 uint32_t returned_size
;
4083 union samr_DispInfo info
;
4086 const char **names
= NULL
;
4088 torture_comment(tctx
, "Testing coherency of querydispinfo vs enumdomgroups\n");
4090 q1
.in
.domain_handle
= handle
;
4091 q1
.in
.resume_handle
= &resume_handle
;
4093 q1
.out
.resume_handle
= &resume_handle
;
4095 status
= STATUS_MORE_ENTRIES
;
4096 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
4097 status
= dcerpc_samr_EnumDomainGroups(p
, tctx
, &q1
);
4099 if (!NT_STATUS_IS_OK(status
) &&
4100 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
4103 for (i
=0; i
<q1
.out
.num_entries
; i
++) {
4104 add_string_to_array(tctx
,
4105 q1
.out
.sam
->entries
[i
].name
.string
,
4106 &names
, &num_names
);
4110 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomainGroups");
4112 torture_assert(tctx
, q1
.out
.sam
, "EnumDomainGroups failed to return q1.out.sam");
4114 q2
.in
.domain_handle
= handle
;
4116 q2
.in
.start_idx
= 0;
4117 q2
.in
.max_entries
= 5;
4118 q2
.in
.buf_size
= (uint32_t)-1;
4119 q2
.out
.total_size
= &total_size
;
4120 q2
.out
.returned_size
= &returned_size
;
4121 q2
.out
.info
= &info
;
4123 status
= STATUS_MORE_ENTRIES
;
4124 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
4125 status
= dcerpc_samr_QueryDisplayInfo(p
, tctx
, &q2
);
4127 if (!NT_STATUS_IS_OK(status
) &&
4128 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
4131 for (i
=0; i
<q2
.out
.info
->info5
.count
; i
++) {
4133 const char *name
= q2
.out
.info
->info5
.entries
[i
].account_name
.string
;
4135 for (j
=0; j
<num_names
; j
++) {
4136 if (names
[j
] == NULL
)
4138 if (strequal(names
[j
], name
)) {
4146 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
4151 q2
.in
.start_idx
+= q2
.out
.info
->info5
.count
;
4154 if (!NT_STATUS_IS_OK(status
)) {
4155 printf("QueryDisplayInfo level 5 failed - %s\n",
4160 for (i
=0; i
<num_names
; i
++) {
4161 if (names
[i
] != NULL
) {
4162 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
4171 static bool test_DeleteDomainGroup(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4172 struct policy_handle
*group_handle
)
4174 struct samr_DeleteDomainGroup d
;
4177 torture_comment(tctx
, "Testing DeleteDomainGroup\n");
4179 d
.in
.group_handle
= group_handle
;
4180 d
.out
.group_handle
= group_handle
;
4182 status
= dcerpc_samr_DeleteDomainGroup(p
, tctx
, &d
);
4183 torture_assert_ntstatus_ok(tctx
, status
, "DeleteDomainGroup");
4188 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4189 struct policy_handle
*domain_handle
)
4191 struct samr_TestPrivateFunctionsDomain r
;
4195 torture_comment(tctx
, "Testing TestPrivateFunctionsDomain\n");
4197 r
.in
.domain_handle
= domain_handle
;
4199 status
= dcerpc_samr_TestPrivateFunctionsDomain(p
, tctx
, &r
);
4200 torture_assert_ntstatus_equal(tctx
, NT_STATUS_NOT_IMPLEMENTED
, status
, "TestPrivateFunctionsDomain");
4205 static bool test_RidToSid(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4206 struct dom_sid
*domain_sid
,
4207 struct policy_handle
*domain_handle
)
4209 struct samr_RidToSid r
;
4212 struct dom_sid
*calc_sid
, *out_sid
;
4213 int rids
[] = { 0, 42, 512, 10200 };
4216 for (i
=0;i
<ARRAY_SIZE(rids
);i
++) {
4217 torture_comment(tctx
, "Testing RidToSid\n");
4219 calc_sid
= dom_sid_dup(tctx
, domain_sid
);
4220 r
.in
.domain_handle
= domain_handle
;
4222 r
.out
.sid
= &out_sid
;
4224 status
= dcerpc_samr_RidToSid(p
, tctx
, &r
);
4225 if (!NT_STATUS_IS_OK(status
)) {
4226 printf("RidToSid for %d failed - %s\n", rids
[i
], nt_errstr(status
));
4229 calc_sid
= dom_sid_add_rid(calc_sid
, calc_sid
, rids
[i
]);
4231 if (!dom_sid_equal(calc_sid
, out_sid
)) {
4232 printf("RidToSid for %d failed - got %s, expected %s\n", rids
[i
],
4233 dom_sid_string(tctx
, out_sid
),
4234 dom_sid_string(tctx
, calc_sid
));
4243 static bool test_GetBootKeyInformation(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4244 struct policy_handle
*domain_handle
)
4246 struct samr_GetBootKeyInformation r
;
4249 uint32_t unknown
= 0;
4251 torture_comment(tctx
, "Testing GetBootKeyInformation\n");
4253 r
.in
.domain_handle
= domain_handle
;
4254 r
.out
.unknown
= &unknown
;
4256 status
= dcerpc_samr_GetBootKeyInformation(p
, tctx
, &r
);
4257 if (!NT_STATUS_IS_OK(status
)) {
4258 /* w2k3 seems to fail this sometimes and pass it sometimes */
4259 torture_comment(tctx
, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status
));
4265 static bool test_AddGroupMember(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4266 struct policy_handle
*domain_handle
,
4267 struct policy_handle
*group_handle
)
4270 struct samr_AddGroupMember r
;
4271 struct samr_DeleteGroupMember d
;
4272 struct samr_QueryGroupMember q
;
4273 struct samr_RidTypeArray
*rids
= NULL
;
4274 struct samr_SetMemberAttributesOfGroup s
;
4277 status
= test_LookupName(p
, tctx
, domain_handle
, TEST_ACCOUNT_NAME
, &rid
);
4278 torture_assert_ntstatus_ok(tctx
, status
, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME
);
4280 r
.in
.group_handle
= group_handle
;
4282 r
.in
.flags
= 0; /* ??? */
4284 torture_comment(tctx
, "Testing AddGroupMember and DeleteGroupMember\n");
4286 d
.in
.group_handle
= group_handle
;
4289 status
= dcerpc_samr_DeleteGroupMember(p
, tctx
, &d
);
4290 torture_assert_ntstatus_equal(tctx
, NT_STATUS_MEMBER_NOT_IN_GROUP
, status
, "DeleteGroupMember");
4292 status
= dcerpc_samr_AddGroupMember(p
, tctx
, &r
);
4293 torture_assert_ntstatus_ok(tctx
, status
, "AddGroupMember");
4295 status
= dcerpc_samr_AddGroupMember(p
, tctx
, &r
);
4296 torture_assert_ntstatus_equal(tctx
, NT_STATUS_MEMBER_IN_GROUP
, status
, "AddGroupMember");
4298 if (torture_setting_bool(tctx
, "samba4", false)) {
4299 torture_comment(tctx
, "skipping SetMemberAttributesOfGroup test against Samba4\n");
4301 /* this one is quite strange. I am using random inputs in the
4302 hope of triggering an error that might give us a clue */
4304 s
.in
.group_handle
= group_handle
;
4305 s
.in
.unknown1
= random();
4306 s
.in
.unknown2
= random();
4308 status
= dcerpc_samr_SetMemberAttributesOfGroup(p
, tctx
, &s
);
4309 torture_assert_ntstatus_ok(tctx
, status
, "SetMemberAttributesOfGroup");
4312 q
.in
.group_handle
= group_handle
;
4315 status
= dcerpc_samr_QueryGroupMember(p
, tctx
, &q
);
4316 torture_assert_ntstatus_ok(tctx
, status
, "QueryGroupMember");
4318 status
= dcerpc_samr_DeleteGroupMember(p
, tctx
, &d
);
4319 torture_assert_ntstatus_ok(tctx
, status
, "DeleteGroupMember");
4321 status
= dcerpc_samr_AddGroupMember(p
, tctx
, &r
);
4322 torture_assert_ntstatus_ok(tctx
, status
, "AddGroupMember");
4328 static bool test_CreateDomainGroup(struct dcerpc_pipe
*p
,
4329 struct torture_context
*tctx
,
4330 struct policy_handle
*domain_handle
,
4331 struct policy_handle
*group_handle
,
4332 struct dom_sid
*domain_sid
)
4335 struct samr_CreateDomainGroup r
;
4337 struct lsa_String name
;
4340 init_lsa_String(&name
, TEST_GROUPNAME
);
4342 r
.in
.domain_handle
= domain_handle
;
4344 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4345 r
.out
.group_handle
= group_handle
;
4348 printf("Testing CreateDomainGroup(%s)\n", r
.in
.name
->string
);
4350 status
= dcerpc_samr_CreateDomainGroup(p
, tctx
, &r
);
4352 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
4353 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
4354 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.name
->string
);
4357 printf("Server should have refused create of '%s', got %s instead\n", r
.in
.name
->string
,
4363 if (NT_STATUS_EQUAL(status
, NT_STATUS_GROUP_EXISTS
)) {
4364 if (!test_DeleteGroup_byname(p
, tctx
, domain_handle
, r
.in
.name
->string
)) {
4365 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r
.in
.name
->string
,
4369 status
= dcerpc_samr_CreateDomainGroup(p
, tctx
, &r
);
4371 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_EXISTS
)) {
4372 if (!test_DeleteUser_byname(p
, tctx
, domain_handle
, r
.in
.name
->string
)) {
4374 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r
.in
.name
->string
,
4378 status
= dcerpc_samr_CreateDomainGroup(p
, tctx
, &r
);
4380 torture_assert_ntstatus_ok(tctx
, status
, "CreateDomainGroup");
4382 if (!test_AddGroupMember(p
, tctx
, domain_handle
, group_handle
)) {
4383 printf("CreateDomainGroup failed - %s\n", nt_errstr(status
));
4387 if (!test_SetGroupInfo(p
, tctx
, group_handle
)) {
4396 its not totally clear what this does. It seems to accept any sid you like.
4398 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe
*p
,
4399 struct torture_context
*tctx
,
4400 struct policy_handle
*domain_handle
)
4403 struct samr_RemoveMemberFromForeignDomain r
;
4405 r
.in
.domain_handle
= domain_handle
;
4406 r
.in
.sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-12-34-56-78");
4408 status
= dcerpc_samr_RemoveMemberFromForeignDomain(p
, tctx
, &r
);
4409 torture_assert_ntstatus_ok(tctx
, status
, "RemoveMemberFromForeignDomain");
4416 static bool test_Connect(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4417 struct policy_handle
*handle
);
4419 static bool test_OpenDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4420 struct policy_handle
*handle
, struct dom_sid
*sid
,
4421 enum torture_samr_choice which_ops
)
4424 struct samr_OpenDomain r
;
4425 struct policy_handle domain_handle
;
4426 struct policy_handle alias_handle
;
4427 struct policy_handle user_handle
;
4428 struct policy_handle group_handle
;
4431 ZERO_STRUCT(alias_handle
);
4432 ZERO_STRUCT(user_handle
);
4433 ZERO_STRUCT(group_handle
);
4434 ZERO_STRUCT(domain_handle
);
4436 torture_comment(tctx
, "Testing OpenDomain of %s\n", dom_sid_string(tctx
, sid
));
4438 r
.in
.connect_handle
= handle
;
4439 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4441 r
.out
.domain_handle
= &domain_handle
;
4443 status
= dcerpc_samr_OpenDomain(p
, tctx
, &r
);
4444 torture_assert_ntstatus_ok(tctx
, status
, "OpenDomain");
4446 /* run the domain tests with the main handle closed - this tests
4447 the servers reference counting */
4448 ret
&= test_samr_handle_Close(p
, tctx
, handle
);
4450 switch (which_ops
) {
4451 case TORTURE_SAMR_USER_ATTRIBUTES
:
4452 case TORTURE_SAMR_PASSWORDS
:
4453 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, which_ops
);
4454 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, &user_handle
, sid
, which_ops
);
4455 /* This test needs 'complex' users to validate */
4456 ret
&= test_QueryDisplayInfo(p
, tctx
, &domain_handle
);
4458 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx
, sid
));
4461 case TORTURE_SAMR_OTHER
:
4462 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, &user_handle
, sid
, which_ops
);
4464 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx
, sid
));
4466 ret
&= test_QuerySecurity(p
, tctx
, &domain_handle
);
4467 ret
&= test_RemoveMemberFromForeignDomain(p
, tctx
, &domain_handle
);
4468 ret
&= test_CreateAlias(p
, tctx
, &domain_handle
, &alias_handle
, sid
);
4469 ret
&= test_CreateDomainGroup(p
, tctx
, &domain_handle
, &group_handle
, sid
);
4470 ret
&= test_QueryDomainInfo(p
, tctx
, &domain_handle
);
4471 ret
&= test_QueryDomainInfo2(p
, tctx
, &domain_handle
);
4472 ret
&= test_EnumDomainUsers(p
, tctx
, &domain_handle
);
4473 ret
&= test_EnumDomainUsers_async(p
, tctx
, &domain_handle
);
4474 ret
&= test_EnumDomainGroups(p
, tctx
, &domain_handle
);
4475 ret
&= test_EnumDomainAliases(p
, tctx
, &domain_handle
);
4476 ret
&= test_QueryDisplayInfo2(p
, tctx
, &domain_handle
);
4477 ret
&= test_QueryDisplayInfo3(p
, tctx
, &domain_handle
);
4478 ret
&= test_QueryDisplayInfo_continue(p
, tctx
, &domain_handle
);
4480 if (torture_setting_bool(tctx
, "samba4", false)) {
4481 torture_comment(tctx
, "skipping GetDisplayEnumerationIndex test against Samba4\n");
4483 ret
&= test_GetDisplayEnumerationIndex(p
, tctx
, &domain_handle
);
4484 ret
&= test_GetDisplayEnumerationIndex2(p
, tctx
, &domain_handle
);
4486 ret
&= test_GroupList(p
, tctx
, &domain_handle
);
4487 ret
&= test_TestPrivateFunctionsDomain(p
, tctx
, &domain_handle
);
4488 ret
&= test_RidToSid(p
, tctx
, sid
, &domain_handle
);
4489 ret
&= test_GetBootKeyInformation(p
, tctx
, &domain_handle
);
4491 torture_comment(tctx
, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx
, sid
));
4496 if (!policy_handle_empty(&user_handle
) &&
4497 !test_DeleteUser(p
, tctx
, &user_handle
)) {
4501 if (!policy_handle_empty(&alias_handle
) &&
4502 !test_DeleteAlias(p
, tctx
, &alias_handle
)) {
4506 if (!policy_handle_empty(&group_handle
) &&
4507 !test_DeleteDomainGroup(p
, tctx
, &group_handle
)) {
4511 ret
&= test_samr_handle_Close(p
, tctx
, &domain_handle
);
4513 /* reconnect the main handle */
4514 ret
&= test_Connect(p
, tctx
, handle
);
4517 printf("Testing domain %s failed!\n", dom_sid_string(tctx
, sid
));
4523 static bool test_LookupDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4524 struct policy_handle
*handle
, const char *domain
,
4525 enum torture_samr_choice which_ops
)
4528 struct samr_LookupDomain r
;
4529 struct lsa_String n1
;
4530 struct lsa_String n2
;
4533 torture_comment(tctx
, "Testing LookupDomain(%s)\n", domain
);
4535 /* check for correct error codes */
4536 r
.in
.connect_handle
= handle
;
4537 r
.in
.domain_name
= &n2
;
4540 status
= dcerpc_samr_LookupDomain(p
, tctx
, &r
);
4541 torture_assert_ntstatus_equal(tctx
, NT_STATUS_INVALID_PARAMETER
, status
, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
4543 init_lsa_String(&n2
, "xxNODOMAINxx");
4545 status
= dcerpc_samr_LookupDomain(p
, tctx
, &r
);
4546 torture_assert_ntstatus_equal(tctx
, NT_STATUS_NO_SUCH_DOMAIN
, status
, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
4548 r
.in
.connect_handle
= handle
;
4550 init_lsa_String(&n1
, domain
);
4551 r
.in
.domain_name
= &n1
;
4553 status
= dcerpc_samr_LookupDomain(p
, tctx
, &r
);
4554 torture_assert_ntstatus_ok(tctx
, status
, "LookupDomain");
4556 if (!test_GetDomPwInfo(p
, tctx
, &n1
)) {
4560 if (!test_OpenDomain(p
, tctx
, handle
, r
.out
.sid
, which_ops
)) {
4568 static bool test_EnumDomains(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4569 struct policy_handle
*handle
, enum torture_samr_choice which_ops
)
4572 struct samr_EnumDomains r
;
4573 uint32_t resume_handle
= 0;
4577 r
.in
.connect_handle
= handle
;
4578 r
.in
.resume_handle
= &resume_handle
;
4579 r
.in
.buf_size
= (uint32_t)-1;
4580 r
.out
.resume_handle
= &resume_handle
;
4582 status
= dcerpc_samr_EnumDomains(p
, tctx
, &r
);
4583 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomains");
4589 for (i
=0;i
<r
.out
.sam
->count
;i
++) {
4590 if (!test_LookupDomain(p
, tctx
, handle
,
4591 r
.out
.sam
->entries
[i
].name
.string
, which_ops
)) {
4596 status
= dcerpc_samr_EnumDomains(p
, tctx
, &r
);
4597 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomains");
4603 static bool test_Connect(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4604 struct policy_handle
*handle
)
4607 struct samr_Connect r
;
4608 struct samr_Connect2 r2
;
4609 struct samr_Connect3 r3
;
4610 struct samr_Connect4 r4
;
4611 struct samr_Connect5 r5
;
4612 union samr_ConnectInfo info
;
4613 struct policy_handle h
;
4614 uint32_t level_out
= 0;
4615 bool ret
= true, got_handle
= false;
4617 torture_comment(tctx
, "testing samr_Connect\n");
4619 r
.in
.system_name
= 0;
4620 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4621 r
.out
.connect_handle
= &h
;
4623 status
= dcerpc_samr_Connect(p
, tctx
, &r
);
4624 if (!NT_STATUS_IS_OK(status
)) {
4625 torture_comment(tctx
, "Connect failed - %s\n", nt_errstr(status
));
4632 torture_comment(tctx
, "testing samr_Connect2\n");
4634 r2
.in
.system_name
= NULL
;
4635 r2
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4636 r2
.out
.connect_handle
= &h
;
4638 status
= dcerpc_samr_Connect2(p
, tctx
, &r2
);
4639 if (!NT_STATUS_IS_OK(status
)) {
4640 torture_comment(tctx
, "Connect2 failed - %s\n", nt_errstr(status
));
4644 test_samr_handle_Close(p
, tctx
, handle
);
4650 torture_comment(tctx
, "testing samr_Connect3\n");
4652 r3
.in
.system_name
= NULL
;
4654 r3
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4655 r3
.out
.connect_handle
= &h
;
4657 status
= dcerpc_samr_Connect3(p
, tctx
, &r3
);
4658 if (!NT_STATUS_IS_OK(status
)) {
4659 printf("Connect3 failed - %s\n", nt_errstr(status
));
4663 test_samr_handle_Close(p
, tctx
, handle
);
4669 torture_comment(tctx
, "testing samr_Connect4\n");
4671 r4
.in
.system_name
= "";
4672 r4
.in
.client_version
= 0;
4673 r4
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4674 r4
.out
.connect_handle
= &h
;
4676 status
= dcerpc_samr_Connect4(p
, tctx
, &r4
);
4677 if (!NT_STATUS_IS_OK(status
)) {
4678 printf("Connect4 failed - %s\n", nt_errstr(status
));
4682 test_samr_handle_Close(p
, tctx
, handle
);
4688 torture_comment(tctx
, "testing samr_Connect5\n");
4690 info
.info1
.client_version
= 0;
4691 info
.info1
.unknown2
= 0;
4693 r5
.in
.system_name
= "";
4694 r5
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4696 r5
.out
.level_out
= &level_out
;
4697 r5
.in
.info_in
= &info
;
4698 r5
.out
.info_out
= &info
;
4699 r5
.out
.connect_handle
= &h
;
4701 status
= dcerpc_samr_Connect5(p
, tctx
, &r5
);
4702 if (!NT_STATUS_IS_OK(status
)) {
4703 printf("Connect5 failed - %s\n", nt_errstr(status
));
4707 test_samr_handle_Close(p
, tctx
, handle
);
4717 bool torture_rpc_samr(struct torture_context
*torture
)
4720 struct dcerpc_pipe
*p
;
4722 struct policy_handle handle
;
4724 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
4725 if (!NT_STATUS_IS_OK(status
)) {
4729 ret
&= test_Connect(p
, torture
, &handle
);
4731 ret
&= test_QuerySecurity(p
, torture
, &handle
);
4733 ret
&= test_EnumDomains(p
, torture
, &handle
, TORTURE_SAMR_OTHER
);
4735 ret
&= test_SetDsrmPassword(p
, torture
, &handle
);
4737 ret
&= test_Shutdown(p
, torture
, &handle
);
4739 ret
&= test_samr_handle_Close(p
, torture
, &handle
);
4745 bool torture_rpc_samr_users(struct torture_context
*torture
)
4748 struct dcerpc_pipe
*p
;
4750 struct policy_handle handle
;
4752 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
4753 if (!NT_STATUS_IS_OK(status
)) {
4757 ret
&= test_Connect(p
, torture
, &handle
);
4759 ret
&= test_QuerySecurity(p
, torture
, &handle
);
4761 ret
&= test_EnumDomains(p
, torture
, &handle
, TORTURE_SAMR_USER_ATTRIBUTES
);
4763 ret
&= test_SetDsrmPassword(p
, torture
, &handle
);
4765 ret
&= test_Shutdown(p
, torture
, &handle
);
4767 ret
&= test_samr_handle_Close(p
, torture
, &handle
);
4773 bool torture_rpc_samr_passwords(struct torture_context
*torture
)
4776 struct dcerpc_pipe
*p
;
4778 struct policy_handle handle
;
4780 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
4781 if (!NT_STATUS_IS_OK(status
)) {
4785 ret
&= test_Connect(p
, torture
, &handle
);
4787 ret
&= test_EnumDomains(p
, torture
, &handle
, TORTURE_SAMR_PASSWORDS
);
4789 ret
&= test_samr_handle_Close(p
, torture
, &handle
);