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 union samr_DomainInfo *info = NULL;
2559 struct samr_SetDomainInfo s;
2560 uint16_t len_old, len;
2561 uint32_t pwd_prop_old;
2562 int64_t min_pwd_age_old;
2567 r.in.domain_handle = domain_handle;
2571 printf("testing samr_QueryDomainInfo level 1\n");
2572 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2573 if (!NT_STATUS_IS_OK(status)) {
2577 s.in.domain_handle = domain_handle;
2581 /* remember the old min length, so we can reset it */
2582 len_old = s.in.info->info1.min_password_length;
2583 s.in.info->info1.min_password_length = len;
2584 pwd_prop_old = s.in.info->info1.password_properties;
2585 /* turn off password complexity checks for this test */
2586 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2588 min_pwd_age_old = s.in.info->info1.min_password_age;
2589 s.in.info->info1.min_password_age = 0;
2591 printf("testing samr_SetDomainInfo level 1\n");
2592 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2593 if (!NT_STATUS_IS_OK(status)) {
2597 printf("calling test_ChangePasswordUser3 with too short password\n");
2599 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
2603 s.in.info->info1.min_password_length = len_old;
2604 s.in.info->info1.password_properties = pwd_prop_old;
2605 s.in.info->info1.min_password_age = min_pwd_age_old;
2607 printf("testing samr_SetDomainInfo level 1\n");
2608 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2609 if (!NT_STATUS_IS_OK(status)) {
2617 struct samr_OpenUser r;
2618 struct samr_QueryUserInfo q;
2619 struct samr_LookupNames n;
2620 struct policy_handle user_handle;
2622 n.in.domain_handle = domain_handle;
2624 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2625 n.in.names[0].string = acct_name;
2627 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2628 if (!NT_STATUS_IS_OK(status)) {
2629 printf("LookupNames failed - %s\n", nt_errstr(status));
2633 r.in.domain_handle = domain_handle;
2634 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2635 r.in.rid = n.out.rids.ids[0];
2636 r.out.user_handle = &user_handle;
2638 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2639 if (!NT_STATUS_IS_OK(status)) {
2640 printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2644 q.in.user_handle = &user_handle;
2647 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2648 if (!NT_STATUS_IS_OK(status)) {
2649 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2653 printf("calling test_ChangePasswordUser3 with too early password change\n");
2655 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2656 q.out.info->info5.last_password_change, true)) {
2661 /* we change passwords twice - this has the effect of verifying
2662 they were changed correctly for the final call */
2663 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2667 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2674 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2675 struct policy_handle *domain_handle,
2676 struct policy_handle *user_handle_out,
2677 struct dom_sid *domain_sid,
2678 enum torture_samr_choice which_ops)
2681 TALLOC_CTX *user_ctx;
2684 struct samr_CreateUser r;
2685 struct samr_QueryUserInfo q;
2686 struct samr_DeleteUser d;
2689 /* This call creates a 'normal' account - check that it really does */
2690 const uint32_t acct_flags = ACB_NORMAL;
2691 struct lsa_String name;
2694 struct policy_handle user_handle;
2695 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2696 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2698 r.in.domain_handle = domain_handle;
2699 r.in.account_name = &name;
2700 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2701 r.out.user_handle = &user_handle;
2704 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2706 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2708 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2709 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2710 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2713 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2719 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2720 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2721 talloc_free(user_ctx);
2724 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2726 if (!NT_STATUS_IS_OK(status)) {
2727 talloc_free(user_ctx);
2728 printf("CreateUser failed - %s\n", nt_errstr(status));
2731 q.in.user_handle = &user_handle;
2734 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2735 if (!NT_STATUS_IS_OK(status)) {
2736 printf("QueryUserInfo level %u failed - %s\n",
2737 q.in.level, nt_errstr(status));
2740 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2741 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2742 q.out.info->info16.acct_flags,
2748 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2749 acct_flags, name.string, which_ops)) {
2753 if (user_handle_out) {
2754 *user_handle_out = user_handle;
2756 printf("Testing DeleteUser (createuser test)\n");
2758 d.in.user_handle = &user_handle;
2759 d.out.user_handle = &user_handle;
2761 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2762 if (!NT_STATUS_IS_OK(status)) {
2763 printf("DeleteUser failed - %s\n", nt_errstr(status));
2770 talloc_free(user_ctx);
2776 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2777 struct policy_handle *domain_handle,
2778 struct dom_sid *domain_sid,
2779 enum torture_samr_choice which_ops)
2782 struct samr_CreateUser2 r;
2783 struct samr_QueryUserInfo q;
2784 struct samr_DeleteUser d;
2785 struct policy_handle user_handle;
2787 struct lsa_String name;
2792 uint32_t acct_flags;
2793 const char *account_name;
2795 } account_types[] = {
2796 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2797 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2798 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2799 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2800 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2801 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2802 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2803 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2804 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2805 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2806 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2807 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2808 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2809 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2810 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2813 for (i = 0; account_types[i].account_name; i++) {
2814 TALLOC_CTX *user_ctx;
2815 uint32_t acct_flags = account_types[i].acct_flags;
2816 uint32_t access_granted;
2817 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2818 init_lsa_String(&name, account_types[i].account_name);
2820 r.in.domain_handle = domain_handle;
2821 r.in.account_name = &name;
2822 r.in.acct_flags = acct_flags;
2823 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2824 r.out.user_handle = &user_handle;
2825 r.out.access_granted = &access_granted;
2828 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2830 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2832 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2833 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2834 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2837 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2844 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2845 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2846 talloc_free(user_ctx);
2850 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2853 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2854 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2855 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2859 if (NT_STATUS_IS_OK(status)) {
2860 q.in.user_handle = &user_handle;
2863 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2864 if (!NT_STATUS_IS_OK(status)) {
2865 printf("QueryUserInfo level %u failed - %s\n",
2866 q.in.level, nt_errstr(status));
2869 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2870 if (acct_flags == ACB_NORMAL) {
2871 expected_flags |= ACB_PW_EXPIRED;
2873 if ((q.out.info->info5.acct_flags) != expected_flags) {
2874 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2875 q.out.info->info5.acct_flags,
2879 switch (acct_flags) {
2881 if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2882 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2883 DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2888 if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2889 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2890 DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2895 if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2896 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2897 DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2904 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2905 acct_flags, name.string, which_ops)) {
2909 printf("Testing DeleteUser (createuser2 test)\n");
2911 d.in.user_handle = &user_handle;
2912 d.out.user_handle = &user_handle;
2914 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2915 if (!NT_STATUS_IS_OK(status)) {
2916 printf("DeleteUser failed - %s\n", nt_errstr(status));
2920 talloc_free(user_ctx);
2926 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2927 struct policy_handle *handle)
2930 struct samr_QueryAliasInfo r;
2931 uint16_t levels[] = {1, 2, 3};
2935 for (i=0;i<ARRAY_SIZE(levels);i++) {
2936 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2938 r.in.alias_handle = handle;
2939 r.in.level = levels[i];
2941 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2942 if (!NT_STATUS_IS_OK(status)) {
2943 printf("QueryAliasInfo level %u failed - %s\n",
2944 levels[i], nt_errstr(status));
2952 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2953 struct policy_handle *handle)
2956 struct samr_QueryGroupInfo r;
2957 uint16_t levels[] = {1, 2, 3, 4, 5};
2961 for (i=0;i<ARRAY_SIZE(levels);i++) {
2962 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2964 r.in.group_handle = handle;
2965 r.in.level = levels[i];
2967 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2968 if (!NT_STATUS_IS_OK(status)) {
2969 printf("QueryGroupInfo level %u failed - %s\n",
2970 levels[i], nt_errstr(status));
2978 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2979 struct policy_handle *handle)
2982 struct samr_QueryGroupMember r;
2983 struct samr_RidTypeArray *rids = NULL;
2986 printf("Testing QueryGroupMember\n");
2988 r.in.group_handle = handle;
2991 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2992 if (!NT_STATUS_IS_OK(status)) {
2993 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
3001 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3002 struct policy_handle *handle)
3005 struct samr_QueryGroupInfo r;
3006 struct samr_SetGroupInfo s;
3007 uint16_t levels[] = {1, 2, 3, 4};
3008 uint16_t set_ok[] = {0, 1, 1, 1};
3012 for (i=0;i<ARRAY_SIZE(levels);i++) {
3013 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3015 r.in.group_handle = handle;
3016 r.in.level = levels[i];
3018 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3019 if (!NT_STATUS_IS_OK(status)) {
3020 printf("QueryGroupInfo level %u failed - %s\n",
3021 levels[i], nt_errstr(status));
3025 printf("Testing SetGroupInfo level %u\n", levels[i]);
3027 s.in.group_handle = handle;
3028 s.in.level = levels[i];
3029 s.in.info = r.out.info;
3032 /* disabled this, as it changes the name only from the point of view of samr,
3033 but leaves the name from the point of view of w2k3 internals (and ldap). This means
3034 the name is still reserved, so creating the old name fails, but deleting by the old name
3036 if (s.in.level == 2) {
3037 init_lsa_String(&s.in.info->string, "NewName");
3041 if (s.in.level == 4) {
3042 init_lsa_String(&s.in.info->description, "test description");
3045 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
3047 if (!NT_STATUS_IS_OK(status)) {
3048 printf("SetGroupInfo level %u failed - %s\n",
3049 r.in.level, nt_errstr(status));
3054 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3055 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3056 r.in.level, nt_errstr(status));
3066 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3067 struct policy_handle *handle)
3070 struct samr_QueryUserInfo r;
3071 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3072 11, 12, 13, 14, 16, 17, 20, 21};
3076 for (i=0;i<ARRAY_SIZE(levels);i++) {
3077 printf("Testing QueryUserInfo level %u\n", levels[i]);
3079 r.in.user_handle = handle;
3080 r.in.level = levels[i];
3082 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
3083 if (!NT_STATUS_IS_OK(status)) {
3084 printf("QueryUserInfo level %u failed - %s\n",
3085 levels[i], nt_errstr(status));
3093 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3094 struct policy_handle *handle)
3097 struct samr_QueryUserInfo2 r;
3098 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3099 11, 12, 13, 14, 16, 17, 20, 21};
3103 for (i=0;i<ARRAY_SIZE(levels);i++) {
3104 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
3106 r.in.user_handle = handle;
3107 r.in.level = levels[i];
3109 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
3110 if (!NT_STATUS_IS_OK(status)) {
3111 printf("QueryUserInfo2 level %u failed - %s\n",
3112 levels[i], nt_errstr(status));
3120 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3121 struct policy_handle *handle, uint32_t rid)
3124 struct samr_OpenUser r;
3125 struct policy_handle user_handle;
3128 printf("Testing OpenUser(%u)\n", rid);
3130 r.in.domain_handle = handle;
3131 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3133 r.out.user_handle = &user_handle;
3135 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3136 if (!NT_STATUS_IS_OK(status)) {
3137 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3141 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
3145 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
3149 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
3153 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
3157 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
3161 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3168 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3169 struct policy_handle *handle, uint32_t rid)
3172 struct samr_OpenGroup r;
3173 struct policy_handle group_handle;
3176 printf("Testing OpenGroup(%u)\n", rid);
3178 r.in.domain_handle = handle;
3179 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3181 r.out.group_handle = &group_handle;
3183 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3184 if (!NT_STATUS_IS_OK(status)) {
3185 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
3189 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
3193 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
3197 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
3201 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3208 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3209 struct policy_handle *handle, uint32_t rid)
3212 struct samr_OpenAlias r;
3213 struct policy_handle alias_handle;
3216 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
3218 r.in.domain_handle = handle;
3219 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3221 r.out.alias_handle = &alias_handle;
3223 status = dcerpc_samr_OpenAlias(p, tctx, &r);
3224 if (!NT_STATUS_IS_OK(status)) {
3225 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3229 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
3233 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
3237 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
3241 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
3248 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
3249 struct policy_handle *handle, uint32_t rid,
3250 uint32_t acct_flag_mask)
3253 struct samr_OpenUser r;
3254 struct samr_QueryUserInfo q;
3255 struct policy_handle user_handle;
3258 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
3260 r.in.domain_handle = handle;
3261 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3263 r.out.user_handle = &user_handle;
3265 status = dcerpc_samr_OpenUser(p, tctx, &r);
3266 if (!NT_STATUS_IS_OK(status)) {
3267 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3271 q.in.user_handle = &user_handle;
3274 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3275 if (!NT_STATUS_IS_OK(status)) {
3276 printf("QueryUserInfo level 16 failed - %s\n",
3280 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
3281 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3282 acct_flag_mask, q.out.info->info16.acct_flags, rid);
3287 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
3294 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
3295 struct policy_handle *handle)
3297 NTSTATUS status = STATUS_MORE_ENTRIES;
3298 struct samr_EnumDomainUsers r;
3299 uint32_t mask, resume_handle=0;
3302 struct samr_LookupNames n;
3303 struct samr_LookupRids lr ;
3304 struct lsa_Strings names;
3305 struct samr_Ids types;
3307 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3308 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3309 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3312 printf("Testing EnumDomainUsers\n");
3314 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3315 r.in.domain_handle = handle;
3316 r.in.resume_handle = &resume_handle;
3317 r.in.acct_flags = mask = masks[mask_idx];
3318 r.in.max_size = (uint32_t)-1;
3319 r.out.resume_handle = &resume_handle;
3321 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
3322 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3323 !NT_STATUS_IS_OK(status)) {
3324 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3328 torture_assert(tctx, r.out.sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
3330 if (r.out.sam->count == 0) {
3334 for (i=0;i<r.out.sam->count;i++) {
3336 if (!check_mask(p, tctx, handle, r.out.sam->entries[i].idx, mask)) {
3339 } else if (!test_OpenUser(p, tctx, handle, r.out.sam->entries[i].idx)) {
3345 printf("Testing LookupNames\n");
3346 n.in.domain_handle = handle;
3347 n.in.num_names = r.out.sam->count;
3348 n.in.names = talloc_array(tctx, struct lsa_String, r.out.sam->count);
3349 for (i=0;i<r.out.sam->count;i++) {
3350 n.in.names[i].string = r.out.sam->entries[i].name.string;
3352 status = dcerpc_samr_LookupNames(p, tctx, &n);
3353 if (!NT_STATUS_IS_OK(status)) {
3354 printf("LookupNames failed - %s\n", nt_errstr(status));
3359 printf("Testing LookupRids\n");
3360 lr.in.domain_handle = handle;
3361 lr.in.num_rids = r.out.sam->count;
3362 lr.in.rids = talloc_array(tctx, uint32_t, r.out.sam->count);
3363 lr.out.names = &names;
3364 lr.out.types = &types;
3365 for (i=0;i<r.out.sam->count;i++) {
3366 lr.in.rids[i] = r.out.sam->entries[i].idx;
3368 status = dcerpc_samr_LookupRids(p, tctx, &lr);
3369 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
3375 try blasting the server with a bunch of sync requests
3377 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
3378 struct policy_handle *handle)
3381 struct samr_EnumDomainUsers r;
3382 uint32_t resume_handle=0;
3384 #define ASYNC_COUNT 100
3385 struct rpc_request *req[ASYNC_COUNT];
3387 if (!torture_setting_bool(tctx, "dangerous", false)) {
3388 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
3391 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
3393 r.in.domain_handle = handle;
3394 r.in.resume_handle = &resume_handle;
3395 r.in.acct_flags = 0;
3396 r.in.max_size = (uint32_t)-1;
3397 r.out.resume_handle = &resume_handle;
3399 for (i=0;i<ASYNC_COUNT;i++) {
3400 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
3403 for (i=0;i<ASYNC_COUNT;i++) {
3404 status = dcerpc_ndr_request_recv(req[i]);
3405 if (!NT_STATUS_IS_OK(status)) {
3406 printf("EnumDomainUsers[%d] failed - %s\n",
3407 i, nt_errstr(status));
3412 torture_comment(tctx, "%d async requests OK\n", i);
3417 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3418 struct policy_handle *handle)
3421 struct samr_EnumDomainGroups r;
3422 uint32_t resume_handle=0;
3426 printf("Testing EnumDomainGroups\n");
3428 r.in.domain_handle = handle;
3429 r.in.resume_handle = &resume_handle;
3430 r.in.max_size = (uint32_t)-1;
3431 r.out.resume_handle = &resume_handle;
3433 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3434 if (!NT_STATUS_IS_OK(status)) {
3435 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3443 for (i=0;i<r.out.sam->count;i++) {
3444 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3452 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3453 struct policy_handle *handle)
3456 struct samr_EnumDomainAliases r;
3457 uint32_t resume_handle=0;
3461 printf("Testing EnumDomainAliases\n");
3463 r.in.domain_handle = handle;
3464 r.in.resume_handle = &resume_handle;
3465 r.in.acct_flags = (uint32_t)-1;
3466 r.out.resume_handle = &resume_handle;
3468 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3469 if (!NT_STATUS_IS_OK(status)) {
3470 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3478 for (i=0;i<r.out.sam->count;i++) {
3479 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3487 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3488 struct policy_handle *handle)
3491 struct samr_GetDisplayEnumerationIndex r;
3493 uint16_t levels[] = {1, 2, 3, 4, 5};
3494 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3495 struct lsa_String name;
3499 for (i=0;i<ARRAY_SIZE(levels);i++) {
3500 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3502 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3504 r.in.domain_handle = handle;
3505 r.in.level = levels[i];
3509 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3512 !NT_STATUS_IS_OK(status) &&
3513 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3514 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3515 levels[i], nt_errstr(status));
3519 init_lsa_String(&name, "zzzzzzzz");
3521 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3523 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3524 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3525 levels[i], nt_errstr(status));
3533 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3534 struct policy_handle *handle)
3537 struct samr_GetDisplayEnumerationIndex2 r;
3539 uint16_t levels[] = {1, 2, 3, 4, 5};
3540 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3541 struct lsa_String name;
3545 for (i=0;i<ARRAY_SIZE(levels);i++) {
3546 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3548 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3550 r.in.domain_handle = handle;
3551 r.in.level = levels[i];
3555 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3557 !NT_STATUS_IS_OK(status) &&
3558 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3559 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3560 levels[i], nt_errstr(status));
3564 init_lsa_String(&name, "zzzzzzzz");
3566 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3567 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3568 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3569 levels[i], nt_errstr(status));
3577 #define STRING_EQUAL_QUERY(s1, s2, user) \
3578 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3579 /* odd, but valid */ \
3580 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3581 printf("%s mismatch for %s: %s != %s (%s)\n", \
3582 #s1, user.string, s1.string, s2.string, __location__); \
3585 #define INT_EQUAL_QUERY(s1, s2, user) \
3587 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3588 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3592 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3593 struct samr_QueryDisplayInfo *querydisplayinfo,
3594 bool *seen_testuser)
3596 struct samr_OpenUser r;
3597 struct samr_QueryUserInfo q;
3598 struct policy_handle user_handle;
3601 r.in.domain_handle = querydisplayinfo->in.domain_handle;
3602 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3603 for (i = 0; ; i++) {
3604 switch (querydisplayinfo->in.level) {
3606 if (i >= querydisplayinfo->out.info.info1.count) {
3609 r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
3612 if (i >= querydisplayinfo->out.info.info2.count) {
3615 r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
3621 /* Not interested in validating just the account name */
3625 r.out.user_handle = &user_handle;
3627 switch (querydisplayinfo->in.level) {
3630 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3631 if (!NT_STATUS_IS_OK(status)) {
3632 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3637 q.in.user_handle = &user_handle;
3639 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3640 if (!NT_STATUS_IS_OK(status)) {
3641 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3645 switch (querydisplayinfo->in.level) {
3647 if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3648 *seen_testuser = true;
3650 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name,
3651 q.out.info->info21.full_name, q.out.info->info21.account_name);
3652 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name,
3653 q.out.info->info21.account_name, q.out.info->info21.account_name);
3654 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description,
3655 q.out.info->info21.description, q.out.info->info21.account_name);
3656 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid,
3657 q.out.info->info21.rid, q.out.info->info21.account_name);
3658 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags,
3659 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3663 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name,
3664 q.out.info->info21.account_name, q.out.info->info21.account_name);
3665 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description,
3666 q.out.info->info21.description, q.out.info->info21.account_name);
3667 INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid,
3668 q.out.info->info21.rid, q.out.info->info21.account_name);
3669 INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL),
3670 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3672 if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
3673 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
3674 q.out.info->info21.account_name.string);
3677 if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3678 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3679 q.out.info->info21.account_name.string,
3680 querydisplayinfo->out.info.info2.entries[i].acct_flags,
3681 q.out.info->info21.acct_flags);
3688 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3695 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3696 struct policy_handle *handle)
3699 struct samr_QueryDisplayInfo r;
3700 struct samr_QueryDomainInfo dom_info;
3701 union samr_DomainInfo *info = NULL;
3703 uint16_t levels[] = {1, 2, 3, 4, 5};
3705 bool seen_testuser = false;
3707 for (i=0;i<ARRAY_SIZE(levels);i++) {
3708 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3711 status = STATUS_MORE_ENTRIES;
3712 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3713 r.in.domain_handle = handle;
3714 r.in.level = levels[i];
3715 r.in.max_entries = 2;
3716 r.in.buf_size = (uint32_t)-1;
3718 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3719 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3720 printf("QueryDisplayInfo level %u failed - %s\n",
3721 levels[i], nt_errstr(status));
3724 switch (r.in.level) {
3726 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3729 r.in.start_idx += r.out.info.info1.count;
3732 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3735 r.in.start_idx += r.out.info.info2.count;
3738 r.in.start_idx += r.out.info.info3.count;
3741 r.in.start_idx += r.out.info.info4.count;
3744 r.in.start_idx += r.out.info.info5.count;
3748 dom_info.in.domain_handle = handle;
3749 dom_info.in.level = 2;
3750 dom_info.out.info = &info;
3752 /* Check number of users returned is correct */
3753 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3754 if (!NT_STATUS_IS_OK(status)) {
3755 printf("QueryDomainInfo level %u failed - %s\n",
3756 r.in.level, nt_errstr(status));
3760 switch (r.in.level) {
3763 if (info->general.num_users < r.in.start_idx) {
3764 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3765 r.in.start_idx, info->general.num_groups,
3766 info->general.domain_name.string);
3769 if (!seen_testuser) {
3770 struct policy_handle user_handle;
3771 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3772 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
3773 info->general.domain_name.string);
3775 test_samr_handle_Close(p, mem_ctx, &user_handle);
3781 if (info->general.num_groups != r.in.start_idx) {
3782 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3783 r.in.start_idx, info->general.num_groups,
3784 info->general.domain_name.string);
3796 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3797 struct policy_handle *handle)
3800 struct samr_QueryDisplayInfo2 r;
3802 uint16_t levels[] = {1, 2, 3, 4, 5};
3805 for (i=0;i<ARRAY_SIZE(levels);i++) {
3806 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3808 r.in.domain_handle = handle;
3809 r.in.level = levels[i];
3811 r.in.max_entries = 1000;
3812 r.in.buf_size = (uint32_t)-1;
3814 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3815 if (!NT_STATUS_IS_OK(status)) {
3816 printf("QueryDisplayInfo2 level %u failed - %s\n",
3817 levels[i], nt_errstr(status));
3825 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
3826 struct policy_handle *handle)
3829 struct samr_QueryDisplayInfo3 r;
3831 uint16_t levels[] = {1, 2, 3, 4, 5};
3834 for (i=0;i<ARRAY_SIZE(levels);i++) {
3835 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
3837 r.in.domain_handle = handle;
3838 r.in.level = levels[i];
3840 r.in.max_entries = 1000;
3841 r.in.buf_size = (uint32_t)-1;
3843 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
3844 if (!NT_STATUS_IS_OK(status)) {
3845 printf("QueryDisplayInfo3 level %u failed - %s\n",
3846 levels[i], nt_errstr(status));
3855 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3856 struct policy_handle *handle)
3859 struct samr_QueryDisplayInfo r;
3862 printf("Testing QueryDisplayInfo continuation\n");
3864 r.in.domain_handle = handle;
3867 r.in.max_entries = 1;
3868 r.in.buf_size = (uint32_t)-1;
3871 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3872 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
3873 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
3874 printf("expected idx %d but got %d\n",
3876 r.out.info.info1.entries[0].idx);
3880 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3881 !NT_STATUS_IS_OK(status)) {
3882 printf("QueryDisplayInfo level %u failed - %s\n",
3883 r.in.level, nt_errstr(status));
3888 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3889 NT_STATUS_IS_OK(status)) &&
3890 r.out.returned_size != 0);
3895 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
3896 struct policy_handle *handle)
3899 struct samr_QueryDomainInfo r;
3900 union samr_DomainInfo *info = NULL;
3901 struct samr_SetDomainInfo s;
3902 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3903 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3906 const char *domain_comment = talloc_asprintf(tctx,
3907 "Tortured by Samba4 RPC-SAMR: %s",
3908 timestring(tctx, time(NULL)));
3910 s.in.domain_handle = handle;
3912 s.in.info = talloc(tctx, union samr_DomainInfo);
3914 s.in.info->oem.oem_information.string = domain_comment;
3915 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
3916 if (!NT_STATUS_IS_OK(status)) {
3917 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3918 r.in.level, nt_errstr(status));
3922 for (i=0;i<ARRAY_SIZE(levels);i++) {
3923 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
3925 r.in.domain_handle = handle;
3926 r.in.level = levels[i];
3929 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
3930 if (!NT_STATUS_IS_OK(status)) {
3931 printf("QueryDomainInfo level %u failed - %s\n",
3932 r.in.level, nt_errstr(status));
3937 switch (levels[i]) {
3939 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
3940 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3941 levels[i], info->general.oem_information.string, domain_comment);
3944 if (!info->general.primary.string) {
3945 printf("QueryDomainInfo level %u returned no PDC name\n",
3948 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
3949 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
3950 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3951 levels[i], info->general.primary.string, dcerpc_server_name(p));
3956 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
3957 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3958 levels[i], info->oem.oem_information.string, domain_comment);
3963 if (!info->info6.primary.string) {
3964 printf("QueryDomainInfo level %u returned no PDC name\n",
3970 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
3971 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3972 levels[i], info->general2.general.oem_information.string, domain_comment);
3978 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
3980 s.in.domain_handle = handle;
3981 s.in.level = levels[i];
3984 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
3986 if (!NT_STATUS_IS_OK(status)) {
3987 printf("SetDomainInfo level %u failed - %s\n",
3988 r.in.level, nt_errstr(status));
3993 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3994 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3995 r.in.level, nt_errstr(status));
4001 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4002 if (!NT_STATUS_IS_OK(status)) {
4003 printf("QueryDomainInfo level %u failed - %s\n",
4004 r.in.level, nt_errstr(status));
4014 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
4015 struct policy_handle *handle)
4018 struct samr_QueryDomainInfo2 r;
4019 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4023 for (i=0;i<ARRAY_SIZE(levels);i++) {
4024 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
4026 r.in.domain_handle = handle;
4027 r.in.level = levels[i];
4029 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
4030 if (!NT_STATUS_IS_OK(status)) {
4031 printf("QueryDomainInfo2 level %u failed - %s\n",
4032 r.in.level, nt_errstr(status));
4041 /* Test whether querydispinfo level 5 and enumdomgroups return the same
4042 set of group names. */
4043 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
4044 struct policy_handle *handle)
4046 struct samr_EnumDomainGroups q1;
4047 struct samr_QueryDisplayInfo q2;
4049 uint32_t resume_handle=0;
4054 const char **names = NULL;
4056 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
4058 q1.in.domain_handle = handle;
4059 q1.in.resume_handle = &resume_handle;
4061 q1.out.resume_handle = &resume_handle;
4063 status = STATUS_MORE_ENTRIES;
4064 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4065 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
4067 if (!NT_STATUS_IS_OK(status) &&
4068 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4071 for (i=0; i<q1.out.num_entries; i++) {
4072 add_string_to_array(tctx,
4073 q1.out.sam->entries[i].name.string,
4074 &names, &num_names);
4078 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
4080 torture_assert(tctx, q1.out.sam, "EnumDomainGroups failed to return q1.out.sam");
4082 q2.in.domain_handle = handle;
4084 q2.in.start_idx = 0;
4085 q2.in.max_entries = 5;
4086 q2.in.buf_size = (uint32_t)-1;
4088 status = STATUS_MORE_ENTRIES;
4089 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4090 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
4092 if (!NT_STATUS_IS_OK(status) &&
4093 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4096 for (i=0; i<q2.out.info.info5.count; i++) {
4098 const char *name = q2.out.info.info5.entries[i].account_name.string;
4100 for (j=0; j<num_names; j++) {
4101 if (names[j] == NULL)
4103 if (strequal(names[j], name)) {
4111 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
4116 q2.in.start_idx += q2.out.info.info5.count;
4119 if (!NT_STATUS_IS_OK(status)) {
4120 printf("QueryDisplayInfo level 5 failed - %s\n",
4125 for (i=0; i<num_names; i++) {
4126 if (names[i] != NULL) {
4127 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
4136 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
4137 struct policy_handle *group_handle)
4139 struct samr_DeleteDomainGroup d;
4142 torture_comment(tctx, "Testing DeleteDomainGroup\n");
4144 d.in.group_handle = group_handle;
4145 d.out.group_handle = group_handle;
4147 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
4148 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
4153 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4154 struct policy_handle *domain_handle)
4156 struct samr_TestPrivateFunctionsDomain r;
4160 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
4162 r.in.domain_handle = domain_handle;
4164 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
4165 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
4170 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
4171 struct dom_sid *domain_sid,
4172 struct policy_handle *domain_handle)
4174 struct samr_RidToSid r;
4177 struct dom_sid *calc_sid, *out_sid;
4178 int rids[] = { 0, 42, 512, 10200 };
4181 for (i=0;i<ARRAY_SIZE(rids);i++) {
4182 torture_comment(tctx, "Testing RidToSid\n");
4184 calc_sid = dom_sid_dup(tctx, domain_sid);
4185 r.in.domain_handle = domain_handle;
4187 r.out.sid = &out_sid;
4189 status = dcerpc_samr_RidToSid(p, tctx, &r);
4190 if (!NT_STATUS_IS_OK(status)) {
4191 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
4194 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
4196 if (!dom_sid_equal(calc_sid, out_sid)) {
4197 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
4198 dom_sid_string(tctx, out_sid),
4199 dom_sid_string(tctx, calc_sid));
4208 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
4209 struct policy_handle *domain_handle)
4211 struct samr_GetBootKeyInformation r;
4214 uint32_t unknown = 0;
4216 torture_comment(tctx, "Testing GetBootKeyInformation\n");
4218 r.in.domain_handle = domain_handle;
4219 r.out.unknown = &unknown;
4221 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
4222 if (!NT_STATUS_IS_OK(status)) {
4223 /* w2k3 seems to fail this sometimes and pass it sometimes */
4224 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4230 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
4231 struct policy_handle *domain_handle,
4232 struct policy_handle *group_handle)
4235 struct samr_AddGroupMember r;
4236 struct samr_DeleteGroupMember d;
4237 struct samr_QueryGroupMember q;
4238 struct samr_RidTypeArray *rids = NULL;
4239 struct samr_SetMemberAttributesOfGroup s;
4242 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4243 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
4245 r.in.group_handle = group_handle;
4247 r.in.flags = 0; /* ??? */
4249 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
4251 d.in.group_handle = group_handle;
4254 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4255 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
4257 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4258 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4260 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4261 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
4263 if (torture_setting_bool(tctx, "samba4", false)) {
4264 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
4266 /* this one is quite strange. I am using random inputs in the
4267 hope of triggering an error that might give us a clue */
4269 s.in.group_handle = group_handle;
4270 s.in.unknown1 = random();
4271 s.in.unknown2 = random();
4273 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4274 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
4277 q.in.group_handle = group_handle;
4280 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4281 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
4283 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4284 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
4286 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4287 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4293 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
4294 struct torture_context *tctx,
4295 struct policy_handle *domain_handle,
4296 struct policy_handle *group_handle,
4297 struct dom_sid *domain_sid)
4300 struct samr_CreateDomainGroup r;
4302 struct lsa_String name;
4305 init_lsa_String(&name, TEST_GROUPNAME);
4307 r.in.domain_handle = domain_handle;
4309 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4310 r.out.group_handle = group_handle;
4313 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4315 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4317 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4318 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4319 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
4322 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
4328 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4329 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
4330 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
4334 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4336 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4337 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
4339 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4343 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4345 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
4347 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
4348 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4352 if (!test_SetGroupInfo(p, tctx, group_handle)) {
4361 its not totally clear what this does. It seems to accept any sid you like.
4363 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
4364 struct torture_context *tctx,
4365 struct policy_handle *domain_handle)
4368 struct samr_RemoveMemberFromForeignDomain r;
4370 r.in.domain_handle = domain_handle;
4371 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
4373 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
4374 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
4381 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4382 struct policy_handle *handle);
4384 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4385 struct policy_handle *handle, struct dom_sid *sid,
4386 enum torture_samr_choice which_ops)
4389 struct samr_OpenDomain r;
4390 struct policy_handle domain_handle;
4391 struct policy_handle alias_handle;
4392 struct policy_handle user_handle;
4393 struct policy_handle group_handle;
4396 ZERO_STRUCT(alias_handle);
4397 ZERO_STRUCT(user_handle);
4398 ZERO_STRUCT(group_handle);
4399 ZERO_STRUCT(domain_handle);
4401 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
4403 r.in.connect_handle = handle;
4404 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4406 r.out.domain_handle = &domain_handle;
4408 status = dcerpc_samr_OpenDomain(p, tctx, &r);
4409 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
4411 /* run the domain tests with the main handle closed - this tests
4412 the servers reference counting */
4413 ret &= test_samr_handle_Close(p, tctx, handle);
4415 switch (which_ops) {
4416 case TORTURE_SAMR_USER_ATTRIBUTES:
4417 case TORTURE_SAMR_PASSWORDS:
4418 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
4419 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4420 /* This test needs 'complex' users to validate */
4421 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
4423 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
4426 case TORTURE_SAMR_OTHER:
4427 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4429 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
4431 ret &= test_QuerySecurity(p, tctx, &domain_handle);
4432 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
4433 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
4434 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
4435 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
4436 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
4437 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
4438 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
4439 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
4440 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
4441 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
4442 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
4443 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
4445 if (torture_setting_bool(tctx, "samba4", false)) {
4446 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
4448 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
4449 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
4451 ret &= test_GroupList(p, tctx, &domain_handle);
4452 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
4453 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
4454 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
4456 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
4461 if (!policy_handle_empty(&user_handle) &&
4462 !test_DeleteUser(p, tctx, &user_handle)) {
4466 if (!policy_handle_empty(&alias_handle) &&
4467 !test_DeleteAlias(p, tctx, &alias_handle)) {
4471 if (!policy_handle_empty(&group_handle) &&
4472 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
4476 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
4478 /* reconnect the main handle */
4479 ret &= test_Connect(p, tctx, handle);
4482 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
4488 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4489 struct policy_handle *handle, const char *domain,
4490 enum torture_samr_choice which_ops)
4493 struct samr_LookupDomain r;
4494 struct lsa_String n1;
4495 struct lsa_String n2;
4498 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
4500 /* check for correct error codes */
4501 r.in.connect_handle = handle;
4502 r.in.domain_name = &n2;
4505 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4506 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
4508 init_lsa_String(&n2, "xxNODOMAINxx");
4510 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4511 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
4513 r.in.connect_handle = handle;
4515 init_lsa_String(&n1, domain);
4516 r.in.domain_name = &n1;
4518 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4519 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
4521 if (!test_GetDomPwInfo(p, tctx, &n1)) {
4525 if (!test_OpenDomain(p, tctx, handle, r.out.sid, which_ops)) {
4533 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
4534 struct policy_handle *handle, enum torture_samr_choice which_ops)
4537 struct samr_EnumDomains r;
4538 uint32_t resume_handle = 0;
4542 r.in.connect_handle = handle;
4543 r.in.resume_handle = &resume_handle;
4544 r.in.buf_size = (uint32_t)-1;
4545 r.out.resume_handle = &resume_handle;
4547 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4548 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4554 for (i=0;i<r.out.sam->count;i++) {
4555 if (!test_LookupDomain(p, tctx, handle,
4556 r.out.sam->entries[i].name.string, which_ops)) {
4561 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4562 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4568 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4569 struct policy_handle *handle)
4572 struct samr_Connect r;
4573 struct samr_Connect2 r2;
4574 struct samr_Connect3 r3;
4575 struct samr_Connect4 r4;
4576 struct samr_Connect5 r5;
4577 union samr_ConnectInfo info;
4578 struct policy_handle h;
4579 uint32_t level_out = 0;
4580 bool ret = true, got_handle = false;
4582 torture_comment(tctx, "testing samr_Connect\n");
4584 r.in.system_name = 0;
4585 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4586 r.out.connect_handle = &h;
4588 status = dcerpc_samr_Connect(p, tctx, &r);
4589 if (!NT_STATUS_IS_OK(status)) {
4590 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
4597 torture_comment(tctx, "testing samr_Connect2\n");
4599 r2.in.system_name = NULL;
4600 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4601 r2.out.connect_handle = &h;
4603 status = dcerpc_samr_Connect2(p, tctx, &r2);
4604 if (!NT_STATUS_IS_OK(status)) {
4605 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
4609 test_samr_handle_Close(p, tctx, handle);
4615 torture_comment(tctx, "testing samr_Connect3\n");
4617 r3.in.system_name = NULL;
4619 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4620 r3.out.connect_handle = &h;
4622 status = dcerpc_samr_Connect3(p, tctx, &r3);
4623 if (!NT_STATUS_IS_OK(status)) {
4624 printf("Connect3 failed - %s\n", nt_errstr(status));
4628 test_samr_handle_Close(p, tctx, handle);
4634 torture_comment(tctx, "testing samr_Connect4\n");
4636 r4.in.system_name = "";
4637 r4.in.client_version = 0;
4638 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4639 r4.out.connect_handle = &h;
4641 status = dcerpc_samr_Connect4(p, tctx, &r4);
4642 if (!NT_STATUS_IS_OK(status)) {
4643 printf("Connect4 failed - %s\n", nt_errstr(status));
4647 test_samr_handle_Close(p, tctx, handle);
4653 torture_comment(tctx, "testing samr_Connect5\n");
4655 info.info1.client_version = 0;
4656 info.info1.unknown2 = 0;
4658 r5.in.system_name = "";
4659 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4661 r5.out.level_out = &level_out;
4662 r5.in.info_in = &info;
4663 r5.out.info_out = &info;
4664 r5.out.connect_handle = &h;
4666 status = dcerpc_samr_Connect5(p, tctx, &r5);
4667 if (!NT_STATUS_IS_OK(status)) {
4668 printf("Connect5 failed - %s\n", nt_errstr(status));
4672 test_samr_handle_Close(p, tctx, handle);
4682 bool torture_rpc_samr(struct torture_context *torture)
4685 struct dcerpc_pipe *p;
4687 struct policy_handle handle;
4689 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4690 if (!NT_STATUS_IS_OK(status)) {
4694 ret &= test_Connect(p, torture, &handle);
4696 ret &= test_QuerySecurity(p, torture, &handle);
4698 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4700 ret &= test_SetDsrmPassword(p, torture, &handle);
4702 ret &= test_Shutdown(p, torture, &handle);
4704 ret &= test_samr_handle_Close(p, torture, &handle);
4710 bool torture_rpc_samr_users(struct torture_context *torture)
4713 struct dcerpc_pipe *p;
4715 struct policy_handle handle;
4717 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4718 if (!NT_STATUS_IS_OK(status)) {
4722 ret &= test_Connect(p, torture, &handle);
4724 ret &= test_QuerySecurity(p, torture, &handle);
4726 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4728 ret &= test_SetDsrmPassword(p, torture, &handle);
4730 ret &= test_Shutdown(p, torture, &handle);
4732 ret &= test_samr_handle_Close(p, torture, &handle);
4738 bool torture_rpc_samr_passwords(struct torture_context *torture)
4741 struct dcerpc_pipe *p;
4743 struct policy_handle handle;
4745 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4746 if (!NT_STATUS_IS_OK(status)) {
4750 ret &= test_Connect(p, torture, &handle);
4752 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4754 ret &= test_samr_handle_Close(p, torture, &handle);