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;
180 union samr_UserInfo *info;
182 const char *test_account_name;
184 uint32_t user_extra_flags = 0;
185 if (base_acct_flags == ACB_NORMAL) {
186 /* When created, accounts are expired by default */
187 user_extra_flags = ACB_PW_EXPIRED;
190 s.in.user_handle = handle;
193 s2.in.user_handle = handle;
196 q.in.user_handle = handle;
200 #define TESTCALL(call, r) \
201 status = dcerpc_samr_ ##call(p, tctx, &r); \
202 if (!NT_STATUS_IS_OK(status)) { \
203 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
204 r.in.level, nt_errstr(status), __location__); \
209 #define STRING_EQUAL(s1, s2, field) \
210 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
211 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
212 #field, s2, __location__); \
217 #define MEM_EQUAL(s1, s2, length, field) \
218 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
219 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
220 #field, (const char *)s2, __location__); \
225 #define INT_EQUAL(i1, i2, field) \
227 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
228 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
233 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
234 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
236 TESTCALL(QueryUserInfo, q) \
238 s2.in.level = lvl1; \
241 ZERO_STRUCT(u.info21); \
242 u.info21.fields_present = fpval; \
244 init_lsa_String(&u.info ## lvl1.field1, value); \
245 TESTCALL(SetUserInfo, s) \
246 TESTCALL(SetUserInfo2, s2) \
247 init_lsa_String(&u.info ## lvl1.field1, ""); \
248 TESTCALL(QueryUserInfo, q); \
250 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
252 TESTCALL(QueryUserInfo, q) \
254 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
257 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
258 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
260 TESTCALL(QueryUserInfo, q) \
262 s2.in.level = lvl1; \
265 ZERO_STRUCT(u.info21); \
266 u.info21.fields_present = fpval; \
268 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
269 TESTCALL(SetUserInfo, s) \
270 TESTCALL(SetUserInfo2, s2) \
271 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
272 TESTCALL(QueryUserInfo, q); \
274 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
276 TESTCALL(QueryUserInfo, q) \
278 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
281 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
282 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
284 TESTCALL(QueryUserInfo, q) \
286 s2.in.level = lvl1; \
289 uint8_t *bits = u.info21.logon_hours.bits; \
290 ZERO_STRUCT(u.info21); \
291 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
292 u.info21.logon_hours.units_per_week = 168; \
293 u.info21.logon_hours.bits = bits; \
295 u.info21.fields_present = fpval; \
297 u.info ## lvl1.field1 = value; \
298 TESTCALL(SetUserInfo, s) \
299 TESTCALL(SetUserInfo2, s2) \
300 u.info ## lvl1.field1 = 0; \
301 TESTCALL(QueryUserInfo, q); \
303 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
305 TESTCALL(QueryUserInfo, q) \
307 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
310 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
311 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
315 do { TESTCALL(QueryUserInfo, q0) } while (0);
317 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
318 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
319 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
322 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
323 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
324 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
325 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
326 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
327 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
328 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
329 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
330 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
331 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
332 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
333 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
334 test_account_name = base_account_name;
335 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
336 SAMR_FIELD_ACCOUNT_NAME);
338 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
339 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
340 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
341 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
342 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
343 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
344 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
345 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
346 SAMR_FIELD_FULL_NAME);
348 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
349 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
350 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
351 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
352 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
353 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
354 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
355 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
356 SAMR_FIELD_FULL_NAME);
358 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
359 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
360 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
361 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
362 SAMR_FIELD_LOGON_SCRIPT);
364 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
365 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
366 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
367 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
368 SAMR_FIELD_PROFILE_PATH);
370 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
371 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
372 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
373 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
374 SAMR_FIELD_HOME_DIRECTORY);
375 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
376 SAMR_FIELD_HOME_DIRECTORY);
378 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
379 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
380 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
381 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
382 SAMR_FIELD_HOME_DRIVE);
383 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
384 SAMR_FIELD_HOME_DRIVE);
386 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
387 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
388 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
389 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
390 SAMR_FIELD_DESCRIPTION);
392 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
393 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
394 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
395 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
396 SAMR_FIELD_WORKSTATIONS);
397 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
398 SAMR_FIELD_WORKSTATIONS);
399 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
400 SAMR_FIELD_WORKSTATIONS);
401 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
402 SAMR_FIELD_WORKSTATIONS);
404 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
405 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
406 SAMR_FIELD_PARAMETERS);
407 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
408 SAMR_FIELD_PARAMETERS);
410 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
411 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
412 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
413 SAMR_FIELD_COUNTRY_CODE);
414 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
415 SAMR_FIELD_COUNTRY_CODE);
417 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
418 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
419 SAMR_FIELD_CODE_PAGE);
420 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
421 SAMR_FIELD_CODE_PAGE);
423 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
424 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
425 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
426 SAMR_FIELD_ACCT_EXPIRY);
427 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
428 SAMR_FIELD_ACCT_EXPIRY);
429 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
430 SAMR_FIELD_ACCT_EXPIRY);
432 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
433 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
434 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
435 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
436 SAMR_FIELD_LOGON_HOURS);
438 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
439 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
440 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
442 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
443 (base_acct_flags | ACB_DISABLED),
444 (base_acct_flags | ACB_DISABLED | user_extra_flags),
447 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
448 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
449 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
450 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
452 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
453 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
454 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
458 /* The 'autolock' flag doesn't stick - check this */
459 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
460 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
461 (base_acct_flags | ACB_DISABLED | user_extra_flags),
464 /* Removing the 'disabled' flag doesn't stick - check this */
465 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
467 (base_acct_flags | ACB_DISABLED | user_extra_flags),
470 /* The 'store plaintext' flag does stick */
471 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
472 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
473 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
475 /* The 'use DES' flag does stick */
476 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
477 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
478 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
480 /* The 'don't require kerberos pre-authentication flag does stick */
481 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
482 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
483 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
485 /* The 'no kerberos PAC required' flag sticks */
486 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
487 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
488 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
491 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
492 (base_acct_flags | ACB_DISABLED),
493 (base_acct_flags | ACB_DISABLED | user_extra_flags),
494 SAMR_FIELD_ACCT_FLAGS);
497 /* these fail with win2003 - it appears you can't set the primary gid?
498 the set succeeds, but the gid isn't changed. Very weird! */
499 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
500 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
501 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
502 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
509 generate a random password for password change tests
511 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
513 size_t len = MAX(8, min_len) + (random() % 6);
514 char *s = generate_random_str(mem_ctx, len);
515 printf("Generated password '%s'\n", s);
520 generate a random password for password change tests
522 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
525 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
526 generate_random_buffer(password.data, password.length);
528 for (i=0; i < len; i++) {
529 if (((uint16_t *)password.data)[i] == 0) {
530 ((uint16_t *)password.data)[i] = 1;
538 generate a random password for password change tests (fixed length)
540 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
542 char *s = generate_random_str(mem_ctx, len);
543 printf("Generated password '%s'\n", s);
547 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
548 struct policy_handle *handle, char **password)
551 struct samr_SetUserInfo s;
552 union samr_UserInfo u;
554 DATA_BLOB session_key;
556 struct samr_GetUserPwInfo pwp;
557 struct samr_PwInfo info;
558 int policy_min_pw_len = 0;
559 pwp.in.user_handle = handle;
560 pwp.out.info = &info;
562 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
563 if (NT_STATUS_IS_OK(status)) {
564 policy_min_pw_len = pwp.out.info->min_password_length;
566 newpass = samr_rand_pass(tctx, policy_min_pw_len);
568 s.in.user_handle = handle;
572 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
573 /* w2k3 ignores this length */
574 u.info24.pw_len = strlen_m(newpass) * 2;
576 status = dcerpc_fetch_session_key(p, &session_key);
577 if (!NT_STATUS_IS_OK(status)) {
578 printf("SetUserInfo level %u - no session key - %s\n",
579 s.in.level, nt_errstr(status));
583 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
585 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
587 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
588 if (!NT_STATUS_IS_OK(status)) {
589 printf("SetUserInfo level %u failed - %s\n",
590 s.in.level, nt_errstr(status));
600 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
601 struct policy_handle *handle, uint32_t fields_present,
605 struct samr_SetUserInfo s;
606 union samr_UserInfo u;
608 DATA_BLOB session_key;
610 struct samr_GetUserPwInfo pwp;
611 struct samr_PwInfo info;
612 int policy_min_pw_len = 0;
613 pwp.in.user_handle = handle;
614 pwp.out.info = &info;
616 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
617 if (NT_STATUS_IS_OK(status)) {
618 policy_min_pw_len = pwp.out.info->min_password_length;
620 newpass = samr_rand_pass(tctx, policy_min_pw_len);
622 s.in.user_handle = handle;
628 u.info23.info.fields_present = fields_present;
630 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
632 status = dcerpc_fetch_session_key(p, &session_key);
633 if (!NT_STATUS_IS_OK(status)) {
634 printf("SetUserInfo level %u - no session key - %s\n",
635 s.in.level, nt_errstr(status));
639 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
641 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
643 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
644 if (!NT_STATUS_IS_OK(status)) {
645 printf("SetUserInfo level %u failed - %s\n",
646 s.in.level, nt_errstr(status));
652 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
654 status = dcerpc_fetch_session_key(p, &session_key);
655 if (!NT_STATUS_IS_OK(status)) {
656 printf("SetUserInfo level %u - no session key - %s\n",
657 s.in.level, nt_errstr(status));
661 /* This should break the key nicely */
662 session_key.length--;
663 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
665 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
667 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
668 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
669 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
670 s.in.level, nt_errstr(status));
678 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
679 struct policy_handle *handle, bool makeshort,
683 struct samr_SetUserInfo s;
684 union samr_UserInfo u;
686 DATA_BLOB session_key;
687 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
688 uint8_t confounder[16];
690 struct MD5Context ctx;
691 struct samr_GetUserPwInfo pwp;
692 struct samr_PwInfo info;
693 int policy_min_pw_len = 0;
694 pwp.in.user_handle = handle;
695 pwp.out.info = &info;
697 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
698 if (NT_STATUS_IS_OK(status)) {
699 policy_min_pw_len = pwp.out.info->min_password_length;
701 if (makeshort && policy_min_pw_len) {
702 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
704 newpass = samr_rand_pass(tctx, policy_min_pw_len);
707 s.in.user_handle = handle;
711 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
712 u.info26.pw_len = strlen(newpass);
714 status = dcerpc_fetch_session_key(p, &session_key);
715 if (!NT_STATUS_IS_OK(status)) {
716 printf("SetUserInfo level %u - no session key - %s\n",
717 s.in.level, nt_errstr(status));
721 generate_random_buffer((uint8_t *)confounder, 16);
724 MD5Update(&ctx, confounder, 16);
725 MD5Update(&ctx, session_key.data, session_key.length);
726 MD5Final(confounded_session_key.data, &ctx);
728 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
729 memcpy(&u.info26.password.data[516], confounder, 16);
731 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
733 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
734 if (!NT_STATUS_IS_OK(status)) {
735 printf("SetUserInfo level %u failed - %s\n",
736 s.in.level, nt_errstr(status));
742 /* This should break the key nicely */
743 confounded_session_key.data[0]++;
745 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
746 memcpy(&u.info26.password.data[516], confounder, 16);
748 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
750 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
751 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
752 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
753 s.in.level, nt_errstr(status));
762 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
763 struct policy_handle *handle, uint32_t fields_present,
767 struct samr_SetUserInfo s;
768 union samr_UserInfo u;
770 DATA_BLOB session_key;
771 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
772 struct MD5Context ctx;
773 uint8_t confounder[16];
775 struct samr_GetUserPwInfo pwp;
776 struct samr_PwInfo info;
777 int policy_min_pw_len = 0;
778 pwp.in.user_handle = handle;
779 pwp.out.info = &info;
781 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
782 if (NT_STATUS_IS_OK(status)) {
783 policy_min_pw_len = pwp.out.info->min_password_length;
785 newpass = samr_rand_pass(tctx, policy_min_pw_len);
787 s.in.user_handle = handle;
793 u.info25.info.fields_present = fields_present;
795 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
797 status = dcerpc_fetch_session_key(p, &session_key);
798 if (!NT_STATUS_IS_OK(status)) {
799 printf("SetUserInfo level %u - no session key - %s\n",
800 s.in.level, nt_errstr(status));
804 generate_random_buffer((uint8_t *)confounder, 16);
807 MD5Update(&ctx, confounder, 16);
808 MD5Update(&ctx, session_key.data, session_key.length);
809 MD5Final(confounded_session_key.data, &ctx);
811 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
812 memcpy(&u.info25.password.data[516], confounder, 16);
814 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
816 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
817 if (!NT_STATUS_IS_OK(status)) {
818 printf("SetUserInfo level %u failed - %s\n",
819 s.in.level, nt_errstr(status));
825 /* This should break the key nicely */
826 confounded_session_key.data[0]++;
828 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
829 memcpy(&u.info25.password.data[516], confounder, 16);
831 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
833 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
834 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
835 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
836 s.in.level, nt_errstr(status));
843 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
844 struct policy_handle *handle)
847 struct samr_SetAliasInfo r;
848 struct samr_QueryAliasInfo q;
849 union samr_AliasInfo *info;
850 uint16_t levels[] = {2, 3};
854 /* Ignoring switch level 1, as that includes the number of members for the alias
855 * and setting this to a wrong value might have negative consequences
858 for (i=0;i<ARRAY_SIZE(levels);i++) {
859 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
861 r.in.alias_handle = handle;
862 r.in.level = levels[i];
863 r.in.info = talloc(tctx, union samr_AliasInfo);
864 switch (r.in.level) {
865 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
866 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
867 "Test Description, should test I18N as well"); break;
868 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
871 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
872 if (!NT_STATUS_IS_OK(status)) {
873 printf("SetAliasInfo level %u failed - %s\n",
874 levels[i], nt_errstr(status));
878 q.in.alias_handle = handle;
879 q.in.level = levels[i];
882 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
883 if (!NT_STATUS_IS_OK(status)) {
884 printf("QueryAliasInfo level %u failed - %s\n",
885 levels[i], nt_errstr(status));
893 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
894 struct policy_handle *user_handle)
896 struct samr_GetGroupsForUser r;
897 struct samr_RidWithAttributeArray *rids = NULL;
900 torture_comment(tctx, "testing GetGroupsForUser\n");
902 r.in.user_handle = user_handle;
905 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
906 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
912 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
913 struct lsa_String *domain_name)
916 struct samr_GetDomPwInfo r;
917 struct samr_PwInfo info;
919 r.in.domain_name = domain_name;
922 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
924 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
925 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
927 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
928 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
930 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
931 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
933 r.in.domain_name->string = "\\\\__NONAME__";
934 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
936 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
937 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
939 r.in.domain_name->string = "\\\\Builtin";
940 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
942 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
943 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
948 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
949 struct policy_handle *handle)
952 struct samr_GetUserPwInfo r;
953 struct samr_PwInfo info;
955 torture_comment(tctx, "Testing GetUserPwInfo\n");
957 r.in.user_handle = handle;
960 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
961 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
966 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
967 struct policy_handle *domain_handle, const char *name,
971 struct samr_LookupNames n;
972 struct lsa_String sname[2];
973 struct samr_Ids rids, types;
975 init_lsa_String(&sname[0], name);
977 n.in.domain_handle = domain_handle;
981 n.out.types = &types;
982 status = dcerpc_samr_LookupNames(p, tctx, &n);
983 if (NT_STATUS_IS_OK(status)) {
984 *rid = n.out.rids->ids[0];
989 init_lsa_String(&sname[1], "xxNONAMExx");
991 status = dcerpc_samr_LookupNames(p, tctx, &n);
992 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
993 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
994 if (NT_STATUS_IS_OK(status)) {
995 return NT_STATUS_UNSUCCESSFUL;
1001 status = dcerpc_samr_LookupNames(p, tctx, &n);
1002 if (!NT_STATUS_IS_OK(status)) {
1003 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1007 init_lsa_String(&sname[0], "xxNONAMExx");
1009 status = dcerpc_samr_LookupNames(p, tctx, &n);
1010 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1011 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1012 if (NT_STATUS_IS_OK(status)) {
1013 return NT_STATUS_UNSUCCESSFUL;
1018 init_lsa_String(&sname[0], "xxNONAMExx");
1019 init_lsa_String(&sname[1], "xxNONAME2xx");
1021 status = dcerpc_samr_LookupNames(p, tctx, &n);
1022 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1023 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1024 if (NT_STATUS_IS_OK(status)) {
1025 return NT_STATUS_UNSUCCESSFUL;
1030 return NT_STATUS_OK;
1033 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1034 struct policy_handle *domain_handle,
1035 const char *name, struct policy_handle *user_handle)
1038 struct samr_OpenUser r;
1041 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1042 if (!NT_STATUS_IS_OK(status)) {
1046 r.in.domain_handle = domain_handle;
1047 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1049 r.out.user_handle = user_handle;
1050 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1051 if (!NT_STATUS_IS_OK(status)) {
1052 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1059 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1060 struct policy_handle *handle)
1063 struct samr_ChangePasswordUser r;
1065 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1066 struct policy_handle user_handle;
1067 char *oldpass = "test";
1068 char *newpass = "test2";
1069 uint8_t old_nt_hash[16], new_nt_hash[16];
1070 uint8_t old_lm_hash[16], new_lm_hash[16];
1072 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1073 if (!NT_STATUS_IS_OK(status)) {
1077 printf("Testing ChangePasswordUser for user 'testuser'\n");
1079 printf("old password: %s\n", oldpass);
1080 printf("new password: %s\n", newpass);
1082 E_md4hash(oldpass, old_nt_hash);
1083 E_md4hash(newpass, new_nt_hash);
1084 E_deshash(oldpass, old_lm_hash);
1085 E_deshash(newpass, new_lm_hash);
1087 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1088 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1089 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1090 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1091 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1092 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1094 r.in.handle = &user_handle;
1095 r.in.lm_present = 1;
1096 r.in.old_lm_crypted = &hash1;
1097 r.in.new_lm_crypted = &hash2;
1098 r.in.nt_present = 1;
1099 r.in.old_nt_crypted = &hash3;
1100 r.in.new_nt_crypted = &hash4;
1101 r.in.cross1_present = 1;
1102 r.in.nt_cross = &hash5;
1103 r.in.cross2_present = 1;
1104 r.in.lm_cross = &hash6;
1106 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1107 if (!NT_STATUS_IS_OK(status)) {
1108 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1112 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1120 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1121 const char *acct_name,
1122 struct policy_handle *handle, char **password)
1125 struct samr_ChangePasswordUser r;
1127 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1128 struct policy_handle user_handle;
1130 uint8_t old_nt_hash[16], new_nt_hash[16];
1131 uint8_t old_lm_hash[16], new_lm_hash[16];
1132 bool changed = true;
1135 struct samr_GetUserPwInfo pwp;
1136 struct samr_PwInfo info;
1137 int policy_min_pw_len = 0;
1139 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1140 if (!NT_STATUS_IS_OK(status)) {
1143 pwp.in.user_handle = &user_handle;
1144 pwp.out.info = &info;
1146 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1147 if (NT_STATUS_IS_OK(status)) {
1148 policy_min_pw_len = pwp.out.info->min_password_length;
1150 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1152 torture_comment(tctx, "Testing ChangePasswordUser\n");
1154 torture_assert(tctx, *password != NULL,
1155 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1157 oldpass = *password;
1159 E_md4hash(oldpass, old_nt_hash);
1160 E_md4hash(newpass, new_nt_hash);
1161 E_deshash(oldpass, old_lm_hash);
1162 E_deshash(newpass, new_lm_hash);
1164 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1165 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1166 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1167 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1168 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1169 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1171 r.in.user_handle = &user_handle;
1172 r.in.lm_present = 1;
1173 /* Break the LM hash */
1175 r.in.old_lm_crypted = &hash1;
1176 r.in.new_lm_crypted = &hash2;
1177 r.in.nt_present = 1;
1178 r.in.old_nt_crypted = &hash3;
1179 r.in.new_nt_crypted = &hash4;
1180 r.in.cross1_present = 1;
1181 r.in.nt_cross = &hash5;
1182 r.in.cross2_present = 1;
1183 r.in.lm_cross = &hash6;
1185 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1186 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1187 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1189 /* Unbreak the LM hash */
1192 r.in.user_handle = &user_handle;
1193 r.in.lm_present = 1;
1194 r.in.old_lm_crypted = &hash1;
1195 r.in.new_lm_crypted = &hash2;
1196 /* Break the NT hash */
1198 r.in.nt_present = 1;
1199 r.in.old_nt_crypted = &hash3;
1200 r.in.new_nt_crypted = &hash4;
1201 r.in.cross1_present = 1;
1202 r.in.nt_cross = &hash5;
1203 r.in.cross2_present = 1;
1204 r.in.lm_cross = &hash6;
1206 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1207 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1208 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1210 /* Unbreak the NT hash */
1213 r.in.user_handle = &user_handle;
1214 r.in.lm_present = 1;
1215 r.in.old_lm_crypted = &hash1;
1216 r.in.new_lm_crypted = &hash2;
1217 r.in.nt_present = 1;
1218 r.in.old_nt_crypted = &hash3;
1219 r.in.new_nt_crypted = &hash4;
1220 r.in.cross1_present = 1;
1221 r.in.nt_cross = &hash5;
1222 r.in.cross2_present = 1;
1223 /* Break the LM cross */
1225 r.in.lm_cross = &hash6;
1227 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1228 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1229 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1233 /* Unbreak the LM cross */
1236 r.in.user_handle = &user_handle;
1237 r.in.lm_present = 1;
1238 r.in.old_lm_crypted = &hash1;
1239 r.in.new_lm_crypted = &hash2;
1240 r.in.nt_present = 1;
1241 r.in.old_nt_crypted = &hash3;
1242 r.in.new_nt_crypted = &hash4;
1243 r.in.cross1_present = 1;
1244 /* Break the NT cross */
1246 r.in.nt_cross = &hash5;
1247 r.in.cross2_present = 1;
1248 r.in.lm_cross = &hash6;
1250 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1251 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1252 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1256 /* Unbreak the NT cross */
1260 /* Reset the hashes to not broken values */
1261 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1262 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1263 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1264 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1265 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1266 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1268 r.in.user_handle = &user_handle;
1269 r.in.lm_present = 1;
1270 r.in.old_lm_crypted = &hash1;
1271 r.in.new_lm_crypted = &hash2;
1272 r.in.nt_present = 1;
1273 r.in.old_nt_crypted = &hash3;
1274 r.in.new_nt_crypted = &hash4;
1275 r.in.cross1_present = 1;
1276 r.in.nt_cross = &hash5;
1277 r.in.cross2_present = 0;
1278 r.in.lm_cross = NULL;
1280 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1281 if (NT_STATUS_IS_OK(status)) {
1283 *password = newpass;
1284 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1285 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1290 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1292 E_md4hash(oldpass, old_nt_hash);
1293 E_md4hash(newpass, new_nt_hash);
1294 E_deshash(oldpass, old_lm_hash);
1295 E_deshash(newpass, new_lm_hash);
1298 /* Reset the hashes to not broken values */
1299 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1300 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1301 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1302 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1303 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1304 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1306 r.in.user_handle = &user_handle;
1307 r.in.lm_present = 1;
1308 r.in.old_lm_crypted = &hash1;
1309 r.in.new_lm_crypted = &hash2;
1310 r.in.nt_present = 1;
1311 r.in.old_nt_crypted = &hash3;
1312 r.in.new_nt_crypted = &hash4;
1313 r.in.cross1_present = 0;
1314 r.in.nt_cross = NULL;
1315 r.in.cross2_present = 1;
1316 r.in.lm_cross = &hash6;
1318 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1319 if (NT_STATUS_IS_OK(status)) {
1321 *password = newpass;
1322 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1323 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1328 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1330 E_md4hash(oldpass, old_nt_hash);
1331 E_md4hash(newpass, new_nt_hash);
1332 E_deshash(oldpass, old_lm_hash);
1333 E_deshash(newpass, new_lm_hash);
1336 /* Reset the hashes to not broken values */
1337 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1338 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1339 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1340 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1341 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1342 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1344 r.in.user_handle = &user_handle;
1345 r.in.lm_present = 1;
1346 r.in.old_lm_crypted = &hash1;
1347 r.in.new_lm_crypted = &hash2;
1348 r.in.nt_present = 1;
1349 r.in.old_nt_crypted = &hash3;
1350 r.in.new_nt_crypted = &hash4;
1351 r.in.cross1_present = 1;
1352 r.in.nt_cross = &hash5;
1353 r.in.cross2_present = 1;
1354 r.in.lm_cross = &hash6;
1356 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1357 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1358 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1359 } else if (!NT_STATUS_IS_OK(status)) {
1360 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1364 *password = newpass;
1367 r.in.user_handle = &user_handle;
1368 r.in.lm_present = 1;
1369 r.in.old_lm_crypted = &hash1;
1370 r.in.new_lm_crypted = &hash2;
1371 r.in.nt_present = 1;
1372 r.in.old_nt_crypted = &hash3;
1373 r.in.new_nt_crypted = &hash4;
1374 r.in.cross1_present = 1;
1375 r.in.nt_cross = &hash5;
1376 r.in.cross2_present = 1;
1377 r.in.lm_cross = &hash6;
1380 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1381 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1382 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1383 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1384 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1390 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1398 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1399 const char *acct_name,
1400 struct policy_handle *handle, char **password)
1403 struct samr_OemChangePasswordUser2 r;
1405 struct samr_Password lm_verifier;
1406 struct samr_CryptPassword lm_pass;
1407 struct lsa_AsciiString server, account, account_bad;
1410 uint8_t old_lm_hash[16], new_lm_hash[16];
1412 struct samr_GetDomPwInfo dom_pw_info;
1413 struct samr_PwInfo info;
1414 int policy_min_pw_len = 0;
1416 struct lsa_String domain_name;
1418 domain_name.string = "";
1419 dom_pw_info.in.domain_name = &domain_name;
1420 dom_pw_info.out.info = &info;
1422 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1424 torture_assert(tctx, *password != NULL,
1425 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1427 oldpass = *password;
1429 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1430 if (NT_STATUS_IS_OK(status)) {
1431 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1434 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1436 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1437 account.string = acct_name;
1439 E_deshash(oldpass, old_lm_hash);
1440 E_deshash(newpass, new_lm_hash);
1442 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1443 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1444 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1446 r.in.server = &server;
1447 r.in.account = &account;
1448 r.in.password = &lm_pass;
1449 r.in.hash = &lm_verifier;
1451 /* Break the verification */
1452 lm_verifier.hash[0]++;
1454 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1456 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1457 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1458 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1463 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1464 /* Break the old password */
1466 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1467 /* unbreak it for the next operation */
1469 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1471 r.in.server = &server;
1472 r.in.account = &account;
1473 r.in.password = &lm_pass;
1474 r.in.hash = &lm_verifier;
1476 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1478 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1479 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1480 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1485 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1486 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1488 r.in.server = &server;
1489 r.in.account = &account;
1490 r.in.password = &lm_pass;
1493 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1495 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1496 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1497 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1502 /* This shouldn't be a valid name */
1503 account_bad.string = TEST_ACCOUNT_NAME "XX";
1504 r.in.account = &account_bad;
1506 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1508 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1509 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1514 /* This shouldn't be a valid name */
1515 account_bad.string = TEST_ACCOUNT_NAME "XX";
1516 r.in.account = &account_bad;
1517 r.in.password = &lm_pass;
1518 r.in.hash = &lm_verifier;
1520 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1522 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1523 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1528 /* This shouldn't be a valid name */
1529 account_bad.string = TEST_ACCOUNT_NAME "XX";
1530 r.in.account = &account_bad;
1531 r.in.password = NULL;
1532 r.in.hash = &lm_verifier;
1534 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1536 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1537 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1542 E_deshash(oldpass, old_lm_hash);
1543 E_deshash(newpass, new_lm_hash);
1545 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1546 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1547 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1549 r.in.server = &server;
1550 r.in.account = &account;
1551 r.in.password = &lm_pass;
1552 r.in.hash = &lm_verifier;
1554 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1555 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1556 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1557 } else if (!NT_STATUS_IS_OK(status)) {
1558 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1561 *password = newpass;
1568 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1569 const char *acct_name,
1571 char *newpass, bool allow_password_restriction)
1574 struct samr_ChangePasswordUser2 r;
1576 struct lsa_String server, account;
1577 struct samr_CryptPassword nt_pass, lm_pass;
1578 struct samr_Password nt_verifier, lm_verifier;
1580 uint8_t old_nt_hash[16], new_nt_hash[16];
1581 uint8_t old_lm_hash[16], new_lm_hash[16];
1583 struct samr_GetDomPwInfo dom_pw_info;
1584 struct samr_PwInfo info;
1586 struct lsa_String domain_name;
1588 domain_name.string = "";
1589 dom_pw_info.in.domain_name = &domain_name;
1590 dom_pw_info.out.info = &info;
1592 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
1594 torture_assert(tctx, *password != NULL,
1595 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
1596 oldpass = *password;
1599 int policy_min_pw_len = 0;
1600 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1601 if (NT_STATUS_IS_OK(status)) {
1602 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1605 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1608 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1609 init_lsa_String(&account, acct_name);
1611 E_md4hash(oldpass, old_nt_hash);
1612 E_md4hash(newpass, new_nt_hash);
1614 E_deshash(oldpass, old_lm_hash);
1615 E_deshash(newpass, new_lm_hash);
1617 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1618 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1619 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1621 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1622 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1623 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1625 r.in.server = &server;
1626 r.in.account = &account;
1627 r.in.nt_password = &nt_pass;
1628 r.in.nt_verifier = &nt_verifier;
1630 r.in.lm_password = &lm_pass;
1631 r.in.lm_verifier = &lm_verifier;
1633 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
1634 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1635 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1636 } else if (!NT_STATUS_IS_OK(status)) {
1637 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1640 *password = newpass;
1647 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
1648 const char *account_string,
1649 int policy_min_pw_len,
1651 const char *newpass,
1652 NTTIME last_password_change,
1653 bool handle_reject_reason)
1656 struct samr_ChangePasswordUser3 r;
1658 struct lsa_String server, account, account_bad;
1659 struct samr_CryptPassword nt_pass, lm_pass;
1660 struct samr_Password nt_verifier, lm_verifier;
1662 uint8_t old_nt_hash[16], new_nt_hash[16];
1663 uint8_t old_lm_hash[16], new_lm_hash[16];
1665 struct samr_DomInfo1 *dominfo = NULL;
1666 struct samr_ChangeReject *reject = NULL;
1668 torture_comment(tctx, "Testing ChangePasswordUser3\n");
1670 if (newpass == NULL) {
1672 if (policy_min_pw_len == 0) {
1673 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1675 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
1677 } while (check_password_quality(newpass) == false);
1679 torture_comment(tctx, "Using password '%s'\n", newpass);
1682 torture_assert(tctx, *password != NULL,
1683 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1685 oldpass = *password;
1686 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1687 init_lsa_String(&account, account_string);
1689 E_md4hash(oldpass, old_nt_hash);
1690 E_md4hash(newpass, new_nt_hash);
1692 E_deshash(oldpass, old_lm_hash);
1693 E_deshash(newpass, new_lm_hash);
1695 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1696 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1697 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1699 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1700 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1701 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1703 /* Break the verification */
1704 nt_verifier.hash[0]++;
1706 r.in.server = &server;
1707 r.in.account = &account;
1708 r.in.nt_password = &nt_pass;
1709 r.in.nt_verifier = &nt_verifier;
1711 r.in.lm_password = &lm_pass;
1712 r.in.lm_verifier = &lm_verifier;
1713 r.in.password3 = NULL;
1714 r.out.dominfo = &dominfo;
1715 r.out.reject = &reject;
1717 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1718 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1719 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1720 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1725 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1726 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1727 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1729 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1730 /* Break the NT hash */
1732 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1733 /* Unbreak it again */
1735 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1737 r.in.server = &server;
1738 r.in.account = &account;
1739 r.in.nt_password = &nt_pass;
1740 r.in.nt_verifier = &nt_verifier;
1742 r.in.lm_password = &lm_pass;
1743 r.in.lm_verifier = &lm_verifier;
1744 r.in.password3 = NULL;
1745 r.out.dominfo = &dominfo;
1746 r.out.reject = &reject;
1748 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1749 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1750 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1751 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1756 /* This shouldn't be a valid name */
1757 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
1759 r.in.account = &account_bad;
1760 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1761 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1762 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1767 E_md4hash(oldpass, old_nt_hash);
1768 E_md4hash(newpass, new_nt_hash);
1770 E_deshash(oldpass, old_lm_hash);
1771 E_deshash(newpass, new_lm_hash);
1773 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1774 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1775 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1777 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1778 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1779 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1781 r.in.server = &server;
1782 r.in.account = &account;
1783 r.in.nt_password = &nt_pass;
1784 r.in.nt_verifier = &nt_verifier;
1786 r.in.lm_password = &lm_pass;
1787 r.in.lm_verifier = &lm_verifier;
1788 r.in.password3 = NULL;
1789 r.out.dominfo = &dominfo;
1790 r.out.reject = &reject;
1792 unix_to_nt_time(&t, time(NULL));
1794 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1796 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1799 && handle_reject_reason
1800 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
1801 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1803 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
1804 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1805 SAMR_REJECT_OTHER, reject->reason);
1810 /* We tested the order of precendence which is as follows:
1819 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1820 (last_password_change + dominfo->min_password_age > t)) {
1822 if (reject->reason != SAMR_REJECT_OTHER) {
1823 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1824 SAMR_REJECT_OTHER, reject->reason);
1828 } else if ((dominfo->min_password_length > 0) &&
1829 (strlen(newpass) < dominfo->min_password_length)) {
1831 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
1832 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1833 SAMR_REJECT_TOO_SHORT, reject->reason);
1837 } else if ((dominfo->password_history_length > 0) &&
1838 strequal(oldpass, newpass)) {
1840 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
1841 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1842 SAMR_REJECT_IN_HISTORY, reject->reason);
1845 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1847 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
1848 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1849 SAMR_REJECT_COMPLEXITY, reject->reason);
1855 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
1856 /* retry with adjusted size */
1857 return test_ChangePasswordUser3(p, tctx, account_string,
1858 dominfo->min_password_length,
1859 password, NULL, 0, false);
1863 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1864 if (reject && reject->reason != SAMR_REJECT_OTHER) {
1865 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1866 SAMR_REJECT_OTHER, reject->reason);
1869 /* Perhaps the server has a 'min password age' set? */
1872 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
1873 *password = talloc_strdup(tctx, newpass);
1879 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
1880 const char *account_string,
1881 struct policy_handle *handle,
1885 struct samr_ChangePasswordUser3 r;
1886 struct samr_SetUserInfo s;
1887 union samr_UserInfo u;
1888 DATA_BLOB session_key;
1889 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1890 uint8_t confounder[16];
1891 struct MD5Context ctx;
1894 struct lsa_String server, account;
1895 struct samr_CryptPassword nt_pass;
1896 struct samr_Password nt_verifier;
1897 DATA_BLOB new_random_pass;
1900 uint8_t old_nt_hash[16], new_nt_hash[16];
1902 struct samr_DomInfo1 *dominfo = NULL;
1903 struct samr_ChangeReject *reject = NULL;
1905 new_random_pass = samr_very_rand_pass(tctx, 128);
1907 torture_assert(tctx, *password != NULL,
1908 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1910 oldpass = *password;
1911 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1912 init_lsa_String(&account, account_string);
1914 s.in.user_handle = handle;
1920 u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
1922 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
1924 status = dcerpc_fetch_session_key(p, &session_key);
1925 if (!NT_STATUS_IS_OK(status)) {
1926 printf("SetUserInfo level %u - no session key - %s\n",
1927 s.in.level, nt_errstr(status));
1931 generate_random_buffer((uint8_t *)confounder, 16);
1934 MD5Update(&ctx, confounder, 16);
1935 MD5Update(&ctx, session_key.data, session_key.length);
1936 MD5Final(confounded_session_key.data, &ctx);
1938 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1939 memcpy(&u.info25.password.data[516], confounder, 16);
1941 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
1943 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1944 if (!NT_STATUS_IS_OK(status)) {
1945 printf("SetUserInfo level %u failed - %s\n",
1946 s.in.level, nt_errstr(status));
1950 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
1952 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1954 new_random_pass = samr_very_rand_pass(tctx, 128);
1956 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
1958 set_pw_in_buffer(nt_pass.data, &new_random_pass);
1959 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1960 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1962 r.in.server = &server;
1963 r.in.account = &account;
1964 r.in.nt_password = &nt_pass;
1965 r.in.nt_verifier = &nt_verifier;
1967 r.in.lm_password = NULL;
1968 r.in.lm_verifier = NULL;
1969 r.in.password3 = NULL;
1970 r.out.dominfo = &dominfo;
1971 r.out.reject = &reject;
1973 unix_to_nt_time(&t, time(NULL));
1975 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1977 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1978 if (reject && reject->reason != SAMR_REJECT_OTHER) {
1979 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1980 SAMR_REJECT_OTHER, reject->reason);
1983 /* Perhaps the server has a 'min password age' set? */
1985 } else if (!NT_STATUS_IS_OK(status)) {
1986 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1990 newpass = samr_rand_pass(tctx, 128);
1992 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1994 E_md4hash(newpass, new_nt_hash);
1996 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1997 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1998 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2000 r.in.server = &server;
2001 r.in.account = &account;
2002 r.in.nt_password = &nt_pass;
2003 r.in.nt_verifier = &nt_verifier;
2005 r.in.lm_password = NULL;
2006 r.in.lm_verifier = NULL;
2007 r.in.password3 = NULL;
2008 r.out.dominfo = &dominfo;
2009 r.out.reject = &reject;
2011 unix_to_nt_time(&t, time(NULL));
2013 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2015 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2016 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2017 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2018 SAMR_REJECT_OTHER, reject->reason);
2021 /* Perhaps the server has a 'min password age' set? */
2024 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2025 *password = talloc_strdup(tctx, newpass);
2032 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2033 struct policy_handle *alias_handle)
2035 struct samr_GetMembersInAlias r;
2036 struct lsa_SidArray sids;
2039 torture_comment(tctx, "Testing GetMembersInAlias\n");
2041 r.in.alias_handle = alias_handle;
2044 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2045 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2050 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2051 struct policy_handle *alias_handle,
2052 const struct dom_sid *domain_sid)
2054 struct samr_AddAliasMember r;
2055 struct samr_DeleteAliasMember d;
2057 struct dom_sid *sid;
2059 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2061 torture_comment(tctx, "testing AddAliasMember\n");
2062 r.in.alias_handle = alias_handle;
2065 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2066 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2068 d.in.alias_handle = alias_handle;
2071 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2072 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2077 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2078 struct policy_handle *alias_handle)
2080 struct samr_AddMultipleMembersToAlias a;
2081 struct samr_RemoveMultipleMembersFromAlias r;
2083 struct lsa_SidArray sids;
2085 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2086 a.in.alias_handle = alias_handle;
2090 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2092 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2093 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2094 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2096 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2097 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2100 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2101 r.in.alias_handle = alias_handle;
2104 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2105 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2107 /* strange! removing twice doesn't give any error */
2108 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2109 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2111 /* but removing an alias that isn't there does */
2112 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2114 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2115 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2120 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2121 struct policy_handle *user_handle)
2123 struct samr_TestPrivateFunctionsUser r;
2126 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2128 r.in.user_handle = user_handle;
2130 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2131 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2137 static bool test_user_ops(struct dcerpc_pipe *p,
2138 struct torture_context *tctx,
2139 struct policy_handle *user_handle,
2140 struct policy_handle *domain_handle,
2141 uint32_t base_acct_flags,
2142 const char *base_acct_name, enum torture_samr_choice which_ops)
2144 char *password = NULL;
2145 struct samr_QueryUserInfo q;
2146 union samr_UserInfo *info;
2152 const uint32_t password_fields[] = {
2153 SAMR_FIELD_PASSWORD,
2154 SAMR_FIELD_PASSWORD2,
2155 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2159 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2160 if (!NT_STATUS_IS_OK(status)) {
2164 switch (which_ops) {
2165 case TORTURE_SAMR_USER_ATTRIBUTES:
2166 if (!test_QuerySecurity(p, tctx, user_handle)) {
2170 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2174 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2178 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2183 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2187 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2191 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2195 case TORTURE_SAMR_PASSWORDS:
2196 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2197 char simple_pass[9];
2198 char *v = generate_random_str(tctx, 1);
2200 ZERO_STRUCT(simple_pass);
2201 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2203 printf("Testing machine account password policy rules\n");
2205 /* Workstation trust accounts don't seem to need to honour password quality policy */
2206 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2210 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2214 /* reset again, to allow another 'user' password change */
2215 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2219 /* Try a 'short' password */
2220 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2224 /* Try a compleatly random password */
2225 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
2230 for (i = 0; password_fields[i]; i++) {
2231 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2235 /* check it was set right */
2236 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2241 for (i = 0; password_fields[i]; i++) {
2242 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2246 /* check it was set right */
2247 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2252 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2256 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2260 q.in.user_handle = user_handle;
2264 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2265 if (!NT_STATUS_IS_OK(status)) {
2266 printf("QueryUserInfo level %u failed - %s\n",
2267 q.in.level, nt_errstr(status));
2270 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2271 if ((info->info5.acct_flags) != expected_flags) {
2272 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2273 info->info5.acct_flags,
2277 if (info->info5.rid != rid) {
2278 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2279 info->info5.rid, rid);
2285 case TORTURE_SAMR_OTHER:
2286 /* We just need the account to exist */
2292 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2293 struct policy_handle *alias_handle,
2294 const struct dom_sid *domain_sid)
2298 if (!test_QuerySecurity(p, tctx, alias_handle)) {
2302 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2306 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2310 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2314 if (torture_setting_bool(tctx, "samba4", false)) {
2315 printf("skipping MultipleMembers Alias tests against Samba4\n");
2319 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2327 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2328 struct policy_handle *user_handle)
2330 struct samr_DeleteUser d;
2332 torture_comment(tctx, "Testing DeleteUser\n");
2334 d.in.user_handle = user_handle;
2335 d.out.user_handle = user_handle;
2337 status = dcerpc_samr_DeleteUser(p, tctx, &d);
2338 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
2343 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2344 struct policy_handle *handle, const char *name)
2347 struct samr_DeleteUser d;
2348 struct policy_handle user_handle;
2351 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2352 if (!NT_STATUS_IS_OK(status)) {
2356 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2357 if (!NT_STATUS_IS_OK(status)) {
2361 d.in.user_handle = &user_handle;
2362 d.out.user_handle = &user_handle;
2363 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2364 if (!NT_STATUS_IS_OK(status)) {
2371 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2376 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2377 struct policy_handle *handle, const char *name)
2380 struct samr_OpenGroup r;
2381 struct samr_DeleteDomainGroup d;
2382 struct policy_handle group_handle;
2385 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2386 if (!NT_STATUS_IS_OK(status)) {
2390 r.in.domain_handle = handle;
2391 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2393 r.out.group_handle = &group_handle;
2394 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2395 if (!NT_STATUS_IS_OK(status)) {
2399 d.in.group_handle = &group_handle;
2400 d.out.group_handle = &group_handle;
2401 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2402 if (!NT_STATUS_IS_OK(status)) {
2409 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2414 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2415 struct policy_handle *domain_handle, const char *name)
2418 struct samr_OpenAlias r;
2419 struct samr_DeleteDomAlias d;
2420 struct policy_handle alias_handle;
2423 printf("testing DeleteAlias_byname\n");
2425 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2426 if (!NT_STATUS_IS_OK(status)) {
2430 r.in.domain_handle = domain_handle;
2431 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2433 r.out.alias_handle = &alias_handle;
2434 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2435 if (!NT_STATUS_IS_OK(status)) {
2439 d.in.alias_handle = &alias_handle;
2440 d.out.alias_handle = &alias_handle;
2441 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2442 if (!NT_STATUS_IS_OK(status)) {
2449 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2453 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2454 struct policy_handle *alias_handle)
2456 struct samr_DeleteDomAlias d;
2459 printf("Testing DeleteAlias\n");
2461 d.in.alias_handle = alias_handle;
2462 d.out.alias_handle = alias_handle;
2464 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2465 if (!NT_STATUS_IS_OK(status)) {
2466 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2473 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2474 struct policy_handle *domain_handle,
2475 struct policy_handle *alias_handle,
2476 const struct dom_sid *domain_sid)
2479 struct samr_CreateDomAlias r;
2480 struct lsa_String name;
2484 init_lsa_String(&name, TEST_ALIASNAME);
2485 r.in.domain_handle = domain_handle;
2486 r.in.alias_name = &name;
2487 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2488 r.out.alias_handle = alias_handle;
2491 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2493 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2495 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2496 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2497 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
2500 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
2506 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2507 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
2510 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2513 if (!NT_STATUS_IS_OK(status)) {
2514 printf("CreateAlias failed - %s\n", nt_errstr(status));
2518 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
2525 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2526 const char *acct_name,
2527 struct policy_handle *domain_handle, char **password)
2535 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2539 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
2543 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2547 /* test what happens when setting the old password again */
2548 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
2553 char simple_pass[9];
2554 char *v = generate_random_str(mem_ctx, 1);
2556 ZERO_STRUCT(simple_pass);
2557 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2559 /* test what happens when picking a simple password */
2560 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
2565 /* set samr_SetDomainInfo level 1 with min_length 5 */
2567 struct samr_QueryDomainInfo r;
2568 union samr_DomainInfo *info = NULL;
2569 struct samr_SetDomainInfo s;
2570 uint16_t len_old, len;
2571 uint32_t pwd_prop_old;
2572 int64_t min_pwd_age_old;
2577 r.in.domain_handle = domain_handle;
2581 printf("testing samr_QueryDomainInfo level 1\n");
2582 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2583 if (!NT_STATUS_IS_OK(status)) {
2587 s.in.domain_handle = domain_handle;
2591 /* remember the old min length, so we can reset it */
2592 len_old = s.in.info->info1.min_password_length;
2593 s.in.info->info1.min_password_length = len;
2594 pwd_prop_old = s.in.info->info1.password_properties;
2595 /* turn off password complexity checks for this test */
2596 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2598 min_pwd_age_old = s.in.info->info1.min_password_age;
2599 s.in.info->info1.min_password_age = 0;
2601 printf("testing samr_SetDomainInfo level 1\n");
2602 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2603 if (!NT_STATUS_IS_OK(status)) {
2607 printf("calling test_ChangePasswordUser3 with too short password\n");
2609 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
2613 s.in.info->info1.min_password_length = len_old;
2614 s.in.info->info1.password_properties = pwd_prop_old;
2615 s.in.info->info1.min_password_age = min_pwd_age_old;
2617 printf("testing samr_SetDomainInfo level 1\n");
2618 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2619 if (!NT_STATUS_IS_OK(status)) {
2627 struct samr_OpenUser r;
2628 struct samr_QueryUserInfo q;
2629 union samr_UserInfo *info;
2630 struct samr_LookupNames n;
2631 struct policy_handle user_handle;
2632 struct samr_Ids rids, types;
2634 n.in.domain_handle = domain_handle;
2636 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2637 n.in.names[0].string = acct_name;
2639 n.out.types = &types;
2641 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2642 if (!NT_STATUS_IS_OK(status)) {
2643 printf("LookupNames failed - %s\n", nt_errstr(status));
2647 r.in.domain_handle = domain_handle;
2648 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2649 r.in.rid = n.out.rids->ids[0];
2650 r.out.user_handle = &user_handle;
2652 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2653 if (!NT_STATUS_IS_OK(status)) {
2654 printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
2658 q.in.user_handle = &user_handle;
2662 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2663 if (!NT_STATUS_IS_OK(status)) {
2664 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2668 printf("calling test_ChangePasswordUser3 with too early password change\n");
2670 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2671 info->info5.last_password_change, true)) {
2676 /* we change passwords twice - this has the effect of verifying
2677 they were changed correctly for the final call */
2678 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2682 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2689 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2690 struct policy_handle *domain_handle,
2691 struct policy_handle *user_handle_out,
2692 struct dom_sid *domain_sid,
2693 enum torture_samr_choice which_ops)
2696 TALLOC_CTX *user_ctx;
2699 struct samr_CreateUser r;
2700 struct samr_QueryUserInfo q;
2701 union samr_UserInfo *info;
2702 struct samr_DeleteUser d;
2705 /* This call creates a 'normal' account - check that it really does */
2706 const uint32_t acct_flags = ACB_NORMAL;
2707 struct lsa_String name;
2710 struct policy_handle user_handle;
2711 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2712 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2714 r.in.domain_handle = domain_handle;
2715 r.in.account_name = &name;
2716 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2717 r.out.user_handle = &user_handle;
2720 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2722 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2724 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2725 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2726 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2729 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2735 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2736 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2737 talloc_free(user_ctx);
2740 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2742 if (!NT_STATUS_IS_OK(status)) {
2743 talloc_free(user_ctx);
2744 printf("CreateUser failed - %s\n", nt_errstr(status));
2747 q.in.user_handle = &user_handle;
2751 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2752 if (!NT_STATUS_IS_OK(status)) {
2753 printf("QueryUserInfo level %u failed - %s\n",
2754 q.in.level, nt_errstr(status));
2757 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
2758 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2759 info->info16.acct_flags,
2765 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2766 acct_flags, name.string, which_ops)) {
2770 if (user_handle_out) {
2771 *user_handle_out = user_handle;
2773 printf("Testing DeleteUser (createuser test)\n");
2775 d.in.user_handle = &user_handle;
2776 d.out.user_handle = &user_handle;
2778 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2779 if (!NT_STATUS_IS_OK(status)) {
2780 printf("DeleteUser failed - %s\n", nt_errstr(status));
2787 talloc_free(user_ctx);
2793 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2794 struct policy_handle *domain_handle,
2795 struct dom_sid *domain_sid,
2796 enum torture_samr_choice which_ops)
2799 struct samr_CreateUser2 r;
2800 struct samr_QueryUserInfo q;
2801 union samr_UserInfo *info;
2802 struct samr_DeleteUser d;
2803 struct policy_handle user_handle;
2805 struct lsa_String name;
2810 uint32_t acct_flags;
2811 const char *account_name;
2813 } account_types[] = {
2814 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2815 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2816 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2817 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2818 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2819 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2820 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2821 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2822 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2823 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2824 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2825 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2826 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2827 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2828 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2831 for (i = 0; account_types[i].account_name; i++) {
2832 TALLOC_CTX *user_ctx;
2833 uint32_t acct_flags = account_types[i].acct_flags;
2834 uint32_t access_granted;
2835 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2836 init_lsa_String(&name, account_types[i].account_name);
2838 r.in.domain_handle = domain_handle;
2839 r.in.account_name = &name;
2840 r.in.acct_flags = acct_flags;
2841 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2842 r.out.user_handle = &user_handle;
2843 r.out.access_granted = &access_granted;
2846 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2848 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2850 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2851 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2852 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2855 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2862 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2863 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2864 talloc_free(user_ctx);
2868 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2871 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2872 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2873 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2877 if (NT_STATUS_IS_OK(status)) {
2878 q.in.user_handle = &user_handle;
2882 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2883 if (!NT_STATUS_IS_OK(status)) {
2884 printf("QueryUserInfo level %u failed - %s\n",
2885 q.in.level, nt_errstr(status));
2888 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2889 if (acct_flags == ACB_NORMAL) {
2890 expected_flags |= ACB_PW_EXPIRED;
2892 if ((info->info5.acct_flags) != expected_flags) {
2893 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2894 info->info5.acct_flags,
2898 switch (acct_flags) {
2900 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
2901 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2902 DOMAIN_RID_DCS, info->info5.primary_gid);
2907 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2908 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2909 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
2914 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
2915 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2916 DOMAIN_RID_USERS, info->info5.primary_gid);
2923 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2924 acct_flags, name.string, which_ops)) {
2928 printf("Testing DeleteUser (createuser2 test)\n");
2930 d.in.user_handle = &user_handle;
2931 d.out.user_handle = &user_handle;
2933 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2934 if (!NT_STATUS_IS_OK(status)) {
2935 printf("DeleteUser failed - %s\n", nt_errstr(status));
2939 talloc_free(user_ctx);
2945 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2946 struct policy_handle *handle)
2949 struct samr_QueryAliasInfo r;
2950 union samr_AliasInfo *info;
2951 uint16_t levels[] = {1, 2, 3};
2955 for (i=0;i<ARRAY_SIZE(levels);i++) {
2956 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2958 r.in.alias_handle = handle;
2959 r.in.level = levels[i];
2962 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2963 if (!NT_STATUS_IS_OK(status)) {
2964 printf("QueryAliasInfo level %u failed - %s\n",
2965 levels[i], nt_errstr(status));
2973 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2974 struct policy_handle *handle)
2977 struct samr_QueryGroupInfo r;
2978 union samr_GroupInfo *info;
2979 uint16_t levels[] = {1, 2, 3, 4, 5};
2983 for (i=0;i<ARRAY_SIZE(levels);i++) {
2984 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2986 r.in.group_handle = handle;
2987 r.in.level = levels[i];
2990 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2991 if (!NT_STATUS_IS_OK(status)) {
2992 printf("QueryGroupInfo level %u failed - %s\n",
2993 levels[i], nt_errstr(status));
3001 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3002 struct policy_handle *handle)
3005 struct samr_QueryGroupMember r;
3006 struct samr_RidTypeArray *rids = NULL;
3009 printf("Testing QueryGroupMember\n");
3011 r.in.group_handle = handle;
3014 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
3015 if (!NT_STATUS_IS_OK(status)) {
3016 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
3024 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3025 struct policy_handle *handle)
3028 struct samr_QueryGroupInfo r;
3029 union samr_GroupInfo *info;
3030 struct samr_SetGroupInfo s;
3031 uint16_t levels[] = {1, 2, 3, 4};
3032 uint16_t set_ok[] = {0, 1, 1, 1};
3036 for (i=0;i<ARRAY_SIZE(levels);i++) {
3037 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3039 r.in.group_handle = handle;
3040 r.in.level = levels[i];
3043 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3044 if (!NT_STATUS_IS_OK(status)) {
3045 printf("QueryGroupInfo level %u failed - %s\n",
3046 levels[i], nt_errstr(status));
3050 printf("Testing SetGroupInfo level %u\n", levels[i]);
3052 s.in.group_handle = handle;
3053 s.in.level = levels[i];
3054 s.in.info = *r.out.info;
3057 /* disabled this, as it changes the name only from the point of view of samr,
3058 but leaves the name from the point of view of w2k3 internals (and ldap). This means
3059 the name is still reserved, so creating the old name fails, but deleting by the old name
3061 if (s.in.level == 2) {
3062 init_lsa_String(&s.in.info->string, "NewName");
3066 if (s.in.level == 4) {
3067 init_lsa_String(&s.in.info->description, "test description");
3070 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
3072 if (!NT_STATUS_IS_OK(status)) {
3073 printf("SetGroupInfo level %u failed - %s\n",
3074 r.in.level, nt_errstr(status));
3079 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3080 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3081 r.in.level, nt_errstr(status));
3091 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3092 struct policy_handle *handle)
3095 struct samr_QueryUserInfo r;
3096 union samr_UserInfo *info;
3097 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3098 11, 12, 13, 14, 16, 17, 20, 21};
3102 for (i=0;i<ARRAY_SIZE(levels);i++) {
3103 printf("Testing QueryUserInfo level %u\n", levels[i]);
3105 r.in.user_handle = handle;
3106 r.in.level = levels[i];
3109 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
3110 if (!NT_STATUS_IS_OK(status)) {
3111 printf("QueryUserInfo level %u failed - %s\n",
3112 levels[i], nt_errstr(status));
3120 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3121 struct policy_handle *handle)
3124 struct samr_QueryUserInfo2 r;
3125 union samr_UserInfo *info;
3126 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3127 11, 12, 13, 14, 16, 17, 20, 21};
3131 for (i=0;i<ARRAY_SIZE(levels);i++) {
3132 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
3134 r.in.user_handle = handle;
3135 r.in.level = levels[i];
3138 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
3139 if (!NT_STATUS_IS_OK(status)) {
3140 printf("QueryUserInfo2 level %u failed - %s\n",
3141 levels[i], nt_errstr(status));
3149 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3150 struct policy_handle *handle, uint32_t rid)
3153 struct samr_OpenUser r;
3154 struct policy_handle user_handle;
3157 printf("Testing OpenUser(%u)\n", rid);
3159 r.in.domain_handle = handle;
3160 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3162 r.out.user_handle = &user_handle;
3164 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3165 if (!NT_STATUS_IS_OK(status)) {
3166 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3170 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
3174 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
3178 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
3182 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
3186 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
3190 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3197 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3198 struct policy_handle *handle, uint32_t rid)
3201 struct samr_OpenGroup r;
3202 struct policy_handle group_handle;
3205 printf("Testing OpenGroup(%u)\n", rid);
3207 r.in.domain_handle = handle;
3208 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3210 r.out.group_handle = &group_handle;
3212 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3213 if (!NT_STATUS_IS_OK(status)) {
3214 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
3218 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
3222 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
3226 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
3230 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3237 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3238 struct policy_handle *handle, uint32_t rid)
3241 struct samr_OpenAlias r;
3242 struct policy_handle alias_handle;
3245 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
3247 r.in.domain_handle = handle;
3248 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3250 r.out.alias_handle = &alias_handle;
3252 status = dcerpc_samr_OpenAlias(p, tctx, &r);
3253 if (!NT_STATUS_IS_OK(status)) {
3254 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3258 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
3262 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
3266 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
3270 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
3277 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
3278 struct policy_handle *handle, uint32_t rid,
3279 uint32_t acct_flag_mask)
3282 struct samr_OpenUser r;
3283 struct samr_QueryUserInfo q;
3284 union samr_UserInfo *info;
3285 struct policy_handle user_handle;
3288 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
3290 r.in.domain_handle = handle;
3291 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3293 r.out.user_handle = &user_handle;
3295 status = dcerpc_samr_OpenUser(p, tctx, &r);
3296 if (!NT_STATUS_IS_OK(status)) {
3297 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3301 q.in.user_handle = &user_handle;
3305 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3306 if (!NT_STATUS_IS_OK(status)) {
3307 printf("QueryUserInfo level 16 failed - %s\n",
3311 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
3312 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3313 acct_flag_mask, info->info16.acct_flags, rid);
3318 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
3325 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
3326 struct policy_handle *handle)
3328 NTSTATUS status = STATUS_MORE_ENTRIES;
3329 struct samr_EnumDomainUsers r;
3330 uint32_t mask, resume_handle=0;
3333 struct samr_LookupNames n;
3334 struct samr_LookupRids lr ;
3335 struct lsa_Strings names;
3336 struct samr_Ids rids, types;
3337 struct samr_SamArray *sam = NULL;
3338 uint32_t num_entries = 0;
3340 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3341 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3342 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3345 printf("Testing EnumDomainUsers\n");
3347 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3348 r.in.domain_handle = handle;
3349 r.in.resume_handle = &resume_handle;
3350 r.in.acct_flags = mask = masks[mask_idx];
3351 r.in.max_size = (uint32_t)-1;
3352 r.out.resume_handle = &resume_handle;
3353 r.out.num_entries = &num_entries;
3356 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
3357 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3358 !NT_STATUS_IS_OK(status)) {
3359 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3363 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
3365 if (sam->count == 0) {
3369 for (i=0;i<sam->count;i++) {
3371 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
3374 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
3380 printf("Testing LookupNames\n");
3381 n.in.domain_handle = handle;
3382 n.in.num_names = sam->count;
3383 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
3385 n.out.types = &types;
3386 for (i=0;i<sam->count;i++) {
3387 n.in.names[i].string = sam->entries[i].name.string;
3389 status = dcerpc_samr_LookupNames(p, tctx, &n);
3390 if (!NT_STATUS_IS_OK(status)) {
3391 printf("LookupNames failed - %s\n", nt_errstr(status));
3396 printf("Testing LookupRids\n");
3397 lr.in.domain_handle = handle;
3398 lr.in.num_rids = sam->count;
3399 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
3400 lr.out.names = &names;
3401 lr.out.types = &types;
3402 for (i=0;i<sam->count;i++) {
3403 lr.in.rids[i] = sam->entries[i].idx;
3405 status = dcerpc_samr_LookupRids(p, tctx, &lr);
3406 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
3412 try blasting the server with a bunch of sync requests
3414 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
3415 struct policy_handle *handle)
3418 struct samr_EnumDomainUsers r;
3419 uint32_t resume_handle=0;
3421 #define ASYNC_COUNT 100
3422 struct rpc_request *req[ASYNC_COUNT];
3424 if (!torture_setting_bool(tctx, "dangerous", false)) {
3425 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
3428 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
3430 r.in.domain_handle = handle;
3431 r.in.resume_handle = &resume_handle;
3432 r.in.acct_flags = 0;
3433 r.in.max_size = (uint32_t)-1;
3434 r.out.resume_handle = &resume_handle;
3436 for (i=0;i<ASYNC_COUNT;i++) {
3437 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
3440 for (i=0;i<ASYNC_COUNT;i++) {
3441 status = dcerpc_ndr_request_recv(req[i]);
3442 if (!NT_STATUS_IS_OK(status)) {
3443 printf("EnumDomainUsers[%d] failed - %s\n",
3444 i, nt_errstr(status));
3449 torture_comment(tctx, "%d async requests OK\n", i);
3454 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3455 struct policy_handle *handle)
3458 struct samr_EnumDomainGroups r;
3459 uint32_t resume_handle=0;
3460 struct samr_SamArray *sam = NULL;
3461 uint32_t num_entries = 0;
3465 printf("Testing EnumDomainGroups\n");
3467 r.in.domain_handle = handle;
3468 r.in.resume_handle = &resume_handle;
3469 r.in.max_size = (uint32_t)-1;
3470 r.out.resume_handle = &resume_handle;
3471 r.out.num_entries = &num_entries;
3474 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3475 if (!NT_STATUS_IS_OK(status)) {
3476 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3484 for (i=0;i<sam->count;i++) {
3485 if (!test_OpenGroup(p, mem_ctx, handle, sam->entries[i].idx)) {
3493 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3494 struct policy_handle *handle)
3497 struct samr_EnumDomainAliases r;
3498 uint32_t resume_handle=0;
3499 struct samr_SamArray *sam = NULL;
3500 uint32_t num_entries = 0;
3504 printf("Testing EnumDomainAliases\n");
3506 r.in.domain_handle = handle;
3507 r.in.resume_handle = &resume_handle;
3508 r.in.max_size = (uint32_t)-1;
3510 r.out.num_entries = &num_entries;
3511 r.out.resume_handle = &resume_handle;
3513 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3514 if (!NT_STATUS_IS_OK(status)) {
3515 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3523 for (i=0;i<sam->count;i++) {
3524 if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) {
3532 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3533 struct policy_handle *handle)
3536 struct samr_GetDisplayEnumerationIndex r;
3538 uint16_t levels[] = {1, 2, 3, 4, 5};
3539 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3540 struct lsa_String name;
3544 for (i=0;i<ARRAY_SIZE(levels);i++) {
3545 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3547 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3549 r.in.domain_handle = handle;
3550 r.in.level = levels[i];
3554 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3557 !NT_STATUS_IS_OK(status) &&
3558 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3559 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3560 levels[i], nt_errstr(status));
3564 init_lsa_String(&name, "zzzzzzzz");
3566 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3568 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3569 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3570 levels[i], nt_errstr(status));
3578 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3579 struct policy_handle *handle)
3582 struct samr_GetDisplayEnumerationIndex2 r;
3584 uint16_t levels[] = {1, 2, 3, 4, 5};
3585 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3586 struct lsa_String name;
3590 for (i=0;i<ARRAY_SIZE(levels);i++) {
3591 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3593 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3595 r.in.domain_handle = handle;
3596 r.in.level = levels[i];
3600 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3602 !NT_STATUS_IS_OK(status) &&
3603 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3604 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3605 levels[i], nt_errstr(status));
3609 init_lsa_String(&name, "zzzzzzzz");
3611 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3612 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3613 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3614 levels[i], nt_errstr(status));
3622 #define STRING_EQUAL_QUERY(s1, s2, user) \
3623 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3624 /* odd, but valid */ \
3625 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3626 printf("%s mismatch for %s: %s != %s (%s)\n", \
3627 #s1, user.string, s1.string, s2.string, __location__); \
3630 #define INT_EQUAL_QUERY(s1, s2, user) \
3632 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3633 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3637 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3638 struct samr_QueryDisplayInfo *querydisplayinfo,
3639 bool *seen_testuser)
3641 struct samr_OpenUser r;
3642 struct samr_QueryUserInfo q;
3643 union samr_UserInfo *info;
3644 struct policy_handle user_handle;
3647 r.in.domain_handle = querydisplayinfo->in.domain_handle;
3648 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3649 for (i = 0; ; i++) {
3650 switch (querydisplayinfo->in.level) {
3652 if (i >= querydisplayinfo->out.info->info1.count) {
3655 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
3658 if (i >= querydisplayinfo->out.info->info2.count) {
3661 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
3667 /* Not interested in validating just the account name */
3671 r.out.user_handle = &user_handle;
3673 switch (querydisplayinfo->in.level) {
3676 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3677 if (!NT_STATUS_IS_OK(status)) {
3678 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3683 q.in.user_handle = &user_handle;
3686 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3687 if (!NT_STATUS_IS_OK(status)) {
3688 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3692 switch (querydisplayinfo->in.level) {
3694 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3695 *seen_testuser = true;
3697 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
3698 info->info21.full_name, info->info21.account_name);
3699 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
3700 info->info21.account_name, info->info21.account_name);
3701 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
3702 info->info21.description, info->info21.account_name);
3703 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
3704 info->info21.rid, info->info21.account_name);
3705 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
3706 info->info21.acct_flags, info->info21.account_name);
3710 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
3711 info->info21.account_name, info->info21.account_name);
3712 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
3713 info->info21.description, info->info21.account_name);
3714 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
3715 info->info21.rid, info->info21.account_name);
3716 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
3717 info->info21.acct_flags, info->info21.account_name);
3719 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
3720 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
3721 info->info21.account_name.string);
3724 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3725 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3726 info->info21.account_name.string,
3727 querydisplayinfo->out.info->info2.entries[i].acct_flags,
3728 info->info21.acct_flags);
3735 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3742 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3743 struct policy_handle *handle)
3746 struct samr_QueryDisplayInfo r;
3747 struct samr_QueryDomainInfo dom_info;
3748 union samr_DomainInfo *info = NULL;
3750 uint16_t levels[] = {1, 2, 3, 4, 5};
3752 bool seen_testuser = false;
3753 uint32_t total_size;
3754 uint32_t returned_size;
3755 union samr_DispInfo disp_info;
3758 for (i=0;i<ARRAY_SIZE(levels);i++) {
3759 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3762 status = STATUS_MORE_ENTRIES;
3763 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3764 r.in.domain_handle = handle;
3765 r.in.level = levels[i];
3766 r.in.max_entries = 2;
3767 r.in.buf_size = (uint32_t)-1;
3768 r.out.total_size = &total_size;
3769 r.out.returned_size = &returned_size;
3770 r.out.info = &disp_info;
3772 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3773 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3774 printf("QueryDisplayInfo level %u failed - %s\n",
3775 levels[i], nt_errstr(status));
3778 switch (r.in.level) {
3780 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3783 r.in.start_idx += r.out.info->info1.count;
3786 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3789 r.in.start_idx += r.out.info->info2.count;
3792 r.in.start_idx += r.out.info->info3.count;
3795 r.in.start_idx += r.out.info->info4.count;
3798 r.in.start_idx += r.out.info->info5.count;
3802 dom_info.in.domain_handle = handle;
3803 dom_info.in.level = 2;
3804 dom_info.out.info = &info;
3806 /* Check number of users returned is correct */
3807 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3808 if (!NT_STATUS_IS_OK(status)) {
3809 printf("QueryDomainInfo level %u failed - %s\n",
3810 r.in.level, nt_errstr(status));
3814 switch (r.in.level) {
3817 if (info->general.num_users < r.in.start_idx) {
3818 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3819 r.in.start_idx, info->general.num_groups,
3820 info->general.domain_name.string);
3823 if (!seen_testuser) {
3824 struct policy_handle user_handle;
3825 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3826 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
3827 info->general.domain_name.string);
3829 test_samr_handle_Close(p, mem_ctx, &user_handle);
3835 if (info->general.num_groups != r.in.start_idx) {
3836 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3837 r.in.start_idx, info->general.num_groups,
3838 info->general.domain_name.string);
3850 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3851 struct policy_handle *handle)
3854 struct samr_QueryDisplayInfo2 r;
3856 uint16_t levels[] = {1, 2, 3, 4, 5};
3858 uint32_t total_size;
3859 uint32_t returned_size;
3860 union samr_DispInfo info;
3862 for (i=0;i<ARRAY_SIZE(levels);i++) {
3863 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3865 r.in.domain_handle = handle;
3866 r.in.level = levels[i];
3868 r.in.max_entries = 1000;
3869 r.in.buf_size = (uint32_t)-1;
3870 r.out.total_size = &total_size;
3871 r.out.returned_size = &returned_size;
3874 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3875 if (!NT_STATUS_IS_OK(status)) {
3876 printf("QueryDisplayInfo2 level %u failed - %s\n",
3877 levels[i], nt_errstr(status));
3885 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
3886 struct policy_handle *handle)
3889 struct samr_QueryDisplayInfo3 r;
3891 uint16_t levels[] = {1, 2, 3, 4, 5};
3893 uint32_t total_size;
3894 uint32_t returned_size;
3895 union samr_DispInfo info;
3897 for (i=0;i<ARRAY_SIZE(levels);i++) {
3898 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
3900 r.in.domain_handle = handle;
3901 r.in.level = levels[i];
3903 r.in.max_entries = 1000;
3904 r.in.buf_size = (uint32_t)-1;
3905 r.out.total_size = &total_size;
3906 r.out.returned_size = &returned_size;
3909 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
3910 if (!NT_STATUS_IS_OK(status)) {
3911 printf("QueryDisplayInfo3 level %u failed - %s\n",
3912 levels[i], nt_errstr(status));
3921 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3922 struct policy_handle *handle)
3925 struct samr_QueryDisplayInfo r;
3927 uint32_t total_size;
3928 uint32_t returned_size;
3929 union samr_DispInfo info;
3931 printf("Testing QueryDisplayInfo continuation\n");
3933 r.in.domain_handle = handle;
3936 r.in.max_entries = 1;
3937 r.in.buf_size = (uint32_t)-1;
3938 r.out.total_size = &total_size;
3939 r.out.returned_size = &returned_size;
3943 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3944 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
3945 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
3946 printf("expected idx %d but got %d\n",
3948 r.out.info->info1.entries[0].idx);
3952 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3953 !NT_STATUS_IS_OK(status)) {
3954 printf("QueryDisplayInfo level %u failed - %s\n",
3955 r.in.level, nt_errstr(status));
3960 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3961 NT_STATUS_IS_OK(status)) &&
3962 *r.out.returned_size != 0);
3967 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
3968 struct policy_handle *handle)
3971 struct samr_QueryDomainInfo r;
3972 union samr_DomainInfo *info = NULL;
3973 struct samr_SetDomainInfo s;
3974 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3975 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3978 const char *domain_comment = talloc_asprintf(tctx,
3979 "Tortured by Samba4 RPC-SAMR: %s",
3980 timestring(tctx, time(NULL)));
3982 s.in.domain_handle = handle;
3984 s.in.info = talloc(tctx, union samr_DomainInfo);
3986 s.in.info->oem.oem_information.string = domain_comment;
3987 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
3988 if (!NT_STATUS_IS_OK(status)) {
3989 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3990 r.in.level, nt_errstr(status));
3994 for (i=0;i<ARRAY_SIZE(levels);i++) {
3995 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
3997 r.in.domain_handle = handle;
3998 r.in.level = levels[i];
4001 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4002 if (!NT_STATUS_IS_OK(status)) {
4003 printf("QueryDomainInfo level %u failed - %s\n",
4004 r.in.level, nt_errstr(status));
4009 switch (levels[i]) {
4011 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
4012 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
4013 levels[i], info->general.oem_information.string, domain_comment);
4016 if (!info->general.primary.string) {
4017 printf("QueryDomainInfo level %u returned no PDC name\n",
4020 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
4021 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
4022 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
4023 levels[i], info->general.primary.string, dcerpc_server_name(p));
4028 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
4029 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
4030 levels[i], info->oem.oem_information.string, domain_comment);
4035 if (!info->info6.primary.string) {
4036 printf("QueryDomainInfo level %u returned no PDC name\n",
4042 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
4043 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
4044 levels[i], info->general2.general.oem_information.string, domain_comment);
4050 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
4052 s.in.domain_handle = handle;
4053 s.in.level = levels[i];
4056 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4058 if (!NT_STATUS_IS_OK(status)) {
4059 printf("SetDomainInfo level %u failed - %s\n",
4060 r.in.level, nt_errstr(status));
4065 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4066 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4067 r.in.level, nt_errstr(status));
4073 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4074 if (!NT_STATUS_IS_OK(status)) {
4075 printf("QueryDomainInfo level %u failed - %s\n",
4076 r.in.level, nt_errstr(status));
4086 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
4087 struct policy_handle *handle)
4090 struct samr_QueryDomainInfo2 r;
4091 union samr_DomainInfo *info = NULL;
4092 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4096 for (i=0;i<ARRAY_SIZE(levels);i++) {
4097 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
4099 r.in.domain_handle = handle;
4100 r.in.level = levels[i];
4103 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
4104 if (!NT_STATUS_IS_OK(status)) {
4105 printf("QueryDomainInfo2 level %u failed - %s\n",
4106 r.in.level, nt_errstr(status));
4115 /* Test whether querydispinfo level 5 and enumdomgroups return the same
4116 set of group names. */
4117 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
4118 struct policy_handle *handle)
4120 struct samr_EnumDomainGroups q1;
4121 struct samr_QueryDisplayInfo q2;
4123 uint32_t resume_handle=0;
4124 struct samr_SamArray *sam = NULL;
4125 uint32_t num_entries = 0;
4128 uint32_t total_size;
4129 uint32_t returned_size;
4130 union samr_DispInfo info;
4133 const char **names = NULL;
4135 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
4137 q1.in.domain_handle = handle;
4138 q1.in.resume_handle = &resume_handle;
4140 q1.out.resume_handle = &resume_handle;
4141 q1.out.num_entries = &num_entries;
4144 status = STATUS_MORE_ENTRIES;
4145 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4146 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
4148 if (!NT_STATUS_IS_OK(status) &&
4149 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4152 for (i=0; i<*q1.out.num_entries; i++) {
4153 add_string_to_array(tctx,
4154 sam->entries[i].name.string,
4155 &names, &num_names);
4159 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
4161 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
4163 q2.in.domain_handle = handle;
4165 q2.in.start_idx = 0;
4166 q2.in.max_entries = 5;
4167 q2.in.buf_size = (uint32_t)-1;
4168 q2.out.total_size = &total_size;
4169 q2.out.returned_size = &returned_size;
4170 q2.out.info = &info;
4172 status = STATUS_MORE_ENTRIES;
4173 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4174 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
4176 if (!NT_STATUS_IS_OK(status) &&
4177 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4180 for (i=0; i<q2.out.info->info5.count; i++) {
4182 const char *name = q2.out.info->info5.entries[i].account_name.string;
4184 for (j=0; j<num_names; j++) {
4185 if (names[j] == NULL)
4187 if (strequal(names[j], name)) {
4195 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
4200 q2.in.start_idx += q2.out.info->info5.count;
4203 if (!NT_STATUS_IS_OK(status)) {
4204 printf("QueryDisplayInfo level 5 failed - %s\n",
4209 for (i=0; i<num_names; i++) {
4210 if (names[i] != NULL) {
4211 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
4220 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
4221 struct policy_handle *group_handle)
4223 struct samr_DeleteDomainGroup d;
4226 torture_comment(tctx, "Testing DeleteDomainGroup\n");
4228 d.in.group_handle = group_handle;
4229 d.out.group_handle = group_handle;
4231 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
4232 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
4237 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4238 struct policy_handle *domain_handle)
4240 struct samr_TestPrivateFunctionsDomain r;
4244 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
4246 r.in.domain_handle = domain_handle;
4248 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
4249 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
4254 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
4255 struct dom_sid *domain_sid,
4256 struct policy_handle *domain_handle)
4258 struct samr_RidToSid r;
4261 struct dom_sid *calc_sid, *out_sid;
4262 int rids[] = { 0, 42, 512, 10200 };
4265 for (i=0;i<ARRAY_SIZE(rids);i++) {
4266 torture_comment(tctx, "Testing RidToSid\n");
4268 calc_sid = dom_sid_dup(tctx, domain_sid);
4269 r.in.domain_handle = domain_handle;
4271 r.out.sid = &out_sid;
4273 status = dcerpc_samr_RidToSid(p, tctx, &r);
4274 if (!NT_STATUS_IS_OK(status)) {
4275 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
4278 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
4280 if (!dom_sid_equal(calc_sid, out_sid)) {
4281 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
4282 dom_sid_string(tctx, out_sid),
4283 dom_sid_string(tctx, calc_sid));
4292 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
4293 struct policy_handle *domain_handle)
4295 struct samr_GetBootKeyInformation r;
4298 uint32_t unknown = 0;
4300 torture_comment(tctx, "Testing GetBootKeyInformation\n");
4302 r.in.domain_handle = domain_handle;
4303 r.out.unknown = &unknown;
4305 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
4306 if (!NT_STATUS_IS_OK(status)) {
4307 /* w2k3 seems to fail this sometimes and pass it sometimes */
4308 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4314 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
4315 struct policy_handle *domain_handle,
4316 struct policy_handle *group_handle)
4319 struct samr_AddGroupMember r;
4320 struct samr_DeleteGroupMember d;
4321 struct samr_QueryGroupMember q;
4322 struct samr_RidTypeArray *rids = NULL;
4323 struct samr_SetMemberAttributesOfGroup s;
4326 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4327 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
4329 r.in.group_handle = group_handle;
4331 r.in.flags = 0; /* ??? */
4333 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
4335 d.in.group_handle = group_handle;
4338 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4339 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
4341 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4342 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4344 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4345 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
4347 if (torture_setting_bool(tctx, "samba4", false)) {
4348 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
4350 /* this one is quite strange. I am using random inputs in the
4351 hope of triggering an error that might give us a clue */
4353 s.in.group_handle = group_handle;
4354 s.in.unknown1 = random();
4355 s.in.unknown2 = random();
4357 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4358 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
4361 q.in.group_handle = group_handle;
4364 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4365 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
4367 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4368 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
4370 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4371 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4377 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
4378 struct torture_context *tctx,
4379 struct policy_handle *domain_handle,
4380 struct policy_handle *group_handle,
4381 struct dom_sid *domain_sid)
4384 struct samr_CreateDomainGroup r;
4386 struct lsa_String name;
4389 init_lsa_String(&name, TEST_GROUPNAME);
4391 r.in.domain_handle = domain_handle;
4393 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4394 r.out.group_handle = group_handle;
4397 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4399 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4401 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4402 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4403 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
4406 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
4412 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4413 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
4414 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
4418 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4420 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4421 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
4423 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4427 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4429 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
4431 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
4432 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4436 if (!test_SetGroupInfo(p, tctx, group_handle)) {
4445 its not totally clear what this does. It seems to accept any sid you like.
4447 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
4448 struct torture_context *tctx,
4449 struct policy_handle *domain_handle)
4452 struct samr_RemoveMemberFromForeignDomain r;
4454 r.in.domain_handle = domain_handle;
4455 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
4457 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
4458 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
4465 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4466 struct policy_handle *handle);
4468 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4469 struct policy_handle *handle, struct dom_sid *sid,
4470 enum torture_samr_choice which_ops)
4473 struct samr_OpenDomain r;
4474 struct policy_handle domain_handle;
4475 struct policy_handle alias_handle;
4476 struct policy_handle user_handle;
4477 struct policy_handle group_handle;
4480 ZERO_STRUCT(alias_handle);
4481 ZERO_STRUCT(user_handle);
4482 ZERO_STRUCT(group_handle);
4483 ZERO_STRUCT(domain_handle);
4485 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
4487 r.in.connect_handle = handle;
4488 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4490 r.out.domain_handle = &domain_handle;
4492 status = dcerpc_samr_OpenDomain(p, tctx, &r);
4493 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
4495 /* run the domain tests with the main handle closed - this tests
4496 the servers reference counting */
4497 ret &= test_samr_handle_Close(p, tctx, handle);
4499 switch (which_ops) {
4500 case TORTURE_SAMR_USER_ATTRIBUTES:
4501 case TORTURE_SAMR_PASSWORDS:
4502 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
4503 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4504 /* This test needs 'complex' users to validate */
4505 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
4507 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
4510 case TORTURE_SAMR_OTHER:
4511 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4513 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
4515 ret &= test_QuerySecurity(p, tctx, &domain_handle);
4516 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
4517 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
4518 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
4519 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
4520 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
4521 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
4522 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
4523 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
4524 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
4525 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
4526 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
4527 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
4529 if (torture_setting_bool(tctx, "samba4", false)) {
4530 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
4532 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
4533 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
4535 ret &= test_GroupList(p, tctx, &domain_handle);
4536 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
4537 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
4538 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
4540 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
4545 if (!policy_handle_empty(&user_handle) &&
4546 !test_DeleteUser(p, tctx, &user_handle)) {
4550 if (!policy_handle_empty(&alias_handle) &&
4551 !test_DeleteAlias(p, tctx, &alias_handle)) {
4555 if (!policy_handle_empty(&group_handle) &&
4556 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
4560 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
4562 /* reconnect the main handle */
4563 ret &= test_Connect(p, tctx, handle);
4566 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
4572 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4573 struct policy_handle *handle, const char *domain,
4574 enum torture_samr_choice which_ops)
4577 struct samr_LookupDomain r;
4578 struct dom_sid2 *sid = NULL;
4579 struct lsa_String n1;
4580 struct lsa_String n2;
4583 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
4585 /* check for correct error codes */
4586 r.in.connect_handle = handle;
4587 r.in.domain_name = &n2;
4591 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4592 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
4594 init_lsa_String(&n2, "xxNODOMAINxx");
4596 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4597 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
4599 r.in.connect_handle = handle;
4601 init_lsa_String(&n1, domain);
4602 r.in.domain_name = &n1;
4604 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4605 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
4607 if (!test_GetDomPwInfo(p, tctx, &n1)) {
4611 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops)) {
4619 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
4620 struct policy_handle *handle, enum torture_samr_choice which_ops)
4623 struct samr_EnumDomains r;
4624 uint32_t resume_handle = 0;
4625 uint32_t num_entries = 0;
4626 struct samr_SamArray *sam = NULL;
4630 r.in.connect_handle = handle;
4631 r.in.resume_handle = &resume_handle;
4632 r.in.buf_size = (uint32_t)-1;
4633 r.out.resume_handle = &resume_handle;
4634 r.out.num_entries = &num_entries;
4637 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4638 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4644 for (i=0;i<sam->count;i++) {
4645 if (!test_LookupDomain(p, tctx, handle,
4646 sam->entries[i].name.string, which_ops)) {
4651 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4652 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4658 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4659 struct policy_handle *handle)
4662 struct samr_Connect r;
4663 struct samr_Connect2 r2;
4664 struct samr_Connect3 r3;
4665 struct samr_Connect4 r4;
4666 struct samr_Connect5 r5;
4667 union samr_ConnectInfo info;
4668 struct policy_handle h;
4669 uint32_t level_out = 0;
4670 bool ret = true, got_handle = false;
4672 torture_comment(tctx, "testing samr_Connect\n");
4674 r.in.system_name = 0;
4675 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4676 r.out.connect_handle = &h;
4678 status = dcerpc_samr_Connect(p, tctx, &r);
4679 if (!NT_STATUS_IS_OK(status)) {
4680 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
4687 torture_comment(tctx, "testing samr_Connect2\n");
4689 r2.in.system_name = NULL;
4690 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4691 r2.out.connect_handle = &h;
4693 status = dcerpc_samr_Connect2(p, tctx, &r2);
4694 if (!NT_STATUS_IS_OK(status)) {
4695 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
4699 test_samr_handle_Close(p, tctx, handle);
4705 torture_comment(tctx, "testing samr_Connect3\n");
4707 r3.in.system_name = NULL;
4709 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4710 r3.out.connect_handle = &h;
4712 status = dcerpc_samr_Connect3(p, tctx, &r3);
4713 if (!NT_STATUS_IS_OK(status)) {
4714 printf("Connect3 failed - %s\n", nt_errstr(status));
4718 test_samr_handle_Close(p, tctx, handle);
4724 torture_comment(tctx, "testing samr_Connect4\n");
4726 r4.in.system_name = "";
4727 r4.in.client_version = 0;
4728 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4729 r4.out.connect_handle = &h;
4731 status = dcerpc_samr_Connect4(p, tctx, &r4);
4732 if (!NT_STATUS_IS_OK(status)) {
4733 printf("Connect4 failed - %s\n", nt_errstr(status));
4737 test_samr_handle_Close(p, tctx, handle);
4743 torture_comment(tctx, "testing samr_Connect5\n");
4745 info.info1.client_version = 0;
4746 info.info1.unknown2 = 0;
4748 r5.in.system_name = "";
4749 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4751 r5.out.level_out = &level_out;
4752 r5.in.info_in = &info;
4753 r5.out.info_out = &info;
4754 r5.out.connect_handle = &h;
4756 status = dcerpc_samr_Connect5(p, tctx, &r5);
4757 if (!NT_STATUS_IS_OK(status)) {
4758 printf("Connect5 failed - %s\n", nt_errstr(status));
4762 test_samr_handle_Close(p, tctx, handle);
4772 bool torture_rpc_samr(struct torture_context *torture)
4775 struct dcerpc_pipe *p;
4777 struct policy_handle handle;
4779 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4780 if (!NT_STATUS_IS_OK(status)) {
4784 ret &= test_Connect(p, torture, &handle);
4786 ret &= test_QuerySecurity(p, torture, &handle);
4788 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4790 ret &= test_SetDsrmPassword(p, torture, &handle);
4792 ret &= test_Shutdown(p, torture, &handle);
4794 ret &= test_samr_handle_Close(p, torture, &handle);
4800 bool torture_rpc_samr_users(struct torture_context *torture)
4803 struct dcerpc_pipe *p;
4805 struct policy_handle handle;
4807 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4808 if (!NT_STATUS_IS_OK(status)) {
4812 ret &= test_Connect(p, torture, &handle);
4814 ret &= test_QuerySecurity(p, torture, &handle);
4816 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4818 ret &= test_SetDsrmPassword(p, torture, &handle);
4820 ret &= test_Shutdown(p, torture, &handle);
4822 ret &= test_samr_handle_Close(p, torture, &handle);
4828 bool torture_rpc_samr_passwords(struct torture_context *torture)
4831 struct dcerpc_pipe *p;
4833 struct policy_handle handle;
4835 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4836 if (!NT_STATUS_IS_OK(status)) {
4840 ret &= test_Connect(p, torture, &handle);
4842 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4844 ret &= test_samr_handle_Close(p, torture, &handle);