2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "torture/torture.h"
24 #include "system/time.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_samr_c.h"
27 #include "../lib/crypto/crypto.h"
28 #include "libcli/auth/libcli_auth.h"
29 #include "libcli/security/security.h"
30 #include "torture/rpc/rpc.h"
32 #define TEST_ACCOUNT_NAME "samrtorturetest"
33 #define TEST_ALIASNAME "samrtorturetestalias"
34 #define TEST_GROUPNAME "samrtorturetestgroup"
35 #define TEST_MACHINENAME "samrtestmach$"
36 #define TEST_DOMAINNAME "samrtestdom$"
38 enum torture_samr_choice {
39 TORTURE_SAMR_PASSWORDS,
40 TORTURE_SAMR_USER_ATTRIBUTES,
44 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
45 struct policy_handle *handle);
47 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
48 struct policy_handle *handle);
50 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
51 struct policy_handle *handle);
53 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
54 const char *acct_name,
55 struct policy_handle *domain_handle, char **password);
57 static void init_lsa_String(struct lsa_String *string, const char *s)
62 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
64 string->length = length;
65 string->size = length;
66 string->array = (uint16_t *)discard_const(s);
69 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
70 struct policy_handle *handle)
76 r.out.handle = handle;
78 status = dcerpc_samr_Close(p, tctx, &r);
79 torture_assert_ntstatus_ok(tctx, status, "Close");
84 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
85 struct policy_handle *handle)
88 struct samr_Shutdown r;
90 if (!torture_setting_bool(tctx, "dangerous", false)) {
91 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
95 r.in.connect_handle = handle;
97 torture_comment(tctx, "testing samr_Shutdown\n");
99 status = dcerpc_samr_Shutdown(p, tctx, &r);
100 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
105 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
106 struct policy_handle *handle)
109 struct samr_SetDsrmPassword r;
110 struct lsa_String string;
111 struct samr_Password hash;
113 if (!torture_setting_bool(tctx, "dangerous", false)) {
114 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
117 E_md4hash("TeSTDSRM123", hash.hash);
119 init_lsa_String(&string, "Administrator");
125 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
127 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
128 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
134 static bool test_QuerySecurity(struct dcerpc_pipe *p,
135 struct torture_context *tctx,
136 struct policy_handle *handle)
139 struct samr_QuerySecurity r;
140 struct samr_SetSecurity s;
141 struct sec_desc_buf *sdbuf = NULL;
143 r.in.handle = handle;
145 r.out.sdbuf = &sdbuf;
147 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
148 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
150 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
152 s.in.handle = handle;
156 if (torture_setting_bool(tctx, "samba4", false)) {
157 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
160 status = dcerpc_samr_SetSecurity(p, tctx, &s);
161 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
163 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
164 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
170 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
171 struct policy_handle *handle, uint32_t base_acct_flags,
172 const char *base_account_name)
175 struct samr_SetUserInfo s;
176 struct samr_SetUserInfo2 s2;
177 struct samr_QueryUserInfo q;
178 struct samr_QueryUserInfo q0;
179 union samr_UserInfo u;
181 const char *test_account_name;
183 uint32_t user_extra_flags = 0;
184 if (base_acct_flags == ACB_NORMAL) {
185 /* When created, accounts are expired by default */
186 user_extra_flags = ACB_PW_EXPIRED;
189 s.in.user_handle = handle;
192 s2.in.user_handle = handle;
195 q.in.user_handle = handle;
199 #define TESTCALL(call, r) \
200 status = dcerpc_samr_ ##call(p, tctx, &r); \
201 if (!NT_STATUS_IS_OK(status)) { \
202 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
203 r.in.level, nt_errstr(status), __location__); \
208 #define STRING_EQUAL(s1, s2, field) \
209 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
210 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
211 #field, s2, __location__); \
216 #define MEM_EQUAL(s1, s2, length, field) \
217 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
218 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
219 #field, (const char *)s2, __location__); \
224 #define INT_EQUAL(i1, i2, field) \
226 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
227 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
232 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
233 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
235 TESTCALL(QueryUserInfo, q) \
237 s2.in.level = lvl1; \
240 ZERO_STRUCT(u.info21); \
241 u.info21.fields_present = fpval; \
243 init_lsa_String(&u.info ## lvl1.field1, value); \
244 TESTCALL(SetUserInfo, s) \
245 TESTCALL(SetUserInfo2, s2) \
246 init_lsa_String(&u.info ## lvl1.field1, ""); \
247 TESTCALL(QueryUserInfo, q); \
249 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
251 TESTCALL(QueryUserInfo, q) \
253 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
256 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
257 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
259 TESTCALL(QueryUserInfo, q) \
261 s2.in.level = lvl1; \
264 ZERO_STRUCT(u.info21); \
265 u.info21.fields_present = fpval; \
267 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
268 TESTCALL(SetUserInfo, s) \
269 TESTCALL(SetUserInfo2, s2) \
270 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
271 TESTCALL(QueryUserInfo, q); \
273 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
275 TESTCALL(QueryUserInfo, q) \
277 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
280 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
281 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
283 TESTCALL(QueryUserInfo, q) \
285 s2.in.level = lvl1; \
288 uint8_t *bits = u.info21.logon_hours.bits; \
289 ZERO_STRUCT(u.info21); \
290 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
291 u.info21.logon_hours.units_per_week = 168; \
292 u.info21.logon_hours.bits = bits; \
294 u.info21.fields_present = fpval; \
296 u.info ## lvl1.field1 = value; \
297 TESTCALL(SetUserInfo, s) \
298 TESTCALL(SetUserInfo2, s2) \
299 u.info ## lvl1.field1 = 0; \
300 TESTCALL(QueryUserInfo, q); \
302 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
304 TESTCALL(QueryUserInfo, q) \
306 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
309 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
310 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
314 do { TESTCALL(QueryUserInfo, q0) } while (0);
316 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
317 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
318 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
321 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
322 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
323 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
324 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
325 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
326 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
327 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
328 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
329 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
330 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
331 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
332 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
333 test_account_name = base_account_name;
334 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
335 SAMR_FIELD_ACCOUNT_NAME);
337 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
338 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
339 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
340 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
341 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
342 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
343 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
344 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
345 SAMR_FIELD_FULL_NAME);
347 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
348 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
349 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
350 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
351 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
352 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
353 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
354 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
355 SAMR_FIELD_FULL_NAME);
357 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
358 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
359 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
360 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
361 SAMR_FIELD_LOGON_SCRIPT);
363 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
364 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
365 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
366 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
367 SAMR_FIELD_PROFILE_PATH);
369 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
370 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
371 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
372 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
373 SAMR_FIELD_HOME_DIRECTORY);
374 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
375 SAMR_FIELD_HOME_DIRECTORY);
377 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
378 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
379 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
380 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
381 SAMR_FIELD_HOME_DRIVE);
382 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
383 SAMR_FIELD_HOME_DRIVE);
385 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
386 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
387 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
388 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
389 SAMR_FIELD_DESCRIPTION);
391 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
392 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
393 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
394 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
395 SAMR_FIELD_WORKSTATIONS);
396 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
397 SAMR_FIELD_WORKSTATIONS);
398 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
399 SAMR_FIELD_WORKSTATIONS);
400 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
401 SAMR_FIELD_WORKSTATIONS);
403 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
404 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
405 SAMR_FIELD_PARAMETERS);
406 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
407 SAMR_FIELD_PARAMETERS);
409 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
410 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
411 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
412 SAMR_FIELD_COUNTRY_CODE);
413 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
414 SAMR_FIELD_COUNTRY_CODE);
416 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
417 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
418 SAMR_FIELD_CODE_PAGE);
419 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
420 SAMR_FIELD_CODE_PAGE);
422 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
423 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
424 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
425 SAMR_FIELD_ACCT_EXPIRY);
426 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
427 SAMR_FIELD_ACCT_EXPIRY);
428 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
429 SAMR_FIELD_ACCT_EXPIRY);
431 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
432 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
433 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
434 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
435 SAMR_FIELD_LOGON_HOURS);
437 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
438 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
439 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
441 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
442 (base_acct_flags | ACB_DISABLED),
443 (base_acct_flags | ACB_DISABLED | user_extra_flags),
446 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
447 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
448 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
449 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
451 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
452 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
453 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
457 /* The 'autolock' flag doesn't stick - check this */
458 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
459 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
460 (base_acct_flags | ACB_DISABLED | user_extra_flags),
463 /* Removing the 'disabled' flag doesn't stick - check this */
464 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
466 (base_acct_flags | ACB_DISABLED | user_extra_flags),
469 /* The 'store plaintext' flag does stick */
470 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
471 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
472 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
474 /* The 'use DES' flag does stick */
475 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
476 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
477 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
479 /* The 'don't require kerberos pre-authentication flag does stick */
480 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
481 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
482 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
484 /* The 'no kerberos PAC required' flag sticks */
485 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
486 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
487 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
490 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
491 (base_acct_flags | ACB_DISABLED),
492 (base_acct_flags | ACB_DISABLED | user_extra_flags),
493 SAMR_FIELD_ACCT_FLAGS);
496 /* these fail with win2003 - it appears you can't set the primary gid?
497 the set succeeds, but the gid isn't changed. Very weird! */
498 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
499 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
500 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
501 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
508 generate a random password for password change tests
510 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
512 size_t len = MAX(8, min_len) + (random() % 6);
513 char *s = generate_random_str(mem_ctx, len);
514 printf("Generated password '%s'\n", s);
519 generate a random password for password change tests
521 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
524 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
525 generate_random_buffer(password.data, password.length);
527 for (i=0; i < len; i++) {
528 if (((uint16_t *)password.data)[i] == 0) {
529 ((uint16_t *)password.data)[i] = 1;
537 generate a random password for password change tests (fixed length)
539 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
541 char *s = generate_random_str(mem_ctx, len);
542 printf("Generated password '%s'\n", s);
546 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
547 struct policy_handle *handle, char **password)
550 struct samr_SetUserInfo s;
551 union samr_UserInfo u;
553 DATA_BLOB session_key;
555 struct samr_GetUserPwInfo pwp;
556 struct samr_PwInfo info;
557 int policy_min_pw_len = 0;
558 pwp.in.user_handle = handle;
559 pwp.out.info = &info;
561 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
562 if (NT_STATUS_IS_OK(status)) {
563 policy_min_pw_len = pwp.out.info->min_password_length;
565 newpass = samr_rand_pass(tctx, policy_min_pw_len);
567 s.in.user_handle = handle;
571 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
572 /* w2k3 ignores this length */
573 u.info24.pw_len = strlen_m(newpass) * 2;
575 status = dcerpc_fetch_session_key(p, &session_key);
576 if (!NT_STATUS_IS_OK(status)) {
577 printf("SetUserInfo level %u - no session key - %s\n",
578 s.in.level, nt_errstr(status));
582 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
584 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
586 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
587 if (!NT_STATUS_IS_OK(status)) {
588 printf("SetUserInfo level %u failed - %s\n",
589 s.in.level, nt_errstr(status));
599 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
600 struct policy_handle *handle, uint32_t fields_present,
604 struct samr_SetUserInfo s;
605 union samr_UserInfo u;
607 DATA_BLOB session_key;
609 struct samr_GetUserPwInfo pwp;
610 struct samr_PwInfo info;
611 int policy_min_pw_len = 0;
612 pwp.in.user_handle = handle;
613 pwp.out.info = &info;
615 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
616 if (NT_STATUS_IS_OK(status)) {
617 policy_min_pw_len = pwp.out.info->min_password_length;
619 newpass = samr_rand_pass(tctx, policy_min_pw_len);
621 s.in.user_handle = handle;
627 u.info23.info.fields_present = fields_present;
629 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
631 status = dcerpc_fetch_session_key(p, &session_key);
632 if (!NT_STATUS_IS_OK(status)) {
633 printf("SetUserInfo level %u - no session key - %s\n",
634 s.in.level, nt_errstr(status));
638 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
640 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
642 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
643 if (!NT_STATUS_IS_OK(status)) {
644 printf("SetUserInfo level %u failed - %s\n",
645 s.in.level, nt_errstr(status));
651 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
653 status = dcerpc_fetch_session_key(p, &session_key);
654 if (!NT_STATUS_IS_OK(status)) {
655 printf("SetUserInfo level %u - no session key - %s\n",
656 s.in.level, nt_errstr(status));
660 /* This should break the key nicely */
661 session_key.length--;
662 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
664 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
666 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
667 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
668 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
669 s.in.level, nt_errstr(status));
677 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
678 struct policy_handle *handle, bool makeshort,
682 struct samr_SetUserInfo s;
683 union samr_UserInfo u;
685 DATA_BLOB session_key;
686 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
687 uint8_t confounder[16];
689 struct MD5Context ctx;
690 struct samr_GetUserPwInfo pwp;
691 struct samr_PwInfo info;
692 int policy_min_pw_len = 0;
693 pwp.in.user_handle = handle;
694 pwp.out.info = &info;
696 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
697 if (NT_STATUS_IS_OK(status)) {
698 policy_min_pw_len = pwp.out.info->min_password_length;
700 if (makeshort && policy_min_pw_len) {
701 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
703 newpass = samr_rand_pass(tctx, policy_min_pw_len);
706 s.in.user_handle = handle;
710 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
711 u.info26.pw_len = strlen(newpass);
713 status = dcerpc_fetch_session_key(p, &session_key);
714 if (!NT_STATUS_IS_OK(status)) {
715 printf("SetUserInfo level %u - no session key - %s\n",
716 s.in.level, nt_errstr(status));
720 generate_random_buffer((uint8_t *)confounder, 16);
723 MD5Update(&ctx, confounder, 16);
724 MD5Update(&ctx, session_key.data, session_key.length);
725 MD5Final(confounded_session_key.data, &ctx);
727 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
728 memcpy(&u.info26.password.data[516], confounder, 16);
730 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
732 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
733 if (!NT_STATUS_IS_OK(status)) {
734 printf("SetUserInfo level %u failed - %s\n",
735 s.in.level, nt_errstr(status));
741 /* This should break the key nicely */
742 confounded_session_key.data[0]++;
744 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
745 memcpy(&u.info26.password.data[516], confounder, 16);
747 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
749 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
750 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
751 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
752 s.in.level, nt_errstr(status));
761 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
762 struct policy_handle *handle, uint32_t fields_present,
766 struct samr_SetUserInfo s;
767 union samr_UserInfo u;
769 DATA_BLOB session_key;
770 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
771 struct MD5Context ctx;
772 uint8_t confounder[16];
774 struct samr_GetUserPwInfo pwp;
775 struct samr_PwInfo info;
776 int policy_min_pw_len = 0;
777 pwp.in.user_handle = handle;
778 pwp.out.info = &info;
780 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
781 if (NT_STATUS_IS_OK(status)) {
782 policy_min_pw_len = pwp.out.info->min_password_length;
784 newpass = samr_rand_pass(tctx, policy_min_pw_len);
786 s.in.user_handle = handle;
792 u.info25.info.fields_present = fields_present;
794 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
796 status = dcerpc_fetch_session_key(p, &session_key);
797 if (!NT_STATUS_IS_OK(status)) {
798 printf("SetUserInfo level %u - no session key - %s\n",
799 s.in.level, nt_errstr(status));
803 generate_random_buffer((uint8_t *)confounder, 16);
806 MD5Update(&ctx, confounder, 16);
807 MD5Update(&ctx, session_key.data, session_key.length);
808 MD5Final(confounded_session_key.data, &ctx);
810 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
811 memcpy(&u.info25.password.data[516], confounder, 16);
813 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
815 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
816 if (!NT_STATUS_IS_OK(status)) {
817 printf("SetUserInfo level %u failed - %s\n",
818 s.in.level, nt_errstr(status));
824 /* This should break the key nicely */
825 confounded_session_key.data[0]++;
827 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
828 memcpy(&u.info25.password.data[516], confounder, 16);
830 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
832 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
833 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
834 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
835 s.in.level, nt_errstr(status));
842 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
843 struct policy_handle *handle)
846 struct samr_SetAliasInfo r;
847 struct samr_QueryAliasInfo q;
848 uint16_t levels[] = {2, 3};
852 /* Ignoring switch level 1, as that includes the number of members for the alias
853 * and setting this to a wrong value might have negative consequences
856 for (i=0;i<ARRAY_SIZE(levels);i++) {
857 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
859 r.in.alias_handle = handle;
860 r.in.level = levels[i];
861 r.in.info = talloc(tctx, union samr_AliasInfo);
862 switch (r.in.level) {
863 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
864 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
865 "Test Description, should test I18N as well"); break;
866 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
869 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
870 if (!NT_STATUS_IS_OK(status)) {
871 printf("SetAliasInfo level %u failed - %s\n",
872 levels[i], nt_errstr(status));
876 q.in.alias_handle = handle;
877 q.in.level = levels[i];
879 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
880 if (!NT_STATUS_IS_OK(status)) {
881 printf("QueryAliasInfo level %u failed - %s\n",
882 levels[i], nt_errstr(status));
890 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
891 struct policy_handle *user_handle)
893 struct samr_GetGroupsForUser r;
894 struct samr_RidWithAttributeArray *rids = NULL;
897 torture_comment(tctx, "testing GetGroupsForUser\n");
899 r.in.user_handle = user_handle;
902 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
903 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
909 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
910 struct lsa_String *domain_name)
913 struct samr_GetDomPwInfo r;
914 struct samr_PwInfo info;
916 r.in.domain_name = domain_name;
919 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
921 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
922 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
924 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
925 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
927 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
928 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
930 r.in.domain_name->string = "\\\\__NONAME__";
931 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
933 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
934 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
936 r.in.domain_name->string = "\\\\Builtin";
937 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
939 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
940 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
945 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
946 struct policy_handle *handle)
949 struct samr_GetUserPwInfo r;
950 struct samr_PwInfo info;
952 torture_comment(tctx, "Testing GetUserPwInfo\n");
954 r.in.user_handle = handle;
957 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
958 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
963 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
964 struct policy_handle *domain_handle, const char *name,
968 struct samr_LookupNames n;
969 struct lsa_String sname[2];
970 struct samr_Ids rids, types;
972 init_lsa_String(&sname[0], name);
974 n.in.domain_handle = domain_handle;
978 n.out.types = &types;
979 status = dcerpc_samr_LookupNames(p, tctx, &n);
980 if (NT_STATUS_IS_OK(status)) {
981 *rid = n.out.rids->ids[0];
986 init_lsa_String(&sname[1], "xxNONAMExx");
988 status = dcerpc_samr_LookupNames(p, tctx, &n);
989 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
990 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
991 if (NT_STATUS_IS_OK(status)) {
992 return NT_STATUS_UNSUCCESSFUL;
998 status = dcerpc_samr_LookupNames(p, tctx, &n);
999 if (!NT_STATUS_IS_OK(status)) {
1000 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1004 init_lsa_String(&sname[0], "xxNONAMExx");
1006 status = dcerpc_samr_LookupNames(p, tctx, &n);
1007 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1008 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1009 if (NT_STATUS_IS_OK(status)) {
1010 return NT_STATUS_UNSUCCESSFUL;
1015 init_lsa_String(&sname[0], "xxNONAMExx");
1016 init_lsa_String(&sname[1], "xxNONAME2xx");
1018 status = dcerpc_samr_LookupNames(p, tctx, &n);
1019 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1020 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1021 if (NT_STATUS_IS_OK(status)) {
1022 return NT_STATUS_UNSUCCESSFUL;
1027 return NT_STATUS_OK;
1030 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1031 struct policy_handle *domain_handle,
1032 const char *name, struct policy_handle *user_handle)
1035 struct samr_OpenUser r;
1038 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1039 if (!NT_STATUS_IS_OK(status)) {
1043 r.in.domain_handle = domain_handle;
1044 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1046 r.out.user_handle = user_handle;
1047 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1048 if (!NT_STATUS_IS_OK(status)) {
1049 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1056 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1057 struct policy_handle *handle)
1060 struct samr_ChangePasswordUser r;
1062 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1063 struct policy_handle user_handle;
1064 char *oldpass = "test";
1065 char *newpass = "test2";
1066 uint8_t old_nt_hash[16], new_nt_hash[16];
1067 uint8_t old_lm_hash[16], new_lm_hash[16];
1069 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1070 if (!NT_STATUS_IS_OK(status)) {
1074 printf("Testing ChangePasswordUser for user 'testuser'\n");
1076 printf("old password: %s\n", oldpass);
1077 printf("new password: %s\n", newpass);
1079 E_md4hash(oldpass, old_nt_hash);
1080 E_md4hash(newpass, new_nt_hash);
1081 E_deshash(oldpass, old_lm_hash);
1082 E_deshash(newpass, new_lm_hash);
1084 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1085 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1086 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1087 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1088 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1089 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1091 r.in.handle = &user_handle;
1092 r.in.lm_present = 1;
1093 r.in.old_lm_crypted = &hash1;
1094 r.in.new_lm_crypted = &hash2;
1095 r.in.nt_present = 1;
1096 r.in.old_nt_crypted = &hash3;
1097 r.in.new_nt_crypted = &hash4;
1098 r.in.cross1_present = 1;
1099 r.in.nt_cross = &hash5;
1100 r.in.cross2_present = 1;
1101 r.in.lm_cross = &hash6;
1103 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1104 if (!NT_STATUS_IS_OK(status)) {
1105 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1109 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1117 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1118 const char *acct_name,
1119 struct policy_handle *handle, char **password)
1122 struct samr_ChangePasswordUser r;
1124 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1125 struct policy_handle user_handle;
1127 uint8_t old_nt_hash[16], new_nt_hash[16];
1128 uint8_t old_lm_hash[16], new_lm_hash[16];
1129 bool changed = true;
1132 struct samr_GetUserPwInfo pwp;
1133 struct samr_PwInfo info;
1134 int policy_min_pw_len = 0;
1136 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1137 if (!NT_STATUS_IS_OK(status)) {
1140 pwp.in.user_handle = &user_handle;
1141 pwp.out.info = &info;
1143 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1144 if (NT_STATUS_IS_OK(status)) {
1145 policy_min_pw_len = pwp.out.info->min_password_length;
1147 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1149 torture_comment(tctx, "Testing ChangePasswordUser\n");
1151 torture_assert(tctx, *password != NULL,
1152 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1154 oldpass = *password;
1156 E_md4hash(oldpass, old_nt_hash);
1157 E_md4hash(newpass, new_nt_hash);
1158 E_deshash(oldpass, old_lm_hash);
1159 E_deshash(newpass, new_lm_hash);
1161 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1162 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1163 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1164 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1165 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1166 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1168 r.in.user_handle = &user_handle;
1169 r.in.lm_present = 1;
1170 /* Break the LM hash */
1172 r.in.old_lm_crypted = &hash1;
1173 r.in.new_lm_crypted = &hash2;
1174 r.in.nt_present = 1;
1175 r.in.old_nt_crypted = &hash3;
1176 r.in.new_nt_crypted = &hash4;
1177 r.in.cross1_present = 1;
1178 r.in.nt_cross = &hash5;
1179 r.in.cross2_present = 1;
1180 r.in.lm_cross = &hash6;
1182 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1183 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1184 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1186 /* Unbreak the LM hash */
1189 r.in.user_handle = &user_handle;
1190 r.in.lm_present = 1;
1191 r.in.old_lm_crypted = &hash1;
1192 r.in.new_lm_crypted = &hash2;
1193 /* Break the NT hash */
1195 r.in.nt_present = 1;
1196 r.in.old_nt_crypted = &hash3;
1197 r.in.new_nt_crypted = &hash4;
1198 r.in.cross1_present = 1;
1199 r.in.nt_cross = &hash5;
1200 r.in.cross2_present = 1;
1201 r.in.lm_cross = &hash6;
1203 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1204 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1205 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1207 /* Unbreak the NT hash */
1210 r.in.user_handle = &user_handle;
1211 r.in.lm_present = 1;
1212 r.in.old_lm_crypted = &hash1;
1213 r.in.new_lm_crypted = &hash2;
1214 r.in.nt_present = 1;
1215 r.in.old_nt_crypted = &hash3;
1216 r.in.new_nt_crypted = &hash4;
1217 r.in.cross1_present = 1;
1218 r.in.nt_cross = &hash5;
1219 r.in.cross2_present = 1;
1220 /* Break the LM cross */
1222 r.in.lm_cross = &hash6;
1224 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1225 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1226 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1230 /* Unbreak the LM cross */
1233 r.in.user_handle = &user_handle;
1234 r.in.lm_present = 1;
1235 r.in.old_lm_crypted = &hash1;
1236 r.in.new_lm_crypted = &hash2;
1237 r.in.nt_present = 1;
1238 r.in.old_nt_crypted = &hash3;
1239 r.in.new_nt_crypted = &hash4;
1240 r.in.cross1_present = 1;
1241 /* Break the NT cross */
1243 r.in.nt_cross = &hash5;
1244 r.in.cross2_present = 1;
1245 r.in.lm_cross = &hash6;
1247 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1248 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1249 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1253 /* Unbreak the NT cross */
1257 /* Reset the hashes to not broken values */
1258 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1259 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1260 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1261 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1262 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1263 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1265 r.in.user_handle = &user_handle;
1266 r.in.lm_present = 1;
1267 r.in.old_lm_crypted = &hash1;
1268 r.in.new_lm_crypted = &hash2;
1269 r.in.nt_present = 1;
1270 r.in.old_nt_crypted = &hash3;
1271 r.in.new_nt_crypted = &hash4;
1272 r.in.cross1_present = 1;
1273 r.in.nt_cross = &hash5;
1274 r.in.cross2_present = 0;
1275 r.in.lm_cross = NULL;
1277 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1278 if (NT_STATUS_IS_OK(status)) {
1280 *password = newpass;
1281 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1282 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1287 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1289 E_md4hash(oldpass, old_nt_hash);
1290 E_md4hash(newpass, new_nt_hash);
1291 E_deshash(oldpass, old_lm_hash);
1292 E_deshash(newpass, new_lm_hash);
1295 /* Reset the hashes to not broken values */
1296 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1297 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1298 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1299 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1300 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1301 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1303 r.in.user_handle = &user_handle;
1304 r.in.lm_present = 1;
1305 r.in.old_lm_crypted = &hash1;
1306 r.in.new_lm_crypted = &hash2;
1307 r.in.nt_present = 1;
1308 r.in.old_nt_crypted = &hash3;
1309 r.in.new_nt_crypted = &hash4;
1310 r.in.cross1_present = 0;
1311 r.in.nt_cross = NULL;
1312 r.in.cross2_present = 1;
1313 r.in.lm_cross = &hash6;
1315 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1316 if (NT_STATUS_IS_OK(status)) {
1318 *password = newpass;
1319 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1320 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1325 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1327 E_md4hash(oldpass, old_nt_hash);
1328 E_md4hash(newpass, new_nt_hash);
1329 E_deshash(oldpass, old_lm_hash);
1330 E_deshash(newpass, new_lm_hash);
1333 /* Reset the hashes to not broken values */
1334 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1335 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1336 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1337 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1338 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1339 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1341 r.in.user_handle = &user_handle;
1342 r.in.lm_present = 1;
1343 r.in.old_lm_crypted = &hash1;
1344 r.in.new_lm_crypted = &hash2;
1345 r.in.nt_present = 1;
1346 r.in.old_nt_crypted = &hash3;
1347 r.in.new_nt_crypted = &hash4;
1348 r.in.cross1_present = 1;
1349 r.in.nt_cross = &hash5;
1350 r.in.cross2_present = 1;
1351 r.in.lm_cross = &hash6;
1353 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1354 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1355 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1356 } else if (!NT_STATUS_IS_OK(status)) {
1357 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1361 *password = newpass;
1364 r.in.user_handle = &user_handle;
1365 r.in.lm_present = 1;
1366 r.in.old_lm_crypted = &hash1;
1367 r.in.new_lm_crypted = &hash2;
1368 r.in.nt_present = 1;
1369 r.in.old_nt_crypted = &hash3;
1370 r.in.new_nt_crypted = &hash4;
1371 r.in.cross1_present = 1;
1372 r.in.nt_cross = &hash5;
1373 r.in.cross2_present = 1;
1374 r.in.lm_cross = &hash6;
1377 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1378 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1379 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1380 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1381 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1387 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1395 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1396 const char *acct_name,
1397 struct policy_handle *handle, char **password)
1400 struct samr_OemChangePasswordUser2 r;
1402 struct samr_Password lm_verifier;
1403 struct samr_CryptPassword lm_pass;
1404 struct lsa_AsciiString server, account, account_bad;
1407 uint8_t old_lm_hash[16], new_lm_hash[16];
1409 struct samr_GetDomPwInfo dom_pw_info;
1410 struct samr_PwInfo info;
1411 int policy_min_pw_len = 0;
1413 struct lsa_String domain_name;
1415 domain_name.string = "";
1416 dom_pw_info.in.domain_name = &domain_name;
1417 dom_pw_info.out.info = &info;
1419 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1421 torture_assert(tctx, *password != NULL,
1422 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1424 oldpass = *password;
1426 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1427 if (NT_STATUS_IS_OK(status)) {
1428 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1431 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1433 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1434 account.string = acct_name;
1436 E_deshash(oldpass, old_lm_hash);
1437 E_deshash(newpass, new_lm_hash);
1439 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1440 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1441 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1443 r.in.server = &server;
1444 r.in.account = &account;
1445 r.in.password = &lm_pass;
1446 r.in.hash = &lm_verifier;
1448 /* Break the verification */
1449 lm_verifier.hash[0]++;
1451 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1453 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1454 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1455 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1460 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1461 /* Break the old password */
1463 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1464 /* unbreak it for the next operation */
1466 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1468 r.in.server = &server;
1469 r.in.account = &account;
1470 r.in.password = &lm_pass;
1471 r.in.hash = &lm_verifier;
1473 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1475 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1476 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1477 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1482 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1483 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1485 r.in.server = &server;
1486 r.in.account = &account;
1487 r.in.password = &lm_pass;
1490 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1492 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1493 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1494 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1499 /* This shouldn't be a valid name */
1500 account_bad.string = TEST_ACCOUNT_NAME "XX";
1501 r.in.account = &account_bad;
1503 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1505 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1506 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1511 /* This shouldn't be a valid name */
1512 account_bad.string = TEST_ACCOUNT_NAME "XX";
1513 r.in.account = &account_bad;
1514 r.in.password = &lm_pass;
1515 r.in.hash = &lm_verifier;
1517 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1519 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1520 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1525 /* This shouldn't be a valid name */
1526 account_bad.string = TEST_ACCOUNT_NAME "XX";
1527 r.in.account = &account_bad;
1528 r.in.password = NULL;
1529 r.in.hash = &lm_verifier;
1531 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1533 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1534 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1539 E_deshash(oldpass, old_lm_hash);
1540 E_deshash(newpass, new_lm_hash);
1542 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1543 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1544 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1546 r.in.server = &server;
1547 r.in.account = &account;
1548 r.in.password = &lm_pass;
1549 r.in.hash = &lm_verifier;
1551 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1552 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1553 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1554 } else if (!NT_STATUS_IS_OK(status)) {
1555 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1558 *password = newpass;
1565 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1566 const char *acct_name,
1568 char *newpass, bool allow_password_restriction)
1571 struct samr_ChangePasswordUser2 r;
1573 struct lsa_String server, account;
1574 struct samr_CryptPassword nt_pass, lm_pass;
1575 struct samr_Password nt_verifier, lm_verifier;
1577 uint8_t old_nt_hash[16], new_nt_hash[16];
1578 uint8_t old_lm_hash[16], new_lm_hash[16];
1580 struct samr_GetDomPwInfo dom_pw_info;
1581 struct samr_PwInfo info;
1583 struct lsa_String domain_name;
1585 domain_name.string = "";
1586 dom_pw_info.in.domain_name = &domain_name;
1587 dom_pw_info.out.info = &info;
1589 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
1591 torture_assert(tctx, *password != NULL,
1592 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
1593 oldpass = *password;
1596 int policy_min_pw_len = 0;
1597 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1598 if (NT_STATUS_IS_OK(status)) {
1599 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1602 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1605 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1606 init_lsa_String(&account, acct_name);
1608 E_md4hash(oldpass, old_nt_hash);
1609 E_md4hash(newpass, new_nt_hash);
1611 E_deshash(oldpass, old_lm_hash);
1612 E_deshash(newpass, new_lm_hash);
1614 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1615 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1616 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1618 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1619 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1620 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1622 r.in.server = &server;
1623 r.in.account = &account;
1624 r.in.nt_password = &nt_pass;
1625 r.in.nt_verifier = &nt_verifier;
1627 r.in.lm_password = &lm_pass;
1628 r.in.lm_verifier = &lm_verifier;
1630 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
1631 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1632 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1633 } else if (!NT_STATUS_IS_OK(status)) {
1634 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1637 *password = newpass;
1644 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
1645 const char *account_string,
1646 int policy_min_pw_len,
1648 const char *newpass,
1649 NTTIME last_password_change,
1650 bool handle_reject_reason)
1653 struct samr_ChangePasswordUser3 r;
1655 struct lsa_String server, account, account_bad;
1656 struct samr_CryptPassword nt_pass, lm_pass;
1657 struct samr_Password nt_verifier, lm_verifier;
1659 uint8_t old_nt_hash[16], new_nt_hash[16];
1660 uint8_t old_lm_hash[16], new_lm_hash[16];
1662 struct samr_DomInfo1 *dominfo = NULL;
1663 struct samr_ChangeReject *reject = NULL;
1665 torture_comment(tctx, "Testing ChangePasswordUser3\n");
1667 if (newpass == NULL) {
1669 if (policy_min_pw_len == 0) {
1670 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1672 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
1674 } while (check_password_quality(newpass) == false);
1676 torture_comment(tctx, "Using password '%s'\n", newpass);
1679 torture_assert(tctx, *password != NULL,
1680 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1682 oldpass = *password;
1683 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1684 init_lsa_String(&account, account_string);
1686 E_md4hash(oldpass, old_nt_hash);
1687 E_md4hash(newpass, new_nt_hash);
1689 E_deshash(oldpass, old_lm_hash);
1690 E_deshash(newpass, new_lm_hash);
1692 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1693 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1694 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1696 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1697 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1698 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1700 /* Break the verification */
1701 nt_verifier.hash[0]++;
1703 r.in.server = &server;
1704 r.in.account = &account;
1705 r.in.nt_password = &nt_pass;
1706 r.in.nt_verifier = &nt_verifier;
1708 r.in.lm_password = &lm_pass;
1709 r.in.lm_verifier = &lm_verifier;
1710 r.in.password3 = NULL;
1711 r.out.dominfo = &dominfo;
1712 r.out.reject = &reject;
1714 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1715 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1716 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1717 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1722 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1723 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1724 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1726 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1727 /* Break the NT hash */
1729 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1730 /* Unbreak it again */
1732 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1734 r.in.server = &server;
1735 r.in.account = &account;
1736 r.in.nt_password = &nt_pass;
1737 r.in.nt_verifier = &nt_verifier;
1739 r.in.lm_password = &lm_pass;
1740 r.in.lm_verifier = &lm_verifier;
1741 r.in.password3 = NULL;
1742 r.out.dominfo = &dominfo;
1743 r.out.reject = &reject;
1745 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1746 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1747 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1748 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1753 /* This shouldn't be a valid name */
1754 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
1756 r.in.account = &account_bad;
1757 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1758 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1759 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1764 E_md4hash(oldpass, old_nt_hash);
1765 E_md4hash(newpass, new_nt_hash);
1767 E_deshash(oldpass, old_lm_hash);
1768 E_deshash(newpass, new_lm_hash);
1770 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1771 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1772 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1774 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1775 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1776 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1778 r.in.server = &server;
1779 r.in.account = &account;
1780 r.in.nt_password = &nt_pass;
1781 r.in.nt_verifier = &nt_verifier;
1783 r.in.lm_password = &lm_pass;
1784 r.in.lm_verifier = &lm_verifier;
1785 r.in.password3 = NULL;
1786 r.out.dominfo = &dominfo;
1787 r.out.reject = &reject;
1789 unix_to_nt_time(&t, time(NULL));
1791 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1793 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1796 && handle_reject_reason
1797 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
1798 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1800 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
1801 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1802 SAMR_REJECT_OTHER, reject->reason);
1807 /* We tested the order of precendence which is as follows:
1816 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1817 (last_password_change + dominfo->min_password_age > t)) {
1819 if (reject->reason != SAMR_REJECT_OTHER) {
1820 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1821 SAMR_REJECT_OTHER, reject->reason);
1825 } else if ((dominfo->min_password_length > 0) &&
1826 (strlen(newpass) < dominfo->min_password_length)) {
1828 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
1829 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1830 SAMR_REJECT_TOO_SHORT, reject->reason);
1834 } else if ((dominfo->password_history_length > 0) &&
1835 strequal(oldpass, newpass)) {
1837 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
1838 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1839 SAMR_REJECT_IN_HISTORY, reject->reason);
1842 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1844 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
1845 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1846 SAMR_REJECT_COMPLEXITY, reject->reason);
1852 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
1853 /* retry with adjusted size */
1854 return test_ChangePasswordUser3(p, tctx, account_string,
1855 dominfo->min_password_length,
1856 password, NULL, 0, false);
1860 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1861 if (reject && reject->reason != SAMR_REJECT_OTHER) {
1862 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1863 SAMR_REJECT_OTHER, reject->reason);
1866 /* Perhaps the server has a 'min password age' set? */
1869 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
1870 *password = talloc_strdup(tctx, newpass);
1876 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
1877 const char *account_string,
1878 struct policy_handle *handle,
1882 struct samr_ChangePasswordUser3 r;
1883 struct samr_SetUserInfo s;
1884 union samr_UserInfo u;
1885 DATA_BLOB session_key;
1886 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1887 uint8_t confounder[16];
1888 struct MD5Context ctx;
1891 struct lsa_String server, account;
1892 struct samr_CryptPassword nt_pass;
1893 struct samr_Password nt_verifier;
1894 DATA_BLOB new_random_pass;
1897 uint8_t old_nt_hash[16], new_nt_hash[16];
1899 struct samr_DomInfo1 *dominfo = NULL;
1900 struct samr_ChangeReject *reject = NULL;
1902 new_random_pass = samr_very_rand_pass(tctx, 128);
1904 torture_assert(tctx, *password != NULL,
1905 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
1907 oldpass = *password;
1908 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1909 init_lsa_String(&account, account_string);
1911 s.in.user_handle = handle;
1917 u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
1919 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
1921 status = dcerpc_fetch_session_key(p, &session_key);
1922 if (!NT_STATUS_IS_OK(status)) {
1923 printf("SetUserInfo level %u - no session key - %s\n",
1924 s.in.level, nt_errstr(status));
1928 generate_random_buffer((uint8_t *)confounder, 16);
1931 MD5Update(&ctx, confounder, 16);
1932 MD5Update(&ctx, session_key.data, session_key.length);
1933 MD5Final(confounded_session_key.data, &ctx);
1935 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1936 memcpy(&u.info25.password.data[516], confounder, 16);
1938 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
1940 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1941 if (!NT_STATUS_IS_OK(status)) {
1942 printf("SetUserInfo level %u failed - %s\n",
1943 s.in.level, nt_errstr(status));
1947 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
1949 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1951 new_random_pass = samr_very_rand_pass(tctx, 128);
1953 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
1955 set_pw_in_buffer(nt_pass.data, &new_random_pass);
1956 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1957 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1959 r.in.server = &server;
1960 r.in.account = &account;
1961 r.in.nt_password = &nt_pass;
1962 r.in.nt_verifier = &nt_verifier;
1964 r.in.lm_password = NULL;
1965 r.in.lm_verifier = NULL;
1966 r.in.password3 = NULL;
1967 r.out.dominfo = &dominfo;
1968 r.out.reject = &reject;
1970 unix_to_nt_time(&t, time(NULL));
1972 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
1974 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1975 if (reject && reject->reason != SAMR_REJECT_OTHER) {
1976 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1977 SAMR_REJECT_OTHER, reject->reason);
1980 /* Perhaps the server has a 'min password age' set? */
1982 } else if (!NT_STATUS_IS_OK(status)) {
1983 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1987 newpass = samr_rand_pass(tctx, 128);
1989 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1991 E_md4hash(newpass, new_nt_hash);
1993 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1994 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1995 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1997 r.in.server = &server;
1998 r.in.account = &account;
1999 r.in.nt_password = &nt_pass;
2000 r.in.nt_verifier = &nt_verifier;
2002 r.in.lm_password = NULL;
2003 r.in.lm_verifier = NULL;
2004 r.in.password3 = NULL;
2005 r.out.dominfo = &dominfo;
2006 r.out.reject = &reject;
2008 unix_to_nt_time(&t, time(NULL));
2010 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2012 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2013 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2014 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2015 SAMR_REJECT_OTHER, reject->reason);
2018 /* Perhaps the server has a 'min password age' set? */
2021 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2022 *password = talloc_strdup(tctx, newpass);
2029 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2030 struct policy_handle *alias_handle)
2032 struct samr_GetMembersInAlias r;
2033 struct lsa_SidArray sids;
2036 torture_comment(tctx, "Testing GetMembersInAlias\n");
2038 r.in.alias_handle = alias_handle;
2041 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2042 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2047 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2048 struct policy_handle *alias_handle,
2049 const struct dom_sid *domain_sid)
2051 struct samr_AddAliasMember r;
2052 struct samr_DeleteAliasMember d;
2054 struct dom_sid *sid;
2056 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2058 torture_comment(tctx, "testing AddAliasMember\n");
2059 r.in.alias_handle = alias_handle;
2062 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2063 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2065 d.in.alias_handle = alias_handle;
2068 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2069 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2074 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2075 struct policy_handle *alias_handle)
2077 struct samr_AddMultipleMembersToAlias a;
2078 struct samr_RemoveMultipleMembersFromAlias r;
2080 struct lsa_SidArray sids;
2082 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2083 a.in.alias_handle = alias_handle;
2087 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2089 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2090 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2091 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2093 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2094 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2097 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2098 r.in.alias_handle = alias_handle;
2101 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2102 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2104 /* strange! removing twice doesn't give any error */
2105 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2106 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2108 /* but removing an alias that isn't there does */
2109 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2111 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2112 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2117 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2118 struct policy_handle *user_handle)
2120 struct samr_TestPrivateFunctionsUser r;
2123 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2125 r.in.user_handle = user_handle;
2127 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2128 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2134 static bool test_user_ops(struct dcerpc_pipe *p,
2135 struct torture_context *tctx,
2136 struct policy_handle *user_handle,
2137 struct policy_handle *domain_handle,
2138 uint32_t base_acct_flags,
2139 const char *base_acct_name, enum torture_samr_choice which_ops)
2141 char *password = NULL;
2142 struct samr_QueryUserInfo q;
2148 const uint32_t password_fields[] = {
2149 SAMR_FIELD_PASSWORD,
2150 SAMR_FIELD_PASSWORD2,
2151 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2155 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2156 if (!NT_STATUS_IS_OK(status)) {
2160 switch (which_ops) {
2161 case TORTURE_SAMR_USER_ATTRIBUTES:
2162 if (!test_QuerySecurity(p, tctx, user_handle)) {
2166 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2170 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2174 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2179 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2183 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2187 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2191 case TORTURE_SAMR_PASSWORDS:
2192 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2193 char simple_pass[9];
2194 char *v = generate_random_str(tctx, 1);
2196 ZERO_STRUCT(simple_pass);
2197 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2199 printf("Testing machine account password policy rules\n");
2201 /* Workstation trust accounts don't seem to need to honour password quality policy */
2202 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2206 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2210 /* reset again, to allow another 'user' password change */
2211 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2215 /* Try a 'short' password */
2216 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2220 /* Try a compleatly random password */
2221 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
2226 for (i = 0; password_fields[i]; i++) {
2227 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2231 /* check it was set right */
2232 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2237 for (i = 0; password_fields[i]; i++) {
2238 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2242 /* check it was set right */
2243 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2248 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2252 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2256 q.in.user_handle = user_handle;
2259 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2260 if (!NT_STATUS_IS_OK(status)) {
2261 printf("QueryUserInfo level %u failed - %s\n",
2262 q.in.level, nt_errstr(status));
2265 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2266 if ((q.out.info->info5.acct_flags) != expected_flags) {
2267 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2268 q.out.info->info5.acct_flags,
2272 if (q.out.info->info5.rid != rid) {
2273 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2274 q.out.info->info5.rid, rid);
2280 case TORTURE_SAMR_OTHER:
2281 /* We just need the account to exist */
2287 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2288 struct policy_handle *alias_handle,
2289 const struct dom_sid *domain_sid)
2293 if (!test_QuerySecurity(p, tctx, alias_handle)) {
2297 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2301 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2305 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2309 if (torture_setting_bool(tctx, "samba4", false)) {
2310 printf("skipping MultipleMembers Alias tests against Samba4\n");
2314 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2322 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2323 struct policy_handle *user_handle)
2325 struct samr_DeleteUser d;
2327 torture_comment(tctx, "Testing DeleteUser\n");
2329 d.in.user_handle = user_handle;
2330 d.out.user_handle = user_handle;
2332 status = dcerpc_samr_DeleteUser(p, tctx, &d);
2333 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
2338 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2339 struct policy_handle *handle, const char *name)
2342 struct samr_DeleteUser d;
2343 struct policy_handle user_handle;
2346 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2347 if (!NT_STATUS_IS_OK(status)) {
2351 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2352 if (!NT_STATUS_IS_OK(status)) {
2356 d.in.user_handle = &user_handle;
2357 d.out.user_handle = &user_handle;
2358 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2359 if (!NT_STATUS_IS_OK(status)) {
2366 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2371 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2372 struct policy_handle *handle, const char *name)
2375 struct samr_OpenGroup r;
2376 struct samr_DeleteDomainGroup d;
2377 struct policy_handle group_handle;
2380 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2381 if (!NT_STATUS_IS_OK(status)) {
2385 r.in.domain_handle = handle;
2386 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2388 r.out.group_handle = &group_handle;
2389 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2390 if (!NT_STATUS_IS_OK(status)) {
2394 d.in.group_handle = &group_handle;
2395 d.out.group_handle = &group_handle;
2396 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2397 if (!NT_STATUS_IS_OK(status)) {
2404 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2409 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2410 struct policy_handle *domain_handle, const char *name)
2413 struct samr_OpenAlias r;
2414 struct samr_DeleteDomAlias d;
2415 struct policy_handle alias_handle;
2418 printf("testing DeleteAlias_byname\n");
2420 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2421 if (!NT_STATUS_IS_OK(status)) {
2425 r.in.domain_handle = domain_handle;
2426 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2428 r.out.alias_handle = &alias_handle;
2429 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2430 if (!NT_STATUS_IS_OK(status)) {
2434 d.in.alias_handle = &alias_handle;
2435 d.out.alias_handle = &alias_handle;
2436 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2437 if (!NT_STATUS_IS_OK(status)) {
2444 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2448 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2449 struct policy_handle *alias_handle)
2451 struct samr_DeleteDomAlias d;
2454 printf("Testing DeleteAlias\n");
2456 d.in.alias_handle = alias_handle;
2457 d.out.alias_handle = alias_handle;
2459 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2460 if (!NT_STATUS_IS_OK(status)) {
2461 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2468 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2469 struct policy_handle *domain_handle,
2470 struct policy_handle *alias_handle,
2471 const struct dom_sid *domain_sid)
2474 struct samr_CreateDomAlias r;
2475 struct lsa_String name;
2479 init_lsa_String(&name, TEST_ALIASNAME);
2480 r.in.domain_handle = domain_handle;
2481 r.in.alias_name = &name;
2482 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2483 r.out.alias_handle = alias_handle;
2486 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2488 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2490 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2491 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2492 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
2495 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
2501 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2502 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
2505 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2508 if (!NT_STATUS_IS_OK(status)) {
2509 printf("CreateAlias failed - %s\n", nt_errstr(status));
2513 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
2520 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2521 const char *acct_name,
2522 struct policy_handle *domain_handle, char **password)
2530 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2534 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
2538 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2542 /* test what happens when setting the old password again */
2543 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
2548 char simple_pass[9];
2549 char *v = generate_random_str(mem_ctx, 1);
2551 ZERO_STRUCT(simple_pass);
2552 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2554 /* test what happens when picking a simple password */
2555 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
2560 /* set samr_SetDomainInfo level 1 with min_length 5 */
2562 struct samr_QueryDomainInfo r;
2563 union samr_DomainInfo *info = NULL;
2564 struct samr_SetDomainInfo s;
2565 uint16_t len_old, len;
2566 uint32_t pwd_prop_old;
2567 int64_t min_pwd_age_old;
2572 r.in.domain_handle = domain_handle;
2576 printf("testing samr_QueryDomainInfo level 1\n");
2577 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2578 if (!NT_STATUS_IS_OK(status)) {
2582 s.in.domain_handle = domain_handle;
2586 /* remember the old min length, so we can reset it */
2587 len_old = s.in.info->info1.min_password_length;
2588 s.in.info->info1.min_password_length = len;
2589 pwd_prop_old = s.in.info->info1.password_properties;
2590 /* turn off password complexity checks for this test */
2591 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2593 min_pwd_age_old = s.in.info->info1.min_password_age;
2594 s.in.info->info1.min_password_age = 0;
2596 printf("testing samr_SetDomainInfo level 1\n");
2597 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2598 if (!NT_STATUS_IS_OK(status)) {
2602 printf("calling test_ChangePasswordUser3 with too short password\n");
2604 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
2608 s.in.info->info1.min_password_length = len_old;
2609 s.in.info->info1.password_properties = pwd_prop_old;
2610 s.in.info->info1.min_password_age = min_pwd_age_old;
2612 printf("testing samr_SetDomainInfo level 1\n");
2613 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2614 if (!NT_STATUS_IS_OK(status)) {
2622 struct samr_OpenUser r;
2623 struct samr_QueryUserInfo q;
2624 struct samr_LookupNames n;
2625 struct policy_handle user_handle;
2626 struct samr_Ids rids, types;
2628 n.in.domain_handle = domain_handle;
2630 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2631 n.in.names[0].string = acct_name;
2633 n.out.types = &types;
2635 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2636 if (!NT_STATUS_IS_OK(status)) {
2637 printf("LookupNames failed - %s\n", nt_errstr(status));
2641 r.in.domain_handle = domain_handle;
2642 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2643 r.in.rid = n.out.rids->ids[0];
2644 r.out.user_handle = &user_handle;
2646 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2647 if (!NT_STATUS_IS_OK(status)) {
2648 printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
2652 q.in.user_handle = &user_handle;
2655 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2656 if (!NT_STATUS_IS_OK(status)) {
2657 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2661 printf("calling test_ChangePasswordUser3 with too early password change\n");
2663 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2664 q.out.info->info5.last_password_change, true)) {
2669 /* we change passwords twice - this has the effect of verifying
2670 they were changed correctly for the final call */
2671 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2675 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2682 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2683 struct policy_handle *domain_handle,
2684 struct policy_handle *user_handle_out,
2685 struct dom_sid *domain_sid,
2686 enum torture_samr_choice which_ops)
2689 TALLOC_CTX *user_ctx;
2692 struct samr_CreateUser r;
2693 struct samr_QueryUserInfo q;
2694 struct samr_DeleteUser d;
2697 /* This call creates a 'normal' account - check that it really does */
2698 const uint32_t acct_flags = ACB_NORMAL;
2699 struct lsa_String name;
2702 struct policy_handle user_handle;
2703 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2704 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2706 r.in.domain_handle = domain_handle;
2707 r.in.account_name = &name;
2708 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2709 r.out.user_handle = &user_handle;
2712 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2714 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2716 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2717 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2718 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2721 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2727 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2728 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2729 talloc_free(user_ctx);
2732 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2734 if (!NT_STATUS_IS_OK(status)) {
2735 talloc_free(user_ctx);
2736 printf("CreateUser failed - %s\n", nt_errstr(status));
2739 q.in.user_handle = &user_handle;
2742 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2743 if (!NT_STATUS_IS_OK(status)) {
2744 printf("QueryUserInfo level %u failed - %s\n",
2745 q.in.level, nt_errstr(status));
2748 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2749 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2750 q.out.info->info16.acct_flags,
2756 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2757 acct_flags, name.string, which_ops)) {
2761 if (user_handle_out) {
2762 *user_handle_out = user_handle;
2764 printf("Testing DeleteUser (createuser test)\n");
2766 d.in.user_handle = &user_handle;
2767 d.out.user_handle = &user_handle;
2769 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2770 if (!NT_STATUS_IS_OK(status)) {
2771 printf("DeleteUser failed - %s\n", nt_errstr(status));
2778 talloc_free(user_ctx);
2784 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2785 struct policy_handle *domain_handle,
2786 struct dom_sid *domain_sid,
2787 enum torture_samr_choice which_ops)
2790 struct samr_CreateUser2 r;
2791 struct samr_QueryUserInfo q;
2792 struct samr_DeleteUser d;
2793 struct policy_handle user_handle;
2795 struct lsa_String name;
2800 uint32_t acct_flags;
2801 const char *account_name;
2803 } account_types[] = {
2804 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2805 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2806 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2807 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2808 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2809 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2810 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2811 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2812 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2813 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2814 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2815 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2816 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2817 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2818 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2821 for (i = 0; account_types[i].account_name; i++) {
2822 TALLOC_CTX *user_ctx;
2823 uint32_t acct_flags = account_types[i].acct_flags;
2824 uint32_t access_granted;
2825 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2826 init_lsa_String(&name, account_types[i].account_name);
2828 r.in.domain_handle = domain_handle;
2829 r.in.account_name = &name;
2830 r.in.acct_flags = acct_flags;
2831 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2832 r.out.user_handle = &user_handle;
2833 r.out.access_granted = &access_granted;
2836 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2838 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2840 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2841 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2842 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2845 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2852 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2853 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2854 talloc_free(user_ctx);
2858 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2861 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2862 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2863 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2867 if (NT_STATUS_IS_OK(status)) {
2868 q.in.user_handle = &user_handle;
2871 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2872 if (!NT_STATUS_IS_OK(status)) {
2873 printf("QueryUserInfo level %u failed - %s\n",
2874 q.in.level, nt_errstr(status));
2877 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2878 if (acct_flags == ACB_NORMAL) {
2879 expected_flags |= ACB_PW_EXPIRED;
2881 if ((q.out.info->info5.acct_flags) != expected_flags) {
2882 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2883 q.out.info->info5.acct_flags,
2887 switch (acct_flags) {
2889 if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2890 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2891 DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2896 if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2897 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2898 DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2903 if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2904 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2905 DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2912 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2913 acct_flags, name.string, which_ops)) {
2917 printf("Testing DeleteUser (createuser2 test)\n");
2919 d.in.user_handle = &user_handle;
2920 d.out.user_handle = &user_handle;
2922 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2923 if (!NT_STATUS_IS_OK(status)) {
2924 printf("DeleteUser failed - %s\n", nt_errstr(status));
2928 talloc_free(user_ctx);
2934 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2935 struct policy_handle *handle)
2938 struct samr_QueryAliasInfo r;
2939 uint16_t levels[] = {1, 2, 3};
2943 for (i=0;i<ARRAY_SIZE(levels);i++) {
2944 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2946 r.in.alias_handle = handle;
2947 r.in.level = levels[i];
2949 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2950 if (!NT_STATUS_IS_OK(status)) {
2951 printf("QueryAliasInfo level %u failed - %s\n",
2952 levels[i], nt_errstr(status));
2960 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2961 struct policy_handle *handle)
2964 struct samr_QueryGroupInfo r;
2965 uint16_t levels[] = {1, 2, 3, 4, 5};
2969 for (i=0;i<ARRAY_SIZE(levels);i++) {
2970 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2972 r.in.group_handle = handle;
2973 r.in.level = levels[i];
2975 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2976 if (!NT_STATUS_IS_OK(status)) {
2977 printf("QueryGroupInfo level %u failed - %s\n",
2978 levels[i], nt_errstr(status));
2986 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2987 struct policy_handle *handle)
2990 struct samr_QueryGroupMember r;
2991 struct samr_RidTypeArray *rids = NULL;
2994 printf("Testing QueryGroupMember\n");
2996 r.in.group_handle = handle;
2999 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
3000 if (!NT_STATUS_IS_OK(status)) {
3001 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
3009 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3010 struct policy_handle *handle)
3013 struct samr_QueryGroupInfo r;
3014 struct samr_SetGroupInfo s;
3015 uint16_t levels[] = {1, 2, 3, 4};
3016 uint16_t set_ok[] = {0, 1, 1, 1};
3020 for (i=0;i<ARRAY_SIZE(levels);i++) {
3021 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3023 r.in.group_handle = handle;
3024 r.in.level = levels[i];
3026 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3027 if (!NT_STATUS_IS_OK(status)) {
3028 printf("QueryGroupInfo level %u failed - %s\n",
3029 levels[i], nt_errstr(status));
3033 printf("Testing SetGroupInfo level %u\n", levels[i]);
3035 s.in.group_handle = handle;
3036 s.in.level = levels[i];
3037 s.in.info = r.out.info;
3040 /* disabled this, as it changes the name only from the point of view of samr,
3041 but leaves the name from the point of view of w2k3 internals (and ldap). This means
3042 the name is still reserved, so creating the old name fails, but deleting by the old name
3044 if (s.in.level == 2) {
3045 init_lsa_String(&s.in.info->string, "NewName");
3049 if (s.in.level == 4) {
3050 init_lsa_String(&s.in.info->description, "test description");
3053 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
3055 if (!NT_STATUS_IS_OK(status)) {
3056 printf("SetGroupInfo level %u failed - %s\n",
3057 r.in.level, nt_errstr(status));
3062 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3063 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3064 r.in.level, nt_errstr(status));
3074 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3075 struct policy_handle *handle)
3078 struct samr_QueryUserInfo r;
3079 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3080 11, 12, 13, 14, 16, 17, 20, 21};
3084 for (i=0;i<ARRAY_SIZE(levels);i++) {
3085 printf("Testing QueryUserInfo level %u\n", levels[i]);
3087 r.in.user_handle = handle;
3088 r.in.level = levels[i];
3090 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
3091 if (!NT_STATUS_IS_OK(status)) {
3092 printf("QueryUserInfo level %u failed - %s\n",
3093 levels[i], nt_errstr(status));
3101 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3102 struct policy_handle *handle)
3105 struct samr_QueryUserInfo2 r;
3106 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3107 11, 12, 13, 14, 16, 17, 20, 21};
3111 for (i=0;i<ARRAY_SIZE(levels);i++) {
3112 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
3114 r.in.user_handle = handle;
3115 r.in.level = levels[i];
3117 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
3118 if (!NT_STATUS_IS_OK(status)) {
3119 printf("QueryUserInfo2 level %u failed - %s\n",
3120 levels[i], nt_errstr(status));
3128 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3129 struct policy_handle *handle, uint32_t rid)
3132 struct samr_OpenUser r;
3133 struct policy_handle user_handle;
3136 printf("Testing OpenUser(%u)\n", rid);
3138 r.in.domain_handle = handle;
3139 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3141 r.out.user_handle = &user_handle;
3143 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3144 if (!NT_STATUS_IS_OK(status)) {
3145 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3149 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
3153 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
3157 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
3161 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
3165 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
3169 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3176 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3177 struct policy_handle *handle, uint32_t rid)
3180 struct samr_OpenGroup r;
3181 struct policy_handle group_handle;
3184 printf("Testing OpenGroup(%u)\n", rid);
3186 r.in.domain_handle = handle;
3187 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3189 r.out.group_handle = &group_handle;
3191 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3192 if (!NT_STATUS_IS_OK(status)) {
3193 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
3197 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
3201 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
3205 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
3209 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3216 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3217 struct policy_handle *handle, uint32_t rid)
3220 struct samr_OpenAlias r;
3221 struct policy_handle alias_handle;
3224 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
3226 r.in.domain_handle = handle;
3227 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3229 r.out.alias_handle = &alias_handle;
3231 status = dcerpc_samr_OpenAlias(p, tctx, &r);
3232 if (!NT_STATUS_IS_OK(status)) {
3233 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3237 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
3241 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
3245 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
3249 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
3256 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
3257 struct policy_handle *handle, uint32_t rid,
3258 uint32_t acct_flag_mask)
3261 struct samr_OpenUser r;
3262 struct samr_QueryUserInfo q;
3263 struct policy_handle user_handle;
3266 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
3268 r.in.domain_handle = handle;
3269 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3271 r.out.user_handle = &user_handle;
3273 status = dcerpc_samr_OpenUser(p, tctx, &r);
3274 if (!NT_STATUS_IS_OK(status)) {
3275 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3279 q.in.user_handle = &user_handle;
3282 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3283 if (!NT_STATUS_IS_OK(status)) {
3284 printf("QueryUserInfo level 16 failed - %s\n",
3288 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
3289 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3290 acct_flag_mask, q.out.info->info16.acct_flags, rid);
3295 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
3302 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
3303 struct policy_handle *handle)
3305 NTSTATUS status = STATUS_MORE_ENTRIES;
3306 struct samr_EnumDomainUsers r;
3307 uint32_t mask, resume_handle=0;
3310 struct samr_LookupNames n;
3311 struct samr_LookupRids lr ;
3312 struct lsa_Strings names;
3313 struct samr_Ids rids, types;
3315 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3316 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3317 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3320 printf("Testing EnumDomainUsers\n");
3322 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3323 r.in.domain_handle = handle;
3324 r.in.resume_handle = &resume_handle;
3325 r.in.acct_flags = mask = masks[mask_idx];
3326 r.in.max_size = (uint32_t)-1;
3327 r.out.resume_handle = &resume_handle;
3329 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
3330 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3331 !NT_STATUS_IS_OK(status)) {
3332 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3336 torture_assert(tctx, r.out.sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
3338 if (r.out.sam->count == 0) {
3342 for (i=0;i<r.out.sam->count;i++) {
3344 if (!check_mask(p, tctx, handle, r.out.sam->entries[i].idx, mask)) {
3347 } else if (!test_OpenUser(p, tctx, handle, r.out.sam->entries[i].idx)) {
3353 printf("Testing LookupNames\n");
3354 n.in.domain_handle = handle;
3355 n.in.num_names = r.out.sam->count;
3356 n.in.names = talloc_array(tctx, struct lsa_String, r.out.sam->count);
3358 n.out.types = &types;
3359 for (i=0;i<r.out.sam->count;i++) {
3360 n.in.names[i].string = r.out.sam->entries[i].name.string;
3362 status = dcerpc_samr_LookupNames(p, tctx, &n);
3363 if (!NT_STATUS_IS_OK(status)) {
3364 printf("LookupNames failed - %s\n", nt_errstr(status));
3369 printf("Testing LookupRids\n");
3370 lr.in.domain_handle = handle;
3371 lr.in.num_rids = r.out.sam->count;
3372 lr.in.rids = talloc_array(tctx, uint32_t, r.out.sam->count);
3373 lr.out.names = &names;
3374 lr.out.types = &types;
3375 for (i=0;i<r.out.sam->count;i++) {
3376 lr.in.rids[i] = r.out.sam->entries[i].idx;
3378 status = dcerpc_samr_LookupRids(p, tctx, &lr);
3379 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
3385 try blasting the server with a bunch of sync requests
3387 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
3388 struct policy_handle *handle)
3391 struct samr_EnumDomainUsers r;
3392 uint32_t resume_handle=0;
3394 #define ASYNC_COUNT 100
3395 struct rpc_request *req[ASYNC_COUNT];
3397 if (!torture_setting_bool(tctx, "dangerous", false)) {
3398 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
3401 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
3403 r.in.domain_handle = handle;
3404 r.in.resume_handle = &resume_handle;
3405 r.in.acct_flags = 0;
3406 r.in.max_size = (uint32_t)-1;
3407 r.out.resume_handle = &resume_handle;
3409 for (i=0;i<ASYNC_COUNT;i++) {
3410 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
3413 for (i=0;i<ASYNC_COUNT;i++) {
3414 status = dcerpc_ndr_request_recv(req[i]);
3415 if (!NT_STATUS_IS_OK(status)) {
3416 printf("EnumDomainUsers[%d] failed - %s\n",
3417 i, nt_errstr(status));
3422 torture_comment(tctx, "%d async requests OK\n", i);
3427 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3428 struct policy_handle *handle)
3431 struct samr_EnumDomainGroups r;
3432 uint32_t resume_handle=0;
3436 printf("Testing EnumDomainGroups\n");
3438 r.in.domain_handle = handle;
3439 r.in.resume_handle = &resume_handle;
3440 r.in.max_size = (uint32_t)-1;
3441 r.out.resume_handle = &resume_handle;
3443 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3444 if (!NT_STATUS_IS_OK(status)) {
3445 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3453 for (i=0;i<r.out.sam->count;i++) {
3454 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3462 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3463 struct policy_handle *handle)
3466 struct samr_EnumDomainAliases r;
3467 uint32_t resume_handle=0;
3468 struct samr_SamArray *sam = NULL;
3469 uint32_t num_entries = 0;
3473 printf("Testing EnumDomainAliases\n");
3475 r.in.domain_handle = handle;
3476 r.in.resume_handle = &resume_handle;
3477 r.in.max_size = (uint32_t)-1;
3479 r.out.num_entries = &num_entries;
3480 r.out.resume_handle = &resume_handle;
3482 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3483 if (!NT_STATUS_IS_OK(status)) {
3484 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3492 for (i=0;i<sam->count;i++) {
3493 if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) {
3501 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3502 struct policy_handle *handle)
3505 struct samr_GetDisplayEnumerationIndex r;
3507 uint16_t levels[] = {1, 2, 3, 4, 5};
3508 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3509 struct lsa_String name;
3513 for (i=0;i<ARRAY_SIZE(levels);i++) {
3514 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3516 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3518 r.in.domain_handle = handle;
3519 r.in.level = levels[i];
3523 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3526 !NT_STATUS_IS_OK(status) &&
3527 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3528 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3529 levels[i], nt_errstr(status));
3533 init_lsa_String(&name, "zzzzzzzz");
3535 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3537 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3538 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3539 levels[i], nt_errstr(status));
3547 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3548 struct policy_handle *handle)
3551 struct samr_GetDisplayEnumerationIndex2 r;
3553 uint16_t levels[] = {1, 2, 3, 4, 5};
3554 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3555 struct lsa_String name;
3559 for (i=0;i<ARRAY_SIZE(levels);i++) {
3560 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3562 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3564 r.in.domain_handle = handle;
3565 r.in.level = levels[i];
3569 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3571 !NT_STATUS_IS_OK(status) &&
3572 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3573 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3574 levels[i], nt_errstr(status));
3578 init_lsa_String(&name, "zzzzzzzz");
3580 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3581 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3582 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3583 levels[i], nt_errstr(status));
3591 #define STRING_EQUAL_QUERY(s1, s2, user) \
3592 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3593 /* odd, but valid */ \
3594 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3595 printf("%s mismatch for %s: %s != %s (%s)\n", \
3596 #s1, user.string, s1.string, s2.string, __location__); \
3599 #define INT_EQUAL_QUERY(s1, s2, user) \
3601 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3602 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3606 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3607 struct samr_QueryDisplayInfo *querydisplayinfo,
3608 bool *seen_testuser)
3610 struct samr_OpenUser r;
3611 struct samr_QueryUserInfo q;
3612 struct policy_handle user_handle;
3615 r.in.domain_handle = querydisplayinfo->in.domain_handle;
3616 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3617 for (i = 0; ; i++) {
3618 switch (querydisplayinfo->in.level) {
3620 if (i >= querydisplayinfo->out.info->info1.count) {
3623 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
3626 if (i >= querydisplayinfo->out.info->info2.count) {
3629 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
3635 /* Not interested in validating just the account name */
3639 r.out.user_handle = &user_handle;
3641 switch (querydisplayinfo->in.level) {
3644 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3645 if (!NT_STATUS_IS_OK(status)) {
3646 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3651 q.in.user_handle = &user_handle;
3653 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3654 if (!NT_STATUS_IS_OK(status)) {
3655 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3659 switch (querydisplayinfo->in.level) {
3661 if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3662 *seen_testuser = true;
3664 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
3665 q.out.info->info21.full_name, q.out.info->info21.account_name);
3666 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
3667 q.out.info->info21.account_name, q.out.info->info21.account_name);
3668 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
3669 q.out.info->info21.description, q.out.info->info21.account_name);
3670 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
3671 q.out.info->info21.rid, q.out.info->info21.account_name);
3672 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
3673 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3677 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
3678 q.out.info->info21.account_name, q.out.info->info21.account_name);
3679 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
3680 q.out.info->info21.description, q.out.info->info21.account_name);
3681 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
3682 q.out.info->info21.rid, q.out.info->info21.account_name);
3683 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
3684 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3686 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
3687 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
3688 q.out.info->info21.account_name.string);
3691 if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3692 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3693 q.out.info->info21.account_name.string,
3694 querydisplayinfo->out.info->info2.entries[i].acct_flags,
3695 q.out.info->info21.acct_flags);
3702 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3709 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3710 struct policy_handle *handle)
3713 struct samr_QueryDisplayInfo r;
3714 struct samr_QueryDomainInfo dom_info;
3715 union samr_DomainInfo *info = NULL;
3717 uint16_t levels[] = {1, 2, 3, 4, 5};
3719 bool seen_testuser = false;
3720 uint32_t total_size;
3721 uint32_t returned_size;
3722 union samr_DispInfo disp_info;
3725 for (i=0;i<ARRAY_SIZE(levels);i++) {
3726 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3729 status = STATUS_MORE_ENTRIES;
3730 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3731 r.in.domain_handle = handle;
3732 r.in.level = levels[i];
3733 r.in.max_entries = 2;
3734 r.in.buf_size = (uint32_t)-1;
3735 r.out.total_size = &total_size;
3736 r.out.returned_size = &returned_size;
3737 r.out.info = &disp_info;
3739 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3740 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3741 printf("QueryDisplayInfo level %u failed - %s\n",
3742 levels[i], nt_errstr(status));
3745 switch (r.in.level) {
3747 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3750 r.in.start_idx += r.out.info->info1.count;
3753 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3756 r.in.start_idx += r.out.info->info2.count;
3759 r.in.start_idx += r.out.info->info3.count;
3762 r.in.start_idx += r.out.info->info4.count;
3765 r.in.start_idx += r.out.info->info5.count;
3769 dom_info.in.domain_handle = handle;
3770 dom_info.in.level = 2;
3771 dom_info.out.info = &info;
3773 /* Check number of users returned is correct */
3774 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3775 if (!NT_STATUS_IS_OK(status)) {
3776 printf("QueryDomainInfo level %u failed - %s\n",
3777 r.in.level, nt_errstr(status));
3781 switch (r.in.level) {
3784 if (info->general.num_users < r.in.start_idx) {
3785 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3786 r.in.start_idx, info->general.num_groups,
3787 info->general.domain_name.string);
3790 if (!seen_testuser) {
3791 struct policy_handle user_handle;
3792 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3793 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
3794 info->general.domain_name.string);
3796 test_samr_handle_Close(p, mem_ctx, &user_handle);
3802 if (info->general.num_groups != r.in.start_idx) {
3803 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3804 r.in.start_idx, info->general.num_groups,
3805 info->general.domain_name.string);
3817 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3818 struct policy_handle *handle)
3821 struct samr_QueryDisplayInfo2 r;
3823 uint16_t levels[] = {1, 2, 3, 4, 5};
3825 uint32_t total_size;
3826 uint32_t returned_size;
3827 union samr_DispInfo info;
3829 for (i=0;i<ARRAY_SIZE(levels);i++) {
3830 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3832 r.in.domain_handle = handle;
3833 r.in.level = levels[i];
3835 r.in.max_entries = 1000;
3836 r.in.buf_size = (uint32_t)-1;
3837 r.out.total_size = &total_size;
3838 r.out.returned_size = &returned_size;
3841 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3842 if (!NT_STATUS_IS_OK(status)) {
3843 printf("QueryDisplayInfo2 level %u failed - %s\n",
3844 levels[i], nt_errstr(status));
3852 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
3853 struct policy_handle *handle)
3856 struct samr_QueryDisplayInfo3 r;
3858 uint16_t levels[] = {1, 2, 3, 4, 5};
3860 uint32_t total_size;
3861 uint32_t returned_size;
3862 union samr_DispInfo info;
3864 for (i=0;i<ARRAY_SIZE(levels);i++) {
3865 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
3867 r.in.domain_handle = handle;
3868 r.in.level = levels[i];
3870 r.in.max_entries = 1000;
3871 r.in.buf_size = (uint32_t)-1;
3872 r.out.total_size = &total_size;
3873 r.out.returned_size = &returned_size;
3876 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
3877 if (!NT_STATUS_IS_OK(status)) {
3878 printf("QueryDisplayInfo3 level %u failed - %s\n",
3879 levels[i], nt_errstr(status));
3888 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3889 struct policy_handle *handle)
3892 struct samr_QueryDisplayInfo r;
3894 uint32_t total_size;
3895 uint32_t returned_size;
3896 union samr_DispInfo info;
3898 printf("Testing QueryDisplayInfo continuation\n");
3900 r.in.domain_handle = handle;
3903 r.in.max_entries = 1;
3904 r.in.buf_size = (uint32_t)-1;
3905 r.out.total_size = &total_size;
3906 r.out.returned_size = &returned_size;
3910 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3911 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
3912 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
3913 printf("expected idx %d but got %d\n",
3915 r.out.info->info1.entries[0].idx);
3919 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3920 !NT_STATUS_IS_OK(status)) {
3921 printf("QueryDisplayInfo level %u failed - %s\n",
3922 r.in.level, nt_errstr(status));
3927 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3928 NT_STATUS_IS_OK(status)) &&
3929 *r.out.returned_size != 0);
3934 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
3935 struct policy_handle *handle)
3938 struct samr_QueryDomainInfo r;
3939 union samr_DomainInfo *info = NULL;
3940 struct samr_SetDomainInfo s;
3941 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3942 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3945 const char *domain_comment = talloc_asprintf(tctx,
3946 "Tortured by Samba4 RPC-SAMR: %s",
3947 timestring(tctx, time(NULL)));
3949 s.in.domain_handle = handle;
3951 s.in.info = talloc(tctx, union samr_DomainInfo);
3953 s.in.info->oem.oem_information.string = domain_comment;
3954 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
3955 if (!NT_STATUS_IS_OK(status)) {
3956 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3957 r.in.level, nt_errstr(status));
3961 for (i=0;i<ARRAY_SIZE(levels);i++) {
3962 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
3964 r.in.domain_handle = handle;
3965 r.in.level = levels[i];
3968 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
3969 if (!NT_STATUS_IS_OK(status)) {
3970 printf("QueryDomainInfo level %u failed - %s\n",
3971 r.in.level, nt_errstr(status));
3976 switch (levels[i]) {
3978 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
3979 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3980 levels[i], info->general.oem_information.string, domain_comment);
3983 if (!info->general.primary.string) {
3984 printf("QueryDomainInfo level %u returned no PDC name\n",
3987 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
3988 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
3989 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3990 levels[i], info->general.primary.string, dcerpc_server_name(p));
3995 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
3996 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3997 levels[i], info->oem.oem_information.string, domain_comment);
4002 if (!info->info6.primary.string) {
4003 printf("QueryDomainInfo level %u returned no PDC name\n",
4009 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
4010 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
4011 levels[i], info->general2.general.oem_information.string, domain_comment);
4017 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
4019 s.in.domain_handle = handle;
4020 s.in.level = levels[i];
4023 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4025 if (!NT_STATUS_IS_OK(status)) {
4026 printf("SetDomainInfo level %u failed - %s\n",
4027 r.in.level, nt_errstr(status));
4032 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4033 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4034 r.in.level, nt_errstr(status));
4040 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4041 if (!NT_STATUS_IS_OK(status)) {
4042 printf("QueryDomainInfo level %u failed - %s\n",
4043 r.in.level, nt_errstr(status));
4053 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
4054 struct policy_handle *handle)
4057 struct samr_QueryDomainInfo2 r;
4058 union samr_DomainInfo *info = NULL;
4059 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4063 for (i=0;i<ARRAY_SIZE(levels);i++) {
4064 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
4066 r.in.domain_handle = handle;
4067 r.in.level = levels[i];
4070 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
4071 if (!NT_STATUS_IS_OK(status)) {
4072 printf("QueryDomainInfo2 level %u failed - %s\n",
4073 r.in.level, nt_errstr(status));
4082 /* Test whether querydispinfo level 5 and enumdomgroups return the same
4083 set of group names. */
4084 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
4085 struct policy_handle *handle)
4087 struct samr_EnumDomainGroups q1;
4088 struct samr_QueryDisplayInfo q2;
4090 uint32_t resume_handle=0;
4093 uint32_t total_size;
4094 uint32_t returned_size;
4095 union samr_DispInfo info;
4098 const char **names = NULL;
4100 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
4102 q1.in.domain_handle = handle;
4103 q1.in.resume_handle = &resume_handle;
4105 q1.out.resume_handle = &resume_handle;
4107 status = STATUS_MORE_ENTRIES;
4108 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4109 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
4111 if (!NT_STATUS_IS_OK(status) &&
4112 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4115 for (i=0; i<q1.out.num_entries; i++) {
4116 add_string_to_array(tctx,
4117 q1.out.sam->entries[i].name.string,
4118 &names, &num_names);
4122 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
4124 torture_assert(tctx, q1.out.sam, "EnumDomainGroups failed to return q1.out.sam");
4126 q2.in.domain_handle = handle;
4128 q2.in.start_idx = 0;
4129 q2.in.max_entries = 5;
4130 q2.in.buf_size = (uint32_t)-1;
4131 q2.out.total_size = &total_size;
4132 q2.out.returned_size = &returned_size;
4133 q2.out.info = &info;
4135 status = STATUS_MORE_ENTRIES;
4136 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4137 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
4139 if (!NT_STATUS_IS_OK(status) &&
4140 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4143 for (i=0; i<q2.out.info->info5.count; i++) {
4145 const char *name = q2.out.info->info5.entries[i].account_name.string;
4147 for (j=0; j<num_names; j++) {
4148 if (names[j] == NULL)
4150 if (strequal(names[j], name)) {
4158 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
4163 q2.in.start_idx += q2.out.info->info5.count;
4166 if (!NT_STATUS_IS_OK(status)) {
4167 printf("QueryDisplayInfo level 5 failed - %s\n",
4172 for (i=0; i<num_names; i++) {
4173 if (names[i] != NULL) {
4174 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
4183 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
4184 struct policy_handle *group_handle)
4186 struct samr_DeleteDomainGroup d;
4189 torture_comment(tctx, "Testing DeleteDomainGroup\n");
4191 d.in.group_handle = group_handle;
4192 d.out.group_handle = group_handle;
4194 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
4195 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
4200 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4201 struct policy_handle *domain_handle)
4203 struct samr_TestPrivateFunctionsDomain r;
4207 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
4209 r.in.domain_handle = domain_handle;
4211 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
4212 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
4217 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
4218 struct dom_sid *domain_sid,
4219 struct policy_handle *domain_handle)
4221 struct samr_RidToSid r;
4224 struct dom_sid *calc_sid, *out_sid;
4225 int rids[] = { 0, 42, 512, 10200 };
4228 for (i=0;i<ARRAY_SIZE(rids);i++) {
4229 torture_comment(tctx, "Testing RidToSid\n");
4231 calc_sid = dom_sid_dup(tctx, domain_sid);
4232 r.in.domain_handle = domain_handle;
4234 r.out.sid = &out_sid;
4236 status = dcerpc_samr_RidToSid(p, tctx, &r);
4237 if (!NT_STATUS_IS_OK(status)) {
4238 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
4241 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
4243 if (!dom_sid_equal(calc_sid, out_sid)) {
4244 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
4245 dom_sid_string(tctx, out_sid),
4246 dom_sid_string(tctx, calc_sid));
4255 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
4256 struct policy_handle *domain_handle)
4258 struct samr_GetBootKeyInformation r;
4261 uint32_t unknown = 0;
4263 torture_comment(tctx, "Testing GetBootKeyInformation\n");
4265 r.in.domain_handle = domain_handle;
4266 r.out.unknown = &unknown;
4268 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
4269 if (!NT_STATUS_IS_OK(status)) {
4270 /* w2k3 seems to fail this sometimes and pass it sometimes */
4271 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4277 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
4278 struct policy_handle *domain_handle,
4279 struct policy_handle *group_handle)
4282 struct samr_AddGroupMember r;
4283 struct samr_DeleteGroupMember d;
4284 struct samr_QueryGroupMember q;
4285 struct samr_RidTypeArray *rids = NULL;
4286 struct samr_SetMemberAttributesOfGroup s;
4289 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4290 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
4292 r.in.group_handle = group_handle;
4294 r.in.flags = 0; /* ??? */
4296 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
4298 d.in.group_handle = group_handle;
4301 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4302 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
4304 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4305 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4307 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4308 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
4310 if (torture_setting_bool(tctx, "samba4", false)) {
4311 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
4313 /* this one is quite strange. I am using random inputs in the
4314 hope of triggering an error that might give us a clue */
4316 s.in.group_handle = group_handle;
4317 s.in.unknown1 = random();
4318 s.in.unknown2 = random();
4320 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4321 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
4324 q.in.group_handle = group_handle;
4327 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4328 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
4330 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4331 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
4333 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4334 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4340 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
4341 struct torture_context *tctx,
4342 struct policy_handle *domain_handle,
4343 struct policy_handle *group_handle,
4344 struct dom_sid *domain_sid)
4347 struct samr_CreateDomainGroup r;
4349 struct lsa_String name;
4352 init_lsa_String(&name, TEST_GROUPNAME);
4354 r.in.domain_handle = domain_handle;
4356 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4357 r.out.group_handle = group_handle;
4360 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4362 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4364 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4365 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4366 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
4369 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
4375 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4376 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
4377 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
4381 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4383 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4384 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
4386 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4390 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4392 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
4394 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
4395 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4399 if (!test_SetGroupInfo(p, tctx, group_handle)) {
4408 its not totally clear what this does. It seems to accept any sid you like.
4410 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
4411 struct torture_context *tctx,
4412 struct policy_handle *domain_handle)
4415 struct samr_RemoveMemberFromForeignDomain r;
4417 r.in.domain_handle = domain_handle;
4418 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
4420 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
4421 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
4428 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4429 struct policy_handle *handle);
4431 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4432 struct policy_handle *handle, struct dom_sid *sid,
4433 enum torture_samr_choice which_ops)
4436 struct samr_OpenDomain r;
4437 struct policy_handle domain_handle;
4438 struct policy_handle alias_handle;
4439 struct policy_handle user_handle;
4440 struct policy_handle group_handle;
4443 ZERO_STRUCT(alias_handle);
4444 ZERO_STRUCT(user_handle);
4445 ZERO_STRUCT(group_handle);
4446 ZERO_STRUCT(domain_handle);
4448 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
4450 r.in.connect_handle = handle;
4451 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4453 r.out.domain_handle = &domain_handle;
4455 status = dcerpc_samr_OpenDomain(p, tctx, &r);
4456 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
4458 /* run the domain tests with the main handle closed - this tests
4459 the servers reference counting */
4460 ret &= test_samr_handle_Close(p, tctx, handle);
4462 switch (which_ops) {
4463 case TORTURE_SAMR_USER_ATTRIBUTES:
4464 case TORTURE_SAMR_PASSWORDS:
4465 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
4466 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4467 /* This test needs 'complex' users to validate */
4468 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
4470 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
4473 case TORTURE_SAMR_OTHER:
4474 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4476 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
4478 ret &= test_QuerySecurity(p, tctx, &domain_handle);
4479 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
4480 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
4481 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
4482 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
4483 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
4484 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
4485 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
4486 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
4487 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
4488 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
4489 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
4490 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
4492 if (torture_setting_bool(tctx, "samba4", false)) {
4493 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
4495 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
4496 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
4498 ret &= test_GroupList(p, tctx, &domain_handle);
4499 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
4500 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
4501 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
4503 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
4508 if (!policy_handle_empty(&user_handle) &&
4509 !test_DeleteUser(p, tctx, &user_handle)) {
4513 if (!policy_handle_empty(&alias_handle) &&
4514 !test_DeleteAlias(p, tctx, &alias_handle)) {
4518 if (!policy_handle_empty(&group_handle) &&
4519 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
4523 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
4525 /* reconnect the main handle */
4526 ret &= test_Connect(p, tctx, handle);
4529 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
4535 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4536 struct policy_handle *handle, const char *domain,
4537 enum torture_samr_choice which_ops)
4540 struct samr_LookupDomain r;
4541 struct dom_sid2 *sid = NULL;
4542 struct lsa_String n1;
4543 struct lsa_String n2;
4546 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
4548 /* check for correct error codes */
4549 r.in.connect_handle = handle;
4550 r.in.domain_name = &n2;
4554 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4555 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
4557 init_lsa_String(&n2, "xxNODOMAINxx");
4559 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4560 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
4562 r.in.connect_handle = handle;
4564 init_lsa_String(&n1, domain);
4565 r.in.domain_name = &n1;
4567 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4568 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
4570 if (!test_GetDomPwInfo(p, tctx, &n1)) {
4574 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops)) {
4582 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
4583 struct policy_handle *handle, enum torture_samr_choice which_ops)
4586 struct samr_EnumDomains r;
4587 uint32_t resume_handle = 0;
4591 r.in.connect_handle = handle;
4592 r.in.resume_handle = &resume_handle;
4593 r.in.buf_size = (uint32_t)-1;
4594 r.out.resume_handle = &resume_handle;
4596 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4597 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4603 for (i=0;i<r.out.sam->count;i++) {
4604 if (!test_LookupDomain(p, tctx, handle,
4605 r.out.sam->entries[i].name.string, which_ops)) {
4610 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4611 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
4617 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
4618 struct policy_handle *handle)
4621 struct samr_Connect r;
4622 struct samr_Connect2 r2;
4623 struct samr_Connect3 r3;
4624 struct samr_Connect4 r4;
4625 struct samr_Connect5 r5;
4626 union samr_ConnectInfo info;
4627 struct policy_handle h;
4628 uint32_t level_out = 0;
4629 bool ret = true, got_handle = false;
4631 torture_comment(tctx, "testing samr_Connect\n");
4633 r.in.system_name = 0;
4634 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4635 r.out.connect_handle = &h;
4637 status = dcerpc_samr_Connect(p, tctx, &r);
4638 if (!NT_STATUS_IS_OK(status)) {
4639 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
4646 torture_comment(tctx, "testing samr_Connect2\n");
4648 r2.in.system_name = NULL;
4649 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4650 r2.out.connect_handle = &h;
4652 status = dcerpc_samr_Connect2(p, tctx, &r2);
4653 if (!NT_STATUS_IS_OK(status)) {
4654 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
4658 test_samr_handle_Close(p, tctx, handle);
4664 torture_comment(tctx, "testing samr_Connect3\n");
4666 r3.in.system_name = NULL;
4668 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4669 r3.out.connect_handle = &h;
4671 status = dcerpc_samr_Connect3(p, tctx, &r3);
4672 if (!NT_STATUS_IS_OK(status)) {
4673 printf("Connect3 failed - %s\n", nt_errstr(status));
4677 test_samr_handle_Close(p, tctx, handle);
4683 torture_comment(tctx, "testing samr_Connect4\n");
4685 r4.in.system_name = "";
4686 r4.in.client_version = 0;
4687 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4688 r4.out.connect_handle = &h;
4690 status = dcerpc_samr_Connect4(p, tctx, &r4);
4691 if (!NT_STATUS_IS_OK(status)) {
4692 printf("Connect4 failed - %s\n", nt_errstr(status));
4696 test_samr_handle_Close(p, tctx, handle);
4702 torture_comment(tctx, "testing samr_Connect5\n");
4704 info.info1.client_version = 0;
4705 info.info1.unknown2 = 0;
4707 r5.in.system_name = "";
4708 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4710 r5.out.level_out = &level_out;
4711 r5.in.info_in = &info;
4712 r5.out.info_out = &info;
4713 r5.out.connect_handle = &h;
4715 status = dcerpc_samr_Connect5(p, tctx, &r5);
4716 if (!NT_STATUS_IS_OK(status)) {
4717 printf("Connect5 failed - %s\n", nt_errstr(status));
4721 test_samr_handle_Close(p, tctx, handle);
4731 bool torture_rpc_samr(struct torture_context *torture)
4734 struct dcerpc_pipe *p;
4736 struct policy_handle handle;
4738 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4739 if (!NT_STATUS_IS_OK(status)) {
4743 ret &= test_Connect(p, torture, &handle);
4745 ret &= test_QuerySecurity(p, torture, &handle);
4747 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4749 ret &= test_SetDsrmPassword(p, torture, &handle);
4751 ret &= test_Shutdown(p, torture, &handle);
4753 ret &= test_samr_handle_Close(p, torture, &handle);
4759 bool torture_rpc_samr_users(struct torture_context *torture)
4762 struct dcerpc_pipe *p;
4764 struct policy_handle handle;
4766 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4767 if (!NT_STATUS_IS_OK(status)) {
4771 ret &= test_Connect(p, torture, &handle);
4773 ret &= test_QuerySecurity(p, torture, &handle);
4775 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4777 ret &= test_SetDsrmPassword(p, torture, &handle);
4779 ret &= test_Shutdown(p, torture, &handle);
4781 ret &= test_samr_handle_Close(p, torture, &handle);
4787 bool torture_rpc_samr_passwords(struct torture_context *torture)
4790 struct dcerpc_pipe *p;
4792 struct policy_handle handle;
4794 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4795 if (!NT_STATUS_IS_OK(status)) {
4799 ret &= test_Connect(p, torture, &handle);
4801 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4803 ret &= test_samr_handle_Close(p, torture, &handle);