2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "torture/torture.h"
24 #include "system/time.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_samr_c.h"
27 #include "../lib/crypto/crypto.h"
28 #include "libcli/auth/libcli_auth.h"
29 #include "libcli/security/security.h"
30 #include "torture/rpc/rpc.h"
32 #define TEST_ACCOUNT_NAME "samrtorturetest"
33 #define TEST_ALIASNAME "samrtorturetestalias"
34 #define TEST_GROUPNAME "samrtorturetestgroup"
35 #define TEST_MACHINENAME "samrtestmach$"
36 #define TEST_DOMAINNAME "samrtestdom$"
38 enum torture_samr_choice {
39 TORTURE_SAMR_PASSWORDS,
40 TORTURE_SAMR_USER_ATTRIBUTES,
44 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
45 struct policy_handle *handle);
47 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
48 struct policy_handle *handle);
50 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
51 struct policy_handle *handle);
53 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
54 const char *acct_name,
55 struct policy_handle *domain_handle, char **password);
57 static void init_lsa_String(struct lsa_String *string, const char *s)
62 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
64 string->length = length;
65 string->size = length;
66 string->array = (uint16_t *)discard_const(s);
69 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
70 struct policy_handle *handle)
76 r.out.handle = handle;
78 status = dcerpc_samr_Close(p, tctx, &r);
79 torture_assert_ntstatus_ok(tctx, status, "Close");
84 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
85 struct policy_handle *handle)
88 struct samr_Shutdown r;
90 if (!torture_setting_bool(tctx, "dangerous", false)) {
91 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
95 r.in.connect_handle = handle;
97 torture_comment(tctx, "testing samr_Shutdown\n");
99 status = dcerpc_samr_Shutdown(p, tctx, &r);
100 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
105 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
106 struct policy_handle *handle)
109 struct samr_SetDsrmPassword r;
110 struct lsa_String string;
111 struct samr_Password hash;
113 if (!torture_setting_bool(tctx, "dangerous", false)) {
114 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
117 E_md4hash("TeSTDSRM123", hash.hash);
119 init_lsa_String(&string, "Administrator");
125 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
127 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
128 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
134 static bool test_QuerySecurity(struct dcerpc_pipe *p,
135 struct torture_context *tctx,
136 struct policy_handle *handle)
139 struct samr_QuerySecurity r;
140 struct samr_SetSecurity s;
141 struct sec_desc_buf *sdbuf = NULL;
143 r.in.handle = handle;
145 r.out.sdbuf = &sdbuf;
147 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
148 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
150 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
152 s.in.handle = handle;
156 if (torture_setting_bool(tctx, "samba4", false)) {
157 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
160 status = dcerpc_samr_SetSecurity(p, tctx, &s);
161 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
163 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
164 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
170 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
171 struct policy_handle *handle, uint32_t base_acct_flags,
172 const char *base_account_name)
175 struct samr_SetUserInfo s;
176 struct samr_SetUserInfo2 s2;
177 struct samr_QueryUserInfo q;
178 struct samr_QueryUserInfo q0;
179 union samr_UserInfo u;
181 const char *test_account_name;
183 uint32_t user_extra_flags = 0;
184 if (base_acct_flags == ACB_NORMAL) {
185 /* When created, accounts are expired by default */
186 user_extra_flags = ACB_PW_EXPIRED;
189 s.in.user_handle = handle;
192 s2.in.user_handle = handle;
195 q.in.user_handle = handle;
199 #define TESTCALL(call, r) \
200 status = dcerpc_samr_ ##call(p, tctx, &r); \
201 if (!NT_STATUS_IS_OK(status)) { \
202 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
203 r.in.level, nt_errstr(status), __location__); \
208 #define STRING_EQUAL(s1, s2, field) \
209 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
210 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
211 #field, s2, __location__); \
216 #define MEM_EQUAL(s1, s2, length, field) \
217 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
218 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
219 #field, (const char *)s2, __location__); \
224 #define INT_EQUAL(i1, i2, field) \
226 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
227 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
232 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
233 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
235 TESTCALL(QueryUserInfo, q) \
237 s2.in.level = lvl1; \
240 ZERO_STRUCT(u.info21); \
241 u.info21.fields_present = fpval; \
243 init_lsa_String(&u.info ## lvl1.field1, value); \
244 TESTCALL(SetUserInfo, s) \
245 TESTCALL(SetUserInfo2, s2) \
246 init_lsa_String(&u.info ## lvl1.field1, ""); \
247 TESTCALL(QueryUserInfo, q); \
249 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
251 TESTCALL(QueryUserInfo, q) \
253 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
256 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
257 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
259 TESTCALL(QueryUserInfo, q) \
261 s2.in.level = lvl1; \
264 ZERO_STRUCT(u.info21); \
265 u.info21.fields_present = fpval; \
267 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
268 TESTCALL(SetUserInfo, s) \
269 TESTCALL(SetUserInfo2, s2) \
270 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
271 TESTCALL(QueryUserInfo, q); \
273 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
275 TESTCALL(QueryUserInfo, q) \
277 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
280 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
281 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
283 TESTCALL(QueryUserInfo, q) \
285 s2.in.level = lvl1; \
288 uint8_t *bits = u.info21.logon_hours.bits; \
289 ZERO_STRUCT(u.info21); \
290 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
291 u.info21.logon_hours.units_per_week = 168; \
292 u.info21.logon_hours.bits = bits; \
294 u.info21.fields_present = fpval; \
296 u.info ## lvl1.field1 = value; \
297 TESTCALL(SetUserInfo, s) \
298 TESTCALL(SetUserInfo2, s2) \
299 u.info ## lvl1.field1 = 0; \
300 TESTCALL(QueryUserInfo, q); \
302 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
304 TESTCALL(QueryUserInfo, q) \
306 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
309 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
310 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
314 do { TESTCALL(QueryUserInfo, q0) } while (0);
316 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
317 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
318 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
321 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
322 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
323 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
324 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
325 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
326 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
327 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
328 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
329 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
330 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
331 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
332 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
333 test_account_name = base_account_name;
334 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
335 SAMR_FIELD_ACCOUNT_NAME);
337 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
338 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
339 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
340 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
341 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
342 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
343 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
344 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
345 SAMR_FIELD_FULL_NAME);
347 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
348 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
349 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
350 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
351 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
352 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
353 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
354 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
355 SAMR_FIELD_FULL_NAME);
357 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
358 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
359 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
360 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
361 SAMR_FIELD_LOGON_SCRIPT);
363 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
364 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
365 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
366 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
367 SAMR_FIELD_PROFILE_PATH);
369 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
370 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
371 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
372 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
373 SAMR_FIELD_HOME_DIRECTORY);
374 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
375 SAMR_FIELD_HOME_DIRECTORY);
377 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
378 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
379 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
380 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
381 SAMR_FIELD_HOME_DRIVE);
382 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
383 SAMR_FIELD_HOME_DRIVE);
385 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
386 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
387 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
388 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
389 SAMR_FIELD_DESCRIPTION);
391 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
392 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
393 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
394 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
395 SAMR_FIELD_WORKSTATIONS);
396 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
397 SAMR_FIELD_WORKSTATIONS);
398 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
399 SAMR_FIELD_WORKSTATIONS);
400 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
401 SAMR_FIELD_WORKSTATIONS);
403 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
404 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
405 SAMR_FIELD_PARAMETERS);
406 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
407 SAMR_FIELD_PARAMETERS);
409 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
410 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
411 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
412 SAMR_FIELD_COUNTRY_CODE);
413 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
414 SAMR_FIELD_COUNTRY_CODE);
416 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
417 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
418 SAMR_FIELD_CODE_PAGE);
419 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
420 SAMR_FIELD_CODE_PAGE);
422 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
423 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
424 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
425 SAMR_FIELD_ACCT_EXPIRY);
426 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
427 SAMR_FIELD_ACCT_EXPIRY);
428 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
429 SAMR_FIELD_ACCT_EXPIRY);
431 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
432 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
433 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
434 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
435 SAMR_FIELD_LOGON_HOURS);
437 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
438 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
439 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
441 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
442 (base_acct_flags | ACB_DISABLED),
443 (base_acct_flags | ACB_DISABLED | user_extra_flags),
446 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
447 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
448 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
449 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
451 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
452 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
453 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
457 /* The 'autolock' flag doesn't stick - check this */
458 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
459 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
460 (base_acct_flags | ACB_DISABLED | user_extra_flags),
463 /* Removing the 'disabled' flag doesn't stick - check this */
464 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
466 (base_acct_flags | ACB_DISABLED | user_extra_flags),
469 /* The 'store plaintext' flag does stick */
470 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
471 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
472 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
474 /* The 'use DES' flag does stick */
475 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
476 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
477 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
479 /* The 'don't require kerberos pre-authentication flag does stick */
480 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
481 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
482 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
484 /* The 'no kerberos PAC required' flag sticks */
485 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
486 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
487 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
490 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
491 (base_acct_flags | ACB_DISABLED),
492 (base_acct_flags | ACB_DISABLED | user_extra_flags),
493 SAMR_FIELD_ACCT_FLAGS);
496 /* these fail with win2003 - it appears you can't set the primary gid?
497 the set succeeds, but the gid isn't changed. Very weird! */
498 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
499 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
500 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
501 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
508 generate a random password for password change tests
510 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
512 size_t len = MAX(8, min_len) + (random() % 6);
513 char *s = generate_random_str(mem_ctx, len);
514 printf("Generated password '%s'\n", s);
519 generate a random password for password change tests
521 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
524 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
525 generate_random_buffer(password.data, password.length);
527 for (i=0; i < len; i++) {
528 if (((uint16_t *)password.data)[i] == 0) {
529 ((uint16_t *)password.data)[i] = 1;
537 generate a random password for password change tests (fixed length)
539 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
541 char *s = generate_random_str(mem_ctx, len);
542 printf("Generated password '%s'\n", s);
546 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
547 struct policy_handle *handle, char **password)
550 struct samr_SetUserInfo s;
551 union samr_UserInfo u;
553 DATA_BLOB session_key;
555 struct samr_GetUserPwInfo pwp;
556 struct samr_PwInfo info;
557 int policy_min_pw_len = 0;
558 pwp.in.user_handle = handle;
559 pwp.out.info = &info;
561 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
562 if (NT_STATUS_IS_OK(status)) {
563 policy_min_pw_len = pwp.out.info->min_password_length;
565 newpass = samr_rand_pass(tctx, policy_min_pw_len);
567 s.in.user_handle = handle;
571 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
572 /* w2k3 ignores this length */
573 u.info24.pw_len = strlen_m(newpass) * 2;
575 status = dcerpc_fetch_session_key(p, &session_key);
576 if (!NT_STATUS_IS_OK(status)) {
577 printf("SetUserInfo level %u - no session key - %s\n",
578 s.in.level, nt_errstr(status));
582 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
584 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
586 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
587 if (!NT_STATUS_IS_OK(status)) {
588 printf("SetUserInfo level %u failed - %s\n",
589 s.in.level, nt_errstr(status));
599 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
600 struct policy_handle *handle, uint32_t fields_present,
604 struct samr_SetUserInfo s;
605 union samr_UserInfo u;
607 DATA_BLOB session_key;
609 struct samr_GetUserPwInfo pwp;
610 struct samr_PwInfo info;
611 int policy_min_pw_len = 0;
612 pwp.in.user_handle = handle;
613 pwp.out.info = &info;
615 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
616 if (NT_STATUS_IS_OK(status)) {
617 policy_min_pw_len = pwp.out.info->min_password_length;
619 newpass = samr_rand_pass(tctx, policy_min_pw_len);
621 s.in.user_handle = handle;
627 u.info23.info.fields_present = fields_present;
629 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
631 status = dcerpc_fetch_session_key(p, &session_key);
632 if (!NT_STATUS_IS_OK(status)) {
633 printf("SetUserInfo level %u - no session key - %s\n",
634 s.in.level, nt_errstr(status));
638 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
640 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
642 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
643 if (!NT_STATUS_IS_OK(status)) {
644 printf("SetUserInfo level %u failed - %s\n",
645 s.in.level, nt_errstr(status));
651 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
653 status = dcerpc_fetch_session_key(p, &session_key);
654 if (!NT_STATUS_IS_OK(status)) {
655 printf("SetUserInfo level %u - no session key - %s\n",
656 s.in.level, nt_errstr(status));
660 /* This should break the key nicely */
661 session_key.length--;
662 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
664 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
666 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
667 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
668 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
669 s.in.level, nt_errstr(status));
677 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
678 struct policy_handle *handle, bool makeshort,
682 struct samr_SetUserInfo s;
683 union samr_UserInfo u;
685 DATA_BLOB session_key;
686 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
687 uint8_t confounder[16];
689 struct MD5Context ctx;
690 struct samr_GetUserPwInfo pwp;
691 struct samr_PwInfo info;
692 int policy_min_pw_len = 0;
693 pwp.in.user_handle = handle;
694 pwp.out.info = &info;
696 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
697 if (NT_STATUS_IS_OK(status)) {
698 policy_min_pw_len = pwp.out.info->min_password_length;
700 if (makeshort && policy_min_pw_len) {
701 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
703 newpass = samr_rand_pass(tctx, policy_min_pw_len);
706 s.in.user_handle = handle;
710 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
711 u.info26.pw_len = strlen(newpass);
713 status = dcerpc_fetch_session_key(p, &session_key);
714 if (!NT_STATUS_IS_OK(status)) {
715 printf("SetUserInfo level %u - no session key - %s\n",
716 s.in.level, nt_errstr(status));
720 generate_random_buffer((uint8_t *)confounder, 16);
723 MD5Update(&ctx, confounder, 16);
724 MD5Update(&ctx, session_key.data, session_key.length);
725 MD5Final(confounded_session_key.data, &ctx);
727 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
728 memcpy(&u.info26.password.data[516], confounder, 16);
730 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
732 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
733 if (!NT_STATUS_IS_OK(status)) {
734 printf("SetUserInfo level %u failed - %s\n",
735 s.in.level, nt_errstr(status));
741 /* This should break the key nicely */
742 confounded_session_key.data[0]++;
744 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
745 memcpy(&u.info26.password.data[516], confounder, 16);
747 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
749 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
750 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
751 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
752 s.in.level, nt_errstr(status));
761 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
762 struct policy_handle *handle, uint32_t fields_present,
766 struct samr_SetUserInfo s;
767 union samr_UserInfo u;
769 DATA_BLOB session_key;
770 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
771 struct MD5Context ctx;
772 uint8_t confounder[16];
774 struct samr_GetUserPwInfo pwp;
775 struct samr_PwInfo info;
776 int policy_min_pw_len = 0;
777 pwp.in.user_handle = handle;
778 pwp.out.info = &info;
780 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
781 if (NT_STATUS_IS_OK(status)) {
782 policy_min_pw_len = pwp.out.info->min_password_length;
784 newpass = samr_rand_pass(tctx, policy_min_pw_len);
786 s.in.user_handle = handle;
792 u.info25.info.fields_present = fields_present;
794 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
796 status = dcerpc_fetch_session_key(p, &session_key);
797 if (!NT_STATUS_IS_OK(status)) {
798 printf("SetUserInfo level %u - no session key - %s\n",
799 s.in.level, nt_errstr(status));
803 generate_random_buffer((uint8_t *)confounder, 16);
806 MD5Update(&ctx, confounder, 16);
807 MD5Update(&ctx, session_key.data, session_key.length);
808 MD5Final(confounded_session_key.data, &ctx);
810 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
811 memcpy(&u.info25.password.data[516], confounder, 16);
813 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
815 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
816 if (!NT_STATUS_IS_OK(status)) {
817 printf("SetUserInfo level %u failed - %s\n",
818 s.in.level, nt_errstr(status));
824 /* This should break the key nicely */
825 confounded_session_key.data[0]++;
827 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
828 memcpy(&u.info25.password.data[516], confounder, 16);
830 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
832 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
833 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
834 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
835 s.in.level, nt_errstr(status));
842 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
843 struct policy_handle *handle)
846 struct samr_SetAliasInfo r;
847 struct samr_QueryAliasInfo q;
848 uint16_t levels[] = {2, 3};
852 /* Ignoring switch level 1, as that includes the number of members for the alias
853 * and setting this to a wrong value might have negative consequences
856 for (i=0;i<ARRAY_SIZE(levels);i++) {
857 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
859 r.in.alias_handle = handle;
860 r.in.level = levels[i];
861 r.in.info = talloc(tctx, union samr_AliasInfo);
862 switch (r.in.level) {
863 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
864 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
865 "Test Description, should test I18N as well"); break;
866 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
869 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
870 if (!NT_STATUS_IS_OK(status)) {
871 printf("SetAliasInfo level %u failed - %s\n",
872 levels[i], nt_errstr(status));
876 q.in.alias_handle = handle;
877 q.in.level = levels[i];
879 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
880 if (!NT_STATUS_IS_OK(status)) {
881 printf("QueryAliasInfo level %u failed - %s\n",
882 levels[i], nt_errstr(status));
890 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
891 struct policy_handle *user_handle)
893 struct samr_GetGroupsForUser r;
896 torture_comment(tctx, "testing GetGroupsForUser\n");
898 r.in.user_handle = user_handle;
900 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
901 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
907 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
908 struct lsa_String *domain_name)
911 struct samr_GetDomPwInfo r;
912 struct samr_PwInfo info;
914 r.in.domain_name = domain_name;
917 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
919 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
920 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
922 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
923 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
925 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
926 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
928 r.in.domain_name->string = "\\\\__NONAME__";
929 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
931 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
932 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
934 r.in.domain_name->string = "\\\\Builtin";
935 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
937 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
938 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
943 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
944 struct policy_handle *handle)
947 struct samr_GetUserPwInfo r;
948 struct samr_PwInfo info;
950 torture_comment(tctx, "Testing GetUserPwInfo\n");
952 r.in.user_handle = handle;
955 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
956 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
961 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
962 struct policy_handle *domain_handle, const char *name,
966 struct samr_LookupNames n;
967 struct lsa_String sname[2];
969 init_lsa_String(&sname[0], name);
971 n.in.domain_handle = domain_handle;
974 status = dcerpc_samr_LookupNames(p, tctx, &n);
975 if (NT_STATUS_IS_OK(status)) {
976 *rid = n.out.rids.ids[0];
981 init_lsa_String(&sname[1], "xxNONAMExx");
983 status = dcerpc_samr_LookupNames(p, tctx, &n);
984 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
985 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
986 if (NT_STATUS_IS_OK(status)) {
987 return NT_STATUS_UNSUCCESSFUL;
993 status = dcerpc_samr_LookupNames(p, tctx, &n);
994 if (!NT_STATUS_IS_OK(status)) {
995 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
999 init_lsa_String(&sname[0], "xxNONAMExx");
1001 status = dcerpc_samr_LookupNames(p, tctx, &n);
1002 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1003 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1004 if (NT_STATUS_IS_OK(status)) {
1005 return NT_STATUS_UNSUCCESSFUL;
1010 init_lsa_String(&sname[0], "xxNONAMExx");
1011 init_lsa_String(&sname[1], "xxNONAME2xx");
1013 status = dcerpc_samr_LookupNames(p, tctx, &n);
1014 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1015 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1016 if (NT_STATUS_IS_OK(status)) {
1017 return NT_STATUS_UNSUCCESSFUL;
1022 return NT_STATUS_OK;
1025 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1026 struct policy_handle *domain_handle,
1027 const char *name, struct policy_handle *user_handle)
1030 struct samr_OpenUser r;
1033 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1034 if (!NT_STATUS_IS_OK(status)) {
1038 r.in.domain_handle = domain_handle;
1039 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1041 r.out.user_handle = user_handle;
1042 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1043 if (!NT_STATUS_IS_OK(status)) {
1044 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1051 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1052 struct policy_handle *handle)
1055 struct samr_ChangePasswordUser r;
1057 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1058 struct policy_handle user_handle;
1059 char *oldpass = "test";
1060 char *newpass = "test2";
1061 uint8_t old_nt_hash[16], new_nt_hash[16];
1062 uint8_t old_lm_hash[16], new_lm_hash[16];
1064 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1065 if (!NT_STATUS_IS_OK(status)) {
1069 printf("Testing ChangePasswordUser for user 'testuser'\n");
1071 printf("old password: %s\n", oldpass);
1072 printf("new password: %s\n", newpass);
1074 E_md4hash(oldpass, old_nt_hash);
1075 E_md4hash(newpass, new_nt_hash);
1076 E_deshash(oldpass, old_lm_hash);
1077 E_deshash(newpass, new_lm_hash);
1079 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1080 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1081 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1082 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1083 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1084 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1086 r.in.handle = &user_handle;
1087 r.in.lm_present = 1;
1088 r.in.old_lm_crypted = &hash1;
1089 r.in.new_lm_crypted = &hash2;
1090 r.in.nt_present = 1;
1091 r.in.old_nt_crypted = &hash3;
1092 r.in.new_nt_crypted = &hash4;
1093 r.in.cross1_present = 1;
1094 r.in.nt_cross = &hash5;
1095 r.in.cross2_present = 1;
1096 r.in.lm_cross = &hash6;
1098 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1099 if (!NT_STATUS_IS_OK(status)) {
1100 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1104 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1112 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1113 const char *acct_name,
1114 struct policy_handle *handle, char **password)
1117 struct samr_ChangePasswordUser r;
1119 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1120 struct policy_handle user_handle;
1122 uint8_t old_nt_hash[16], new_nt_hash[16];
1123 uint8_t old_lm_hash[16], new_lm_hash[16];
1124 bool changed = true;
1127 struct samr_GetUserPwInfo pwp;
1128 struct samr_PwInfo info;
1129 int policy_min_pw_len = 0;
1131 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1132 if (!NT_STATUS_IS_OK(status)) {
1135 pwp.in.user_handle = &user_handle;
1136 pwp.out.info = &info;
1138 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1139 if (NT_STATUS_IS_OK(status)) {
1140 policy_min_pw_len = pwp.out.info->min_password_length;
1142 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1144 torture_comment(tctx, "Testing ChangePasswordUser\n");
1146 torture_assert(tctx, *password != NULL,
1147 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1149 oldpass = *password;
1151 E_md4hash(oldpass, old_nt_hash);
1152 E_md4hash(newpass, new_nt_hash);
1153 E_deshash(oldpass, old_lm_hash);
1154 E_deshash(newpass, new_lm_hash);
1156 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1157 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1158 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1159 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1160 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1161 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1163 r.in.user_handle = &user_handle;
1164 r.in.lm_present = 1;
1165 /* Break the LM hash */
1167 r.in.old_lm_crypted = &hash1;
1168 r.in.new_lm_crypted = &hash2;
1169 r.in.nt_present = 1;
1170 r.in.old_nt_crypted = &hash3;
1171 r.in.new_nt_crypted = &hash4;
1172 r.in.cross1_present = 1;
1173 r.in.nt_cross = &hash5;
1174 r.in.cross2_present = 1;
1175 r.in.lm_cross = &hash6;
1177 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1178 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1179 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1181 /* Unbreak the LM hash */
1184 r.in.user_handle = &user_handle;
1185 r.in.lm_present = 1;
1186 r.in.old_lm_crypted = &hash1;
1187 r.in.new_lm_crypted = &hash2;
1188 /* Break the NT hash */
1190 r.in.nt_present = 1;
1191 r.in.old_nt_crypted = &hash3;
1192 r.in.new_nt_crypted = &hash4;
1193 r.in.cross1_present = 1;
1194 r.in.nt_cross = &hash5;
1195 r.in.cross2_present = 1;
1196 r.in.lm_cross = &hash6;
1198 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1199 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1200 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1202 /* Unbreak the NT hash */
1205 r.in.user_handle = &user_handle;
1206 r.in.lm_present = 1;
1207 r.in.old_lm_crypted = &hash1;
1208 r.in.new_lm_crypted = &hash2;
1209 r.in.nt_present = 1;
1210 r.in.old_nt_crypted = &hash3;
1211 r.in.new_nt_crypted = &hash4;
1212 r.in.cross1_present = 1;
1213 r.in.nt_cross = &hash5;
1214 r.in.cross2_present = 1;
1215 /* Break the LM cross */
1217 r.in.lm_cross = &hash6;
1219 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1220 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1221 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1225 /* Unbreak the LM cross */
1228 r.in.user_handle = &user_handle;
1229 r.in.lm_present = 1;
1230 r.in.old_lm_crypted = &hash1;
1231 r.in.new_lm_crypted = &hash2;
1232 r.in.nt_present = 1;
1233 r.in.old_nt_crypted = &hash3;
1234 r.in.new_nt_crypted = &hash4;
1235 r.in.cross1_present = 1;
1236 /* Break the NT cross */
1238 r.in.nt_cross = &hash5;
1239 r.in.cross2_present = 1;
1240 r.in.lm_cross = &hash6;
1242 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1243 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1244 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1248 /* Unbreak the NT cross */
1252 /* Reset the hashes to not broken values */
1253 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1254 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1255 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1256 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1257 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1258 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1260 r.in.user_handle = &user_handle;
1261 r.in.lm_present = 1;
1262 r.in.old_lm_crypted = &hash1;
1263 r.in.new_lm_crypted = &hash2;
1264 r.in.nt_present = 1;
1265 r.in.old_nt_crypted = &hash3;
1266 r.in.new_nt_crypted = &hash4;
1267 r.in.cross1_present = 1;
1268 r.in.nt_cross = &hash5;
1269 r.in.cross2_present = 0;
1270 r.in.lm_cross = NULL;
1272 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1273 if (NT_STATUS_IS_OK(status)) {
1275 *password = newpass;
1276 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1277 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1282 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1284 E_md4hash(oldpass, old_nt_hash);
1285 E_md4hash(newpass, new_nt_hash);
1286 E_deshash(oldpass, old_lm_hash);
1287 E_deshash(newpass, new_lm_hash);
1290 /* Reset the hashes to not broken values */
1291 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1292 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1293 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1294 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1295 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1296 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1298 r.in.user_handle = &user_handle;
1299 r.in.lm_present = 1;
1300 r.in.old_lm_crypted = &hash1;
1301 r.in.new_lm_crypted = &hash2;
1302 r.in.nt_present = 1;
1303 r.in.old_nt_crypted = &hash3;
1304 r.in.new_nt_crypted = &hash4;
1305 r.in.cross1_present = 0;
1306 r.in.nt_cross = NULL;
1307 r.in.cross2_present = 1;
1308 r.in.lm_cross = &hash6;
1310 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1311 if (NT_STATUS_IS_OK(status)) {
1313 *password = newpass;
1314 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1315 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1320 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1322 E_md4hash(oldpass, old_nt_hash);
1323 E_md4hash(newpass, new_nt_hash);
1324 E_deshash(oldpass, old_lm_hash);
1325 E_deshash(newpass, new_lm_hash);
1328 /* Reset the hashes to not broken values */
1329 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1330 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1331 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1332 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1333 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1334 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1336 r.in.user_handle = &user_handle;
1337 r.in.lm_present = 1;
1338 r.in.old_lm_crypted = &hash1;
1339 r.in.new_lm_crypted = &hash2;
1340 r.in.nt_present = 1;
1341 r.in.old_nt_crypted = &hash3;
1342 r.in.new_nt_crypted = &hash4;
1343 r.in.cross1_present = 1;
1344 r.in.nt_cross = &hash5;
1345 r.in.cross2_present = 1;
1346 r.in.lm_cross = &hash6;
1348 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1349 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1350 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1351 } else if (!NT_STATUS_IS_OK(status)) {
1352 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1356 *password = newpass;
1359 r.in.user_handle = &user_handle;
1360 r.in.lm_present = 1;
1361 r.in.old_lm_crypted = &hash1;
1362 r.in.new_lm_crypted = &hash2;
1363 r.in.nt_present = 1;
1364 r.in.old_nt_crypted = &hash3;
1365 r.in.new_nt_crypted = &hash4;
1366 r.in.cross1_present = 1;
1367 r.in.nt_cross = &hash5;
1368 r.in.cross2_present = 1;
1369 r.in.lm_cross = &hash6;
1372 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1373 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1374 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1375 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1376 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1382 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1390 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1391 const char *acct_name,
1392 struct policy_handle *handle, char **password)
1395 struct samr_OemChangePasswordUser2 r;
1397 struct samr_Password lm_verifier;
1398 struct samr_CryptPassword lm_pass;
1399 struct lsa_AsciiString server, account, account_bad;
1402 uint8_t old_lm_hash[16], new_lm_hash[16];
1404 struct samr_GetDomPwInfo dom_pw_info;
1405 struct samr_PwInfo info;
1406 int policy_min_pw_len = 0;
1408 struct lsa_String domain_name;
1410 domain_name.string = "";
1411 dom_pw_info.in.domain_name = &domain_name;
1412 dom_pw_info.out.info = &info;
1414 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1416 torture_assert(tctx, *password != NULL,
1417 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1419 oldpass = *password;
1421 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1422 if (NT_STATUS_IS_OK(status)) {
1423 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1426 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1428 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1429 account.string = acct_name;
1431 E_deshash(oldpass, old_lm_hash);
1432 E_deshash(newpass, new_lm_hash);
1434 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1435 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1436 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1438 r.in.server = &server;
1439 r.in.account = &account;
1440 r.in.password = &lm_pass;
1441 r.in.hash = &lm_verifier;
1443 /* Break the verification */
1444 lm_verifier.hash[0]++;
1446 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1448 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1449 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1450 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1455 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1456 /* Break the old password */
1458 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1459 /* unbreak it for the next operation */
1461 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1463 r.in.server = &server;
1464 r.in.account = &account;
1465 r.in.password = &lm_pass;
1466 r.in.hash = &lm_verifier;
1468 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1470 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1471 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1472 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1477 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1478 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1480 r.in.server = &server;
1481 r.in.account = &account;
1482 r.in.password = &lm_pass;
1485 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1487 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1488 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1489 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1494 /* This shouldn't be a valid name */
1495 account_bad.string = TEST_ACCOUNT_NAME "XX";
1496 r.in.account = &account_bad;
1498 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1500 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1501 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1506 /* This shouldn't be a valid name */
1507 account_bad.string = TEST_ACCOUNT_NAME "XX";
1508 r.in.account = &account_bad;
1509 r.in.password = &lm_pass;
1510 r.in.hash = &lm_verifier;
1512 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1514 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1515 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1520 /* This shouldn't be a valid name */
1521 account_bad.string = TEST_ACCOUNT_NAME "XX";
1522 r.in.account = &account_bad;
1523 r.in.password = NULL;
1524 r.in.hash = &lm_verifier;
1526 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1528 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1529 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1534 E_deshash(oldpass, old_lm_hash);
1535 E_deshash(newpass, new_lm_hash);
1537 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1538 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1539 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1541 r.in.server = &server;
1542 r.in.account = &account;
1543 r.in.password = &lm_pass;
1544 r.in.hash = &lm_verifier;
1546 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1547 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1548 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1549 } else if (!NT_STATUS_IS_OK(status)) {
1550 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1553 *password = newpass;
1560 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1561 const char *acct_name,
1563 char *newpass, bool allow_password_restriction)
1566 struct samr_ChangePasswordUser2 r;
1568 struct lsa_String server, account;
1569 struct samr_CryptPassword nt_pass, lm_pass;
1570 struct samr_Password nt_verifier, lm_verifier;
1572 uint8_t old_nt_hash[16], new_nt_hash[16];
1573 uint8_t old_lm_hash[16], new_lm_hash[16];
1575 struct samr_GetDomPwInfo dom_pw_info;
1576 struct samr_PwInfo info;
1578 struct lsa_String domain_name;
1580 domain_name.string = "";
1581 dom_pw_info.in.domain_name = &domain_name;
1582 dom_pw_info.out.info = &info;
1584 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
1586 torture_assert(tctx, *password != NULL,
1587 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
1588 oldpass = *password;
1591 int policy_min_pw_len = 0;
1592 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1593 if (NT_STATUS_IS_OK(status)) {
1594 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1597 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1600 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1601 init_lsa_String(&account, acct_name);
1603 E_md4hash(oldpass, old_nt_hash);
1604 E_md4hash(newpass, new_nt_hash);
1606 E_deshash(oldpass, old_lm_hash);
1607 E_deshash(newpass, new_lm_hash);
1609 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1610 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1611 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1613 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1614 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1615 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1617 r.in.server = &server;
1618 r.in.account = &account;
1619 r.in.nt_password = &nt_pass;
1620 r.in.nt_verifier = &nt_verifier;
1622 r.in.lm_password = &lm_pass;
1623 r.in.lm_verifier = &lm_verifier;
1625 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
1626 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1627 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1628 } else if (!NT_STATUS_IS_OK(status)) {
1629 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1632 *password = newpass;
1639 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
1640 const char *account_string,
1641 int policy_min_pw_len,
1643 const char *newpass,
1644 NTTIME last_password_change,
1645 bool handle_reject_reason)
1648 struct samr_ChangePasswordUser3 r;
1650 struct lsa_String server, account, account_bad;
1651 struct samr_CryptPassword nt_pass, lm_pass;
1652 struct samr_Password nt_verifier, lm_verifier;
1654 uint8_t old_nt_hash[16], new_nt_hash[16];
1655 uint8_t old_lm_hash[16], new_lm_hash[16];
1657 struct samr_DomInfo1 *dominfo = NULL;
1658 struct samr_ChangeReject *reject = NULL;
1660 torture_comment(tctx, "Testing ChangePasswordUser3\n");
1662 if (newpass == NULL) {
1664 if (policy_min_pw_len == 0) {
1665 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1667 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
1669 } while (check_password_quality(newpass) == false);
1671 torture_comment(tctx, "Using password '%s'\n", newpass);
1674 torture_assert(tctx, *password != NULL,
1675 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1677 oldpass = *password;
1678 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1679 init_lsa_String(&account, account_string);
1681 E_md4hash(oldpass, old_nt_hash);
1682 E_md4hash(newpass, new_nt_hash);
1684 E_deshash(oldpass, old_lm_hash);
1685 E_deshash(newpass, new_lm_hash);
1687 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1688 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1689 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1691 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1692 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1693 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1695 /* Break the verification */
1696 nt_verifier.hash[0]++;
1698 r.in.server = &server;
1699 r.in.account = &account;
1700 r.in.nt_password = &nt_pass;
1701 r.in.nt_verifier = &nt_verifier;
1703 r.in.lm_password = &lm_pass;
1704 r.in.lm_verifier = &lm_verifier;
1705 r.in.password3 = NULL;
1706 r.out.dominfo = &dominfo;
1707 r.out.reject = &reject;
1709 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1710 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1711 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1712 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1717 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1718 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1719 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1721 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1722 /* Break the NT hash */
1724 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1725 /* Unbreak it again */
1727 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1729 r.in.server = &server;
1730 r.in.account = &account;
1731 r.in.nt_password = &nt_pass;
1732 r.in.nt_verifier = &nt_verifier;
1734 r.in.lm_password = &lm_pass;
1735 r.in.lm_verifier = &lm_verifier;
1736 r.in.password3 = NULL;
1737 r.out.dominfo = &dominfo;
1738 r.out.reject = &reject;
1740 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1741 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1742 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1743 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1748 /* This shouldn't be a valid name */
1749 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
1751 r.in.account = &account_bad;
1752 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1753 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1754 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1759 E_md4hash(oldpass, old_nt_hash);
1760 E_md4hash(newpass, new_nt_hash);
1762 E_deshash(oldpass, old_lm_hash);
1763 E_deshash(newpass, new_lm_hash);
1765 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1766 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1767 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1769 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1770 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1771 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1773 r.in.server = &server;
1774 r.in.account = &account;
1775 r.in.nt_password = &nt_pass;
1776 r.in.nt_verifier = &nt_verifier;
1778 r.in.lm_password = &lm_pass;
1779 r.in.lm_verifier = &lm_verifier;
1780 r.in.password3 = NULL;
1781 r.out.dominfo = &dominfo;
1782 r.out.reject = &reject;
1784 unix_to_nt_time(&t, time(NULL));
1786 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1788 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1791 && handle_reject_reason
1792 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
1793 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1795 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
1796 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1797 SAMR_REJECT_OTHER, reject->reason);
1802 /* We tested the order of precendence which is as follows:
1811 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1812 (last_password_change + dominfo->min_password_age > t)) {
1814 if (reject->reason != SAMR_REJECT_OTHER) {
1815 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1816 SAMR_REJECT_OTHER, reject->reason);
1820 } else if ((dominfo->min_password_length > 0) &&
1821 (strlen(newpass) < dominfo->min_password_length)) {
1823 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
1824 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1825 SAMR_REJECT_TOO_SHORT, reject->reason);
1829 } else if ((dominfo->password_history_length > 0) &&
1830 strequal(oldpass, newpass)) {
1832 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
1833 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1834 SAMR_REJECT_IN_HISTORY, reject->reason);
1837 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1839 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
1840 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1841 SAMR_REJECT_COMPLEXITY, reject->reason);
1847 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
1848 /* retry with adjusted size */
1849 return test_ChangePasswordUser3(p, tctx, account_string,
1850 dominfo->min_password_length,
1851 password, NULL, 0, false);
1855 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1856 if (reject && reject->reason != SAMR_REJECT_OTHER) {
1857 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1858 SAMR_REJECT_OTHER, reject->reason);
1861 /* Perhaps the server has a 'min password age' set? */
1864 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
1865 *password = talloc_strdup(tctx, newpass);
1871 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
1872 const char *account_string,
1873 struct policy_handle *handle,
1877 struct samr_ChangePasswordUser3 r;
1878 struct samr_SetUserInfo s;
1879 union samr_UserInfo u;
1880 DATA_BLOB session_key;
1881 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1882 uint8_t confounder[16];
1883 struct MD5Context ctx;
1886 struct lsa_String server, account;
1887 struct samr_CryptPassword nt_pass;
1888 struct samr_Password nt_verifier;
1889 DATA_BLOB new_random_pass;
1892 uint8_t old_nt_hash[16], new_nt_hash[16];
1894 struct samr_DomInfo1 *dominfo = NULL;
1895 struct samr_ChangeReject *reject = NULL;
1897 new_random_pass = samr_very_rand_pass(tctx, 128);
1899 torture_assert(tctx, *password != NULL,
1900 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1902 oldpass = *password;
1903 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1904 init_lsa_String(&account, account_string);
1906 s.in.user_handle = handle;
1912 u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
1914 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
1916 status = dcerpc_fetch_session_key(p, &session_key);
1917 if (!NT_STATUS_IS_OK(status)) {
1918 printf("SetUserInfo level %u - no session key - %s\n",
1919 s.in.level, nt_errstr(status));
1923 generate_random_buffer((uint8_t *)confounder, 16);
1926 MD5Update(&ctx, confounder, 16);
1927 MD5Update(&ctx, session_key.data, session_key.length);
1928 MD5Final(confounded_session_key.data, &ctx);
1930 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1931 memcpy(&u.info25.password.data[516], confounder, 16);
1933 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
1935 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1936 if (!NT_STATUS_IS_OK(status)) {
1937 printf("SetUserInfo level %u failed - %s\n",
1938 s.in.level, nt_errstr(status));
1942 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
1944 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1946 new_random_pass = samr_very_rand_pass(tctx, 128);
1948 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
1950 set_pw_in_buffer(nt_pass.data, &new_random_pass);
1951 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1952 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1954 r.in.server = &server;
1955 r.in.account = &account;
1956 r.in.nt_password = &nt_pass;
1957 r.in.nt_verifier = &nt_verifier;
1959 r.in.lm_password = NULL;
1960 r.in.lm_verifier = NULL;
1961 r.in.password3 = NULL;
1962 r.out.dominfo = &dominfo;
1963 r.out.reject = &reject;
1965 unix_to_nt_time(&t, time(NULL));
1967 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1969 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1970 if (reject && reject->reason != SAMR_REJECT_OTHER) {
1971 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1972 SAMR_REJECT_OTHER, reject->reason);
1975 /* Perhaps the server has a 'min password age' set? */
1977 } else if (!NT_STATUS_IS_OK(status)) {
1978 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1982 newpass = samr_rand_pass(tctx, 128);
1984 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1986 E_md4hash(newpass, new_nt_hash);
1988 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1989 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1990 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1992 r.in.server = &server;
1993 r.in.account = &account;
1994 r.in.nt_password = &nt_pass;
1995 r.in.nt_verifier = &nt_verifier;
1997 r.in.lm_password = NULL;
1998 r.in.lm_verifier = NULL;
1999 r.in.password3 = NULL;
2000 r.out.dominfo = &dominfo;
2001 r.out.reject = &reject;
2003 unix_to_nt_time(&t, time(NULL));
2005 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2007 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2008 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2009 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2010 SAMR_REJECT_OTHER, reject->reason);
2013 /* Perhaps the server has a 'min password age' set? */
2016 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2017 *password = talloc_strdup(tctx, newpass);
2024 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2025 struct policy_handle *alias_handle)
2027 struct samr_GetMembersInAlias r;
2028 struct lsa_SidArray sids;
2031 torture_comment(tctx, "Testing GetMembersInAlias\n");
2033 r.in.alias_handle = alias_handle;
2036 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2037 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2042 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2043 struct policy_handle *alias_handle,
2044 const struct dom_sid *domain_sid)
2046 struct samr_AddAliasMember r;
2047 struct samr_DeleteAliasMember d;
2049 struct dom_sid *sid;
2051 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2053 torture_comment(tctx, "testing AddAliasMember\n");
2054 r.in.alias_handle = alias_handle;
2057 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2058 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2060 d.in.alias_handle = alias_handle;
2063 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2064 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2069 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2070 struct policy_handle *alias_handle)
2072 struct samr_AddMultipleMembersToAlias a;
2073 struct samr_RemoveMultipleMembersFromAlias r;
2075 struct lsa_SidArray sids;
2077 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2078 a.in.alias_handle = alias_handle;
2082 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2084 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2085 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2086 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2088 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2089 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2092 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2093 r.in.alias_handle = alias_handle;
2096 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2097 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2099 /* strange! removing twice doesn't give any error */
2100 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2101 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2103 /* but removing an alias that isn't there does */
2104 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2106 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2107 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2112 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2113 struct policy_handle *user_handle)
2115 struct samr_TestPrivateFunctionsUser r;
2118 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2120 r.in.user_handle = user_handle;
2122 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2123 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2129 static bool test_user_ops(struct dcerpc_pipe *p,
2130 struct torture_context *tctx,
2131 struct policy_handle *user_handle,
2132 struct policy_handle *domain_handle,
2133 uint32_t base_acct_flags,
2134 const char *base_acct_name, enum torture_samr_choice which_ops)
2136 char *password = NULL;
2137 struct samr_QueryUserInfo q;
2143 const uint32_t password_fields[] = {
2144 SAMR_FIELD_PASSWORD,
2145 SAMR_FIELD_PASSWORD2,
2146 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2150 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2151 if (!NT_STATUS_IS_OK(status)) {
2155 switch (which_ops) {
2156 case TORTURE_SAMR_USER_ATTRIBUTES:
2157 if (!test_QuerySecurity(p, tctx, user_handle)) {
2161 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2165 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2169 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2174 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2178 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2182 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2186 case TORTURE_SAMR_PASSWORDS:
2187 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2188 char simple_pass[9];
2189 char *v = generate_random_str(tctx, 1);
2191 ZERO_STRUCT(simple_pass);
2192 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2194 printf("Testing machine account password policy rules\n");
2196 /* Workstation trust accounts don't seem to need to honour password quality policy */
2197 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2201 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2205 /* reset again, to allow another 'user' password change */
2206 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2210 /* Try a 'short' password */
2211 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2215 /* Try a compleatly random password */
2216 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
2221 for (i = 0; password_fields[i]; i++) {
2222 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2226 /* check it was set right */
2227 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2232 for (i = 0; password_fields[i]; i++) {
2233 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2237 /* check it was set right */
2238 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2243 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2247 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2251 q.in.user_handle = user_handle;
2254 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2255 if (!NT_STATUS_IS_OK(status)) {
2256 printf("QueryUserInfo level %u failed - %s\n",
2257 q.in.level, nt_errstr(status));
2260 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2261 if ((q.out.info->info5.acct_flags) != expected_flags) {
2262 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2263 q.out.info->info5.acct_flags,
2267 if (q.out.info->info5.rid != rid) {
2268 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2269 q.out.info->info5.rid, rid);
2275 case TORTURE_SAMR_OTHER:
2276 /* We just need the account to exist */
2282 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2283 struct policy_handle *alias_handle,
2284 const struct dom_sid *domain_sid)
2288 if (!test_QuerySecurity(p, tctx, alias_handle)) {
2292 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2296 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2300 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2304 if (torture_setting_bool(tctx, "samba4", false)) {
2305 printf("skipping MultipleMembers Alias tests against Samba4\n");
2309 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2317 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2318 struct policy_handle *user_handle)
2320 struct samr_DeleteUser d;
2322 torture_comment(tctx, "Testing DeleteUser\n");
2324 d.in.user_handle = user_handle;
2325 d.out.user_handle = user_handle;
2327 status = dcerpc_samr_DeleteUser(p, tctx, &d);
2328 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
2333 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2334 struct policy_handle *handle, const char *name)
2337 struct samr_DeleteUser d;
2338 struct policy_handle user_handle;
2341 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2342 if (!NT_STATUS_IS_OK(status)) {
2346 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2347 if (!NT_STATUS_IS_OK(status)) {
2351 d.in.user_handle = &user_handle;
2352 d.out.user_handle = &user_handle;
2353 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2354 if (!NT_STATUS_IS_OK(status)) {
2361 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2366 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2367 struct policy_handle *handle, const char *name)
2370 struct samr_OpenGroup r;
2371 struct samr_DeleteDomainGroup d;
2372 struct policy_handle group_handle;
2375 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2376 if (!NT_STATUS_IS_OK(status)) {
2380 r.in.domain_handle = handle;
2381 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2383 r.out.group_handle = &group_handle;
2384 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2385 if (!NT_STATUS_IS_OK(status)) {
2389 d.in.group_handle = &group_handle;
2390 d.out.group_handle = &group_handle;
2391 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2392 if (!NT_STATUS_IS_OK(status)) {
2399 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2404 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2405 struct policy_handle *domain_handle, const char *name)
2408 struct samr_OpenAlias r;
2409 struct samr_DeleteDomAlias d;
2410 struct policy_handle alias_handle;
2413 printf("testing DeleteAlias_byname\n");
2415 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2416 if (!NT_STATUS_IS_OK(status)) {
2420 r.in.domain_handle = domain_handle;
2421 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2423 r.out.alias_handle = &alias_handle;
2424 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2425 if (!NT_STATUS_IS_OK(status)) {
2429 d.in.alias_handle = &alias_handle;
2430 d.out.alias_handle = &alias_handle;
2431 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2432 if (!NT_STATUS_IS_OK(status)) {
2439 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2443 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2444 struct policy_handle *alias_handle)
2446 struct samr_DeleteDomAlias d;
2449 printf("Testing DeleteAlias\n");
2451 d.in.alias_handle = alias_handle;
2452 d.out.alias_handle = alias_handle;
2454 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2455 if (!NT_STATUS_IS_OK(status)) {
2456 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2463 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2464 struct policy_handle *domain_handle,
2465 struct policy_handle *alias_handle,
2466 const struct dom_sid *domain_sid)
2469 struct samr_CreateDomAlias r;
2470 struct lsa_String name;
2474 init_lsa_String(&name, TEST_ALIASNAME);
2475 r.in.domain_handle = domain_handle;
2476 r.in.alias_name = &name;
2477 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2478 r.out.alias_handle = alias_handle;
2481 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2483 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2485 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2486 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2487 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
2490 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
2496 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2497 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
2500 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2503 if (!NT_STATUS_IS_OK(status)) {
2504 printf("CreateAlias failed - %s\n", nt_errstr(status));
2508 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
2515 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2516 const char *acct_name,
2517 struct policy_handle *domain_handle, char **password)
2525 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2529 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
2533 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2537 /* test what happens when setting the old password again */
2538 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
2543 char simple_pass[9];
2544 char *v = generate_random_str(mem_ctx, 1);
2546 ZERO_STRUCT(simple_pass);
2547 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2549 /* test what happens when picking a simple password */
2550 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
2555 /* set samr_SetDomainInfo level 1 with min_length 5 */
2557 struct samr_QueryDomainInfo r;
2558 struct samr_SetDomainInfo s;
2559 uint16_t len_old, len;
2560 uint32_t pwd_prop_old;
2561 int64_t min_pwd_age_old;
2566 r.in.domain_handle = domain_handle;
2569 printf("testing samr_QueryDomainInfo level 1\n");
2570 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2571 if (!NT_STATUS_IS_OK(status)) {
2575 s.in.domain_handle = domain_handle;
2577 s.in.info = r.out.info;
2579 /* remember the old min length, so we can reset it */
2580 len_old = s.in.info->info1.min_password_length;
2581 s.in.info->info1.min_password_length = len;
2582 pwd_prop_old = s.in.info->info1.password_properties;
2583 /* turn off password complexity checks for this test */
2584 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2586 min_pwd_age_old = s.in.info->info1.min_password_age;
2587 s.in.info->info1.min_password_age = 0;
2589 printf("testing samr_SetDomainInfo level 1\n");
2590 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2591 if (!NT_STATUS_IS_OK(status)) {
2595 printf("calling test_ChangePasswordUser3 with too short password\n");
2597 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
2601 s.in.info->info1.min_password_length = len_old;
2602 s.in.info->info1.password_properties = pwd_prop_old;
2603 s.in.info->info1.min_password_age = min_pwd_age_old;
2605 printf("testing samr_SetDomainInfo level 1\n");
2606 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2607 if (!NT_STATUS_IS_OK(status)) {
2615 struct samr_OpenUser r;
2616 struct samr_QueryUserInfo q;
2617 struct samr_LookupNames n;
2618 struct policy_handle user_handle;
2620 n.in.domain_handle = domain_handle;
2622 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2623 n.in.names[0].string = acct_name;
2625 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2626 if (!NT_STATUS_IS_OK(status)) {
2627 printf("LookupNames failed - %s\n", nt_errstr(status));
2631 r.in.domain_handle = domain_handle;
2632 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2633 r.in.rid = n.out.rids.ids[0];
2634 r.out.user_handle = &user_handle;
2636 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2637 if (!NT_STATUS_IS_OK(status)) {
2638 printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2642 q.in.user_handle = &user_handle;
2645 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2646 if (!NT_STATUS_IS_OK(status)) {
2647 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2651 printf("calling test_ChangePasswordUser3 with too early password change\n");
2653 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2654 q.out.info->info5.last_password_change, true)) {
2659 /* we change passwords twice - this has the effect of verifying
2660 they were changed correctly for the final call */
2661 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2665 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2672 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2673 struct policy_handle *domain_handle,
2674 struct policy_handle *user_handle_out,
2675 struct dom_sid *domain_sid,
2676 enum torture_samr_choice which_ops)
2679 TALLOC_CTX *user_ctx;
2682 struct samr_CreateUser r;
2683 struct samr_QueryUserInfo q;
2684 struct samr_DeleteUser d;
2687 /* This call creates a 'normal' account - check that it really does */
2688 const uint32_t acct_flags = ACB_NORMAL;
2689 struct lsa_String name;
2692 struct policy_handle user_handle;
2693 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2694 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2696 r.in.domain_handle = domain_handle;
2697 r.in.account_name = &name;
2698 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2699 r.out.user_handle = &user_handle;
2702 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2704 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2706 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2707 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2708 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2711 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2717 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2718 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2719 talloc_free(user_ctx);
2722 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2724 if (!NT_STATUS_IS_OK(status)) {
2725 talloc_free(user_ctx);
2726 printf("CreateUser failed - %s\n", nt_errstr(status));
2729 q.in.user_handle = &user_handle;
2732 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2733 if (!NT_STATUS_IS_OK(status)) {
2734 printf("QueryUserInfo level %u failed - %s\n",
2735 q.in.level, nt_errstr(status));
2738 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2739 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2740 q.out.info->info16.acct_flags,
2746 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2747 acct_flags, name.string, which_ops)) {
2751 if (user_handle_out) {
2752 *user_handle_out = user_handle;
2754 printf("Testing DeleteUser (createuser test)\n");
2756 d.in.user_handle = &user_handle;
2757 d.out.user_handle = &user_handle;
2759 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2760 if (!NT_STATUS_IS_OK(status)) {
2761 printf("DeleteUser failed - %s\n", nt_errstr(status));
2768 talloc_free(user_ctx);
2774 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2775 struct policy_handle *domain_handle,
2776 struct dom_sid *domain_sid,
2777 enum torture_samr_choice which_ops)
2780 struct samr_CreateUser2 r;
2781 struct samr_QueryUserInfo q;
2782 struct samr_DeleteUser d;
2783 struct policy_handle user_handle;
2785 struct lsa_String name;
2790 uint32_t acct_flags;
2791 const char *account_name;
2793 } account_types[] = {
2794 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2795 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2796 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2797 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2798 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2799 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2800 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2801 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2802 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2803 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2804 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2805 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2806 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2807 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2808 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2811 for (i = 0; account_types[i].account_name; i++) {
2812 TALLOC_CTX *user_ctx;
2813 uint32_t acct_flags = account_types[i].acct_flags;
2814 uint32_t access_granted;
2815 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2816 init_lsa_String(&name, account_types[i].account_name);
2818 r.in.domain_handle = domain_handle;
2819 r.in.account_name = &name;
2820 r.in.acct_flags = acct_flags;
2821 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2822 r.out.user_handle = &user_handle;
2823 r.out.access_granted = &access_granted;
2826 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2828 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2830 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2831 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2832 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2835 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2842 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2843 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2844 talloc_free(user_ctx);
2848 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2851 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2852 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2853 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2857 if (NT_STATUS_IS_OK(status)) {
2858 q.in.user_handle = &user_handle;
2861 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2862 if (!NT_STATUS_IS_OK(status)) {
2863 printf("QueryUserInfo level %u failed - %s\n",
2864 q.in.level, nt_errstr(status));
2867 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2868 if (acct_flags == ACB_NORMAL) {
2869 expected_flags |= ACB_PW_EXPIRED;
2871 if ((q.out.info->info5.acct_flags) != expected_flags) {
2872 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2873 q.out.info->info5.acct_flags,
2877 switch (acct_flags) {
2879 if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2880 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2881 DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2886 if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2887 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2888 DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2893 if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2894 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2895 DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2902 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2903 acct_flags, name.string, which_ops)) {
2907 printf("Testing DeleteUser (createuser2 test)\n");
2909 d.in.user_handle = &user_handle;
2910 d.out.user_handle = &user_handle;
2912 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2913 if (!NT_STATUS_IS_OK(status)) {
2914 printf("DeleteUser failed - %s\n", nt_errstr(status));
2918 talloc_free(user_ctx);
2924 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2925 struct policy_handle *handle)
2928 struct samr_QueryAliasInfo r;
2929 uint16_t levels[] = {1, 2, 3};
2933 for (i=0;i<ARRAY_SIZE(levels);i++) {
2934 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2936 r.in.alias_handle = handle;
2937 r.in.level = levels[i];
2939 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2940 if (!NT_STATUS_IS_OK(status)) {
2941 printf("QueryAliasInfo level %u failed - %s\n",
2942 levels[i], nt_errstr(status));
2950 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2951 struct policy_handle *handle)
2954 struct samr_QueryGroupInfo r;
2955 uint16_t levels[] = {1, 2, 3, 4, 5};
2959 for (i=0;i<ARRAY_SIZE(levels);i++) {
2960 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2962 r.in.group_handle = handle;
2963 r.in.level = levels[i];
2965 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2966 if (!NT_STATUS_IS_OK(status)) {
2967 printf("QueryGroupInfo level %u failed - %s\n",
2968 levels[i], nt_errstr(status));
2976 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2977 struct policy_handle *handle)
2980 struct samr_QueryGroupMember r;
2983 printf("Testing QueryGroupMember\n");
2985 r.in.group_handle = handle;
2987 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2988 if (!NT_STATUS_IS_OK(status)) {
2989 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2997 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2998 struct policy_handle *handle)
3001 struct samr_QueryGroupInfo r;
3002 struct samr_SetGroupInfo s;
3003 uint16_t levels[] = {1, 2, 3, 4};
3004 uint16_t set_ok[] = {0, 1, 1, 1};
3008 for (i=0;i<ARRAY_SIZE(levels);i++) {
3009 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3011 r.in.group_handle = handle;
3012 r.in.level = levels[i];
3014 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3015 if (!NT_STATUS_IS_OK(status)) {
3016 printf("QueryGroupInfo level %u failed - %s\n",
3017 levels[i], nt_errstr(status));
3021 printf("Testing SetGroupInfo level %u\n", levels[i]);
3023 s.in.group_handle = handle;
3024 s.in.level = levels[i];
3025 s.in.info = r.out.info;
3028 /* disabled this, as it changes the name only from the point of view of samr,
3029 but leaves the name from the point of view of w2k3 internals (and ldap). This means
3030 the name is still reserved, so creating the old name fails, but deleting by the old name
3032 if (s.in.level == 2) {
3033 init_lsa_String(&s.in.info->string, "NewName");
3037 if (s.in.level == 4) {
3038 init_lsa_String(&s.in.info->description, "test description");
3041 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
3043 if (!NT_STATUS_IS_OK(status)) {
3044 printf("SetGroupInfo level %u failed - %s\n",
3045 r.in.level, nt_errstr(status));
3050 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3051 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3052 r.in.level, nt_errstr(status));
3062 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3063 struct policy_handle *handle)
3066 struct samr_QueryUserInfo r;
3067 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3068 11, 12, 13, 14, 16, 17, 20, 21};
3072 for (i=0;i<ARRAY_SIZE(levels);i++) {
3073 printf("Testing QueryUserInfo level %u\n", levels[i]);
3075 r.in.user_handle = handle;
3076 r.in.level = levels[i];
3078 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
3079 if (!NT_STATUS_IS_OK(status)) {
3080 printf("QueryUserInfo level %u failed - %s\n",
3081 levels[i], nt_errstr(status));
3089 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3090 struct policy_handle *handle)
3093 struct samr_QueryUserInfo2 r;
3094 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3095 11, 12, 13, 14, 16, 17, 20, 21};
3099 for (i=0;i<ARRAY_SIZE(levels);i++) {
3100 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
3102 r.in.user_handle = handle;
3103 r.in.level = levels[i];
3105 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
3106 if (!NT_STATUS_IS_OK(status)) {
3107 printf("QueryUserInfo2 level %u failed - %s\n",
3108 levels[i], nt_errstr(status));
3116 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3117 struct policy_handle *handle, uint32_t rid)
3120 struct samr_OpenUser r;
3121 struct policy_handle user_handle;
3124 printf("Testing OpenUser(%u)\n", rid);
3126 r.in.domain_handle = handle;
3127 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3129 r.out.user_handle = &user_handle;
3131 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3132 if (!NT_STATUS_IS_OK(status)) {
3133 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3137 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
3141 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
3145 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
3149 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
3153 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
3157 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3164 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3165 struct policy_handle *handle, uint32_t rid)
3168 struct samr_OpenGroup r;
3169 struct policy_handle group_handle;
3172 printf("Testing OpenGroup(%u)\n", rid);
3174 r.in.domain_handle = handle;
3175 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3177 r.out.group_handle = &group_handle;
3179 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3180 if (!NT_STATUS_IS_OK(status)) {
3181 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
3185 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
3189 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
3193 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
3197 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3204 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3205 struct policy_handle *handle, uint32_t rid)
3208 struct samr_OpenAlias r;
3209 struct policy_handle alias_handle;
3212 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
3214 r.in.domain_handle = handle;
3215 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3217 r.out.alias_handle = &alias_handle;
3219 status = dcerpc_samr_OpenAlias(p, tctx, &r);
3220 if (!NT_STATUS_IS_OK(status)) {
3221 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3225 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
3229 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
3233 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
3237 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
3244 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
3245 struct policy_handle *handle, uint32_t rid,
3246 uint32_t acct_flag_mask)
3249 struct samr_OpenUser r;
3250 struct samr_QueryUserInfo q;
3251 struct policy_handle user_handle;
3254 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
3256 r.in.domain_handle = handle;
3257 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3259 r.out.user_handle = &user_handle;
3261 status = dcerpc_samr_OpenUser(p, tctx, &r);
3262 if (!NT_STATUS_IS_OK(status)) {
3263 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3267 q.in.user_handle = &user_handle;
3270 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3271 if (!NT_STATUS_IS_OK(status)) {
3272 printf("QueryUserInfo level 16 failed - %s\n",
3276 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
3277 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3278 acct_flag_mask, q.out.info->info16.acct_flags, rid);
3283 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
3290 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
3291 struct policy_handle *handle)
3293 NTSTATUS status = STATUS_MORE_ENTRIES;
3294 struct samr_EnumDomainUsers r;
3295 uint32_t mask, resume_handle=0;
3298 struct samr_LookupNames n;
3299 struct samr_LookupRids lr ;
3300 struct lsa_Strings names;
3301 struct samr_Ids types;
3303 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3304 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3305 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3308 printf("Testing EnumDomainUsers\n");
3310 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3311 r.in.domain_handle = handle;
3312 r.in.resume_handle = &resume_handle;
3313 r.in.acct_flags = mask = masks[mask_idx];
3314 r.in.max_size = (uint32_t)-1;
3315 r.out.resume_handle = &resume_handle;
3317 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
3318 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3319 !NT_STATUS_IS_OK(status)) {
3320 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3324 torture_assert(tctx, r.out.sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
3326 if (r.out.sam->count == 0) {
3330 for (i=0;i<r.out.sam->count;i++) {
3332 if (!check_mask(p, tctx, handle, r.out.sam->entries[i].idx, mask)) {
3335 } else if (!test_OpenUser(p, tctx, handle, r.out.sam->entries[i].idx)) {
3341 printf("Testing LookupNames\n");
3342 n.in.domain_handle = handle;
3343 n.in.num_names = r.out.sam->count;
3344 n.in.names = talloc_array(tctx, struct lsa_String, r.out.sam->count);
3345 for (i=0;i<r.out.sam->count;i++) {
3346 n.in.names[i].string = r.out.sam->entries[i].name.string;
3348 status = dcerpc_samr_LookupNames(p, tctx, &n);
3349 if (!NT_STATUS_IS_OK(status)) {
3350 printf("LookupNames failed - %s\n", nt_errstr(status));
3355 printf("Testing LookupRids\n");
3356 lr.in.domain_handle = handle;
3357 lr.in.num_rids = r.out.sam->count;
3358 lr.in.rids = talloc_array(tctx, uint32_t, r.out.sam->count);
3359 lr.out.names = &names;
3360 lr.out.types = &types;
3361 for (i=0;i<r.out.sam->count;i++) {
3362 lr.in.rids[i] = r.out.sam->entries[i].idx;
3364 status = dcerpc_samr_LookupRids(p, tctx, &lr);
3365 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
3371 try blasting the server with a bunch of sync requests
3373 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
3374 struct policy_handle *handle)
3377 struct samr_EnumDomainUsers r;
3378 uint32_t resume_handle=0;
3380 #define ASYNC_COUNT 100
3381 struct rpc_request *req[ASYNC_COUNT];
3383 if (!torture_setting_bool(tctx, "dangerous", false)) {
3384 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
3387 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
3389 r.in.domain_handle = handle;
3390 r.in.resume_handle = &resume_handle;
3391 r.in.acct_flags = 0;
3392 r.in.max_size = (uint32_t)-1;
3393 r.out.resume_handle = &resume_handle;
3395 for (i=0;i<ASYNC_COUNT;i++) {
3396 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
3399 for (i=0;i<ASYNC_COUNT;i++) {
3400 status = dcerpc_ndr_request_recv(req[i]);
3401 if (!NT_STATUS_IS_OK(status)) {
3402 printf("EnumDomainUsers[%d] failed - %s\n",
3403 i, nt_errstr(status));
3408 torture_comment(tctx, "%d async requests OK\n", i);
3413 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3414 struct policy_handle *handle)
3417 struct samr_EnumDomainGroups r;
3418 uint32_t resume_handle=0;
3422 printf("Testing EnumDomainGroups\n");
3424 r.in.domain_handle = handle;
3425 r.in.resume_handle = &resume_handle;
3426 r.in.max_size = (uint32_t)-1;
3427 r.out.resume_handle = &resume_handle;
3429 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3430 if (!NT_STATUS_IS_OK(status)) {
3431 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3439 for (i=0;i<r.out.sam->count;i++) {
3440 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3448 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3449 struct policy_handle *handle)
3452 struct samr_EnumDomainAliases r;
3453 uint32_t resume_handle=0;
3457 printf("Testing EnumDomainAliases\n");
3459 r.in.domain_handle = handle;
3460 r.in.resume_handle = &resume_handle;
3461 r.in.acct_flags = (uint32_t)-1;
3462 r.out.resume_handle = &resume_handle;
3464 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3465 if (!NT_STATUS_IS_OK(status)) {
3466 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3474 for (i=0;i<r.out.sam->count;i++) {
3475 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3483 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3484 struct policy_handle *handle)
3487 struct samr_GetDisplayEnumerationIndex r;
3489 uint16_t levels[] = {1, 2, 3, 4, 5};
3490 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3491 struct lsa_String name;
3495 for (i=0;i<ARRAY_SIZE(levels);i++) {
3496 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3498 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3500 r.in.domain_handle = handle;
3501 r.in.level = levels[i];
3505 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3508 !NT_STATUS_IS_OK(status) &&
3509 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3510 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3511 levels[i], nt_errstr(status));
3515 init_lsa_String(&name, "zzzzzzzz");
3517 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3519 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3520 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3521 levels[i], nt_errstr(status));
3529 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3530 struct policy_handle *handle)
3533 struct samr_GetDisplayEnumerationIndex2 r;
3535 uint16_t levels[] = {1, 2, 3, 4, 5};
3536 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3537 struct lsa_String name;
3541 for (i=0;i<ARRAY_SIZE(levels);i++) {
3542 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3544 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3546 r.in.domain_handle = handle;
3547 r.in.level = levels[i];
3551 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3553 !NT_STATUS_IS_OK(status) &&
3554 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3555 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3556 levels[i], nt_errstr(status));
3560 init_lsa_String(&name, "zzzzzzzz");
3562 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3563 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3564 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3565 levels[i], nt_errstr(status));
3573 #define STRING_EQUAL_QUERY(s1, s2, user) \
3574 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3575 /* odd, but valid */ \
3576 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3577 printf("%s mismatch for %s: %s != %s (%s)\n", \
3578 #s1, user.string, s1.string, s2.string, __location__); \
3581 #define INT_EQUAL_QUERY(s1, s2, user) \
3583 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3584 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3588 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3589 struct samr_QueryDisplayInfo *querydisplayinfo,
3590 bool *seen_testuser)
3592 struct samr_OpenUser r;
3593 struct samr_QueryUserInfo q;
3594 struct policy_handle user_handle;
3597 r.in.domain_handle = querydisplayinfo->in.domain_handle;
3598 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3599 for (i = 0; ; i++) {
3600 switch (querydisplayinfo->in.level) {
3602 if (i >= querydisplayinfo->out.info.info1.count) {
3605 r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
3608 if (i >= querydisplayinfo->out.info.info2.count) {
3611 r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
3617 /* Not interested in validating just the account name */
3621 r.out.user_handle = &user_handle;
3623 switch (querydisplayinfo->in.level) {
3626 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3627 if (!NT_STATUS_IS_OK(status)) {
3628 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3633 q.in.user_handle = &user_handle;
3635 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3636 if (!NT_STATUS_IS_OK(status)) {
3637 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3641 switch (querydisplayinfo->in.level) {
3643 if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3644 *seen_testuser = true;
3646 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name,
3647 q.out.info->info21.full_name, q.out.info->info21.account_name);
3648 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name,
3649 q.out.info->info21.account_name, q.out.info->info21.account_name);
3650 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description,
3651 q.out.info->info21.description, q.out.info->info21.account_name);
3652 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid,
3653 q.out.info->info21.rid, q.out.info->info21.account_name);
3654 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags,
3655 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3659 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name,
3660 q.out.info->info21.account_name, q.out.info->info21.account_name);
3661 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description,
3662 q.out.info->info21.description, q.out.info->info21.account_name);
3663 INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid,
3664 q.out.info->info21.rid, q.out.info->info21.account_name);
3665 INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL),
3666 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3668 if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
3669 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
3670 q.out.info->info21.account_name.string);
3673 if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3674 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3675 q.out.info->info21.account_name.string,
3676 querydisplayinfo->out.info.info2.entries[i].acct_flags,
3677 q.out.info->info21.acct_flags);
3684 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3691 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3692 struct policy_handle *handle)
3695 struct samr_QueryDisplayInfo r;
3696 struct samr_QueryDomainInfo dom_info;
3698 uint16_t levels[] = {1, 2, 3, 4, 5};
3700 bool seen_testuser = false;
3702 for (i=0;i<ARRAY_SIZE(levels);i++) {
3703 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3706 status = STATUS_MORE_ENTRIES;
3707 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3708 r.in.domain_handle = handle;
3709 r.in.level = levels[i];
3710 r.in.max_entries = 2;
3711 r.in.buf_size = (uint32_t)-1;
3713 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3714 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3715 printf("QueryDisplayInfo level %u failed - %s\n",
3716 levels[i], nt_errstr(status));
3719 switch (r.in.level) {
3721 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3724 r.in.start_idx += r.out.info.info1.count;
3727 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3730 r.in.start_idx += r.out.info.info2.count;
3733 r.in.start_idx += r.out.info.info3.count;
3736 r.in.start_idx += r.out.info.info4.count;
3739 r.in.start_idx += r.out.info.info5.count;
3743 dom_info.in.domain_handle = handle;
3744 dom_info.in.level = 2;
3745 /* Check number of users returned is correct */
3746 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3747 if (!NT_STATUS_IS_OK(status)) {
3748 printf("QueryDomainInfo level %u failed - %s\n",
3749 r.in.level, nt_errstr(status));
3753 switch (r.in.level) {
3756 if (dom_info.out.info->general.num_users < r.in.start_idx) {
3757 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3758 r.in.start_idx, dom_info.out.info->general.num_groups,
3759 dom_info.out.info->general.domain_name.string);
3762 if (!seen_testuser) {
3763 struct policy_handle user_handle;
3764 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3765 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
3766 dom_info.out.info->general.domain_name.string);
3768 test_samr_handle_Close(p, mem_ctx, &user_handle);
3774 if (dom_info.out.info->general.num_groups != r.in.start_idx) {
3775 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3776 r.in.start_idx, dom_info.out.info->general.num_groups,
3777 dom_info.out.info->general.domain_name.string);
3789 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3790 struct policy_handle *handle)
3793 struct samr_QueryDisplayInfo2 r;
3795 uint16_t levels[] = {1, 2, 3, 4, 5};
3798 for (i=0;i<ARRAY_SIZE(levels);i++) {
3799 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3801 r.in.domain_handle = handle;
3802 r.in.level = levels[i];
3804 r.in.max_entries = 1000;
3805 r.in.buf_size = (uint32_t)-1;
3807 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3808 if (!NT_STATUS_IS_OK(status)) {
3809 printf("QueryDisplayInfo2 level %u failed - %s\n",
3810 levels[i], nt_errstr(status));
3818 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
3819 struct policy_handle *handle)
3822 struct samr_QueryDisplayInfo3 r;
3824 uint16_t levels[] = {1, 2, 3, 4, 5};
3827 for (i=0;i<ARRAY_SIZE(levels);i++) {
3828 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
3830 r.in.domain_handle = handle;
3831 r.in.level = levels[i];
3833 r.in.max_entries = 1000;
3834 r.in.buf_size = (uint32_t)-1;
3836 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
3837 if (!NT_STATUS_IS_OK(status)) {
3838 printf("QueryDisplayInfo3 level %u failed - %s\n",
3839 levels[i], nt_errstr(status));
3848 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3849 struct policy_handle *handle)
3852 struct samr_QueryDisplayInfo r;
3855 printf("Testing QueryDisplayInfo continuation\n");
3857 r.in.domain_handle = handle;
3860 r.in.max_entries = 1;
3861 r.in.buf_size = (uint32_t)-1;
3864 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3865 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
3866 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
3867 printf("expected idx %d but got %d\n",
3869 r.out.info.info1.entries[0].idx);
3873 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3874 !NT_STATUS_IS_OK(status)) {
3875 printf("QueryDisplayInfo level %u failed - %s\n",
3876 r.in.level, nt_errstr(status));
3881 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3882 NT_STATUS_IS_OK(status)) &&
3883 r.out.returned_size != 0);
3888 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
3889 struct policy_handle *handle)
3892 struct samr_QueryDomainInfo r;
3893 struct samr_SetDomainInfo s;
3894 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3895 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3898 const char *domain_comment = talloc_asprintf(tctx,
3899 "Tortured by Samba4 RPC-SAMR: %s",
3900 timestring(tctx, time(NULL)));
3902 s.in.domain_handle = handle;
3904 s.in.info = talloc(tctx, union samr_DomainInfo);
3906 s.in.info->oem.oem_information.string = domain_comment;
3907 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
3908 if (!NT_STATUS_IS_OK(status)) {
3909 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3910 r.in.level, nt_errstr(status));
3914 for (i=0;i<ARRAY_SIZE(levels);i++) {
3915 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
3917 r.in.domain_handle = handle;
3918 r.in.level = levels[i];
3920 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
3921 if (!NT_STATUS_IS_OK(status)) {
3922 printf("QueryDomainInfo level %u failed - %s\n",
3923 r.in.level, nt_errstr(status));
3928 switch (levels[i]) {
3930 if (strcmp(r.out.info->general.oem_information.string, domain_comment) != 0) {
3931 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3932 levels[i], r.out.info->general.oem_information.string, domain_comment);
3935 if (!r.out.info->general.primary.string) {
3936 printf("QueryDomainInfo level %u returned no PDC name\n",
3939 } else if (r.out.info->general.role == SAMR_ROLE_DOMAIN_PDC) {
3940 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->general.primary.string) != 0) {
3941 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3942 levels[i], r.out.info->general.primary.string, dcerpc_server_name(p));
3947 if (strcmp(r.out.info->oem.oem_information.string, domain_comment) != 0) {
3948 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3949 levels[i], r.out.info->oem.oem_information.string, domain_comment);
3954 if (!r.out.info->info6.primary.string) {
3955 printf("QueryDomainInfo level %u returned no PDC name\n",
3961 if (strcmp(r.out.info->general2.general.oem_information.string, domain_comment) != 0) {
3962 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3963 levels[i], r.out.info->general2.general.oem_information.string, domain_comment);
3969 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
3971 s.in.domain_handle = handle;
3972 s.in.level = levels[i];
3973 s.in.info = r.out.info;
3975 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
3977 if (!NT_STATUS_IS_OK(status)) {
3978 printf("SetDomainInfo level %u failed - %s\n",
3979 r.in.level, nt_errstr(status));
3984 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3985 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3986 r.in.level, nt_errstr(status));
3992 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
3993 if (!NT_STATUS_IS_OK(status)) {
3994 printf("QueryDomainInfo level %u failed - %s\n",
3995 r.in.level, nt_errstr(status));
4005 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
4006 struct policy_handle *handle)
4009 struct samr_QueryDomainInfo2 r;
4010 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4014 for (i=0;i<ARRAY_SIZE(levels);i++) {
4015 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
4017 r.in.domain_handle = handle;
4018 r.in.level = levels[i];
4020 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
4021 if (!NT_STATUS_IS_OK(status)) {
4022 printf("QueryDomainInfo2 level %u failed - %s\n",
4023 r.in.level, nt_errstr(status));
4032 /* Test whether querydispinfo level 5 and enumdomgroups return the same
4033 set of group names. */
4034 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
4035 struct policy_handle *handle)
4037 struct samr_EnumDomainGroups q1;
4038 struct samr_QueryDisplayInfo q2;
4040 uint32_t resume_handle=0;
4045 const char **names = NULL;
4047 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
4049 q1.in.domain_handle = handle;
4050 q1.in.resume_handle = &resume_handle;
4052 q1.out.resume_handle = &resume_handle;
4054 status = STATUS_MORE_ENTRIES;
4055 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4056 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
4058 if (!NT_STATUS_IS_OK(status) &&
4059 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4062 for (i=0; i<q1.out.num_entries; i++) {
4063 add_string_to_array(tctx,
4064 q1.out.sam->entries[i].name.string,
4065 &names, &num_names);
4069 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
4071 torture_assert(tctx, q1.out.sam, "EnumDomainGroups failed to return q1.out.sam");
4073 q2.in.domain_handle = handle;
4075 q2.in.start_idx = 0;
4076 q2.in.max_entries = 5;
4077 q2.in.buf_size = (uint32_t)-1;
4079 status = STATUS_MORE_ENTRIES;
4080 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4081 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
4083 if (!NT_STATUS_IS_OK(status) &&
4084 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4087 for (i=0; i<q2.out.info.info5.count; i++) {
4089 const char *name = q2.out.info.info5.entries[i].account_name.string;
4091 for (j=0; j<num_names; j++) {
4092 if (names[j] == NULL)
4094 if (strequal(names[j], name)) {
4102 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
4107 q2.in.start_idx += q2.out.info.info5.count;
4110 if (!NT_STATUS_IS_OK(status)) {
4111 printf("QueryDisplayInfo level 5 failed - %s\n",
4116 for (i=0; i<num_names; i++) {
4117 if (names[i] != NULL) {
4118 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
4127 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
4128 struct policy_handle *group_handle)
4130 struct samr_DeleteDomainGroup d;
4133 torture_comment(tctx, "Testing DeleteDomainGroup\n");
4135 d.in.group_handle = group_handle;
4136 d.out.group_handle = group_handle;
4138 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
4139 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
4144 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4145 struct policy_handle *domain_handle)
4147 struct samr_TestPrivateFunctionsDomain r;
4151 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
4153 r.in.domain_handle = domain_handle;
4155 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
4156 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
4161 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
4162 struct dom_sid *domain_sid,
4163 struct policy_handle *domain_handle)
4165 struct samr_RidToSid r;
4168 struct dom_sid *calc_sid, *out_sid;
4169 int rids[] = { 0, 42, 512, 10200 };
4172 for (i=0;i<ARRAY_SIZE(rids);i++) {
4173 torture_comment(tctx, "Testing RidToSid\n");
4175 calc_sid = dom_sid_dup(tctx, domain_sid);
4176 r.in.domain_handle = domain_handle;
4178 r.out.sid = &out_sid;
4180 status = dcerpc_samr_RidToSid(p, tctx, &r);
4181 if (!NT_STATUS_IS_OK(status)) {
4182 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
4185 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
4187 if (!dom_sid_equal(calc_sid, out_sid)) {
4188 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
4189 dom_sid_string(tctx, out_sid),
4190 dom_sid_string(tctx, calc_sid));
4199 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
4200 struct policy_handle *domain_handle)
4202 struct samr_GetBootKeyInformation r;
4205 uint32_t unknown = 0;
4207 torture_comment(tctx, "Testing GetBootKeyInformation\n");
4209 r.in.domain_handle = domain_handle;
4210 r.out.unknown = &unknown;
4212 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
4213 if (!NT_STATUS_IS_OK(status)) {
4214 /* w2k3 seems to fail this sometimes and pass it sometimes */
4215 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4221 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
4222 struct policy_handle *domain_handle,
4223 struct policy_handle *group_handle)
4226 struct samr_AddGroupMember r;
4227 struct samr_DeleteGroupMember d;
4228 struct samr_QueryGroupMember q;
4229 struct samr_SetMemberAttributesOfGroup s;
4232 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4233 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
4235 r.in.group_handle = group_handle;
4237 r.in.flags = 0; /* ??? */
4239 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
4241 d.in.group_handle = group_handle;
4244 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4245 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
4247 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4248 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4250 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4251 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
4253 if (torture_setting_bool(tctx, "samba4", false)) {
4254 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
4256 /* this one is quite strange. I am using random inputs in the
4257 hope of triggering an error that might give us a clue */
4259 s.in.group_handle = group_handle;
4260 s.in.unknown1 = random();
4261 s.in.unknown2 = random();
4263 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4264 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
4267 q.in.group_handle = group_handle;
4269 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4270 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
4272 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4273 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
4275 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4276 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4282 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
4283 struct torture_context *tctx,
4284 struct policy_handle *domain_handle,
4285 struct policy_handle *group_handle,
4286 struct dom_sid *domain_sid)
4289 struct samr_CreateDomainGroup r;
4291 struct lsa_String name;
4294 init_lsa_String(&name, TEST_GROUPNAME);
4296 r.in.domain_handle = domain_handle;
4298 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4299 r.out.group_handle = group_handle;
4302 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4304 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4306 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4307 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4308 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
4311 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
4317 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4318 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
4319 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
4323 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4325 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4326 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
4328 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4332 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4334 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
4336 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
4337 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4341 if (!test_SetGroupInfo(p, tctx, group_handle)) {
4350 its not totally clear what this does. It seems to accept any sid you like.
4352 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
4353 struct torture_context *tctx,
4354 struct policy_handle *domain_handle)
4357 struct samr_RemoveMemberFromForeignDomain r;
4359 r.in.domain_handle = domain_handle;
4360 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
4362 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
4363 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
4370 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4371 struct policy_handle *handle);
4373 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4374 struct policy_handle *handle, struct dom_sid *sid,
4375 enum torture_samr_choice which_ops)
4378 struct samr_OpenDomain r;
4379 struct policy_handle domain_handle;
4380 struct policy_handle alias_handle;
4381 struct policy_handle user_handle;
4382 struct policy_handle group_handle;
4385 ZERO_STRUCT(alias_handle);
4386 ZERO_STRUCT(user_handle);
4387 ZERO_STRUCT(group_handle);
4388 ZERO_STRUCT(domain_handle);
4390 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
4392 r.in.connect_handle = handle;
4393 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4395 r.out.domain_handle = &domain_handle;
4397 status = dcerpc_samr_OpenDomain(p, tctx, &r);
4398 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
4400 /* run the domain tests with the main handle closed - this tests
4401 the servers reference counting */
4402 ret &= test_samr_handle_Close(p, tctx, handle);
4404 switch (which_ops) {
4405 case TORTURE_SAMR_USER_ATTRIBUTES:
4406 case TORTURE_SAMR_PASSWORDS:
4407 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
4408 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4409 /* This test needs 'complex' users to validate */
4410 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
4412 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
4415 case TORTURE_SAMR_OTHER:
4416 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4418 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
4420 ret &= test_QuerySecurity(p, tctx, &domain_handle);
4421 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
4422 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
4423 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
4424 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
4425 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
4426 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
4427 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
4428 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
4429 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
4430 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
4431 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
4432 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
4434 if (torture_setting_bool(tctx, "samba4", false)) {
4435 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
4437 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
4438 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
4440 ret &= test_GroupList(p, tctx, &domain_handle);
4441 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
4442 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
4443 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
4445 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
4450 if (!policy_handle_empty(&user_handle) &&
4451 !test_DeleteUser(p, tctx, &user_handle)) {
4455 if (!policy_handle_empty(&alias_handle) &&
4456 !test_DeleteAlias(p, tctx, &alias_handle)) {
4460 if (!policy_handle_empty(&group_handle) &&
4461 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
4465 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
4467 /* reconnect the main handle */
4468 ret &= test_Connect(p, tctx, handle);
4471 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
4477 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4478 struct policy_handle *handle, const char *domain,
4479 enum torture_samr_choice which_ops)
4482 struct samr_LookupDomain r;
4483 struct lsa_String n1;
4484 struct lsa_String n2;
4487 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
4489 /* check for correct error codes */
4490 r.in.connect_handle = handle;
4491 r.in.domain_name = &n2;
4494 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4495 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
4497 init_lsa_String(&n2, "xxNODOMAINxx");
4499 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4500 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
4502 r.in.connect_handle = handle;
4504 init_lsa_String(&n1, domain);
4505 r.in.domain_name = &n1;
4507 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4508 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
4510 if (!test_GetDomPwInfo(p, tctx, &n1)) {
4514 if (!test_OpenDomain(p, tctx, handle, r.out.sid, which_ops)) {
4522 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
4523 struct policy_handle *handle, enum torture_samr_choice which_ops)
4526 struct samr_EnumDomains r;
4527 uint32_t resume_handle = 0;
4531 r.in.connect_handle = handle;
4532 r.in.resume_handle = &resume_handle;
4533 r.in.buf_size = (uint32_t)-1;
4534 r.out.resume_handle = &resume_handle;
4536 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4537 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4543 for (i=0;i<r.out.sam->count;i++) {
4544 if (!test_LookupDomain(p, tctx, handle,
4545 r.out.sam->entries[i].name.string, which_ops)) {
4550 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4551 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4557 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4558 struct policy_handle *handle)
4561 struct samr_Connect r;
4562 struct samr_Connect2 r2;
4563 struct samr_Connect3 r3;
4564 struct samr_Connect4 r4;
4565 struct samr_Connect5 r5;
4566 union samr_ConnectInfo info;
4567 struct policy_handle h;
4568 bool ret = true, got_handle = false;
4570 torture_comment(tctx, "testing samr_Connect\n");
4572 r.in.system_name = 0;
4573 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4574 r.out.connect_handle = &h;
4576 status = dcerpc_samr_Connect(p, tctx, &r);
4577 if (!NT_STATUS_IS_OK(status)) {
4578 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
4585 torture_comment(tctx, "testing samr_Connect2\n");
4587 r2.in.system_name = NULL;
4588 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4589 r2.out.connect_handle = &h;
4591 status = dcerpc_samr_Connect2(p, tctx, &r2);
4592 if (!NT_STATUS_IS_OK(status)) {
4593 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
4597 test_samr_handle_Close(p, tctx, handle);
4603 torture_comment(tctx, "testing samr_Connect3\n");
4605 r3.in.system_name = NULL;
4607 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4608 r3.out.connect_handle = &h;
4610 status = dcerpc_samr_Connect3(p, tctx, &r3);
4611 if (!NT_STATUS_IS_OK(status)) {
4612 printf("Connect3 failed - %s\n", nt_errstr(status));
4616 test_samr_handle_Close(p, tctx, handle);
4622 torture_comment(tctx, "testing samr_Connect4\n");
4624 r4.in.system_name = "";
4625 r4.in.client_version = 0;
4626 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4627 r4.out.connect_handle = &h;
4629 status = dcerpc_samr_Connect4(p, tctx, &r4);
4630 if (!NT_STATUS_IS_OK(status)) {
4631 printf("Connect4 failed - %s\n", nt_errstr(status));
4635 test_samr_handle_Close(p, tctx, handle);
4641 torture_comment(tctx, "testing samr_Connect5\n");
4643 info.info1.client_version = 0;
4644 info.info1.unknown2 = 0;
4646 r5.in.system_name = "";
4647 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4650 r5.out.info = &info;
4651 r5.out.connect_handle = &h;
4653 status = dcerpc_samr_Connect5(p, tctx, &r5);
4654 if (!NT_STATUS_IS_OK(status)) {
4655 printf("Connect5 failed - %s\n", nt_errstr(status));
4659 test_samr_handle_Close(p, tctx, handle);
4669 bool torture_rpc_samr(struct torture_context *torture)
4672 struct dcerpc_pipe *p;
4674 struct policy_handle handle;
4676 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4677 if (!NT_STATUS_IS_OK(status)) {
4681 ret &= test_Connect(p, torture, &handle);
4683 ret &= test_QuerySecurity(p, torture, &handle);
4685 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4687 ret &= test_SetDsrmPassword(p, torture, &handle);
4689 ret &= test_Shutdown(p, torture, &handle);
4691 ret &= test_samr_handle_Close(p, torture, &handle);
4697 bool torture_rpc_samr_users(struct torture_context *torture)
4700 struct dcerpc_pipe *p;
4702 struct policy_handle handle;
4704 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4705 if (!NT_STATUS_IS_OK(status)) {
4709 ret &= test_Connect(p, torture, &handle);
4711 ret &= test_QuerySecurity(p, torture, &handle);
4713 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4715 ret &= test_SetDsrmPassword(p, torture, &handle);
4717 ret &= test_Shutdown(p, torture, &handle);
4719 ret &= test_samr_handle_Close(p, torture, &handle);
4725 bool torture_rpc_samr_passwords(struct torture_context *torture)
4728 struct dcerpc_pipe *p;
4730 struct policy_handle handle;
4732 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4733 if (!NT_STATUS_IS_OK(status)) {
4737 ret &= test_Connect(p, torture, &handle);
4739 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4741 ret &= test_samr_handle_Close(p, torture, &handle);